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 #include "upb/mini_table/decode.h"
29 
30 #include <inttypes.h>
31 #include <stdlib.h>
32 
33 #include "upb/base/log2.h"
34 #include "upb/base/string_view.h"
35 #include "upb/mem/arena.h"
36 #include "upb/mini_table/common.h"
37 #include "upb/mini_table/common_internal.h"
38 #include "upb/mini_table/enum_internal.h"
39 #include "upb/mini_table/extension_internal.h"
40 
41 // Must be last.
42 #include "upb/port/def.inc"
43 
44 // Note: we sort by this number when calculating layout order.
45 typedef enum {
46   kUpb_LayoutItemType_OneofCase,   // Oneof case.
47   kUpb_LayoutItemType_OneofField,  // Oneof field data.
48   kUpb_LayoutItemType_Field,       // Non-oneof field data.
49 
50   kUpb_LayoutItemType_Max = kUpb_LayoutItemType_Field,
51 } upb_LayoutItemType;
52 
53 #define kUpb_LayoutItem_IndexSentinel ((uint16_t)-1)
54 
55 typedef struct {
56   // Index of the corresponding field.  When this is a oneof field, the field's
57   // offset will be the index of the next field in a linked list.
58   uint16_t field_index;
59   uint16_t offset;
60   upb_FieldRep rep;
61   upb_LayoutItemType type;
62 } upb_LayoutItem;
63 
64 typedef struct {
65   upb_LayoutItem* data;
66   size_t size;
67   size_t capacity;
68 } upb_LayoutItemVector;
69 
70 typedef struct {
71   const char* end;
72   upb_MiniTable* table;
73   upb_MiniTableField* fields;
74   upb_MiniTablePlatform platform;
75   upb_LayoutItemVector vec;
76   upb_Arena* arena;
77   upb_Status* status;
78 
79   // When building enums.
80   upb_MiniTableEnum* enum_table;
81   uint32_t enum_value_count;
82   uint32_t enum_data_count;
83   uint32_t enum_data_capacity;
84 
85   jmp_buf err;
86 } upb_MtDecoder;
87 
88 UPB_PRINTF(2, 3)
upb_MtDecoder_ErrorFormat(upb_MtDecoder * d,const char * fmt,...)89 UPB_NORETURN static void upb_MtDecoder_ErrorFormat(upb_MtDecoder* d,
90                                                    const char* fmt, ...) {
91   if (d->status) {
92     va_list argp;
93     upb_Status_SetErrorMessage(d->status, "Error building mini table: ");
94     va_start(argp, fmt);
95     upb_Status_VAppendErrorFormat(d->status, fmt, argp);
96     va_end(argp);
97   }
98   UPB_LONGJMP(d->err, 1);
99 }
100 
upb_MtDecoder_CheckOutOfMemory(upb_MtDecoder * d,const void * ptr)101 static void upb_MtDecoder_CheckOutOfMemory(upb_MtDecoder* d, const void* ptr) {
102   if (!ptr) upb_MtDecoder_ErrorFormat(d, "Out of memory");
103 }
104 
105 // In each field's offset, we temporarily store a presence classifier:
106 enum PresenceClass {
107   kNoPresence = 0,
108   kHasbitPresence = 1,
109   kRequiredPresence = 2,
110   kOneofBase = 3,
111   // Negative values refer to a specific oneof with that number.  Positive
112   // values >= kOneofBase indicate that this field is in a oneof, and specify
113   // the next field in this oneof's linked list.
114 };
115 
upb_MiniTable_DecodeBase92Varint(upb_MtDecoder * d,const char * ptr,char first_ch,uint8_t min,uint8_t max,uint32_t * out_val)116 static const char* upb_MiniTable_DecodeBase92Varint(upb_MtDecoder* d,
117                                                     const char* ptr,
118                                                     char first_ch, uint8_t min,
119                                                     uint8_t max,
120                                                     uint32_t* out_val) {
121   uint32_t val = 0;
122   uint32_t shift = 0;
123   const int bits_per_char =
124       upb_Log2Ceiling(_upb_FromBase92(max) - _upb_FromBase92(min));
125   char ch = first_ch;
126   while (1) {
127     uint32_t bits = _upb_FromBase92(ch) - _upb_FromBase92(min);
128     val |= bits << shift;
129     if (ptr == d->end || *ptr < min || max < *ptr) {
130       *out_val = val;
131       return ptr;
132     }
133     ch = *ptr++;
134     shift += bits_per_char;
135     if (shift >= 32) upb_MtDecoder_ErrorFormat(d, "Overlong varint");
136   }
137 }
138 
upb_MiniTable_HasSub(upb_MiniTableField * field,uint64_t msg_modifiers)139 static bool upb_MiniTable_HasSub(upb_MiniTableField* field,
140                                  uint64_t msg_modifiers) {
141   switch (field->UPB_PRIVATE(descriptortype)) {
142     case kUpb_FieldType_Message:
143     case kUpb_FieldType_Group:
144     case kUpb_FieldType_Enum:
145       return true;
146     case kUpb_FieldType_String:
147       if (!(msg_modifiers & kUpb_MessageModifier_ValidateUtf8)) {
148         field->UPB_PRIVATE(descriptortype) = kUpb_FieldType_Bytes;
149         field->mode |= kUpb_LabelFlags_IsAlternate;
150       }
151       return false;
152     default:
153       return false;
154   }
155 }
156 
upb_MtDecoder_FieldIsPackable(upb_MiniTableField * field)157 static bool upb_MtDecoder_FieldIsPackable(upb_MiniTableField* field) {
158   return (field->mode & kUpb_FieldMode_Array) &&
159          upb_FieldType_IsPackable(field->UPB_PRIVATE(descriptortype));
160 }
161 
upb_MiniTable_SetTypeAndSub(upb_MiniTableField * field,upb_FieldType type,uint32_t * sub_count,uint64_t msg_modifiers,bool is_proto3_enum)162 static void upb_MiniTable_SetTypeAndSub(upb_MiniTableField* field,
163                                         upb_FieldType type, uint32_t* sub_count,
164                                         uint64_t msg_modifiers,
165                                         bool is_proto3_enum) {
166   field->UPB_PRIVATE(descriptortype) = type;
167 
168   if (is_proto3_enum) {
169     UPB_ASSERT(field->UPB_PRIVATE(descriptortype) == kUpb_FieldType_Enum);
170     field->UPB_PRIVATE(descriptortype) = kUpb_FieldType_Int32;
171     field->mode |= kUpb_LabelFlags_IsAlternate;
172   }
173 
174   if (upb_MiniTable_HasSub(field, msg_modifiers)) {
175     field->UPB_PRIVATE(submsg_index) = sub_count ? (*sub_count)++ : 0;
176   } else {
177     field->UPB_PRIVATE(submsg_index) = kUpb_NoSub;
178   }
179 
180   if (upb_MtDecoder_FieldIsPackable(field) &&
181       (msg_modifiers & kUpb_MessageModifier_DefaultIsPacked)) {
182     field->mode |= kUpb_LabelFlags_IsPacked;
183   }
184 }
185 
186 static const char kUpb_EncodedToType[] = {
187     [kUpb_EncodedType_Double] = kUpb_FieldType_Double,
188     [kUpb_EncodedType_Float] = kUpb_FieldType_Float,
189     [kUpb_EncodedType_Int64] = kUpb_FieldType_Int64,
190     [kUpb_EncodedType_UInt64] = kUpb_FieldType_UInt64,
191     [kUpb_EncodedType_Int32] = kUpb_FieldType_Int32,
192     [kUpb_EncodedType_Fixed64] = kUpb_FieldType_Fixed64,
193     [kUpb_EncodedType_Fixed32] = kUpb_FieldType_Fixed32,
194     [kUpb_EncodedType_Bool] = kUpb_FieldType_Bool,
195     [kUpb_EncodedType_String] = kUpb_FieldType_String,
196     [kUpb_EncodedType_Group] = kUpb_FieldType_Group,
197     [kUpb_EncodedType_Message] = kUpb_FieldType_Message,
198     [kUpb_EncodedType_Bytes] = kUpb_FieldType_Bytes,
199     [kUpb_EncodedType_UInt32] = kUpb_FieldType_UInt32,
200     [kUpb_EncodedType_OpenEnum] = kUpb_FieldType_Enum,
201     [kUpb_EncodedType_SFixed32] = kUpb_FieldType_SFixed32,
202     [kUpb_EncodedType_SFixed64] = kUpb_FieldType_SFixed64,
203     [kUpb_EncodedType_SInt32] = kUpb_FieldType_SInt32,
204     [kUpb_EncodedType_SInt64] = kUpb_FieldType_SInt64,
205     [kUpb_EncodedType_ClosedEnum] = kUpb_FieldType_Enum,
206 };
207 
upb_MiniTable_SetField(upb_MtDecoder * d,uint8_t ch,upb_MiniTableField * field,uint64_t msg_modifiers,uint32_t * sub_count)208 static void upb_MiniTable_SetField(upb_MtDecoder* d, uint8_t ch,
209                                    upb_MiniTableField* field,
210                                    uint64_t msg_modifiers,
211                                    uint32_t* sub_count) {
212   static const char kUpb_EncodedToFieldRep[] = {
213       [kUpb_EncodedType_Double] = kUpb_FieldRep_8Byte,
214       [kUpb_EncodedType_Float] = kUpb_FieldRep_4Byte,
215       [kUpb_EncodedType_Int64] = kUpb_FieldRep_8Byte,
216       [kUpb_EncodedType_UInt64] = kUpb_FieldRep_8Byte,
217       [kUpb_EncodedType_Int32] = kUpb_FieldRep_4Byte,
218       [kUpb_EncodedType_Fixed64] = kUpb_FieldRep_8Byte,
219       [kUpb_EncodedType_Fixed32] = kUpb_FieldRep_4Byte,
220       [kUpb_EncodedType_Bool] = kUpb_FieldRep_1Byte,
221       [kUpb_EncodedType_String] = kUpb_FieldRep_StringView,
222       [kUpb_EncodedType_Bytes] = kUpb_FieldRep_StringView,
223       [kUpb_EncodedType_UInt32] = kUpb_FieldRep_4Byte,
224       [kUpb_EncodedType_OpenEnum] = kUpb_FieldRep_4Byte,
225       [kUpb_EncodedType_SFixed32] = kUpb_FieldRep_4Byte,
226       [kUpb_EncodedType_SFixed64] = kUpb_FieldRep_8Byte,
227       [kUpb_EncodedType_SInt32] = kUpb_FieldRep_4Byte,
228       [kUpb_EncodedType_SInt64] = kUpb_FieldRep_8Byte,
229       [kUpb_EncodedType_ClosedEnum] = kUpb_FieldRep_4Byte,
230   };
231 
232   char pointer_rep = d->platform == kUpb_MiniTablePlatform_32Bit
233                          ? kUpb_FieldRep_4Byte
234                          : kUpb_FieldRep_8Byte;
235 
236   int8_t type = _upb_FromBase92(ch);
237   if (ch >= _upb_ToBase92(kUpb_EncodedType_RepeatedBase)) {
238     type -= kUpb_EncodedType_RepeatedBase;
239     field->mode = kUpb_FieldMode_Array;
240     field->mode |= pointer_rep << kUpb_FieldRep_Shift;
241     field->offset = kNoPresence;
242   } else {
243     field->mode = kUpb_FieldMode_Scalar;
244     field->offset = kHasbitPresence;
245     if (type == kUpb_EncodedType_Group || type == kUpb_EncodedType_Message) {
246       field->mode |= pointer_rep << kUpb_FieldRep_Shift;
247     } else if ((unsigned long)type >= sizeof(kUpb_EncodedToFieldRep)) {
248       upb_MtDecoder_ErrorFormat(d, "Invalid field type: %d", (int)type);
249       UPB_UNREACHABLE();
250     } else {
251       field->mode |= kUpb_EncodedToFieldRep[type] << kUpb_FieldRep_Shift;
252     }
253   }
254   if ((unsigned long)type >= sizeof(kUpb_EncodedToType)) {
255     upb_MtDecoder_ErrorFormat(d, "Invalid field type: %d", (int)type);
256     UPB_UNREACHABLE();
257   }
258   upb_MiniTable_SetTypeAndSub(field, kUpb_EncodedToType[type], sub_count,
259                               msg_modifiers, type == kUpb_EncodedType_OpenEnum);
260 }
261 
upb_MtDecoder_ModifyField(upb_MtDecoder * d,uint32_t message_modifiers,uint32_t field_modifiers,upb_MiniTableField * field)262 static void upb_MtDecoder_ModifyField(upb_MtDecoder* d,
263                                       uint32_t message_modifiers,
264                                       uint32_t field_modifiers,
265                                       upb_MiniTableField* field) {
266   if (field_modifiers & kUpb_EncodedFieldModifier_FlipPacked) {
267     if (!upb_MtDecoder_FieldIsPackable(field)) {
268       upb_MtDecoder_ErrorFormat(
269           d, "Cannot flip packed on unpackable field %" PRIu32, field->number);
270       UPB_UNREACHABLE();
271     }
272     field->mode ^= kUpb_LabelFlags_IsPacked;
273   }
274 
275   bool singular = field_modifiers & kUpb_EncodedFieldModifier_IsProto3Singular;
276   bool required = field_modifiers & kUpb_EncodedFieldModifier_IsRequired;
277 
278   // Validate.
279   if ((singular || required) && field->offset != kHasbitPresence) {
280     upb_MtDecoder_ErrorFormat(
281         d, "Invalid modifier(s) for repeated field %" PRIu32, field->number);
282     UPB_UNREACHABLE();
283   }
284   if (singular && required) {
285     upb_MtDecoder_ErrorFormat(
286         d, "Field %" PRIu32 " cannot be both singular and required",
287         field->number);
288     UPB_UNREACHABLE();
289   }
290 
291   if (singular) field->offset = kNoPresence;
292   if (required) {
293     field->offset = kRequiredPresence;
294   }
295 }
296 
upb_MtDecoder_PushItem(upb_MtDecoder * d,upb_LayoutItem item)297 static void upb_MtDecoder_PushItem(upb_MtDecoder* d, upb_LayoutItem item) {
298   if (d->vec.size == d->vec.capacity) {
299     size_t new_cap = UPB_MAX(8, d->vec.size * 2);
300     d->vec.data = realloc(d->vec.data, new_cap * sizeof(*d->vec.data));
301     upb_MtDecoder_CheckOutOfMemory(d, d->vec.data);
302     d->vec.capacity = new_cap;
303   }
304   d->vec.data[d->vec.size++] = item;
305 }
306 
upb_MtDecoder_PushOneof(upb_MtDecoder * d,upb_LayoutItem item)307 static void upb_MtDecoder_PushOneof(upb_MtDecoder* d, upb_LayoutItem item) {
308   if (item.field_index == kUpb_LayoutItem_IndexSentinel) {
309     upb_MtDecoder_ErrorFormat(d, "Empty oneof");
310     UPB_UNREACHABLE();
311   }
312   item.field_index -= kOneofBase;
313 
314   // Push oneof data.
315   item.type = kUpb_LayoutItemType_OneofField;
316   upb_MtDecoder_PushItem(d, item);
317 
318   // Push oneof case.
319   item.rep = kUpb_FieldRep_4Byte;  // Field Number.
320   item.type = kUpb_LayoutItemType_OneofCase;
321   upb_MtDecoder_PushItem(d, item);
322 }
323 
upb_MtDecoder_SizeOfRep(upb_FieldRep rep,upb_MiniTablePlatform platform)324 size_t upb_MtDecoder_SizeOfRep(upb_FieldRep rep,
325                                upb_MiniTablePlatform platform) {
326   static const uint8_t kRepToSize32[] = {
327       [kUpb_FieldRep_1Byte] = 1,
328       [kUpb_FieldRep_4Byte] = 4,
329       [kUpb_FieldRep_StringView] = 8,
330       [kUpb_FieldRep_8Byte] = 8,
331   };
332   static const uint8_t kRepToSize64[] = {
333       [kUpb_FieldRep_1Byte] = 1,
334       [kUpb_FieldRep_4Byte] = 4,
335       [kUpb_FieldRep_StringView] = 16,
336       [kUpb_FieldRep_8Byte] = 8,
337   };
338   UPB_ASSERT(sizeof(upb_StringView) ==
339              UPB_SIZE(kRepToSize32, kRepToSize64)[kUpb_FieldRep_StringView]);
340   return platform == kUpb_MiniTablePlatform_32Bit ? kRepToSize32[rep]
341                                                   : kRepToSize64[rep];
342 }
343 
upb_MtDecoder_AlignOfRep(upb_FieldRep rep,upb_MiniTablePlatform platform)344 size_t upb_MtDecoder_AlignOfRep(upb_FieldRep rep,
345                                 upb_MiniTablePlatform platform) {
346   static const uint8_t kRepToAlign32[] = {
347       [kUpb_FieldRep_1Byte] = 1,
348       [kUpb_FieldRep_4Byte] = 4,
349       [kUpb_FieldRep_StringView] = 4,
350       [kUpb_FieldRep_8Byte] = 8,
351   };
352   static const uint8_t kRepToAlign64[] = {
353       [kUpb_FieldRep_1Byte] = 1,
354       [kUpb_FieldRep_4Byte] = 4,
355       [kUpb_FieldRep_StringView] = 8,
356       [kUpb_FieldRep_8Byte] = 8,
357   };
358   UPB_ASSERT(UPB_ALIGN_OF(upb_StringView) ==
359              UPB_SIZE(kRepToAlign32, kRepToAlign64)[kUpb_FieldRep_StringView]);
360   return platform == kUpb_MiniTablePlatform_32Bit ? kRepToAlign32[rep]
361                                                   : kRepToAlign64[rep];
362 }
363 
upb_MtDecoder_DecodeOneofField(upb_MtDecoder * d,const char * ptr,char first_ch,upb_LayoutItem * item)364 static const char* upb_MtDecoder_DecodeOneofField(upb_MtDecoder* d,
365                                                   const char* ptr,
366                                                   char first_ch,
367                                                   upb_LayoutItem* item) {
368   uint32_t field_num;
369   ptr = upb_MiniTable_DecodeBase92Varint(
370       d, ptr, first_ch, kUpb_EncodedValue_MinOneofField,
371       kUpb_EncodedValue_MaxOneofField, &field_num);
372   upb_MiniTableField* f =
373       (void*)upb_MiniTable_FindFieldByNumber(d->table, field_num);
374 
375   if (!f) {
376     upb_MtDecoder_ErrorFormat(d,
377                               "Couldn't add field number %" PRIu32
378                               " to oneof, no such field number.",
379                               field_num);
380     UPB_UNREACHABLE();
381   }
382   if (f->offset != kHasbitPresence) {
383     upb_MtDecoder_ErrorFormat(
384         d,
385         "Cannot add repeated, required, or singular field %" PRIu32
386         " to oneof.",
387         field_num);
388     UPB_UNREACHABLE();
389   }
390 
391   // Oneof storage must be large enough to accommodate the largest member.
392   int rep = f->mode >> kUpb_FieldRep_Shift;
393   if (upb_MtDecoder_SizeOfRep(rep, d->platform) >
394       upb_MtDecoder_SizeOfRep(item->rep, d->platform)) {
395     item->rep = rep;
396   }
397   // Prepend this field to the linked list.
398   f->offset = item->field_index;
399   item->field_index = (f - d->fields) + kOneofBase;
400   return ptr;
401 }
402 
upb_MtDecoder_DecodeOneofs(upb_MtDecoder * d,const char * ptr)403 static const char* upb_MtDecoder_DecodeOneofs(upb_MtDecoder* d,
404                                               const char* ptr) {
405   upb_LayoutItem item = {.rep = 0,
406                          .field_index = kUpb_LayoutItem_IndexSentinel};
407   while (ptr < d->end) {
408     char ch = *ptr++;
409     if (ch == kUpb_EncodedValue_FieldSeparator) {
410       // Field separator, no action needed.
411     } else if (ch == kUpb_EncodedValue_OneofSeparator) {
412       // End of oneof.
413       upb_MtDecoder_PushOneof(d, item);
414       item.field_index = kUpb_LayoutItem_IndexSentinel;  // Move to next oneof.
415     } else {
416       ptr = upb_MtDecoder_DecodeOneofField(d, ptr, ch, &item);
417     }
418   }
419 
420   // Push final oneof.
421   upb_MtDecoder_PushOneof(d, item);
422   return ptr;
423 }
424 
upb_MtDecoder_ParseModifier(upb_MtDecoder * d,const char * ptr,char first_ch,upb_MiniTableField * last_field,uint64_t * msg_modifiers)425 static const char* upb_MtDecoder_ParseModifier(upb_MtDecoder* d,
426                                                const char* ptr, char first_ch,
427                                                upb_MiniTableField* last_field,
428                                                uint64_t* msg_modifiers) {
429   uint32_t mod;
430   ptr = upb_MiniTable_DecodeBase92Varint(d, ptr, first_ch,
431                                          kUpb_EncodedValue_MinModifier,
432                                          kUpb_EncodedValue_MaxModifier, &mod);
433   if (last_field) {
434     upb_MtDecoder_ModifyField(d, *msg_modifiers, mod, last_field);
435   } else {
436     if (!d->table) {
437       upb_MtDecoder_ErrorFormat(d, "Extensions cannot have message modifiers");
438       UPB_UNREACHABLE();
439     }
440     *msg_modifiers = mod;
441   }
442 
443   return ptr;
444 }
445 
upb_MtDecoder_AllocateSubs(upb_MtDecoder * d,uint32_t sub_count)446 static void upb_MtDecoder_AllocateSubs(upb_MtDecoder* d, uint32_t sub_count) {
447   size_t subs_bytes = sizeof(*d->table->subs) * sub_count;
448   void* subs = upb_Arena_Malloc(d->arena, subs_bytes);
449   memset(subs, 0, subs_bytes);
450   d->table->subs = subs;
451   upb_MtDecoder_CheckOutOfMemory(d, d->table->subs);
452 }
453 
upb_MtDecoder_Parse(upb_MtDecoder * d,const char * ptr,size_t len,void * fields,size_t field_size,uint16_t * field_count,uint32_t * sub_count)454 static const char* upb_MtDecoder_Parse(upb_MtDecoder* d, const char* ptr,
455                                        size_t len, void* fields,
456                                        size_t field_size, uint16_t* field_count,
457                                        uint32_t* sub_count) {
458   uint64_t msg_modifiers = 0;
459   uint32_t last_field_number = 0;
460   upb_MiniTableField* last_field = NULL;
461   bool need_dense_below = d->table != NULL;
462 
463   d->end = UPB_PTRADD(ptr, len);
464 
465   while (ptr < d->end) {
466     char ch = *ptr++;
467     if (ch <= kUpb_EncodedValue_MaxField) {
468       if (!d->table && last_field) {
469         // For extensions, consume only a single field and then return.
470         return --ptr;
471       }
472       upb_MiniTableField* field = fields;
473       *field_count += 1;
474       fields = (char*)fields + field_size;
475       field->number = ++last_field_number;
476       last_field = field;
477       upb_MiniTable_SetField(d, ch, field, msg_modifiers, sub_count);
478     } else if (kUpb_EncodedValue_MinModifier <= ch &&
479                ch <= kUpb_EncodedValue_MaxModifier) {
480       ptr = upb_MtDecoder_ParseModifier(d, ptr, ch, last_field, &msg_modifiers);
481       if (msg_modifiers & kUpb_MessageModifier_IsExtendable) {
482         d->table->ext |= kUpb_ExtMode_Extendable;
483       }
484     } else if (ch == kUpb_EncodedValue_End) {
485       if (!d->table) {
486         upb_MtDecoder_ErrorFormat(d, "Extensions cannot have oneofs.");
487         UPB_UNREACHABLE();
488       }
489       ptr = upb_MtDecoder_DecodeOneofs(d, ptr);
490     } else if (kUpb_EncodedValue_MinSkip <= ch &&
491                ch <= kUpb_EncodedValue_MaxSkip) {
492       if (need_dense_below) {
493         d->table->dense_below = d->table->field_count;
494         need_dense_below = false;
495       }
496       uint32_t skip;
497       ptr = upb_MiniTable_DecodeBase92Varint(d, ptr, ch,
498                                              kUpb_EncodedValue_MinSkip,
499                                              kUpb_EncodedValue_MaxSkip, &skip);
500       last_field_number += skip;
501       last_field_number--;  // Next field seen will increment.
502     } else {
503       upb_MtDecoder_ErrorFormat(d, "Invalid char: %c", ch);
504       UPB_UNREACHABLE();
505     }
506   }
507 
508   if (need_dense_below) {
509     d->table->dense_below = d->table->field_count;
510   }
511 
512   return ptr;
513 }
514 
upb_MtDecoder_ParseMessage(upb_MtDecoder * d,const char * data,size_t len)515 static void upb_MtDecoder_ParseMessage(upb_MtDecoder* d, const char* data,
516                                        size_t len) {
517   // Buffer length is an upper bound on the number of fields. We will return
518   // what we don't use.
519   d->fields = upb_Arena_Malloc(d->arena, sizeof(*d->fields) * len);
520   upb_MtDecoder_CheckOutOfMemory(d, d->fields);
521 
522   uint32_t sub_count = 0;
523   d->table->field_count = 0;
524   d->table->fields = d->fields;
525   upb_MtDecoder_Parse(d, data, len, d->fields, sizeof(*d->fields),
526                       &d->table->field_count, &sub_count);
527 
528   upb_Arena_ShrinkLast(d->arena, d->fields, sizeof(*d->fields) * len,
529                        sizeof(*d->fields) * d->table->field_count);
530   d->table->fields = d->fields;
531   upb_MtDecoder_AllocateSubs(d, sub_count);
532 }
533 
upb_MtDecoder_CompareFields(const void * _a,const void * _b)534 int upb_MtDecoder_CompareFields(const void* _a, const void* _b) {
535   const upb_LayoutItem* a = _a;
536   const upb_LayoutItem* b = _b;
537   // Currently we just sort by:
538   //  1. rep (smallest fields first)
539   //  2. type (oneof cases first)
540   //  2. field_index (smallest numbers first)
541   // The main goal of this is to reduce space lost to padding.
542   // Later we may have more subtle reasons to prefer a different ordering.
543   const int rep_bits = upb_Log2Ceiling(kUpb_FieldRep_Max);
544   const int type_bits = upb_Log2Ceiling(kUpb_LayoutItemType_Max);
545   const int idx_bits = (sizeof(a->field_index) * 8);
546   UPB_ASSERT(idx_bits + rep_bits + type_bits < 32);
547 #define UPB_COMBINE(rep, ty, idx) (((rep << type_bits) | ty) << idx_bits) | idx
548   uint32_t a_packed = UPB_COMBINE(a->rep, a->type, a->field_index);
549   uint32_t b_packed = UPB_COMBINE(b->rep, b->type, b->field_index);
550   assert(a_packed != b_packed);
551 #undef UPB_COMBINE
552   return a_packed < b_packed ? -1 : 1;
553 }
554 
upb_MtDecoder_SortLayoutItems(upb_MtDecoder * d)555 static bool upb_MtDecoder_SortLayoutItems(upb_MtDecoder* d) {
556   // Add items for all non-oneof fields (oneofs were already added).
557   int n = d->table->field_count;
558   for (int i = 0; i < n; i++) {
559     upb_MiniTableField* f = &d->fields[i];
560     if (f->offset >= kOneofBase) continue;
561     upb_LayoutItem item = {.field_index = i,
562                            .rep = f->mode >> kUpb_FieldRep_Shift,
563                            .type = kUpb_LayoutItemType_Field};
564     upb_MtDecoder_PushItem(d, item);
565   }
566 
567   if (d->vec.size) {
568     qsort(d->vec.data, d->vec.size, sizeof(*d->vec.data),
569           upb_MtDecoder_CompareFields);
570   }
571 
572   return true;
573 }
574 
upb_MiniTable_DivideRoundUp(size_t n,size_t d)575 static size_t upb_MiniTable_DivideRoundUp(size_t n, size_t d) {
576   return (n + d - 1) / d;
577 }
578 
upb_MtDecoder_AssignHasbits(upb_MiniTable * ret)579 static void upb_MtDecoder_AssignHasbits(upb_MiniTable* ret) {
580   int n = ret->field_count;
581   int last_hasbit = 0;  // 0 cannot be used.
582 
583   // First assign required fields, which must have the lowest hasbits.
584   for (int i = 0; i < n; i++) {
585     upb_MiniTableField* field = (upb_MiniTableField*)&ret->fields[i];
586     if (field->offset == kRequiredPresence) {
587       field->presence = ++last_hasbit;
588     } else if (field->offset == kNoPresence) {
589       field->presence = 0;
590     }
591   }
592   ret->required_count = last_hasbit;
593 
594   // Next assign non-required hasbit fields.
595   for (int i = 0; i < n; i++) {
596     upb_MiniTableField* field = (upb_MiniTableField*)&ret->fields[i];
597     if (field->offset == kHasbitPresence) {
598       field->presence = ++last_hasbit;
599     }
600   }
601 
602   ret->size = last_hasbit ? upb_MiniTable_DivideRoundUp(last_hasbit + 1, 8) : 0;
603 }
604 
upb_MtDecoder_Place(upb_MtDecoder * d,upb_FieldRep rep)605 size_t upb_MtDecoder_Place(upb_MtDecoder* d, upb_FieldRep rep) {
606   size_t size = upb_MtDecoder_SizeOfRep(rep, d->platform);
607   size_t align = upb_MtDecoder_AlignOfRep(rep, d->platform);
608   size_t ret = UPB_ALIGN_UP(d->table->size, align);
609   static const size_t max = UINT16_MAX;
610   size_t new_size = ret + size;
611   if (new_size > max) {
612     upb_MtDecoder_ErrorFormat(
613         d, "Message size exceeded maximum size of %zu bytes", max);
614   }
615   d->table->size = new_size;
616   return ret;
617 }
618 
upb_MtDecoder_AssignOffsets(upb_MtDecoder * d)619 static void upb_MtDecoder_AssignOffsets(upb_MtDecoder* d) {
620   upb_LayoutItem* end = UPB_PTRADD(d->vec.data, d->vec.size);
621 
622   // Compute offsets.
623   for (upb_LayoutItem* item = d->vec.data; item < end; item++) {
624     item->offset = upb_MtDecoder_Place(d, item->rep);
625   }
626 
627   // Assign oneof case offsets.  We must do these first, since assigning
628   // actual offsets will overwrite the links of the linked list.
629   for (upb_LayoutItem* item = d->vec.data; item < end; item++) {
630     if (item->type != kUpb_LayoutItemType_OneofCase) continue;
631     upb_MiniTableField* f = &d->fields[item->field_index];
632     while (true) {
633       f->presence = ~item->offset;
634       if (f->offset == kUpb_LayoutItem_IndexSentinel) break;
635       UPB_ASSERT(f->offset - kOneofBase < d->table->field_count);
636       f = &d->fields[f->offset - kOneofBase];
637     }
638   }
639 
640   // Assign offsets.
641   for (upb_LayoutItem* item = d->vec.data; item < end; item++) {
642     upb_MiniTableField* f = &d->fields[item->field_index];
643     switch (item->type) {
644       case kUpb_LayoutItemType_OneofField:
645         while (true) {
646           uint16_t next_offset = f->offset;
647           f->offset = item->offset;
648           if (next_offset == kUpb_LayoutItem_IndexSentinel) break;
649           f = &d->fields[next_offset - kOneofBase];
650         }
651         break;
652       case kUpb_LayoutItemType_Field:
653         f->offset = item->offset;
654         break;
655       default:
656         break;
657     }
658   }
659 
660   // The fasttable parser (supported on 64-bit only) depends on this being a
661   // multiple of 8 in order to satisfy UPB_MALLOC_ALIGN, which is also 8.
662   //
663   // On 32-bit we could potentially make this smaller, but there is no
664   // compelling reason to optimize this right now.
665   d->table->size = UPB_ALIGN_UP(d->table->size, 8);
666 }
667 
upb_MtDecoder_ValidateEntryField(upb_MtDecoder * d,const upb_MiniTableField * f,uint32_t expected_num)668 static void upb_MtDecoder_ValidateEntryField(upb_MtDecoder* d,
669                                              const upb_MiniTableField* f,
670                                              uint32_t expected_num) {
671   const char* name = expected_num == 1 ? "key" : "val";
672   if (f->number != expected_num) {
673     upb_MtDecoder_ErrorFormat(d,
674                               "map %s did not have expected number (%d vs %d)",
675                               name, expected_num, (int)f->number);
676   }
677 
678   if (upb_IsRepeatedOrMap(f)) {
679     upb_MtDecoder_ErrorFormat(
680         d, "map %s cannot be repeated or map, or be in oneof", name);
681   }
682 
683   uint32_t not_ok_types;
684   if (expected_num == 1) {
685     not_ok_types = (1 << kUpb_FieldType_Float) | (1 << kUpb_FieldType_Double) |
686                    (1 << kUpb_FieldType_Message) | (1 << kUpb_FieldType_Group) |
687                    (1 << kUpb_FieldType_Bytes) | (1 << kUpb_FieldType_Enum);
688   } else {
689     not_ok_types = 1 << kUpb_FieldType_Group;
690   }
691 
692   if ((1 << upb_MiniTableField_Type(f)) & not_ok_types) {
693     upb_MtDecoder_ErrorFormat(d, "map %s cannot have type %d", name,
694                               (int)f->UPB_PRIVATE(descriptortype));
695   }
696 }
697 
upb_MtDecoder_ParseMap(upb_MtDecoder * d,const char * data,size_t len)698 static void upb_MtDecoder_ParseMap(upb_MtDecoder* d, const char* data,
699                                    size_t len) {
700   upb_MtDecoder_ParseMessage(d, data, len);
701   upb_MtDecoder_AssignHasbits(d->table);
702 
703   if (UPB_UNLIKELY(d->table->field_count != 2)) {
704     upb_MtDecoder_ErrorFormat(d, "%hu fields in map", d->table->field_count);
705     UPB_UNREACHABLE();
706   }
707 
708   upb_LayoutItem* end = UPB_PTRADD(d->vec.data, d->vec.size);
709   for (upb_LayoutItem* item = d->vec.data; item < end; item++) {
710     if (item->type == kUpb_LayoutItemType_OneofCase) {
711       upb_MtDecoder_ErrorFormat(d, "Map entry cannot have oneof");
712     }
713   }
714 
715   upb_MtDecoder_ValidateEntryField(d, &d->table->fields[0], 1);
716   upb_MtDecoder_ValidateEntryField(d, &d->table->fields[1], 2);
717 
718   // Map entries have a pre-determined layout, regardless of types.
719   // NOTE: sync with mini_table/message_internal.h.
720   const size_t kv_size = d->platform == kUpb_MiniTablePlatform_32Bit ? 8 : 16;
721   const size_t hasbit_size = 8;
722   d->fields[0].offset = hasbit_size;
723   d->fields[1].offset = hasbit_size + kv_size;
724   d->table->size = UPB_ALIGN_UP(hasbit_size + kv_size + kv_size, 8);
725 
726   // Map entries have a special bit set to signal it's a map entry, used in
727   // upb_MiniTable_SetSubMessage() below.
728   d->table->ext |= kUpb_ExtMode_IsMapEntry;
729 }
730 
upb_MtDecoder_ParseMessageSet(upb_MtDecoder * d,const char * data,size_t len)731 static void upb_MtDecoder_ParseMessageSet(upb_MtDecoder* d, const char* data,
732                                           size_t len) {
733   if (len > 0) {
734     upb_MtDecoder_ErrorFormat(d, "Invalid message set encode length: %zu", len);
735     UPB_UNREACHABLE();
736   }
737 
738   upb_MiniTable* ret = d->table;
739   ret->size = 0;
740   ret->field_count = 0;
741   ret->ext = kUpb_ExtMode_IsMessageSet;
742   ret->dense_below = 0;
743   ret->table_mask = -1;
744   ret->required_count = 0;
745 }
746 
upb_MtDecoder_DoBuildMiniTableWithBuf(upb_MtDecoder * decoder,const char * data,size_t len,void ** buf,size_t * buf_size)747 static upb_MiniTable* upb_MtDecoder_DoBuildMiniTableWithBuf(
748     upb_MtDecoder* decoder, const char* data, size_t len, void** buf,
749     size_t* buf_size) {
750   upb_MtDecoder_CheckOutOfMemory(decoder, decoder->table);
751 
752   decoder->table->size = 0;
753   decoder->table->field_count = 0;
754   decoder->table->ext = kUpb_ExtMode_NonExtendable;
755   decoder->table->dense_below = 0;
756   decoder->table->table_mask = -1;
757   decoder->table->required_count = 0;
758 
759   // Strip off and verify the version tag.
760   if (!len--) goto done;
761   const char vers = *data++;
762 
763   switch (vers) {
764     case kUpb_EncodedVersion_MapV1:
765       upb_MtDecoder_ParseMap(decoder, data, len);
766       break;
767 
768     case kUpb_EncodedVersion_MessageV1:
769       upb_MtDecoder_ParseMessage(decoder, data, len);
770       upb_MtDecoder_AssignHasbits(decoder->table);
771       upb_MtDecoder_SortLayoutItems(decoder);
772       upb_MtDecoder_AssignOffsets(decoder);
773       break;
774 
775     case kUpb_EncodedVersion_MessageSetV1:
776       upb_MtDecoder_ParseMessageSet(decoder, data, len);
777       break;
778 
779     default:
780       upb_MtDecoder_ErrorFormat(decoder, "Invalid message version: %c", vers);
781       UPB_UNREACHABLE();
782   }
783 
784 done:
785   *buf = decoder->vec.data;
786   *buf_size = decoder->vec.capacity * sizeof(*decoder->vec.data);
787   return decoder->table;
788 }
789 
upb_MtDecoder_BuildMiniTableWithBuf(upb_MtDecoder * const decoder,const char * const data,const size_t len,void ** const buf,size_t * const buf_size)790 static upb_MiniTable* upb_MtDecoder_BuildMiniTableWithBuf(
791     upb_MtDecoder* const decoder, const char* const data, const size_t len,
792     void** const buf, size_t* const buf_size) {
793   if (UPB_SETJMP(decoder->err) != 0) {
794     *buf = decoder->vec.data;
795     *buf_size = decoder->vec.capacity * sizeof(*decoder->vec.data);
796     return NULL;
797   }
798 
799   return upb_MtDecoder_DoBuildMiniTableWithBuf(decoder, data, len, buf,
800                                                buf_size);
801 }
802 
upb_MiniTable_BuildWithBuf(const char * data,size_t len,upb_MiniTablePlatform platform,upb_Arena * arena,void ** buf,size_t * buf_size,upb_Status * status)803 upb_MiniTable* upb_MiniTable_BuildWithBuf(const char* data, size_t len,
804                                           upb_MiniTablePlatform platform,
805                                           upb_Arena* arena, void** buf,
806                                           size_t* buf_size,
807                                           upb_Status* status) {
808   upb_MtDecoder decoder = {
809       .platform = platform,
810       .vec =
811           {
812               .data = *buf,
813               .capacity = *buf_size / sizeof(*decoder.vec.data),
814               .size = 0,
815           },
816       .arena = arena,
817       .status = status,
818       .table = upb_Arena_Malloc(arena, sizeof(*decoder.table)),
819   };
820 
821   return upb_MtDecoder_BuildMiniTableWithBuf(&decoder, data, len, buf,
822                                              buf_size);
823 }
824 
upb_MiniTableEnum_Size(size_t count)825 static size_t upb_MiniTableEnum_Size(size_t count) {
826   return sizeof(upb_MiniTableEnum) + count * sizeof(uint32_t);
827 }
828 
_upb_MiniTable_AddEnumDataMember(upb_MtDecoder * d,uint32_t val)829 static upb_MiniTableEnum* _upb_MiniTable_AddEnumDataMember(upb_MtDecoder* d,
830                                                            uint32_t val) {
831   if (d->enum_data_count == d->enum_data_capacity) {
832     size_t old_sz = upb_MiniTableEnum_Size(d->enum_data_capacity);
833     d->enum_data_capacity = UPB_MAX(2, d->enum_data_capacity * 2);
834     size_t new_sz = upb_MiniTableEnum_Size(d->enum_data_capacity);
835     d->enum_table = upb_Arena_Realloc(d->arena, d->enum_table, old_sz, new_sz);
836     upb_MtDecoder_CheckOutOfMemory(d, d->enum_table);
837   }
838   d->enum_table->data[d->enum_data_count++] = val;
839   return d->enum_table;
840 }
841 
upb_MiniTableEnum_BuildValue(upb_MtDecoder * d,uint32_t val)842 static void upb_MiniTableEnum_BuildValue(upb_MtDecoder* d, uint32_t val) {
843   upb_MiniTableEnum* table = d->enum_table;
844   d->enum_value_count++;
845   if (table->value_count || (val > 512 && d->enum_value_count < val / 32)) {
846     if (table->value_count == 0) {
847       assert(d->enum_data_count == table->mask_limit / 32);
848     }
849     table = _upb_MiniTable_AddEnumDataMember(d, val);
850     table->value_count++;
851   } else {
852     uint32_t new_mask_limit = ((val / 32) + 1) * 32;
853     while (table->mask_limit < new_mask_limit) {
854       table = _upb_MiniTable_AddEnumDataMember(d, 0);
855       table->mask_limit += 32;
856     }
857     table->data[val / 32] |= 1ULL << (val % 32);
858   }
859 }
860 
upb_MtDecoder_DoBuildMiniTableEnum(upb_MtDecoder * decoder,const char * data,size_t len)861 static upb_MiniTableEnum* upb_MtDecoder_DoBuildMiniTableEnum(
862     upb_MtDecoder* decoder, const char* data, size_t len) {
863   // If the string is non-empty then it must begin with a version tag.
864   if (len) {
865     if (*data != kUpb_EncodedVersion_EnumV1) {
866       upb_MtDecoder_ErrorFormat(decoder, "Invalid enum version: %c", *data);
867       UPB_UNREACHABLE();
868     }
869     data++;
870     len--;
871   }
872 
873   upb_MtDecoder_CheckOutOfMemory(decoder, decoder->enum_table);
874 
875   // Guarantee at least 64 bits of mask without checking mask size.
876   decoder->enum_table->mask_limit = 64;
877   decoder->enum_table = _upb_MiniTable_AddEnumDataMember(decoder, 0);
878   decoder->enum_table = _upb_MiniTable_AddEnumDataMember(decoder, 0);
879 
880   decoder->enum_table->value_count = 0;
881 
882   const char* ptr = data;
883   uint32_t base = 0;
884 
885   while (ptr < decoder->end) {
886     char ch = *ptr++;
887     if (ch <= kUpb_EncodedValue_MaxEnumMask) {
888       uint32_t mask = _upb_FromBase92(ch);
889       for (int i = 0; i < 5; i++, base++, mask >>= 1) {
890         if (mask & 1) upb_MiniTableEnum_BuildValue(decoder, base);
891       }
892     } else if (kUpb_EncodedValue_MinSkip <= ch &&
893                ch <= kUpb_EncodedValue_MaxSkip) {
894       uint32_t skip;
895       ptr = upb_MiniTable_DecodeBase92Varint(decoder, ptr, ch,
896                                              kUpb_EncodedValue_MinSkip,
897                                              kUpb_EncodedValue_MaxSkip, &skip);
898       base += skip;
899     } else {
900       upb_MtDecoder_ErrorFormat(decoder, "Unexpected character: %c", ch);
901       return NULL;
902     }
903   }
904 
905   return decoder->enum_table;
906 }
907 
upb_MtDecoder_BuildMiniTableEnum(upb_MtDecoder * const decoder,const char * const data,size_t const len)908 static upb_MiniTableEnum* upb_MtDecoder_BuildMiniTableEnum(
909     upb_MtDecoder* const decoder, const char* const data, size_t const len) {
910   if (UPB_SETJMP(decoder->err) != 0) return NULL;
911   return upb_MtDecoder_DoBuildMiniTableEnum(decoder, data, len);
912 }
913 
upb_MiniTableEnum_Build(const char * data,size_t len,upb_Arena * arena,upb_Status * status)914 upb_MiniTableEnum* upb_MiniTableEnum_Build(const char* data, size_t len,
915                                            upb_Arena* arena,
916                                            upb_Status* status) {
917   upb_MtDecoder decoder = {
918       .enum_table = upb_Arena_Malloc(arena, upb_MiniTableEnum_Size(2)),
919       .enum_value_count = 0,
920       .enum_data_count = 0,
921       .enum_data_capacity = 1,
922       .status = status,
923       .end = UPB_PTRADD(data, len),
924       .arena = arena,
925   };
926 
927   return upb_MtDecoder_BuildMiniTableEnum(&decoder, data, len);
928 }
929 
upb_MtDecoder_DoBuildMiniTableExtension(upb_MtDecoder * decoder,const char * data,size_t len,upb_MiniTableExtension * ext,const upb_MiniTable * extendee,upb_MiniTableSub sub)930 static const char* upb_MtDecoder_DoBuildMiniTableExtension(
931     upb_MtDecoder* decoder, const char* data, size_t len,
932     upb_MiniTableExtension* ext, const upb_MiniTable* extendee,
933     upb_MiniTableSub sub) {
934   // If the string is non-empty then it must begin with a version tag.
935   if (len) {
936     if (*data != kUpb_EncodedVersion_ExtensionV1) {
937       upb_MtDecoder_ErrorFormat(decoder, "Invalid ext version: %c", *data);
938       UPB_UNREACHABLE();
939     }
940     data++;
941     len--;
942   }
943 
944   uint16_t count = 0;
945   const char* ret =
946       upb_MtDecoder_Parse(decoder, data, len, ext, sizeof(*ext), &count, NULL);
947   if (!ret || count != 1) return NULL;
948 
949   upb_MiniTableField* f = &ext->field;
950 
951   f->mode |= kUpb_LabelFlags_IsExtension;
952   f->offset = 0;
953   f->presence = 0;
954 
955   if (extendee->ext & kUpb_ExtMode_IsMessageSet) {
956     // Extensions of MessageSet must be messages.
957     if (!upb_IsSubMessage(f)) return NULL;
958 
959     // Extensions of MessageSet must be non-repeating.
960     if ((f->mode & kUpb_FieldMode_Mask) == kUpb_FieldMode_Array) return NULL;
961   }
962 
963   ext->extendee = extendee;
964   ext->sub = sub;
965 
966   return ret;
967 }
968 
upb_MtDecoder_BuildMiniTableExtension(upb_MtDecoder * const decoder,const char * const data,const size_t len,upb_MiniTableExtension * const ext,const upb_MiniTable * const extendee,const upb_MiniTableSub sub)969 static const char* upb_MtDecoder_BuildMiniTableExtension(
970     upb_MtDecoder* const decoder, const char* const data, const size_t len,
971     upb_MiniTableExtension* const ext, const upb_MiniTable* const extendee,
972     const upb_MiniTableSub sub) {
973   if (UPB_SETJMP(decoder->err) != 0) return NULL;
974   return upb_MtDecoder_DoBuildMiniTableExtension(decoder, data, len, ext,
975                                                  extendee, sub);
976 }
977 
_upb_MiniTableExtension_Init(const char * data,size_t len,upb_MiniTableExtension * ext,const upb_MiniTable * extendee,upb_MiniTableSub sub,upb_MiniTablePlatform platform,upb_Status * status)978 const char* _upb_MiniTableExtension_Init(const char* data, size_t len,
979                                          upb_MiniTableExtension* ext,
980                                          const upb_MiniTable* extendee,
981                                          upb_MiniTableSub sub,
982                                          upb_MiniTablePlatform platform,
983                                          upb_Status* status) {
984   upb_MtDecoder decoder = {
985       .arena = NULL,
986       .status = status,
987       .table = NULL,
988       .platform = platform,
989   };
990 
991   return upb_MtDecoder_BuildMiniTableExtension(&decoder, data, len, ext,
992                                                extendee, sub);
993 }
994 
_upb_MiniTableExtension_Build(const char * data,size_t len,const upb_MiniTable * extendee,upb_MiniTableSub sub,upb_MiniTablePlatform platform,upb_Arena * arena,upb_Status * status)995 upb_MiniTableExtension* _upb_MiniTableExtension_Build(
996     const char* data, size_t len, const upb_MiniTable* extendee,
997     upb_MiniTableSub sub, upb_MiniTablePlatform platform, upb_Arena* arena,
998     upb_Status* status) {
999   upb_MiniTableExtension* ext =
1000       upb_Arena_Malloc(arena, sizeof(upb_MiniTableExtension));
1001   if (UPB_UNLIKELY(!ext)) return NULL;
1002 
1003   const char* ptr = _upb_MiniTableExtension_Init(data, len, ext, extendee, sub,
1004                                                  platform, status);
1005   if (UPB_UNLIKELY(!ptr)) return NULL;
1006 
1007   return ext;
1008 }
1009 
_upb_MiniTable_Build(const char * data,size_t len,upb_MiniTablePlatform platform,upb_Arena * arena,upb_Status * status)1010 upb_MiniTable* _upb_MiniTable_Build(const char* data, size_t len,
1011                                     upb_MiniTablePlatform platform,
1012                                     upb_Arena* arena, upb_Status* status) {
1013   void* buf = NULL;
1014   size_t size = 0;
1015   upb_MiniTable* ret = upb_MiniTable_BuildWithBuf(data, len, platform, arena,
1016                                                   &buf, &size, status);
1017   free(buf);
1018   return ret;
1019 }
1020 
upb_MiniTable_SetSubMessage(upb_MiniTable * table,upb_MiniTableField * field,const upb_MiniTable * sub)1021 bool upb_MiniTable_SetSubMessage(upb_MiniTable* table,
1022                                  upb_MiniTableField* field,
1023                                  const upb_MiniTable* sub) {
1024   UPB_ASSERT((uintptr_t)table->fields <= (uintptr_t)field &&
1025              (uintptr_t)field <
1026                  (uintptr_t)(table->fields + table->field_count));
1027   UPB_ASSERT(sub);
1028 
1029   const bool sub_is_map = sub->ext & kUpb_ExtMode_IsMapEntry;
1030 
1031   switch (field->UPB_PRIVATE(descriptortype)) {
1032     case kUpb_FieldType_Message:
1033       if (sub_is_map) {
1034         const bool table_is_map = table->ext & kUpb_ExtMode_IsMapEntry;
1035         if (UPB_UNLIKELY(table_is_map)) return false;
1036 
1037         field->mode = (field->mode & ~kUpb_FieldMode_Mask) | kUpb_FieldMode_Map;
1038       }
1039       break;
1040 
1041     case kUpb_FieldType_Group:
1042       if (UPB_UNLIKELY(sub_is_map)) return false;
1043       break;
1044 
1045     default:
1046       return false;
1047   }
1048 
1049   upb_MiniTableSub* table_sub =
1050       (void*)&table->subs[field->UPB_PRIVATE(submsg_index)];
1051   table_sub->submsg = sub;
1052   return true;
1053 }
1054 
upb_MiniTable_SetSubEnum(upb_MiniTable * table,upb_MiniTableField * field,const upb_MiniTableEnum * sub)1055 bool upb_MiniTable_SetSubEnum(upb_MiniTable* table, upb_MiniTableField* field,
1056                               const upb_MiniTableEnum* sub) {
1057   UPB_ASSERT((uintptr_t)table->fields <= (uintptr_t)field &&
1058              (uintptr_t)field <
1059                  (uintptr_t)(table->fields + table->field_count));
1060   UPB_ASSERT(sub);
1061 
1062   upb_MiniTableSub* table_sub =
1063       (void*)&table->subs[field->UPB_PRIVATE(submsg_index)];
1064   table_sub->subenum = sub;
1065   return true;
1066 }
1067 
upb_MiniTable_GetSubList(const upb_MiniTable * mt,const upb_MiniTableField ** subs)1068 uint32_t upb_MiniTable_GetSubList(const upb_MiniTable* mt,
1069                                   const upb_MiniTableField** subs) {
1070   uint32_t msg_count = 0;
1071   uint32_t enum_count = 0;
1072 
1073   for (int i = 0; i < mt->field_count; i++) {
1074     const upb_MiniTableField* f = &mt->fields[i];
1075     if (upb_MiniTableField_CType(f) == kUpb_CType_Message) {
1076       *subs = f;
1077       ++subs;
1078       msg_count++;
1079     }
1080   }
1081 
1082   for (int i = 0; i < mt->field_count; i++) {
1083     const upb_MiniTableField* f = &mt->fields[i];
1084     if (upb_MiniTableField_CType(f) == kUpb_CType_Enum) {
1085       *subs = f;
1086       ++subs;
1087       enum_count++;
1088     }
1089   }
1090 
1091   return (msg_count << 16) | enum_count;
1092 }
1093 
1094 // The list of sub_tables and sub_enums must exactly match the number and order
1095 // of sub-message fields and sub-enum fields given by upb_MiniTable_GetSubList()
1096 // above.
upb_MiniTable_Link(upb_MiniTable * mt,const upb_MiniTable ** sub_tables,size_t sub_table_count,const upb_MiniTableEnum ** sub_enums,size_t sub_enum_count)1097 bool upb_MiniTable_Link(upb_MiniTable* mt, const upb_MiniTable** sub_tables,
1098                         size_t sub_table_count,
1099                         const upb_MiniTableEnum** sub_enums,
1100                         size_t sub_enum_count) {
1101   uint32_t msg_count = 0;
1102   uint32_t enum_count = 0;
1103 
1104   for (int i = 0; i < mt->field_count; i++) {
1105     upb_MiniTableField* f = (upb_MiniTableField*)&mt->fields[i];
1106     if (upb_MiniTableField_CType(f) == kUpb_CType_Message) {
1107       const upb_MiniTable* sub = sub_tables[msg_count++];
1108       if (msg_count > sub_table_count) return false;
1109       if (sub != NULL) {
1110         if (!upb_MiniTable_SetSubMessage(mt, f, sub)) return false;
1111       }
1112     }
1113   }
1114 
1115   for (int i = 0; i < mt->field_count; i++) {
1116     upb_MiniTableField* f = (upb_MiniTableField*)&mt->fields[i];
1117     if (upb_MiniTableField_CType(f) == kUpb_CType_Enum) {
1118       const upb_MiniTableEnum* sub = sub_enums[enum_count++];
1119       if (enum_count > sub_enum_count) return false;
1120       if (sub != NULL) {
1121         if (!upb_MiniTable_SetSubEnum(mt, f, sub)) return false;
1122       }
1123     }
1124   }
1125 
1126   return true;
1127 }
1128