• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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