[ObjC] Update oneof clearing internals.

- Add/document an public api for clearing oneofs.
- Move the current library internals to a new api and keep a shim for old
  generated code.
pull/7429/head
Thomas Van Lenten 5 years ago
parent e1e5b8af79
commit 3c8e959b60
  1. 10
      objectivec/GPBUtilities.h
  2. 59
      objectivec/GPBUtilities.m
  3. 7
      objectivec/GPBUtilities_PackagePrivate.h

@ -34,6 +34,8 @@
#import "GPBMessage.h" #import "GPBMessage.h"
#import "GPBRuntimeTypes.h" #import "GPBRuntimeTypes.h"
@class GPBOneofDescriptor;
CF_EXTERN_C_BEGIN CF_EXTERN_C_BEGIN
NS_ASSUME_NONNULL_BEGIN NS_ASSUME_NONNULL_BEGIN
@ -92,6 +94,14 @@ BOOL GPBMessageHasFieldSet(GPBMessage *self, GPBFieldDescriptor *field);
**/ **/
void GPBClearMessageField(GPBMessage *self, GPBFieldDescriptor *field); void GPBClearMessageField(GPBMessage *self, GPBFieldDescriptor *field);
/**
* Clears the given onoof field for the given message.
*
* @param self The message for which to clear the field.
* @param oneof The oneof to clear.
**/
void GPBClearOneof(GPBMessage *self, GPBOneofDescriptor *oneof);
//%PDDM-EXPAND GPB_ACCESSORS() //%PDDM-EXPAND GPB_ACCESSORS()
// This block of code is generated, do not edit it directly. // This block of code is generated, do not edit it directly.
// clang-format off // clang-format off

@ -62,6 +62,12 @@ static GPBDataType BaseDataType(GPBDataType type) __attribute__ ((unused));
// Marked unused because currently only called from asserts/debug. // Marked unused because currently only called from asserts/debug.
static NSString *TypeToString(GPBDataType dataType) __attribute__ ((unused)); static NSString *TypeToString(GPBDataType dataType) __attribute__ ((unused));
// Helper for clearing oneofs.
static void GPBMaybeClearOneofPrivate(GPBMessage *self,
GPBOneofDescriptor *oneof,
int32_t oneofHasIndex,
uint32_t fieldNumberNotToClear);
NSData *GPBEmptyNSData(void) { NSData *GPBEmptyNSData(void) {
static dispatch_once_t onceToken; static dispatch_once_t onceToken;
static NSData *defaultNSData = nil; static NSData *defaultNSData = nil;
@ -281,6 +287,16 @@ void GPBClearMessageField(GPBMessage *self, GPBFieldDescriptor *field) {
GPBSetHasIvar(self, fieldDesc->hasIndex, fieldDesc->number, NO); GPBSetHasIvar(self, fieldDesc->hasIndex, fieldDesc->number, NO);
} }
void GPBClearOneof(GPBMessage *self, GPBOneofDescriptor *oneof) {
#if defined(DEBUG) && DEBUG
NSCAssert([[self descriptor] oneofWithName:oneof.name] == oneof,
@"OneofDescriptor %@ doesn't appear to be for %@ messages.",
oneof.name, [self class]);
#endif
GPBFieldDescriptor *firstField = oneof->fields_[0];
GPBMaybeClearOneofPrivate(self, oneof, firstField->description_->hasIndex, 0);
}
BOOL GPBGetHasIvar(GPBMessage *self, int32_t idx, uint32_t fieldNumber) { BOOL GPBGetHasIvar(GPBMessage *self, int32_t idx, uint32_t fieldNumber) {
NSCAssert(self->messageStorage_ != NULL, NSCAssert(self->messageStorage_ != NULL,
@"%@: All messages should have storage (from init)", @"%@: All messages should have storage (from init)",
@ -325,8 +341,10 @@ void GPBSetHasIvar(GPBMessage *self, int32_t idx, uint32_t fieldNumber,
} }
} }
void GPBMaybeClearOneof(GPBMessage *self, GPBOneofDescriptor *oneof, static void GPBMaybeClearOneofPrivate(GPBMessage *self,
int32_t oneofHasIndex, uint32_t fieldNumberNotToClear) { GPBOneofDescriptor *oneof,
int32_t oneofHasIndex,
uint32_t fieldNumberNotToClear) {
uint32_t fieldNumberSet = GPBGetHasOneof(self, oneofHasIndex); uint32_t fieldNumberSet = GPBGetHasOneof(self, oneofHasIndex);
if ((fieldNumberSet == fieldNumberNotToClear) || (fieldNumberSet == 0)) { if ((fieldNumberSet == fieldNumberNotToClear) || (fieldNumberSet == 0)) {
// Do nothing/nothing set in the oneof. // Do nothing/nothing set in the oneof.
@ -401,7 +419,7 @@ void GPBMaybeClearOneof(GPBMessage *self, GPBOneofDescriptor *oneof,
//% GPBOneofDescriptor *oneof = field->containingOneof_; //% GPBOneofDescriptor *oneof = field->containingOneof_;
//% GPBMessageFieldDescription *fieldDesc = field->description_; //% GPBMessageFieldDescription *fieldDesc = field->description_;
//% if (oneof) { //% if (oneof) {
//% GPBMaybeClearOneof(self, oneof, fieldDesc->hasIndex, fieldDesc->number); //% GPBMaybeClearOneofPrivate(self, oneof, fieldDesc->hasIndex, fieldDesc->number);
//% } //% }
//%#if defined(DEBUG) && DEBUG //%#if defined(DEBUG) && DEBUG
//% NSCAssert(self->messageStorage_ != NULL, //% NSCAssert(self->messageStorage_ != NULL,
@ -583,7 +601,7 @@ void GPBSetRetainedObjectIvarWithFieldPrivate(GPBMessage *self,
// oneof. // oneof.
GPBOneofDescriptor *oneof = field->containingOneof_; GPBOneofDescriptor *oneof = field->containingOneof_;
if (oneof) { if (oneof) {
GPBMaybeClearOneof(self, oneof, fieldDesc->hasIndex, fieldDesc->number); GPBMaybeClearOneofPrivate(self, oneof, fieldDesc->hasIndex, fieldDesc->number);
} }
// Clear "has" if they are being set to nil. // Clear "has" if they are being set to nil.
BOOL setHasValue = (value != nil); BOOL setHasValue = (value != nil);
@ -778,7 +796,7 @@ void GPBSetBoolIvarWithFieldPrivate(GPBMessage *self,
GPBMessageFieldDescription *fieldDesc = field->description_; GPBMessageFieldDescription *fieldDesc = field->description_;
GPBOneofDescriptor *oneof = field->containingOneof_; GPBOneofDescriptor *oneof = field->containingOneof_;
if (oneof) { if (oneof) {
GPBMaybeClearOneof(self, oneof, fieldDesc->hasIndex, fieldDesc->number); GPBMaybeClearOneofPrivate(self, oneof, fieldDesc->hasIndex, fieldDesc->number);
} }
// Bools are stored in the has bits to avoid needing explicit space in the // Bools are stored in the has bits to avoid needing explicit space in the
@ -846,7 +864,7 @@ void GPBSetInt32IvarWithFieldPrivate(GPBMessage *self,
GPBOneofDescriptor *oneof = field->containingOneof_; GPBOneofDescriptor *oneof = field->containingOneof_;
GPBMessageFieldDescription *fieldDesc = field->description_; GPBMessageFieldDescription *fieldDesc = field->description_;
if (oneof) { if (oneof) {
GPBMaybeClearOneof(self, oneof, fieldDesc->hasIndex, fieldDesc->number); GPBMaybeClearOneofPrivate(self, oneof, fieldDesc->hasIndex, fieldDesc->number);
} }
#if defined(DEBUG) && DEBUG #if defined(DEBUG) && DEBUG
NSCAssert(self->messageStorage_ != NULL, NSCAssert(self->messageStorage_ != NULL,
@ -919,7 +937,7 @@ void GPBSetUInt32IvarWithFieldPrivate(GPBMessage *self,
GPBOneofDescriptor *oneof = field->containingOneof_; GPBOneofDescriptor *oneof = field->containingOneof_;
GPBMessageFieldDescription *fieldDesc = field->description_; GPBMessageFieldDescription *fieldDesc = field->description_;
if (oneof) { if (oneof) {
GPBMaybeClearOneof(self, oneof, fieldDesc->hasIndex, fieldDesc->number); GPBMaybeClearOneofPrivate(self, oneof, fieldDesc->hasIndex, fieldDesc->number);
} }
#if defined(DEBUG) && DEBUG #if defined(DEBUG) && DEBUG
NSCAssert(self->messageStorage_ != NULL, NSCAssert(self->messageStorage_ != NULL,
@ -992,7 +1010,7 @@ void GPBSetInt64IvarWithFieldPrivate(GPBMessage *self,
GPBOneofDescriptor *oneof = field->containingOneof_; GPBOneofDescriptor *oneof = field->containingOneof_;
GPBMessageFieldDescription *fieldDesc = field->description_; GPBMessageFieldDescription *fieldDesc = field->description_;
if (oneof) { if (oneof) {
GPBMaybeClearOneof(self, oneof, fieldDesc->hasIndex, fieldDesc->number); GPBMaybeClearOneofPrivate(self, oneof, fieldDesc->hasIndex, fieldDesc->number);
} }
#if defined(DEBUG) && DEBUG #if defined(DEBUG) && DEBUG
NSCAssert(self->messageStorage_ != NULL, NSCAssert(self->messageStorage_ != NULL,
@ -1065,7 +1083,7 @@ void GPBSetUInt64IvarWithFieldPrivate(GPBMessage *self,
GPBOneofDescriptor *oneof = field->containingOneof_; GPBOneofDescriptor *oneof = field->containingOneof_;
GPBMessageFieldDescription *fieldDesc = field->description_; GPBMessageFieldDescription *fieldDesc = field->description_;
if (oneof) { if (oneof) {
GPBMaybeClearOneof(self, oneof, fieldDesc->hasIndex, fieldDesc->number); GPBMaybeClearOneofPrivate(self, oneof, fieldDesc->hasIndex, fieldDesc->number);
} }
#if defined(DEBUG) && DEBUG #if defined(DEBUG) && DEBUG
NSCAssert(self->messageStorage_ != NULL, NSCAssert(self->messageStorage_ != NULL,
@ -1138,7 +1156,7 @@ void GPBSetFloatIvarWithFieldPrivate(GPBMessage *self,
GPBOneofDescriptor *oneof = field->containingOneof_; GPBOneofDescriptor *oneof = field->containingOneof_;
GPBMessageFieldDescription *fieldDesc = field->description_; GPBMessageFieldDescription *fieldDesc = field->description_;
if (oneof) { if (oneof) {
GPBMaybeClearOneof(self, oneof, fieldDesc->hasIndex, fieldDesc->number); GPBMaybeClearOneofPrivate(self, oneof, fieldDesc->hasIndex, fieldDesc->number);
} }
#if defined(DEBUG) && DEBUG #if defined(DEBUG) && DEBUG
NSCAssert(self->messageStorage_ != NULL, NSCAssert(self->messageStorage_ != NULL,
@ -1211,7 +1229,7 @@ void GPBSetDoubleIvarWithFieldPrivate(GPBMessage *self,
GPBOneofDescriptor *oneof = field->containingOneof_; GPBOneofDescriptor *oneof = field->containingOneof_;
GPBMessageFieldDescription *fieldDesc = field->description_; GPBMessageFieldDescription *fieldDesc = field->description_;
if (oneof) { if (oneof) {
GPBMaybeClearOneof(self, oneof, fieldDesc->hasIndex, fieldDesc->number); GPBMaybeClearOneofPrivate(self, oneof, fieldDesc->hasIndex, fieldDesc->number);
} }
#if defined(DEBUG) && DEBUG #if defined(DEBUG) && DEBUG
NSCAssert(self->messageStorage_ != NULL, NSCAssert(self->messageStorage_ != NULL,
@ -2221,8 +2239,6 @@ NSString *GPBDecodeTextFormatName(const uint8_t *decodeData, int32_t key,
return result; return result;
} }
#pragma clang diagnostic pop
#pragma mark Legacy methods old generated code calls #pragma mark Legacy methods old generated code calls
// Shim from the older generated code into the runtime. // Shim from the older generated code into the runtime.
@ -2234,6 +2250,23 @@ void GPBSetInt32IvarWithFieldInternal(GPBMessage *self,
GPBSetMessageInt32Field(self, field, value); GPBSetMessageInt32Field(self, field, value);
} }
void GPBMaybeClearOneof(GPBMessage *self, GPBOneofDescriptor *oneof,
int32_t oneofHasIndex, uint32_t fieldNumberNotToClear) {
#pragma unused(fieldNumberNotToClear)
#if defined(DEBUG) && DEBUG
NSCAssert([[self descriptor] oneofWithName:oneof.name] == oneof,
@"OneofDescriptor %@ doesn't appear to be for %@ messages.",
oneof.name, [self class]);
GPBFieldDescriptor *firstField = oneof->fields_[0];
NSCAssert(firstField->description_->hasIndex == oneofHasIndex,
@"Internal error, oneofHasIndex (%d) doesn't match (%d).",
firstField->description_->hasIndex, oneofHasIndex);
#endif
GPBMaybeClearOneofPrivate(self, oneof, oneofHasIndex, 0);
}
#pragma clang diagnostic pop
#pragma mark Misc Helpers #pragma mark Misc Helpers
BOOL GPBClassHasSel(Class aClass, SEL sel) { BOOL GPBClassHasSel(Class aClass, SEL sel) {

@ -207,9 +207,6 @@ GPBGetHasIvarField(GPBMessage *self, GPBFieldDescriptor *field) {
return GPBGetHasIvar(self, fieldDesc->hasIndex, fieldDesc->number); return GPBGetHasIvar(self, fieldDesc->hasIndex, fieldDesc->number);
} }
void GPBMaybeClearOneof(GPBMessage *self, GPBOneofDescriptor *oneof,
int32_t oneofHasIndex, uint32_t fieldNumberNotToClear);
#pragma clang diagnostic pop #pragma clang diagnostic pop
//%PDDM-DEFINE GPB_IVAR_SET_DECL(NAME, TYPE) //%PDDM-DEFINE GPB_IVAR_SET_DECL(NAME, TYPE)
@ -313,11 +310,13 @@ NSString *GPBDecodeTextFormatName(const uint8_t *decodeData, int32_t key,
NSString *inputString); NSString *inputString);
// Shim from the older generated code into the runtime. // Shims from the older generated code into the runtime.
void GPBSetInt32IvarWithFieldInternal(GPBMessage *self, void GPBSetInt32IvarWithFieldInternal(GPBMessage *self,
GPBFieldDescriptor *field, GPBFieldDescriptor *field,
int32_t value, int32_t value,
GPBFileSyntax syntax); GPBFileSyntax syntax);
void GPBMaybeClearOneof(GPBMessage *self, GPBOneofDescriptor *oneof,
int32_t oneofHasIndex, uint32_t fieldNumberNotToClear);
// A series of selectors that are used solely to get @encoding values // A series of selectors that are used solely to get @encoding values
// for them by the dynamic protobuf runtime code. See // for them by the dynamic protobuf runtime code. See

Loading…
Cancel
Save