Line data Source code
1 : /* 2 : * Licensed to the Apache Software Foundation (ASF) under one 3 : * or more contributor license agreements. See the NOTICE file 4 : * distributed with this work for additional information 5 : * regarding copyright ownership. The ASF licenses this file 6 : * to you under the Apache License, Version 2.0 (the 7 : * "License"); you may not use this file except in compliance 8 : * with the License. You may obtain a copy of the License at 9 : * 10 : * http://www.apache.org/licenses/LICENSE-2.0 11 : * 12 : * Unless required by applicable law or agreed to in writing, 13 : * software distributed under the License is distributed on an 14 : * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 : * KIND, either express or implied. See the License for the 16 : * specific language governing permissions and limitations 17 : * under the License. 18 : * 19 : * Modifications Copyright (c) Juniper Networks, Inc. 20 : * Copyright Contributors to the OpenSDN project 21 : */ 22 : 23 : #ifndef T_PROGRAM_H 24 : #define T_PROGRAM_H 25 : 26 : #include <map> 27 : #include <string> 28 : #include <vector> 29 : 30 : // For program_name() 31 : #include "main.h" 32 : 33 : #include "t_doc.h" 34 : #include "t_scope.h" 35 : #include "t_base_type.h" 36 : #include "t_typedef.h" 37 : #include "t_enum.h" 38 : #include "t_const.h" 39 : #include "t_struct.h" 40 : #include "t_service.h" 41 : #include "t_list.h" 42 : #include "t_map.h" 43 : #include "t_set.h" 44 : #ifdef SANDESH 45 : #include "t_sandesh.h" 46 : #endif 47 : #include "generate/t_generator_registry.h" 48 : //#include "t_doc.h" 49 : 50 : /** 51 : * Top level class representing an entire thrift program. A program consists 52 : * fundamentally of the following: 53 : * 54 : * Typedefs 55 : * Enumerations 56 : * Constants 57 : * Structs 58 : * Exceptions 59 : * Services 60 : #ifdef SANDESH 61 : * Sandeshs 62 : #endif 63 : * 64 : * The program module also contains the definitions of the base types. 65 : * 66 : */ 67 : class t_program : public t_doc { 68 : public: 69 : t_program(std::string path, std::string name) : 70 : path_(path), 71 : name_(name), 72 : out_path_("./"), 73 : out_path_is_absolute_(false) { 74 : scope_ = new t_scope(); 75 : } 76 : 77 776 : t_program(std::string path) : 78 776 : path_(path), 79 776 : out_path_("./"), 80 2328 : out_path_is_absolute_(false) { 81 776 : name_ = program_name(path); 82 776 : scope_ = new t_scope(); 83 776 : } 84 : 85 : // Path accessor 86 1338 : const std::string& get_path() const { return path_; } 87 : 88 : // Output path accessor 89 2506 : const std::string& get_out_path() const { return out_path_; } 90 : 91 : // Create gen-* dir accessor 92 2506 : bool is_out_path_absolute() { return out_path_is_absolute_; } 93 : 94 : // Name accessor 95 3503 : const std::string& get_name() const { return name_; } 96 : 97 : // Namespace 98 : const std::string& get_namespace() const { return namespace_; } 99 : 100 : // Include prefix accessor 101 1350 : const std::string& get_include_prefix() const { return include_prefix_; } 102 : 103 : // Accessors for program elements 104 398 : const std::vector<t_typedef*>& get_typedefs() const { return typedefs_; } 105 960 : const std::vector<t_enum*>& get_enums() const { return enums_; } 106 398 : const std::vector<t_const*>& get_consts() const { return consts_; } 107 562 : const std::vector<t_struct*>& get_structs() const { return structs_; } 108 562 : const std::vector<t_struct*>& get_xceptions() const { return xceptions_; } 109 936 : const std::vector<t_struct*>& get_objects() const { return objects_; } 110 563 : const std::vector<t_service*>& get_services() const { return services_; } 111 : #ifdef SANDESH 112 1630 : const std::vector<t_sandesh*>& get_sandeshs() const { return sandeshs_; } 113 : #endif 114 : 115 : // Program elements 116 4 : void add_typedef (t_typedef* td) { typedefs_.push_back(td); } 117 505 : void add_enum (t_enum* te) { enums_.push_back(te); } 118 3481 : void add_const (t_const* tc) { consts_.push_back(tc); } 119 4524 : void add_struct (t_struct* ts) { objects_.push_back(ts); 120 4524 : structs_.push_back(ts); } 121 0 : void add_xception (t_struct* tx) { objects_.push_back(tx); 122 0 : xceptions_.push_back(tx); } 123 0 : void add_service (t_service* ts) { services_.push_back(ts); } 124 : #ifdef SANDESH 125 5804 : void add_sandesh (t_sandesh* ts) { sandeshs_.push_back(ts); } 126 : #endif 127 : 128 : // Programs to include 129 35 : const std::vector<t_program*>& get_includes() const { return includes_; } 130 : 131 562 : void set_out_path(std::string out_path, bool out_path_is_absolute) { 132 562 : out_path_ = out_path; 133 562 : out_path_is_absolute_ = out_path_is_absolute; 134 : // Ensure that it ends with a trailing '/') 135 562 : char c = out_path_.at(out_path_.size() - 1); 136 562 : if (!(c == '/')) { 137 561 : out_path_.push_back('/'); 138 : } 139 562 : } 140 : 141 : // Scoping and namespacing 142 : void set_namespace(std::string name) { 143 : namespace_ = name; 144 : } 145 : 146 : // Scope accessor 147 1766 : t_scope* scope() { 148 1766 : return scope_; 149 : } 150 : 151 : // Includes 152 : 153 214 : void add_include(std::string path, std::string include_site) { 154 214 : t_program* program = new t_program(path); 155 : 156 : // include prefix for this program is the site at which it was included 157 : // (minus the filename) 158 214 : std::string include_prefix; 159 214 : std::string::size_type last_slash = std::string::npos; 160 214 : if ((last_slash = include_site.rfind("/")) != std::string::npos) { 161 214 : include_prefix = include_site.substr(0, last_slash); 162 : } 163 : 164 214 : program->set_include_prefix(include_prefix); 165 214 : includes_.push_back(program); 166 214 : } 167 : 168 1174 : std::vector<t_program*>& get_includes() { 169 1174 : return includes_; 170 : } 171 : 172 776 : void set_include_prefix(std::string include_prefix) { 173 776 : include_prefix_ = include_prefix; 174 : 175 : // this is intended to be a directory; add a trailing slash if necessary 176 776 : int len = include_prefix_.size(); 177 776 : if (len > 0 && include_prefix_[len - 1] != '/') { 178 776 : include_prefix_ += '/'; 179 : } 180 776 : } 181 : 182 : // Language neutral namespace / packaging 183 94 : void set_namespace(std::string language, std::string name_space) { 184 : #if 0 185 : if (language != "*") { 186 : size_t sub_index = language.find('.'); 187 : std::string base_language = language.substr(0, sub_index); 188 : std::string sub_namespace; 189 : 190 : if(base_language == "smalltalk") { 191 : pwarning(1, "Namespace 'smalltalk' is deprecated. Use 'st' instead"); 192 : base_language = "st"; 193 : } 194 : 195 : t_generator_registry::gen_map_t my_copy = t_generator_registry::get_generator_map(); 196 : 197 : t_generator_registry::gen_map_t::iterator it; 198 : it=my_copy.find(base_language); 199 : 200 : if (it == my_copy.end()) { 201 : throw "No generator named '" + base_language + "' could be found!"; 202 : } 203 : 204 : if (sub_index != std::string::npos) { 205 : std::string sub_namespace = language.substr(sub_index+1); 206 : if(! it->second->is_valid_namespace(sub_namespace)) { 207 : throw base_language +" generator does not accept '" + sub_namespace + "' as sub-namespace!"; 208 : } 209 : } 210 : } 211 : #endif 212 : 213 94 : namespaces_[language] = name_space; 214 94 : } 215 : 216 2488 : std::string get_namespace(std::string language) const { 217 2488 : std::map<std::string, std::string>::const_iterator iter; 218 4257 : if ((iter = namespaces_.find(language)) != namespaces_.end() || 219 4257 : (iter = namespaces_.find("*" )) != namespaces_.end()) { 220 719 : return iter->second; 221 : } 222 1769 : return std::string(); 223 : } 224 : 225 : // Language specific namespace / packaging 226 : 227 0 : void add_cpp_include(std::string path) { 228 0 : cpp_includes_.push_back(path); 229 0 : } 230 : 231 228 : const std::vector<std::string>& get_cpp_includes() { 232 228 : return cpp_includes_; 233 : } 234 : 235 : void add_c_include(std::string path) { 236 : c_includes_.push_back(path); 237 : } 238 : 239 5 : const std::vector<std::string>& get_c_includes() { 240 5 : return c_includes_; 241 : } 242 : 243 : #ifdef SANDESH 244 538 : t_struct* get_struct(const char *name) const { 245 : // Extract structs, exceptions, or unions matching the name 246 538 : std::vector<t_struct*> objects = get_objects(); 247 538 : std::vector<t_struct*>::iterator o_iter; 248 5000 : for (o_iter = objects.begin(); o_iter != objects.end(); ++o_iter) { 249 4944 : if (strcmp(((*o_iter)->get_name()).c_str(), name) == 0) { 250 482 : return *o_iter; 251 : } 252 : } 253 56 : return NULL; 254 538 : } 255 : #endif 256 : 257 : private: 258 : 259 : // File path 260 : std::string path_; 261 : 262 : // Name 263 : std::string name_; 264 : 265 : // Output directory 266 : std::string out_path_; 267 : 268 : // Output directory is absolute location for generated source (no gen-*) 269 : bool out_path_is_absolute_; 270 : 271 : // Namespace 272 : std::string namespace_; 273 : 274 : // Included programs 275 : std::vector<t_program*> includes_; 276 : 277 : // Include prefix for this program, if any 278 : std::string include_prefix_; 279 : 280 : // Identifier lookup scope 281 : t_scope* scope_; 282 : 283 : // Components to generate code for 284 : std::vector<t_typedef*> typedefs_; 285 : std::vector<t_enum*> enums_; 286 : std::vector<t_const*> consts_; 287 : std::vector<t_struct*> objects_; 288 : std::vector<t_struct*> structs_; 289 : std::vector<t_struct*> xceptions_; 290 : std::vector<t_service*> services_; 291 : #ifdef SANDESH 292 : std::vector<t_sandesh*> sandeshs_; 293 : #endif 294 : 295 : // Dynamic namespaces 296 : std::map<std::string, std::string> namespaces_; 297 : 298 : // C++ extra includes 299 : std::vector<std::string> cpp_includes_; 300 : 301 : // C extra includes 302 : std::vector<std::string> c_includes_; 303 : 304 : }; 305 : 306 : #endif