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