add external dependencies in a pre-built way to avoid incompatibilities
This commit is contained in:
108
external/include/google/protobuf/util/delimited_message_util.h
vendored
Normal file
108
external/include/google/protobuf/util/delimited_message_util.h
vendored
Normal file
@@ -0,0 +1,108 @@
|
||||
// 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.
|
||||
|
||||
// Adapted from the patch of kenton@google.com (Kenton Varda)
|
||||
// See https://github.com/protocolbuffers/protobuf/pull/710 for details.
|
||||
|
||||
#ifndef GOOGLE_PROTOBUF_UTIL_DELIMITED_MESSAGE_UTIL_H__
|
||||
#define GOOGLE_PROTOBUF_UTIL_DELIMITED_MESSAGE_UTIL_H__
|
||||
|
||||
|
||||
#include <ostream>
|
||||
|
||||
#include <google/protobuf/message_lite.h>
|
||||
#include <google/protobuf/io/coded_stream.h>
|
||||
#include <google/protobuf/io/zero_copy_stream_impl.h>
|
||||
|
||||
#include <google/protobuf/port_def.inc>
|
||||
|
||||
namespace google {
|
||||
namespace protobuf {
|
||||
namespace util {
|
||||
|
||||
// Write a single size-delimited message from the given stream. Delimited
|
||||
// format allows a single file or stream to contain multiple messages,
|
||||
// whereas normally writing multiple non-delimited messages to the same
|
||||
// stream would cause them to be merged. A delimited message is a varint
|
||||
// encoding the message size followed by a message of exactly that size.
|
||||
//
|
||||
// Note that if you want to *read* a delimited message from a file descriptor
|
||||
// or istream, you will need to construct an io::FileInputStream or
|
||||
// io::OstreamInputStream (implementations of io::ZeroCopyStream) and use the
|
||||
// utility function ParseDelimitedFromZeroCopyStream(). You must then
|
||||
// continue to use the same ZeroCopyInputStream to read all further data from
|
||||
// the stream until EOF. This is because these ZeroCopyInputStream
|
||||
// implementations are buffered: they read a big chunk of data at a time,
|
||||
// then parse it. As a result, they may read past the end of the delimited
|
||||
// message. There is no way for them to push the extra data back into the
|
||||
// underlying source, so instead you must keep using the same stream object.
|
||||
bool PROTOBUF_EXPORT SerializeDelimitedToFileDescriptor(
|
||||
const MessageLite& message, int file_descriptor);
|
||||
|
||||
bool PROTOBUF_EXPORT SerializeDelimitedToOstream(const MessageLite& message,
|
||||
std::ostream* output);
|
||||
|
||||
// Read a single size-delimited message from the given stream. Delimited
|
||||
// format allows a single file or stream to contain multiple messages,
|
||||
// whereas normally parsing consumes the entire input. A delimited message
|
||||
// is a varint encoding the message size followed by a message of exactly
|
||||
// that size.
|
||||
//
|
||||
// If |clean_eof| is not NULL, then it will be set to indicate whether the
|
||||
// stream ended cleanly. That is, if the stream ends without this method
|
||||
// having read any data at all from it, then *clean_eof will be set true,
|
||||
// otherwise it will be set false. Note that these methods return false
|
||||
// on EOF, but they also return false on other errors, so |clean_eof| is
|
||||
// needed to distinguish a clean end from errors.
|
||||
bool PROTOBUF_EXPORT ParseDelimitedFromZeroCopyStream(
|
||||
MessageLite* message, io::ZeroCopyInputStream* input, bool* clean_eof);
|
||||
|
||||
bool PROTOBUF_EXPORT ParseDelimitedFromCodedStream(MessageLite* message,
|
||||
io::CodedInputStream* input,
|
||||
bool* clean_eof);
|
||||
|
||||
// Write a single size-delimited message from the given stream. Delimited
|
||||
// format allows a single file or stream to contain multiple messages,
|
||||
// whereas normally writing multiple non-delimited messages to the same
|
||||
// stream would cause them to be merged. A delimited message is a varint
|
||||
// encoding the message size followed by a message of exactly that size.
|
||||
bool PROTOBUF_EXPORT SerializeDelimitedToZeroCopyStream(
|
||||
const MessageLite& message, io::ZeroCopyOutputStream* output);
|
||||
|
||||
bool PROTOBUF_EXPORT SerializeDelimitedToCodedStream(
|
||||
const MessageLite& message, io::CodedOutputStream* output);
|
||||
|
||||
} // namespace util
|
||||
} // namespace protobuf
|
||||
} // namespace google
|
||||
|
||||
#include <google/protobuf/port_undef.inc>
|
||||
|
||||
#endif // GOOGLE_PROTOBUF_UTIL_DELIMITED_MESSAGE_UTIL_H__
|
||||
285
external/include/google/protobuf/util/field_comparator.h
vendored
Normal file
285
external/include/google/protobuf/util/field_comparator.h
vendored
Normal file
@@ -0,0 +1,285 @@
|
||||
// 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.
|
||||
|
||||
// Defines classes for field comparison.
|
||||
|
||||
#ifndef GOOGLE_PROTOBUF_UTIL_FIELD_COMPARATOR_H__
|
||||
#define GOOGLE_PROTOBUF_UTIL_FIELD_COMPARATOR_H__
|
||||
|
||||
#include <cstdint>
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include <google/protobuf/stubs/common.h>
|
||||
#include <google/protobuf/port_def.inc>
|
||||
|
||||
namespace google {
|
||||
namespace protobuf {
|
||||
|
||||
class Message;
|
||||
class EnumValueDescriptor;
|
||||
class FieldDescriptor;
|
||||
|
||||
namespace util {
|
||||
|
||||
class FieldContext;
|
||||
class MessageDifferencer;
|
||||
|
||||
// Base class specifying the interface for comparing protocol buffer fields.
|
||||
// Regular users should consider using or subclassing DefaultFieldComparator
|
||||
// rather than this interface.
|
||||
// Currently, this does not support comparing unknown fields.
|
||||
class PROTOBUF_EXPORT FieldComparator {
|
||||
public:
|
||||
FieldComparator();
|
||||
virtual ~FieldComparator();
|
||||
|
||||
enum ComparisonResult {
|
||||
SAME, // Compared fields are equal. In case of comparing submessages,
|
||||
// user should not recursively compare their contents.
|
||||
DIFFERENT, // Compared fields are different. In case of comparing
|
||||
// submessages, user should not recursively compare their
|
||||
// contents.
|
||||
RECURSE, // Compared submessages need to be compared recursively.
|
||||
// FieldComparator does not specify the semantics of recursive
|
||||
// comparison. This value should not be returned for simple
|
||||
// values.
|
||||
};
|
||||
|
||||
// Compares the values of a field in two protocol buffer messages.
|
||||
// Returns SAME or DIFFERENT for simple values, and SAME, DIFFERENT or RECURSE
|
||||
// for submessages. Returning RECURSE for fields not being submessages is
|
||||
// illegal.
|
||||
// In case the given FieldDescriptor points to a repeated field, the indices
|
||||
// need to be valid. Otherwise they should be ignored.
|
||||
//
|
||||
// FieldContext contains information about the specific instances of the
|
||||
// fields being compared, versus FieldDescriptor which only contains general
|
||||
// type information about the fields.
|
||||
virtual ComparisonResult Compare(const Message& message_1,
|
||||
const Message& message_2,
|
||||
const FieldDescriptor* field, int index_1,
|
||||
int index_2,
|
||||
const util::FieldContext* field_context) = 0;
|
||||
|
||||
private:
|
||||
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(FieldComparator);
|
||||
};
|
||||
|
||||
// Basic implementation of FieldComparator. Supports three modes of floating
|
||||
// point value comparison: exact, approximate using MathUtil::AlmostEqual
|
||||
// method, and arbitrarily precise using MathUtil::WithinFractionOrMargin.
|
||||
class PROTOBUF_EXPORT SimpleFieldComparator : public FieldComparator {
|
||||
public:
|
||||
enum FloatComparison {
|
||||
EXACT, // Floats and doubles are compared exactly.
|
||||
APPROXIMATE, // Floats and doubles are compared using the
|
||||
// MathUtil::AlmostEqual method or
|
||||
// MathUtil::WithinFractionOrMargin method.
|
||||
// TODO(ksroka): Introduce third value to differentiate uses of AlmostEqual
|
||||
// and WithinFractionOrMargin.
|
||||
};
|
||||
|
||||
// Creates new comparator with float comparison set to EXACT.
|
||||
SimpleFieldComparator();
|
||||
|
||||
~SimpleFieldComparator() override;
|
||||
|
||||
void set_float_comparison(FloatComparison float_comparison) {
|
||||
float_comparison_ = float_comparison;
|
||||
}
|
||||
|
||||
FloatComparison float_comparison() const { return float_comparison_; }
|
||||
|
||||
// Set whether the FieldComparator shall treat floats or doubles that are both
|
||||
// NaN as equal (treat_nan_as_equal = true) or as different
|
||||
// (treat_nan_as_equal = false). Default is treating NaNs always as different.
|
||||
void set_treat_nan_as_equal(bool treat_nan_as_equal) {
|
||||
treat_nan_as_equal_ = treat_nan_as_equal;
|
||||
}
|
||||
|
||||
bool treat_nan_as_equal() const { return treat_nan_as_equal_; }
|
||||
|
||||
// Sets the fraction and margin for the float comparison of a given field.
|
||||
// Uses MathUtil::WithinFractionOrMargin to compare the values.
|
||||
//
|
||||
// REQUIRES: field->cpp_type == FieldDescriptor::CPPTYPE_DOUBLE or
|
||||
// field->cpp_type == FieldDescriptor::CPPTYPE_FLOAT
|
||||
// REQUIRES: float_comparison_ == APPROXIMATE
|
||||
void SetFractionAndMargin(const FieldDescriptor* field, double fraction,
|
||||
double margin);
|
||||
|
||||
// Sets the fraction and margin for the float comparison of all float and
|
||||
// double fields, unless a field has been given a specific setting via
|
||||
// SetFractionAndMargin() above.
|
||||
// Uses MathUtil::WithinFractionOrMargin to compare the values.
|
||||
//
|
||||
// REQUIRES: float_comparison_ == APPROXIMATE
|
||||
void SetDefaultFractionAndMargin(double fraction, double margin);
|
||||
|
||||
protected:
|
||||
// Returns the comparison result for the given field in two messages.
|
||||
//
|
||||
// This function is called directly by DefaultFieldComparator::Compare.
|
||||
// Subclasses can call this function to compare fields they do not need to
|
||||
// handle specially.
|
||||
ComparisonResult SimpleCompare(const Message& message_1,
|
||||
const Message& message_2,
|
||||
const FieldDescriptor* field, int index_1,
|
||||
int index_2,
|
||||
const util::FieldContext* field_context);
|
||||
|
||||
// Compare using the provided message_differencer. For example, a subclass can
|
||||
// use this method to compare some field in a certain way using the same
|
||||
// message_differencer instance and the field context.
|
||||
bool CompareWithDifferencer(MessageDifferencer* differencer,
|
||||
const Message& message1, const Message& message2,
|
||||
const util::FieldContext* field_context);
|
||||
|
||||
// Returns FieldComparator::SAME if boolean_result is true and
|
||||
// FieldComparator::DIFFERENT otherwise.
|
||||
ComparisonResult ResultFromBoolean(bool boolean_result) const;
|
||||
|
||||
private:
|
||||
// Defines the tolerance for floating point comparison (fraction and margin).
|
||||
struct Tolerance {
|
||||
double fraction;
|
||||
double margin;
|
||||
Tolerance() : fraction(0.0), margin(0.0) {}
|
||||
Tolerance(double f, double m) : fraction(f), margin(m) {}
|
||||
};
|
||||
|
||||
// Defines the map to store the tolerances for floating point comparison.
|
||||
typedef std::map<const FieldDescriptor*, Tolerance> ToleranceMap;
|
||||
|
||||
friend class MessageDifferencer;
|
||||
// The following methods get executed when CompareFields is called for the
|
||||
// basic types (instead of submessages). They return true on success. One
|
||||
// can use ResultFromBoolean() to convert that boolean to a ComparisonResult
|
||||
// value.
|
||||
bool CompareBool(const FieldDescriptor& /* unused */, bool value_1,
|
||||
bool value_2) {
|
||||
return value_1 == value_2;
|
||||
}
|
||||
|
||||
// Uses CompareDoubleOrFloat, a helper function used by both CompareDouble and
|
||||
// CompareFloat.
|
||||
bool CompareDouble(const FieldDescriptor& field, double value_1,
|
||||
double value_2);
|
||||
|
||||
bool CompareEnum(const FieldDescriptor& field,
|
||||
const EnumValueDescriptor* value_1,
|
||||
const EnumValueDescriptor* value_2);
|
||||
|
||||
// Uses CompareDoubleOrFloat, a helper function used by both CompareDouble and
|
||||
// CompareFloat.
|
||||
bool CompareFloat(const FieldDescriptor& field, float value_1, float value_2);
|
||||
|
||||
bool CompareInt32(const FieldDescriptor& /* unused */, int32_t value_1,
|
||||
int32_t value_2) {
|
||||
return value_1 == value_2;
|
||||
}
|
||||
|
||||
bool CompareInt64(const FieldDescriptor& /* unused */, int64_t value_1,
|
||||
int64_t value_2) {
|
||||
return value_1 == value_2;
|
||||
}
|
||||
|
||||
bool CompareString(const FieldDescriptor& /* unused */,
|
||||
const std::string& value_1, const std::string& value_2) {
|
||||
return value_1 == value_2;
|
||||
}
|
||||
|
||||
bool CompareUInt32(const FieldDescriptor& /* unused */, uint32_t value_1,
|
||||
uint32_t value_2) {
|
||||
return value_1 == value_2;
|
||||
}
|
||||
|
||||
bool CompareUInt64(const FieldDescriptor& /* unused */, uint64_t value_1,
|
||||
uint64_t value_2) {
|
||||
return value_1 == value_2;
|
||||
}
|
||||
|
||||
// This function is used by CompareDouble and CompareFloat to avoid code
|
||||
// duplication. There are no checks done against types of the values passed,
|
||||
// but it's likely to fail if passed non-numeric arguments.
|
||||
template <typename T>
|
||||
bool CompareDoubleOrFloat(const FieldDescriptor& field, T value_1, T value_2);
|
||||
|
||||
FloatComparison float_comparison_;
|
||||
|
||||
// If true, floats and doubles that are both NaN are considered to be
|
||||
// equal. Otherwise, two floats or doubles that are NaN are considered to be
|
||||
// different.
|
||||
bool treat_nan_as_equal_;
|
||||
|
||||
// True iff default_tolerance_ has been explicitly set.
|
||||
//
|
||||
// If false, then the default tolerance for floats and doubles is that which
|
||||
// is used by MathUtil::AlmostEquals().
|
||||
bool has_default_tolerance_;
|
||||
|
||||
// Default float/double tolerance. Only meaningful if
|
||||
// has_default_tolerance_ == true.
|
||||
Tolerance default_tolerance_;
|
||||
|
||||
// Field-specific float/double tolerances, which override any default for
|
||||
// those particular fields.
|
||||
ToleranceMap map_tolerance_;
|
||||
|
||||
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(SimpleFieldComparator);
|
||||
};
|
||||
|
||||
// Default field comparison: use the basic implementation of FieldComparator.
|
||||
#ifdef PROTOBUF_FUTURE_BREAKING_CHANGES
|
||||
class PROTOBUF_EXPORT DefaultFieldComparator final
|
||||
: public SimpleFieldComparator
|
||||
#else // PROTOBUF_FUTURE_BREAKING_CHANGES
|
||||
class PROTOBUF_EXPORT DefaultFieldComparator : public SimpleFieldComparator
|
||||
#endif // PROTOBUF_FUTURE_BREAKING_CHANGES
|
||||
{
|
||||
public:
|
||||
ComparisonResult Compare(const Message& message_1, const Message& message_2,
|
||||
const FieldDescriptor* field, int index_1,
|
||||
int index_2,
|
||||
const util::FieldContext* field_context) override {
|
||||
return SimpleCompare(message_1, message_2, field, index_1, index_2,
|
||||
field_context);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace util
|
||||
} // namespace protobuf
|
||||
} // namespace google
|
||||
|
||||
#include <google/protobuf/port_undef.inc>
|
||||
|
||||
#endif // GOOGLE_PROTOBUF_UTIL_FIELD_COMPARATOR_H__
|
||||
262
external/include/google/protobuf/util/field_mask_util.h
vendored
Normal file
262
external/include/google/protobuf/util/field_mask_util.h
vendored
Normal file
@@ -0,0 +1,262 @@
|
||||
// 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.
|
||||
|
||||
// Defines utilities for the FieldMask well known type.
|
||||
|
||||
#ifndef GOOGLE_PROTOBUF_UTIL_FIELD_MASK_UTIL_H__
|
||||
#define GOOGLE_PROTOBUF_UTIL_FIELD_MASK_UTIL_H__
|
||||
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
|
||||
#include <google/protobuf/field_mask.pb.h>
|
||||
#include <google/protobuf/descriptor.h>
|
||||
#include <google/protobuf/stubs/strutil.h>
|
||||
|
||||
// Must be included last.
|
||||
#include <google/protobuf/port_def.inc>
|
||||
|
||||
namespace google {
|
||||
namespace protobuf {
|
||||
namespace util {
|
||||
|
||||
class PROTOBUF_EXPORT FieldMaskUtil {
|
||||
typedef google::protobuf::FieldMask FieldMask;
|
||||
|
||||
public:
|
||||
// Converts FieldMask to/from string, formatted by separating each path
|
||||
// with a comma (e.g., "foo_bar,baz.quz").
|
||||
static std::string ToString(const FieldMask& mask);
|
||||
static void FromString(StringPiece str, FieldMask* out);
|
||||
|
||||
// Populates the FieldMask with the paths corresponding to the fields with the
|
||||
// given numbers, after checking that all field numbers are valid.
|
||||
template <typename T>
|
||||
static void FromFieldNumbers(const std::vector<int64_t>& field_numbers,
|
||||
FieldMask* out) {
|
||||
for (const auto field_number : field_numbers) {
|
||||
const FieldDescriptor* field_desc =
|
||||
T::descriptor()->FindFieldByNumber(field_number);
|
||||
GOOGLE_CHECK(field_desc != nullptr)
|
||||
<< "Invalid field number for " << T::descriptor()->full_name() << ": "
|
||||
<< field_number;
|
||||
AddPathToFieldMask<T>(field_desc->lowercase_name(), out);
|
||||
}
|
||||
}
|
||||
|
||||
// Converts FieldMask to/from string, formatted according to proto3 JSON
|
||||
// spec for FieldMask (e.g., "fooBar,baz.quz"). If the field name is not
|
||||
// style conforming (i.e., not snake_case when converted to string, or not
|
||||
// camelCase when converted from string), the conversion will fail.
|
||||
static bool ToJsonString(const FieldMask& mask, std::string* out);
|
||||
static bool FromJsonString(StringPiece str, FieldMask* out);
|
||||
|
||||
// Get the descriptors of the fields which the given path from the message
|
||||
// descriptor traverses, if field_descriptors is not null.
|
||||
// Return false if the path is not valid, and the content of field_descriptors
|
||||
// is unspecified.
|
||||
static bool GetFieldDescriptors(
|
||||
const Descriptor* descriptor, StringPiece path,
|
||||
std::vector<const FieldDescriptor*>* field_descriptors);
|
||||
|
||||
// Checks whether the given path is valid for type T.
|
||||
template <typename T>
|
||||
static bool IsValidPath(StringPiece path) {
|
||||
return GetFieldDescriptors(T::descriptor(), path, nullptr);
|
||||
}
|
||||
|
||||
// Checks whether the given FieldMask is valid for type T.
|
||||
template <typename T>
|
||||
static bool IsValidFieldMask(const FieldMask& mask) {
|
||||
for (int i = 0; i < mask.paths_size(); ++i) {
|
||||
if (!GetFieldDescriptors(T::descriptor(), mask.paths(i), nullptr))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// Adds a path to FieldMask after checking whether the given path is valid.
|
||||
// This method check-fails if the path is not a valid path for type T.
|
||||
template <typename T>
|
||||
static void AddPathToFieldMask(StringPiece path, FieldMask* mask) {
|
||||
GOOGLE_CHECK(IsValidPath<T>(path)) << path;
|
||||
mask->add_paths(std::string(path));
|
||||
}
|
||||
|
||||
// Creates a FieldMask with all fields of type T. This FieldMask only
|
||||
// contains fields of T but not any sub-message fields.
|
||||
template <typename T>
|
||||
static FieldMask GetFieldMaskForAllFields() {
|
||||
FieldMask out;
|
||||
GetFieldMaskForAllFields(T::descriptor(), &out);
|
||||
return out;
|
||||
}
|
||||
template <typename T>
|
||||
PROTOBUF_DEPRECATED_MSG("Use *out = GetFieldMaskForAllFields() instead")
|
||||
static void GetFieldMaskForAllFields(FieldMask* out) {
|
||||
GetFieldMaskForAllFields(T::descriptor(), out);
|
||||
}
|
||||
// This flavor takes the protobuf type descriptor as an argument.
|
||||
// Useful when the type is not known at compile time.
|
||||
static void GetFieldMaskForAllFields(const Descriptor* descriptor,
|
||||
FieldMask* out);
|
||||
|
||||
// Converts a FieldMask to the canonical form. It will:
|
||||
// 1. Remove paths that are covered by another path. For example,
|
||||
// "foo.bar" is covered by "foo" and will be removed if "foo"
|
||||
// is also in the FieldMask.
|
||||
// 2. Sort all paths in alphabetical order.
|
||||
static void ToCanonicalForm(const FieldMask& mask, FieldMask* out);
|
||||
|
||||
// Creates an union of two FieldMasks.
|
||||
static void Union(const FieldMask& mask1, const FieldMask& mask2,
|
||||
FieldMask* out);
|
||||
|
||||
// Creates an intersection of two FieldMasks.
|
||||
static void Intersect(const FieldMask& mask1, const FieldMask& mask2,
|
||||
FieldMask* out);
|
||||
|
||||
// Subtracts mask2 from mask1 base of type T.
|
||||
template <typename T>
|
||||
static void Subtract(const FieldMask& mask1, const FieldMask& mask2,
|
||||
FieldMask* out) {
|
||||
Subtract(T::descriptor(), mask1, mask2, out);
|
||||
}
|
||||
// This flavor takes the protobuf type descriptor as an argument.
|
||||
// Useful when the type is not known at compile time.
|
||||
static void Subtract(const Descriptor* descriptor, const FieldMask& mask1,
|
||||
const FieldMask& mask2, FieldMask* out);
|
||||
|
||||
// Returns true if path is covered by the given FieldMask. Note that path
|
||||
// "foo.bar" covers all paths like "foo.bar.baz", "foo.bar.quz.x", etc.
|
||||
// Also note that parent paths are not covered by explicit child path, i.e.
|
||||
// "foo.bar" does NOT cover "foo", even if "bar" is the only child.
|
||||
static bool IsPathInFieldMask(StringPiece path, const FieldMask& mask);
|
||||
|
||||
class MergeOptions;
|
||||
// Merges fields specified in a FieldMask into another message.
|
||||
static void MergeMessageTo(const Message& source, const FieldMask& mask,
|
||||
const MergeOptions& options, Message* destination);
|
||||
|
||||
class TrimOptions;
|
||||
// Removes from 'message' any field that is not represented in the given
|
||||
// FieldMask. If the FieldMask is empty, does nothing.
|
||||
// Returns true if the message is modified.
|
||||
static bool TrimMessage(const FieldMask& mask, Message* message);
|
||||
|
||||
// Removes from 'message' any field that is not represented in the given
|
||||
// FieldMask with customized TrimOptions.
|
||||
// If the FieldMask is empty, does nothing.
|
||||
// Returns true if the message is modified.
|
||||
static bool TrimMessage(const FieldMask& mask, Message* message,
|
||||
const TrimOptions& options);
|
||||
|
||||
private:
|
||||
friend class SnakeCaseCamelCaseTest;
|
||||
// Converts a field name from snake_case to camelCase:
|
||||
// 1. Every character after "_" will be converted to uppercase.
|
||||
// 2. All "_"s are removed.
|
||||
// The conversion will fail if:
|
||||
// 1. The field name contains uppercase letters.
|
||||
// 2. Any character after a "_" is not a lowercase letter.
|
||||
// If the conversion succeeds, it's guaranteed that the resulted
|
||||
// camelCase name will yield the original snake_case name when
|
||||
// converted using CamelCaseToSnakeCase().
|
||||
//
|
||||
// Note that the input can contain characters not allowed in C identifiers.
|
||||
// For example, "foo_bar,baz_quz" will be converted to "fooBar,bazQuz"
|
||||
// successfully.
|
||||
static bool SnakeCaseToCamelCase(StringPiece input,
|
||||
std::string* output);
|
||||
// Converts a field name from camelCase to snake_case:
|
||||
// 1. Every uppercase letter is converted to lowercase with an additional
|
||||
// preceding "_".
|
||||
// The conversion will fail if:
|
||||
// 1. The field name contains "_"s.
|
||||
// If the conversion succeeds, it's guaranteed that the resulted
|
||||
// snake_case name will yield the original camelCase name when
|
||||
// converted using SnakeCaseToCamelCase().
|
||||
//
|
||||
// Note that the input can contain characters not allowed in C identifiers.
|
||||
// For example, "fooBar,bazQuz" will be converted to "foo_bar,baz_quz"
|
||||
// successfully.
|
||||
static bool CamelCaseToSnakeCase(StringPiece input,
|
||||
std::string* output);
|
||||
};
|
||||
|
||||
class PROTOBUF_EXPORT FieldMaskUtil::MergeOptions {
|
||||
public:
|
||||
MergeOptions()
|
||||
: replace_message_fields_(false), replace_repeated_fields_(false) {}
|
||||
// When merging message fields, the default behavior is to merge the
|
||||
// content of two message fields together. If you instead want to use
|
||||
// the field from the source message to replace the corresponding field
|
||||
// in the destination message, set this flag to true. When this flag is set,
|
||||
// specified submessage fields that are missing in source will be cleared in
|
||||
// destination.
|
||||
void set_replace_message_fields(bool value) {
|
||||
replace_message_fields_ = value;
|
||||
}
|
||||
bool replace_message_fields() const { return replace_message_fields_; }
|
||||
// The default merging behavior will append entries from the source
|
||||
// repeated field to the destination repeated field. If you only want
|
||||
// to keep the entries from the source repeated field, set this flag
|
||||
// to true.
|
||||
void set_replace_repeated_fields(bool value) {
|
||||
replace_repeated_fields_ = value;
|
||||
}
|
||||
bool replace_repeated_fields() const { return replace_repeated_fields_; }
|
||||
|
||||
private:
|
||||
bool replace_message_fields_;
|
||||
bool replace_repeated_fields_;
|
||||
};
|
||||
|
||||
class PROTOBUF_EXPORT FieldMaskUtil::TrimOptions {
|
||||
public:
|
||||
TrimOptions() : keep_required_fields_(false) {}
|
||||
// When trimming message fields, the default behavior is to trim required
|
||||
// fields of the present message if they are not specified in the field mask.
|
||||
// If you instead want to keep required fields of the present message even
|
||||
// they are not specified in the field mask, set this flag to true.
|
||||
void set_keep_required_fields(bool value) { keep_required_fields_ = value; }
|
||||
bool keep_required_fields() const { return keep_required_fields_; }
|
||||
|
||||
private:
|
||||
bool keep_required_fields_;
|
||||
};
|
||||
|
||||
} // namespace util
|
||||
} // namespace protobuf
|
||||
} // namespace google
|
||||
|
||||
#include <google/protobuf/port_undef.inc>
|
||||
|
||||
#endif // GOOGLE_PROTOBUF_UTIL_FIELD_MASK_UTIL_H__
|
||||
204
external/include/google/protobuf/util/json_util.h
vendored
Normal file
204
external/include/google/protobuf/util/json_util.h
vendored
Normal file
@@ -0,0 +1,204 @@
|
||||
// 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.
|
||||
|
||||
// Utility functions to convert between protobuf binary format and proto3 JSON
|
||||
// format.
|
||||
#ifndef GOOGLE_PROTOBUF_UTIL_JSON_UTIL_H__
|
||||
#define GOOGLE_PROTOBUF_UTIL_JSON_UTIL_H__
|
||||
|
||||
#include <google/protobuf/message.h>
|
||||
#include <google/protobuf/util/type_resolver.h>
|
||||
#include <google/protobuf/stubs/bytestream.h>
|
||||
#include <google/protobuf/stubs/status.h>
|
||||
#include <google/protobuf/stubs/strutil.h>
|
||||
|
||||
#include <google/protobuf/port_def.inc>
|
||||
|
||||
namespace google {
|
||||
namespace protobuf {
|
||||
namespace io {
|
||||
class ZeroCopyInputStream;
|
||||
class ZeroCopyOutputStream;
|
||||
} // namespace io
|
||||
namespace util {
|
||||
|
||||
struct JsonParseOptions {
|
||||
// Whether to ignore unknown JSON fields during parsing
|
||||
bool ignore_unknown_fields;
|
||||
|
||||
// If true, when a lowercase enum value fails to parse, try convert it to
|
||||
// UPPER_CASE and see if it matches a valid enum.
|
||||
// WARNING: This option exists only to preserve legacy behavior. Avoid using
|
||||
// this option. If your enum needs to support different casing, consider using
|
||||
// allow_alias instead.
|
||||
bool case_insensitive_enum_parsing;
|
||||
|
||||
JsonParseOptions()
|
||||
: ignore_unknown_fields(false),
|
||||
case_insensitive_enum_parsing(false) {}
|
||||
};
|
||||
|
||||
struct JsonPrintOptions {
|
||||
// Whether to add spaces, line breaks and indentation to make the JSON output
|
||||
// easy to read.
|
||||
bool add_whitespace;
|
||||
// Whether to always print primitive fields. By default proto3 primitive
|
||||
// fields with default values will be omitted in JSON output. For example, an
|
||||
// int32 field set to 0 will be omitted. Set this flag to true will override
|
||||
// the default behavior and print primitive fields regardless of their values.
|
||||
bool always_print_primitive_fields;
|
||||
// Whether to always print enums as ints. By default they are rendered as
|
||||
// strings.
|
||||
bool always_print_enums_as_ints;
|
||||
// Whether to preserve proto field names
|
||||
bool preserve_proto_field_names;
|
||||
|
||||
JsonPrintOptions()
|
||||
: add_whitespace(false),
|
||||
always_print_primitive_fields(false),
|
||||
always_print_enums_as_ints(false),
|
||||
preserve_proto_field_names(false) {}
|
||||
};
|
||||
|
||||
// DEPRECATED. Use JsonPrintOptions instead.
|
||||
typedef JsonPrintOptions JsonOptions;
|
||||
|
||||
// Converts from protobuf message to JSON and appends it to |output|. This is a
|
||||
// simple wrapper of BinaryToJsonString(). It will use the DescriptorPool of the
|
||||
// passed-in message to resolve Any types.
|
||||
PROTOBUF_EXPORT util::Status MessageToJsonString(const Message& message,
|
||||
std::string* output,
|
||||
const JsonOptions& options);
|
||||
|
||||
inline util::Status MessageToJsonString(const Message& message,
|
||||
std::string* output) {
|
||||
return MessageToJsonString(message, output, JsonOptions());
|
||||
}
|
||||
|
||||
// Converts from JSON to protobuf message. This is a simple wrapper of
|
||||
// JsonStringToBinary(). It will use the DescriptorPool of the passed-in
|
||||
// message to resolve Any types.
|
||||
PROTOBUF_EXPORT util::Status JsonStringToMessage(
|
||||
StringPiece input, Message* message, const JsonParseOptions& options);
|
||||
|
||||
inline util::Status JsonStringToMessage(StringPiece input,
|
||||
Message* message) {
|
||||
return JsonStringToMessage(input, message, JsonParseOptions());
|
||||
}
|
||||
|
||||
// Converts protobuf binary data to JSON.
|
||||
// The conversion will fail if:
|
||||
// 1. TypeResolver fails to resolve a type.
|
||||
// 2. input is not valid protobuf wire format, or conflicts with the type
|
||||
// information returned by TypeResolver.
|
||||
// Note that unknown fields will be discarded silently.
|
||||
PROTOBUF_EXPORT util::Status BinaryToJsonStream(
|
||||
TypeResolver* resolver, const std::string& type_url,
|
||||
io::ZeroCopyInputStream* binary_input,
|
||||
io::ZeroCopyOutputStream* json_output, const JsonPrintOptions& options);
|
||||
|
||||
inline util::Status BinaryToJsonStream(TypeResolver* resolver,
|
||||
const std::string& type_url,
|
||||
io::ZeroCopyInputStream* binary_input,
|
||||
io::ZeroCopyOutputStream* json_output) {
|
||||
return BinaryToJsonStream(resolver, type_url, binary_input, json_output,
|
||||
JsonPrintOptions());
|
||||
}
|
||||
|
||||
PROTOBUF_EXPORT util::Status BinaryToJsonString(
|
||||
TypeResolver* resolver, const std::string& type_url,
|
||||
const std::string& binary_input, std::string* json_output,
|
||||
const JsonPrintOptions& options);
|
||||
|
||||
inline util::Status BinaryToJsonString(TypeResolver* resolver,
|
||||
const std::string& type_url,
|
||||
const std::string& binary_input,
|
||||
std::string* json_output) {
|
||||
return BinaryToJsonString(resolver, type_url, binary_input, json_output,
|
||||
JsonPrintOptions());
|
||||
}
|
||||
|
||||
// Converts JSON data to protobuf binary format.
|
||||
// The conversion will fail if:
|
||||
// 1. TypeResolver fails to resolve a type.
|
||||
// 2. input is not valid JSON format, or conflicts with the type
|
||||
// information returned by TypeResolver.
|
||||
PROTOBUF_EXPORT util::Status JsonToBinaryStream(
|
||||
TypeResolver* resolver, const std::string& type_url,
|
||||
io::ZeroCopyInputStream* json_input,
|
||||
io::ZeroCopyOutputStream* binary_output, const JsonParseOptions& options);
|
||||
|
||||
inline util::Status JsonToBinaryStream(
|
||||
TypeResolver* resolver, const std::string& type_url,
|
||||
io::ZeroCopyInputStream* json_input,
|
||||
io::ZeroCopyOutputStream* binary_output) {
|
||||
return JsonToBinaryStream(resolver, type_url, json_input, binary_output,
|
||||
JsonParseOptions());
|
||||
}
|
||||
|
||||
PROTOBUF_EXPORT util::Status JsonToBinaryString(
|
||||
TypeResolver* resolver, const std::string& type_url,
|
||||
StringPiece json_input, std::string* binary_output,
|
||||
const JsonParseOptions& options);
|
||||
|
||||
inline util::Status JsonToBinaryString(TypeResolver* resolver,
|
||||
const std::string& type_url,
|
||||
StringPiece json_input,
|
||||
std::string* binary_output) {
|
||||
return JsonToBinaryString(resolver, type_url, json_input, binary_output,
|
||||
JsonParseOptions());
|
||||
}
|
||||
|
||||
namespace internal {
|
||||
// Internal helper class. Put in the header so we can write unit-tests for it.
|
||||
class PROTOBUF_EXPORT ZeroCopyStreamByteSink : public strings::ByteSink {
|
||||
public:
|
||||
explicit ZeroCopyStreamByteSink(io::ZeroCopyOutputStream* stream)
|
||||
: stream_(stream), buffer_(NULL), buffer_size_(0) {}
|
||||
~ZeroCopyStreamByteSink();
|
||||
|
||||
void Append(const char* bytes, size_t len) override;
|
||||
|
||||
private:
|
||||
io::ZeroCopyOutputStream* stream_;
|
||||
void* buffer_;
|
||||
int buffer_size_;
|
||||
|
||||
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ZeroCopyStreamByteSink);
|
||||
};
|
||||
} // namespace internal
|
||||
|
||||
} // namespace util
|
||||
} // namespace protobuf
|
||||
} // namespace google
|
||||
|
||||
#include <google/protobuf/port_undef.inc>
|
||||
|
||||
#endif // GOOGLE_PROTOBUF_UTIL_JSON_UTIL_H__
|
||||
972
external/include/google/protobuf/util/message_differencer.h
vendored
Normal file
972
external/include/google/protobuf/util/message_differencer.h
vendored
Normal file
@@ -0,0 +1,972 @@
|
||||
// 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.
|
||||
|
||||
// Author: jschorr@google.com (Joseph Schorr)
|
||||
// Based on original Protocol Buffers design by
|
||||
// Sanjay Ghemawat, Jeff Dean, and others.
|
||||
//
|
||||
// This file defines static methods and classes for comparing Protocol
|
||||
// Messages.
|
||||
//
|
||||
// Aug. 2008: Added Unknown Fields Comparison for messages.
|
||||
// Aug. 2009: Added different options to compare repeated fields.
|
||||
// Apr. 2010: Moved field comparison to FieldComparator
|
||||
// Sep. 2020: Added option to output map keys in path
|
||||
|
||||
#ifndef GOOGLE_PROTOBUF_UTIL_MESSAGE_DIFFERENCER_H__
|
||||
#define GOOGLE_PROTOBUF_UTIL_MESSAGE_DIFFERENCER_H__
|
||||
|
||||
#include <functional>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <set>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include <google/protobuf/descriptor.h> // FieldDescriptor
|
||||
#include <google/protobuf/message.h> // Message
|
||||
#include <google/protobuf/unknown_field_set.h>
|
||||
#include <google/protobuf/util/field_comparator.h>
|
||||
|
||||
// Always include as last one, otherwise it can break compilation
|
||||
#include <google/protobuf/port_def.inc>
|
||||
|
||||
namespace google {
|
||||
namespace protobuf {
|
||||
|
||||
class DynamicMessageFactory;
|
||||
class FieldDescriptor;
|
||||
|
||||
namespace io {
|
||||
class ZeroCopyOutputStream;
|
||||
class Printer;
|
||||
} // namespace io
|
||||
|
||||
namespace util {
|
||||
|
||||
class DefaultFieldComparator;
|
||||
class FieldContext; // declared below MessageDifferencer
|
||||
|
||||
// Defines a collection of field descriptors.
|
||||
// In case of internal google codebase we are using absl::FixedArray instead
|
||||
// of vector. It significantly speeds up proto comparison (by ~30%) by
|
||||
// reducing the number of malloc/free operations
|
||||
typedef std::vector<const FieldDescriptor*> FieldDescriptorArray;
|
||||
|
||||
// A basic differencer that can be used to determine
|
||||
// the differences between two specified Protocol Messages. If any differences
|
||||
// are found, the Compare method will return false, and any differencer reporter
|
||||
// specified via ReportDifferencesTo will have its reporting methods called (see
|
||||
// below for implementation of the report). Based off of the original
|
||||
// ProtocolDifferencer implementation in //net/proto/protocol-differencer.h
|
||||
// (Thanks Todd!).
|
||||
//
|
||||
// MessageDifferencer REQUIRES that compared messages be the same type, defined
|
||||
// as messages that share the same descriptor. If not, the behavior of this
|
||||
// class is undefined.
|
||||
//
|
||||
// People disagree on what MessageDifferencer should do when asked to compare
|
||||
// messages with different descriptors. Some people think it should always
|
||||
// return false. Others expect it to try to look for similar fields and
|
||||
// compare them anyway -- especially if the descriptors happen to be identical.
|
||||
// If we chose either of these behaviors, some set of people would find it
|
||||
// surprising, and could end up writing code expecting the other behavior
|
||||
// without realizing their error. Therefore, we forbid that usage.
|
||||
//
|
||||
// This class is implemented based on the proto2 reflection. The performance
|
||||
// should be good enough for normal usages. However, for places where the
|
||||
// performance is extremely sensitive, there are several alternatives:
|
||||
// - Comparing serialized string
|
||||
// Downside: false negatives (there are messages that are the same but their
|
||||
// serialized strings are different).
|
||||
// - Equals code generator by compiler plugin (net/proto2/contrib/equals_plugin)
|
||||
// Downside: more generated code; maintenance overhead for the additional rule
|
||||
// (must be in sync with the original proto_library).
|
||||
//
|
||||
// Note on handling of google.protobuf.Any: MessageDifferencer automatically
|
||||
// unpacks Any::value into a Message and compares its individual fields.
|
||||
// Messages encoded in a repeated Any cannot be compared using TreatAsMap.
|
||||
//
|
||||
// Note on thread-safety: MessageDifferencer is *not* thread-safe. You need to
|
||||
// guard it with a lock to use the same MessageDifferencer instance from
|
||||
// multiple threads. Note that it's fine to call static comparison methods
|
||||
// (like MessageDifferencer::Equals) concurrently, but it's not recommended for
|
||||
// performance critical code as it leads to extra allocations.
|
||||
class PROTOBUF_EXPORT MessageDifferencer {
|
||||
public:
|
||||
// Determines whether the supplied messages are equal. Equality is defined as
|
||||
// all fields within the two messages being set to the same value. Primitive
|
||||
// fields and strings are compared by value while embedded messages/groups
|
||||
// are compared as if via a recursive call. Use Compare() with IgnoreField()
|
||||
// if some fields should be ignored in the comparison. Use Compare() with
|
||||
// TreatAsSet() if there are repeated fields where ordering does not matter.
|
||||
//
|
||||
// This method REQUIRES that the two messages have the same
|
||||
// Descriptor (message1.GetDescriptor() == message2.GetDescriptor()).
|
||||
static bool Equals(const Message& message1, const Message& message2);
|
||||
|
||||
// Determines whether the supplied messages are equivalent. Equivalency is
|
||||
// defined as all fields within the two messages having the same value. This
|
||||
// differs from the Equals method above in that fields with default values
|
||||
// are considered set to said value automatically. For details on how default
|
||||
// values are defined for each field type, see:
|
||||
// https://developers.google.com/protocol-buffers/docs/proto?csw=1#optional.
|
||||
// Also, Equivalent() ignores unknown fields. Use IgnoreField() and Compare()
|
||||
// if some fields should be ignored in the comparison.
|
||||
//
|
||||
// This method REQUIRES that the two messages have the same
|
||||
// Descriptor (message1.GetDescriptor() == message2.GetDescriptor()).
|
||||
static bool Equivalent(const Message& message1, const Message& message2);
|
||||
|
||||
// Determines whether the supplied messages are approximately equal.
|
||||
// Approximate equality is defined as all fields within the two messages
|
||||
// being approximately equal. Primitive (non-float) fields and strings are
|
||||
// compared by value, floats are compared using MathUtil::AlmostEquals() and
|
||||
// embedded messages/groups are compared as if via a recursive call. Use
|
||||
// IgnoreField() and Compare() if some fields should be ignored in the
|
||||
// comparison.
|
||||
//
|
||||
// This method REQUIRES that the two messages have the same
|
||||
// Descriptor (message1.GetDescriptor() == message2.GetDescriptor()).
|
||||
static bool ApproximatelyEquals(const Message& message1,
|
||||
const Message& message2);
|
||||
|
||||
// Determines whether the supplied messages are approximately equivalent.
|
||||
// Approximate equivalency is defined as all fields within the two messages
|
||||
// being approximately equivalent. As in
|
||||
// MessageDifferencer::ApproximatelyEquals, primitive (non-float) fields and
|
||||
// strings are compared by value, floats are compared using
|
||||
// MathUtil::AlmostEquals() and embedded messages/groups are compared as if
|
||||
// via a recursive call. However, fields with default values are considered
|
||||
// set to said value, as per MessageDiffencer::Equivalent. Use IgnoreField()
|
||||
// and Compare() if some fields should be ignored in the comparison.
|
||||
//
|
||||
// This method REQUIRES that the two messages have the same
|
||||
// Descriptor (message1.GetDescriptor() == message2.GetDescriptor()).
|
||||
static bool ApproximatelyEquivalent(const Message& message1,
|
||||
const Message& message2);
|
||||
|
||||
// Identifies an individual field in a message instance. Used for field_path,
|
||||
// below.
|
||||
struct SpecificField {
|
||||
// For known fields, "field" is filled in and "unknown_field_number" is -1.
|
||||
// For unknown fields, "field" is NULL, "unknown_field_number" is the field
|
||||
// number, and "unknown_field_type" is its type.
|
||||
const FieldDescriptor* field = nullptr;
|
||||
int unknown_field_number = -1;
|
||||
UnknownField::Type unknown_field_type = UnknownField::Type::TYPE_VARINT;
|
||||
|
||||
// If this a repeated field, "index" is the index within it. For unknown
|
||||
// fields, this is the index of the field among all unknown fields of the
|
||||
// same field number and type.
|
||||
int index = -1;
|
||||
|
||||
// If "field" is a repeated field which is being treated as a map or
|
||||
// a set (see TreatAsMap() and TreatAsSet(), below), new_index indicates
|
||||
// the index the position to which the element has moved. If the element
|
||||
// has not moved, "new_index" will have the same value as "index".
|
||||
int new_index = -1;
|
||||
|
||||
// For unknown fields, these are the pointers to the UnknownFieldSet
|
||||
// containing the unknown fields. In certain cases (e.g. proto1's
|
||||
// MessageSet, or nested groups of unknown fields), these may differ from
|
||||
// the messages' internal UnknownFieldSets.
|
||||
const UnknownFieldSet* unknown_field_set1 = nullptr;
|
||||
const UnknownFieldSet* unknown_field_set2 = nullptr;
|
||||
|
||||
// For unknown fields, these are the index of the field within the
|
||||
// UnknownFieldSets. One or the other will be -1 when
|
||||
// reporting an addition or deletion.
|
||||
int unknown_field_index1 = -1;
|
||||
int unknown_field_index2 = -1;
|
||||
};
|
||||
|
||||
// Class for processing Any deserialization. This logic is used by both the
|
||||
// MessageDifferencer and StreamReporter classes.
|
||||
class UnpackAnyField {
|
||||
private:
|
||||
std::unique_ptr<DynamicMessageFactory> dynamic_message_factory_;
|
||||
|
||||
public:
|
||||
UnpackAnyField() = default;
|
||||
~UnpackAnyField() = default;
|
||||
// If "any" is of type google.protobuf.Any, extract its payload using
|
||||
// DynamicMessageFactory and store in "data".
|
||||
bool UnpackAny(const Message& any, std::unique_ptr<Message>* data);
|
||||
};
|
||||
|
||||
// Abstract base class from which all MessageDifferencer
|
||||
// reporters derive. The five Report* methods below will be called when
|
||||
// a field has been added, deleted, modified, moved, or matched. The third
|
||||
// argument is a vector of FieldDescriptor pointers which describes the chain
|
||||
// of fields that was taken to find the current field. For example, for a
|
||||
// field found in an embedded message, the vector will contain two
|
||||
// FieldDescriptors. The first will be the field of the embedded message
|
||||
// itself and the second will be the actual field in the embedded message
|
||||
// that was added/deleted/modified.
|
||||
// Fields will be reported in PostTraversalOrder.
|
||||
// For example, given following proto, if both baz and quux are changed.
|
||||
// foo {
|
||||
// bar {
|
||||
// baz: 1
|
||||
// quux: 2
|
||||
// }
|
||||
// }
|
||||
// ReportModified will be invoked with following order:
|
||||
// 1. foo.bar.baz or foo.bar.quux
|
||||
// 2. foo.bar.quux or foo.bar.baz
|
||||
// 2. foo.bar
|
||||
// 3. foo
|
||||
class PROTOBUF_EXPORT Reporter {
|
||||
public:
|
||||
Reporter();
|
||||
virtual ~Reporter();
|
||||
|
||||
// Reports that a field has been added into Message2.
|
||||
virtual void ReportAdded(const Message& message1, const Message& message2,
|
||||
const std::vector<SpecificField>& field_path) = 0;
|
||||
|
||||
// Reports that a field has been deleted from Message1.
|
||||
virtual void ReportDeleted(
|
||||
const Message& message1, const Message& message2,
|
||||
const std::vector<SpecificField>& field_path) = 0;
|
||||
|
||||
// Reports that the value of a field has been modified.
|
||||
virtual void ReportModified(
|
||||
const Message& message1, const Message& message2,
|
||||
const std::vector<SpecificField>& field_path) = 0;
|
||||
|
||||
// Reports that a repeated field has been moved to another location. This
|
||||
// only applies when using TreatAsSet or TreatAsMap() -- see below. Also
|
||||
// note that for any given field, ReportModified and ReportMoved are
|
||||
// mutually exclusive. If a field has been both moved and modified, then
|
||||
// only ReportModified will be called.
|
||||
virtual void ReportMoved(
|
||||
const Message& /* message1 */, const Message& /* message2 */,
|
||||
const std::vector<SpecificField>& /* field_path */) {}
|
||||
|
||||
// Reports that two fields match. Useful for doing side-by-side diffs.
|
||||
// This function is mutually exclusive with ReportModified and ReportMoved.
|
||||
// Note that you must call set_report_matches(true) before calling Compare
|
||||
// to make use of this function.
|
||||
virtual void ReportMatched(
|
||||
const Message& /* message1 */, const Message& /* message2 */,
|
||||
const std::vector<SpecificField>& /* field_path */) {}
|
||||
|
||||
// Reports that two fields would have been compared, but the
|
||||
// comparison has been skipped because the field was marked as
|
||||
// 'ignored' using IgnoreField(). This function is mutually
|
||||
// exclusive with all the other Report() functions.
|
||||
//
|
||||
// The contract of ReportIgnored is slightly different than the
|
||||
// other Report() functions, in that |field_path.back().index| is
|
||||
// always equal to -1, even if the last field is repeated. This is
|
||||
// because while the other Report() functions indicate where in a
|
||||
// repeated field the action (Addition, Deletion, etc...)
|
||||
// happened, when a repeated field is 'ignored', the differencer
|
||||
// simply calls ReportIgnored on the repeated field as a whole and
|
||||
// moves on without looking at its individual elements.
|
||||
//
|
||||
// Furthermore, ReportIgnored() does not indicate whether the
|
||||
// fields were in fact equal or not, as Compare() does not inspect
|
||||
// these fields at all. It is up to the Reporter to decide whether
|
||||
// the fields are equal or not (perhaps with a second call to
|
||||
// Compare()), if it cares.
|
||||
virtual void ReportIgnored(
|
||||
const Message& /* message1 */, const Message& /* message2 */,
|
||||
const std::vector<SpecificField>& /* field_path */) {}
|
||||
|
||||
// Report that an unknown field is ignored. (see comment above).
|
||||
// Note this is a different function since the last SpecificField in field
|
||||
// path has a null field. This could break existing Reporter.
|
||||
virtual void ReportUnknownFieldIgnored(
|
||||
const Message& /* message1 */, const Message& /* message2 */,
|
||||
const std::vector<SpecificField>& /* field_path */) {}
|
||||
|
||||
private:
|
||||
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(Reporter);
|
||||
};
|
||||
|
||||
// MapKeyComparator is used to determine if two elements have the same key
|
||||
// when comparing elements of a repeated field as a map.
|
||||
class PROTOBUF_EXPORT MapKeyComparator {
|
||||
public:
|
||||
MapKeyComparator();
|
||||
virtual ~MapKeyComparator();
|
||||
|
||||
virtual bool IsMatch(
|
||||
const Message& /* message1 */, const Message& /* message2 */,
|
||||
const std::vector<SpecificField>& /* parent_fields */) const {
|
||||
GOOGLE_CHECK(false) << "IsMatch() is not implemented.";
|
||||
return false;
|
||||
}
|
||||
|
||||
private:
|
||||
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MapKeyComparator);
|
||||
};
|
||||
|
||||
// Abstract base class from which all IgnoreCriteria derive.
|
||||
// By adding IgnoreCriteria more complex ignore logic can be implemented.
|
||||
// IgnoreCriteria are registered with AddIgnoreCriteria. For each compared
|
||||
// field IsIgnored is called on each added IgnoreCriteria until one returns
|
||||
// true or all return false.
|
||||
// IsIgnored is called for fields where at least one side has a value.
|
||||
class PROTOBUF_EXPORT IgnoreCriteria {
|
||||
public:
|
||||
IgnoreCriteria();
|
||||
virtual ~IgnoreCriteria();
|
||||
|
||||
// Returns true if the field should be ignored.
|
||||
virtual bool IsIgnored(
|
||||
const Message& /* message1 */, const Message& /* message2 */,
|
||||
const FieldDescriptor* /* field */,
|
||||
const std::vector<SpecificField>& /* parent_fields */) = 0;
|
||||
|
||||
// Returns true if the unknown field should be ignored.
|
||||
// Note: This will be called for unknown fields as well in which case
|
||||
// field.field will be null.
|
||||
virtual bool IsUnknownFieldIgnored(
|
||||
const Message& /* message1 */, const Message& /* message2 */,
|
||||
const SpecificField& /* field */,
|
||||
const std::vector<SpecificField>& /* parent_fields */) {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
// To add a Reporter, construct default here, then use ReportDifferencesTo or
|
||||
// ReportDifferencesToString.
|
||||
explicit MessageDifferencer();
|
||||
|
||||
~MessageDifferencer();
|
||||
|
||||
enum MessageFieldComparison {
|
||||
EQUAL, // Fields must be present in both messages
|
||||
// for the messages to be considered the same.
|
||||
EQUIVALENT, // Fields with default values are considered set
|
||||
// for comparison purposes even if not explicitly
|
||||
// set in the messages themselves. Unknown fields
|
||||
// are ignored.
|
||||
};
|
||||
|
||||
enum Scope {
|
||||
FULL, // All fields of both messages are considered in the comparison.
|
||||
PARTIAL // Only fields present in the first message are considered; fields
|
||||
// set only in the second message will be skipped during
|
||||
// comparison.
|
||||
};
|
||||
|
||||
// DEPRECATED. Use FieldComparator::FloatComparison instead.
|
||||
enum FloatComparison {
|
||||
EXACT, // Floats and doubles are compared exactly.
|
||||
APPROXIMATE // Floats and doubles are compared using the
|
||||
// MathUtil::AlmostEquals method.
|
||||
};
|
||||
|
||||
enum RepeatedFieldComparison {
|
||||
AS_LIST, // Repeated fields are compared in order. Differing values at
|
||||
// the same index are reported using ReportModified(). If the
|
||||
// repeated fields have different numbers of elements, the
|
||||
// unpaired elements are reported using ReportAdded() or
|
||||
// ReportDeleted().
|
||||
AS_SET, // Treat all the repeated fields as sets.
|
||||
// See TreatAsSet(), as below.
|
||||
AS_SMART_LIST, // Similar to AS_SET, but preserve the order and find the
|
||||
// longest matching sequence from the first matching
|
||||
// element. To use an optimal solution, call
|
||||
// SetMatchIndicesForSmartListCallback() to pass it in.
|
||||
AS_SMART_SET, // Similar to AS_SET, but match elements with fewest diffs.
|
||||
};
|
||||
|
||||
// The elements of the given repeated field will be treated as a set for
|
||||
// diffing purposes, so different orderings of the same elements will be
|
||||
// considered equal. Elements which are present on both sides of the
|
||||
// comparison but which have changed position will be reported with
|
||||
// ReportMoved(). Elements which only exist on one side or the other are
|
||||
// reported with ReportAdded() and ReportDeleted() regardless of their
|
||||
// positions. ReportModified() is never used for this repeated field. If
|
||||
// the only differences between the compared messages is that some fields
|
||||
// have been moved, then the comparison returns true.
|
||||
//
|
||||
// Note that despite the name of this method, this is really
|
||||
// comparison as multisets: if one side of the comparison has a duplicate
|
||||
// in the repeated field but the other side doesn't, this will count as
|
||||
// a mismatch.
|
||||
//
|
||||
// If the scope of comparison is set to PARTIAL, then in addition to what's
|
||||
// above, extra values added to repeated fields of the second message will
|
||||
// not cause the comparison to fail.
|
||||
//
|
||||
// Note that set comparison is currently O(k * n^2) (where n is the total
|
||||
// number of elements, and k is the average size of each element). In theory
|
||||
// it could be made O(n * k) with a more complex hashing implementation. Feel
|
||||
// free to contribute one if the current implementation is too slow for you.
|
||||
// If partial matching is also enabled, the time complexity will be O(k * n^2
|
||||
// + n^3) in which n^3 is the time complexity of the maximum matching
|
||||
// algorithm.
|
||||
//
|
||||
// REQUIRES: field->is_repeated() and field not registered with TreatAsMap*
|
||||
void TreatAsSet(const FieldDescriptor* field);
|
||||
void TreatAsSmartSet(const FieldDescriptor* field);
|
||||
|
||||
// The elements of the given repeated field will be treated as a list for
|
||||
// diffing purposes, so different orderings of the same elements will NOT be
|
||||
// considered equal.
|
||||
//
|
||||
// REQUIRES: field->is_repeated() and field not registered with TreatAsMap*
|
||||
void TreatAsList(const FieldDescriptor* field);
|
||||
// Note that the complexity is similar to treating as SET.
|
||||
void TreatAsSmartList(const FieldDescriptor* field);
|
||||
|
||||
// The elements of the given repeated field will be treated as a map for
|
||||
// diffing purposes, with |key| being the map key. Thus, elements with the
|
||||
// same key will be compared even if they do not appear at the same index.
|
||||
// Differences are reported similarly to TreatAsSet(), except that
|
||||
// ReportModified() is used to report elements with the same key but
|
||||
// different values. Note that if an element is both moved and modified,
|
||||
// only ReportModified() will be called. As with TreatAsSet, if the only
|
||||
// differences between the compared messages is that some fields have been
|
||||
// moved, then the comparison returns true. See TreatAsSet for notes on
|
||||
// performance.
|
||||
//
|
||||
// REQUIRES: field->is_repeated()
|
||||
// REQUIRES: field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE
|
||||
// REQUIRES: key->containing_type() == field->message_type()
|
||||
void TreatAsMap(const FieldDescriptor* field, const FieldDescriptor* key);
|
||||
// Same as TreatAsMap except that this method will use multiple fields as
|
||||
// the key in comparison. All specified fields in 'key_fields' should be
|
||||
// present in the compared elements. Two elements will be treated as having
|
||||
// the same key iff they have the same value for every specified field. There
|
||||
// are two steps in the comparison process. The first one is key matching.
|
||||
// Every element from one message will be compared to every element from
|
||||
// the other message. Only fields in 'key_fields' are compared in this step
|
||||
// to decide if two elements have the same key. The second step is value
|
||||
// comparison. Those pairs of elements with the same key (with equal value
|
||||
// for every field in 'key_fields') will be compared in this step.
|
||||
// Time complexity of the first step is O(s * m * n ^ 2) where s is the
|
||||
// average size of the fields specified in 'key_fields', m is the number of
|
||||
// fields in 'key_fields' and n is the number of elements. If partial
|
||||
// matching is enabled, an extra O(n^3) will be incured by the maximum
|
||||
// matching algorithm. The second step is O(k * n) where k is the average
|
||||
// size of each element.
|
||||
void TreatAsMapWithMultipleFieldsAsKey(
|
||||
const FieldDescriptor* field,
|
||||
const std::vector<const FieldDescriptor*>& key_fields);
|
||||
// Same as TreatAsMapWithMultipleFieldsAsKey, except that each of the field
|
||||
// do not necessarily need to be a direct subfield. Each element in
|
||||
// key_field_paths indicate a path from the message being compared, listing
|
||||
// successive subfield to reach the key field.
|
||||
//
|
||||
// REQUIRES:
|
||||
// for key_field_path in key_field_paths:
|
||||
// key_field_path[0]->containing_type() == field->message_type()
|
||||
// for i in [0, key_field_path.size() - 1):
|
||||
// key_field_path[i+1]->containing_type() ==
|
||||
// key_field_path[i]->message_type()
|
||||
// key_field_path[i]->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE
|
||||
// !key_field_path[i]->is_repeated()
|
||||
void TreatAsMapWithMultipleFieldPathsAsKey(
|
||||
const FieldDescriptor* field,
|
||||
const std::vector<std::vector<const FieldDescriptor*> >& key_field_paths);
|
||||
|
||||
// Uses a custom MapKeyComparator to determine if two elements have the same
|
||||
// key when comparing a repeated field as a map.
|
||||
// The caller is responsible to delete the key_comparator.
|
||||
// This method varies from TreatAsMapWithMultipleFieldsAsKey only in the
|
||||
// first key matching step. Rather than comparing some specified fields, it
|
||||
// will invoke the IsMatch method of the given 'key_comparator' to decide if
|
||||
// two elements have the same key.
|
||||
void TreatAsMapUsingKeyComparator(const FieldDescriptor* field,
|
||||
const MapKeyComparator* key_comparator);
|
||||
|
||||
// Initiates and returns a new instance of MultipleFieldsMapKeyComparator.
|
||||
MapKeyComparator* CreateMultipleFieldsMapKeyComparator(
|
||||
const std::vector<std::vector<const FieldDescriptor*> >& key_field_paths);
|
||||
|
||||
// Add a custom ignore criteria that is evaluated in addition to the
|
||||
// ignored fields added with IgnoreField.
|
||||
// Takes ownership of ignore_criteria.
|
||||
void AddIgnoreCriteria(IgnoreCriteria* ignore_criteria);
|
||||
|
||||
// Indicates that any field with the given descriptor should be
|
||||
// ignored for the purposes of comparing two messages. This applies
|
||||
// to fields nested in the message structure as well as top level
|
||||
// ones. When the MessageDifferencer encounters an ignored field,
|
||||
// ReportIgnored is called on the reporter, if one is specified.
|
||||
//
|
||||
// The only place where the field's 'ignored' status is not applied is when
|
||||
// it is being used as a key in a field passed to TreatAsMap or is one of
|
||||
// the fields passed to TreatAsMapWithMultipleFieldsAsKey.
|
||||
// In this case it is compared in key matching but after that it's ignored
|
||||
// in value comparison.
|
||||
void IgnoreField(const FieldDescriptor* field);
|
||||
|
||||
// Sets the field comparator used to determine differences between protocol
|
||||
// buffer fields. By default it's set to a DefaultFieldComparator instance.
|
||||
// MessageDifferencer doesn't take ownership over the passed object.
|
||||
// Note that this method must be called before Compare for the comparator to
|
||||
// be used.
|
||||
void set_field_comparator(FieldComparator* comparator);
|
||||
#ifdef PROTOBUF_FUTURE_BREAKING_CHANGES
|
||||
void set_field_comparator(DefaultFieldComparator* comparator);
|
||||
#endif // PROTOBUF_FUTURE_BREAKING_CHANGES
|
||||
|
||||
// DEPRECATED. Pass a DefaultFieldComparator instance instead.
|
||||
// Sets the fraction and margin for the float comparison of a given field.
|
||||
// Uses MathUtil::WithinFractionOrMargin to compare the values.
|
||||
// NOTE: this method does nothing if differencer's field comparator has been
|
||||
// set to a custom object.
|
||||
//
|
||||
// REQUIRES: field->cpp_type == FieldDescriptor::CPPTYPE_DOUBLE or
|
||||
// field->cpp_type == FieldDescriptor::CPPTYPE_FLOAT
|
||||
// REQUIRES: float_comparison_ == APPROXIMATE
|
||||
void SetFractionAndMargin(const FieldDescriptor* field, double fraction,
|
||||
double margin);
|
||||
|
||||
// Sets the type of comparison (as defined in the MessageFieldComparison
|
||||
// enumeration above) that is used by this differencer when determining how
|
||||
// to compare fields in messages.
|
||||
void set_message_field_comparison(MessageFieldComparison comparison);
|
||||
|
||||
// Tells the differencer whether or not to report matches. This method must
|
||||
// be called before Compare. The default for a new differencer is false.
|
||||
void set_report_matches(bool report_matches) {
|
||||
report_matches_ = report_matches;
|
||||
}
|
||||
|
||||
// Tells the differencer whether or not to report moves (in a set or map
|
||||
// repeated field). This method must be called before Compare. The default for
|
||||
// a new differencer is true.
|
||||
void set_report_moves(bool report_moves) { report_moves_ = report_moves; }
|
||||
|
||||
// Tells the differencer whether or not to report ignored values. This method
|
||||
// must be called before Compare. The default for a new differencer is true.
|
||||
void set_report_ignores(bool report_ignores) {
|
||||
report_ignores_ = report_ignores;
|
||||
}
|
||||
|
||||
// Sets the scope of the comparison (as defined in the Scope enumeration
|
||||
// above) that is used by this differencer when determining which fields to
|
||||
// compare between the messages.
|
||||
void set_scope(Scope scope);
|
||||
|
||||
// Returns the current scope used by this differencer.
|
||||
Scope scope();
|
||||
|
||||
// DEPRECATED. Pass a DefaultFieldComparator instance instead.
|
||||
// Sets the type of comparison (as defined in the FloatComparison enumeration
|
||||
// above) that is used by this differencer when comparing float (and double)
|
||||
// fields in messages.
|
||||
// NOTE: this method does nothing if differencer's field comparator has been
|
||||
// set to a custom object.
|
||||
void set_float_comparison(FloatComparison comparison);
|
||||
|
||||
// Sets the type of comparison for repeated field (as defined in the
|
||||
// RepeatedFieldComparison enumeration above) that is used by this
|
||||
// differencer when compare repeated fields in messages.
|
||||
void set_repeated_field_comparison(RepeatedFieldComparison comparison);
|
||||
|
||||
// Returns the current repeated field comparison used by this differencer.
|
||||
RepeatedFieldComparison repeated_field_comparison();
|
||||
|
||||
// Compares the two specified messages, returning true if they are the same,
|
||||
// false otherwise. If this method returns false, any changes between the
|
||||
// two messages will be reported if a Reporter was specified via
|
||||
// ReportDifferencesTo (see also ReportDifferencesToString).
|
||||
//
|
||||
// This method REQUIRES that the two messages have the same
|
||||
// Descriptor (message1.GetDescriptor() == message2.GetDescriptor()).
|
||||
bool Compare(const Message& message1, const Message& message2);
|
||||
|
||||
// Same as above, except comparing only the list of fields specified by the
|
||||
// two vectors of FieldDescriptors.
|
||||
bool CompareWithFields(
|
||||
const Message& message1, const Message& message2,
|
||||
const std::vector<const FieldDescriptor*>& message1_fields,
|
||||
const std::vector<const FieldDescriptor*>& message2_fields);
|
||||
|
||||
// Automatically creates a reporter that will output the differences
|
||||
// found (if any) to the specified output string pointer. Note that this
|
||||
// method must be called before Compare.
|
||||
void ReportDifferencesToString(std::string* output);
|
||||
|
||||
// Tells the MessageDifferencer to report differences via the specified
|
||||
// reporter. Note that this method must be called before Compare for
|
||||
// the reporter to be used. It is the responsibility of the caller to delete
|
||||
// this object.
|
||||
// If the provided pointer equals NULL, the MessageDifferencer stops reporting
|
||||
// differences to any previously set reporters or output strings.
|
||||
void ReportDifferencesTo(Reporter* reporter);
|
||||
|
||||
// An implementation of the MessageDifferencer Reporter that outputs
|
||||
// any differences found in human-readable form to the supplied
|
||||
// ZeroCopyOutputStream or Printer. If a printer is used, the delimiter
|
||||
// *must* be '$'.
|
||||
//
|
||||
// WARNING: this reporter does not necessarily flush its output until it is
|
||||
// destroyed. As a result, it is not safe to assume the output is valid or
|
||||
// complete until after you destroy the reporter. For example, if you use a
|
||||
// StreamReporter to write to a StringOutputStream, the target string may
|
||||
// contain uninitialized data until the reporter is destroyed.
|
||||
class PROTOBUF_EXPORT StreamReporter : public Reporter {
|
||||
public:
|
||||
explicit StreamReporter(io::ZeroCopyOutputStream* output);
|
||||
explicit StreamReporter(io::Printer* printer); // delimiter '$'
|
||||
~StreamReporter() override;
|
||||
|
||||
// When set to true, the stream reporter will also output aggregates nodes
|
||||
// (i.e. messages and groups) whose subfields have been modified. When
|
||||
// false, will only report the individual subfields. Defaults to false.
|
||||
void set_report_modified_aggregates(bool report) {
|
||||
report_modified_aggregates_ = report;
|
||||
}
|
||||
|
||||
// The following are implementations of the methods described above.
|
||||
|
||||
void ReportAdded(const Message& message1, const Message& message2,
|
||||
const std::vector<SpecificField>& field_path) override;
|
||||
|
||||
void ReportDeleted(const Message& message1, const Message& message2,
|
||||
const std::vector<SpecificField>& field_path) override;
|
||||
|
||||
void ReportModified(const Message& message1, const Message& message2,
|
||||
const std::vector<SpecificField>& field_path) override;
|
||||
|
||||
void ReportMoved(const Message& message1, const Message& message2,
|
||||
const std::vector<SpecificField>& field_path) override;
|
||||
|
||||
void ReportMatched(const Message& message1, const Message& message2,
|
||||
const std::vector<SpecificField>& field_path) override;
|
||||
|
||||
void ReportIgnored(const Message& message1, const Message& message2,
|
||||
const std::vector<SpecificField>& field_path) override;
|
||||
|
||||
void ReportUnknownFieldIgnored(
|
||||
const Message& message1, const Message& message2,
|
||||
const std::vector<SpecificField>& field_path) override;
|
||||
|
||||
// Messages that are being compared must be provided to StreamReporter prior
|
||||
// to processing
|
||||
void SetMessages(const Message& message1, const Message& message2);
|
||||
|
||||
protected:
|
||||
// Prints the specified path of fields to the buffer.
|
||||
virtual void PrintPath(const std::vector<SpecificField>& field_path,
|
||||
bool left_side);
|
||||
|
||||
// Prints the value of fields to the buffer. left_side is true if the
|
||||
// given message is from the left side of the comparison, false if it
|
||||
// was the right. This is relevant only to decide whether to follow
|
||||
// unknown_field_index1 or unknown_field_index2 when an unknown field
|
||||
// is encountered in field_path.
|
||||
virtual void PrintValue(const Message& message,
|
||||
const std::vector<SpecificField>& field_path,
|
||||
bool left_side);
|
||||
|
||||
// Prints the specified path of unknown fields to the buffer.
|
||||
virtual void PrintUnknownFieldValue(const UnknownField* unknown_field);
|
||||
|
||||
// Just print a string
|
||||
void Print(const std::string& str);
|
||||
|
||||
// helper function for PrintPath that contains logic for printing maps
|
||||
void PrintMapKey(const std::vector<SpecificField>& field_path,
|
||||
bool left_side, const SpecificField& specific_field,
|
||||
size_t target_field_index);
|
||||
|
||||
private:
|
||||
io::Printer* printer_;
|
||||
bool delete_printer_;
|
||||
bool report_modified_aggregates_;
|
||||
const Message* message1_;
|
||||
const Message* message2_;
|
||||
MessageDifferencer::UnpackAnyField unpack_any_field_;
|
||||
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(StreamReporter);
|
||||
};
|
||||
|
||||
private:
|
||||
friend class SimpleFieldComparator;
|
||||
|
||||
// A MapKeyComparator to be used in TreatAsMapUsingKeyComparator.
|
||||
// Implementation of this class needs to do field value comparison which
|
||||
// relies on some private methods of MessageDifferencer. That's why this
|
||||
// class is declared as a nested class of MessageDifferencer.
|
||||
class MultipleFieldsMapKeyComparator;
|
||||
|
||||
// A MapKeyComparator for use with map_entries.
|
||||
class PROTOBUF_EXPORT MapEntryKeyComparator : public MapKeyComparator {
|
||||
public:
|
||||
explicit MapEntryKeyComparator(MessageDifferencer* message_differencer);
|
||||
bool IsMatch(
|
||||
const Message& message1, const Message& message2,
|
||||
const std::vector<SpecificField>& parent_fields) const override;
|
||||
|
||||
private:
|
||||
MessageDifferencer* message_differencer_;
|
||||
};
|
||||
|
||||
// Returns true if field1's number() is less than field2's.
|
||||
static bool FieldBefore(const FieldDescriptor* field1,
|
||||
const FieldDescriptor* field2);
|
||||
|
||||
// Retrieve all the set fields, including extensions.
|
||||
FieldDescriptorArray RetrieveFields(const Message& message,
|
||||
bool base_message);
|
||||
|
||||
// Combine the two lists of fields into the combined_fields output vector.
|
||||
// All fields present in both lists will always be included in the combined
|
||||
// list. Fields only present in one of the lists will only appear in the
|
||||
// combined list if the corresponding fields_scope option is set to FULL.
|
||||
FieldDescriptorArray CombineFields(const FieldDescriptorArray& fields1,
|
||||
Scope fields1_scope,
|
||||
const FieldDescriptorArray& fields2,
|
||||
Scope fields2_scope);
|
||||
|
||||
// Internal version of the Compare method which performs the actual
|
||||
// comparison. The parent_fields vector is a vector containing field
|
||||
// descriptors of all fields accessed to get to this comparison operation
|
||||
// (i.e. if the current message is an embedded message, the parent_fields
|
||||
// vector will contain the field that has this embedded message).
|
||||
bool Compare(const Message& message1, const Message& message2,
|
||||
std::vector<SpecificField>* parent_fields);
|
||||
|
||||
// Compares all the unknown fields in two messages.
|
||||
bool CompareUnknownFields(const Message& message1, const Message& message2,
|
||||
const UnknownFieldSet&, const UnknownFieldSet&,
|
||||
std::vector<SpecificField>* parent_fields);
|
||||
|
||||
// Compares the specified messages for the requested field lists. The field
|
||||
// lists are modified depending on comparison settings, and then passed to
|
||||
// CompareWithFieldsInternal.
|
||||
bool CompareRequestedFieldsUsingSettings(
|
||||
const Message& message1, const Message& message2,
|
||||
const FieldDescriptorArray& message1_fields,
|
||||
const FieldDescriptorArray& message2_fields,
|
||||
std::vector<SpecificField>* parent_fields);
|
||||
|
||||
// Compares the specified messages with the specified field lists.
|
||||
bool CompareWithFieldsInternal(const Message& message1,
|
||||
const Message& message2,
|
||||
const FieldDescriptorArray& message1_fields,
|
||||
const FieldDescriptorArray& message2_fields,
|
||||
std::vector<SpecificField>* parent_fields);
|
||||
|
||||
// Compares the repeated fields, and report the error.
|
||||
bool CompareRepeatedField(const Message& message1, const Message& message2,
|
||||
const FieldDescriptor* field,
|
||||
std::vector<SpecificField>* parent_fields);
|
||||
|
||||
// Compares map fields, and report the error.
|
||||
bool CompareMapField(const Message& message1, const Message& message2,
|
||||
const FieldDescriptor* field,
|
||||
std::vector<SpecificField>* parent_fields);
|
||||
|
||||
// Helper for CompareRepeatedField and CompareMapField: compares and reports
|
||||
// differences element-wise. This is the implementation for non-map fields,
|
||||
// and can also compare map fields by using the underlying representation.
|
||||
bool CompareRepeatedRep(const Message& message1, const Message& message2,
|
||||
const FieldDescriptor* field,
|
||||
std::vector<SpecificField>* parent_fields);
|
||||
|
||||
// Helper for CompareMapField: compare the map fields using map reflection
|
||||
// instead of sync to repeated.
|
||||
bool CompareMapFieldByMapReflection(const Message& message1,
|
||||
const Message& message2,
|
||||
const FieldDescriptor* field,
|
||||
std::vector<SpecificField>* parent_fields,
|
||||
DefaultFieldComparator* comparator);
|
||||
|
||||
// Shorthand for CompareFieldValueUsingParentFields with NULL parent_fields.
|
||||
bool CompareFieldValue(const Message& message1, const Message& message2,
|
||||
const FieldDescriptor* field, int index1, int index2);
|
||||
|
||||
// Compares the specified field on the two messages, returning
|
||||
// true if they are the same, false otherwise. For repeated fields,
|
||||
// this method only compares the value in the specified index. This method
|
||||
// uses Compare functions to recurse into submessages.
|
||||
// The parent_fields vector is used in calls to a Reporter instance calls.
|
||||
// It can be NULL, in which case the MessageDifferencer will create new
|
||||
// list of parent messages if it needs to recursively compare the given field.
|
||||
// To avoid confusing users you should not set it to NULL unless you modified
|
||||
// Reporter to handle the change of parent_fields correctly.
|
||||
bool CompareFieldValueUsingParentFields(
|
||||
const Message& message1, const Message& message2,
|
||||
const FieldDescriptor* field, int index1, int index2,
|
||||
std::vector<SpecificField>* parent_fields);
|
||||
|
||||
// Compares the specified field on the two messages, returning comparison
|
||||
// result, as returned by appropriate FieldComparator.
|
||||
FieldComparator::ComparisonResult GetFieldComparisonResult(
|
||||
const Message& message1, const Message& message2,
|
||||
const FieldDescriptor* field, int index1, int index2,
|
||||
const FieldContext* field_context);
|
||||
|
||||
// Check if the two elements in the repeated field are match to each other.
|
||||
// if the key_comprator is NULL, this function returns true when the two
|
||||
// elements are equal.
|
||||
bool IsMatch(const FieldDescriptor* repeated_field,
|
||||
const MapKeyComparator* key_comparator, const Message* message1,
|
||||
const Message* message2,
|
||||
const std::vector<SpecificField>& parent_fields,
|
||||
Reporter* reporter, int index1, int index2);
|
||||
|
||||
// Returns true when this repeated field has been configured to be treated
|
||||
// as a Set / SmartSet / SmartList.
|
||||
bool IsTreatedAsSet(const FieldDescriptor* field);
|
||||
bool IsTreatedAsSmartSet(const FieldDescriptor* field);
|
||||
|
||||
bool IsTreatedAsSmartList(const FieldDescriptor* field);
|
||||
// When treating as SMART_LIST, it uses MatchIndicesPostProcessorForSmartList
|
||||
// by default to find the longest matching sequence from the first matching
|
||||
// element. The callback takes two vectors showing the matching indices from
|
||||
// the other vector, where -1 means an unmatch.
|
||||
void SetMatchIndicesForSmartListCallback(
|
||||
std::function<void(std::vector<int>*, std::vector<int>*)> callback);
|
||||
|
||||
// Returns true when this repeated field is to be compared as a subset, ie.
|
||||
// has been configured to be treated as a set or map and scope is set to
|
||||
// PARTIAL.
|
||||
bool IsTreatedAsSubset(const FieldDescriptor* field);
|
||||
|
||||
// Returns true if this field is to be ignored when this
|
||||
// MessageDifferencer compares messages.
|
||||
bool IsIgnored(const Message& message1, const Message& message2,
|
||||
const FieldDescriptor* field,
|
||||
const std::vector<SpecificField>& parent_fields);
|
||||
|
||||
// Returns true if this unknown field is to be ignored when this
|
||||
// MessageDifferencer compares messages.
|
||||
bool IsUnknownFieldIgnored(const Message& message1, const Message& message2,
|
||||
const SpecificField& field,
|
||||
const std::vector<SpecificField>& parent_fields);
|
||||
|
||||
// Returns MapKeyComparator* when this field has been configured to be treated
|
||||
// as a map or its is_map() return true. If not, returns NULL.
|
||||
const MapKeyComparator* GetMapKeyComparator(
|
||||
const FieldDescriptor* field) const;
|
||||
|
||||
// Attempts to match indices of a repeated field, so that the contained values
|
||||
// match. Clears output vectors and sets their values to indices of paired
|
||||
// messages, ie. if message1[0] matches message2[1], then match_list1[0] == 1
|
||||
// and match_list2[1] == 0. The unmatched indices are indicated by -1.
|
||||
// Assumes the repeated field is not treated as a simple list.
|
||||
// This method returns false if the match failed. However, it doesn't mean
|
||||
// that the comparison succeeds when this method returns true (you need to
|
||||
// double-check in this case).
|
||||
bool MatchRepeatedFieldIndices(
|
||||
const Message& message1, const Message& message2,
|
||||
const FieldDescriptor* repeated_field,
|
||||
const MapKeyComparator* key_comparator,
|
||||
const std::vector<SpecificField>& parent_fields,
|
||||
std::vector<int>* match_list1, std::vector<int>* match_list2);
|
||||
|
||||
// Checks if index is equal to new_index in all the specific fields.
|
||||
static bool CheckPathChanged(const std::vector<SpecificField>& parent_fields);
|
||||
|
||||
// CHECKs that the given repeated field can be compared according to
|
||||
// new_comparison.
|
||||
void CheckRepeatedFieldComparisons(
|
||||
const FieldDescriptor* field,
|
||||
const RepeatedFieldComparison& new_comparison);
|
||||
|
||||
// Defines a map between field descriptors and their MapKeyComparators.
|
||||
// Used for repeated fields when they are configured as TreatAsMap.
|
||||
typedef std::map<const FieldDescriptor*, const MapKeyComparator*>
|
||||
FieldKeyComparatorMap;
|
||||
|
||||
// Defines a set to store field descriptors. Used for repeated fields when
|
||||
// they are configured as TreatAsSet.
|
||||
typedef std::set<const FieldDescriptor*> FieldSet;
|
||||
typedef std::map<const FieldDescriptor*, RepeatedFieldComparison> FieldMap;
|
||||
|
||||
Reporter* reporter_;
|
||||
DefaultFieldComparator default_field_comparator_;
|
||||
MessageFieldComparison message_field_comparison_;
|
||||
Scope scope_;
|
||||
RepeatedFieldComparison repeated_field_comparison_;
|
||||
|
||||
FieldMap repeated_field_comparisons_;
|
||||
// Keeps track of MapKeyComparators that are created within
|
||||
// MessageDifferencer. These MapKeyComparators should be deleted
|
||||
// before MessageDifferencer is destroyed.
|
||||
// When TreatAsMap or TreatAsMapWithMultipleFieldsAsKey is called, we don't
|
||||
// store the supplied FieldDescriptors directly. Instead, a new
|
||||
// MapKeyComparator is created for comparison purpose.
|
||||
std::vector<MapKeyComparator*> owned_key_comparators_;
|
||||
FieldKeyComparatorMap map_field_key_comparator_;
|
||||
MapEntryKeyComparator map_entry_key_comparator_;
|
||||
std::vector<IgnoreCriteria*> ignore_criteria_;
|
||||
// Reused multiple times in RetrieveFields to avoid extra allocations
|
||||
std::vector<const FieldDescriptor*> tmp_message_fields_;
|
||||
|
||||
FieldSet ignored_fields_;
|
||||
|
||||
union {
|
||||
DefaultFieldComparator* default_impl;
|
||||
FieldComparator* base;
|
||||
} field_comparator_ = {&default_field_comparator_};
|
||||
enum { kFCDefault, kFCBase } field_comparator_kind_ = kFCDefault;
|
||||
|
||||
bool report_matches_;
|
||||
bool report_moves_;
|
||||
bool report_ignores_;
|
||||
|
||||
std::string* output_string_;
|
||||
|
||||
// Callback to post-process the matched indices to support SMART_LIST.
|
||||
std::function<void(std::vector<int>*, std::vector<int>*)>
|
||||
match_indices_for_smart_list_callback_;
|
||||
|
||||
MessageDifferencer::UnpackAnyField unpack_any_field_;
|
||||
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MessageDifferencer);
|
||||
};
|
||||
|
||||
// This class provides extra information to the FieldComparator::Compare
|
||||
// function.
|
||||
class PROTOBUF_EXPORT FieldContext {
|
||||
public:
|
||||
explicit FieldContext(
|
||||
std::vector<MessageDifferencer::SpecificField>* parent_fields)
|
||||
: parent_fields_(parent_fields) {}
|
||||
|
||||
std::vector<MessageDifferencer::SpecificField>* parent_fields() const {
|
||||
return parent_fields_;
|
||||
}
|
||||
|
||||
private:
|
||||
std::vector<MessageDifferencer::SpecificField>* parent_fields_;
|
||||
};
|
||||
|
||||
} // namespace util
|
||||
} // namespace protobuf
|
||||
} // namespace google
|
||||
|
||||
#include <google/protobuf/port_undef.inc>
|
||||
|
||||
#endif // GOOGLE_PROTOBUF_UTIL_MESSAGE_DIFFERENCER_H__
|
||||
313
external/include/google/protobuf/util/time_util.h
vendored
Normal file
313
external/include/google/protobuf/util/time_util.h
vendored
Normal file
@@ -0,0 +1,313 @@
|
||||
// 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.
|
||||
|
||||
// Defines utilities for the Timestamp and Duration well known types.
|
||||
|
||||
#ifndef GOOGLE_PROTOBUF_UTIL_TIME_UTIL_H__
|
||||
#define GOOGLE_PROTOBUF_UTIL_TIME_UTIL_H__
|
||||
|
||||
#include <cstdint>
|
||||
#include <ctime>
|
||||
#include <ostream>
|
||||
#include <string>
|
||||
#ifdef _MSC_VER
|
||||
#ifdef _XBOX_ONE
|
||||
struct timeval {
|
||||
int64 tv_sec; /* seconds */
|
||||
int64 tv_usec; /* and microseconds */
|
||||
};
|
||||
#else
|
||||
#include <winsock2.h>
|
||||
#endif // _XBOX_ONE
|
||||
#else
|
||||
#include <sys/time.h>
|
||||
#endif
|
||||
|
||||
#include <google/protobuf/duration.pb.h>
|
||||
#include <google/protobuf/timestamp.pb.h>
|
||||
|
||||
#include <google/protobuf/port_def.inc>
|
||||
|
||||
namespace google {
|
||||
namespace protobuf {
|
||||
namespace util {
|
||||
|
||||
// Utility functions for Timestamp and Duration.
|
||||
class PROTOBUF_EXPORT TimeUtil {
|
||||
typedef google::protobuf::Timestamp Timestamp;
|
||||
typedef google::protobuf::Duration Duration;
|
||||
|
||||
public:
|
||||
// The min/max Timestamp/Duration values we support.
|
||||
//
|
||||
// For "0001-01-01T00:00:00Z".
|
||||
static const int64_t kTimestampMinSeconds = -62135596800LL;
|
||||
// For "9999-12-31T23:59:59.999999999Z".
|
||||
static const int64_t kTimestampMaxSeconds = 253402300799LL;
|
||||
static const int64_t kDurationMinSeconds = -315576000000LL;
|
||||
static const int64_t kDurationMaxSeconds = 315576000000LL;
|
||||
|
||||
// Converts Timestamp to/from RFC 3339 date string format.
|
||||
// Generated output will always be Z-normalized and uses 3, 6 or 9
|
||||
// fractional digits as required to represent the exact time. When
|
||||
// parsing, any fractional digits (or none) and any offset are
|
||||
// accepted as long as they fit into nano-seconds precision.
|
||||
// Note that Timestamp can only represent time from
|
||||
// 0001-01-01T00:00:00Z to 9999-12-31T23:59:59.999999999Z. Converting
|
||||
// a Timestamp outside of this range is undefined behavior.
|
||||
// See https://www.ietf.org/rfc/rfc3339.txt
|
||||
//
|
||||
// Example of generated format:
|
||||
// "1972-01-01T10:00:20.021Z"
|
||||
//
|
||||
// Example of accepted format:
|
||||
// "1972-01-01T10:00:20.021-05:00"
|
||||
static std::string ToString(const Timestamp& timestamp);
|
||||
static bool FromString(const std::string& value, Timestamp* timestamp);
|
||||
|
||||
// Converts Duration to/from string format. The string format will contains
|
||||
// 3, 6, or 9 fractional digits depending on the precision required to
|
||||
// represent the exact Duration value. For example:
|
||||
// "1s", "1.010s", "1.000000100s", "-3.100s"
|
||||
// The range that can be represented by Duration is from -315,576,000,000
|
||||
// to +315,576,000,000 inclusive (in seconds).
|
||||
static std::string ToString(const Duration& duration);
|
||||
static bool FromString(const std::string& value, Duration* timestamp);
|
||||
|
||||
#ifdef GetCurrentTime
|
||||
#undef GetCurrentTime // Visual Studio has macro GetCurrentTime
|
||||
#endif
|
||||
// Gets the current UTC time.
|
||||
static Timestamp GetCurrentTime();
|
||||
// Returns the Time representing "1970-01-01 00:00:00".
|
||||
static Timestamp GetEpoch();
|
||||
|
||||
// Converts between Duration and integer types. The behavior is undefined if
|
||||
// the input value is not in the valid range of Duration.
|
||||
static Duration NanosecondsToDuration(int64_t nanos);
|
||||
static Duration MicrosecondsToDuration(int64_t micros);
|
||||
static Duration MillisecondsToDuration(int64_t millis);
|
||||
static Duration SecondsToDuration(int64_t seconds);
|
||||
static Duration MinutesToDuration(int64_t minutes);
|
||||
static Duration HoursToDuration(int64_t hours);
|
||||
// Result will be truncated towards zero. For example, "-1.5s" will be
|
||||
// truncated to "-1s", and "1.5s" to "1s" when converting to seconds.
|
||||
// It's undefined behavior if the input duration is not valid or the result
|
||||
// exceeds the range of int64. A duration is not valid if it's not in the
|
||||
// valid range of Duration, or have an invalid nanos value (i.e., larger
|
||||
// than 999999999, less than -999999999, or have a different sign from the
|
||||
// seconds part).
|
||||
static int64_t DurationToNanoseconds(const Duration& duration);
|
||||
static int64_t DurationToMicroseconds(const Duration& duration);
|
||||
static int64_t DurationToMilliseconds(const Duration& duration);
|
||||
static int64_t DurationToSeconds(const Duration& duration);
|
||||
static int64_t DurationToMinutes(const Duration& duration);
|
||||
static int64_t DurationToHours(const Duration& duration);
|
||||
// Creates Timestamp from integer types. The integer value indicates the
|
||||
// time elapsed from Epoch time. The behavior is undefined if the input
|
||||
// value is not in the valid range of Timestamp.
|
||||
static Timestamp NanosecondsToTimestamp(int64_t nanos);
|
||||
static Timestamp MicrosecondsToTimestamp(int64_t micros);
|
||||
static Timestamp MillisecondsToTimestamp(int64_t millis);
|
||||
static Timestamp SecondsToTimestamp(int64_t seconds);
|
||||
// Result will be truncated down to the nearest integer value. For example,
|
||||
// with "1969-12-31T23:59:59.9Z", TimestampToMilliseconds() returns -100
|
||||
// and TimestampToSeconds() returns -1. It's undefined behavior if the input
|
||||
// Timestamp is not valid (i.e., its seconds part or nanos part does not fall
|
||||
// in the valid range) or the return value doesn't fit into int64.
|
||||
static int64_t TimestampToNanoseconds(const Timestamp& timestamp);
|
||||
static int64_t TimestampToMicroseconds(const Timestamp& timestamp);
|
||||
static int64_t TimestampToMilliseconds(const Timestamp& timestamp);
|
||||
static int64_t TimestampToSeconds(const Timestamp& timestamp);
|
||||
|
||||
// Conversion to/from other time/date types. Note that these types may
|
||||
// have a different precision and time range from Timestamp/Duration.
|
||||
// When converting to a lower precision type, the value will be truncated
|
||||
// to the nearest value that can be represented. If the value is
|
||||
// out of the range of the result type, the return value is undefined.
|
||||
//
|
||||
// Conversion to/from time_t
|
||||
static Timestamp TimeTToTimestamp(time_t value);
|
||||
static time_t TimestampToTimeT(const Timestamp& value);
|
||||
|
||||
// Conversion to/from timeval
|
||||
static Timestamp TimevalToTimestamp(const timeval& value);
|
||||
static timeval TimestampToTimeval(const Timestamp& value);
|
||||
static Duration TimevalToDuration(const timeval& value);
|
||||
static timeval DurationToTimeval(const Duration& value);
|
||||
};
|
||||
|
||||
} // namespace util
|
||||
} // namespace protobuf
|
||||
} // namespace google
|
||||
|
||||
namespace google {
|
||||
namespace protobuf {
|
||||
// Overloaded operators for Duration.
|
||||
//
|
||||
// Assignment operators.
|
||||
PROTOBUF_EXPORT Duration& operator+=(Duration& d1,
|
||||
const Duration& d2); // NOLINT
|
||||
PROTOBUF_EXPORT Duration& operator-=(Duration& d1,
|
||||
const Duration& d2); // NOLINT
|
||||
PROTOBUF_EXPORT Duration& operator*=(Duration& d, int64_t r); // NOLINT
|
||||
PROTOBUF_EXPORT Duration& operator*=(Duration& d, double r); // NOLINT
|
||||
PROTOBUF_EXPORT Duration& operator/=(Duration& d, int64_t r); // NOLINT
|
||||
PROTOBUF_EXPORT Duration& operator/=(Duration& d, double r); // NOLINT
|
||||
// Overload for other integer types.
|
||||
template <typename T>
|
||||
Duration& operator*=(Duration& d, T r) { // NOLINT
|
||||
int64_t x = r;
|
||||
return d *= x;
|
||||
}
|
||||
template <typename T>
|
||||
Duration& operator/=(Duration& d, T r) { // NOLINT
|
||||
int64_t x = r;
|
||||
return d /= x;
|
||||
}
|
||||
PROTOBUF_EXPORT Duration& operator%=(Duration& d1,
|
||||
const Duration& d2); // NOLINT
|
||||
// Relational operators.
|
||||
inline bool operator<(const Duration& d1, const Duration& d2) {
|
||||
if (d1.seconds() == d2.seconds()) {
|
||||
return d1.nanos() < d2.nanos();
|
||||
}
|
||||
return d1.seconds() < d2.seconds();
|
||||
}
|
||||
inline bool operator>(const Duration& d1, const Duration& d2) {
|
||||
return d2 < d1;
|
||||
}
|
||||
inline bool operator>=(const Duration& d1, const Duration& d2) {
|
||||
return !(d1 < d2);
|
||||
}
|
||||
inline bool operator<=(const Duration& d1, const Duration& d2) {
|
||||
return !(d2 < d1);
|
||||
}
|
||||
inline bool operator==(const Duration& d1, const Duration& d2) {
|
||||
return d1.seconds() == d2.seconds() && d1.nanos() == d2.nanos();
|
||||
}
|
||||
inline bool operator!=(const Duration& d1, const Duration& d2) {
|
||||
return !(d1 == d2);
|
||||
}
|
||||
// Additive operators
|
||||
inline Duration operator-(const Duration& d) {
|
||||
Duration result;
|
||||
result.set_seconds(-d.seconds());
|
||||
result.set_nanos(-d.nanos());
|
||||
return result;
|
||||
}
|
||||
inline Duration operator+(const Duration& d1, const Duration& d2) {
|
||||
Duration result = d1;
|
||||
return result += d2;
|
||||
}
|
||||
inline Duration operator-(const Duration& d1, const Duration& d2) {
|
||||
Duration result = d1;
|
||||
return result -= d2;
|
||||
}
|
||||
// Multiplicative operators
|
||||
template <typename T>
|
||||
inline Duration operator*(Duration d, T r) {
|
||||
return d *= r;
|
||||
}
|
||||
template <typename T>
|
||||
inline Duration operator*(T r, Duration d) {
|
||||
return d *= r;
|
||||
}
|
||||
template <typename T>
|
||||
inline Duration operator/(Duration d, T r) {
|
||||
return d /= r;
|
||||
}
|
||||
PROTOBUF_EXPORT int64_t operator/(const Duration& d1, const Duration& d2);
|
||||
|
||||
inline Duration operator%(const Duration& d1, const Duration& d2) {
|
||||
Duration result = d1;
|
||||
return result %= d2;
|
||||
}
|
||||
|
||||
inline std::ostream& operator<<(std::ostream& out, const Duration& d) {
|
||||
out << ::PROTOBUF_NAMESPACE_ID::util::TimeUtil::ToString(d);
|
||||
return out;
|
||||
}
|
||||
|
||||
// Overloaded operators for Timestamp
|
||||
//
|
||||
// Assignment operators.
|
||||
PROTOBUF_EXPORT Timestamp& operator+=(Timestamp& t,
|
||||
const Duration& d); // NOLINT
|
||||
PROTOBUF_EXPORT Timestamp& operator-=(Timestamp& t,
|
||||
const Duration& d); // NOLINT
|
||||
// Relational operators.
|
||||
inline bool operator<(const Timestamp& t1, const Timestamp& t2) {
|
||||
if (t1.seconds() == t2.seconds()) {
|
||||
return t1.nanos() < t2.nanos();
|
||||
}
|
||||
return t1.seconds() < t2.seconds();
|
||||
}
|
||||
inline bool operator>(const Timestamp& t1, const Timestamp& t2) {
|
||||
return t2 < t1;
|
||||
}
|
||||
inline bool operator>=(const Timestamp& t1, const Timestamp& t2) {
|
||||
return !(t1 < t2);
|
||||
}
|
||||
inline bool operator<=(const Timestamp& t1, const Timestamp& t2) {
|
||||
return !(t2 < t1);
|
||||
}
|
||||
inline bool operator==(const Timestamp& t1, const Timestamp& t2) {
|
||||
return t1.seconds() == t2.seconds() && t1.nanos() == t2.nanos();
|
||||
}
|
||||
inline bool operator!=(const Timestamp& t1, const Timestamp& t2) {
|
||||
return !(t1 == t2);
|
||||
}
|
||||
// Additive operators.
|
||||
inline Timestamp operator+(const Timestamp& t, const Duration& d) {
|
||||
Timestamp result = t;
|
||||
return result += d;
|
||||
}
|
||||
inline Timestamp operator+(const Duration& d, const Timestamp& t) {
|
||||
Timestamp result = t;
|
||||
return result += d;
|
||||
}
|
||||
inline Timestamp operator-(const Timestamp& t, const Duration& d) {
|
||||
Timestamp result = t;
|
||||
return result -= d;
|
||||
}
|
||||
PROTOBUF_EXPORT Duration operator-(const Timestamp& t1, const Timestamp& t2);
|
||||
|
||||
inline std::ostream& operator<<(std::ostream& out, const Timestamp& t) {
|
||||
out << ::PROTOBUF_NAMESPACE_ID::util::TimeUtil::ToString(t);
|
||||
return out;
|
||||
}
|
||||
|
||||
} // namespace protobuf
|
||||
} // namespace google
|
||||
|
||||
#include <google/protobuf/port_undef.inc>
|
||||
|
||||
#endif // GOOGLE_PROTOBUF_UTIL_TIME_UTIL_H__
|
||||
76
external/include/google/protobuf/util/type_resolver.h
vendored
Normal file
76
external/include/google/protobuf/util/type_resolver.h
vendored
Normal file
@@ -0,0 +1,76 @@
|
||||
// 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.
|
||||
|
||||
// Defines a TypeResolver for the Any message.
|
||||
|
||||
#ifndef GOOGLE_PROTOBUF_UTIL_TYPE_RESOLVER_H__
|
||||
#define GOOGLE_PROTOBUF_UTIL_TYPE_RESOLVER_H__
|
||||
|
||||
#include <string>
|
||||
|
||||
#include <google/protobuf/stubs/common.h>
|
||||
#include <google/protobuf/type.pb.h>
|
||||
#include <google/protobuf/stubs/status.h>
|
||||
#include <google/protobuf/stubs/status.h>
|
||||
|
||||
#include <google/protobuf/port_def.inc>
|
||||
|
||||
namespace google {
|
||||
namespace protobuf {
|
||||
class DescriptorPool;
|
||||
namespace util {
|
||||
|
||||
// Abstract interface for a type resolver.
|
||||
//
|
||||
// Implementations of this interface must be thread-safe.
|
||||
class PROTOBUF_EXPORT TypeResolver {
|
||||
public:
|
||||
TypeResolver() {}
|
||||
virtual ~TypeResolver() {}
|
||||
|
||||
// Resolves a type url for a message type.
|
||||
virtual util::Status ResolveMessageType(
|
||||
const std::string& type_url, google::protobuf::Type* message_type) = 0;
|
||||
|
||||
// Resolves a type url for an enum type.
|
||||
virtual util::Status ResolveEnumType(const std::string& type_url,
|
||||
google::protobuf::Enum* enum_type) = 0;
|
||||
|
||||
private:
|
||||
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(TypeResolver);
|
||||
};
|
||||
|
||||
} // namespace util
|
||||
} // namespace protobuf
|
||||
} // namespace google
|
||||
|
||||
#include <google/protobuf/port_undef.inc>
|
||||
|
||||
#endif // GOOGLE_PROTOBUF_UTIL_TYPE_RESOLVER_H__
|
||||
57
external/include/google/protobuf/util/type_resolver_util.h
vendored
Normal file
57
external/include/google/protobuf/util/type_resolver_util.h
vendored
Normal file
@@ -0,0 +1,57 @@
|
||||
// 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.
|
||||
|
||||
// Defines utilities for the TypeResolver.
|
||||
|
||||
#ifndef GOOGLE_PROTOBUF_UTIL_TYPE_RESOLVER_UTIL_H__
|
||||
#define GOOGLE_PROTOBUF_UTIL_TYPE_RESOLVER_UTIL_H__
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace google {
|
||||
namespace protobuf {
|
||||
class DescriptorPool;
|
||||
namespace util {
|
||||
class TypeResolver;
|
||||
|
||||
#include <google/protobuf/port_def.inc>
|
||||
|
||||
// Creates a TypeResolver that serves type information in the given descriptor
|
||||
// pool. Caller takes ownership of the returned TypeResolver.
|
||||
PROTOBUF_EXPORT TypeResolver* NewTypeResolverForDescriptorPool(
|
||||
const std::string& url_prefix, const DescriptorPool* pool);
|
||||
|
||||
} // namespace util
|
||||
} // namespace protobuf
|
||||
} // namespace google
|
||||
|
||||
#include <google/protobuf/port_undef.inc>
|
||||
|
||||
#endif // GOOGLE_PROTOBUF_UTIL_TYPE_RESOLVER_UTIL_H__
|
||||
Reference in New Issue
Block a user