// 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 "hpb_generator/gen_messages.h"

#include <cstddef>
#include <string>
#include <vector>

#include "google/protobuf/descriptor.pb.h"
#include "absl/numeric/bits.h"
#include "absl/strings/ascii.h"
#include "absl/strings/str_cat.h"
#include "absl/strings/string_view.h"
#include "hpb_generator/context.h"
#include "hpb_generator/gen_accessors.h"
#include "hpb_generator/gen_enums.h"
#include "hpb_generator/gen_extensions.h"
#include "hpb_generator/gen_utils.h"
#include "hpb_generator/names.h"
#include "google/protobuf/descriptor.h"
#include "upb_generator/c/names.h"
#include "upb_generator/minitable/names.h"

namespace google {
namespace protobuf {
namespace hpb_generator {

using Sub = google::protobuf::io::Printer::Sub;

void WriteModelAccessDeclaration(const google::protobuf::Descriptor* descriptor,
                                 Context& ctx);
void WriteModelPublicDeclaration(
    const google::protobuf::Descriptor* descriptor,
    const std::vector<const google::protobuf::FieldDescriptor*>& file_exts,
    const std::vector<const google::protobuf::EnumDescriptor*>& file_enums, Context& ctx);
void WriteExtensionIdentifiersInClassHeader(
    const google::protobuf::Descriptor* message,
    const std::vector<const google::protobuf::FieldDescriptor*>& file_exts, Context& ctx);
void WriteModelProxyDeclaration(const google::protobuf::Descriptor* descriptor,
                                Context& ctx);
void WriteModelCProxyDeclaration(const google::protobuf::Descriptor* descriptor,
                                 Context& ctx);
void WriteDefaultInstanceHeader(const google::protobuf::Descriptor* message,
                                Context& ctx);
void WriteDefaultInstanceDefinitionHeader(const google::protobuf::Descriptor* message,
                                          Context& ctx);
void WriteUsingEnumsInHeader(
    const google::protobuf::Descriptor* message,
    const std::vector<const google::protobuf::EnumDescriptor*>& file_enums, Context& ctx);

// Writes message class declarations into .hpb.h.
//
// For each proto Foo, FooAccess and FooProxy/FooCProxy are generated
// that are exposed to users as Foo , Ptr<Foo> and Ptr<const Foo>.
void WriteMessageClassDeclarations(
    const google::protobuf::Descriptor* descriptor,
    const std::vector<const google::protobuf::FieldDescriptor*>& file_exts,
    const std::vector<const google::protobuf::EnumDescriptor*>& file_enums,
    Context& ctx) {
  if (IsMapEntryMessage(descriptor)) {
    // Skip map entry generation. Low level accessors for maps are
    // generated that don't require a separate map type.
    return;
  }

  // Forward declaration of Proto Class for GCC handling of free friend method.
  ctx.Emit(
      {
          Sub("class_name", ClassName(descriptor)),
          Sub("model_access",
              [&] { WriteModelAccessDeclaration(descriptor, ctx); })
              .WithSuffix(";"),
          Sub("public_decl",
              [&] {
                WriteModelPublicDeclaration(descriptor, file_exts, file_enums,
                                            ctx);
              })
              .WithSuffix(";"),
          Sub("cproxy_decl",
              [&] { WriteModelCProxyDeclaration(descriptor, ctx); })
              .WithSuffix(";"),
          Sub("proxy_decl",
              [&] { WriteModelProxyDeclaration(descriptor, ctx); })
              .WithSuffix(";"),
          Sub("default_instance",
              [&] { WriteDefaultInstanceDefinitionHeader(descriptor, ctx); })
              .WithSuffix(";"),
      },
      R"cc(
        class $class_name$;
        namespace internal {
        $model_access$;
        }  // namespace internal

        $public_decl$;
        namespace internal {
        $cproxy_decl$;
        $proxy_decl$;
        }  // namespace internal
        $default_instance$;
      )cc");
}

void WriteModelAccessDeclaration(const google::protobuf::Descriptor* descriptor,
                                 Context& ctx) {
  ctx.Emit({Sub("class_name", ClassName(descriptor)),
            Sub("qualified_class_name", QualifiedClassName(descriptor)),
            Sub("upb_msg_name",
                upb::generator::CApiMessageType(descriptor->full_name())),
            Sub("field_accessors",
                [&] { WriteFieldAccessorsInHeader(descriptor, ctx); })
                .WithSuffix(";"),
            Sub("oneof_accessors",
                [&] { WriteOneofAccessorsInHeader(descriptor, ctx); })
                .WithSuffix(";")},
           R"cc(
             class $class_name$Access {
              public:
               $class_name$Access() {}
               $class_name$Access($upb_msg_name$* msg, upb_Arena* arena)
                   : msg_(msg), arena_(arena) {
                 assert(arena != nullptr);
               }  // NOLINT
               $class_name$Access(const $upb_msg_name$* msg, upb_Arena* arena)
                   : msg_(const_cast<$upb_msg_name$*>(msg)), arena_(arena) {
                 assert(arena != nullptr);
               }  // NOLINT

               $field_accessors$;
               $oneof_accessors$;

              private:
               friend class $qualified_class_name$;
               friend class $class_name$Proxy;
               friend class $class_name$CProxy;
               friend struct ::hpb::internal::PrivateAccess;
               $upb_msg_name$* msg_;
               upb_Arena* arena_;
             };
           )cc");
}

std::string UnderscoresToCamelCase(absl::string_view input,
                                   bool cap_next_letter) {
  std::string result;

  for (size_t i = 0; i < input.size(); i++) {
    if (absl::ascii_islower(input[i])) {
      if (cap_next_letter) {
        result += absl::ascii_toupper(input[i]);
      } else {
        result += input[i];
      }
      cap_next_letter = false;
    } else if (absl::ascii_isupper(input[i])) {
      // Capital letters are left as-is.
      result += input[i];
      cap_next_letter = false;
    } else if (absl::ascii_isdigit(input[i])) {
      result += input[i];
      cap_next_letter = true;
    } else {
      cap_next_letter = true;
    }
  }
  return result;
}

std::string FieldConstantName(const google::protobuf::FieldDescriptor* field) {
  std::string field_name = UnderscoresToCamelCase(field->name(), true);
  std::string result = absl::StrCat("k", field_name, "FieldNumber");

  if (!field->is_extension() &&
      field->containing_type()->FindFieldByCamelcaseName(
          field->camelcase_name()) != field) {
    // This field's camelcase name is not unique, add field number to make it
    // unique.
    absl::StrAppend(&result, "_", field->number());
  }
  return result;
}

void WriteConstFieldNumbers(Context& ctx,
                            const google::protobuf::Descriptor* descriptor) {
  for (auto field : FieldRange(descriptor)) {
    ctx.Emit({{"name", FieldConstantName(field)}, {"number", field->number()}},
             "static constexpr ::uint32_t $name$ = $number$;\n");
  }
  ctx.Emit("\n\n");
}

void WriteModelPublicDeclaration(
    const google::protobuf::Descriptor* descriptor,
    const std::vector<const google::protobuf::FieldDescriptor*>& file_exts,
    const std::vector<const google::protobuf::EnumDescriptor*>& file_enums,
    Context& ctx) {
  ctx.Emit({{"class_name", ClassName(descriptor)},
            {"qualified_class_name", QualifiedClassName(descriptor)}},
           R"cc(
             class $class_name$ final : private internal::$class_name$Access {
              public:
               using Access = internal::$class_name$Access;
               using Proxy = internal::$class_name$Proxy;
               using CProxy = internal::$class_name$CProxy;

               $class_name$();

               $class_name$(const $class_name$& from);
               $class_name$& operator=(const $qualified_class_name$& from);
               $class_name$(const CProxy& from);
               $class_name$(const Proxy& from);
               $class_name$& operator=(const CProxy& from);

               $class_name$($class_name$&& m)
                   : Access(std::exchange(m.msg_, nullptr),
                            std::exchange(m.arena_, nullptr)),
                     owned_arena_(std::move(m.owned_arena_)) {}

               $class_name$& operator=($class_name$&& m) {
                 msg_ = std::exchange(m.msg_, nullptr);
                 arena_ = std::exchange(m.arena_, nullptr);
                 owned_arena_ = std::move(m.owned_arena_);
                 return *this;
               }
           )cc");

  WriteUsingAccessorsInHeader(descriptor, MessageClassType::kMessage, ctx);
  WriteUsingEnumsInHeader(descriptor, file_enums, ctx);
  WriteDefaultInstanceHeader(descriptor, ctx);
  WriteExtensionIdentifiersInClassHeader(descriptor, file_exts, ctx);
  if (descriptor->extension_range_count()) {
    // for typetrait checking
    ctx.Emit({{"class_name", ClassName(descriptor)}},
             "using ExtendableType = $class_name$;\n");
  }
  // Note: free function friends that are templates such as ::hpb::Parse
  // require explicit <$2> type parameter in declaration to be able to compile
  // with gcc otherwise the compiler will fail with
  // "has not been declared within namespace" error. Even though there is a
  // namespace qualifier, cross namespace matching fails.
  ctx.Emit(
      R"cc(
        static const upb_MiniTable* minitable();
      )cc");
  ctx.Emit("\n");
  WriteConstFieldNumbers(ctx, descriptor);
  ctx.Emit({{"class_name", ClassName(descriptor)},
            {"c_api_msg_type",
             upb::generator::CApiMessageType(descriptor->full_name())}},
           R"cc(
             private:
             const upb_Message* msg() const { return UPB_UPCAST(msg_); }
             upb_Message* msg() { return UPB_UPCAST(msg_); }

             upb_Arena* arena() const { return arena_; }

             $class_name$(upb_Message* msg, upb_Arena* arena) : $class_name$Access() {
               msg_ = ($c_api_msg_type$*)msg;
               arena_ = ::hpb::interop::upb::UnwrapArena(owned_arena_);
               upb_Arena_Fuse(arena_, arena);
             }
             ::hpb::Arena owned_arena_;
             friend struct ::hpb::internal::PrivateAccess;
             friend Proxy;
             friend CProxy;
           )cc");
  ctx.Emit("};\n\n");
}

void WriteModelProxyDeclaration(const google::protobuf::Descriptor* descriptor,
                                Context& ctx) {
  // Foo::Proxy.
  ctx.Emit({{"class_name", ClassName(descriptor)}},
           R"cc(
             class $class_name$Proxy final
                 : private internal::$class_name$Access {
              public:
               $class_name$Proxy() = delete;
               $class_name$Proxy(const $class_name$Proxy& m)
                   : internal::$class_name$Access() {
                 msg_ = m.msg_;
                 arena_ = m.arena_;
               }
               $class_name$Proxy($class_name$* m) : internal::$class_name$Access() {
                 msg_ = m->msg_;
                 arena_ = m->arena_;
               }
               $class_name$Proxy operator=(const $class_name$Proxy& m) {
                 msg_ = m.msg_;
                 arena_ = m.arena_;
                 return *this;
               }
           )cc");

  WriteUsingAccessorsInHeader(descriptor, MessageClassType::kMessageProxy, ctx);
  ctx.Emit("\n");
  ctx.Emit(
      {{"class_name", ClassName(descriptor)},
       {"c_api_msg_type",
        upb::generator::CApiMessageType(descriptor->full_name())},
       {"qualified_class_name", QualifiedClassName(descriptor)}},
      R"cc(
        private:
        upb_Message* msg() const { return UPB_UPCAST(msg_); }

        upb_Arena* arena() const { return arena_; }

        $class_name$Proxy(upb_Message* msg, upb_Arena* arena)
            : internal::$class_name$Access(($c_api_msg_type$*)msg, arena) {}
        friend $class_name$::Proxy(
            ::hpb::CreateMessage<$class_name$>(::hpb::Arena& arena));
        friend $class_name$::Proxy(hpb::interop::upb::MakeHandle<$class_name$>(
            upb_Message*, upb_Arena*));
        friend struct ::hpb::internal::PrivateAccess;
        friend class RepeatedFieldProxy;
        friend class $class_name$CProxy;
        friend class $class_name$Access;
        friend class ::hpb::Ptr<$class_name$>;
        friend class ::hpb::Ptr<const $class_name$>;
        static const upb_MiniTable* minitable() { return $class_name$::minitable(); }
        friend const upb_MiniTable* ::hpb::interop::upb::GetMiniTable<
            $class_name$Proxy>(const $class_name$Proxy* message);
        friend const upb_MiniTable* ::hpb::interop::upb::GetMiniTable<
            $class_name$Proxy>(::hpb::Ptr<$class_name$Proxy> message);
        friend upb_Arena* hpb::interop::upb::GetArena<$qualified_class_name$>(
            $qualified_class_name$* message);
        friend upb_Arena* hpb::interop::upb::GetArena<$qualified_class_name$>(
            ::hpb::Ptr<$qualified_class_name$> message);
        static void Rebind($class_name$Proxy& lhs, const $class_name$Proxy& rhs) {
          lhs.msg_ = rhs.msg_;
          lhs.arena_ = rhs.arena_;
        }
      )cc");
  ctx.Emit("};\n\n");
}

void WriteModelCProxyDeclaration(const google::protobuf::Descriptor* descriptor,
                                 Context& ctx) {
  // Foo::CProxy.
  ctx.Emit({{"class_name", ClassName(descriptor)}},
           R"cc(
             class $class_name$CProxy final
                 : private internal::$class_name$Access {
              public:
               $class_name$CProxy() = delete;
               $class_name$CProxy(const $class_name$* m)
                   : internal::$class_name$Access(
                         m->msg_, hpb::interop::upb::GetArena(m)) {}
               $class_name$CProxy($class_name$Proxy m);
           )cc");

  WriteUsingAccessorsInHeader(descriptor, MessageClassType::kMessageCProxy,
                              ctx);

  ctx.Emit({{"class_name", ClassName(descriptor)},
            {"c_api_msg_type",
             upb::generator::CApiMessageType(descriptor->full_name())}},
           R"cc(
             private:
             using AsNonConst = $class_name$Proxy;
             const upb_Message* msg() const { return UPB_UPCAST(msg_); }
             upb_Arena* arena() const { return arena_; }

             $class_name$CProxy(const upb_Message* msg, upb_Arena* arena)
                 : internal::$class_name$Access(($c_api_msg_type$*)msg,
                                                arena){};
             friend struct ::hpb::internal::PrivateAccess;
             friend class RepeatedFieldProxy;
             friend class ::hpb::Ptr<$class_name$>;
             friend class ::hpb::Ptr<const $class_name$>;
             static const upb_MiniTable* minitable() { return $class_name$::minitable(); }
             friend const upb_MiniTable* ::hpb::interop::upb::GetMiniTable<
                 $class_name$CProxy>(const $class_name$CProxy* message);
             friend const upb_MiniTable* ::hpb::interop::upb::GetMiniTable<
                 $class_name$CProxy>(::hpb::Ptr<$class_name$CProxy> message);

             static void Rebind($class_name$CProxy& lhs, const $class_name$CProxy& rhs) {
               lhs.msg_ = rhs.msg_;
               lhs.arena_ = rhs.arena_;
             }
           )cc");
  ctx.Emit("};\n\n");
}

void WriteDefaultInstanceHeader(const google::protobuf::Descriptor* message,
                                Context& ctx) {
  if (message->options().map_entry()) {
    return;
  }
  ctx.Emit({{"class_name", ClassName(message)}},
           R"cc(
             static ::hpb::Ptr<const $class_name$> default_instance();
           )cc");
}

void WriteDefaultInstanceDefinitionHeader(const google::protobuf::Descriptor* message,
                                          Context& ctx) {
  if (message->options().map_entry()) {
    return;
  }
  ctx.Emit(
      {{"class_name", ClassName(message)},
       {"size_class",
        // Use log2 size class of message size to reduce the number of default
        // instances created.
        absl::bit_ceil(static_cast<size_t>(ctx.GetLayoutSize(message)))}},
      R"cc(
        inline ::hpb::Ptr<const $class_name$> $class_name$::default_instance() {
          return ::hpb::interop::upb::MakeCHandle<$class_name$>(
              ::hpb::internal::backend::upb::DefaultInstance<
                  $size_class$>::msg(),
              ::hpb::internal::backend::upb::DefaultInstance<
                  $size_class$>::arena());
        }
      )cc");
}

void WriteMessageImplementation(
    const google::protobuf::Descriptor* descriptor,
    const std::vector<const google::protobuf::FieldDescriptor*>& file_exts,
    Context& ctx) {
  bool message_is_map_entry = descriptor->options().map_entry();
  if (!message_is_map_entry) {
    // Constructor.
    ctx.Emit(
        {{"class_name", ClassName(descriptor)},
         {"c_api_msg_type",
          upb::generator::CApiMessageType(descriptor->full_name())},
         {"minitable_var",
          ::upb::generator::MiniTableMessageVarName(descriptor->full_name())},
         {"qualified_class_name", QualifiedClassName(descriptor)}},
        R"cc(
          $class_name$::$class_name$() : $class_name$Access() {
            arena_ = ::hpb::interop::upb::UnwrapArena(owned_arena_);
            msg_ = $c_api_msg_type$_new(arena_);
          }
          $class_name$::$class_name$(const $class_name$& from) : $class_name$Access() {
            arena_ = ::hpb::interop::upb::UnwrapArena(owned_arena_);
            msg_ = ($c_api_msg_type$*)::hpb::internal::DeepClone(
                UPB_UPCAST(from.msg_), &$minitable_var$, arena_);
          }
          $class_name$::$class_name$(const CProxy& from) : $class_name$Access() {
            arena_ = ::hpb::interop::upb::UnwrapArena(owned_arena_);
            msg_ = ($c_api_msg_type$*)::hpb::internal::DeepClone(
                ::hpb::interop::upb::GetMessage(&from), &$minitable_var$,
                arena_);
          }
          $class_name$::$class_name$(const Proxy& from)
              : $class_name$(static_cast<const CProxy&>(from)) {}
          internal::$class_name$CProxy::$class_name$CProxy($class_name$Proxy m)
              : $class_name$Access() {
            arena_ = m.arena_;
            msg_ = ($c_api_msg_type$*)::hpb::interop::upb::GetMessage(&m);
          }
          $class_name$& $class_name$::operator=(const $qualified_class_name$& from) {
            arena_ = ::hpb::interop::upb::UnwrapArena(owned_arena_);
            msg_ = ($c_api_msg_type$*)::hpb::internal::DeepClone(
                UPB_UPCAST(from.msg_), &$minitable_var$, arena_);
            return *this;
          }
          $class_name$& $class_name$::operator=(const CProxy& from) {
            arena_ = ::hpb::interop::upb::UnwrapArena(owned_arena_);
            msg_ = ($c_api_msg_type$*)::hpb::internal::DeepClone(
                ::hpb::interop::upb::GetMessage(&from), &$minitable_var$,
                arena_);
            return *this;
          }
        )cc");
    ctx.Emit("\n");
    // Minitable
    ctx.Emit({{"class_name", ClassName(descriptor)},
              {"minitable_var", ::upb::generator::MiniTableMessageVarName(
                                    descriptor->full_name())}},
             R"cc(
               const upb_MiniTable* $class_name$::minitable() {
                 return &$minitable_var$;
               }
             )cc");
    ctx.Emit("\n");
  }

  WriteAccessorsInSource(descriptor, ctx);
}

void WriteExtensionIdentifiersInClassHeader(
    const google::protobuf::Descriptor* message,
    const std::vector<const google::protobuf::FieldDescriptor*>& file_exts,
    Context& ctx) {
  for (auto* ext : file_exts) {
    if (ext->extension_scope() &&
        ext->extension_scope()->full_name() == message->full_name()) {
      WriteExtensionIdentifierHeader(ext, ctx);
    }
  }
}

void WriteUsingEnumsInHeader(
    const google::protobuf::Descriptor* message,
    const std::vector<const google::protobuf::EnumDescriptor*>& file_enums,
    Context& ctx) {
  for (auto* enum_descriptor : file_enums) {
    std::string enum_type_name = EnumTypeName(enum_descriptor);
    std::string enum_resolved_type_name =
        enum_descriptor->file()->package().empty() &&
                enum_descriptor->containing_type() == nullptr
            ? absl::StrCat(kNoPackageNamePrefix,
                           ToCIdent(enum_descriptor->name()))
            : enum_type_name;
    if (enum_descriptor->containing_type() == nullptr ||
        enum_descriptor->containing_type()->full_name() !=
            message->full_name()) {
      continue;
    }
    ctx.Emit({{"enum_name", enum_descriptor->name()}}, "using $enum_name$");
    if (enum_descriptor->options().deprecated()) {
      ctx.Emit({{"enum_name", enum_descriptor->name()}},
               " ABSL_DEPRECATED(\"Proto enum $enum_name$\")");
    }
    ctx.Emit({{"enum_resolved_type_name", enum_resolved_type_name}},
             " = $enum_resolved_type_name$;\n");
    int value_count = enum_descriptor->value_count();
    for (int i = 0; i < value_count; i++) {
      ctx.Emit({{"enum_name", enum_descriptor->name()},
                {"enum_value_name", enum_descriptor->value(i)->name()}},
               "static constexpr $enum_name$ $enum_value_name$");
      if (enum_descriptor->options().deprecated() ||
          enum_descriptor->value(i)->options().deprecated()) {
        ctx.Emit({{"enum_value_name", enum_descriptor->value(i)->name()}},
                 " ABSL_DEPRECATED(\"Proto enum value $enum_value_name$\") ");
      }
      ctx.Emit({{"enum_value_symbol",
                 EnumValueSymbolInNameSpace(enum_descriptor,
                                            enum_descriptor->value(i))}},
               " = $enum_value_symbol$;\n");
    }
  }
}

}  // namespace hpb_generator
}  // namespace protobuf
}  // namespace google
