cpp_map_field.cc
Go to the documentation of this file.
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 
36 
37 
38 namespace google {
39 namespace protobuf {
40 namespace compiler {
41 namespace cpp {
42 
43 bool IsProto3Field(const FieldDescriptor* field_descriptor) {
44  const FileDescriptor* file_descriptor = field_descriptor->file();
45  return file_descriptor->syntax() == FileDescriptor::SYNTAX_PROTO3;
46 }
47 
49  std::map<std::string, std::string>* variables,
50  const Options& options) {
52  (*variables)["type"] = ClassName(descriptor->message_type(), false);
53  (*variables)["stream_writer"] =
54  (*variables)["declared_type"] +
55  (HasFastArraySerialization(descriptor->message_type()->file(), options)
56  ? "MaybeToArray"
57  : "");
58  (*variables)["full_name"] = descriptor->full_name();
59 
60  const FieldDescriptor* key =
61  descriptor->message_type()->FindFieldByName("key");
62  const FieldDescriptor* val =
63  descriptor->message_type()->FindFieldByName("value");
64  (*variables)["key_cpp"] = PrimitiveTypeName(options, key->cpp_type());
65  switch (val->cpp_type()) {
67  (*variables)["val_cpp"] = FieldMessageTypeName(val, options);
68  break;
70  (*variables)["val_cpp"] = ClassName(val->enum_type(), true);
71  break;
72  default:
73  (*variables)["val_cpp"] = PrimitiveTypeName(options, val->cpp_type());
74  }
75  (*variables)["key_wire_type"] =
76  "TYPE_" + ToUpper(DeclaredTypeMethodName(key->type()));
77  (*variables)["val_wire_type"] =
78  "TYPE_" + ToUpper(DeclaredTypeMethodName(val->type()));
79  (*variables)["map_classname"] = ClassName(descriptor->message_type(), false);
80  (*variables)["number"] = StrCat(descriptor->number());
81  (*variables)["tag"] = StrCat(internal::WireFormat::MakeTag(descriptor));
82 
83  if (HasDescriptorMethods(descriptor->file(), options)) {
84  (*variables)["lite"] = "";
85  } else {
86  (*variables)["lite"] = "Lite";
87  }
88 
90  const EnumValueDescriptor* default_value = val->default_value_enum();
91  (*variables)["default_enum_value"] = Int32ToString(default_value->number());
92  } else {
93  (*variables)["default_enum_value"] = "0";
94  }
95 }
96 
98  const Options& options)
101 }
102 
104 
106  Formatter format(printer, variables_);
107  format(
108  "::$proto_ns$::internal::MapField$lite$<\n"
109  " $map_classname$,\n"
110  " $key_cpp$, $val_cpp$,\n"
111  " ::$proto_ns$::internal::WireFormatLite::$key_wire_type$,\n"
112  " ::$proto_ns$::internal::WireFormatLite::$val_wire_type$,\n"
113  " $default_enum_value$ > $name$_;\n");
114 }
115 
117  io::Printer* printer) const {
118  Formatter format(printer, variables_);
119  format(
120  "$deprecated_attr$const ::$proto_ns$::Map< $key_cpp$, $val_cpp$ >&\n"
121  " ${1$$name$$}$() const;\n"
122  "$deprecated_attr$::$proto_ns$::Map< $key_cpp$, $val_cpp$ >*\n"
123  " ${1$mutable_$name$$}$();\n",
124  descriptor_);
125 }
126 
128  io::Printer* printer) const {
129  Formatter format(printer, variables_);
130  format(
131  "inline const ::$proto_ns$::Map< $key_cpp$, $val_cpp$ >&\n"
132  "$classname$::$name$() const {\n"
133  " // @@protoc_insertion_point(field_map:$full_name$)\n"
134  " return $name$_.GetMap();\n"
135  "}\n"
136  "inline ::$proto_ns$::Map< $key_cpp$, $val_cpp$ >*\n"
137  "$classname$::mutable_$name$() {\n"
138  " // @@protoc_insertion_point(field_mutable_map:$full_name$)\n"
139  " return $name$_.MutableMap();\n"
140  "}\n");
141 }
142 
144  Formatter format(printer, variables_);
145  format("$name$_.Clear();\n");
146 }
147 
149  Formatter format(printer, variables_);
150  format("$name$_.MergeFrom(from.$name$_);\n");
151 }
152 
154  Formatter format(printer, variables_);
155  format("$name$_.Swap(&other->$name$_);\n");
156 }
157 
159  io::Printer* printer) const {
160  GenerateConstructorCode(printer);
161  GenerateMergingCode(printer);
162 }
163 
165  io::Printer* printer) const {
166  Formatter format(printer, variables_);
167  const FieldDescriptor* key_field =
169  const FieldDescriptor* value_field =
173  format(
174  "$map_classname$::Parser< ::$proto_ns$::internal::MapField$lite$<\n"
175  " $map_classname$,\n"
176  " $key_cpp$, $val_cpp$,\n"
177  " ::$proto_ns$::internal::WireFormatLite::$key_wire_type$,\n"
178  " ::$proto_ns$::internal::WireFormatLite::$val_wire_type$,\n"
179  " $default_enum_value$ >,\n"
180  " ::$proto_ns$::Map< $key_cpp$, $val_cpp$ > >"
181  " parser(&$name$_);\n");
182  if (IsProto3Field(descriptor_) ||
183  value_field->type() != FieldDescriptor::TYPE_ENUM) {
184  format(
185  "DO_(::$proto_ns$::internal::WireFormatLite::ReadMessageNoVirtual(\n"
186  " input, &parser));\n");
187  key = "parser.key()";
188  value = "parser.value()";
189  } else {
190  key = "entry->key()";
191  value = "entry->value()";
192  format("auto entry = parser.NewEntry();\n");
193  format(
194  "std::string data;\n"
195  "DO_(::$proto_ns$::internal::WireFormatLite::ReadString(input, "
196  "&data));\n"
197  "DO_(entry->ParseFromString(data));\n"
198  "if ($val_cpp$_IsValid(*entry->mutable_value())) {\n"
199  " (*mutable_$name$())[entry->key()] =\n"
200  " static_cast< $val_cpp$ >(*entry->mutable_value());\n"
201  "} else {\n");
203  format(
204  " mutable_unknown_fields()"
205  "->AddLengthDelimited($number$, data);\n");
206  } else {
207  format(
208  " unknown_fields_stream.WriteVarint32($tag$u);\n"
209  " unknown_fields_stream.WriteVarint32(\n"
210  " static_cast< ::google::protobuf::uint32>(data.size()));\n"
211  " unknown_fields_stream.WriteString(data);\n");
212  }
213  format("}\n");
214  }
215 
216  if (key_field->type() == FieldDescriptor::TYPE_STRING) {
218  key_field, options_, true,
219  StrCat(key, ".data(), static_cast<int>(", key, ".length()),\n")
220  .data(),
221  format);
222  }
223  if (value_field->type() == FieldDescriptor::TYPE_STRING) {
225  value_field, options_, true,
226  StrCat(value, ".data(), static_cast<int>(", value,
227  ".length()),\n")
228  .data(),
229  format);
230  }
231 }
232 
233 static void GenerateSerializationLoop(const Formatter& format, bool string_key,
234  bool string_value, bool to_array,
235  bool is_deterministic) {
236  std::string ptr;
237  if (is_deterministic) {
238  format("for (size_type i = 0; i < n; i++) {\n");
239  ptr = string_key ? "items[static_cast<ptrdiff_t>(i)]"
240  : "items[static_cast<ptrdiff_t>(i)].second";
241  } else {
242  format(
243  "for (::$proto_ns$::Map< $key_cpp$, $val_cpp$ >::const_iterator\n"
244  " it = this->$name$().begin();\n"
245  " it != this->$name$().end(); ++it) {\n");
246  ptr = "it";
247  }
248  format.Indent();
249 
250  if (to_array) {
251  format(
252  "target = $map_classname$::Funcs::SerializeToArray($number$, "
253  "$1$->first, $1$->second, target);\n",
254  ptr);
255  } else {
256  format(
257  "$map_classname$::Funcs::SerializeToCodedStream($number$, "
258  "$1$->first, $1$->second, output);\n",
259  ptr);
260  }
261 
262  if (string_key || string_value) {
263  // ptr is either an actual pointer or an iterator, either way we can
264  // create a pointer by taking the address after de-referencing it.
265  format("Utf8Check::Check(&(*$1$));\n", ptr);
266  }
267 
268  format.Outdent();
269  format("}\n");
270 }
271 
273  io::Printer* printer) const {
274  GenerateSerializeWithCachedSizes(printer, false);
275 }
276 
278  io::Printer* printer) const {
279  GenerateSerializeWithCachedSizes(printer, true);
280 }
281 
283  bool to_array) const {
284  Formatter format(printer, variables_);
285  format("if (!this->$name$().empty()) {\n");
286  format.Indent();
287  const FieldDescriptor* key_field =
289  const FieldDescriptor* value_field =
291  const bool string_key = key_field->type() == FieldDescriptor::TYPE_STRING;
292  const bool string_value = value_field->type() == FieldDescriptor::TYPE_STRING;
293 
294  format(
295  "typedef ::$proto_ns$::Map< $key_cpp$, $val_cpp$ >::const_pointer\n"
296  " ConstPtr;\n");
297  if (string_key) {
298  format(
299  "typedef ConstPtr SortItem;\n"
300  "typedef ::$proto_ns$::internal::"
301  "CompareByDerefFirst<SortItem> Less;\n");
302  } else {
303  format(
304  "typedef ::$proto_ns$::internal::SortItem< $key_cpp$, ConstPtr > "
305  "SortItem;\n"
306  "typedef ::$proto_ns$::internal::CompareByFirstField<SortItem> "
307  "Less;\n");
308  }
309  bool utf8_check = string_key || string_value;
310  if (utf8_check) {
311  format(
312  "struct Utf8Check {\n"
313  " static void Check(ConstPtr p) {\n");
314  format.Indent();
315  format.Indent();
316  if (string_key) {
318  key_field, options_, false,
319  "p->first.data(), static_cast<int>(p->first.length()),\n", format);
320  }
321  if (string_value) {
323  value_field, options_, false,
324  "p->second.data(), static_cast<int>(p->second.length()),\n", format);
325  }
326  format.Outdent();
327  format.Outdent();
328  format(
329  " }\n"
330  "};\n");
331  }
332 
333  format(
334  "\n"
335  "if ($1$ &&\n"
336  " this->$name$().size() > 1) {\n"
337  " ::std::unique_ptr<SortItem[]> items(\n"
338  " new SortItem[this->$name$().size()]);\n"
339  " typedef ::$proto_ns$::Map< $key_cpp$, $val_cpp$ >::size_type "
340  "size_type;\n"
341  " size_type n = 0;\n"
342  " for (::$proto_ns$::Map< $key_cpp$, $val_cpp$ >::const_iterator\n"
343  " it = this->$name$().begin();\n"
344  " it != this->$name$().end(); ++it, ++n) {\n"
345  " items[static_cast<ptrdiff_t>(n)] = SortItem(&*it);\n"
346  " }\n"
347  " ::std::sort(&items[0], &items[static_cast<ptrdiff_t>(n)], Less());\n",
348  to_array ? "false" : "output->IsSerializationDeterministic()");
349  format.Indent();
350  GenerateSerializationLoop(format, string_key, string_value, to_array, true);
351  format.Outdent();
352  format("} else {\n");
353  format.Indent();
354  GenerateSerializationLoop(format, string_key, string_value, to_array, false);
355  format.Outdent();
356  format("}\n");
357  format.Outdent();
358  format("}\n");
359 }
360 
362  Formatter format(printer, variables_);
363  format(
364  "total_size += $tag_size$ *\n"
365  " ::$proto_ns$::internal::FromIntSize(this->$name$_size());\n"
366  "for (::$proto_ns$::Map< $key_cpp$, $val_cpp$ >::const_iterator\n"
367  " it = this->$name$().begin();\n"
368  " it != this->$name$().end(); ++it) {\n"
369  " total_size += $map_classname$::Funcs::ByteSizeLong(it->first, "
370  "it->second);\n"
371  "}\n");
372 }
373 
374 } // namespace cpp
375 } // namespace compiler
376 } // namespace protobuf
377 } // namespace google
google::protobuf::compiler::cpp::MapFieldGenerator::GenerateConstructorCode
void GenerateConstructorCode(io::Printer *printer) const
Definition: cpp_map_field.h:56
google::protobuf::FieldDescriptor::CPPTYPE_ENUM
@ CPPTYPE_ENUM
Definition: src/google/protobuf/descriptor.h:561
google::protobuf::value
const Descriptor::ReservedRange value
Definition: src/google/protobuf/descriptor.h:1954
google::protobuf::FieldDescriptor
Definition: src/google/protobuf/descriptor.h:515
google::protobuf::StrCat
string StrCat(const AlphaNum &a, const AlphaNum &b)
Definition: strutil.cc:1480
options
Message * options
Definition: src/google/protobuf/descriptor.cc:3119
google::protobuf::compiler::cpp::MapFieldGenerator::GenerateSerializeWithCachedSizesToArray
void GenerateSerializeWithCachedSizesToArray(io::Printer *printer) const
Definition: cpp_map_field.cc:277
google::protobuf::compiler::cpp::SetCommonFieldVariables
void SetCommonFieldVariables(const FieldDescriptor *descriptor, std::map< std::string, std::string > *variables, const Options &options)
Definition: cpp_field.cc:59
google::protobuf.internal::WireFormat::MakeTag
static uint32 MakeTag(const FieldDescriptor *field)
Definition: wire_format.h:289
google::protobuf::compiler::cpp::FieldGenerator::options_
const Options & options_
Definition: cpp_field.h:206
string
GLsizei const GLchar *const * string
Definition: glcorearb.h:3083
descriptor
Descriptor * descriptor
Definition: php/ext/google/protobuf/protobuf.h:936
google::protobuf::compiler::cpp::DeclaredTypeMethodName
const char * DeclaredTypeMethodName(FieldDescriptor::Type type)
Definition: cpp_helpers.cc:545
google::protobuf::FileDescriptor::syntax
Syntax syntax() const
Definition: src/google/protobuf/descriptor.h:2175
google::protobuf::compiler::cpp::FieldGenerator::descriptor_
const FieldDescriptor * descriptor_
Definition: cpp_field.h:205
cpp_helpers.h
google::protobuf::compiler::cpp::FieldGenerator::variables_
std::map< std::string, std::string > variables_
Definition: cpp_field.h:207
google::protobuf::compiler::cpp::MapFieldGenerator::GenerateAccessorDeclarations
void GenerateAccessorDeclarations(io::Printer *printer) const
Definition: cpp_map_field.cc:116
google::protobuf::compiler::cpp::GenerateUtf8CheckCodeForString
void GenerateUtf8CheckCodeForString(const FieldDescriptor *field, const Options &options, bool for_parse, const char *parameters, const Formatter &format)
Definition: cpp_helpers.cc:1069
google::protobuf::compiler::cpp::MapFieldGenerator::GenerateInlineAccessorDefinitions
void GenerateInlineAccessorDefinitions(io::Printer *printer) const
Definition: cpp_map_field.cc:127
google::protobuf::compiler::cpp::SetMessageVariables
void SetMessageVariables(const FieldDescriptor *descriptor, std::map< std::string, std::string > *variables, const Options &options)
Definition: cpp_map_field.cc:48
google::protobuf::compiler::cpp::FieldGenerator
Definition: cpp_field.h:71
google::protobuf::compiler::cpp::MapFieldGenerator::GenerateMergeFromCodedStream
void GenerateMergeFromCodedStream(io::Printer *printer) const
Definition: cpp_map_field.cc:164
strutil.h
google::protobuf::FieldDescriptor::file
const FileDescriptor * file() const
format
GLint GLint GLsizei GLint GLenum format
Definition: glcorearb.h:2773
google::protobuf::compiler::cpp::MapFieldGenerator::GenerateSwappingCode
void GenerateSwappingCode(io::Printer *printer) const
Definition: cpp_map_field.cc:153
google::protobuf::compiler::cpp::MapFieldGenerator::MapFieldGenerator
MapFieldGenerator(const FieldDescriptor *descriptor, const Options &options)
Definition: cpp_map_field.cc:97
printer.h
google::protobuf::compiler::cpp::FieldMessageTypeName
std::string FieldMessageTypeName(const FieldDescriptor *field, const Options &options)
Definition: cpp_helpers.cc:467
google::protobuf::FieldDescriptor::TYPE_STRING
@ TYPE_STRING
Definition: src/google/protobuf/descriptor.h:534
cpp
Definition: third_party/googletest/googlemock/scripts/generator/cpp/__init__.py:1
google::protobuf::compiler::cpp::Options
Definition: cpp_options.h:52
google::protobuf::FileDescriptor::SYNTAX_PROTO3
@ SYNTAX_PROTO3
Definition: src/google/protobuf/descriptor.h:1394
google::protobuf::compiler::cpp::HasDescriptorMethods
bool HasDescriptorMethods(const FileDescriptor *file, const Options &options)
Definition: cpp_helpers.h:365
key
const SETUP_TEARDOWN_TESTCONTEXT char * key
Definition: test_wss_transport.cpp:10
google::protobuf::io::Printer
Definition: printer.h:181
google::protobuf::compiler::cpp::IsProto3Field
bool IsProto3Field(const FieldDescriptor *field_descriptor)
Definition: cpp_map_field.cc:43
google::protobuf::compiler::cpp::Int32ToString
std::string Int32ToString(int number)
Definition: cpp_helpers.cc:593
google::protobuf::FieldDescriptor::type
Type type() const
Definition: src/google/protobuf/descriptor.h:2052
google::protobuf::compiler::cpp::MapFieldGenerator::~MapFieldGenerator
~MapFieldGenerator()
Definition: cpp_map_field.cc:103
google::protobuf::Descriptor::FindFieldByName
const FieldDescriptor * FindFieldByName(const std::string &name) const
Definition: src/google/protobuf/descriptor.cc:1615
google::protobuf::compiler::cpp::MapFieldGenerator::GenerateMergingCode
void GenerateMergingCode(io::Printer *printer) const
Definition: cpp_map_field.cc:148
wire_format.h
google::protobuf::compiler::cpp::GenerateSerializationLoop
static void GenerateSerializationLoop(const Formatter &format, bool string_key, bool string_value, bool to_array, bool is_deterministic)
Definition: cpp_map_field.cc:233
google::protobuf::EnumValueDescriptor
Definition: src/google/protobuf/descriptor.h:1075
google::protobuf::compiler::cpp::ClassName
std::string ClassName(const Descriptor *descriptor)
Definition: cpp_helpers.cc:301
default_value
def default_value(type_)
cpp_map_field.h
google::protobuf::compiler::cpp::PrimitiveTypeName
const char * PrimitiveTypeName(FieldDescriptor::CppType type)
Definition: cpp_helpers.cc:482
google::protobuf::ToUpper
string ToUpper(const string &s)
Definition: strutil.h:193
google::protobuf::FieldDescriptor::message_type
const Descriptor * message_type() const
Definition: src/google/protobuf/descriptor.cc:7228
google::protobuf::FileDescriptor
Definition: src/google/protobuf/descriptor.h:1320
data
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: glcorearb.h:2879
val
GLuint GLfloat * val
Definition: glcorearb.h:3604
value
GLsizei const GLfloat * value
Definition: glcorearb.h:3093
google::protobuf::FieldDescriptor::CPPTYPE_MESSAGE
@ CPPTYPE_MESSAGE
Definition: src/google/protobuf/descriptor.h:563
google::protobuf::compiler::cpp::MapFieldGenerator::GenerateClearingCode
void GenerateClearingCode(io::Printer *printer) const
Definition: cpp_map_field.cc:143
google::protobuf::FieldDescriptor::TYPE_ENUM
@ TYPE_ENUM
Definition: src/google/protobuf/descriptor.h:540
google::protobuf::compiler::cpp::MapFieldGenerator::GeneratePrivateMembers
void GeneratePrivateMembers(io::Printer *printer) const
Definition: cpp_map_field.cc:105
google::protobuf::compiler::cpp::MapFieldGenerator::GenerateByteSize
void GenerateByteSize(io::Printer *printer) const
Definition: cpp_map_field.cc:361
google::protobuf::compiler::cpp::HasFastArraySerialization
bool HasFastArraySerialization(const FileDescriptor *file, const Options &options)
Definition: cpp_helpers.h:381
google::protobuf::compiler::cpp::MapFieldGenerator::GenerateCopyConstructorCode
void GenerateCopyConstructorCode(io::Printer *printer) const
Definition: cpp_map_field.cc:158
compiler
Definition: plugin.pb.cc:22
google
Definition: data_proto2_to_proto3_util.h:11
google::protobuf::compiler::cpp::Formatter
Definition: cpp_helpers.h:637
google::protobuf::compiler::cpp::MapFieldGenerator::GenerateSerializeWithCachedSizes
void GenerateSerializeWithCachedSizes(io::Printer *printer) const
Definition: cpp_map_field.cc:272


libaditof
Author(s):
autogenerated on Wed May 21 2025 02:06:49