blob: ed424ce399b393a8b0c47eb9ace63a7c9d8979ba [file] [log] [blame]
Brian Silverman9c614bc2016-02-15 20:20:02 -05001// 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 "GPBUtilities.h"
34
35#import "GPBDescriptor_PackagePrivate.h"
36
37// Macros for stringifying library symbols. These are used in the generated
38// PB descriptor classes wherever a library symbol name is represented as a
39// string. See README.google for more information.
40#define GPBStringify(S) #S
41#define GPBStringifySymbol(S) GPBStringify(S)
42
43#define GPBNSStringify(S) @#S
44#define GPBNSStringifySymbol(S) GPBNSStringify(S)
45
46// Constant to internally mark when there is no has bit.
47#define GPBNoHasBit INT32_MAX
48
49CF_EXTERN_C_BEGIN
50
51// These two are used to inject a runtime check for version mismatch into the
52// generated sources to make sure they are linked with a supporting runtime.
Austin Schuh40c16522018-10-28 20:27:54 -070053void GPBCheckRuntimeVersionSupport(int32_t objcRuntimeVersion);
54GPB_INLINE void GPB_DEBUG_CHECK_RUNTIME_VERSIONS() {
55 // NOTE: By being inline here, this captures the value from the library's
56 // headers at the time the generated code was compiled.
57#if defined(DEBUG) && DEBUG
58 GPBCheckRuntimeVersionSupport(GOOGLE_PROTOBUF_OBJC_VERSION);
59#endif
60}
61
62// Legacy version of the checks, remove when GOOGLE_PROTOBUF_OBJC_GEN_VERSION
63// goes away (see more info in GPBBootstrap.h).
Brian Silverman9c614bc2016-02-15 20:20:02 -050064void GPBCheckRuntimeVersionInternal(int32_t version);
65GPB_INLINE void GPBDebugCheckRuntimeVersion() {
Austin Schuh40c16522018-10-28 20:27:54 -070066#if defined(DEBUG) && DEBUG
Brian Silverman9c614bc2016-02-15 20:20:02 -050067 GPBCheckRuntimeVersionInternal(GOOGLE_PROTOBUF_OBJC_GEN_VERSION);
68#endif
69}
70
71// Conversion functions for de/serializing floating point types.
72
73GPB_INLINE int64_t GPBConvertDoubleToInt64(double v) {
74 union { double f; int64_t i; } u;
75 u.f = v;
76 return u.i;
77}
78
79GPB_INLINE int32_t GPBConvertFloatToInt32(float v) {
80 union { float f; int32_t i; } u;
81 u.f = v;
82 return u.i;
83}
84
85GPB_INLINE double GPBConvertInt64ToDouble(int64_t v) {
86 union { double f; int64_t i; } u;
87 u.i = v;
88 return u.f;
89}
90
91GPB_INLINE float GPBConvertInt32ToFloat(int32_t v) {
92 union { float f; int32_t i; } u;
93 u.i = v;
94 return u.f;
95}
96
97GPB_INLINE int32_t GPBLogicalRightShift32(int32_t value, int32_t spaces) {
98 return (int32_t)((uint32_t)(value) >> spaces);
99}
100
101GPB_INLINE int64_t GPBLogicalRightShift64(int64_t value, int32_t spaces) {
102 return (int64_t)((uint64_t)(value) >> spaces);
103}
104
105// Decode a ZigZag-encoded 32-bit value. ZigZag encodes signed integers
106// into values that can be efficiently encoded with varint. (Otherwise,
107// negative values must be sign-extended to 64 bits to be varint encoded,
108// thus always taking 10 bytes on the wire.)
109GPB_INLINE int32_t GPBDecodeZigZag32(uint32_t n) {
Austin Schuh40c16522018-10-28 20:27:54 -0700110 return (int32_t)(GPBLogicalRightShift32((int32_t)n, 1) ^ -((int32_t)(n) & 1));
Brian Silverman9c614bc2016-02-15 20:20:02 -0500111}
112
113// Decode a ZigZag-encoded 64-bit value. ZigZag encodes signed integers
114// into values that can be efficiently encoded with varint. (Otherwise,
115// negative values must be sign-extended to 64 bits to be varint encoded,
116// thus always taking 10 bytes on the wire.)
117GPB_INLINE int64_t GPBDecodeZigZag64(uint64_t n) {
Austin Schuh40c16522018-10-28 20:27:54 -0700118 return (int64_t)(GPBLogicalRightShift64((int64_t)n, 1) ^ -((int64_t)(n) & 1));
Brian Silverman9c614bc2016-02-15 20:20:02 -0500119}
120
121// Encode a ZigZag-encoded 32-bit value. ZigZag encodes signed integers
122// into values that can be efficiently encoded with varint. (Otherwise,
123// negative values must be sign-extended to 64 bits to be varint encoded,
124// thus always taking 10 bytes on the wire.)
125GPB_INLINE uint32_t GPBEncodeZigZag32(int32_t n) {
126 // Note: the right-shift must be arithmetic
Austin Schuh40c16522018-10-28 20:27:54 -0700127 return ((uint32_t)n << 1) ^ (uint32_t)(n >> 31);
Brian Silverman9c614bc2016-02-15 20:20:02 -0500128}
129
130// Encode a ZigZag-encoded 64-bit value. ZigZag encodes signed integers
131// into values that can be efficiently encoded with varint. (Otherwise,
132// negative values must be sign-extended to 64 bits to be varint encoded,
133// thus always taking 10 bytes on the wire.)
134GPB_INLINE uint64_t GPBEncodeZigZag64(int64_t n) {
135 // Note: the right-shift must be arithmetic
Austin Schuh40c16522018-10-28 20:27:54 -0700136 return ((uint64_t)n << 1) ^ (uint64_t)(n >> 63);
Brian Silverman9c614bc2016-02-15 20:20:02 -0500137}
138
Austin Schuh40c16522018-10-28 20:27:54 -0700139#pragma clang diagnostic push
140#pragma clang diagnostic ignored "-Wswitch-enum"
141#pragma clang diagnostic ignored "-Wdirect-ivar-access"
142
Brian Silverman9c614bc2016-02-15 20:20:02 -0500143GPB_INLINE BOOL GPBDataTypeIsObject(GPBDataType type) {
144 switch (type) {
145 case GPBDataTypeBytes:
146 case GPBDataTypeString:
147 case GPBDataTypeMessage:
148 case GPBDataTypeGroup:
149 return YES;
150 default:
151 return NO;
152 }
153}
154
155GPB_INLINE BOOL GPBDataTypeIsMessage(GPBDataType type) {
156 switch (type) {
157 case GPBDataTypeMessage:
158 case GPBDataTypeGroup:
159 return YES;
160 default:
161 return NO;
162 }
163}
164
165GPB_INLINE BOOL GPBFieldDataTypeIsMessage(GPBFieldDescriptor *field) {
166 return GPBDataTypeIsMessage(field->description_->dataType);
167}
168
169GPB_INLINE BOOL GPBFieldDataTypeIsObject(GPBFieldDescriptor *field) {
170 return GPBDataTypeIsObject(field->description_->dataType);
171}
172
173GPB_INLINE BOOL GPBExtensionIsMessage(GPBExtensionDescriptor *ext) {
174 return GPBDataTypeIsMessage(ext->description_->dataType);
175}
176
177// The field is an array/map or it has an object value.
178GPB_INLINE BOOL GPBFieldStoresObject(GPBFieldDescriptor *field) {
179 GPBMessageFieldDescription *desc = field->description_;
180 if ((desc->flags & (GPBFieldRepeated | GPBFieldMapKeyMask)) != 0) {
181 return YES;
182 }
183 return GPBDataTypeIsObject(desc->dataType);
184}
185
186BOOL GPBGetHasIvar(GPBMessage *self, int32_t index, uint32_t fieldNumber);
187void GPBSetHasIvar(GPBMessage *self, int32_t idx, uint32_t fieldNumber,
188 BOOL value);
189uint32_t GPBGetHasOneof(GPBMessage *self, int32_t index);
190
191GPB_INLINE BOOL
192GPBGetHasIvarField(GPBMessage *self, GPBFieldDescriptor *field) {
193 GPBMessageFieldDescription *fieldDesc = field->description_;
194 return GPBGetHasIvar(self, fieldDesc->hasIndex, fieldDesc->number);
195}
196GPB_INLINE void GPBSetHasIvarField(GPBMessage *self, GPBFieldDescriptor *field,
197 BOOL value) {
198 GPBMessageFieldDescription *fieldDesc = field->description_;
199 GPBSetHasIvar(self, fieldDesc->hasIndex, fieldDesc->number, value);
200}
201
202void GPBMaybeClearOneof(GPBMessage *self, GPBOneofDescriptor *oneof,
Austin Schuh40c16522018-10-28 20:27:54 -0700203 int32_t oneofHasIndex, uint32_t fieldNumberNotToClear);
204
205#pragma clang diagnostic pop
Brian Silverman9c614bc2016-02-15 20:20:02 -0500206
207//%PDDM-DEFINE GPB_IVAR_SET_DECL(NAME, TYPE)
208//%void GPBSet##NAME##IvarWithFieldInternal(GPBMessage *self,
209//% NAME$S GPBFieldDescriptor *field,
210//% NAME$S TYPE value,
211//% NAME$S GPBFileSyntax syntax);
212//%PDDM-EXPAND GPB_IVAR_SET_DECL(Bool, BOOL)
213// This block of code is generated, do not edit it directly.
214
215void GPBSetBoolIvarWithFieldInternal(GPBMessage *self,
216 GPBFieldDescriptor *field,
217 BOOL value,
218 GPBFileSyntax syntax);
219//%PDDM-EXPAND GPB_IVAR_SET_DECL(Int32, int32_t)
220// This block of code is generated, do not edit it directly.
221
222void GPBSetInt32IvarWithFieldInternal(GPBMessage *self,
223 GPBFieldDescriptor *field,
224 int32_t value,
225 GPBFileSyntax syntax);
226//%PDDM-EXPAND GPB_IVAR_SET_DECL(UInt32, uint32_t)
227// This block of code is generated, do not edit it directly.
228
229void GPBSetUInt32IvarWithFieldInternal(GPBMessage *self,
230 GPBFieldDescriptor *field,
231 uint32_t value,
232 GPBFileSyntax syntax);
233//%PDDM-EXPAND GPB_IVAR_SET_DECL(Int64, int64_t)
234// This block of code is generated, do not edit it directly.
235
236void GPBSetInt64IvarWithFieldInternal(GPBMessage *self,
237 GPBFieldDescriptor *field,
238 int64_t value,
239 GPBFileSyntax syntax);
240//%PDDM-EXPAND GPB_IVAR_SET_DECL(UInt64, uint64_t)
241// This block of code is generated, do not edit it directly.
242
243void GPBSetUInt64IvarWithFieldInternal(GPBMessage *self,
244 GPBFieldDescriptor *field,
245 uint64_t value,
246 GPBFileSyntax syntax);
247//%PDDM-EXPAND GPB_IVAR_SET_DECL(Float, float)
248// This block of code is generated, do not edit it directly.
249
250void GPBSetFloatIvarWithFieldInternal(GPBMessage *self,
251 GPBFieldDescriptor *field,
252 float value,
253 GPBFileSyntax syntax);
254//%PDDM-EXPAND GPB_IVAR_SET_DECL(Double, double)
255// This block of code is generated, do not edit it directly.
256
257void GPBSetDoubleIvarWithFieldInternal(GPBMessage *self,
258 GPBFieldDescriptor *field,
259 double value,
260 GPBFileSyntax syntax);
261//%PDDM-EXPAND GPB_IVAR_SET_DECL(Enum, int32_t)
262// This block of code is generated, do not edit it directly.
263
264void GPBSetEnumIvarWithFieldInternal(GPBMessage *self,
265 GPBFieldDescriptor *field,
266 int32_t value,
267 GPBFileSyntax syntax);
268//%PDDM-EXPAND-END (8 expansions)
269
270int32_t GPBGetEnumIvarWithFieldInternal(GPBMessage *self,
271 GPBFieldDescriptor *field,
272 GPBFileSyntax syntax);
273
274id GPBGetObjectIvarWithField(GPBMessage *self, GPBFieldDescriptor *field);
275
276void GPBSetObjectIvarWithFieldInternal(GPBMessage *self,
277 GPBFieldDescriptor *field, id value,
278 GPBFileSyntax syntax);
279void GPBSetRetainedObjectIvarWithFieldInternal(GPBMessage *self,
280 GPBFieldDescriptor *field,
281 id __attribute__((ns_consumed))
282 value,
283 GPBFileSyntax syntax);
284
285// GPBGetObjectIvarWithField will automatically create the field (message) if
286// it doesn't exist. GPBGetObjectIvarWithFieldNoAutocreate will return nil.
287id GPBGetObjectIvarWithFieldNoAutocreate(GPBMessage *self,
288 GPBFieldDescriptor *field);
289
290void GPBSetAutocreatedRetainedObjectIvarWithField(
291 GPBMessage *self, GPBFieldDescriptor *field,
292 id __attribute__((ns_consumed)) value);
293
294// Clears and releases the autocreated message ivar, if it's autocreated. If
295// it's not set as autocreated, this method does nothing.
296void GPBClearAutocreatedMessageIvarWithField(GPBMessage *self,
297 GPBFieldDescriptor *field);
298
299// Returns an Objective C encoding for |selector|. |instanceSel| should be
300// YES if it's an instance selector (as opposed to a class selector).
301// |selector| must be a selector from MessageSignatureProtocol.
302const char *GPBMessageEncodingForSelector(SEL selector, BOOL instanceSel);
303
304// Helper for text format name encoding.
305// decodeData is the data describing the sepecial decodes.
306// key and inputString are the input that needs decoding.
307NSString *GPBDecodeTextFormatName(const uint8_t *decodeData, int32_t key,
308 NSString *inputString);
309
310// A series of selectors that are used solely to get @encoding values
311// for them by the dynamic protobuf runtime code. See
Austin Schuh40c16522018-10-28 20:27:54 -0700312// GPBMessageEncodingForSelector for details. GPBRootObject conforms to
313// the protocol so that it is encoded in the Objective C runtime.
Brian Silverman9c614bc2016-02-15 20:20:02 -0500314@protocol GPBMessageSignatureProtocol
315@optional
316
317#define GPB_MESSAGE_SIGNATURE_ENTRY(TYPE, NAME) \
318 -(TYPE)get##NAME; \
319 -(void)set##NAME : (TYPE)value; \
320 -(TYPE)get##NAME##AtIndex : (NSUInteger)index;
321
322GPB_MESSAGE_SIGNATURE_ENTRY(BOOL, Bool)
323GPB_MESSAGE_SIGNATURE_ENTRY(uint32_t, Fixed32)
324GPB_MESSAGE_SIGNATURE_ENTRY(int32_t, SFixed32)
325GPB_MESSAGE_SIGNATURE_ENTRY(float, Float)
326GPB_MESSAGE_SIGNATURE_ENTRY(uint64_t, Fixed64)
327GPB_MESSAGE_SIGNATURE_ENTRY(int64_t, SFixed64)
328GPB_MESSAGE_SIGNATURE_ENTRY(double, Double)
329GPB_MESSAGE_SIGNATURE_ENTRY(int32_t, Int32)
330GPB_MESSAGE_SIGNATURE_ENTRY(int64_t, Int64)
331GPB_MESSAGE_SIGNATURE_ENTRY(int32_t, SInt32)
332GPB_MESSAGE_SIGNATURE_ENTRY(int64_t, SInt64)
333GPB_MESSAGE_SIGNATURE_ENTRY(uint32_t, UInt32)
334GPB_MESSAGE_SIGNATURE_ENTRY(uint64_t, UInt64)
335GPB_MESSAGE_SIGNATURE_ENTRY(NSData *, Bytes)
336GPB_MESSAGE_SIGNATURE_ENTRY(NSString *, String)
337GPB_MESSAGE_SIGNATURE_ENTRY(GPBMessage *, Message)
338GPB_MESSAGE_SIGNATURE_ENTRY(GPBMessage *, Group)
339GPB_MESSAGE_SIGNATURE_ENTRY(int32_t, Enum)
340
341#undef GPB_MESSAGE_SIGNATURE_ENTRY
342
343- (id)getArray;
344- (NSUInteger)getArrayCount;
345- (void)setArray:(NSArray *)array;
346+ (id)getClassValue;
347@end
348
Austin Schuh40c16522018-10-28 20:27:54 -0700349BOOL GPBClassHasSel(Class aClass, SEL sel);
350
Brian Silverman9c614bc2016-02-15 20:20:02 -0500351CF_EXTERN_C_END