1 // Protocol Buffers - Google's data interchange format
2 // Copyright 2008 Google Inc.
3 // http://code.google.com/p/protobuf/
5 // Licensed under the Apache License, Version 2.0 (the "License");
6 // you may not use this file except in compliance with the License.
7 // You may obtain a copy of the License at
9 // http://www.apache.org/licenses/LICENSE-2.0
11 // Unless required by applicable law or agreed to in writing, software
12 // distributed under the License is distributed on an "AS IS" BASIS,
13 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 // See the License for the specific language governing permissions and
15 // limitations under the License.
17 // Author: kenton@google.com (Kenton Varda)
18 // Based on original Protocol Buffers design by
19 // Sanjay Ghemawat, Jeff Dean, and others.
24 #include <google/protobuf/compiler/cpp/cpp_enum.h>
25 #include <google/protobuf/compiler/cpp/cpp_helpers.h>
26 #include <google/protobuf/io/printer.h>
27 #include <google/protobuf/stubs/strutil.h>
34 EnumGenerator::EnumGenerator(const EnumDescriptor
* descriptor
,
35 const string
& dllexport_decl
)
36 : descriptor_(descriptor
),
37 classname_(ClassName(descriptor
, false)),
38 dllexport_decl_(dllexport_decl
) {
41 EnumGenerator::~EnumGenerator() {}
43 void EnumGenerator::GenerateDefinition(io::Printer
* printer
) {
44 map
<string
, string
> vars
;
45 vars
["classname"] = classname_
;
46 vars
["short_name"] = descriptor_
->name();
48 printer
->Print(vars
, "enum $classname$ {\n");
51 const EnumValueDescriptor
* min_value
= descriptor_
->value(0);
52 const EnumValueDescriptor
* max_value
= descriptor_
->value(0);
54 for (int i
= 0; i
< descriptor_
->value_count(); i
++) {
55 vars
["name"] = descriptor_
->value(i
)->name();
56 vars
["number"] = SimpleItoa(descriptor_
->value(i
)->number());
57 vars
["prefix"] = (descriptor_
->containing_type() == NULL
) ?
58 "" : classname_
+ "_";
60 printer
->Print(vars
, "$prefix$$name$ = $number$,\n");
62 if (descriptor_
->value(i
)->number() < min_value
->number()) {
63 min_value
= descriptor_
->value(i
);
65 if (descriptor_
->value(i
)->number() > max_value
->number()) {
66 max_value
= descriptor_
->value(i
);
71 printer
->Print("};\n");
73 vars
["min_name"] = min_value
->name();
74 vars
["max_name"] = max_value
->name();
76 if (dllexport_decl_
.empty()) {
77 vars
["dllexport"] = "";
79 vars
["dllexport"] = dllexport_decl_
+ " ";
83 "$dllexport$const ::google::protobuf::EnumDescriptor* $classname$_descriptor();\n"
84 "$dllexport$bool $classname$_IsValid(int value);\n"
85 "const $classname$ $prefix$$short_name$_MIN = $prefix$$min_name$;\n"
86 "const $classname$ $prefix$$short_name$_MAX = $prefix$$max_name$;\n"
90 void EnumGenerator::GenerateSymbolImports(io::Printer
* printer
) {
91 map
<string
, string
> vars
;
92 vars
["nested_name"] = descriptor_
->name();
93 vars
["classname"] = classname_
;
94 printer
->Print(vars
, "typedef $classname$ $nested_name$;\n");
96 for (int j
= 0; j
< descriptor_
->value_count(); j
++) {
97 vars
["tag"] = descriptor_
->value(j
)->name();
99 "static const $nested_name$ $tag$ = $classname$_$tag$;\n");
103 "static inline const ::google::protobuf::EnumDescriptor*\n"
104 "$nested_name$_descriptor() {\n"
105 " return $classname$_descriptor();\n"
107 "static inline bool $nested_name$_IsValid(int value) {\n"
108 " return $classname$_IsValid(value);\n"
110 "static const $nested_name$ $nested_name$_MIN =\n"
111 " $classname$_$nested_name$_MIN;\n"
112 "static const $nested_name$ $nested_name$_MAX =\n"
113 " $classname$_$nested_name$_MAX;\n");
116 void EnumGenerator::GenerateDescriptorInitializer(
117 io::Printer
* printer
, int index
) {
118 map
<string
, string
> vars
;
119 vars
["classname"] = classname_
;
120 vars
["index"] = SimpleItoa(index
);
122 if (descriptor_
->containing_type() == NULL
) {
124 "$classname$_descriptor_ = file->enum_type($index$);\n");
126 vars
["parent"] = ClassName(descriptor_
->containing_type(), false);
128 "$classname$_descriptor_ = $parent$_descriptor_->enum_type($index$);\n");
132 void EnumGenerator::GenerateMethods(io::Printer
* printer
) {
133 map
<string
, string
> vars
;
134 vars
["classname"] = classname_
;
135 vars
["builddescriptorsname"] =
136 GlobalBuildDescriptorsName(descriptor_
->file()->name());
139 "const ::google::protobuf::EnumDescriptor* $classname$_descriptor() {\n"
140 " if ($classname$_descriptor_ == NULL) $builddescriptorsname$();\n"
141 " return $classname$_descriptor_;\n"
143 "bool $classname$_IsValid(int value) {\n"
144 " switch(value) {\n");
146 // Multiple values may have the same number. Make sure we only cover
147 // each number once by first constructing a set containing all valid
148 // numbers, then printing a case statement for each element.
151 for (int j
= 0; j
< descriptor_
->value_count(); j
++) {
152 const EnumValueDescriptor
* value
= descriptor_
->value(j
);
153 numbers
.insert(value
->number());
156 for (set
<int>::iterator iter
= numbers
.begin();
157 iter
!= numbers
.end(); ++iter
) {
160 "number", SimpleItoa(*iter
));
171 if (descriptor_
->containing_type() != NULL
) {
172 // We need to "define" the static constants which were declared in the
173 // header, to give the linker a place to put them. Or at least the C++
174 // standard says we have to. MSVC actually insists tha we do _not_ define
175 // them again in the .cc file.
176 printer
->Print("#ifndef _MSC_VER\n");
178 vars
["parent"] = ClassName(descriptor_
->containing_type(), false);
179 vars
["nested_name"] = descriptor_
->name();
180 for (int i
= 0; i
< descriptor_
->value_count(); i
++) {
181 vars
["value"] = descriptor_
->value(i
)->name();
183 "const $classname$ $parent$::$value$;\n");
186 "const $classname$ $parent$::$nested_name$_MIN;\n"
187 "const $classname$ $parent$::$nested_name$_MAX;\n");
189 printer
->Print("#endif // _MSC_VER\n");
194 } // namespace compiler
195 } // namespace protobuf
196 } // namespace google