| OLD | NEW |
| 1 // Protocol Buffers - Google's data interchange format | 1 // Protocol Buffers - Google's data interchange format |
| 2 // Copyright 2008 Google Inc. All rights reserved. | 2 // Copyright 2008 Google Inc. All rights reserved. |
| 3 // https://developers.google.com/protocol-buffers/ | 3 // https://developers.google.com/protocol-buffers/ |
| 4 // | 4 // |
| 5 // Redistribution and use in source and binary forms, with or without | 5 // Redistribution and use in source and binary forms, with or without |
| 6 // modification, are permitted provided that the following conditions are | 6 // modification, are permitted provided that the following conditions are |
| 7 // met: | 7 // met: |
| 8 // | 8 // |
| 9 // * Redistributions of source code must retain the above copyright | 9 // * Redistributions of source code must retain the above copyright |
| 10 // notice, this list of conditions and the following disclaimer. | 10 // notice, this list of conditions and the following disclaimer. |
| (...skipping 27 matching lines...) Expand all Loading... |
| 38 namespace protobuf { | 38 namespace protobuf { |
| 39 namespace compiler { | 39 namespace compiler { |
| 40 namespace cpp { | 40 namespace cpp { |
| 41 | 41 |
| 42 bool IsProto3Field(const FieldDescriptor* field_descriptor) { | 42 bool IsProto3Field(const FieldDescriptor* field_descriptor) { |
| 43 const FileDescriptor* file_descriptor = field_descriptor->file(); | 43 const FileDescriptor* file_descriptor = field_descriptor->file(); |
| 44 return file_descriptor->syntax() == FileDescriptor::SYNTAX_PROTO3; | 44 return file_descriptor->syntax() == FileDescriptor::SYNTAX_PROTO3; |
| 45 } | 45 } |
| 46 | 46 |
| 47 void SetMessageVariables(const FieldDescriptor* descriptor, | 47 void SetMessageVariables(const FieldDescriptor* descriptor, |
| 48 map<string, string>* variables, | 48 std::map<string, string>* variables, |
| 49 const Options& options) { | 49 const Options& options) { |
| 50 SetCommonFieldVariables(descriptor, variables, options); | 50 SetCommonFieldVariables(descriptor, variables, options); |
| 51 (*variables)["type"] = FieldMessageTypeName(descriptor); | 51 (*variables)["type"] = ClassName(descriptor->message_type(), false); |
| 52 (*variables)["stream_writer"] = | 52 (*variables)["stream_writer"] = |
| 53 (*variables)["declared_type"] + | 53 (*variables)["declared_type"] + |
| 54 (HasFastArraySerialization(descriptor->message_type()->file(), options) | 54 (HasFastArraySerialization(descriptor->message_type()->file(), options) |
| 55 ? "MaybeToArray" | 55 ? "MaybeToArray" |
| 56 : ""); | 56 : ""); |
| 57 (*variables)["full_name"] = descriptor->full_name(); | 57 (*variables)["full_name"] = descriptor->full_name(); |
| 58 | 58 |
| 59 const FieldDescriptor* key = | 59 const FieldDescriptor* key = |
| 60 descriptor->message_type()->FindFieldByName("key"); | 60 descriptor->message_type()->FindFieldByName("key"); |
| 61 const FieldDescriptor* val = | 61 const FieldDescriptor* val = |
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 130 printer->Print(variables_, | 130 printer->Print(variables_, |
| 131 "$deprecated_attr$const ::google::protobuf::Map< $key_cpp$, $val_cpp$ >&\n
" | 131 "$deprecated_attr$const ::google::protobuf::Map< $key_cpp$, $val_cpp$ >&\n
" |
| 132 " $name$() const;\n" | 132 " $name$() const;\n" |
| 133 "$deprecated_attr$::google::protobuf::Map< $key_cpp$, $val_cpp$ >*\n" | 133 "$deprecated_attr$::google::protobuf::Map< $key_cpp$, $val_cpp$ >*\n" |
| 134 " mutable_$name$();\n"); | 134 " mutable_$name$();\n"); |
| 135 } | 135 } |
| 136 | 136 |
| 137 void MapFieldGenerator:: | 137 void MapFieldGenerator:: |
| 138 GenerateInlineAccessorDefinitions(io::Printer* printer, | 138 GenerateInlineAccessorDefinitions(io::Printer* printer, |
| 139 bool is_inline) const { | 139 bool is_inline) const { |
| 140 map<string, string> variables(variables_); | 140 std::map<string, string> variables(variables_); |
| 141 variables["inline"] = is_inline ? "inline" : ""; | 141 variables["inline"] = is_inline ? "inline" : ""; |
| 142 printer->Print(variables, | 142 printer->Print(variables, |
| 143 "$inline$ const ::google::protobuf::Map< $key_cpp$, $val_cpp$ >&\n" | 143 "$inline$ const ::google::protobuf::Map< $key_cpp$, $val_cpp$ >&\n" |
| 144 "$classname$::$name$() const {\n" | 144 "$classname$::$name$() const {\n" |
| 145 " // @@protoc_insertion_point(field_map:$full_name$)\n" | 145 " // @@protoc_insertion_point(field_map:$full_name$)\n" |
| 146 " return $name$_.GetMap();\n" | 146 " return $name$_.GetMap();\n" |
| 147 "}\n" | 147 "}\n" |
| 148 "$inline$ ::google::protobuf::Map< $key_cpp$, $val_cpp$ >*\n" | 148 "$inline$ ::google::protobuf::Map< $key_cpp$, $val_cpp$ >*\n" |
| 149 "$classname$::mutable_$name$() {\n" | 149 "$classname$::mutable_$name$() {\n" |
| 150 " // @@protoc_insertion_point(field_mutable_map:$full_name$)\n" | 150 " // @@protoc_insertion_point(field_mutable_map:$full_name$)\n" |
| 151 " return $name$_.MutableMap();\n" | 151 " return $name$_.MutableMap();\n" |
| 152 "}\n"); | 152 "}\n"); |
| 153 } | 153 } |
| 154 | 154 |
| 155 void MapFieldGenerator:: | 155 void MapFieldGenerator:: |
| 156 GenerateClearingCode(io::Printer* printer) const { | 156 GenerateClearingCode(io::Printer* printer) const { |
| 157 map<string, string> variables(variables_); | 157 std::map<string, string> variables(variables_); |
| 158 variables["this_message"] = dependent_field_ ? DependentBaseDownCast() : ""; | 158 variables["this_message"] = dependent_field_ ? DependentBaseDownCast() : ""; |
| 159 printer->Print(variables, "$this_message$$name$_.Clear();\n"); | 159 printer->Print(variables, "$this_message$$name$_.Clear();\n"); |
| 160 } | 160 } |
| 161 | 161 |
| 162 void MapFieldGenerator:: | 162 void MapFieldGenerator:: |
| 163 GenerateMergingCode(io::Printer* printer) const { | 163 GenerateMergingCode(io::Printer* printer) const { |
| 164 printer->Print(variables_, "$name$_.MergeFrom(from.$name$_);\n"); | 164 printer->Print(variables_, "$name$_.MergeFrom(from.$name$_);\n"); |
| 165 } | 165 } |
| 166 | 166 |
| 167 void MapFieldGenerator:: | 167 void MapFieldGenerator:: |
| 168 GenerateSwappingCode(io::Printer* printer) const { | 168 GenerateSwappingCode(io::Printer* printer) const { |
| 169 printer->Print(variables_, "$name$_.Swap(&other->$name$_);\n"); | 169 printer->Print(variables_, "$name$_.Swap(&other->$name$_);\n"); |
| 170 } | 170 } |
| 171 | 171 |
| 172 void MapFieldGenerator:: | 172 void MapFieldGenerator:: |
| 173 GenerateConstructorCode(io::Printer* printer) const { | 173 GenerateConstructorCode(io::Printer* printer) const { |
| 174 if (HasDescriptorMethods(descriptor_->file(), options_)) { | 174 if (HasDescriptorMethods(descriptor_->file(), options_)) { |
| 175 printer->Print(variables_, | 175 printer->Print(variables_, |
| 176 "$name$_.SetAssignDescriptorCallback(\n" | 176 "$name$_.SetAssignDescriptorCallback(\n" |
| 177 " protobuf_AssignDescriptorsOnce);\n" | 177 " protobuf_AssignDescriptorsOnce);\n" |
| 178 "$name$_.SetEntryDescriptor(\n" | 178 "$name$_.SetEntryDescriptor(\n" |
| 179 " &$type$_descriptor_);\n"); | 179 " &$type$_descriptor);\n"); |
| 180 } | 180 } |
| 181 } | 181 } |
| 182 | 182 |
| 183 void MapFieldGenerator:: | 183 void MapFieldGenerator:: |
| 184 GenerateCopyConstructorCode(io::Printer* printer) const { |
| 185 GenerateConstructorCode(printer); |
| 186 GenerateMergingCode(printer); |
| 187 } |
| 188 |
| 189 void MapFieldGenerator:: |
| 184 GenerateMergeFromCodedStream(io::Printer* printer) const { | 190 GenerateMergeFromCodedStream(io::Printer* printer) const { |
| 191 const FieldDescriptor* key_field = |
| 192 descriptor_->message_type()->FindFieldByName("key"); |
| 185 const FieldDescriptor* value_field = | 193 const FieldDescriptor* value_field = |
| 186 descriptor_->message_type()->FindFieldByName("value"); | 194 descriptor_->message_type()->FindFieldByName("value"); |
| 187 printer->Print(variables_, | 195 bool using_entry = false; |
| 188 "::google::protobuf::scoped_ptr<$map_classname$> entry($name$_.NewEntry())
;\n"); | 196 string key; |
| 189 | 197 string value; |
| 190 if (IsProto3Field(descriptor_) || | 198 if (IsProto3Field(descriptor_) || |
| 191 value_field->type() != FieldDescriptor::TYPE_ENUM) { | 199 value_field->type() != FieldDescriptor::TYPE_ENUM) { |
| 192 printer->Print(variables_, | 200 printer->Print(variables_, |
| 201 "$map_classname$::Parser< ::google::protobuf::internal::MapField$lite$<\
n" |
| 202 " $key_cpp$, $val_cpp$,\n" |
| 203 " $key_wire_type$,\n" |
| 204 " $val_wire_type$,\n" |
| 205 " $default_enum_value$ >,\n" |
| 206 " ::google::protobuf::Map< $key_cpp$, $val_cpp$ > >" |
| 207 " parser(&$name$_);\n" |
| 193 "DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
\n" | 208 "DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
\n" |
| 194 " input, entry.get()));\n"); | 209 " input, &parser));\n"); |
| 195 switch (value_field->cpp_type()) { | 210 key = "parser.key()"; |
| 196 case FieldDescriptor::CPPTYPE_MESSAGE: | 211 value = "parser.value()"; |
| 197 printer->Print(variables_, | |
| 198 "(*mutable_$name$())[entry->key()].Swap(" | |
| 199 "entry->mutable_value());\n"); | |
| 200 break; | |
| 201 case FieldDescriptor::CPPTYPE_ENUM: | |
| 202 printer->Print(variables_, | |
| 203 "(*mutable_$name$())[entry->key()] =\n" | |
| 204 " static_cast< $val_cpp$ >(*entry->mutable_value());\n"); | |
| 205 break; | |
| 206 default: | |
| 207 printer->Print(variables_, | |
| 208 "(*mutable_$name$())[entry->key()] = *entry->mutable_value();\n"); | |
| 209 break; | |
| 210 } | |
| 211 } else { | 212 } else { |
| 213 using_entry = true; |
| 214 key = "entry->key()"; |
| 215 value = "entry->value()"; |
| 216 printer->Print(variables_, |
| 217 "::google::protobuf::scoped_ptr<$map_classname$> entry($name$_.NewEntry(
));\n"); |
| 212 printer->Print(variables_, | 218 printer->Print(variables_, |
| 213 "{\n" | 219 "{\n" |
| 214 " ::std::string data;\n" | 220 " ::std::string data;\n" |
| 215 " DO_(::google::protobuf::internal::WireFormatLite::ReadString(input, &
data));\n" | 221 " DO_(::google::protobuf::internal::WireFormatLite::ReadString(input, &
data));\n" |
| 216 " DO_(entry->ParseFromString(data));\n" | 222 " DO_(entry->ParseFromString(data));\n" |
| 217 " if ($val_cpp$_IsValid(*entry->mutable_value())) {\n" | 223 " if ($val_cpp$_IsValid(*entry->mutable_value())) {\n" |
| 218 " (*mutable_$name$())[entry->key()] =\n" | 224 " (*mutable_$name$())[entry->key()] =\n" |
| 219 " static_cast< $val_cpp$ >(*entry->mutable_value());\n" | 225 " static_cast< $val_cpp$ >(*entry->mutable_value());\n" |
| 220 " } else {\n"); | 226 " } else {\n"); |
| 221 if (HasDescriptorMethods(descriptor_->file(), options_)) { | 227 if (HasDescriptorMethods(descriptor_->file(), options_)) { |
| 222 printer->Print(variables_, | 228 printer->Print(variables_, |
| 223 " mutable_unknown_fields()" | 229 " mutable_unknown_fields()" |
| 224 "->AddLengthDelimited($number$, data);\n"); | 230 "->AddLengthDelimited($number$, data);\n"); |
| 225 } else { | 231 } else { |
| 226 printer->Print(variables_, | 232 printer->Print(variables_, |
| 227 " unknown_fields_stream.WriteVarint32($tag$);\n" | 233 " unknown_fields_stream.WriteVarint32($tag$u);\n" |
| 228 " unknown_fields_stream.WriteVarint32(data.size());\n" | 234 " unknown_fields_stream.WriteVarint32(data.size());\n" |
| 229 " unknown_fields_stream.WriteString(data);\n"); | 235 " unknown_fields_stream.WriteString(data);\n"); |
| 230 } | 236 } |
| 231 | 237 |
| 232 | |
| 233 printer->Print(variables_, | 238 printer->Print(variables_, |
| 234 " }\n" | 239 " }\n" |
| 235 "}\n"); | 240 "}\n"); |
| 236 } | 241 } |
| 237 | 242 |
| 238 const FieldDescriptor* key_field = | |
| 239 descriptor_->message_type()->FindFieldByName("key"); | |
| 240 if (key_field->type() == FieldDescriptor::TYPE_STRING) { | 243 if (key_field->type() == FieldDescriptor::TYPE_STRING) { |
| 241 GenerateUtf8CheckCodeForString( | 244 GenerateUtf8CheckCodeForString( |
| 242 key_field, options_, true, variables_, | 245 key_field, options_, true, variables_, |
| 243 "entry->key().data(), entry->key().length(),\n", printer); | 246 StrCat(key, ".data(), ", key, ".length(),\n").data(), printer); |
| 244 } | 247 } |
| 245 if (value_field->type() == FieldDescriptor::TYPE_STRING) { | 248 if (value_field->type() == FieldDescriptor::TYPE_STRING) { |
| 246 GenerateUtf8CheckCodeForString(value_field, options_, true, variables_, | 249 GenerateUtf8CheckCodeForString(value_field, options_, true, variables_, |
| 247 "entry->mutable_value()->data(),\n" | 250 StrCat(value, ".data(), ", value, ".length(),\n").data(), printer); |
| 248 "entry->mutable_value()->length(),\n", | |
| 249 printer); | |
| 250 } | 251 } |
| 251 | 252 |
| 252 // If entry is allocated by arena, its desctructor should be avoided. | 253 // If entry is allocated by arena, its desctructor should be avoided. |
| 253 if (SupportsArenas(descriptor_)) { | 254 if (using_entry && SupportsArenas(descriptor_)) { |
| 254 printer->Print(variables_, | 255 printer->Print(variables_, |
| 255 "if (entry->GetArena() != NULL) entry.release();\n"); | 256 "if (entry->GetArena() != NULL) entry.release();\n"); |
| 256 } | 257 } |
| 257 } | 258 } |
| 258 | 259 |
| 260 static void GenerateSerializationLoop(io::Printer* printer, |
| 261 const std::map<string, string>& variables, |
| 262 bool supports_arenas, |
| 263 const string& utf8_check, |
| 264 const string& loop_header, |
| 265 const string& ptr, |
| 266 bool loop_via_iterators) { |
| 267 printer->Print(variables, |
| 268 StrCat("::google::protobuf::scoped_ptr<$map_classname$> entry;\n", |
| 269 loop_header, " {\n").c_str()); |
| 270 printer->Indent(); |
| 271 |
| 272 printer->Print(variables, StrCat( |
| 273 "entry.reset($name$_.New$wrapper$(\n" |
| 274 " ", ptr, "->first, ", ptr, "->second));\n" |
| 275 "$write_entry$;\n").c_str()); |
| 276 |
| 277 // If entry is allocated by arena, its desctructor should be avoided. |
| 278 if (supports_arenas) { |
| 279 printer->Print( |
| 280 "if (entry->GetArena() != NULL) {\n" |
| 281 " entry.release();\n" |
| 282 "}\n"); |
| 283 } |
| 284 |
| 285 if (!utf8_check.empty()) { |
| 286 // If loop_via_iterators is true then ptr is actually an iterator, and we |
| 287 // create a pointer by prefixing it with "&*". |
| 288 printer->Print( |
| 289 StrCat(utf8_check, "(", (loop_via_iterators ? "&*" : ""), ptr, ");\n") |
| 290 .c_str()); |
| 291 } |
| 292 |
| 293 printer->Outdent(); |
| 294 printer->Print( |
| 295 "}\n"); |
| 296 } |
| 297 |
| 259 void MapFieldGenerator:: | 298 void MapFieldGenerator:: |
| 260 GenerateSerializeWithCachedSizes(io::Printer* printer) const { | 299 GenerateSerializeWithCachedSizes(io::Printer* printer) const { |
| 261 printer->Print(variables_, | 300 std::map<string, string> variables(variables_); |
| 262 "{\n" | 301 variables["write_entry"] = "::google::protobuf::internal::WireFormatLite::Writ
e" + |
| 263 " ::google::protobuf::scoped_ptr<$map_classname$> entry;\n" | 302 variables["stream_writer"] + "(\n " + |
| 264 " for (::google::protobuf::Map< $key_cpp$, $val_cpp$ >::const_iterator\n" | 303 variables["number"] + ", *entry, output)"; |
| 265 " it = this->$name$().begin();\n" | 304 variables["deterministic"] = "output->IsSerializationDeterministic()"; |
| 266 " it != this->$name$().end(); ++it) {\n"); | 305 GenerateSerializeWithCachedSizes(printer, variables); |
| 306 } |
| 267 | 307 |
| 268 // If entry is allocated by arena, its desctructor should be avoided. | 308 void MapFieldGenerator:: |
| 269 if (SupportsArenas(descriptor_)) { | 309 GenerateSerializeWithCachedSizesToArray(io::Printer* printer) const { |
| 270 printer->Print(variables_, | 310 std::map<string, string> variables(variables_); |
| 271 " if (entry.get() != NULL && entry->GetArena() != NULL) {\n" | 311 variables["write_entry"] = |
| 272 " entry.release();\n" | 312 "target = ::google::protobuf::internal::WireFormatLite::\n" |
| 273 " }\n"); | 313 " InternalWrite" + variables["declared_type"] + |
| 274 } | 314 "NoVirtualToArray(\n " + variables["number"] + |
| 315 ", *entry, deterministic, target);\n"; |
| 316 variables["deterministic"] = "deterministic"; |
| 317 GenerateSerializeWithCachedSizes(printer, variables); |
| 318 } |
| 275 | 319 |
| 276 printer->Print(variables_, | 320 void MapFieldGenerator::GenerateSerializeWithCachedSizes( |
| 277 " entry.reset($name$_.New$wrapper$(it->first, it->second));\n" | 321 io::Printer* printer, const std::map<string, string>& variables) const { |
| 278 " ::google::protobuf::internal::WireFormatLite::Write$stream_writer$(\n
" | 322 printer->Print(variables, |
| 279 " $number$, *entry, output);\n"); | 323 "if (!this->$name$().empty()) {\n"); |
| 280 | |
| 281 printer->Indent(); | 324 printer->Indent(); |
| 282 printer->Indent(); | |
| 283 | |
| 284 const FieldDescriptor* key_field = | 325 const FieldDescriptor* key_field = |
| 285 descriptor_->message_type()->FindFieldByName("key"); | 326 descriptor_->message_type()->FindFieldByName("key"); |
| 286 const FieldDescriptor* value_field = | 327 const FieldDescriptor* value_field = |
| 287 descriptor_->message_type()->FindFieldByName("value"); | 328 descriptor_->message_type()->FindFieldByName("value"); |
| 288 if (key_field->type() == FieldDescriptor::TYPE_STRING) { | 329 const bool string_key = key_field->type() == FieldDescriptor::TYPE_STRING; |
| 289 GenerateUtf8CheckCodeForString(key_field, options_, false, variables_, | 330 const bool string_value = value_field->type() == FieldDescriptor::TYPE_STRING; |
| 290 "it->first.data(), it->first.length(),\n", | 331 |
| 291 printer); | 332 printer->Print(variables, |
| 333 "typedef ::google::protobuf::Map< $key_cpp$, $val_cpp$ >::const_pointer\n" |
| 334 " ConstPtr;\n"); |
| 335 if (string_key) { |
| 336 printer->Print(variables, |
| 337 "typedef ConstPtr SortItem;\n" |
| 338 "typedef ::google::protobuf::internal::" |
| 339 "CompareByDerefFirst<SortItem> Less;\n"); |
| 340 } else { |
| 341 printer->Print(variables, |
| 342 "typedef ::google::protobuf::internal::SortItem< $key_cpp$, ConstPtr > " |
| 343 "SortItem;\n" |
| 344 "typedef ::google::protobuf::internal::CompareByFirstField<SortItem> Les
s;\n"); |
| 292 } | 345 } |
| 293 if (value_field->type() == FieldDescriptor::TYPE_STRING) { | 346 string utf8_check; |
| 294 GenerateUtf8CheckCodeForString(value_field, options_, false, variables_, | 347 if (string_key || string_value) { |
| 295 "it->second.data(), it->second.length(),\n", | 348 printer->Print( |
| 296 printer); | 349 "struct Utf8Check {\n" |
| 350 " static void Check(ConstPtr p) {\n"); |
| 351 printer->Indent(); |
| 352 printer->Indent(); |
| 353 if (string_key) { |
| 354 GenerateUtf8CheckCodeForString(key_field, options_, false, variables, |
| 355 "p->first.data(), p->first.length(),\n", |
| 356 printer); |
| 357 } |
| 358 if (string_value) { |
| 359 GenerateUtf8CheckCodeForString(value_field, options_, false, variables, |
| 360 "p->second.data(), p->second.length(),\n", |
| 361 printer); |
| 362 } |
| 363 printer->Outdent(); |
| 364 printer->Outdent(); |
| 365 printer->Print( |
| 366 " }\n" |
| 367 "};\n"); |
| 368 utf8_check = "Utf8Check::Check"; |
| 297 } | 369 } |
| 298 | 370 |
| 299 printer->Outdent(); | 371 printer->Print(variables, |
| 300 printer->Outdent(); | 372 "\n" |
| 301 | 373 "if ($deterministic$ &&\n" |
| 302 printer->Print( | 374 " this->$name$().size() > 1) {\n" |
| 303 " }\n"); | 375 " ::google::protobuf::scoped_array<SortItem> items(\n" |
| 304 | 376 " new SortItem[this->$name$().size()]);\n" |
| 305 // If entry is allocated by arena, its desctructor should be avoided. | 377 " typedef ::google::protobuf::Map< $key_cpp$, $val_cpp$ >::size_type size
_type;\n" |
| 306 if (SupportsArenas(descriptor_)) { | 378 " size_type n = 0;\n" |
| 307 printer->Print(variables_, | |
| 308 " if (entry.get() != NULL && entry->GetArena() != NULL) {\n" | |
| 309 " entry.release();\n" | |
| 310 " }\n"); | |
| 311 } | |
| 312 | |
| 313 printer->Print("}\n"); | |
| 314 } | |
| 315 | |
| 316 void MapFieldGenerator:: | |
| 317 GenerateSerializeWithCachedSizesToArray(io::Printer* printer) const { | |
| 318 printer->Print(variables_, | |
| 319 "{\n" | |
| 320 " ::google::protobuf::scoped_ptr<$map_classname$> entry;\n" | |
| 321 " for (::google::protobuf::Map< $key_cpp$, $val_cpp$ >::const_iterator\n" | 379 " for (::google::protobuf::Map< $key_cpp$, $val_cpp$ >::const_iterator\n" |
| 322 " it = this->$name$().begin();\n" | 380 " it = this->$name$().begin();\n" |
| 323 " it != this->$name$().end(); ++it) {\n"); | 381 " it != this->$name$().end(); ++it, ++n) {\n" |
| 324 | 382 " items[n] = SortItem(&*it);\n" |
| 325 // If entry is allocated by arena, its desctructor should be avoided. | 383 " }\n" |
| 326 if (SupportsArenas(descriptor_)) { | 384 " ::std::sort(&items[0], &items[n], Less());\n"); |
| 327 printer->Print(variables_, | |
| 328 " if (entry.get() != NULL && entry->GetArena() != NULL) {\n" | |
| 329 " entry.release();\n" | |
| 330 " }\n"); | |
| 331 } | |
| 332 | |
| 333 printer->Print(variables_, | |
| 334 " entry.reset($name$_.New$wrapper$(it->first, it->second));\n" | |
| 335 " target = ::google::protobuf::internal::WireFormatLite::\n" | |
| 336 " Write$declared_type$NoVirtualToArray(\n" | |
| 337 " $number$, *entry, target);\n"); | |
| 338 | |
| 339 printer->Indent(); | 385 printer->Indent(); |
| 340 printer->Indent(); | 386 GenerateSerializationLoop(printer, variables, SupportsArenas(descriptor_), |
| 341 | 387 utf8_check, "for (size_type i = 0; i < n; i++)", |
| 342 const FieldDescriptor* key_field = | 388 string_key ? "items[i]" : "items[i].second", false); |
| 343 descriptor_->message_type()->FindFieldByName("key"); | |
| 344 const FieldDescriptor* value_field = | |
| 345 descriptor_->message_type()->FindFieldByName("value"); | |
| 346 if (key_field->type() == FieldDescriptor::TYPE_STRING) { | |
| 347 GenerateUtf8CheckCodeForString(key_field, options_, false, variables_, | |
| 348 "it->first.data(), it->first.length(),\n", | |
| 349 printer); | |
| 350 } | |
| 351 if (value_field->type() == FieldDescriptor::TYPE_STRING) { | |
| 352 GenerateUtf8CheckCodeForString(value_field, options_, false, variables_, | |
| 353 "it->second.data(), it->second.length(),\n", | |
| 354 printer); | |
| 355 } | |
| 356 | |
| 357 printer->Outdent(); | |
| 358 printer->Outdent(); | 389 printer->Outdent(); |
| 359 printer->Print( | 390 printer->Print( |
| 360 " }\n"); | 391 "} else {\n"); |
| 361 | 392 printer->Indent(); |
| 362 // If entry is allocated by arena, its desctructor should be avoided. | 393 GenerateSerializationLoop( |
| 363 if (SupportsArenas(descriptor_)) { | 394 printer, variables, SupportsArenas(descriptor_), utf8_check, |
| 364 printer->Print(variables_, | 395 "for (::google::protobuf::Map< $key_cpp$, $val_cpp$ >::const_iterator\n" |
| 365 " if (entry.get() != NULL && entry->GetArena() != NULL) {\n" | 396 " it = this->$name$().begin();\n" |
| 366 " entry.release();\n" | 397 " it != this->$name$().end(); ++it)", |
| 367 " }\n"); | 398 "it", true); |
| 368 } | 399 printer->Outdent(); |
| 369 | 400 printer->Print("}\n"); |
| 401 printer->Outdent(); |
| 370 printer->Print("}\n"); | 402 printer->Print("}\n"); |
| 371 } | 403 } |
| 372 | 404 |
| 373 void MapFieldGenerator:: | 405 void MapFieldGenerator:: |
| 374 GenerateByteSize(io::Printer* printer) const { | 406 GenerateByteSize(io::Printer* printer) const { |
| 375 printer->Print(variables_, | 407 printer->Print(variables_, |
| 376 "total_size += $tag_size$ * this->$name$_size();\n" | 408 "total_size += $tag_size$ *\n" |
| 409 " ::google::protobuf::internal::FromIntSize(this->$name$_size());\n" |
| 377 "{\n" | 410 "{\n" |
| 378 " ::google::protobuf::scoped_ptr<$map_classname$> entry;\n" | 411 " ::google::protobuf::scoped_ptr<$map_classname$> entry;\n" |
| 379 " for (::google::protobuf::Map< $key_cpp$, $val_cpp$ >::const_iterator\n" | 412 " for (::google::protobuf::Map< $key_cpp$, $val_cpp$ >::const_iterator\n" |
| 380 " it = this->$name$().begin();\n" | 413 " it = this->$name$().begin();\n" |
| 381 " it != this->$name$().end(); ++it) {\n"); | 414 " it != this->$name$().end(); ++it) {\n"); |
| 382 | 415 |
| 383 // If entry is allocated by arena, its desctructor should be avoided. | 416 // If entry is allocated by arena, its desctructor should be avoided. |
| 384 if (SupportsArenas(descriptor_)) { | 417 if (SupportsArenas(descriptor_)) { |
| 385 printer->Print(variables_, | 418 printer->Print(variables_, |
| 386 " if (entry.get() != NULL && entry->GetArena() != NULL) {\n" | 419 " if (entry.get() != NULL && entry->GetArena() != NULL) {\n" |
| (...skipping 15 matching lines...) Expand all Loading... |
| 402 " }\n"); | 435 " }\n"); |
| 403 } | 436 } |
| 404 | 437 |
| 405 printer->Print("}\n"); | 438 printer->Print("}\n"); |
| 406 } | 439 } |
| 407 | 440 |
| 408 } // namespace cpp | 441 } // namespace cpp |
| 409 } // namespace compiler | 442 } // namespace compiler |
| 410 } // namespace protobuf | 443 } // namespace protobuf |
| 411 } // namespace google | 444 } // namespace google |
| OLD | NEW |