From e636fb909926a2ce28f9efa91ce49893596115e5 Mon Sep 17 00:00:00 2001 From: Dave MacLachlan Date: Fri, 17 Apr 2026 10:51:01 -0700 Subject: [PATCH] Add External Types. This simplifies the handling of the Map code and sets us up to have potentially different internal (stored in fields) vs external types. This will be used in later cls to support unknown enum values. PiperOrigin-RevId: 901372833 --- .../src/com/google/protobuf/Descriptors.m | 18 +- .../protobuf/Descriptors_PackagePrivate.h | 127 +++++- .../src/com/google/protobuf/FieldTypes.h | 251 +++++------ .../com/google/protobuf/GeneratedMessage.mm | 389 ++++++++---------- .../src/com/google/protobuf/MapField.m | 12 +- .../src/com/google/protobuf/RepeatedField.m | 60 +-- 6 files changed, 421 insertions(+), 436 deletions(-) diff --git a/protobuf/runtime/src/com/google/protobuf/Descriptors.m b/protobuf/runtime/src/com/google/protobuf/Descriptors.m index 5e34185e44..66d49632bf 100644 --- a/protobuf/runtime/src/com/google/protobuf/Descriptors.m +++ b/protobuf/runtime/src/com/google/protobuf/Descriptors.m @@ -51,15 +51,6 @@ #import "java/util/Arrays.h" #import "java/util/Collections.h" -// Defines the field in the CGPValue union type to use for each field type. -#define VALUE_FIELD_Int valueInt -#define VALUE_FIELD_Long valueLong -#define VALUE_FIELD_Float valueFloat -#define VALUE_FIELD_Double valueDouble -#define VALUE_FIELD_Bool valueBool -#define VALUE_FIELD_Enum valueId -#define VALUE_FIELD_Retainable valueId - BOOL CGPIsRetainedType(CGPFieldJavaType type) { switch (type) { case ComGoogleProtobufDescriptors_FieldDescriptor_JavaType_Enum_INT: @@ -79,7 +70,7 @@ BOOL CGPIsRetainedType(CGPFieldJavaType type) { size_t CGPGetTypeSize(CGPFieldJavaType type) { #define GET_TYPE_SIZE_CASE(NAME) return sizeof(TYPE_##NAME); - SWITCH_TYPES_NO_ENUM(type, GET_TYPE_SIZE_CASE) + SWITCH_TYPES(type, GET_TYPE_SIZE_CASE, GET_TYPE_SIZE_CASE, GET_TYPE_SIZE_CASE) #undef GET_TYPE_SIZE_CASE } @@ -329,7 +320,7 @@ static void CGPFieldFixDefaultValue(CGPFieldDescriptor *descriptor) { CGPEnumDescriptor *enumDescriptor = [enumClass performSelector:@selector(getDescriptor)]; CGPEnumValueDescriptor *valueDescriptor = IOSObjectArray_Get(enumDescriptor->values_, data->defaultValue.valueInt); - data->defaultValue.valueId = valueDescriptor->enum_; + data->defaultValue.valueEnum = valueDescriptor->enum_; descriptor->valueType_ = enumDescriptor; break; } @@ -459,9 +450,10 @@ id CGPFieldGetDefaultValue(CGPFieldDescriptor *field) { } #define GET_DEFAULT_VALUE_CASE(NAME) \ - return CGPToReflectionType##NAME(field->data_->defaultValue.VALUE_FIELD_##NAME, field); + return CGPToReflectionType##NAME(field->data_->defaultValue.CGPValueField_##NAME, field); - SWITCH_TYPES_WITH_ENUM(CGPFieldGetJavaType(field), GET_DEFAULT_VALUE_CASE) + SWITCH_TYPES(CGPFieldGetJavaType(field), GET_DEFAULT_VALUE_CASE, GET_DEFAULT_VALUE_CASE, + GET_DEFAULT_VALUE_CASE) #undef GET_DEFAULT_VALUE_CASE } diff --git a/protobuf/runtime/src/com/google/protobuf/Descriptors_PackagePrivate.h b/protobuf/runtime/src/com/google/protobuf/Descriptors_PackagePrivate.h index 5829afda29..a6c576620b 100644 --- a/protobuf/runtime/src/com/google/protobuf/Descriptors_PackagePrivate.h +++ b/protobuf/runtime/src/com/google/protobuf/Descriptors_PackagePrivate.h @@ -45,6 +45,7 @@ typedef union { jdouble valueDouble; bool valueBool; __unsafe_unretained id valueId; + __unsafe_unretained JavaLangEnum *valueEnum; const void *valuePtr; } CGPValue; @@ -53,8 +54,7 @@ typedef union { #define CGPValueField_Float valueFloat #define CGPValueField_Double valueDouble #define CGPValueField_Bool valueBool -#define CGPValueField_Enum valueId -#define CGPValueField_Retainable valueId +#define CGPValueField_Enum valueEnum #define CGPValueField_Id valueId typedef NS_OPTIONS(uint32_t, CGPMessageFlags) { @@ -160,26 +160,13 @@ typedef struct CGPOneofData { @end -// Functions that convert a value from its field storage type to the type -// expected by a reflection accessor. (accessing with a descriptor) -// For enums, the reflection type is a EnumValueDescriptor. -#define CGPToReflectionTypeInt(value, field) [JavaLangInteger valueOfWithInt:value] -#define CGPToReflectionTypeLong(value, field) [JavaLangLong valueOfWithLong:value] -#define CGPToReflectionTypeFloat(value, field) [JavaLangFloat valueOfWithFloat:value] -#define CGPToReflectionTypeDouble(value, field) [JavaLangDouble valueOfWithDouble:value] -#define CGPToReflectionTypeBool(value, field) [JavaLangBoolean valueOfWithBoolean:value] -#define CGPToReflectionTypeEnum(value, field) \ - ((CGPEnumDescriptor *)field->valueType_)->values_->buffer_[[(JavaLangEnum *)value ordinal]] -#define CGPToReflectionTypeRetainable(value, field) RETAIN_AND_AUTORELEASE(value) - CF_EXTERN_C_BEGIN NS_RETURNS_RETAINED CGPDescriptor *CGPInitDescriptor(Class messageClass, Class builderClass, CGPMessageFlags flags, size_t storageSize); -void CGPInitFields( - CGPDescriptor *descriptor, jint fieldCount, CGPFieldData *fieldData, - jint oneofCount, const CGPOneofData *oneofData); +void CGPInitFields(CGPDescriptor *descriptor, jint fieldCount, CGPFieldData *fieldData, + jint oneofCount, const CGPOneofData *oneofData); CGP_ALWAYS_INLINE BOOL CGPIsExtendable(const CGPDescriptor *descriptor) { return descriptor->flags_ & CGPMessageFlagExtendable; @@ -264,7 +251,7 @@ CGP_ALWAYS_INLINE BOOL CGPJavaTypeIsEnum(CGPFieldJavaType type) { return type == ComGoogleProtobufDescriptors_FieldDescriptor_JavaType_Enum_ENUM; } -CGP_ALWAYS_INLINE jint CGPEnumGetIntValue(CGPEnumDescriptor *descriptor, id enumObj) { +CGP_ALWAYS_INLINE jint CGPEnumGetIntValue(CGPEnumDescriptor *descriptor, TYPE_Enum enumObj) { return *(jint *)((char *)(ARCBRIDGE void *)enumObj + descriptor->valueOffset_); } @@ -306,4 +293,108 @@ J2OBJC_FIELD_SETTER(ComGoogleProtobufDescriptors_FieldDescriptor_Type, javaType_ J2OBJC_FIELD_SETTER(ComGoogleProtobufDescriptors_FieldDescriptor_JavaType, defaultDefault_, id) +// Functions that box a value from its field storage type into an object type. +// For enums, the boxed type is a Java enum object. +CGP_ALWAYS_INLINE JavaLangInteger *CGPBoxedValueInt(jint value) { + return [JavaLangInteger valueOfWithInt:value]; +} +CGP_ALWAYS_INLINE JavaLangLong *CGPBoxedValueLong(jlong value) { + return [JavaLangLong valueOfWithLong:value]; +} +CGP_ALWAYS_INLINE JavaLangFloat *CGPBoxedValueFloat(jfloat value) { + return [JavaLangFloat valueOfWithFloat:value]; +} +CGP_ALWAYS_INLINE JavaLangDouble *CGPBoxedValueDouble(jdouble value) { + return [JavaLangDouble valueOfWithDouble:value]; +} +CGP_ALWAYS_INLINE JavaLangBoolean *CGPBoxedValueBool(bool value) { + return [JavaLangBoolean valueOfWithBoolean:value]; +} +CGP_ALWAYS_INLINE JavaLangEnum *CGPBoxedValueEnum( + JavaLangEnum *value) { + return value; +} +CGP_ALWAYS_INLINE id CGPBoxedValueId(id value) { return value; } + +// Functions that unbox a value into its primitive type. +CGP_ALWAYS_INLINE jint CGPUnboxValueInt(JavaLangInteger *value) { return [value intValue]; } +CGP_ALWAYS_INLINE jlong CGPUnboxValueLong(JavaLangLong *value) { return [value longLongValue]; } +CGP_ALWAYS_INLINE jfloat CGPUnboxValueFloat(JavaLangFloat *value) { return [value floatValue]; } +CGP_ALWAYS_INLINE jdouble CGPUnboxValueDouble(JavaLangDouble *value) { return [value doubleValue]; } +CGP_ALWAYS_INLINE bool CGPUnboxValueBool(JavaLangBoolean *value) { return [value booleanValue]; } +CGP_ALWAYS_INLINE JavaLangEnum *CGPUnboxValueEnum( + JavaLangEnum *value) { + return value; +} +CGP_ALWAYS_INLINE id CGPUnboxValueId(id value) { return value; } + +// Functions that convert a value from its reflection to its storage type. +CGP_ALWAYS_INLINE jint CGPFromReflectionTypeInt(JavaLangInteger *value) { return [value intValue]; } +CGP_ALWAYS_INLINE jlong CGPFromReflectionTypeLong(JavaLangLong *value) { + return [value longLongValue]; +} +CGP_ALWAYS_INLINE jfloat CGPFromReflectionTypeFloat(JavaLangFloat *value) { + return [value floatValue]; +} +CGP_ALWAYS_INLINE jdouble CGPFromReflectionTypeDouble(JavaLangDouble *value) { + return [value doubleValue]; +} +CGP_ALWAYS_INLINE bool CGPFromReflectionTypeBool(JavaLangBoolean *value) { + return [value booleanValue]; +} +CGP_ALWAYS_INLINE JavaLangEnum *CGPFromReflectionTypeEnum( + CGPEnumValueDescriptor *value) { + return value->enum_; +} +CGP_ALWAYS_INLINE id CGPFromReflectionTypeId(id value) { return value; } + +// Functions that convert a value from its field storage type to the type +// expected by a reflection accessor. (accessing with a descriptor) +// For enums, the reflection type is a EnumValueDescriptor. +CGP_ALWAYS_INLINE JavaLangInteger *CGPToReflectionTypeInt(jint value, CGPFieldDescriptor *field) { + return [JavaLangInteger valueOfWithInt:value]; +} +CGP_ALWAYS_INLINE JavaLangLong *CGPToReflectionTypeLong(jlong value, CGPFieldDescriptor *field) { + return [JavaLangLong valueOfWithLong:value]; +} +CGP_ALWAYS_INLINE JavaLangFloat *CGPToReflectionTypeFloat(jfloat value, CGPFieldDescriptor *field) { + return [JavaLangFloat valueOfWithFloat:value]; +} +CGP_ALWAYS_INLINE JavaLangDouble *CGPToReflectionTypeDouble(jdouble value, + CGPFieldDescriptor *field) { + return [JavaLangDouble valueOfWithDouble:value]; +} +CGP_ALWAYS_INLINE JavaLangBoolean *CGPToReflectionTypeBool(bool value, CGPFieldDescriptor *field) { + return [JavaLangBoolean valueOfWithBoolean:value]; +} +CGP_ALWAYS_INLINE CGPEnumValueDescriptor *CGPToReflectionTypeEnum( + JavaLangEnum *value, CGPFieldDescriptor *field) { + return ((CGPEnumDescriptor *)field->valueType_)->values_->buffer_[[value ordinal]]; +} +CGP_ALWAYS_INLINE id CGPToReflectionTypeId(id value, CGPFieldDescriptor *field) { + return RETAIN_AND_AUTORELEASE(value); +} + +// Functions that convert a value from its field storage type to its external +// type. +CGP_ALWAYS_INLINE EXTERNAL_TYPE_Int ToExternalTypeInt(TYPE_Int value) { return value; } +CGP_ALWAYS_INLINE EXTERNAL_TYPE_Long ToExternalTypeLong(TYPE_Long value) { return value; } +CGP_ALWAYS_INLINE EXTERNAL_TYPE_Float ToExternalTypeFloat(TYPE_Float value) { return value; } +CGP_ALWAYS_INLINE EXTERNAL_TYPE_Double ToExternalTypeDouble(TYPE_Double value) { return value; } +CGP_ALWAYS_INLINE EXTERNAL_TYPE_Bool ToExternalTypeBool(TYPE_Bool value) { return value; } +CGP_ALWAYS_INLINE EXTERNAL_TYPE_Enum ToExternalTypeEnum(TYPE_Enum value) { return value; } +CGP_ALWAYS_INLINE EXTERNAL_TYPE_Id ToExternalTypeId(TYPE_Id value) { + return RETAIN_AND_AUTORELEASE(value); +} + +// Functions that convert a value from its external type to its field storage +// type. +CGP_ALWAYS_INLINE TYPE_Int ToTypeInt(EXTERNAL_TYPE_Int value) { return value; } +CGP_ALWAYS_INLINE TYPE_Long ToTypeLong(EXTERNAL_TYPE_Long value) { return value; } +CGP_ALWAYS_INLINE TYPE_Float ToTypeFloat(EXTERNAL_TYPE_Float value) { return value; } +CGP_ALWAYS_INLINE TYPE_Double ToTypeDouble(EXTERNAL_TYPE_Double value) { return value; } +CGP_ALWAYS_INLINE TYPE_Bool ToTypeBool(EXTERNAL_TYPE_Bool value) { return value; } +CGP_ALWAYS_INLINE TYPE_Enum ToTypeEnum(EXTERNAL_TYPE_Enum value) { return value; } +CGP_ALWAYS_INLINE TYPE_Id ToTypeId(EXTERNAL_TYPE_Id value) { return value; } + #endif // __ComGoogleProtobufDescriptors_PackagePrivate_H__ diff --git a/protobuf/runtime/src/com/google/protobuf/FieldTypes.h b/protobuf/runtime/src/com/google/protobuf/FieldTypes.h index 5c61026278..a7a5b49f98 100644 --- a/protobuf/runtime/src/com/google/protobuf/FieldTypes.h +++ b/protobuf/runtime/src/com/google/protobuf/FieldTypes.h @@ -36,6 +36,7 @@ #define __ComGoogleProtobufFieldTypes_H__ #import "com/google/protobuf/ProtocolMessageEnum.h" +#import "com/google/protobuf/common.h" #import "java/lang/Boolean.h" #import "java/lang/Double.h" #import "java/lang/Enum.h" @@ -46,151 +47,93 @@ @class ComGoogleProtobufDescriptors_FieldDescriptor_JavaType; @class ComGoogleProtobufDescriptorProtos_FieldDescriptorProto_Type; -#define TYPE_Int jint -#define TYPE_Long jlong -#define TYPE_Float jfloat -#define TYPE_Double jdouble -#define TYPE_Bool bool -#define TYPE_Enum id -#define TYPE_Id id -#define TYPE_Retainable id - -#define TYPE_RETAIN_Int(value) value -#define TYPE_RETAIN_Long(value) value -#define TYPE_RETAIN_Float(value) value -#define TYPE_RETAIN_Double(value) value -#define TYPE_RETAIN_Bool(value) value -#define TYPE_RETAIN_Enum(value) value -#if __has_feature(objc_arc) -#define TYPE_RETAIN_Retainable(value) value -#else -#define TYPE_RETAIN_Retainable(value) [value retain] -#endif - -#define TYPE_ASSIGN_Int(assignee, value) assignee = value -#define TYPE_ASSIGN_Long(assignee, value) assignee = value -#define TYPE_ASSIGN_Float(assignee, value) assignee = value -#define TYPE_ASSIGN_Double(assignee, value) assignee = value -#define TYPE_ASSIGN_Bool(assignee, value) assignee = value -#define TYPE_ASSIGN_Enum(assignee, value) assignee = value -#if __has_feature(objc_arc) -#define TYPE_ASSIGN_Retainable(assignee, value) assignee = value -#else -#define TYPE_ASSIGN_Retainable(assignee, value) \ - ([assignee autorelease], assignee = [value retain]) -#endif - -#define HASH_Int(value) value -#define HASH_Long(value) (int)((uint64_t)value ^ ((uint64_t)value >> 32)) -#define HASH_Float(value) *(int *)&value -#define HASH_Double(value) (int)(*(uint64_t *)&value ^ (*(uint64_t *)&value >> 32)) -#define HASH_Bool(value) (value ? 1231 : 1237) -#define HASH_Id(value) (int)[value hash] - -// Functions that box a value from its field storage type into an object type. -// For enums, the boxed type is the same as its storage type. (a Java enum -// object) -#define CGPBoxedValueInt(value) [JavaLangInteger valueOfWithInt:value] -#define CGPBoxedValueLong(value) [JavaLangLong valueOfWithLong:value] -#define CGPBoxedValueFloat(value) [JavaLangFloat valueOfWithFloat:value] -#define CGPBoxedValueDouble(value) [JavaLangDouble valueOfWithDouble:value] -#define CGPBoxedValueBool(value) [JavaLangBoolean valueOfWithBoolean:value] -#define CGPBoxedValueId(value) value - -// Functions that unbox a value into its primitive type. -#define CGPUnboxValueInt(value) [value intValue] -#define CGPUnboxValueLong(value) [value longLongValue] -#define CGPUnboxValueFloat(value) [value floatValue] -#define CGPUnboxValueDouble(value) [value doubleValue] -#define CGPUnboxValueBool(value) [value booleanValue] -#define CGPUnboxValueEnum(value) value -#define CGPUnboxValueRetainable(value) value - -// Functions that convert a value from its reflection to its storage type. -#define CGPFromReflectionTypeInt(value) [value intValue] -#define CGPFromReflectionTypeLong(value) [value longLongValue] -#define CGPFromReflectionTypeFloat(value) [value floatValue] -#define CGPFromReflectionTypeDouble(value) [value doubleValue] -#define CGPFromReflectionTypeBool(value) [value booleanValue] -#define CGPFromReflectionTypeEnum(value) ((CGPEnumValueDescriptor *)value)->enum_ -#define CGPFromReflectionTypeRetainable(value) value +typedef jint TYPE_Int; +typedef jlong TYPE_Long; +typedef jfloat TYPE_Float; +typedef jdouble TYPE_Double; +typedef bool TYPE_Bool; +typedef JavaLangEnum *TYPE_Enum; +typedef id TYPE_Id; + +typedef TYPE_Int EXTERNAL_TYPE_Int; +typedef TYPE_Long EXTERNAL_TYPE_Long; +typedef TYPE_Float EXTERNAL_TYPE_Float; +typedef TYPE_Double EXTERNAL_TYPE_Double; +typedef TYPE_Bool EXTERNAL_TYPE_Bool; +typedef TYPE_Enum EXTERNAL_TYPE_Enum; +typedef TYPE_Id EXTERNAL_TYPE_Id; + +CGP_ALWAYS_INLINE void TYPE_ASSIGN_Int(jint *assignee, jint value) { *assignee = value; } +CGP_ALWAYS_INLINE void TYPE_ASSIGN_Long(jlong *assignee, jlong value) { *assignee = value; } +CGP_ALWAYS_INLINE void TYPE_ASSIGN_Float(jfloat *assignee, jfloat value) { *assignee = value; } +CGP_ALWAYS_INLINE void TYPE_ASSIGN_Double(jdouble *assignee, jdouble value) { *assignee = value; } +CGP_ALWAYS_INLINE void TYPE_ASSIGN_Bool(bool *assignee, bool value) { *assignee = value; } +CGP_ALWAYS_INLINE void TYPE_ASSIGN_Enum(id *assignee, id value) { *assignee = value; } +CGP_ALWAYS_INLINE void TYPE_ASSIGN_Id(id *assignee, id value) { + __unused id unused = AUTORELEASE(*assignee); + *assignee = RETAIN_(value); +} + +CGP_ALWAYS_INLINE int HASH_Int(jint value) { return value; } +CGP_ALWAYS_INLINE int HASH_Long(jlong value) { + return (int)((uint64_t)value ^ ((uint64_t)value >> 32)); +} +CGP_ALWAYS_INLINE int HASH_Float(jfloat value) { + uint32_t bits; + memcpy(&bits, &value, sizeof(bits)); + return bits; +} +CGP_ALWAYS_INLINE int HASH_Double(jdouble value) { + uint64_t bits; + memcpy(&bits, &value, sizeof(bits)); + return (int)(bits ^ (bits >> 32)); +} +CGP_ALWAYS_INLINE int HASH_Bool(bool value) { return (value ? 1231 : 1237); } +CGP_ALWAYS_INLINE int HASH_Enum(id value) { return (int)[value hash]; } +CGP_ALWAYS_INLINE int HASH_Id(id value) { return (int)[value hash]; } // Creates a switch statement over the java types grouping enums together with // the other object types. -#define SWITCH_TYPES_NO_ENUM(type, CASE_MACRO) \ - switch (type) { \ - case ComGoogleProtobufDescriptors_FieldDescriptor_JavaType_Enum_INT: \ - CASE_MACRO(Int) \ - case ComGoogleProtobufDescriptors_FieldDescriptor_JavaType_Enum_LONG: \ - CASE_MACRO(Long) \ - case ComGoogleProtobufDescriptors_FieldDescriptor_JavaType_Enum_FLOAT: \ - CASE_MACRO(Float) \ - case ComGoogleProtobufDescriptors_FieldDescriptor_JavaType_Enum_DOUBLE: \ - CASE_MACRO(Double) \ - case ComGoogleProtobufDescriptors_FieldDescriptor_JavaType_Enum_BOOLEAN: \ - CASE_MACRO(Bool) \ - case ComGoogleProtobufDescriptors_FieldDescriptor_JavaType_Enum_STRING: \ +#define SWITCH_TYPES(type, PRIMITIVE_TYPE_MACRO, ENUM_TYPE_MACRO, ID_TYPE_MACRO) \ + switch (type) { \ + case ComGoogleProtobufDescriptors_FieldDescriptor_JavaType_Enum_INT: \ + PRIMITIVE_TYPE_MACRO(Int) \ + break; \ + case ComGoogleProtobufDescriptors_FieldDescriptor_JavaType_Enum_LONG: \ + PRIMITIVE_TYPE_MACRO(Long) \ + break; \ + case ComGoogleProtobufDescriptors_FieldDescriptor_JavaType_Enum_FLOAT: \ + PRIMITIVE_TYPE_MACRO(Float) \ + break; \ + case ComGoogleProtobufDescriptors_FieldDescriptor_JavaType_Enum_DOUBLE: \ + PRIMITIVE_TYPE_MACRO(Double) \ + break; \ + case ComGoogleProtobufDescriptors_FieldDescriptor_JavaType_Enum_BOOLEAN: \ + PRIMITIVE_TYPE_MACRO(Bool) \ + break; \ + case ComGoogleProtobufDescriptors_FieldDescriptor_JavaType_Enum_ENUM: \ + ENUM_TYPE_MACRO(Enum) \ + break; \ + case ComGoogleProtobufDescriptors_FieldDescriptor_JavaType_Enum_STRING: \ case ComGoogleProtobufDescriptors_FieldDescriptor_JavaType_Enum_BYTE_STRING: \ - case ComGoogleProtobufDescriptors_FieldDescriptor_JavaType_Enum_ENUM: \ - case ComGoogleProtobufDescriptors_FieldDescriptor_JavaType_Enum_MESSAGE: \ - CASE_MACRO(Id) \ + case ComGoogleProtobufDescriptors_FieldDescriptor_JavaType_Enum_MESSAGE: \ + ID_TYPE_MACRO(Id) \ + break; \ } -// Creates a switch statement over the java types separating enums from the -// other object types. -#define SWITCH_TYPES_WITH_ENUM(type, CASE_MACRO) \ - switch (type) { \ - case ComGoogleProtobufDescriptors_FieldDescriptor_JavaType_Enum_INT: \ - CASE_MACRO(Int) \ - case ComGoogleProtobufDescriptors_FieldDescriptor_JavaType_Enum_LONG: \ - CASE_MACRO(Long) \ - case ComGoogleProtobufDescriptors_FieldDescriptor_JavaType_Enum_FLOAT: \ - CASE_MACRO(Float) \ - case ComGoogleProtobufDescriptors_FieldDescriptor_JavaType_Enum_DOUBLE: \ - CASE_MACRO(Double) \ - case ComGoogleProtobufDescriptors_FieldDescriptor_JavaType_Enum_BOOLEAN: \ - CASE_MACRO(Bool) \ - case ComGoogleProtobufDescriptors_FieldDescriptor_JavaType_Enum_STRING: \ - case ComGoogleProtobufDescriptors_FieldDescriptor_JavaType_Enum_BYTE_STRING: \ - case ComGoogleProtobufDescriptors_FieldDescriptor_JavaType_Enum_MESSAGE: \ - CASE_MACRO(Retainable) \ - case ComGoogleProtobufDescriptors_FieldDescriptor_JavaType_Enum_ENUM: \ - CASE_MACRO(Enum) \ - } - - -// Declares the given macro once for each java field type, grouping enums and -// the other object types together as "Id". Non-retainable types use the -// PRIMITIVE_TYPE_MACRO, retainable types use the RETAINABLE_TYPE_MACRO -#define FOR_EACH_TYPE_NO_ENUM(PRIMITIVE_TYPE_MACRO, RETAINABLE_TYPE_MACRO) \ - PRIMITIVE_TYPE_MACRO(Int) \ - PRIMITIVE_TYPE_MACRO(Long) \ - PRIMITIVE_TYPE_MACRO(Float) \ - PRIMITIVE_TYPE_MACRO(Double) \ - PRIMITIVE_TYPE_MACRO(Bool) \ - RETAINABLE_TYPE_MACRO(Id) - - -// Declares the given macro once for each java field type, declaring it -// separately for enums (as "Enum) and the other object types (as "Retainable"). -#define FOR_EACH_TYPE_WITH_ENUM(MACRO) \ - MACRO(Int) \ - MACRO(Long) \ - MACRO(Float) \ - MACRO(Double) \ - MACRO(Bool) \ - MACRO(Enum) \ - MACRO(Retainable) - // Declares the given macro once for each java field type except for retainable -//types. -#define FOR_EACH_TYPE_NO_RETAINABLE(MACRO) \ - MACRO(Int) \ - MACRO(Long) \ - MACRO(Float) \ - MACRO(Double) \ - MACRO(Bool) \ - MACRO(Enum) +// types. +#define FOR_EACH_PRIMITIVE_TYPE(PRIMITIVE_TYPE_MACRO) \ + PRIMITIVE_TYPE_MACRO(Int) \ + PRIMITIVE_TYPE_MACRO(Long) \ + PRIMITIVE_TYPE_MACRO(Float) \ + PRIMITIVE_TYPE_MACRO(Double) \ + PRIMITIVE_TYPE_MACRO(Bool) + +#define FOR_EACH_TYPE(TYPE_MACRO) \ + FOR_EACH_PRIMITIVE_TYPE(TYPE_MACRO) \ + TYPE_MACRO(Enum) \ + TYPE_MACRO(Id) // The remainder of this file is copied from the translation of the types // FieldDescriptor.Type and FieldDescriptor.JavaType in Descriptor.java. @@ -218,7 +161,7 @@ typedef NS_ENUM(NSUInteger, ComGoogleProtobufDescriptors_FieldDescriptor_Type_En typedef ComGoogleProtobufDescriptors_FieldDescriptor_Type_Enum CGPFieldType; -@interface ComGoogleProtobufDescriptors_FieldDescriptor_Type : JavaLangEnum < NSCopying > +@interface ComGoogleProtobufDescriptors_FieldDescriptor_Type : JavaLangEnum #pragma mark Public @@ -226,7 +169,9 @@ typedef ComGoogleProtobufDescriptors_FieldDescriptor_Type_Enum CGPFieldType; - (ComGoogleProtobufDescriptorProtos_FieldDescriptorProto_Type *)toProto; -+ (ComGoogleProtobufDescriptors_FieldDescriptor_Type *)valueOfWithComGoogleProtobufDescriptorProtos_FieldDescriptorProto_Type:(ComGoogleProtobufDescriptorProtos_FieldDescriptorProto_Type *)type; ++ (ComGoogleProtobufDescriptors_FieldDescriptor_Type *) + valueOfWithComGoogleProtobufDescriptorProtos_FieldDescriptorProto_Type: + (ComGoogleProtobufDescriptorProtos_FieldDescriptorProto_Type *)type; #pragma mark Package-Private @@ -241,7 +186,8 @@ typedef ComGoogleProtobufDescriptors_FieldDescriptor_Type_Enum CGPFieldType; J2OBJC_STATIC_INIT(ComGoogleProtobufDescriptors_FieldDescriptor_Type) /*! INTERNAL ONLY - Use enum accessors declared below. */ -FOUNDATION_EXPORT ComGoogleProtobufDescriptors_FieldDescriptor_Type *ComGoogleProtobufDescriptors_FieldDescriptor_Type_values_[]; +FOUNDATION_EXPORT ComGoogleProtobufDescriptors_FieldDescriptor_Type + *ComGoogleProtobufDescriptors_FieldDescriptor_Type_values_[]; inline ComGoogleProtobufDescriptors_FieldDescriptor_Type * ComGoogleProtobufDescriptors_FieldDescriptor_Type_get_DOUBLE(void); @@ -315,13 +261,17 @@ inline ComGoogleProtobufDescriptors_FieldDescriptor_Type * ComGoogleProtobufDescriptors_FieldDescriptor_Type_get_SINT64(void); J2OBJC_ENUM_CONSTANT(ComGoogleProtobufDescriptors_FieldDescriptor_Type, SINT64) -FOUNDATION_EXPORT ComGoogleProtobufDescriptors_FieldDescriptor_Type *ComGoogleProtobufDescriptors_FieldDescriptor_Type_valueOfWithComGoogleProtobufDescriptorProtos_FieldDescriptorProto_Type_(ComGoogleProtobufDescriptorProtos_FieldDescriptorProto_Type *type); +FOUNDATION_EXPORT ComGoogleProtobufDescriptors_FieldDescriptor_Type * +ComGoogleProtobufDescriptors_FieldDescriptor_Type_valueOfWithComGoogleProtobufDescriptorProtos_FieldDescriptorProto_Type_( + ComGoogleProtobufDescriptorProtos_FieldDescriptorProto_Type *type); FOUNDATION_EXPORT IOSObjectArray *ComGoogleProtobufDescriptors_FieldDescriptor_Type_values(void); -FOUNDATION_EXPORT ComGoogleProtobufDescriptors_FieldDescriptor_Type *ComGoogleProtobufDescriptors_FieldDescriptor_Type_valueOfWithNSString_(NSString *name); +FOUNDATION_EXPORT ComGoogleProtobufDescriptors_FieldDescriptor_Type * +ComGoogleProtobufDescriptors_FieldDescriptor_Type_valueOfWithNSString_(NSString *name); -FOUNDATION_EXPORT ComGoogleProtobufDescriptors_FieldDescriptor_Type *ComGoogleProtobufDescriptors_FieldDescriptor_Type_fromOrdinal(NSUInteger ordinal); +FOUNDATION_EXPORT ComGoogleProtobufDescriptors_FieldDescriptor_Type * +ComGoogleProtobufDescriptors_FieldDescriptor_Type_fromOrdinal(NSUInteger ordinal); J2OBJC_TYPE_LITERAL_HEADER(ComGoogleProtobufDescriptors_FieldDescriptor_Type) @@ -337,7 +287,7 @@ typedef NS_ENUM(NSUInteger, ComGoogleProtobufDescriptors_FieldDescriptor_JavaTyp ComGoogleProtobufDescriptors_FieldDescriptor_JavaType_Enum_MESSAGE = 8, }; -@interface ComGoogleProtobufDescriptors_FieldDescriptor_JavaType : JavaLangEnum < NSCopying > +@interface ComGoogleProtobufDescriptors_FieldDescriptor_JavaType : JavaLangEnum #pragma mark Package-Private @@ -352,7 +302,8 @@ typedef NS_ENUM(NSUInteger, ComGoogleProtobufDescriptors_FieldDescriptor_JavaTyp J2OBJC_STATIC_INIT(ComGoogleProtobufDescriptors_FieldDescriptor_JavaType) /*! INTERNAL ONLY - Use enum accessors declared below. */ -FOUNDATION_EXPORT ComGoogleProtobufDescriptors_FieldDescriptor_JavaType *ComGoogleProtobufDescriptors_FieldDescriptor_JavaType_values_[]; +FOUNDATION_EXPORT ComGoogleProtobufDescriptors_FieldDescriptor_JavaType + *ComGoogleProtobufDescriptors_FieldDescriptor_JavaType_values_[]; inline ComGoogleProtobufDescriptors_FieldDescriptor_JavaType * ComGoogleProtobufDescriptors_FieldDescriptor_JavaType_get_INT(void); @@ -393,10 +344,12 @@ J2OBJC_ENUM_CONSTANT(ComGoogleProtobufDescriptors_FieldDescriptor_JavaType, MESS FOUNDATION_EXPORT IOSObjectArray *ComGoogleProtobufDescriptors_FieldDescriptor_JavaType_values( void); -FOUNDATION_EXPORT ComGoogleProtobufDescriptors_FieldDescriptor_JavaType *ComGoogleProtobufDescriptors_FieldDescriptor_JavaType_valueOfWithNSString_(NSString *name); +FOUNDATION_EXPORT ComGoogleProtobufDescriptors_FieldDescriptor_JavaType * +ComGoogleProtobufDescriptors_FieldDescriptor_JavaType_valueOfWithNSString_(NSString *name); -FOUNDATION_EXPORT ComGoogleProtobufDescriptors_FieldDescriptor_JavaType *ComGoogleProtobufDescriptors_FieldDescriptor_JavaType_fromOrdinal(NSUInteger ordinal); +FOUNDATION_EXPORT ComGoogleProtobufDescriptors_FieldDescriptor_JavaType * +ComGoogleProtobufDescriptors_FieldDescriptor_JavaType_fromOrdinal(NSUInteger ordinal); J2OBJC_TYPE_LITERAL_HEADER(ComGoogleProtobufDescriptors_FieldDescriptor_JavaType) -#endif // __ComGoogleProtobufFieldTypes_H__ +#endif // __ComGoogleProtobufFieldTypes_H__ diff --git a/protobuf/runtime/src/com/google/protobuf/GeneratedMessage.mm b/protobuf/runtime/src/com/google/protobuf/GeneratedMessage.mm index 0027d399ff..006ba9d2e8 100644 --- a/protobuf/runtime/src/com/google/protobuf/GeneratedMessage.mm +++ b/protobuf/runtime/src/com/google/protobuf/GeneratedMessage.mm @@ -71,8 +71,8 @@ #define NIL_CHECK_Float(value) #define NIL_CHECK_Double(value) #define NIL_CHECK_Bool(value) -#define NIL_CHECK_Enum(value) (void)nil_chk(value); -#define NIL_CHECK_Retainable(value) (void)nil_chk(value); +#define NIL_CHECK_Enum(value) (void)nil_chk(value) +#define NIL_CHECK_Id(value) (void)nil_chk(value) // Forward declarations. class CGPExtensionValue; @@ -90,33 +90,17 @@ static inline int SerializedSizeForMessage(ComGoogleProtobufGeneratedMessage *ms static void MessageToString(id msg, CGPDescriptor *descriptor, NSMutableString *builder, int indent); -#define REPEATED_PRIMITIVE_FIELD_GETTER_IMP(NAME) \ - CGP_ALWAYS_INLINE TYPE_##NAME CGPRepeatedFieldGet##NAME(CGPRepeatedField *field, jint idx) { \ - CGPRepeatedFieldCheckBounds(field, idx); \ - return ((TYPE_##NAME *)field->data->buffer)[idx]; \ - } - -#define REPEATED_RETAINABLE_FIELD_GETTER_IMP(NAME) \ - CGP_ALWAYS_INLINE TYPE_##NAME CGPRepeatedFieldGet##NAME(CGPRepeatedField *field, jint idx) { \ - CGPRepeatedFieldCheckBounds(field, idx); \ - return RETAIN_AND_AUTORELEASE(((TYPE_##NAME *)field->data->buffer)[idx]); \ - } - -FOR_EACH_TYPE_NO_ENUM(REPEATED_PRIMITIVE_FIELD_GETTER_IMP, REPEATED_RETAINABLE_FIELD_GETTER_IMP) - -#undef REPEATED_PRIMITIVE_FIELD_GETTER_IMP -#undef REPEATED_RETAINABLE_FIELD_GETTER_IMP - #define REPEATED_FIELD_ADDER_IMP(NAME) \ CGP_ALWAYS_INLINE void CGPRepeatedFieldAdd##NAME(CGPRepeatedField *field, TYPE_##NAME value) { \ uint32_t total_size = CGPRepeatedFieldTotalSize(field); \ if (CGPRepeatedFieldSize(field) == total_size) { \ CGPRepeatedFieldReserve(field, total_size + 1, sizeof(TYPE_##NAME)); \ } \ - ((TYPE_##NAME *)field->data->buffer)[field->data->size++] = TYPE_RETAIN_##NAME(value); \ + TYPE_##NAME *ptr = &((TYPE_##NAME *)field->data->buffer)[field->data->size++]; \ + TYPE_ASSIGN_##NAME(ptr, value); \ } -FOR_EACH_TYPE_WITH_ENUM(REPEATED_FIELD_ADDER_IMP) +FOR_EACH_TYPE(REPEATED_FIELD_ADDER_IMP) #undef REPEATED_FIELD_ADDER_IMP @@ -125,10 +109,10 @@ static void MessageToString(id msg, CGPDescriptor *descriptor, NSMutableString * TYPE_##NAME value) { \ CGPRepeatedFieldCheckBounds(field, idx); \ TYPE_##NAME *ptr = &((TYPE_##NAME *)field->data->buffer)[idx]; \ - TYPE_ASSIGN_##NAME(*ptr, value); \ + TYPE_ASSIGN_##NAME(ptr, value); \ } -FOR_EACH_TYPE_WITH_ENUM(REPEATED_FIELD_SETTER_IMP) +FOR_EACH_TYPE(REPEATED_FIELD_SETTER_IMP) #undef REPEATED_FIELD_SETTER_IMP @@ -302,23 +286,26 @@ static inline BOOL ClearPreviousOneof(id msg, CGPHasLocator loc, uintptr_t ptr) return wasCleared; } -#define REPEATED_FIELD_PTR(msg, offset) ((CGPRepeatedField *)((uint8_t *)msg + offset)) -#define MAP_FIELD_PTR(msg, offset) ((CGPMapField *)((uint8_t *)msg + offset)) +CGP_ALWAYS_INLINE CGPRepeatedField *REPEATED_FIELD_PTR(id msg, ptrdiff_t offset) { + return (CGPRepeatedField *)((uint8_t *)msg + offset); +} +CGP_ALWAYS_INLINE CGPMapField *MAP_FIELD_PTR(id msg, ptrdiff_t offset) { + return (CGPMapField *)((uint8_t *)msg + offset); +} #define FIELD_PTR(TYPE, msg, offset) ((TYPE *)((uint8_t *)msg + offset)) #define SINGULAR_SETTER_IMP(NAME) \ static void SingularSet##NAME(id msg, TYPE_##NAME value, size_t offset, CGPHasLocator hasLoc) { \ TYPE_##NAME *ptr = FIELD_PTR(TYPE_##NAME, msg, offset); \ ClearPreviousOneof(msg, hasLoc, (uintptr_t)ptr); \ - TYPE_ASSIGN_##NAME(*ptr, value); \ + TYPE_ASSIGN_##NAME(ptr, value); \ SetHas(msg, hasLoc); \ } -FOR_EACH_TYPE_NO_RETAINABLE(SINGULAR_SETTER_IMP) +FOR_EACH_PRIMITIVE_TYPE(SINGULAR_SETTER_IMP) -static void SingularSetRetainable(id msg, TYPE_Retainable value, size_t offset, - CGPHasLocator hasLoc) { - TYPE_Retainable *ptr = FIELD_PTR(TYPE_Retainable, msg, offset); +static void SingularSetId(id msg, TYPE_Id value, size_t offset, CGPHasLocator hasLoc) { + TYPE_Id *ptr = FIELD_PTR(TYPE_Id, msg, offset); if (!ClearPreviousOneof(msg, hasLoc, (uintptr_t)ptr)) { // If it is not a one of field, we need to release the previous value. // Otherwise ClearPreviousOneof has already done it for us if necessary. @@ -328,49 +315,43 @@ static void SingularSetRetainable(id msg, TYPE_Retainable value, size_t offset, SetHas(msg, hasLoc); } +static void SingularSetEnum(id msg, TYPE_Enum value, size_t offset, CGPHasLocator hasLoc) { + TYPE_Enum *ptr = FIELD_PTR(TYPE_Enum, msg, offset); + ClearPreviousOneof(msg, hasLoc, (uintptr_t)ptr); + TYPE_ASSIGN_Enum(ptr, value); + SetHas(msg, hasLoc); +} + #undef SINGULAR_SETTER_IMP // ***************************************************************************** // ********** Dynamic field accessors ****************************************** // ***************************************************************************** -#define SINGULAR_PRIMITIVE_GETTER_IMP(NAME) \ - static IMP GetSingularGetterImp##NAME(size_t offset, CGPHasLocator hasLoc, \ - TYPE_##NAME defaultValue) { \ - return imp_implementationWithBlock(^TYPE_##NAME(id msg) { \ - if (GetHas(msg, hasLoc)) { \ - return *FIELD_PTR(TYPE_##NAME, msg, offset); \ - } \ - return defaultValue; \ - }); \ - } - -#define SINGULAR_RETAINABLE_GETTER_IMP(NAME) \ - static IMP GetSingularGetterImp##NAME(size_t offset, CGPHasLocator hasLoc, \ - TYPE_##NAME defaultValue) { \ - return imp_implementationWithBlock(^TYPE_##NAME(id msg) { \ - if (GetHas(msg, hasLoc)) { \ - return RETAIN_AND_AUTORELEASE(*FIELD_PTR(TYPE_##NAME, msg, offset)); \ - } \ - return defaultValue; \ - }); \ +#define SINGULAR_GETTER_IMP(NAME) \ + static IMP GetSingularGetterImp##NAME(size_t offset, CGPHasLocator hasLoc, \ + TYPE_##NAME defaultValue) { \ + return imp_implementationWithBlock(^EXTERNAL_TYPE_##NAME(id msg) { \ + TYPE_##NAME value = \ + GetHas(msg, hasLoc) ? *FIELD_PTR(TYPE_##NAME, msg, offset) : defaultValue; \ + return ToExternalType##NAME(value); \ + }); \ } -FOR_EACH_TYPE_NO_ENUM(SINGULAR_PRIMITIVE_GETTER_IMP, SINGULAR_RETAINABLE_GETTER_IMP) +FOR_EACH_TYPE(SINGULAR_GETTER_IMP) -#undef SINGULAR_PRIMITIVE_GETTER_IMP -#undef SINGULAR_RETAINABLE_GETTER_IMP +#undef SINGULAR_GETTER_IMP -#define REPEATED_GETTER_IMP(NAME) \ - static IMP GetRepeatedGetterImp##NAME(size_t offset) { \ - return imp_implementationWithBlock(^TYPE_##NAME(id msg, jint idx) { \ - return CGPRepeatedFieldGet##NAME(REPEATED_FIELD_PTR(msg, offset), idx); \ - }); \ +#define REPEATED_GETTER_IMP(NAME) \ + static IMP GetRepeatedGetterImp##NAME(size_t offset) { \ + return imp_implementationWithBlock(^EXTERNAL_TYPE_##NAME(id msg, jint idx) { \ + CGPRepeatedField *field = REPEATED_FIELD_PTR(msg, offset); \ + CGPRepeatedFieldCheckBounds(field, idx); \ + return ToExternalType##NAME(((TYPE_##NAME *)field->data->buffer)[idx]); \ + }); \ } -// Same macro for all types, uses getter functions defined earlier that -// already handle primitive vs retainable. -FOR_EACH_TYPE_NO_ENUM(REPEATED_GETTER_IMP, REPEATED_GETTER_IMP) +FOR_EACH_TYPE(REPEATED_GETTER_IMP) #undef REPEATED_GETTER_IMP @@ -385,10 +366,10 @@ static BOOL AddGetterMethod(Class cls, SEL sel, CGPFieldDescriptor *field) { imp = repeated \ ? GetRepeatedGetterImp##NAME(offset) \ : GetSingularGetterImp##NAME(offset, hasLoc, field->data_->defaultValue.value##NAME); \ - strcpy(encoding, @encode(TYPE_##NAME)); \ - break; + strcpy(encoding, @encode(TYPE_##NAME)); - SWITCH_TYPES_NO_ENUM(CGPFieldGetJavaType(field), ADD_GETTER_METHOD_CASE) + SWITCH_TYPES(CGPFieldGetJavaType(field), ADD_GETTER_METHOD_CASE, ADD_GETTER_METHOD_CASE, + ADD_GETTER_METHOD_CASE) #undef ADD_GETTER_METHOD_CASE @@ -505,28 +486,31 @@ static BOOL AddClearMethod(Class cls, SEL sel, CGPFieldDescriptor *field) { return class_addMethod(cls, sel, imp, "@@:"); } -#define GET_SINGULAR_SETTER_IMP(NAME) \ - static IMP GetSingularSetterImp##NAME(size_t offset, CGPHasLocator hasLoc) { \ - return imp_implementationWithBlock(^id(id msg, TYPE_##NAME value) { \ - NIL_CHECK_##NAME(value) SingularSet##NAME(msg, value, offset, hasLoc); \ - return msg; \ - }); \ +#define GET_SINGULAR_SETTER_IMP(NAME) \ + static IMP GetSingularSetterImp##NAME(size_t offset, CGPHasLocator hasLoc) { \ + return imp_implementationWithBlock(^id(id msg, EXTERNAL_TYPE_##NAME value) { \ + NIL_CHECK_##NAME(value); \ + TYPE_##NAME internalValue = ToType##NAME(value); \ + SingularSet##NAME(msg, internalValue, offset, hasLoc); \ + return msg; \ + }); \ } -FOR_EACH_TYPE_WITH_ENUM(GET_SINGULAR_SETTER_IMP) +FOR_EACH_TYPE(GET_SINGULAR_SETTER_IMP) #undef GET_SINGULAR_SETTER_IMP -#define GET_REPEATED_SETTER_IMP(NAME) \ - static IMP GetRepeatedSetterImp##NAME(size_t offset) { \ - return imp_implementationWithBlock(^id(id msg, jint idx, TYPE_##NAME value) { \ - NIL_CHECK_##NAME(value) \ - CGPRepeatedFieldSet##NAME(REPEATED_FIELD_PTR(msg, offset), idx, value); \ - return msg; \ - }); \ +#define GET_REPEATED_SETTER_IMP(NAME) \ + static IMP GetRepeatedSetterImp##NAME(size_t offset) { \ + return imp_implementationWithBlock(^id(id msg, jint idx, EXTERNAL_TYPE_##NAME value) { \ + NIL_CHECK_##NAME(value); \ + TYPE_##NAME internalValue = ToType##NAME(value); \ + CGPRepeatedFieldSet##NAME(REPEATED_FIELD_PTR(msg, offset), idx, internalValue); \ + return msg; \ + }); \ } -FOR_EACH_TYPE_WITH_ENUM(GET_REPEATED_SETTER_IMP) +FOR_EACH_TYPE(GET_REPEATED_SETTER_IMP) #undef GET_REPEATED_SETTER_IMP @@ -543,10 +527,10 @@ static BOOL AddSetterMethod(Class cls, SEL sel, CGPFieldDescriptor *field) { #define ADD_SETTER_METHOD_CASE(NAME) \ imp = repeated ? GetRepeatedSetterImp##NAME(offset) \ : GetSingularSetterImp##NAME(offset, GetHasLocator(cls, field)); \ - strcat(encoding, @encode(TYPE_##NAME)); \ - break; + strcat(encoding, @encode(TYPE_##NAME)); - SWITCH_TYPES_WITH_ENUM(CGPFieldGetJavaType(field), ADD_SETTER_METHOD_CASE) + SWITCH_TYPES(CGPFieldGetJavaType(field), ADD_SETTER_METHOD_CASE, ADD_SETTER_METHOD_CASE, + ADD_SETTER_METHOD_CASE) #undef ADD_SETTER_METHOD_CASE @@ -572,15 +556,17 @@ static BOOL AddBuilderSetterMethod(Class cls, SEL sel, CGPFieldDescriptor *field return class_addMethod(cls, sel, imp, "@@:@"); } -#define GET_ADDER_IMP(NAME) \ - static IMP GetAdderImp##NAME(size_t offset) { \ - return imp_implementationWithBlock(^id(id msg, TYPE_##NAME value) { \ - NIL_CHECK_##NAME(value) CGPRepeatedFieldAdd##NAME(REPEATED_FIELD_PTR(msg, offset), value); \ - return msg; \ - }); \ +#define GET_ADDER_IMP(NAME) \ + static IMP GetAdderImp##NAME(size_t offset) { \ + return imp_implementationWithBlock(^id(id msg, EXTERNAL_TYPE_##NAME value) { \ + NIL_CHECK_##NAME(value); \ + TYPE_##NAME internalValue = ToType##NAME(value); \ + CGPRepeatedFieldAdd##NAME(REPEATED_FIELD_PTR(msg, offset), internalValue); \ + return msg; \ + }); \ } -FOR_EACH_TYPE_WITH_ENUM(GET_ADDER_IMP) +FOR_EACH_TYPE(GET_ADDER_IMP) #undef GET_ADDER_IMP @@ -590,12 +576,12 @@ static BOOL AddAdderMethod(Class cls, SEL sel, CGPFieldDescriptor *field) { strcpy(encoding, "@@:"); size_t offset = CGPFieldGetOffset(field, cls); -#define ADD_ADDER_METHOD_CASE(NAME) \ - imp = GetAdderImp##NAME(offset); \ - strcat(encoding, @encode(TYPE_##NAME)); \ - break; +#define ADD_ADDER_METHOD_CASE(NAME) \ + imp = GetAdderImp##NAME(offset); \ + strcat(encoding, @encode(TYPE_##NAME)); - SWITCH_TYPES_WITH_ENUM(CGPFieldGetJavaType(field), ADD_ADDER_METHOD_CASE) + SWITCH_TYPES(CGPFieldGetJavaType(field), ADD_ADDER_METHOD_CASE, ADD_ADDER_METHOD_CASE, + ADD_ADDER_METHOD_CASE) #undef ADD_ADDER_METHOD_CASE @@ -607,7 +593,7 @@ static BOOL AddBuilderAdderMethod(Class cls, SEL sel, CGPFieldDescriptor *field) IMP imp = imp_implementationWithBlock(^id(id msg, ComGoogleProtobufGeneratedMessage_Builder *value) { (void)nil_chk(value); - CGPRepeatedFieldAddRetainable(REPEATED_FIELD_PTR(msg, offset), [value build]); + CGPRepeatedFieldAddId(REPEATED_FIELD_PTR(msg, offset), [value build]); return msg; }); return class_addMethod(cls, sel, imp, "@@:@"); @@ -624,7 +610,7 @@ static BOOL AddBuilderAdderMethod(Class cls, SEL sel, CGPFieldDescriptor *field) }); \ } -FOR_EACH_TYPE_WITH_ENUM(GET_ADD_ALL_IMP) +FOR_EACH_TYPE(GET_ADD_ALL_IMP) #undef GET_ADD_ALL_IMP @@ -632,11 +618,10 @@ static BOOL AddAddAllMethod(Class cls, SEL sel, CGPFieldDescriptor *field) { IMP imp = NULL; size_t offset = CGPFieldGetOffset(field, cls); -#define ADD_ALL_METHOD_CASE(NAME) \ - imp = GetAddAllImp##NAME(offset); \ - break; +#define ADD_ALL_METHOD_CASE(NAME) imp = GetAddAllImp##NAME(offset); - SWITCH_TYPES_WITH_ENUM(CGPFieldGetJavaType(field), ADD_ALL_METHOD_CASE) + SWITCH_TYPES(CGPFieldGetJavaType(field), ADD_ALL_METHOD_CASE, ADD_ALL_METHOD_CASE, + ADD_ALL_METHOD_CASE) #undef ADD_ALL_METHOD_CASE @@ -646,9 +631,9 @@ static BOOL AddAddAllMethod(Class cls, SEL sel, CGPFieldDescriptor *field) { #define GET_CONTAINS_IMP(NAME) \ static IMP GetContainsImp##NAME(size_t offset, CGPFieldJavaType keyType, \ CGPFieldJavaType valueType) { \ - return imp_implementationWithBlock(^bool(id msg, TYPE_##NAME pKey) { \ + return imp_implementationWithBlock(^bool(id msg, EXTERNAL_TYPE_##NAME pKey) { \ CGPValue key; \ - key.CGPValueField_##NAME = pKey; \ + key.CGPValueField_##NAME = ToType##NAME(pKey); \ return CGPMapFieldGetWithKey(MAP_FIELD_PTR(msg, offset), key, keyType, valueType) != nil; \ }); \ } @@ -696,83 +681,46 @@ static BOOL AddContainsMethod(Class cls, SEL sel, CGPFieldDescriptor *field) { return class_addMethod(cls, sel, imp, encoding); } -#define GET_MAP_PRIMITIVE_GETTER_IMP(KEY_NAME, VALUE_NAME) \ +#define GET_MAP_GETTER_IMP(KEY_NAME, VALUE_NAME) \ static IMP GetMapGetOrThrowImp##KEY_NAME##VALUE_NAME(size_t offset, CGPFieldJavaType keyType, \ CGPFieldJavaType valueType) { \ - return imp_implementationWithBlock(^TYPE_##VALUE_NAME(id msg, TYPE_##KEY_NAME pKey) { \ - CGPValue key; \ - key.CGPValueField_##KEY_NAME = pKey; \ - CGPMapFieldEntry *entry = \ - CGPMapFieldGetWithKey(MAP_FIELD_PTR(msg, offset), key, keyType, valueType); \ - if (entry) { \ - return entry->value.CGPValueField_##VALUE_NAME; \ - } \ - @throw create_JavaLangIllegalArgumentException_init(); \ - }); \ - } \ - static IMP GetMapGetOrDefaultImp##KEY_NAME##VALUE_NAME(size_t offset, CGPFieldJavaType keyType, \ - CGPFieldJavaType valueType) { \ return imp_implementationWithBlock( \ - ^TYPE_##VALUE_NAME(id msg, TYPE_##KEY_NAME pKey, TYPE_##VALUE_NAME defaultValue) { \ + ^EXTERNAL_TYPE_##VALUE_NAME(id msg, EXTERNAL_TYPE_##KEY_NAME pKey) { \ CGPValue key; \ - key.CGPValueField_##KEY_NAME = pKey; \ + key.CGPValueField_##KEY_NAME = ToType##KEY_NAME(pKey); \ CGPMapFieldEntry *entry = \ CGPMapFieldGetWithKey(MAP_FIELD_PTR(msg, offset), key, keyType, valueType); \ if (entry) { \ - return entry->value.CGPValueField_##VALUE_NAME; \ + return ToExternalType##VALUE_NAME(entry->value.CGPValueField_##VALUE_NAME); \ } \ - return defaultValue; \ + @throw create_JavaLangIllegalArgumentException_init(); \ }); \ - } - -#define GET_MAP_RETAINABLE_GETTER_IMP(KEY_NAME, VALUE_NAME) \ - static IMP GetMapGetOrThrowImp##KEY_NAME##VALUE_NAME(size_t offset, CGPFieldJavaType keyType, \ - CGPFieldJavaType valueType) { \ - return imp_implementationWithBlock(^TYPE_##VALUE_NAME(id msg, TYPE_##KEY_NAME pKey) { \ + } \ + static IMP GetMapGetOrDefaultImp##KEY_NAME##VALUE_NAME(size_t offset, CGPFieldJavaType keyType, \ + CGPFieldJavaType valueType) { \ + return imp_implementationWithBlock(^EXTERNAL_TYPE_##VALUE_NAME( \ + id msg, EXTERNAL_TYPE_##KEY_NAME pKey, TYPE_##VALUE_NAME defaultValue) { \ CGPValue key; \ - key.CGPValueField_##KEY_NAME = pKey; \ + key.CGPValueField_##KEY_NAME = ToType##KEY_NAME(pKey); \ CGPMapFieldEntry *entry = \ CGPMapFieldGetWithKey(MAP_FIELD_PTR(msg, offset), key, keyType, valueType); \ if (entry) { \ - return RETAIN_AND_AUTORELEASE(entry->value.CGPValueField_##VALUE_NAME); \ + return ToExternalType##VALUE_NAME(entry->value.CGPValueField_##VALUE_NAME); \ } \ - @throw create_JavaLangIllegalArgumentException_init(); \ + return ToExternalType##VALUE_NAME(defaultValue); \ }); \ - } \ - static IMP GetMapGetOrDefaultImp##KEY_NAME##VALUE_NAME(size_t offset, CGPFieldJavaType keyType, \ - CGPFieldJavaType valueType) { \ - return imp_implementationWithBlock( \ - ^TYPE_##VALUE_NAME(id msg, TYPE_##KEY_NAME pKey, TYPE_##VALUE_NAME defaultValue) { \ - CGPValue key; \ - key.CGPValueField_##KEY_NAME = pKey; \ - CGPMapFieldEntry *entry = \ - CGPMapFieldGetWithKey(MAP_FIELD_PTR(msg, offset), key, keyType, valueType); \ - if (entry) { \ - return RETAIN_AND_AUTORELEASE(entry->value.CGPValueField_##VALUE_NAME); \ - } \ - return defaultValue; \ - }); \ } -#define GET_MAP_PRIMITIVE_GETTER_IMP_FOR_VALUE(VALUE_NAME) \ - GET_MAP_PRIMITIVE_GETTER_IMP(Int, VALUE_NAME) \ - GET_MAP_PRIMITIVE_GETTER_IMP(Long, VALUE_NAME) \ - GET_MAP_PRIMITIVE_GETTER_IMP(Bool, VALUE_NAME) \ - GET_MAP_PRIMITIVE_GETTER_IMP(Id, VALUE_NAME) +#define GET_MAP_GETTER_IMP_FOR_VALUE(VALUE_NAME) \ + GET_MAP_GETTER_IMP(Int, VALUE_NAME) \ + GET_MAP_GETTER_IMP(Long, VALUE_NAME) \ + GET_MAP_GETTER_IMP(Bool, VALUE_NAME) \ + GET_MAP_GETTER_IMP(Id, VALUE_NAME) -#define GET_MAP_RETAINABLE_GETTER_IMP_FOR_VALUE(VALUE_NAME) \ - GET_MAP_RETAINABLE_GETTER_IMP(Int, VALUE_NAME) \ - GET_MAP_RETAINABLE_GETTER_IMP(Long, VALUE_NAME) \ - GET_MAP_RETAINABLE_GETTER_IMP(Bool, VALUE_NAME) \ - GET_MAP_RETAINABLE_GETTER_IMP(Id, VALUE_NAME) +FOR_EACH_TYPE(GET_MAP_GETTER_IMP_FOR_VALUE) -FOR_EACH_TYPE_NO_ENUM(GET_MAP_PRIMITIVE_GETTER_IMP_FOR_VALUE, - GET_MAP_RETAINABLE_GETTER_IMP_FOR_VALUE) - -#undef GET_MAP_PRIMITIVE_GETTER_IMP -#undef GET_MAP_RETAINABLE_GETTER_IMP -#undef GET_MAP_PRIMITIVE_GETTER_IMP_FOR_VALUE -#undef GET_MAP_RETAINABLE_GETTER_IMP_FOR_VALUE +#undef GET_MAP_GETTER_IMP +#undef GET_MAP_GETTER_IMP_FOR_VALUE static BOOL AddMapGetWithKeyMethod(Class cls, SEL sel, CGPFieldDescriptor *field, bool orDefault) { IMP imp = NULL; @@ -808,10 +756,9 @@ static BOOL AddMapGetWithKeyMethod(Class cls, SEL sel, CGPFieldDescriptor *field } \ if (orDefault) { \ strcat(encoding, @encode(TYPE_##VALUE_NAME)); \ - } \ - break; + } - SWITCH_TYPES_NO_ENUM(valueType, MAP_GETTER_INNER_SWITCH) + SWITCH_TYPES(valueType, MAP_GETTER_INNER_SWITCH, MAP_GETTER_INNER_SWITCH, MAP_GETTER_INNER_SWITCH) #undef MAP_GETTER_CASE #undef MAP_GETTER_INNER_SWITCH @@ -819,19 +766,19 @@ static BOOL AddMapGetWithKeyMethod(Class cls, SEL sel, CGPFieldDescriptor *field return class_addMethod(cls, sel, imp, encoding); } -#define GET_PUT_IMP(KEY_NAME, VALUE_NAME) \ - static IMP GetPutImp##KEY_NAME##VALUE_NAME(size_t offset, CGPFieldJavaType keyType, \ - CGPFieldJavaType valueType) { \ - return imp_implementationWithBlock( \ - ^id(id msg, TYPE_##KEY_NAME pKey, TYPE_##VALUE_NAME pValue) { \ - CGPValue key; \ - key.CGPValueField_##KEY_NAME = pKey; \ - CGPValue value; \ - value.CGPValueField_##VALUE_NAME = pValue; \ - CGPMapFieldPut(MAP_FIELD_PTR(msg, offset), key, keyType, value, valueType, \ - /* retainedKeyAndValue */ false); \ - return msg; \ - }); \ +#define GET_PUT_IMP(KEY_NAME, VALUE_NAME) \ + static IMP GetPutImp##KEY_NAME##VALUE_NAME(size_t offset, CGPFieldJavaType keyType, \ + CGPFieldJavaType valueType) { \ + return imp_implementationWithBlock( \ + ^id(id msg, EXTERNAL_TYPE_##KEY_NAME pKey, EXTERNAL_TYPE_##VALUE_NAME pValue) { \ + CGPValue key; \ + key.CGPValueField_##KEY_NAME = ToType##KEY_NAME(pKey); \ + CGPValue value; \ + value.CGPValueField_##VALUE_NAME = ToType##VALUE_NAME(pValue); \ + CGPMapFieldPut(MAP_FIELD_PTR(msg, offset), key, keyType, value, valueType, \ + /* retainedKeyAndValue */ false); \ + return msg; \ + }); \ } #define GET_PUT_IMP_FOR_VALUE(VALUE_NAME) \ @@ -841,7 +788,7 @@ static BOOL AddMapGetWithKeyMethod(Class cls, SEL sel, CGPFieldDescriptor *field GET_PUT_IMP(Id, VALUE_NAME) // No difference in put implementation by type, CGPMapFieldPut() handles both types. -FOR_EACH_TYPE_NO_ENUM(GET_PUT_IMP_FOR_VALUE, GET_PUT_IMP_FOR_VALUE) +FOR_EACH_TYPE(GET_PUT_IMP_FOR_VALUE) #undef GET_PUT_IMP #undef GET_PUT_IMP_FOR_VALUE @@ -876,10 +823,9 @@ static BOOL AddPutMethod(Class cls, SEL sel, CGPFieldDescriptor *field) { case ComGoogleProtobufDescriptors_FieldDescriptor_JavaType_Enum_MESSAGE: \ return NO; \ } \ - strcat(encoding, @encode(TYPE_##VALUE_NAME)); \ - break; + strcat(encoding, @encode(TYPE_##VALUE_NAME)); - SWITCH_TYPES_NO_ENUM(valueType, PUT_METHOD_INNER_SWITCH) + SWITCH_TYPES(valueType, PUT_METHOD_INNER_SWITCH, PUT_METHOD_INNER_SWITCH, PUT_METHOD_INNER_SWITCH) #undef PUT_METHOD_CASE #undef PUT_METHOD_INNER_SWITCH @@ -887,15 +833,15 @@ static BOOL AddPutMethod(Class cls, SEL sel, CGPFieldDescriptor *field) { return class_addMethod(cls, sel, imp, encoding); } -#define GET_MAP_REMOVE_IMP(NAME) \ - static IMP GetMapRemoveImp##NAME(size_t offset, CGPFieldJavaType keyType, \ - CGPFieldJavaType valueType) { \ - return imp_implementationWithBlock(^id(id msg, TYPE_##NAME pKey) { \ - CGPValue key; \ - key.CGPValueField_##NAME = pKey; \ - CGPMapFieldRemove(MAP_FIELD_PTR(msg, offset), key, keyType, valueType); \ - return msg; \ - }); \ +#define GET_MAP_REMOVE_IMP(NAME) \ + static IMP GetMapRemoveImp##NAME(size_t offset, CGPFieldJavaType keyType, \ + CGPFieldJavaType valueType) { \ + return imp_implementationWithBlock(^id(id msg, EXTERNAL_TYPE_##NAME pKey) { \ + CGPValue key; \ + key.CGPValueField_##NAME = ToType##NAME(pKey); \ + CGPMapFieldRemove(MAP_FIELD_PTR(msg, offset), key, keyType, valueType); \ + return msg; \ + }); \ } GET_MAP_REMOVE_IMP(Int) @@ -1303,7 +1249,7 @@ static id GetSingularField(id msg, CGPFieldDescriptor *field) { return CGPToReflectionType##NAME(value, field); \ } - SWITCH_TYPES_WITH_ENUM(CGPFieldGetJavaType(field), GET_FIELD_CASE) + SWITCH_TYPES(CGPFieldGetJavaType(field), GET_FIELD_CASE, GET_FIELD_CASE, GET_FIELD_CASE) #undef GET_FIELD_CASE @@ -1501,13 +1447,10 @@ static void MergeFieldsFromMessage(id msg, id other, CGPDescriptor *descriptor) } ClearPreviousOneof(msg, hasLoc, fieldPtr); -#define MERGE_FIELD_CASE(NAME) \ - { \ - TYPE_ASSIGN_##NAME(*(TYPE_##NAME *)fieldPtr, *(TYPE_##NAME *)otherFieldPtr); \ - break; \ - } +#define MERGE_FIELD_CASE(NAME) \ + TYPE_ASSIGN_##NAME((TYPE_##NAME *)fieldPtr, *(TYPE_##NAME *)otherFieldPtr); - SWITCH_TYPES_WITH_ENUM(type, MERGE_FIELD_CASE) + SWITCH_TYPES(type, MERGE_FIELD_CASE, MERGE_FIELD_CASE, MERGE_FIELD_CASE) #undef MERGE_FIELD_CASE @@ -1572,7 +1515,7 @@ static id DynamicMergeFromMessage(id builder, SEL _cmd, id other) { // ***************************************************************************** static inline BOOL ReadEnumValueDescriptor(CGPCodedInputStream *input, CGPEnumDescriptor *enumType, - id *valueDescriptor) { + CGPEnumValueDescriptor **valueDescriptor) { jint value; if (!CGPReadEnum(input, &value)) return NO; *valueDescriptor = CGPEnumValueDescriptorFromInt(enumType, value); @@ -1580,7 +1523,7 @@ static inline BOOL ReadEnumValueDescriptor(CGPCodedInputStream *input, CGPEnumDe } static BOOL ReadEnumJavaValue(CGPCodedInputStream *input, CGPEnumDescriptor *enumType, - id *javaValue) { + TYPE_Enum *javaValue) { CGPEnumValueDescriptor *valueDescriptor; if (!ReadEnumValueDescriptor(input, enumType, &valueDescriptor)) return NO; *javaValue = valueDescriptor == nil ? nil : valueDescriptor->enum_; @@ -1643,7 +1586,8 @@ static BOOL ReadMapEntryField(CGPCodedInputStream *stream, CGPFieldDescriptor *f case ComGoogleProtobufDescriptors_FieldDescriptor_Type_Enum_DOUBLE: return CGPReadDouble(stream, &value->valueDouble); case ComGoogleProtobufDescriptors_FieldDescriptor_Type_Enum_ENUM: - return ReadEnumJavaValue(stream, field->valueType_, &value->valueId) && value->valueId != nil; + return ReadEnumJavaValue(stream, field->valueType_, &value->valueEnum) && + value->valueEnum != nil; case ComGoogleProtobufDescriptors_FieldDescriptor_Type_Enum_BYTES: return stream->ReadRetainedByteString(&value->valueId); case ComGoogleProtobufDescriptors_FieldDescriptor_Type_Enum_STRING: @@ -2266,7 +2210,7 @@ static int SerializedSizeForMapEntryField(CGPFieldDescriptor *field, CGPValue va case ComGoogleProtobufDescriptors_FieldDescriptor_Type_Enum_BOOL: return tagSize + 1; case ComGoogleProtobufDescriptors_FieldDescriptor_Type_Enum_ENUM: - return tagSize + CGPGetEnumSize(CGPEnumGetIntValue(field->valueType_, value.valueId)); + return tagSize + CGPGetEnumSize(CGPEnumGetIntValue(field->valueType_, value.valueEnum)); case ComGoogleProtobufDescriptors_FieldDescriptor_Type_Enum_BYTES: return tagSize + CGPGetBytesSize(value.valueId); case ComGoogleProtobufDescriptors_FieldDescriptor_Type_Enum_STRING: @@ -2348,7 +2292,7 @@ static int SerializedSizeForRepeatedField(id msg, CGPFieldDescriptor *field) { break; case ComGoogleProtobufDescriptors_FieldDescriptor_Type_Enum_ENUM: { CGPEnumDescriptor *enumType = field->valueType_; - id *buffer = (id *)data->buffer; + TYPE_Enum *buffer = (TYPE_Enum *)data->buffer; for (uint32_t i = 0; i < arrayLen; i++) { arraySize += CGPGetEnumSize(CGPEnumGetIntValue(enumType, buffer[i])); } @@ -2496,8 +2440,8 @@ static void WriteSingularExtensionValue(CGPFieldDescriptor *field, id value, WRITE_SINGULAR_EXTENSION_CASE(Bool, BOOL, Bool) WRITE_SINGULAR_EXTENSION_CASE(Float, FLOAT, Float) WRITE_SINGULAR_EXTENSION_CASE(Double, DOUBLE, Double) - WRITE_SINGULAR_EXTENSION_CASE(Bytes, BYTES, Retainable) - WRITE_SINGULAR_EXTENSION_CASE(String, STRING, Retainable) + WRITE_SINGULAR_EXTENSION_CASE(Bytes, BYTES, Id) + WRITE_SINGULAR_EXTENSION_CASE(String, STRING, Id) case ComGoogleProtobufDescriptors_FieldDescriptor_Type_Enum_ENUM: CGPWriteEnum(((CGPEnumValueDescriptor *)value)->number_, output); return; @@ -2640,7 +2584,7 @@ static void WriteMapEntryField(CGPFieldDescriptor *field, CGPValue value, CGPWriteDouble(value.valueDouble, output); return; case ComGoogleProtobufDescriptors_FieldDescriptor_Type_Enum_ENUM: - CGPWriteEnum(CGPEnumGetIntValue(field->valueType_, value.valueId), output); + CGPWriteEnum(CGPEnumGetIntValue(field->valueType_, value.valueEnum), output); return; case ComGoogleProtobufDescriptors_FieldDescriptor_Type_Enum_BYTES: CGPWriteBytes(value.valueId, output); @@ -2743,7 +2687,7 @@ static void WriteRepeatedField(id msg, CGPFieldDescriptor *field, CGPCodedOutput WRITE_REPEATED_FIELD_FIXED_LENGTH_CASE(Float, FLOAT, Float, sizeof(uint32_t)) WRITE_REPEATED_FIELD_FIXED_LENGTH_CASE(Double, DOUBLE, Double, sizeof(uint64_t)) case ComGoogleProtobufDescriptors_FieldDescriptor_Type_Enum_ENUM: { - id *buffer = (id *)data->buffer; + TYPE_Enum *buffer = (TYPE_Enum *)data->buffer; CGPEnumDescriptor *enumType = field->valueType_; if (CGPFieldIsPacked(field)) { std::vector intValues(arrayLen); @@ -3041,7 +2985,7 @@ void ValueToString(CGPValue value, CGPFieldDescriptor *field, NSMutableString *b [builder appendFormat:@"%s%s: %g\n", padding, fieldName, value.valueDouble]; return; case ComGoogleProtobufDescriptors_FieldDescriptor_Type_Enum_ENUM: - [builder appendFormat:@"%s%s: %@\n", padding, fieldName, value.valueId]; + [builder appendFormat:@"%s%s: %@\n", padding, fieldName, value.valueEnum]; return; case ComGoogleProtobufDescriptors_FieldDescriptor_Type_Enum_BYTES: [builder appendFormat:@"%s%s: %@\n", padding, fieldName, BytesToString(value.valueId)]; @@ -3193,20 +3137,20 @@ static void MessageToString(id msg, CGPDescriptor *descriptor, NSMutableString * // ********** isEqual and hash ************************************************* // ***************************************************************************** -#define FieldIsEqualInt(a, b) a == b -#define FieldIsEqualLong(a, b) a == b -#define FieldIsEqualFloat(a, b) a == b -#define FieldIsEqualDouble(a, b) a == b -#define FieldIsEqualBool(a, b) a == b -#define FieldIsEqualEnum(a, b) a == b -#define FieldIsEqualRetainable(a, b) a == b || [a isEqual:b] +CGP_ALWAYS_INLINE BOOL FieldIsEqualInt(jint a, jint b) { return a == b; } +CGP_ALWAYS_INLINE BOOL FieldIsEqualLong(jlong a, jlong b) { return a == b; } +CGP_ALWAYS_INLINE BOOL FieldIsEqualFloat(jfloat a, jfloat b) { return a == b; } +CGP_ALWAYS_INLINE BOOL FieldIsEqualDouble(jdouble a, jdouble b) { return a == b; } +CGP_ALWAYS_INLINE BOOL FieldIsEqualBool(bool a, bool b) { return a == b; } +CGP_ALWAYS_INLINE BOOL FieldIsEqualEnum(id a, id b) { return a == b; } +CGP_ALWAYS_INLINE BOOL FieldIsEqualId(id a, id b) { return a == b || [a isEqual:b]; } static BOOL FieldIsEqual(id self, id other, size_t offset, CGPFieldJavaType type) { #define IS_FIELD_EQUAL_CASE(NAME) \ return FieldIsEqual##NAME(*FIELD_PTR(TYPE_##NAME, self, offset), \ *FIELD_PTR(TYPE_##NAME, other, offset)); - SWITCH_TYPES_WITH_ENUM(type, IS_FIELD_EQUAL_CASE) + SWITCH_TYPES(type, IS_FIELD_EQUAL_CASE, IS_FIELD_EQUAL_CASE, IS_FIELD_EQUAL_CASE) #undef IS_FIELD_EQUAL_CASE @@ -3290,10 +3234,10 @@ static int RepeatedFieldHash(id msg, CGPFieldDescriptor *field, int hash) { TYPE_##NAME value = buffer[i]; \ hash = 31 * hash + HASH_##NAME(value); \ } \ - } \ - break; + } - SWITCH_TYPES_NO_ENUM(CGPFieldGetJavaType(field), REPEATED_FIELD_HASH_CASE) + SWITCH_TYPES(CGPFieldGetJavaType(field), REPEATED_FIELD_HASH_CASE, REPEATED_FIELD_HASH_CASE, + REPEATED_FIELD_HASH_CASE) #undef REPEATED_FIELD_HASH_CASE @@ -3314,7 +3258,8 @@ static int SingularFieldHash(id msg, CGPFieldDescriptor *field, int hash) { return 53 * hash + HASH_##NAME(value); \ } - SWITCH_TYPES_NO_ENUM(CGPFieldGetJavaType(field), SINGULAR_FIELD_HASH_CASE) + SWITCH_TYPES(CGPFieldGetJavaType(field), SINGULAR_FIELD_HASH_CASE, SINGULAR_FIELD_HASH_CASE, + SINGULAR_FIELD_HASH_CASE) #undef SINGULAR_FIELD_HASH_CASE @@ -3697,11 +3642,11 @@ - (id)getRepeatedFieldWithComGoogleProtobufDescriptors_FieldDescriptor: } else { CGPHasLocator hasLoc = GetHasLocator(cls, descriptor); -#define SET_SINGULAR_FIELD_CASE(NAME) \ - SingularSet##NAME(self, CGPFromReflectionType##NAME(object), offset, hasLoc); \ - break; +#define SET_SINGULAR_FIELD_CASE(NAME) \ + SingularSet##NAME(self, CGPFromReflectionType##NAME(object), offset, hasLoc); - SWITCH_TYPES_WITH_ENUM(javaType, SET_SINGULAR_FIELD_CASE) + SWITCH_TYPES(javaType, SET_SINGULAR_FIELD_CASE, SET_SINGULAR_FIELD_CASE, + SET_SINGULAR_FIELD_CASE) #undef SET_SINGULAR_FIELD_CASE } diff --git a/protobuf/runtime/src/com/google/protobuf/MapField.m b/protobuf/runtime/src/com/google/protobuf/MapField.m index 5af34ab0e8..e348ecf798 100644 --- a/protobuf/runtime/src/com/google/protobuf/MapField.m +++ b/protobuf/runtime/src/com/google/protobuf/MapField.m @@ -50,7 +50,7 @@ static uint32_t Hash0(CGPValue value, CGPFieldJavaType type) { #define HASH_CASE(NAME) return HASH_##NAME(value.CGPValueField_##NAME); -SWITCH_TYPES_NO_ENUM(type, HASH_CASE) + SWITCH_TYPES(type, HASH_CASE, HASH_CASE, HASH_CASE) #undef HASH_CASE } @@ -76,7 +76,7 @@ static bool Equals(CGPValue a, CGPValue b, CGPFieldJavaType type) { case ComGoogleProtobufDescriptors_FieldDescriptor_JavaType_Enum_BOOLEAN: return a.valueBool == b.valueBool; case ComGoogleProtobufDescriptors_FieldDescriptor_JavaType_Enum_ENUM: - return a.valueId == b.valueId; + return a.valueEnum == b.valueEnum; case ComGoogleProtobufDescriptors_FieldDescriptor_JavaType_Enum_FLOAT: return a.valueFloat == b.valueFloat; case ComGoogleProtobufDescriptors_FieldDescriptor_JavaType_Enum_DOUBLE: @@ -507,6 +507,7 @@ static id BoxedValue(CGPValue value, CGPFieldJavaType type) { case ComGoogleProtobufDescriptors_FieldDescriptor_JavaType_Enum_BOOLEAN: return JavaLangBoolean_valueOfWithBoolean_(value.valueBool); case ComGoogleProtobufDescriptors_FieldDescriptor_JavaType_Enum_ENUM: + return value.valueEnum; case ComGoogleProtobufDescriptors_FieldDescriptor_JavaType_Enum_STRING: case ComGoogleProtobufDescriptors_FieldDescriptor_JavaType_Enum_BYTE_STRING: case ComGoogleProtobufDescriptors_FieldDescriptor_JavaType_Enum_MESSAGE: @@ -533,6 +534,8 @@ static CGPValue UnboxValue(id value, CGPFieldJavaType type) { result.valueBool = [value booleanValue]; break; case ComGoogleProtobufDescriptors_FieldDescriptor_JavaType_Enum_ENUM: + result.valueEnum = value; + break; case ComGoogleProtobufDescriptors_FieldDescriptor_JavaType_Enum_STRING: case ComGoogleProtobufDescriptors_FieldDescriptor_JavaType_Enum_BYTE_STRING: case ComGoogleProtobufDescriptors_FieldDescriptor_JavaType_Enum_MESSAGE: @@ -546,8 +549,7 @@ static CGPValue UnboxValue(id value, CGPFieldJavaType type) { // java.lang.Integer using the enum number (not ordinal). static id BoxedReflectionValue(CGPValue value, CGPFieldJavaType type) { if (type == ComGoogleProtobufDescriptors_FieldDescriptor_JavaType_Enum_ENUM) { - return JavaLangInteger_valueOfWithInt_( - [(id)value.valueId getNumber]); + return JavaLangInteger_valueOfWithInt_([value.valueEnum getNumber]); } return BoxedValue(value, type); } @@ -558,7 +560,7 @@ static CGPValue UnboxReflectionValue(id value, CGPFieldDescriptor *field) { CGPEnumValueDescriptor *valueDesc = CGPEnumValueDescriptorFromInt(field->valueType_, [value intValue]); CGPValue result; - result.valueId = valueDesc ? valueDesc->enum_ : nil; + result.valueEnum = valueDesc ? valueDesc->enum_ : nil; return result; } return UnboxValue(value, type); diff --git a/protobuf/runtime/src/com/google/protobuf/RepeatedField.m b/protobuf/runtime/src/com/google/protobuf/RepeatedField.m index 90a090af6d..227426694e 100644 --- a/protobuf/runtime/src/com/google/protobuf/RepeatedField.m +++ b/protobuf/runtime/src/com/google/protobuf/RepeatedField.m @@ -58,8 +58,10 @@ void CGPRepeatedFieldReserve(CGPRepeatedField *field, uint32_t new_size, size_t } uint32_t newTotalSize = MAX(MIN_REPEATED_FIELD_SIZE, MAX(data->total_size * 2, new_size)); + uint32_t oldTotalSize = data->total_size; data->total_size = newTotalSize; data->buffer = realloc(data->buffer, newTotalSize * elemSize); + bzero(data->buffer + elemSize * oldTotalSize, elemSize * (newTotalSize - oldTotalSize)); } void CGPRepeatedFieldCopyData(CGPRepeatedField *field, CGPFieldJavaType type) { @@ -82,8 +84,8 @@ void CGPRepeatedFieldCopyData(CGPRepeatedField *field, CGPFieldJavaType type) { } } -void CGPRepeatedFieldAppendOther( - CGPRepeatedField *field, CGPRepeatedField *other, CGPFieldJavaType type) { +void CGPRepeatedFieldAppendOther(CGPRepeatedField *field, CGPRepeatedField *other, + CGPFieldJavaType type) { uint32_t otherSize = CGPRepeatedFieldSize(other); if (otherSize == 0) { return; @@ -130,9 +132,10 @@ id CGPRepeatedFieldGet(CGPRepeatedField *field, jint index, CGPFieldDescriptor * CGPRepeatedFieldCheckBounds(field, index); #define REPEATED_GET_CASE(NAME) \ - return CGPToReflectionType##NAME(((TYPE_##NAME *)field->data->buffer)[index], descriptor); \ + return CGPToReflectionType##NAME(((TYPE_##NAME *)field->data->buffer)[index], descriptor); - SWITCH_TYPES_WITH_ENUM(CGPFieldGetJavaType(descriptor), REPEATED_GET_CASE) + SWITCH_TYPES(CGPFieldGetJavaType(descriptor), REPEATED_GET_CASE, REPEATED_GET_CASE, + REPEATED_GET_CASE) #undef REPEATED_GET_CASE } @@ -143,9 +146,7 @@ void CGPRepeatedMessageFieldRemove(CGPRepeatedField *field, jint index) { id *msgBuffer = (id *)field->data->buffer; AUTORELEASE(msgBuffer[index]); if (count > (uint32_t)index + 1) { - memmove(&(msgBuffer[index]), - &(msgBuffer[index + 1]), - sizeof(id) * (count - (index + 1))); + memmove(&(msgBuffer[index]), &(msgBuffer[index + 1]), sizeof(id) * (count - (index + 1))); } field->data->size -= 1; } @@ -153,26 +154,26 @@ void CGPRepeatedMessageFieldRemove(CGPRepeatedField *field, jint index) { void CGPRepeatedFieldSet(CGPRepeatedField *field, jint index, id value, CGPFieldJavaType type) { CGPRepeatedFieldCheckBounds(field, index); -#define REPEATED_SET_CASE(NAME) \ - { \ +#define REPEATED_SET_CASE(NAME) \ + { \ TYPE_##NAME *ptr = &((TYPE_##NAME *)field->data->buffer)[index]; \ - TYPE_ASSIGN_##NAME(*ptr, CGPFromReflectionType##NAME(value)); \ - break; \ + TYPE_ASSIGN_##NAME(ptr, CGPFromReflectionType##NAME(value)); \ } - SWITCH_TYPES_WITH_ENUM(type, REPEATED_SET_CASE) + SWITCH_TYPES(type, REPEATED_SET_CASE, REPEATED_SET_CASE, REPEATED_SET_CASE) #undef REPEATED_SET_CASE } // Make sure to reserve enough space in the buffer BEFORE calling this. static void CGPRepeatedFieldAddUnsafe(CGPRepeatedFieldData *data, id value, CGPFieldJavaType type) { -#define REPEATED_ADD_CASE(NAME) \ - ((TYPE_##NAME *)data->buffer)[data->size++] = \ - TYPE_RETAIN_##NAME(CGPFromReflectionType##NAME(value)); \ - break; +#define REPEATED_ADD_CASE(NAME) \ + { \ + TYPE_##NAME *ptr = &((TYPE_##NAME *)data->buffer)[data->size++]; \ + TYPE_ASSIGN_##NAME(ptr, CGPFromReflectionType##NAME(value)); \ + } - SWITCH_TYPES_WITH_ENUM(type, REPEATED_ADD_CASE) + SWITCH_TYPES(type, REPEATED_ADD_CASE, REPEATED_ADD_CASE, REPEATED_ADD_CASE) #undef REPEATED_ADD_CASE } @@ -185,8 +186,8 @@ void CGPRepeatedFieldAdd(CGPRepeatedField *field, id value, CGPFieldJavaType typ CGPRepeatedFieldAddUnsafe(field->data, value, type); } -void CGPRepeatedFieldAssignFromList( - CGPRepeatedField *field, id list, CGPFieldJavaType type) { +void CGPRepeatedFieldAssignFromList(CGPRepeatedField *field, id list, + CGPFieldJavaType type) { CGPRepeatedFieldClear(field, type); CGPRepeatedFieldReserve(field, [list size], CGPGetTypeSize(type)); @@ -203,13 +204,13 @@ void CGPRepeatedFieldAssignFromList( return newList; } -#define REPEATED_COPY_ELEM_CASE(NAME) \ - for (uint32_t i = 0; i < data->size; i++) { \ +#define REPEATED_COPY_ELEM_CASE(NAME) \ + for (uint32_t i = 0; i < data->size; i++) { \ [newList addWithId:CGPToReflectionType##NAME(((TYPE_##NAME *)data->buffer)[i], descriptor)]; \ - } \ - break; + } - SWITCH_TYPES_WITH_ENUM(CGPFieldGetJavaType(descriptor), REPEATED_COPY_ELEM_CASE) + SWITCH_TYPES(CGPFieldGetJavaType(descriptor), REPEATED_COPY_ELEM_CASE, REPEATED_COPY_ELEM_CASE, + REPEATED_COPY_ELEM_CASE) #undef REPEATED_COPY_ELEM_CASE @@ -254,7 +255,7 @@ @interface CGPRepeatedFieldList : JavaUtilAbstractList { @end // We need a subclass for String fields which must implement the ProtocolStringList interface. -@interface CGPRepeatedStringFieldList : CGPRepeatedFieldList < ComGoogleProtobufProtocolStringList > +@interface CGPRepeatedStringFieldList : CGPRepeatedFieldList @end @interface CGPStringAsByteStringList : JavaUtilAbstractList { @@ -265,8 +266,9 @@ @interface CGPStringAsByteStringList : JavaUtilAbstractList { id CGPNewRepeatedFieldList(CGPRepeatedField *field, CGPFieldJavaType type) { CGPRepeatedFieldList *list = - type == ComGoogleProtobufDescriptors_FieldDescriptor_JavaType_Enum_STRING ? - [[CGPRepeatedStringFieldList alloc] init] : [[CGPRepeatedFieldList alloc] init]; + type == ComGoogleProtobufDescriptors_FieldDescriptor_JavaType_Enum_STRING + ? [[CGPRepeatedStringFieldList alloc] init] + : [[CGPRepeatedFieldList alloc] init]; CGPRepeatedFieldData *data = field->data; if (data != NULL) { list->field_.data = data; @@ -293,9 +295,9 @@ - (id)getWithInt:(jint)index { CGPRepeatedFieldCheckBounds(&field_, index); #define REPEATED_LIST_GET_CASE(NAME) \ - return CGPBoxedValue##NAME(((TYPE_##NAME *)field_.data->buffer)[index]); \ + return CGPBoxedValue##NAME(((TYPE_##NAME *)field_.data->buffer)[index]); - SWITCH_TYPES_NO_ENUM(type_, REPEATED_LIST_GET_CASE) + SWITCH_TYPES(type_, REPEATED_LIST_GET_CASE, REPEATED_LIST_GET_CASE, REPEATED_LIST_GET_CASE) #undef REPEATED_LIST_GET_CASE }