GPBDescriptor_PackagePrivate.h 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378
  1. // Protocol Buffers - Google's data interchange format
  2. // Copyright 2008 Google Inc. All rights reserved.
  3. //
  4. // Use of this source code is governed by a BSD-style
  5. // license that can be found in the LICENSE file or at
  6. // https://developers.google.com/open-source/licenses/bsd
  7. // This header is private to the ProtobolBuffers library and must NOT be
  8. // included by any sources outside this library. The contents of this file are
  9. // subject to change at any time without notice.
  10. #import "GPBDescriptor.h"
  11. #import "GPBWireFormat.h"
  12. // Describes attributes of the field.
  13. typedef NS_OPTIONS(uint16_t, GPBFieldFlags) {
  14. GPBFieldNone = 0,
  15. // These map to standard protobuf concepts.
  16. GPBFieldRequired = 1 << 0,
  17. GPBFieldRepeated = 1 << 1,
  18. GPBFieldPacked = 1 << 2,
  19. GPBFieldOptional = 1 << 3,
  20. GPBFieldHasDefaultValue = 1 << 4,
  21. // Indicate that the field should "clear" when set to zero value. This is the
  22. // proto3 non optional behavior for singular data (ints, data, string, enum)
  23. // fields.
  24. GPBFieldClearHasIvarOnZero = 1 << 5,
  25. // Indicates the field needs custom handling for the TextFormat name, if not
  26. // set, the name can be derived from the ObjC name.
  27. GPBFieldTextFormatNameCustom = 1 << 6,
  28. // This flag has never had any meaning, it was set on all enum fields.
  29. GPBFieldHasEnumDescriptor = 1 << 7,
  30. // These are not standard protobuf concepts, they are specific to the
  31. // Objective C runtime.
  32. // These bits are used to mark the field as a map and what the key
  33. // type is.
  34. GPBFieldMapKeyMask = 0xF << 8,
  35. GPBFieldMapKeyInt32 = 1 << 8,
  36. GPBFieldMapKeyInt64 = 2 << 8,
  37. GPBFieldMapKeyUInt32 = 3 << 8,
  38. GPBFieldMapKeyUInt64 = 4 << 8,
  39. GPBFieldMapKeySInt32 = 5 << 8,
  40. GPBFieldMapKeySInt64 = 6 << 8,
  41. GPBFieldMapKeyFixed32 = 7 << 8,
  42. GPBFieldMapKeyFixed64 = 8 << 8,
  43. GPBFieldMapKeySFixed32 = 9 << 8,
  44. GPBFieldMapKeySFixed64 = 10 << 8,
  45. GPBFieldMapKeyBool = 11 << 8,
  46. GPBFieldMapKeyString = 12 << 8,
  47. // If the enum for this field is "closed", meaning that it:
  48. // - Has a fixed set of named values.
  49. // - Encountering values not in this set causes them to be treated as unknown
  50. // fields.
  51. // - The first value (i.e., the default) may be nonzero.
  52. // NOTE: This could be tracked just on the GPBEnumDescriptor, but to support
  53. // previously generated code, there would be not data to get the behavior
  54. // correct, so instead it is tracked on the field. If old source compatibility
  55. // is removed, this could be removed and the GPBEnumDescription fetched from
  56. // the GPBFieldDescriptor instead.
  57. GPBFieldClosedEnum = 1 << 12,
  58. };
  59. // NOTE: The structures defined here have their members ordered to minimize
  60. // their size. This directly impacts the size of apps since these exist per
  61. // field/extension.
  62. typedef struct GPBFileDescription {
  63. // The proto package for the file.
  64. const char *package;
  65. // The objc_class_prefix option if present.
  66. const char *prefix;
  67. // The file's proto syntax.
  68. GPBFileSyntax syntax;
  69. } GPBFileDescription;
  70. // Describes a single field in a protobuf as it is represented as an ivar.
  71. typedef struct GPBMessageFieldDescription {
  72. // Name of ivar.
  73. const char *name;
  74. union {
  75. // className is deprecated and will be removed in favor of clazz.
  76. // kept around right now for backwards compatibility.
  77. // clazz is used iff GPBDescriptorInitializationFlag_UsesClassRefs is set.
  78. char *className; // Name of the class of the message.
  79. Class clazz; // Class of the message.
  80. // For enums only.
  81. GPBEnumDescriptorFunc enumDescFunc;
  82. } dataTypeSpecific;
  83. // The field number for the ivar.
  84. uint32_t number;
  85. // The index (in bits) into _has_storage_.
  86. // >= 0: the bit to use for a value being set.
  87. // = GPBNoHasBit(INT32_MAX): no storage used.
  88. // < 0: in a oneOf, use a full int32 to record the field active.
  89. int32_t hasIndex;
  90. // Offset of the variable into it's structure struct.
  91. uint32_t offset;
  92. // Field flags. Use accessor functions below.
  93. GPBFieldFlags flags;
  94. // Data type of the ivar.
  95. GPBDataType dataType;
  96. } GPBMessageFieldDescription;
  97. // If a message uses fields where they provide default values that are non zero, then this
  98. // struct is used to provide the values along with the field info.
  99. typedef struct GPBMessageFieldDescriptionWithDefault {
  100. // Default value for the ivar.
  101. GPBGenericValue defaultValue;
  102. GPBMessageFieldDescription core;
  103. } GPBMessageFieldDescriptionWithDefault;
  104. // Describes attributes of the extension.
  105. typedef NS_OPTIONS(uint8_t, GPBExtensionOptions) {
  106. GPBExtensionNone = 0,
  107. // These map to standard protobuf concepts.
  108. GPBExtensionRepeated = 1 << 0,
  109. GPBExtensionPacked = 1 << 1,
  110. GPBExtensionSetWireFormat = 1 << 2,
  111. };
  112. // An extension
  113. typedef struct GPBExtensionDescription {
  114. GPBGenericValue defaultValue;
  115. const char *singletonName;
  116. // Before 3.12, `extendedClass` was just a `const char *`. Thanks to nested
  117. // initialization
  118. // (https://en.cppreference.com/w/c/language/struct_initialization#Nested_initialization) old
  119. // generated code with `.extendedClass = GPBStringifySymbol(Something)` still works; and the
  120. // current generator can use `extendedClass.clazz`, to pass a Class reference.
  121. union {
  122. const char *name;
  123. Class clazz;
  124. } extendedClass;
  125. // Before 3.12, this was `const char *messageOrGroupClassName`. In the
  126. // initial 3.12 release, we moved the `union messageOrGroupClass`, and failed
  127. // to realize that would break existing source code for extensions. So to
  128. // keep existing source code working, we added an unnamed union (C11) to
  129. // provide both the old field name and the new union. This keeps both older
  130. // and newer code working.
  131. // Background: https://github.com/protocolbuffers/protobuf/issues/7555
  132. union {
  133. const char *messageOrGroupClassName;
  134. union {
  135. const char *name;
  136. Class clazz;
  137. } messageOrGroupClass;
  138. };
  139. GPBEnumDescriptorFunc enumDescriptorFunc;
  140. int32_t fieldNumber;
  141. GPBDataType dataType;
  142. GPBExtensionOptions options;
  143. } GPBExtensionDescription;
  144. typedef NS_OPTIONS(uint32_t, GPBDescriptorInitializationFlags) {
  145. GPBDescriptorInitializationFlag_None = 0,
  146. GPBDescriptorInitializationFlag_FieldsWithDefault = 1 << 0,
  147. GPBDescriptorInitializationFlag_WireFormat = 1 << 1,
  148. // This is used as a stopgap as we move from using class names to class
  149. // references. The runtime needs to support both until we allow a
  150. // breaking change in the runtime.
  151. GPBDescriptorInitializationFlag_UsesClassRefs = 1 << 2,
  152. // This flag is used to indicate that the generated sources already contain
  153. // the `GPBFieldClearHasIvarOnZero` flag and it doesn't have to be computed
  154. // at startup. This allows older generated code to still work with the
  155. // current runtime library.
  156. GPBDescriptorInitializationFlag_Proto3OptionalKnown = 1 << 3,
  157. // This flag is used to indicate that the generated sources already contain
  158. // the `GPBFieldCloseEnum` flag and it doesn't have to be computed at startup.
  159. // This allows the older generated code to still work with the current runtime
  160. // library.
  161. GPBDescriptorInitializationFlag_ClosedEnumSupportKnown = 1 << 4,
  162. };
  163. @interface GPBDescriptor () {
  164. @package
  165. NSArray *fields_;
  166. NSArray *oneofs_;
  167. uint32_t storageSize_;
  168. }
  169. // fieldDescriptions and fileDescription have to be long lived, they are held as raw pointers.
  170. + (instancetype)allocDescriptorForClass:(Class)messageClass
  171. messageName:(NSString *)messageName
  172. fileDescription:(GPBFileDescription *)fileDescription
  173. fields:(void *)fieldDescriptions
  174. fieldCount:(uint32_t)fieldCount
  175. storageSize:(uint32_t)storageSize
  176. flags:(GPBDescriptorInitializationFlags)flags;
  177. // Called right after init to provide extra information to avoid init having
  178. // an explosion of args. These pointers are recorded, so they are expected
  179. // to live for the lifetime of the app.
  180. - (void)setupOneofs:(const char **)oneofNames
  181. count:(uint32_t)count
  182. firstHasIndex:(int32_t)firstHasIndex;
  183. - (void)setupExtraTextInfo:(const char *)extraTextFormatInfo;
  184. - (void)setupExtensionRanges:(const GPBExtensionRange *)ranges count:(int32_t)count;
  185. - (void)setupContainingMessageClass:(Class)msgClass;
  186. // Deprecated, these remain to support older versions of source generation.
  187. + (instancetype)allocDescriptorForClass:(Class)messageClass
  188. file:(GPBFileDescriptor *)file
  189. fields:(void *)fieldDescriptions
  190. fieldCount:(uint32_t)fieldCount
  191. storageSize:(uint32_t)storageSize
  192. flags:(GPBDescriptorInitializationFlags)flags;
  193. + (instancetype)allocDescriptorForClass:(Class)messageClass
  194. rootClass:(Class)rootClass
  195. file:(GPBFileDescriptor *)file
  196. fields:(void *)fieldDescriptions
  197. fieldCount:(uint32_t)fieldCount
  198. storageSize:(uint32_t)storageSize
  199. flags:(GPBDescriptorInitializationFlags)flags;
  200. - (void)setupContainingMessageClassName:(const char *)msgClassName;
  201. - (void)setupMessageClassNameSuffix:(NSString *)suffix;
  202. @end
  203. @interface GPBFileDescriptor ()
  204. - (instancetype)initWithPackage:(NSString *)package
  205. objcPrefix:(NSString *)objcPrefix
  206. syntax:(GPBFileSyntax)syntax;
  207. - (instancetype)initWithPackage:(NSString *)package syntax:(GPBFileSyntax)syntax;
  208. @end
  209. @interface GPBOneofDescriptor () {
  210. @package
  211. const char *name_;
  212. NSArray *fields_;
  213. SEL caseSel_;
  214. }
  215. // name must be long lived.
  216. - (instancetype)initWithName:(const char *)name fields:(NSArray *)fields;
  217. @end
  218. @interface GPBFieldDescriptor () {
  219. @package
  220. GPBMessageFieldDescription *description_;
  221. GPB_UNSAFE_UNRETAINED GPBOneofDescriptor *containingOneof_;
  222. SEL getSel_;
  223. SEL setSel_;
  224. SEL hasOrCountSel_; // *Count for map<>/repeated fields, has* otherwise.
  225. SEL setHasSel_;
  226. }
  227. @end
  228. typedef NS_OPTIONS(uint32_t, GPBEnumDescriptorInitializationFlags) {
  229. GPBEnumDescriptorInitializationFlag_None = 0,
  230. // Available: 1 << 0
  231. // Marks this enum as a closed enum.
  232. GPBEnumDescriptorInitializationFlag_IsClosed = 1 << 1,
  233. };
  234. @interface GPBEnumDescriptor ()
  235. // valueNames, values and extraTextFormatInfo have to be long lived, they are
  236. // held as raw pointers.
  237. + (instancetype)allocDescriptorForName:(NSString *)name
  238. valueNames:(const char *)valueNames
  239. values:(const int32_t *)values
  240. count:(uint32_t)valueCount
  241. enumVerifier:(GPBEnumValidationFunc)enumVerifier
  242. flags:(GPBEnumDescriptorInitializationFlags)flags;
  243. + (instancetype)allocDescriptorForName:(NSString *)name
  244. valueNames:(const char *)valueNames
  245. values:(const int32_t *)values
  246. count:(uint32_t)valueCount
  247. enumVerifier:(GPBEnumValidationFunc)enumVerifier
  248. flags:(GPBEnumDescriptorInitializationFlags)flags
  249. extraTextFormatInfo:(const char *)extraTextFormatInfo;
  250. // Deprecated, these remain to support older versions of source generation.
  251. + (instancetype)allocDescriptorForName:(NSString *)name
  252. valueNames:(const char *)valueNames
  253. values:(const int32_t *)values
  254. count:(uint32_t)valueCount
  255. enumVerifier:(GPBEnumValidationFunc)enumVerifier;
  256. + (instancetype)allocDescriptorForName:(NSString *)name
  257. valueNames:(const char *)valueNames
  258. values:(const int32_t *)values
  259. count:(uint32_t)valueCount
  260. enumVerifier:(GPBEnumValidationFunc)enumVerifier
  261. extraTextFormatInfo:(const char *)extraTextFormatInfo;
  262. @end
  263. @interface GPBExtensionDescriptor () {
  264. @package
  265. GPBExtensionDescription *description_;
  266. }
  267. @property(nonatomic, readonly) GPBWireFormat wireType;
  268. // For repeated extensions, alternateWireType is the wireType with the opposite
  269. // value for the packable property. i.e. - if the extension was marked packed
  270. // it would be the wire type for unpacked; if the extension was marked unpacked,
  271. // it would be the wire type for packed.
  272. @property(nonatomic, readonly) GPBWireFormat alternateWireType;
  273. // description has to be long lived, it is held as a raw pointer.
  274. - (instancetype)initWithExtensionDescription:(GPBExtensionDescription *)desc
  275. usesClassRefs:(BOOL)usesClassRefs;
  276. // Deprecated. Calls above with `usesClassRefs = NO`
  277. - (instancetype)initWithExtensionDescription:(GPBExtensionDescription *)desc;
  278. - (NSComparisonResult)compareByFieldNumber:(GPBExtensionDescriptor *)other;
  279. @end
  280. CF_EXTERN_C_BEGIN
  281. // Direct access is use for speed, to avoid even internally declaring things
  282. // read/write, etc. The warning is enabled in the project to ensure code calling
  283. // protos can turn on -Wdirect-ivar-access without issues.
  284. #pragma clang diagnostic push
  285. #pragma clang diagnostic ignored "-Wdirect-ivar-access"
  286. GPB_INLINE BOOL GPBFieldIsMapOrArray(GPBFieldDescriptor *field) {
  287. return (field->description_->flags & (GPBFieldRepeated | GPBFieldMapKeyMask)) != 0;
  288. }
  289. GPB_INLINE GPBDataType GPBGetFieldDataType(GPBFieldDescriptor *field) {
  290. return field->description_->dataType;
  291. }
  292. GPB_INLINE int32_t GPBFieldHasIndex(GPBFieldDescriptor *field) {
  293. return field->description_->hasIndex;
  294. }
  295. GPB_INLINE uint32_t GPBFieldNumber(GPBFieldDescriptor *field) {
  296. return field->description_->number;
  297. }
  298. GPB_INLINE BOOL GPBFieldIsClosedEnum(GPBFieldDescriptor *field) {
  299. return (field->description_->flags & GPBFieldClosedEnum) != 0;
  300. }
  301. #pragma clang diagnostic pop
  302. uint32_t GPBFieldTag(GPBFieldDescriptor *self);
  303. // For repeated fields, alternateWireType is the wireType with the opposite
  304. // value for the packable property. i.e. - if the field was marked packed it
  305. // would be the wire type for unpacked; if the field was marked unpacked, it
  306. // would be the wire type for packed.
  307. uint32_t GPBFieldAlternateTag(GPBFieldDescriptor *self);
  308. GPB_INLINE BOOL GPBExtensionIsRepeated(GPBExtensionDescription *description) {
  309. return (description->options & GPBExtensionRepeated) != 0;
  310. }
  311. GPB_INLINE BOOL GPBExtensionIsPacked(GPBExtensionDescription *description) {
  312. return (description->options & GPBExtensionPacked) != 0;
  313. }
  314. GPB_INLINE BOOL GPBExtensionIsWireFormat(GPBExtensionDescription *description) {
  315. return (description->options & GPBExtensionSetWireFormat) != 0;
  316. }
  317. // Helper for compile time assets.
  318. #ifndef GPBInternalCompileAssert
  319. #define GPBInternalCompileAssert(test, msg) _Static_assert((test), #msg)
  320. #endif // GPBInternalCompileAssert
  321. // Sanity check that there isn't padding between the field description
  322. // structures with and without a default.
  323. GPBInternalCompileAssert(sizeof(GPBMessageFieldDescriptionWithDefault) ==
  324. (sizeof(GPBGenericValue) + sizeof(GPBMessageFieldDescription)),
  325. DescriptionsWithDefault_different_size_than_expected);
  326. CF_EXTERN_C_END