• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 // Author: kenton@google.com (Kenton Varda)
32 //  Based on original Protocol Buffers design by
33 //  Sanjay Ghemawat, Jeff Dean, and others.
34 #include <google/protobuf/reflection_ops.h>
35 
36 #include <string>
37 #include <vector>
38 
39 #include <google/protobuf/stubs/logging.h>
40 #include <google/protobuf/stubs/common.h>
41 #include <google/protobuf/descriptor.pb.h>
42 #include <google/protobuf/descriptor.h>
43 #include <google/protobuf/map_field.h>
44 #include <google/protobuf/map_field_inl.h>
45 #include <google/protobuf/unknown_field_set.h>
46 
47 #include <google/protobuf/port_def.inc>
48 
49 namespace google {
50 namespace protobuf {
51 namespace internal {
52 
GetReflectionOrDie(const Message & m)53 static const Reflection* GetReflectionOrDie(const Message& m) {
54   const Reflection* r = m.GetReflection();
55   if (r == nullptr) {
56     const Descriptor* d = m.GetDescriptor();
57     const std::string& mtype = d ? d->name() : "unknown";
58     // RawMessage is one known type for which GetReflection() returns nullptr.
59     GOOGLE_LOG(FATAL) << "Message does not support reflection (type " << mtype << ").";
60   }
61   return r;
62 }
63 
Copy(const Message & from,Message * to)64 void ReflectionOps::Copy(const Message& from, Message* to) {
65   if (&from == to) return;
66   Clear(to);
67   Merge(from, to);
68 }
69 
Merge(const Message & from,Message * to)70 void ReflectionOps::Merge(const Message& from, Message* to) {
71   GOOGLE_CHECK_NE(&from, to);
72 
73   const Descriptor* descriptor = from.GetDescriptor();
74   GOOGLE_CHECK_EQ(to->GetDescriptor(), descriptor)
75       << "Tried to merge messages of different types "
76       << "(merge " << descriptor->full_name() << " to "
77       << to->GetDescriptor()->full_name() << ")";
78 
79   const Reflection* from_reflection = GetReflectionOrDie(from);
80   const Reflection* to_reflection = GetReflectionOrDie(*to);
81   bool is_from_generated = (from_reflection->GetMessageFactory() ==
82                             google::protobuf::MessageFactory::generated_factory());
83   bool is_to_generated = (to_reflection->GetMessageFactory() ==
84                           google::protobuf::MessageFactory::generated_factory());
85 
86   std::vector<const FieldDescriptor*> fields;
87   from_reflection->ListFieldsOmitStripped(from, &fields);
88   for (const FieldDescriptor* field : fields) {
89     if (field->is_repeated()) {
90       // Use map reflection if both are in map status and have the
91       // same map type to avoid sync with repeated field.
92       // Note: As from and to messages have the same descriptor, the
93       // map field types are the same if they are both generated
94       // messages or both dynamic messages.
95       if (is_from_generated == is_to_generated && field->is_map()) {
96         const MapFieldBase* from_field =
97             from_reflection->GetMapData(from, field);
98         MapFieldBase* to_field = to_reflection->MutableMapData(to, field);
99         if (to_field->IsMapValid() && from_field->IsMapValid()) {
100           to_field->MergeFrom(*from_field);
101           continue;
102         }
103       }
104       int count = from_reflection->FieldSize(from, field);
105       for (int j = 0; j < count; j++) {
106         switch (field->cpp_type()) {
107 #define HANDLE_TYPE(CPPTYPE, METHOD)                                      \
108   case FieldDescriptor::CPPTYPE_##CPPTYPE:                                \
109     to_reflection->Add##METHOD(                                           \
110         to, field, from_reflection->GetRepeated##METHOD(from, field, j)); \
111     break;
112 
113           HANDLE_TYPE(INT32, Int32);
114           HANDLE_TYPE(INT64, Int64);
115           HANDLE_TYPE(UINT32, UInt32);
116           HANDLE_TYPE(UINT64, UInt64);
117           HANDLE_TYPE(FLOAT, Float);
118           HANDLE_TYPE(DOUBLE, Double);
119           HANDLE_TYPE(BOOL, Bool);
120           HANDLE_TYPE(STRING, String);
121           HANDLE_TYPE(ENUM, Enum);
122 #undef HANDLE_TYPE
123 
124           case FieldDescriptor::CPPTYPE_MESSAGE:
125             const Message& from_child =
126                 from_reflection->GetRepeatedMessage(from, field, j);
127             if (from_reflection == to_reflection) {
128               to_reflection
129                   ->AddMessage(to, field,
130                                from_child.GetReflection()->GetMessageFactory())
131                   ->MergeFrom(from_child);
132             } else {
133               to_reflection->AddMessage(to, field)->MergeFrom(from_child);
134             }
135             break;
136         }
137       }
138     } else {
139       switch (field->cpp_type()) {
140 #define HANDLE_TYPE(CPPTYPE, METHOD)                                       \
141   case FieldDescriptor::CPPTYPE_##CPPTYPE:                                 \
142     to_reflection->Set##METHOD(to, field,                                  \
143                                from_reflection->Get##METHOD(from, field)); \
144     break;
145 
146         HANDLE_TYPE(INT32, Int32);
147         HANDLE_TYPE(INT64, Int64);
148         HANDLE_TYPE(UINT32, UInt32);
149         HANDLE_TYPE(UINT64, UInt64);
150         HANDLE_TYPE(FLOAT, Float);
151         HANDLE_TYPE(DOUBLE, Double);
152         HANDLE_TYPE(BOOL, Bool);
153         HANDLE_TYPE(STRING, String);
154         HANDLE_TYPE(ENUM, Enum);
155 #undef HANDLE_TYPE
156 
157         case FieldDescriptor::CPPTYPE_MESSAGE:
158           const Message& from_child = from_reflection->GetMessage(from, field);
159           if (from_reflection == to_reflection) {
160             to_reflection
161                 ->MutableMessage(
162                     to, field, from_child.GetReflection()->GetMessageFactory())
163                 ->MergeFrom(from_child);
164           } else {
165             to_reflection->MutableMessage(to, field)->MergeFrom(from_child);
166           }
167           break;
168       }
169     }
170   }
171 
172   to_reflection->MutableUnknownFields(to)->MergeFrom(
173       from_reflection->GetUnknownFields(from));
174 }
175 
Clear(Message * message)176 void ReflectionOps::Clear(Message* message) {
177   const Reflection* reflection = GetReflectionOrDie(*message);
178 
179   std::vector<const FieldDescriptor*> fields;
180   reflection->ListFieldsOmitStripped(*message, &fields);
181   for (const FieldDescriptor* field : fields) {
182     reflection->ClearField(message, field);
183   }
184 
185   reflection->MutableUnknownFields(message)->Clear();
186 }
187 
IsInitialized(const Message & message,bool check_fields,bool check_descendants)188 bool ReflectionOps::IsInitialized(const Message& message, bool check_fields,
189                                   bool check_descendants) {
190   const Descriptor* descriptor = message.GetDescriptor();
191   const Reflection* reflection = GetReflectionOrDie(message);
192   if (const int field_count = descriptor->field_count()) {
193     const FieldDescriptor* begin = descriptor->field(0);
194     const FieldDescriptor* end = begin + field_count;
195     GOOGLE_DCHECK_EQ(descriptor->field(field_count - 1), end - 1);
196 
197     if (check_fields) {
198       // Check required fields of this message.
199       for (const FieldDescriptor* field = begin; field != end; ++field) {
200         if (field->is_required() && !reflection->HasField(message, field)) {
201           return false;
202         }
203       }
204     }
205 
206     if (check_descendants) {
207       for (const FieldDescriptor* field = begin; field != end; ++field) {
208         if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
209           const Descriptor* message_type = field->message_type();
210           if (PROTOBUF_PREDICT_FALSE(message_type->options().map_entry())) {
211             if (message_type->field(1)->cpp_type() ==
212                 FieldDescriptor::CPPTYPE_MESSAGE) {
213               const MapFieldBase* map_field =
214                   reflection->GetMapData(message, field);
215               if (map_field->IsMapValid()) {
216                 MapIterator it(const_cast<Message*>(&message), field);
217                 MapIterator end(const_cast<Message*>(&message), field);
218                 for (map_field->MapBegin(&it), map_field->MapEnd(&end);
219                      it != end; ++it) {
220                   if (!it.GetValueRef().GetMessageValue().IsInitialized()) {
221                     return false;
222                   }
223                 }
224               }
225             }
226           } else if (field->is_repeated()) {
227             const int size = reflection->FieldSize(message, field);
228             for (int j = 0; j < size; j++) {
229               if (!reflection->GetRepeatedMessage(message, field, j)
230                        .IsInitialized()) {
231                 return false;
232               }
233             }
234           } else if (reflection->HasField(message, field)) {
235             if (!reflection->GetMessage(message, field).IsInitialized()) {
236               return false;
237             }
238           }
239         }
240       }
241     }
242   }
243   if (check_descendants && reflection->HasExtensionSet(message) &&
244       !reflection->GetExtensionSet(message).IsInitialized()) {
245     return false;
246   }
247   return true;
248 }
249 
IsInitialized(const Message & message)250 bool ReflectionOps::IsInitialized(const Message& message) {
251   const Descriptor* descriptor = message.GetDescriptor();
252   const Reflection* reflection = GetReflectionOrDie(message);
253 
254   // Check required fields of this message.
255   {
256     const int field_count = descriptor->field_count();
257     for (int i = 0; i < field_count; i++) {
258       if (descriptor->field(i)->is_required()) {
259         if (!reflection->HasField(message, descriptor->field(i))) {
260           return false;
261         }
262       }
263     }
264   }
265 
266   // Check that sub-messages are initialized.
267   std::vector<const FieldDescriptor*> fields;
268   // Should be safe to skip stripped fields because required fields are not
269   // stripped.
270   reflection->ListFieldsOmitStripped(message, &fields);
271   for (const FieldDescriptor* field : fields) {
272     if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
273 
274       if (field->is_map()) {
275         const FieldDescriptor* value_field = field->message_type()->field(1);
276         if (value_field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
277           const MapFieldBase* map_field =
278               reflection->GetMapData(message, field);
279           if (map_field->IsMapValid()) {
280             MapIterator iter(const_cast<Message*>(&message), field);
281             MapIterator end(const_cast<Message*>(&message), field);
282             for (map_field->MapBegin(&iter), map_field->MapEnd(&end);
283                  iter != end; ++iter) {
284               if (!iter.GetValueRef().GetMessageValue().IsInitialized()) {
285                 return false;
286               }
287             }
288             continue;
289           }
290         } else {
291           continue;
292         }
293       }
294 
295       if (field->is_repeated()) {
296         int size = reflection->FieldSize(message, field);
297 
298         for (int j = 0; j < size; j++) {
299           if (!reflection->GetRepeatedMessage(message, field, j)
300                    .IsInitialized()) {
301             return false;
302           }
303         }
304       } else {
305         if (!reflection->GetMessage(message, field).IsInitialized()) {
306           return false;
307         }
308       }
309     }
310   }
311 
312   return true;
313 }
314 
IsMapValueMessageTyped(const FieldDescriptor * map_field)315 static bool IsMapValueMessageTyped(const FieldDescriptor* map_field) {
316   return map_field->message_type()->field(1)->cpp_type() ==
317          FieldDescriptor::CPPTYPE_MESSAGE;
318 }
319 
DiscardUnknownFields(Message * message)320 void ReflectionOps::DiscardUnknownFields(Message* message) {
321   const Reflection* reflection = GetReflectionOrDie(*message);
322 
323   reflection->MutableUnknownFields(message)->Clear();
324 
325   // Walk through the fields of this message and DiscardUnknownFields on any
326   // messages present.
327   std::vector<const FieldDescriptor*> fields;
328   reflection->ListFields(*message, &fields);
329   for (const FieldDescriptor* field : fields) {
330     // Skip over non-message fields.
331     if (field->cpp_type() != FieldDescriptor::CPPTYPE_MESSAGE) {
332       continue;
333     }
334     // Discard the unknown fields in maps that contain message values.
335     if (field->is_map() && IsMapValueMessageTyped(field)) {
336       const MapFieldBase* map_field =
337           reflection->MutableMapData(message, field);
338       if (map_field->IsMapValid()) {
339         MapIterator iter(message, field);
340         MapIterator end(message, field);
341         for (map_field->MapBegin(&iter), map_field->MapEnd(&end); iter != end;
342              ++iter) {
343           iter.MutableValueRef()->MutableMessageValue()->DiscardUnknownFields();
344         }
345       }
346       // Discard every unknown field inside messages in a repeated field.
347     } else if (field->is_repeated()) {
348       int size = reflection->FieldSize(*message, field);
349       for (int j = 0; j < size; j++) {
350         reflection->MutableRepeatedMessage(message, field, j)
351             ->DiscardUnknownFields();
352       }
353       // Discard the unknown fields inside an optional message.
354     } else {
355       reflection->MutableMessage(message, field)->DiscardUnknownFields();
356     }
357   }
358 }
359 
SubMessagePrefix(const std::string & prefix,const FieldDescriptor * field,int index)360 static std::string SubMessagePrefix(const std::string& prefix,
361                                     const FieldDescriptor* field, int index) {
362   std::string result(prefix);
363   if (field->is_extension()) {
364     result.append("(");
365     result.append(field->full_name());
366     result.append(")");
367   } else {
368     result.append(field->name());
369   }
370   if (index != -1) {
371     result.append("[");
372     result.append(StrCat(index));
373     result.append("]");
374   }
375   result.append(".");
376   return result;
377 }
378 
FindInitializationErrors(const Message & message,const std::string & prefix,std::vector<std::string> * errors)379 void ReflectionOps::FindInitializationErrors(const Message& message,
380                                              const std::string& prefix,
381                                              std::vector<std::string>* errors) {
382   const Descriptor* descriptor = message.GetDescriptor();
383   const Reflection* reflection = GetReflectionOrDie(message);
384 
385   // Check required fields of this message.
386   {
387     const int field_count = descriptor->field_count();
388     for (int i = 0; i < field_count; i++) {
389       if (descriptor->field(i)->is_required()) {
390         if (!reflection->HasField(message, descriptor->field(i))) {
391           errors->push_back(prefix + descriptor->field(i)->name());
392         }
393       }
394     }
395   }
396 
397   // Check sub-messages.
398   std::vector<const FieldDescriptor*> fields;
399   reflection->ListFieldsOmitStripped(message, &fields);
400   for (const FieldDescriptor* field : fields) {
401     if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
402 
403       if (field->is_repeated()) {
404         int size = reflection->FieldSize(message, field);
405 
406         for (int j = 0; j < size; j++) {
407           const Message& sub_message =
408               reflection->GetRepeatedMessage(message, field, j);
409           FindInitializationErrors(sub_message,
410                                    SubMessagePrefix(prefix, field, j), errors);
411         }
412       } else {
413         const Message& sub_message = reflection->GetMessage(message, field);
414         FindInitializationErrors(sub_message,
415                                  SubMessagePrefix(prefix, field, -1), errors);
416       }
417     }
418   }
419 }
420 
GenericSwap(Message * m1,Message * m2)421 void GenericSwap(Message* m1, Message* m2) {
422   Arena* m2_arena = m2->GetArena();
423   GOOGLE_DCHECK(m1->GetArena() != m2_arena);
424 
425   // Copy semantics in this case. We try to improve efficiency by placing the
426   // temporary on |m2|'s arena so that messages are copied twice rather than
427   // three times.
428   Message* tmp = m2->New(m2_arena);
429   std::unique_ptr<Message> tmp_deleter(m2_arena == nullptr ? tmp : nullptr);
430   tmp->CheckTypeAndMergeFrom(*m1);
431   m1->Clear();
432   m1->CheckTypeAndMergeFrom(*m2);
433   m2->GetReflection()->Swap(tmp, m2);
434 }
435 
436 }  // namespace internal
437 }  // namespace protobuf
438 }  // namespace google
439