PageRenderTime 45ms CodeModel.GetById 27ms app.highlight 13ms RepoModel.GetById 1ms app.codeStats 0ms

/thirdparty/breakpad/third_party/protobuf/protobuf/src/google/protobuf/compiler/cpp/cpp_enum.cc

http://github.com/tomahawk-player/tomahawk
C++ | 258 lines | 183 code | 35 blank | 40 comment | 21 complexity | 532687fbee947fc523f602ac8265ba47 MD5 | raw file
  1// Protocol Buffers - Google's data interchange format
  2// Copyright 2008 Google Inc.  All rights reserved.
  3// http://code.google.com/p/protobuf/
  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// Author: kenton@google.com (Kenton Varda)
 32//  Based on original Protocol Buffers design by
 33//  Sanjay Ghemawat, Jeff Dean, and others.
 34
 35#include <set>
 36#include <map>
 37
 38#include <google/protobuf/compiler/cpp/cpp_enum.h>
 39#include <google/protobuf/compiler/cpp/cpp_helpers.h>
 40#include <google/protobuf/io/printer.h>
 41#include <google/protobuf/stubs/strutil.h>
 42
 43namespace google {
 44namespace protobuf {
 45namespace compiler {
 46namespace cpp {
 47
 48EnumGenerator::EnumGenerator(const EnumDescriptor* descriptor,
 49                             const string& dllexport_decl)
 50  : descriptor_(descriptor),
 51    classname_(ClassName(descriptor, false)),
 52    dllexport_decl_(dllexport_decl) {
 53}
 54
 55EnumGenerator::~EnumGenerator() {}
 56
 57void EnumGenerator::GenerateDefinition(io::Printer* printer) {
 58  map<string, string> vars;
 59  vars["classname"] = classname_;
 60  vars["short_name"] = descriptor_->name();
 61
 62  printer->Print(vars, "enum $classname$ {\n");
 63  printer->Indent();
 64
 65  const EnumValueDescriptor* min_value = descriptor_->value(0);
 66  const EnumValueDescriptor* max_value = descriptor_->value(0);
 67
 68  for (int i = 0; i < descriptor_->value_count(); i++) {
 69    vars["name"] = descriptor_->value(i)->name();
 70    vars["number"] = SimpleItoa(descriptor_->value(i)->number());
 71    vars["prefix"] = (descriptor_->containing_type() == NULL) ?
 72      "" : classname_ + "_";
 73
 74    if (i > 0) printer->Print(",\n");
 75    printer->Print(vars, "$prefix$$name$ = $number$");
 76
 77    if (descriptor_->value(i)->number() < min_value->number()) {
 78      min_value = descriptor_->value(i);
 79    }
 80    if (descriptor_->value(i)->number() > max_value->number()) {
 81      max_value = descriptor_->value(i);
 82    }
 83  }
 84
 85  printer->Outdent();
 86  printer->Print("\n};\n");
 87
 88  vars["min_name"] = min_value->name();
 89  vars["max_name"] = max_value->name();
 90
 91  if (dllexport_decl_.empty()) {
 92    vars["dllexport"] = "";
 93  } else {
 94    vars["dllexport"] = dllexport_decl_ + " ";
 95  }
 96
 97  printer->Print(vars,
 98    "$dllexport$bool $classname$_IsValid(int value);\n"
 99    "const $classname$ $prefix$$short_name$_MIN = $prefix$$min_name$;\n"
100    "const $classname$ $prefix$$short_name$_MAX = $prefix$$max_name$;\n"
101    "const int $prefix$$short_name$_ARRAYSIZE = $prefix$$short_name$_MAX + 1;\n"
102    "\n");
103
104  if (HasDescriptorMethods(descriptor_->file())) {
105    printer->Print(vars,
106      "$dllexport$const ::google::protobuf::EnumDescriptor* $classname$_descriptor();\n");
107    // The _Name and _Parse methods
108    printer->Print(vars,
109      "inline const ::std::string& $classname$_Name($classname$ value) {\n"
110      "  return ::google::protobuf::internal::NameOfEnum(\n"
111      "    $classname$_descriptor(), value);\n"
112      "}\n");
113    printer->Print(vars,
114      "inline bool $classname$_Parse(\n"
115      "    const ::std::string& name, $classname$* value) {\n"
116      "  return ::google::protobuf::internal::ParseNamedEnum<$classname$>(\n"
117      "    $classname$_descriptor(), name, value);\n"
118      "}\n");
119  }
120}
121
122void EnumGenerator::
123GenerateGetEnumDescriptorSpecializations(io::Printer* printer) {
124  if (HasDescriptorMethods(descriptor_->file())) {
125    printer->Print(
126      "template <>\n"
127      "inline const EnumDescriptor* GetEnumDescriptor< $classname$>() {\n"
128      "  return $classname$_descriptor();\n"
129      "}\n",
130      "classname", ClassName(descriptor_, true));
131  }
132}
133
134void EnumGenerator::GenerateSymbolImports(io::Printer* printer) {
135  map<string, string> vars;
136  vars["nested_name"] = descriptor_->name();
137  vars["classname"] = classname_;
138  printer->Print(vars, "typedef $classname$ $nested_name$;\n");
139
140  for (int j = 0; j < descriptor_->value_count(); j++) {
141    vars["tag"] = descriptor_->value(j)->name();
142    printer->Print(vars,
143      "static const $nested_name$ $tag$ = $classname$_$tag$;\n");
144  }
145
146  printer->Print(vars,
147    "static inline bool $nested_name$_IsValid(int value) {\n"
148    "  return $classname$_IsValid(value);\n"
149    "}\n"
150    "static const $nested_name$ $nested_name$_MIN =\n"
151    "  $classname$_$nested_name$_MIN;\n"
152    "static const $nested_name$ $nested_name$_MAX =\n"
153    "  $classname$_$nested_name$_MAX;\n"
154    "static const int $nested_name$_ARRAYSIZE =\n"
155    "  $classname$_$nested_name$_ARRAYSIZE;\n");
156
157  if (HasDescriptorMethods(descriptor_->file())) {
158    printer->Print(vars,
159      "static inline const ::google::protobuf::EnumDescriptor*\n"
160      "$nested_name$_descriptor() {\n"
161      "  return $classname$_descriptor();\n"
162      "}\n");
163    printer->Print(vars,
164      "static inline const ::std::string& $nested_name$_Name($nested_name$ value) {\n"
165      "  return $classname$_Name(value);\n"
166      "}\n");
167    printer->Print(vars,
168      "static inline bool $nested_name$_Parse(const ::std::string& name,\n"
169      "    $nested_name$* value) {\n"
170      "  return $classname$_Parse(name, value);\n"
171      "}\n");
172  }
173}
174
175void EnumGenerator::GenerateDescriptorInitializer(
176    io::Printer* printer, int index) {
177  map<string, string> vars;
178  vars["classname"] = classname_;
179  vars["index"] = SimpleItoa(index);
180
181  if (descriptor_->containing_type() == NULL) {
182    printer->Print(vars,
183      "$classname$_descriptor_ = file->enum_type($index$);\n");
184  } else {
185    vars["parent"] = ClassName(descriptor_->containing_type(), false);
186    printer->Print(vars,
187      "$classname$_descriptor_ = $parent$_descriptor_->enum_type($index$);\n");
188  }
189}
190
191void EnumGenerator::GenerateMethods(io::Printer* printer) {
192  map<string, string> vars;
193  vars["classname"] = classname_;
194
195  if (HasDescriptorMethods(descriptor_->file())) {
196    printer->Print(vars,
197      "const ::google::protobuf::EnumDescriptor* $classname$_descriptor() {\n"
198      "  protobuf_AssignDescriptorsOnce();\n"
199      "  return $classname$_descriptor_;\n"
200      "}\n");
201  }
202
203  printer->Print(vars,
204    "bool $classname$_IsValid(int value) {\n"
205    "  switch(value) {\n");
206
207  // Multiple values may have the same number.  Make sure we only cover
208  // each number once by first constructing a set containing all valid
209  // numbers, then printing a case statement for each element.
210
211  set<int> numbers;
212  for (int j = 0; j < descriptor_->value_count(); j++) {
213    const EnumValueDescriptor* value = descriptor_->value(j);
214    numbers.insert(value->number());
215  }
216
217  for (set<int>::iterator iter = numbers.begin();
218       iter != numbers.end(); ++iter) {
219    printer->Print(
220      "    case $number$:\n",
221      "number", SimpleItoa(*iter));
222  }
223
224  printer->Print(vars,
225    "      return true;\n"
226    "    default:\n"
227    "      return false;\n"
228    "  }\n"
229    "}\n"
230    "\n");
231
232  if (descriptor_->containing_type() != NULL) {
233    // We need to "define" the static constants which were declared in the
234    // header, to give the linker a place to put them.  Or at least the C++
235    // standard says we have to.  MSVC actually insists tha we do _not_ define
236    // them again in the .cc file.
237    printer->Print("#ifndef _MSC_VER\n");
238
239    vars["parent"] = ClassName(descriptor_->containing_type(), false);
240    vars["nested_name"] = descriptor_->name();
241    for (int i = 0; i < descriptor_->value_count(); i++) {
242      vars["value"] = descriptor_->value(i)->name();
243      printer->Print(vars,
244        "const $classname$ $parent$::$value$;\n");
245    }
246    printer->Print(vars,
247      "const $classname$ $parent$::$nested_name$_MIN;\n"
248      "const $classname$ $parent$::$nested_name$_MAX;\n"
249      "const int $parent$::$nested_name$_ARRAYSIZE;\n");
250
251    printer->Print("#endif  // _MSC_VER\n");
252  }
253}
254
255}  // namespace cpp
256}  // namespace compiler
257}  // namespace protobuf
258}  // namespace google