• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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