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