You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

2289 lines
87 KiB

6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
  1. // Protocol Buffers - Google's data interchange format
  2. // Copyright 2008 Google Inc. All rights reserved.
  3. // https://developers.google.com/protocol-buffers/
  4. //
  5. // Redistribution and use in source and binary forms, with or without
  6. // modification, are permitted provided that the following conditions are
  7. // met:
  8. //
  9. // * Redistributions of source code must retain the above copyright
  10. // notice, this list of conditions and the following disclaimer.
  11. // * Redistributions in binary form must reproduce the above
  12. // copyright notice, this list of conditions and the following disclaimer
  13. // in the documentation and/or other materials provided with the
  14. // distribution.
  15. // * Neither the name of Google Inc. nor the names of its
  16. // contributors may be used to endorse or promote products derived from
  17. // this software without specific prior written permission.
  18. //
  19. // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  20. // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  21. // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  22. // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  23. // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  24. // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  25. // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  26. // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  27. // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  28. // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  29. // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  30. #import "GPBUtilities_PackagePrivate.h"
  31. #import <objc/runtime.h>
  32. #import "GPBArray_PackagePrivate.h"
  33. #import "GPBDescriptor_PackagePrivate.h"
  34. #import "GPBDictionary_PackagePrivate.h"
  35. #import "GPBMessage_PackagePrivate.h"
  36. #import "GPBUnknownField.h"
  37. #import "GPBUnknownFieldSet.h"
  38. // Direct access is use for speed, to avoid even internally declaring things
  39. // read/write, etc. The warning is enabled in the project to ensure code calling
  40. // protos can turn on -Wdirect-ivar-access without issues.
  41. #pragma clang diagnostic push
  42. #pragma clang diagnostic ignored "-Wdirect-ivar-access"
  43. static void AppendTextFormatForMessage(GPBMessage *message,
  44. NSMutableString *toStr,
  45. NSString *lineIndent);
  46. // Are two datatypes the same basic type representation (ex Int32 and SInt32).
  47. // Marked unused because currently only called from asserts/debug.
  48. static BOOL DataTypesEquivalent(GPBDataType type1,
  49. GPBDataType type2) __attribute__ ((unused));
  50. // Basic type representation for a type (ex: for SInt32 it is Int32).
  51. // Marked unused because currently only called from asserts/debug.
  52. static GPBDataType BaseDataType(GPBDataType type) __attribute__ ((unused));
  53. // String name for a data type.
  54. // Marked unused because currently only called from asserts/debug.
  55. static NSString *TypeToString(GPBDataType dataType) __attribute__ ((unused));
  56. // Helper for clearing oneofs.
  57. static void GPBMaybeClearOneofPrivate(GPBMessage *self,
  58. GPBOneofDescriptor *oneof,
  59. int32_t oneofHasIndex,
  60. uint32_t fieldNumberNotToClear);
  61. NSData *GPBEmptyNSData(void) {
  62. static dispatch_once_t onceToken;
  63. static NSData *defaultNSData = nil;
  64. dispatch_once(&onceToken, ^{
  65. defaultNSData = [[NSData alloc] init];
  66. });
  67. return defaultNSData;
  68. }
  69. void GPBMessageDropUnknownFieldsRecursively(GPBMessage *initialMessage) {
  70. if (!initialMessage) {
  71. return;
  72. }
  73. // Use an array as a list to process to avoid recursion.
  74. NSMutableArray *todo = [NSMutableArray arrayWithObject:initialMessage];
  75. while (todo.count) {
  76. GPBMessage *msg = todo.lastObject;
  77. [todo removeLastObject];
  78. // Clear unknowns.
  79. msg.unknownFields = nil;
  80. // Handle the message fields.
  81. GPBDescriptor *descriptor = [[msg class] descriptor];
  82. for (GPBFieldDescriptor *field in descriptor->fields_) {
  83. if (!GPBFieldDataTypeIsMessage(field)) {
  84. continue;
  85. }
  86. switch (field.fieldType) {
  87. case GPBFieldTypeSingle:
  88. if (GPBGetHasIvarField(msg, field)) {
  89. GPBMessage *fieldMessage = GPBGetObjectIvarWithFieldNoAutocreate(msg, field);
  90. [todo addObject:fieldMessage];
  91. }
  92. break;
  93. case GPBFieldTypeRepeated: {
  94. NSArray *fieldMessages = GPBGetObjectIvarWithFieldNoAutocreate(msg, field);
  95. if (fieldMessages.count) {
  96. [todo addObjectsFromArray:fieldMessages];
  97. }
  98. break;
  99. }
  100. case GPBFieldTypeMap: {
  101. id rawFieldMap = GPBGetObjectIvarWithFieldNoAutocreate(msg, field);
  102. switch (field.mapKeyDataType) {
  103. case GPBDataTypeBool:
  104. [(GPBBoolObjectDictionary*)rawFieldMap enumerateKeysAndObjectsUsingBlock:^(
  105. BOOL key, id _Nonnull object, BOOL * _Nonnull stop) {
  106. #pragma unused(key, stop)
  107. [todo addObject:object];
  108. }];
  109. break;
  110. case GPBDataTypeFixed32:
  111. case GPBDataTypeUInt32:
  112. [(GPBUInt32ObjectDictionary*)rawFieldMap enumerateKeysAndObjectsUsingBlock:^(
  113. uint32_t key, id _Nonnull object, BOOL * _Nonnull stop) {
  114. #pragma unused(key, stop)
  115. [todo addObject:object];
  116. }];
  117. break;
  118. case GPBDataTypeInt32:
  119. case GPBDataTypeSFixed32:
  120. case GPBDataTypeSInt32:
  121. [(GPBInt32ObjectDictionary*)rawFieldMap enumerateKeysAndObjectsUsingBlock:^(
  122. int32_t key, id _Nonnull object, BOOL * _Nonnull stop) {
  123. #pragma unused(key, stop)
  124. [todo addObject:object];
  125. }];
  126. break;
  127. case GPBDataTypeFixed64:
  128. case GPBDataTypeUInt64:
  129. [(GPBUInt64ObjectDictionary*)rawFieldMap enumerateKeysAndObjectsUsingBlock:^(
  130. uint64_t key, id _Nonnull object, BOOL * _Nonnull stop) {
  131. #pragma unused(key, stop)
  132. [todo addObject:object];
  133. }];
  134. break;
  135. case GPBDataTypeInt64:
  136. case GPBDataTypeSFixed64:
  137. case GPBDataTypeSInt64:
  138. [(GPBInt64ObjectDictionary*)rawFieldMap enumerateKeysAndObjectsUsingBlock:^(
  139. int64_t key, id _Nonnull object, BOOL * _Nonnull stop) {
  140. #pragma unused(key, stop)
  141. [todo addObject:object];
  142. }];
  143. break;
  144. case GPBDataTypeString:
  145. [(NSDictionary*)rawFieldMap enumerateKeysAndObjectsUsingBlock:^(
  146. NSString * _Nonnull key, GPBMessage * _Nonnull obj, BOOL * _Nonnull stop) {
  147. #pragma unused(key, stop)
  148. [todo addObject:obj];
  149. }];
  150. break;
  151. case GPBDataTypeFloat:
  152. case GPBDataTypeDouble:
  153. case GPBDataTypeEnum:
  154. case GPBDataTypeBytes:
  155. case GPBDataTypeGroup:
  156. case GPBDataTypeMessage:
  157. NSCAssert(NO, @"Aren't valid key types.");
  158. }
  159. break;
  160. } // switch(field.mapKeyDataType)
  161. } // switch(field.fieldType)
  162. } // for(fields)
  163. // Handle any extensions holding messages.
  164. for (GPBExtensionDescriptor *extension in [msg extensionsCurrentlySet]) {
  165. if (!GPBDataTypeIsMessage(extension.dataType)) {
  166. continue;
  167. }
  168. if (extension.isRepeated) {
  169. NSArray *extMessages = [msg getExtension:extension];
  170. [todo addObjectsFromArray:extMessages];
  171. } else {
  172. GPBMessage *extMessage = [msg getExtension:extension];
  173. [todo addObject:extMessage];
  174. }
  175. } // for(extensionsCurrentlySet)
  176. } // while(todo.count)
  177. }
  178. // -- About Version Checks --
  179. // There's actually 3 places these checks all come into play:
  180. // 1. When the generated source is compile into .o files, the header check
  181. // happens. This is checking the protoc used matches the library being used
  182. // when making the .o.
  183. // 2. Every place a generated proto header is included in a developer's code,
  184. // the header check comes into play again. But this time it is checking that
  185. // the current library headers being used still support/match the ones for
  186. // the generated code.
  187. // 3. At runtime the final check here (GPBCheckRuntimeVersionsInternal), is
  188. // called from the generated code passing in values captured when the
  189. // generated code's .o was made. This checks that at runtime the generated
  190. // code and runtime library match.
  191. void GPBCheckRuntimeVersionSupport(int32_t objcRuntimeVersion) {
  192. // NOTE: This is passing the value captured in the compiled code to check
  193. // against the values captured when the runtime support was compiled. This
  194. // ensures the library code isn't in a different framework/library that
  195. // was generated with a non matching version.
  196. if (GOOGLE_PROTOBUF_OBJC_VERSION < objcRuntimeVersion) {
  197. // Library is too old for headers.
  198. [NSException raise:NSInternalInconsistencyException
  199. format:@"Linked to ProtocolBuffer runtime version %d,"
  200. @" but code compiled needing atleast %d!",
  201. GOOGLE_PROTOBUF_OBJC_VERSION, objcRuntimeVersion];
  202. }
  203. if (objcRuntimeVersion < GOOGLE_PROTOBUF_OBJC_MIN_SUPPORTED_VERSION) {
  204. // Headers are too old for library.
  205. [NSException raise:NSInternalInconsistencyException
  206. format:@"Proto generation source compiled against runtime"
  207. @" version %d, but this version of the runtime only"
  208. @" supports back to %d!",
  209. objcRuntimeVersion,
  210. GOOGLE_PROTOBUF_OBJC_MIN_SUPPORTED_VERSION];
  211. }
  212. }
  213. // This api is no longer used for version checks. 30001 is the last version
  214. // using this old versioning model. When that support is removed, this function
  215. // can be removed (along with the declaration in GPBUtilities_PackagePrivate.h).
  216. void GPBCheckRuntimeVersionInternal(int32_t version) {
  217. GPBInternalCompileAssert(GOOGLE_PROTOBUF_OBJC_MIN_SUPPORTED_VERSION == 30001,
  218. time_to_remove_this_old_version_shim);
  219. if (version != GOOGLE_PROTOBUF_OBJC_MIN_SUPPORTED_VERSION) {
  220. [NSException raise:NSInternalInconsistencyException
  221. format:@"Linked to ProtocolBuffer runtime version %d,"
  222. @" but code compiled with version %d!",
  223. GOOGLE_PROTOBUF_OBJC_GEN_VERSION, version];
  224. }
  225. }
  226. BOOL GPBMessageHasFieldNumberSet(GPBMessage *self, uint32_t fieldNumber) {
  227. GPBDescriptor *descriptor = [self descriptor];
  228. GPBFieldDescriptor *field = [descriptor fieldWithNumber:fieldNumber];
  229. return GPBMessageHasFieldSet(self, field);
  230. }
  231. BOOL GPBMessageHasFieldSet(GPBMessage *self, GPBFieldDescriptor *field) {
  232. if (self == nil || field == nil) return NO;
  233. // Repeated/Map don't use the bit, they check the count.
  234. if (GPBFieldIsMapOrArray(field)) {
  235. // Array/map type doesn't matter, since GPB*Array/NSArray and
  236. // GPB*Dictionary/NSDictionary all support -count;
  237. NSArray *arrayOrMap = GPBGetObjectIvarWithFieldNoAutocreate(self, field);
  238. return (arrayOrMap.count > 0);
  239. } else {
  240. return GPBGetHasIvarField(self, field);
  241. }
  242. }
  243. void GPBClearMessageField(GPBMessage *self, GPBFieldDescriptor *field) {
  244. // If not set, nothing to do.
  245. if (!GPBGetHasIvarField(self, field)) {
  246. return;
  247. }
  248. GPBMessageFieldDescription *fieldDesc = field->description_;
  249. if (GPBFieldStoresObject(field)) {
  250. // Object types are handled slightly differently, they need to be released.
  251. uint8_t *storage = (uint8_t *)self->messageStorage_;
  252. id *typePtr = (id *)&storage[fieldDesc->offset];
  253. [*typePtr release];
  254. *typePtr = nil;
  255. } else {
  256. // POD types just need to clear the has bit as the Get* method will
  257. // fetch the default when needed.
  258. }
  259. GPBSetHasIvar(self, fieldDesc->hasIndex, fieldDesc->number, NO);
  260. }
  261. void GPBClearOneof(GPBMessage *self, GPBOneofDescriptor *oneof) {
  262. #if defined(DEBUG) && DEBUG
  263. NSCAssert([[self descriptor] oneofWithName:oneof.name] == oneof,
  264. @"OneofDescriptor %@ doesn't appear to be for %@ messages.",
  265. oneof.name, [self class]);
  266. #endif
  267. GPBFieldDescriptor *firstField = oneof->fields_[0];
  268. GPBMaybeClearOneofPrivate(self, oneof, firstField->description_->hasIndex, 0);
  269. }
  270. BOOL GPBGetHasIvar(GPBMessage *self, int32_t idx, uint32_t fieldNumber) {
  271. NSCAssert(self->messageStorage_ != NULL,
  272. @"%@: All messages should have storage (from init)",
  273. [self class]);
  274. if (idx < 0) {
  275. NSCAssert(fieldNumber != 0, @"Invalid field number.");
  276. BOOL hasIvar = (self->messageStorage_->_has_storage_[-idx] == fieldNumber);
  277. return hasIvar;
  278. } else {
  279. NSCAssert(idx != GPBNoHasBit, @"Invalid has bit.");
  280. uint32_t byteIndex = idx / 32;
  281. uint32_t bitMask = (1U << (idx % 32));
  282. BOOL hasIvar =
  283. (self->messageStorage_->_has_storage_[byteIndex] & bitMask) ? YES : NO;
  284. return hasIvar;
  285. }
  286. }
  287. uint32_t GPBGetHasOneof(GPBMessage *self, int32_t idx) {
  288. NSCAssert(idx < 0, @"%@: invalid index (%d) for oneof.",
  289. [self class], idx);
  290. uint32_t result = self->messageStorage_->_has_storage_[-idx];
  291. return result;
  292. }
  293. void GPBSetHasIvar(GPBMessage *self, int32_t idx, uint32_t fieldNumber,
  294. BOOL value) {
  295. if (idx < 0) {
  296. NSCAssert(fieldNumber != 0, @"Invalid field number.");
  297. uint32_t *has_storage = self->messageStorage_->_has_storage_;
  298. has_storage[-idx] = (value ? fieldNumber : 0);
  299. } else {
  300. NSCAssert(idx != GPBNoHasBit, @"Invalid has bit.");
  301. uint32_t *has_storage = self->messageStorage_->_has_storage_;
  302. uint32_t byte = idx / 32;
  303. uint32_t bitMask = (1U << (idx % 32));
  304. if (value) {
  305. has_storage[byte] |= bitMask;
  306. } else {
  307. has_storage[byte] &= ~bitMask;
  308. }
  309. }
  310. }
  311. static void GPBMaybeClearOneofPrivate(GPBMessage *self,
  312. GPBOneofDescriptor *oneof,
  313. int32_t oneofHasIndex,
  314. uint32_t fieldNumberNotToClear) {
  315. uint32_t fieldNumberSet = GPBGetHasOneof(self, oneofHasIndex);
  316. if ((fieldNumberSet == fieldNumberNotToClear) || (fieldNumberSet == 0)) {
  317. // Do nothing/nothing set in the oneof.
  318. return;
  319. }
  320. // Like GPBClearMessageField(), free the memory if an objecttype is set,
  321. // pod types don't need to do anything.
  322. GPBFieldDescriptor *fieldSet = [oneof fieldWithNumber:fieldNumberSet];
  323. NSCAssert(fieldSet,
  324. @"%@: oneof set to something (%u) not in the oneof?",
  325. [self class], fieldNumberSet);
  326. if (fieldSet && GPBFieldStoresObject(fieldSet)) {
  327. uint8_t *storage = (uint8_t *)self->messageStorage_;
  328. id *typePtr = (id *)&storage[fieldSet->description_->offset];
  329. [*typePtr release];
  330. *typePtr = nil;
  331. }
  332. // Set to nothing stored in the oneof.
  333. // (field number doesn't matter since setting to nothing).
  334. GPBSetHasIvar(self, oneofHasIndex, 1, NO);
  335. }
  336. #pragma mark - IVar accessors
  337. //%PDDM-DEFINE IVAR_POD_ACCESSORS_DEFN(NAME, TYPE)
  338. //%TYPE GPBGetMessage##NAME##Field(GPBMessage *self,
  339. //% TYPE$S NAME$S GPBFieldDescriptor *field) {
  340. //%#if defined(DEBUG) && DEBUG
  341. //% NSCAssert([[self descriptor] fieldWithNumber:field.number] == field,
  342. //% @"FieldDescriptor %@ doesn't appear to be for %@ messages.",
  343. //% field.name, [self class]);
  344. //% NSCAssert(DataTypesEquivalent(GPBGetFieldDataType(field),
  345. //% GPBDataType##NAME),
  346. //% @"Attempting to get value of TYPE from field %@ "
  347. //% @"of %@ which is of type %@.",
  348. //% [self class], field.name,
  349. //% TypeToString(GPBGetFieldDataType(field)));
  350. //%#endif
  351. //% if (GPBGetHasIvarField(self, field)) {
  352. //% uint8_t *storage = (uint8_t *)self->messageStorage_;
  353. //% TYPE *typePtr = (TYPE *)&storage[field->description_->offset];
  354. //% return *typePtr;
  355. //% } else {
  356. //% return field.defaultValue.value##NAME;
  357. //% }
  358. //%}
  359. //%
  360. //%// Only exists for public api, no core code should use this.
  361. //%void GPBSetMessage##NAME##Field(GPBMessage *self,
  362. //% NAME$S GPBFieldDescriptor *field,
  363. //% NAME$S TYPE value) {
  364. //% if (self == nil || field == nil) return;
  365. //%#if defined(DEBUG) && DEBUG
  366. //% NSCAssert([[self descriptor] fieldWithNumber:field.number] == field,
  367. //% @"FieldDescriptor %@ doesn't appear to be for %@ messages.",
  368. //% field.name, [self class]);
  369. //% NSCAssert(DataTypesEquivalent(GPBGetFieldDataType(field),
  370. //% GPBDataType##NAME),
  371. //% @"Attempting to set field %@ of %@ which is of type %@ with "
  372. //% @"value of type TYPE.",
  373. //% [self class], field.name,
  374. //% TypeToString(GPBGetFieldDataType(field)));
  375. //%#endif
  376. //% GPBSet##NAME##IvarWithFieldPrivate(self, field, value);
  377. //%}
  378. //%
  379. //%void GPBSet##NAME##IvarWithFieldPrivate(GPBMessage *self,
  380. //% NAME$S GPBFieldDescriptor *field,
  381. //% NAME$S TYPE value) {
  382. //% GPBOneofDescriptor *oneof = field->containingOneof_;
  383. //% GPBMessageFieldDescription *fieldDesc = field->description_;
  384. //% if (oneof) {
  385. //% GPBMaybeClearOneofPrivate(self, oneof, fieldDesc->hasIndex, fieldDesc->number);
  386. //% }
  387. //%#if defined(DEBUG) && DEBUG
  388. //% NSCAssert(self->messageStorage_ != NULL,
  389. //% @"%@: All messages should have storage (from init)",
  390. //% [self class]);
  391. //%#endif
  392. //%#if defined(__clang_analyzer__)
  393. //% if (self->messageStorage_ == NULL) return;
  394. //%#endif
  395. //% uint8_t *storage = (uint8_t *)self->messageStorage_;
  396. //% TYPE *typePtr = (TYPE *)&storage[fieldDesc->offset];
  397. //% *typePtr = value;
  398. //% // If the value is zero, then we only count the field as "set" if the field
  399. //% // shouldn't auto clear on zero.
  400. //% BOOL hasValue = ((value != (TYPE)0)
  401. //% || ((fieldDesc->flags & GPBFieldClearHasIvarOnZero) == 0));
  402. //% GPBSetHasIvar(self, fieldDesc->hasIndex, fieldDesc->number, hasValue);
  403. //% GPBBecomeVisibleToAutocreator(self);
  404. //%}
  405. //%
  406. //%PDDM-DEFINE IVAR_ALIAS_DEFN_OBJECT(NAME, TYPE)
  407. //%// Only exists for public api, no core code should use this.
  408. //%TYPE *GPBGetMessage##NAME##Field(GPBMessage *self,
  409. //% TYPE$S NAME$S GPBFieldDescriptor *field) {
  410. //%#if defined(DEBUG) && DEBUG
  411. //% NSCAssert(DataTypesEquivalent(GPBGetFieldDataType(field),
  412. //% GPBDataType##NAME),
  413. //% @"Attempting to get value of TYPE from field %@ "
  414. //% @"of %@ which is of type %@.",
  415. //% [self class], field.name,
  416. //% TypeToString(GPBGetFieldDataType(field)));
  417. //%#endif
  418. //% return (TYPE *)GPBGetObjectIvarWithField(self, field);
  419. //%}
  420. //%
  421. //%// Only exists for public api, no core code should use this.
  422. //%void GPBSetMessage##NAME##Field(GPBMessage *self,
  423. //% NAME$S GPBFieldDescriptor *field,
  424. //% NAME$S TYPE *value) {
  425. //%#if defined(DEBUG) && DEBUG
  426. //% NSCAssert(DataTypesEquivalent(GPBGetFieldDataType(field),
  427. //% GPBDataType##NAME),
  428. //% @"Attempting to set field %@ of %@ which is of type %@ with "
  429. //% @"value of type TYPE.",
  430. //% [self class], field.name,
  431. //% TypeToString(GPBGetFieldDataType(field)));
  432. //%#endif
  433. //% GPBSetObjectIvarWithField(self, field, (id)value);
  434. //%}
  435. //%
  436. //%PDDM-DEFINE IVAR_ALIAS_DEFN_COPY_OBJECT(NAME, TYPE)
  437. //%// Only exists for public api, no core code should use this.
  438. //%TYPE *GPBGetMessage##NAME##Field(GPBMessage *self,
  439. //% TYPE$S NAME$S GPBFieldDescriptor *field) {
  440. //%#if defined(DEBUG) && DEBUG
  441. //% NSCAssert(DataTypesEquivalent(GPBGetFieldDataType(field),
  442. //% GPBDataType##NAME),
  443. //% @"Attempting to get value of TYPE from field %@ "
  444. //% @"of %@ which is of type %@.",
  445. //% [self class], field.name,
  446. //% TypeToString(GPBGetFieldDataType(field)));
  447. //%#endif
  448. //% return (TYPE *)GPBGetObjectIvarWithField(self, field);
  449. //%}
  450. //%
  451. //%// Only exists for public api, no core code should use this.
  452. //%void GPBSetMessage##NAME##Field(GPBMessage *self,
  453. //% NAME$S GPBFieldDescriptor *field,
  454. //% NAME$S TYPE *value) {
  455. //%#if defined(DEBUG) && DEBUG
  456. //% NSCAssert(DataTypesEquivalent(GPBGetFieldDataType(field),
  457. //% GPBDataType##NAME),
  458. //% @"Attempting to set field %@ of %@ which is of type %@ with "
  459. //% @"value of type TYPE.",
  460. //% [self class], field.name,
  461. //% TypeToString(GPBGetFieldDataType(field)));
  462. //%#endif
  463. //% GPBSetCopyObjectIvarWithField(self, field, (id)value);
  464. //%}
  465. //%
  466. // Object types are handled slightly differently, they need to be released
  467. // and retained.
  468. void GPBSetAutocreatedRetainedObjectIvarWithField(
  469. GPBMessage *self, GPBFieldDescriptor *field,
  470. id __attribute__((ns_consumed)) value) {
  471. uint8_t *storage = (uint8_t *)self->messageStorage_;
  472. id *typePtr = (id *)&storage[field->description_->offset];
  473. NSCAssert(*typePtr == NULL, @"Can't set autocreated object more than once.");
  474. *typePtr = value;
  475. }
  476. void GPBClearAutocreatedMessageIvarWithField(GPBMessage *self,
  477. GPBFieldDescriptor *field) {
  478. if (GPBGetHasIvarField(self, field)) {
  479. return;
  480. }
  481. uint8_t *storage = (uint8_t *)self->messageStorage_;
  482. id *typePtr = (id *)&storage[field->description_->offset];
  483. GPBMessage *oldValue = *typePtr;
  484. *typePtr = NULL;
  485. GPBClearMessageAutocreator(oldValue);
  486. [oldValue release];
  487. }
  488. // This exists only for bridging some aliased types, nothing else should use it.
  489. static void GPBSetObjectIvarWithField(GPBMessage *self,
  490. GPBFieldDescriptor *field, id value) {
  491. if (self == nil || field == nil) return;
  492. GPBSetRetainedObjectIvarWithFieldPrivate(self, field, [value retain]);
  493. }
  494. static void GPBSetCopyObjectIvarWithField(GPBMessage *self,
  495. GPBFieldDescriptor *field, id value);
  496. // GPBSetCopyObjectIvarWithField is blocked from the analyzer because it flags
  497. // a leak for the -copy even though GPBSetRetainedObjectIvarWithFieldPrivate
  498. // is marked as consuming the value. Note: For some reason this doesn't happen
  499. // with the -retain in GPBSetObjectIvarWithField.
  500. #if !defined(__clang_analyzer__)
  501. // This exists only for bridging some aliased types, nothing else should use it.
  502. static void GPBSetCopyObjectIvarWithField(GPBMessage *self,
  503. GPBFieldDescriptor *field, id value) {
  504. if (self == nil || field == nil) return;
  505. GPBSetRetainedObjectIvarWithFieldPrivate(self, field, [value copy]);
  506. }
  507. #endif // !defined(__clang_analyzer__)
  508. void GPBSetObjectIvarWithFieldPrivate(GPBMessage *self,
  509. GPBFieldDescriptor *field, id value) {
  510. GPBSetRetainedObjectIvarWithFieldPrivate(self, field, [value retain]);
  511. }
  512. void GPBSetRetainedObjectIvarWithFieldPrivate(GPBMessage *self,
  513. GPBFieldDescriptor *field,
  514. id value) {
  515. NSCAssert(self->messageStorage_ != NULL,
  516. @"%@: All messages should have storage (from init)",
  517. [self class]);
  518. #if defined(__clang_analyzer__)
  519. if (self->messageStorage_ == NULL) return;
  520. #endif
  521. GPBDataType fieldType = GPBGetFieldDataType(field);
  522. BOOL isMapOrArray = GPBFieldIsMapOrArray(field);
  523. BOOL fieldIsMessage = GPBDataTypeIsMessage(fieldType);
  524. #if defined(DEBUG) && DEBUG
  525. if (value == nil && !isMapOrArray && !fieldIsMessage &&
  526. field.hasDefaultValue) {
  527. // Setting a message to nil is an obvious way to "clear" the value
  528. // as there is no way to set a non-empty default value for messages.
  529. //
  530. // For Strings and Bytes that have default values set it is not clear what
  531. // should be done when their value is set to nil. Is the intention just to
  532. // clear the set value and reset to default, or is the intention to set the
  533. // value to the empty string/data? Arguments can be made for both cases.
  534. // 'nil' has been abused as a replacement for an empty string/data in ObjC.
  535. // We decided to be consistent with all "object" types and clear the has
  536. // field, and fall back on the default value. The warning below will only
  537. // appear in debug, but the could should be changed so the intention is
  538. // clear.
  539. NSString *hasSel = NSStringFromSelector(field->hasOrCountSel_);
  540. NSString *propName = field.name;
  541. NSString *className = self.descriptor.name;
  542. NSLog(@"warning: '%@.%@ = nil;' is not clearly defined for fields with "
  543. @"default values. Please use '%@.%@ = %@' if you want to set it to "
  544. @"empty, or call '%@.%@ = NO' to reset it to it's default value of "
  545. @"'%@'. Defaulting to resetting default value.",
  546. className, propName, className, propName,
  547. (fieldType == GPBDataTypeString) ? @"@\"\"" : @"GPBEmptyNSData()",
  548. className, hasSel, field.defaultValue.valueString);
  549. // Note: valueString, depending on the type, it could easily be
  550. // valueData/valueMessage.
  551. }
  552. #endif // DEBUG
  553. GPBMessageFieldDescription *fieldDesc = field->description_;
  554. if (!isMapOrArray) {
  555. // Non repeated/map can be in an oneof, clear any existing value from the
  556. // oneof.
  557. GPBOneofDescriptor *oneof = field->containingOneof_;
  558. if (oneof) {
  559. GPBMaybeClearOneofPrivate(self, oneof, fieldDesc->hasIndex, fieldDesc->number);
  560. }
  561. // Clear "has" if they are being set to nil.
  562. BOOL setHasValue = (value != nil);
  563. // If the field should clear on a "zero" value, then check if the string/data
  564. // was zero length, and clear instead.
  565. if (((fieldDesc->flags & GPBFieldClearHasIvarOnZero) != 0) &&
  566. ([value length] == 0)) {
  567. setHasValue = NO;
  568. // The value passed in was retained, it must be released since we
  569. // aren't saving anything in the field.
  570. [value release];
  571. value = nil;
  572. }
  573. GPBSetHasIvar(self, fieldDesc->hasIndex, fieldDesc->number, setHasValue);
  574. }
  575. uint8_t *storage = (uint8_t *)self->messageStorage_;
  576. id *typePtr = (id *)&storage[fieldDesc->offset];
  577. id oldValue = *typePtr;
  578. *typePtr = value;
  579. if (oldValue) {
  580. if (isMapOrArray) {
  581. if (field.fieldType == GPBFieldTypeRepeated) {
  582. // If the old array was autocreated by us, then clear it.
  583. if (GPBDataTypeIsObject(fieldType)) {
  584. if ([oldValue isKindOfClass:[GPBAutocreatedArray class]]) {
  585. GPBAutocreatedArray *autoArray = oldValue;
  586. if (autoArray->_autocreator == self) {
  587. autoArray->_autocreator = nil;
  588. }
  589. }
  590. } else {
  591. // Type doesn't matter, it is a GPB*Array.
  592. GPBInt32Array *gpbArray = oldValue;
  593. if (gpbArray->_autocreator == self) {
  594. gpbArray->_autocreator = nil;
  595. }
  596. }
  597. } else { // GPBFieldTypeMap
  598. // If the old map was autocreated by us, then clear it.
  599. if ((field.mapKeyDataType == GPBDataTypeString) &&
  600. GPBDataTypeIsObject(fieldType)) {
  601. if ([oldValue isKindOfClass:[GPBAutocreatedDictionary class]]) {
  602. GPBAutocreatedDictionary *autoDict = oldValue;
  603. if (autoDict->_autocreator == self) {
  604. autoDict->_autocreator = nil;
  605. }
  606. }
  607. } else {
  608. // Type doesn't matter, it is a GPB*Dictionary.
  609. GPBInt32Int32Dictionary *gpbDict = oldValue;
  610. if (gpbDict->_autocreator == self) {
  611. gpbDict->_autocreator = nil;
  612. }
  613. }
  614. }
  615. } else if (fieldIsMessage) {
  616. // If the old message value was autocreated by us, then clear it.
  617. GPBMessage *oldMessageValue = oldValue;
  618. if (GPBWasMessageAutocreatedBy(oldMessageValue, self)) {
  619. GPBClearMessageAutocreator(oldMessageValue);
  620. }
  621. }
  622. [oldValue release];
  623. }
  624. GPBBecomeVisibleToAutocreator(self);
  625. }
  626. id GPBGetObjectIvarWithFieldNoAutocreate(GPBMessage *self,
  627. GPBFieldDescriptor *field) {
  628. if (self->messageStorage_ == nil) {
  629. return nil;
  630. }
  631. uint8_t *storage = (uint8_t *)self->messageStorage_;
  632. id *typePtr = (id *)&storage[field->description_->offset];
  633. return *typePtr;
  634. }
  635. // Only exists for public api, no core code should use this.
  636. int32_t GPBGetMessageEnumField(GPBMessage *self, GPBFieldDescriptor *field) {
  637. #if defined(DEBUG) && DEBUG
  638. NSCAssert([[self descriptor] fieldWithNumber:field.number] == field,
  639. @"FieldDescriptor %@ doesn't appear to be for %@ messages.",
  640. field.name, [self class]);
  641. NSCAssert(GPBGetFieldDataType(field) == GPBDataTypeEnum,
  642. @"Attempting to get value of type Enum from field %@ "
  643. @"of %@ which is of type %@.",
  644. [self class], field.name,
  645. TypeToString(GPBGetFieldDataType(field)));
  646. #endif
  647. int32_t result = GPBGetMessageInt32Field(self, field);
  648. // If this is presevering unknown enums, make sure the value is valid before
  649. // returning it.
  650. GPBFileSyntax syntax = [self descriptor].file.syntax;
  651. if (GPBHasPreservingUnknownEnumSemantics(syntax) &&
  652. ![field isValidEnumValue:result]) {
  653. result = kGPBUnrecognizedEnumeratorValue;
  654. }
  655. return result;
  656. }
  657. // Only exists for public api, no core code should use this.
  658. void GPBSetMessageEnumField(GPBMessage *self, GPBFieldDescriptor *field,
  659. int32_t value) {
  660. #if defined(DEBUG) && DEBUG
  661. NSCAssert([[self descriptor] fieldWithNumber:field.number] == field,
  662. @"FieldDescriptor %@ doesn't appear to be for %@ messages.",
  663. field.name, [self class]);
  664. NSCAssert(GPBGetFieldDataType(field) == GPBDataTypeEnum,
  665. @"Attempting to set field %@ of %@ which is of type %@ with "
  666. @"value of type Enum.",
  667. [self class], field.name,
  668. TypeToString(GPBGetFieldDataType(field)));
  669. #endif
  670. GPBSetEnumIvarWithFieldPrivate(self, field, value);
  671. }
  672. void GPBSetEnumIvarWithFieldPrivate(GPBMessage *self,
  673. GPBFieldDescriptor *field, int32_t value) {
  674. // Don't allow in unknown values. Proto3 can use the Raw method.
  675. if (![field isValidEnumValue:value]) {
  676. [NSException raise:NSInvalidArgumentException
  677. format:@"%@.%@: Attempt to set an unknown enum value (%d)",
  678. [self class], field.name, value];
  679. }
  680. GPBSetInt32IvarWithFieldPrivate(self, field, value);
  681. }
  682. // Only exists for public api, no core code should use this.
  683. int32_t GPBGetMessageRawEnumField(GPBMessage *self,
  684. GPBFieldDescriptor *field) {
  685. int32_t result = GPBGetMessageInt32Field(self, field);
  686. return result;
  687. }
  688. // Only exists for public api, no core code should use this.
  689. void GPBSetMessageRawEnumField(GPBMessage *self, GPBFieldDescriptor *field,
  690. int32_t value) {
  691. GPBSetInt32IvarWithFieldPrivate(self, field, value);
  692. }
  693. BOOL GPBGetMessageBoolField(GPBMessage *self,
  694. GPBFieldDescriptor *field) {
  695. #if defined(DEBUG) && DEBUG
  696. NSCAssert([[self descriptor] fieldWithNumber:field.number] == field,
  697. @"FieldDescriptor %@ doesn't appear to be for %@ messages.",
  698. field.name, [self class]);
  699. NSCAssert(DataTypesEquivalent(GPBGetFieldDataType(field), GPBDataTypeBool),
  700. @"Attempting to get value of type bool from field %@ "
  701. @"of %@ which is of type %@.",
  702. [self class], field.name,
  703. TypeToString(GPBGetFieldDataType(field)));
  704. #endif
  705. if (GPBGetHasIvarField(self, field)) {
  706. // Bools are stored in the has bits to avoid needing explicit space in the
  707. // storage structure.
  708. // (the field number passed to the HasIvar helper doesn't really matter
  709. // since the offset is never negative)
  710. GPBMessageFieldDescription *fieldDesc = field->description_;
  711. return GPBGetHasIvar(self, (int32_t)(fieldDesc->offset), fieldDesc->number);
  712. } else {
  713. return field.defaultValue.valueBool;
  714. }
  715. }
  716. // Only exists for public api, no core code should use this.
  717. void GPBSetMessageBoolField(GPBMessage *self,
  718. GPBFieldDescriptor *field,
  719. BOOL value) {
  720. if (self == nil || field == nil) return;
  721. #if defined(DEBUG) && DEBUG
  722. NSCAssert([[self descriptor] fieldWithNumber:field.number] == field,
  723. @"FieldDescriptor %@ doesn't appear to be for %@ messages.",
  724. field.name, [self class]);
  725. NSCAssert(DataTypesEquivalent(GPBGetFieldDataType(field), GPBDataTypeBool),
  726. @"Attempting to set field %@ of %@ which is of type %@ with "
  727. @"value of type bool.",
  728. [self class], field.name,
  729. TypeToString(GPBGetFieldDataType(field)));
  730. #endif
  731. GPBSetBoolIvarWithFieldPrivate(self, field, value);
  732. }
  733. void GPBSetBoolIvarWithFieldPrivate(GPBMessage *self,
  734. GPBFieldDescriptor *field,
  735. BOOL value) {
  736. GPBMessageFieldDescription *fieldDesc = field->description_;
  737. GPBOneofDescriptor *oneof = field->containingOneof_;
  738. if (oneof) {
  739. GPBMaybeClearOneofPrivate(self, oneof, fieldDesc->hasIndex, fieldDesc->number);
  740. }
  741. // Bools are stored in the has bits to avoid needing explicit space in the
  742. // storage structure.
  743. // (the field number passed to the HasIvar helper doesn't really matter since
  744. // the offset is never negative)
  745. GPBSetHasIvar(self, (int32_t)(fieldDesc->offset), fieldDesc->number, value);
  746. // If the value is zero, then we only count the field as "set" if the field
  747. // shouldn't auto clear on zero.
  748. BOOL hasValue = ((value != (BOOL)0)
  749. || ((fieldDesc->flags & GPBFieldClearHasIvarOnZero) == 0));
  750. GPBSetHasIvar(self, fieldDesc->hasIndex, fieldDesc->number, hasValue);
  751. GPBBecomeVisibleToAutocreator(self);
  752. }
  753. //%PDDM-EXPAND IVAR_POD_ACCESSORS_DEFN(Int32, int32_t)
  754. // This block of code is generated, do not edit it directly.
  755. // clang-format off
  756. int32_t GPBGetMessageInt32Field(GPBMessage *self,
  757. GPBFieldDescriptor *field) {
  758. #if defined(DEBUG) && DEBUG
  759. NSCAssert([[self descriptor] fieldWithNumber:field.number] == field,
  760. @"FieldDescriptor %@ doesn't appear to be for %@ messages.",
  761. field.name, [self class]);
  762. NSCAssert(DataTypesEquivalent(GPBGetFieldDataType(field),
  763. GPBDataTypeInt32),
  764. @"Attempting to get value of int32_t from field %@ "
  765. @"of %@ which is of type %@.",
  766. [self class], field.name,
  767. TypeToString(GPBGetFieldDataType(field)));
  768. #endif
  769. if (GPBGetHasIvarField(self, field)) {
  770. uint8_t *storage = (uint8_t *)self->messageStorage_;
  771. int32_t *typePtr = (int32_t *)&storage[field->description_->offset];
  772. return *typePtr;
  773. } else {
  774. return field.defaultValue.valueInt32;
  775. }
  776. }
  777. // Only exists for public api, no core code should use this.
  778. void GPBSetMessageInt32Field(GPBMessage *self,
  779. GPBFieldDescriptor *field,
  780. int32_t value) {
  781. if (self == nil || field == nil) return;
  782. #if defined(DEBUG) && DEBUG
  783. NSCAssert([[self descriptor] fieldWithNumber:field.number] == field,
  784. @"FieldDescriptor %@ doesn't appear to be for %@ messages.",
  785. field.name, [self class]);
  786. NSCAssert(DataTypesEquivalent(GPBGetFieldDataType(field),
  787. GPBDataTypeInt32),
  788. @"Attempting to set field %@ of %@ which is of type %@ with "
  789. @"value of type int32_t.",
  790. [self class], field.name,
  791. TypeToString(GPBGetFieldDataType(field)));
  792. #endif
  793. GPBSetInt32IvarWithFieldPrivate(self, field, value);
  794. }
  795. void GPBSetInt32IvarWithFieldPrivate(GPBMessage *self,
  796. GPBFieldDescriptor *field,
  797. int32_t value) {
  798. GPBOneofDescriptor *oneof = field->containingOneof_;
  799. GPBMessageFieldDescription *fieldDesc = field->description_;
  800. if (oneof) {
  801. GPBMaybeClearOneofPrivate(self, oneof, fieldDesc->hasIndex, fieldDesc->number);
  802. }
  803. #if defined(DEBUG) && DEBUG
  804. NSCAssert(self->messageStorage_ != NULL,
  805. @"%@: All messages should have storage (from init)",
  806. [self class]);
  807. #endif
  808. #if defined(__clang_analyzer__)
  809. if (self->messageStorage_ == NULL) return;
  810. #endif
  811. uint8_t *storage = (uint8_t *)self->messageStorage_;
  812. int32_t *typePtr = (int32_t *)&storage[fieldDesc->offset];
  813. *typePtr = value;
  814. // If the value is zero, then we only count the field as "set" if the field
  815. // shouldn't auto clear on zero.
  816. BOOL hasValue = ((value != (int32_t)0)
  817. || ((fieldDesc->flags & GPBFieldClearHasIvarOnZero) == 0));
  818. GPBSetHasIvar(self, fieldDesc->hasIndex, fieldDesc->number, hasValue);
  819. GPBBecomeVisibleToAutocreator(self);
  820. }
  821. // clang-format on
  822. //%PDDM-EXPAND IVAR_POD_ACCESSORS_DEFN(UInt32, uint32_t)
  823. // This block of code is generated, do not edit it directly.
  824. // clang-format off
  825. uint32_t GPBGetMessageUInt32Field(GPBMessage *self,
  826. GPBFieldDescriptor *field) {
  827. #if defined(DEBUG) && DEBUG
  828. NSCAssert([[self descriptor] fieldWithNumber:field.number] == field,
  829. @"FieldDescriptor %@ doesn't appear to be for %@ messages.",
  830. field.name, [self class]);
  831. NSCAssert(DataTypesEquivalent(GPBGetFieldDataType(field),
  832. GPBDataTypeUInt32),
  833. @"Attempting to get value of uint32_t from field %@ "
  834. @"of %@ which is of type %@.",
  835. [self class], field.name,
  836. TypeToString(GPBGetFieldDataType(field)));
  837. #endif
  838. if (GPBGetHasIvarField(self, field)) {
  839. uint8_t *storage = (uint8_t *)self->messageStorage_;
  840. uint32_t *typePtr = (uint32_t *)&storage[field->description_->offset];
  841. return *typePtr;
  842. } else {
  843. return field.defaultValue.valueUInt32;
  844. }
  845. }
  846. // Only exists for public api, no core code should use this.
  847. void GPBSetMessageUInt32Field(GPBMessage *self,
  848. GPBFieldDescriptor *field,
  849. uint32_t value) {
  850. if (self == nil || field == nil) return;
  851. #if defined(DEBUG) && DEBUG
  852. NSCAssert([[self descriptor] fieldWithNumber:field.number] == field,
  853. @"FieldDescriptor %@ doesn't appear to be for %@ messages.",
  854. field.name, [self class]);
  855. NSCAssert(DataTypesEquivalent(GPBGetFieldDataType(field),
  856. GPBDataTypeUInt32),
  857. @"Attempting to set field %@ of %@ which is of type %@ with "
  858. @"value of type uint32_t.",
  859. [self class], field.name,
  860. TypeToString(GPBGetFieldDataType(field)));
  861. #endif
  862. GPBSetUInt32IvarWithFieldPrivate(self, field, value);
  863. }
  864. void GPBSetUInt32IvarWithFieldPrivate(GPBMessage *self,
  865. GPBFieldDescriptor *field,
  866. uint32_t value) {
  867. GPBOneofDescriptor *oneof = field->containingOneof_;
  868. GPBMessageFieldDescription *fieldDesc = field->description_;
  869. if (oneof) {
  870. GPBMaybeClearOneofPrivate(self, oneof, fieldDesc->hasIndex, fieldDesc->number);
  871. }
  872. #if defined(DEBUG) && DEBUG
  873. NSCAssert(self->messageStorage_ != NULL,
  874. @"%@: All messages should have storage (from init)",
  875. [self class]);
  876. #endif
  877. #if defined(__clang_analyzer__)
  878. if (self->messageStorage_ == NULL) return;
  879. #endif
  880. uint8_t *storage = (uint8_t *)self->messageStorage_;
  881. uint32_t *typePtr = (uint32_t *)&storage[fieldDesc->offset];
  882. *typePtr = value;
  883. // If the value is zero, then we only count the field as "set" if the field
  884. // shouldn't auto clear on zero.
  885. BOOL hasValue = ((value != (uint32_t)0)
  886. || ((fieldDesc->flags & GPBFieldClearHasIvarOnZero) == 0));
  887. GPBSetHasIvar(self, fieldDesc->hasIndex, fieldDesc->number, hasValue);
  888. GPBBecomeVisibleToAutocreator(self);
  889. }
  890. // clang-format on
  891. //%PDDM-EXPAND IVAR_POD_ACCESSORS_DEFN(Int64, int64_t)
  892. // This block of code is generated, do not edit it directly.
  893. // clang-format off
  894. int64_t GPBGetMessageInt64Field(GPBMessage *self,
  895. GPBFieldDescriptor *field) {
  896. #if defined(DEBUG) && DEBUG
  897. NSCAssert([[self descriptor] fieldWithNumber:field.number] == field,
  898. @"FieldDescriptor %@ doesn't appear to be for %@ messages.",
  899. field.name, [self class]);
  900. NSCAssert(DataTypesEquivalent(GPBGetFieldDataType(field),
  901. GPBDataTypeInt64),
  902. @"Attempting to get value of int64_t from field %@ "
  903. @"of %@ which is of type %@.",
  904. [self class], field.name,
  905. TypeToString(GPBGetFieldDataType(field)));
  906. #endif
  907. if (GPBGetHasIvarField(self, field)) {
  908. uint8_t *storage = (uint8_t *)self->messageStorage_;
  909. int64_t *typePtr = (int64_t *)&storage[field->description_->offset];
  910. return *typePtr;
  911. } else {
  912. return field.defaultValue.valueInt64;
  913. }
  914. }
  915. // Only exists for public api, no core code should use this.
  916. void GPBSetMessageInt64Field(GPBMessage *self,
  917. GPBFieldDescriptor *field,
  918. int64_t value) {
  919. if (self == nil || field == nil) return;
  920. #if defined(DEBUG) && DEBUG
  921. NSCAssert([[self descriptor] fieldWithNumber:field.number] == field,
  922. @"FieldDescriptor %@ doesn't appear to be for %@ messages.",
  923. field.name, [self class]);
  924. NSCAssert(DataTypesEquivalent(GPBGetFieldDataType(field),
  925. GPBDataTypeInt64),
  926. @"Attempting to set field %@ of %@ which is of type %@ with "
  927. @"value of type int64_t.",
  928. [self class], field.name,
  929. TypeToString(GPBGetFieldDataType(field)));
  930. #endif
  931. GPBSetInt64IvarWithFieldPrivate(self, field, value);
  932. }
  933. void GPBSetInt64IvarWithFieldPrivate(GPBMessage *self,
  934. GPBFieldDescriptor *field,
  935. int64_t value) {
  936. GPBOneofDescriptor *oneof = field->containingOneof_;
  937. GPBMessageFieldDescription *fieldDesc = field->description_;
  938. if (oneof) {
  939. GPBMaybeClearOneofPrivate(self, oneof, fieldDesc->hasIndex, fieldDesc->number);
  940. }
  941. #if defined(DEBUG) && DEBUG
  942. NSCAssert(self->messageStorage_ != NULL,
  943. @"%@: All messages should have storage (from init)",
  944. [self class]);
  945. #endif
  946. #if defined(__clang_analyzer__)
  947. if (self->messageStorage_ == NULL) return;
  948. #endif
  949. uint8_t *storage = (uint8_t *)self->messageStorage_;
  950. int64_t *typePtr = (int64_t *)&storage[fieldDesc->offset];
  951. *typePtr = value;
  952. // If the value is zero, then we only count the field as "set" if the field
  953. // shouldn't auto clear on zero.
  954. BOOL hasValue = ((value != (int64_t)0)
  955. || ((fieldDesc->flags & GPBFieldClearHasIvarOnZero) == 0));
  956. GPBSetHasIvar(self, fieldDesc->hasIndex, fieldDesc->number, hasValue);
  957. GPBBecomeVisibleToAutocreator(self);
  958. }
  959. // clang-format on
  960. //%PDDM-EXPAND IVAR_POD_ACCESSORS_DEFN(UInt64, uint64_t)
  961. // This block of code is generated, do not edit it directly.
  962. // clang-format off
  963. uint64_t GPBGetMessageUInt64Field(GPBMessage *self,
  964. GPBFieldDescriptor *field) {
  965. #if defined(DEBUG) && DEBUG
  966. NSCAssert([[self descriptor] fieldWithNumber:field.number] == field,
  967. @"FieldDescriptor %@ doesn't appear to be for %@ messages.",
  968. field.name, [self class]);
  969. NSCAssert(DataTypesEquivalent(GPBGetFieldDataType(field),
  970. GPBDataTypeUInt64),
  971. @"Attempting to get value of uint64_t from field %@ "
  972. @"of %@ which is of type %@.",
  973. [self class], field.name,
  974. TypeToString(GPBGetFieldDataType(field)));
  975. #endif
  976. if (GPBGetHasIvarField(self, field)) {
  977. uint8_t *storage = (uint8_t *)self->messageStorage_;
  978. uint64_t *typePtr = (uint64_t *)&storage[field->description_->offset];
  979. return *typePtr;
  980. } else {
  981. return field.defaultValue.valueUInt64;
  982. }
  983. }
  984. // Only exists for public api, no core code should use this.
  985. void GPBSetMessageUInt64Field(GPBMessage *self,
  986. GPBFieldDescriptor *field,
  987. uint64_t value) {
  988. if (self == nil || field == nil) return;
  989. #if defined(DEBUG) && DEBUG
  990. NSCAssert([[self descriptor] fieldWithNumber:field.number] == field,
  991. @"FieldDescriptor %@ doesn't appear to be for %@ messages.",
  992. field.name, [self class]);
  993. NSCAssert(DataTypesEquivalent(GPBGetFieldDataType(field),
  994. GPBDataTypeUInt64),
  995. @"Attempting to set field %@ of %@ which is of type %@ with "
  996. @"value of type uint64_t.",
  997. [self class], field.name,
  998. TypeToString(GPBGetFieldDataType(field)));
  999. #endif
  1000. GPBSetUInt64IvarWithFieldPrivate(self, field, value);
  1001. }
  1002. void GPBSetUInt64IvarWithFieldPrivate(GPBMessage *self,
  1003. GPBFieldDescriptor *field,
  1004. uint64_t value) {
  1005. GPBOneofDescriptor *oneof = field->containingOneof_;
  1006. GPBMessageFieldDescription *fieldDesc = field->description_;
  1007. if (oneof) {
  1008. GPBMaybeClearOneofPrivate(self, oneof, fieldDesc->hasIndex, fieldDesc->number);
  1009. }
  1010. #if defined(DEBUG) && DEBUG
  1011. NSCAssert(self->messageStorage_ != NULL,
  1012. @"%@: All messages should have storage (from init)",
  1013. [self class]);
  1014. #endif
  1015. #if defined(__clang_analyzer__)
  1016. if (self->messageStorage_ == NULL) return;
  1017. #endif
  1018. uint8_t *storage = (uint8_t *)self->messageStorage_;
  1019. uint64_t *typePtr = (uint64_t *)&storage[fieldDesc->offset];
  1020. *typePtr = value;
  1021. // If the value is zero, then we only count the field as "set" if the field
  1022. // shouldn't auto clear on zero.
  1023. BOOL hasValue = ((value != (uint64_t)0)
  1024. || ((fieldDesc->flags & GPBFieldClearHasIvarOnZero) == 0));
  1025. GPBSetHasIvar(self, fieldDesc->hasIndex, fieldDesc->number, hasValue);
  1026. GPBBecomeVisibleToAutocreator(self);
  1027. }
  1028. // clang-format on
  1029. //%PDDM-EXPAND IVAR_POD_ACCESSORS_DEFN(Float, float)
  1030. // This block of code is generated, do not edit it directly.
  1031. // clang-format off
  1032. float GPBGetMessageFloatField(GPBMessage *self,
  1033. GPBFieldDescriptor *field) {
  1034. #if defined(DEBUG) && DEBUG
  1035. NSCAssert([[self descriptor] fieldWithNumber:field.number] == field,
  1036. @"FieldDescriptor %@ doesn't appear to be for %@ messages.",
  1037. field.name, [self class]);
  1038. NSCAssert(DataTypesEquivalent(GPBGetFieldDataType(field),
  1039. GPBDataTypeFloat),
  1040. @"Attempting to get value of float from field %@ "
  1041. @"of %@ which is of type %@.",
  1042. [self class], field.name,
  1043. TypeToString(GPBGetFieldDataType(field)));
  1044. #endif
  1045. if (GPBGetHasIvarField(self, field)) {
  1046. uint8_t *storage = (uint8_t *)self->messageStorage_;
  1047. float *typePtr = (float *)&storage[field->description_->offset];
  1048. return *typePtr;
  1049. } else {
  1050. return field.defaultValue.valueFloat;
  1051. }
  1052. }
  1053. // Only exists for public api, no core code should use this.
  1054. void GPBSetMessageFloatField(GPBMessage *self,
  1055. GPBFieldDescriptor *field,
  1056. float value) {
  1057. if (self == nil || field == nil) return;
  1058. #if defined(DEBUG) && DEBUG
  1059. NSCAssert([[self descriptor] fieldWithNumber:field.number] == field,
  1060. @"FieldDescriptor %@ doesn't appear to be for %@ messages.",
  1061. field.name, [self class]);
  1062. NSCAssert(DataTypesEquivalent(GPBGetFieldDataType(field),
  1063. GPBDataTypeFloat),
  1064. @"Attempting to set field %@ of %@ which is of type %@ with "
  1065. @"value of type float.",
  1066. [self class], field.name,
  1067. TypeToString(GPBGetFieldDataType(field)));
  1068. #endif
  1069. GPBSetFloatIvarWithFieldPrivate(self, field, value);
  1070. }
  1071. void GPBSetFloatIvarWithFieldPrivate(GPBMessage *self,
  1072. GPBFieldDescriptor *field,
  1073. float value) {
  1074. GPBOneofDescriptor *oneof = field->containingOneof_;
  1075. GPBMessageFieldDescription *fieldDesc = field->description_;
  1076. if (oneof) {
  1077. GPBMaybeClearOneofPrivate(self, oneof, fieldDesc->hasIndex, fieldDesc->number);
  1078. }
  1079. #if defined(DEBUG) && DEBUG
  1080. NSCAssert(self->messageStorage_ != NULL,
  1081. @"%@: All messages should have storage (from init)",
  1082. [self class]);
  1083. #endif
  1084. #if defined(__clang_analyzer__)
  1085. if (self->messageStorage_ == NULL) return;
  1086. #endif
  1087. uint8_t *storage = (uint8_t *)self->messageStorage_;
  1088. float *typePtr = (float *)&storage[fieldDesc->offset];
  1089. *typePtr = value;
  1090. // If the value is zero, then we only count the field as "set" if the field
  1091. // shouldn't auto clear on zero.
  1092. BOOL hasValue = ((value != (float)0)
  1093. || ((fieldDesc->flags & GPBFieldClearHasIvarOnZero) == 0));
  1094. GPBSetHasIvar(self, fieldDesc->hasIndex, fieldDesc->number, hasValue);
  1095. GPBBecomeVisibleToAutocreator(self);
  1096. }
  1097. // clang-format on
  1098. //%PDDM-EXPAND IVAR_POD_ACCESSORS_DEFN(Double, double)
  1099. // This block of code is generated, do not edit it directly.
  1100. // clang-format off
  1101. double GPBGetMessageDoubleField(GPBMessage *self,
  1102. GPBFieldDescriptor *field) {
  1103. #if defined(DEBUG) && DEBUG
  1104. NSCAssert([[self descriptor] fieldWithNumber:field.number] == field,
  1105. @"FieldDescriptor %@ doesn't appear to be for %@ messages.",
  1106. field.name, [self class]);
  1107. NSCAssert(DataTypesEquivalent(GPBGetFieldDataType(field),
  1108. GPBDataTypeDouble),
  1109. @"Attempting to get value of double from field %@ "
  1110. @"of %@ which is of type %@.",
  1111. [self class], field.name,
  1112. TypeToString(GPBGetFieldDataType(field)));
  1113. #endif
  1114. if (GPBGetHasIvarField(self, field)) {
  1115. uint8_t *storage = (uint8_t *)self->messageStorage_;
  1116. double *typePtr = (double *)&storage[field->description_->offset];
  1117. return *typePtr;
  1118. } else {
  1119. return field.defaultValue.valueDouble;
  1120. }
  1121. }
  1122. // Only exists for public api, no core code should use this.
  1123. void GPBSetMessageDoubleField(GPBMessage *self,
  1124. GPBFieldDescriptor *field,
  1125. double value) {
  1126. if (self == nil || field == nil) return;
  1127. #if defined(DEBUG) && DEBUG
  1128. NSCAssert([[self descriptor] fieldWithNumber:field.number] == field,
  1129. @"FieldDescriptor %@ doesn't appear to be for %@ messages.",
  1130. field.name, [self class]);
  1131. NSCAssert(DataTypesEquivalent(GPBGetFieldDataType(field),
  1132. GPBDataTypeDouble),
  1133. @"Attempting to set field %@ of %@ which is of type %@ with "
  1134. @"value of type double.",
  1135. [self class], field.name,
  1136. TypeToString(GPBGetFieldDataType(field)));
  1137. #endif
  1138. GPBSetDoubleIvarWithFieldPrivate(self, field, value);
  1139. }
  1140. void GPBSetDoubleIvarWithFieldPrivate(GPBMessage *self,
  1141. GPBFieldDescriptor *field,
  1142. double value) {
  1143. GPBOneofDescriptor *oneof = field->containingOneof_;
  1144. GPBMessageFieldDescription *fieldDesc = field->description_;
  1145. if (oneof) {
  1146. GPBMaybeClearOneofPrivate(self, oneof, fieldDesc->hasIndex, fieldDesc->number);
  1147. }
  1148. #if defined(DEBUG) && DEBUG
  1149. NSCAssert(self->messageStorage_ != NULL,
  1150. @"%@: All messages should have storage (from init)",
  1151. [self class]);
  1152. #endif
  1153. #if defined(__clang_analyzer__)
  1154. if (self->messageStorage_ == NULL) return;
  1155. #endif
  1156. uint8_t *storage = (uint8_t *)self->messageStorage_;
  1157. double *typePtr = (double *)&storage[fieldDesc->offset];
  1158. *typePtr = value;
  1159. // If the value is zero, then we only count the field as "set" if the field
  1160. // shouldn't auto clear on zero.
  1161. BOOL hasValue = ((value != (double)0)
  1162. || ((fieldDesc->flags & GPBFieldClearHasIvarOnZero) == 0));
  1163. GPBSetHasIvar(self, fieldDesc->hasIndex, fieldDesc->number, hasValue);
  1164. GPBBecomeVisibleToAutocreator(self);
  1165. }
  1166. // clang-format on
  1167. //%PDDM-EXPAND-END (6 expansions)
  1168. // Aliases are function calls that are virtually the same.
  1169. //%PDDM-EXPAND IVAR_ALIAS_DEFN_COPY_OBJECT(String, NSString)
  1170. // This block of code is generated, do not edit it directly.
  1171. // clang-format off
  1172. // Only exists for public api, no core code should use this.
  1173. NSString *GPBGetMessageStringField(GPBMessage *self,
  1174. GPBFieldDescriptor *field) {
  1175. #if defined(DEBUG) && DEBUG
  1176. NSCAssert(DataTypesEquivalent(GPBGetFieldDataType(field),
  1177. GPBDataTypeString),
  1178. @"Attempting to get value of NSString from field %@ "
  1179. @"of %@ which is of type %@.",
  1180. [self class], field.name,
  1181. TypeToString(GPBGetFieldDataType(field)));
  1182. #endif
  1183. return (NSString *)GPBGetObjectIvarWithField(self, field);
  1184. }
  1185. // Only exists for public api, no core code should use this.
  1186. void GPBSetMessageStringField(GPBMessage *self,
  1187. GPBFieldDescriptor *field,
  1188. NSString *value) {
  1189. #if defined(DEBUG) && DEBUG
  1190. NSCAssert(DataTypesEquivalent(GPBGetFieldDataType(field),
  1191. GPBDataTypeString),
  1192. @"Attempting to set field %@ of %@ which is of type %@ with "
  1193. @"value of type NSString.",
  1194. [self class], field.name,
  1195. TypeToString(GPBGetFieldDataType(field)));
  1196. #endif
  1197. GPBSetCopyObjectIvarWithField(self, field, (id)value);
  1198. }
  1199. // clang-format on
  1200. //%PDDM-EXPAND IVAR_ALIAS_DEFN_COPY_OBJECT(Bytes, NSData)
  1201. // This block of code is generated, do not edit it directly.
  1202. // clang-format off
  1203. // Only exists for public api, no core code should use this.
  1204. NSData *GPBGetMessageBytesField(GPBMessage *self,
  1205. GPBFieldDescriptor *field) {
  1206. #if defined(DEBUG) && DEBUG
  1207. NSCAssert(DataTypesEquivalent(GPBGetFieldDataType(field),
  1208. GPBDataTypeBytes),
  1209. @"Attempting to get value of NSData from field %@ "
  1210. @"of %@ which is of type %@.",
  1211. [self class], field.name,
  1212. TypeToString(GPBGetFieldDataType(field)));
  1213. #endif
  1214. return (NSData *)GPBGetObjectIvarWithField(self, field);
  1215. }
  1216. // Only exists for public api, no core code should use this.
  1217. void GPBSetMessageBytesField(GPBMessage *self,
  1218. GPBFieldDescriptor *field,
  1219. NSData *value) {
  1220. #if defined(DEBUG) && DEBUG
  1221. NSCAssert(DataTypesEquivalent(GPBGetFieldDataType(field),
  1222. GPBDataTypeBytes),
  1223. @"Attempting to set field %@ of %@ which is of type %@ with "
  1224. @"value of type NSData.",
  1225. [self class], field.name,
  1226. TypeToString(GPBGetFieldDataType(field)));
  1227. #endif
  1228. GPBSetCopyObjectIvarWithField(self, field, (id)value);
  1229. }
  1230. // clang-format on
  1231. //%PDDM-EXPAND IVAR_ALIAS_DEFN_OBJECT(Message, GPBMessage)
  1232. // This block of code is generated, do not edit it directly.
  1233. // clang-format off
  1234. // Only exists for public api, no core code should use this.
  1235. GPBMessage *GPBGetMessageMessageField(GPBMessage *self,
  1236. GPBFieldDescriptor *field) {
  1237. #if defined(DEBUG) && DEBUG
  1238. NSCAssert(DataTypesEquivalent(GPBGetFieldDataType(field),
  1239. GPBDataTypeMessage),
  1240. @"Attempting to get value of GPBMessage from field %@ "
  1241. @"of %@ which is of type %@.",
  1242. [self class], field.name,
  1243. TypeToString(GPBGetFieldDataType(field)));
  1244. #endif
  1245. return (GPBMessage *)GPBGetObjectIvarWithField(self, field);
  1246. }
  1247. // Only exists for public api, no core code should use this.
  1248. void GPBSetMessageMessageField(GPBMessage *self,
  1249. GPBFieldDescriptor *field,
  1250. GPBMessage *value) {
  1251. #if defined(DEBUG) && DEBUG
  1252. NSCAssert(DataTypesEquivalent(GPBGetFieldDataType(field),
  1253. GPBDataTypeMessage),
  1254. @"Attempting to set field %@ of %@ which is of type %@ with "
  1255. @"value of type GPBMessage.",
  1256. [self class], field.name,
  1257. TypeToString(GPBGetFieldDataType(field)));
  1258. #endif
  1259. GPBSetObjectIvarWithField(self, field, (id)value);
  1260. }
  1261. // clang-format on
  1262. //%PDDM-EXPAND IVAR_ALIAS_DEFN_OBJECT(Group, GPBMessage)
  1263. // This block of code is generated, do not edit it directly.
  1264. // clang-format off
  1265. // Only exists for public api, no core code should use this.
  1266. GPBMessage *GPBGetMessageGroupField(GPBMessage *self,
  1267. GPBFieldDescriptor *field) {
  1268. #if defined(DEBUG) && DEBUG
  1269. NSCAssert(DataTypesEquivalent(GPBGetFieldDataType(field),
  1270. GPBDataTypeGroup),
  1271. @"Attempting to get value of GPBMessage from field %@ "
  1272. @"of %@ which is of type %@.",
  1273. [self class], field.name,
  1274. TypeToString(GPBGetFieldDataType(field)));
  1275. #endif
  1276. return (GPBMessage *)GPBGetObjectIvarWithField(self, field);
  1277. }
  1278. // Only exists for public api, no core code should use this.
  1279. void GPBSetMessageGroupField(GPBMessage *self,
  1280. GPBFieldDescriptor *field,
  1281. GPBMessage *value) {
  1282. #if defined(DEBUG) && DEBUG
  1283. NSCAssert(DataTypesEquivalent(GPBGetFieldDataType(field),
  1284. GPBDataTypeGroup),
  1285. @"Attempting to set field %@ of %@ which is of type %@ with "
  1286. @"value of type GPBMessage.",
  1287. [self class], field.name,
  1288. TypeToString(GPBGetFieldDataType(field)));
  1289. #endif
  1290. GPBSetObjectIvarWithField(self, field, (id)value);
  1291. }
  1292. // clang-format on
  1293. //%PDDM-EXPAND-END (4 expansions)
  1294. // GPBGetMessageRepeatedField is defined in GPBMessage.m
  1295. // Only exists for public api, no core code should use this.
  1296. void GPBSetMessageRepeatedField(GPBMessage *self, GPBFieldDescriptor *field, id array) {
  1297. #if defined(DEBUG) && DEBUG
  1298. if (field.fieldType != GPBFieldTypeRepeated) {
  1299. [NSException raise:NSInvalidArgumentException
  1300. format:@"%@.%@ is not a repeated field.",
  1301. [self class], field.name];
  1302. }
  1303. Class expectedClass = Nil;
  1304. switch (GPBGetFieldDataType(field)) {
  1305. case GPBDataTypeBool:
  1306. expectedClass = [GPBBoolArray class];
  1307. break;
  1308. case GPBDataTypeSFixed32:
  1309. case GPBDataTypeInt32:
  1310. case GPBDataTypeSInt32:
  1311. expectedClass = [GPBInt32Array class];
  1312. break;
  1313. case GPBDataTypeFixed32:
  1314. case GPBDataTypeUInt32:
  1315. expectedClass = [GPBUInt32Array class];
  1316. break;
  1317. case GPBDataTypeSFixed64:
  1318. case GPBDataTypeInt64:
  1319. case GPBDataTypeSInt64:
  1320. expectedClass = [GPBInt64Array class];
  1321. break;
  1322. case GPBDataTypeFixed64:
  1323. case GPBDataTypeUInt64:
  1324. expectedClass = [GPBUInt64Array class];
  1325. break;
  1326. case GPBDataTypeFloat:
  1327. expectedClass = [GPBFloatArray class];
  1328. break;
  1329. case GPBDataTypeDouble:
  1330. expectedClass = [GPBDoubleArray class];
  1331. break;
  1332. case GPBDataTypeBytes:
  1333. case GPBDataTypeString:
  1334. case GPBDataTypeMessage:
  1335. case GPBDataTypeGroup:
  1336. expectedClass = [NSMutableArray class];
  1337. break;
  1338. case GPBDataTypeEnum:
  1339. expectedClass = [GPBEnumArray class];
  1340. break;
  1341. }
  1342. if (array && ![array isKindOfClass:expectedClass]) {
  1343. [NSException raise:NSInvalidArgumentException
  1344. format:@"%@.%@: Expected %@ object, got %@.",
  1345. [self class], field.name, expectedClass, [array class]];
  1346. }
  1347. #endif
  1348. GPBSetObjectIvarWithField(self, field, array);
  1349. }
  1350. static GPBDataType BaseDataType(GPBDataType type) {
  1351. switch (type) {
  1352. case GPBDataTypeSFixed32:
  1353. case GPBDataTypeInt32:
  1354. case GPBDataTypeSInt32:
  1355. case GPBDataTypeEnum:
  1356. return GPBDataTypeInt32;
  1357. case GPBDataTypeFixed32:
  1358. case GPBDataTypeUInt32:
  1359. return GPBDataTypeUInt32;
  1360. case GPBDataTypeSFixed64:
  1361. case GPBDataTypeInt64:
  1362. case GPBDataTypeSInt64:
  1363. return GPBDataTypeInt64;
  1364. case GPBDataTypeFixed64:
  1365. case GPBDataTypeUInt64:
  1366. return GPBDataTypeUInt64;
  1367. case GPBDataTypeMessage:
  1368. case GPBDataTypeGroup:
  1369. return GPBDataTypeMessage;
  1370. case GPBDataTypeBool:
  1371. case GPBDataTypeFloat:
  1372. case GPBDataTypeDouble:
  1373. case GPBDataTypeBytes:
  1374. case GPBDataTypeString:
  1375. return type;
  1376. }
  1377. }
  1378. static BOOL DataTypesEquivalent(GPBDataType type1, GPBDataType type2) {
  1379. return BaseDataType(type1) == BaseDataType(type2);
  1380. }
  1381. static NSString *TypeToString(GPBDataType dataType) {
  1382. switch (dataType) {
  1383. case GPBDataTypeBool:
  1384. return @"Bool";
  1385. case GPBDataTypeSFixed32:
  1386. case GPBDataTypeInt32:
  1387. case GPBDataTypeSInt32:
  1388. return @"Int32";
  1389. case GPBDataTypeFixed32:
  1390. case GPBDataTypeUInt32:
  1391. return @"UInt32";
  1392. case GPBDataTypeSFixed64:
  1393. case GPBDataTypeInt64:
  1394. case GPBDataTypeSInt64:
  1395. return @"Int64";
  1396. case GPBDataTypeFixed64:
  1397. case GPBDataTypeUInt64:
  1398. return @"UInt64";
  1399. case GPBDataTypeFloat:
  1400. return @"Float";
  1401. case GPBDataTypeDouble:
  1402. return @"Double";
  1403. case GPBDataTypeBytes:
  1404. case GPBDataTypeString:
  1405. case GPBDataTypeMessage:
  1406. case GPBDataTypeGroup:
  1407. return @"Object";
  1408. case GPBDataTypeEnum:
  1409. return @"Enum";
  1410. }
  1411. }
  1412. // GPBGetMessageMapField is defined in GPBMessage.m
  1413. // Only exists for public api, no core code should use this.
  1414. void GPBSetMessageMapField(GPBMessage *self, GPBFieldDescriptor *field,
  1415. id dictionary) {
  1416. #if defined(DEBUG) && DEBUG
  1417. if (field.fieldType != GPBFieldTypeMap) {
  1418. [NSException raise:NSInvalidArgumentException
  1419. format:@"%@.%@ is not a map<> field.",
  1420. [self class], field.name];
  1421. }
  1422. if (dictionary) {
  1423. GPBDataType keyDataType = field.mapKeyDataType;
  1424. GPBDataType valueDataType = GPBGetFieldDataType(field);
  1425. NSString *keyStr = TypeToString(keyDataType);
  1426. NSString *valueStr = TypeToString(valueDataType);
  1427. if (keyDataType == GPBDataTypeString) {
  1428. keyStr = @"String";
  1429. }
  1430. Class expectedClass = Nil;
  1431. if ((keyDataType == GPBDataTypeString) &&
  1432. GPBDataTypeIsObject(valueDataType)) {
  1433. expectedClass = [NSMutableDictionary class];
  1434. } else {
  1435. NSString *className =
  1436. [NSString stringWithFormat:@"GPB%@%@Dictionary", keyStr, valueStr];
  1437. expectedClass = NSClassFromString(className);
  1438. NSCAssert(expectedClass, @"Missing a class (%@)?", expectedClass);
  1439. }
  1440. if (![dictionary isKindOfClass:expectedClass]) {
  1441. [NSException raise:NSInvalidArgumentException
  1442. format:@"%@.%@: Expected %@ object, got %@.",
  1443. [self class], field.name, expectedClass,
  1444. [dictionary class]];
  1445. }
  1446. }
  1447. #endif
  1448. GPBSetObjectIvarWithField(self, field, dictionary);
  1449. }
  1450. #pragma mark - Misc Dynamic Runtime Utils
  1451. const char *GPBMessageEncodingForSelector(SEL selector, BOOL instanceSel) {
  1452. Protocol *protocol =
  1453. objc_getProtocol(GPBStringifySymbol(GPBMessageSignatureProtocol));
  1454. NSCAssert(protocol, @"Missing GPBMessageSignatureProtocol");
  1455. struct objc_method_description description =
  1456. protocol_getMethodDescription(protocol, selector, NO, instanceSel);
  1457. NSCAssert(description.name != Nil && description.types != nil,
  1458. @"Missing method for selector %@", NSStringFromSelector(selector));
  1459. return description.types;
  1460. }
  1461. #pragma mark - Text Format Support
  1462. static void AppendStringEscaped(NSString *toPrint, NSMutableString *destStr) {
  1463. [destStr appendString:@"\""];
  1464. NSUInteger len = [toPrint length];
  1465. for (NSUInteger i = 0; i < len; ++i) {
  1466. unichar aChar = [toPrint characterAtIndex:i];
  1467. switch (aChar) {
  1468. case '\n': [destStr appendString:@"\\n"]; break;
  1469. case '\r': [destStr appendString:@"\\r"]; break;
  1470. case '\t': [destStr appendString:@"\\t"]; break;
  1471. case '\"': [destStr appendString:@"\\\""]; break;
  1472. case '\'': [destStr appendString:@"\\\'"]; break;
  1473. case '\\': [destStr appendString:@"\\\\"]; break;
  1474. default:
  1475. // This differs slightly from the C++ code in that the C++ doesn't
  1476. // generate UTF8; it looks at the string in UTF8, but escapes every
  1477. // byte > 0x7E.
  1478. if (aChar < 0x20) {
  1479. [destStr appendFormat:@"\\%d%d%d",
  1480. (aChar / 64), ((aChar % 64) / 8), (aChar % 8)];
  1481. } else {
  1482. [destStr appendFormat:@"%C", aChar];
  1483. }
  1484. break;
  1485. }
  1486. }
  1487. [destStr appendString:@"\""];
  1488. }
  1489. static void AppendBufferAsString(NSData *buffer, NSMutableString *destStr) {
  1490. const char *src = (const char *)[buffer bytes];
  1491. size_t srcLen = [buffer length];
  1492. [destStr appendString:@"\""];
  1493. for (const char *srcEnd = src + srcLen; src < srcEnd; src++) {
  1494. switch (*src) {
  1495. case '\n': [destStr appendString:@"\\n"]; break;
  1496. case '\r': [destStr appendString:@"\\r"]; break;
  1497. case '\t': [destStr appendString:@"\\t"]; break;
  1498. case '\"': [destStr appendString:@"\\\""]; break;
  1499. case '\'': [destStr appendString:@"\\\'"]; break;
  1500. case '\\': [destStr appendString:@"\\\\"]; break;
  1501. default:
  1502. if (isprint(*src)) {
  1503. [destStr appendFormat:@"%c", *src];
  1504. } else {
  1505. // NOTE: doing hex means you have to worry about the letter after
  1506. // the hex being another hex char and forcing that to be escaped, so
  1507. // use octal to keep it simple.
  1508. [destStr appendFormat:@"\\%03o", (uint8_t)(*src)];
  1509. }
  1510. break;
  1511. }
  1512. }
  1513. [destStr appendString:@"\""];
  1514. }
  1515. static void AppendTextFormatForMapMessageField(
  1516. id map, GPBFieldDescriptor *field, NSMutableString *toStr,
  1517. NSString *lineIndent, NSString *fieldName, NSString *lineEnding) {
  1518. GPBDataType keyDataType = field.mapKeyDataType;
  1519. GPBDataType valueDataType = GPBGetFieldDataType(field);
  1520. BOOL isMessageValue = GPBDataTypeIsMessage(valueDataType);
  1521. NSString *msgStartFirst =
  1522. [NSString stringWithFormat:@"%@%@ {%@\n", lineIndent, fieldName, lineEnding];
  1523. NSString *msgStart =
  1524. [NSString stringWithFormat:@"%@%@ {\n", lineIndent, fieldName];
  1525. NSString *msgEnd = [NSString stringWithFormat:@"%@}\n", lineIndent];
  1526. NSString *keyLine = [NSString stringWithFormat:@"%@ key: ", lineIndent];
  1527. NSString *valueLine = [NSString stringWithFormat:@"%@ value%s ", lineIndent,
  1528. (isMessageValue ? "" : ":")];
  1529. __block BOOL isFirst = YES;
  1530. if ((keyDataType == GPBDataTypeString) &&
  1531. GPBDataTypeIsObject(valueDataType)) {
  1532. // map is an NSDictionary.
  1533. NSDictionary *dict = map;
  1534. [dict enumerateKeysAndObjectsUsingBlock:^(NSString *key, id value, BOOL *stop) {
  1535. #pragma unused(stop)
  1536. [toStr appendString:(isFirst ? msgStartFirst : msgStart)];
  1537. isFirst = NO;
  1538. [toStr appendString:keyLine];
  1539. AppendStringEscaped(key, toStr);
  1540. [toStr appendString:@"\n"];
  1541. [toStr appendString:valueLine];
  1542. #pragma clang diagnostic push
  1543. #pragma clang diagnostic ignored "-Wswitch-enum"
  1544. switch (valueDataType) {
  1545. case GPBDataTypeString:
  1546. AppendStringEscaped(value, toStr);
  1547. break;
  1548. case GPBDataTypeBytes:
  1549. AppendBufferAsString(value, toStr);
  1550. break;
  1551. case GPBDataTypeMessage:
  1552. [toStr appendString:@"{\n"];
  1553. NSString *subIndent = [lineIndent stringByAppendingString:@" "];
  1554. AppendTextFormatForMessage(value, toStr, subIndent);
  1555. [toStr appendFormat:@"%@ }", lineIndent];
  1556. break;
  1557. default:
  1558. NSCAssert(NO, @"Can't happen");
  1559. break;
  1560. }
  1561. #pragma clang diagnostic pop
  1562. [toStr appendString:@"\n"];
  1563. [toStr appendString:msgEnd];
  1564. }];
  1565. } else {
  1566. // map is one of the GPB*Dictionary classes, type doesn't matter.
  1567. GPBInt32Int32Dictionary *dict = map;
  1568. [dict enumerateForTextFormat:^(id keyObj, id valueObj) {
  1569. [toStr appendString:(isFirst ? msgStartFirst : msgStart)];
  1570. isFirst = NO;
  1571. // Key always is a NSString.
  1572. if (keyDataType == GPBDataTypeString) {
  1573. [toStr appendString:keyLine];
  1574. AppendStringEscaped(keyObj, toStr);
  1575. [toStr appendString:@"\n"];
  1576. } else {
  1577. [toStr appendFormat:@"%@%@\n", keyLine, keyObj];
  1578. }
  1579. [toStr appendString:valueLine];
  1580. #pragma clang diagnostic push
  1581. #pragma clang diagnostic ignored "-Wswitch-enum"
  1582. switch (valueDataType) {
  1583. case GPBDataTypeString:
  1584. AppendStringEscaped(valueObj, toStr);
  1585. break;
  1586. case GPBDataTypeBytes:
  1587. AppendBufferAsString(valueObj, toStr);
  1588. break;
  1589. case GPBDataTypeMessage:
  1590. [toStr appendString:@"{\n"];
  1591. NSString *subIndent = [lineIndent stringByAppendingString:@" "];
  1592. AppendTextFormatForMessage(valueObj, toStr, subIndent);
  1593. [toStr appendFormat:@"%@ }", lineIndent];
  1594. break;
  1595. case GPBDataTypeEnum: {
  1596. int32_t enumValue = [valueObj intValue];
  1597. NSString *valueStr = nil;
  1598. GPBEnumDescriptor *descriptor = field.enumDescriptor;
  1599. if (descriptor) {
  1600. valueStr = [descriptor textFormatNameForValue:enumValue];
  1601. }
  1602. if (valueStr) {
  1603. [toStr appendString:valueStr];
  1604. } else {
  1605. [toStr appendFormat:@"%d", enumValue];
  1606. }
  1607. break;
  1608. }
  1609. default:
  1610. NSCAssert(valueDataType != GPBDataTypeGroup, @"Can't happen");
  1611. // Everything else is a NSString.
  1612. [toStr appendString:valueObj];
  1613. break;
  1614. }
  1615. #pragma clang diagnostic pop
  1616. [toStr appendString:@"\n"];
  1617. [toStr appendString:msgEnd];
  1618. }];
  1619. }
  1620. }
  1621. static void AppendTextFormatForMessageField(GPBMessage *message,
  1622. GPBFieldDescriptor *field,
  1623. NSMutableString *toStr,
  1624. NSString *lineIndent) {
  1625. id arrayOrMap;
  1626. NSUInteger count;
  1627. GPBFieldType fieldType = field.fieldType;
  1628. switch (fieldType) {
  1629. case GPBFieldTypeSingle:
  1630. arrayOrMap = nil;
  1631. count = (GPBGetHasIvarField(message, field) ? 1 : 0);
  1632. break;
  1633. case GPBFieldTypeRepeated:
  1634. // Will be NSArray or GPB*Array, type doesn't matter, they both
  1635. // implement count.
  1636. arrayOrMap = GPBGetObjectIvarWithFieldNoAutocreate(message, field);
  1637. count = [(NSArray *)arrayOrMap count];
  1638. break;
  1639. case GPBFieldTypeMap: {
  1640. // Will be GPB*Dictionary or NSMutableDictionary, type doesn't matter,
  1641. // they both implement count.
  1642. arrayOrMap = GPBGetObjectIvarWithFieldNoAutocreate(message, field);
  1643. count = [(NSDictionary *)arrayOrMap count];
  1644. break;
  1645. }
  1646. }
  1647. if (count == 0) {
  1648. // Nothing to print, out of here.
  1649. return;
  1650. }
  1651. NSString *lineEnding = @"";
  1652. // If the name can't be reversed or support for extra info was turned off,
  1653. // this can return nil.
  1654. NSString *fieldName = [field textFormatName];
  1655. if ([fieldName length] == 0) {
  1656. fieldName = [NSString stringWithFormat:@"%u", GPBFieldNumber(field)];
  1657. // If there is only one entry, put the objc name as a comment, other wise
  1658. // add it before the repeated values.
  1659. if (count > 1) {
  1660. [toStr appendFormat:@"%@# %@\n", lineIndent, field.name];
  1661. } else {
  1662. lineEnding = [NSString stringWithFormat:@" # %@", field.name];
  1663. }
  1664. }
  1665. if (fieldType == GPBFieldTypeMap) {
  1666. AppendTextFormatForMapMessageField(arrayOrMap, field, toStr, lineIndent,
  1667. fieldName, lineEnding);
  1668. return;
  1669. }
  1670. id array = arrayOrMap;
  1671. const BOOL isRepeated = (array != nil);
  1672. GPBDataType fieldDataType = GPBGetFieldDataType(field);
  1673. BOOL isMessageField = GPBDataTypeIsMessage(fieldDataType);
  1674. for (NSUInteger j = 0; j < count; ++j) {
  1675. // Start the line.
  1676. [toStr appendFormat:@"%@%@%s ", lineIndent, fieldName,
  1677. (isMessageField ? "" : ":")];
  1678. // The value.
  1679. switch (fieldDataType) {
  1680. #define FIELD_CASE(GPBDATATYPE, CTYPE, REAL_TYPE, ...) \
  1681. case GPBDataType##GPBDATATYPE: { \
  1682. CTYPE v = (isRepeated ? [(GPB##REAL_TYPE##Array *)array valueAtIndex:j] \
  1683. : GPBGetMessage##REAL_TYPE##Field(message, field)); \
  1684. [toStr appendFormat:__VA_ARGS__, v]; \
  1685. break; \
  1686. }
  1687. FIELD_CASE(Int32, int32_t, Int32, @"%d")
  1688. FIELD_CASE(SInt32, int32_t, Int32, @"%d")
  1689. FIELD_CASE(SFixed32, int32_t, Int32, @"%d")
  1690. FIELD_CASE(UInt32, uint32_t, UInt32, @"%u")
  1691. FIELD_CASE(Fixed32, uint32_t, UInt32, @"%u")
  1692. FIELD_CASE(Int64, int64_t, Int64, @"%lld")
  1693. FIELD_CASE(SInt64, int64_t, Int64, @"%lld")
  1694. FIELD_CASE(SFixed64, int64_t, Int64, @"%lld")
  1695. FIELD_CASE(UInt64, uint64_t, UInt64, @"%llu")
  1696. FIELD_CASE(Fixed64, uint64_t, UInt64, @"%llu")
  1697. FIELD_CASE(Float, float, Float, @"%.*g", FLT_DIG)
  1698. FIELD_CASE(Double, double, Double, @"%.*lg", DBL_DIG)
  1699. #undef FIELD_CASE
  1700. case GPBDataTypeEnum: {
  1701. int32_t v = (isRepeated ? [(GPBEnumArray *)array rawValueAtIndex:j]
  1702. : GPBGetMessageInt32Field(message, field));
  1703. NSString *valueStr = nil;
  1704. GPBEnumDescriptor *descriptor = field.enumDescriptor;
  1705. if (descriptor) {
  1706. valueStr = [descriptor textFormatNameForValue:v];
  1707. }
  1708. if (valueStr) {
  1709. [toStr appendString:valueStr];
  1710. } else {
  1711. [toStr appendFormat:@"%d", v];
  1712. }
  1713. break;
  1714. }
  1715. case GPBDataTypeBool: {
  1716. BOOL v = (isRepeated ? [(GPBBoolArray *)array valueAtIndex:j]
  1717. : GPBGetMessageBoolField(message, field));
  1718. [toStr appendString:(v ? @"true" : @"false")];
  1719. break;
  1720. }
  1721. case GPBDataTypeString: {
  1722. NSString *v = (isRepeated ? [(NSArray *)array objectAtIndex:j]
  1723. : GPBGetMessageStringField(message, field));
  1724. AppendStringEscaped(v, toStr);
  1725. break;
  1726. }
  1727. case GPBDataTypeBytes: {
  1728. NSData *v = (isRepeated ? [(NSArray *)array objectAtIndex:j]
  1729. : GPBGetMessageBytesField(message, field));
  1730. AppendBufferAsString(v, toStr);
  1731. break;
  1732. }
  1733. case GPBDataTypeGroup:
  1734. case GPBDataTypeMessage: {
  1735. GPBMessage *v =
  1736. (isRepeated ? [(NSArray *)array objectAtIndex:j]
  1737. : GPBGetObjectIvarWithField(message, field));
  1738. [toStr appendFormat:@"{%@\n", lineEnding];
  1739. NSString *subIndent = [lineIndent stringByAppendingString:@" "];
  1740. AppendTextFormatForMessage(v, toStr, subIndent);
  1741. [toStr appendFormat:@"%@}", lineIndent];
  1742. lineEnding = @"";
  1743. break;
  1744. }
  1745. } // switch(fieldDataType)
  1746. // End the line.
  1747. [toStr appendFormat:@"%@\n", lineEnding];
  1748. } // for(count)
  1749. }
  1750. static void AppendTextFormatForMessageExtensionRange(GPBMessage *message,
  1751. NSArray *activeExtensions,
  1752. GPBExtensionRange range,
  1753. NSMutableString *toStr,
  1754. NSString *lineIndent) {
  1755. uint32_t start = range.start;
  1756. uint32_t end = range.end;
  1757. for (GPBExtensionDescriptor *extension in activeExtensions) {
  1758. uint32_t fieldNumber = extension.fieldNumber;
  1759. if (fieldNumber < start) {
  1760. // Not there yet.
  1761. continue;
  1762. }
  1763. if (fieldNumber >= end) {
  1764. // Done.
  1765. break;
  1766. }
  1767. id rawExtValue = [message getExtension:extension];
  1768. BOOL isRepeated = extension.isRepeated;
  1769. NSUInteger numValues = 1;
  1770. NSString *lineEnding = @"";
  1771. if (isRepeated) {
  1772. numValues = [(NSArray *)rawExtValue count];
  1773. }
  1774. NSString *singletonName = extension.singletonName;
  1775. if (numValues == 1) {
  1776. lineEnding = [NSString stringWithFormat:@" # [%@]", singletonName];
  1777. } else {
  1778. [toStr appendFormat:@"%@# [%@]\n", lineIndent, singletonName];
  1779. }
  1780. GPBDataType extDataType = extension.dataType;
  1781. for (NSUInteger j = 0; j < numValues; ++j) {
  1782. id curValue = (isRepeated ? [rawExtValue objectAtIndex:j] : rawExtValue);
  1783. // Start the line.
  1784. [toStr appendFormat:@"%@%u%s ", lineIndent, fieldNumber,
  1785. (GPBDataTypeIsMessage(extDataType) ? "" : ":")];
  1786. // The value.
  1787. switch (extDataType) {
  1788. #define FIELD_CASE(GPBDATATYPE, CTYPE, NUMSELECTOR, ...) \
  1789. case GPBDataType##GPBDATATYPE: { \
  1790. CTYPE v = [(NSNumber *)curValue NUMSELECTOR]; \
  1791. [toStr appendFormat:__VA_ARGS__, v]; \
  1792. break; \
  1793. }
  1794. FIELD_CASE(Int32, int32_t, intValue, @"%d")
  1795. FIELD_CASE(SInt32, int32_t, intValue, @"%d")
  1796. FIELD_CASE(SFixed32, int32_t, unsignedIntValue, @"%d")
  1797. FIELD_CASE(UInt32, uint32_t, unsignedIntValue, @"%u")
  1798. FIELD_CASE(Fixed32, uint32_t, unsignedIntValue, @"%u")
  1799. FIELD_CASE(Int64, int64_t, longLongValue, @"%lld")
  1800. FIELD_CASE(SInt64, int64_t, longLongValue, @"%lld")
  1801. FIELD_CASE(SFixed64, int64_t, longLongValue, @"%lld")
  1802. FIELD_CASE(UInt64, uint64_t, unsignedLongLongValue, @"%llu")
  1803. FIELD_CASE(Fixed64, uint64_t, unsignedLongLongValue, @"%llu")
  1804. FIELD_CASE(Float, float, floatValue, @"%.*g", FLT_DIG)
  1805. FIELD_CASE(Double, double, doubleValue, @"%.*lg", DBL_DIG)
  1806. // TODO: Add a comment with the enum name from enum descriptors
  1807. // (might not be real value, so leave it as a comment, ObjC compiler
  1808. // name mangles differently). Doesn't look like we actually generate
  1809. // an enum descriptor reference like we do for normal fields, so this
  1810. // will take a compiler change.
  1811. FIELD_CASE(Enum, int32_t, intValue, @"%d")
  1812. #undef FIELD_CASE
  1813. case GPBDataTypeBool:
  1814. [toStr appendString:([(NSNumber *)curValue boolValue] ? @"true"
  1815. : @"false")];
  1816. break;
  1817. case GPBDataTypeString:
  1818. AppendStringEscaped(curValue, toStr);
  1819. break;
  1820. case GPBDataTypeBytes:
  1821. AppendBufferAsString((NSData *)curValue, toStr);
  1822. break;
  1823. case GPBDataTypeGroup:
  1824. case GPBDataTypeMessage: {
  1825. [toStr appendFormat:@"{%@\n", lineEnding];
  1826. NSString *subIndent = [lineIndent stringByAppendingString:@" "];
  1827. AppendTextFormatForMessage(curValue, toStr, subIndent);
  1828. [toStr appendFormat:@"%@}", lineIndent];
  1829. lineEnding = @"";
  1830. break;
  1831. }
  1832. } // switch(extDataType)
  1833. // End the line.
  1834. [toStr appendFormat:@"%@\n", lineEnding];
  1835. } // for(numValues)
  1836. } // for..in(activeExtensions)
  1837. }
  1838. static void AppendTextFormatForMessage(GPBMessage *message,
  1839. NSMutableString *toStr,
  1840. NSString *lineIndent) {
  1841. GPBDescriptor *descriptor = [message descriptor];
  1842. NSArray *fieldsArray = descriptor->fields_;
  1843. NSUInteger fieldCount = fieldsArray.count;
  1844. const GPBExtensionRange *extensionRanges = descriptor.extensionRanges;
  1845. NSUInteger extensionRangesCount = descriptor.extensionRangesCount;
  1846. NSArray *activeExtensions = [[message extensionsCurrentlySet]
  1847. sortedArrayUsingSelector:@selector(compareByFieldNumber:)];
  1848. for (NSUInteger i = 0, j = 0; i < fieldCount || j < extensionRangesCount;) {
  1849. if (i == fieldCount) {
  1850. AppendTextFormatForMessageExtensionRange(
  1851. message, activeExtensions, extensionRanges[j++], toStr, lineIndent);
  1852. } else if (j == extensionRangesCount ||
  1853. GPBFieldNumber(fieldsArray[i]) < extensionRanges[j].start) {
  1854. AppendTextFormatForMessageField(message, fieldsArray[i++], toStr,
  1855. lineIndent);
  1856. } else {
  1857. AppendTextFormatForMessageExtensionRange(
  1858. message, activeExtensions, extensionRanges[j++], toStr, lineIndent);
  1859. }
  1860. }
  1861. NSString *unknownFieldsStr =
  1862. GPBTextFormatForUnknownFieldSet(message.unknownFields, lineIndent);
  1863. if ([unknownFieldsStr length] > 0) {
  1864. [toStr appendFormat:@"%@# --- Unknown fields ---\n", lineIndent];
  1865. [toStr appendString:unknownFieldsStr];
  1866. }
  1867. }
  1868. NSString *GPBTextFormatForMessage(GPBMessage *message, NSString *lineIndent) {
  1869. if (message == nil) return @"";
  1870. if (lineIndent == nil) lineIndent = @"";
  1871. NSMutableString *buildString = [NSMutableString string];
  1872. AppendTextFormatForMessage(message, buildString, lineIndent);
  1873. return buildString;
  1874. }
  1875. NSString *GPBTextFormatForUnknownFieldSet(GPBUnknownFieldSet *unknownSet,
  1876. NSString *lineIndent) {
  1877. if (unknownSet == nil) return @"";
  1878. if (lineIndent == nil) lineIndent = @"";
  1879. NSMutableString *result = [NSMutableString string];
  1880. for (GPBUnknownField *field in [unknownSet sortedFields]) {
  1881. int32_t fieldNumber = [field number];
  1882. #define PRINT_LOOP(PROPNAME, CTYPE, FORMAT) \
  1883. [field.PROPNAME \
  1884. enumerateValuesWithBlock:^(CTYPE value, NSUInteger idx, BOOL * stop) { \
  1885. _Pragma("unused(idx, stop)"); \
  1886. [result \
  1887. appendFormat:@"%@%d: " #FORMAT "\n", lineIndent, fieldNumber, value]; \
  1888. }];
  1889. PRINT_LOOP(varintList, uint64_t, %llu);
  1890. PRINT_LOOP(fixed32List, uint32_t, 0x%X);
  1891. PRINT_LOOP(fixed64List, uint64_t, 0x%llX);
  1892. #undef PRINT_LOOP
  1893. // NOTE: C++ version of TextFormat tries to parse this as a message
  1894. // and print that if it succeeds.
  1895. for (NSData *data in field.lengthDelimitedList) {
  1896. [result appendFormat:@"%@%d: ", lineIndent, fieldNumber];
  1897. AppendBufferAsString(data, result);
  1898. [result appendString:@"\n"];
  1899. }
  1900. for (GPBUnknownFieldSet *subUnknownSet in field.groupList) {
  1901. [result appendFormat:@"%@%d: {\n", lineIndent, fieldNumber];
  1902. NSString *subIndent = [lineIndent stringByAppendingString:@" "];
  1903. NSString *subUnknwonSetStr =
  1904. GPBTextFormatForUnknownFieldSet(subUnknownSet, subIndent);
  1905. [result appendString:subUnknwonSetStr];
  1906. [result appendFormat:@"%@}\n", lineIndent];
  1907. }
  1908. }
  1909. return result;
  1910. }
  1911. // Helpers to decode a varint. Not using GPBCodedInputStream version because
  1912. // that needs a state object, and we don't want to create an input stream out
  1913. // of the data.
  1914. GPB_INLINE int8_t ReadRawByteFromData(const uint8_t **data) {
  1915. int8_t result = *((int8_t *)(*data));
  1916. ++(*data);
  1917. return result;
  1918. }
  1919. static int32_t ReadRawVarint32FromData(const uint8_t **data) {
  1920. int8_t tmp = ReadRawByteFromData(data);
  1921. if (tmp >= 0) {
  1922. return tmp;
  1923. }
  1924. int32_t result = tmp & 0x7f;
  1925. if ((tmp = ReadRawByteFromData(data)) >= 0) {
  1926. result |= tmp << 7;
  1927. } else {
  1928. result |= (tmp & 0x7f) << 7;
  1929. if ((tmp = ReadRawByteFromData(data)) >= 0) {
  1930. result |= tmp << 14;
  1931. } else {
  1932. result |= (tmp & 0x7f) << 14;
  1933. if ((tmp = ReadRawByteFromData(data)) >= 0) {
  1934. result |= tmp << 21;
  1935. } else {
  1936. result |= (tmp & 0x7f) << 21;
  1937. result |= (tmp = ReadRawByteFromData(data)) << 28;
  1938. if (tmp < 0) {
  1939. // Discard upper 32 bits.
  1940. for (int i = 0; i < 5; i++) {
  1941. if (ReadRawByteFromData(data) >= 0) {
  1942. return result;
  1943. }
  1944. }
  1945. [NSException raise:NSParseErrorException
  1946. format:@"Unable to read varint32"];
  1947. }
  1948. }
  1949. }
  1950. }
  1951. return result;
  1952. }
  1953. NSString *GPBDecodeTextFormatName(const uint8_t *decodeData, int32_t key,
  1954. NSString *inputStr) {
  1955. // decodData form:
  1956. // varint32: num entries
  1957. // for each entry:
  1958. // varint32: key
  1959. // bytes*: decode data
  1960. //
  1961. // decode data one of two forms:
  1962. // 1: a \0 followed by the string followed by an \0
  1963. // 2: bytecodes to transform an input into the right thing, ending with \0
  1964. //
  1965. // the bytes codes are of the form:
  1966. // 0xabbccccc
  1967. // 0x0 (all zeros), end.
  1968. // a - if set, add an underscore
  1969. // bb - 00 ccccc bytes as is
  1970. // bb - 10 ccccc upper first, as is on rest, ccccc byte total
  1971. // bb - 01 ccccc lower first, as is on rest, ccccc byte total
  1972. // bb - 11 ccccc all upper, ccccc byte total
  1973. if (!decodeData || !inputStr) {
  1974. return nil;
  1975. }
  1976. // Find key
  1977. const uint8_t *scan = decodeData;
  1978. int32_t numEntries = ReadRawVarint32FromData(&scan);
  1979. BOOL foundKey = NO;
  1980. while (!foundKey && (numEntries > 0)) {
  1981. --numEntries;
  1982. int32_t dataKey = ReadRawVarint32FromData(&scan);
  1983. if (dataKey == key) {
  1984. foundKey = YES;
  1985. } else {
  1986. // If it is a inlined string, it will start with \0; if it is bytecode it
  1987. // will start with a code. So advance one (skipping the inline string
  1988. // marker), and then loop until reaching the end marker (\0).
  1989. ++scan;
  1990. while (*scan != 0) ++scan;
  1991. // Now move past the end marker.
  1992. ++scan;
  1993. }
  1994. }
  1995. if (!foundKey) {
  1996. return nil;
  1997. }
  1998. // Decode
  1999. if (*scan == 0) {
  2000. // Inline string. Move over the marker, and NSString can take it as
  2001. // UTF8.
  2002. ++scan;
  2003. NSString *result = [NSString stringWithUTF8String:(const char *)scan];
  2004. return result;
  2005. }
  2006. NSMutableString *result =
  2007. [NSMutableString stringWithCapacity:[inputStr length]];
  2008. const uint8_t kAddUnderscore = 0b10000000;
  2009. const uint8_t kOpMask = 0b01100000;
  2010. // const uint8_t kOpAsIs = 0b00000000;
  2011. const uint8_t kOpFirstUpper = 0b01000000;
  2012. const uint8_t kOpFirstLower = 0b00100000;
  2013. const uint8_t kOpAllUpper = 0b01100000;
  2014. const uint8_t kSegmentLenMask = 0b00011111;
  2015. NSInteger i = 0;
  2016. for (; *scan != 0; ++scan) {
  2017. if (*scan & kAddUnderscore) {
  2018. [result appendString:@"_"];
  2019. }
  2020. int segmentLen = *scan & kSegmentLenMask;
  2021. uint8_t decodeOp = *scan & kOpMask;
  2022. // Do op specific handling of the first character.
  2023. if (decodeOp == kOpFirstUpper) {
  2024. unichar c = [inputStr characterAtIndex:i];
  2025. [result appendFormat:@"%c", toupper((char)c)];
  2026. ++i;
  2027. --segmentLen;
  2028. } else if (decodeOp == kOpFirstLower) {
  2029. unichar c = [inputStr characterAtIndex:i];
  2030. [result appendFormat:@"%c", tolower((char)c)];
  2031. ++i;
  2032. --segmentLen;
  2033. }
  2034. // else op == kOpAsIs || op == kOpAllUpper
  2035. // Now pull over the rest of the length for this segment.
  2036. for (int x = 0; x < segmentLen; ++x) {
  2037. unichar c = [inputStr characterAtIndex:(i + x)];
  2038. if (decodeOp == kOpAllUpper) {
  2039. [result appendFormat:@"%c", toupper((char)c)];
  2040. } else {
  2041. [result appendFormat:@"%C", c];
  2042. }
  2043. }
  2044. i += segmentLen;
  2045. }
  2046. return result;
  2047. }
  2048. #pragma mark Legacy methods old generated code calls
  2049. // Shim from the older generated code into the runtime.
  2050. void GPBSetInt32IvarWithFieldInternal(GPBMessage *self,
  2051. GPBFieldDescriptor *field,
  2052. int32_t value,
  2053. GPBFileSyntax syntax) {
  2054. #pragma unused(syntax)
  2055. GPBSetMessageInt32Field(self, field, value);
  2056. }
  2057. void GPBMaybeClearOneof(GPBMessage *self, GPBOneofDescriptor *oneof,
  2058. int32_t oneofHasIndex, uint32_t fieldNumberNotToClear) {
  2059. #pragma unused(fieldNumberNotToClear)
  2060. #if defined(DEBUG) && DEBUG
  2061. NSCAssert([[self descriptor] oneofWithName:oneof.name] == oneof,
  2062. @"OneofDescriptor %@ doesn't appear to be for %@ messages.",
  2063. oneof.name, [self class]);
  2064. GPBFieldDescriptor *firstField = oneof->fields_[0];
  2065. NSCAssert(firstField->description_->hasIndex == oneofHasIndex,
  2066. @"Internal error, oneofHasIndex (%d) doesn't match (%d).",
  2067. firstField->description_->hasIndex, oneofHasIndex);
  2068. #endif
  2069. GPBMaybeClearOneofPrivate(self, oneof, oneofHasIndex, 0);
  2070. }
  2071. #pragma clang diagnostic pop
  2072. #pragma mark Misc Helpers
  2073. BOOL GPBClassHasSel(Class aClass, SEL sel) {
  2074. // NOTE: We have to use class_copyMethodList, all other runtime method
  2075. // lookups actually also resolve the method implementation and this
  2076. // is called from within those methods.
  2077. BOOL result = NO;
  2078. unsigned int methodCount = 0;
  2079. Method *methodList = class_copyMethodList(aClass, &methodCount);
  2080. for (unsigned int i = 0; i < methodCount; ++i) {
  2081. SEL methodSelector = method_getName(methodList[i]);
  2082. if (methodSelector == sel) {
  2083. result = YES;
  2084. break;
  2085. }
  2086. }
  2087. free(methodList);
  2088. return result;
  2089. }