I want to compare two Messages or (two sub parameters) of Google protocol buffers. I don't find an API to achieve it.
Any ideas?
I want to compare two Messages or (two sub parameters) of Google protocol buffers. I don't find an API to achieve it.
Any ideas?
You can use the class google::protobuf::util::MessageDifferencer for this. I think it's only available since v3.0.2:
Introduced new utility functions/classes in the google/protobuf/util directory:
- MessageDifferencer: compare two proto messages and report their differences.
#include <google/protobuf/util/message_differencer.h>
MessageDifferencer::Equals(msg1, msg2);
You can rely on the fact that all of your protobuf messages inherit from the google::protobuf::MesageLite
type, which in turn has everything you need to compare any two protobuf messages, regardless of if they are even of the same derived type:
bool operator==(const google::protobuf::MessageLite& msg_a,
const google::protobuf::MessageLite& msg_b) {
return (msg_a.GetTypeName() == msg_b.GetTypeName()) &&
(msg_a.SerializeAsString() == msg_b.SerializeAsString());
}
EDIT
As was pointed out in the comments below, and especially for map
fields, this answer is incorrect. map
elements have non-deterministic ordering. Use MessageDifferencer
if map
fields might be present in your messages.
Instead of using message.DebugString
you could also do
std::string strMsg;
message.SerializeToString(&strMsg);
with both messages and then compare the two (binary) strings. I didn't test the performance but I assume that it is faster than comparing the human readable message strings returned by .DebugString(). +You can do that with the protobuf-lite library (while for message.DebugString you need the full version).
You can compare the descriptor's pointer (super fast):
if (mMessages[i]->body()->GetDescriptor() == T::descriptor())
mMessages it's a pool of network messages with header and crypto which creates a packet with the protobuf body(google::protobuf::Message*).
so, to get the right kind of message i compare the descriptors constant pointer which is the same for every single type of message (not %100 sure but i haven't got any problem so far).
That would be the fastest way to compare a protobuf Message wthout having to use string comparasion, which by the way you gan get the type name from the descriptor. :-)