reflection_ops.cc 11 KB

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