GPBMessage.h 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537
  1. // Protocol Buffers - Google's data interchange format
  2. // Copyright 2008 Google Inc. All rights reserved.
  3. //
  4. // Use of this source code is governed by a BSD-style
  5. // license that can be found in the LICENSE file or at
  6. // https://developers.google.com/open-source/licenses/bsd
  7. #import <Foundation/Foundation.h>
  8. #import "GPBBootstrap.h"
  9. #import "GPBCodedInputStream.h"
  10. #import "GPBCodedOutputStream.h"
  11. #import "GPBDescriptor.h"
  12. #import "GPBExtensionRegistry.h"
  13. #import "GPBUnknownFieldSet.h"
  14. #import "GPBUnknownFields.h"
  15. @class GPBCodedInputStream;
  16. @class GPBCodedOutputStream;
  17. @class GPBUnknownFieldSet;
  18. @class GPBUnknownFields;
  19. NS_ASSUME_NONNULL_BEGIN
  20. CF_EXTERN_C_BEGIN
  21. /** NSError domain used for errors. */
  22. extern NSString *const GPBMessageErrorDomain;
  23. /** Error codes for NSErrors originated in GPBMessage. */
  24. typedef NS_ENUM(NSInteger, GPBMessageErrorCode) {
  25. /** Uncategorized error. */
  26. GPBMessageErrorCodeOther = -100,
  27. /** Message couldn't be serialized because it is missing required fields. */
  28. GPBMessageErrorCodeMissingRequiredField = -101,
  29. };
  30. /**
  31. * Key under which the GPBMessage error's reason is stored inside the userInfo
  32. * dictionary.
  33. **/
  34. extern NSString *const GPBErrorReasonKey;
  35. /**
  36. * An exception name raised during serialization when the message would be
  37. * larger than the 2GB limit.
  38. **/
  39. extern NSString *const GPBMessageExceptionMessageTooLarge;
  40. CF_EXTERN_C_END
  41. /**
  42. * Base class that each generated message subclasses from.
  43. *
  44. * @note @c NSCopying support is a "deep copy", in that all sub objects are
  45. * copied. Just like you wouldn't want a UIView/NSView trying to
  46. * exist in two places, you don't want a sub message to be a property
  47. * property of two other messages.
  48. *
  49. * @note While the class supports NSSecureCoding, if the message has any
  50. * extensions, they will end up reloaded in the unknown fields as there is
  51. * no way for the @c NSCoding plumbing to pass through a
  52. * @c GPBExtensionRegistry. To support extensions, instead of passing the
  53. * calls off to the Message, simple store the result of @c data, and then
  54. * when loading, fetch the data and use
  55. * @c +parseFromData:extensionRegistry:error: to provide an extension
  56. * registry.
  57. **/
  58. @interface GPBMessage : NSObject <NSSecureCoding, NSCopying>
  59. // If you add an instance method/property to this class that may conflict with
  60. // fields declared in protos, you need to update objective_helpers.cc. The main
  61. // cases are methods that take no arguments, or setFoo:/hasFoo: type methods.
  62. /**
  63. * The set of unknown fields for this message.
  64. **/
  65. @property(nonatomic, copy, nullable) GPBUnknownFieldSet *unknownFields __attribute__((
  66. deprecated("Use GPBUnknownFields and the -initFromMessage: initializer and "
  67. "mergeUnknownFields:extensionRegistry:error: to add the data back to a message.")));
  68. /**
  69. * Whether the message, along with all submessages, have the required fields
  70. * set.
  71. **/
  72. @property(nonatomic, readonly, getter=isInitialized) BOOL initialized;
  73. /**
  74. * @return An autoreleased message with the default values set.
  75. **/
  76. + (instancetype)message;
  77. /**
  78. * Creates a new instance by parsing the provided data. This method should be
  79. * sent to the generated message class that the data should be interpreted as.
  80. * If there is an error the method returns nil and the error is returned in
  81. * errorPtr (when provided).
  82. *
  83. * @note In DEBUG builds, the parsed message is checked to be sure all required
  84. * fields were provided, and the parse will fail if some are missing.
  85. *
  86. * @note The errors returned are likely coming from the domain and codes listed
  87. * at the top of this file and GPBCodedInputStream.h.
  88. *
  89. * @param data The data to parse.
  90. * @param errorPtr An optional error pointer to fill in with a failure reason if
  91. * the data can not be parsed.
  92. *
  93. * @return A new instance of the generated class.
  94. **/
  95. + (nullable instancetype)parseFromData:(NSData *)data error:(NSError **)errorPtr;
  96. /**
  97. * Creates a new instance by parsing the data. This method should be sent to
  98. * the generated message class that the data should be interpreted as. If
  99. * there is an error the method returns nil and the error is returned in
  100. * errorPtr (when provided).
  101. *
  102. * @note In DEBUG builds, the parsed message is checked to be sure all required
  103. * fields were provided, and the parse will fail if some are missing.
  104. *
  105. * @note The errors returned are likely coming from the domain and codes listed
  106. * at the top of this file and GPBCodedInputStream.h.
  107. *
  108. * @param data The data to parse.
  109. * @param extensionRegistry The extension registry to use to look up extensions.
  110. * @param errorPtr An optional error pointer to fill in with a failure
  111. * reason if the data can not be parsed.
  112. *
  113. * @return A new instance of the generated class.
  114. **/
  115. + (nullable instancetype)parseFromData:(NSData *)data
  116. extensionRegistry:(nullable id<GPBExtensionRegistry>)extensionRegistry
  117. error:(NSError **)errorPtr;
  118. /**
  119. * Creates a new instance by parsing the data from the given input stream. This
  120. * method should be sent to the generated message class that the data should
  121. * be interpreted as. If there is an error the method returns nil and the error
  122. * is returned in errorPtr (when provided).
  123. *
  124. * @note In DEBUG builds, the parsed message is checked to be sure all required
  125. * fields were provided, and the parse will fail if some are missing.
  126. *
  127. * @note The errors returned are likely coming from the domain and codes listed
  128. * at the top of this file and GPBCodedInputStream.h.
  129. *
  130. * @param input The stream to read data from.
  131. * @param extensionRegistry The extension registry to use to look up extensions.
  132. * @param errorPtr An optional error pointer to fill in with a failure
  133. * reason if the data can not be parsed.
  134. *
  135. * @return A new instance of the generated class.
  136. **/
  137. + (nullable instancetype)parseFromCodedInputStream:(GPBCodedInputStream *)input
  138. extensionRegistry:
  139. (nullable id<GPBExtensionRegistry>)extensionRegistry
  140. error:(NSError **)errorPtr;
  141. /**
  142. * Creates a new instance by parsing the data from the given input stream. This
  143. * method should be sent to the generated message class that the data should
  144. * be interpreted as. If there is an error the method returns nil and the error
  145. * is returned in errorPtr (when provided).
  146. *
  147. * @note Unlike the parseFrom... methods, this never checks to see if all of
  148. * the required fields are set. So this method can be used to reload
  149. * messages that may not be complete.
  150. *
  151. * @note The errors returned are likely coming from the domain and codes listed
  152. * at the top of this file and GPBCodedInputStream.h.
  153. *
  154. * @param input The stream to read data from.
  155. * @param extensionRegistry The extension registry to use to look up extensions.
  156. * @param errorPtr An optional error pointer to fill in with a failure
  157. * reason if the data can not be parsed.
  158. *
  159. * @return A new instance of the generated class.
  160. **/
  161. + (nullable instancetype)parseDelimitedFromCodedInputStream:(GPBCodedInputStream *)input
  162. extensionRegistry:
  163. (nullable id<GPBExtensionRegistry>)extensionRegistry
  164. error:(NSError **)errorPtr;
  165. /**
  166. * Initializes an instance by parsing the data. This method should be sent to
  167. * the generated message class that the data should be interpreted as. If
  168. * there is an error the method returns nil and the error is returned in
  169. * errorPtr (when provided).
  170. *
  171. * @note In DEBUG builds, the parsed message is checked to be sure all required
  172. * fields were provided, and the parse will fail if some are missing.
  173. *
  174. * @note The errors returned are likely coming from the domain and codes listed
  175. * at the top of this file and GPBCodedInputStream.h.
  176. *
  177. * @param data The data to parse.
  178. * @param errorPtr An optional error pointer to fill in with a failure reason if
  179. * the data can not be parsed.
  180. *
  181. * @return An initialized instance of the generated class.
  182. **/
  183. - (nullable instancetype)initWithData:(NSData *)data error:(NSError **)errorPtr;
  184. /**
  185. * Initializes an instance by parsing the data. This method should be sent to
  186. * the generated message class that the data should be interpreted as. If
  187. * there is an error the method returns nil and the error is returned in
  188. * errorPtr (when provided).
  189. *
  190. * @note In DEBUG builds, the parsed message is checked to be sure all required
  191. * fields were provided, and the parse will fail if some are missing.
  192. *
  193. * @note The errors returned are likely coming from the domain and codes listed
  194. * at the top of this file and GPBCodedInputStream.h.
  195. *
  196. * @param data The data to parse.
  197. * @param extensionRegistry The extension registry to use to look up extensions.
  198. * @param errorPtr An optional error pointer to fill in with a failure
  199. * reason if the data can not be parsed.
  200. *
  201. * @return An initialized instance of the generated class.
  202. **/
  203. - (nullable instancetype)initWithData:(NSData *)data
  204. extensionRegistry:(nullable id<GPBExtensionRegistry>)extensionRegistry
  205. error:(NSError **)errorPtr;
  206. /**
  207. * Initializes an instance by parsing the data from the given input stream. This
  208. * method should be sent to the generated message class that the data should
  209. * be interpreted as. If there is an error the method returns nil and the error
  210. * is returned in errorPtr (when provided).
  211. *
  212. * @note Unlike the parseFrom... methods, this never checks to see if all of
  213. * the required fields are set. So this method can be used to reload
  214. * messages that may not be complete.
  215. *
  216. * @note The errors returned are likely coming from the domain and codes listed
  217. * at the top of this file and GPBCodedInputStream.h.
  218. *
  219. * @param input The stream to read data from.
  220. * @param extensionRegistry The extension registry to use to look up extensions.
  221. * @param errorPtr An optional error pointer to fill in with a failure
  222. * reason if the data can not be parsed.
  223. *
  224. * @return An initialized instance of the generated class.
  225. **/
  226. - (nullable instancetype)initWithCodedInputStream:(GPBCodedInputStream *)input
  227. extensionRegistry:
  228. (nullable id<GPBExtensionRegistry>)extensionRegistry
  229. error:(NSError **)errorPtr;
  230. /**
  231. * Parses the given data as this message's class, and merges those values into
  232. * this message.
  233. *
  234. * @param data The binary representation of the message to merge.
  235. * @param extensionRegistry The extension registry to use to look up extensions.
  236. *
  237. * @exception GPBCodedInputStreamException Exception thrown when parsing was
  238. * unsuccessful.
  239. **/
  240. - (void)mergeFromData:(NSData *)data
  241. extensionRegistry:(nullable id<GPBExtensionRegistry>)extensionRegistry
  242. __attribute__((deprecated(
  243. "Use -mergeFromData:extensionRegistry:error: instead, especaily if calling from Swift.")));
  244. /**
  245. * Parses the given data as this message's class, and merges those values into
  246. * this message.
  247. *
  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.
  253. *
  254. * @return Boolean indicating success. errorPtr will only be fill in on failure.
  255. **/
  256. - (BOOL)mergeFromData:(NSData *)data
  257. extensionRegistry:(nullable id<GPBExtensionRegistry>)extensionRegistry
  258. error:(NSError **)errorPtr;
  259. /**
  260. * Merges the fields from another message (of the same type) into this
  261. * message.
  262. *
  263. * @param other Message to merge into this message.
  264. **/
  265. - (void)mergeFrom:(GPBMessage *)other;
  266. /**
  267. * Writes out the message to the given coded output stream.
  268. *
  269. * @param output The coded output stream into which to write the message.
  270. *
  271. * @note This can raise the GPBCodedOutputStreamException_* exceptions.
  272. *
  273. * @note The most common cause of this failing is from one thread calling this
  274. * while another thread has a reference to this message or a message used
  275. * within a field and that other thread mutating the message while this
  276. * serialization is taking place.
  277. **/
  278. - (void)writeToCodedOutputStream:(GPBCodedOutputStream *)output;
  279. /**
  280. * Writes out the message to the given output stream.
  281. *
  282. * @param output The output stream into which to write the message.
  283. *
  284. * @note This can raise the GPBCodedOutputStreamException_* exceptions.
  285. *
  286. * @note The most common cause of this failing is from one thread calling this
  287. * while another thread has a reference to this message or a message used
  288. * within a field and that other thread mutating the message while this
  289. * serialization is taking place.
  290. **/
  291. - (void)writeToOutputStream:(NSOutputStream *)output;
  292. /**
  293. * Writes out a varint for the message size followed by the message to
  294. * the given output stream.
  295. *
  296. * @param output The coded output stream into which to write the message.
  297. *
  298. * @note This can raise the GPBCodedOutputStreamException_* exceptions.
  299. *
  300. * @note The most common cause of this failing is from one thread calling this
  301. * while another thread has a reference to this message or a message used
  302. * within a field and that other thread mutating the message while this
  303. * serialization is taking place.
  304. **/
  305. - (void)writeDelimitedToCodedOutputStream:(GPBCodedOutputStream *)output;
  306. /**
  307. * Writes out a varint for the message size followed by the message to
  308. * the given output stream.
  309. *
  310. * @param output The output stream into which to write the message.
  311. *
  312. * @note This can raise the GPBCodedOutputStreamException_* exceptions.
  313. *
  314. * @note The most common cause of this failing is from one thread calling this
  315. * while another thread has a reference to this message or a message used
  316. * within a field and that other thread mutating the message while this
  317. * serialization is taking place.
  318. **/
  319. - (void)writeDelimitedToOutputStream:(NSOutputStream *)output;
  320. /**
  321. * Serializes the message to an NSData.
  322. *
  323. * If there is an error while generating the data, nil is returned.
  324. *
  325. * @note This value is not cached, so if you are using it repeatedly, cache
  326. * it yourself.
  327. *
  328. * @note In DEBUG ONLY, the message is also checked for all required field,
  329. * if one is missing, nil will be returned.
  330. *
  331. * @note The most common cause of this failing is from one thread calling this
  332. * while another thread has a reference to this message or a message used
  333. * within a field and that other thread mutating the message while this
  334. * serialization is taking place.
  335. *
  336. * @return The binary representation of the message.
  337. **/
  338. - (nullable NSData *)data;
  339. /**
  340. * Serializes a varint with the message size followed by the message data,
  341. * returning that as an NSData.
  342. *
  343. * @note This value is not cached, so if you are using it repeatedly, it is
  344. * recommended to keep a local copy.
  345. *
  346. * @note The most common cause of this failing is from one thread calling this
  347. * while another thread has a reference to this message or a message used
  348. * within a field and that other thread mutating the message while this
  349. * serialization is taking place.
  350. *
  351. * @return The binary representation of the size along with the message.
  352. **/
  353. - (NSData *)delimitedData;
  354. /**
  355. * Calculates the size of the object if it were serialized.
  356. *
  357. * This is not a cached value. If you are following a pattern like this:
  358. *
  359. * ```
  360. * size_t size = [aMsg serializedSize];
  361. * NSMutableData *foo = [NSMutableData dataWithCapacity:size + sizeof(size)];
  362. * [foo writeSize:size];
  363. * [foo appendData:[aMsg data]];
  364. * ```
  365. *
  366. * you would be better doing:
  367. *
  368. * ```
  369. * NSData *data = [aMsg data];
  370. * NSUInteger size = [aMsg length];
  371. * NSMutableData *foo = [NSMutableData dataWithCapacity:size + sizeof(size)];
  372. * [foo writeSize:size];
  373. * [foo appendData:data];
  374. * ```
  375. *
  376. * @return The size of the message in it's binary representation.
  377. **/
  378. - (size_t)serializedSize;
  379. /**
  380. * @return The descriptor for the message class.
  381. **/
  382. + (GPBDescriptor *)descriptor;
  383. /**
  384. * Return the descriptor for the message.
  385. **/
  386. - (GPBDescriptor *)descriptor;
  387. /**
  388. * @return An array with the extension descriptors that are currently set on the
  389. * message.
  390. **/
  391. - (NSArray *)extensionsCurrentlySet;
  392. /**
  393. * Checks whether there is an extension set on the message which matches the
  394. * given extension descriptor.
  395. *
  396. * @param extension Extension descriptor to check if it's set on the message.
  397. *
  398. * @return Whether the extension is currently set on the message.
  399. **/
  400. - (BOOL)hasExtension:(GPBExtensionDescriptor *)extension;
  401. /*
  402. * Fetches the given extension's value for this message.
  403. *
  404. * Extensions use boxed values (NSNumbers) for PODs and NSMutableArrays for
  405. * repeated fields. If the extension is a Message one will be auto created for
  406. * you and returned similar to fields.
  407. *
  408. * NOTE: For Enum extensions, if the enum was _closed_, then unknown values
  409. * were parsed into the message's unknown fields instead of ending up in the
  410. * extensions, just like what happens with singular/repeated fields. For open
  411. * enums, the _raw_ value will be in the NSNumber, meaning if one does a
  412. * `switch` on the values, a `default` case should also be included.
  413. *
  414. * @param extension The extension descriptor of the extension to fetch.
  415. *
  416. * @return The extension matching the given descriptor, or nil if none found.
  417. **/
  418. - (nullable id)getExtension:(GPBExtensionDescriptor *)extension;
  419. /**
  420. * Sets the given extension's value for this message. This only applies for
  421. * single field extensions (i.e. - not repeated fields).
  422. *
  423. * Extensions use boxed values (NSNumbers).
  424. *
  425. * @param extension The extension descriptor under which to set the value.
  426. * @param value The value to be set as the extension.
  427. **/
  428. - (void)setExtension:(GPBExtensionDescriptor *)extension value:(nullable id)value;
  429. /**
  430. * Adds the given value to the extension for this message. This only applies
  431. * to repeated field extensions. If the field is a repeated POD type, the value
  432. * should be an NSNumber.
  433. *
  434. * @param extension The extension descriptor under which to add the value.
  435. * @param value The value to be added to the repeated extension.
  436. **/
  437. - (void)addExtension:(GPBExtensionDescriptor *)extension value:(id)value;
  438. /**
  439. * Replaces the value at the given index with the given value for the extension
  440. * on this message. This only applies to repeated field extensions. If the field
  441. * is a repeated POD type, the value is should be an NSNumber.
  442. *
  443. * @param extension The extension descriptor under which to replace the value.
  444. * @param index The index of the extension to be replaced.
  445. * @param value The value to be replaced in the repeated extension.
  446. **/
  447. - (void)setExtension:(GPBExtensionDescriptor *)extension index:(NSUInteger)index value:(id)value;
  448. /**
  449. * Clears the given extension for this message.
  450. *
  451. * @param extension The extension descriptor to be cleared from this message.
  452. **/
  453. - (void)clearExtension:(GPBExtensionDescriptor *)extension;
  454. /**
  455. * Resets all of the fields of this message to their default values.
  456. **/
  457. - (void)clear;
  458. /**
  459. * Clears any unknown fields on this message.
  460. *
  461. * Note: To clear this message's unknown field and all the unknown fields of the
  462. * messages within the fields of this message, use
  463. * `GPBMessageDropUnknownFieldsRecursively()`.
  464. **/
  465. - (void)clearUnknownFields;
  466. /**
  467. * Merges in the data from an `GPBUnknownFields`, meaning the data from the unknown fields gets
  468. * re-parsed so any known fields will be properly set.
  469. *
  470. * If the intent is to *replace* the message's unknown fields, call `-clearUnknownFields` first.
  471. *
  472. * Since the data from the GPBUnknownFields will always be well formed, this call will almost never
  473. * fail. What could cause it to fail is if the GPBUnknownFields contains a field value that is
  474. * an error for the message's schema - i.e.: if it contains a length delimited field where the
  475. * field number for the message is defined to be a _string_ field, however the length delimited
  476. * data provide is not a valid UTF8 string, or if the field is a _packed_ number field, but the
  477. * data provided is not a valid for that field.
  478. *
  479. * @param unknownFields The unknown fields to merge the data from.
  480. * @param extensionRegistry The extension registry to use to look up extensions, can be `nil`.
  481. * @param errorPtr An optional error pointer to fill in with a failure
  482. * reason if the data can not be parsed. Will only be
  483. * filled in if the data failed to be parsed.
  484. *
  485. * @return Boolean indicating success. errorPtr will only be fill in on failure.
  486. **/
  487. - (BOOL)mergeUnknownFields:(GPBUnknownFields *)unknownFields
  488. extensionRegistry:(nullable id<GPBExtensionRegistry>)extensionRegistry
  489. error:(NSError **)errorPtr;
  490. @end
  491. NS_ASSUME_NONNULL_END