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
24namespace 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"); }
39class CodeWriter {
40 public:
41 CodeWriter() {}
42
43 // Clears the current "written" code.
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.
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.
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
70class 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:
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) {}
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
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
123struct CommentConfig {
124 const char *first_line;
125 const char *content_line_prefix;
126 const char *last_line;
127};
128
129extern void GenComment(const std::vector<std::string> &dc,
130 std::string *code_ptr, const CommentConfig *config,
131 const char *prefix = "");
132
133class FloatConstantGenerator {
134 public:
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
151class 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.
173class 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