GPBUtilities.m 88 KB

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