1 // Protocol Buffers - Google's data interchange format
2 // Copyright 2023 Google LLC. All rights reserved.
3 //
4 // Use of this source code is governed by a BSD-style
5 // license that can be found in the LICENSE file or at
6 // https://developers.google.com/open-source/licenses/bsd
7
8 /*
9 ** Our memory representation for parsing tables and messages themselves.
10 ** Functions in this file are used by generated code and possibly reflection.
11 **
12 ** The definitions in this file are internal to upb.
13 **/
14
15 #ifndef UPB_MESSAGE_INTERNAL_MESSAGE_H_
16 #define UPB_MESSAGE_INTERNAL_MESSAGE_H_
17
18 #include <stdlib.h>
19 #include <string.h>
20
21 #include "upb/mem/arena.h"
22 #include "upb/message/internal/extension.h"
23 #include "upb/mini_table/message.h"
24
25 // Must be last.
26 #include "upb/port/def.inc"
27
28 #ifdef __cplusplus
29 extern "C" {
30 #endif
31
32 extern const float kUpb_FltInfinity;
33 extern const double kUpb_Infinity;
34 extern const double kUpb_NaN;
35
36 // Internal members of a upb_Message that track unknown fields and/or
37 // extensions. We can change this without breaking binary compatibility.
38
39 typedef struct upb_Message_Internal {
40 // Total size of this structure, including the data that follows.
41 // Must be aligned to 8, which is alignof(upb_Extension)
42 uint32_t size;
43
44 /* Offsets relative to the beginning of this structure.
45 *
46 * Unknown data grows forward from the beginning to unknown_end.
47 * Extension data grows backward from size to ext_begin.
48 * When the two meet, we're out of data and have to realloc.
49 *
50 * If we imagine that the final member of this struct is:
51 * char data[size - overhead]; // overhead = sizeof(upb_Message_Internal)
52 *
53 * Then we have:
54 * unknown data: data[0 .. (unknown_end - overhead)]
55 * extensions data: data[(ext_begin - overhead) .. (size - overhead)] */
56 uint32_t unknown_end;
57 uint32_t ext_begin;
58 // Data follows, as if there were an array:
59 // char data[size - sizeof(upb_Message_Internal)];
60 } upb_Message_Internal;
61
62 #ifdef UPB_TRACING_ENABLED
63 UPB_API void upb_Message_LogNewMessage(const upb_MiniTable* m,
64 const upb_Arena* arena);
65 UPB_API void upb_Message_SetNewMessageTraceHandler(
66 void (*handler)(const upb_MiniTable*, const upb_Arena*));
67 #endif // UPB_TRACING_ENABLED
68
69 // Inline version upb_Message_New(), for internal use.
_upb_Message_New(const upb_MiniTable * m,upb_Arena * a)70 UPB_INLINE struct upb_Message* _upb_Message_New(const upb_MiniTable* m,
71 upb_Arena* a) {
72 #ifdef UPB_TRACING_ENABLED
73 upb_Message_LogNewMessage(m, a);
74 #endif // UPB_TRACING_ENABLED
75
76 const int size = m->UPB_PRIVATE(size);
77 struct upb_Message* msg = (struct upb_Message*)upb_Arena_Malloc(a, size);
78 if (UPB_UNLIKELY(!msg)) return NULL;
79 memset(msg, 0, size);
80 return msg;
81 }
82
83 // Discards the unknown fields for this message only.
84 void _upb_Message_DiscardUnknown_shallow(struct upb_Message* msg);
85
86 // Adds unknown data (serialized protobuf data) to the given message.
87 // The data is copied into the message instance.
88 bool UPB_PRIVATE(_upb_Message_AddUnknown)(struct upb_Message* msg,
89 const char* data, size_t len,
90 upb_Arena* arena);
91
92 bool UPB_PRIVATE(_upb_Message_Realloc)(struct upb_Message* msg, size_t need,
93 upb_Arena* arena);
94
95 #ifdef __cplusplus
96 } /* extern "C" */
97 #endif
98
99 #include "upb/port/undef.inc"
100
101 #endif /* UPB_MESSAGE_INTERNAL_MESSAGE_H_ */
102