// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc.  All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
//     * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//     * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
//     * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

// Author: kenton@google.com (Kenton Varda)
//  Based on original Protocol Buffers design by
//  Sanjay Ghemawat, Jeff Dean, and others.

#include <google/protobuf/io/printer.h>

#include <cctype>

#include <google/protobuf/stubs/logging.h>
#include <google/protobuf/stubs/common.h>
#include <google/protobuf/io/zero_copy_stream.h>

namespace google {
namespace protobuf {
namespace io {

Printer::Printer(ZeroCopyOutputStream* output, char variable_delimiter)
    : variable_delimiter_(variable_delimiter),
      output_(output),
      buffer_(NULL),
      buffer_size_(0),
      offset_(0),
      at_start_of_line_(true),
      failed_(false),
      annotation_collector_(NULL) {}

Printer::Printer(ZeroCopyOutputStream* output, char variable_delimiter,
                 AnnotationCollector* annotation_collector)
    : variable_delimiter_(variable_delimiter),
      output_(output),
      buffer_(NULL),
      buffer_size_(0),
      offset_(0),
      at_start_of_line_(true),
      failed_(false),
      annotation_collector_(annotation_collector) {}

Printer::~Printer() {
  // Only BackUp() if we have called Next() at least once and never failed.
  if (buffer_size_ > 0 && !failed_) {
    output_->BackUp(buffer_size_);
  }
}

bool Printer::GetSubstitutionRange(const char* varname,
                                   std::pair<size_t, size_t>* range) {
  std::map<std::string, std::pair<size_t, size_t> >::const_iterator iter =
      substitutions_.find(varname);
  if (iter == substitutions_.end()) {
    GOOGLE_LOG(DFATAL) << " Undefined variable in annotation: " << varname;
    return false;
  }
  if (iter->second.first > iter->second.second) {
    GOOGLE_LOG(DFATAL) << " Variable used for annotation used multiple times: "
                << varname;
    return false;
  }
  *range = iter->second;
  return true;
}

void Printer::Annotate(const char* begin_varname, const char* end_varname,
                       const std::string& file_path,
                       const std::vector<int>& path) {
  if (annotation_collector_ == NULL) {
    // Can't generate signatures with this Printer.
    return;
  }
  std::pair<size_t, size_t> begin, end;
  if (!GetSubstitutionRange(begin_varname, &begin) ||
      !GetSubstitutionRange(end_varname, &end)) {
    return;
  }
  if (begin.first > end.second) {
    GOOGLE_LOG(DFATAL) << "  Annotation has negative length from " << begin_varname
                << " to " << end_varname;
  } else {
    annotation_collector_->AddAnnotation(begin.first, end.second, file_path,
                                         path);
  }
}

void Printer::Print(const std::map<std::string, std::string>& variables,
                    const char* text) {
  int size = strlen(text);
  int pos = 0;  // The number of bytes we've written so far.
  substitutions_.clear();
  line_start_variables_.clear();

  for (int i = 0; i < size; i++) {
    if (text[i] == '\n') {
      // Saw newline.  If there is more text, we may need to insert an indent
      // here.  So, write what we have so far, including the '\n'.
      WriteRaw(text + pos, i - pos + 1);
      pos = i + 1;

      // Setting this true will cause the next WriteRaw() to insert an indent
      // first.
      at_start_of_line_ = true;
      line_start_variables_.clear();

    } else if (text[i] == variable_delimiter_) {
      // Saw the start of a variable name.

      // Write what we have so far.
      WriteRaw(text + pos, i - pos);
      pos = i + 1;

      // Find closing delimiter.
      const char* end = strchr(text + pos, variable_delimiter_);
      if (end == NULL) {
        GOOGLE_LOG(DFATAL) << " Unclosed variable name.";
        end = text + pos;
      }
      int endpos = end - text;

      std::string varname(text + pos, endpos - pos);
      if (varname.empty()) {
        // Two delimiters in a row reduce to a literal delimiter character.
        WriteRaw(&variable_delimiter_, 1);
      } else {
        // Replace with the variable's value.
        std::map<std::string, std::string>::const_iterator iter =
            variables.find(varname);
        if (iter == variables.end()) {
          GOOGLE_LOG(DFATAL) << " Undefined variable: " << varname;
        } else {
          if (at_start_of_line_ && iter->second.empty()) {
            line_start_variables_.push_back(varname);
          }
          WriteRaw(iter->second.data(), iter->second.size());
          std::pair<std::map<std::string, std::pair<size_t, size_t> >::iterator,
                    bool>
              inserted = substitutions_.insert(std::make_pair(
                  varname,
                  std::make_pair(offset_ - iter->second.size(), offset_)));
          if (!inserted.second) {
            // This variable was used multiple times.  Make its span have
            // negative length so we can detect it if it gets used in an
            // annotation.
            inserted.first->second = std::make_pair(1, 0);
          }
        }
      }

      // Advance past this variable.
      i = endpos;
      pos = endpos + 1;
    }
  }

  // Write the rest.
  WriteRaw(text + pos, size - pos);
}

void Printer::Indent() { indent_ += "  "; }

void Printer::Outdent() {
  if (indent_.empty()) {
    GOOGLE_LOG(DFATAL) << " Outdent() without matching Indent().";
    return;
  }

  indent_.resize(indent_.size() - 2);
}

void Printer::PrintRaw(const std::string& data) {
  WriteRaw(data.data(), data.size());
}

void Printer::PrintRaw(const char* data) {
  if (failed_) return;
  WriteRaw(data, strlen(data));
}

void Printer::WriteRaw(const char* data, int size) {
  if (failed_) return;
  if (size == 0) return;

  if (at_start_of_line_ && (size > 0) && (data[0] != '\n')) {
    // Insert an indent.
    at_start_of_line_ = false;
    CopyToBuffer(indent_.data(), indent_.size());
    if (failed_) return;
    // Fix up empty variables (e.g., "{") that should be annotated as
    // coming after the indent.
    for (std::vector<std::string>::iterator i = line_start_variables_.begin();
         i != line_start_variables_.end(); ++i) {
      substitutions_[*i].first += indent_.size();
      substitutions_[*i].second += indent_.size();
    }
  }

  // If we're going to write any data, clear line_start_variables_, since
  // we've either updated them in the block above or they no longer refer to
  // the current line.
  line_start_variables_.clear();

  CopyToBuffer(data, size);
}

bool Printer::Next() {
  do {
    void* void_buffer;
    if (!output_->Next(&void_buffer, &buffer_size_)) {
      failed_ = true;
      return false;
    }
    buffer_ = reinterpret_cast<char*>(void_buffer);
  } while (buffer_size_ == 0);
  return true;
}

void Printer::CopyToBuffer(const char* data, int size) {
  if (failed_) return;
  if (size == 0) return;

  while (size > buffer_size_) {
    // Data exceeds space in the buffer.  Copy what we can and request a
    // new buffer.
    if (buffer_size_ > 0) {
      memcpy(buffer_, data, buffer_size_);
      offset_ += buffer_size_;
      data += buffer_size_;
      size -= buffer_size_;
    }
    void* void_buffer;
    failed_ = !output_->Next(&void_buffer, &buffer_size_);
    if (failed_) return;
    buffer_ = reinterpret_cast<char*>(void_buffer);
  }

  // Buffer is big enough to receive the data; copy it.
  memcpy(buffer_, data, size);
  buffer_ += size;
  buffer_size_ -= size;
  offset_ += size;
}

void Printer::IndentIfAtStart() {
  if (at_start_of_line_) {
    CopyToBuffer(indent_.data(), indent_.size());
    at_start_of_line_ = false;
  }
}

void Printer::FormatInternal(const std::vector<std::string>& args,
                             const std::map<std::string, std::string>& vars,
                             const char* format) {
  auto save = format;
  int arg_index = 0;
  std::vector<AnnotationCollector::Annotation> annotations;
  while (*format) {
    char c = *format++;
    switch (c) {
      case '$':
        format = WriteVariable(args, vars, format, &arg_index, &annotations);
        continue;
      case '\n':
        at_start_of_line_ = true;
        line_start_variables_.clear();
        break;
      default:
        IndentIfAtStart();
        break;
    }
    push_back(c);
  }
  if (arg_index != static_cast<int>(args.size())) {
    GOOGLE_LOG(FATAL) << " Unused arguments. " << save;
  }
  if (!annotations.empty()) {
    GOOGLE_LOG(FATAL) << " Annotation range is not-closed, expect $}$. " << save;
  }
}

const char* Printer::WriteVariable(
    const std::vector<std::string>& args,
    const std::map<std::string, std::string>& vars, const char* format,
    int* arg_index, std::vector<AnnotationCollector::Annotation>* annotations) {
  auto start = format;
  auto end = strchr(format, '$');
  if (!end) {
    GOOGLE_LOG(FATAL) << " Unclosed variable name.";
  }
  format = end + 1;
  if (end == start) {
    // "$$" is an escape for just '$'
    IndentIfAtStart();
    push_back('$');
    return format;
  }
  if (*start == '{') {
    GOOGLE_CHECK(std::isdigit(start[1]));
    GOOGLE_CHECK_EQ(end - start, 2);
    int idx = start[1] - '1';
    if (idx < 0 || static_cast<size_t>(idx) >= args.size()) {
      GOOGLE_LOG(FATAL) << "Annotation ${" << idx + 1 << "$ is out of bounds.";
    }
    if (idx > *arg_index) {
      GOOGLE_LOG(FATAL) << "Annotation arg must be in correct order as given. Expected"
                 << " ${" << (*arg_index) + 1 << "$ got ${" << idx + 1 << "$.";
    } else if (idx == *arg_index) {
      (*arg_index)++;
    }
    IndentIfAtStart();
    annotations->push_back({{offset_, 0}, args[idx]});
    return format;
  } else if (*start == '}') {
    GOOGLE_CHECK(annotations);
    if (annotations->empty()) {
      GOOGLE_LOG(FATAL) << "Unexpected end of annotation found.";
    }
    auto& a = annotations->back();
    a.first.second = offset_;
    if (annotation_collector_) annotation_collector_->AddAnnotationNew(a);
    annotations->pop_back();
    return format;
  }
  auto start_var = start;
  while (start_var < end && *start_var == ' ') start_var++;
  if (start_var == end) {
    GOOGLE_LOG(FATAL) << " Empty variable.";
  }
  auto end_var = end;
  while (start_var < end_var && *(end_var - 1) == ' ') end_var--;
  std::string var_name{
      start_var, static_cast<std::string::size_type>(end_var - start_var)};
  std::string sub;
  if (std::isdigit(var_name[0])) {
    GOOGLE_CHECK_EQ(var_name.size(), 1U);  // No need for multi-digits
    int idx = var_name[0] - '1';   // Start counting at 1
    GOOGLE_CHECK_GE(idx, 0);
    if (static_cast<size_t>(idx) >= args.size()) {
      GOOGLE_LOG(FATAL) << "Argument $" << idx + 1 << "$ is out of bounds.";
    }
    if (idx > *arg_index) {
      GOOGLE_LOG(FATAL) << "Arguments must be used in same order as given. Expected $"
                 << (*arg_index) + 1 << "$ got $" << idx + 1 << "$.";
    } else if (idx == *arg_index) {
      (*arg_index)++;
    }
    sub = args[idx];
  } else {
    auto it = vars.find(var_name);
    if (it == vars.end()) {
      GOOGLE_LOG(FATAL) << " Unknown variable: " << var_name << ".";
    }
    sub = it->second;
  }

  // By returning here in case of empty we also skip possible spaces inside
  // the $...$, i.e. "void$ dllexpor$ f();" -> "void f();" in the empty case.
  if (sub.empty()) return format;

  // We're going to write something non-empty so we need a possible indent.
  IndentIfAtStart();

  // Write the possible spaces in front.
  CopyToBuffer(start, start_var - start);
  // Write a non-empty substituted variable.
  CopyToBuffer(sub.c_str(), sub.size());
  // Finish off with writing possible trailing spaces.
  CopyToBuffer(end_var, end - end_var);
  return format;
}

}  // namespace io
}  // namespace protobuf
}  // namespace google
