chromium/third_party/protobuf/src/google/protobuf/generated_message_tctable_lite.cc

// 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.

#include <cstdint>
#include <numeric>

#include <google/protobuf/extension_set.h>
#include <google/protobuf/generated_message_tctable_decl.h>
#include <google/protobuf/generated_message_tctable_impl.h>
#include <google/protobuf/inlined_string_field.h>
#include <google/protobuf/message_lite.h>
#include <google/protobuf/parse_context.h>
#include <google/protobuf/wire_format_lite.h>

// clang-format off
#include <google/protobuf/port_def.inc>
// clang-format on

namespace google {
namespace protobuf {
namespace internal {

FieldEntry;

//////////////////////////////////////////////////////////////////////////////
// Template instantiations:
//////////////////////////////////////////////////////////////////////////////

#ifndef NDEBUG
template void AlignFail<4>(uintptr_t);
template void AlignFail<8>(uintptr_t);
#endif

const char* TcParser::GenericFallbackLite(PROTOBUF_TC_PARAM_DECL) {}

//////////////////////////////////////////////////////////////////////////////
// Core fast parsing implementation:
//////////////////////////////////////////////////////////////////////////////

class TcParser::ScopedArenaSwap final {};

PROTOBUF_NOINLINE const char* TcParser::ParseLoop(
    MessageLite* msg, const char* ptr, ParseContext* ctx,
    const TcParseTableBase* table) {}

  // Dispatch to the designated parse function
inline PROTOBUF_ALWAYS_INLINE const char* TcParser::TagDispatch(
    PROTOBUF_TC_PARAM_DECL) {}

// We can only safely call from field to next field if the call is optimized
// to a proper tail call. Otherwise we blow through stack. Clang and gcc
// reliably do this optimization in opt mode, but do not perform this in debug
// mode. Luckily the structure of the algorithm is such that it's always
// possible to just return and use the enclosing parse loop as a trampoline.
inline PROTOBUF_ALWAYS_INLINE const char* TcParser::ToTagDispatch(
    PROTOBUF_TC_PARAM_DECL) {}

inline PROTOBUF_ALWAYS_INLINE const char* TcParser::ToParseLoop(
    PROTOBUF_TC_PARAM_DECL) {}

inline PROTOBUF_ALWAYS_INLINE const char* TcParser::Error(
    PROTOBUF_TC_PARAM_DECL) {}

// On the fast path, a (matching) 1-byte tag already has the decoded value.
static uint32_t FastDecodeTag(uint8_t coded_tag) {}

// On the fast path, a (matching) 2-byte tag always needs to be decoded.
static uint32_t FastDecodeTag(uint16_t coded_tag) {}

//////////////////////////////////////////////////////////////////////////////
// Core mini parsing implementation:
//////////////////////////////////////////////////////////////////////////////

// Field lookup table layout:
//
// Because it consists of a series of variable-length segments, the lookuup
// table is organized within an array of uint16_t, and each element is either
// a uint16_t or a uint32_t stored little-endian as a pair of uint16_t.
//
// Its fundamental building block maps 16 contiguously ascending field numbers
// to their locations within the field entry table:

struct SkipEntry16 {};

// The skipmap is a bitfield of which of those field numbers do NOT have a
// field entry.  The lowest bit of the skipmap corresponds to the lowest of
// the 16 field numbers, so if a proto had only fields 1, 2, 3, and 7, the
// skipmap would contain 0b11111111'10111000.
//
// The field lookup table begins with a single 32-bit skipmap that maps the
// field numbers 1 through 32.  This is because the majority of proto
// messages only contain fields numbered 1 to 32.
//
// The rest of the lookup table is a repeated series of
// { 32-bit field #,  #SkipEntry16s,  {SkipEntry16...} }
// That is, the next thing is a pair of uint16_t that form the next
// lowest field number that the lookup table handles.  If this number is -1,
// that is the end of the table.  Then there is a uint16_t that is
// the number of contiguous SkipEntry16 entries that follow, and then of
// course the SkipEntry16s themselves.

// Originally developed and tested at https://godbolt.org/z/vbc7enYcf

// Returns the address of the field for `tag` in the table's field entries.
// Returns nullptr if the field was not found.
const TcParseTableBase::FieldEntry* TcParser::FindFieldEntry(
    const TcParseTableBase* table, uint32_t field_num) {}

// Field names are stored in a format of:
//
// 1) A table of name sizes, one byte each, from 1 to 255 per name.
//    `entries` is the size of this first table.
// 1a) padding bytes, so the table of name sizes is a multiple of
//     eight bytes in length. They are zero.
//
// 2) All the names, concatenated, with neither separation nor termination.
//
// This is designed to be compact but not particularly fast to retrieve.
// In particular, it takes O(n) to retrieve the name of the n'th field,
// which is usually fine because most protos have fewer than 10 fields.
static StringPiece FindName(const char* name_data, size_t entries,
                                  size_t index) {}

StringPiece TcParser::MessageName(const TcParseTableBase* table) {}

StringPiece TcParser::FieldName(const TcParseTableBase* table,
                                      const FieldEntry* field_entry) {}

const char* TcParser::MiniParse(PROTOBUF_TC_PARAM_DECL) {}

namespace {

// Offset returns the address `offset` bytes after `base`.
inline void* Offset(void* base, uint32_t offset) {}

// InvertPacked changes tag bits from the given wire type to length
// delimited. This is the difference expected between packed and non-packed
// repeated fields.
template <WireFormatLite::WireType Wt>
inline PROTOBUF_ALWAYS_INLINE void InvertPacked(TcFieldData& data) {}

}  // namespace

//////////////////////////////////////////////////////////////////////////////
// Message fields
//////////////////////////////////////////////////////////////////////////////

template <typename TagType, bool group_coding>
inline PROTOBUF_ALWAYS_INLINE
const char* TcParser::SingularParseMessageAuxImpl(PROTOBUF_TC_PARAM_DECL) {}

const char* TcParser::FastMS1(PROTOBUF_TC_PARAM_DECL) {}

const char* TcParser::FastMS2(PROTOBUF_TC_PARAM_DECL) {}

const char* TcParser::FastGS1(PROTOBUF_TC_PARAM_DECL) {}

const char* TcParser::FastGS2(PROTOBUF_TC_PARAM_DECL) {}

template <typename TagType, bool group_coding>
inline PROTOBUF_ALWAYS_INLINE
const char* TcParser::RepeatedParseMessageAuxImpl(PROTOBUF_TC_PARAM_DECL) {}

const char* TcParser::FastMR1(PROTOBUF_TC_PARAM_DECL) {}

const char* TcParser::FastMR2(PROTOBUF_TC_PARAM_DECL) {}

const char* TcParser::FastGR1(PROTOBUF_TC_PARAM_DECL) {}

const char* TcParser::FastGR2(PROTOBUF_TC_PARAM_DECL) {}

//////////////////////////////////////////////////////////////////////////////
// Fixed fields
//////////////////////////////////////////////////////////////////////////////

template <typename LayoutType, typename TagType>
PROTOBUF_ALWAYS_INLINE const char* TcParser::SingularFixed(
    PROTOBUF_TC_PARAM_DECL) {}

const char* TcParser::FastF32S1(PROTOBUF_TC_PARAM_DECL) {}
const char* TcParser::FastF32S2(PROTOBUF_TC_PARAM_DECL) {}
const char* TcParser::FastF64S1(PROTOBUF_TC_PARAM_DECL) {}
const char* TcParser::FastF64S2(PROTOBUF_TC_PARAM_DECL) {}

template <typename LayoutType, typename TagType>
PROTOBUF_ALWAYS_INLINE const char* TcParser::RepeatedFixed(
    PROTOBUF_TC_PARAM_DECL) {}

const char* TcParser::FastF32R1(PROTOBUF_TC_PARAM_DECL) {}
const char* TcParser::FastF32R2(PROTOBUF_TC_PARAM_DECL) {}
const char* TcParser::FastF64R1(PROTOBUF_TC_PARAM_DECL) {}
const char* TcParser::FastF64R2(PROTOBUF_TC_PARAM_DECL) {}

// Note: some versions of GCC will fail with error "function not inlinable" if
// corecursive functions are both marked with PROTOBUF_ALWAYS_INLINE (Clang
// accepts this). We can still apply the attribute to one of the two functions,
// just not both (so we do mark the Repeated variant as always inlined). This
// also applies to PackedVarint, below.
template <typename LayoutType, typename TagType>
const char* TcParser::PackedFixed(PROTOBUF_TC_PARAM_DECL) {}

const char* TcParser::FastF32P1(PROTOBUF_TC_PARAM_DECL) {}
const char* TcParser::FastF32P2(PROTOBUF_TC_PARAM_DECL) {}
const char* TcParser::FastF64P1(PROTOBUF_TC_PARAM_DECL) {}
const char* TcParser::FastF64P2(PROTOBUF_TC_PARAM_DECL) {}

//////////////////////////////////////////////////////////////////////////////
// Varint fields
//////////////////////////////////////////////////////////////////////////////

namespace {

// Shift "byte" left by n * 7 bits, filling vacated bits with ones.
template <int n>
inline PROTOBUF_ALWAYS_INLINE uint64_t
shift_left_fill_with_ones(uint64_t byte, uint64_t ones) {}

// Shift "byte" left by n * 7 bits, filling vacated bits with ones, and
// put the new value in res.  Return whether the result was negative.
template <int n>
inline PROTOBUF_ALWAYS_INLINE bool shift_left_fill_with_ones_was_negative(
    uint64_t byte, uint64_t ones, int64_t& res) {}

inline PROTOBUF_ALWAYS_INLINE std::pair<const char*, uint64_t>
Parse64FallbackPair(const char* p, int64_t res1) {}

inline PROTOBUF_ALWAYS_INLINE const char* ParseVarint(const char* p,
                                                      uint64_t* value) {}

template <typename FieldType, bool zigzag = false>
inline FieldType ZigZagDecodeHelper(uint64_t value) {}

template <>
inline int32_t ZigZagDecodeHelper<int32_t, true>(uint64_t value) {}

template <>
inline int64_t ZigZagDecodeHelper<int64_t, true>(uint64_t value) {}

bool EnumIsValidAux(int32_t val, uint16_t xform_val,
                    TcParseTableBase::FieldAux aux) {}

}  // namespace

template <typename FieldType, typename TagType, bool zigzag>
PROTOBUF_ALWAYS_INLINE const char* TcParser::SingularVarint(
    PROTOBUF_TC_PARAM_DECL) {}

template <typename FieldType, typename TagType, bool zigzag>
PROTOBUF_NOINLINE const char* TcParser::SingularVarBigint(
    PROTOBUF_TC_PARAM_DECL) {}

const char* TcParser::FastV8S1(PROTOBUF_TC_PARAM_DECL) {}
const char* TcParser::FastV8S2(PROTOBUF_TC_PARAM_DECL) {}
const char* TcParser::FastV32S1(PROTOBUF_TC_PARAM_DECL) {}
const char* TcParser::FastV32S2(PROTOBUF_TC_PARAM_DECL) {}
const char* TcParser::FastV64S1(PROTOBUF_TC_PARAM_DECL) {}
const char* TcParser::FastV64S2(PROTOBUF_TC_PARAM_DECL) {}

const char* TcParser::FastZ32S1(PROTOBUF_TC_PARAM_DECL) {}
const char* TcParser::FastZ32S2(PROTOBUF_TC_PARAM_DECL) {}
const char* TcParser::FastZ64S1(PROTOBUF_TC_PARAM_DECL) {}
const char* TcParser::FastZ64S2(PROTOBUF_TC_PARAM_DECL) {}

template <typename FieldType, typename TagType, bool zigzag>
PROTOBUF_ALWAYS_INLINE const char* TcParser::RepeatedVarint(
    PROTOBUF_TC_PARAM_DECL) {}

const char* TcParser::FastV8R1(PROTOBUF_TC_PARAM_DECL) {}
const char* TcParser::FastV8R2(PROTOBUF_TC_PARAM_DECL) {}
const char* TcParser::FastV32R1(PROTOBUF_TC_PARAM_DECL) {}
const char* TcParser::FastV32R2(PROTOBUF_TC_PARAM_DECL) {}
const char* TcParser::FastV64R1(PROTOBUF_TC_PARAM_DECL) {}
const char* TcParser::FastV64R2(PROTOBUF_TC_PARAM_DECL) {}

const char* TcParser::FastZ32R1(PROTOBUF_TC_PARAM_DECL) {}
const char* TcParser::FastZ32R2(PROTOBUF_TC_PARAM_DECL) {}
const char* TcParser::FastZ64R1(PROTOBUF_TC_PARAM_DECL) {}
const char* TcParser::FastZ64R2(PROTOBUF_TC_PARAM_DECL) {}

// See comment on PackedFixed for why this is not PROTOBUF_ALWAYS_INLINE.
template <typename FieldType, typename TagType, bool zigzag>
const char* TcParser::PackedVarint(PROTOBUF_TC_PARAM_DECL) {}

const char* TcParser::FastV8P1(PROTOBUF_TC_PARAM_DECL) {}
const char* TcParser::FastV8P2(PROTOBUF_TC_PARAM_DECL) {}
const char* TcParser::FastV32P1(PROTOBUF_TC_PARAM_DECL) {}
const char* TcParser::FastV32P2(PROTOBUF_TC_PARAM_DECL) {}
const char* TcParser::FastV64P1(PROTOBUF_TC_PARAM_DECL) {}
const char* TcParser::FastV64P2(PROTOBUF_TC_PARAM_DECL) {}

const char* TcParser::FastZ32P1(PROTOBUF_TC_PARAM_DECL) {}
const char* TcParser::FastZ32P2(PROTOBUF_TC_PARAM_DECL) {}
const char* TcParser::FastZ64P1(PROTOBUF_TC_PARAM_DECL) {}
const char* TcParser::FastZ64P2(PROTOBUF_TC_PARAM_DECL) {}

//////////////////////////////////////////////////////////////////////////////
// Enum fields
//////////////////////////////////////////////////////////////////////////////

PROTOBUF_NOINLINE const char* TcParser::FastUnknownEnumFallback(
    PROTOBUF_TC_PARAM_DECL) {}

template <typename TagType, uint16_t xform_val>
PROTOBUF_ALWAYS_INLINE const char* TcParser::SingularEnum(
    PROTOBUF_TC_PARAM_DECL) {}

const char* TcParser::FastErS1(PROTOBUF_TC_PARAM_DECL) {}
const char* TcParser::FastErS2(PROTOBUF_TC_PARAM_DECL) {}
const char* TcParser::FastEvS1(PROTOBUF_TC_PARAM_DECL) {}
const char* TcParser::FastEvS2(PROTOBUF_TC_PARAM_DECL) {}

template <typename TagType, uint16_t xform_val>
PROTOBUF_ALWAYS_INLINE const char* TcParser::RepeatedEnum(
    PROTOBUF_TC_PARAM_DECL) {}

const char* TcParser::FastErR1(PROTOBUF_TC_PARAM_DECL) {}
const char* TcParser::FastErR2(PROTOBUF_TC_PARAM_DECL) {}
const char* TcParser::FastEvR1(PROTOBUF_TC_PARAM_DECL) {}
const char* TcParser::FastEvR2(PROTOBUF_TC_PARAM_DECL) {}

//////////////////////////////////////////////////////////////////////////////
// String/bytes fields
//////////////////////////////////////////////////////////////////////////////

// Defined in wire_format_lite.cc
void PrintUTF8ErrorLog(StringPiece message_name,
                       StringPiece field_name, const char* operation_str,
                       bool emit_stacktrace);

void TcParser::ReportFastUtf8Error(uint32_t decoded_tag,
                                   const TcParseTableBase* table) {}

namespace {

PROTOBUF_NOINLINE
const char* SingularStringParserFallback(ArenaStringPtr* s, const char* ptr,
                                         EpsCopyInputStream* stream) {}

}  // namespace

template <typename TagType, TcParser::Utf8Type utf8>
PROTOBUF_ALWAYS_INLINE const char* TcParser::SingularString(
    PROTOBUF_TC_PARAM_DECL) {}

const char* TcParser::FastBS1(PROTOBUF_TC_PARAM_DECL) {}
const char* TcParser::FastBS2(PROTOBUF_TC_PARAM_DECL) {}
const char* TcParser::FastSS1(PROTOBUF_TC_PARAM_DECL) {}
const char* TcParser::FastSS2(PROTOBUF_TC_PARAM_DECL) {}
const char* TcParser::FastUS1(PROTOBUF_TC_PARAM_DECL) {}
const char* TcParser::FastUS2(PROTOBUF_TC_PARAM_DECL) {}

// Inlined string variants:

const char* TcParser::FastBiS1(PROTOBUF_TC_PARAM_DECL) {}
const char* TcParser::FastBiS2(PROTOBUF_TC_PARAM_DECL) {}
const char* TcParser::FastSiS1(PROTOBUF_TC_PARAM_DECL) {}
const char* TcParser::FastSiS2(PROTOBUF_TC_PARAM_DECL) {}
const char* TcParser::FastUiS1(PROTOBUF_TC_PARAM_DECL) {}
const char* TcParser::FastUiS2(PROTOBUF_TC_PARAM_DECL) {}

template <typename TagType, TcParser::Utf8Type utf8>
PROTOBUF_ALWAYS_INLINE const char* TcParser::RepeatedString(
    PROTOBUF_TC_PARAM_DECL) {}

const char* TcParser::FastBR1(PROTOBUF_TC_PARAM_DECL) {}
const char* TcParser::FastBR2(PROTOBUF_TC_PARAM_DECL) {}
const char* TcParser::FastSR1(PROTOBUF_TC_PARAM_DECL) {}
const char* TcParser::FastSR2(PROTOBUF_TC_PARAM_DECL) {}
const char* TcParser::FastUR1(PROTOBUF_TC_PARAM_DECL) {}
const char* TcParser::FastUR2(PROTOBUF_TC_PARAM_DECL) {}

//////////////////////////////////////////////////////////////////////////////
// Mini parsing
//////////////////////////////////////////////////////////////////////////////

namespace {
inline void SetHas(const TcParseTableBase* table, const FieldEntry& entry,
                   MessageLite* msg, uint64_t& hasbits) {}
}  // namespace

// Destroys any existing oneof union member (if necessary). Returns true if the
// caller is responsible for initializing the object, or false if the field
// already has the desired case.
bool TcParser::ChangeOneof(const TcParseTableBase* table,
                           const TcParseTableBase::FieldEntry& entry,
                           uint32_t field_num, ParseContext* ctx,
                           MessageLite* msg) {}

const char* TcParser::MpFixed(PROTOBUF_TC_PARAM_DECL) {}

const char* TcParser::MpRepeatedFixed(PROTOBUF_TC_PARAM_DECL) {}

const char* TcParser::MpPackedFixed(PROTOBUF_TC_PARAM_DECL) {}

const char* TcParser::MpVarint(PROTOBUF_TC_PARAM_DECL) {}

const char* TcParser::MpRepeatedVarint(PROTOBUF_TC_PARAM_DECL) {}

const char* TcParser::MpPackedVarint(PROTOBUF_TC_PARAM_DECL) {}

bool TcParser::MpVerifyUtf8(StringPiece wire_bytes,
                            const TcParseTableBase* table,
                            const FieldEntry& entry, uint16_t xform_val) {}

const char* TcParser::MpString(PROTOBUF_TC_PARAM_DECL) {}

const char* TcParser::MpRepeatedString(PROTOBUF_TC_PARAM_DECL) {}

const char* TcParser::MpMessage(PROTOBUF_TC_PARAM_DECL) {}

const char* TcParser::MpRepeatedMessage(PROTOBUF_TC_PARAM_DECL) {}

const char* TcParser::MpMap(PROTOBUF_TC_PARAM_DECL) {}

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