Skip to content

Commit

Permalink
upb: implement IsExactlyEqual() for proto messages
Browse files Browse the repository at this point in the history
PiperOrigin-RevId: 543780133
  • Loading branch information
ericsalo authored and copybara-github committed Jun 27, 2023
1 parent dbbc4a3 commit 0c2a251
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 0 deletions.
24 changes: 24 additions & 0 deletions upb/message/accessors.c
Original file line number Diff line number Diff line change
Expand Up @@ -66,3 +66,27 @@ upb_MapInsertStatus upb_Message_InsertMapEntry(upb_Map* map,
&map_entry_value);
return upb_Map_Insert(map, map_entry_key, map_entry_value, arena);
}

bool upb_Message_IsExactlyEqual(const upb_Message* m1, const upb_Message* m2,
const upb_MiniTable* layout) {
if (m1 == m2) return true;

int opts = kUpb_EncodeOption_SkipUnknown | kUpb_EncodeOption_Deterministic;
upb_Arena* a = upb_Arena_New();

// Compare deterministically serialized payloads with no unknown fields.
size_t size1, size2;
char *data1, *data2;
upb_EncodeStatus status1 = upb_Encode(m1, layout, opts, a, &data1, &size1);
upb_EncodeStatus status2 = upb_Encode(m2, layout, opts, a, &data2, &size2);

if (status1 != kUpb_EncodeStatus_Ok || status2 != kUpb_EncodeStatus_Ok) {
// TODO(salo): How should we fail here? (In Ruby we throw an exception.)
upb_Arena_Free(a);
return false;
}

const bool ret = (size1 == size2) && (memcmp(data1, data2, size1) == 0);
upb_Arena_Free(a);
return ret;
}
4 changes: 4 additions & 0 deletions upb/message/accessors.h
Original file line number Diff line number Diff line change
Expand Up @@ -387,6 +387,10 @@ upb_MapInsertStatus upb_Message_InsertMapEntry(upb_Map* map,
upb_Message* map_entry_message,
upb_Arena* arena);

// Compares two messages by serializing them and calling memcmp().
bool upb_Message_IsExactlyEqual(const upb_Message* m1, const upb_Message* m2,
const upb_MiniTable* layout);

#ifdef __cplusplus
} /* extern "C" */
#endif
Expand Down

0 comments on commit 0c2a251

Please sign in to comment.