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