void CodeWriter::AppendInternal()

in tensorflow_lite_support/codegen/utils.cc [91:145]


void CodeWriter::AppendInternal(const std::string& text, bool newline) {
  // Prefix indent
  if ((buffer_.empty()             // nothing in the buffer
       || buffer_.back() == '\n')  // is on new line
      // is writing on current line
      && (!text.empty() && text[0] != '\n' && text[0] != '\r')) {
    buffer_.append(GenerateIndent());
  }
  // State machine variables
  bool in_token = false;
  int i = 0;
  // Rough memory reserve
  buffer_.reserve(buffer_.size() + text.size());
  std::string token_buffer;
  // A simple LL1 analysis
  while (i < text.size()) {
    char cur = text[i];
    char cur_next = i == text.size() - 1 ? '\0' : text[i + 1];  // Set guardian
    if (!in_token) {
      if (cur == '{' && cur_next == '{') {  // Enter token
        in_token = true;
        i += 2;
      } else if (cur == '\n') {  // We need to apply global indent here
        buffer_.push_back(cur);
        if (cur_next != '\0' && cur_next != '\n' && cur_next != '\r') {
          buffer_.append(GenerateIndent());
        }
        i += 1;
      } else {
        buffer_.push_back(cur);
        i += 1;
      }
    } else {
      if (cur == '}' && cur_next == '}') {  // Close token
        in_token = false;
        const auto value = GetTokenValue(token_buffer);
        buffer_.append(value);
        token_buffer.clear();
        i += 2;
      } else {
        token_buffer.push_back(cur);
        i += 1;
      }
    }
  }
  if (!token_buffer.empty()) {
    // Typically only Code Generator's call this function. It's
    // their duty to make sure the code (or template) has valid syntax, and
    // unclosed "{{...}}" implicits severe error in the template.
    err_->Error("Internal: Invalid template: {{token}} is not closed.");
  }
  if (newline) {
    buffer_.push_back('\n');
  }
}