Fix GPBGetMessage{Repeated,Map}Field()

- Correct impl by using helpers the message wiring does.
- Add unittests.

Fixes https://github.com/google/protobuf/issues/1716
This commit is contained in:
Thomas Van Lenten 2016-06-27 20:45:16 -04:00
parent 2bcd43afe4
commit fc4c617199
3 changed files with 72 additions and 22 deletions

View File

@ -3199,4 +3199,34 @@ static void ResolveIvarSet(GPBFieldDescriptor *field,
@end
#pragma mark - Messages from GPBUtilities.h but defined here for access to helpers.
// Only exists for public api, no core code should use this.
id GPBGetMessageRepeatedField(GPBMessage *self, GPBFieldDescriptor *field) {
#if defined(DEBUG) && DEBUG
if (field.fieldType != GPBFieldTypeRepeated) {
[NSException raise:NSInvalidArgumentException
format:@"%@.%@ is not a repeated field.",
[self class], field.name];
}
#endif
GPBDescriptor *descriptor = [[self class] descriptor];
GPBFileSyntax syntax = descriptor.file.syntax;
return GetOrCreateArrayIvarWithField(self, field, syntax);
}
// Only exists for public api, no core code should use this.
id GPBGetMessageMapField(GPBMessage *self, GPBFieldDescriptor *field) {
#if defined(DEBUG) && DEBUG
if (field.fieldType != GPBFieldTypeMap) {
[NSException raise:NSInvalidArgumentException
format:@"%@.%@ is not a map<> field.",
[self class], field.name];
}
#endif
GPBDescriptor *descriptor = [[self class] descriptor];
GPBFileSyntax syntax = descriptor.file.syntax;
return GetOrCreateMapIvarWithField(self, field, syntax);
}
#pragma clang diagnostic pop

View File

@ -895,17 +895,7 @@ void GPBSetMessageGroupField(GPBMessage *self,
//%PDDM-EXPAND-END (4 expansions)
// Only exists for public api, no core code should use this.
id GPBGetMessageRepeatedField(GPBMessage *self, GPBFieldDescriptor *field) {
#if defined(DEBUG) && DEBUG
if (field.fieldType != GPBFieldTypeRepeated) {
[NSException raise:NSInvalidArgumentException
format:@"%@.%@ is not a repeated field.",
[self class], field.name];
}
#endif
return GPBGetObjectIvarWithField(self, field);
}
// GPBGetMessageRepeatedField is defined in GPBMessage.m
// Only exists for public api, no core code should use this.
void GPBSetMessageRepeatedField(GPBMessage *self, GPBFieldDescriptor *field, id array) {
@ -997,17 +987,7 @@ static NSString *TypeToStr(GPBDataType dataType) {
}
#endif
// Only exists for public api, no core code should use this.
id GPBGetMessageMapField(GPBMessage *self, GPBFieldDescriptor *field) {
#if defined(DEBUG) && DEBUG
if (field.fieldType != GPBFieldTypeMap) {
[NSException raise:NSInvalidArgumentException
format:@"%@.%@ is not a map<> field.",
[self class], field.name];
}
#endif
return GPBGetObjectIvarWithField(self, field);
}
// GPBGetMessageMapField is defined in GPBMessage.m
// Only exists for public api, no core code should use this.
void GPBSetMessageMapField(GPBMessage *self, GPBFieldDescriptor *field,

View File

@ -2066,6 +2066,46 @@
}];
}
- (void)test_GPBGetMessageRepeatedField {
TestAllTypes *message = [TestAllTypes message];
GPBFieldDescriptor *fieldDescriptor = [[message descriptor] fieldWithName:@"repeatedStringArray"];
XCTAssertNotNil(fieldDescriptor);
NSMutableArray *fieldArray = GPBGetMessageRepeatedField(message, fieldDescriptor);
XCTAssertNotNil(fieldArray); // Should have autocreated.
XCTAssertTrue(fieldArray == message.repeatedStringArray); // Same pointer
}
- (void)test_GPBSetMessageRepeatedField {
TestAllTypes *message = [TestAllTypes message];
GPBFieldDescriptor *fieldDescriptor = [[message descriptor] fieldWithName:@"repeatedStringArray"];
XCTAssertNotNil(fieldDescriptor);
NSMutableArray *fieldArray = [NSMutableArray arrayWithObject:@"foo"];
GPBSetMessageRepeatedField(message, fieldDescriptor, fieldArray);
XCTAssertTrue(fieldArray == message.repeatedStringArray); // Same pointer
XCTAssertEqualObjects(@"foo", message.repeatedStringArray.firstObject);
}
- (void)test_GPBGetMessageMapField {
TestMap *message = [TestMap message];
GPBFieldDescriptor *fieldDescriptor = [[message descriptor] fieldWithName:@"mapStringString"];
XCTAssertNotNil(fieldDescriptor);
NSMutableDictionary *fieldMap = GPBGetMessageMapField(message, fieldDescriptor);
XCTAssertNotNil(fieldMap); // Should have autocreated.
XCTAssertTrue(fieldMap == message.mapStringString); // Same pointer
}
- (void)test_GPBSetMessageMapField {
TestMap *message = [TestMap message];
GPBFieldDescriptor *fieldDescriptor = [[message descriptor] fieldWithName:@"mapStringString"];
XCTAssertNotNil(fieldDescriptor);
NSMutableDictionary *fieldMap = [NSMutableDictionary dictionaryWithObject:@"bar" forKey:@"foo"];
GPBSetMessageMapField(message, fieldDescriptor, fieldMap);
XCTAssertTrue(fieldMap == message.mapStringString); // Same pointer
XCTAssertEqualObjects(@"bar", message.mapStringString[@"foo"]);
}
#pragma mark - Subset from from map_tests.cc
// TEST(GeneratedMapFieldTest, IsInitialized)