Merge remote-tracking branch 'remotes/upstream/master' into kotlinProtos

pull/8272/head
Deanna Garcia 4 years ago
commit 7b23ae1e66
  1. 2
      .github/mergeable.yml
  2. 2
      .github/workflows/codespell.yml
  3. 1
      .gitignore
  4. 1
      CHANGES.txt
  5. 5
      benchmarks/download_data.sh
  6. 1
      java/core/BUILD
  7. 22
      java/core/src/main/java/com/google/protobuf/CodedInputStream.java
  8. 49
      java/core/src/test/java/com/google/protobuf/CodedInputStreamTest.java
  9. 1
      java/lite/pom.xml
  10. 13
      java/util/src/main/java/com/google/protobuf/util/Durations.java
  11. 1
      kokoro/linux/benchmark/run.sh
  12. 22
      kokoro/release/python/linux/build_artifacts.sh
  13. 57
      kokoro/release/python/linux/config.sh
  14. 2
      protoc-artifacts/README.md
  15. 3
      python/google/protobuf/pyext/descriptor.cc
  16. 3
      python/google/protobuf/pyext/descriptor_pool.cc
  17. 6
      python/google/protobuf/pyext/map_container.cc
  18. 15
      python/google/protobuf/pyext/message.cc
  19. 3
      python/google/protobuf/pyext/message_factory.cc
  20. 18
      python/setup.py
  21. 8
      src/google/protobuf/compiler/command_line_interface.cc
  22. 19
      src/google/protobuf/compiler/command_line_interface_unittest.cc
  23. 7
      src/google/protobuf/port.h
  24. 15
      src/google/protobuf/stubs/int128.cc
  25. 127
      src/google/protobuf/stubs/int128.h
  26. 200
      src/google/protobuf/stubs/int128_unittest.cc
  27. 2
      src/google/protobuf/stubs/logging.h
  28. 10
      src/google/protobuf/stubs/status.cc
  29. 10
      src/google/protobuf/stubs/status.h
  30. 4
      src/google/protobuf/stubs/status_test.cc
  31. 6
      src/google/protobuf/stubs/statusor.h
  32. 4
      src/google/protobuf/stubs/statusor_test.cc
  33. 8
      src/google/protobuf/util/field_comparator.h
  34. 15
      src/google/protobuf/util/internal/datapiece.cc
  35. 21
      src/google/protobuf/util/internal/field_mask_utility.cc
  36. 11
      src/google/protobuf/util/internal/json_stream_parser.cc
  37. 4
      src/google/protobuf/util/internal/protostream_objectsource.cc
  38. 15
      src/google/protobuf/util/internal/protostream_objectwriter.cc
  39. 5
      src/google/protobuf/util/json_util.cc
  40. 8
      src/google/protobuf/util/type_resolver_util.cc

@ -11,7 +11,7 @@ mergeable:
regex: 'release notes: yes'
message: 'Please include release notes: yes'
- must_include:
regex: '^(autotools|bazel|c#|c\+\+|cleanup|cmake|conformance tests|integration|go|java|javascript|objective-c|php|protoc|python|ruby)'
regex: '^(autotools|bazel|c#|c\+\+|cleanup|cmake|conformance tests|integration|go|java|javascript|objective-c|php|protoc|python|ruby|kotlin)'
message: 'Please include at least a language label (e.g., c++, java, python). Or apply one of the following labels: autotools, bazel, cmake, cleanup, conformance tests, integration, protoc.'
- must_include:
regex: 'release notes: no'

@ -13,4 +13,4 @@ jobs:
with:
check_filenames: true
skip: ./.git,./conformance/third_party,*.snk,*.pb,*.pb.cc,*.pb.h,./src/google/protobuf/testdata,./objectivec/Tests,./python/compatibility_tests/v2.5.0/tests/google/protobuf/internal
ignore_words_list: "alow,alse,ba,cleare,copyable,cloneable,dedup,dur,errorprone,files',fo,fundementals,hel,importd,inout,leapyear,nd,nin,ois,ons,parseable,process',te,testof,ue,unparseable,wasn,wee,gae,keyserver,objext,od"
ignore_words_list: "alow,alse,ba,cleare,copyable,cloneable,dedup,dur,errorprone,files',fo,fundementals,hel,importd,inout,leapyear,nd,nin,ois,ons,parseable,process',te,testof,ue,unparseable,wasn,wee,gae,keyserver,objext,od,OptIn"

1
.gitignore vendored

@ -83,6 +83,7 @@ src/**/*.trs
# JavaBuild output.
java/core/target
java/lite/target
java/util/target
javanano/target
java/.idea

@ -1,6 +1,7 @@
Unreleased Changes (C++/Java/Python/PHP/Objective-C/C#/Ruby/JavaScript)
C++
* The ::pb namespace is no longer exposed due to conflicts.
* Allow MessageDifferencer::TreatAsSet() (and friends) to override previous
calls instead of crashing.
* Reduce the size of generated proto headers for protos with `string` or

@ -1,5 +0,0 @@
#! /bin/sh
curl -O https://storage.googleapis.com/protobuf_opensource_benchmark_data/datasets.tar.gz
tar -zvxf datasets.tar.gz

@ -85,6 +85,7 @@ LITE_SRCS = [
"src/main/java/com/google/protobuf/UnknownFieldSetLite.java",
"src/main/java/com/google/protobuf/UnknownFieldSetLiteSchema.java",
"src/main/java/com/google/protobuf/UnmodifiableLazyStringList.java",
"src/main/java/com/google/protobuf/UnsafeByteOperations.java",
"src/main/java/com/google/protobuf/UnsafeUtil.java",
"src/main/java/com/google/protobuf/Utf8.java",
"src/main/java/com/google/protobuf/WireFormat.java",

@ -3523,9 +3523,25 @@ public abstract class CodedInputStream {
return ByteString.wrap(bytes);
}
} else if (size > 0 && size <= remaining()) {
byte[] temp = new byte[size];
readRawBytesTo(temp, 0, size);
return ByteString.wrap(temp);
if (immutable && enableAliasing) {
ArrayList<ByteString> byteStrings = new ArrayList<>();
int l = size;
while (l > 0) {
if (currentRemaining() == 0) {
getNextByteBuffer();
}
int bytesToCopy = Math.min(l, (int) currentRemaining());
int idx = (int) (currentByteBufferPos - currentAddress);
byteStrings.add(ByteString.wrap(slice(idx, idx + bytesToCopy)));
l -= bytesToCopy;
currentByteBufferPos += bytesToCopy;
}
return ByteString.copyFrom(byteStrings);
} else {
byte[] temp = new byte[size];
readRawBytesTo(temp, 0, size);
return ByteString.wrap(temp);
}
}
if (size == 0) {

@ -1142,6 +1142,39 @@ public class CodedInputStreamTest extends TestCase {
}
}
public void testIterableByteBufferInputStreamReadBytesWithAlias() throws Exception {
ByteArrayOutputStream byteArrayStream = new ByteArrayOutputStream();
CodedOutputStream output = CodedOutputStream.newInstance(byteArrayStream);
// A bytes field large enough that won't fit into the default block buffer.
// 4.5 is to test the case where the total size of input is not aligned with DEFAULT_BLOCK_SIZE.
final int bytesLength = DEFAULT_BLOCK_SIZE * 4 + (DEFAULT_BLOCK_SIZE / 2);
byte[] bytes = new byte[bytesLength];
for (int i = 0; i < bytesLength; i++) {
bytes[i] = (byte) (i % 256);
}
output.writeByteArrayNoTag(bytes);
output.flush();
// Input data is split into multiple ByteBuffers so that a single bytes spans across them.
// CodedInputStream with aliasing will decode it as a consequent rope by wrapping ByteBuffers.
byte[] data = byteArrayStream.toByteArray();
ArrayList<ByteBuffer> input = new ArrayList<>();
for (int i = 0; i < data.length; i += DEFAULT_BLOCK_SIZE) {
int rl = Math.min(DEFAULT_BLOCK_SIZE, data.length - i);
ByteBuffer rb = ByteBuffer.allocateDirect(rl);
rb.put(data, i, rl);
rb.flip();
input.add(rb);
}
final CodedInputStream inputStream = CodedInputStream.newInstance(input, true);
inputStream.enableAliasing(true);
ByteString result = inputStream.readBytes();
for (int i = 0; i < bytesLength; i++) {
assertEquals((byte) (i % 256), result.byteAt(i));
}
}
public void testCompatibleTypes() throws Exception {
long data = 0x100000000L;
Int64Message message = Int64Message.newBuilder().setData(data).build();
@ -1196,7 +1229,7 @@ public class CodedInputStreamTest extends TestCase {
// Expected
}
}
public void testMaliciousInputStream() throws Exception {
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
CodedOutputStream codedOutputStream = CodedOutputStream.newInstance(outputStream);
@ -1210,17 +1243,17 @@ public class CodedInputStreamTest extends TestCase {
return super.read(b, off, len);
}
};
// test ByteString
CodedInputStream codedInputStream = CodedInputStream.newInstance(inputStream, 1);
ByteString byteString = codedInputStream.readBytes();
assertEquals(0x0, byteString.byteAt(0));
maliciousCapture.get(1)[0] = 0x9;
assertEquals(0x0, byteString.byteAt(0));
// test ByteBuffer
inputStream.reset();
maliciousCapture.clear();
codedInputStream = CodedInputStream.newInstance(inputStream, 1);
@ -1228,10 +1261,10 @@ public class CodedInputStreamTest extends TestCase {
assertEquals(0x0, byteBuffer.get(0));
maliciousCapture.get(1)[0] = 0x9;
assertEquals(0x0, byteBuffer.get(0));
// test byte[]
inputStream.reset();
maliciousCapture.clear();
codedInputStream = CodedInputStream.newInstance(inputStream, 1);
@ -1241,7 +1274,7 @@ public class CodedInputStreamTest extends TestCase {
assertEquals(0x9, byteArray[0]); // MODIFICATION! Should we fix?
// test rawBytes
inputStream.reset();
maliciousCapture.clear();
codedInputStream = CodedInputStream.newInstance(inputStream, 1);

@ -173,6 +173,7 @@
<include>UnknownFieldSetLite.java</include>
<include>UnknownFieldSetLiteSchema.java</include>
<include>UnmodifiableLazyStringList.java</include>
<include>UnsafeByteOperations.java</include>
<include>UnsafeUtil.java</include>
<include>Utf8.java</include>
<include>WireFormat.java</include>

@ -149,6 +149,12 @@ public final class Durations {
return (duration.getSeconds() == 0) ? duration.getNanos() < 0 : duration.getSeconds() < 0;
}
/** Returns whether the given {@link Duration} is positive or not. */
public static boolean isPositive(Duration duration) {
checkValid(duration);
return !isNegative(duration) && !duration.equals(ZERO);
}
/**
* Ensures that the given {@link Duration} is not negative.
*
@ -157,7 +163,6 @@ public final class Durations {
*/
@CanIgnoreReturnValue
public static Duration checkNotNegative(Duration duration) {
checkValid(duration);
checkArgument(!isNegative(duration), "duration (%s) must not be negative", toString(duration));
return duration;
}
@ -170,11 +175,7 @@ public final class Durations {
*/
@CanIgnoreReturnValue
public static Duration checkPositive(Duration duration) {
checkValid(duration);
checkArgument(
!isNegative(duration) && !duration.equals(ZERO),
"duration (%s) must be positive",
toString(duration));
checkArgument(isPositive(duration), "duration (%s) must be positive", toString(duration));
return duration;
}

@ -18,7 +18,6 @@ fi
# download datasets for benchmark
cd benchmarks
./download_data.sh
datasets=$(for file in $(find . -type f -name "dataset.*.pb" -not -path "./tmp/*"); do echo "$(pwd)/$file"; done | xargs)
echo $datasets
cd $oldpwd

@ -49,9 +49,31 @@ build_artifact_version() {
sudo rm -rf $REPO_DIR
}
build_crosscompiled_aarch64_artifact_version() {
# crosscompilation is only supported with the dockcross manylinux2014 image
DOCKER_IMAGE=dockcross/manylinux2014-aarch64
PLAT=aarch64
# TODO(jtatermusch): currently when crosscompiling, "auditwheel repair" will be disabled
# since auditwheel doesn't work for crosscomiled wheels.
build_artifact_version $@
}
build_artifact_version 2.7
build_artifact_version 3.5
build_artifact_version 3.6
build_artifact_version 3.7
build_artifact_version 3.8
build_artifact_version 3.9
build_crosscompiled_aarch64_artifact_version 3.7
build_crosscompiled_aarch64_artifact_version 3.8
build_crosscompiled_aarch64_artifact_version 3.9
# Put the aarch64 manylinux wheels under the "unofficial" subdirectory.
# Only wheels directly under the artifacts/ directory will be published
# to PyPI as part of the protobuf release process.
# TODO(jtattermusch): include aarch64 wheels in the release
# once they are sufficiently tested.
mkdir -p $ARTIFACT_DIR/unofficial
mv $ARTIFACT_DIR/protobuf-*-manylinux*_aarch64.whl $ARTIFACT_DIR/unofficial

@ -6,15 +6,38 @@ function pre_build {
# Runs in the root directory of this repository.
pushd protobuf
yum install -y devtoolset-2-libatomic-devel
if [ "$PLAT" == "aarch64" ]
then
local configure_host_flag="--host=aarch64"
else
yum install -y devtoolset-2-libatomic-devel
fi
# Build protoc
# Build protoc and libprotobuf
./autogen.sh
./configure
CXXFLAGS="-fPIC -g -O2" ./configure
CXXFLAGS="-fPIC -g -O2" ./configure $configure_host_flag
make -j8
if [ "$PLAT" == "aarch64" ]
then
# we are crosscompiling for aarch64 while running on x64
# the simplest way for build_py command to be able to generate
# the protos is by running the protoc process under
# an emulator. That way we don't have to build a x64 version
# of protoc. The qemu-arm emulator is already included
# in the dockcross docker image.
# Running protoc under an emulator is fast as protoc doesn't
# really do much.
# create a simple shell wrapper that runs crosscompiled protoc under qemu
echo '#!/bin/bash' >protoc_qemu_wrapper.sh
echo 'exec qemu-aarch64 "../src/protoc" "$@"' >>protoc_qemu_wrapper.sh
chmod ugo+x protoc_qemu_wrapper.sh
# PROTOC variable is by build_py step that runs under ./python directory
export PROTOC=../protoc_qemu_wrapper.sh
fi
# Generate python dependencies.
pushd python
python setup.py build_py
@ -35,7 +58,20 @@ function bdist_wheel_cmd {
# Modify build version
pwd
ls
python setup.py bdist_wheel --cpp_implementation --compile_static_extension
if [ "$PLAT" == "aarch64" ]
then
# when crosscompiling for aarch64, --plat-name needs to be set explicitly
# to end up with correctly named wheel file
# the value should be manylinuxABC_ARCH and dockcross docker image
# conveniently provides the value in the AUDITWHEEL_PLAT env
local plat_name_flag="--plat-name=$AUDITWHEEL_PLAT"
# override the value of EXT_SUFFIX to make sure the crosscompiled .so files in the wheel have the correct filename suffix
export PROTOCOL_BUFFERS_OVERRIDE_EXT_SUFFIX="$(python -c 'import sysconfig; print(sysconfig.get_config_var("EXT_SUFFIX").replace("-x86_64-linux-gnu.so", "-aarch64-linux-gnu.so"))')"
fi
python setup.py bdist_wheel --cpp_implementation --compile_static_extension $plat_name_flag
cp dist/*.whl $abs_wheelhouse
}
@ -48,3 +84,12 @@ function run_tests {
python --version
python -c "from google.protobuf.pyext import _message;"
}
if [ "$PLAT" == "aarch64" ]
then
# when crosscompiling for aarch64, override the default multibuild's repair_wheelhouse logic
# since "auditwheel repair" doesn't work for crosscompiled wheels
function repair_wheelhouse {
echo "Skipping repair_wheelhouse since auditwheel requires build architecture to match wheel architecture."
}
fi

@ -20,7 +20,7 @@ the following files:
## Maven Location
The published protoc artifacts are available on Maven here:
http://central.maven.org/maven2/com/google/protobuf/protoc/
https://repo.maven.apache.org/maven2/com/google/protobuf/protoc/
## Versioning
The version of the ``protoc`` artifact must be the same as the version of the

@ -250,8 +250,9 @@ static PyObject* GetOrBuildOptions(const DescriptorClass *descriptor) {
message_type->full_name().c_str());
return NULL;
}
ScopedPyObjectPtr args(PyTuple_New(0));
ScopedPyObjectPtr value(
PyObject_Call(message_class->AsPyObject(), NULL, NULL));
PyObject_Call(message_class->AsPyObject(), args.get(), NULL));
Py_DECREF(message_class);
if (value == NULL) {
return NULL;

@ -178,7 +178,8 @@ static PyObject* New(PyTypeObject* type,
PyObject* args, PyObject* kwargs) {
static const char* kwlist[] = {"descriptor_db", 0};
PyObject* py_database = NULL;
if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|O", const_cast<char**>(kwlist), &py_database)) {
if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|O",
const_cast<char**>(kwlist), &py_database)) {
return NULL;
}
DescriptorDatabase* database = NULL;

@ -466,7 +466,8 @@ static PyObject* ScalarMapGet(PyObject* self, PyObject* args,
static const char* kwlist[] = {"key", "default", nullptr};
PyObject* key;
PyObject* default_value = NULL;
if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|O", const_cast<char**>(kwlist), &key,
if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|O",
const_cast<char**>(kwlist), &key,
&default_value)) {
return NULL;
}
@ -761,7 +762,8 @@ PyObject* MessageMapGet(PyObject* self, PyObject* args, PyObject* kwargs) {
static const char* kwlist[] = {"key", "default", nullptr};
PyObject* key;
PyObject* default_value = NULL;
if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|O", const_cast<char**>(kwlist), &key,
if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|O",
const_cast<char**>(kwlist), &key,
&default_value)) {
return NULL;
}

@ -197,15 +197,14 @@ static int AddDescriptors(PyObject* cls, const Descriptor* descriptor) {
}
static PyObject* New(PyTypeObject* type, PyObject* args, PyObject* kwargs) {
static const char *kwlist[] = {"name", "bases", "dict", 0};
static const char* kwlist[] = {"name", "bases", "dict", 0};
PyObject *bases, *dict;
const char* name;
// Check arguments: (name, bases, dict)
if (!PyArg_ParseTupleAndKeywords(args, kwargs, "sO!O!:type", const_cast<char**>(kwlist),
&name,
&PyTuple_Type, &bases,
&PyDict_Type, &dict)) {
if (!PyArg_ParseTupleAndKeywords(
args, kwargs, "sO!O!:type", const_cast<char**>(kwlist), &name,
&PyTuple_Type, &bases, &PyDict_Type, &dict)) {
return NULL;
}
@ -1680,10 +1679,10 @@ static PyObject* InternalSerializeToString(
CMessage* self, PyObject* args, PyObject* kwargs,
bool require_initialized) {
// Parse the "deterministic" kwarg; defaults to False.
static const char* kwlist[] = { "deterministic", 0 };
static const char* kwlist[] = {"deterministic", 0};
PyObject* deterministic_obj = Py_None;
if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|O", const_cast<char**>(kwlist),
&deterministic_obj)) {
if (!PyArg_ParseTupleAndKeywords(
args, kwargs, "|O", const_cast<char**>(kwlist), &deterministic_obj)) {
return NULL;
}
// Preemptively convert to a bool first, so we don't need to back out of

@ -79,7 +79,8 @@ PyMessageFactory* NewMessageFactory(PyTypeObject* type, PyDescriptorPool* pool)
PyObject* New(PyTypeObject* type, PyObject* args, PyObject* kwargs) {
static const char* kwlist[] = {"pool", 0};
PyObject* pool = NULL;
if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|O", const_cast<char**>(kwlist), &pool)) {
if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|O",
const_cast<char**>(kwlist), &pool)) {
return NULL;
}
ScopedPyObjectPtr owned_pool;

@ -18,6 +18,7 @@ from setuptools import setup, Extension, find_packages
from distutils.command.build_py import build_py as _build_py
from distutils.command.clean import clean as _clean
from distutils.command.build_ext import build_ext as _build_ext
from distutils.spawn import find_executable
# Find the Protocol Compiler.
@ -157,6 +158,22 @@ class build_py(_build_py):
if not any(fnmatch.fnmatchcase(fil, pat=pat) for pat in exclude)]
class build_ext(_build_ext):
def get_ext_filename(self, ext_name):
# since python3.5, python extensions' shared libraries use a suffix that corresponds to the value
# of sysconfig.get_config_var('EXT_SUFFIX') and contains info about the architecture the library targets.
# E.g. on x64 linux the suffix is ".cpython-XYZ-x86_64-linux-gnu.so"
# When crosscompiling python wheels, we need to be able to override this suffix
# so that the resulting file name matches the target architecture and we end up with a well-formed
# wheel.
filename = _build_ext.get_ext_filename(self, ext_name)
orig_ext_suffix = sysconfig.get_config_var("EXT_SUFFIX")
new_ext_suffix = os.getenv("PROTOCOL_BUFFERS_OVERRIDE_EXT_SUFFIX")
if new_ext_suffix and filename.endswith(orig_ext_suffix):
filename = filename[:-len(orig_ext_suffix)] + new_ext_suffix
return filename
class test_conformance(_build_py):
target = 'test_python'
def run(self):
@ -291,6 +308,7 @@ if __name__ == '__main__':
cmdclass={
'clean': clean,
'build_py': build_py,
'build_ext': build_ext,
'test_conformance': test_conformance,
},
install_requires=install_requires,

@ -290,7 +290,10 @@ class CommandLineInterface::ErrorPrinter
public DescriptorPool::ErrorCollector {
public:
ErrorPrinter(ErrorFormat format, DiskSourceTree* tree = NULL)
: format_(format), tree_(tree), found_errors_(false), found_warnings_(false) {}
: format_(format),
tree_(tree),
found_errors_(false),
found_warnings_(false) {}
~ErrorPrinter() {}
// implements MultiFileErrorCollector ------------------------------
@ -1639,8 +1642,7 @@ bool CommandLineInterface::ParseArgument(const char* arg, std::string* name,
*name == "--version" || *name == "--decode_raw" ||
*name == "--print_free_field_numbers" ||
*name == "--experimental_allow_proto3_optional" ||
*name == "--deterministic_output" ||
*name == "--fatal_warnings") {
*name == "--deterministic_output" || *name == "--fatal_warnings") {
// HACK: These are the only flags that don't take a value.
// They probably should not be hard-coded like this but for now it's
// not worth doing better.

@ -525,8 +525,7 @@ void CommandLineInterfaceTest::ExpectCapturedStdoutSubstringWithZeroReturnCode(
void CommandLineInterfaceTest::ExpectCapturedStderrSubstringWithZeroReturnCode(
const std::string& expected_substring) {
EXPECT_EQ(0, return_code_);
EXPECT_PRED_FORMAT2(testing::IsSubstring, expected_substring,
error_text_);
EXPECT_PRED_FORMAT2(testing::IsSubstring, expected_substring, error_text_);
}
void CommandLineInterfaceTest::ExpectFileContent(const std::string& filename,
@ -2333,20 +2332,18 @@ TEST_F(CommandLineInterfaceTest, Warnings) {
// Test --fatal_warnings.
CreateTempFile("foo.proto",
"syntax = \"proto2\";\n"
"import \"bar.proto\";\n");
CreateTempFile("bar.proto",
"syntax = \"proto2\";\n");
"syntax = \"proto2\";\n"
"import \"bar.proto\";\n");
CreateTempFile("bar.proto", "syntax = \"proto2\";\n");
Run("protocol_compiler --test_out=$tmpdir "
"--proto_path=$tmpdir foo.proto");
"--proto_path=$tmpdir foo.proto");
ExpectCapturedStderrSubstringWithZeroReturnCode(
"foo.proto:2:1: warning: Import bar.proto is unused.");
"foo.proto:2:1: warning: Import bar.proto is unused.");
Run("protocol_compiler --test_out=$tmpdir --fatal_warnings "
"--proto_path=$tmpdir foo.proto");
ExpectErrorSubstring(
"foo.proto:2:1: warning: Import bar.proto is unused.");
"--proto_path=$tmpdir foo.proto");
ExpectErrorSubstring("foo.proto:2:1: warning: Import bar.proto is unused.");
}
// -------------------------------------------------------------------

@ -37,11 +37,4 @@
#define GOOGLE_PROTOBUF_PORT_H__
#include <google/protobuf/stubs/port.h>
// Protobuf intends to move into the pb:: namespace.
namespace protobuf_future_namespace_placeholder {}
namespace pb = ::protobuf_future_namespace_placeholder;
#endif // GOOGLE_PROTOBUF_PORT_H__

@ -33,6 +33,7 @@
#include <iomanip>
#include <ostream> // NOLINT(readability/streams)
#include <sstream>
#include <string>
#include <google/protobuf/stubs/logging.h>
@ -40,11 +41,7 @@
namespace google {
namespace protobuf {
const uint128_pod kuint128max = {
static_cast<uint64>(PROTOBUF_LONGLONG(0xFFFFFFFFFFFFFFFF)),
static_cast<uint64>(PROTOBUF_LONGLONG(0xFFFFFFFFFFFFFFFF))
};
namespace int128_internal {
// Returns the 0-based position of the last set bit (i.e., most significant bit)
// in the given uint64. The argument may not be 0.
@ -188,6 +185,14 @@ std::ostream& operator<<(std::ostream& o, const uint128& b) {
return o << rep;
}
void VerifyValidShift(std::string op, int amount) {
// Shifting more than 127 is UB in Abseil, just crash for now to verify
// callers don't depend on it returning 0.
GOOGLE_CHECK_LT(amount, 128) << "Error executing operator " << op
<< ": shifts of more than 127 are undefined";
}
} // namespace int128_internal
} // namespace protobuf
} // namespace google

@ -33,38 +33,33 @@
#include <google/protobuf/stubs/common.h>
#include <iosfwd>
#include <limits>
#include <string>
#include <google/protobuf/port_def.inc>
namespace google {
namespace protobuf {
struct uint128_pod;
// TODO(xiaofeng): Define GOOGLE_PROTOBUF_HAS_CONSTEXPR when constexpr is
// available.
#ifdef GOOGLE_PROTOBUF_HAS_CONSTEXPR
# define UINT128_CONSTEXPR constexpr
#else
# define UINT128_CONSTEXPR
#endif
namespace int128_internal {
// An unsigned 128-bit integer type. Thread-compatible.
class PROTOBUF_EXPORT uint128 {
public:
UINT128_CONSTEXPR uint128(); // Sets to 0, but don't trust on this behavior.
UINT128_CONSTEXPR uint128(uint64 top, uint64 bottom);
uint128() = default;
private:
// Use `MakeUint128` instead.
constexpr uint128(uint64 top, uint64 bottom);
public:
#ifndef SWIG
UINT128_CONSTEXPR uint128(int bottom);
UINT128_CONSTEXPR uint128(uint32 bottom); // Top 96 bits = 0
constexpr uint128(int bottom);
constexpr uint128(uint32 bottom); // Top 96 bits = 0
#endif
UINT128_CONSTEXPR uint128(uint64 bottom); // hi_ = 0
UINT128_CONSTEXPR uint128(const uint128_pod &val);
constexpr uint128(uint64 bottom); // hi_ = 0
// Trivial copy constructor, assignment operator and destructor.
void Initialize(uint64 top, uint64 bottom);
// Arithmetic operators.
uint128& operator+=(const uint128& b);
uint128& operator-=(const uint128& b);
@ -82,8 +77,10 @@ class PROTOBUF_EXPORT uint128 {
uint128& operator++();
uint128& operator--();
friend uint64 Uint128Low64(const uint128& v);
friend uint64 Uint128High64(const uint128& v);
friend constexpr uint64 Uint128Low64(const uint128& v);
friend constexpr uint64 Uint128High64(const uint128& v);
friend constexpr uint128 MakeUint128(uint64_t high, uint64_t low);
// We add "std::" to avoid including all of port.h.
PROTOBUF_EXPORT friend std::ostream& operator<<(std::ostream& o,
@ -100,26 +97,12 @@ class PROTOBUF_EXPORT uint128 {
uint64 hi_;
// Not implemented, just declared for catching automatic type conversions.
uint128(uint8);
uint128(uint16);
uint128(float v);
uint128(double v);
};
// This is a POD form of uint128 which can be used for static variables which
// need to be operated on as uint128.
struct uint128_pod {
// Note: The ordering of fields is different than 'class uint128' but the
// same as its 2-arg constructor. This enables more obvious initialization
// of static instances, which is the primary reason for this struct in the
// first place. This does not seem to defeat any optimizations wrt
// operations involving this struct.
uint64 hi;
uint64 lo;
uint128(uint8) = delete;
uint128(uint16) = delete;
uint128(float v) = delete;
uint128(double v) = delete;
};
PROTOBUF_EXPORT extern const uint128_pod kuint128max;
// allow uint128 to be logged
PROTOBUF_EXPORT extern std::ostream& operator<<(std::ostream& o,
const uint128& b);
@ -127,8 +110,12 @@ PROTOBUF_EXPORT extern std::ostream& operator<<(std::ostream& o,
// Methods to access low and high pieces of 128-bit value.
// Defined externally from uint128 to facilitate conversion
// to native 128-bit types when compilers support them.
inline uint64 Uint128Low64(const uint128& v) { return v.lo_; }
inline uint64 Uint128High64(const uint128& v) { return v.hi_; }
inline constexpr uint64 Uint128Low64(const uint128& v) { return v.lo_; }
inline constexpr uint64 Uint128High64(const uint128& v) { return v.hi_; }
constexpr uint128 MakeUint128(uint64_t high, uint64_t low) {
return uint128(high, low);
}
// TODO: perhaps it would be nice to have int128, a signed 128-bit type?
@ -143,27 +130,17 @@ inline bool operator!=(const uint128& lhs, const uint128& rhs) {
return !(lhs == rhs);
}
inline UINT128_CONSTEXPR uint128::uint128() : lo_(0), hi_(0) {}
inline UINT128_CONSTEXPR uint128::uint128(uint64 top, uint64 bottom)
inline constexpr uint128::uint128(uint64 top, uint64 bottom)
: lo_(bottom), hi_(top) {}
inline UINT128_CONSTEXPR uint128::uint128(const uint128_pod& v)
: lo_(v.lo), hi_(v.hi) {}
inline UINT128_CONSTEXPR uint128::uint128(uint64 bottom)
inline constexpr uint128::uint128(uint64 bottom)
: lo_(bottom), hi_(0) {}
#ifndef SWIG
inline UINT128_CONSTEXPR uint128::uint128(uint32 bottom)
inline constexpr uint128::uint128(uint32 bottom)
: lo_(bottom), hi_(0) {}
inline UINT128_CONSTEXPR uint128::uint128(int bottom)
inline constexpr uint128::uint128(int bottom)
: lo_(bottom), hi_(static_cast<int64>((bottom < 0) ? -1 : 0)) {}
#endif
#undef UINT128_CONSTEXPR
inline void uint128::Initialize(uint64 top, uint64 bottom) {
hi_ = top;
lo_ = bottom;
}
// Comparison operators.
#define CMP128(op) \
@ -187,9 +164,9 @@ inline uint128 operator-(const uint128& val) {
const uint64 lo_flip = ~Uint128Low64(val);
const uint64 lo_add = lo_flip + 1;
if (lo_add < lo_flip) {
return uint128(hi_flip + 1, lo_add);
return MakeUint128(hi_flip + 1, lo_add);
}
return uint128(hi_flip, lo_add);
return MakeUint128(hi_flip, lo_add);
}
inline bool operator!(const uint128& val) {
@ -199,13 +176,13 @@ inline bool operator!(const uint128& val) {
// Logical operators.
inline uint128 operator~(const uint128& val) {
return uint128(~Uint128High64(val), ~Uint128Low64(val));
return MakeUint128(~Uint128High64(val), ~Uint128Low64(val));
}
#define LOGIC128(op) \
inline uint128 operator op(const uint128& lhs, const uint128& rhs) { \
return uint128(Uint128High64(lhs) op Uint128High64(rhs), \
Uint128Low64(lhs) op Uint128Low64(rhs)); \
return MakeUint128(Uint128High64(lhs) op Uint128High64(rhs), \
Uint128Low64(lhs) op Uint128Low64(rhs)); \
}
LOGIC128(|)
@ -229,7 +206,11 @@ LOGICASSIGN128(^=)
// Shift operators.
void VerifyValidShift(std::string op, int amount);
inline uint128 operator<<(const uint128& val, int amount) {
VerifyValidShift("<<", amount);
// uint64 shifts of >= 64 are undefined, so we will need some special-casing.
if (amount < 64) {
if (amount == 0) {
@ -238,15 +219,14 @@ inline uint128 operator<<(const uint128& val, int amount) {
uint64 new_hi = (Uint128High64(val) << amount) |
(Uint128Low64(val) >> (64 - amount));
uint64 new_lo = Uint128Low64(val) << amount;
return uint128(new_hi, new_lo);
} else if (amount < 128) {
return uint128(Uint128Low64(val) << (amount - 64), 0);
} else {
return uint128(0, 0);
return MakeUint128(new_hi, new_lo);
}
return MakeUint128(Uint128Low64(val) << (amount - 64), 0);
}
inline uint128 operator>>(const uint128& val, int amount) {
VerifyValidShift(">>", amount);
// uint64 shifts of >= 64 are undefined, so we will need some special-casing.
if (amount < 64) {
if (amount == 0) {
@ -255,12 +235,10 @@ inline uint128 operator>>(const uint128& val, int amount) {
uint64 new_hi = Uint128High64(val) >> amount;
uint64 new_lo = (Uint128Low64(val) >> amount) |
(Uint128High64(val) << (64 - amount));
return uint128(new_hi, new_lo);
} else if (amount < 128) {
return uint128(0, Uint128High64(val) >> (amount - 64));
} else {
return uint128(0, 0);
return MakeUint128(new_hi, new_lo);
}
return MakeUint128(0, Uint128High64(val) >> (amount - 64));
}
inline uint128& uint128::operator<<=(int amount) {
@ -379,6 +357,17 @@ inline uint128& uint128::operator--() {
return *this;
}
constexpr uint128 Uint128Max() {
return MakeUint128((std::numeric_limits<uint64>::max)(),
(std::numeric_limits<uint64>::max)());
}
} // namespace int128_internal
using google::protobuf::int128_internal::uint128;
using google::protobuf::int128_internal::Uint128Max;
using google::protobuf::int128_internal::MakeUint128;
} // namespace protobuf
} // namespace google

@ -33,6 +33,7 @@
#include <algorithm>
#include <sstream>
#include <utility>
#include <type_traits>
#include <google/protobuf/testing/googletest.h>
#include <gtest/gtest.h>
@ -44,16 +45,18 @@ namespace protobuf {
TEST(Int128, AllTests) {
uint128 zero(0);
EXPECT_EQ(zero, uint128());
uint128 one(1);
uint128 one_2arg(0, 1);
uint128 two(0, 2);
uint128 three(0, 3);
uint128 big(2000, 2);
uint128 big_minus_one(2000, 1);
uint128 bigger(2001, 1);
uint128 biggest(kuint128max);
uint128 high_low(1, 0);
uint128 low_high(0, kuint64max);
uint128 one_2arg = MakeUint128(0, 1);
uint128 two = MakeUint128(0, 2);
uint128 three = MakeUint128(0, 3);
uint128 big = MakeUint128(2000, 2);
uint128 big_minus_one = MakeUint128(2000, 1);
uint128 bigger = MakeUint128(2001, 1);
uint128 biggest(Uint128Max());
uint128 high_low = MakeUint128(1, 0);
uint128 low_high = MakeUint128(0, kuint64max);
EXPECT_LT(one, two);
EXPECT_GT(two, one);
EXPECT_LT(one, big);
@ -92,8 +95,6 @@ TEST(Int128, AllTests) {
EXPECT_EQ(big, (big >> 1) << 1);
EXPECT_EQ(one, (one << 80) >> 80);
EXPECT_EQ(zero, (one >> 80) << 80);
EXPECT_EQ(zero, big >> 128);
EXPECT_EQ(zero, big << 128);
// Shift assignments.
uint128 big_copy = big;
@ -117,9 +118,9 @@ TEST(Int128, AllTests) {
big_copy = big;
EXPECT_EQ(big >> 73, big_copy >>= 73);
big_copy = big;
EXPECT_EQ(big << 128, big_copy <<= 128);
EXPECT_EQ(big << 127, big_copy <<= 127);
big_copy = big;
EXPECT_EQ(big >> 128, big_copy >>= 128);
EXPECT_EQ(big >> 127, big_copy >>= 127);
EXPECT_EQ(Uint128High64(biggest), kuint64max);
EXPECT_EQ(Uint128Low64(biggest), kuint64max);
@ -170,92 +171,13 @@ TEST(Int128, AllTests) {
EXPECT_EQ(big, -(-big));
EXPECT_EQ(two, -((-one) - 1));
EXPECT_EQ(kuint128max, -one);
EXPECT_EQ(Uint128Max(), -one);
EXPECT_EQ(zero, -zero);
GOOGLE_LOG(INFO) << one;
GOOGLE_LOG(INFO) << big_minus_one;
}
TEST(Int128, PodTests) {
uint128_pod pod = { 12345, 67890 };
uint128 from_pod(pod);
EXPECT_EQ(12345, Uint128High64(from_pod));
EXPECT_EQ(67890, Uint128Low64(from_pod));
uint128 zero(0);
uint128_pod zero_pod = {0, 0};
uint128 one(1);
uint128_pod one_pod = {0, 1};
uint128 two(2);
uint128_pod two_pod = {0, 2};
uint128 three(3);
uint128_pod three_pod = {0, 3};
uint128 big(1, 0);
uint128_pod big_pod = {1, 0};
EXPECT_EQ(zero, zero_pod);
EXPECT_EQ(zero_pod, zero);
EXPECT_EQ(zero_pod, zero_pod);
EXPECT_EQ(one, one_pod);
EXPECT_EQ(one_pod, one);
EXPECT_EQ(one_pod, one_pod);
EXPECT_EQ(two, two_pod);
EXPECT_EQ(two_pod, two);
EXPECT_EQ(two_pod, two_pod);
EXPECT_NE(one, two_pod);
EXPECT_NE(one_pod, two);
EXPECT_NE(one_pod, two_pod);
EXPECT_LT(one, two_pod);
EXPECT_LT(one_pod, two);
EXPECT_LT(one_pod, two_pod);
EXPECT_LE(one, one_pod);
EXPECT_LE(one_pod, one);
EXPECT_LE(one_pod, one_pod);
EXPECT_LE(one, two_pod);
EXPECT_LE(one_pod, two);
EXPECT_LE(one_pod, two_pod);
EXPECT_GT(two, one_pod);
EXPECT_GT(two_pod, one);
EXPECT_GT(two_pod, one_pod);
EXPECT_GE(two, two_pod);
EXPECT_GE(two_pod, two);
EXPECT_GE(two_pod, two_pod);
EXPECT_GE(two, one_pod);
EXPECT_GE(two_pod, one);
EXPECT_GE(two_pod, one_pod);
EXPECT_EQ(three, one | two_pod);
EXPECT_EQ(three, one_pod | two);
EXPECT_EQ(three, one_pod | two_pod);
EXPECT_EQ(one, three & one_pod);
EXPECT_EQ(one, three_pod & one);
EXPECT_EQ(one, three_pod & one_pod);
EXPECT_EQ(two, three ^ one_pod);
EXPECT_EQ(two, three_pod ^ one);
EXPECT_EQ(two, three_pod ^ one_pod);
EXPECT_EQ(two, three & (~one));
EXPECT_EQ(three, ~~three);
EXPECT_EQ(two, two_pod << 0);
EXPECT_EQ(two, one_pod << 1);
EXPECT_EQ(big, one_pod << 64);
EXPECT_EQ(zero, one_pod << 128);
EXPECT_EQ(two, two_pod >> 0);
EXPECT_EQ(one, two_pod >> 1);
EXPECT_EQ(one, big_pod >> 64);
EXPECT_EQ(one, zero + one_pod);
EXPECT_EQ(one, zero_pod + one);
EXPECT_EQ(one, zero_pod + one_pod);
EXPECT_EQ(one, two - one_pod);
EXPECT_EQ(one, two_pod - one);
EXPECT_EQ(one, two_pod - one_pod);
}
TEST(Int128, OperatorAssignReturnRef) {
uint128 v(1);
(v += 4) -= 3;
@ -293,38 +215,38 @@ TEST(Int128, Multiply) {
}
// Verified with dc.
a = uint128(PROTOBUF_ULONGLONG(0xffffeeeeddddcccc),
PROTOBUF_ULONGLONG(0xbbbbaaaa99998888));
b = uint128(PROTOBUF_ULONGLONG(0x7777666655554444),
PROTOBUF_ULONGLONG(0x3333222211110000));
a = MakeUint128(PROTOBUF_ULONGLONG(0xffffeeeeddddcccc),
PROTOBUF_ULONGLONG(0xbbbbaaaa99998888));
b = MakeUint128(PROTOBUF_ULONGLONG(0x7777666655554444),
PROTOBUF_ULONGLONG(0x3333222211110000));
c = a * b;
EXPECT_EQ(uint128(PROTOBUF_ULONGLONG(0x530EDA741C71D4C3),
PROTOBUF_ULONGLONG(0xBF25975319080000)),
EXPECT_EQ(MakeUint128(PROTOBUF_ULONGLONG(0x530EDA741C71D4C3),
PROTOBUF_ULONGLONG(0xBF25975319080000)),
c);
EXPECT_EQ(0, c - b * a);
EXPECT_EQ(a * a - b * b, (a + b) * (a - b));
// Verified with dc.
a = uint128(PROTOBUF_ULONGLONG(0x0123456789abcdef),
PROTOBUF_ULONGLONG(0xfedcba9876543210));
b = uint128(PROTOBUF_ULONGLONG(0x02468ace13579bdf),
PROTOBUF_ULONGLONG(0xfdb97531eca86420));
a = MakeUint128(PROTOBUF_ULONGLONG(0x0123456789abcdef),
PROTOBUF_ULONGLONG(0xfedcba9876543210));
b = MakeUint128(PROTOBUF_ULONGLONG(0x02468ace13579bdf),
PROTOBUF_ULONGLONG(0xfdb97531eca86420));
c = a * b;
EXPECT_EQ(uint128(PROTOBUF_ULONGLONG(0x97a87f4f261ba3f2),
PROTOBUF_ULONGLONG(0x342d0bbf48948200)),
EXPECT_EQ(MakeUint128(PROTOBUF_ULONGLONG(0x97a87f4f261ba3f2),
PROTOBUF_ULONGLONG(0x342d0bbf48948200)),
c);
EXPECT_EQ(0, c - b * a);
EXPECT_EQ(a*a - b*b, (a+b) * (a-b));
}
TEST(Int128, AliasTests) {
uint128 x1(1, 2);
uint128 x2(2, 4);
uint128 x1 = MakeUint128(1, 2);
uint128 x2 = MakeUint128(2, 4);
x1 += x1;
EXPECT_EQ(x2, x1);
uint128 x3(1, static_cast<uint64>(1) << 63);
uint128 x4(3, 0);
uint128 x3 = MakeUint128(1, static_cast<uint64>(1) << 63);
uint128 x4 = MakeUint128(3, 0);
x3 += x3;
EXPECT_EQ(x4, x3);
}
@ -345,6 +267,12 @@ TEST(Int128, ModByZeroCheckFails) {
a = 123;
EXPECT_DEATH(a % b, "Division or mod by zero:");
}
TEST(Int128, ShiftGreater128) {
uint128 a;
EXPECT_DEATH(a << 128, "Left-shift greater or equal 128");
EXPECT_DEATH(a >> 128, "Right-shift greater or equal 128");
}
#endif // PROTOBUF_HAS_DEATH_TEST
TEST(Int128, DivideAndMod) {
@ -359,10 +287,10 @@ TEST(Int128, DivideAndMod) {
EXPECT_EQ(0, q);
EXPECT_EQ(0, r);
a = uint128(PROTOBUF_ULONGLONG(0x530eda741c71d4c3),
PROTOBUF_ULONGLONG(0xbf25975319080000));
q = uint128(PROTOBUF_ULONGLONG(0x4de2cab081),
PROTOBUF_ULONGLONG(0x14c34ab4676e4bab));
a = MakeUint128(PROTOBUF_ULONGLONG(0x530eda741c71d4c3),
PROTOBUF_ULONGLONG(0xbf25975319080000));
q = MakeUint128(PROTOBUF_ULONGLONG(0x4de2cab081),
PROTOBUF_ULONGLONG(0x14c34ab4676e4bab));
b = uint128(0x1110001);
r = uint128(0x3eb455);
ASSERT_EQ(a, q * b + r); // Sanity-check.
@ -400,8 +328,8 @@ TEST(Int128, DivideAndMod) {
// Try a large remainder.
b = a / 2 + 1;
uint128 expected_r(PROTOBUF_ULONGLONG(0x29876d3a0e38ea61),
PROTOBUF_ULONGLONG(0xdf92cba98c83ffff));
uint128 expected_r = MakeUint128(PROTOBUF_ULONGLONG(0x29876d3a0e38ea61),
PROTOBUF_ULONGLONG(0xdf92cba98c83ffff));
// Sanity checks.
ASSERT_EQ(a / 2 - 1, expected_r);
ASSERT_EQ(a, b + expected_r);
@ -421,8 +349,8 @@ static uint64 RandomUint64() {
TEST(Int128, DivideAndModRandomInputs) {
const int kNumIters = 1 << 18;
for (int i = 0; i < kNumIters; ++i) {
const uint128 a(RandomUint64(), RandomUint64());
const uint128 b(RandomUint64(), RandomUint64());
const uint128 a = MakeUint128(RandomUint64(), RandomUint64());
const uint128 b = MakeUint128(RandomUint64(), RandomUint64());
if (b == 0) {
continue; // Avoid a div-by-zero.
}
@ -432,24 +360,22 @@ TEST(Int128, DivideAndModRandomInputs) {
}
}
#ifdef GOOGLE_PROTOBUF_HAS_CONSTEXPR
TEST(Int128, ConstexprTest) {
constexpr uint128 zero;
constexpr uint128 one = 1;
constexpr uint128_pod pod = {2, 3};
constexpr uint128 from_pod = pod;
constexpr uint128 minus_two = -2;
EXPECT_EQ(one, uint128(1));
EXPECT_EQ(from_pod, uint128(2, 3));
EXPECT_EQ(minus_two, uint128(-1ULL, -2ULL));
EXPECT_EQ(minus_two, MakeUint128(-1ULL, -2ULL));
}
#if !defined(__GNUC__) || __GNUC__ > 4
// libstdc++ is missing the required type traits pre gcc-5.0.0
// https://gcc.gnu.org/onlinedocs/gcc-4.9.4/libstdc++/manual/manual/status.html#:~:text=20.9.4.3
TEST(Int128, Traits) {
EXPECT_TRUE(std::is_trivially_copy_constructible<uint128>::value);
EXPECT_TRUE(std::is_trivially_copy_assignable<uint128>::value);
EXPECT_TRUE(std::is_trivially_destructible<uint128>::value);
}
#endif // GOOGLE_PROTOBUF_HAS_CONSTEXPR
#endif // !defined(__GNUC__) || __GNUC__ > 4
TEST(Int128, OStream) {
struct {
@ -464,28 +390,28 @@ TEST(Int128, OStream) {
{uint128(0), std::ios::oct, 0, '_', "0"},
{uint128(0), std::ios::hex, 0, '_', "0"},
// crossover between lo_ and hi_
{uint128(0, -1), std::ios::dec, 0, '_', "18446744073709551615"},
{uint128(0, -1), std::ios::oct, 0, '_', "1777777777777777777777"},
{uint128(0, -1), std::ios::hex, 0, '_', "ffffffffffffffff"},
{uint128(1, 0), std::ios::dec, 0, '_', "18446744073709551616"},
{uint128(1, 0), std::ios::oct, 0, '_', "2000000000000000000000"},
{uint128(1, 0), std::ios::hex, 0, '_', "10000000000000000"},
{MakeUint128(0, -1), std::ios::dec, 0, '_', "18446744073709551615"},
{MakeUint128(0, -1), std::ios::oct, 0, '_', "1777777777777777777777"},
{MakeUint128(0, -1), std::ios::hex, 0, '_', "ffffffffffffffff"},
{MakeUint128(1, 0), std::ios::dec, 0, '_', "18446744073709551616"},
{MakeUint128(1, 0), std::ios::oct, 0, '_', "2000000000000000000000"},
{MakeUint128(1, 0), std::ios::hex, 0, '_', "10000000000000000"},
// just the top bit
{uint128(PROTOBUF_ULONGLONG(0x8000000000000000), 0), std::ios::dec, 0,
{MakeUint128(PROTOBUF_ULONGLONG(0x8000000000000000), 0), std::ios::dec, 0,
'_', "170141183460469231731687303715884105728"},
{uint128(PROTOBUF_ULONGLONG(0x8000000000000000), 0), std::ios::oct, 0,
{MakeUint128(PROTOBUF_ULONGLONG(0x8000000000000000), 0), std::ios::oct, 0,
'_', "2000000000000000000000000000000000000000000"},
{uint128(PROTOBUF_ULONGLONG(0x8000000000000000), 0), std::ios::hex, 0,
{MakeUint128(PROTOBUF_ULONGLONG(0x8000000000000000), 0), std::ios::hex, 0,
'_', "80000000000000000000000000000000"},
// maximum uint128 value
{uint128(-1, -1), std::ios::dec, 0, '_',
{MakeUint128(-1, -1), std::ios::dec, 0, '_',
"340282366920938463463374607431768211455"},
{uint128(-1, -1), std::ios::oct, 0, '_',
{MakeUint128(-1, -1), std::ios::oct, 0, '_',
"3777777777777777777777777777777777777777777"},
{uint128(-1, -1), std::ios::hex, 0, '_',
{MakeUint128(-1, -1), std::ios::hex, 0, '_',
"ffffffffffffffffffffffffffffffff"},
// uppercase
{uint128(-1, -1), std::ios::hex | std::ios::uppercase, 0, '_',
{MakeUint128(-1, -1), std::ios::hex | std::ios::uppercase, 0, '_',
"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"},
// showbase
{uint128(1), std::ios::dec | std::ios::showbase, 0, '_', "1"},

@ -31,6 +31,7 @@
#ifndef GOOGLE_PROTOBUF_STUBS_LOGGING_H_
#define GOOGLE_PROTOBUF_STUBS_LOGGING_H_
#include <google/protobuf/stubs/int128.h>
#include <google/protobuf/stubs/macros.h>
#include <google/protobuf/stubs/port.h>
#include <google/protobuf/stubs/status.h>
@ -65,7 +66,6 @@ enum LogLevel {
#endif
};
class uint128;
namespace internal {
class LogFinisher;

@ -85,8 +85,7 @@ inline std::string StatusCodeToString(StatusCode code) {
} // namespace
Status::Status() : error_code_(StatusCode::kOk) {
}
Status::Status() : error_code_(StatusCode::kOk) {}
Status::Status(StatusCode error_code, StringPiece error_message)
: error_code_(error_code) {
@ -117,15 +116,12 @@ std::string Status::ToString() const {
if (error_message_.empty()) {
return StatusCodeToString(error_code_);
} else {
return StatusCodeToString(error_code_) + ":" +
error_message_;
return StatusCodeToString(error_code_) + ":" + error_message_;
}
}
}
Status OkStatus() {
return Status();
}
Status OkStatus() { return Status(); }
std::ostream& operator<<(std::ostream& os, const Status& x) {
os << x.ToString();

@ -78,12 +78,8 @@ class PROTOBUF_EXPORT Status {
~Status() {}
// Accessor
bool ok() const {
return error_code_ == StatusCode::kOk;
}
StatusCode code() const {
return error_code_;
}
bool ok() const { return error_code_ == StatusCode::kOk; }
StatusCode code() const { return error_code_; }
StringPiece message() const {
return error_message_;
}
@ -173,7 +169,6 @@ using ::google::protobuf::util::status_internal::IsUnavailable;
using ::google::protobuf::util::status_internal::IsUnimplemented;
using ::google::protobuf::util::status_internal::IsUnknown;
using ::google::protobuf::util::status_internal::OkStatus;
using ::google::protobuf::util::status_internal::AbortedError;
using ::google::protobuf::util::status_internal::AlreadyExistsError;
using ::google::protobuf::util::status_internal::CancelledError;
@ -183,6 +178,7 @@ using ::google::protobuf::util::status_internal::FailedPreconditionError;
using ::google::protobuf::util::status_internal::InternalError;
using ::google::protobuf::util::status_internal::InvalidArgumentError;
using ::google::protobuf::util::status_internal::NotFoundError;
using ::google::protobuf::util::status_internal::OkStatus;
using ::google::protobuf::util::status_internal::OutOfRangeError;
using ::google::protobuf::util::status_internal::PermissionDeniedError;
using ::google::protobuf::util::status_internal::ResourceExhaustedError;

@ -247,9 +247,7 @@ TEST(Status, AssignEmpty) {
ASSERT_TRUE(a.ok());
}
TEST(Status, EqualsOK) {
ASSERT_EQ(util::OkStatus(), util::Status());
}
TEST(Status, EqualsOK) { ASSERT_EQ(util::OkStatus(), util::Status()); }
TEST(Status, EqualsSame) {
const util::Status a = util::CancelledError("message");

@ -174,10 +174,8 @@ struct StatusOrHelper::Specialize<T*> {
static inline bool IsValueNull(const T* t) { return t == nullptr; }
};
template<typename T>
inline StatusOr<T>::StatusOr()
: status_(util::UnknownError("")) {
}
template <typename T>
inline StatusOr<T>::StatusOr() : status_(util::UnknownError("")) {}
template<typename T>
inline StatusOr<T>::StatusOr(const Status& status) {

@ -110,7 +110,7 @@ TEST(StatusOr, TestCopyCtorStatusOKConverting) {
}
TEST(StatusOr, TestCopyCtorStatusNotOkConverting) {
StatusOr<int> original(util::CancelledError(""));
StatusOr<int> original(util::CancelledError(""));
StatusOr<double> copy(original);
EXPECT_EQ(original.status(), copy.status());
}
@ -141,7 +141,7 @@ TEST(StatusOr, TestAssignmentStatusOKConverting) {
}
TEST(StatusOr, TestAssignmentStatusNotOkConverting) {
StatusOr<int> source(util::CancelledError(""));
StatusOr<int> source(util::CancelledError(""));
StatusOr<double> target;
target = source;
EXPECT_EQ(source.status(), target.status());

@ -173,6 +173,10 @@ class PROTOBUF_EXPORT SimpleFieldComparator : public FieldComparator {
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 {
@ -239,10 +243,6 @@ class PROTOBUF_EXPORT SimpleFieldComparator : public FieldComparator {
template <typename T>
bool CompareDoubleOrFloat(const FieldDescriptor& field, T value_1, T value_2);
// Returns FieldComparator::SAME if boolean_result is true and
// FieldComparator::DIFFERENT otherwise.
ComparisonResult ResultFromBoolean(bool boolean_result) const;
FloatComparison float_comparison_;
// If true, floats and doubles that are both NaN are considered to be

@ -57,11 +57,10 @@ util::StatusOr<To> ValidateNumberConversion(To after, From before) {
MathUtil::Sign<From>(before) == MathUtil::Sign<To>(after)) {
return after;
} else {
return util::InvalidArgumentError(std::is_integral<From>::value
? ValueAsString(before)
: std::is_same<From, double>::value
? DoubleAsString(before)
: FloatAsString(before));
return util::InvalidArgumentError(
std::is_integral<From>::value ? ValueAsString(before)
: std::is_same<From, double>::value ? DoubleAsString(before)
: FloatAsString(before));
}
}
@ -260,7 +259,8 @@ util::StatusOr<std::string> DataPiece::ToBytes() const {
if (type_ == TYPE_STRING) {
std::string decoded;
if (!DecodeBase64(str_, &decoded)) {
return util::InvalidArgumentError(ValueAsStringOrDefault("Invalid data in input."));
return util::InvalidArgumentError(
ValueAsStringOrDefault("Invalid data in input."));
}
return decoded;
} else {
@ -358,7 +358,8 @@ util::StatusOr<To> DataPiece::StringToNumber(bool (*func)(StringPiece,
}
To result;
if (func(str_, &result)) return result;
return util::InvalidArgumentError(StrCat("\"", std::string(str_), "\""));
return util::InvalidArgumentError(
StrCat("\"", std::string(str_), "\""));
}
bool DataPiece::DecodeBase64(StringPiece src, std::string* dest) const {

@ -134,10 +134,9 @@ util::Status DecodeCompactFieldMaskPaths(StringPiece paths,
}
// Un-escaped '"' must be followed with a ']'.
if (i >= length - 1 || paths[i + 1] != ']') {
return util::InvalidArgumentError(
StrCat(
"Invalid FieldMask '", paths,
"'. Map keys should be represented as [\"some_key\"]."));
return util::InvalidArgumentError(StrCat(
"Invalid FieldMask '", paths,
"'. Map keys should be represented as [\"some_key\"]."));
}
// The end of the map key ("\"]") has been found.
in_map_key = false;
@ -146,10 +145,9 @@ util::Status DecodeCompactFieldMaskPaths(StringPiece paths,
// Checks whether the key ends at the end of a path segment.
if (i < length - 1 && paths[i + 1] != '.' && paths[i + 1] != ',' &&
paths[i + 1] != ')' && paths[i + 1] != '(') {
return util::InvalidArgumentError(
StrCat(
"Invalid FieldMask '", paths,
"'. Map keys should be at the end of a path segment."));
return util::InvalidArgumentError(StrCat(
"Invalid FieldMask '", paths,
"'. Map keys should be at the end of a path segment."));
}
is_escaping = false;
continue;
@ -158,10 +156,9 @@ util::Status DecodeCompactFieldMaskPaths(StringPiece paths,
// We are not in a map key, look for the start of one.
if (paths[i] == '[') {
if (i >= length - 1 || paths[i + 1] != '\"') {
return util::InvalidArgumentError(
StrCat(
"Invalid FieldMask '", paths,
"'. Map keys should be represented as [\"some_key\"]."));
return util::InvalidArgumentError(StrCat(
"Invalid FieldMask '", paths,
"'. Map keys should be represented as [\"some_key\"]."));
}
// "[\"" starts a map key.
in_map_key = true;

@ -302,7 +302,8 @@ util::Status JsonStreamParser::RunParser() {
break;
default:
result = util::InternalError(StrCat("Unknown parse type: ", type));
result =
util::InternalError(StrCat("Unknown parse type: ", type));
break;
}
if (!result.ok()) {
@ -872,8 +873,9 @@ util::Status JsonStreamParser::ReportFailure(StringPiece message,
StringPiece segment(begin, end - begin);
std::string location(p_start - begin, ' ');
location.push_back('^');
return util::InvalidArgumentError(
auto status = util::InvalidArgumentError(
StrCat(message, "\n", segment, "\n", location));
return status;
}
util::Status JsonStreamParser::ReportUnknown(StringPiece message,
@ -892,9 +894,8 @@ util::Status JsonStreamParser::ReportUnknown(StringPiece message,
util::Status JsonStreamParser::IncrementRecursionDepth(
StringPiece key) const {
if (++recursion_depth_ > max_recursion_depth_) {
return util::InvalidArgumentError(
StrCat("Message too deep. Max recursion depth reached for key '",
key, "'"));
return util::InvalidArgumentError(StrCat(
"Message too deep. Max recursion depth reached for key '", key, "'"));
}
return util::Status();
}

@ -317,8 +317,8 @@ util::Status ProtoStreamObjectSource::RenderTimestamp(
int64_t seconds = p.first;
int32_t nanos = p.second;
if (seconds > kTimestampMaxSeconds || seconds < kTimestampMinSeconds) {
return util::InternalError(
StrCat("Timestamp seconds exceeds limit for field: ", field_name));
return util::InternalError(StrCat(
"Timestamp seconds exceeds limit for field: ", field_name));
}
if (nanos < 0 || nanos >= kNanosPerSecond) {

@ -1025,9 +1025,8 @@ Status ProtoStreamObjectWriter::RenderTimestamp(ProtoStreamObjectWriter* ow,
if (data.type() == DataPiece::TYPE_NULL) return Status();
if (data.type() != DataPiece::TYPE_STRING) {
return util::InvalidArgumentError(
StrCat(
"Invalid data type for timestamp, value is ",
data.ValueAsStringOrDefault("")));
StrCat("Invalid data type for timestamp, value is ",
data.ValueAsStringOrDefault("")));
}
StringPiece value(data.str());
@ -1057,9 +1056,8 @@ Status ProtoStreamObjectWriter::RenderFieldMask(ProtoStreamObjectWriter* ow,
if (data.type() == DataPiece::TYPE_NULL) return Status();
if (data.type() != DataPiece::TYPE_STRING) {
return util::InvalidArgumentError(
StrCat(
"Invalid data type for field mask, value is ",
data.ValueAsStringOrDefault("")));
StrCat("Invalid data type for field mask, value is ",
data.ValueAsStringOrDefault("")));
}
// TODO(tsun): figure out how to do proto descriptor based snake case
@ -1074,9 +1072,8 @@ Status ProtoStreamObjectWriter::RenderDuration(ProtoStreamObjectWriter* ow,
if (data.type() == DataPiece::TYPE_NULL) return Status();
if (data.type() != DataPiece::TYPE_STRING) {
return util::InvalidArgumentError(
StrCat(
"Invalid data type for duration, value is ",
data.ValueAsStringOrDefault("")));
StrCat("Invalid data type for duration, value is ",
data.ValueAsStringOrDefault("")));
}
StringPiece value(data.str());

@ -154,9 +154,8 @@ class StatusErrorListener : public converter::ErrorListener {
void MissingField(const converter::LocationTrackerInterface& loc,
StringPiece missing_name) override {
status_ = util::InvalidArgumentError(
StrCat(
GetLocString(loc), ": missing field ", std::string(missing_name)));
status_ = util::InvalidArgumentError(StrCat(
GetLocString(loc), ": missing field ", std::string(missing_name)));
}
private:

@ -80,8 +80,8 @@ class DescriptorPoolTypeResolver : public TypeResolver {
const Descriptor* descriptor = pool_->FindMessageTypeByName(type_name);
if (descriptor == NULL) {
return util::NotFoundError(
"Invalid type URL, unknown type: " + type_name);
return util::NotFoundError("Invalid type URL, unknown type: " +
type_name);
}
ConvertDescriptor(descriptor, type);
return util::Status();
@ -97,8 +97,8 @@ class DescriptorPoolTypeResolver : public TypeResolver {
const EnumDescriptor* descriptor = pool_->FindEnumTypeByName(type_name);
if (descriptor == NULL) {
return util::InvalidArgumentError(
"Invalid type URL, unknown type: " + type_name);
return util::InvalidArgumentError("Invalid type URL, unknown type: " +
type_name);
}
ConvertEnumDescriptor(descriptor, enum_type);
return util::Status();

Loading…
Cancel
Save