• 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 #include <google/protobuf/stubs/strutil.h>
47 
48 
49 #include <google/protobuf/port_def.inc>
50 
51 namespace google {
52 namespace protobuf {
53 namespace internal {
54 
GetReflectionOrDie(const Message & m)55 static const Reflection* GetReflectionOrDie(const Message& m) {
56   const Reflection* r = m.GetReflection();
57   if (r == nullptr) {
58     const Descriptor* d = m.GetDescriptor();
59     const std::string& mtype = d ? d->name() : "unknown";
60     // RawMessage is one known type for which GetReflection() returns nullptr.
61     GOOGLE_LOG(FATAL) << "Message does not support reflection (type " << mtype << ").";
62   }
63   return r;
64 }
65 
Copy(const Message & from,Message * to)66 void ReflectionOps::Copy(const Message& from, Message* to) {
67   if (&from == to) return;
68   Clear(to);
69   Merge(from, to);
70 }
71 
Merge(const Message & from,Message * to)72 void ReflectionOps::Merge(const Message& from, Message* to) {
73   GOOGLE_CHECK_NE(&from, to);
74 
75   const Descriptor* descriptor = from.GetDescriptor();
76   GOOGLE_CHECK_EQ(to->GetDescriptor(), descriptor)
77       << "Tried to merge messages of different types "
78       << "(merge " << descriptor->full_name() << " to "
79       << to->GetDescriptor()->full_name() << ")";
80 
81   const Reflection* from_reflection = GetReflectionOrDie(from);
82   const Reflection* to_reflection = GetReflectionOrDie(*to);
83   bool is_from_generated = (from_reflection->GetMessageFactory() ==
84                             google::protobuf::MessageFactory::generated_factory());
85   bool is_to_generated = (to_reflection->GetMessageFactory() ==
86                           google::protobuf::MessageFactory::generated_factory());
87 
88   std::vector<const FieldDescriptor*> fields;
89   from_reflection->ListFields(from, &fields);
90   for (int i = 0; i < fields.size(); i++) {
91     const FieldDescriptor* field = fields[i];
92 
93     if (field->is_repeated()) {
94       // Use map reflection if both are in map status and have the
95       // same map type to avoid sync with repeated field.
96       // Note: As from and to messages have the same descriptor, the
97       // map field types are the same if they are both generated
98       // messages or both dynamic messages.
99       if (is_from_generated == is_to_generated && field->is_map()) {
100         const MapFieldBase* from_field =
101             from_reflection->GetMapData(from, field);
102         MapFieldBase* to_field = to_reflection->MutableMapData(to, field);
103         if (to_field->IsMapValid() && from_field->IsMapValid()) {
104           to_field->MergeFrom(*from_field);
105           continue;
106         }
107       }
108       int count = from_reflection->FieldSize(from, field);
109       for (int j = 0; j < count; j++) {
110         switch (field->cpp_type()) {
111 #define HANDLE_TYPE(CPPTYPE, METHOD)                                      \
112   case FieldDescriptor::CPPTYPE_##CPPTYPE:                                \
113     to_reflection->Add##METHOD(                                           \
114         to, field, from_reflection->GetRepeated##METHOD(from, field, j)); \
115     break;
116 
117           HANDLE_TYPE(INT32, Int32);
118           HANDLE_TYPE(INT64, Int64);
119           HANDLE_TYPE(UINT32, UInt32);
120           HANDLE_TYPE(UINT64, UInt64);
121           HANDLE_TYPE(FLOAT, Float);
122           HANDLE_TYPE(DOUBLE, Double);
123           HANDLE_TYPE(BOOL, Bool);
124           HANDLE_TYPE(STRING, String);
125           HANDLE_TYPE(ENUM, Enum);
126 #undef HANDLE_TYPE
127 
128           case FieldDescriptor::CPPTYPE_MESSAGE:
129             to_reflection->AddMessage(to, field)->MergeFrom(
130                 from_reflection->GetRepeatedMessage(from, field, j));
131             break;
132         }
133       }
134     } else {
135       switch (field->cpp_type()) {
136 #define HANDLE_TYPE(CPPTYPE, METHOD)                                       \
137   case FieldDescriptor::CPPTYPE_##CPPTYPE:                                 \
138     to_reflection->Set##METHOD(to, field,                                  \
139                                from_reflection->Get##METHOD(from, field)); \
140     break;
141 
142         HANDLE_TYPE(INT32, Int32);
143         HANDLE_TYPE(INT64, Int64);
144         HANDLE_TYPE(UINT32, UInt32);
145         HANDLE_TYPE(UINT64, UInt64);
146         HANDLE_TYPE(FLOAT, Float);
147         HANDLE_TYPE(DOUBLE, Double);
148         HANDLE_TYPE(BOOL, Bool);
149         HANDLE_TYPE(STRING, String);
150         HANDLE_TYPE(ENUM, Enum);
151 #undef HANDLE_TYPE
152 
153         case FieldDescriptor::CPPTYPE_MESSAGE:
154           to_reflection->MutableMessage(to, field)->MergeFrom(
155               from_reflection->GetMessage(from, field));
156           break;
157       }
158     }
159   }
160 
161   to_reflection->MutableUnknownFields(to)->MergeFrom(
162       from_reflection->GetUnknownFields(from));
163 }
164 
Clear(Message * message)165 void ReflectionOps::Clear(Message* message) {
166   const Reflection* reflection = GetReflectionOrDie(*message);
167 
168   std::vector<const FieldDescriptor*> fields;
169   reflection->ListFields(*message, &fields);
170   for (int i = 0; i < fields.size(); i++) {
171     reflection->ClearField(message, fields[i]);
172   }
173 
174   reflection->MutableUnknownFields(message)->Clear();
175 }
176 
IsInitialized(const Message & message)177 bool ReflectionOps::IsInitialized(const Message& message) {
178   const Descriptor* descriptor = message.GetDescriptor();
179   const Reflection* reflection = GetReflectionOrDie(message);
180 
181   // Check required fields of this message.
182   for (int i = 0; i < descriptor->field_count(); i++) {
183     if (descriptor->field(i)->is_required()) {
184       if (!reflection->HasField(message, descriptor->field(i))) {
185         return false;
186       }
187     }
188   }
189 
190   // Check that sub-messages are initialized.
191   std::vector<const FieldDescriptor*> fields;
192   reflection->ListFields(message, &fields);
193   for (int i = 0; i < fields.size(); i++) {
194     const FieldDescriptor* field = fields[i];
195     if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
196 
197       if (field->is_map()) {
198         const FieldDescriptor* value_field = field->message_type()->field(1);
199         if (value_field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
200           const MapFieldBase* map_field =
201               reflection->GetMapData(message, field);
202           if (map_field->IsMapValid()) {
203             MapIterator iter(const_cast<Message*>(&message), field);
204             MapIterator end(const_cast<Message*>(&message), field);
205             for (map_field->MapBegin(&iter), map_field->MapEnd(&end);
206                  iter != end; ++iter) {
207               if (!iter.GetValueRef().GetMessageValue().IsInitialized()) {
208                 return false;
209               }
210             }
211             continue;
212           }
213         } else {
214           continue;
215         }
216       }
217 
218       if (field->is_repeated()) {
219         int size = reflection->FieldSize(message, field);
220 
221         for (int j = 0; j < size; j++) {
222           if (!reflection->GetRepeatedMessage(message, field, j)
223                    .IsInitialized()) {
224             return false;
225           }
226         }
227       } else {
228         if (!reflection->GetMessage(message, field).IsInitialized()) {
229           return false;
230         }
231       }
232     }
233   }
234 
235   return true;
236 }
237 
DiscardUnknownFields(Message * message)238 void ReflectionOps::DiscardUnknownFields(Message* message) {
239   const Reflection* reflection = GetReflectionOrDie(*message);
240 
241   reflection->MutableUnknownFields(message)->Clear();
242 
243   std::vector<const FieldDescriptor*> fields;
244   reflection->ListFields(*message, &fields);
245   for (int i = 0; i < fields.size(); i++) {
246     const FieldDescriptor* field = fields[i];
247     if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
248       if (field->is_repeated()) {
249         if (field->is_map()) {
250           const FieldDescriptor* value_field = field->message_type()->field(1);
251           if (value_field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
252             const MapFieldBase* map_field =
253                 reflection->MutableMapData(message, field);
254             if (map_field->IsMapValid()) {
255               MapIterator iter(message, field);
256               MapIterator end(message, field);
257               for (map_field->MapBegin(&iter), map_field->MapEnd(&end);
258                    iter != end; ++iter) {
259                 iter.MutableValueRef()
260                     ->MutableMessageValue()
261                     ->DiscardUnknownFields();
262               }
263               continue;
264             }
265           } else {
266             continue;
267           }
268         }
269         int size = reflection->FieldSize(*message, field);
270         for (int j = 0; j < size; j++) {
271           reflection->MutableRepeatedMessage(message, field, j)
272               ->DiscardUnknownFields();
273         }
274       } else {
275         reflection->MutableMessage(message, field)->DiscardUnknownFields();
276       }
277     }
278   }
279 }
280 
SubMessagePrefix(const std::string & prefix,const FieldDescriptor * field,int index)281 static std::string SubMessagePrefix(const std::string& prefix,
282                                     const FieldDescriptor* field, int index) {
283   std::string result(prefix);
284   if (field->is_extension()) {
285     result.append("(");
286     result.append(field->full_name());
287     result.append(")");
288   } else {
289     result.append(field->name());
290   }
291   if (index != -1) {
292     result.append("[");
293     result.append(StrCat(index));
294     result.append("]");
295   }
296   result.append(".");
297   return result;
298 }
299 
FindInitializationErrors(const Message & message,const std::string & prefix,std::vector<std::string> * errors)300 void ReflectionOps::FindInitializationErrors(const Message& message,
301                                              const std::string& prefix,
302                                              std::vector<std::string>* errors) {
303   const Descriptor* descriptor = message.GetDescriptor();
304   const Reflection* reflection = GetReflectionOrDie(message);
305 
306   // Check required fields of this message.
307   for (int i = 0; i < descriptor->field_count(); i++) {
308     if (descriptor->field(i)->is_required()) {
309       if (!reflection->HasField(message, descriptor->field(i))) {
310         errors->push_back(prefix + descriptor->field(i)->name());
311       }
312     }
313   }
314 
315   // Check sub-messages.
316   std::vector<const FieldDescriptor*> fields;
317   reflection->ListFields(message, &fields);
318   for (int i = 0; i < fields.size(); i++) {
319     const FieldDescriptor* field = fields[i];
320     if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
321 
322       if (field->is_repeated()) {
323         int size = reflection->FieldSize(message, field);
324 
325         for (int j = 0; j < size; j++) {
326           const Message& sub_message =
327               reflection->GetRepeatedMessage(message, field, j);
328           FindInitializationErrors(sub_message,
329                                    SubMessagePrefix(prefix, field, j), errors);
330         }
331       } else {
332         const Message& sub_message = reflection->GetMessage(message, field);
333         FindInitializationErrors(sub_message,
334                                  SubMessagePrefix(prefix, field, -1), errors);
335       }
336     }
337   }
338 }
339 
340 }  // namespace internal
341 }  // namespace protobuf
342 }  // namespace google
343