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