From fd040a8bff5d810ed1c62b164f0dd1abc518d18d Mon Sep 17 00:00:00 2001 From: Eric Salo Date: Fri, 4 Nov 2022 22:08:16 -0700 Subject: [PATCH] create collections/map_internal.h and collections/map_gencode_util.h Move the map-related functions from msg_internal.h that are only used in generated code into map_gencode_util.h. Then move the rest of the map-related functions from msg_internal.h into map_internal.h. PiperOrigin-RevId: 486299140 --- BUILD | 15 ++- upb/collections/map.c | 19 ++- upb/collections/map.h | 2 - upb/collections/map_gencode_util.h | 122 +++++++++++++++++ upb/collections/map_internal.h | 163 +++++++++++++++++++++++ upb/collections/message_value.h | 3 + upb/msg.c | 22 +--- upb/msg_internal.h | 204 +---------------------------- upb/upb.h | 7 - upb/wire/decode.c | 4 +- upb/wire/encode.c | 3 - upbc/protoc-gen-upb.cc | 1 + 12 files changed, 323 insertions(+), 242 deletions(-) create mode 100644 upb/collections/map_gencode_util.h create mode 100644 upb/collections/map_internal.h diff --git a/BUILD b/BUILD index 47785fc657..f77dc05dbb 100644 --- a/BUILD +++ b/BUILD @@ -170,6 +170,7 @@ cc_library( copts = UPB_DEFAULT_COPTS, visibility = ["//visibility:public"], deps = [ + ":collections_internal", ":port", ":table_internal", ], @@ -188,6 +189,7 @@ cc_library( ], visibility = ["//:__subpackages__"], deps = [ + ":collections_internal", ":extension_registry", ":port", ":table_internal", @@ -213,6 +215,7 @@ cc_library( copts = UPB_DEFAULT_COPTS, visibility = ["//visibility:public"], deps = [ + ":collections_internal", ":extension_registry", ":mini_table_internal", ":port", @@ -313,6 +316,7 @@ cc_library( hdrs = [ "upb/collections/array.h", "upb/collections/array_internal.h", + "upb/collections/map_gencode_util.h", "upb/collections/message_value.h", "upb/extension_registry.h", "upb/msg.h", @@ -326,6 +330,7 @@ cc_library( copts = UPB_DEFAULT_COPTS, visibility = ["//visibility:public"], deps = [ + ":collections_internal", ":table_internal", ":upb", ], @@ -347,6 +352,7 @@ cc_library( copts = UPB_DEFAULT_COPTS, visibility = ["//visibility:public"], deps = [ + ":collections_internal", ":mini_table", ":table_internal", ":upb", @@ -403,6 +409,7 @@ cc_library( "upb/collections/array.c", "upb/collections/array_internal.h", "upb/collections/map.c", + "upb/collections/map_internal.h", "upb/collections/map_sorter.c", "upb/collections/message_value.h", "upb/extension_registry.h", @@ -958,19 +965,24 @@ cc_library( name = "collections_internal", srcs = [ "upb/collections/array.h", + "upb/collections/map_gencode_util.h", "upb/collections/message_value.h", "upb/msg.h", "upb/status.h", "upb/string_view.h", "upb/upb.h", ], - hdrs = ["upb/collections/array_internal.h"], + hdrs = [ + "upb/collections/array_internal.h", + "upb/collections/map_internal.h", + ], copts = UPB_DEFAULT_COPTS, visibility = ["//:__subpackages__"], deps = [ ":collections", ":mem", ":port", + ":table_internal", ], ) @@ -1025,6 +1037,7 @@ cc_library( copts = UPB_DEFAULT_COPTS, visibility = ["//:__subpackages__"], deps = [ + ":collections_internal", ":mem_internal", ":port", ":table_internal", diff --git a/upb/collections/map.c b/upb/collections/map.c index 644deea8b7..e09d2cc922 100644 --- a/upb/collections/map.c +++ b/upb/collections/map.c @@ -29,8 +29,9 @@ #include +#include "upb/collections/map_internal.h" +#include "upb/mem/arena.h" #include "upb/msg.h" -#include "upb/msg_internal.h" // Must be last. #include "upb/port_def.inc" @@ -87,7 +88,7 @@ bool upb_MapIterator_Done(const upb_Map* map, size_t iter) { return upb_strtable_done(&i); } -/* Returns the key and value for this entry of the map. */ +// Returns the key and value for this entry of the map. upb_MessageValue upb_MapIterator_Key(const upb_Map* map, size_t iter) { upb_strtable_iter i; upb_MessageValue ret; @@ -106,5 +107,15 @@ upb_MessageValue upb_MapIterator_Value(const upb_Map* map, size_t iter) { return ret; } -/* void upb_MapIterator_SetValue(upb_Map *map, size_t iter, upb_MessageValue - * value); */ +// EVERYTHING BELOW THIS LINE IS INTERNAL - DO NOT USE ///////////////////////// + +upb_Map* _upb_Map_New(upb_Arena* a, size_t key_size, size_t value_size) { + upb_Map* map = upb_Arena_Malloc(a, sizeof(upb_Map)); + if (!map) return NULL; + + upb_strtable_init(&map->table, 4, a); + map->key_size = key_size; + map->val_size = value_size; + + return map; +} diff --git a/upb/collections/map.h b/upb/collections/map.h index 20245a9374..121dd4a5a0 100644 --- a/upb/collections/map.h +++ b/upb/collections/map.h @@ -53,11 +53,9 @@ bool upb_Map_Get(const upb_Map* map, upb_MessageValue key, void upb_Map_Clear(upb_Map* map); typedef enum { - // LINT.IfChange kUpb_MapInsertStatus_Inserted = 0, kUpb_MapInsertStatus_Replaced = 1, kUpb_MapInsertStatus_OutOfMemory = 2, - // LINT.ThenChange(//depot/google3/third_party/upb/upb/msg_internal.h) } upb_MapInsertStatus; /* Sets the given key to the given value, returning whether the key was inserted diff --git a/upb/collections/map_gencode_util.h b/upb/collections/map_gencode_util.h new file mode 100644 index 0000000000..1d90f7735f --- /dev/null +++ b/upb/collections/map_gencode_util.h @@ -0,0 +1,122 @@ +/* + * 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. + */ + +// These functions are only used by generated code. + +#ifndef UPB_COLLECTIONS_MAP_GENCODE_UTIL_H_ +#define UPB_COLLECTIONS_MAP_GENCODE_UTIL_H_ + +#include "upb/collections/map_internal.h" + +// Must be last. +#include "upb/port_def.inc" + +#ifdef __cplusplus +extern "C" { +#endif + +// Message map operations, these get the map from the message first. + +UPB_INLINE size_t _upb_msg_map_size(const upb_Message* msg, size_t ofs) { + upb_Map* map = *UPB_PTR_AT(msg, ofs, upb_Map*); + return map ? _upb_Map_Size(map) : 0; +} + +UPB_INLINE bool _upb_msg_map_get(const upb_Message* msg, size_t ofs, + const void* key, size_t key_size, void* val, + size_t val_size) { + upb_Map* map = *UPB_PTR_AT(msg, ofs, upb_Map*); + if (!map) return false; + return _upb_Map_Get(map, key, key_size, val, val_size); +} + +UPB_INLINE void* _upb_msg_map_next(const upb_Message* msg, size_t ofs, + size_t* iter) { + upb_Map* map = *UPB_PTR_AT(msg, ofs, upb_Map*); + if (!map) return NULL; + return _upb_map_next(map, iter); +} + +UPB_INLINE bool _upb_msg_map_set(upb_Message* msg, size_t ofs, const void* key, + size_t key_size, void* val, size_t val_size, + upb_Arena* arena) { + upb_Map** map = UPB_PTR_AT(msg, ofs, upb_Map*); + if (!*map) { + *map = _upb_Map_New(arena, key_size, val_size); + } + return _upb_Map_Insert(*map, key, key_size, val, val_size, arena) != + kUpb_MapInsertStatus_OutOfMemory; +} + +UPB_INLINE bool _upb_msg_map_delete(upb_Message* msg, size_t ofs, + const void* key, size_t key_size) { + upb_Map* map = *UPB_PTR_AT(msg, ofs, upb_Map*); + if (!map) return false; + return _upb_Map_Delete(map, key, key_size); +} + +UPB_INLINE void _upb_msg_map_clear(upb_Message* msg, size_t ofs) { + upb_Map* map = *UPB_PTR_AT(msg, ofs, upb_Map*); + if (!map) return; + _upb_Map_Clear(map); +} + +UPB_INLINE void _upb_msg_map_key(const void* msg, void* key, size_t size) { + const upb_tabent* ent = (const upb_tabent*)msg; + uint32_t u32len; + upb_StringView k; + k.data = upb_tabstr(ent->key, &u32len); + k.size = u32len; + _upb_map_fromkey(k, key, size); +} + +UPB_INLINE void _upb_msg_map_value(const void* msg, void* val, size_t size) { + const upb_tabent* ent = (const upb_tabent*)msg; + upb_value v = {ent->val.val}; + _upb_map_fromvalue(v, val, size); +} + +UPB_INLINE void _upb_msg_map_set_value(void* msg, const void* val, + size_t size) { + upb_tabent* ent = (upb_tabent*)msg; + // This is like _upb_map_tovalue() except the entry already exists + // so we can reuse the allocated upb_StringView for string fields. + if (size == UPB_MAPTYPE_STRING) { + upb_StringView* strp = (upb_StringView*)(uintptr_t)ent->val.val; + memcpy(strp, val, sizeof(*strp)); + } else { + memcpy(&ent->val.val, val, size); + } +} + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#include "upb/port_undef.inc" + +#endif /* UPB_COLLECTIONS_MAP_GENCODE_UTIL_H_ */ diff --git a/upb/collections/map_internal.h b/upb/collections/map_internal.h new file mode 100644 index 0000000000..eb7deb7b50 --- /dev/null +++ b/upb/collections/map_internal.h @@ -0,0 +1,163 @@ +/* + * 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. + */ + +// EVERYTHING BELOW THIS LINE IS INTERNAL - DO NOT USE ///////////////////////// + +#ifndef UPB_COLLECTIONS_MAP_INTERNAL_H_ +#define UPB_COLLECTIONS_MAP_INTERNAL_H_ + +#include "upb/collections/map.h" +#include "upb/internal/table.h" +#include "upb/mem/arena.h" +#include "upb/string_view.h" + +// Must be last. +#include "upb/port_def.inc" + +struct upb_Map { + // Size of key and val, based on the map type. + // Strings are represented as '0' because they must be handled specially. + char key_size; + char val_size; + + upb_strtable table; +}; + +#ifdef __cplusplus +extern "C" { +#endif + +// Converting between internal table representation and user values. +// +// _upb_map_tokey() and _upb_map_fromkey() are inverses. +// _upb_map_tovalue() and _upb_map_fromvalue() are inverses. +// +// These functions account for the fact that strings are treated differently +// from other types when stored in a map. + +UPB_INLINE upb_StringView _upb_map_tokey(const void* key, size_t size) { + if (size == UPB_MAPTYPE_STRING) { + return *(upb_StringView*)key; + } else { + return upb_StringView_FromDataAndSize((const char*)key, size); + } +} + +UPB_INLINE void _upb_map_fromkey(upb_StringView key, void* out, size_t size) { + if (size == UPB_MAPTYPE_STRING) { + memcpy(out, &key, sizeof(key)); + } else { + memcpy(out, key.data, size); + } +} + +UPB_INLINE bool _upb_map_tovalue(const void* val, size_t size, + upb_value* msgval, upb_Arena* a) { + if (size == UPB_MAPTYPE_STRING) { + upb_StringView* strp = (upb_StringView*)upb_Arena_Malloc(a, sizeof(*strp)); + if (!strp) return false; + *strp = *(upb_StringView*)val; + *msgval = upb_value_ptr(strp); + } else { + memcpy(msgval, val, size); + } + return true; +} + +UPB_INLINE void _upb_map_fromvalue(upb_value val, void* out, size_t size) { + if (size == UPB_MAPTYPE_STRING) { + const upb_StringView* strp = (const upb_StringView*)upb_value_getptr(val); + memcpy(out, strp, sizeof(upb_StringView)); + } else { + memcpy(out, &val, size); + } +} + +UPB_INLINE void* _upb_map_next(const upb_Map* map, size_t* iter) { + upb_strtable_iter it; + it.t = &map->table; + it.index = *iter; + upb_strtable_next(&it); + *iter = it.index; + if (upb_strtable_done(&it)) return NULL; + return (void*)str_tabent(&it); +} + +UPB_INLINE void _upb_Map_Clear(upb_Map* map) { + upb_strtable_clear(&map->table); +} + +UPB_INLINE bool _upb_Map_Delete(upb_Map* map, const void* key, + size_t key_size) { + upb_StringView k = _upb_map_tokey(key, key_size); + return upb_strtable_remove2(&map->table, k.data, k.size, NULL); +} + +UPB_INLINE bool _upb_Map_Get(const upb_Map* map, const void* key, + size_t key_size, void* val, size_t val_size) { + upb_value tabval; + upb_StringView k = _upb_map_tokey(key, key_size); + bool ret = upb_strtable_lookup2(&map->table, k.data, k.size, &tabval); + if (ret && val) { + _upb_map_fromvalue(tabval, val, val_size); + } + return ret; +} + +UPB_INLINE upb_MapInsertStatus _upb_Map_Insert(upb_Map* map, const void* key, + size_t key_size, void* val, + size_t val_size, upb_Arena* a) { + upb_StringView strkey = _upb_map_tokey(key, key_size); + upb_value tabval = {0}; + if (!_upb_map_tovalue(val, val_size, &tabval, a)) { + return kUpb_MapInsertStatus_OutOfMemory; + } + + // TODO(haberman): add overwrite operation to minimize number of lookups. + bool removed = + upb_strtable_remove2(&map->table, strkey.data, strkey.size, NULL); + if (!upb_strtable_insert(&map->table, strkey.data, strkey.size, tabval, a)) { + return kUpb_MapInsertStatus_OutOfMemory; + } + return removed ? kUpb_MapInsertStatus_Replaced + : kUpb_MapInsertStatus_Inserted; +} + +UPB_INLINE size_t _upb_Map_Size(const upb_Map* map) { + return map->table.t.count; +} + +// Creates a new map on the given arena with this key/value type. +upb_Map* _upb_Map_New(upb_Arena* a, size_t key_size, size_t value_size); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#include "upb/port_undef.inc" + +#endif /* UPB_COLLECTIONS_MAP_INTERNAL_H_ */ diff --git a/upb/collections/message_value.h b/upb/collections/message_value.h index 148ed424cd..86bfbb9465 100644 --- a/upb/collections/message_value.h +++ b/upb/collections/message_value.h @@ -35,6 +35,9 @@ // Must be last. #include "upb/port_def.inc" +typedef struct upb_Array upb_Array; +typedef struct upb_Map upb_Map; + typedef union { bool bool_val; float float_val; diff --git a/upb/msg.c b/upb/msg.c index 08f0887c3e..7cd77147d1 100644 --- a/upb/msg.c +++ b/upb/msg.c @@ -34,7 +34,8 @@ // Must be last. #include "upb/port_def.inc" -/** upb_Message ***************************************************************/ +const float kUpb_FltInfinity = INFINITY; +const double kUpb_Infinity = INFINITY; static const size_t overhead = sizeof(upb_Message_InternalData); @@ -194,22 +195,3 @@ size_t upb_Message_ExtensionCount(const upb_Message* msg) { _upb_Message_Getexts(msg, &count); return count; } - -/** upb_Map *******************************************************************/ - -upb_Map* _upb_Map_New(upb_Arena* a, size_t key_size, size_t value_size) { - upb_Map* map = upb_Arena_Malloc(a, sizeof(upb_Map)); - - if (!map) { - return NULL; - } - - upb_strtable_init(&map->table, 4, a); - map->key_size = key_size; - map->val_size = value_size; - - return map; -} - -const float kUpb_FltInfinity = INFINITY; -const double kUpb_Infinity = INFINITY; diff --git a/upb/msg_internal.h b/upb/msg_internal.h index 0986a5bbc9..6935190b90 100644 --- a/upb/msg_internal.h +++ b/upb/msg_internal.h @@ -38,6 +38,7 @@ #include #include +#include "upb/collections/map_internal.h" #include "upb/extension_registry.h" #include "upb/internal/table.h" #include "upb/msg.h" @@ -429,19 +430,6 @@ UPB_INLINE bool _upb_has_submsg_nohasbit(const upb_Message* msg, size_t ofs) { return *UPB_PTR_AT(msg, ofs, const upb_Message*) != NULL; } -/** upb_Map *******************************************************************/ - -/* Right now we use strmaps for everything. We'll likely want to use - * integer-specific maps for integer-keyed maps.*/ -struct upb_Map { - /* Size of key and val, based on the map type. Strings are represented as '0' - * because they must be handled specially. */ - char key_size; - char val_size; - - upb_strtable table; -}; - /* Map entries aren't actually stored, they are only used during parsing. For * parsing, it helps a lot if all map entry messages have the same layout. * The compiler and def.c must ensure that all map entries have this layout. */ @@ -457,196 +445,6 @@ typedef struct { } v; } upb_MapEntry; -/* Creates a new map on the given arena with this key/value type. */ -upb_Map* _upb_Map_New(upb_Arena* a, size_t key_size, size_t value_size); - -/* Converting between internal table representation and user values. - * - * _upb_map_tokey() and _upb_map_fromkey() are inverses. - * _upb_map_tovalue() and _upb_map_fromvalue() are inverses. - * - * These functions account for the fact that strings are treated differently - * from other types when stored in a map. - */ - -UPB_INLINE upb_StringView _upb_map_tokey(const void* key, size_t size) { - if (size == UPB_MAPTYPE_STRING) { - return *(upb_StringView*)key; - } else { - return upb_StringView_FromDataAndSize((const char*)key, size); - } -} - -UPB_INLINE void _upb_map_fromkey(upb_StringView key, void* out, size_t size) { - if (size == UPB_MAPTYPE_STRING) { - memcpy(out, &key, sizeof(key)); - } else { - memcpy(out, key.data, size); - } -} - -UPB_INLINE bool _upb_map_tovalue(const void* val, size_t size, - upb_value* msgval, upb_Arena* a) { - if (size == UPB_MAPTYPE_STRING) { - upb_StringView* strp = (upb_StringView*)upb_Arena_Malloc(a, sizeof(*strp)); - if (!strp) return false; - *strp = *(upb_StringView*)val; - *msgval = upb_value_ptr(strp); - } else { - memcpy(msgval, val, size); - } - return true; -} - -UPB_INLINE void _upb_map_fromvalue(upb_value val, void* out, size_t size) { - if (size == UPB_MAPTYPE_STRING) { - const upb_StringView* strp = (const upb_StringView*)upb_value_getptr(val); - memcpy(out, strp, sizeof(upb_StringView)); - } else { - memcpy(out, &val, size); - } -} - -/* Map operations, shared by reflection and generated code. */ - -UPB_INLINE size_t _upb_Map_Size(const upb_Map* map) { - return map->table.t.count; -} - -UPB_INLINE bool _upb_Map_Get(const upb_Map* map, const void* key, - size_t key_size, void* val, size_t val_size) { - upb_value tabval; - upb_StringView k = _upb_map_tokey(key, key_size); - bool ret = upb_strtable_lookup2(&map->table, k.data, k.size, &tabval); - if (ret && val) { - _upb_map_fromvalue(tabval, val, val_size); - } - return ret; -} - -UPB_INLINE void* _upb_map_next(const upb_Map* map, size_t* iter) { - upb_strtable_iter it; - it.t = &map->table; - it.index = *iter; - upb_strtable_next(&it); - *iter = it.index; - if (upb_strtable_done(&it)) return NULL; - return (void*)str_tabent(&it); -} - -typedef enum { - // LINT.IfChange - _kUpb_MapInsertStatus_Inserted = 0, - _kUpb_MapInsertStatus_Replaced = 1, - _kUpb_MapInsertStatus_OutOfMemory = 2, - // LINT.ThenChange(//depot/google3/third_party/upb/upb/map.h) -} _upb_MapInsertStatus; - -UPB_INLINE _upb_MapInsertStatus _upb_Map_Insert(upb_Map* map, const void* key, - size_t key_size, void* val, - size_t val_size, upb_Arena* a) { - upb_StringView strkey = _upb_map_tokey(key, key_size); - upb_value tabval = {0}; - if (!_upb_map_tovalue(val, val_size, &tabval, a)) { - return _kUpb_MapInsertStatus_OutOfMemory; - } - - /* TODO(haberman): add overwrite operation to minimize number of lookups. */ - bool removed = - upb_strtable_remove2(&map->table, strkey.data, strkey.size, NULL); - if (!upb_strtable_insert(&map->table, strkey.data, strkey.size, tabval, a)) { - return _kUpb_MapInsertStatus_OutOfMemory; - } - return removed ? _kUpb_MapInsertStatus_Replaced - : _kUpb_MapInsertStatus_Inserted; -} - -UPB_INLINE bool _upb_Map_Delete(upb_Map* map, const void* key, - size_t key_size) { - upb_StringView k = _upb_map_tokey(key, key_size); - return upb_strtable_remove2(&map->table, k.data, k.size, NULL); -} - -UPB_INLINE void _upb_Map_Clear(upb_Map* map) { - upb_strtable_clear(&map->table); -} - -/* Message map operations, these get the map from the message first. */ - -UPB_INLINE size_t _upb_msg_map_size(const upb_Message* msg, size_t ofs) { - upb_Map* map = *UPB_PTR_AT(msg, ofs, upb_Map*); - return map ? _upb_Map_Size(map) : 0; -} - -UPB_INLINE bool _upb_msg_map_get(const upb_Message* msg, size_t ofs, - const void* key, size_t key_size, void* val, - size_t val_size) { - upb_Map* map = *UPB_PTR_AT(msg, ofs, upb_Map*); - if (!map) return false; - return _upb_Map_Get(map, key, key_size, val, val_size); -} - -UPB_INLINE void* _upb_msg_map_next(const upb_Message* msg, size_t ofs, - size_t* iter) { - upb_Map* map = *UPB_PTR_AT(msg, ofs, upb_Map*); - if (!map) return NULL; - return _upb_map_next(map, iter); -} - -UPB_INLINE bool _upb_msg_map_set(upb_Message* msg, size_t ofs, const void* key, - size_t key_size, void* val, size_t val_size, - upb_Arena* arena) { - upb_Map** map = UPB_PTR_AT(msg, ofs, upb_Map*); - if (!*map) { - *map = _upb_Map_New(arena, key_size, val_size); - } - return _upb_Map_Insert(*map, key, key_size, val, val_size, arena) != - _kUpb_MapInsertStatus_OutOfMemory; -} - -UPB_INLINE bool _upb_msg_map_delete(upb_Message* msg, size_t ofs, - const void* key, size_t key_size) { - upb_Map* map = *UPB_PTR_AT(msg, ofs, upb_Map*); - if (!map) return false; - return _upb_Map_Delete(map, key, key_size); -} - -UPB_INLINE void _upb_msg_map_clear(upb_Message* msg, size_t ofs) { - upb_Map* map = *UPB_PTR_AT(msg, ofs, upb_Map*); - if (!map) return; - _upb_Map_Clear(map); -} - -/* Accessing map key/value from a pointer, used by generated code only. */ - -UPB_INLINE void _upb_msg_map_key(const void* msg, void* key, size_t size) { - const upb_tabent* ent = (const upb_tabent*)msg; - uint32_t u32len; - upb_StringView k; - k.data = upb_tabstr(ent->key, &u32len); - k.size = u32len; - _upb_map_fromkey(k, key, size); -} - -UPB_INLINE void _upb_msg_map_value(const void* msg, void* val, size_t size) { - const upb_tabent* ent = (const upb_tabent*)msg; - upb_value v = {ent->val.val}; - _upb_map_fromvalue(v, val, size); -} - -UPB_INLINE void _upb_msg_map_set_value(void* msg, const void* val, - size_t size) { - upb_tabent* ent = (upb_tabent*)msg; - /* This is like _upb_map_tovalue() except the entry already exists so we can - * reuse the allocated upb_StringView for string fields. */ - if (size == UPB_MAPTYPE_STRING) { - upb_StringView* strp = (upb_StringView*)(uintptr_t)ent->val.val; - memcpy(strp, val, sizeof(*strp)); - } else { - memcpy(&ent->val.val, val, size); - } -} - #ifdef __cplusplus } /* extern "C" */ #endif diff --git a/upb/upb.h b/upb/upb.h index 2bbf848323..4ac33cc170 100644 --- a/upb/upb.h +++ b/upb/upb.h @@ -51,13 +51,6 @@ extern "C" { #endif -// These types appear in circular references so we need to forward-declare them. -// There is no obviously good place for this so let's just put it here. -typedef struct upb_Array upb_Array; -typedef struct upb_Map upb_Map; - -/* Constants ******************************************************************/ - /* A list of types as they are encoded on-the-wire. */ typedef enum { kUpb_WireType_Varint = 0, diff --git a/upb/wire/decode.c b/upb/wire/decode.c index 0d0611b806..f8748dbd8a 100644 --- a/upb/wire/decode.c +++ b/upb/wire/decode.c @@ -30,7 +30,7 @@ #include #include "upb/collections/array_internal.h" -#include "upb/msg_internal.h" +#include "upb/collections/map_internal.h" #include "upb/upb.h" #include "upb/wire/decode_internal.h" @@ -619,7 +619,7 @@ static const char* _upb_Decoder_DecodeToMap(upb_Decoder* d, const char* ptr, } } else { if (_upb_Map_Insert(map, &ent.k, map->key_size, &ent.v, map->val_size, - &d->arena) == _kUpb_MapInsertStatus_OutOfMemory) { + &d->arena) == kUpb_MapInsertStatus_OutOfMemory) { _upb_Decoder_ErrorJmp(d, kUpb_DecodeStatus_OutOfMemory); } } diff --git a/upb/wire/encode.c b/upb/wire/encode.c index 1f73c0e8ec..66bbf50ccb 100644 --- a/upb/wire/encode.c +++ b/upb/wire/encode.c @@ -33,9 +33,6 @@ #include "upb/collections/array_internal.h" #include "upb/collections/map_sorter_internal.h" -#include "upb/extension_registry.h" -#include "upb/msg_internal.h" -#include "upb/upb.h" // Must be last. #include "upb/port_def.inc" diff --git a/upbc/protoc-gen-upb.cc b/upbc/protoc-gen-upb.cc index c97030aae0..6632746839 100644 --- a/upbc/protoc-gen-upb.cc +++ b/upbc/protoc-gen-upb.cc @@ -884,6 +884,7 @@ void WriteHeader(const FileLayout& layout, Output& output) { "#ifndef $0_UPB_H_\n" "#define $0_UPB_H_\n\n" "#include \"upb/collections/array_internal.h\"\n" + "#include \"upb/collections/map_gencode_util.h\"\n" "#include \"upb/msg_internal.h\"\n" "#include \"upb/wire/decode.h\"\n" "#include \"upb/wire/decode_fast.h\"\n"