blob: 1e786a829e975b46f7423bdd3c2a3e3c71cb4ca8 [file] [log] [blame]
Derek Bensone2ab51b2024-06-25 07:25:21 -07001#include "upb/message/merge.h"
2
3#include "stddef.h"
4#include "upb/mem/arena.h"
5#include "upb/message/message.h"
6#include "upb/mini_table/extension_registry.h"
7#include "upb/mini_table/message.h"
8#include "upb/wire/decode.h"
9#include "upb/wire/encode.h"
10
11// Must be last.
12#include "upb/port/def.inc"
13
14bool upb_Message_MergeFrom(upb_Message* dst, const upb_Message* src,
15 const upb_MiniTable* mt,
16 const upb_ExtensionRegistry* extreg,
17 upb_Arena* arena) {
18 char* buf = NULL;
19 size_t size = 0;
20 // This tmp arena is used to hold the bytes for `src` serialized. This bends
21 // the typical "no hidden allocations" design of upb, but under a properly
22 // optimized implementation this extra allocation would not be necessary and
23 // so we don't want to unnecessarily have the bad API or bloat the passed-in
24 // arena with this very-short-term allocation.
25 upb_Arena* encode_arena = upb_Arena_New();
26 upb_EncodeStatus e_status = upb_Encode(src, mt, 0, encode_arena, &buf, &size);
27 if (e_status != kUpb_EncodeStatus_Ok) {
28 upb_Arena_Free(encode_arena);
29 return false;
30 }
31 upb_DecodeStatus d_status = upb_Decode(buf, size, dst, mt, extreg, 0, arena);
32 if (d_status != kUpb_DecodeStatus_Ok) {
33 upb_Arena_Free(encode_arena);
34 return false;
35 }
36 upb_Arena_Free(encode_arena);
37 return true;
38}