protobuf/src/google/protobuf/compiler/objectivec/objectivec_enum.cc
Go to the documentation of this file.
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 #include <map>
32 #include <string>
33 
34 #include <google/protobuf/compiler/objectivec/objectivec_enum.h>
35 #include <google/protobuf/compiler/objectivec/objectivec_helpers.h>
36 #include <google/protobuf/io/printer.h>
37 #include <google/protobuf/stubs/strutil.h>
38 #include <algorithm> // std::find()
39 
40 namespace google {
41 namespace protobuf {
42 namespace compiler {
43 namespace objectivec {
44 
48  // Track the names for the enum values, and if an alias overlaps a base
49  // value, skip making a name for it. Likewise if two alias overlap, the
50  // first one wins.
51  // The one gap in this logic is if two base values overlap, but for that
52  // to happen you have to have "Foo" and "FOO" or "FOO_BAR" and "FooBar",
53  // and if an enum has that, it is already going to be confusing and a
54  // compile error is just fine.
55  // The values are still tracked to support the reflection apis and
56  // TextFormat handing since they are different there.
57  std::set<std::string> value_names;
58 
59  for (int i = 0; i < descriptor_->value_count(); i++) {
61  const EnumValueDescriptor* canonical_value =
63 
64  if (value == canonical_value) {
65  base_values_.push_back(value);
66  value_names.insert(EnumValueName(value));
67  } else {
68  std::string value_name(EnumValueName(value));
69  if (value_names.find(value_name) != value_names.end()) {
71  } else {
72  value_names.insert(value_name);
73  }
74  }
75  all_values_.push_back(value);
76  }
77 }
78 
80 
82  std::string enum_comments;
83  SourceLocation location;
84  if (descriptor_->GetSourceLocation(&location)) {
85  enum_comments = BuildCommentsString(location, true);
86  } else {
87  enum_comments = "";
88  }
89 
90  printer->Print(
91  "#pragma mark - Enum $name$\n"
92  "\n",
93  "name", name_);
94 
95  // Swift 5 included SE0192 "Handling Future Enum Cases"
96  // https://github.com/apple/swift-evolution/blob/master/proposals/0192-non-exhaustive-enums.md
97  // Since a .proto file can get new values added to an enum at any time, they
98  // are effectively "non-frozen". Even in a proto3 syntax file where there is
99  // support for the unknown value, an edit to the file can always add a new
100  // value moving something from unknown to known. Since Swift is now ABI
101  // stable, it also means a binary could contain Swift compiled against one
102  // version of the .pbobjc.h file, but finally linked against an enum with
103  // more cases. So the Swift code will always have to treat ObjC Proto Enums
104  // as "non-frozen". The default behavior in SE0192 is for all objc enums to
105  // be "non-frozen" unless marked as otherwise, so this means this generation
106  // doesn't have to bother with the `enum_extensibility` attribute, as the
107  // default will be what is needed.
108 
109  printer->Print("$comments$typedef$deprecated_attribute$ GPB_ENUM($name$) {\n",
110  "comments", enum_comments,
111  "deprecated_attribute", GetOptionalDeprecatedAttribute(descriptor_, descriptor_->file()),
112  "name", name_);
113  printer->Indent();
114 
116  // Include the unknown value.
117  printer->Print(
118  "/**\n"
119  " * Value used if any message's field encounters a value that is not defined\n"
120  " * by this enum. The message will also have C functions to get/set the rawValue\n"
121  " * of the field.\n"
122  " **/\n"
123  "$name$_GPBUnrecognizedEnumeratorValue = kGPBUnrecognizedEnumeratorValue,\n",
124  "name", name_);
125  }
126  for (int i = 0; i < all_values_.size(); i++) {
128  continue;
129  }
130  if (all_values_[i]->GetSourceLocation(&location)) {
131  std::string comments = BuildCommentsString(location, true).c_str();
132  if (comments.length() > 0) {
133  if (i > 0) {
134  printer->Print("\n");
135  }
136  printer->Print(comments.c_str());
137  }
138  }
139 
140  printer->Print(
141  "$name$$deprecated_attribute$ = $value$,\n",
142  "name", EnumValueName(all_values_[i]),
143  "deprecated_attribute", GetOptionalDeprecatedAttribute(all_values_[i]),
144  "value", StrCat(all_values_[i]->number()));
145  }
146  printer->Outdent();
147  printer->Print(
148  "};\n"
149  "\n"
150  "GPBEnumDescriptor *$name$_EnumDescriptor(void);\n"
151  "\n"
152  "/**\n"
153  " * Checks to see if the given value is defined by the enum or was not known at\n"
154  " * the time this source was generated.\n"
155  " **/\n"
156  "BOOL $name$_IsValidValue(int32_t value);\n"
157  "\n",
158  "name", name_);
159 }
160 
162  printer->Print(
163  "#pragma mark - Enum $name$\n"
164  "\n",
165  "name", name_);
166 
167  // Note: For the TextFormat decode info, we can't use the enum value as
168  // the key because protocol buffer enums have 'allow_alias', which lets
169  // a value be used more than once. Instead, the index into the list of
170  // enum value descriptions is used. Note: start with -1 so the first one
171  // will be zero.
172  TextFormatDecodeData text_format_decode_data;
173  int enum_value_description_key = -1;
174  std::string text_blob;
175 
176  for (int i = 0; i < all_values_.size(); i++) {
177  ++enum_value_description_key;
179  text_blob += short_name + '\0';
180  if (UnCamelCaseEnumShortName(short_name) != all_values_[i]->name()) {
181  text_format_decode_data.AddString(enum_value_description_key, short_name,
182  all_values_[i]->name());
183  }
184  }
185 
186  printer->Print(
187  "GPBEnumDescriptor *$name$_EnumDescriptor(void) {\n"
188  " static _Atomic(GPBEnumDescriptor*) descriptor = nil;\n"
189  " if (!descriptor) {\n",
190  "name", name_);
191 
192  static const int kBytesPerLine = 40; // allow for escaping
193  printer->Print(
194  " static const char *valueNames =");
195  for (int i = 0; i < text_blob.size(); i += kBytesPerLine) {
196  printer->Print(
197  "\n \"$data$\"",
198  "data", EscapeTrigraphs(CEscape(text_blob.substr(i, kBytesPerLine))));
199  }
200  printer->Print(
201  ";\n"
202  " static const int32_t values[] = {\n");
203  for (int i = 0; i < all_values_.size(); i++) {
204  printer->Print(" $name$,\n", "name", EnumValueName(all_values_[i]));
205  }
206  printer->Print(" };\n");
207 
208  if (text_format_decode_data.num_entries() == 0) {
209  printer->Print(
210  " GPBEnumDescriptor *worker =\n"
211  " [GPBEnumDescriptor allocDescriptorForName:GPBNSStringifySymbol($name$)\n"
212  " valueNames:valueNames\n"
213  " values:values\n"
214  " count:(uint32_t)(sizeof(values) / sizeof(int32_t))\n"
215  " enumVerifier:$name$_IsValidValue];\n",
216  "name", name_);
217  } else {
218  printer->Print(
219  " static const char *extraTextFormatInfo = \"$extraTextFormatInfo$\";\n"
220  " GPBEnumDescriptor *worker =\n"
221  " [GPBEnumDescriptor allocDescriptorForName:GPBNSStringifySymbol($name$)\n"
222  " valueNames:valueNames\n"
223  " values:values\n"
224  " count:(uint32_t)(sizeof(values) / sizeof(int32_t))\n"
225  " enumVerifier:$name$_IsValidValue\n"
226  " extraTextFormatInfo:extraTextFormatInfo];\n",
227  "name", name_,
228  "extraTextFormatInfo", CEscape(text_format_decode_data.Data()));
229  }
230  printer->Print(
231  " GPBEnumDescriptor *expected = nil;\n"
232  " if (!atomic_compare_exchange_strong(&descriptor, &expected, worker)) {\n"
233  " [worker release];\n"
234  " }\n"
235  " }\n"
236  " return descriptor;\n"
237  "}\n\n");
238 
239  printer->Print(
240  "BOOL $name$_IsValidValue(int32_t value__) {\n"
241  " switch (value__) {\n",
242  "name", name_);
243 
244  for (int i = 0; i < base_values_.size(); i++) {
245  printer->Print(
246  " case $name$:\n",
247  "name", EnumValueName(base_values_[i]));
248  }
249 
250  printer->Print(
251  " return YES;\n"
252  " default:\n"
253  " return NO;\n"
254  " }\n"
255  "}\n\n");
256 }
257 } // namespace objectivec
258 } // namespace compiler
259 } // namespace protobuf
260 } // namespace google
google::protobuf::compiler::objectivec::EnumGenerator::alias_values_to_skip_
std::set< const EnumValueDescriptor * > alias_values_to_skip_
Definition: bloaty/third_party/protobuf/src/google/protobuf/compiler/objectivec/objectivec_enum.h:62
descriptor_
string_view descriptor_
Definition: elf.cc:154
google::protobuf::value
const Descriptor::ReservedRange value
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.h:1954
google::protobuf::compiler::objectivec::HasPreservingUnknownEnumSemantics
bool HasPreservingUnknownEnumSemantics(const FileDescriptor *file)
Definition: bloaty/third_party/protobuf/src/google/protobuf/compiler/objectivec/objectivec_helpers.h:125
google::protobuf::compiler::objectivec::EnumGenerator::~EnumGenerator
~EnumGenerator()
Definition: bloaty/third_party/protobuf/src/google/protobuf/compiler/objectivec/objectivec_enum.cc:79
google::protobuf::EnumDescriptor::value_count
int value_count() const
google::protobuf::compiler::objectivec::EnumGenerator::name
const string & name() const
Definition: bloaty/third_party/protobuf/src/google/protobuf/compiler/objectivec/objectivec_enum.h:56
google::protobuf::compiler::objectivec::EnumGenerator::descriptor_
const EnumDescriptor * descriptor_
Definition: bloaty/third_party/protobuf/src/google/protobuf/compiler/objectivec/objectivec_enum.h:59
testing::internal::string
::std::string string
Definition: bloaty/third_party/protobuf/third_party/googletest/googletest/include/gtest/internal/gtest-port.h:881
google::protobuf::CEscape
string CEscape(const string &src)
Definition: bloaty/third_party/protobuf/src/google/protobuf/stubs/strutil.cc:615
grpc::protobuf::io::Printer
GRPC_CUSTOM_PRINTER Printer
Definition: src/compiler/config.h:54
google::protobuf
Definition: bloaty/third_party/protobuf/benchmarks/util/data_proto2_to_proto3_util.h:12
google::protobuf::compiler::objectivec::EnumValueName
string EnumValueName(const EnumValueDescriptor *descriptor)
Definition: bloaty/third_party/protobuf/src/google/protobuf/compiler/objectivec/objectivec_helpers.cc:486
name_
const std::string name_
Definition: priority.cc:233
google::protobuf::StrCat
string StrCat(const AlphaNum &a, const AlphaNum &b)
Definition: bloaty/third_party/protobuf/src/google/protobuf/stubs/strutil.cc:1482
google::protobuf::compiler::objectivec::EnumValueShortName
string EnumValueShortName(const EnumValueDescriptor *descriptor)
Definition: bloaty/third_party/protobuf/src/google/protobuf/compiler/objectivec/objectivec_helpers.cc:501
google::protobuf::EnumDescriptor::FindValueByNumber
const EnumValueDescriptor * FindValueByNumber(int number) const
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:1694
google::protobuf::compiler::objectivec::GetOptionalDeprecatedAttribute
string GetOptionalDeprecatedAttribute(const TDescriptor *descriptor, const FileDescriptor *file=NULL, bool preSpace=true, bool postNewline=false)
Definition: bloaty/third_party/protobuf/src/google/protobuf/compiler/objectivec/objectivec_helpers.h:158
google::protobuf::EnumDescriptor::file
const FileDescriptor * file() const
google::protobuf::EnumDescriptor::value
const EnumValueDescriptor * value(int index) const
google::protobuf::compiler::objectivec::EnumGenerator::name_
const string name_
Definition: bloaty/third_party/protobuf/src/google/protobuf/compiler/objectivec/objectivec_enum.h:63
number
int32_t number
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/protobuf.h:850
google::protobuf::compiler::objectivec::EnumGenerator::GenerateSource
void GenerateSource(io::Printer *printer)
Definition: bloaty/third_party/protobuf/src/google/protobuf/compiler/objectivec/objectivec_enum.cc:162
EnumValueDescriptor
Definition: protobuf/php/ext/google/protobuf/def.c:63
EnumDescriptor
Definition: bloaty/third_party/protobuf/ruby/ext/google/protobuf_c/protobuf.h:143
google::protobuf::compiler::objectivec::UnCamelCaseEnumShortName
string UnCamelCaseEnumShortName(const string &name)
Definition: bloaty/third_party/protobuf/src/google/protobuf/compiler/objectivec/objectivec_helpers.cc:520
google::protobuf::compiler::objectivec::EnumGenerator::GenerateHeader
void GenerateHeader(io::Printer *printer)
Definition: bloaty/third_party/protobuf/src/google/protobuf/compiler/objectivec/objectivec_enum.cc:81
grpc::protobuf::SourceLocation
GRPC_CUSTOM_SOURCELOCATION SourceLocation
Definition: include/grpcpp/impl/codegen/config_protobuf.h:90
google::protobuf::compiler::objectivec::EnumGenerator::base_values_
std::vector< const EnumValueDescriptor * > base_values_
Definition: bloaty/third_party/protobuf/src/google/protobuf/compiler/objectivec/objectivec_enum.h:60
google::protobuf::compiler::objectivec::EnumName
string EnumName(const EnumDescriptor *descriptor)
Definition: bloaty/third_party/protobuf/src/google/protobuf/compiler/objectivec/objectivec_helpers.cc:472
google::protobuf::EnumDescriptor::GetSourceLocation
bool GetSourceLocation(SourceLocation *out_location) const
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:2990
google::protobuf::compiler::objectivec::EnumGenerator::EnumGenerator
EnumGenerator(const EnumDescriptor *descriptor)
Definition: bloaty/third_party/protobuf/src/google/protobuf/compiler/objectivec/objectivec_enum.cc:45
google::protobuf::compiler::objectivec::EscapeTrigraphs
string EscapeTrigraphs(const string &to_escape)
Definition: bloaty/third_party/protobuf/src/google/protobuf/compiler/objectivec/objectivec_helpers.cc:355
descriptor
static const char descriptor[1336]
Definition: certs.upbdefs.c:16
compiler
Definition: bloaty/third_party/protobuf/src/google/protobuf/compiler/plugin.pb.cc:21
google
Definition: bloaty/third_party/protobuf/benchmarks/util/data_proto2_to_proto3_util.h:11
i
uint64_t i
Definition: abseil-cpp/absl/container/btree_benchmark.cc:230
google::protobuf::compiler::objectivec::BuildCommentsString
string BuildCommentsString(const SourceLocation &location, bool prefer_single_line)
Definition: bloaty/third_party/protobuf/src/google/protobuf/compiler/objectivec/objectivec_helpers.cc:928
google::protobuf::compiler::objectivec::EnumGenerator::all_values_
std::vector< const EnumValueDescriptor * > all_values_
Definition: bloaty/third_party/protobuf/src/google/protobuf/compiler/objectivec/objectivec_enum.h:61


grpc
Author(s):
autogenerated on Fri May 16 2025 02:59:34