// Copyright 2017 Google Inc. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#ifndef NINJA_PROTO_H_
#define NINJA_PROTO_H_

#include <iostream>

// This file and proto.cc implement a minimal write-only protobuf runtime to be
// used with headers generated by misc/generate_proto_header.py.

// Based on https://github.com/google/protobuf/blob/3.0.x/src/google/protobuf/wire_format_lite.h
static inline uint32_t ZigZagEncode32(int32_t n) {
  // Note:  the right-shift must be arithmetic
  return (static_cast<uint32_t>(n) << 1) ^ (n >> 31);
}

static inline uint64_t ZigZagEncode64(int64_t n) {
  // Note:  the right-shift must be arithmetic
  return (static_cast<uint64_t>(n) << 1) ^ (n >> 63);
}

// Based on https://github.com/google/protobuf/blob/3.0.x/src/google/protobuf/io/coded_stream.h
static inline size_t VarintSize32(uint32_t value) {
  if (value < (1 << 7)) {
    return 1;
  } else if (value < (1 << 14)) {
    return 2;
  } else if (value < (1 << 21)) {
    return 3;
  } else if (value < (1 << 28)) {
    return 4;
  } else {
    return 5;
  }
}

static inline size_t VarintSize32SignExtended(int32_t value) {
  if (value < 0) {
    return 10;     // TODO(kenton):  Make this a symbolic constant.
  } else {
    return VarintSize32(static_cast<uint32_t>(value));
  }
}

static inline size_t VarintSize64(uint64_t value) {
  if (value < (1ull << 35)) {
    if (value < (1ull << 7)) {
      return 1;
    } else if (value < (1ull << 14)) {
      return 2;
    } else if (value < (1ull << 21)) {
      return 3;
    } else if (value < (1ull << 28)) {
      return 4;
    } else {
      return 5;
    }
  } else {
    if (value < (1ull << 42)) {
      return 6;
    } else if (value < (1ull << 49)) {
      return 7;
    } else if (value < (1ull << 56)) {
      return 8;
    } else if (value < (1ull << 63)) {
      return 9;
    } else {
      return 10;
    }
  }
}

static inline size_t VarintSizeBool(bool /*value*/) {
  return 1;
}

static inline size_t FixedSize32(uint32_t /*value*/) {
  return 4;
}

static inline size_t FixedSize64(uint64_t /*value*/) {
  return 8;
}

static inline size_t StringSize(const std::string& value) {
  return VarintSize32(value.size()) + value.size();
}

void WriteVarint32(std::ostream* output, int number, uint32_t value);
void WriteVarint32NoTag(std::ostream* output, uint32_t value);
void WriteVarint32SignExtended(std::ostream* output, int number, int32_t value);
void WriteVarint64(std::ostream* output, int number, uint64_t value);
void WriteFixed32(std::ostream* output, int number, uint32_t value);
void WriteFixed64(std::ostream* output, int number, uint64_t value);
void WriteString(std::ostream* output, int number, const std::string& value);
void WriteLengthDelimited(std::ostream* output, int number, size_t size);

#endif
