• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* Copyright 2019 The TensorFlow Authors. All Rights Reserved.
2 
3 Licensed under the Apache License, Version 2.0 (the "License");
4 you may not use this file except in compliance with the License.
5 You may obtain a copy of the License at
6 
7     http://www.apache.org/licenses/LICENSE-2.0
8 
9 Unless required by applicable law or agreed to in writing, software
10 distributed under the License is distributed on an "AS IS" BASIS,
11 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 See the License for the specific language governing permissions and
13 limitations under the License.
14 ==============================================================================*/
15 #ifndef TENSORFLOW_TENSORFLOW_LITE_SUPPORT_CODEGEN_UTILS_H_
16 #define TENSORFLOW_TENSORFLOW_LITE_SUPPORT_CODEGEN_UTILS_H_
17 
18 #include <map>
19 #include <sstream>
20 #include <string>
21 
22 namespace tflite {
23 namespace support {
24 namespace codegen {
25 
26 /// Collects runtime error logs which could be showed later.
27 // TODO(b/150538286): Consider a better mechanism to simplify callsite code.
28 class ErrorReporter {
29  public:
30   int Warning(const char* format, ...);
31   int Error(const char* format, ...);
32   std::string GetMessage();
33 
34  private:
35   int Report(const char* prefix, const char* format, va_list args);
36   std::stringstream buffer_;
37 };
38 
39 /// Implements basic code generating with text templates.
40 ///
41 /// It could accept code templates and concatenate them into complete codes. A
42 /// template could contain named values.
43 ///
44 /// Example code:
45 ///   CodeWriter code;
46 ///   code.SetValue("NAME", "Foo");
47 ///   code.Append("void {{NAME}}() { printf("%s", "{{NAME}}"); }");
48 ///   code.SetValue("NAME", "Bar");
49 ///   code.Append("void {{NAME}}() { printf("%s", "{{NAME}}"); }");
50 ///
51 /// Output:
52 ///  void Foo() { printf("%s", "Foo"); }
53 ///  void Bar() { printf("%s", "Bar"); }
54 class CodeWriter {
55  public:
56   explicit CodeWriter(ErrorReporter* err);
57   /// Sets value to a token. When generating code with template, a string in a
58   /// pair of {{ and }} will be regarded as a token and replaced with the
59   /// corresponding value in code generation.
60   /// It rewrites if the token already has a value.
61   void SetTokenValue(const std::string& token, const std::string& value);
62 
63   /// Gets the current value set on the given token.
64   const std::string GetTokenValue(const std::string& token) const;
65 
66   /// Sets the unit indent string. For example, in Java it should be "  ".
67   void SetIndentString(const std::string& indent);
68 
69   /// Increases the indent by a unit (the string set in SetIndentString).
70   void Indent();
71 
72   /// Decreases the indent by a unit (the string set in SetIndentString).
73   void Outdent();
74 
75   /// Generates the indentation string.
76   std::string GenerateIndent() const;
77 
78   /// Appends a piece of template codes to the stream. Every named value will be
79   /// replaced via the real value. A new line will always be appended at the
80   /// end.
81   void Append(const std::string& text);
82 
83   /// Appends a piece of template codes to the stream. Same with `Append`, but a
84   /// new line will not be appended at the end.
85   void AppendNoNewLine(const std::string& text);
86 
87   /// Appends a new line to the stream.
88   void NewLine();
89 
90   /// Deletes the last N charaters in the stream. If the stream has less than N
91   /// characters, deletes all.
92   void Backspace(int n);
93 
94   std::string ToString() const;
95 
96   /// Checks if the internal string stream is empty. Note: This method has
97   // overhead.
98   bool IsStreamEmpty() const;
99 
100   /// Clears all the internal string stream and value map.
101   void Clear();
102 
103  private:
104   void AppendInternal(const std::string& text, bool newline);
105 
106   std::string indent_str_;
107   int indent_;
108 
109   std::map<std::string, std::string> value_map_;
110   std::string buffer_;
111 
112   ErrorReporter* err_;
113 };
114 
115 /// Converts foo_bar_name to fooBarName. It's callers duty to make sure given
116 /// string "s" is already in snake case; or unexpected behavior may occur.
117 std::string SnakeCaseToCamelCase(const std::string& s);
118 
119 /// Joins 2 parts of file path into one, connected by unix path seperator '/'.
120 /// It's callers duty to ensure the two parts are valid.
121 std::string JoinPath(const std::string& a, const std::string& b);
122 
123 }  // namespace codegen
124 }  // namespace support
125 }  // namespace tflite
126 
127 #endif  // TENSORFLOW_TENSORFLOW_LITE_SUPPORT_CODEGEN_UTILS_H_
128