浏览代码

Merge pull request #1720 from thomasvl/issue_1716

Fix GPBGetMessage{Repeated,Map}Field()
Thomas Van Lenten 9 年之前
父节点
当前提交
e0016c5b6a
共有 3 个文件被更改,包括 72 次插入22 次删除
  1. 30 0
      objectivec/GPBMessage.m
  2. 2 22
      objectivec/GPBUtilities.m
  3. 40 0
      objectivec/Tests/GPBMessageTests+Runtime.m

+ 30 - 0
objectivec/GPBMessage.m

@@ -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

+ 2 - 22
objectivec/GPBUtilities.m

@@ -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,

+ 40 - 0
objectivec/Tests/GPBMessageTests+Runtime.m

@@ -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)