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 // 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 
49 CF_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.
53 void GPBCheckRuntimeVersionSupport(int32_t objcRuntimeVersion);
GPB_DEBUG_CHECK_RUNTIME_VERSIONS()54 GPB_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).
64 void GPBCheckRuntimeVersionInternal(int32_t version);
GPBDebugCheckRuntimeVersion()65 GPB_INLINE void GPBDebugCheckRuntimeVersion() {
66 #if defined(DEBUG) && DEBUG
67   GPBCheckRuntimeVersionInternal(GOOGLE_PROTOBUF_OBJC_GEN_VERSION);
68 #endif
69 }
70 
71 // Conversion functions for de/serializing floating point types.
72 
GPBConvertDoubleToInt64(double v)73 GPB_INLINE int64_t GPBConvertDoubleToInt64(double v) {
74   union { double f; int64_t i; } u;
75   u.f = v;
76   return u.i;
77 }
78 
GPBConvertFloatToInt32(float v)79 GPB_INLINE int32_t GPBConvertFloatToInt32(float v) {
80   union { float f; int32_t i; } u;
81   u.f = v;
82   return u.i;
83 }
84 
GPBConvertInt64ToDouble(int64_t v)85 GPB_INLINE double GPBConvertInt64ToDouble(int64_t v) {
86   union { double f; int64_t i; } u;
87   u.i = v;
88   return u.f;
89 }
90 
GPBConvertInt32ToFloat(int32_t v)91 GPB_INLINE float GPBConvertInt32ToFloat(int32_t v) {
92   union { float f; int32_t i; } u;
93   u.i = v;
94   return u.f;
95 }
96 
GPBLogicalRightShift32(int32_t value,int32_t spaces)97 GPB_INLINE int32_t GPBLogicalRightShift32(int32_t value, int32_t spaces) {
98   return (int32_t)((uint32_t)(value) >> spaces);
99 }
100 
GPBLogicalRightShift64(int64_t value,int32_t spaces)101 GPB_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.)
GPBDecodeZigZag32(uint32_t n)109 GPB_INLINE int32_t GPBDecodeZigZag32(uint32_t n) {
110   return (int32_t)(GPBLogicalRightShift32((int32_t)n, 1) ^ -((int32_t)(n) & 1));
111 }
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.)
GPBDecodeZigZag64(uint64_t n)117 GPB_INLINE int64_t GPBDecodeZigZag64(uint64_t n) {
118   return (int64_t)(GPBLogicalRightShift64((int64_t)n, 1) ^ -((int64_t)(n) & 1));
119 }
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.)
GPBEncodeZigZag32(int32_t n)125 GPB_INLINE uint32_t GPBEncodeZigZag32(int32_t n) {
126   // Note:  the right-shift must be arithmetic
127   return ((uint32_t)n << 1) ^ (uint32_t)(n >> 31);
128 }
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.)
GPBEncodeZigZag64(int64_t n)134 GPB_INLINE uint64_t GPBEncodeZigZag64(int64_t n) {
135   // Note:  the right-shift must be arithmetic
136   return ((uint64_t)n << 1) ^ (uint64_t)(n >> 63);
137 }
138 
139 #pragma clang diagnostic push
140 #pragma clang diagnostic ignored "-Wswitch-enum"
141 #pragma clang diagnostic ignored "-Wdirect-ivar-access"
142 
GPBDataTypeIsObject(GPBDataType type)143 GPB_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 
GPBDataTypeIsMessage(GPBDataType type)155 GPB_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 
GPBFieldDataTypeIsMessage(GPBFieldDescriptor * field)165 GPB_INLINE BOOL GPBFieldDataTypeIsMessage(GPBFieldDescriptor *field) {
166   return GPBDataTypeIsMessage(field->description_->dataType);
167 }
168 
GPBFieldDataTypeIsObject(GPBFieldDescriptor * field)169 GPB_INLINE BOOL GPBFieldDataTypeIsObject(GPBFieldDescriptor *field) {
170   return GPBDataTypeIsObject(field->description_->dataType);
171 }
172 
GPBExtensionIsMessage(GPBExtensionDescriptor * ext)173 GPB_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.
GPBFieldStoresObject(GPBFieldDescriptor * field)178 GPB_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 
186 BOOL GPBGetHasIvar(GPBMessage *self, int32_t index, uint32_t fieldNumber);
187 void GPBSetHasIvar(GPBMessage *self, int32_t idx, uint32_t fieldNumber,
188                    BOOL value);
189 uint32_t GPBGetHasOneof(GPBMessage *self, int32_t index);
190 
191 GPB_INLINE BOOL
GPBGetHasIvarField(GPBMessage * self,GPBFieldDescriptor * field)192 GPBGetHasIvarField(GPBMessage *self, GPBFieldDescriptor *field) {
193   GPBMessageFieldDescription *fieldDesc = field->description_;
194   return GPBGetHasIvar(self, fieldDesc->hasIndex, fieldDesc->number);
195 }
GPBSetHasIvarField(GPBMessage * self,GPBFieldDescriptor * field,BOOL value)196 GPB_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 
202 void GPBMaybeClearOneof(GPBMessage *self, GPBOneofDescriptor *oneof,
203                         int32_t oneofHasIndex, uint32_t fieldNumberNotToClear);
204 
205 #pragma clang diagnostic pop
206 
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 
215 void 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 
222 void 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 
229 void 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 
236 void 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 
243 void 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 
250 void 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 
257 void 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 
264 void GPBSetEnumIvarWithFieldInternal(GPBMessage *self,
265                                      GPBFieldDescriptor *field,
266                                      int32_t value,
267                                      GPBFileSyntax syntax);
268 //%PDDM-EXPAND-END (8 expansions)
269 
270 int32_t GPBGetEnumIvarWithFieldInternal(GPBMessage *self,
271                                         GPBFieldDescriptor *field,
272                                         GPBFileSyntax syntax);
273 
274 id GPBGetObjectIvarWithField(GPBMessage *self, GPBFieldDescriptor *field);
275 
276 void GPBSetObjectIvarWithFieldInternal(GPBMessage *self,
277                                        GPBFieldDescriptor *field, id value,
278                                        GPBFileSyntax syntax);
279 void 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.
287 id GPBGetObjectIvarWithFieldNoAutocreate(GPBMessage *self,
288                                          GPBFieldDescriptor *field);
289 
290 void 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.
296 void 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.
302 const 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.
307 NSString *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
312 // GPBMessageEncodingForSelector for details. GPBRootObject conforms to
313 // the protocol so that it is encoded in the Objective C runtime.
314 @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 
322 GPB_MESSAGE_SIGNATURE_ENTRY(BOOL, Bool)
323 GPB_MESSAGE_SIGNATURE_ENTRY(uint32_t, Fixed32)
324 GPB_MESSAGE_SIGNATURE_ENTRY(int32_t, SFixed32)
325 GPB_MESSAGE_SIGNATURE_ENTRY(float, Float)
326 GPB_MESSAGE_SIGNATURE_ENTRY(uint64_t, Fixed64)
327 GPB_MESSAGE_SIGNATURE_ENTRY(int64_t, SFixed64)
328 GPB_MESSAGE_SIGNATURE_ENTRY(double, Double)
329 GPB_MESSAGE_SIGNATURE_ENTRY(int32_t, Int32)
330 GPB_MESSAGE_SIGNATURE_ENTRY(int64_t, Int64)
331 GPB_MESSAGE_SIGNATURE_ENTRY(int32_t, SInt32)
332 GPB_MESSAGE_SIGNATURE_ENTRY(int64_t, SInt64)
333 GPB_MESSAGE_SIGNATURE_ENTRY(uint32_t, UInt32)
334 GPB_MESSAGE_SIGNATURE_ENTRY(uint64_t, UInt64)
335 GPB_MESSAGE_SIGNATURE_ENTRY(NSData *, Bytes)
336 GPB_MESSAGE_SIGNATURE_ENTRY(NSString *, String)
337 GPB_MESSAGE_SIGNATURE_ENTRY(GPBMessage *, Message)
338 GPB_MESSAGE_SIGNATURE_ENTRY(GPBMessage *, Group)
339 GPB_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 
349 BOOL GPBClassHasSel(Class aClass, SEL sel);
350 
351 CF_EXTERN_C_END
352