reflection_ops.cc 9.1 KB

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