1 /* 2 * Copyright 2014 Google Inc. All rights reserved. 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #ifndef FLATBUFFERS_CODE_GENERATORS_H_ 18 #define FLATBUFFERS_CODE_GENERATORS_H_ 19 20 #include <map> 21 #include <sstream> 22 #include "flatbuffers/idl.h" 23 24 namespace flatbuffers { 25 26 // Utility class to assist in generating code through use of text templates. 27 // 28 // Example code: 29 // CodeWriter code; 30 // code.SetValue("NAME", "Foo"); 31 // code += "void {{NAME}}() { printf("%s", "{{NAME}}"); }"; 32 // code.SetValue("NAME", "Bar"); 33 // code += "void {{NAME}}() { printf("%s", "{{NAME}}"); }"; 34 // std::cout << code.ToString() << std::endl; 35 // 36 // Output: 37 // void Foo() { printf("%s", "Foo"); } 38 // void Bar() { printf("%s", "Bar"); } 39 class CodeWriter { 40 public: CodeWriter()41 CodeWriter() {} 42 43 // Clears the current "written" code. Clear()44 void Clear() { 45 stream_.str(""); 46 stream_.clear(); 47 } 48 49 // Associates a key with a value. All subsequent calls to operator+=, where 50 // the specified key is contained in {{ and }} delimiters will be replaced by 51 // the given value. SetValue(const std::string & key,const std::string & value)52 void SetValue(const std::string &key, const std::string &value) { 53 value_map_[key] = value; 54 } 55 56 // Appends the given text to the generated code as well as a newline 57 // character. Any text within {{ and }} delimeters is replaced by values 58 // previously stored in the CodeWriter by calling SetValue above. The newline 59 // will be suppressed if the text ends with the \\ character. 60 void operator+=(std::string text); 61 62 // Returns the current contents of the CodeWriter as a std::string. ToString()63 std::string ToString() const { return stream_.str(); } 64 65 private: 66 std::map<std::string, std::string> value_map_; 67 std::stringstream stream_; 68 }; 69 70 class BaseGenerator { 71 public: 72 virtual bool generate() = 0; 73 74 static std::string NamespaceDir(const Parser &parser, const std::string &path, 75 const Namespace &ns); 76 77 protected: BaseGenerator(const Parser & parser,const std::string & path,const std::string & file_name,const std::string qualifying_start,const std::string qualifying_separator)78 BaseGenerator(const Parser &parser, const std::string &path, 79 const std::string &file_name, 80 const std::string qualifying_start, 81 const std::string qualifying_separator) 82 : parser_(parser), 83 path_(path), 84 file_name_(file_name), 85 qualifying_start_(qualifying_start), 86 qualifying_separator_(qualifying_separator) {} ~BaseGenerator()87 virtual ~BaseGenerator() {} 88 89 // No copy/assign. 90 BaseGenerator &operator=(const BaseGenerator &); 91 BaseGenerator(const BaseGenerator &); 92 93 std::string NamespaceDir(const Namespace &ns) const; 94 95 static const char *FlatBuffersGeneratedWarning(); 96 97 static std::string FullNamespace(const char *separator, const Namespace &ns); 98 99 static std::string LastNamespacePart(const Namespace &ns); 100 101 // tracks the current namespace for early exit in WrapInNameSpace 102 // c++, java and csharp returns a different namespace from 103 // the following default (no early exit, always fully qualify), 104 // which works for js and php CurrentNameSpace()105 virtual const Namespace *CurrentNameSpace() const { return nullptr; } 106 107 // Ensure that a type is prefixed with its namespace whenever it is used 108 // outside of its namespace. 109 std::string WrapInNameSpace(const Namespace *ns, 110 const std::string &name) const; 111 112 std::string WrapInNameSpace(const Definition &def) const; 113 114 std::string GetNameSpace(const Definition &def) const; 115 116 const Parser &parser_; 117 const std::string &path_; 118 const std::string &file_name_; 119 const std::string qualifying_start_; 120 const std::string qualifying_separator_; 121 }; 122 123 struct CommentConfig { 124 const char *first_line; 125 const char *content_line_prefix; 126 const char *last_line; 127 }; 128 129 extern void GenComment(const std::vector<std::string> &dc, 130 std::string *code_ptr, const CommentConfig *config, 131 const char *prefix = ""); 132 133 class FloatConstantGenerator { 134 public: ~FloatConstantGenerator()135 virtual ~FloatConstantGenerator() {} 136 std::string GenFloatConstant(const FieldDef &field) const; 137 138 private: 139 virtual std::string Value(double v, const std::string &src) const = 0; 140 virtual std::string Inf(double v) const = 0; 141 virtual std::string NaN(double v) const = 0; 142 143 virtual std::string Value(float v, const std::string &src) const = 0; 144 virtual std::string Inf(float v) const = 0; 145 virtual std::string NaN(float v) const = 0; 146 147 template<typename T> 148 std::string GenFloatConstantImpl(const FieldDef &field) const; 149 }; 150 151 class SimpleFloatConstantGenerator : public FloatConstantGenerator { 152 public: 153 SimpleFloatConstantGenerator(const char *nan_number, 154 const char *pos_inf_number, 155 const char *neg_inf_number); 156 157 private: 158 std::string Value(double v, 159 const std::string &src) const FLATBUFFERS_OVERRIDE; 160 std::string Inf(double v) const FLATBUFFERS_OVERRIDE; 161 std::string NaN(double v) const FLATBUFFERS_OVERRIDE; 162 163 std::string Value(float v, const std::string &src) const FLATBUFFERS_OVERRIDE; 164 std::string Inf(float v) const FLATBUFFERS_OVERRIDE; 165 std::string NaN(float v) const FLATBUFFERS_OVERRIDE; 166 167 const std::string nan_number_; 168 const std::string pos_inf_number_; 169 const std::string neg_inf_number_; 170 }; 171 172 // C++, C#, Java like generator. 173 class TypedFloatConstantGenerator : public FloatConstantGenerator { 174 public: 175 TypedFloatConstantGenerator(const char *double_prefix, 176 const char *single_prefix, const char *nan_number, 177 const char *pos_inf_number, 178 const char *neg_inf_number = ""); 179 180 private: 181 std::string Value(double v, 182 const std::string &src) const FLATBUFFERS_OVERRIDE; 183 std::string Inf(double v) const FLATBUFFERS_OVERRIDE; 184 185 std::string NaN(double v) const FLATBUFFERS_OVERRIDE; 186 187 std::string Value(float v, const std::string &src) const FLATBUFFERS_OVERRIDE; 188 std::string Inf(float v) const FLATBUFFERS_OVERRIDE; 189 std::string NaN(float v) const FLATBUFFERS_OVERRIDE; 190 191 std::string MakeNaN(const std::string &prefix) const; 192 std::string MakeInf(bool neg, const std::string &prefix) const; 193 194 const std::string double_prefix_; 195 const std::string single_prefix_; 196 const std::string nan_number_; 197 const std::string pos_inf_number_; 198 const std::string neg_inf_number_; 199 }; 200 201 } // namespace flatbuffers 202 203 #endif // FLATBUFFERS_CODE_GENERATORS_H_ 204