1 // Protocol Buffers - Google's data interchange format 2 // Copyright 2008 Google Inc. All rights reserved. 3 // https://developers.google.com/protocol-buffers/ 4 // 5 // Redistribution and use in source and binary forms, with or without 6 // modification, are permitted provided that the following conditions are 7 // met: 8 // 9 // * Redistributions of source code must retain the above copyright 10 // notice, this list of conditions and the following disclaimer. 11 // * Redistributions in binary form must reproduce the above 12 // copyright notice, this list of conditions and the following disclaimer 13 // in the documentation and/or other materials provided with the 14 // distribution. 15 // * Neither the name of Google Inc. nor the names of its 16 // contributors may be used to endorse or promote products derived from 17 // this software without specific prior written permission. 18 // 19 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 20 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 21 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 22 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 23 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 24 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 25 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 26 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 27 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 28 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 31 #import <Foundation/Foundation.h> 32 33 #import "GPBBootstrap.h" 34 35 @class GPBDescriptor; 36 @class GPBCodedInputStream; 37 @class GPBCodedOutputStream; 38 @class GPBExtensionDescriptor; 39 @class GPBExtensionRegistry; 40 @class GPBFieldDescriptor; 41 @class GPBUnknownFieldSet; 42 43 NS_ASSUME_NONNULL_BEGIN 44 45 CF_EXTERN_C_BEGIN 46 47 /** NSError domain used for errors. */ 48 extern NSString *const GPBMessageErrorDomain; 49 50 /** Error codes for NSErrors originated in GPBMessage. */ 51 typedef NS_ENUM(NSInteger, GPBMessageErrorCode) { 52 /** Uncategorized error. */ 53 GPBMessageErrorCodeOther = -100, 54 /** Message couldn't be serialized because it is missing required fields. */ 55 GPBMessageErrorCodeMissingRequiredField = -101, 56 }; 57 58 /** 59 * Key under which the GPBMessage error's reason is stored inside the userInfo 60 * dictionary. 61 **/ 62 extern NSString *const GPBErrorReasonKey; 63 64 CF_EXTERN_C_END 65 66 /** 67 * Base class that each generated message subclasses from. 68 * 69 * @note @c NSCopying support is a "deep copy", in that all sub objects are 70 * copied. Just like you wouldn't want a UIView/NSView trying to 71 * exist in two places, you don't want a sub message to be a property 72 * property of two other messages. 73 * 74 * @note While the class support NSSecureCoding, if the message has any 75 * extensions, they will end up reloaded in @c unknownFields as there is 76 * no way for the @c NSCoding plumbing to pass through a 77 * @c GPBExtensionRegistry. To support extensions, instead of passing the 78 * calls off to the Message, simple store the result of @c data, and then 79 * when loading, fetch the data and use 80 * @c +parseFromData:extensionRegistry:error: to provide an extension 81 * registry. 82 **/ 83 @interface GPBMessage : NSObject<NSSecureCoding, NSCopying> 84 85 // If you add an instance method/property to this class that may conflict with 86 // fields declared in protos, you need to update objective_helpers.cc. The main 87 // cases are methods that take no arguments, or setFoo:/hasFoo: type methods. 88 89 /** 90 * The set of unknown fields for this message. 91 * 92 * Only messages from proto files declared with "proto2" syntax support unknown 93 * fields. For "proto3" syntax, any unknown fields found while parsing are 94 * dropped. 95 **/ 96 @property(nonatomic, copy, nullable) GPBUnknownFieldSet *unknownFields; 97 98 /** 99 * Whether the message, along with all submessages, have the required fields 100 * set. This is only applicable for files declared with "proto2" syntax, as 101 * there are no required fields for "proto3" syntax. 102 **/ 103 @property(nonatomic, readonly, getter=isInitialized) BOOL initialized; 104 105 /** 106 * @return An autoreleased message with the default values set. 107 **/ 108 + (instancetype)message; 109 110 /** 111 * Creates a new instance by parsing the provided data. This method should be 112 * sent to the generated message class that the data should be interpreted as. 113 * If there is an error the method returns nil and the error is returned in 114 * errorPtr (when provided). 115 * 116 * @note In DEBUG builds, the parsed message is checked to be sure all required 117 * fields were provided, and the parse will fail if some are missing. 118 * 119 * @note The errors returned are likely coming from the domain and codes listed 120 * at the top of this file and GPBCodedInputStream.h. 121 * 122 * @param data The data to parse. 123 * @param errorPtr An optional error pointer to fill in with a failure reason if 124 * the data can not be parsed. 125 * 126 * @return A new instance of the generated class. 127 **/ 128 + (nullable instancetype)parseFromData:(NSData *)data error:(NSError **)errorPtr; 129 130 /** 131 * Creates a new instance by parsing the data. This method should be sent to 132 * the generated message class that the data should be interpreted as. If 133 * there is an error the method returns nil and the error is returned in 134 * errorPtr (when provided). 135 * 136 * @note In DEBUG builds, the parsed message is checked to be sure all required 137 * fields were provided, and the parse will fail if some are missing. 138 * 139 * @note The errors returned are likely coming from the domain and codes listed 140 * at the top of this file and GPBCodedInputStream.h. 141 * 142 * @param data The data to parse. 143 * @param extensionRegistry The extension registry to use to look up extensions. 144 * @param errorPtr An optional error pointer to fill in with a failure 145 * reason if the data can not be parsed. 146 * 147 * @return A new instance of the generated class. 148 **/ 149 + (nullable instancetype)parseFromData:(NSData *)data 150 extensionRegistry:(nullable GPBExtensionRegistry *)extensionRegistry 151 error:(NSError **)errorPtr; 152 153 /** 154 * Creates a new instance by parsing the data from the given input stream. This 155 * method should be sent to the generated message class that the data should 156 * be interpreted as. If there is an error the method returns nil and the error 157 * is returned in errorPtr (when provided). 158 * 159 * @note In DEBUG builds, the parsed message is checked to be sure all required 160 * fields were provided, and the parse will fail if some are missing. 161 * 162 * @note The errors returned are likely coming from the domain and codes listed 163 * at the top of this file and GPBCodedInputStream.h. 164 * 165 * @param input The stream to read data from. 166 * @param extensionRegistry The extension registry to use to look up extensions. 167 * @param errorPtr An optional error pointer to fill in with a failure 168 * reason if the data can not be parsed. 169 * 170 * @return A new instance of the generated class. 171 **/ 172 + (nullable instancetype)parseFromCodedInputStream:(GPBCodedInputStream *)input 173 extensionRegistry: 174 (nullable GPBExtensionRegistry *)extensionRegistry 175 error:(NSError **)errorPtr; 176 177 /** 178 * Creates a new instance by parsing the data from the given input stream. This 179 * method should be sent to the generated message class that the data should 180 * be interpreted as. If there is an error the method returns nil and the error 181 * is returned in errorPtr (when provided). 182 * 183 * @note Unlike the parseFrom... methods, this never checks to see if all of 184 * the required fields are set. So this method can be used to reload 185 * messages that may not be complete. 186 * 187 * @note The errors returned are likely coming from the domain and codes listed 188 * at the top of this file and GPBCodedInputStream.h. 189 * 190 * @param input The stream to read data from. 191 * @param extensionRegistry The extension registry to use to look up extensions. 192 * @param errorPtr An optional error pointer to fill in with a failure 193 * reason if the data can not be parsed. 194 * 195 * @return A new instance of the generated class. 196 **/ 197 + (nullable instancetype)parseDelimitedFromCodedInputStream:(GPBCodedInputStream *)input 198 extensionRegistry: 199 (nullable GPBExtensionRegistry *)extensionRegistry 200 error:(NSError **)errorPtr; 201 202 /** 203 * Initializes an instance by parsing the data. This method should be sent to 204 * the generated message class that the data should be interpreted as. If 205 * there is an error the method returns nil and the error is returned in 206 * errorPtr (when provided). 207 * 208 * @note In DEBUG builds, the parsed message is checked to be sure all required 209 * fields were provided, and the parse will fail if some are missing. 210 * 211 * @note The errors returned are likely coming from the domain and codes listed 212 * at the top of this file and GPBCodedInputStream.h. 213 * 214 * @param data The data to parse. 215 * @param errorPtr An optional error pointer to fill in with a failure reason if 216 * the data can not be parsed. 217 * 218 * @return An initialized instance of the generated class. 219 **/ 220 - (nullable instancetype)initWithData:(NSData *)data error:(NSError **)errorPtr; 221 222 /** 223 * Initializes an instance by parsing the data. This method should be sent to 224 * the generated message class that the data should be interpreted as. If 225 * there is an error the method returns nil and the error is returned in 226 * errorPtr (when provided). 227 * 228 * @note In DEBUG builds, the parsed message is checked to be sure all required 229 * fields were provided, and the parse will fail if some are missing. 230 * 231 * @note The errors returned are likely coming from the domain and codes listed 232 * at the top of this file and GPBCodedInputStream.h. 233 * 234 * @param data The data to parse. 235 * @param extensionRegistry The extension registry to use to look up extensions. 236 * @param errorPtr An optional error pointer to fill in with a failure 237 * reason if the data can not be parsed. 238 * 239 * @return An initialized instance of the generated class. 240 **/ 241 - (nullable instancetype)initWithData:(NSData *)data 242 extensionRegistry:(nullable GPBExtensionRegistry *)extensionRegistry 243 error:(NSError **)errorPtr; 244 245 /** 246 * Initializes an instance by parsing the data from the given input stream. This 247 * method should be sent to the generated message class that the data should 248 * be interpreted as. If there is an error the method returns nil and the error 249 * is returned in errorPtr (when provided). 250 * 251 * @note Unlike the parseFrom... methods, this never checks to see if all of 252 * the required fields are set. So this method can be used to reload 253 * messages that may not be complete. 254 * 255 * @note The errors returned are likely coming from the domain and codes listed 256 * at the top of this file and GPBCodedInputStream.h. 257 * 258 * @param input The stream to read data from. 259 * @param extensionRegistry The extension registry to use to look up extensions. 260 * @param errorPtr An optional error pointer to fill in with a failure 261 * reason if the data can not be parsed. 262 * 263 * @return An initialized instance of the generated class. 264 **/ 265 - (nullable instancetype)initWithCodedInputStream:(GPBCodedInputStream *)input 266 extensionRegistry: 267 (nullable GPBExtensionRegistry *)extensionRegistry 268 error:(NSError **)errorPtr; 269 270 /** 271 * Parses the given data as this message's class, and merges those values into 272 * this message. 273 * 274 * @param data The binary representation of the message to merge. 275 * @param extensionRegistry The extension registry to use to look up extensions. 276 * 277 * @exception GPBCodedInputStreamException Exception thrown when parsing was 278 * unsuccessful. 279 **/ 280 - (void)mergeFromData:(NSData *)data 281 extensionRegistry:(nullable GPBExtensionRegistry *)extensionRegistry; 282 283 /** 284 * Merges the fields from another message (of the same type) into this 285 * message. 286 * 287 * @param other Message to merge into this message. 288 **/ 289 - (void)mergeFrom:(GPBMessage *)other; 290 291 /** 292 * Writes out the message to the given coded output stream. 293 * 294 * @param output The coded output stream into which to write the message. 295 * 296 * @note This can raise the GPBCodedOutputStreamException_* exceptions. 297 * 298 **/ 299 - (void)writeToCodedOutputStream:(GPBCodedOutputStream *)output; 300 301 /** 302 * Writes out the message to the given output stream. 303 * 304 * @param output The output stream into which to write the message. 305 * 306 * @note This can raise the GPBCodedOutputStreamException_* exceptions. 307 **/ 308 - (void)writeToOutputStream:(NSOutputStream *)output; 309 310 /** 311 * Writes out a varint for the message size followed by the message to 312 * the given output stream. 313 * 314 * @param output The coded output stream into which to write the message. 315 * 316 * @note This can raise the GPBCodedOutputStreamException_* exceptions. 317 **/ 318 - (void)writeDelimitedToCodedOutputStream:(GPBCodedOutputStream *)output; 319 320 /** 321 * Writes out a varint for the message size followed by the message to 322 * the given output stream. 323 * 324 * @param output The output stream into which to write the message. 325 * 326 * @note This can raise the GPBCodedOutputStreamException_* exceptions. 327 **/ 328 - (void)writeDelimitedToOutputStream:(NSOutputStream *)output; 329 330 /** 331 * Serializes the message to an NSData. 332 * 333 * If there is an error while generating the data, nil is returned. 334 * 335 * @note This value is not cached, so if you are using it repeatedly, cache 336 * it yourself. 337 * 338 * @note In DEBUG ONLY, the message is also checked for all required field, 339 * if one is missing, nil will be returned. 340 * 341 * @return The binary representation of the message. 342 **/ 343 - (nullable NSData *)data; 344 345 /** 346 * Serializes a varint with the message size followed by the message data, 347 * returning that as an NSData. 348 * 349 * @note This value is not cached, so if you are using it repeatedly, it is 350 * recommended to keep a local copy. 351 * 352 * @return The binary representation of the size along with the message. 353 **/ 354 - (NSData *)delimitedData; 355 356 /** 357 * Calculates the size of the object if it were serialized. 358 * 359 * This is not a cached value. If you are following a pattern like this: 360 * 361 * ``` 362 * size_t size = [aMsg serializedSize]; 363 * NSMutableData *foo = [NSMutableData dataWithCapacity:size + sizeof(size)]; 364 * [foo writeSize:size]; 365 * [foo appendData:[aMsg data]]; 366 * ``` 367 * 368 * you would be better doing: 369 * 370 * ``` 371 * NSData *data = [aMsg data]; 372 * NSUInteger size = [aMsg length]; 373 * NSMutableData *foo = [NSMutableData dataWithCapacity:size + sizeof(size)]; 374 * [foo writeSize:size]; 375 * [foo appendData:data]; 376 * ``` 377 * 378 * @return The size of the message in it's binary representation. 379 **/ 380 - (size_t)serializedSize; 381 382 /** 383 * @return The descriptor for the message class. 384 **/ 385 + (GPBDescriptor *)descriptor; 386 387 /** 388 * Return the descriptor for the message. 389 **/ 390 - (GPBDescriptor *)descriptor; 391 392 /** 393 * @return An array with the extension descriptors that are currently set on the 394 * message. 395 **/ 396 - (NSArray *)extensionsCurrentlySet; 397 398 /** 399 * Checks whether there is an extension set on the message which matches the 400 * given extension descriptor. 401 * 402 * @param extension Extension descriptor to check if it's set on the message. 403 * 404 * @return Whether the extension is currently set on the message. 405 **/ 406 - (BOOL)hasExtension:(GPBExtensionDescriptor *)extension; 407 408 /* 409 * Fetches the given extension's value for this message. 410 * 411 * Extensions use boxed values (NSNumbers) for PODs and NSMutableArrays for 412 * repeated fields. If the extension is a Message one will be auto created for 413 * you and returned similar to fields. 414 * 415 * @param extension The extension descriptor of the extension to fetch. 416 * 417 * @return The extension matching the given descriptor, or nil if none found. 418 **/ 419 - (nullable id)getExtension:(GPBExtensionDescriptor *)extension; 420 421 /** 422 * Sets the given extension's value for this message. This only applies for 423 * single field extensions (i.e. - not repeated fields). 424 * 425 * Extensions use boxed values (NSNumbers). 426 * 427 * @param extension The extension descriptor under which to set the value. 428 * @param value The value to be set as the extension. 429 **/ 430 - (void)setExtension:(GPBExtensionDescriptor *)extension 431 value:(nullable id)value; 432 433 /** 434 * Adds the given value to the extension for this message. This only applies 435 * to repeated field extensions. If the field is a repeated POD type, the value 436 * should be an NSNumber. 437 * 438 * @param extension The extension descriptor under which to add the value. 439 * @param value The value to be added to the repeated extension. 440 **/ 441 - (void)addExtension:(GPBExtensionDescriptor *)extension value:(id)value; 442 443 /** 444 * Replaces the value at the given index with the given value for the extension 445 * on this message. This only applies to repeated field extensions. If the field 446 * is a repeated POD type, the value is should be an NSNumber. 447 * 448 * @param extension The extension descriptor under which to replace the value. 449 * @param index The index of the extension to be replaced. 450 * @param value The value to be replaced in the repeated extension. 451 **/ 452 - (void)setExtension:(GPBExtensionDescriptor *)extension 453 index:(NSUInteger)index 454 value:(id)value; 455 456 /** 457 * Clears the given extension for this message. 458 * 459 * @param extension The extension descriptor to be cleared from this message. 460 **/ 461 - (void)clearExtension:(GPBExtensionDescriptor *)extension; 462 463 /** 464 * Resets all of the fields of this message to their default values. 465 **/ 466 - (void)clear; 467 468 @end 469 470 NS_ASSUME_NONNULL_END 471