reflection_ops.cc
Go to the documentation of this file.
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.
35 
36 #include <string>
37 #include <vector>
38 
47 
48 
49 #include <google/protobuf/port_def.inc>
50 
51 namespace google {
52 namespace protobuf {
53 namespace internal {
54 
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 
66 void ReflectionOps::Copy(const Message& from, Message* to) {
67  if (&from == to) return;
68  Clear(to);
69  Merge(from, to);
70 }
71 
72 void ReflectionOps::Merge(const Message& from, Message* to) {
73  GOOGLE_CHECK_NE(&from, to);
74 
75  const Descriptor* descriptor = from.GetDescriptor();
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() ==
85  bool is_to_generated = (to_reflection->GetMessageFactory() ==
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 
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 
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 
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 
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 
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);
257  for (map_field->MapBegin(&iter), map_field->MapEnd(&end);
258  iter != end; ++iter) {
259  iter.MutableValueRef()
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)
273  }
274  } else {
276  }
277  }
278  }
279 }
280 
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 
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,
330  }
331  } else {
332  const Message& sub_message = reflection->GetMessage(message, field);
333  FindInitializationErrors(sub_message,
335  }
336  }
337  }
338 }
339 
340 } // namespace internal
341 } // namespace protobuf
342 } // namespace google
google::protobuf::Descriptor::full_name
const std::string & full_name() const
reflection_ops.h
GOOGLE_CHECK_EQ
#define GOOGLE_CHECK_EQ(A, B)
Definition: logging.h:156
Json::UInt64
unsigned long long int UInt64
Definition: json.h:241
google::protobuf.internal::GetReflectionOrDie
static const Reflection * GetReflectionOrDie(const Message &m)
Definition: reflection_ops.cc:55
google::protobuf::MapIterator::GetValueRef
const MapValueRef & GetValueRef()
Definition: map_field.h:750
google::protobuf::Reflection::MutableMapData
internal::MapFieldBase * MutableMapData(Message *message, const FieldDescriptor *field) const
Definition: generated_message_reflection.cc:2211
google::protobuf::FieldDescriptor
Definition: src/google/protobuf/descriptor.h:515
end
GLuint GLuint end
Definition: glcorearb.h:2858
Bool
Definition: gtest_pred_impl_unittest.cc:56
map_field_inl.h
google::protobuf::StrCat
string StrCat(const AlphaNum &a, const AlphaNum &b)
Definition: strutil.cc:1480
FATAL
const int FATAL
Definition: log_severity.h:60
google::protobuf::MessageFactory::generated_factory
static MessageFactory * generated_factory()
Definition: src/google/protobuf/message.cc:655
google::protobuf::Reflection::GetMessageFactory
MessageFactory * GetMessageFactory() const
Definition: generated_message_reflection.cc:2185
errors
const char * errors
Definition: tokenizer_unittest.cc:841
string
GLsizei const GLchar *const * string
Definition: glcorearb.h:3083
google::protobuf::Reflection
Definition: src/google/protobuf/message.h:400
google::protobuf::MapValueRef::GetMessageValue
const Message & GetMessageValue() const
Definition: map_field.h:644
descriptor
Descriptor * descriptor
Definition: php/ext/google/protobuf/protobuf.h:936
google::protobuf::Reflection::HasField
bool HasField(const Message &message, const FieldDescriptor *field) const
Definition: generated_message_reflection.cc:728
google::protobuf::HANDLE_TYPE
HANDLE_TYPE(int32, FieldDescriptor::CPPTYPE_INT32, -1)
google::protobuf::UnknownFieldSet::Clear
void Clear()
Definition: unknown_field_set.h:299
testing::internal::Int32
TypeWithSize< 4 >::Int Int32
Definition: gtest-port.h:2241
google::protobuf::MapIterator::MutableValueRef
MapValueRef * MutableValueRef()
Definition: map_field.h:751
Enum
Definition: type.pb.h:797
google::protobuf::Message::IsInitialized
bool IsInitialized() const override
Definition: src/google/protobuf/message.cc:116
map_field.h
testing::internal::Double
FloatingPoint< double > Double
Definition: gtest-internal.h:429
google::protobuf.internal::ReflectionOps::FindInitializationErrors
static void FindInitializationErrors(const Message &message, const std::string &prefix, std::vector< std::string > *errors)
Definition: reflection_ops.cc:300
testing::internal::UInt32
TypeWithSize< 4 >::UInt UInt32
Definition: gtest-port.h:2242
google::protobuf.internal::ReflectionOps::Merge
static void Merge(const Message &from, Message *to)
Definition: reflection_ops.cc:72
strutil.h
unknown_field_set.h
google::protobuf::Reflection::MutableUnknownFields
UnknownFieldSet * MutableUnknownFields(Message *message) const
Definition: generated_message_reflection.cc:237
testing::internal::Float
FloatingPoint< float > Float
Definition: gtest-internal.h:428
prefix
static const char prefix[]
Definition: test_pair_ipc.cpp:26
google::protobuf.internal::ReflectionOps::DiscardUnknownFields
static void DiscardUnknownFields(Message *message)
Definition: reflection_ops.cc:238
google::protobuf.internal::SubMessagePrefix
static std::string SubMessagePrefix(const std::string &prefix, const FieldDescriptor *field, int index)
Definition: reflection_ops.cc:281
google::protobuf::UnknownFieldSet::MergeFrom
void MergeFrom(const UnknownFieldSet &other)
Definition: unknown_field_set.cc:77
google::protobuf::Reflection::GetUnknownFields
const UnknownFieldSet & GetUnknownFields(const Message &message) const
Definition: generated_message_reflection.cc:232
GOOGLE_LOG
#define GOOGLE_LOG(LEVEL)
Definition: logging.h:146
google::protobuf::Reflection::ClearField
void ClearField(Message *message, const FieldDescriptor *field) const
Definition: generated_message_reflection.cc:789
size
#define size
Definition: glcorearb.h:2944
d
d
google::protobuf.internal::MapFieldBase::MapBegin
virtual void MapBegin(MapIterator *map_iter) const =0
field
const FieldDescriptor * field
Definition: parser_unittest.cc:2694
google::protobuf::Reflection::FieldSize
int FieldSize(const Message &message, const FieldDescriptor *field) const
Definition: generated_message_reflection.cc:744
GOOGLE_CHECK_NE
#define GOOGLE_CHECK_NE(A, B)
Definition: logging.h:157
google::protobuf.internal::MapFieldBase::MapEnd
virtual void MapEnd(MapIterator *map_iter) const =0
google::protobuf::Reflection::MutableMessage
Message * MutableMessage(Message *message, const FieldDescriptor *field, MessageFactory *factory=nullptr) const
Definition: generated_message_reflection.cc:1462
i
int i
Definition: gmock-matchers_test.cc:764
fields
static const upb_fielddef fields[107]
Definition: ruby/ext/google/protobuf_c/upb.c:7671
google::protobuf::Message
Definition: src/google/protobuf/message.h:205
google::protobuf::Message::GetDescriptor
const Descriptor * GetDescriptor() const
Definition: src/google/protobuf/message.h:326
common.h
google::protobuf::Reflection::MutableRepeatedMessage
Message * MutableRepeatedMessage(Message *message, const FieldDescriptor *field, int index) const
Definition: generated_message_reflection.cc:1617
google::protobuf.internal::MapFieldBase::IsMapValid
bool IsMapValid() const
Definition: map_field.cc:72
size
GLsizeiptr size
Definition: glcorearb.h:2943
m
const upb_json_parsermethod * m
Definition: ruby/ext/google/protobuf_c/upb.h:10501
logging.h
google::protobuf::Message::MergeFrom
virtual void MergeFrom(const Message &from)
Definition: src/google/protobuf/message.cc:82
r
GLboolean r
Definition: glcorearb.h:3228
google::protobuf::Descriptor
Definition: src/google/protobuf/descriptor.h:231
descriptor.h
google::protobuf.internal::ReflectionOps::Copy
static void Copy(const Message &from, Message *to)
Definition: reflection_ops.cc:66
internal
Definition: any.pb.h:40
google::protobuf.internal::MapFieldBase
Definition: map_field.h:69
google::protobuf::Reflection::GetMapData
const internal::MapFieldBase * GetMapData(const Message &message, const FieldDescriptor *field) const
Definition: generated_message_reflection.cc:2218
google::protobuf.internal::ReflectionOps::IsInitialized
static bool IsInitialized(const Message &message)
Definition: reflection_ops.cc:177
google::protobuf.internal::MapFieldBase::MergeFrom
virtual void MergeFrom(const MapFieldBase &other)=0
descriptor.pb.h
google::protobuf::Reflection::AddMessage
Message * AddMessage(Message *message, const FieldDescriptor *field, MessageFactory *factory=nullptr) const
Definition: generated_message_reflection.cc:1638
google::protobuf::FieldDescriptor::CPPTYPE_MESSAGE
@ CPPTYPE_MESSAGE
Definition: src/google/protobuf/descriptor.h:563
google::protobuf::MapIterator
Definition: map_field.h:712
google::protobuf::Message::DiscardUnknownFields
virtual void DiscardUnknownFields()
Definition: src/google/protobuf/message.cc:136
count
GLint GLsizei count
Definition: glcorearb.h:2830
index
GLuint index
Definition: glcorearb.h:3055
google::protobuf::Reflection::ListFields
void ListFields(const Message &message, std::vector< const FieldDescriptor * > *output) const
Definition: generated_message_reflection.cc:1029
Json::Int64
long long int Int64
Definition: json.h:240
google::protobuf::FieldDescriptor::cpp_type
CppType cpp_type() const
Definition: src/google/protobuf/descriptor.h:2139
google
Definition: data_proto2_to_proto3_util.h:11
message
GLenum GLuint GLenum GLsizei const GLchar * message
Definition: glcorearb.h:2695
google::protobuf.internal::ReflectionOps::Clear
static void Clear(Message *message)
Definition: reflection_ops.cc:165
google::protobuf::Reflection::GetRepeatedMessage
const Message & GetRepeatedMessage(const Message &message, const FieldDescriptor *field, int index) const
Definition: generated_message_reflection.cc:1597
google::protobuf::MapValueRef::MutableMessageValue
Message * MutableMessageValue()
Definition: map_field.h:650
google::protobuf::Reflection::GetMessage
const Message & GetMessage(const Message &message, const FieldDescriptor *field, MessageFactory *factory=nullptr) const
Definition: generated_message_reflection.cc:1443


libaditof
Author(s):
autogenerated on Wed May 21 2025 02:06:58