GPBUtilities.m 84 KB

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