chromium/third_party/protobuf/src/google/protobuf/parse_context.h

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

#ifndef GOOGLE_PROTOBUF_PARSE_CONTEXT_H__
#define GOOGLE_PROTOBUF_PARSE_CONTEXT_H__

#include <cstdint>
#include <cstring>
#include <string>
#include <type_traits>

#include <google/protobuf/io/coded_stream.h>
#include <google/protobuf/io/zero_copy_stream.h>
#include <google/protobuf/arena.h>
#include <google/protobuf/port.h>
#include <google/protobuf/stubs/strutil.h>
#include <google/protobuf/arenastring.h>
#include <google/protobuf/endian.h>
#include <google/protobuf/implicit_weak_message.h>
#include <google/protobuf/inlined_string_field.h>
#include <google/protobuf/metadata_lite.h>
#include <google/protobuf/repeated_field.h>
#include <google/protobuf/wire_format_lite.h>

// Must be included last.
#include <google/protobuf/port_def.inc>


namespace google {
namespace protobuf {

class UnknownFieldSet;
class DescriptorPool;
class MessageFactory;

namespace internal {

// Template code below needs to know about the existence of these functions.
PROTOBUF_EXPORT void WriteVarint(uint32_t num, uint64_t val, std::string* s);
PROTOBUF_EXPORT void WriteLengthDelimited(uint32_t num, StringPiece val,
                                          std::string* s);
// Inline because it is just forwarding to s->WriteVarint
inline void WriteVarint(uint32_t num, uint64_t val, UnknownFieldSet* s);
inline void WriteLengthDelimited(uint32_t num, StringPiece val,
                                 UnknownFieldSet* s);


// The basic abstraction the parser is designed for is a slight modification
// of the ZeroCopyInputStream (ZCIS) abstraction. A ZCIS presents a serialized
// stream as a series of buffers that concatenate to the full stream.
// Pictorially a ZCIS presents a stream in chunks like so
// [---------------------------------------------------------------]
// [---------------------] chunk 1
//                      [----------------------------] chunk 2
//                                          chunk 3 [--------------]
//
// Where the '-' represent the bytes which are vertically lined up with the
// bytes of the stream. The proto parser requires its input to be presented
// similarly with the extra
// property that each chunk has kSlopBytes past its end that overlaps with the
// first kSlopBytes of the next chunk, or if there is no next chunk at least its
// still valid to read those bytes. Again, pictorially, we now have
//
// [---------------------------------------------------------------]
// [-------------------....] chunk 1
//                    [------------------------....] chunk 2
//                                    chunk 3 [------------------..**]
//                                                      chunk 4 [--****]
// Here '-' mean the bytes of the stream or chunk and '.' means bytes past the
// chunk that match up with the start of the next chunk. Above each chunk has
// 4 '.' after the chunk. In the case these 'overflow' bytes represents bytes
// past the stream, indicated by '*' above, their values are unspecified. It is
// still legal to read them (ie. should not segfault). Reading past the
// end should be detected by the user and indicated as an error.
//
// The reason for this, admittedly, unconventional invariant is to ruthlessly
// optimize the protobuf parser. Having an overlap helps in two important ways.
// Firstly it alleviates having to performing bounds checks if a piece of code
// is guaranteed to not read more than kSlopBytes. Secondly, and more
// importantly, the protobuf wireformat is such that reading a key/value pair is
// always less than 16 bytes. This removes the need to change to next buffer in
// the middle of reading primitive values. Hence there is no need to store and
// load the current position.

class PROTOBUF_EXPORT EpsCopyInputStream {};

LazyEagerVerifyFnType;
LazyEagerVerifyFnRef;

// ParseContext holds all data that is global to the entire parse. Most
// importantly it contains the input stream, but also recursion depth and also
// stores the end group tag, in case a parser ended on a endgroup, to verify
// matching start/end group tags.
class PROTOBUF_EXPORT ParseContext : public EpsCopyInputStream {};

template <uint32_t tag>
bool ExpectTag(const char* ptr) {}

template <int>
struct EndianHelper;

template <>
struct EndianHelper<1> {};

template <>
struct EndianHelper<2> {};

template <>
struct EndianHelper<4> {};

template <>
struct EndianHelper<8> {};

template <typename T>
T UnalignedLoad(const char* p) {}

PROTOBUF_EXPORT
std::pair<const char*, uint32_t> VarintParseSlow32(const char* p, uint32_t res);
PROTOBUF_EXPORT
std::pair<const char*, uint64_t> VarintParseSlow64(const char* p, uint32_t res);

inline const char* VarintParseSlow(const char* p, uint32_t res, uint32_t* out) {}

inline const char* VarintParseSlow(const char* p, uint32_t res, uint64_t* out) {}

template <typename T>
PROTOBUF_NODISCARD const char* VarintParse(const char* p, T* out) {}

// Used for tags, could read up to 5 bytes which must be available.
// Caller must ensure its safe to call.

PROTOBUF_EXPORT
std::pair<const char*, uint32_t> ReadTagFallback(const char* p, uint32_t res);

// Same as ParseVarint but only accept 5 bytes at most.
inline const char* ReadTag(const char* p, uint32_t* out,
                           uint32_t /*max_tag*/ = 0) {}

// As above, but optimized to consume very few registers while still being fast,
// ReadTagInlined is useful for callers that don't mind the extra code but would
// like to avoid an extern function call causing spills into the stack.
//
// Two support routines for ReadTagInlined come first...
template <class T>
PROTOBUF_NODISCARD PROTOBUF_ALWAYS_INLINE constexpr T RotateLeft(
    T x, int s) noexcept {}

PROTOBUF_NODISCARD inline PROTOBUF_ALWAYS_INLINE uint64_t
RotRight7AndReplaceLowByte(uint64_t res, const char& byte) {}

inline PROTOBUF_ALWAYS_INLINE
const char* ReadTagInlined(const char* ptr, uint32_t* out) {}

// Decode 2 consecutive bytes of a varint and returns the value, shifted left
// by 1. It simultaneous updates *ptr to *ptr + 1 or *ptr + 2 depending if the
// first byte's continuation bit is set.
// If bit 15 of return value is set (equivalent to the continuation bits of both
// bytes being set) the varint continues, otherwise the parse is done. On x86
// movsx eax, dil
// and edi, eax
// add eax, edi
// adc [rsi], 1
inline uint32_t DecodeTwoBytes(const char** ptr) {}

// More efficient varint parsing for big varints
inline const char* ParseBigVarint(const char* p, uint64_t* out) {}

PROTOBUF_EXPORT
std::pair<const char*, int32_t> ReadSizeFallback(const char* p, uint32_t first);
// Used for tags, could read up to 5 bytes which must be available. Additionally
// it makes sure the unsigned value fits a int32_t, otherwise returns nullptr.
// Caller must ensure its safe to call.
inline uint32_t ReadSize(const char** pp) {}

// Some convenience functions to simplify the generated parse loop code.
// Returning the value and updating the buffer pointer allows for nicer
// function composition. We rely on the compiler to inline this.
// Also in debug compiles having local scoped variables tend to generated
// stack frames that scale as O(num fields).
inline uint64_t ReadVarint64(const char** p) {}

inline uint32_t ReadVarint32(const char** p) {}

inline int64_t ReadVarintZigZag64(const char** p) {}

inline int32_t ReadVarintZigZag32(const char** p) {}

template <typename T, typename std::enable_if<
                          !std::is_base_of<MessageLite, T>::value, bool>::type>
PROTOBUF_NODISCARD const char* ParseContext::ParseMessage(T* msg,
                                                          const char* ptr) {}

template <typename Tag, typename T>
const char* EpsCopyInputStream::ReadRepeatedFixed(const char* ptr,
                                                  Tag expected_tag,
                                                  RepeatedField<T>* out) {}

// Add any of the following lines to debug which parse function is failing.

#define GOOGLE_PROTOBUF_ASSERT_RETURN(predicate, ret)

#define GOOGLE_PROTOBUF_PARSER_ASSERT(predicate)

template <typename T>
const char* EpsCopyInputStream::ReadPackedFixed(const char* ptr, int size,
                                                RepeatedField<T>* out) {}

template <typename Add>
const char* ReadPackedVarintArray(const char* ptr, const char* end, Add add) {}

template <typename Add>
const char* EpsCopyInputStream::ReadPackedVarint(const char* ptr, Add add) {}

// Helper for verification of utf8
PROTOBUF_EXPORT
bool VerifyUTF8(StringPiece s, const char* field_name);

inline bool VerifyUTF8(const std::string* s, const char* field_name) {}

// All the string parsers with or without UTF checking and for all CTypes.
PROTOBUF_NODISCARD PROTOBUF_EXPORT const char* InlineGreedyStringParser(
    std::string* s, const char* ptr, ParseContext* ctx);


template <typename T>
PROTOBUF_NODISCARD const char* FieldParser(uint64_t tag, T& field_parser,
                                           const char* ptr, ParseContext* ctx) {}

template <typename T>
PROTOBUF_NODISCARD const char* WireFormatParser(T& field_parser,
                                                const char* ptr,
                                                ParseContext* ctx) {}

// The packed parsers parse repeated numeric primitives directly into  the
// corresponding field

// These are packed varints
PROTOBUF_NODISCARD PROTOBUF_EXPORT const char* PackedInt32Parser(
    void* object, const char* ptr, ParseContext* ctx);
PROTOBUF_NODISCARD PROTOBUF_EXPORT const char* PackedUInt32Parser(
    void* object, const char* ptr, ParseContext* ctx);
PROTOBUF_NODISCARD PROTOBUF_EXPORT const char* PackedInt64Parser(
    void* object, const char* ptr, ParseContext* ctx);
PROTOBUF_NODISCARD PROTOBUF_EXPORT const char* PackedUInt64Parser(
    void* object, const char* ptr, ParseContext* ctx);
PROTOBUF_NODISCARD PROTOBUF_EXPORT const char* PackedSInt32Parser(
    void* object, const char* ptr, ParseContext* ctx);
PROTOBUF_NODISCARD PROTOBUF_EXPORT const char* PackedSInt64Parser(
    void* object, const char* ptr, ParseContext* ctx);
PROTOBUF_NODISCARD PROTOBUF_EXPORT const char* PackedEnumParser(
    void* object, const char* ptr, ParseContext* ctx);

template <typename T>
PROTOBUF_NODISCARD const char* PackedEnumParser(void* object, const char* ptr,
                                                ParseContext* ctx,
                                                bool (*is_valid)(int),
                                                InternalMetadata* metadata,
                                                int field_num) {}

template <typename T>
PROTOBUF_NODISCARD const char* PackedEnumParserArg(
    void* object, const char* ptr, ParseContext* ctx,
    bool (*is_valid)(const void*, int), const void* data,
    InternalMetadata* metadata, int field_num) {}

PROTOBUF_NODISCARD PROTOBUF_EXPORT const char* PackedBoolParser(
    void* object, const char* ptr, ParseContext* ctx);
PROTOBUF_NODISCARD PROTOBUF_EXPORT const char* PackedFixed32Parser(
    void* object, const char* ptr, ParseContext* ctx);
PROTOBUF_NODISCARD PROTOBUF_EXPORT const char* PackedSFixed32Parser(
    void* object, const char* ptr, ParseContext* ctx);
PROTOBUF_NODISCARD PROTOBUF_EXPORT const char* PackedFixed64Parser(
    void* object, const char* ptr, ParseContext* ctx);
PROTOBUF_NODISCARD PROTOBUF_EXPORT const char* PackedSFixed64Parser(
    void* object, const char* ptr, ParseContext* ctx);
PROTOBUF_NODISCARD PROTOBUF_EXPORT const char* PackedFloatParser(
    void* object, const char* ptr, ParseContext* ctx);
PROTOBUF_NODISCARD PROTOBUF_EXPORT const char* PackedDoubleParser(
    void* object, const char* ptr, ParseContext* ctx);

// This is the only recursive parser.
PROTOBUF_NODISCARD PROTOBUF_EXPORT const char* UnknownGroupLiteParse(
    std::string* unknown, const char* ptr, ParseContext* ctx);
// This is a helper to for the UnknownGroupLiteParse but is actually also
// useful in the generated code. It uses overload on std::string* vs
// UnknownFieldSet* to make the generated code isomorphic between full and lite.
PROTOBUF_NODISCARD PROTOBUF_EXPORT const char* UnknownFieldParse(
    uint32_t tag, std::string* unknown, const char* ptr, ParseContext* ctx);

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

#include <google/protobuf/port_undef.inc>

#endif  // GOOGLE_PROTOBUF_PARSE_CONTEXT_H__