LCOV - code coverage report
Current view: top level - third_party/protobuf/src/google/protobuf - reflection_ops.cc (source / functions) Hit Total Coverage
Test: tmp.zDYK9MVh93 Lines: 17 116 14.7 %
Date: 2015-10-10 Functions: 2 7 28.6 %

          Line data    Source code
       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             : 
      35             : #include <string>
      36             : #include <vector>
      37             : 
      38             : #include <google/protobuf/reflection_ops.h>
      39             : #include <google/protobuf/descriptor.h>
      40             : #include <google/protobuf/descriptor.pb.h>
      41             : #include <google/protobuf/unknown_field_set.h>
      42             : #include <google/protobuf/stubs/strutil.h>
      43             : 
      44             : namespace google {
      45             : namespace protobuf {
      46             : namespace internal {
      47             : 
      48           0 : void ReflectionOps::Copy(const Message& from, Message* to) {
      49           0 :   if (&from == to) return;
      50           0 :   Clear(to);
      51           0 :   Merge(from, to);
      52             : }
      53             : 
      54           0 : void ReflectionOps::Merge(const Message& from, Message* to) {
      55           0 :   GOOGLE_CHECK_NE(&from, to);
      56             : 
      57           0 :   const Descriptor* descriptor = from.GetDescriptor();
      58           0 :   GOOGLE_CHECK_EQ(to->GetDescriptor(), descriptor)
      59           0 :     << "Tried to merge messages of different types "
      60           0 :     << "(merge " << descriptor->full_name()
      61           0 :     << " to " << to->GetDescriptor()->full_name() << ")";
      62             : 
      63           0 :   const Reflection* from_reflection = from.GetReflection();
      64           0 :   const Reflection* to_reflection = to->GetReflection();
      65             : 
      66             :   vector<const FieldDescriptor*> fields;
      67           0 :   from_reflection->ListFields(from, &fields);
      68           0 :   for (int i = 0; i < fields.size(); i++) {
      69           0 :     const FieldDescriptor* field = fields[i];
      70             : 
      71           0 :     if (field->is_repeated()) {
      72           0 :       int count = from_reflection->FieldSize(from, field);
      73           0 :       for (int j = 0; j < count; j++) {
      74           0 :         switch (field->cpp_type()) {
      75             : #define HANDLE_TYPE(CPPTYPE, METHOD)                                     \
      76             :           case FieldDescriptor::CPPTYPE_##CPPTYPE:                       \
      77             :             to_reflection->Add##METHOD(to, field,                        \
      78             :               from_reflection->GetRepeated##METHOD(from, field, j));     \
      79             :             break;
      80             : 
      81           0 :           HANDLE_TYPE(INT32 , Int32 );
      82           0 :           HANDLE_TYPE(INT64 , Int64 );
      83           0 :           HANDLE_TYPE(UINT32, UInt32);
      84           0 :           HANDLE_TYPE(UINT64, UInt64);
      85           0 :           HANDLE_TYPE(FLOAT , Float );
      86           0 :           HANDLE_TYPE(DOUBLE, Double);
      87           0 :           HANDLE_TYPE(BOOL  , Bool  );
      88           0 :           HANDLE_TYPE(STRING, String);
      89           0 :           HANDLE_TYPE(ENUM  , Enum  );
      90             : #undef HANDLE_TYPE
      91             : 
      92             :           case FieldDescriptor::CPPTYPE_MESSAGE:
      93           0 :             to_reflection->AddMessage(to, field)->MergeFrom(
      94           0 :               from_reflection->GetRepeatedMessage(from, field, j));
      95             :             break;
      96             :         }
      97             :       }
      98             :     } else {
      99           0 :       switch (field->cpp_type()) {
     100             : #define HANDLE_TYPE(CPPTYPE, METHOD)                                        \
     101             :         case FieldDescriptor::CPPTYPE_##CPPTYPE:                            \
     102             :           to_reflection->Set##METHOD(to, field,                             \
     103             :             from_reflection->Get##METHOD(from, field));                     \
     104             :           break;
     105             : 
     106           0 :         HANDLE_TYPE(INT32 , Int32 );
     107           0 :         HANDLE_TYPE(INT64 , Int64 );
     108           0 :         HANDLE_TYPE(UINT32, UInt32);
     109           0 :         HANDLE_TYPE(UINT64, UInt64);
     110           0 :         HANDLE_TYPE(FLOAT , Float );
     111           0 :         HANDLE_TYPE(DOUBLE, Double);
     112           0 :         HANDLE_TYPE(BOOL  , Bool  );
     113           0 :         HANDLE_TYPE(STRING, String);
     114           0 :         HANDLE_TYPE(ENUM  , Enum  );
     115             : #undef HANDLE_TYPE
     116             : 
     117             :         case FieldDescriptor::CPPTYPE_MESSAGE:
     118           0 :           to_reflection->MutableMessage(to, field)->MergeFrom(
     119           0 :             from_reflection->GetMessage(from, field));
     120             :           break;
     121             :       }
     122             :     }
     123             :   }
     124             : 
     125           0 :   to_reflection->MutableUnknownFields(to)->MergeFrom(
     126           0 :     from_reflection->GetUnknownFields(from));
     127           0 : }
     128             : 
     129           9 : void ReflectionOps::Clear(Message* message) {
     130           9 :   const Reflection* reflection = message->GetReflection();
     131             : 
     132             :   vector<const FieldDescriptor*> fields;
     133           9 :   reflection->ListFields(*message, &fields);
     134           9 :   for (int i = 0; i < fields.size(); i++) {
     135           0 :     reflection->ClearField(message, fields[i]);
     136             :   }
     137             : 
     138           9 :   reflection->MutableUnknownFields(message)->Clear();
     139           9 : }
     140             : 
     141          14 : bool ReflectionOps::IsInitialized(const Message& message) {
     142         156 :   const Descriptor* descriptor = message.GetDescriptor();
     143          14 :   const Reflection* reflection = message.GetReflection();
     144             : 
     145             :   // Check required fields of this message.
     146         142 :   for (int i = 0; i < descriptor->field_count(); i++) {
     147         192 :     if (descriptor->field(i)->is_required()) {
     148           0 :       if (!reflection->HasField(message, descriptor->field(i))) {
     149             :         return false;
     150             :       }
     151             :     }
     152             :   }
     153             : 
     154             :   // Check that sub-messages are initialized.
     155             :   vector<const FieldDescriptor*> fields;
     156          14 :   reflection->ListFields(message, &fields);
     157          52 :   for (int i = 0; i < fields.size(); i++) {
     158          38 :     const FieldDescriptor* field = fields[i];
     159          38 :     if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
     160             : 
     161           5 :       if (field->is_repeated()) {
     162           0 :         int size = reflection->FieldSize(message, field);
     163             : 
     164           0 :         for (int j = 0; j < size; j++) {
     165           0 :           if (!reflection->GetRepeatedMessage(message, field, j)
     166           0 :                           .IsInitialized()) {
     167             :             return false;
     168             :           }
     169             :         }
     170             :       } else {
     171           5 :         if (!reflection->GetMessage(message, field).IsInitialized()) {
     172             :           return false;
     173             :         }
     174             :       }
     175             :     }
     176             :   }
     177             : 
     178             :   return true;
     179             : }
     180             : 
     181           0 : void ReflectionOps::DiscardUnknownFields(Message* message) {
     182           0 :   const Reflection* reflection = message->GetReflection();
     183             : 
     184           0 :   reflection->MutableUnknownFields(message)->Clear();
     185             : 
     186             :   vector<const FieldDescriptor*> fields;
     187           0 :   reflection->ListFields(*message, &fields);
     188           0 :   for (int i = 0; i < fields.size(); i++) {
     189           0 :     const FieldDescriptor* field = fields[i];
     190           0 :     if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
     191           0 :       if (field->is_repeated()) {
     192           0 :         int size = reflection->FieldSize(*message, field);
     193           0 :         for (int j = 0; j < size; j++) {
     194           0 :           reflection->MutableRepeatedMessage(message, field, j)
     195           0 :                     ->DiscardUnknownFields();
     196             :         }
     197             :       } else {
     198           0 :         reflection->MutableMessage(message, field)->DiscardUnknownFields();
     199             :       }
     200             :     }
     201             :   }
     202           0 : }
     203             : 
     204           0 : static string SubMessagePrefix(const string& prefix,
     205           0 :                                const FieldDescriptor* field,
     206             :                                int index) {
     207           0 :   string result(prefix);
     208           0 :   if (field->is_extension()) {
     209           0 :     result.append("(");
     210           0 :     result.append(field->full_name());
     211           0 :     result.append(")");
     212             :   } else {
     213           0 :     result.append(field->name());
     214             :   }
     215           0 :   if (index != -1) {
     216           0 :     result.append("[");
     217           0 :     result.append(SimpleItoa(index));
     218           0 :     result.append("]");
     219             :   }
     220           0 :   result.append(".");
     221           0 :   return result;
     222             : }
     223             : 
     224           0 : void ReflectionOps::FindInitializationErrors(
     225             :     const Message& message,
     226             :     const string& prefix,
     227             :     vector<string>* errors) {
     228           0 :   const Descriptor* descriptor = message.GetDescriptor();
     229           0 :   const Reflection* reflection = message.GetReflection();
     230             : 
     231             :   // Check required fields of this message.
     232           0 :   for (int i = 0; i < descriptor->field_count(); i++) {
     233           0 :     if (descriptor->field(i)->is_required()) {
     234           0 :       if (!reflection->HasField(message, descriptor->field(i))) {
     235           0 :         errors->push_back(prefix + descriptor->field(i)->name());
     236             :       }
     237             :     }
     238             :   }
     239             : 
     240             :   // Check sub-messages.
     241             :   vector<const FieldDescriptor*> fields;
     242           0 :   reflection->ListFields(message, &fields);
     243           0 :   for (int i = 0; i < fields.size(); i++) {
     244           0 :     const FieldDescriptor* field = fields[i];
     245           0 :     if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
     246             : 
     247           0 :       if (field->is_repeated()) {
     248           0 :         int size = reflection->FieldSize(message, field);
     249             : 
     250           0 :         for (int j = 0; j < size; j++) {
     251             :           const Message& sub_message =
     252           0 :             reflection->GetRepeatedMessage(message, field, j);
     253             :           FindInitializationErrors(sub_message,
     254             :                                    SubMessagePrefix(prefix, field, j),
     255           0 :                                    errors);
     256             :         }
     257             :       } else {
     258           0 :         const Message& sub_message = reflection->GetMessage(message, field);
     259             :         FindInitializationErrors(sub_message,
     260             :                                  SubMessagePrefix(prefix, field, -1),
     261           0 :                                  errors);
     262             :       }
     263             :     }
     264             :   }
     265           0 : }
     266             : 
     267             : }  // namespace internal
     268             : }  // namespace protobuf
     269             : }  // namespace google

Generated by: LCOV version 1.10