// Protocol Buffers - Google's data interchange format
// Copyright 2023 Google LLC.  All rights reserved.
//
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file or at
// https://developers.google.com/open-source/licenses/bsd

#include "upb_generator/common.h"

#include <assert.h>
#include <stdint.h>
#include <stdlib.h>

#include <string>

#include "absl/strings/ascii.h"
#include "absl/strings/str_cat.h"
#include "absl/strings/str_replace.h"
#include "absl/strings/string_view.h"
#include "absl/strings/substitute.h"
#include "upb/mini_table/field.h"
#include "upb/reflection/def.hpp"
#include "upb_generator/mangle.h"

// Must be last
#include "upb/port/def.inc"

namespace upb {
namespace generator {

std::string StripExtension(absl::string_view fname) {
  size_t lastdot = fname.find_last_of('.');
  if (lastdot == std::string::npos) {
    return std::string(fname);
  }
  return std::string(fname.substr(0, lastdot));
}

std::string ToCIdent(absl::string_view str) {
  return absl::StrReplaceAll(str, {{".", "_"}, {"/", "_"}, {"-", "_"}});
}

std::string ToPreproc(absl::string_view str) {
  return absl::AsciiStrToUpper(ToCIdent(str));
}

void EmitFileWarning(absl::string_view name, Output& output) {
  output(
      "/* This file was generated by upb_generator from the input file:\n"
      " *\n"
      " *     $0\n"
      " *\n"
      " * Do not edit -- your changes will be discarded when the file is\n"
      " * regenerated.\n"
      " * NO CHECKED-IN "
      // Intentional line break.
      "PROTOBUF GENCODE */\n"
      "\n",
      name);
}

std::string MessageInitName(upb::MessageDefPtr descriptor) {
  return MessageInit(descriptor.full_name());
}

std::string PadPrefix(absl::string_view tag) {
  return tag.empty() ? "" : absl::StrCat(" ", tag);
}

std::string MessageName(upb::MessageDefPtr descriptor) {
  return ToCIdent(descriptor.full_name());
}

std::string FileLayoutName(upb::FileDefPtr file) {
  return ToCIdent(file.name()) + "_upb_file_layout";
}

bool HasFilename(upb::FileDefPtr file, absl::string_view filename) {
  return file.name() == filename;
}

bool IsDescriptorProto(upb::FileDefPtr file) {
  return HasFilename(file, "net/proto2/proto/descriptor.proto") ||
         HasFilename(file, "google/protobuf/descriptor.proto");
}

std::string CApiHeaderFilename(upb::FileDefPtr file, bool bootstrap) {
  if (bootstrap) {
    if (IsDescriptorProto(file)) {
      return "upb/reflection/descriptor_bootstrap.h";
    } else {
      return "upb_generator/plugin_bootstrap.h";
    }
  }
  return StripExtension(file.name()) + ".upb.h";
}

std::string MiniTableHeaderFilename(upb::FileDefPtr file, bool bootstrap) {
  std::string base;
  if (bootstrap) {
    if (IsDescriptorProto(file)) {
      base = "upb/reflection/stage1/";
    } else {
      base = "upb_generator/stage1/";
    }
  }
  return base + StripExtension(file.name()) + ".upb_minitable.h";
}

std::string EnumInit(upb::EnumDefPtr descriptor) {
  return ToCIdent(descriptor.full_name()) + "_enum_init";
}

std::string FieldInitializer(upb::FieldDefPtr field,
                             const upb_MiniTableField* field64,
                             const upb_MiniTableField* field32) {
  return absl::Substitute(
      "{$0, $1, $2, $3, $4, $5}", upb_MiniTableField_Number(field64),
      ArchDependentSize(field32->UPB_PRIVATE(offset),
                        field64->UPB_PRIVATE(offset)),
      ArchDependentSize(field32->presence, field64->presence),
      field64->UPB_PRIVATE(submsg_index) == kUpb_NoSub
          ? "kUpb_NoSub"
          : absl::StrCat(field64->UPB_PRIVATE(submsg_index)).c_str(),
      field64->UPB_PRIVATE(descriptortype), GetModeInit(field32, field64));
}

std::string ArchDependentSize(int64_t size32, int64_t size64) {
  if (size32 == size64) return absl::StrCat(size32);
  return absl::Substitute("UPB_SIZE($0, $1)", size32, size64);
}

// Returns the field mode as a string initializer.
//
// We could just emit this as a number (and we may yet go in that direction) but
// for now emitting symbolic constants gives this better readability and
// debuggability.
std::string GetModeInit(const upb_MiniTableField* field32,
                        const upb_MiniTableField* field64) {
  std::string ret;
  uint8_t mode32 = field32->UPB_PRIVATE(mode);
  switch (mode32 & kUpb_FieldMode_Mask) {
    case kUpb_FieldMode_Map:
      ret = "(int)kUpb_FieldMode_Map";
      break;
    case kUpb_FieldMode_Array:
      ret = "(int)kUpb_FieldMode_Array";
      break;
    case kUpb_FieldMode_Scalar:
      ret = "(int)kUpb_FieldMode_Scalar";
      break;
    default:
      break;
  }

  if (mode32 & kUpb_LabelFlags_IsPacked) {
    absl::StrAppend(&ret, " | (int)kUpb_LabelFlags_IsPacked");
  }

  if (mode32 & kUpb_LabelFlags_IsExtension) {
    absl::StrAppend(&ret, " | (int)kUpb_LabelFlags_IsExtension");
  }

  if (mode32 & kUpb_LabelFlags_IsAlternate) {
    absl::StrAppend(&ret, " | (int)kUpb_LabelFlags_IsAlternate");
  }

  absl::StrAppend(&ret, " | ((int)", GetFieldRep(field32, field64),
                  " << kUpb_FieldRep_Shift)");
  return ret;
}

std::string GetFieldRep(const upb_MiniTableField* field32,
                        const upb_MiniTableField* field64) {
  const auto rep32 = UPB_PRIVATE(_upb_MiniTableField_GetRep)(field32);
  const auto rep64 = UPB_PRIVATE(_upb_MiniTableField_GetRep)(field64);

  switch (rep32) {
    case kUpb_FieldRep_1Byte:
      return "kUpb_FieldRep_1Byte";
      break;
    case kUpb_FieldRep_4Byte: {
      if (rep64 == kUpb_FieldRep_4Byte) {
        return "kUpb_FieldRep_4Byte";
      } else {
        assert(rep64 == kUpb_FieldRep_8Byte);
        return "UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte)";
      }
      break;
    }
    case kUpb_FieldRep_StringView:
      return "kUpb_FieldRep_StringView";
      break;
    case kUpb_FieldRep_8Byte:
      return "kUpb_FieldRep_8Byte";
      break;
  }
  UPB_UNREACHABLE();
}

}  // namespace generator
}  // namespace upb
