1 // Protocol Buffers - Google's data interchange format
2 // Copyright 2008 Google Inc. All rights reserved.
4 // Use of this source code is governed by a BSD-style
5 // license that can be found in the LICENSE file or at
6 // https://developers.google.com/open-source/licenses/bsd
8 #import <Foundation/Foundation.h>
10 #import "GPBBootstrap.h"
11 #import "GPBCodedInputStream.h"
12 #import "GPBCodedOutputStream.h"
13 #import "GPBDescriptor.h"
14 #import "GPBExtensionRegistry.h"
15 #import "GPBUnknownFields.h"
17 @
class GPBCodedInputStream
;
18 @
class GPBCodedOutputStream
;
19 @
class GPBUnknownFields
;
21 NS_ASSUME_NONNULL_BEGIN
25 /** NSError domain used for errors. */
26 extern NSString
*const GPBMessageErrorDomain
;
28 /** Error codes for NSErrors originated in GPBMessage. */
29 typedef NS_ENUM(NSInteger
, GPBMessageErrorCode
) {
30 /** Uncategorized error. */
31 GPBMessageErrorCodeOther
= -100,
32 /** Message couldn't be serialized because it is missing required fields. */
33 GPBMessageErrorCodeMissingRequiredField
= -101,
37 * Key under which the GPBMessage error's reason is stored inside the userInfo
40 extern NSString
*const GPBErrorReasonKey
;
43 * An exception name raised during serialization when the message would be
44 * larger than the 2GB limit.
46 extern NSString
*const GPBMessageExceptionMessageTooLarge
;
51 * Base class that each generated message subclasses from.
53 * @note @c NSCopying support is a "deep copy", in that all sub objects are
54 * copied. Just like you wouldn't want a UIView/NSView trying to
55 * exist in two places, you don't want a sub message to be a property
56 * property of two other messages.
58 * @note While the class supports NSSecureCoding, if the message has any
59 * extensions, they will end up reloaded in the unknown fields as there is
60 * no way for the @c NSCoding plumbing to pass through a
61 * @c GPBExtensionRegistry. To support extensions, instead of passing the
62 * calls off to the Message, simple store the result of @c data, and then
63 * when loading, fetch the data and use
64 * @c +parseFromData:extensionRegistry:error: to provide an extension
67 @interface GPBMessage
: NSObject
<NSSecureCoding
, NSCopying
>
69 // If you add an instance method/property to this class that may conflict with
70 // fields declared in protos, you need to update objective_helpers.cc. The main
71 // cases are methods that take no arguments, or setFoo:/hasFoo: type methods.
74 * Whether the message, along with all submessages, have the required fields
77 @
property(nonatomic
, readonly
, getter
=isInitialized
) BOOL initialized
;
80 * @return An autoreleased message with the default values set.
82 + (instancetype
)message
;
85 * Creates a new instance by parsing the provided data. This method should be
86 * sent to the generated message class that the data should be interpreted as.
87 * If there is an error the method returns nil and the error is returned in
88 * errorPtr (when provided).
90 * @note In DEBUG builds, the parsed message is checked to be sure all required
91 * fields were provided, and the parse will fail if some are missing.
93 * @note The errors returned are likely coming from the domain and codes listed
94 * at the top of this file and GPBCodedInputStream.h.
96 * @param data The data to parse.
97 * @param errorPtr An optional error pointer to fill in with a failure reason if
98 * the data can not be parsed.
100 * @return A new instance of the generated class.
102 + (nullable instancetype
)parseFromData
:(NSData
*)data error
:(NSError
**)errorPtr
;
105 * Creates a new instance by parsing the data. This method should be sent to
106 * the generated message class that the data should be interpreted as. If
107 * there is an error the method returns nil and the error is returned in
108 * errorPtr (when provided).
110 * @note In DEBUG builds, the parsed message is checked to be sure all required
111 * fields were provided, and the parse will fail if some are missing.
113 * @note The errors returned are likely coming from the domain and codes listed
114 * at the top of this file and GPBCodedInputStream.h.
116 * @param data The data to parse.
117 * @param extensionRegistry The extension registry to use to look up extensions.
118 * @param errorPtr An optional error pointer to fill in with a failure
119 * reason if the data can not be parsed.
121 * @return A new instance of the generated class.
123 + (nullable instancetype
)parseFromData
:(NSData
*)data
124 extensionRegistry
:(nullable id
<GPBExtensionRegistry
>)extensionRegistry
125 error
:(NSError
**)errorPtr
;
128 * Creates a new instance by parsing the data from the given input stream. This
129 * method should be sent to the generated message class that the data should
130 * be interpreted as. If there is an error the method returns nil and the error
131 * is returned in errorPtr (when provided).
133 * @note In DEBUG builds, the parsed message is checked to be sure all required
134 * fields were provided, and the parse will fail if some are missing.
136 * @note The errors returned are likely coming from the domain and codes listed
137 * at the top of this file and GPBCodedInputStream.h.
139 * @param input The stream to read data from.
140 * @param extensionRegistry The extension registry to use to look up extensions.
141 * @param errorPtr An optional error pointer to fill in with a failure
142 * reason if the data can not be parsed.
144 * @return A new instance of the generated class.
146 + (nullable instancetype
)parseFromCodedInputStream
:(GPBCodedInputStream
*)input
148 (nullable id
<GPBExtensionRegistry
>)extensionRegistry
149 error
:(NSError
**)errorPtr
;
152 * Creates a new instance by parsing the data from the given input stream. This
153 * method should be sent to the generated message class that the data should
154 * be interpreted as. If there is an error the method returns nil and the error
155 * is returned in errorPtr (when provided).
157 * @note Unlike the parseFrom... methods, this never checks to see if all of
158 * the required fields are set. So this method can be used to reload
159 * messages that may not be complete.
161 * @note The errors returned are likely coming from the domain and codes listed
162 * at the top of this file and GPBCodedInputStream.h.
164 * @param input The stream to read data from.
165 * @param extensionRegistry The extension registry to use to look up extensions.
166 * @param errorPtr An optional error pointer to fill in with a failure
167 * reason if the data can not be parsed.
169 * @return A new instance of the generated class.
171 + (nullable instancetype
)parseDelimitedFromCodedInputStream
:(GPBCodedInputStream
*)input
173 (nullable id
<GPBExtensionRegistry
>)extensionRegistry
174 error
:(NSError
**)errorPtr
;
177 * Initializes an instance by parsing the data. This method should be sent to
178 * the generated message class that the data should be interpreted as. If
179 * there is an error the method returns nil and the error is returned in
180 * errorPtr (when provided).
182 * @note In DEBUG builds, the parsed message is checked to be sure all required
183 * fields were provided, and the parse will fail if some are missing.
185 * @note The errors returned are likely coming from the domain and codes listed
186 * at the top of this file and GPBCodedInputStream.h.
188 * @param data The data to parse.
189 * @param errorPtr An optional error pointer to fill in with a failure reason if
190 * the data can not be parsed.
192 * @return An initialized instance of the generated class.
194 - (nullable instancetype
)initWithData
:(NSData
*)data error
:(NSError
**)errorPtr
;
197 * Initializes an instance by parsing the data. This method should be sent to
198 * the generated message class that the data should be interpreted as. If
199 * there is an error the method returns nil and the error is returned in
200 * errorPtr (when provided).
202 * @note In DEBUG builds, the parsed message is checked to be sure all required
203 * fields were provided, and the parse will fail if some are missing.
205 * @note The errors returned are likely coming from the domain and codes listed
206 * at the top of this file and GPBCodedInputStream.h.
208 * @param data The data to parse.
209 * @param extensionRegistry The extension registry to use to look up extensions.
210 * @param errorPtr An optional error pointer to fill in with a failure
211 * reason if the data can not be parsed.
213 * @return An initialized instance of the generated class.
215 - (nullable instancetype
)initWithData
:(NSData
*)data
216 extensionRegistry
:(nullable id
<GPBExtensionRegistry
>)extensionRegistry
217 error
:(NSError
**)errorPtr
;
220 * Initializes an instance by parsing the data from the given input stream. This
221 * method should be sent to the generated message class that the data should
222 * be interpreted as. If there is an error the method returns nil and the error
223 * is returned in errorPtr (when provided).
225 * @note Unlike the parseFrom... methods, this never checks to see if all of
226 * the required fields are set. So this method can be used to reload
227 * messages that may not be complete.
229 * @note The errors returned are likely coming from the domain and codes listed
230 * at the top of this file and GPBCodedInputStream.h.
232 * @param input The stream to read data from.
233 * @param extensionRegistry The extension registry to use to look up extensions.
234 * @param errorPtr An optional error pointer to fill in with a failure
235 * reason if the data can not be parsed.
237 * @return An initialized instance of the generated class.
239 - (nullable instancetype
)initWithCodedInputStream
:(GPBCodedInputStream
*)input
241 (nullable id
<GPBExtensionRegistry
>)extensionRegistry
242 error
:(NSError
**)errorPtr
;
245 * Parses the given data as this message's class, and merges those values into
248 * @param data The binary representation of the message to merge.
249 * @param extensionRegistry The extension registry to use to look up extensions.
250 * @param errorPtr An optional error pointer to fill in with a failure
251 * reason if the data can not be parsed. Will only be
252 * filled in if the data failed to be parsed.
254 * @return Boolean indicating success. errorPtr will only be fill in on failure.
256 - (BOOL
)mergeFromData
:(NSData
*)data
257 extensionRegistry
:(nullable id
<GPBExtensionRegistry
>)extensionRegistry
258 error
:(NSError
**)errorPtr
;
261 * Merges the fields from another message (of the same type) into this
264 * @param other Message to merge into this message.
266 - (void)mergeFrom
:(GPBMessage
*)other
;
269 * Writes out the message to the given coded output stream.
271 * @param output The coded output stream into which to write the message.
273 * @note This can raise the GPBCodedOutputStreamException_* exceptions.
275 * @note The most common cause of this failing is from one thread calling this
276 * while another thread has a reference to this message or a message used
277 * within a field and that other thread mutating the message while this
278 * serialization is taking place.
280 - (void)writeToCodedOutputStream
:(GPBCodedOutputStream
*)output
;
283 * Writes out the message to the given output stream.
285 * @param output The output stream into which to write the message.
287 * @note This can raise the GPBCodedOutputStreamException_* exceptions.
289 * @note The most common cause of this failing is from one thread calling this
290 * while another thread has a reference to this message or a message used
291 * within a field and that other thread mutating the message while this
292 * serialization is taking place.
294 - (void)writeToOutputStream
:(NSOutputStream
*)output
;
297 * Writes out a varint for the message size followed by the message to
298 * the given output stream.
300 * @param output The coded output stream into which to write the message.
302 * @note This can raise the GPBCodedOutputStreamException_* exceptions.
304 * @note The most common cause of this failing is from one thread calling this
305 * while another thread has a reference to this message or a message used
306 * within a field and that other thread mutating the message while this
307 * serialization is taking place.
309 - (void)writeDelimitedToCodedOutputStream
:(GPBCodedOutputStream
*)output
;
312 * Writes out a varint for the message size followed by the message to
313 * the given output stream.
315 * @param output The output stream into which to write the message.
317 * @note This can raise the GPBCodedOutputStreamException_* exceptions.
319 * @note The most common cause of this failing is from one thread calling this
320 * while another thread has a reference to this message or a message used
321 * within a field and that other thread mutating the message while this
322 * serialization is taking place.
324 - (void)writeDelimitedToOutputStream
:(NSOutputStream
*)output
;
327 * Serializes the message to an NSData.
329 * If there is an error while generating the data, nil is returned.
331 * @note This value is not cached, so if you are using it repeatedly, cache
334 * @note In DEBUG ONLY, the message is also checked for all required field,
335 * if one is missing, nil will be returned.
337 * @note The most common cause of this failing is from one thread calling this
338 * while another thread has a reference to this message or a message used
339 * within a field and that other thread mutating the message while this
340 * serialization is taking place.
342 * @return The binary representation of the message.
344 - (nullable NSData
*)data
;
347 * Serializes a varint with the message size followed by the message data,
348 * returning that as an NSData.
350 * @note This value is not cached, so if you are using it repeatedly, it is
351 * recommended to keep a local copy.
353 * @note The most common cause of this failing is from one thread calling this
354 * while another thread has a reference to this message or a message used
355 * within a field and that other thread mutating the message while this
356 * serialization is taking place.
358 * @return The binary representation of the size along with the message.
360 - (NSData
*)delimitedData
;
363 * Calculates the size of the object if it were serialized.
365 * This is not a cached value. If you are following a pattern like this:
368 * size_t size = [aMsg serializedSize];
369 * NSMutableData *foo = [NSMutableData dataWithCapacity:size + sizeof(size)];
370 * [foo writeSize:size];
371 * [foo appendData:[aMsg data]];
374 * you would be better doing:
377 * NSData *data = [aMsg data];
378 * NSUInteger size = [aMsg length];
379 * NSMutableData *foo = [NSMutableData dataWithCapacity:size + sizeof(size)];
380 * [foo writeSize:size];
381 * [foo appendData:data];
384 * @return The size of the message in it's binary representation.
386 - (size_t)serializedSize
;
389 * @return The descriptor for the message class.
391 + (GPBDescriptor
*)descriptor
;
394 * Return the descriptor for the message.
396 - (GPBDescriptor
*)descriptor
;
399 * @return An array with the extension descriptors that are currently set on the
402 - (NSArray
*)extensionsCurrentlySet
;
405 * Checks whether there is an extension set on the message which matches the
406 * given extension descriptor.
408 * @param extension Extension descriptor to check if it's set on the message.
410 * @return Whether the extension is currently set on the message.
412 - (BOOL
)hasExtension
:(GPBExtensionDescriptor
*)extension
;
415 * Fetches the given extension's value for this message.
417 * Extensions use boxed values (NSNumbers) for PODs and NSMutableArrays for
418 * repeated fields. If the extension is a Message one will be auto created for
419 * you and returned similar to fields.
421 * NOTE: For Enum extensions, if the enum was _closed_, then unknown values
422 * were parsed into the message's unknown fields instead of ending up in the
423 * extensions, just like what happens with singular/repeated fields. For open
424 * enums, the _raw_ value will be in the NSNumber, meaning if one does a
425 * `switch` on the values, a `default` case should also be included.
427 * @param extension The extension descriptor of the extension to fetch.
429 * @return The extension matching the given descriptor, or nil if none found.
431 - (nullable id
)getExtension
:(GPBExtensionDescriptor
*)extension
;
434 * Sets the given extension's value for this message. This only applies for
435 * single field extensions (i.e. - not repeated fields).
437 * Extensions use boxed values (NSNumbers).
439 * @param extension The extension descriptor under which to set the value.
440 * @param value The value to be set as the extension.
442 - (void)setExtension
:(GPBExtensionDescriptor
*)extension value
:(nullable id
)value
;
445 * Adds the given value to the extension for this message. This only applies
446 * to repeated field extensions. If the field is a repeated POD type, the value
447 * should be an NSNumber.
449 * @param extension The extension descriptor under which to add the value.
450 * @param value The value to be added to the repeated extension.
452 - (void)addExtension
:(GPBExtensionDescriptor
*)extension value
:(id
)value
;
455 * Replaces the value at the given index with the given value for the extension
456 * on this message. This only applies to repeated field extensions. If the field
457 * is a repeated POD type, the value is should be an NSNumber.
459 * @param extension The extension descriptor under which to replace the value.
460 * @param index The index of the extension to be replaced.
461 * @param value The value to be replaced in the repeated extension.
463 - (void)setExtension
:(GPBExtensionDescriptor
*)extension index
:(NSUInteger
)index value
:(id
)value
;
466 * Clears the given extension for this message.
468 * @param extension The extension descriptor to be cleared from this message.
470 - (void)clearExtension
:(GPBExtensionDescriptor
*)extension
;
473 * Resets all of the fields of this message to their default values.
478 * Clears any unknown fields on this message.
480 * Note: To clear this message's unknown field and all the unknown fields of the
481 * messages within the fields of this message, use
482 * `GPBMessageDropUnknownFieldsRecursively()`.
484 - (void)clearUnknownFields
;
487 * Merges in the data from an `GPBUnknownFields`, meaning the data from the unknown fields gets
488 * re-parsed so any known fields will be properly set.
490 * If the intent is to *replace* the message's unknown fields, call `-clearUnknownFields` first.
492 * Since the data from the GPBUnknownFields will always be well formed, this call will almost never
493 * fail. What could cause it to fail is if the GPBUnknownFields contains a field value that is
494 * an error for the message's schema - i.e.: if it contains a length delimited field where the
495 * field number for the message is defined to be a _string_ field, however the length delimited
496 * data provide is not a valid UTF8 string, or if the field is a _packed_ number field, but the
497 * data provided is not a valid for that field.
499 * @param unknownFields The unknown fields to merge the data from.
500 * @param extensionRegistry The extension registry to use to look up extensions, can be `nil`.
501 * @param errorPtr An optional error pointer to fill in with a failure
502 * reason if the data can not be parsed. Will only be
503 * filled in if the data failed to be parsed.
505 * @return Boolean indicating success. errorPtr will only be fill in on failure.
507 - (BOOL
)mergeUnknownFields
:(GPBUnknownFields
*)unknownFields
508 extensionRegistry
:(nullable id
<GPBExtensionRegistry
>)extensionRegistry
509 error
:(NSError
**)errorPtr
;
513 NS_ASSUME_NONNULL_END