From 54573a45d28a58b4f010733397ffb1594de6f322 Mon Sep 17 00:00:00 2001 From: Protobuf Team Bot Date: Tue, 21 Nov 2023 14:47:34 +0000 Subject: [PATCH] Auto-generate files after cl/584309590 --- php/ext/google/protobuf/php-upb.c | 18 +- php/ext/google/protobuf/php-upb.h | 869 ++++++++++++++------------ ruby/ext/google/protobuf_c/ruby-upb.c | 18 +- ruby/ext/google/protobuf_c/ruby-upb.h | 869 ++++++++++++++------------ 4 files changed, 948 insertions(+), 826 deletions(-) diff --git a/php/ext/google/protobuf/php-upb.c b/php/ext/google/protobuf/php-upb.c index 7a7a804638..3009ffe575 100644 --- a/php/ext/google/protobuf/php-upb.c +++ b/php/ext/google/protobuf/php-upb.c @@ -5874,6 +5874,8 @@ void upb_Arena_DecRefFor(upb_Arena* arena, const void* owner) { } +#include + // Must be last. @@ -5894,12 +5896,10 @@ upb_MapInsertStatus upb_Message_InsertMapEntry(upb_Map* map, // hence assuming a zero default is valid. upb_MessageValue default_val; memset(&default_val, 0, sizeof(upb_MessageValue)); - upb_MessageValue map_entry_key; - upb_MessageValue map_entry_value; - _upb_Message_GetField(map_entry_message, map_entry_key_field, &default_val, - &map_entry_key); - _upb_Message_GetField(map_entry_message, map_entry_value_field, &default_val, - &map_entry_value); + upb_MessageValue map_entry_key = + upb_Message_GetField(map_entry_message, map_entry_key_field, default_val); + upb_MessageValue map_entry_value = upb_Message_GetField( + map_entry_message, map_entry_value_field, default_val); return upb_Map_Insert(map, map_entry_key, map_entry_value, arena); } @@ -11193,9 +11193,7 @@ const upb_FieldDef* upb_Message_WhichOneof(const upb_Message* msg, upb_MessageValue upb_Message_GetFieldByDef(const upb_Message* msg, const upb_FieldDef* f) { upb_MessageValue default_val = upb_FieldDef_Default(f); - upb_MessageValue ret; - _upb_Message_GetField(msg, upb_FieldDef_MiniTable(f), &default_val, &ret); - return ret; + return upb_Message_GetField(msg, upb_FieldDef_MiniTable(f), default_val); } upb_MutableMessageValue upb_Message_Mutable(upb_Message* msg, @@ -11239,7 +11237,7 @@ make: bool upb_Message_SetFieldByDef(upb_Message* msg, const upb_FieldDef* f, upb_MessageValue val, upb_Arena* a) { - return _upb_Message_SetField(msg, upb_FieldDef_MiniTable(f), &val, a); + return upb_Message_SetField(msg, upb_FieldDef_MiniTable(f), val, a); } void upb_Message_ClearFieldByDef(upb_Message* msg, const upb_FieldDef* f) { diff --git a/php/ext/google/protobuf/php-upb.h b/php/ext/google/protobuf/php-upb.h index 4d762828b2..2d29839fe9 100644 --- a/php/ext/google/protobuf/php-upb.h +++ b/php/ext/google/protobuf/php-upb.h @@ -373,6 +373,10 @@ void upb_Status_VAppendErrorFormat(upb_Status* status, const char* fmt, #ifndef UPB_MESSAGE_ACCESSORS_H_ #define UPB_MESSAGE_ACCESSORS_H_ +#include +#include +#include + #ifndef UPB_BASE_DESCRIPTOR_CONSTANTS_H_ #define UPB_BASE_DESCRIPTOR_CONSTANTS_H_ @@ -476,12 +480,55 @@ UPB_INLINE bool upb_FieldType_IsPackable(upb_FieldType field_type) { #endif /* UPB_BASE_DESCRIPTOR_CONSTANTS_H_ */ +#ifndef UPB_BASE_STRING_VIEW_H_ +#define UPB_BASE_STRING_VIEW_H_ -#ifndef UPB_MESSAGE_ARRAY_H_ -#define UPB_MESSAGE_ARRAY_H_ +#include + +// Must be last. + +#define UPB_STRINGVIEW_INIT(ptr, len) \ + { ptr, len } + +#define UPB_STRINGVIEW_FORMAT "%.*s" +#define UPB_STRINGVIEW_ARGS(view) (int)(view).size, (view).data + +// LINT.IfChange(struct_definition) +typedef struct { + const char* data; + size_t size; +} upb_StringView; +// LINT.ThenChange( +// GoogleInternalName0, +// //depot/google3/third_party/upb/bits/golang/accessor.go:map_go_string +// ) + +#ifdef __cplusplus +extern "C" { +#endif + +UPB_API_INLINE upb_StringView upb_StringView_FromDataAndSize(const char* data, + size_t size) { + upb_StringView ret; + ret.data = data; + ret.size = size; + return ret; +} + +UPB_INLINE upb_StringView upb_StringView_FromString(const char* data) { + return upb_StringView_FromDataAndSize(data, strlen(data)); +} + +UPB_INLINE bool upb_StringView_IsEqual(upb_StringView a, upb_StringView b) { + return a.size == b.size && memcmp(a.data, b.data, a.size) == 0; +} + +#ifdef __cplusplus +} /* extern "C" */ +#endif -#include +#endif /* UPB_BASE_STRING_VIEW_H_ */ /* upb_Arena is a specific allocator implementation that uses arena allocation. * The user provides an allocator that will be used to allocate the underlying @@ -676,6 +723,12 @@ UPB_API_INLINE upb_Arena* upb_Arena_New(void) { #endif /* UPB_MEM_ARENA_H_ */ +#ifndef UPB_MESSAGE_ARRAY_H_ +#define UPB_MESSAGE_ARRAY_H_ + +#include + + // Users should include array.h or map.h instead. // IWYU pragma: private, include "upb/message/array.h" @@ -684,55 +737,6 @@ UPB_API_INLINE upb_Arena* upb_Arena_New(void) { #include -#ifndef UPB_BASE_STRING_VIEW_H_ -#define UPB_BASE_STRING_VIEW_H_ - -#include - -// Must be last. - -#define UPB_STRINGVIEW_INIT(ptr, len) \ - { ptr, len } - -#define UPB_STRINGVIEW_FORMAT "%.*s" -#define UPB_STRINGVIEW_ARGS(view) (int)(view).size, (view).data - -// LINT.IfChange(struct_definition) -typedef struct { - const char* data; - size_t size; -} upb_StringView; -// LINT.ThenChange( -// GoogleInternalName0, -// //depot/google3/third_party/upb/bits/golang/accessor.go:map_go_string -// ) - -#ifdef __cplusplus -extern "C" { -#endif - -UPB_API_INLINE upb_StringView upb_StringView_FromDataAndSize(const char* data, - size_t size) { - upb_StringView ret; - ret.data = data; - ret.size = size; - return ret; -} - -UPB_INLINE upb_StringView upb_StringView_FromString(const char* data) { - return upb_StringView_FromDataAndSize(data, strlen(data)); -} - -UPB_INLINE bool upb_StringView_IsEqual(upb_StringView a, upb_StringView b) { - return a.size == b.size && memcmp(a.data, b.data, a.size) == 0; -} - -#ifdef __cplusplus -} /* extern "C" */ -#endif - - -#endif /* UPB_BASE_STRING_VIEW_H_ */ #ifndef UPB_MINI_TABLE_TYPES_H_ #define UPB_MINI_TABLE_TYPES_H_ @@ -2396,7 +2400,7 @@ _upb_MiniTable_ElementSizeLg2(const upb_MiniTableField* field) { // UPB_ASSUME(field->UPB_PRIVATE(descriptortype) == kUpb_FieldType_Bool); // UPB_ASSUME(!upb_MiniTableField_IsRepeatedOrMap(field)); // UPB_ASSUME(_upb_MiniTableField_GetRep(field) == kUpb_FieldRep_1Byte); -// _upb_Message_SetField(msg, field, &value, a); +// upb_Message_SetField(msg, field, &value, a); // } // // As a result, we can use these universal getters/setters for *all* message @@ -2451,15 +2455,31 @@ UPB_INLINE void _upb_Message_GetExtensionField( } } -UPB_INLINE void _upb_Message_GetField(const upb_Message* msg, - const upb_MiniTableField* field, - const void* default_val, void* val) { +// Gets a mutable Array, Map or Message field. +// NOTE: For repeated/map fields, the resulting upb_Array*/upb_Map* can +// be NULL if a upb_Array/upb_Map has not been allocated yet. Array/map +// fields do not have presence, so this is semantically identical to a +// pointer to an empty array/map, and must be treated the same for all +// semantic purposes. +// +// For message fields, the pointer is guaranteed to be NULL iff the field +// is unset (as message fields do have presence). +UPB_INLINE upb_MutableMessageValue _upb_Message_GetMutableField( + const upb_Message* msg, const upb_MiniTableField* field) { + UPB_ASSUME(upb_MiniTableField_IsRepeatedOrMap(field) || + upb_MiniTableField_IsSubMessage(field)); + + upb_MutableMessageValue default_val; + default_val.msg = NULL; + + upb_MutableMessageValue ret; if (upb_MiniTableField_IsExtension(field)) { _upb_Message_GetExtensionField(msg, (upb_MiniTableExtension*)field, - default_val, val); + &default_val, &ret); } else { - _upb_Message_GetNonExtensionField(msg, field, default_val, val); + _upb_Message_GetNonExtensionField(msg, field, &default_val, &ret); } + return ret; } UPB_INLINE void _upb_Message_SetNonExtensionField( @@ -2481,18 +2501,6 @@ UPB_INLINE bool _upb_Message_SetExtensionField( return true; } -UPB_INLINE bool _upb_Message_SetField(upb_Message* msg, - const upb_MiniTableField* field, - const void* val, upb_Arena* a) { - if (upb_MiniTableField_IsExtension(field)) { - const upb_MiniTableExtension* ext = (const upb_MiniTableExtension*)field; - return _upb_Message_SetExtensionField(msg, ext, val, a); - } else { - _upb_Message_SetNonExtensionField(msg, field, val); - return true; - } -} - UPB_INLINE void _upb_Message_ClearExtensionField( upb_Message* msg, const upb_MiniTableExtension* ext_l) { upb_Message_Internal* in = upb_Message_Getinternal(msg); @@ -2714,15 +2722,45 @@ UPB_API_INLINE uint32_t upb_Message_WhichOneofFieldNumber( return _upb_Message_GetOneofCase(message, oneof_field); } +// NOTE: The default_val is only used for fields that support presence. +// For repeated/map fields, the resulting upb_Array*/upb_Map* can be NULL if a +// upb_Array/upb_Map has not been allocated yet. Array/map fields do not have +// presence, so this is semantically identical to a pointer to an empty +// array/map, and must be treated the same for all semantic purposes. +UPB_INLINE upb_MessageValue +upb_Message_GetField(const upb_Message* msg, const upb_MiniTableField* field, + upb_MessageValue default_val) { + upb_MessageValue ret; + if (upb_MiniTableField_IsExtension(field)) { + _upb_Message_GetExtensionField(msg, (upb_MiniTableExtension*)field, + &default_val, &ret); + } else { + _upb_Message_GetNonExtensionField(msg, field, &default_val, &ret); + } + return ret; +} + +UPB_INLINE bool upb_Message_SetField(upb_Message* msg, + const upb_MiniTableField* field, + upb_MessageValue val, upb_Arena* a) { + if (upb_MiniTableField_IsExtension(field)) { + const upb_MiniTableExtension* ext = (const upb_MiniTableExtension*)field; + return _upb_Message_SetExtensionField(msg, ext, &val, a); + } else { + _upb_Message_SetNonExtensionField(msg, field, &val); + return true; + } +} + UPB_API_INLINE bool upb_Message_GetBool(const upb_Message* msg, const upb_MiniTableField* field, bool default_val) { UPB_ASSUME(upb_MiniTableField_CType(field) == kUpb_CType_Bool); UPB_ASSUME(_upb_MiniTableField_GetRep(field) == kUpb_FieldRep_1Byte); UPB_ASSUME(!upb_MiniTableField_IsRepeatedOrMap(field)); - bool ret; - _upb_Message_GetField(msg, field, &default_val, &ret); - return ret; + upb_MessageValue def; + def.bool_val = default_val; + return upb_Message_GetField(msg, field, def).bool_val; } UPB_API_INLINE bool upb_Message_SetBool(upb_Message* msg, @@ -2731,7 +2769,9 @@ UPB_API_INLINE bool upb_Message_SetBool(upb_Message* msg, UPB_ASSUME(upb_MiniTableField_CType(field) == kUpb_CType_Bool); UPB_ASSUME(_upb_MiniTableField_GetRep(field) == kUpb_FieldRep_1Byte); UPB_ASSUME(!upb_MiniTableField_IsRepeatedOrMap(field)); - return _upb_Message_SetField(msg, field, &value, a); + upb_MessageValue val; + val.bool_val = value; + return upb_Message_SetField(msg, field, val, a); } UPB_API_INLINE int32_t upb_Message_GetInt32(const upb_Message* msg, @@ -2741,9 +2781,10 @@ UPB_API_INLINE int32_t upb_Message_GetInt32(const upb_Message* msg, upb_MiniTableField_CType(field) == kUpb_CType_Enum); UPB_ASSUME(_upb_MiniTableField_GetRep(field) == kUpb_FieldRep_4Byte); UPB_ASSUME(!upb_MiniTableField_IsRepeatedOrMap(field)); - int32_t ret; - _upb_Message_GetField(msg, field, &default_val, &ret); - return ret; + + upb_MessageValue def; + def.int32_val = default_val; + return upb_Message_GetField(msg, field, def).int32_val; } UPB_API_INLINE bool upb_Message_SetInt32(upb_Message* msg, @@ -2753,7 +2794,9 @@ UPB_API_INLINE bool upb_Message_SetInt32(upb_Message* msg, upb_MiniTableField_CType(field) == kUpb_CType_Enum); UPB_ASSUME(_upb_MiniTableField_GetRep(field) == kUpb_FieldRep_4Byte); UPB_ASSUME(!upb_MiniTableField_IsRepeatedOrMap(field)); - return _upb_Message_SetField(msg, field, &value, a); + upb_MessageValue val; + val.int32_val = value; + return upb_Message_SetField(msg, field, val, a); } UPB_API_INLINE uint32_t upb_Message_GetUInt32(const upb_Message* msg, @@ -2762,9 +2805,10 @@ UPB_API_INLINE uint32_t upb_Message_GetUInt32(const upb_Message* msg, UPB_ASSUME(upb_MiniTableField_CType(field) == kUpb_CType_UInt32); UPB_ASSUME(_upb_MiniTableField_GetRep(field) == kUpb_FieldRep_4Byte); UPB_ASSUME(!upb_MiniTableField_IsRepeatedOrMap(field)); - uint32_t ret; - _upb_Message_GetField(msg, field, &default_val, &ret); - return ret; + + upb_MessageValue def; + def.uint32_val = default_val; + return upb_Message_GetField(msg, field, def).uint32_val; } UPB_API_INLINE bool upb_Message_SetUInt32(upb_Message* msg, @@ -2773,7 +2817,9 @@ UPB_API_INLINE bool upb_Message_SetUInt32(upb_Message* msg, UPB_ASSUME(upb_MiniTableField_CType(field) == kUpb_CType_UInt32); UPB_ASSUME(_upb_MiniTableField_GetRep(field) == kUpb_FieldRep_4Byte); UPB_ASSUME(!upb_MiniTableField_IsRepeatedOrMap(field)); - return _upb_Message_SetField(msg, field, &value, a); + upb_MessageValue val; + val.uint32_val = value; + return upb_Message_SetField(msg, field, val, a); } UPB_API_INLINE void upb_Message_SetClosedEnum( @@ -2789,13 +2835,14 @@ UPB_API_INLINE void upb_Message_SetClosedEnum( UPB_API_INLINE int64_t upb_Message_GetInt64(const upb_Message* msg, const upb_MiniTableField* field, - uint64_t default_val) { + int64_t default_val) { UPB_ASSUME(upb_MiniTableField_CType(field) == kUpb_CType_Int64); UPB_ASSUME(_upb_MiniTableField_GetRep(field) == kUpb_FieldRep_8Byte); UPB_ASSUME(!upb_MiniTableField_IsRepeatedOrMap(field)); - int64_t ret; - _upb_Message_GetField(msg, field, &default_val, &ret); - return ret; + + upb_MessageValue def; + def.int64_val = default_val; + return upb_Message_GetField(msg, field, def).int64_val; } UPB_API_INLINE bool upb_Message_SetInt64(upb_Message* msg, @@ -2804,7 +2851,9 @@ UPB_API_INLINE bool upb_Message_SetInt64(upb_Message* msg, UPB_ASSUME(upb_MiniTableField_CType(field) == kUpb_CType_Int64); UPB_ASSUME(_upb_MiniTableField_GetRep(field) == kUpb_FieldRep_8Byte); UPB_ASSUME(!upb_MiniTableField_IsRepeatedOrMap(field)); - return _upb_Message_SetField(msg, field, &value, a); + upb_MessageValue val; + val.int64_val = value; + return upb_Message_SetField(msg, field, val, a); } UPB_API_INLINE uint64_t upb_Message_GetUInt64(const upb_Message* msg, @@ -2813,9 +2862,10 @@ UPB_API_INLINE uint64_t upb_Message_GetUInt64(const upb_Message* msg, UPB_ASSUME(upb_MiniTableField_CType(field) == kUpb_CType_UInt64); UPB_ASSUME(_upb_MiniTableField_GetRep(field) == kUpb_FieldRep_8Byte); UPB_ASSUME(!upb_MiniTableField_IsRepeatedOrMap(field)); - uint64_t ret; - _upb_Message_GetField(msg, field, &default_val, &ret); - return ret; + + upb_MessageValue def; + def.uint64_val = default_val; + return upb_Message_GetField(msg, field, def).uint64_val; } UPB_API_INLINE bool upb_Message_SetUInt64(upb_Message* msg, @@ -2824,7 +2874,9 @@ UPB_API_INLINE bool upb_Message_SetUInt64(upb_Message* msg, UPB_ASSUME(upb_MiniTableField_CType(field) == kUpb_CType_UInt64); UPB_ASSUME(_upb_MiniTableField_GetRep(field) == kUpb_FieldRep_8Byte); UPB_ASSUME(!upb_MiniTableField_IsRepeatedOrMap(field)); - return _upb_Message_SetField(msg, field, &value, a); + upb_MessageValue val; + val.uint64_val = value; + return upb_Message_SetField(msg, field, val, a); } UPB_API_INLINE float upb_Message_GetFloat(const upb_Message* msg, @@ -2833,9 +2885,10 @@ UPB_API_INLINE float upb_Message_GetFloat(const upb_Message* msg, UPB_ASSUME(upb_MiniTableField_CType(field) == kUpb_CType_Float); UPB_ASSUME(_upb_MiniTableField_GetRep(field) == kUpb_FieldRep_4Byte); UPB_ASSUME(!upb_MiniTableField_IsRepeatedOrMap(field)); - float ret; - _upb_Message_GetField(msg, field, &default_val, &ret); - return ret; + + upb_MessageValue def; + def.float_val = default_val; + return upb_Message_GetField(msg, field, def).float_val; } UPB_API_INLINE bool upb_Message_SetFloat(upb_Message* msg, @@ -2844,7 +2897,9 @@ UPB_API_INLINE bool upb_Message_SetFloat(upb_Message* msg, UPB_ASSUME(upb_MiniTableField_CType(field) == kUpb_CType_Float); UPB_ASSUME(_upb_MiniTableField_GetRep(field) == kUpb_FieldRep_4Byte); UPB_ASSUME(!upb_MiniTableField_IsRepeatedOrMap(field)); - return _upb_Message_SetField(msg, field, &value, a); + upb_MessageValue val; + val.float_val = value; + return upb_Message_SetField(msg, field, val, a); } UPB_API_INLINE double upb_Message_GetDouble(const upb_Message* msg, @@ -2853,9 +2908,10 @@ UPB_API_INLINE double upb_Message_GetDouble(const upb_Message* msg, UPB_ASSUME(upb_MiniTableField_CType(field) == kUpb_CType_Double); UPB_ASSUME(_upb_MiniTableField_GetRep(field) == kUpb_FieldRep_8Byte); UPB_ASSUME(!upb_MiniTableField_IsRepeatedOrMap(field)); - double ret; - _upb_Message_GetField(msg, field, &default_val, &ret); - return ret; + + upb_MessageValue def; + def.double_val = default_val; + return upb_Message_GetField(msg, field, def).double_val; } UPB_API_INLINE bool upb_Message_SetDouble(upb_Message* msg, @@ -2864,19 +2920,22 @@ UPB_API_INLINE bool upb_Message_SetDouble(upb_Message* msg, UPB_ASSUME(upb_MiniTableField_CType(field) == kUpb_CType_Double); UPB_ASSUME(_upb_MiniTableField_GetRep(field) == kUpb_FieldRep_8Byte); UPB_ASSUME(!upb_MiniTableField_IsRepeatedOrMap(field)); - return _upb_Message_SetField(msg, field, &value, a); + upb_MessageValue val; + val.double_val = value; + return upb_Message_SetField(msg, field, val, a); } UPB_API_INLINE upb_StringView upb_Message_GetString(const upb_Message* msg, const upb_MiniTableField* field, - upb_StringView def_val) { + upb_StringView default_val) { UPB_ASSUME(upb_MiniTableField_CType(field) == kUpb_CType_String || upb_MiniTableField_CType(field) == kUpb_CType_Bytes); UPB_ASSUME(_upb_MiniTableField_GetRep(field) == kUpb_FieldRep_StringView); UPB_ASSUME(!upb_MiniTableField_IsRepeatedOrMap(field)); - upb_StringView ret; - _upb_Message_GetField(msg, field, &def_val, &ret); - return ret; + + upb_MessageValue def; + def.str_val = default_val; + return upb_Message_GetField(msg, field, def).str_val; } UPB_API_INLINE bool upb_Message_SetString(upb_Message* msg, @@ -2886,7 +2945,9 @@ UPB_API_INLINE bool upb_Message_SetString(upb_Message* msg, upb_MiniTableField_CType(field) == kUpb_CType_Bytes); UPB_ASSUME(_upb_MiniTableField_GetRep(field) == kUpb_FieldRep_StringView); UPB_ASSUME(!upb_MiniTableField_IsRepeatedOrMap(field)); - return _upb_Message_SetField(msg, field, &value, a); + upb_MessageValue val; + val.str_val = value; + return upb_Message_SetField(msg, field, val, a); } UPB_API_INLINE upb_TaggedMessagePtr upb_Message_GetTaggedMessagePtr( @@ -2972,7 +3033,9 @@ UPB_API_INLINE upb_Array* upb_Message_GetOrCreateMutableArray( array = _upb_Array_New(arena, 4, _upb_MiniTable_ElementSizeLg2(field)); // Check again due to: https://godbolt.org/z/7WfaoKG1r _upb_MiniTableField_CheckIsArray(field); - _upb_Message_SetField(msg, field, &array, arena); + upb_MessageValue val; + val.array_val = array; + upb_Message_SetField(msg, field, val, arena); } return array; } @@ -11954,14 +12017,9 @@ UPB_INLINE bool _upb_NonAtomic_CompareExchangeStrongP(void* addr, #endif // UPB_PORT_ATOMIC_H_ -#ifndef UPB_WIRE_READER_H_ -#define UPB_WIRE_READER_H_ - - -#ifndef UPB_WIRE_INTERNAL_SWAP_H_ -#define UPB_WIRE_INTERNAL_SWAP_H_ +#ifndef UPB_MESSAGE_COPY_H_ +#define UPB_MESSAGE_COPY_H_ -#include // Must be last. @@ -11969,316 +12027,73 @@ UPB_INLINE bool _upb_NonAtomic_CompareExchangeStrongP(void* addr, extern "C" { #endif -UPB_INLINE bool _upb_IsLittleEndian(void) { - int x = 1; - return *(char*)&x == 1; -} - -UPB_INLINE uint32_t _upb_BigEndian_Swap32(uint32_t val) { - if (_upb_IsLittleEndian()) return val; +// Deep clones a message using the provided target arena. +upb_Message* upb_Message_DeepClone(const upb_Message* message, + const upb_MiniTable* mini_table, + upb_Arena* arena); - return ((val & 0xff) << 24) | ((val & 0xff00) << 8) | - ((val & 0xff0000) >> 8) | ((val & 0xff000000) >> 24); -} +// Deep clones array contents. +upb_Array* upb_Array_DeepClone(const upb_Array* array, upb_CType value_type, + const upb_MiniTable* sub, upb_Arena* arena); -UPB_INLINE uint64_t _upb_BigEndian_Swap64(uint64_t val) { - if (_upb_IsLittleEndian()) return val; +// Deep clones map contents. +upb_Map* upb_Map_DeepClone(const upb_Map* map, upb_CType key_type, + upb_CType value_type, + const upb_MiniTable* map_entry_table, + upb_Arena* arena); - return ((uint64_t)_upb_BigEndian_Swap32((uint32_t)val) << 32) | - _upb_BigEndian_Swap32((uint32_t)(val >> 32)); -} +// Deep copies the message from src to dst. +bool upb_Message_DeepCopy(upb_Message* dst, const upb_Message* src, + const upb_MiniTable* mini_table, upb_Arena* arena); #ifdef __cplusplus } /* extern "C" */ #endif -#endif /* UPB_WIRE_INTERNAL_SWAP_H_ */ +#endif // UPB_MESSAGE_COPY_H_ -#ifndef UPB_WIRE_TYPES_H_ -#define UPB_WIRE_TYPES_H_ +// EVERYTHING BELOW THIS LINE IS INTERNAL - DO NOT USE ///////////////////////// -// A list of types as they are encoded on the wire. -typedef enum { - kUpb_WireType_Varint = 0, - kUpb_WireType_64Bit = 1, - kUpb_WireType_Delimited = 2, - kUpb_WireType_StartGroup = 3, - kUpb_WireType_EndGroup = 4, - kUpb_WireType_32Bit = 5 -} upb_WireType; +#ifndef UPB_COLLECTIONS_INTERNAL_MAP_SORTER_H_ +#define UPB_COLLECTIONS_INTERNAL_MAP_SORTER_H_ -#endif /* UPB_WIRE_TYPES_H_ */ +#include -// Must be last. -#ifdef __cplusplus -extern "C" { -#endif +#ifndef UPB_COLLECTIONS_INTERNAL_MAP_ENTRY_H_ +#define UPB_COLLECTIONS_INTERNAL_MAP_ENTRY_H_ -// The upb_WireReader interface is suitable for general-purpose parsing of -// protobuf binary wire format. It is designed to be used along with -// upb_EpsCopyInputStream for buffering, and all parsing routines in this file -// assume that at least kUpb_EpsCopyInputStream_SlopBytes worth of data is -// available to read without any bounds checks. -#define kUpb_WireReader_WireTypeMask 7 -#define kUpb_WireReader_WireTypeBits 3 +// Map entries aren't actually stored for map fields, they are only used during +// parsing. For parsing, it helps a lot if all map entry messages have the same +// layout. The layout code in mini_table/decode.c will ensure that all map +// entries have this layout. +// +// Note that users can and do create map entries directly, which will also use +// this layout. +// +// NOTE: sync with wire/decode.c. +typedef struct { + // We only need 2 hasbits max, but due to alignment we'll use 8 bytes here, + // and the uint64_t helps make this clear. + uint64_t hasbits; + union { + upb_StringView str; // For str/bytes. + upb_value val; // For all other types. + } k; + union { + upb_StringView str; // For str/bytes. + upb_value val; // For all other types. + } v; +} upb_MapEntryData; typedef struct { - const char* ptr; - uint64_t val; -} _upb_WireReader_ReadLongVarintRet; + upb_Message_Internal internal; + upb_MapEntryData data; +} upb_MapEntry; -_upb_WireReader_ReadLongVarintRet _upb_WireReader_ReadLongVarint( - const char* ptr, uint64_t val); - -static UPB_FORCEINLINE const char* _upb_WireReader_ReadVarint(const char* ptr, - uint64_t* val, - int maxlen, - uint64_t maxval) { - uint64_t byte = (uint8_t)*ptr; - if (UPB_LIKELY((byte & 0x80) == 0)) { - *val = (uint32_t)byte; - return ptr + 1; - } - const char* start = ptr; - _upb_WireReader_ReadLongVarintRet res = - _upb_WireReader_ReadLongVarint(ptr, byte); - if (!res.ptr || (maxlen < 10 && res.ptr - start > maxlen) || - res.val > maxval) { - return NULL; // Malformed. - } - *val = res.val; - return res.ptr; -} - -// Parses a tag into `tag`, and returns a pointer past the end of the tag, or -// NULL if there was an error in the tag data. -// -// REQUIRES: there must be at least 10 bytes of data available at `ptr`. -// Bounds checks must be performed before calling this function, preferably -// by calling upb_EpsCopyInputStream_IsDone(). -static UPB_FORCEINLINE const char* upb_WireReader_ReadTag(const char* ptr, - uint32_t* tag) { - uint64_t val; - ptr = _upb_WireReader_ReadVarint(ptr, &val, 5, UINT32_MAX); - if (!ptr) return NULL; - *tag = val; - return ptr; -} - -// Given a tag, returns the field number. -UPB_INLINE uint32_t upb_WireReader_GetFieldNumber(uint32_t tag) { - return tag >> kUpb_WireReader_WireTypeBits; -} - -// Given a tag, returns the wire type. -UPB_INLINE uint8_t upb_WireReader_GetWireType(uint32_t tag) { - return tag & kUpb_WireReader_WireTypeMask; -} - -UPB_INLINE const char* upb_WireReader_ReadVarint(const char* ptr, - uint64_t* val) { - return _upb_WireReader_ReadVarint(ptr, val, 10, UINT64_MAX); -} - -// Skips data for a varint, returning a pointer past the end of the varint, or -// NULL if there was an error in the varint data. -// -// REQUIRES: there must be at least 10 bytes of data available at `ptr`. -// Bounds checks must be performed before calling this function, preferably -// by calling upb_EpsCopyInputStream_IsDone(). -UPB_INLINE const char* upb_WireReader_SkipVarint(const char* ptr) { - uint64_t val; - return upb_WireReader_ReadVarint(ptr, &val); -} - -// Reads a varint indicating the size of a delimited field into `size`, or -// NULL if there was an error in the varint data. -// -// REQUIRES: there must be at least 10 bytes of data available at `ptr`. -// Bounds checks must be performed before calling this function, preferably -// by calling upb_EpsCopyInputStream_IsDone(). -UPB_INLINE const char* upb_WireReader_ReadSize(const char* ptr, int* size) { - uint64_t size64; - ptr = upb_WireReader_ReadVarint(ptr, &size64); - if (!ptr || size64 >= INT32_MAX) return NULL; - *size = size64; - return ptr; -} - -// Reads a fixed32 field, performing byte swapping if necessary. -// -// REQUIRES: there must be at least 4 bytes of data available at `ptr`. -// Bounds checks must be performed before calling this function, preferably -// by calling upb_EpsCopyInputStream_IsDone(). -UPB_INLINE const char* upb_WireReader_ReadFixed32(const char* ptr, void* val) { - uint32_t uval; - memcpy(&uval, ptr, 4); - uval = _upb_BigEndian_Swap32(uval); - memcpy(val, &uval, 4); - return ptr + 4; -} - -// Reads a fixed64 field, performing byte swapping if necessary. -// -// REQUIRES: there must be at least 4 bytes of data available at `ptr`. -// Bounds checks must be performed before calling this function, preferably -// by calling upb_EpsCopyInputStream_IsDone(). -UPB_INLINE const char* upb_WireReader_ReadFixed64(const char* ptr, void* val) { - uint64_t uval; - memcpy(&uval, ptr, 8); - uval = _upb_BigEndian_Swap64(uval); - memcpy(val, &uval, 8); - return ptr + 8; -} - -const char* _upb_WireReader_SkipGroup(const char* ptr, uint32_t tag, - int depth_limit, - upb_EpsCopyInputStream* stream); - -// Skips data for a group, returning a pointer past the end of the group, or -// NULL if there was an error parsing the group. The `tag` argument should be -// the start group tag that begins the group. The `depth_limit` argument -// indicates how many levels of recursion the group is allowed to have before -// reporting a parse error (this limit exists to protect against stack -// overflow). -// -// TODO: evaluate how the depth_limit should be specified. Do users need -// control over this? -UPB_INLINE const char* upb_WireReader_SkipGroup( - const char* ptr, uint32_t tag, upb_EpsCopyInputStream* stream) { - return _upb_WireReader_SkipGroup(ptr, tag, 100, stream); -} - -UPB_INLINE const char* _upb_WireReader_SkipValue( - const char* ptr, uint32_t tag, int depth_limit, - upb_EpsCopyInputStream* stream) { - switch (upb_WireReader_GetWireType(tag)) { - case kUpb_WireType_Varint: - return upb_WireReader_SkipVarint(ptr); - case kUpb_WireType_32Bit: - return ptr + 4; - case kUpb_WireType_64Bit: - return ptr + 8; - case kUpb_WireType_Delimited: { - int size; - ptr = upb_WireReader_ReadSize(ptr, &size); - if (!ptr) return NULL; - ptr += size; - return ptr; - } - case kUpb_WireType_StartGroup: - return _upb_WireReader_SkipGroup(ptr, tag, depth_limit, stream); - case kUpb_WireType_EndGroup: - return NULL; // Should be handled before now. - default: - return NULL; // Unknown wire type. - } -} - -// Skips data for a wire value of any type, returning a pointer past the end of -// the data, or NULL if there was an error parsing the group. The `tag` argument -// should be the tag that was just parsed. The `depth_limit` argument indicates -// how many levels of recursion a group is allowed to have before reporting a -// parse error (this limit exists to protect against stack overflow). -// -// REQUIRES: there must be at least 10 bytes of data available at `ptr`. -// Bounds checks must be performed before calling this function, preferably -// by calling upb_EpsCopyInputStream_IsDone(). -// -// TODO: evaluate how the depth_limit should be specified. Do users need -// control over this? -UPB_INLINE const char* upb_WireReader_SkipValue( - const char* ptr, uint32_t tag, upb_EpsCopyInputStream* stream) { - return _upb_WireReader_SkipValue(ptr, tag, 100, stream); -} - -#ifdef __cplusplus -} /* extern "C" */ -#endif - - -#endif // UPB_WIRE_READER_H_ - -#ifndef UPB_MESSAGE_COPY_H_ -#define UPB_MESSAGE_COPY_H_ - - -// Must be last. - -#ifdef __cplusplus -extern "C" { -#endif - -// Deep clones a message using the provided target arena. -upb_Message* upb_Message_DeepClone(const upb_Message* message, - const upb_MiniTable* mini_table, - upb_Arena* arena); - -// Deep clones array contents. -upb_Array* upb_Array_DeepClone(const upb_Array* array, upb_CType value_type, - const upb_MiniTable* sub, upb_Arena* arena); - -// Deep clones map contents. -upb_Map* upb_Map_DeepClone(const upb_Map* map, upb_CType key_type, - upb_CType value_type, - const upb_MiniTable* map_entry_table, - upb_Arena* arena); - -// Deep copies the message from src to dst. -bool upb_Message_DeepCopy(upb_Message* dst, const upb_Message* src, - const upb_MiniTable* mini_table, upb_Arena* arena); - -#ifdef __cplusplus -} /* extern "C" */ -#endif - - -#endif // UPB_MESSAGE_COPY_H_ - -// EVERYTHING BELOW THIS LINE IS INTERNAL - DO NOT USE ///////////////////////// - -#ifndef UPB_COLLECTIONS_INTERNAL_MAP_SORTER_H_ -#define UPB_COLLECTIONS_INTERNAL_MAP_SORTER_H_ - -#include - - -#ifndef UPB_COLLECTIONS_INTERNAL_MAP_ENTRY_H_ -#define UPB_COLLECTIONS_INTERNAL_MAP_ENTRY_H_ - - -// Map entries aren't actually stored for map fields, they are only used during -// parsing. For parsing, it helps a lot if all map entry messages have the same -// layout. The layout code in mini_table/decode.c will ensure that all map -// entries have this layout. -// -// Note that users can and do create map entries directly, which will also use -// this layout. -// -// NOTE: sync with wire/decode.c. -typedef struct { - // We only need 2 hasbits max, but due to alignment we'll use 8 bytes here, - // and the uint64_t helps make this clear. - uint64_t hasbits; - union { - upb_StringView str; // For str/bytes. - upb_value val; // For all other types. - } k; - union { - upb_StringView str; // For str/bytes. - upb_value val; // For all other types. - } v; -} upb_MapEntryData; - -typedef struct { - upb_Message_Internal internal; - upb_MapEntryData data; -} upb_MapEntry; - -#endif // UPB_COLLECTIONS_INTERNAL_MAP_ENTRY_H_ +#endif // UPB_COLLECTIONS_INTERNAL_MAP_ENTRY_H_ // Must be last. @@ -13364,6 +13179,254 @@ UPB_INLINE uint32_t _upb_FastDecoder_LoadTag(const char* ptr) { #endif /* UPB_WIRE_INTERNAL_DECODE_H_ */ +#ifndef UPB_WIRE_INTERNAL_SWAP_H_ +#define UPB_WIRE_INTERNAL_SWAP_H_ + +#include + +// Must be last. + +#ifdef __cplusplus +extern "C" { +#endif + +UPB_INLINE bool _upb_IsLittleEndian(void) { + int x = 1; + return *(char*)&x == 1; +} + +UPB_INLINE uint32_t _upb_BigEndian_Swap32(uint32_t val) { + if (_upb_IsLittleEndian()) return val; + + return ((val & 0xff) << 24) | ((val & 0xff00) << 8) | + ((val & 0xff0000) >> 8) | ((val & 0xff000000) >> 24); +} + +UPB_INLINE uint64_t _upb_BigEndian_Swap64(uint64_t val) { + if (_upb_IsLittleEndian()) return val; + + return ((uint64_t)_upb_BigEndian_Swap32((uint32_t)val) << 32) | + _upb_BigEndian_Swap32((uint32_t)(val >> 32)); +} + +#ifdef __cplusplus +} /* extern "C" */ +#endif + + +#endif /* UPB_WIRE_INTERNAL_SWAP_H_ */ + +#ifndef UPB_WIRE_READER_H_ +#define UPB_WIRE_READER_H_ + + +#ifndef UPB_WIRE_TYPES_H_ +#define UPB_WIRE_TYPES_H_ + +// A list of types as they are encoded on the wire. +typedef enum { + kUpb_WireType_Varint = 0, + kUpb_WireType_64Bit = 1, + kUpb_WireType_Delimited = 2, + kUpb_WireType_StartGroup = 3, + kUpb_WireType_EndGroup = 4, + kUpb_WireType_32Bit = 5 +} upb_WireType; + +#endif /* UPB_WIRE_TYPES_H_ */ + +// Must be last. + +#ifdef __cplusplus +extern "C" { +#endif + +// The upb_WireReader interface is suitable for general-purpose parsing of +// protobuf binary wire format. It is designed to be used along with +// upb_EpsCopyInputStream for buffering, and all parsing routines in this file +// assume that at least kUpb_EpsCopyInputStream_SlopBytes worth of data is +// available to read without any bounds checks. + +#define kUpb_WireReader_WireTypeMask 7 +#define kUpb_WireReader_WireTypeBits 3 + +typedef struct { + const char* ptr; + uint64_t val; +} _upb_WireReader_ReadLongVarintRet; + +_upb_WireReader_ReadLongVarintRet _upb_WireReader_ReadLongVarint( + const char* ptr, uint64_t val); + +static UPB_FORCEINLINE const char* _upb_WireReader_ReadVarint(const char* ptr, + uint64_t* val, + int maxlen, + uint64_t maxval) { + uint64_t byte = (uint8_t)*ptr; + if (UPB_LIKELY((byte & 0x80) == 0)) { + *val = (uint32_t)byte; + return ptr + 1; + } + const char* start = ptr; + _upb_WireReader_ReadLongVarintRet res = + _upb_WireReader_ReadLongVarint(ptr, byte); + if (!res.ptr || (maxlen < 10 && res.ptr - start > maxlen) || + res.val > maxval) { + return NULL; // Malformed. + } + *val = res.val; + return res.ptr; +} + +// Parses a tag into `tag`, and returns a pointer past the end of the tag, or +// NULL if there was an error in the tag data. +// +// REQUIRES: there must be at least 10 bytes of data available at `ptr`. +// Bounds checks must be performed before calling this function, preferably +// by calling upb_EpsCopyInputStream_IsDone(). +static UPB_FORCEINLINE const char* upb_WireReader_ReadTag(const char* ptr, + uint32_t* tag) { + uint64_t val; + ptr = _upb_WireReader_ReadVarint(ptr, &val, 5, UINT32_MAX); + if (!ptr) return NULL; + *tag = val; + return ptr; +} + +// Given a tag, returns the field number. +UPB_INLINE uint32_t upb_WireReader_GetFieldNumber(uint32_t tag) { + return tag >> kUpb_WireReader_WireTypeBits; +} + +// Given a tag, returns the wire type. +UPB_INLINE uint8_t upb_WireReader_GetWireType(uint32_t tag) { + return tag & kUpb_WireReader_WireTypeMask; +} + +UPB_INLINE const char* upb_WireReader_ReadVarint(const char* ptr, + uint64_t* val) { + return _upb_WireReader_ReadVarint(ptr, val, 10, UINT64_MAX); +} + +// Skips data for a varint, returning a pointer past the end of the varint, or +// NULL if there was an error in the varint data. +// +// REQUIRES: there must be at least 10 bytes of data available at `ptr`. +// Bounds checks must be performed before calling this function, preferably +// by calling upb_EpsCopyInputStream_IsDone(). +UPB_INLINE const char* upb_WireReader_SkipVarint(const char* ptr) { + uint64_t val; + return upb_WireReader_ReadVarint(ptr, &val); +} + +// Reads a varint indicating the size of a delimited field into `size`, or +// NULL if there was an error in the varint data. +// +// REQUIRES: there must be at least 10 bytes of data available at `ptr`. +// Bounds checks must be performed before calling this function, preferably +// by calling upb_EpsCopyInputStream_IsDone(). +UPB_INLINE const char* upb_WireReader_ReadSize(const char* ptr, int* size) { + uint64_t size64; + ptr = upb_WireReader_ReadVarint(ptr, &size64); + if (!ptr || size64 >= INT32_MAX) return NULL; + *size = size64; + return ptr; +} + +// Reads a fixed32 field, performing byte swapping if necessary. +// +// REQUIRES: there must be at least 4 bytes of data available at `ptr`. +// Bounds checks must be performed before calling this function, preferably +// by calling upb_EpsCopyInputStream_IsDone(). +UPB_INLINE const char* upb_WireReader_ReadFixed32(const char* ptr, void* val) { + uint32_t uval; + memcpy(&uval, ptr, 4); + uval = _upb_BigEndian_Swap32(uval); + memcpy(val, &uval, 4); + return ptr + 4; +} + +// Reads a fixed64 field, performing byte swapping if necessary. +// +// REQUIRES: there must be at least 4 bytes of data available at `ptr`. +// Bounds checks must be performed before calling this function, preferably +// by calling upb_EpsCopyInputStream_IsDone(). +UPB_INLINE const char* upb_WireReader_ReadFixed64(const char* ptr, void* val) { + uint64_t uval; + memcpy(&uval, ptr, 8); + uval = _upb_BigEndian_Swap64(uval); + memcpy(val, &uval, 8); + return ptr + 8; +} + +const char* _upb_WireReader_SkipGroup(const char* ptr, uint32_t tag, + int depth_limit, + upb_EpsCopyInputStream* stream); + +// Skips data for a group, returning a pointer past the end of the group, or +// NULL if there was an error parsing the group. The `tag` argument should be +// the start group tag that begins the group. The `depth_limit` argument +// indicates how many levels of recursion the group is allowed to have before +// reporting a parse error (this limit exists to protect against stack +// overflow). +// +// TODO: evaluate how the depth_limit should be specified. Do users need +// control over this? +UPB_INLINE const char* upb_WireReader_SkipGroup( + const char* ptr, uint32_t tag, upb_EpsCopyInputStream* stream) { + return _upb_WireReader_SkipGroup(ptr, tag, 100, stream); +} + +UPB_INLINE const char* _upb_WireReader_SkipValue( + const char* ptr, uint32_t tag, int depth_limit, + upb_EpsCopyInputStream* stream) { + switch (upb_WireReader_GetWireType(tag)) { + case kUpb_WireType_Varint: + return upb_WireReader_SkipVarint(ptr); + case kUpb_WireType_32Bit: + return ptr + 4; + case kUpb_WireType_64Bit: + return ptr + 8; + case kUpb_WireType_Delimited: { + int size; + ptr = upb_WireReader_ReadSize(ptr, &size); + if (!ptr) return NULL; + ptr += size; + return ptr; + } + case kUpb_WireType_StartGroup: + return _upb_WireReader_SkipGroup(ptr, tag, depth_limit, stream); + case kUpb_WireType_EndGroup: + return NULL; // Should be handled before now. + default: + return NULL; // Unknown wire type. + } +} + +// Skips data for a wire value of any type, returning a pointer past the end of +// the data, or NULL if there was an error parsing the group. The `tag` argument +// should be the tag that was just parsed. The `depth_limit` argument indicates +// how many levels of recursion a group is allowed to have before reporting a +// parse error (this limit exists to protect against stack overflow). +// +// REQUIRES: there must be at least 10 bytes of data available at `ptr`. +// Bounds checks must be performed before calling this function, preferably +// by calling upb_EpsCopyInputStream_IsDone(). +// +// TODO: evaluate how the depth_limit should be specified. Do users need +// control over this? +UPB_INLINE const char* upb_WireReader_SkipValue( + const char* ptr, uint32_t tag, upb_EpsCopyInputStream* stream) { + return _upb_WireReader_SkipValue(ptr, tag, 100, stream); +} + +#ifdef __cplusplus +} /* extern "C" */ +#endif + + +#endif // UPB_WIRE_READER_H_ + // This should #undef all macros #defined in def.inc #undef UPB_SIZE diff --git a/ruby/ext/google/protobuf_c/ruby-upb.c b/ruby/ext/google/protobuf_c/ruby-upb.c index bb52bcf6be..8e6e835f3b 100644 --- a/ruby/ext/google/protobuf_c/ruby-upb.c +++ b/ruby/ext/google/protobuf_c/ruby-upb.c @@ -5389,6 +5389,8 @@ void upb_Arena_DecRefFor(upb_Arena* arena, const void* owner) { } +#include + // Must be last. @@ -5409,12 +5411,10 @@ upb_MapInsertStatus upb_Message_InsertMapEntry(upb_Map* map, // hence assuming a zero default is valid. upb_MessageValue default_val; memset(&default_val, 0, sizeof(upb_MessageValue)); - upb_MessageValue map_entry_key; - upb_MessageValue map_entry_value; - _upb_Message_GetField(map_entry_message, map_entry_key_field, &default_val, - &map_entry_key); - _upb_Message_GetField(map_entry_message, map_entry_value_field, &default_val, - &map_entry_value); + upb_MessageValue map_entry_key = + upb_Message_GetField(map_entry_message, map_entry_key_field, default_val); + upb_MessageValue map_entry_value = upb_Message_GetField( + map_entry_message, map_entry_value_field, default_val); return upb_Map_Insert(map, map_entry_key, map_entry_value, arena); } @@ -10708,9 +10708,7 @@ const upb_FieldDef* upb_Message_WhichOneof(const upb_Message* msg, upb_MessageValue upb_Message_GetFieldByDef(const upb_Message* msg, const upb_FieldDef* f) { upb_MessageValue default_val = upb_FieldDef_Default(f); - upb_MessageValue ret; - _upb_Message_GetField(msg, upb_FieldDef_MiniTable(f), &default_val, &ret); - return ret; + return upb_Message_GetField(msg, upb_FieldDef_MiniTable(f), default_val); } upb_MutableMessageValue upb_Message_Mutable(upb_Message* msg, @@ -10754,7 +10752,7 @@ make: bool upb_Message_SetFieldByDef(upb_Message* msg, const upb_FieldDef* f, upb_MessageValue val, upb_Arena* a) { - return _upb_Message_SetField(msg, upb_FieldDef_MiniTable(f), &val, a); + return upb_Message_SetField(msg, upb_FieldDef_MiniTable(f), val, a); } void upb_Message_ClearFieldByDef(upb_Message* msg, const upb_FieldDef* f) { diff --git a/ruby/ext/google/protobuf_c/ruby-upb.h b/ruby/ext/google/protobuf_c/ruby-upb.h index 5714b9f6a1..c45ecb08ba 100755 --- a/ruby/ext/google/protobuf_c/ruby-upb.h +++ b/ruby/ext/google/protobuf_c/ruby-upb.h @@ -375,6 +375,10 @@ void upb_Status_VAppendErrorFormat(upb_Status* status, const char* fmt, #ifndef UPB_MESSAGE_ACCESSORS_H_ #define UPB_MESSAGE_ACCESSORS_H_ +#include +#include +#include + #ifndef UPB_BASE_DESCRIPTOR_CONSTANTS_H_ #define UPB_BASE_DESCRIPTOR_CONSTANTS_H_ @@ -478,12 +482,55 @@ UPB_INLINE bool upb_FieldType_IsPackable(upb_FieldType field_type) { #endif /* UPB_BASE_DESCRIPTOR_CONSTANTS_H_ */ +#ifndef UPB_BASE_STRING_VIEW_H_ +#define UPB_BASE_STRING_VIEW_H_ -#ifndef UPB_MESSAGE_ARRAY_H_ -#define UPB_MESSAGE_ARRAY_H_ +#include + +// Must be last. + +#define UPB_STRINGVIEW_INIT(ptr, len) \ + { ptr, len } + +#define UPB_STRINGVIEW_FORMAT "%.*s" +#define UPB_STRINGVIEW_ARGS(view) (int)(view).size, (view).data + +// LINT.IfChange(struct_definition) +typedef struct { + const char* data; + size_t size; +} upb_StringView; +// LINT.ThenChange( +// GoogleInternalName0, +// //depot/google3/third_party/upb/bits/golang/accessor.go:map_go_string +// ) + +#ifdef __cplusplus +extern "C" { +#endif + +UPB_API_INLINE upb_StringView upb_StringView_FromDataAndSize(const char* data, + size_t size) { + upb_StringView ret; + ret.data = data; + ret.size = size; + return ret; +} + +UPB_INLINE upb_StringView upb_StringView_FromString(const char* data) { + return upb_StringView_FromDataAndSize(data, strlen(data)); +} + +UPB_INLINE bool upb_StringView_IsEqual(upb_StringView a, upb_StringView b) { + return a.size == b.size && memcmp(a.data, b.data, a.size) == 0; +} + +#ifdef __cplusplus +} /* extern "C" */ +#endif -#include +#endif /* UPB_BASE_STRING_VIEW_H_ */ /* upb_Arena is a specific allocator implementation that uses arena allocation. * The user provides an allocator that will be used to allocate the underlying @@ -678,6 +725,12 @@ UPB_API_INLINE upb_Arena* upb_Arena_New(void) { #endif /* UPB_MEM_ARENA_H_ */ +#ifndef UPB_MESSAGE_ARRAY_H_ +#define UPB_MESSAGE_ARRAY_H_ + +#include + + // Users should include array.h or map.h instead. // IWYU pragma: private, include "upb/message/array.h" @@ -686,55 +739,6 @@ UPB_API_INLINE upb_Arena* upb_Arena_New(void) { #include -#ifndef UPB_BASE_STRING_VIEW_H_ -#define UPB_BASE_STRING_VIEW_H_ - -#include - -// Must be last. - -#define UPB_STRINGVIEW_INIT(ptr, len) \ - { ptr, len } - -#define UPB_STRINGVIEW_FORMAT "%.*s" -#define UPB_STRINGVIEW_ARGS(view) (int)(view).size, (view).data - -// LINT.IfChange(struct_definition) -typedef struct { - const char* data; - size_t size; -} upb_StringView; -// LINT.ThenChange( -// GoogleInternalName0, -// //depot/google3/third_party/upb/bits/golang/accessor.go:map_go_string -// ) - -#ifdef __cplusplus -extern "C" { -#endif - -UPB_API_INLINE upb_StringView upb_StringView_FromDataAndSize(const char* data, - size_t size) { - upb_StringView ret; - ret.data = data; - ret.size = size; - return ret; -} - -UPB_INLINE upb_StringView upb_StringView_FromString(const char* data) { - return upb_StringView_FromDataAndSize(data, strlen(data)); -} - -UPB_INLINE bool upb_StringView_IsEqual(upb_StringView a, upb_StringView b) { - return a.size == b.size && memcmp(a.data, b.data, a.size) == 0; -} - -#ifdef __cplusplus -} /* extern "C" */ -#endif - - -#endif /* UPB_BASE_STRING_VIEW_H_ */ #ifndef UPB_MINI_TABLE_TYPES_H_ #define UPB_MINI_TABLE_TYPES_H_ @@ -2398,7 +2402,7 @@ _upb_MiniTable_ElementSizeLg2(const upb_MiniTableField* field) { // UPB_ASSUME(field->UPB_PRIVATE(descriptortype) == kUpb_FieldType_Bool); // UPB_ASSUME(!upb_MiniTableField_IsRepeatedOrMap(field)); // UPB_ASSUME(_upb_MiniTableField_GetRep(field) == kUpb_FieldRep_1Byte); -// _upb_Message_SetField(msg, field, &value, a); +// upb_Message_SetField(msg, field, &value, a); // } // // As a result, we can use these universal getters/setters for *all* message @@ -2453,15 +2457,31 @@ UPB_INLINE void _upb_Message_GetExtensionField( } } -UPB_INLINE void _upb_Message_GetField(const upb_Message* msg, - const upb_MiniTableField* field, - const void* default_val, void* val) { +// Gets a mutable Array, Map or Message field. +// NOTE: For repeated/map fields, the resulting upb_Array*/upb_Map* can +// be NULL if a upb_Array/upb_Map has not been allocated yet. Array/map +// fields do not have presence, so this is semantically identical to a +// pointer to an empty array/map, and must be treated the same for all +// semantic purposes. +// +// For message fields, the pointer is guaranteed to be NULL iff the field +// is unset (as message fields do have presence). +UPB_INLINE upb_MutableMessageValue _upb_Message_GetMutableField( + const upb_Message* msg, const upb_MiniTableField* field) { + UPB_ASSUME(upb_MiniTableField_IsRepeatedOrMap(field) || + upb_MiniTableField_IsSubMessage(field)); + + upb_MutableMessageValue default_val; + default_val.msg = NULL; + + upb_MutableMessageValue ret; if (upb_MiniTableField_IsExtension(field)) { _upb_Message_GetExtensionField(msg, (upb_MiniTableExtension*)field, - default_val, val); + &default_val, &ret); } else { - _upb_Message_GetNonExtensionField(msg, field, default_val, val); + _upb_Message_GetNonExtensionField(msg, field, &default_val, &ret); } + return ret; } UPB_INLINE void _upb_Message_SetNonExtensionField( @@ -2483,18 +2503,6 @@ UPB_INLINE bool _upb_Message_SetExtensionField( return true; } -UPB_INLINE bool _upb_Message_SetField(upb_Message* msg, - const upb_MiniTableField* field, - const void* val, upb_Arena* a) { - if (upb_MiniTableField_IsExtension(field)) { - const upb_MiniTableExtension* ext = (const upb_MiniTableExtension*)field; - return _upb_Message_SetExtensionField(msg, ext, val, a); - } else { - _upb_Message_SetNonExtensionField(msg, field, val); - return true; - } -} - UPB_INLINE void _upb_Message_ClearExtensionField( upb_Message* msg, const upb_MiniTableExtension* ext_l) { upb_Message_Internal* in = upb_Message_Getinternal(msg); @@ -2716,15 +2724,45 @@ UPB_API_INLINE uint32_t upb_Message_WhichOneofFieldNumber( return _upb_Message_GetOneofCase(message, oneof_field); } +// NOTE: The default_val is only used for fields that support presence. +// For repeated/map fields, the resulting upb_Array*/upb_Map* can be NULL if a +// upb_Array/upb_Map has not been allocated yet. Array/map fields do not have +// presence, so this is semantically identical to a pointer to an empty +// array/map, and must be treated the same for all semantic purposes. +UPB_INLINE upb_MessageValue +upb_Message_GetField(const upb_Message* msg, const upb_MiniTableField* field, + upb_MessageValue default_val) { + upb_MessageValue ret; + if (upb_MiniTableField_IsExtension(field)) { + _upb_Message_GetExtensionField(msg, (upb_MiniTableExtension*)field, + &default_val, &ret); + } else { + _upb_Message_GetNonExtensionField(msg, field, &default_val, &ret); + } + return ret; +} + +UPB_INLINE bool upb_Message_SetField(upb_Message* msg, + const upb_MiniTableField* field, + upb_MessageValue val, upb_Arena* a) { + if (upb_MiniTableField_IsExtension(field)) { + const upb_MiniTableExtension* ext = (const upb_MiniTableExtension*)field; + return _upb_Message_SetExtensionField(msg, ext, &val, a); + } else { + _upb_Message_SetNonExtensionField(msg, field, &val); + return true; + } +} + UPB_API_INLINE bool upb_Message_GetBool(const upb_Message* msg, const upb_MiniTableField* field, bool default_val) { UPB_ASSUME(upb_MiniTableField_CType(field) == kUpb_CType_Bool); UPB_ASSUME(_upb_MiniTableField_GetRep(field) == kUpb_FieldRep_1Byte); UPB_ASSUME(!upb_MiniTableField_IsRepeatedOrMap(field)); - bool ret; - _upb_Message_GetField(msg, field, &default_val, &ret); - return ret; + upb_MessageValue def; + def.bool_val = default_val; + return upb_Message_GetField(msg, field, def).bool_val; } UPB_API_INLINE bool upb_Message_SetBool(upb_Message* msg, @@ -2733,7 +2771,9 @@ UPB_API_INLINE bool upb_Message_SetBool(upb_Message* msg, UPB_ASSUME(upb_MiniTableField_CType(field) == kUpb_CType_Bool); UPB_ASSUME(_upb_MiniTableField_GetRep(field) == kUpb_FieldRep_1Byte); UPB_ASSUME(!upb_MiniTableField_IsRepeatedOrMap(field)); - return _upb_Message_SetField(msg, field, &value, a); + upb_MessageValue val; + val.bool_val = value; + return upb_Message_SetField(msg, field, val, a); } UPB_API_INLINE int32_t upb_Message_GetInt32(const upb_Message* msg, @@ -2743,9 +2783,10 @@ UPB_API_INLINE int32_t upb_Message_GetInt32(const upb_Message* msg, upb_MiniTableField_CType(field) == kUpb_CType_Enum); UPB_ASSUME(_upb_MiniTableField_GetRep(field) == kUpb_FieldRep_4Byte); UPB_ASSUME(!upb_MiniTableField_IsRepeatedOrMap(field)); - int32_t ret; - _upb_Message_GetField(msg, field, &default_val, &ret); - return ret; + + upb_MessageValue def; + def.int32_val = default_val; + return upb_Message_GetField(msg, field, def).int32_val; } UPB_API_INLINE bool upb_Message_SetInt32(upb_Message* msg, @@ -2755,7 +2796,9 @@ UPB_API_INLINE bool upb_Message_SetInt32(upb_Message* msg, upb_MiniTableField_CType(field) == kUpb_CType_Enum); UPB_ASSUME(_upb_MiniTableField_GetRep(field) == kUpb_FieldRep_4Byte); UPB_ASSUME(!upb_MiniTableField_IsRepeatedOrMap(field)); - return _upb_Message_SetField(msg, field, &value, a); + upb_MessageValue val; + val.int32_val = value; + return upb_Message_SetField(msg, field, val, a); } UPB_API_INLINE uint32_t upb_Message_GetUInt32(const upb_Message* msg, @@ -2764,9 +2807,10 @@ UPB_API_INLINE uint32_t upb_Message_GetUInt32(const upb_Message* msg, UPB_ASSUME(upb_MiniTableField_CType(field) == kUpb_CType_UInt32); UPB_ASSUME(_upb_MiniTableField_GetRep(field) == kUpb_FieldRep_4Byte); UPB_ASSUME(!upb_MiniTableField_IsRepeatedOrMap(field)); - uint32_t ret; - _upb_Message_GetField(msg, field, &default_val, &ret); - return ret; + + upb_MessageValue def; + def.uint32_val = default_val; + return upb_Message_GetField(msg, field, def).uint32_val; } UPB_API_INLINE bool upb_Message_SetUInt32(upb_Message* msg, @@ -2775,7 +2819,9 @@ UPB_API_INLINE bool upb_Message_SetUInt32(upb_Message* msg, UPB_ASSUME(upb_MiniTableField_CType(field) == kUpb_CType_UInt32); UPB_ASSUME(_upb_MiniTableField_GetRep(field) == kUpb_FieldRep_4Byte); UPB_ASSUME(!upb_MiniTableField_IsRepeatedOrMap(field)); - return _upb_Message_SetField(msg, field, &value, a); + upb_MessageValue val; + val.uint32_val = value; + return upb_Message_SetField(msg, field, val, a); } UPB_API_INLINE void upb_Message_SetClosedEnum( @@ -2791,13 +2837,14 @@ UPB_API_INLINE void upb_Message_SetClosedEnum( UPB_API_INLINE int64_t upb_Message_GetInt64(const upb_Message* msg, const upb_MiniTableField* field, - uint64_t default_val) { + int64_t default_val) { UPB_ASSUME(upb_MiniTableField_CType(field) == kUpb_CType_Int64); UPB_ASSUME(_upb_MiniTableField_GetRep(field) == kUpb_FieldRep_8Byte); UPB_ASSUME(!upb_MiniTableField_IsRepeatedOrMap(field)); - int64_t ret; - _upb_Message_GetField(msg, field, &default_val, &ret); - return ret; + + upb_MessageValue def; + def.int64_val = default_val; + return upb_Message_GetField(msg, field, def).int64_val; } UPB_API_INLINE bool upb_Message_SetInt64(upb_Message* msg, @@ -2806,7 +2853,9 @@ UPB_API_INLINE bool upb_Message_SetInt64(upb_Message* msg, UPB_ASSUME(upb_MiniTableField_CType(field) == kUpb_CType_Int64); UPB_ASSUME(_upb_MiniTableField_GetRep(field) == kUpb_FieldRep_8Byte); UPB_ASSUME(!upb_MiniTableField_IsRepeatedOrMap(field)); - return _upb_Message_SetField(msg, field, &value, a); + upb_MessageValue val; + val.int64_val = value; + return upb_Message_SetField(msg, field, val, a); } UPB_API_INLINE uint64_t upb_Message_GetUInt64(const upb_Message* msg, @@ -2815,9 +2864,10 @@ UPB_API_INLINE uint64_t upb_Message_GetUInt64(const upb_Message* msg, UPB_ASSUME(upb_MiniTableField_CType(field) == kUpb_CType_UInt64); UPB_ASSUME(_upb_MiniTableField_GetRep(field) == kUpb_FieldRep_8Byte); UPB_ASSUME(!upb_MiniTableField_IsRepeatedOrMap(field)); - uint64_t ret; - _upb_Message_GetField(msg, field, &default_val, &ret); - return ret; + + upb_MessageValue def; + def.uint64_val = default_val; + return upb_Message_GetField(msg, field, def).uint64_val; } UPB_API_INLINE bool upb_Message_SetUInt64(upb_Message* msg, @@ -2826,7 +2876,9 @@ UPB_API_INLINE bool upb_Message_SetUInt64(upb_Message* msg, UPB_ASSUME(upb_MiniTableField_CType(field) == kUpb_CType_UInt64); UPB_ASSUME(_upb_MiniTableField_GetRep(field) == kUpb_FieldRep_8Byte); UPB_ASSUME(!upb_MiniTableField_IsRepeatedOrMap(field)); - return _upb_Message_SetField(msg, field, &value, a); + upb_MessageValue val; + val.uint64_val = value; + return upb_Message_SetField(msg, field, val, a); } UPB_API_INLINE float upb_Message_GetFloat(const upb_Message* msg, @@ -2835,9 +2887,10 @@ UPB_API_INLINE float upb_Message_GetFloat(const upb_Message* msg, UPB_ASSUME(upb_MiniTableField_CType(field) == kUpb_CType_Float); UPB_ASSUME(_upb_MiniTableField_GetRep(field) == kUpb_FieldRep_4Byte); UPB_ASSUME(!upb_MiniTableField_IsRepeatedOrMap(field)); - float ret; - _upb_Message_GetField(msg, field, &default_val, &ret); - return ret; + + upb_MessageValue def; + def.float_val = default_val; + return upb_Message_GetField(msg, field, def).float_val; } UPB_API_INLINE bool upb_Message_SetFloat(upb_Message* msg, @@ -2846,7 +2899,9 @@ UPB_API_INLINE bool upb_Message_SetFloat(upb_Message* msg, UPB_ASSUME(upb_MiniTableField_CType(field) == kUpb_CType_Float); UPB_ASSUME(_upb_MiniTableField_GetRep(field) == kUpb_FieldRep_4Byte); UPB_ASSUME(!upb_MiniTableField_IsRepeatedOrMap(field)); - return _upb_Message_SetField(msg, field, &value, a); + upb_MessageValue val; + val.float_val = value; + return upb_Message_SetField(msg, field, val, a); } UPB_API_INLINE double upb_Message_GetDouble(const upb_Message* msg, @@ -2855,9 +2910,10 @@ UPB_API_INLINE double upb_Message_GetDouble(const upb_Message* msg, UPB_ASSUME(upb_MiniTableField_CType(field) == kUpb_CType_Double); UPB_ASSUME(_upb_MiniTableField_GetRep(field) == kUpb_FieldRep_8Byte); UPB_ASSUME(!upb_MiniTableField_IsRepeatedOrMap(field)); - double ret; - _upb_Message_GetField(msg, field, &default_val, &ret); - return ret; + + upb_MessageValue def; + def.double_val = default_val; + return upb_Message_GetField(msg, field, def).double_val; } UPB_API_INLINE bool upb_Message_SetDouble(upb_Message* msg, @@ -2866,19 +2922,22 @@ UPB_API_INLINE bool upb_Message_SetDouble(upb_Message* msg, UPB_ASSUME(upb_MiniTableField_CType(field) == kUpb_CType_Double); UPB_ASSUME(_upb_MiniTableField_GetRep(field) == kUpb_FieldRep_8Byte); UPB_ASSUME(!upb_MiniTableField_IsRepeatedOrMap(field)); - return _upb_Message_SetField(msg, field, &value, a); + upb_MessageValue val; + val.double_val = value; + return upb_Message_SetField(msg, field, val, a); } UPB_API_INLINE upb_StringView upb_Message_GetString(const upb_Message* msg, const upb_MiniTableField* field, - upb_StringView def_val) { + upb_StringView default_val) { UPB_ASSUME(upb_MiniTableField_CType(field) == kUpb_CType_String || upb_MiniTableField_CType(field) == kUpb_CType_Bytes); UPB_ASSUME(_upb_MiniTableField_GetRep(field) == kUpb_FieldRep_StringView); UPB_ASSUME(!upb_MiniTableField_IsRepeatedOrMap(field)); - upb_StringView ret; - _upb_Message_GetField(msg, field, &def_val, &ret); - return ret; + + upb_MessageValue def; + def.str_val = default_val; + return upb_Message_GetField(msg, field, def).str_val; } UPB_API_INLINE bool upb_Message_SetString(upb_Message* msg, @@ -2888,7 +2947,9 @@ UPB_API_INLINE bool upb_Message_SetString(upb_Message* msg, upb_MiniTableField_CType(field) == kUpb_CType_Bytes); UPB_ASSUME(_upb_MiniTableField_GetRep(field) == kUpb_FieldRep_StringView); UPB_ASSUME(!upb_MiniTableField_IsRepeatedOrMap(field)); - return _upb_Message_SetField(msg, field, &value, a); + upb_MessageValue val; + val.str_val = value; + return upb_Message_SetField(msg, field, val, a); } UPB_API_INLINE upb_TaggedMessagePtr upb_Message_GetTaggedMessagePtr( @@ -2974,7 +3035,9 @@ UPB_API_INLINE upb_Array* upb_Message_GetOrCreateMutableArray( array = _upb_Array_New(arena, 4, _upb_MiniTable_ElementSizeLg2(field)); // Check again due to: https://godbolt.org/z/7WfaoKG1r _upb_MiniTableField_CheckIsArray(field); - _upb_Message_SetField(msg, field, &array, arena); + upb_MessageValue val; + val.array_val = array; + upb_Message_SetField(msg, field, val, arena); } return array; } @@ -11726,14 +11789,9 @@ UPB_INLINE bool _upb_NonAtomic_CompareExchangeStrongP(void* addr, #endif // UPB_PORT_ATOMIC_H_ -#ifndef UPB_WIRE_READER_H_ -#define UPB_WIRE_READER_H_ - - -#ifndef UPB_WIRE_INTERNAL_SWAP_H_ -#define UPB_WIRE_INTERNAL_SWAP_H_ +#ifndef UPB_MESSAGE_COPY_H_ +#define UPB_MESSAGE_COPY_H_ -#include // Must be last. @@ -11741,316 +11799,73 @@ UPB_INLINE bool _upb_NonAtomic_CompareExchangeStrongP(void* addr, extern "C" { #endif -UPB_INLINE bool _upb_IsLittleEndian(void) { - int x = 1; - return *(char*)&x == 1; -} - -UPB_INLINE uint32_t _upb_BigEndian_Swap32(uint32_t val) { - if (_upb_IsLittleEndian()) return val; +// Deep clones a message using the provided target arena. +upb_Message* upb_Message_DeepClone(const upb_Message* message, + const upb_MiniTable* mini_table, + upb_Arena* arena); - return ((val & 0xff) << 24) | ((val & 0xff00) << 8) | - ((val & 0xff0000) >> 8) | ((val & 0xff000000) >> 24); -} +// Deep clones array contents. +upb_Array* upb_Array_DeepClone(const upb_Array* array, upb_CType value_type, + const upb_MiniTable* sub, upb_Arena* arena); -UPB_INLINE uint64_t _upb_BigEndian_Swap64(uint64_t val) { - if (_upb_IsLittleEndian()) return val; +// Deep clones map contents. +upb_Map* upb_Map_DeepClone(const upb_Map* map, upb_CType key_type, + upb_CType value_type, + const upb_MiniTable* map_entry_table, + upb_Arena* arena); - return ((uint64_t)_upb_BigEndian_Swap32((uint32_t)val) << 32) | - _upb_BigEndian_Swap32((uint32_t)(val >> 32)); -} +// Deep copies the message from src to dst. +bool upb_Message_DeepCopy(upb_Message* dst, const upb_Message* src, + const upb_MiniTable* mini_table, upb_Arena* arena); #ifdef __cplusplus } /* extern "C" */ #endif -#endif /* UPB_WIRE_INTERNAL_SWAP_H_ */ +#endif // UPB_MESSAGE_COPY_H_ -#ifndef UPB_WIRE_TYPES_H_ -#define UPB_WIRE_TYPES_H_ +// EVERYTHING BELOW THIS LINE IS INTERNAL - DO NOT USE ///////////////////////// -// A list of types as they are encoded on the wire. -typedef enum { - kUpb_WireType_Varint = 0, - kUpb_WireType_64Bit = 1, - kUpb_WireType_Delimited = 2, - kUpb_WireType_StartGroup = 3, - kUpb_WireType_EndGroup = 4, - kUpb_WireType_32Bit = 5 -} upb_WireType; +#ifndef UPB_COLLECTIONS_INTERNAL_MAP_SORTER_H_ +#define UPB_COLLECTIONS_INTERNAL_MAP_SORTER_H_ -#endif /* UPB_WIRE_TYPES_H_ */ +#include -// Must be last. -#ifdef __cplusplus -extern "C" { -#endif +#ifndef UPB_COLLECTIONS_INTERNAL_MAP_ENTRY_H_ +#define UPB_COLLECTIONS_INTERNAL_MAP_ENTRY_H_ -// The upb_WireReader interface is suitable for general-purpose parsing of -// protobuf binary wire format. It is designed to be used along with -// upb_EpsCopyInputStream for buffering, and all parsing routines in this file -// assume that at least kUpb_EpsCopyInputStream_SlopBytes worth of data is -// available to read without any bounds checks. -#define kUpb_WireReader_WireTypeMask 7 -#define kUpb_WireReader_WireTypeBits 3 +// Map entries aren't actually stored for map fields, they are only used during +// parsing. For parsing, it helps a lot if all map entry messages have the same +// layout. The layout code in mini_table/decode.c will ensure that all map +// entries have this layout. +// +// Note that users can and do create map entries directly, which will also use +// this layout. +// +// NOTE: sync with wire/decode.c. +typedef struct { + // We only need 2 hasbits max, but due to alignment we'll use 8 bytes here, + // and the uint64_t helps make this clear. + uint64_t hasbits; + union { + upb_StringView str; // For str/bytes. + upb_value val; // For all other types. + } k; + union { + upb_StringView str; // For str/bytes. + upb_value val; // For all other types. + } v; +} upb_MapEntryData; typedef struct { - const char* ptr; - uint64_t val; -} _upb_WireReader_ReadLongVarintRet; + upb_Message_Internal internal; + upb_MapEntryData data; +} upb_MapEntry; -_upb_WireReader_ReadLongVarintRet _upb_WireReader_ReadLongVarint( - const char* ptr, uint64_t val); - -static UPB_FORCEINLINE const char* _upb_WireReader_ReadVarint(const char* ptr, - uint64_t* val, - int maxlen, - uint64_t maxval) { - uint64_t byte = (uint8_t)*ptr; - if (UPB_LIKELY((byte & 0x80) == 0)) { - *val = (uint32_t)byte; - return ptr + 1; - } - const char* start = ptr; - _upb_WireReader_ReadLongVarintRet res = - _upb_WireReader_ReadLongVarint(ptr, byte); - if (!res.ptr || (maxlen < 10 && res.ptr - start > maxlen) || - res.val > maxval) { - return NULL; // Malformed. - } - *val = res.val; - return res.ptr; -} - -// Parses a tag into `tag`, and returns a pointer past the end of the tag, or -// NULL if there was an error in the tag data. -// -// REQUIRES: there must be at least 10 bytes of data available at `ptr`. -// Bounds checks must be performed before calling this function, preferably -// by calling upb_EpsCopyInputStream_IsDone(). -static UPB_FORCEINLINE const char* upb_WireReader_ReadTag(const char* ptr, - uint32_t* tag) { - uint64_t val; - ptr = _upb_WireReader_ReadVarint(ptr, &val, 5, UINT32_MAX); - if (!ptr) return NULL; - *tag = val; - return ptr; -} - -// Given a tag, returns the field number. -UPB_INLINE uint32_t upb_WireReader_GetFieldNumber(uint32_t tag) { - return tag >> kUpb_WireReader_WireTypeBits; -} - -// Given a tag, returns the wire type. -UPB_INLINE uint8_t upb_WireReader_GetWireType(uint32_t tag) { - return tag & kUpb_WireReader_WireTypeMask; -} - -UPB_INLINE const char* upb_WireReader_ReadVarint(const char* ptr, - uint64_t* val) { - return _upb_WireReader_ReadVarint(ptr, val, 10, UINT64_MAX); -} - -// Skips data for a varint, returning a pointer past the end of the varint, or -// NULL if there was an error in the varint data. -// -// REQUIRES: there must be at least 10 bytes of data available at `ptr`. -// Bounds checks must be performed before calling this function, preferably -// by calling upb_EpsCopyInputStream_IsDone(). -UPB_INLINE const char* upb_WireReader_SkipVarint(const char* ptr) { - uint64_t val; - return upb_WireReader_ReadVarint(ptr, &val); -} - -// Reads a varint indicating the size of a delimited field into `size`, or -// NULL if there was an error in the varint data. -// -// REQUIRES: there must be at least 10 bytes of data available at `ptr`. -// Bounds checks must be performed before calling this function, preferably -// by calling upb_EpsCopyInputStream_IsDone(). -UPB_INLINE const char* upb_WireReader_ReadSize(const char* ptr, int* size) { - uint64_t size64; - ptr = upb_WireReader_ReadVarint(ptr, &size64); - if (!ptr || size64 >= INT32_MAX) return NULL; - *size = size64; - return ptr; -} - -// Reads a fixed32 field, performing byte swapping if necessary. -// -// REQUIRES: there must be at least 4 bytes of data available at `ptr`. -// Bounds checks must be performed before calling this function, preferably -// by calling upb_EpsCopyInputStream_IsDone(). -UPB_INLINE const char* upb_WireReader_ReadFixed32(const char* ptr, void* val) { - uint32_t uval; - memcpy(&uval, ptr, 4); - uval = _upb_BigEndian_Swap32(uval); - memcpy(val, &uval, 4); - return ptr + 4; -} - -// Reads a fixed64 field, performing byte swapping if necessary. -// -// REQUIRES: there must be at least 4 bytes of data available at `ptr`. -// Bounds checks must be performed before calling this function, preferably -// by calling upb_EpsCopyInputStream_IsDone(). -UPB_INLINE const char* upb_WireReader_ReadFixed64(const char* ptr, void* val) { - uint64_t uval; - memcpy(&uval, ptr, 8); - uval = _upb_BigEndian_Swap64(uval); - memcpy(val, &uval, 8); - return ptr + 8; -} - -const char* _upb_WireReader_SkipGroup(const char* ptr, uint32_t tag, - int depth_limit, - upb_EpsCopyInputStream* stream); - -// Skips data for a group, returning a pointer past the end of the group, or -// NULL if there was an error parsing the group. The `tag` argument should be -// the start group tag that begins the group. The `depth_limit` argument -// indicates how many levels of recursion the group is allowed to have before -// reporting a parse error (this limit exists to protect against stack -// overflow). -// -// TODO: evaluate how the depth_limit should be specified. Do users need -// control over this? -UPB_INLINE const char* upb_WireReader_SkipGroup( - const char* ptr, uint32_t tag, upb_EpsCopyInputStream* stream) { - return _upb_WireReader_SkipGroup(ptr, tag, 100, stream); -} - -UPB_INLINE const char* _upb_WireReader_SkipValue( - const char* ptr, uint32_t tag, int depth_limit, - upb_EpsCopyInputStream* stream) { - switch (upb_WireReader_GetWireType(tag)) { - case kUpb_WireType_Varint: - return upb_WireReader_SkipVarint(ptr); - case kUpb_WireType_32Bit: - return ptr + 4; - case kUpb_WireType_64Bit: - return ptr + 8; - case kUpb_WireType_Delimited: { - int size; - ptr = upb_WireReader_ReadSize(ptr, &size); - if (!ptr) return NULL; - ptr += size; - return ptr; - } - case kUpb_WireType_StartGroup: - return _upb_WireReader_SkipGroup(ptr, tag, depth_limit, stream); - case kUpb_WireType_EndGroup: - return NULL; // Should be handled before now. - default: - return NULL; // Unknown wire type. - } -} - -// Skips data for a wire value of any type, returning a pointer past the end of -// the data, or NULL if there was an error parsing the group. The `tag` argument -// should be the tag that was just parsed. The `depth_limit` argument indicates -// how many levels of recursion a group is allowed to have before reporting a -// parse error (this limit exists to protect against stack overflow). -// -// REQUIRES: there must be at least 10 bytes of data available at `ptr`. -// Bounds checks must be performed before calling this function, preferably -// by calling upb_EpsCopyInputStream_IsDone(). -// -// TODO: evaluate how the depth_limit should be specified. Do users need -// control over this? -UPB_INLINE const char* upb_WireReader_SkipValue( - const char* ptr, uint32_t tag, upb_EpsCopyInputStream* stream) { - return _upb_WireReader_SkipValue(ptr, tag, 100, stream); -} - -#ifdef __cplusplus -} /* extern "C" */ -#endif - - -#endif // UPB_WIRE_READER_H_ - -#ifndef UPB_MESSAGE_COPY_H_ -#define UPB_MESSAGE_COPY_H_ - - -// Must be last. - -#ifdef __cplusplus -extern "C" { -#endif - -// Deep clones a message using the provided target arena. -upb_Message* upb_Message_DeepClone(const upb_Message* message, - const upb_MiniTable* mini_table, - upb_Arena* arena); - -// Deep clones array contents. -upb_Array* upb_Array_DeepClone(const upb_Array* array, upb_CType value_type, - const upb_MiniTable* sub, upb_Arena* arena); - -// Deep clones map contents. -upb_Map* upb_Map_DeepClone(const upb_Map* map, upb_CType key_type, - upb_CType value_type, - const upb_MiniTable* map_entry_table, - upb_Arena* arena); - -// Deep copies the message from src to dst. -bool upb_Message_DeepCopy(upb_Message* dst, const upb_Message* src, - const upb_MiniTable* mini_table, upb_Arena* arena); - -#ifdef __cplusplus -} /* extern "C" */ -#endif - - -#endif // UPB_MESSAGE_COPY_H_ - -// EVERYTHING BELOW THIS LINE IS INTERNAL - DO NOT USE ///////////////////////// - -#ifndef UPB_COLLECTIONS_INTERNAL_MAP_SORTER_H_ -#define UPB_COLLECTIONS_INTERNAL_MAP_SORTER_H_ - -#include - - -#ifndef UPB_COLLECTIONS_INTERNAL_MAP_ENTRY_H_ -#define UPB_COLLECTIONS_INTERNAL_MAP_ENTRY_H_ - - -// Map entries aren't actually stored for map fields, they are only used during -// parsing. For parsing, it helps a lot if all map entry messages have the same -// layout. The layout code in mini_table/decode.c will ensure that all map -// entries have this layout. -// -// Note that users can and do create map entries directly, which will also use -// this layout. -// -// NOTE: sync with wire/decode.c. -typedef struct { - // We only need 2 hasbits max, but due to alignment we'll use 8 bytes here, - // and the uint64_t helps make this clear. - uint64_t hasbits; - union { - upb_StringView str; // For str/bytes. - upb_value val; // For all other types. - } k; - union { - upb_StringView str; // For str/bytes. - upb_value val; // For all other types. - } v; -} upb_MapEntryData; - -typedef struct { - upb_Message_Internal internal; - upb_MapEntryData data; -} upb_MapEntry; - -#endif // UPB_COLLECTIONS_INTERNAL_MAP_ENTRY_H_ +#endif // UPB_COLLECTIONS_INTERNAL_MAP_ENTRY_H_ // Must be last. @@ -13183,6 +12998,254 @@ UPB_INLINE uint32_t _upb_FastDecoder_LoadTag(const char* ptr) { #endif /* UPB_WIRE_INTERNAL_DECODE_H_ */ +#ifndef UPB_WIRE_INTERNAL_SWAP_H_ +#define UPB_WIRE_INTERNAL_SWAP_H_ + +#include + +// Must be last. + +#ifdef __cplusplus +extern "C" { +#endif + +UPB_INLINE bool _upb_IsLittleEndian(void) { + int x = 1; + return *(char*)&x == 1; +} + +UPB_INLINE uint32_t _upb_BigEndian_Swap32(uint32_t val) { + if (_upb_IsLittleEndian()) return val; + + return ((val & 0xff) << 24) | ((val & 0xff00) << 8) | + ((val & 0xff0000) >> 8) | ((val & 0xff000000) >> 24); +} + +UPB_INLINE uint64_t _upb_BigEndian_Swap64(uint64_t val) { + if (_upb_IsLittleEndian()) return val; + + return ((uint64_t)_upb_BigEndian_Swap32((uint32_t)val) << 32) | + _upb_BigEndian_Swap32((uint32_t)(val >> 32)); +} + +#ifdef __cplusplus +} /* extern "C" */ +#endif + + +#endif /* UPB_WIRE_INTERNAL_SWAP_H_ */ + +#ifndef UPB_WIRE_READER_H_ +#define UPB_WIRE_READER_H_ + + +#ifndef UPB_WIRE_TYPES_H_ +#define UPB_WIRE_TYPES_H_ + +// A list of types as they are encoded on the wire. +typedef enum { + kUpb_WireType_Varint = 0, + kUpb_WireType_64Bit = 1, + kUpb_WireType_Delimited = 2, + kUpb_WireType_StartGroup = 3, + kUpb_WireType_EndGroup = 4, + kUpb_WireType_32Bit = 5 +} upb_WireType; + +#endif /* UPB_WIRE_TYPES_H_ */ + +// Must be last. + +#ifdef __cplusplus +extern "C" { +#endif + +// The upb_WireReader interface is suitable for general-purpose parsing of +// protobuf binary wire format. It is designed to be used along with +// upb_EpsCopyInputStream for buffering, and all parsing routines in this file +// assume that at least kUpb_EpsCopyInputStream_SlopBytes worth of data is +// available to read without any bounds checks. + +#define kUpb_WireReader_WireTypeMask 7 +#define kUpb_WireReader_WireTypeBits 3 + +typedef struct { + const char* ptr; + uint64_t val; +} _upb_WireReader_ReadLongVarintRet; + +_upb_WireReader_ReadLongVarintRet _upb_WireReader_ReadLongVarint( + const char* ptr, uint64_t val); + +static UPB_FORCEINLINE const char* _upb_WireReader_ReadVarint(const char* ptr, + uint64_t* val, + int maxlen, + uint64_t maxval) { + uint64_t byte = (uint8_t)*ptr; + if (UPB_LIKELY((byte & 0x80) == 0)) { + *val = (uint32_t)byte; + return ptr + 1; + } + const char* start = ptr; + _upb_WireReader_ReadLongVarintRet res = + _upb_WireReader_ReadLongVarint(ptr, byte); + if (!res.ptr || (maxlen < 10 && res.ptr - start > maxlen) || + res.val > maxval) { + return NULL; // Malformed. + } + *val = res.val; + return res.ptr; +} + +// Parses a tag into `tag`, and returns a pointer past the end of the tag, or +// NULL if there was an error in the tag data. +// +// REQUIRES: there must be at least 10 bytes of data available at `ptr`. +// Bounds checks must be performed before calling this function, preferably +// by calling upb_EpsCopyInputStream_IsDone(). +static UPB_FORCEINLINE const char* upb_WireReader_ReadTag(const char* ptr, + uint32_t* tag) { + uint64_t val; + ptr = _upb_WireReader_ReadVarint(ptr, &val, 5, UINT32_MAX); + if (!ptr) return NULL; + *tag = val; + return ptr; +} + +// Given a tag, returns the field number. +UPB_INLINE uint32_t upb_WireReader_GetFieldNumber(uint32_t tag) { + return tag >> kUpb_WireReader_WireTypeBits; +} + +// Given a tag, returns the wire type. +UPB_INLINE uint8_t upb_WireReader_GetWireType(uint32_t tag) { + return tag & kUpb_WireReader_WireTypeMask; +} + +UPB_INLINE const char* upb_WireReader_ReadVarint(const char* ptr, + uint64_t* val) { + return _upb_WireReader_ReadVarint(ptr, val, 10, UINT64_MAX); +} + +// Skips data for a varint, returning a pointer past the end of the varint, or +// NULL if there was an error in the varint data. +// +// REQUIRES: there must be at least 10 bytes of data available at `ptr`. +// Bounds checks must be performed before calling this function, preferably +// by calling upb_EpsCopyInputStream_IsDone(). +UPB_INLINE const char* upb_WireReader_SkipVarint(const char* ptr) { + uint64_t val; + return upb_WireReader_ReadVarint(ptr, &val); +} + +// Reads a varint indicating the size of a delimited field into `size`, or +// NULL if there was an error in the varint data. +// +// REQUIRES: there must be at least 10 bytes of data available at `ptr`. +// Bounds checks must be performed before calling this function, preferably +// by calling upb_EpsCopyInputStream_IsDone(). +UPB_INLINE const char* upb_WireReader_ReadSize(const char* ptr, int* size) { + uint64_t size64; + ptr = upb_WireReader_ReadVarint(ptr, &size64); + if (!ptr || size64 >= INT32_MAX) return NULL; + *size = size64; + return ptr; +} + +// Reads a fixed32 field, performing byte swapping if necessary. +// +// REQUIRES: there must be at least 4 bytes of data available at `ptr`. +// Bounds checks must be performed before calling this function, preferably +// by calling upb_EpsCopyInputStream_IsDone(). +UPB_INLINE const char* upb_WireReader_ReadFixed32(const char* ptr, void* val) { + uint32_t uval; + memcpy(&uval, ptr, 4); + uval = _upb_BigEndian_Swap32(uval); + memcpy(val, &uval, 4); + return ptr + 4; +} + +// Reads a fixed64 field, performing byte swapping if necessary. +// +// REQUIRES: there must be at least 4 bytes of data available at `ptr`. +// Bounds checks must be performed before calling this function, preferably +// by calling upb_EpsCopyInputStream_IsDone(). +UPB_INLINE const char* upb_WireReader_ReadFixed64(const char* ptr, void* val) { + uint64_t uval; + memcpy(&uval, ptr, 8); + uval = _upb_BigEndian_Swap64(uval); + memcpy(val, &uval, 8); + return ptr + 8; +} + +const char* _upb_WireReader_SkipGroup(const char* ptr, uint32_t tag, + int depth_limit, + upb_EpsCopyInputStream* stream); + +// Skips data for a group, returning a pointer past the end of the group, or +// NULL if there was an error parsing the group. The `tag` argument should be +// the start group tag that begins the group. The `depth_limit` argument +// indicates how many levels of recursion the group is allowed to have before +// reporting a parse error (this limit exists to protect against stack +// overflow). +// +// TODO: evaluate how the depth_limit should be specified. Do users need +// control over this? +UPB_INLINE const char* upb_WireReader_SkipGroup( + const char* ptr, uint32_t tag, upb_EpsCopyInputStream* stream) { + return _upb_WireReader_SkipGroup(ptr, tag, 100, stream); +} + +UPB_INLINE const char* _upb_WireReader_SkipValue( + const char* ptr, uint32_t tag, int depth_limit, + upb_EpsCopyInputStream* stream) { + switch (upb_WireReader_GetWireType(tag)) { + case kUpb_WireType_Varint: + return upb_WireReader_SkipVarint(ptr); + case kUpb_WireType_32Bit: + return ptr + 4; + case kUpb_WireType_64Bit: + return ptr + 8; + case kUpb_WireType_Delimited: { + int size; + ptr = upb_WireReader_ReadSize(ptr, &size); + if (!ptr) return NULL; + ptr += size; + return ptr; + } + case kUpb_WireType_StartGroup: + return _upb_WireReader_SkipGroup(ptr, tag, depth_limit, stream); + case kUpb_WireType_EndGroup: + return NULL; // Should be handled before now. + default: + return NULL; // Unknown wire type. + } +} + +// Skips data for a wire value of any type, returning a pointer past the end of +// the data, or NULL if there was an error parsing the group. The `tag` argument +// should be the tag that was just parsed. The `depth_limit` argument indicates +// how many levels of recursion a group is allowed to have before reporting a +// parse error (this limit exists to protect against stack overflow). +// +// REQUIRES: there must be at least 10 bytes of data available at `ptr`. +// Bounds checks must be performed before calling this function, preferably +// by calling upb_EpsCopyInputStream_IsDone(). +// +// TODO: evaluate how the depth_limit should be specified. Do users need +// control over this? +UPB_INLINE const char* upb_WireReader_SkipValue( + const char* ptr, uint32_t tag, upb_EpsCopyInputStream* stream) { + return _upb_WireReader_SkipValue(ptr, tag, 100, stream); +} + +#ifdef __cplusplus +} /* extern "C" */ +#endif + + +#endif // UPB_WIRE_READER_H_ + // This should #undef all macros #defined in def.inc #undef UPB_SIZE