PageRenderTime 53ms CodeModel.GetById 20ms app.highlight 27ms RepoModel.GetById 1ms app.codeStats 0ms

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

http://github.com/tomahawk-player/tomahawk
C++ | 210 lines | 142 code | 22 blank | 46 comment | 12 complexity | 76cd8ff04f3b2c9f2b26e80bb73b0db1 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 <google/protobuf/compiler/cpp/cpp_extension.h>
 36#include <map>
 37#include <google/protobuf/compiler/cpp/cpp_helpers.h>
 38#include <google/protobuf/stubs/strutil.h>
 39#include <google/protobuf/io/printer.h>
 40#include <google/protobuf/descriptor.pb.h>
 41
 42namespace google {
 43namespace protobuf {
 44namespace compiler {
 45namespace cpp {
 46
 47namespace {
 48
 49// Returns the fully-qualified class name of the message that this field
 50// extends. This function is used in the Google-internal code to handle some
 51// legacy cases.
 52string ExtendeeClassName(const FieldDescriptor* descriptor) {
 53  const Descriptor* extendee = descriptor->containing_type();
 54  return ClassName(extendee, true);
 55}
 56
 57}  // anonymous namespace
 58
 59ExtensionGenerator::ExtensionGenerator(const FieldDescriptor* descriptor,
 60                                       const string& dllexport_decl)
 61  : descriptor_(descriptor),
 62    dllexport_decl_(dllexport_decl) {
 63  // Construct type_traits_.
 64  if (descriptor_->is_repeated()) {
 65    type_traits_ = "Repeated";
 66  }
 67
 68  switch (descriptor_->cpp_type()) {
 69    case FieldDescriptor::CPPTYPE_ENUM:
 70      type_traits_.append("EnumTypeTraits< ");
 71      type_traits_.append(ClassName(descriptor_->enum_type(), true));
 72      type_traits_.append(", ");
 73      type_traits_.append(ClassName(descriptor_->enum_type(), true));
 74      type_traits_.append("_IsValid>");
 75      break;
 76    case FieldDescriptor::CPPTYPE_STRING:
 77      type_traits_.append("StringTypeTraits");
 78      break;
 79    case FieldDescriptor::CPPTYPE_MESSAGE:
 80      type_traits_.append("MessageTypeTraits< ");
 81      type_traits_.append(ClassName(descriptor_->message_type(), true));
 82      type_traits_.append(" >");
 83      break;
 84    default:
 85      type_traits_.append("PrimitiveTypeTraits< ");
 86      type_traits_.append(PrimitiveTypeName(descriptor_->cpp_type()));
 87      type_traits_.append(" >");
 88      break;
 89  }
 90}
 91
 92ExtensionGenerator::~ExtensionGenerator() {}
 93
 94void ExtensionGenerator::GenerateDeclaration(io::Printer* printer) {
 95  map<string, string> vars;
 96  vars["extendee"     ] = ExtendeeClassName(descriptor_);
 97  vars["number"       ] = SimpleItoa(descriptor_->number());
 98  vars["type_traits"  ] = type_traits_;
 99  vars["name"         ] = descriptor_->name();
100  vars["field_type"   ] = SimpleItoa(static_cast<int>(descriptor_->type()));
101  vars["packed"       ] = descriptor_->options().packed() ? "true" : "false";
102  vars["constant_name"] = FieldConstantName(descriptor_);
103
104  // If this is a class member, it needs to be declared "static".  Otherwise,
105  // it needs to be "extern".  In the latter case, it also needs the DLL
106  // export/import specifier.
107  if (descriptor_->extension_scope() == NULL) {
108    vars["qualifier"] = "extern";
109    if (!dllexport_decl_.empty()) {
110      vars["qualifier"] = dllexport_decl_ + " " + vars["qualifier"];
111    }
112  } else {
113    vars["qualifier"] = "static";
114  }
115
116  printer->Print(vars,
117    "static const int $constant_name$ = $number$;\n"
118    "$qualifier$ ::google::protobuf::internal::ExtensionIdentifier< $extendee$,\n"
119    "    ::google::protobuf::internal::$type_traits$, $field_type$, $packed$ >\n"
120    "  $name$;\n"
121    );
122
123}
124
125void ExtensionGenerator::GenerateDefinition(io::Printer* printer) {
126  // If this is a class member, it needs to be declared in its class scope.
127  string scope = (descriptor_->extension_scope() == NULL) ? "" :
128    ClassName(descriptor_->extension_scope(), false) + "::";
129  string name = scope + descriptor_->name();
130
131  map<string, string> vars;
132  vars["extendee"     ] = ExtendeeClassName(descriptor_);
133  vars["type_traits"  ] = type_traits_;
134  vars["name"         ] = name;
135  vars["constant_name"] = FieldConstantName(descriptor_);
136  vars["default"      ] = DefaultValue(descriptor_);
137  vars["field_type"   ] = SimpleItoa(static_cast<int>(descriptor_->type()));
138  vars["packed"       ] = descriptor_->options().packed() ? "true" : "false";
139  vars["scope"        ] = scope;
140
141  if (descriptor_->cpp_type() == FieldDescriptor::CPPTYPE_STRING) {
142    // We need to declare a global string which will contain the default value.
143    // We cannot declare it at class scope because that would require exposing
144    // it in the header which would be annoying for other reasons.  So we
145    // replace :: with _ in the name and declare it as a global.
146    string global_name = StringReplace(name, "::", "_", true);
147    vars["global_name"] = global_name;
148    printer->Print(vars,
149      "const ::std::string $global_name$_default($default$);\n");
150
151    // Update the default to refer to the string global.
152    vars["default"] = global_name + "_default";
153  }
154
155  // Likewise, class members need to declare the field constant variable.
156  if (descriptor_->extension_scope() != NULL) {
157    printer->Print(vars,
158      "#ifndef _MSC_VER\n"
159      "const int $scope$$constant_name$;\n"
160      "#endif\n");
161  }
162
163  printer->Print(vars,
164    "::google::protobuf::internal::ExtensionIdentifier< $extendee$,\n"
165    "    ::google::protobuf::internal::$type_traits$, $field_type$, $packed$ >\n"
166    "  $name$($constant_name$, $default$);\n");
167}
168
169void ExtensionGenerator::GenerateRegistration(io::Printer* printer) {
170  map<string, string> vars;
171  vars["extendee"   ] = ExtendeeClassName(descriptor_);
172  vars["number"     ] = SimpleItoa(descriptor_->number());
173  vars["field_type" ] = SimpleItoa(static_cast<int>(descriptor_->type()));
174  vars["is_repeated"] = descriptor_->is_repeated() ? "true" : "false";
175  vars["is_packed"  ] = (descriptor_->is_repeated() &&
176                         descriptor_->options().packed())
177                        ? "true" : "false";
178
179  switch (descriptor_->cpp_type()) {
180    case FieldDescriptor::CPPTYPE_ENUM:
181      printer->Print(vars,
182        "::google::protobuf::internal::ExtensionSet::RegisterEnumExtension(\n"
183        "  &$extendee$::default_instance(),\n"
184        "  $number$, $field_type$, $is_repeated$, $is_packed$,\n");
185      printer->Print(
186        "  &$type$_IsValid);\n",
187        "type", ClassName(descriptor_->enum_type(), true));
188      break;
189    case FieldDescriptor::CPPTYPE_MESSAGE:
190      printer->Print(vars,
191        "::google::protobuf::internal::ExtensionSet::RegisterMessageExtension(\n"
192        "  &$extendee$::default_instance(),\n"
193        "  $number$, $field_type$, $is_repeated$, $is_packed$,\n");
194      printer->Print(
195        "  &$type$::default_instance());\n",
196        "type", ClassName(descriptor_->message_type(), true));
197      break;
198    default:
199      printer->Print(vars,
200        "::google::protobuf::internal::ExtensionSet::RegisterExtension(\n"
201        "  &$extendee$::default_instance(),\n"
202        "  $number$, $field_type$, $is_repeated$, $is_packed$);\n");
203      break;
204  }
205}
206
207}  // namespace cpp
208}  // namespace compiler
209}  // namespace protobuf
210}  // namespace google