// Protocol Buffers - Google's data interchange format
// Copyright 2022 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.

#include <limits>
#include <memory>
#include <utility>

#include "google/protobuf/io/coded_stream.h"
#include "google/protobuf/io/zero_copy_stream_impl_lite.h"
#include "google/protobuf/lazy_field.h"

// Must be included last.
// clang-format off
#include "google/protobuf/port_def.inc"
// clang-format on

namespace google {
namespace protobuf {
namespace internal {

namespace {

// Returns the initial depth for a local context.
// --The default depth for lazily verified LazyField.
// --Eagerly verified LazyField has no limit (max int).
inline int GetInitDepth(LazyVerifyOption option) {
  return option == LazyVerifyOption::kLazy
             ? io::CodedInputStream::GetDefaultRecursionLimit()
             : std::numeric_limits<int>::max();
}  // namespace

template <typename T>
inline bool ParseWithOuterContextImpl(const T& input, LazyVerifyOption option,
                                      ParseContext* ctx, MessageLite* message) {
  GOOGLE_DCHECK(ctx == nullptr || !ctx->AliasingEnabled());

  // Create local context with depth.
  const char* ptr;
  ParseContext local_ctx =
      ctx != nullptr ? ctx->Spawn(&ptr, input)
                     : ParseContext(GetInitDepth(option), false, &ptr, input);

  if (ctx == nullptr ||
      ctx->lazy_parse_mode() == ParseContext::LazyParseMode::kEagerVerify) {
    // Unparsed data is already verified at parsing. Disable eager-verification.
    (void)local_ctx.set_lazy_parse_mode(ParseContext::LazyParseMode::kLazy);
  }

  ptr = message->_InternalParse(ptr, &local_ctx);

  if (ctx != nullptr && local_ctx.missing_required_fields()) {
    ctx->SetMissingRequiredFields();
  }

  return ptr != nullptr &&
         (local_ctx.EndedAtEndOfStream() || local_ctx.EndedAtLimit());
}

}  // namespace

namespace {
class ByPrototype {
 public:
  explicit ByPrototype(const MessageLite* prototype) : prototype_(prototype) {}

  MessageLite* New(Arena* arena) const { return prototype_->New(arena); }

  const MessageLite& Default() const { return *prototype_; }

 private:
  const MessageLite* prototype_;
};
}  // namespace

const MessageLite& LazyField::GetByPrototype(const MessageLite& prototype,
                                             Arena* arena,
                                             LazyVerifyOption option,
                                             ParseContext* ctx) const {
  return GetGeneric(ByPrototype(&prototype), arena, option, ctx);
}

MessageLite* LazyField::MutableByPrototype(const MessageLite& prototype,
                                           Arena* arena,
                                           LazyVerifyOption option,
                                           ParseContext* ctx) {
  return MutableGeneric(ByPrototype(&prototype), arena, option, ctx);
}

MessageLite* LazyField::ReleaseByPrototype(const MessageLite& prototype,
                                           Arena* arena,
                                           LazyVerifyOption option) {
  return ReleaseGeneric(ByPrototype(&prototype), arena, option);
}

MessageLite* LazyField::UnsafeArenaReleaseByPrototype(
    const MessageLite& prototype, Arena* arena, LazyVerifyOption option) {
  return UnsafeArenaReleaseGeneric(ByPrototype(&prototype), arena, option);
}

bool LazyField::ParseWithOuterContext(MessageLite* message,
                                      LazyVerifyOption option,
                                      ParseContext* ctx) const {
  absl::optional<absl::string_view> flat = unparsed_.TryFlat();
  if (flat.has_value()) {
    return ParseWithOuterContextImpl(*flat, option, ctx, message);
  }

  io::CordInputStream input(unparsed_);
  return ParseWithOuterContextImpl(&input, option, ctx, message);
}

void LazyField::LogParseError(const MessageLite* message) {
  GOOGLE_LOG_EVERY_N(INFO, 100) << "Lazy parsing failed for " << message->GetTypeName()
                         << " error=" << message->InitializationErrorString()
                         << " (N = " << COUNTER << ")";
}

}  // namespace internal
}  // namespace protobuf
}  // namespace google

#include "google/protobuf/port_undef.inc"
