1fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// Protocol Buffers - Google's data interchange format 2fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// Copyright 2008 Google Inc. All rights reserved. 3fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// http://code.google.com/p/protobuf/ 4fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// 5fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// Redistribution and use in source and binary forms, with or without 6fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// modification, are permitted provided that the following conditions are 7fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// met: 8fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// 9fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// * Redistributions of source code must retain the above copyright 10fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// notice, this list of conditions and the following disclaimer. 11fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// * Redistributions in binary form must reproduce the above 12fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// copyright notice, this list of conditions and the following disclaimer 13fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// in the documentation and/or other materials provided with the 14fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// distribution. 15fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// * Neither the name of Google Inc. nor the names of its 16fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// contributors may be used to endorse or promote products derived from 17fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// this software without specific prior written permission. 18fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// 19fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 20fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 21fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 22fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 23fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 24fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 25fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 26fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 27fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 28fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 31fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// Author: kenton@google.com (Kenton Varda) 32fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// Based on original Protocol Buffers design by 33fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// Sanjay Ghemawat, Jeff Dean, and others. 34fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 35fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#include <set> 36fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#include <map> 37fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 38fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#include <google/protobuf/compiler/cpp/cpp_enum.h> 39fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#include <google/protobuf/compiler/cpp/cpp_helpers.h> 40fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#include <google/protobuf/io/printer.h> 41fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#include <google/protobuf/stubs/strutil.h> 42fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 43fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillenamespace google { 44fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillenamespace protobuf { 45fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillenamespace compiler { 46fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillenamespace cpp { 47fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 48fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleEnumGenerator::EnumGenerator(const EnumDescriptor* descriptor, 49fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const string& dllexport_decl) 50fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville : descriptor_(descriptor), 51fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville classname_(ClassName(descriptor, false)), 52fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville dllexport_decl_(dllexport_decl) { 53fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 54fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 55fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleEnumGenerator::~EnumGenerator() {} 56fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 57fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillevoid EnumGenerator::GenerateDefinition(io::Printer* printer) { 58fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville map<string, string> vars; 59fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville vars["classname"] = classname_; 60fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville vars["short_name"] = descriptor_->name(); 61fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 62fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville printer->Print(vars, "enum $classname$ {\n"); 63fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville printer->Indent(); 64fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 65fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const EnumValueDescriptor* min_value = descriptor_->value(0); 66fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const EnumValueDescriptor* max_value = descriptor_->value(0); 67fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 68fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville for (int i = 0; i < descriptor_->value_count(); i++) { 69fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville vars["name"] = descriptor_->value(i)->name(); 70fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville vars["number"] = SimpleItoa(descriptor_->value(i)->number()); 71fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville vars["prefix"] = (descriptor_->containing_type() == NULL) ? 72fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "" : classname_ + "_"; 73fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 74fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (i > 0) printer->Print(",\n"); 75fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville printer->Print(vars, "$prefix$$name$ = $number$"); 76fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 77fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (descriptor_->value(i)->number() < min_value->number()) { 78fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville min_value = descriptor_->value(i); 79fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 80fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (descriptor_->value(i)->number() > max_value->number()) { 81fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville max_value = descriptor_->value(i); 82fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 83fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 84fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 85fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville printer->Outdent(); 86fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville printer->Print("\n};\n"); 87fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 88fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville vars["min_name"] = min_value->name(); 89fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville vars["max_name"] = max_value->name(); 90fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 91fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (dllexport_decl_.empty()) { 92fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville vars["dllexport"] = ""; 93fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } else { 94fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville vars["dllexport"] = dllexport_decl_ + " "; 95fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 96fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 97fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville printer->Print(vars, 98fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "$dllexport$bool $classname$_IsValid(int value);\n" 99fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "const $classname$ $prefix$$short_name$_MIN = $prefix$$min_name$;\n" 100fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "const $classname$ $prefix$$short_name$_MAX = $prefix$$max_name$;\n" 101d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville "const int $prefix$$short_name$_ARRAYSIZE = $prefix$$short_name$_MAX + 1;\n" 102fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "\n"); 103fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 104fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (HasDescriptorMethods(descriptor_->file())) { 105fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville printer->Print(vars, 106fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "$dllexport$const ::google::protobuf::EnumDescriptor* $classname$_descriptor();\n"); 107fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // The _Name and _Parse methods 108fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville printer->Print(vars, 109fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "inline const ::std::string& $classname$_Name($classname$ value) {\n" 110fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville " return ::google::protobuf::internal::NameOfEnum(\n" 111fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville " $classname$_descriptor(), value);\n" 112fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "}\n"); 113fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville printer->Print(vars, 114fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "inline bool $classname$_Parse(\n" 115fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville " const ::std::string& name, $classname$* value) {\n" 116fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville " return ::google::protobuf::internal::ParseNamedEnum<$classname$>(\n" 117fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville " $classname$_descriptor(), name, value);\n" 118fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "}\n"); 119fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 120fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 121fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 122fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillevoid EnumGenerator:: 123fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleGenerateGetEnumDescriptorSpecializations(io::Printer* printer) { 124fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (HasDescriptorMethods(descriptor_->file())) { 125fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville printer->Print( 126fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "template <>\n" 127fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "inline const EnumDescriptor* GetEnumDescriptor< $classname$>() {\n" 128fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville " return $classname$_descriptor();\n" 129fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "}\n", 130fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "classname", ClassName(descriptor_, true)); 131fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 132fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 133fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 134fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillevoid EnumGenerator::GenerateSymbolImports(io::Printer* printer) { 135fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville map<string, string> vars; 136fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville vars["nested_name"] = descriptor_->name(); 137fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville vars["classname"] = classname_; 138fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville printer->Print(vars, "typedef $classname$ $nested_name$;\n"); 139fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 140fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville for (int j = 0; j < descriptor_->value_count(); j++) { 141fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville vars["tag"] = descriptor_->value(j)->name(); 142fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville printer->Print(vars, 143fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "static const $nested_name$ $tag$ = $classname$_$tag$;\n"); 144fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 145fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 146fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville printer->Print(vars, 147fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "static inline bool $nested_name$_IsValid(int value) {\n" 148fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville " return $classname$_IsValid(value);\n" 149fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "}\n" 150fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "static const $nested_name$ $nested_name$_MIN =\n" 151fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville " $classname$_$nested_name$_MIN;\n" 152fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "static const $nested_name$ $nested_name$_MAX =\n" 153d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville " $classname$_$nested_name$_MAX;\n" 154d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville "static const int $nested_name$_ARRAYSIZE =\n" 155d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville " $classname$_$nested_name$_ARRAYSIZE;\n"); 156fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 157fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (HasDescriptorMethods(descriptor_->file())) { 158fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville printer->Print(vars, 159fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "static inline const ::google::protobuf::EnumDescriptor*\n" 160fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "$nested_name$_descriptor() {\n" 161fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville " return $classname$_descriptor();\n" 162d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville "}\n"); 163d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville printer->Print(vars, 164fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "static inline const ::std::string& $nested_name$_Name($nested_name$ value) {\n" 165fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville " return $classname$_Name(value);\n" 166d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville "}\n"); 167d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville printer->Print(vars, 168fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "static inline bool $nested_name$_Parse(const ::std::string& name,\n" 169fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville " $nested_name$* value) {\n" 170fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville " return $classname$_Parse(name, value);\n" 171fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "}\n"); 172fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 173fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 174fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 175fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillevoid EnumGenerator::GenerateDescriptorInitializer( 176fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville io::Printer* printer, int index) { 177fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville map<string, string> vars; 178fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville vars["classname"] = classname_; 179fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville vars["index"] = SimpleItoa(index); 180fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 181fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (descriptor_->containing_type() == NULL) { 182fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville printer->Print(vars, 183fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "$classname$_descriptor_ = file->enum_type($index$);\n"); 184fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } else { 185fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville vars["parent"] = ClassName(descriptor_->containing_type(), false); 186fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville printer->Print(vars, 187fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "$classname$_descriptor_ = $parent$_descriptor_->enum_type($index$);\n"); 188fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 189fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 190fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 191fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillevoid EnumGenerator::GenerateMethods(io::Printer* printer) { 192fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville map<string, string> vars; 193fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville vars["classname"] = classname_; 194fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 195fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (HasDescriptorMethods(descriptor_->file())) { 196fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville printer->Print(vars, 197fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "const ::google::protobuf::EnumDescriptor* $classname$_descriptor() {\n" 198fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville " protobuf_AssignDescriptorsOnce();\n" 199fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville " return $classname$_descriptor_;\n" 200fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "}\n"); 201fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 202fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 203fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville printer->Print(vars, 204fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "bool $classname$_IsValid(int value) {\n" 205fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville " switch(value) {\n"); 206fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 207fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Multiple values may have the same number. Make sure we only cover 208fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // each number once by first constructing a set containing all valid 209fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // numbers, then printing a case statement for each element. 210fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 211fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville set<int> numbers; 212fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville for (int j = 0; j < descriptor_->value_count(); j++) { 213fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const EnumValueDescriptor* value = descriptor_->value(j); 214fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville numbers.insert(value->number()); 215fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 216fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 217fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville for (set<int>::iterator iter = numbers.begin(); 218fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville iter != numbers.end(); ++iter) { 219fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville printer->Print( 220fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville " case $number$:\n", 221fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "number", SimpleItoa(*iter)); 222fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 223fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 224fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville printer->Print(vars, 225fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville " return true;\n" 226fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville " default:\n" 227fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville " return false;\n" 228fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville " }\n" 229fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "}\n" 230fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "\n"); 231fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 232fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (descriptor_->containing_type() != NULL) { 233fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // We need to "define" the static constants which were declared in the 234fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // header, to give the linker a place to put them. Or at least the C++ 235fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // standard says we have to. MSVC actually insists tha we do _not_ define 236fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // them again in the .cc file. 237fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville printer->Print("#ifndef _MSC_VER\n"); 238fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 239fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville vars["parent"] = ClassName(descriptor_->containing_type(), false); 240fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville vars["nested_name"] = descriptor_->name(); 241fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville for (int i = 0; i < descriptor_->value_count(); i++) { 242fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville vars["value"] = descriptor_->value(i)->name(); 243fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville printer->Print(vars, 244fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "const $classname$ $parent$::$value$;\n"); 245fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 246fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville printer->Print(vars, 247fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "const $classname$ $parent$::$nested_name$_MIN;\n" 248d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville "const $classname$ $parent$::$nested_name$_MAX;\n" 249d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville "const int $parent$::$nested_name$_ARRAYSIZE;\n"); 250fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 251fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville printer->Print("#endif // _MSC_VER\n"); 252fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 253fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 254fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 255fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} // namespace cpp 256fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} // namespace compiler 257fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} // namespace protobuf 258fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} // namespace google 259