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