OLD | NEW |
1 // Protocol Buffers - Google's data interchange format | 1 // Protocol Buffers - Google's data interchange format |
2 // Copyright 2008 Google Inc. All rights reserved. | 2 // Copyright 2008 Google Inc. All rights reserved. |
3 // https://developers.google.com/protocol-buffers/ | 3 // https://developers.google.com/protocol-buffers/ |
4 // | 4 // |
5 // Redistribution and use in source and binary forms, with or without | 5 // Redistribution and use in source and binary forms, with or without |
6 // modification, are permitted provided that the following conditions are | 6 // modification, are permitted provided that the following conditions are |
7 // met: | 7 // met: |
8 // | 8 // |
9 // * Redistributions of source code must retain the above copyright | 9 // * Redistributions of source code must retain the above copyright |
10 // notice, this list of conditions and the following disclaimer. | 10 // notice, this list of conditions and the following disclaimer. |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
65 enum_comments = BuildCommentsString(location); | 65 enum_comments = BuildCommentsString(location); |
66 } else { | 66 } else { |
67 enum_comments = ""; | 67 enum_comments = ""; |
68 } | 68 } |
69 | 69 |
70 printer->Print( | 70 printer->Print( |
71 "#pragma mark - Enum $name$\n" | 71 "#pragma mark - Enum $name$\n" |
72 "\n", | 72 "\n", |
73 "name", name_); | 73 "name", name_); |
74 | 74 |
75 printer->Print("$comments$typedef GPB_ENUM($name$) {\n", | 75 printer->Print("$comments$typedef$deprecated_attribute$ GPB_ENUM($name$) {\n", |
76 "comments", enum_comments, | 76 "comments", enum_comments, |
| 77 "deprecated_attribute", GetOptionalDeprecatedAttribute(descript
or_), |
77 "name", name_); | 78 "name", name_); |
78 printer->Indent(); | 79 printer->Indent(); |
79 | 80 |
80 if (HasPreservingUnknownEnumSemantics(descriptor_->file())) { | 81 if (HasPreservingUnknownEnumSemantics(descriptor_->file())) { |
81 // Include the unknown value. | 82 // Include the unknown value. |
82 printer->Print( | 83 printer->Print( |
| 84 "/// Value used if any message's field encounters a value that is not defi
ned\n" |
| 85 "/// by this enum. The message will also have C functions to get/set the r
awValue\n" |
| 86 "/// of the field.\n" |
83 "$name$_GPBUnrecognizedEnumeratorValue = kGPBUnrecognizedEnumeratorValue,\
n", | 87 "$name$_GPBUnrecognizedEnumeratorValue = kGPBUnrecognizedEnumeratorValue,\
n", |
84 "name", name_); | 88 "name", name_); |
85 } | 89 } |
86 | |
87 for (int i = 0; i < all_values_.size(); i++) { | 90 for (int i = 0; i < all_values_.size(); i++) { |
88 SourceLocation location; | 91 SourceLocation location; |
89 if (all_values_[i]->GetSourceLocation(&location)) { | 92 if (all_values_[i]->GetSourceLocation(&location)) { |
90 string comments = BuildCommentsString(location).c_str(); | 93 string comments = BuildCommentsString(location).c_str(); |
91 if (comments.length() > 0) { | 94 if (comments.length() > 0) { |
92 if (i > 0) { | 95 if (i > 0) { |
93 printer->Print("\n"); | 96 printer->Print("\n"); |
94 } | 97 } |
95 printer->Print(comments.c_str()); | 98 printer->Print(comments.c_str()); |
96 } | 99 } |
97 } | 100 } |
98 | 101 |
99 printer->Print( | 102 printer->Print( |
100 "$name$ = $value$,\n", | 103 "$name$$deprecated_attribute$ = $value$,\n", |
101 "name", EnumValueName(all_values_[i]), | 104 "name", EnumValueName(all_values_[i]), |
| 105 "deprecated_attribute", GetOptionalDeprecatedAttribute(all_values_[i]), |
102 "value", SimpleItoa(all_values_[i]->number())); | 106 "value", SimpleItoa(all_values_[i]->number())); |
103 } | 107 } |
104 printer->Outdent(); | 108 printer->Outdent(); |
105 printer->Print( | 109 printer->Print( |
106 "};\n" | 110 "};\n" |
107 "\n" | 111 "\n" |
108 "GPBEnumDescriptor *$name$_EnumDescriptor(void);\n" | 112 "GPBEnumDescriptor *$name$_EnumDescriptor(void);\n" |
109 "\n" | 113 "\n" |
| 114 "/// Checks to see if the given value is defined by the enum or was not kn
own at\n" |
| 115 "/// the time this source was generated.\n" |
110 "BOOL $name$_IsValidValue(int32_t value);\n" | 116 "BOOL $name$_IsValidValue(int32_t value);\n" |
111 "\n", | 117 "\n", |
112 "name", name_); | 118 "name", name_); |
113 } | 119 } |
114 | 120 |
115 void EnumGenerator::GenerateSource(io::Printer* printer) { | 121 void EnumGenerator::GenerateSource(io::Printer* printer) { |
116 printer->Print( | 122 printer->Print( |
117 "#pragma mark - Enum $name$\n" | 123 "#pragma mark - Enum $name$\n" |
118 "\n", | 124 "\n", |
119 "name", name_); | 125 "name", name_); |
120 | 126 |
121 printer->Print( | |
122 "GPBEnumDescriptor *$name$_EnumDescriptor(void) {\n" | |
123 " static GPBEnumDescriptor *descriptor = NULL;\n" | |
124 " if (!descriptor) {\n" | |
125 " static GPBMessageEnumValueDescription values[] = {\n", | |
126 "name", name_); | |
127 printer->Indent(); | |
128 printer->Indent(); | |
129 printer->Indent(); | |
130 | |
131 // Note: For the TextFormat decode info, we can't use the enum value as | 127 // Note: For the TextFormat decode info, we can't use the enum value as |
132 // the key because protocol buffer enums have 'allow_alias', which lets | 128 // the key because protocol buffer enums have 'allow_alias', which lets |
133 // a value be used more than once. Instead, the index into the list of | 129 // a value be used more than once. Instead, the index into the list of |
134 // enum value descriptions is used. Note: start with -1 so the first one | 130 // enum value descriptions is used. Note: start with -1 so the first one |
135 // will be zero. | 131 // will be zero. |
136 TextFormatDecodeData text_format_decode_data; | 132 TextFormatDecodeData text_format_decode_data; |
137 int enum_value_description_key = -1; | 133 int enum_value_description_key = -1; |
| 134 string text_blob; |
138 | 135 |
139 for (int i = 0; i < all_values_.size(); i++) { | 136 for (int i = 0; i < all_values_.size(); i++) { |
140 ++enum_value_description_key; | 137 ++enum_value_description_key; |
141 string short_name(EnumValueShortName(all_values_[i])); | 138 string short_name(EnumValueShortName(all_values_[i])); |
142 printer->Print("{ .name = \"$short_name$\", .number = $name$ },\n", | 139 text_blob += short_name + '\0'; |
143 "short_name", short_name, | |
144 "name", EnumValueName(all_values_[i])); | |
145 if (UnCamelCaseEnumShortName(short_name) != all_values_[i]->name()) { | 140 if (UnCamelCaseEnumShortName(short_name) != all_values_[i]->name()) { |
146 text_format_decode_data.AddString(enum_value_description_key, short_name, | 141 text_format_decode_data.AddString(enum_value_description_key, short_name, |
147 all_values_[i]->name()); | 142 all_values_[i]->name()); |
148 } | 143 } |
149 } | 144 } |
150 printer->Outdent(); | 145 |
151 printer->Outdent(); | 146 printer->Print( |
152 printer->Outdent(); | 147 "GPBEnumDescriptor *$name$_EnumDescriptor(void) {\n" |
| 148 " static GPBEnumDescriptor *descriptor = NULL;\n" |
| 149 " if (!descriptor) {\n", |
| 150 "name", name_); |
| 151 |
| 152 static const int kBytesPerLine = 40; // allow for escaping |
| 153 printer->Print( |
| 154 " static const char *valueNames ="); |
| 155 for (int i = 0; i < text_blob.size(); i += kBytesPerLine) { |
| 156 printer->Print( |
| 157 "\n \"$data$\"", |
| 158 "data", EscapeTrigraphs(CEscape(text_blob.substr(i, kBytesPerLine)))); |
| 159 } |
| 160 printer->Print( |
| 161 ";\n" |
| 162 " static const int32_t values[] = {\n"); |
| 163 for (int i = 0; i < all_values_.size(); i++) { |
| 164 printer->Print(" $name$,\n", "name", EnumValueName(all_values_[i])); |
| 165 } |
153 printer->Print(" };\n"); | 166 printer->Print(" };\n"); |
| 167 |
154 if (text_format_decode_data.num_entries() == 0) { | 168 if (text_format_decode_data.num_entries() == 0) { |
155 printer->Print( | 169 printer->Print( |
156 " descriptor = [GPBEnumDescriptor allocDescriptorForName:GPBNSStringi
fySymbol($name$)\n" | 170 " GPBEnumDescriptor *worker =\n" |
157 " values:values\n" | 171 " [GPBEnumDescriptor allocDescriptorForName:GPBNSStringifySymbol(
$name$)\n" |
158 " valueCount:sizeof(values
) / sizeof(GPBMessageEnumValueDescription)\n" | 172 " valueNames:valueNames\n" |
159 " enumVerifier:$name$_IsVali
dValue];\n", | 173 " values:values\n" |
| 174 " count:(uint32_t)(sizeof(val
ues) / sizeof(int32_t))\n" |
| 175 " enumVerifier:$name$_IsValidValue];
\n", |
160 "name", name_); | 176 "name", name_); |
161 } else { | 177 } else { |
162 printer->Print( | 178 printer->Print( |
163 " static const char *extraTextFormatInfo = \"$extraTextFormatInfo$\";
\n" | 179 " static const char *extraTextFormatInfo = \"$extraTextFormatInfo$\";
\n" |
164 " descriptor = [GPBEnumDescriptor allocDescriptorForName:GPBNSStringi
fySymbol($name$)\n" | 180 " GPBEnumDescriptor *worker =\n" |
165 " values:values\n" | 181 " [GPBEnumDescriptor allocDescriptorForName:GPBNSStringifySymbol(
$name$)\n" |
166 " valueCount:sizeof(values
) / sizeof(GPBMessageEnumValueDescription)\n" | 182 " valueNames:valueNames\n" |
167 " enumVerifier:$name$_IsVali
dValue\n" | 183 " values:values\n" |
168 " extraTextFormatInfo:extraTextForm
atInfo];\n", | 184 " count:(uint32_t)(sizeof(val
ues) / sizeof(int32_t))\n" |
| 185 " enumVerifier:$name$_IsValidValue\n
" |
| 186 " extraTextFormatInfo:extraTextFormatInfo];
\n", |
169 "name", name_, | 187 "name", name_, |
170 "extraTextFormatInfo", CEscape(text_format_decode_data.Data())); | 188 "extraTextFormatInfo", CEscape(text_format_decode_data.Data())); |
171 } | 189 } |
172 printer->Print( | 190 printer->Print( |
| 191 " if (!OSAtomicCompareAndSwapPtrBarrier(nil, worker, (void * volatile *
)&descriptor)) {\n" |
| 192 " [worker release];\n" |
| 193 " }\n" |
173 " }\n" | 194 " }\n" |
174 " return descriptor;\n" | 195 " return descriptor;\n" |
175 "}\n\n"); | 196 "}\n\n"); |
176 | 197 |
177 printer->Print( | 198 printer->Print( |
178 "BOOL $name$_IsValidValue(int32_t value__) {\n" | 199 "BOOL $name$_IsValidValue(int32_t value__) {\n" |
179 " switch (value__) {\n", | 200 " switch (value__) {\n", |
180 "name", name_); | 201 "name", name_); |
181 | 202 |
182 for (int i = 0; i < base_values_.size(); i++) { | 203 for (int i = 0; i < base_values_.size(); i++) { |
183 printer->Print( | 204 printer->Print( |
184 " case $name$:\n", | 205 " case $name$:\n", |
185 "name", EnumValueName(base_values_[i])); | 206 "name", EnumValueName(base_values_[i])); |
186 } | 207 } |
187 | 208 |
188 printer->Print( | 209 printer->Print( |
189 " return YES;\n" | 210 " return YES;\n" |
190 " default:\n" | 211 " default:\n" |
191 " return NO;\n" | 212 " return NO;\n" |
192 " }\n" | 213 " }\n" |
193 "}\n\n"); | 214 "}\n\n"); |
194 } | 215 } |
195 } // namespace objectivec | 216 } // namespace objectivec |
196 } // namespace compiler | 217 } // namespace compiler |
197 } // namespace protobuf | 218 } // namespace protobuf |
198 } // namespace google | 219 } // namespace google |
OLD | NEW |