Thrift now a TLP - INFRA-3116

git-svn-id: https://svn.apache.org/repos/asf/thrift/branches/0.1.x@1028168 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/compiler/cpp/src/parse/t_program.h b/compiler/cpp/src/parse/t_program.h
new file mode 100644
index 0000000..4e1ab6a
--- /dev/null
+++ b/compiler/cpp/src/parse/t_program.h
@@ -0,0 +1,223 @@
+/*
+ * 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_PROGRAM_H
+#define T_PROGRAM_H
+
+#include <map>
+#include <string>
+#include <vector>
+
+// For program_name()
+#include "main.h"
+
+#include "t_doc.h"
+#include "t_scope.h"
+#include "t_base_type.h"
+#include "t_typedef.h"
+#include "t_enum.h"
+#include "t_const.h"
+#include "t_struct.h"
+#include "t_service.h"
+#include "t_list.h"
+#include "t_map.h"
+#include "t_set.h"
+//#include "t_doc.h"
+
+/**
+ * Top level class representing an entire thrift program. A program consists
+ * fundamentally of the following:
+ *
+ *   Typedefs
+ *   Enumerations
+ *   Constants
+ *   Structs
+ *   Exceptions
+ *   Services
+ *
+ * The program module also contains the definitions of the base types.
+ *
+ */
+class t_program : public t_doc {
+ public:
+  t_program(std::string path, std::string name) :
+    path_(path),
+    name_(name),
+    out_path_("./") {
+    scope_ = new t_scope();
+  }
+
+  t_program(std::string path) :
+    path_(path),
+    out_path_("./") {
+    name_ = program_name(path);
+    scope_ = new t_scope();
+  }
+
+  // Path accessor
+  const std::string& get_path() const { return path_; }
+
+  // Output path accessor
+  const std::string& get_out_path() const { return out_path_; }
+
+  // Name accessor
+  const std::string& get_name() const { return name_; }
+
+  // Namespace
+  const std::string& get_namespace() const { return namespace_; }
+
+  // Include prefix accessor
+  const std::string& get_include_prefix() const { return include_prefix_; }
+
+  // Accessors for program elements
+  const std::vector<t_typedef*>& get_typedefs()  const { return typedefs_;  }
+  const std::vector<t_enum*>&    get_enums()     const { return enums_;     }
+  const std::vector<t_const*>&   get_consts()    const { return consts_;    }
+  const std::vector<t_struct*>&  get_structs()   const { return structs_;   }
+  const std::vector<t_struct*>&  get_xceptions() const { return xceptions_; }
+  const std::vector<t_struct*>&  get_objects()   const { return objects_;   }
+  const std::vector<t_service*>& get_services()  const { return services_;  }
+
+  // Program elements
+  void add_typedef  (t_typedef* td) { typedefs_.push_back(td);  }
+  void add_enum     (t_enum*    te) { enums_.push_back(te);     }
+  void add_const    (t_const*   tc) { consts_.push_back(tc);    }
+  void add_struct   (t_struct*  ts) { objects_.push_back(ts);
+                                      structs_.push_back(ts);   }
+  void add_xception (t_struct*  tx) { objects_.push_back(tx);
+                                      xceptions_.push_back(tx); }
+  void add_service  (t_service* ts) { services_.push_back(ts);  }
+
+  // Programs to include
+  const std::vector<t_program*>& get_includes() const { return includes_; }
+
+  void set_out_path(std::string out_path) {
+    out_path_ = out_path;
+    // Ensure that it ends with a trailing '/' (or '\' for windows machines)
+    char c = out_path_.at(out_path_.size() - 1);
+    if (!(c == '/' || c == '\\')) {
+      out_path_.push_back('/');
+    }
+  }
+
+  // Scoping and namespacing
+  void set_namespace(std::string name) {
+    namespace_ = name;
+  }
+
+  // Scope accessor
+  t_scope* scope() {
+    return scope_;
+  }
+
+  // Includes
+
+  void add_include(std::string path, std::string include_site) {
+    t_program* program = new t_program(path);
+
+    // include prefix for this program is the site at which it was included
+    // (minus the filename)
+    std::string include_prefix;
+    std::string::size_type last_slash = std::string::npos;
+    if ((last_slash = include_site.rfind("/")) != std::string::npos) {
+      include_prefix = include_site.substr(0, last_slash);
+    }
+
+    program->set_include_prefix(include_prefix);
+    includes_.push_back(program);
+  }
+
+  std::vector<t_program*>& get_includes() {
+    return includes_;
+  }
+
+  void set_include_prefix(std::string include_prefix) {
+    include_prefix_ = include_prefix;
+
+    // this is intended to be a directory; add a trailing slash if necessary
+    int len = include_prefix_.size();
+    if (len > 0 && include_prefix_[len - 1] != '/') {
+      include_prefix_ += '/';
+    }
+  }
+
+  // Language neutral namespace / packaging
+  void set_namespace(std::string language, std::string name_space) {
+    namespaces_[language] = name_space;
+  }
+
+  std::string get_namespace(std::string language) const {
+    std::map<std::string, std::string>::const_iterator iter = namespaces_.find(language);
+    if (iter == namespaces_.end()) {
+      return std::string();
+    }
+    return iter->second;
+  }
+
+  // Language specific namespace / packaging
+
+  void add_cpp_include(std::string path) {
+    cpp_includes_.push_back(path);
+  }
+
+  const std::vector<std::string>& get_cpp_includes() {
+    return cpp_includes_;
+  }
+
+ private:
+
+  // File path
+  std::string path_;
+
+  // Name
+  std::string name_;
+
+  // Output directory
+  std::string out_path_;
+
+  // Namespace
+  std::string namespace_;
+
+  // Included programs
+  std::vector<t_program*> includes_;
+
+  // Include prefix for this program, if any
+  std::string include_prefix_;
+
+  // Identifier lookup scope
+  t_scope* scope_;
+
+  // Components to generate code for
+  std::vector<t_typedef*> typedefs_;
+  std::vector<t_enum*>    enums_;
+  std::vector<t_const*>   consts_;
+  std::vector<t_struct*>  objects_;
+  std::vector<t_struct*>  structs_;
+  std::vector<t_struct*>  xceptions_;
+  std::vector<t_service*> services_;
+
+  // Dynamic namespaces
+  std::map<std::string, std::string> namespaces_;
+
+  // C++ extra includes
+  std::vector<std::string> cpp_includes_;
+
+};
+
+#endif