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 code for NSError with GPBMessageErrorDomain.
51 typedef NS_ENUM(NSInteger, GPBMessageErrorCode) {
52   /// Uncategorized error.
53   GPBMessageErrorCodeOther = -100,
54   /// A message can't be serialized because it is missing required fields.
55   GPBMessageErrorCodeMissingRequiredField = -101,
56 };
57 
58 /// Key under which the error's reason is stored inside the userInfo dictionary.
59 extern NSString *const GPBErrorReasonKey;
60 
61 CF_EXTERN_C_END
62 
63 /// Base class for all of the generated message classes.
64 @interface GPBMessage : NSObject<NSSecureCoding, NSCopying>
65 
66 // NOTE: If you add a instance method/property to this class that may conflict
67 // with methods declared in protos, you need to update objective_helpers.cc.
68 // The main cases are methods that take no arguments, or setFoo:/hasFoo: type
69 // methods.
70 
71 /// The unknown fields for this message.
72 ///
73 /// Only messages from proto files declared with "proto2" syntax support unknown
74 /// fields. For "proto3" syntax, any unknown fields found while parsing are
75 /// dropped.
76 @property(nonatomic, copy, nullable) GPBUnknownFieldSet *unknownFields;
77 
78 /// Are all required fields set in the message and all embedded messages.
79 @property(nonatomic, readonly, getter=isInitialized) BOOL initialized;
80 
81 /// Returns an autoreleased instance.
82 + (instancetype)message;
83 
84 /// Creates a new instance by parsing the data. This method should be sent to
85 /// the generated message class that the data should be interpreted as. If
86 /// there is an error the method returns nil and the error is returned in
87 /// errorPtr (when provided).
88 ///
89 /// @note In DEBUG builds, the parsed message is checked to be sure all required
90 ///       fields were provided, and the parse will fail if some are missing.
91 ///
92 /// @note The errors returned are likely coming from the domain and codes listed
93 ///       at the top of this file and GPBCodedInputStream.h.
94 ///
95 /// @param data     The data to parse.
96 /// @param errorPtr An optional error pointer to fill in with a failure reason if
97 ///                 the data can not be parsed.
98 ///
99 /// @return A new instance of the class messaged.
100 + (nullable instancetype)parseFromData:(NSData *)data error:(NSError **)errorPtr;
101 
102 /// Creates a new instance by parsing the data. This method should be sent to
103 /// the generated message class that the data should be interpreted as. If
104 /// there is an error the method returns nil and the error is returned in
105 /// errorPtr (when provided).
106 ///
107 /// @note In DEBUG builds, the parsed message is checked to be sure all required
108 ///       fields were provided, and the parse will fail if some are missing.
109 ///
110 /// @note The errors returned are likely coming from the domain and codes listed
111 ///       at the top of this file and GPBCodedInputStream.h.
112 ///
113 /// @param data              The data to parse.
114 /// @param extensionRegistry The extension registry to use to look up extensions.
115 /// @param errorPtr          An optional error pointer to fill in with a failure
116 ///                          reason if the data can not be parsed.
117 ///
118 /// @return A new instance of the class messaged.
119 + (nullable instancetype)parseFromData:(NSData *)data
120                      extensionRegistry:(nullable GPBExtensionRegistry *)extensionRegistry
121                                  error:(NSError **)errorPtr;
122 
123 /// Creates a new instance by parsing the data from the given input stream. This
124 /// method should be sent to the generated message class that the data should
125 /// be interpreted as. If there is an error the method returns nil and the error
126 /// is returned in errorPtr (when provided).
127 ///
128 /// @note In DEBUG builds, the parsed message is checked to be sure all required
129 ///       fields were provided, and the parse will fail if some are missing.
130 ///
131 /// @note The errors returned are likely coming from the domain and codes listed
132 ///       at the top of this file and GPBCodedInputStream.h.
133 ///
134 /// @param input             The stream to read data from.
135 /// @param extensionRegistry The extension registry to use to look up extensions.
136 /// @param errorPtr          An optional error pointer to fill in with a failure
137 ///                          reason if the data can not be parsed.
138 ///
139 /// @return A new instance of the class messaged.
140 + (nullable instancetype)parseFromCodedInputStream:(GPBCodedInputStream *)input
141                                  extensionRegistry:
142                                      (nullable GPBExtensionRegistry *)extensionRegistry
143                                              error:(NSError **)errorPtr;
144 
145 /// Creates a new instance by parsing the data from the given input stream. This
146 /// method should be sent to the generated message class that the data should
147 /// be interpreted as. If there is an error the method returns nil and the error
148 /// is returned in errorPtr (when provided).
149 ///
150 /// @note Unlike the parseFrom... methods, this never checks to see if all of
151 ///       the required fields are set. So this method can be used to reload
152 ///       messages that may not be complete.
153 ///
154 /// @note The errors returned are likely coming from the domain and codes listed
155 ///       at the top of this file and GPBCodedInputStream.h.
156 ///
157 /// @param input             The stream to read data from.
158 /// @param extensionRegistry The extension registry to use to look up extensions.
159 /// @param errorPtr          An optional error pointer to fill in with a failure
160 ///                          reason if the data can not be parsed.
161 ///
162 /// @return A new instance of the class messaged.
163 + (nullable instancetype)parseDelimitedFromCodedInputStream:(GPBCodedInputStream *)input
164                                           extensionRegistry:
165                                               (nullable GPBExtensionRegistry *)extensionRegistry
166                                                       error:(NSError **)errorPtr;
167 
168 /// Initializes an instance by parsing the data. This method should be sent to
169 /// the generated message class that the data should be interpreted as. If
170 /// there is an error the method returns nil and the error is returned in
171 /// errorPtr (when provided).
172 ///
173 /// @note In DEBUG builds, the parsed message is checked to be sure all required
174 ///       fields were provided, and the parse will fail if some are missing.
175 ///
176 /// @note The errors returned are likely coming from the domain and codes listed
177 ///       at the top of this file and GPBCodedInputStream.h.
178 ///
179 /// @param data     The data to parse.
180 /// @param errorPtr An optional error pointer to fill in with a failure reason if
181 ///                 the data can not be parsed.
182 - (nullable instancetype)initWithData:(NSData *)data error:(NSError **)errorPtr;
183 
184 /// Initializes an instance by parsing the data. This method should be sent to
185 /// the generated message class that the data should be interpreted as. If
186 /// there is an error the method returns nil and the error is returned in
187 /// errorPtr (when provided).
188 ///
189 /// @note In DEBUG builds, the parsed message is checked to be sure all required
190 ///       fields were provided, and the parse will fail if some are missing.
191 ///
192 /// @note The errors returned are likely coming from the domain and codes listed
193 ///       at the top of this file and GPBCodedInputStream.h.
194 ///
195 /// @param data              The data to parse.
196 /// @param extensionRegistry The extension registry to use to look up extensions.
197 /// @param errorPtr          An optional error pointer to fill in with a failure
198 ///                          reason if the data can not be parsed.
199 - (nullable instancetype)initWithData:(NSData *)data
200                     extensionRegistry:(nullable GPBExtensionRegistry *)extensionRegistry
201                                 error:(NSError **)errorPtr;
202 
203 /// Initializes an instance by parsing the data from the given input stream. This
204 /// method should be sent to the generated message class that the data should
205 /// be interpreted as. If there is an error the method returns nil and the error
206 /// is returned in errorPtr (when provided).
207 ///
208 /// @note Unlike the parseFrom... methods, this never checks to see if all of
209 ///       the required fields are set. So this method can be used to reload
210 ///       messages that may not be complete.
211 ///
212 /// @note The errors returned are likely coming from the domain and codes listed
213 ///       at the top of this file and GPBCodedInputStream.h.
214 ///
215 /// @param input             The stream to read data from.
216 /// @param extensionRegistry The extension registry to use to look up extensions.
217 /// @param errorPtr          An optional error pointer to fill in with a failure
218 ///                          reason if the data can not be parsed.
219 - (nullable instancetype)initWithCodedInputStream:(GPBCodedInputStream *)input
220                                 extensionRegistry:
221                                     (nullable GPBExtensionRegistry *)extensionRegistry
222                                             error:(NSError **)errorPtr;
223 
224 /// Writes out the message to the given output stream.
225 - (void)writeToCodedOutputStream:(GPBCodedOutputStream *)output;
226 /// Writes out the message to the given output stream.
227 - (void)writeToOutputStream:(NSOutputStream *)output;
228 
229 /// Writes out a varint for the message size followed by the the message to
230 /// the given output stream.
231 - (void)writeDelimitedToCodedOutputStream:(GPBCodedOutputStream *)output;
232 /// Writes out a varint for the message size followed by the the message to
233 /// the given output stream.
234 - (void)writeDelimitedToOutputStream:(NSOutputStream *)output;
235 
236 /// Serializes the message to a @c NSData.
237 ///
238 /// If there is an error while generating the data, nil is returned.
239 ///
240 /// @note This value is not cached, so if you are using it repeatedly, cache
241 ///       it yourself.
242 ///
243 /// @note In DEBUG ONLY, the message is also checked for all required field,
244 ///       if one is missing, nil will be returned.
245 - (nullable NSData *)data;
246 
247 /// Serializes a varint with the message size followed by the message data,
248 /// returning that as a @c NSData.
249 ///
250 /// @note This value is not cached, so if you are using it repeatedly, cache
251 ///       it yourself.
252 - (NSData *)delimitedData;
253 
254 /// Calculates the size of the object if it were serialized.
255 ///
256 /// This is not a cached value. If you are following a pattern like this:
257 /// @code
258 ///   size_t size = [aMsg serializedSize];
259 ///   NSMutableData *foo = [NSMutableData dataWithCapacity:size + sizeof(size)];
260 ///   [foo writeSize:size];
261 ///   [foo appendData:[aMsg data]];
262 /// @endcode
263 /// you would be better doing:
264 /// @code
265 ///   NSData *data = [aMsg data];
266 ///   NSUInteger size = [aMsg length];
267 ///   NSMutableData *foo = [NSMutableData dataWithCapacity:size + sizeof(size)];
268 ///   [foo writeSize:size];
269 ///   [foo appendData:data];
270 /// @endcode
271 - (size_t)serializedSize;
272 
273 /// Return the descriptor for the message class.
274 + (GPBDescriptor *)descriptor;
275 /// Return the descriptor for the message.
276 - (GPBDescriptor *)descriptor;
277 
278 /// Returns an array with the currently set GPBExtensionDescriptors.
279 - (NSArray *)extensionsCurrentlySet;
280 
281 /// Test to see if the given extension is set on the message.
282 - (BOOL)hasExtension:(GPBExtensionDescriptor *)extension;
283 
284 /// Fetches the given extension's value for this message.
285 ///
286 /// Extensions use boxed values (NSNumbers) for PODs and NSMutableArrays for
287 /// repeated fields. If the extension is a Message one will be auto created for you
288 /// and returned similar to fields.
289 - (nullable id)getExtension:(GPBExtensionDescriptor *)extension;
290 
291 /// Sets the given extension's value for this message. This is only for single
292 /// field extensions (i.e. - not repeated fields).
293 ///
294 /// Extensions use boxed values (@c NSNumbers).
295 - (void)setExtension:(GPBExtensionDescriptor *)extension value:(nullable id)value;
296 
297 /// Adds the given value to the extension for this message. This is only for
298 /// repeated field extensions. If the field is a repeated POD type the @c value
299 /// is a @c NSNumber.
300 - (void)addExtension:(GPBExtensionDescriptor *)extension value:(id)value;
301 
302 /// Replaces the given value at an index for the extension on this message. This
303 /// is only for repeated field extensions. If the field is a repeated POD type
304 /// the @c value is a @c NSNumber.
305 - (void)setExtension:(GPBExtensionDescriptor *)extension
306                index:(NSUInteger)index
307                value:(id)value;
308 
309 /// Clears the given extension for this message.
310 - (void)clearExtension:(GPBExtensionDescriptor *)extension;
311 
312 /// Resets all of the fields of this message to their default values.
313 - (void)clear;
314 
315 /// Parses a message of this type from the input and merges it with this
316 /// message.
317 ///
318 /// @note This will throw if there is an error parsing the data.
319 - (void)mergeFromData:(NSData *)data
320     extensionRegistry:(nullable GPBExtensionRegistry *)extensionRegistry;
321 
322 /// Merges the fields from another message (of the same type) into this
323 /// message.
324 - (void)mergeFrom:(GPBMessage *)other;
325 
326 @end
327 
328 NS_ASSUME_NONNULL_END
329