1 /*
2 * Copyright (c) 2009-2021, Google LLC
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of Google LLC nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 * ARE DISCLAIMED. IN NO EVENT SHALL Google LLC BE LIABLE FOR ANY DIRECT,
20 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28 #ifndef UPB_MINI_TABLE_MESSAGE_INTERNAL_H_
29 #define UPB_MINI_TABLE_MESSAGE_INTERNAL_H_
30
31 #include "upb/base/string_view.h"
32 #include "upb/hash/common.h"
33 #include "upb/mini_table/types.h"
34
35 // Must be last.
36 #include "upb/port/def.inc"
37
38 struct upb_Decoder;
39 typedef const char* _upb_FieldParser(struct upb_Decoder* d, const char* ptr,
40 upb_Message* msg, intptr_t table,
41 uint64_t hasbits, uint64_t data);
42 typedef struct {
43 uint64_t field_data;
44 _upb_FieldParser* field_parser;
45 } _upb_FastTable_Entry;
46
47 typedef enum {
48 kUpb_ExtMode_NonExtendable = 0, // Non-extendable message.
49 kUpb_ExtMode_Extendable = 1, // Normal extendable message.
50 kUpb_ExtMode_IsMessageSet = 2, // MessageSet message.
51 kUpb_ExtMode_IsMessageSet_ITEM =
52 3, // MessageSet item (temporary only, see decode.c)
53
54 // During table building we steal a bit to indicate that the message is a map
55 // entry. *Only* used during table building!
56 kUpb_ExtMode_IsMapEntry = 4,
57 } upb_ExtMode;
58
59 // LINT.IfChange(mini_table_layout)
60
61 // upb_MiniTable represents the memory layout of a given upb_MessageDef.
62 // The members are public so generated code can initialize them,
63 // but users MUST NOT directly read or write any of its members.
64 struct upb_MiniTable {
65 const upb_MiniTableSub* subs;
66 const upb_MiniTableField* fields;
67
68 // Must be aligned to sizeof(void*). Doesn't include internal members like
69 // unknown fields, extension dict, pointer to msglayout, etc.
70 uint16_t size;
71
72 uint16_t field_count;
73 uint8_t ext; // upb_ExtMode, declared as uint8_t so sizeof(ext) == 1
74 uint8_t dense_below;
75 uint8_t table_mask;
76 uint8_t required_count; // Required fields have the lowest hasbits.
77
78 // To statically initialize the tables of variable length, we need a flexible
79 // array member, and we need to compile in gnu99 mode (constant initialization
80 // of flexible array members is a GNU extension, not in C99 unfortunately.
81 _upb_FastTable_Entry fasttable[];
82 };
83
84 // LINT.ThenChange(//depot/google3/third_party/upb/js/impl/upb_bits/mini_table.ts:presence_logic)
85
86 // Map entries aren't actually stored for map fields, they are only used during
87 // parsing. For parsing, it helps a lot if all map entry messages have the same
88 // layout. The layout code in mini_table/decode.c will ensure that all map
89 // entries have this layout.
90 //
91 // Note that users can and do create map entries directly, which will also use
92 // this layout.
93 //
94 // NOTE: sync with mini_table/decode.c.
95 typedef struct {
96 // We only need 2 hasbits max, but due to alignment we'll use 8 bytes here,
97 // and the uint64_t helps make this clear.
98 uint64_t hasbits;
99 union {
100 upb_StringView str; // For str/bytes.
101 upb_value val; // For all other types.
102 } k;
103 union {
104 upb_StringView str; // For str/bytes.
105 upb_value val; // For all other types.
106 } v;
107 } upb_MapEntryData;
108
109 typedef struct {
110 void* internal_data;
111 upb_MapEntryData data;
112 } upb_MapEntry;
113
114 #ifdef __cplusplus
115 extern "C" {
116 #endif
117
118 // Computes a bitmask in which the |l->required_count| lowest bits are set,
119 // except that we skip the lowest bit (because upb never uses hasbit 0).
120 //
121 // Sample output:
122 // requiredmask(1) => 0b10 (0x2)
123 // requiredmask(5) => 0b111110 (0x3e)
upb_MiniTable_requiredmask(const upb_MiniTable * l)124 UPB_INLINE uint64_t upb_MiniTable_requiredmask(const upb_MiniTable* l) {
125 int n = l->required_count;
126 assert(0 < n && n <= 63);
127 return ((1ULL << n) - 1) << 1;
128 }
129
130 #ifdef __cplusplus
131 } /* extern "C" */
132 #endif
133
134 #include "upb/port/undef.inc"
135
136 #endif /* UPB_MINI_TABLE_MESSAGE_INTERNAL_H_ */
137