GPBUtilities.m 71 KB

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