This will make it easier to experiment with changes in the decoder. PiperOrigin-RevId: 543765363pull/13171/head
parent
07f6b578ee
commit
dbbc4a30f9
9 changed files with 625 additions and 377 deletions
@ -0,0 +1,150 @@ |
||||
/*
|
||||
* Copyright (c) 2009-2021, Google LLC |
||||
* All rights reserved. |
||||
* |
||||
* Redistribution and use in source and binary forms, with or without |
||||
* modification, are permitted provided that the following conditions are met: |
||||
* * Redistributions of source code must retain the above copyright |
||||
* notice, this list of conditions and the following disclaimer. |
||||
* * Redistributions in binary form must reproduce the above copyright |
||||
* notice, this list of conditions and the following disclaimer in the |
||||
* documentation and/or other materials provided with the distribution. |
||||
* * Neither the name of Google LLC nor the |
||||
* names of its contributors may be used to endorse or promote products |
||||
* derived from this software without specific prior written permission. |
||||
* |
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" |
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
||||
* ARE DISCLAIMED. IN NO EVENT SHALL Google LLC BE LIABLE FOR ANY DIRECT, |
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; |
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND |
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS |
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||||
*/ |
||||
|
||||
#include "upb/mini_descriptor/build_enum.h" |
||||
|
||||
#include "upb/mini_descriptor/internal/decoder.h" |
||||
#include "upb/mini_descriptor/internal/wire_constants.h" |
||||
#include "upb/mini_table/internal/enum.h" |
||||
|
||||
// Must be last.
|
||||
#include "upb/port/def.inc" |
||||
|
||||
typedef struct { |
||||
upb_MdDecoder base; |
||||
upb_Arena* arena; |
||||
upb_MiniTableEnum* enum_table; |
||||
uint32_t enum_value_count; |
||||
uint32_t enum_data_count; |
||||
uint32_t enum_data_capacity; |
||||
} upb_MdEnumDecoder; |
||||
|
||||
static size_t upb_MiniTableEnum_Size(size_t count) { |
||||
return sizeof(upb_MiniTableEnum) + count * sizeof(uint32_t); |
||||
} |
||||
|
||||
static upb_MiniTableEnum* _upb_MiniTable_AddEnumDataMember(upb_MdEnumDecoder* d, |
||||
uint32_t val) { |
||||
if (d->enum_data_count == d->enum_data_capacity) { |
||||
size_t old_sz = upb_MiniTableEnum_Size(d->enum_data_capacity); |
||||
d->enum_data_capacity = UPB_MAX(2, d->enum_data_capacity * 2); |
||||
size_t new_sz = upb_MiniTableEnum_Size(d->enum_data_capacity); |
||||
d->enum_table = upb_Arena_Realloc(d->arena, d->enum_table, old_sz, new_sz); |
||||
upb_MdDecoder_CheckOutOfMemory(&d->base, d->enum_table); |
||||
} |
||||
d->enum_table->data[d->enum_data_count++] = val; |
||||
return d->enum_table; |
||||
} |
||||
|
||||
static void upb_MiniTableEnum_BuildValue(upb_MdEnumDecoder* d, uint32_t val) { |
||||
upb_MiniTableEnum* table = d->enum_table; |
||||
d->enum_value_count++; |
||||
if (table->value_count || (val > 512 && d->enum_value_count < val / 32)) { |
||||
if (table->value_count == 0) { |
||||
assert(d->enum_data_count == table->mask_limit / 32); |
||||
} |
||||
table = _upb_MiniTable_AddEnumDataMember(d, val); |
||||
table->value_count++; |
||||
} else { |
||||
uint32_t new_mask_limit = ((val / 32) + 1) * 32; |
||||
while (table->mask_limit < new_mask_limit) { |
||||
table = _upb_MiniTable_AddEnumDataMember(d, 0); |
||||
table->mask_limit += 32; |
||||
} |
||||
table->data[val / 32] |= 1ULL << (val % 32); |
||||
} |
||||
} |
||||
|
||||
static upb_MiniTableEnum* upb_MtDecoder_DoBuildMiniTableEnum( |
||||
upb_MdEnumDecoder* d, const char* data, size_t len) { |
||||
// If the string is non-empty then it must begin with a version tag.
|
||||
if (len) { |
||||
if (*data != kUpb_EncodedVersion_EnumV1) { |
||||
upb_MdDecoder_ErrorJmp(&d->base, "Invalid enum version: %c", *data); |
||||
} |
||||
data++; |
||||
len--; |
||||
} |
||||
|
||||
upb_MdDecoder_CheckOutOfMemory(&d->base, d->enum_table); |
||||
|
||||
// Guarantee at least 64 bits of mask without checking mask size.
|
||||
d->enum_table->mask_limit = 64; |
||||
d->enum_table = _upb_MiniTable_AddEnumDataMember(d, 0); |
||||
d->enum_table = _upb_MiniTable_AddEnumDataMember(d, 0); |
||||
|
||||
d->enum_table->value_count = 0; |
||||
|
||||
const char* ptr = data; |
||||
uint32_t base = 0; |
||||
|
||||
while (ptr < d->base.end) { |
||||
char ch = *ptr++; |
||||
if (ch <= kUpb_EncodedValue_MaxEnumMask) { |
||||
uint32_t mask = _upb_FromBase92(ch); |
||||
for (int i = 0; i < 5; i++, base++, mask >>= 1) { |
||||
if (mask & 1) upb_MiniTableEnum_BuildValue(d, base); |
||||
} |
||||
} else if (kUpb_EncodedValue_MinSkip <= ch && |
||||
ch <= kUpb_EncodedValue_MaxSkip) { |
||||
uint32_t skip; |
||||
ptr = upb_MdDecoder_DecodeBase92Varint(&d->base, ptr, ch, |
||||
kUpb_EncodedValue_MinSkip, |
||||
kUpb_EncodedValue_MaxSkip, &skip); |
||||
base += skip; |
||||
} else { |
||||
upb_MdDecoder_ErrorJmp(&d->base, "Unexpected character: %c", ch); |
||||
} |
||||
} |
||||
|
||||
return d->enum_table; |
||||
} |
||||
|
||||
static upb_MiniTableEnum* upb_MtDecoder_BuildMiniTableEnum( |
||||
upb_MdEnumDecoder* const decoder, const char* const data, size_t const len) { |
||||
if (UPB_SETJMP(decoder->base.err) != 0) return NULL; |
||||
return upb_MtDecoder_DoBuildMiniTableEnum(decoder, data, len); |
||||
} |
||||
|
||||
upb_MiniTableEnum* upb_MiniDescriptor_BuildEnum(const char* data, size_t len, |
||||
upb_Arena* arena, |
||||
upb_Status* status) { |
||||
upb_MdEnumDecoder decoder = { |
||||
.base = |
||||
{ |
||||
.end = UPB_PTRADD(data, len), |
||||
.status = status, |
||||
}, |
||||
.arena = arena, |
||||
.enum_table = upb_Arena_Malloc(arena, upb_MiniTableEnum_Size(2)), |
||||
.enum_value_count = 0, |
||||
.enum_data_count = 0, |
||||
.enum_data_capacity = 1, |
||||
}; |
||||
|
||||
return upb_MtDecoder_BuildMiniTableEnum(&decoder, data, len); |
||||
} |
@ -0,0 +1,63 @@ |
||||
/*
|
||||
* Copyright (c) 2009-2022, Google LLC |
||||
* All rights reserved. |
||||
* |
||||
* Redistribution and use in source and binary forms, with or without |
||||
* modification, are permitted provided that the following conditions are met: |
||||
* * Redistributions of source code must retain the above copyright |
||||
* notice, this list of conditions and the following disclaimer. |
||||
* * Redistributions in binary form must reproduce the above copyright |
||||
* notice, this list of conditions and the following disclaimer in the |
||||
* documentation and/or other materials provided with the distribution. |
||||
* * Neither the name of Google LLC nor the |
||||
* names of its contributors may be used to endorse or promote products |
||||
* derived from this software without specific prior written permission. |
||||
* |
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" |
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
||||
* ARE DISCLAIMED. IN NO EVENT SHALL Google LLC BE LIABLE FOR ANY DIRECT, |
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; |
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND |
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS |
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||||
*/ |
||||
|
||||
#ifndef UPB_MINI_DESCRIPTOR_BUILD_ENUM_H_ |
||||
#define UPB_MINI_DESCRIPTOR_BUILD_ENUM_H_ |
||||
|
||||
#include "upb/base/status.h" |
||||
#include "upb/mem/arena.h" |
||||
#include "upb/mini_table/enum.h" |
||||
|
||||
// Must be last.
|
||||
#include "upb/port/def.inc" |
||||
|
||||
#ifdef __cplusplus |
||||
extern "C" { |
||||
#endif |
||||
|
||||
// Builds a upb_MiniTableEnum from an enum MiniDescriptor. The MiniDescriptor
|
||||
// must be for an enum, not a message.
|
||||
UPB_API upb_MiniTableEnum* upb_MiniDescriptor_BuildEnum(const char* data, |
||||
size_t len, |
||||
upb_Arena* arena, |
||||
upb_Status* status); |
||||
|
||||
// TODO(b/289057707): Deprecated name; update callers.
|
||||
UPB_API_INLINE upb_MiniTableEnum* upb_MiniTableEnum_Build(const char* data, |
||||
size_t len, |
||||
upb_Arena* arena, |
||||
upb_Status* status) { |
||||
return upb_MiniDescriptor_BuildEnum(data, len, arena, status); |
||||
} |
||||
|
||||
#ifdef __cplusplus |
||||
} /* extern "C" */ |
||||
#endif |
||||
|
||||
#include "upb/port/undef.inc" |
||||
|
||||
#endif // UPB_MINI_DESCRIPTOR_BUILD_ENUM_H_
|
@ -0,0 +1,73 @@ |
||||
/*
|
||||
* Copyright (c) 2009-2021, Google LLC |
||||
* All rights reserved. |
||||
* |
||||
* Redistribution and use in source and binary forms, with or without |
||||
* modification, are permitted provided that the following conditions are met: |
||||
* * Redistributions of source code must retain the above copyright |
||||
* notice, this list of conditions and the following disclaimer. |
||||
* * Redistributions in binary form must reproduce the above copyright |
||||
* notice, this list of conditions and the following disclaimer in the |
||||
* documentation and/or other materials provided with the distribution. |
||||
* * Neither the name of Google LLC nor the |
||||
* names of its contributors may be used to endorse or promote products |
||||
* derived from this software without specific prior written permission. |
||||
* |
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" |
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
||||
* ARE DISCLAIMED. IN NO EVENT SHALL Google LLC BE LIABLE FOR ANY DIRECT, |
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; |
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND |
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS |
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||||
*/ |
||||
|
||||
#ifndef UPB_MINI_DESCRIPTOR_INTERNAL_DECODER_H_ |
||||
#define UPB_MINI_DESCRIPTOR_INTERNAL_DECODER_H_ |
||||
|
||||
#include "upb/base/status.h" |
||||
#include "upb/mini_descriptor/internal/base92.h" |
||||
|
||||
// Must be last.
|
||||
#include "upb/port/def.inc" |
||||
|
||||
// upb_MdDecoder: used internally for decoding MiniDescriptors for messages,
|
||||
// extensions, and enums.
|
||||
typedef struct { |
||||
const char* end; |
||||
upb_Status* status; |
||||
jmp_buf err; |
||||
} upb_MdDecoder; |
||||
|
||||
UPB_PRINTF(2, 3) |
||||
UPB_NORETURN UPB_INLINE void upb_MdDecoder_ErrorJmp(upb_MdDecoder* d, |
||||
const char* fmt, ...) { |
||||
if (d->status) { |
||||
va_list argp; |
||||
upb_Status_SetErrorMessage(d->status, "Error building mini table: "); |
||||
va_start(argp, fmt); |
||||
upb_Status_VAppendErrorFormat(d->status, fmt, argp); |
||||
va_end(argp); |
||||
} |
||||
UPB_LONGJMP(d->err, 1); |
||||
} |
||||
|
||||
UPB_INLINE void upb_MdDecoder_CheckOutOfMemory(upb_MdDecoder* d, |
||||
const void* ptr) { |
||||
if (!ptr) upb_MdDecoder_ErrorJmp(d, "Out of memory"); |
||||
} |
||||
|
||||
UPB_INLINE const char* upb_MdDecoder_DecodeBase92Varint( |
||||
upb_MdDecoder* d, const char* ptr, char first_ch, uint8_t min, uint8_t max, |
||||
uint32_t* out_val) { |
||||
ptr = _upb_Base92_DecodeVarint(ptr, d->end, first_ch, min, max, out_val); |
||||
if (!ptr) upb_MdDecoder_ErrorJmp(d, "Overlong varint"); |
||||
return ptr; |
||||
} |
||||
|
||||
#include "upb/port/undef.inc" |
||||
|
||||
#endif // UPB_MINI_DESCRIPTOR_INTERNAL_DECODER_H_
|
@ -0,0 +1,142 @@ |
||||
/*
|
||||
* Copyright (c) 2009-2021, Google LLC |
||||
* All rights reserved. |
||||
* |
||||
* Redistribution and use in source and binary forms, with or without |
||||
* modification, are permitted provided that the following conditions are met: |
||||
* * Redistributions of source code must retain the above copyright |
||||
* notice, this list of conditions and the following disclaimer. |
||||
* * Redistributions in binary form must reproduce the above copyright |
||||
* notice, this list of conditions and the following disclaimer in the |
||||
* documentation and/or other materials provided with the distribution. |
||||
* * Neither the name of Google LLC nor the |
||||
* names of its contributors may be used to endorse or promote products |
||||
* derived from this software without specific prior written permission. |
||||
* |
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" |
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
||||
* ARE DISCLAIMED. IN NO EVENT SHALL Google LLC BE LIABLE FOR ANY DIRECT, |
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; |
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND |
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS |
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||||
*/ |
||||
|
||||
#include "upb/mini_descriptor/link.h" |
||||
|
||||
// Must be last.
|
||||
#include "upb/port/def.inc" |
||||
|
||||
bool upb_MiniTable_SetSubMessage(upb_MiniTable* table, |
||||
upb_MiniTableField* field, |
||||
const upb_MiniTable* sub) { |
||||
UPB_ASSERT((uintptr_t)table->fields <= (uintptr_t)field && |
||||
(uintptr_t)field < |
||||
(uintptr_t)(table->fields + table->field_count)); |
||||
UPB_ASSERT(sub); |
||||
|
||||
const bool sub_is_map = sub->ext & kUpb_ExtMode_IsMapEntry; |
||||
|
||||
switch (field->UPB_PRIVATE(descriptortype)) { |
||||
case kUpb_FieldType_Message: |
||||
if (sub_is_map) { |
||||
const bool table_is_map = table->ext & kUpb_ExtMode_IsMapEntry; |
||||
if (UPB_UNLIKELY(table_is_map)) return false; |
||||
|
||||
field->mode = (field->mode & ~kUpb_FieldMode_Mask) | kUpb_FieldMode_Map; |
||||
} |
||||
break; |
||||
|
||||
case kUpb_FieldType_Group: |
||||
if (UPB_UNLIKELY(sub_is_map)) return false; |
||||
break; |
||||
|
||||
default: |
||||
return false; |
||||
} |
||||
|
||||
upb_MiniTableSub* table_sub = |
||||
(void*)&table->subs[field->UPB_PRIVATE(submsg_index)]; |
||||
// TODO(haberman): Add this assert back once YouTube is updated to not call
|
||||
// this function repeatedly.
|
||||
// UPB_ASSERT(table_sub->submsg == &_kUpb_MiniTable_Empty);
|
||||
table_sub->submsg = sub; |
||||
return true; |
||||
} |
||||
|
||||
bool upb_MiniTable_SetSubEnum(upb_MiniTable* table, upb_MiniTableField* field, |
||||
const upb_MiniTableEnum* sub) { |
||||
UPB_ASSERT((uintptr_t)table->fields <= (uintptr_t)field && |
||||
(uintptr_t)field < |
||||
(uintptr_t)(table->fields + table->field_count)); |
||||
UPB_ASSERT(sub); |
||||
|
||||
upb_MiniTableSub* table_sub = |
||||
(void*)&table->subs[field->UPB_PRIVATE(submsg_index)]; |
||||
table_sub->subenum = sub; |
||||
return true; |
||||
} |
||||
|
||||
uint32_t upb_MiniTable_GetSubList(const upb_MiniTable* mt, |
||||
const upb_MiniTableField** subs) { |
||||
uint32_t msg_count = 0; |
||||
uint32_t enum_count = 0; |
||||
|
||||
for (int i = 0; i < mt->field_count; i++) { |
||||
const upb_MiniTableField* f = &mt->fields[i]; |
||||
if (upb_MiniTableField_CType(f) == kUpb_CType_Message) { |
||||
*subs = f; |
||||
++subs; |
||||
msg_count++; |
||||
} |
||||
} |
||||
|
||||
for (int i = 0; i < mt->field_count; i++) { |
||||
const upb_MiniTableField* f = &mt->fields[i]; |
||||
if (upb_MiniTableField_CType(f) == kUpb_CType_Enum) { |
||||
*subs = f; |
||||
++subs; |
||||
enum_count++; |
||||
} |
||||
} |
||||
|
||||
return (msg_count << 16) | enum_count; |
||||
} |
||||
|
||||
// The list of sub_tables and sub_enums must exactly match the number and order
|
||||
// of sub-message fields and sub-enum fields given by upb_MiniTable_GetSubList()
|
||||
// above.
|
||||
bool 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) { |
||||
uint32_t msg_count = 0; |
||||
uint32_t enum_count = 0; |
||||
|
||||
for (int i = 0; i < mt->field_count; i++) { |
||||
upb_MiniTableField* f = (upb_MiniTableField*)&mt->fields[i]; |
||||
if (upb_MiniTableField_CType(f) == kUpb_CType_Message) { |
||||
const upb_MiniTable* sub = sub_tables[msg_count++]; |
||||
if (msg_count > sub_table_count) return false; |
||||
if (sub != NULL) { |
||||
if (!upb_MiniTable_SetSubMessage(mt, f, sub)) return false; |
||||
} |
||||
} |
||||
} |
||||
|
||||
for (int i = 0; i < mt->field_count; i++) { |
||||
upb_MiniTableField* f = (upb_MiniTableField*)&mt->fields[i]; |
||||
if (upb_MiniTableField_CType(f) == kUpb_CType_Enum) { |
||||
const upb_MiniTableEnum* sub = sub_enums[enum_count++]; |
||||
if (enum_count > sub_enum_count) return false; |
||||
if (sub != NULL) { |
||||
if (!upb_MiniTable_SetSubEnum(mt, f, sub)) return false; |
||||
} |
||||
} |
||||
} |
||||
|
||||
return true; |
||||
} |
@ -0,0 +1,104 @@ |
||||
/*
|
||||
* Copyright (c) 2009-2022, Google LLC |
||||
* All rights reserved. |
||||
* |
||||
* Redistribution and use in source and binary forms, with or without |
||||
* modification, are permitted provided that the following conditions are met: |
||||
* * Redistributions of source code must retain the above copyright |
||||
* notice, this list of conditions and the following disclaimer. |
||||
* * Redistributions in binary form must reproduce the above copyright |
||||
* notice, this list of conditions and the following disclaimer in the |
||||
* documentation and/or other materials provided with the distribution. |
||||
* * Neither the name of Google LLC nor the |
||||
* names of its contributors may be used to endorse or promote products |
||||
* derived from this software without specific prior written permission. |
||||
* |
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" |
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
||||
* ARE DISCLAIMED. IN NO EVENT SHALL Google LLC BE LIABLE FOR ANY DIRECT, |
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; |
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND |
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS |
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||||
*/ |
||||
|
||||
// Functions for linking MiniTables together once they are built from a
|
||||
// MiniDescriptor.
|
||||
//
|
||||
// These functions have names like upb_MiniTable_Link() because they operate on
|
||||
// MiniTables. We put them here, rather than in the mini_table/ directory,
|
||||
// because they are only needed when building MiniTables from MiniDescriptors.
|
||||
// The interfaces in mini_table/ assume that MiniTables are immutable.
|
||||
|
||||
#ifndef UPB_MINI_DESCRIPTOR_LINK_H_ |
||||
#define UPB_MINI_DESCRIPTOR_LINK_H_ |
||||
|
||||
#include "upb/base/status.h" |
||||
#include "upb/mem/arena.h" |
||||
#include "upb/mini_table/extension.h" |
||||
#include "upb/mini_table/field.h" |
||||
#include "upb/mini_table/message.h" |
||||
#include "upb/mini_table/sub.h" |
||||
|
||||
// Must be last.
|
||||
#include "upb/port/def.inc" |
||||
|
||||
#ifdef __cplusplus |
||||
extern "C" { |
||||
#endif |
||||
|
||||
// Links a sub-message field to a MiniTable for that sub-message. If a
|
||||
// sub-message field is not linked, it will be treated as an unknown field
|
||||
// during parsing, and setting the field will not be allowed. It is possible
|
||||
// to link the message field later, at which point it will no longer be treated
|
||||
// as unknown. However there is no synchronization for this operation, which
|
||||
// means parallel mutation requires external synchronization.
|
||||
// Returns success/failure.
|
||||
UPB_API bool upb_MiniTable_SetSubMessage(upb_MiniTable* table, |
||||
upb_MiniTableField* field, |
||||
const upb_MiniTable* sub); |
||||
|
||||
// Links an enum field to a MiniTable for that enum.
|
||||
// All enum fields must be linked prior to parsing.
|
||||
// Returns success/failure.
|
||||
UPB_API bool upb_MiniTable_SetSubEnum(upb_MiniTable* table, |
||||
upb_MiniTableField* field, |
||||
const upb_MiniTableEnum* sub); |
||||
|
||||
// Returns a list of fields that require linking at runtime, to connect the
|
||||
// MiniTable to its sub-messages and sub-enums. The list of fields will be
|
||||
// written to the `subs` array, which must have been allocated by the caller
|
||||
// and must be large enough to hold a list of all fields in the message.
|
||||
//
|
||||
// The order of the fields returned by this function is significant: it matches
|
||||
// the order expected by upb_MiniTable_Link() below.
|
||||
//
|
||||
// The return value packs the sub-message count and sub-enum count into a single
|
||||
// integer like so:
|
||||
// return (msg_count << 16) | enum_count;
|
||||
UPB_API uint32_t upb_MiniTable_GetSubList(const upb_MiniTable* mt, |
||||
const upb_MiniTableField** subs); |
||||
|
||||
// Links a message to its sub-messages and sub-enums. The caller must pass
|
||||
// arrays of sub-tables and sub-enums, in the same length and order as is
|
||||
// returned by upb_MiniTable_GetSubList() above. However, individual elements
|
||||
// of the sub_tables may be NULL if those sub-messages were tree shaken.
|
||||
//
|
||||
// Returns false if either array is too short, or if any of the tables fails
|
||||
// to link.
|
||||
UPB_API bool 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); |
||||
|
||||
#ifdef __cplusplus |
||||
} /* extern "C" */ |
||||
#endif |
||||
|
||||
#include "upb/port/undef.inc" |
||||
|
||||
#endif // UPB_MINI_DESCRIPTOR_LINK_H_
|
Loading…
Reference in new issue