1 // Protocol Buffers - Google's data interchange format 2 // Copyright 2023 Google LLC. All rights reserved. 3 // 4 // Use of this source code is governed by a BSD-style 5 // license that can be found in the LICENSE file or at 6 // https://developers.google.com/open-source/licenses/bsd 7 8 #ifndef UPB_MESSAGE_PROMOTE_H_ 9 #define UPB_MESSAGE_PROMOTE_H_ 10 11 #include "upb/message/array.h" 12 #include "upb/message/internal/extension.h" 13 #include "upb/message/map.h" 14 #include "upb/wire/decode.h" 15 16 // Must be last. 17 #include "upb/port/def.inc" 18 19 #ifdef __cplusplus 20 extern "C" { 21 #endif 22 23 typedef enum { 24 kUpb_GetExtension_Ok, 25 kUpb_GetExtension_NotPresent, 26 kUpb_GetExtension_ParseError, 27 kUpb_GetExtension_OutOfMemory, 28 } upb_GetExtension_Status; 29 30 typedef enum { 31 kUpb_GetExtensionAsBytes_Ok, 32 kUpb_GetExtensionAsBytes_NotPresent, 33 kUpb_GetExtensionAsBytes_EncodeError, 34 } upb_GetExtensionAsBytes_Status; 35 36 // Returns a message value or promotes an unknown field to an extension. 37 // 38 // TODO: Only supports extension fields that are messages, 39 // expand support to include non-message types. 40 upb_GetExtension_Status upb_Message_GetOrPromoteExtension( 41 upb_Message* msg, const upb_MiniTableExtension* ext_table, 42 int decode_options, upb_Arena* arena, upb_MessageValue* value); 43 44 typedef enum { 45 kUpb_FindUnknown_Ok, 46 kUpb_FindUnknown_NotPresent, 47 kUpb_FindUnknown_ParseError, 48 } upb_FindUnknown_Status; 49 50 typedef struct { 51 upb_FindUnknown_Status status; 52 // Start of unknown field data in message arena. 53 const char* ptr; 54 // Size of unknown field data. 55 size_t len; 56 } upb_FindUnknownRet; 57 58 // Finds first occurrence of unknown data by tag id in message. 59 // A depth_limit of zero means to just use the upb default depth limit. 60 upb_FindUnknownRet upb_Message_FindUnknown(const upb_Message* msg, 61 uint32_t field_number, 62 int depth_limit); 63 64 typedef enum { 65 kUpb_UnknownToMessage_Ok, 66 kUpb_UnknownToMessage_ParseError, 67 kUpb_UnknownToMessage_OutOfMemory, 68 kUpb_UnknownToMessage_NotFound, 69 } upb_UnknownToMessage_Status; 70 71 typedef struct { 72 upb_UnknownToMessage_Status status; 73 upb_Message* message; 74 } upb_UnknownToMessageRet; 75 76 // Promotes an "empty" non-repeated message field in `parent` to a message of 77 // the correct type. 78 // 79 // Preconditions: 80 // 81 // 1. The message field must currently be in the "empty" state (this must have 82 // been previously verified by the caller by calling 83 // `upb_Message_GetTaggedMessagePtr()` and observing that the message is 84 // indeed empty). 85 // 86 // 2. This `field` must have previously been linked. 87 // 88 // If the promotion succeeds, `parent` will have its data for `field` replaced 89 // by the promoted message, which is also returned in `*promoted`. If the 90 // return value indicates an error status, `parent` and `promoted` are 91 // unchanged. 92 upb_DecodeStatus upb_Message_PromoteMessage(upb_Message* parent, 93 const upb_MiniTable* mini_table, 94 const upb_MiniTableField* field, 95 int decode_options, 96 upb_Arena* arena, 97 upb_Message** promoted); 98 99 // Promotes any "empty" messages in this array to a message of the correct type 100 // `mini_table`. This function should only be called for arrays of messages. 101 // 102 // If the return value indicates an error status, some but not all elements may 103 // have been promoted, but the array itself will not be corrupted. 104 upb_DecodeStatus upb_Array_PromoteMessages(upb_Array* arr, 105 const upb_MiniTable* mini_table, 106 int decode_options, 107 upb_Arena* arena); 108 109 // Promotes any "empty" entries in this map to a message of the correct type 110 // `mini_table`. This function should only be called for maps that have a 111 // message type as the map value. 112 // 113 // If the return value indicates an error status, some but not all elements may 114 // have been promoted, but the map itself will not be corrupted. 115 upb_DecodeStatus upb_Map_PromoteMessages(upb_Map* map, 116 const upb_MiniTable* mini_table, 117 int decode_options, upb_Arena* arena); 118 119 //////////////////////////////////////////////////////////////////////////////// 120 // OLD promotion interfaces, will be removed! 121 //////////////////////////////////////////////////////////////////////////////// 122 123 // Promotes unknown data inside message to a upb_Message parsing the unknown. 124 // 125 // The unknown data is removed from message after field value is set 126 // using upb_Message_SetMessage. 127 // 128 // WARNING!: See b/267655898 129 upb_UnknownToMessageRet upb_MiniTable_PromoteUnknownToMessage( 130 upb_Message* msg, const upb_MiniTable* mini_table, 131 const upb_MiniTableField* field, const upb_MiniTable* sub_mini_table, 132 int decode_options, upb_Arena* arena); 133 134 // Promotes all unknown data that matches field tag id to repeated messages 135 // in upb_Array. 136 // 137 // The unknown data is removed from message after upb_Array is populated. 138 // Since repeated messages can't be packed we remove each unknown that 139 // contains the target tag id. 140 upb_UnknownToMessage_Status upb_MiniTable_PromoteUnknownToMessageArray( 141 upb_Message* msg, const upb_MiniTableField* field, 142 const upb_MiniTable* mini_table, int decode_options, upb_Arena* arena); 143 144 // Promotes all unknown data that matches field tag id to upb_Map. 145 // 146 // The unknown data is removed from message after upb_Map is populated. 147 // Since repeated messages can't be packed we remove each unknown that 148 // contains the target tag id. 149 upb_UnknownToMessage_Status upb_MiniTable_PromoteUnknownToMap( 150 upb_Message* msg, const upb_MiniTable* mini_table, 151 const upb_MiniTableField* field, int decode_options, upb_Arena* arena); 152 153 #ifdef __cplusplus 154 } /* extern "C" */ 155 #endif 156 157 #include "upb/port/undef.inc" 158 159 #endif // UPB_MESSAGE_PROMOTE_H_ 160