diff --git a/php/ext/google/protobuf/php-upb.c b/php/ext/google/protobuf/php-upb.c index fd2f3e29d4..ef9572417e 100644 --- a/php/ext/google/protobuf/php-upb.c +++ b/php/ext/google/protobuf/php-upb.c @@ -5811,6 +5811,7 @@ upb_FindUnknownRet upb_MiniTable_FindUnknown(const upb_Message* msg, return ret; } +// Warning: See TODO(b/267655898) upb_UnknownToMessageRet upb_MiniTable_PromoteUnknownToMessage( upb_Message* msg, const upb_MiniTable* mini_table, const upb_MiniTableField* field, const upb_MiniTable* sub_mini_table, @@ -5821,7 +5822,10 @@ upb_UnknownToMessageRet upb_MiniTable_PromoteUnknownToMessage( // Callers should check that message is not set first before calling // PromotoUnknownToMessage. UPB_ASSERT(mini_table->subs[field->submsg_index].submsg == sub_mini_table); - UPB_ASSERT(upb_Message_GetMessage(msg, field, NULL) == NULL); + bool is_oneof = _upb_MiniTableField_InOneOf(field); + if (!is_oneof || _upb_getoneofcase_field(msg, field) == field->number) { + UPB_ASSERT(upb_Message_GetMessage(msg, field, NULL) == NULL); + } upb_UnknownToMessageRet ret; ret.status = kUpb_UnknownToMessage_Ok; do { @@ -5849,6 +5853,9 @@ upb_UnknownToMessageRet upb_MiniTable_PromoteUnknownToMessage( } } while (unknown.status == kUpb_FindUnknown_Ok); if (message) { + if (is_oneof) { + *_upb_oneofcase_field(msg, field) = field->number; + } upb_Message_SetMessage(msg, mini_table, field, message); ret.message = message; } @@ -6170,6 +6177,38 @@ upb_FieldType upb_MiniTableField_Type(const upb_MiniTableField* field) { return field->descriptortype; } +static bool upb_MiniTable_Is_Oneof(const upb_MiniTableField* f) { + return f->presence < 0; +} + +const upb_MiniTableField* upb_MiniTable_GetOneof(const upb_MiniTable* m, + const upb_MiniTableField* f) { + if (UPB_UNLIKELY(!upb_MiniTable_Is_Oneof(f))) { + return NULL; + } + const upb_MiniTableField* ptr = &m->fields[0]; + const upb_MiniTableField* end = &m->fields[m->field_count]; + while (++ptr < end) { + if (ptr->presence == (*f).presence) { + return ptr; + } + } + return NULL; +} + +bool upb_MiniTable_NextOneofField(const upb_MiniTable* m, + const upb_MiniTableField** f) { + const upb_MiniTableField* ptr = *f; + const upb_MiniTableField* end = &m->fields[m->field_count]; + while (++ptr < end) { + if (ptr->presence == (*f)->presence) { + *f = ptr; + return true; + } + } + return false; +} + #include #include diff --git a/php/ext/google/protobuf/php-upb.h b/php/ext/google/protobuf/php-upb.h index f17a2dd827..6b554cc342 100644 --- a/php/ext/google/protobuf/php-upb.h +++ b/php/ext/google/protobuf/php-upb.h @@ -2253,6 +2253,26 @@ UPB_API_INLINE const upb_MiniTableEnum* upb_MiniTable_GetSubEnumTable( return mini_table->subs[field->submsg_index].subenum; } +// If this field is in a oneof, returns the first field in the oneof. +// +// Otherwise returns NULL. +// +// Usage: +// const upb_MiniTableField* field = upb_MiniTable_GetOneof(m, f); +// do { +// .. +// } while (upb_MiniTable_NextOneofField(m, &field); +// +const upb_MiniTableField* upb_MiniTable_GetOneof(const upb_MiniTable* m, + const upb_MiniTableField* f); + +// Returns the next field in the oneof. If this is the last field in the +// oneof, returns NULL. The ordering of fields in the oneof is not +// guaranteed. +// REQUIRES: |iter| is and iterator. +bool upb_MiniTable_NextOneofField(const upb_MiniTable* m, + const upb_MiniTableField** f); + #ifdef __cplusplus } /* extern "C" */ #endif @@ -2942,6 +2962,8 @@ typedef struct { // // The unknown data is removed from message after field value is set // using upb_Message_SetMessage. +// +// WARNING!: See b/267655898 upb_UnknownToMessageRet upb_MiniTable_PromoteUnknownToMessage( upb_Message* msg, const upb_MiniTable* mini_table, const upb_MiniTableField* field, const upb_MiniTable* sub_mini_table, @@ -3289,6 +3311,12 @@ extern const upb_MiniTable google_protobuf_SourceCodeInfo_Location_msg_init; extern const upb_MiniTable google_protobuf_GeneratedCodeInfo_msg_init; extern const upb_MiniTable google_protobuf_GeneratedCodeInfo_Annotation_msg_init; +typedef enum { + google_protobuf_FieldDescriptorProto_LABEL_OPTIONAL = 1, + google_protobuf_FieldDescriptorProto_LABEL_REQUIRED = 2, + google_protobuf_FieldDescriptorProto_LABEL_REPEATED = 3 +} google_protobuf_FieldDescriptorProto_Label; + typedef enum { google_protobuf_FieldDescriptorProto_TYPE_DOUBLE = 1, google_protobuf_FieldDescriptorProto_TYPE_FLOAT = 2, @@ -3310,18 +3338,6 @@ typedef enum { google_protobuf_FieldDescriptorProto_TYPE_SINT64 = 18 } google_protobuf_FieldDescriptorProto_Type; -typedef enum { - google_protobuf_FieldDescriptorProto_LABEL_OPTIONAL = 1, - google_protobuf_FieldDescriptorProto_LABEL_REQUIRED = 2, - google_protobuf_FieldDescriptorProto_LABEL_REPEATED = 3 -} google_protobuf_FieldDescriptorProto_Label; - -typedef enum { - google_protobuf_FileOptions_SPEED = 1, - google_protobuf_FileOptions_CODE_SIZE = 2, - google_protobuf_FileOptions_LITE_RUNTIME = 3 -} google_protobuf_FileOptions_OptimizeMode; - typedef enum { google_protobuf_FieldOptions_STRING = 0, google_protobuf_FieldOptions_CORD = 1, @@ -3354,10 +3370,10 @@ typedef enum { } google_protobuf_FieldOptions_OptionTargetType; typedef enum { - google_protobuf_MethodOptions_IDEMPOTENCY_UNKNOWN = 0, - google_protobuf_MethodOptions_NO_SIDE_EFFECTS = 1, - google_protobuf_MethodOptions_IDEMPOTENT = 2 -} google_protobuf_MethodOptions_IdempotencyLevel; + google_protobuf_FileOptions_SPEED = 1, + google_protobuf_FileOptions_CODE_SIZE = 2, + google_protobuf_FileOptions_LITE_RUNTIME = 3 +} google_protobuf_FileOptions_OptimizeMode; typedef enum { google_protobuf_GeneratedCodeInfo_Annotation_NONE = 0, @@ -3365,16 +3381,22 @@ typedef enum { google_protobuf_GeneratedCodeInfo_Annotation_ALIAS = 2 } google_protobuf_GeneratedCodeInfo_Annotation_Semantic; +typedef enum { + google_protobuf_MethodOptions_IDEMPOTENCY_UNKNOWN = 0, + google_protobuf_MethodOptions_NO_SIDE_EFFECTS = 1, + google_protobuf_MethodOptions_IDEMPOTENT = 2 +} google_protobuf_MethodOptions_IdempotencyLevel; + -extern const upb_MiniTableEnum google_protobuf_FieldDescriptorProto_Type_enum_init; extern const upb_MiniTableEnum google_protobuf_FieldDescriptorProto_Label_enum_init; -extern const upb_MiniTableEnum google_protobuf_FileOptions_OptimizeMode_enum_init; +extern const upb_MiniTableEnum google_protobuf_FieldDescriptorProto_Type_enum_init; extern const upb_MiniTableEnum google_protobuf_FieldOptions_CType_enum_init; extern const upb_MiniTableEnum google_protobuf_FieldOptions_JSType_enum_init; extern const upb_MiniTableEnum google_protobuf_FieldOptions_OptionRetention_enum_init; extern const upb_MiniTableEnum google_protobuf_FieldOptions_OptionTargetType_enum_init; -extern const upb_MiniTableEnum google_protobuf_MethodOptions_IdempotencyLevel_enum_init; +extern const upb_MiniTableEnum google_protobuf_FileOptions_OptimizeMode_enum_init; extern const upb_MiniTableEnum google_protobuf_GeneratedCodeInfo_Annotation_Semantic_enum_init; +extern const upb_MiniTableEnum google_protobuf_MethodOptions_IdempotencyLevel_enum_init; /* google.protobuf.FileDescriptorSet */ diff --git a/protobuf_deps.bzl b/protobuf_deps.bzl index 18439ab126..fee1e9c1b1 100644 --- a/protobuf_deps.bzl +++ b/protobuf_deps.bzl @@ -149,7 +149,7 @@ def protobuf_deps(): _github_archive( name = "upb", repo = "https://github.com/protocolbuffers/upb", - commit = "84a3fd2d2d943c8ff37f09feadb1dd3f60f954ee", - sha256 = "5c144471b9d92250e77710376251a6929e47b49eea50b8f380e759a9447fb60b", + commit = "662497f1d3dcced2bba1620cea9aae8b484bd3cd", + sha256 = "57c87ca4145d2cbc162a6c613b114b9325b577f4f6525bd78747a34b3d03627c", patches = ["@com_google_protobuf//build_defs:upb.patch"], ) diff --git a/ruby/ext/google/protobuf_c/ruby-upb.c b/ruby/ext/google/protobuf_c/ruby-upb.c index 47636836b5..6fbf78bc02 100644 --- a/ruby/ext/google/protobuf_c/ruby-upb.c +++ b/ruby/ext/google/protobuf_c/ruby-upb.c @@ -5448,6 +5448,7 @@ upb_FindUnknownRet upb_MiniTable_FindUnknown(const upb_Message* msg, return ret; } +// Warning: See TODO(b/267655898) upb_UnknownToMessageRet upb_MiniTable_PromoteUnknownToMessage( upb_Message* msg, const upb_MiniTable* mini_table, const upb_MiniTableField* field, const upb_MiniTable* sub_mini_table, @@ -5458,7 +5459,10 @@ upb_UnknownToMessageRet upb_MiniTable_PromoteUnknownToMessage( // Callers should check that message is not set first before calling // PromotoUnknownToMessage. UPB_ASSERT(mini_table->subs[field->submsg_index].submsg == sub_mini_table); - UPB_ASSERT(upb_Message_GetMessage(msg, field, NULL) == NULL); + bool is_oneof = _upb_MiniTableField_InOneOf(field); + if (!is_oneof || _upb_getoneofcase_field(msg, field) == field->number) { + UPB_ASSERT(upb_Message_GetMessage(msg, field, NULL) == NULL); + } upb_UnknownToMessageRet ret; ret.status = kUpb_UnknownToMessage_Ok; do { @@ -5486,6 +5490,9 @@ upb_UnknownToMessageRet upb_MiniTable_PromoteUnknownToMessage( } } while (unknown.status == kUpb_FindUnknown_Ok); if (message) { + if (is_oneof) { + *_upb_oneofcase_field(msg, field) = field->number; + } upb_Message_SetMessage(msg, mini_table, field, message); ret.message = message; } @@ -5807,6 +5814,38 @@ upb_FieldType upb_MiniTableField_Type(const upb_MiniTableField* field) { return field->descriptortype; } +static bool upb_MiniTable_Is_Oneof(const upb_MiniTableField* f) { + return f->presence < 0; +} + +const upb_MiniTableField* upb_MiniTable_GetOneof(const upb_MiniTable* m, + const upb_MiniTableField* f) { + if (UPB_UNLIKELY(!upb_MiniTable_Is_Oneof(f))) { + return NULL; + } + const upb_MiniTableField* ptr = &m->fields[0]; + const upb_MiniTableField* end = &m->fields[m->field_count]; + while (++ptr < end) { + if (ptr->presence == (*f).presence) { + return ptr; + } + } + return NULL; +} + +bool upb_MiniTable_NextOneofField(const upb_MiniTable* m, + const upb_MiniTableField** f) { + const upb_MiniTableField* ptr = *f; + const upb_MiniTableField* end = &m->fields[m->field_count]; + while (++ptr < end) { + if (ptr->presence == (*f)->presence) { + *f = ptr; + return true; + } + } + return false; +} + #include #include diff --git a/ruby/ext/google/protobuf_c/ruby-upb.h b/ruby/ext/google/protobuf_c/ruby-upb.h index 7d01e6c986..cd703c288f 100755 --- a/ruby/ext/google/protobuf_c/ruby-upb.h +++ b/ruby/ext/google/protobuf_c/ruby-upb.h @@ -2255,6 +2255,26 @@ UPB_API_INLINE const upb_MiniTableEnum* upb_MiniTable_GetSubEnumTable( return mini_table->subs[field->submsg_index].subenum; } +// If this field is in a oneof, returns the first field in the oneof. +// +// Otherwise returns NULL. +// +// Usage: +// const upb_MiniTableField* field = upb_MiniTable_GetOneof(m, f); +// do { +// .. +// } while (upb_MiniTable_NextOneofField(m, &field); +// +const upb_MiniTableField* upb_MiniTable_GetOneof(const upb_MiniTable* m, + const upb_MiniTableField* f); + +// Returns the next field in the oneof. If this is the last field in the +// oneof, returns NULL. The ordering of fields in the oneof is not +// guaranteed. +// REQUIRES: |iter| is and iterator. +bool upb_MiniTable_NextOneofField(const upb_MiniTable* m, + const upb_MiniTableField** f); + #ifdef __cplusplus } /* extern "C" */ #endif @@ -2944,6 +2964,8 @@ typedef struct { // // The unknown data is removed from message after field value is set // using upb_Message_SetMessage. +// +// WARNING!: See b/267655898 upb_UnknownToMessageRet upb_MiniTable_PromoteUnknownToMessage( upb_Message* msg, const upb_MiniTable* mini_table, const upb_MiniTableField* field, const upb_MiniTable* sub_mini_table, @@ -3291,6 +3313,12 @@ extern const upb_MiniTable google_protobuf_SourceCodeInfo_Location_msg_init; extern const upb_MiniTable google_protobuf_GeneratedCodeInfo_msg_init; extern const upb_MiniTable google_protobuf_GeneratedCodeInfo_Annotation_msg_init; +typedef enum { + google_protobuf_FieldDescriptorProto_LABEL_OPTIONAL = 1, + google_protobuf_FieldDescriptorProto_LABEL_REQUIRED = 2, + google_protobuf_FieldDescriptorProto_LABEL_REPEATED = 3 +} google_protobuf_FieldDescriptorProto_Label; + typedef enum { google_protobuf_FieldDescriptorProto_TYPE_DOUBLE = 1, google_protobuf_FieldDescriptorProto_TYPE_FLOAT = 2, @@ -3312,18 +3340,6 @@ typedef enum { google_protobuf_FieldDescriptorProto_TYPE_SINT64 = 18 } google_protobuf_FieldDescriptorProto_Type; -typedef enum { - google_protobuf_FieldDescriptorProto_LABEL_OPTIONAL = 1, - google_protobuf_FieldDescriptorProto_LABEL_REQUIRED = 2, - google_protobuf_FieldDescriptorProto_LABEL_REPEATED = 3 -} google_protobuf_FieldDescriptorProto_Label; - -typedef enum { - google_protobuf_FileOptions_SPEED = 1, - google_protobuf_FileOptions_CODE_SIZE = 2, - google_protobuf_FileOptions_LITE_RUNTIME = 3 -} google_protobuf_FileOptions_OptimizeMode; - typedef enum { google_protobuf_FieldOptions_STRING = 0, google_protobuf_FieldOptions_CORD = 1, @@ -3356,10 +3372,10 @@ typedef enum { } google_protobuf_FieldOptions_OptionTargetType; typedef enum { - google_protobuf_MethodOptions_IDEMPOTENCY_UNKNOWN = 0, - google_protobuf_MethodOptions_NO_SIDE_EFFECTS = 1, - google_protobuf_MethodOptions_IDEMPOTENT = 2 -} google_protobuf_MethodOptions_IdempotencyLevel; + google_protobuf_FileOptions_SPEED = 1, + google_protobuf_FileOptions_CODE_SIZE = 2, + google_protobuf_FileOptions_LITE_RUNTIME = 3 +} google_protobuf_FileOptions_OptimizeMode; typedef enum { google_protobuf_GeneratedCodeInfo_Annotation_NONE = 0, @@ -3367,16 +3383,22 @@ typedef enum { google_protobuf_GeneratedCodeInfo_Annotation_ALIAS = 2 } google_protobuf_GeneratedCodeInfo_Annotation_Semantic; +typedef enum { + google_protobuf_MethodOptions_IDEMPOTENCY_UNKNOWN = 0, + google_protobuf_MethodOptions_NO_SIDE_EFFECTS = 1, + google_protobuf_MethodOptions_IDEMPOTENT = 2 +} google_protobuf_MethodOptions_IdempotencyLevel; + -extern const upb_MiniTableEnum google_protobuf_FieldDescriptorProto_Type_enum_init; extern const upb_MiniTableEnum google_protobuf_FieldDescriptorProto_Label_enum_init; -extern const upb_MiniTableEnum google_protobuf_FileOptions_OptimizeMode_enum_init; +extern const upb_MiniTableEnum google_protobuf_FieldDescriptorProto_Type_enum_init; extern const upb_MiniTableEnum google_protobuf_FieldOptions_CType_enum_init; extern const upb_MiniTableEnum google_protobuf_FieldOptions_JSType_enum_init; extern const upb_MiniTableEnum google_protobuf_FieldOptions_OptionRetention_enum_init; extern const upb_MiniTableEnum google_protobuf_FieldOptions_OptionTargetType_enum_init; -extern const upb_MiniTableEnum google_protobuf_MethodOptions_IdempotencyLevel_enum_init; +extern const upb_MiniTableEnum google_protobuf_FileOptions_OptimizeMode_enum_init; extern const upb_MiniTableEnum google_protobuf_GeneratedCodeInfo_Annotation_Semantic_enum_init; +extern const upb_MiniTableEnum google_protobuf_MethodOptions_IdempotencyLevel_enum_init; /* google.protobuf.FileDescriptorSet */