You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@thrift.apache.org by ns...@apache.org on 2016/09/25 16:43:13 UTC

[24/55] [abbrv] [partial] thrift git commit: THRIFT-2835 Add possibility to distribute generators separately from thrift core, and load them dynamically

http://git-wip-us.apache.org/repos/asf/thrift/blob/052abc39/compiler/cpp/src/plugin/plugin.cc
----------------------------------------------------------------------
diff --git a/compiler/cpp/src/plugin/plugin.cc b/compiler/cpp/src/plugin/plugin.cc
deleted file mode 100644
index d969f50..0000000
--- a/compiler/cpp/src/plugin/plugin.cc
+++ /dev/null
@@ -1,503 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-#include "plugin/plugin.h"
-
-#ifdef _WIN32
-#include <fcntl.h>
-#include <io.h>
-#endif
-
-#include <cassert>
-#include <iostream>
-
-#include <boost/bind.hpp>
-#include <boost/range/adaptor/map.hpp>
-#include <boost/range/algorithm/for_each.hpp>
-#include <boost/smart_ptr.hpp>
-
-#include "generate/t_generator.h"
-#include "plugin/type_util.h"
-#include "thrift/protocol/TBinaryProtocol.h"
-#include "thrift/transport/TBufferTransports.h"
-#include "thrift/transport/TFDTransport.h"
-
-#include "plugin/plugin_types.h"
-
-namespace apache {
-namespace thrift {
-namespace plugin {
-
-using apache::thrift::protocol::TBinaryProtocol;
-using apache::thrift::transport::TFDTransport;
-using apache::thrift::transport::TFramedTransport;
-
-#define THRIFT_CONVERT_FORWARD(from_type)                                                          \
-  template <>                                                                                      \
-  typename ToType<from_type>::type* convert_forward<from_type>(const from_type& from)
-
-#define THRIFT_CONVERT_COMPLETE_DECL(from_type)                                                    \
-  template <>                                                                                      \
-  void convert(const from_type& from, ToType<from_type>::type* to)
-
-#define THRIFT_CONVERT_UNARY_DECL(from_type)                                                       \
-  template <>                                                                                      \
-  typename ToType<from_type>::type* convert<from_type>(const from_type& from)
-
-#define THRIFT_CONVERSION_DECL(from_type)                                                          \
-  THRIFT_CONVERT_FORWARD(from_type);                                                               \
-  THRIFT_CONVERT_COMPLETE_DECL(from_type);                                                         \
-  THRIFT_CONVERT_UNARY_DECL(from_type)
-
-#define THRIFT_CONVERT_COMPLETE(from_type)                                                         \
-  THRIFT_CONVERSION_DECL(from_type) {                                                              \
-    ToType<from_type>::type* to = convert_forward(from);                                           \
-    convert(from, to);                                                                             \
-    return to;                                                                                     \
-  }                                                                                                \
-  THRIFT_CONVERT_COMPLETE_DECL(from_type)
-
-#define THRIFT_CONVERSION(from_type, ...)                                                          \
-  THRIFT_CONVERT_FORWARD(from_type) {                                                              \
-    (void)from;                                                                                    \
-    return new ToType<from_type>::type(__VA_ARGS__);                                               \
-  }                                                                                                \
-  THRIFT_CONVERT_COMPLETE(from_type)
-
-#define THRIFT_ASSIGN_DOC()                                                                        \
-  do {                                                                                             \
-    if (from.__isset.doc)                                                                          \
-      to->set_doc(from.doc);                                                                       \
-  } while (0)
-
-#define THRIFT_ASSIGN_ANNOTATIONS()                                                                \
-  THRIFT_ASSIGN_DOC();                                                                             \
-  do {                                                                                             \
-    if (from.__isset.annotations)                                                                  \
-      to->annotations_ = from.annotations;                                                         \
-  } while (0)
-
-#define THRIFT_ASSIGN_METADATA()                                                                   \
-  do {                                                                                             \
-    to->set_name(from.metadata.name);                                                              \
-    if (from.metadata.__isset.doc)                                                                 \
-      to->set_doc(from.metadata.doc);                                                              \
-    if (from.metadata.__isset.annotations)                                                         \
-      to->annotations_ = from.metadata.annotations;                                                \
-  } while (0)
-
-::t_program* g_program = 0;
-
-template <typename C, typename S>
-struct TypeCache {
-  C* operator[](const int64_t& k) {
-    typename std::map<int64_t, C*>::iterator it = cache.find(k);
-    if (it != cache.end()) {
-      return it->second;
-    } else {
-      typename std::map<int64_t, S>::const_iterator cit = source->find(k);
-      if (cit == source->end()) {
-        throw ThriftPluginError("Type not found");
-      }
-      return (cache)[k] = convert_forward(cit->second);
-    }
-  }
-
-  void compileAll() {
-    boost::for_each(*source | boost::adaptors::map_keys,
-                    boost::bind(&TypeCache::compile, this, _1));
-  }
-
-  std::map<int64_t, S> const* source;
-
-protected:
-  std::map<int64_t, C*> cache;
-
-private:
-  void compile(const int64_t& k) {
-    typename std::map<int64_t, S>::const_iterator cit = source->find(k);
-    if (cit == source->end()) {
-      throw ThriftPluginError("Type not found ");
-    }
-    convert(cit->second, (*this)[k]);
-  }
-};
-std::map<int64_t, ::t_program*> g_program_cache;
-TypeCache< ::t_type, t_type> g_type_cache;
-TypeCache< ::t_const, t_const> g_const_cache;
-TypeCache< ::t_service, t_service> g_service_cache;
-
-void set_global_cache(const TypeRegistry& from) {
-  g_type_cache.source = &from.types;
-  g_const_cache.source = &from.constants;
-  g_service_cache.source = &from.services;
-
-  g_type_cache.compileAll();
-  g_const_cache.compileAll();
-  g_service_cache.compileAll();
-}
-
-template <typename T>
-T* resolve_type(int64_t name) {
-  return reinterpret_cast<T*>(g_type_cache[name]);
-}
-
-::t_const* resolve_const(int64_t name) {
-  return g_const_cache[name];
-}
-
-::t_service* resolve_service(int64_t name) {
-  return g_service_cache[name];
-}
-
-THRIFT_CONVERT_FORWARD(t_base_type) {
-#define T_BASETYPE_CASE(type)                                                                      \
-  case t_base::TYPE_##type:                                                                        \
-    t = ::t_base_type::TYPE_##type;                                                                \
-    break
-
-  ::t_base_type::t_base t = ::t_base_type::TYPE_VOID;
-  bool is_binary = false;
-  switch (from.value) {
-    T_BASETYPE_CASE(VOID);
-    T_BASETYPE_CASE(STRING);
-    T_BASETYPE_CASE(BOOL);
-    T_BASETYPE_CASE(I8);
-    T_BASETYPE_CASE(I16);
-    T_BASETYPE_CASE(I32);
-    T_BASETYPE_CASE(I64);
-    T_BASETYPE_CASE(DOUBLE);
-  case t_base::TYPE_BINARY:
-    t = ::t_base_type::TYPE_STRING;
-    is_binary = true;
-    break;
-  }
-  ::t_base_type* to = new ::t_base_type(from.metadata.name, t);
-  to->set_binary(is_binary);
-  return to;
-#undef T_BASETYPE_CASE
-}
-THRIFT_CONVERT_COMPLETE(t_base_type) {
-  THRIFT_ASSIGN_METADATA();
-}
-
-THRIFT_CONVERT_FORWARD(t_typedef) {
-  ::t_typedef* to;
-  if (from.forward) {
-    to = new ::t_typedef(g_program_cache[from.metadata.program_id], from.symbolic, true);
-  } else {
-    to = new ::t_typedef(g_program_cache[from.metadata.program_id],
-                         resolve_type< ::t_type>(from.type), from.symbolic);
-  }
-  return to;
-}
-THRIFT_CONVERT_COMPLETE(t_typedef) {
-  THRIFT_ASSIGN_METADATA();
-}
-THRIFT_CONVERSION(t_enum_value, from.name, from.value) {
-  assert(to);
-  THRIFT_ASSIGN_ANNOTATIONS();
-}
-THRIFT_CONVERSION(t_enum, g_program_cache[from.metadata.program_id]) {
-  assert(to);
-  THRIFT_ASSIGN_METADATA();
-  boost::for_each(from.constants | boost::adaptors::transformed(convert<t_enum_value>),
-                  boost::bind(&::t_enum::append, to, _1));
-}
-THRIFT_CONVERSION(t_list, resolve_type< ::t_type>(from.elem_type)) {
-  assert(to);
-  THRIFT_ASSIGN_METADATA();
-  if (from.__isset.cpp_name)
-    to->set_cpp_name(from.cpp_name);
-}
-THRIFT_CONVERSION(t_set, resolve_type< ::t_type>(from.elem_type)) {
-  assert(to);
-  THRIFT_ASSIGN_METADATA();
-  if (from.__isset.cpp_name)
-    to->set_cpp_name(from.cpp_name);
-}
-THRIFT_CONVERSION(t_map,
-                  resolve_type< ::t_type>(from.key_type),
-                  resolve_type< ::t_type>(from.val_type)) {
-  assert(to);
-  THRIFT_ASSIGN_METADATA();
-  if (from.__isset.cpp_name)
-    to->set_cpp_name(from.cpp_name);
-}
-THRIFT_CONVERSION(t_const_value, ) {
-#define T_CONST_VALUE_CASE(type)                                                                   \
-  if (from.__isset.type##_val)                                                                     \
-  to->set_##type(from.type##_val)
-
-  assert(to);
-  if (from.__isset.map_val) {
-    to->set_map();
-    for (std::map<t_const_value, t_const_value>::const_iterator it = from.map_val.begin();
-         it != from.map_val.end(); it++) {
-      to->add_map(convert(it->first), convert(it->second));
-    }
-  } else if (from.__isset.list_val) {
-    to->set_list();
-    boost::for_each(from.list_val | boost::adaptors::transformed(&convert<t_const_value>),
-                    boost::bind(&::t_const_value::add_list, to, _1));
-  } else
-    T_CONST_VALUE_CASE(string);
-  else T_CONST_VALUE_CASE(integer);
-  else T_CONST_VALUE_CASE(double);
-  else {
-    T_CONST_VALUE_CASE(identifier);
-    if (from.__isset.enum_val)
-      to->set_enum(resolve_type< ::t_enum>(from.enum_val));
-  }
-#undef T_CONST_VALUE_CASE
-}
-THRIFT_CONVERSION(t_field, resolve_type< ::t_type>(from.type), from.name, from.key) {
-  assert(to);
-  THRIFT_ASSIGN_ANNOTATIONS();
-  to->set_reference(from.reference);
-  to->set_req(static_cast< ::t_field::e_req>(from.req));
-  if (from.__isset.value) {
-    to->set_value(convert(from.value));
-  }
-}
-THRIFT_CONVERSION(t_struct, g_program_cache[from.metadata.program_id]) {
-  assert(to);
-  THRIFT_ASSIGN_METADATA();
-  to->set_union(from.is_union);
-  to->set_xception(from.is_xception);
-  boost::for_each(from.members | boost::adaptors::transformed(convert<t_field>),
-                  boost::bind(&::t_struct::append, to, _1));
-}
-THRIFT_CONVERSION(t_const,
-                  resolve_type< ::t_type>(from.type),
-                  from.name,
-                  convert<t_const_value>(from.value)) {
-  assert(to);
-  THRIFT_ASSIGN_DOC();
-}
-
-THRIFT_CONVERSION(t_function,
-                  resolve_type< ::t_type>(from.returntype),
-                  from.name,
-                  resolve_type< ::t_struct>(from.arglist),
-                  resolve_type< ::t_struct>(from.xceptions),
-                  from.is_oneway) {
-  assert(to);
-  THRIFT_ASSIGN_DOC();
-}
-
-THRIFT_CONVERSION(t_service, g_program_cache[from.metadata.program_id]) {
-  assert(to);
-  assert(from.metadata.program_id);
-  assert(g_program_cache[from.metadata.program_id]);
-  THRIFT_ASSIGN_METADATA();
-
-  boost::for_each(from.functions | boost::adaptors::transformed(convert<t_function>),
-                  boost::bind(&::t_service::add_function, to, _1));
-
-  if (from.__isset.extends_)
-    to->set_extends(resolve_service(from.extends_));
-}
-
-THRIFT_CONVERT_FORWARD(t_type) {
-#define T_TYPE_CASE_FW_T(case, type)                                                               \
-  if (from.__isset.case##_val)                                                                     \
-  return convert_forward<type>(from.case##_val)
-#define T_TYPE_CASE_FW(case) T_TYPE_CASE_FW_T(case, t_##case)
-
-  T_TYPE_CASE_FW(base_type);
-  T_TYPE_CASE_FW(typedef);
-  T_TYPE_CASE_FW(enum);
-  T_TYPE_CASE_FW(struct);
-  T_TYPE_CASE_FW_T(xception, t_struct);
-  T_TYPE_CASE_FW(list);
-  T_TYPE_CASE_FW(set);
-  T_TYPE_CASE_FW(map);
-  T_TYPE_CASE_FW(service);
-  throw ThriftPluginError("Invalid data: Type union has no value.");
-#undef T_TYPE_CASE_FW_T
-#undef T_TYPE_CASE_FW
-}
-THRIFT_CONVERT_COMPLETE(t_type) {
-#define T_TYPE_CASE_T(case, type)                                                                  \
-  else if (from.__isset.case##_val)                                                                \
-      convert<type, ::type>(from.case##_val, reinterpret_cast< ::type*>(to))
-#define T_TYPE_CASE(case) T_TYPE_CASE_T(case, t_##case)
-
-  if (false) {
-  }
-  T_TYPE_CASE(base_type);
-  T_TYPE_CASE(typedef);
-  T_TYPE_CASE(enum);
-  T_TYPE_CASE(struct);
-  T_TYPE_CASE_T(xception, t_struct);
-  T_TYPE_CASE(list);
-  T_TYPE_CASE(set);
-  T_TYPE_CASE(map);
-  T_TYPE_CASE(service);
-  else {
-    throw ThriftPluginError("Invalid data: Type union has no value.");
-  }
-#undef T_TYPE_CASE_T
-#undef T_TYPE_CASE
-}
-
-THRIFT_CONVERSION(t_scope, ) {
-  assert(to);
-#define T_SCOPE_RESOLVE(type, name, a)                                                             \
-  for (std::vector<int64_t>::const_iterator it = from.name##s.begin(); it != from.name##s.end();   \
-       it++) {                                                                                     \
-    ::t_##type* t = resolve_##type a(*it);                                                         \
-    to->add_##name(t->get_name(), t);                                                              \
-  }
-  T_SCOPE_RESOLVE(type, type, < ::t_type>);
-  T_SCOPE_RESOLVE(const, constant, );
-  T_SCOPE_RESOLVE(service, service, );
-#undef T_SCOPE_RESOLVE
-}
-
-THRIFT_CONVERT_FORWARD(t_program) {
-  ::t_program* to = new ::t_program(from.path, from.name);
-  for (std::vector<t_program>::const_iterator it = from.includes.begin(); it != from.includes.end();
-       it++) {
-    to->add_include(convert_forward(*it));
-  }
-  g_program_cache[from.program_id] = to;
-  return to;
-}
-THRIFT_CONVERT_COMPLETE(t_program) {
-  assert(to);
-  g_program = to;
-  convert<t_scope, ::t_scope>(from.scope, to->scope());
-  THRIFT_ASSIGN_DOC();
-
-  to->set_out_path(from.out_path, from.out_path_is_absolute);
-
-  boost::for_each(from.typedefs | boost::adaptors::transformed(&resolve_type< ::t_typedef>),
-                  boost::bind(&::t_program::add_typedef, to, _1));
-  boost::for_each(from.enums | boost::adaptors::transformed(&resolve_type< ::t_enum>),
-                  boost::bind(&::t_program::add_enum, to, _1));
-  for (std::vector<int64_t>::const_iterator it = from.objects.begin(); it != from.objects.end();
-       it++) {
-    ::t_struct* t2 = resolve_type< ::t_struct>(*it);
-    if (t2->is_xception()) {
-      to->add_xception(t2);
-    } else {
-      to->add_struct(t2);
-    }
-  }
-  boost::for_each(from.consts | boost::adaptors::transformed(&resolve_const),
-                  boost::bind(&::t_program::add_const, to, _1));
-  boost::for_each(from.services | boost::adaptors::transformed(&resolve_service),
-                  boost::bind(&::t_program::add_service, to, _1));
-
-  for (std::vector<t_program>::const_iterator it = from.includes.begin(); it != from.includes.end();
-       it++) {
-    convert(*it, g_program_cache[it->program_id]);
-  }
-  std::for_each(from.c_includes.begin(), from.c_includes.end(),
-                boost::bind(&::t_program::add_c_include, to, _1));
-  std::for_each(from.cpp_includes.begin(), from.cpp_includes.end(),
-                boost::bind(&::t_program::add_cpp_include, to, _1));
-  for (std::map<std::string, std::string>::const_iterator it = from.namespaces.begin();
-       it != from.namespaces.end(); it++) {
-    to->set_namespace(it->first, it->second);
-  }
-
-  to->set_include_prefix(from.include_prefix);
-  to->set_namespace(from.namespace_);
-}
-
-int GeneratorPlugin::exec(int, char* []) {
-#ifdef _WIN32
-  _setmode(fileno(stdin), _O_BINARY);
-#endif
-  boost::shared_ptr<TFramedTransport> transport(
-      new TFramedTransport(boost::make_shared<TFDTransport>(fileno(stdin))));
-  TBinaryProtocol proto(transport);
-  GeneratorInput input;
-  try {
-    input.read(&proto);
-  } catch (std::exception& err) {
-    std::cerr << "Error while receiving plugin data: " << err.what() << std::endl;
-    return -1;
-  }
-  initGlobals();
-  ::t_program* p = g_program = convert_forward(input.program);
-  set_global_cache(input.type_registry);
-  convert(input.program, p);
-
-  int ret = generate(p, input.parsed_options);
-  clearGlobals();
-
-  return ret;
-}
-
-::t_const_value::t_const_value_type const_value_case(const t_const_value& v) {
-  if (v.__isset.map_val)
-    return ::t_const_value::CV_MAP;
-  if (v.__isset.list_val)
-    return ::t_const_value::CV_LIST;
-  if (v.__isset.string_val)
-    return ::t_const_value::CV_STRING;
-  if (v.__isset.integer_val)
-    return ::t_const_value::CV_INTEGER;
-  if (v.__isset.double_val)
-    return ::t_const_value::CV_DOUBLE;
-  if (v.__isset.identifier_val)
-    return ::t_const_value::CV_IDENTIFIER;
-  if (v.__isset.enum_val)
-    return ::t_const_value::CV_IDENTIFIER;
-  throw ThriftPluginError("Unknown const value type");
-}
-
-bool t_const_value::operator<(const t_const_value& that) const {
-  ::t_const_value::t_const_value_type t1 = const_value_case(*this);
-  ::t_const_value::t_const_value_type t2 = const_value_case(that);
-  if (t1 != t2)
-    return t1 < t2;
-  switch (t1) {
-  case ::t_const_value::CV_INTEGER:
-    return integer_val < that.integer_val;
-  case ::t_const_value::CV_DOUBLE:
-    return double_val < that.double_val;
-  case ::t_const_value::CV_STRING:
-    return string_val < that.string_val;
-  case ::t_const_value::CV_MAP:
-    if (that.map_val.empty())
-      return false;
-    else if (map_val.empty())
-      return true;
-    else
-      return map_val.begin()->first < that.map_val.begin()->first;
-  case ::t_const_value::CV_LIST:
-    if (that.list_val.empty())
-      return false;
-    else if (list_val.empty())
-      return true;
-    else
-      return list_val.front() < that.list_val.front();
-  case ::t_const_value::CV_IDENTIFIER:
-    return integer_val < that.integer_val;
-  }
-  throw ThriftPluginError("Unknown const value type");
-}
-}
-}
-}

http://git-wip-us.apache.org/repos/asf/thrift/blob/052abc39/compiler/cpp/src/plugin/plugin.h
----------------------------------------------------------------------
diff --git a/compiler/cpp/src/plugin/plugin.h b/compiler/cpp/src/plugin/plugin.h
deleted file mode 100644
index 705cd41..0000000
--- a/compiler/cpp/src/plugin/plugin.h
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-#ifndef T_PLUGIN_PLUGIN_H
-#define T_PLUGIN_PLUGIN_H
-
-#include "thrift/Thrift.h"
-
-class t_program;
-
-namespace apache {
-namespace thrift {
-namespace plugin {
-
-struct ThriftPluginError : public apache::thrift::TException {
-  ThriftPluginError(const std::string& msg) : apache::thrift::TException(msg) {}
-};
-
-class GeneratorPlugin {
-public:
-  int exec(int argc, char* argv[]);
-  virtual int generate(::t_program*, const std::map<std::string, std::string>&) = 0;
-};
-}
-}
-}
-
-#endif

http://git-wip-us.apache.org/repos/asf/thrift/blob/052abc39/compiler/cpp/src/plugin/plugin.thrift
----------------------------------------------------------------------
diff --git a/compiler/cpp/src/plugin/plugin.thrift b/compiler/cpp/src/plugin/plugin.thrift
deleted file mode 100644
index a93873d..0000000
--- a/compiler/cpp/src/plugin/plugin.thrift
+++ /dev/null
@@ -1,202 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-namespace as3 org.apache.thrift.plugin
-namespace cpp apache.thrift.plugin
-namespace csharp Thrift.Plugin
-namespace d thrift.plugin
-namespace delphi Thrift.Plugin
-namespace erl thrift.plugin
-namespace go thrift
-namespace haxe org.apache.thrift.plugin
-namespace hs Thrift.Plugin
-namespace java org.apache.thrift.plugin
-namespace ocaml Thrift
-namespace perl Thrift.Plugin
-namespace php thrift.plugin
-namespace py thrift.plugin
-namespace rb Thrift
-
-typedef i64 t_program_id
-typedef i64 t_type_id
-typedef i64 t_const_id
-typedef i64 t_service_id
-
-enum t_base {
-    TYPE_VOID
-    TYPE_STRING
-    TYPE_BOOL
-    TYPE_I8
-    TYPE_I16
-    TYPE_I32
-    TYPE_I64
-    TYPE_DOUBLE
-    TYPE_BINARY
-}
-
-struct TypeMetadata {
-  1: required string name
-  2: required t_program_id program_id
-  99: optional map<string, string> annotations
-  100: optional string doc
-}
-
-struct t_base_type {
-  1: required TypeMetadata metadata
-  2: required t_base value
-}
-
-struct t_list {
-  1: required TypeMetadata metadata
-  2: optional string cpp_name
-  3: required t_type_id elem_type
-}
-
-struct t_set {
-  1: required TypeMetadata metadata
-  2: optional string cpp_name
-  3: required t_type_id elem_type
-}
-
-struct t_map {
-  1: required TypeMetadata metadata
-  2: optional string cpp_name
-  3: required t_type_id key_type
-  4: required t_type_id val_type
-}
-
-struct t_typedef {
-  1: required TypeMetadata metadata
-  2: required t_type_id type
-  3: required string symbolic
-  4: required bool forward
-}
-
-struct t_enum_value {
-  1: required string name
-  2: required i32 value
-  99: optional map<string, string> annotations
-  100: optional string doc
-}
-struct t_enum {
-  1: required TypeMetadata metadata
-  2: required list<t_enum_value> constants
-}
-
-enum Requiredness {
-  T_REQUIRED = 0
-  T_OPTIONAL = 1
-  T_OPT_IN_REQ_OUT = 2
-}
-
-union t_const_value {
-  1: optional map<t_const_value, t_const_value> map_val
-  2: optional list<t_const_value> list_val
-  3: optional string string_val
-  4: optional i64 integer_val
-  5: optional double double_val
-  6: optional string identifier_val
-  7: optional t_type_id enum_val
-}
-struct t_const {
-  1: required string name
-  2: required t_type_id type
-  3: required t_const_value value
-  100: optional string doc
-}
-struct t_struct {
-  1: required TypeMetadata metadata
-  2: required list<t_field> members
-  3: required bool is_union
-  4: required bool is_xception
-}
-struct t_field {
-  1: required string name
-  2: required t_type_id type
-  3: required i32 key
-  4: required Requiredness req
-  5: optional t_const_value value
-  10: required bool reference
-  99: optional map<string, string> annotations
-  100: optional string doc
-}
-struct t_function {
-  1: required string name
-  2: required t_type_id returntype
-  3: required t_type_id arglist
-  4: required t_type_id xceptions
-  5: required bool is_oneway
-  100: optional string doc
-}
-struct t_service {
-  1: required TypeMetadata metadata
-  2: required list<t_function> functions
-  3: optional t_service_id extends_
-}
-union t_type {
-  1: optional t_base_type base_type_val
-  2: optional t_typedef typedef_val
-  3: optional t_enum enum_val
-  4: optional t_struct struct_val
-  5: optional t_struct xception_val
-  6: optional t_list list_val
-  7: optional t_set set_val
-  8: optional t_map map_val
-  9: optional t_service service_val
-}
-struct t_scope {
-  1: required list<t_type_id> types
-  2: required list<t_const_id> constants
-  3: required list<t_service_id> services
-}
-
-struct TypeRegistry {
-  1: required map<t_type_id, t_type> types
-  2: required map<t_const_id, t_const> constants
-  3: required map<t_service_id, t_service> services
-}
-
-struct t_program {
-  1: required string name
-  2: required t_program_id program_id
-  3: required string path
-  4: required string namespace_
-  5: required string out_path
-  6: required bool out_path_is_absolute
-  8: required list<t_program> includes
-  9: required string include_prefix
-  10: required t_scope scope
-
-  11: required list<t_type_id> typedefs
-  12: required list<t_type_id> enums
-  13: required list<t_const_id> consts
-  14: required list<t_type_id> objects
-  15: required list<t_service_id> services
-
-  16: required map<string, string> namespaces
-  17: required list<string> cpp_includes
-  18: required list<string> c_includes
-  100: optional string doc
-}
-
-struct GeneratorInput {
-  1: required t_program program
-  2: required TypeRegistry type_registry
-  3: required map<string, string> parsed_options
-}

http://git-wip-us.apache.org/repos/asf/thrift/blob/052abc39/compiler/cpp/src/plugin/plugin_output.cc
----------------------------------------------------------------------
diff --git a/compiler/cpp/src/plugin/plugin_output.cc b/compiler/cpp/src/plugin/plugin_output.cc
deleted file mode 100644
index 1ab015e..0000000
--- a/compiler/cpp/src/plugin/plugin_output.cc
+++ /dev/null
@@ -1,410 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-#ifdef _WIN32
-#include <cstdio>
-#include <fcntl.h>
-#include <io.h>
-#include <iostream>
-#define THRIFT_POPEN(cmd) _popen(cmd, "wb")
-#define THRIFT_PCLOSE _pclose
-#else
-#define THRIFT_POPEN(cmd) popen(cmd, "w")
-#define THRIFT_PCLOSE pclose
-#endif
-
-#include "plugin/plugin_output.h"
-
-#include <boost/range/adaptor/map.hpp>
-#include <boost/range/algorithm/copy.hpp>
-#include <boost/range/algorithm/transform.hpp>
-#include <boost/smart_ptr.hpp>
-
-#include "generate/t_generator.h"
-#include "plugin/plugin.h"
-#include "plugin/type_util.h"
-#include "thrift/protocol/TBinaryProtocol.h"
-#include "thrift/transport/TBufferTransports.h"
-#include "thrift/transport/TFDTransport.h"
-
-#include "plugin/plugin_types.h"
-
-namespace plugin_output {
-
-template <typename From>
-typename apache::thrift::plugin::ToType<From>::type convert(From* from) {
-  typename apache::thrift::plugin::ToType<From>::type to;
-  convert(from, to);
-  return to;
-}
-
-using apache::thrift::protocol::TBinaryProtocol;
-using apache::thrift::transport::TFDTransport;
-using apache::thrift::transport::TFramedTransport;
-
-using namespace apache::thrift;
-
-#define THRIFT_CONVERSION_N(from_type, to_type)                                                    \
-  template <>                                                                                      \
-  void convert<from_type, to_type>(from_type * from, to_type & to)
-#define THRIFT_CONVERSION(type) THRIFT_CONVERSION_N(::type, plugin::type)
-
-#define THRIFT_ASSIGN_N(from_name, to_name, prefix)                                                \
-  do {                                                                                             \
-    if (from)                                                                                      \
-      to.__set_##to_name(prefix(from->from_name));                                                 \
-  } while (0)
-
-#define THRIFT_ASSIGN(name) THRIFT_ASSIGN_N(get_##name(), name, )
-#define THRIFT_ASSIGN_CONVERT(type, from_name, to_name)                                            \
-  do {                                                                                             \
-    if (from && from->from_name) {                                                                 \
-      to.__set_##to_name(convert(from->from_name));                                                \
-    }                                                                                              \
-  } while (0)
-
-#define THRIFT_ASSIGN_OPT(name)                                                                    \
-  do {                                                                                             \
-    if (from->has_##name())                                                                        \
-      THRIFT_ASSIGN(name);                                                                         \
-  } while (0)
-
-#define THRIFT_ASSIGN_LIST_N(type, from_name, to_name)                                             \
-  do {                                                                                             \
-    if (from && !from->from_name.empty()) {                                                        \
-      std::transform(from->from_name.begin(),                                                      \
-                     from->from_name.end(),                                                        \
-                     std::back_inserter(to.to_name),                                               \
-                     convert< ::type>);                                                            \
-    }                                                                                              \
-  } while (0)
-
-#define THRIFT_ASSIGN_METADATA() convert(reinterpret_cast<t_type*>(from), to.metadata)
-
-// To avoid multiple instances of same type, t_type, t_const and t_service are stored in one place
-// and referenced by ID.
-template <typename T>
-struct TypeCache {
-  typedef typename plugin::ToType<T>::type to_type;
-  std::map<int64_t, to_type> cache;
-
-  template <typename T2>
-  int64_t store(T2* t) {
-    intptr_t id = reinterpret_cast<intptr_t>(t);
-    if (id) {
-      typename std::map<int64_t, to_type>::iterator it = cache.find(id);
-      if (it == cache.end()) {
-        // HACK: fake resolve for recursive type
-        cache.insert(std::make_pair(id, to_type()));
-        // overwrite with true value
-        cache[id] = convert(t);
-      }
-    }
-    return static_cast<int64_t>(id);
-  }
-
-  void clear() { cache.clear(); }
-};
-
-template <typename T>
-int64_t store_type(T* t);
-
-#define T_STORE(type)                                                                              \
-  TypeCache<t_##type> type##_cache;                                                                \
-  template <>                                                                                      \
-  plugin::t_##type##_id store_type<t_##type>(t_##type * t) {                                       \
-    return type##_cache.store<t_##type>(t);                                                        \
-  }
-T_STORE(type)
-T_STORE(const)
-T_STORE(service)
-#undef T_STORE
-
-#define THRIFT_ASSIGN_ID_N(t, from_name, to_name)                                                  \
-  do {                                                                                             \
-    if (from && from->from_name)                                                                   \
-      to.__set_##to_name(store_type<t>(from->from_name));                                          \
-  } while (0)
-
-#define THRIFT_ASSIGN_ID(name) THRIFT_ASSIGN_ID_N(t_type, get_##name(), name)
-
-#define THRIFT_ASSIGN_LIST_ID(t, name)                                                             \
-  do {                                                                                             \
-    if (from && !from->get_##name##s().empty()) {                                                  \
-      std::transform(from->get_##name##s().begin(),                                                \
-                     from->get_##name##s().end(),                                                  \
-                     std::back_inserter(to.name##s),                                               \
-                     &store_type<t>);                                                              \
-    }                                                                                              \
-  } while (0)
-
-THRIFT_CONVERSION_N(::t_type, plugin::TypeMetadata) {
-  to.program_id = reinterpret_cast<int64_t>(from->get_program());
-  THRIFT_ASSIGN_N(annotations_, annotations, );
-  if (from->has_doc()) {
-    to.__set_doc(from->get_doc());
-  }
-  THRIFT_ASSIGN(name);
-}
-
-THRIFT_CONVERSION(t_typedef) {
-  THRIFT_ASSIGN_METADATA();
-  THRIFT_ASSIGN_ID(type);
-  THRIFT_ASSIGN(symbolic);
-  THRIFT_ASSIGN_N(is_forward_typedef(), forward, );
-}
-
-THRIFT_CONVERSION(t_enum_value) {
-  THRIFT_ASSIGN_OPT(doc);
-  THRIFT_ASSIGN(name);
-  THRIFT_ASSIGN(value);
-}
-
-THRIFT_CONVERSION(t_enum) {
-  THRIFT_ASSIGN_METADATA();
-  THRIFT_ASSIGN_LIST_N(t_enum_value, get_constants(), constants);
-}
-
-THRIFT_CONVERSION(t_const_value) {
-  switch (from->get_type()) {
-  case t_const_value::CV_INTEGER:
-    THRIFT_ASSIGN_N(get_integer(), integer_val, );
-    break;
-  case t_const_value::CV_DOUBLE:
-    THRIFT_ASSIGN_N(get_double(), double_val, );
-    break;
-  case t_const_value::CV_STRING:
-    THRIFT_ASSIGN_N(get_string(), string_val, );
-    break;
-  case t_const_value::CV_IDENTIFIER:
-    THRIFT_ASSIGN_ID_N(t_type, enum_, enum_val);
-    THRIFT_ASSIGN_N(get_identifier(), identifier_val, );
-    break;
-  case t_const_value::CV_MAP:
-    to.__isset.map_val = true;
-    if (from && !from->get_map().empty()) {
-      for (std::map< ::t_const_value*, ::t_const_value*>::const_iterator it
-           = from->get_map().begin();
-           it != from->get_map().end();
-           it++) {
-        to.map_val.insert(std::make_pair(convert(it->first), convert(it->second)));
-      }
-    }
-    break;
-  case t_const_value::CV_LIST:
-    to.__isset.list_val = true;
-    THRIFT_ASSIGN_LIST_N(t_const_value, get_list(), list_val);
-    break;
-  default:
-    throw plugin::ThriftPluginError("const value has no value");
-  }
-}
-THRIFT_CONVERSION(t_const) {
-  THRIFT_ASSIGN_OPT(doc);
-  THRIFT_ASSIGN(name);
-  THRIFT_ASSIGN_ID(type);
-  THRIFT_ASSIGN_CONVERT(t_const_value, get_value(), value);
-}
-THRIFT_CONVERSION(t_field) {
-  THRIFT_ASSIGN_OPT(doc);
-  THRIFT_ASSIGN(name);
-  THRIFT_ASSIGN(key);
-  THRIFT_ASSIGN_N(get_req(), req, (plugin::Requiredness::type));
-  THRIFT_ASSIGN(reference);
-  THRIFT_ASSIGN_ID(type);
-  THRIFT_ASSIGN_CONVERT(t_const_value, get_value(), value);
-}
-THRIFT_CONVERSION(t_struct) {
-  THRIFT_ASSIGN_METADATA();
-  THRIFT_ASSIGN_LIST_N(t_field, get_members(), members);
-  THRIFT_ASSIGN_N(is_union(), is_union, );
-  THRIFT_ASSIGN_N(is_xception(), is_xception, );
-}
-THRIFT_CONVERSION(t_function) {
-  THRIFT_ASSIGN_OPT(doc);
-  THRIFT_ASSIGN(name);
-  THRIFT_ASSIGN_ID(returntype);
-  THRIFT_ASSIGN_N(is_oneway(), is_oneway, );
-  THRIFT_ASSIGN_ID(arglist);
-  THRIFT_ASSIGN_ID(xceptions);
-}
-
-THRIFT_CONVERSION(t_list) {
-  THRIFT_ASSIGN_METADATA();
-  THRIFT_ASSIGN_OPT(cpp_name);
-  THRIFT_ASSIGN_ID(elem_type);
-}
-THRIFT_CONVERSION(t_set) {
-  THRIFT_ASSIGN_METADATA();
-  THRIFT_ASSIGN_OPT(cpp_name);
-  THRIFT_ASSIGN_ID(elem_type);
-}
-THRIFT_CONVERSION(t_map) {
-  THRIFT_ASSIGN_METADATA();
-  THRIFT_ASSIGN_OPT(cpp_name);
-  THRIFT_ASSIGN_ID(key_type);
-  THRIFT_ASSIGN_ID(val_type);
-}
-
-THRIFT_CONVERSION(t_service) {
-  THRIFT_ASSIGN_METADATA();
-  THRIFT_ASSIGN_LIST_N(t_function, get_functions(), functions);
-  THRIFT_ASSIGN_ID_N(t_service, get_extends(), extends_);
-}
-
-THRIFT_CONVERSION(t_base_type) {
-  THRIFT_ASSIGN_METADATA();
-  if (from->is_binary()) {
-    to.value = plugin::t_base::TYPE_BINARY;
-  } else {
-    switch (from->get_base()) {
-#define T_BASETYPE_CASE(name)                                                                      \
-  case t_base_type::TYPE_##name:                                                                   \
-    to.value = plugin::t_base::TYPE_##name;                                                        \
-    break
-      T_BASETYPE_CASE(VOID);
-      T_BASETYPE_CASE(STRING);
-      T_BASETYPE_CASE(BOOL);
-      T_BASETYPE_CASE(I8);
-      T_BASETYPE_CASE(I16);
-      T_BASETYPE_CASE(I32);
-      T_BASETYPE_CASE(I64);
-      T_BASETYPE_CASE(DOUBLE);
-    default:
-      throw plugin::ThriftPluginError("Base type union has no value");
-      break;
-#undef T_BASETYPE_CASE
-    }
-  }
-}
-THRIFT_CONVERSION(t_type) {
-#define T_CONVERT_UNION_N(name, type)                                                              \
-  else if (from->is_##name()) {                                                                    \
-    to.__isset.name##_val = true;                                                                  \
-    convert(reinterpret_cast< ::type*>(from), to.name##_val);                                      \
-  }
-#define T_CONVERT_UNION(name) T_CONVERT_UNION_N(name, t_##name)
-  if (false) {
-  }
-  T_CONVERT_UNION(base_type)
-  T_CONVERT_UNION(typedef)
-  T_CONVERT_UNION(enum)
-  T_CONVERT_UNION(struct)
-  T_CONVERT_UNION_N(xception, t_struct)
-  T_CONVERT_UNION(list)
-  T_CONVERT_UNION(set)
-  T_CONVERT_UNION(map)
-  T_CONVERT_UNION(service)
-  else {
-    throw plugin::ThriftPluginError("Type union has no value");
-  }
-#undef T_CONVERT_UNION_N
-#undef T_CONVERT_UNION
-}
-
-THRIFT_CONVERSION(t_scope) {
-#define T_SCOPE_ASSIGN(name, type)                                                                 \
-  boost::copy(from->name##s_ | boost::adaptors::map_values                                         \
-              | boost::adaptors::transformed(&store_type<type>),                                   \
-              std::back_inserter(to.name##s))
-  T_SCOPE_ASSIGN(type, t_type);
-  T_SCOPE_ASSIGN(constant, t_const);
-  T_SCOPE_ASSIGN(service, t_service);
-#undef T_SCOPE_ASSIGN
-}
-
-void get_global_cache(plugin::TypeRegistry& reg) {
-  reg.types = type_cache.cache;
-  reg.constants = const_cache.cache;
-  reg.services = service_cache.cache;
-}
-
-void clear_global_cache() {
-  type_cache.clear();
-  const_cache.clear();
-  service_cache.clear();
-}
-
-THRIFT_CONVERSION(t_program) {
-  THRIFT_ASSIGN_CONVERT(t_scope, scope(), scope);
-  THRIFT_ASSIGN(path);
-  THRIFT_ASSIGN(out_path);
-  THRIFT_ASSIGN(name);
-  THRIFT_ASSIGN(include_prefix);
-  THRIFT_ASSIGN(cpp_includes);
-  THRIFT_ASSIGN(c_includes);
-  THRIFT_ASSIGN(namespaces);
-  THRIFT_ASSIGN_N(is_out_path_absolute(), out_path_is_absolute, );
-  THRIFT_ASSIGN_N(get_namespace(), namespace_, );
-  THRIFT_ASSIGN_LIST_ID(t_type, typedef);
-  THRIFT_ASSIGN_LIST_ID(t_type, enum);
-  THRIFT_ASSIGN_LIST_ID(t_type, object);
-  THRIFT_ASSIGN_LIST_ID(t_const, const);
-  THRIFT_ASSIGN_LIST_ID(t_service, service);
-  THRIFT_ASSIGN_LIST_N(t_program, get_includes(), includes);
-  to.program_id = reinterpret_cast<plugin::t_program_id>(from);
-}
-
-PluginDelegateResult delegateToPlugin(t_program* program, const std::string& options) {
-  std::string language;
-  std::map<std::string, std::string> parsed_options;
-  t_generator::parse_options(options, language, parsed_options);
-  std::string cmd = "thrift-gen-";
-  if (language.find_first_not_of("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_-0123456789")
-      != std::string::npos) {
-    std::cerr << "Invalid language name" << std::endl;
-    return PLUGIN_FAILURE;
-  }
-  cmd.append(language);
-  FILE* fd = THRIFT_POPEN(cmd.c_str());
-  if (fd) {
-#ifdef _WIN32
-    _setmode(fileno(fd), _O_BINARY);
-#endif
-    boost::shared_ptr<TFramedTransport> transport(
-        new TFramedTransport(boost::make_shared<TFDTransport>(fileno(fd))));
-    TBinaryProtocol proto(transport);
-
-    plugin::GeneratorInput input;
-    input.__set_parsed_options(parsed_options);
-    clear_global_cache();
-    convert(program, input.program);
-    get_global_cache(input.type_registry);
-    try {
-      input.write(&proto);
-      transport->flush();
-    } catch (std::exception& err) {
-      std::cerr << "Error while sending data to plugin: " << err.what() << std::endl;
-      THRIFT_PCLOSE(fd);
-      return PLUGIN_FAILURE;
-    }
-
-    // TODO: be prepared for hang or crash of child process
-    int ret = THRIFT_PCLOSE(fd);
-    if (!ret) {
-      return PLUGIN_SUCCEESS;
-    } else {
-      std::cerr << "plugin process returned non zero exit code: " << ret << std::endl;
-      return PLUGIN_FAILURE;
-    }
-  }
-  clear_global_cache();
-  return PLUGIN_NOT_FOUND;
-}
-}

http://git-wip-us.apache.org/repos/asf/thrift/blob/052abc39/compiler/cpp/src/plugin/plugin_output.h
----------------------------------------------------------------------
diff --git a/compiler/cpp/src/plugin/plugin_output.h b/compiler/cpp/src/plugin/plugin_output.h
deleted file mode 100644
index eab2d1b..0000000
--- a/compiler/cpp/src/plugin/plugin_output.h
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-#ifndef T_PLUGIN_PLUGIN_OUTPUT_H
-#define T_PLUGIN_PLUGIN_OUTPUT_H
-
-#include <string>
-
-class t_program;
-
-namespace plugin_output {
-
-enum PluginDelegateResult {
-  PLUGIN_NOT_FOUND,
-  PLUGIN_FAILURE,
-  PLUGIN_SUCCEESS,
-};
-
-PluginDelegateResult delegateToPlugin(t_program* program, const std::string& options);
-}
-
-#endif

http://git-wip-us.apache.org/repos/asf/thrift/blob/052abc39/compiler/cpp/src/plugin/type_util.h
----------------------------------------------------------------------
diff --git a/compiler/cpp/src/plugin/type_util.h b/compiler/cpp/src/plugin/type_util.h
deleted file mode 100644
index 508b741..0000000
--- a/compiler/cpp/src/plugin/type_util.h
+++ /dev/null
@@ -1,94 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-#ifndef T_PLUGIN_TYPE_UTIL_H
-#define T_PLUGIN_TYPE_UTIL_H
-
-namespace apache {
-namespace thrift {
-namespace plugin {
-
-template <typename From>
-struct ToType {};
-
-template <typename From>
-typename ToType<From>::type* convert_forward(const From&);
-
-template <typename From, typename To>
-void convert(const From&, To*);
-
-template <typename From>
-typename ToType<From>::type* convert(const From& from);
-
-class TypeRegistry;
-void set_global_cache(const TypeRegistry&);
-}
-}
-}
-
-// conversion from raw compiler types to plugin wire type
-namespace plugin_output {
-
-template <typename From, typename To>
-void convert(From* from, To& to);
-
-template <typename From>
-typename apache::thrift::plugin::ToType<From>::type convert(From* from);
-
-void get_global_cache(apache::thrift::plugin::TypeRegistry&);
-void clear_global_cache();
-}
-
-#define THRIFT_TYPE_MAPPING(TYPE)                                                                  \
-  class TYPE;                                                                                      \
-  namespace apache {                                                                               \
-  namespace thrift {                                                                               \
-  namespace plugin {                                                                               \
-  class TYPE;                                                                                      \
-  template <>                                                                                      \
-  struct ToType< ::TYPE> {                                                                         \
-    typedef TYPE type;                                                                             \
-  };                                                                                               \
-  template <>                                                                                      \
-  struct ToType<TYPE> {                                                                            \
-    typedef ::TYPE type;                                                                           \
-  };                                                                                               \
-  }                                                                                                \
-  }                                                                                                \
-  }
-THRIFT_TYPE_MAPPING(t_base_type)
-THRIFT_TYPE_MAPPING(t_const)
-THRIFT_TYPE_MAPPING(t_const_value)
-THRIFT_TYPE_MAPPING(t_container)
-THRIFT_TYPE_MAPPING(t_doc)
-THRIFT_TYPE_MAPPING(t_enum)
-THRIFT_TYPE_MAPPING(t_enum_value)
-THRIFT_TYPE_MAPPING(t_field)
-THRIFT_TYPE_MAPPING(t_function)
-THRIFT_TYPE_MAPPING(t_list)
-THRIFT_TYPE_MAPPING(t_map)
-THRIFT_TYPE_MAPPING(t_program)
-THRIFT_TYPE_MAPPING(t_scope)
-THRIFT_TYPE_MAPPING(t_service)
-THRIFT_TYPE_MAPPING(t_set)
-THRIFT_TYPE_MAPPING(t_struct)
-THRIFT_TYPE_MAPPING(t_type)
-THRIFT_TYPE_MAPPING(t_typedef)
-#undef THRIFT_TYPE_MAPPING
-#endif

http://git-wip-us.apache.org/repos/asf/thrift/blob/052abc39/compiler/cpp/src/thrift/audit/t_audit.cpp
----------------------------------------------------------------------
diff --git a/compiler/cpp/src/thrift/audit/t_audit.cpp b/compiler/cpp/src/thrift/audit/t_audit.cpp
new file mode 100644
index 0000000..1386f3b
--- /dev/null
+++ b/compiler/cpp/src/thrift/audit/t_audit.cpp
@@ -0,0 +1,464 @@
+
+#include <cassert>
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdarg.h>
+#include <time.h>
+#include <string>
+#include <algorithm>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <errno.h>
+#include <limits.h>
+
+// Careful: must include globals first for extern definitions
+#include "thrift/globals.h"
+
+#include "thrift/parse/t_program.h"
+#include "thrift/parse/t_scope.h"
+#include "thrift/parse/t_const.h"
+#include "thrift/parse/t_field.h"
+
+#include "thrift/version.h"
+
+#include "thrift/audit/t_audit.h"
+
+extern int g_warn;
+extern std::string g_curpath;
+extern bool g_return_failure;
+
+void thrift_audit_warning(int level, const char* fmt, ...) {
+   if (g_warn < level) {
+      return;
+   }
+   va_list args;
+   printf("[Thrift Audit Warning:%s] ", g_curpath.c_str());
+   va_start(args, fmt);
+   vprintf(fmt, args);
+   va_end(args);
+   printf("\n");
+}
+
+void thrift_audit_failure(const char* fmt, ...) {
+  va_list args;
+  fprintf(stderr, "[Thrift Audit Failure:%s] ", g_curpath.c_str());
+  va_start(args, fmt);
+  vfprintf(stderr, fmt, args);
+  va_end(args);
+  fprintf(stderr, "\n");
+  g_return_failure = true;
+}
+
+void compare_namespace(t_program* newProgram, t_program* oldProgram)
+{
+   const std::map<std::string, std::string>& newNamespaceMap = newProgram->get_all_namespaces();
+   const std::map<std::string, std::string>& oldNamespaceMap = oldProgram->get_all_namespaces();
+
+   for(std::map<std::string, std::string>::const_iterator oldNamespaceMapIt = oldNamespaceMap.begin();
+         oldNamespaceMapIt != oldNamespaceMap.end();
+         oldNamespaceMapIt++)
+   {
+      std::map<std::string, std::string>::const_iterator newNamespaceMapIt = newNamespaceMap.find(oldNamespaceMapIt->first);
+      if(newNamespaceMapIt == newNamespaceMap.end())
+      {
+         thrift_audit_warning(1, "Language %s not found in new thrift file\n", (oldNamespaceMapIt->first).c_str());
+      }
+      else if((newNamespaceMapIt->second) != oldNamespaceMapIt->second)
+      {
+         thrift_audit_warning(1, "Namespace %s changed in new thrift file\n", (oldNamespaceMapIt->second).c_str());
+      }
+   }
+}
+
+void compare_enum_values(t_enum* newEnum,t_enum* oldEnum)
+{
+   const std::vector<t_enum_value*>& oldEnumValues = oldEnum->get_constants();
+   for(std::vector<t_enum_value*>::const_iterator oldEnumValuesIt = oldEnumValues.begin();
+         oldEnumValuesIt != oldEnumValues.end();
+         oldEnumValuesIt++)
+   {
+      int enumValue = (*oldEnumValuesIt)->get_value();
+      t_enum_value* newEnumValue = newEnum->get_constant_by_value(enumValue);
+      if(newEnumValue != NULL)
+      {
+         std::string enumName = (*oldEnumValuesIt)->get_name();
+         if(enumName != newEnumValue->get_name())
+         {
+            thrift_audit_warning(1, "Name of the value %d changed in enum %s\n", enumValue, oldEnum->get_name().c_str());
+         }
+      }
+      else
+      {
+         thrift_audit_failure("Enum value %d missing in %s\n", enumValue, oldEnum->get_name().c_str());
+      }
+
+   }
+}
+
+void compare_enums(const std::vector<t_enum*>& newEnumList, const std::vector<t_enum*>& oldEnumList)
+{
+   std::map<std::string,t_enum*> newEnumMap;
+   std::vector<t_enum*>::const_iterator newEnumIt;
+   for(newEnumIt = newEnumList.begin(); newEnumIt != newEnumList.end(); newEnumIt++)
+   {
+      newEnumMap[(*newEnumIt)->get_name()] = *newEnumIt;
+   }
+   std::vector<t_enum*>::const_iterator oldEnumIt;
+   for(oldEnumIt = oldEnumList.begin(); oldEnumIt != oldEnumList.end(); oldEnumIt++)
+   {
+      std::map<std::string,t_enum*>::iterator newEnumMapIt;
+      newEnumMapIt = newEnumMap.find((*oldEnumIt)->get_name());
+
+      if(newEnumMapIt == newEnumMap.end())
+      {
+         thrift_audit_warning(1, "Enum %s not found in new thrift file\n",(*oldEnumIt)->get_name().c_str());
+      }
+      else
+      {
+         compare_enum_values(newEnumMapIt->second, *oldEnumIt);
+      }
+   }
+}
+
+//This function returns 'true' if the two arguements are of same types.
+//Returns false if they are of different type
+bool compare_type(t_type* newType, t_type* oldType)
+{
+   //Comparing names of two types will work when the newType and oldType are basic types or structs or enums.
+   //However, when they are containers, get_name() returns empty for which we have to compare the type of
+   //their elements as well.
+   if((newType->get_name()).empty() && (oldType->get_name()).empty())
+   {
+
+      if(newType->is_list() && oldType->is_list())
+      {
+         t_type* newElementType = ((t_list*)newType)->get_elem_type();
+         t_type* oldElementType = ((t_list*)oldType)->get_elem_type();
+         return compare_type(newElementType, oldElementType);
+      }
+      else if(newType->is_map() && oldType->is_map())
+      {
+         t_type* newKeyType = ((t_map*)newType)->get_key_type();
+         t_type* oldKeyType = ((t_map*)oldType)->get_key_type();
+
+         t_type* newValType = ((t_map*)newType)->get_val_type();
+         t_type* oldValType = ((t_map*)oldType)->get_val_type();
+
+         return (compare_type(newKeyType, oldKeyType) && compare_type(newValType, oldValType));
+      }
+      else if(newType->is_set() && oldType->is_set())
+      {
+         t_type* newElementType = ((t_set*)newType)->get_elem_type();
+         t_type* oldElementType = ((t_set*)oldType)->get_elem_type();
+         return compare_type(newElementType, oldElementType);
+      }
+      else
+      {
+         return false;
+      }
+   }
+   else if(newType->get_name() == oldType->get_name())
+   {
+      return true;
+   }
+   else
+   {
+      return false;
+   }
+}
+
+bool compare_pair(std::pair<t_const_value*, t_const_value*> newMapPair, std::pair<t_const_value*, t_const_value*> oldMapPair)
+{
+   return compare_defaults(newMapPair.first, oldMapPair.first) && compare_defaults(newMapPair.second, oldMapPair.second);
+}
+
+// This function returns 'true' if the default values are same. Returns false if they are different.
+bool compare_defaults(t_const_value* newStructDefault, t_const_value* oldStructDefault)
+{
+   if(newStructDefault == NULL && oldStructDefault == NULL) return true;
+   else if(newStructDefault == NULL && oldStructDefault != NULL) return false;
+   else if (newStructDefault != NULL && oldStructDefault == NULL) return false;
+
+   if(newStructDefault->get_type() != oldStructDefault->get_type())
+   {
+      return false;
+   }
+
+   switch(newStructDefault->get_type())
+   {
+      case t_const_value::CV_INTEGER:
+         return (newStructDefault->get_integer() == oldStructDefault->get_integer());
+      case t_const_value::CV_DOUBLE:
+         return (newStructDefault->get_double() == oldStructDefault->get_double());
+      case t_const_value::CV_STRING:
+         return (newStructDefault->get_string() == oldStructDefault->get_string());
+      case t_const_value::CV_LIST:
+         {
+            const std::vector<t_const_value*>& oldDefaultList = oldStructDefault->get_list();
+            const std::vector<t_const_value*>& newDefaultList = newStructDefault->get_list();
+            bool defaultValuesCompare = (oldDefaultList.size() == newDefaultList.size());
+
+            return defaultValuesCompare && std::equal(newDefaultList.begin(), newDefaultList.end(), oldDefaultList.begin(), compare_defaults);
+         }
+      case t_const_value::CV_MAP:
+         {
+            const std::map<t_const_value*, t_const_value*> newMap = newStructDefault->get_map();
+            const std::map<t_const_value*, t_const_value*> oldMap = oldStructDefault->get_map();
+
+            bool defaultValuesCompare = (oldMap.size() == newMap.size());
+
+            return defaultValuesCompare && std::equal(newMap.begin(), newMap.end(), oldMap.begin(), compare_pair);
+         }
+      case t_const_value::CV_IDENTIFIER:
+         return (newStructDefault->get_identifier() == oldStructDefault->get_identifier());
+      default:
+         return false;
+   }
+
+}
+
+void compare_struct_field(t_field* newField, t_field* oldField, std::string oldStructName)
+{
+   t_type* newFieldType = newField->get_type();
+   t_type* oldFieldType = oldField->get_type();
+   if(!compare_type(newFieldType, oldFieldType))
+   {
+      thrift_audit_failure("Struct Field Type Changed for Id = %d in %s \n", newField->get_key(), oldStructName.c_str());
+   }
+
+   // A Struct member can be optional if it is mentioned explicitly, or if it is assigned with default values.
+   bool newStructFieldOptional = (newField->get_req() != t_field::T_REQUIRED);
+   bool oldStructFieldOptional = (oldField->get_req() != t_field::T_REQUIRED);
+
+   if(newStructFieldOptional != oldStructFieldOptional)
+   {
+      thrift_audit_failure("Struct Field Requiredness Changed for Id = %d in %s \n", newField->get_key(), oldStructName.c_str());
+   }
+   if(newStructFieldOptional || oldStructFieldOptional)
+   {
+      if(!compare_defaults(newField->get_value(), oldField->get_value()))
+      {
+         thrift_audit_warning(1, "Default value changed for Id = %d in %s \n", newField->get_key(), oldStructName.c_str());
+      }
+   }
+
+   std::string fieldName = newField->get_name();
+   if(fieldName != oldField->get_name())
+   {
+      thrift_audit_warning(1, "Struct field name changed for Id = %d in %s\n", newField->get_key(), oldStructName.c_str());
+   }
+
+}
+
+void compare_single_struct(t_struct* newStruct, t_struct* oldStruct, const std::string& oldStructName = std::string())
+{
+   std::string structName = oldStructName.empty() ? oldStruct->get_name() : oldStructName;
+   const std::vector<t_field*>& oldStructMembersInIdOrder = oldStruct->get_sorted_members();
+   const std::vector<t_field*>& newStructMembersInIdOrder = newStruct->get_sorted_members();
+   std::vector<t_field*>::const_iterator oldStructMemberIt = oldStructMembersInIdOrder.begin();
+   std::vector<t_field*>::const_iterator newStructMemberIt = newStructMembersInIdOrder.begin();
+
+   // Since we have the struct members in their ID order, comparing their IDs can be done by traversing the two member
+   // lists together.
+   while(!(oldStructMemberIt == oldStructMembersInIdOrder.end() && newStructMemberIt == newStructMembersInIdOrder.end()))
+   {
+      if(newStructMemberIt == newStructMembersInIdOrder.end() && oldStructMemberIt != oldStructMembersInIdOrder.end())
+      {
+         // A field ID has been removed from the end.
+         thrift_audit_failure("Struct Field removed for Id = %d in %s \n", (*oldStructMemberIt)->get_key(), structName.c_str());
+         oldStructMemberIt++;
+      }
+      else if(newStructMemberIt != newStructMembersInIdOrder.end() && oldStructMemberIt == oldStructMembersInIdOrder.end())
+      {
+         //New field ID has been added to the end.
+         if((*newStructMemberIt)->get_req() == t_field::T_REQUIRED)
+         {
+            thrift_audit_failure("Required Struct Field Added for Id = %d in %s \n", (*newStructMemberIt)->get_key(), structName.c_str());
+         }
+         newStructMemberIt++;
+      }
+      else if((*newStructMemberIt)->get_key() == (*oldStructMemberIt)->get_key())
+      {
+         //Field ID found in both structs. Compare field types, default values.
+         compare_struct_field(*newStructMemberIt, *oldStructMemberIt, structName);
+
+         newStructMemberIt++;
+         oldStructMemberIt++;
+      }
+      else if((*newStructMemberIt)->get_key() < (*oldStructMemberIt)->get_key())
+      {
+         //New Field Id is inserted in between
+         //Adding fields to struct is fine, but adding them in the middle is suspicious. Error!!
+         thrift_audit_failure("Struct field is added in the middle with Id = %d in %s\n",  (*newStructMemberIt)->get_key(),  structName.c_str());
+         newStructMemberIt++;
+      }
+      else if((*newStructMemberIt)->get_key() > (*oldStructMemberIt)->get_key())
+      {
+         //A field is deleted in newStruct.
+         thrift_audit_failure("Struct Field removed for Id = %d in %s \n",  (*oldStructMemberIt)->get_key(), structName.c_str());
+         oldStructMemberIt++;
+      }
+
+   }
+}
+
+void compare_structs(const std::vector<t_struct*>& newStructList, const std::vector<t_struct*>& oldStructList)
+{
+   std::map<std::string,t_struct*> newStructMap;
+   std::vector<t_struct*>::const_iterator newStructListIt;
+   for(newStructListIt = newStructList.begin(); newStructListIt != newStructList.end(); newStructListIt++)
+   {
+      newStructMap[(*newStructListIt)->get_name()] = *newStructListIt;
+   }
+
+   std::vector<t_struct*>::const_iterator oldStructListIt;
+   for(oldStructListIt = oldStructList.begin(); oldStructListIt != oldStructList.end(); oldStructListIt++)
+   {
+      std::map<std::string, t_struct*>::iterator newStructMapIt;
+      newStructMapIt = newStructMap.find((*oldStructListIt)->get_name());
+      if(newStructMapIt == newStructMap.end())
+      {
+         thrift_audit_failure("Struct %s not found in new thrift file\n", (*oldStructListIt)->get_name().c_str());
+      }
+      else
+      {
+         compare_single_struct(newStructMapIt->second, *oldStructListIt);
+      }
+   }
+
+}
+
+void compare_single_function(t_function* newFunction, t_function* oldFunction)
+{
+   t_type* newFunctionReturnType = newFunction->get_returntype();
+
+   if(newFunction->is_oneway() != oldFunction->is_oneway())
+   {
+      thrift_audit_failure("Oneway attribute changed for function %s\n",oldFunction->get_name().c_str());
+   }
+   if(!compare_type(newFunctionReturnType, oldFunction->get_returntype()))
+   {
+      thrift_audit_failure("Return type changed for function %s\n",oldFunction->get_name().c_str());
+   }
+
+   //Compare function arguments.
+   compare_single_struct(newFunction->get_arglist(), oldFunction->get_arglist());
+   std::string exceptionName = oldFunction->get_name();
+   exceptionName += "_exception";
+   compare_single_struct(newFunction->get_xceptions(), oldFunction->get_xceptions(), exceptionName);
+}
+
+void compare_functions(const std::vector<t_function*>& newFunctionList, const std::vector<t_function*>& oldFunctionList)
+{
+   std::map<std::string, t_function*> newFunctionMap;
+   std::map<std::string, t_function*>::iterator newFunctionMapIt;
+   for(std::vector<t_function*>::const_iterator newFunctionIt = newFunctionList.begin();
+         newFunctionIt != newFunctionList.end();
+         newFunctionIt++)
+   {
+      newFunctionMap[(*newFunctionIt)->get_name()] = *newFunctionIt;
+   }
+
+   for(std::vector<t_function*>::const_iterator oldFunctionIt = oldFunctionList.begin();
+         oldFunctionIt != oldFunctionList.end();
+         oldFunctionIt++)
+   {
+      newFunctionMapIt = newFunctionMap.find((*oldFunctionIt)->get_name());
+      if(newFunctionMapIt == newFunctionMap.end())
+      {
+         thrift_audit_failure("New Thrift File has missing function %s\n",(*oldFunctionIt)->get_name().c_str());
+         continue;
+      }
+      else
+      {
+         //Function is found in both thrift files. Compare return type and argument list
+         compare_single_function(newFunctionMapIt->second, *oldFunctionIt);
+      }
+   }
+
+}
+
+void compare_services(const std::vector<t_service*>& newServices, const std::vector<t_service*>& oldServices)
+{
+   std::vector<t_service*>::const_iterator oldServiceIt;
+
+   std::map<std::string, t_service*> newServiceMap;
+   for(std::vector<t_service*>::const_iterator newServiceIt = newServices.begin();
+         newServiceIt != newServices.end();
+         newServiceIt++)
+   {
+      newServiceMap[(*newServiceIt)->get_name()] = *newServiceIt;
+   }
+
+
+   for(oldServiceIt = oldServices.begin(); oldServiceIt != oldServices.end(); oldServiceIt++)
+   {
+      const std::string oldServiceName = (*oldServiceIt)->get_name();
+      std::map<std::string, t_service*>::iterator newServiceMapIt = newServiceMap.find(oldServiceName);
+
+      if(newServiceMapIt == newServiceMap.end())
+      {
+         thrift_audit_failure("New Thrift file is missing a service %s\n", oldServiceName.c_str());
+      }
+      else
+      {
+         t_service* oldServiceExtends = (*oldServiceIt)->get_extends();
+         t_service* newServiceExtends = (newServiceMapIt->second)->get_extends();
+
+         if(oldServiceExtends == NULL)
+         {
+            // It is fine to add extends. So if service in older thrift did not have any extends, we are fine.
+            // DO Nothing
+         }
+         else if(oldServiceExtends != NULL && newServiceExtends == NULL)
+         {
+            thrift_audit_failure("Change in Service inheritance for %s\n", oldServiceName.c_str());
+         }
+         else
+         {
+            std::string oldExtendsName = oldServiceExtends->get_name();
+            std::string newExtendsName = newServiceExtends->get_name();
+
+            if( newExtendsName != oldExtendsName)
+            {
+               thrift_audit_failure("Change in Service inheritance for %s\n", oldServiceName.c_str());
+            }
+         }
+
+         compare_functions((newServiceMapIt->second)->get_functions(), (*oldServiceIt)->get_functions());
+      }
+
+   }
+
+}
+
+void compare_consts(const std::vector<t_const*>& newConst, const std::vector<t_const*>& oldConst)
+{
+   std::vector<t_const*>::const_iterator newConstIt;
+   std::vector<t_const*>::const_iterator oldConstIt;
+
+   std::map<std::string, t_const*> newConstMap;
+
+   for(newConstIt = newConst.begin(); newConstIt != newConst.end(); newConstIt++)
+   {
+      newConstMap[(*newConstIt)->get_name()] = *newConstIt;
+   }
+
+   std::map<std::string, t_const*>::const_iterator newConstMapIt;
+   for(oldConstIt = oldConst.begin(); oldConstIt != oldConst.end(); oldConstIt++)
+   {
+      newConstMapIt = newConstMap.find((*oldConstIt)->get_name());
+      if(newConstMapIt == newConstMap.end())
+      {
+         thrift_audit_warning(1, "Constants Missing %s \n", ((*oldConstIt)->get_name()).c_str());
+      }
+      else if(!compare_type((newConstMapIt->second)->get_type(), (*oldConstIt)->get_type()))
+      {
+         thrift_audit_warning(1, "Constant %s is of different type \n", ((*oldConstIt)->get_name()).c_str());
+      }
+      else if(!compare_defaults((newConstMapIt->second)->get_value(), (*oldConstIt)->get_value()))
+      {
+         thrift_audit_warning(1, "Constant %s has different value\n", ((*oldConstIt)->get_name()).c_str());
+      }
+   }
+}

http://git-wip-us.apache.org/repos/asf/thrift/blob/052abc39/compiler/cpp/src/thrift/audit/t_audit.h
----------------------------------------------------------------------
diff --git a/compiler/cpp/src/thrift/audit/t_audit.h b/compiler/cpp/src/thrift/audit/t_audit.h
new file mode 100644
index 0000000..be79e31
--- /dev/null
+++ b/compiler/cpp/src/thrift/audit/t_audit.h
@@ -0,0 +1,14 @@
+#ifndef T_AUDIT_H
+#define T_AUDIT_H
+
+void compare_namespace(t_program* newProgram, t_program* oldProgram);
+void compare_enums(const std::vector<t_enum*>& newEnumList,
+                   const std::vector<t_enum*>& oldEnumList);
+bool compare_defaults(t_const_value* newStructDefault, t_const_value* oldStructDefault);
+void compare_structs(const std::vector<t_struct*>& newStructList,
+                     const std::vector<t_struct*>& oldStructList);
+void compare_services(const std::vector<t_service*>& newServices,
+                      const std::vector<t_service*>& oldServices);
+void compare_consts(const std::vector<t_const*>& newConst, const std::vector<t_const*>& oldConst);
+
+#endif

http://git-wip-us.apache.org/repos/asf/thrift/blob/052abc39/compiler/cpp/src/thrift/common.cc
----------------------------------------------------------------------
diff --git a/compiler/cpp/src/thrift/common.cc b/compiler/cpp/src/thrift/common.cc
new file mode 100644
index 0000000..3a2b9d3
--- /dev/null
+++ b/compiler/cpp/src/thrift/common.cc
@@ -0,0 +1,69 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#include "thrift/common.h"
+#include "thrift/parse/t_base_type.h"
+
+t_type* g_type_void;
+t_type* g_type_string;
+t_type* g_type_binary;
+t_type* g_type_slist;
+t_type* g_type_bool;
+t_type* g_type_i8;
+t_type* g_type_i16;
+t_type* g_type_i32;
+t_type* g_type_i64;
+t_type* g_type_double;
+
+void initGlobals() {
+  g_type_void = new t_base_type("void", t_base_type::TYPE_VOID);
+  g_type_string = new t_base_type("string", t_base_type::TYPE_STRING);
+  g_type_binary = new t_base_type("string", t_base_type::TYPE_STRING);
+  ((t_base_type*)g_type_binary)->set_binary(true);
+  g_type_slist = new t_base_type("string", t_base_type::TYPE_STRING);
+  ((t_base_type*)g_type_slist)->set_string_list(true);
+  g_type_bool = new t_base_type("bool", t_base_type::TYPE_BOOL);
+  g_type_i8 = new t_base_type("i8", t_base_type::TYPE_I8);
+  g_type_i16 = new t_base_type("i16", t_base_type::TYPE_I16);
+  g_type_i32 = new t_base_type("i32", t_base_type::TYPE_I32);
+  g_type_i64 = new t_base_type("i64", t_base_type::TYPE_I64);
+  g_type_double = new t_base_type("double", t_base_type::TYPE_DOUBLE);
+}
+
+void clearGlobals() {
+  delete g_type_void;
+  delete g_type_string;
+  delete g_type_bool;
+  delete g_type_i8;
+  delete g_type_i16;
+  delete g_type_i32;
+  delete g_type_i64;
+  delete g_type_double;
+}
+
+/**
+ * Those are not really needed for plugins but causes link errors without
+ */
+
+/**
+ * The location of the last parsed doctext comment.
+ */
+int g_doctext_lineno;
+int g_program_doctext_lineno = 0;
+PROGDOCTEXT_STATUS g_program_doctext_status = INVALID;

http://git-wip-us.apache.org/repos/asf/thrift/blob/052abc39/compiler/cpp/src/thrift/common.h
----------------------------------------------------------------------
diff --git a/compiler/cpp/src/thrift/common.h b/compiler/cpp/src/thrift/common.h
new file mode 100644
index 0000000..6948846
--- /dev/null
+++ b/compiler/cpp/src/thrift/common.h
@@ -0,0 +1,43 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#ifndef T_COMMON_H
+#define T_COMMON_H
+
+#include "thrift/parse/t_type.h"
+
+/**
+ * Global types for the parser to be able to reference
+ */
+
+extern t_type* g_type_void;
+extern t_type* g_type_string;
+extern t_type* g_type_binary;
+extern t_type* g_type_slist;
+extern t_type* g_type_bool;
+extern t_type* g_type_i8;
+extern t_type* g_type_i16;
+extern t_type* g_type_i32;
+extern t_type* g_type_i64;
+extern t_type* g_type_double;
+
+void initGlobals();
+void clearGlobals();
+
+#endif