Down-integrate from internal branch.
Change-Id: Ieb7a2c2fbf35bc2a8fa65b915a5ecb68c83863e4
This commit is contained in:
parent
d119a27549
commit
b0f661181d
68
appveyor.yml
68
appveyor.yml
@ -1,34 +1,34 @@
|
||||
# Only test one combination: "Visual Studio 12 + Win64 + Debug + DLL". We can
|
||||
# test more combinations but AppVeyor just takes too long to finish (each
|
||||
# combination takes ~15mins).
|
||||
platform:
|
||||
- Win64
|
||||
|
||||
configuration:
|
||||
- Debug
|
||||
|
||||
environment:
|
||||
matrix:
|
||||
- BUILD_DLL: ON
|
||||
|
||||
install:
|
||||
- ps: Start-FileDownload https://googlemock.googlecode.com/files/gmock-1.7.0.zip
|
||||
- 7z x gmock-1.7.0.zip
|
||||
- rename gmock-1.7.0 gmock
|
||||
|
||||
before_build:
|
||||
- if %platform%==Win32 set generator=Visual Studio 12
|
||||
- if %platform%==Win64 set generator=Visual Studio 12 Win64
|
||||
- if %platform%==Win32 set vcplatform=Win32
|
||||
- if %platform%==Win64 set vcplatform=x64
|
||||
|
||||
build_script:
|
||||
- mkdir build_msvc
|
||||
- cd build_msvc
|
||||
- cmake -G "%generator%" -DBUILD_SHARED_LIBS=%BUILD_DLL% ../cmake
|
||||
- msbuild protobuf.sln /p:Platform=%vcplatform% /logger:"C:\Program Files\AppVeyor\BuildAgent\Appveyor.MSBuildLogger.dll"
|
||||
- cd %configuration%
|
||||
- tests.exe
|
||||
|
||||
skip_commits:
|
||||
message: /.*\[skip appveyor\].*/
|
||||
# Only test one combination: "Visual Studio 12 + Win64 + Debug + DLL". We can
|
||||
# test more combinations but AppVeyor just takes too long to finish (each
|
||||
# combination takes ~15mins).
|
||||
platform:
|
||||
- Win64
|
||||
|
||||
configuration:
|
||||
- Debug
|
||||
|
||||
environment:
|
||||
matrix:
|
||||
- BUILD_DLL: ON
|
||||
|
||||
install:
|
||||
- ps: Start-FileDownload https://googlemock.googlecode.com/files/gmock-1.7.0.zip
|
||||
- 7z x gmock-1.7.0.zip
|
||||
- rename gmock-1.7.0 gmock
|
||||
|
||||
before_build:
|
||||
- if %platform%==Win32 set generator=Visual Studio 12
|
||||
- if %platform%==Win64 set generator=Visual Studio 12 Win64
|
||||
- if %platform%==Win32 set vcplatform=Win32
|
||||
- if %platform%==Win64 set vcplatform=x64
|
||||
|
||||
build_script:
|
||||
- mkdir build_msvc
|
||||
- cd build_msvc
|
||||
- cmake -G "%generator%" -DBUILD_SHARED_LIBS=%BUILD_DLL% ../cmake
|
||||
- msbuild protobuf.sln /p:Platform=%vcplatform% /logger:"C:\Program Files\AppVeyor\BuildAgent\Appveyor.MSBuildLogger.dll"
|
||||
- cd %configuration%
|
||||
- tests.exe
|
||||
|
||||
skip_commits:
|
||||
message: /.*\[skip appveyor\].*/
|
||||
|
@ -109,8 +109,10 @@ copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\timestamp.pb.h include
|
||||
copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\type.pb.h include\google\protobuf\type.pb.h
|
||||
copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\unknown_field_set.h include\google\protobuf\unknown_field_set.h
|
||||
copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\util\field_comparator.h include\google\protobuf\util\field_comparator.h
|
||||
copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\util\field_mask_util.h include\google\protobuf\util\field_mask_util.h
|
||||
copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\util\json_util.h include\google\protobuf\util\json_util.h
|
||||
copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\util\message_differencer.h include\google\protobuf\util\message_differencer.h
|
||||
copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\util\time_util.h include\google\protobuf\util\time_util.h
|
||||
copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\util\type_resolver.h include\google\protobuf\util\type_resolver.h
|
||||
copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\util\type_resolver_util.h include\google\protobuf\util\type_resolver_util.h
|
||||
copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\wire_format.h include\google\protobuf\wire_format.h
|
||||
|
@ -12,6 +12,7 @@ set(libprotobuf_lite_files
|
||||
${protobuf_source_dir}/src/google/protobuf/stubs/atomicops_internals_x86_msvc.cc
|
||||
${protobuf_source_dir}/src/google/protobuf/stubs/bytestream.cc
|
||||
${protobuf_source_dir}/src/google/protobuf/stubs/common.cc
|
||||
${protobuf_source_dir}/src/google/protobuf/stubs/int128.cc
|
||||
${protobuf_source_dir}/src/google/protobuf/stubs/once.cc
|
||||
${protobuf_source_dir}/src/google/protobuf/stubs/status.cc
|
||||
${protobuf_source_dir}/src/google/protobuf/stubs/statusor.cc
|
||||
|
@ -32,6 +32,7 @@ set(libprotobuf_files
|
||||
${protobuf_source_dir}/src/google/protobuf/type.pb.cc
|
||||
${protobuf_source_dir}/src/google/protobuf/unknown_field_set.cc
|
||||
${protobuf_source_dir}/src/google/protobuf/util/field_comparator.cc
|
||||
${protobuf_source_dir}/src/google/protobuf/util/field_mask_util.cc
|
||||
${protobuf_source_dir}/src/google/protobuf/util/internal/datapiece.cc
|
||||
${protobuf_source_dir}/src/google/protobuf/util/internal/default_value_objectwriter.cc
|
||||
${protobuf_source_dir}/src/google/protobuf/util/internal/error_listener.cc
|
||||
@ -47,6 +48,7 @@ set(libprotobuf_files
|
||||
${protobuf_source_dir}/src/google/protobuf/util/internal/utility.cc
|
||||
${protobuf_source_dir}/src/google/protobuf/util/json_util.cc
|
||||
${protobuf_source_dir}/src/google/protobuf/util/message_differencer.cc
|
||||
${protobuf_source_dir}/src/google/protobuf/util/time_util.cc
|
||||
${protobuf_source_dir}/src/google/protobuf/util/type_resolver_util.cc
|
||||
${protobuf_source_dir}/src/google/protobuf/wire_format.cc
|
||||
${protobuf_source_dir}/src/google/protobuf/wrappers.pb.cc
|
||||
|
@ -34,6 +34,7 @@ set(libprotoc_files
|
||||
${protobuf_source_dir}/src/google/protobuf/compiler/java/java_enum.cc
|
||||
${protobuf_source_dir}/src/google/protobuf/compiler/java/java_enum_field.cc
|
||||
${protobuf_source_dir}/src/google/protobuf/compiler/java/java_enum_field_lite.cc
|
||||
${protobuf_source_dir}/src/google/protobuf/compiler/java/java_enum_lite.cc
|
||||
${protobuf_source_dir}/src/google/protobuf/compiler/java/java_extension.cc
|
||||
${protobuf_source_dir}/src/google/protobuf/compiler/java/java_field.cc
|
||||
${protobuf_source_dir}/src/google/protobuf/compiler/java/java_file.cc
|
||||
|
@ -21,6 +21,7 @@ set(lite_test_protos
|
||||
google/protobuf/unittest_import_lite.proto
|
||||
google/protobuf/unittest_import_public_lite.proto
|
||||
google/protobuf/unittest_lite.proto
|
||||
google/protobuf/unittest_no_arena_lite.proto
|
||||
)
|
||||
|
||||
set(tests_protos
|
||||
@ -40,6 +41,7 @@ set(tests_protos
|
||||
google/protobuf/unittest_import_public.proto
|
||||
google/protobuf/unittest_lite_imports_nonlite.proto
|
||||
google/protobuf/unittest_mset.proto
|
||||
google/protobuf/unittest_mset_wire_format.proto
|
||||
google/protobuf/unittest_no_arena.proto
|
||||
google/protobuf/unittest_no_arena_import.proto
|
||||
google/protobuf/unittest_no_field_presence.proto
|
||||
@ -55,6 +57,7 @@ set(tests_protos
|
||||
google/protobuf/util/internal/testdata/default_value_test.proto
|
||||
google/protobuf/util/internal/testdata/field_mask.proto
|
||||
google/protobuf/util/internal/testdata/maps.proto
|
||||
google/protobuf/util/internal/testdata/oneofs.proto
|
||||
google/protobuf/util/internal/testdata/struct.proto
|
||||
google/protobuf/util/internal/testdata/timestamp_duration.proto
|
||||
google/protobuf/util/json_format_proto3.proto
|
||||
@ -134,6 +137,7 @@ set(tests_files
|
||||
${protobuf_source_dir}/src/google/protobuf/repeated_field_unittest.cc
|
||||
${protobuf_source_dir}/src/google/protobuf/stubs/bytestream_unittest.cc
|
||||
${protobuf_source_dir}/src/google/protobuf/stubs/common_unittest.cc
|
||||
${protobuf_source_dir}/src/google/protobuf/stubs/int128_unittest.cc
|
||||
${protobuf_source_dir}/src/google/protobuf/stubs/once_unittest.cc
|
||||
${protobuf_source_dir}/src/google/protobuf/stubs/status_test.cc
|
||||
${protobuf_source_dir}/src/google/protobuf/stubs/statusor_test.cc
|
||||
@ -147,6 +151,7 @@ set(tests_files
|
||||
${protobuf_source_dir}/src/google/protobuf/text_format_unittest.cc
|
||||
${protobuf_source_dir}/src/google/protobuf/unknown_field_set_unittest.cc
|
||||
${protobuf_source_dir}/src/google/protobuf/util/field_comparator_test.cc
|
||||
${protobuf_source_dir}/src/google/protobuf/util/field_mask_util_test.cc
|
||||
${protobuf_source_dir}/src/google/protobuf/util/internal/default_value_objectwriter_test.cc
|
||||
${protobuf_source_dir}/src/google/protobuf/util/internal/json_objectwriter_test.cc
|
||||
${protobuf_source_dir}/src/google/protobuf/util/internal/json_stream_parser_test.cc
|
||||
@ -154,6 +159,7 @@ set(tests_files
|
||||
${protobuf_source_dir}/src/google/protobuf/util/internal/protostream_objectwriter_test.cc
|
||||
${protobuf_source_dir}/src/google/protobuf/util/internal/type_info_test_helper.cc
|
||||
${protobuf_source_dir}/src/google/protobuf/util/json_util_test.cc
|
||||
${protobuf_source_dir}/src/google/protobuf/util/time_util_test.cc
|
||||
${protobuf_source_dir}/src/google/protobuf/util/type_resolver_util_test.cc
|
||||
${protobuf_source_dir}/src/google/protobuf/well_known_types_unittest.cc
|
||||
${protobuf_source_dir}/src/google/protobuf/wire_format_unittest.cc
|
||||
|
@ -114,6 +114,7 @@
|
||||
<arg value="../src/google/protobuf/unittest_import.proto" />
|
||||
<arg value="../src/google/protobuf/unittest_import_public.proto" />
|
||||
<arg value="../src/google/protobuf/unittest_mset.proto" />
|
||||
<arg value="../src/google/protobuf/unittest_mset_wire_format.proto" />
|
||||
<arg value="src/test/java/com/google/protobuf/lazy_fields_lite.proto" />
|
||||
<arg value="src/test/java/com/google/protobuf/lite_equals_and_hash.proto" />
|
||||
<arg
|
||||
|
66
python/google/protobuf/internal/message_set_extensions.proto
Normal file
66
python/google/protobuf/internal/message_set_extensions.proto
Normal file
@ -0,0 +1,66 @@
|
||||
// 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.
|
||||
|
||||
// This file contains messages that extend MessageSet.
|
||||
|
||||
syntax = "proto2";
|
||||
package google.protobuf.internal;
|
||||
|
||||
|
||||
// A message with message_set_wire_format.
|
||||
message TestMessageSet {
|
||||
option message_set_wire_format = true;
|
||||
extensions 4 to max;
|
||||
}
|
||||
|
||||
message TestMessageSetExtension1 {
|
||||
extend TestMessageSet {
|
||||
optional TestMessageSetExtension1 message_set_extension = 98418603;
|
||||
}
|
||||
optional int32 i = 15;
|
||||
}
|
||||
|
||||
message TestMessageSetExtension2 {
|
||||
extend TestMessageSet {
|
||||
optional TestMessageSetExtension2 message_set_extension = 98418634;
|
||||
}
|
||||
optional string str = 25;
|
||||
}
|
||||
|
||||
// This message was used to generate
|
||||
// //net/proto2/python/internal/testdata/message_set_message, but is commented
|
||||
// out since it must not actually exist in code, to simulate an "unknown"
|
||||
// extension.
|
||||
// message TestMessageSetUnknownExtension {
|
||||
// extend TestMessageSet {
|
||||
// optional TestMessageSetUnknownExtension message_set_extension = 56141421;
|
||||
// }
|
||||
// optional int64 a = 1;
|
||||
// }
|
@ -91,11 +91,15 @@ def generate_proto(source, require = True):
|
||||
|
||||
def GenerateUnittestProtos():
|
||||
generate_proto("../src/google/protobuf/map_unittest.proto", False)
|
||||
generate_proto("../src/google/protobuf/unittest_arena.proto", False)
|
||||
generate_proto("../src/google/protobuf/unittest_no_arena.proto", False)
|
||||
generate_proto("../src/google/protobuf/unittest_no_arena_import.proto", False)
|
||||
generate_proto("../src/google/protobuf/unittest.proto", False)
|
||||
generate_proto("../src/google/protobuf/unittest_custom_options.proto", False)
|
||||
generate_proto("../src/google/protobuf/unittest_import.proto", False)
|
||||
generate_proto("../src/google/protobuf/unittest_import_public.proto", False)
|
||||
generate_proto("../src/google/protobuf/unittest_mset.proto", False)
|
||||
generate_proto("../src/google/protobuf/unittest_mset_wire_format.proto", False)
|
||||
generate_proto("../src/google/protobuf/unittest_no_generic_services.proto", False)
|
||||
generate_proto("../src/google/protobuf/unittest_proto3_arena.proto", False)
|
||||
generate_proto("google/protobuf/internal/descriptor_pool_test1.proto", False)
|
||||
@ -105,9 +109,11 @@ def GenerateUnittestProtos():
|
||||
generate_proto("google/protobuf/internal/import_test_package/inner.proto", False)
|
||||
generate_proto("google/protobuf/internal/import_test_package/outer.proto", False)
|
||||
generate_proto("google/protobuf/internal/missing_enum_values.proto", False)
|
||||
generate_proto("google/protobuf/internal/message_set_extensions.proto", False)
|
||||
generate_proto("google/protobuf/internal/more_extensions.proto", False)
|
||||
generate_proto("google/protobuf/internal/more_extensions_dynamic.proto", False)
|
||||
generate_proto("google/protobuf/internal/more_messages.proto", False)
|
||||
generate_proto("google/protobuf/internal/packed_field_test.proto", False)
|
||||
generate_proto("google/protobuf/internal/test_bad_identifiers.proto", False)
|
||||
generate_proto("google/protobuf/pyext/python.proto", False)
|
||||
|
||||
|
@ -157,9 +157,11 @@ nobase_include_HEADERS = \
|
||||
google/protobuf/compiler/ruby/ruby_generator.h \
|
||||
google/protobuf/compiler/csharp/csharp_generator.h \
|
||||
google/protobuf/util/type_resolver.h \
|
||||
google/protobuf/util/type_resolver_util.h \
|
||||
google/protobuf/util/json_util.h \
|
||||
google/protobuf/util/field_comparator.h \
|
||||
google/protobuf/util/field_mask_util.h \
|
||||
google/protobuf/util/json_util.h \
|
||||
google/protobuf/util/time_util.h \
|
||||
google/protobuf/util/type_resolver_util.h \
|
||||
google/protobuf/util/message_differencer.h
|
||||
|
||||
lib_LTLIBRARIES = libprotobuf-lite.la libprotobuf.la libprotoc.la
|
||||
@ -173,6 +175,8 @@ libprotobuf_lite_la_SOURCES = \
|
||||
google/protobuf/stubs/bytestream.h \
|
||||
google/protobuf/stubs/common.cc \
|
||||
google/protobuf/stubs/hash.h \
|
||||
google/protobuf/stubs/int128.cc \
|
||||
google/protobuf/stubs/int128.h \
|
||||
google/protobuf/stubs/map_util.h \
|
||||
google/protobuf/stubs/mathutil.h \
|
||||
google/protobuf/stubs/once.cc \
|
||||
@ -208,8 +212,8 @@ libprotobuf_la_SOURCES = \
|
||||
$(libprotobuf_lite_la_SOURCES) \
|
||||
google/protobuf/any.pb.cc \
|
||||
google/protobuf/api.pb.cc \
|
||||
google/protobuf/stubs/mathlimits.h \
|
||||
google/protobuf/stubs/mathlimits.cc \
|
||||
google/protobuf/stubs/mathlimits.h \
|
||||
google/protobuf/any.cc \
|
||||
google/protobuf/descriptor.cc \
|
||||
google/protobuf/descriptor_database.cc \
|
||||
@ -244,6 +248,7 @@ libprotobuf_la_SOURCES = \
|
||||
google/protobuf/compiler/importer.cc \
|
||||
google/protobuf/compiler/parser.cc \
|
||||
google/protobuf/util/field_comparator.cc \
|
||||
google/protobuf/util/field_mask_util.cc \
|
||||
google/protobuf/util/internal/constants.h \
|
||||
google/protobuf/util/internal/datapiece.cc \
|
||||
google/protobuf/util/internal/datapiece.h \
|
||||
@ -280,8 +285,10 @@ libprotobuf_la_SOURCES = \
|
||||
google/protobuf/util/internal/utility.cc \
|
||||
google/protobuf/util/internal/utility.h \
|
||||
google/protobuf/util/json_util.cc \
|
||||
google/protobuf/util/type_resolver_util.cc \
|
||||
google/protobuf/util/message_differencer.cc
|
||||
google/protobuf/util/message_differencer.cc \
|
||||
google/protobuf/util/time_util.cc \
|
||||
google/protobuf/util/type_resolver_util.cc
|
||||
|
||||
nodist_libprotobuf_la_SOURCES = $(nodist_libprotobuf_lite_la_SOURCES)
|
||||
|
||||
libprotoc_la_LIBADD = $(PTHREAD_LIBS) libprotobuf.la
|
||||
@ -324,11 +331,13 @@ libprotoc_la_SOURCES = \
|
||||
google/protobuf/compiler/java/java_context.cc \
|
||||
google/protobuf/compiler/java/java_context.h \
|
||||
google/protobuf/compiler/java/java_enum.cc \
|
||||
google/protobuf/compiler/java/java_enum_lite.cc \
|
||||
google/protobuf/compiler/java/java_enum_field.cc \
|
||||
google/protobuf/compiler/java/java_enum_field.h \
|
||||
google/protobuf/compiler/java/java_enum_field_lite.cc \
|
||||
google/protobuf/compiler/java/java_enum_field_lite.h \
|
||||
google/protobuf/compiler/java/java_enum.h \
|
||||
google/protobuf/compiler/java/java_enum_lite.h \
|
||||
google/protobuf/compiler/java/java_extension.cc \
|
||||
google/protobuf/compiler/java/java_extension.h \
|
||||
google/protobuf/compiler/java/java_field.cc \
|
||||
@ -479,6 +488,8 @@ protoc_inputs = \
|
||||
google/protobuf/unittest_lite_imports_nonlite.proto \
|
||||
google/protobuf/unittest_lite.proto \
|
||||
google/protobuf/unittest_mset.proto \
|
||||
google/protobuf/unittest_mset_wire_format.proto \
|
||||
google/protobuf/unittest_no_arena_lite.proto \
|
||||
google/protobuf/unittest_no_arena_import.proto \
|
||||
google/protobuf/unittest_no_arena.proto \
|
||||
google/protobuf/unittest_no_field_presence.proto \
|
||||
@ -495,6 +506,7 @@ protoc_inputs = \
|
||||
google/protobuf/util/internal/testdata/default_value_test.proto \
|
||||
google/protobuf/util/internal/testdata/field_mask.proto \
|
||||
google/protobuf/util/internal/testdata/maps.proto \
|
||||
google/protobuf/util/internal/testdata/oneofs.proto \
|
||||
google/protobuf/util/internal/testdata/struct.proto \
|
||||
google/protobuf/util/internal/testdata/timestamp_duration.proto \
|
||||
google/protobuf/util/json_format_proto3.proto \
|
||||
@ -529,6 +541,8 @@ protoc_lite_outputs = \
|
||||
google/protobuf/map_lite_unittest.pb.h \
|
||||
google/protobuf/unittest_lite.pb.cc \
|
||||
google/protobuf/unittest_lite.pb.h \
|
||||
google/protobuf/unittest_no_arena_lite.pb.cc \
|
||||
google/protobuf/unittest_no_arena_lite.pb.h \
|
||||
google/protobuf/unittest_import_lite.pb.cc \
|
||||
google/protobuf/unittest_import_lite.pb.h \
|
||||
google/protobuf/unittest_import_public_lite.pb.cc \
|
||||
@ -566,6 +580,8 @@ protoc_outputs = \
|
||||
google/protobuf/unittest_lite_imports_nonlite.pb.h \
|
||||
google/protobuf/unittest_mset.pb.cc \
|
||||
google/protobuf/unittest_mset.pb.h \
|
||||
google/protobuf/unittest_mset_wire_format.pb.cc \
|
||||
google/protobuf/unittest_mset_wire_format.pb.h \
|
||||
google/protobuf/unittest_no_arena_import.pb.cc \
|
||||
google/protobuf/unittest_no_arena_import.pb.h \
|
||||
google/protobuf/unittest_no_arena.pb.cc \
|
||||
@ -598,6 +614,8 @@ protoc_outputs = \
|
||||
google/protobuf/util/internal/testdata/field_mask.pb.h \
|
||||
google/protobuf/util/internal/testdata/maps.pb.cc \
|
||||
google/protobuf/util/internal/testdata/maps.pb.h \
|
||||
google/protobuf/util/internal/testdata/oneofs.pb.cc \
|
||||
google/protobuf/util/internal/testdata/oneofs.pb.h \
|
||||
google/protobuf/util/internal/testdata/struct.pb.cc \
|
||||
google/protobuf/util/internal/testdata/struct.pb.h \
|
||||
google/protobuf/util/internal/testdata/timestamp_duration.pb.cc \
|
||||
@ -654,6 +672,7 @@ protobuf_test_CXXFLAGS = $(NO_OPT_CXXFLAGS)
|
||||
protobuf_test_SOURCES = \
|
||||
google/protobuf/stubs/bytestream_unittest.cc \
|
||||
google/protobuf/stubs/common_unittest.cc \
|
||||
google/protobuf/stubs/int128_unittest.cc \
|
||||
google/protobuf/stubs/once_unittest.cc \
|
||||
google/protobuf/stubs/statusor_test.cc \
|
||||
google/protobuf/stubs/status_test.cc \
|
||||
@ -706,6 +725,7 @@ protobuf_test_SOURCES = \
|
||||
google/protobuf/compiler/ruby/ruby_generator_unittest.cc \
|
||||
google/protobuf/compiler/csharp/csharp_generator_unittest.cc \
|
||||
google/protobuf/util/field_comparator_test.cc \
|
||||
google/protobuf/util/field_mask_util_test.cc \
|
||||
google/protobuf/util/internal/default_value_objectwriter_test.cc \
|
||||
google/protobuf/util/internal/json_objectwriter_test.cc \
|
||||
google/protobuf/util/internal/json_stream_parser_test.cc \
|
||||
@ -713,6 +733,7 @@ protobuf_test_SOURCES = \
|
||||
google/protobuf/util/internal/protostream_objectwriter_test.cc \
|
||||
google/protobuf/util/internal/type_info_test_helper.cc \
|
||||
google/protobuf/util/json_util_test.cc \
|
||||
google/protobuf/util/time_util_test.cc \
|
||||
google/protobuf/util/type_resolver_util_test.cc \
|
||||
$(COMMON_TEST_SOURCES)
|
||||
|
||||
|
@ -42,10 +42,8 @@ option objc_class_prefix = "GPB";
|
||||
// `Any` contains an arbitrary serialized message along with a URL
|
||||
// that describes the type of the serialized message.
|
||||
//
|
||||
// The proto runtimes and/or compiler will eventually
|
||||
// provide utilities to pack/unpack Any values (projected Q1/15).
|
||||
//
|
||||
// # JSON
|
||||
// JSON
|
||||
// ====
|
||||
// The JSON representation of an `Any` value uses the regular
|
||||
// representation of the deserialized, embedded message, with an
|
||||
// additional field `@type` which contains the type URL. Example:
|
||||
@ -93,10 +91,6 @@ message Any {
|
||||
// Schemas other than `http`, `https` (or the empty schema) might be
|
||||
// used with implementation specific semantics.
|
||||
//
|
||||
// Types originating from the `google.*` package
|
||||
// namespace should use `type.googleapis.com/full.type.name` (without
|
||||
// schema and path). A type service will eventually become available which
|
||||
// serves those URLs (projected Q2/15).
|
||||
string type_url = 1;
|
||||
|
||||
// Must be valid serialized data of the above specified type.
|
||||
|
@ -27,6 +27,9 @@ const ::google::protobuf::internal::GeneratedMessageReflection*
|
||||
const ::google::protobuf::Descriptor* Method_descriptor_ = NULL;
|
||||
const ::google::protobuf::internal::GeneratedMessageReflection*
|
||||
Method_reflection_ = NULL;
|
||||
const ::google::protobuf::Descriptor* Mixin_descriptor_ = NULL;
|
||||
const ::google::protobuf::internal::GeneratedMessageReflection*
|
||||
Mixin_reflection_ = NULL;
|
||||
|
||||
} // namespace
|
||||
|
||||
@ -38,12 +41,14 @@ void protobuf_AssignDesc_google_2fprotobuf_2fapi_2eproto() {
|
||||
"google/protobuf/api.proto");
|
||||
GOOGLE_CHECK(file != NULL);
|
||||
Api_descriptor_ = file->message_type(0);
|
||||
static const int Api_offsets_[5] = {
|
||||
static const int Api_offsets_[7] = {
|
||||
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Api, name_),
|
||||
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Api, methods_),
|
||||
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Api, options_),
|
||||
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Api, version_),
|
||||
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Api, source_context_),
|
||||
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Api, mixins_),
|
||||
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Api, syntax_),
|
||||
};
|
||||
Api_reflection_ =
|
||||
::google::protobuf::internal::GeneratedMessageReflection::NewGeneratedMessageReflection(
|
||||
@ -57,13 +62,14 @@ void protobuf_AssignDesc_google_2fprotobuf_2fapi_2eproto() {
|
||||
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Api, _internal_metadata_),
|
||||
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Api, _is_default_instance_));
|
||||
Method_descriptor_ = file->message_type(1);
|
||||
static const int Method_offsets_[6] = {
|
||||
static const int Method_offsets_[7] = {
|
||||
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Method, name_),
|
||||
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Method, request_type_url_),
|
||||
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Method, request_streaming_),
|
||||
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Method, response_type_url_),
|
||||
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Method, response_streaming_),
|
||||
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Method, options_),
|
||||
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Method, syntax_),
|
||||
};
|
||||
Method_reflection_ =
|
||||
::google::protobuf::internal::GeneratedMessageReflection::NewGeneratedMessageReflection(
|
||||
@ -76,6 +82,22 @@ void protobuf_AssignDesc_google_2fprotobuf_2fapi_2eproto() {
|
||||
sizeof(Method),
|
||||
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Method, _internal_metadata_),
|
||||
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Method, _is_default_instance_));
|
||||
Mixin_descriptor_ = file->message_type(2);
|
||||
static const int Mixin_offsets_[2] = {
|
||||
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Mixin, name_),
|
||||
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Mixin, root_),
|
||||
};
|
||||
Mixin_reflection_ =
|
||||
::google::protobuf::internal::GeneratedMessageReflection::NewGeneratedMessageReflection(
|
||||
Mixin_descriptor_,
|
||||
Mixin::default_instance_,
|
||||
Mixin_offsets_,
|
||||
-1,
|
||||
-1,
|
||||
-1,
|
||||
sizeof(Mixin),
|
||||
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Mixin, _internal_metadata_),
|
||||
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Mixin, _is_default_instance_));
|
||||
}
|
||||
|
||||
namespace {
|
||||
@ -92,6 +114,8 @@ void protobuf_RegisterTypes(const ::std::string&) {
|
||||
Api_descriptor_, &Api::default_instance());
|
||||
::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(
|
||||
Method_descriptor_, &Method::default_instance());
|
||||
::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(
|
||||
Mixin_descriptor_, &Mixin::default_instance());
|
||||
}
|
||||
|
||||
} // namespace
|
||||
@ -101,6 +125,8 @@ void protobuf_ShutdownFile_google_2fprotobuf_2fapi_2eproto() {
|
||||
delete Api_reflection_;
|
||||
delete Method::default_instance_;
|
||||
delete Method_reflection_;
|
||||
delete Mixin::default_instance_;
|
||||
delete Mixin_reflection_;
|
||||
}
|
||||
|
||||
void protobuf_AddDesc_google_2fprotobuf_2fapi_2eproto() {
|
||||
@ -114,23 +140,29 @@ void protobuf_AddDesc_google_2fprotobuf_2fapi_2eproto() {
|
||||
::google::protobuf::DescriptorPool::InternalAddGeneratedFile(
|
||||
"\n\031google/protobuf/api.proto\022\017google.prot"
|
||||
"obuf\032$google/protobuf/source_context.pro"
|
||||
"to\032\032google/protobuf/type.proto\"\260\001\n\003Api\022\014"
|
||||
"to\032\032google/protobuf/type.proto\"\201\002\n\003Api\022\014"
|
||||
"\n\004name\030\001 \001(\t\022(\n\007methods\030\002 \003(\0132\027.google.p"
|
||||
"rotobuf.Method\022(\n\007options\030\003 \003(\0132\027.google"
|
||||
".protobuf.Option\022\017\n\007version\030\004 \001(\t\0226\n\016sou"
|
||||
"rce_context\030\005 \001(\0132\036.google.protobuf.Sour"
|
||||
"ceContext\"\254\001\n\006Method\022\014\n\004name\030\001 \001(\t\022\030\n\020re"
|
||||
"quest_type_url\030\002 \001(\t\022\031\n\021request_streamin"
|
||||
"g\030\003 \001(\010\022\031\n\021response_type_url\030\004 \001(\t\022\032\n\022re"
|
||||
"sponse_streaming\030\005 \001(\010\022(\n\007options\030\006 \003(\0132"
|
||||
"\027.google.protobuf.OptionB\'\n\023com.google.p"
|
||||
"rotobufB\010ApiProtoP\001\242\002\003GPBb\006proto3", 513);
|
||||
"ceContext\022&\n\006mixins\030\006 \003(\0132\026.google.proto"
|
||||
"buf.Mixin\022\'\n\006syntax\030\007 \001(\0162\027.google.proto"
|
||||
"buf.Syntax\"\325\001\n\006Method\022\014\n\004name\030\001 \001(\t\022\030\n\020r"
|
||||
"equest_type_url\030\002 \001(\t\022\031\n\021request_streami"
|
||||
"ng\030\003 \001(\010\022\031\n\021response_type_url\030\004 \001(\t\022\032\n\022r"
|
||||
"esponse_streaming\030\005 \001(\010\022(\n\007options\030\006 \003(\013"
|
||||
"2\027.google.protobuf.Option\022\'\n\006syntax\030\007 \001("
|
||||
"\0162\027.google.protobuf.Syntax\"#\n\005Mixin\022\014\n\004n"
|
||||
"ame\030\001 \001(\t\022\014\n\004root\030\002 \001(\tB*\n\023com.google.pr"
|
||||
"otobufB\010ApiProtoP\001\240\001\001\242\002\003GPBb\006proto3", 675);
|
||||
::google::protobuf::MessageFactory::InternalRegisterGeneratedFile(
|
||||
"google/protobuf/api.proto", &protobuf_RegisterTypes);
|
||||
Api::default_instance_ = new Api();
|
||||
Method::default_instance_ = new Method();
|
||||
Mixin::default_instance_ = new Mixin();
|
||||
Api::default_instance_->InitAsDefaultInstance();
|
||||
Method::default_instance_->InitAsDefaultInstance();
|
||||
Mixin::default_instance_->InitAsDefaultInstance();
|
||||
::google::protobuf::internal::OnShutdown(&protobuf_ShutdownFile_google_2fprotobuf_2fapi_2eproto);
|
||||
}
|
||||
|
||||
@ -159,6 +191,8 @@ const int Api::kMethodsFieldNumber;
|
||||
const int Api::kOptionsFieldNumber;
|
||||
const int Api::kVersionFieldNumber;
|
||||
const int Api::kSourceContextFieldNumber;
|
||||
const int Api::kMixinsFieldNumber;
|
||||
const int Api::kSyntaxFieldNumber;
|
||||
#endif // !_MSC_VER
|
||||
|
||||
Api::Api()
|
||||
@ -187,6 +221,7 @@ void Api::SharedCtor() {
|
||||
name_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
|
||||
version_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
|
||||
source_context_ = NULL;
|
||||
syntax_ = 0;
|
||||
}
|
||||
|
||||
Api::~Api() {
|
||||
@ -232,8 +267,10 @@ void Api::Clear() {
|
||||
version_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
|
||||
if (GetArenaNoVirtual() == NULL && source_context_ != NULL) delete source_context_;
|
||||
source_context_ = NULL;
|
||||
syntax_ = 0;
|
||||
methods_.Clear();
|
||||
options_.Clear();
|
||||
mixins_.Clear();
|
||||
}
|
||||
|
||||
bool Api::MergePartialFromCodedStream(
|
||||
@ -321,6 +358,39 @@ bool Api::MergePartialFromCodedStream(
|
||||
} else {
|
||||
goto handle_unusual;
|
||||
}
|
||||
if (input->ExpectTag(50)) goto parse_mixins;
|
||||
break;
|
||||
}
|
||||
|
||||
// repeated .google.protobuf.Mixin mixins = 6;
|
||||
case 6: {
|
||||
if (tag == 50) {
|
||||
parse_mixins:
|
||||
DO_(input->IncrementRecursionDepth());
|
||||
parse_loop_mixins:
|
||||
DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtualNoRecursionDepth(
|
||||
input, add_mixins()));
|
||||
} else {
|
||||
goto handle_unusual;
|
||||
}
|
||||
if (input->ExpectTag(50)) goto parse_loop_mixins;
|
||||
input->UnsafeDecrementRecursionDepth();
|
||||
if (input->ExpectTag(56)) goto parse_syntax;
|
||||
break;
|
||||
}
|
||||
|
||||
// optional .google.protobuf.Syntax syntax = 7;
|
||||
case 7: {
|
||||
if (tag == 56) {
|
||||
parse_syntax:
|
||||
int value;
|
||||
DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
|
||||
int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>(
|
||||
input, &value)));
|
||||
set_syntax(static_cast< ::google::protobuf::Syntax >(value));
|
||||
} else {
|
||||
goto handle_unusual;
|
||||
}
|
||||
if (input->ExpectAtEnd()) goto success;
|
||||
break;
|
||||
}
|
||||
@ -387,6 +457,18 @@ void Api::SerializeWithCachedSizes(
|
||||
5, *this->source_context_, output);
|
||||
}
|
||||
|
||||
// repeated .google.protobuf.Mixin mixins = 6;
|
||||
for (unsigned int i = 0, n = this->mixins_size(); i < n; i++) {
|
||||
::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
|
||||
6, this->mixins(i), output);
|
||||
}
|
||||
|
||||
// optional .google.protobuf.Syntax syntax = 7;
|
||||
if (this->syntax() != 0) {
|
||||
::google::protobuf::internal::WireFormatLite::WriteEnum(
|
||||
7, this->syntax(), output);
|
||||
}
|
||||
|
||||
// @@protoc_insertion_point(serialize_end:google.protobuf.Api)
|
||||
}
|
||||
|
||||
@ -436,6 +518,19 @@ void Api::SerializeWithCachedSizes(
|
||||
5, *this->source_context_, target);
|
||||
}
|
||||
|
||||
// repeated .google.protobuf.Mixin mixins = 6;
|
||||
for (unsigned int i = 0, n = this->mixins_size(); i < n; i++) {
|
||||
target = ::google::protobuf::internal::WireFormatLite::
|
||||
WriteMessageNoVirtualToArray(
|
||||
6, this->mixins(i), target);
|
||||
}
|
||||
|
||||
// optional .google.protobuf.Syntax syntax = 7;
|
||||
if (this->syntax() != 0) {
|
||||
target = ::google::protobuf::internal::WireFormatLite::WriteEnumToArray(
|
||||
7, this->syntax(), target);
|
||||
}
|
||||
|
||||
// @@protoc_insertion_point(serialize_to_array_end:google.protobuf.Api)
|
||||
return target;
|
||||
}
|
||||
@ -464,6 +559,12 @@ int Api::ByteSize() const {
|
||||
*this->source_context_);
|
||||
}
|
||||
|
||||
// optional .google.protobuf.Syntax syntax = 7;
|
||||
if (this->syntax() != 0) {
|
||||
total_size += 1 +
|
||||
::google::protobuf::internal::WireFormatLite::EnumSize(this->syntax());
|
||||
}
|
||||
|
||||
// repeated .google.protobuf.Method methods = 2;
|
||||
total_size += 1 * this->methods_size();
|
||||
for (int i = 0; i < this->methods_size(); i++) {
|
||||
@ -480,6 +581,14 @@ int Api::ByteSize() const {
|
||||
this->options(i));
|
||||
}
|
||||
|
||||
// repeated .google.protobuf.Mixin mixins = 6;
|
||||
total_size += 1 * this->mixins_size();
|
||||
for (int i = 0; i < this->mixins_size(); i++) {
|
||||
total_size +=
|
||||
::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
|
||||
this->mixins(i));
|
||||
}
|
||||
|
||||
GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
|
||||
_cached_size_ = total_size;
|
||||
GOOGLE_SAFE_CONCURRENT_WRITES_END();
|
||||
@ -502,6 +611,7 @@ void Api::MergeFrom(const Api& from) {
|
||||
if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
|
||||
methods_.MergeFrom(from.methods_);
|
||||
options_.MergeFrom(from.options_);
|
||||
mixins_.MergeFrom(from.mixins_);
|
||||
if (from.name().size() > 0) {
|
||||
|
||||
name_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.name_);
|
||||
@ -513,6 +623,9 @@ void Api::MergeFrom(const Api& from) {
|
||||
if (from.has_source_context()) {
|
||||
mutable_source_context()->::google::protobuf::SourceContext::MergeFrom(from.source_context());
|
||||
}
|
||||
if (from.syntax() != 0) {
|
||||
set_syntax(from.syntax());
|
||||
}
|
||||
}
|
||||
|
||||
void Api::CopyFrom(const ::google::protobuf::Message& from) {
|
||||
@ -542,6 +655,8 @@ void Api::InternalSwap(Api* other) {
|
||||
options_.UnsafeArenaSwap(&other->options_);
|
||||
version_.Swap(&other->version_);
|
||||
std::swap(source_context_, other->source_context_);
|
||||
mixins_.UnsafeArenaSwap(&other->mixins_);
|
||||
std::swap(syntax_, other->syntax_);
|
||||
_internal_metadata_.Swap(&other->_internal_metadata_);
|
||||
std::swap(_cached_size_, other->_cached_size_);
|
||||
}
|
||||
@ -740,6 +855,50 @@ void Api::clear_source_context() {
|
||||
// @@protoc_insertion_point(field_set_allocated:google.protobuf.Api.source_context)
|
||||
}
|
||||
|
||||
// repeated .google.protobuf.Mixin mixins = 6;
|
||||
int Api::mixins_size() const {
|
||||
return mixins_.size();
|
||||
}
|
||||
void Api::clear_mixins() {
|
||||
mixins_.Clear();
|
||||
}
|
||||
const ::google::protobuf::Mixin& Api::mixins(int index) const {
|
||||
// @@protoc_insertion_point(field_get:google.protobuf.Api.mixins)
|
||||
return mixins_.Get(index);
|
||||
}
|
||||
::google::protobuf::Mixin* Api::mutable_mixins(int index) {
|
||||
// @@protoc_insertion_point(field_mutable:google.protobuf.Api.mixins)
|
||||
return mixins_.Mutable(index);
|
||||
}
|
||||
::google::protobuf::Mixin* Api::add_mixins() {
|
||||
// @@protoc_insertion_point(field_add:google.protobuf.Api.mixins)
|
||||
return mixins_.Add();
|
||||
}
|
||||
const ::google::protobuf::RepeatedPtrField< ::google::protobuf::Mixin >&
|
||||
Api::mixins() const {
|
||||
// @@protoc_insertion_point(field_list:google.protobuf.Api.mixins)
|
||||
return mixins_;
|
||||
}
|
||||
::google::protobuf::RepeatedPtrField< ::google::protobuf::Mixin >*
|
||||
Api::mutable_mixins() {
|
||||
// @@protoc_insertion_point(field_mutable_list:google.protobuf.Api.mixins)
|
||||
return &mixins_;
|
||||
}
|
||||
|
||||
// optional .google.protobuf.Syntax syntax = 7;
|
||||
void Api::clear_syntax() {
|
||||
syntax_ = 0;
|
||||
}
|
||||
::google::protobuf::Syntax Api::syntax() const {
|
||||
// @@protoc_insertion_point(field_get:google.protobuf.Api.syntax)
|
||||
return static_cast< ::google::protobuf::Syntax >(syntax_);
|
||||
}
|
||||
void Api::set_syntax(::google::protobuf::Syntax value) {
|
||||
|
||||
syntax_ = value;
|
||||
// @@protoc_insertion_point(field_set:google.protobuf.Api.syntax)
|
||||
}
|
||||
|
||||
#endif // PROTOBUF_INLINE_NOT_IN_HEADERS
|
||||
|
||||
// ===================================================================
|
||||
@ -751,6 +910,7 @@ const int Method::kRequestStreamingFieldNumber;
|
||||
const int Method::kResponseTypeUrlFieldNumber;
|
||||
const int Method::kResponseStreamingFieldNumber;
|
||||
const int Method::kOptionsFieldNumber;
|
||||
const int Method::kSyntaxFieldNumber;
|
||||
#endif // !_MSC_VER
|
||||
|
||||
Method::Method()
|
||||
@ -780,6 +940,7 @@ void Method::SharedCtor() {
|
||||
request_streaming_ = false;
|
||||
response_type_url_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
|
||||
response_streaming_ = false;
|
||||
syntax_ = 0;
|
||||
}
|
||||
|
||||
Method::~Method() {
|
||||
@ -829,7 +990,7 @@ void Method::Clear() {
|
||||
ZR_HELPER_(last) - ZR_HELPER_(first) + sizeof(last));\
|
||||
} while (0)
|
||||
|
||||
ZR_(request_streaming_, response_streaming_);
|
||||
ZR_(request_streaming_, syntax_);
|
||||
name_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
|
||||
request_type_url_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
|
||||
response_type_url_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
|
||||
@ -943,6 +1104,22 @@ bool Method::MergePartialFromCodedStream(
|
||||
}
|
||||
if (input->ExpectTag(50)) goto parse_loop_options;
|
||||
input->UnsafeDecrementRecursionDepth();
|
||||
if (input->ExpectTag(56)) goto parse_syntax;
|
||||
break;
|
||||
}
|
||||
|
||||
// optional .google.protobuf.Syntax syntax = 7;
|
||||
case 7: {
|
||||
if (tag == 56) {
|
||||
parse_syntax:
|
||||
int value;
|
||||
DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
|
||||
int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>(
|
||||
input, &value)));
|
||||
set_syntax(static_cast< ::google::protobuf::Syntax >(value));
|
||||
} else {
|
||||
goto handle_unusual;
|
||||
}
|
||||
if (input->ExpectAtEnd()) goto success;
|
||||
break;
|
||||
}
|
||||
@ -1017,6 +1194,12 @@ void Method::SerializeWithCachedSizes(
|
||||
6, this->options(i), output);
|
||||
}
|
||||
|
||||
// optional .google.protobuf.Syntax syntax = 7;
|
||||
if (this->syntax() != 0) {
|
||||
::google::protobuf::internal::WireFormatLite::WriteEnum(
|
||||
7, this->syntax(), output);
|
||||
}
|
||||
|
||||
// @@protoc_insertion_point(serialize_end:google.protobuf.Method)
|
||||
}
|
||||
|
||||
@ -1073,6 +1256,12 @@ void Method::SerializeWithCachedSizes(
|
||||
6, this->options(i), target);
|
||||
}
|
||||
|
||||
// optional .google.protobuf.Syntax syntax = 7;
|
||||
if (this->syntax() != 0) {
|
||||
target = ::google::protobuf::internal::WireFormatLite::WriteEnumToArray(
|
||||
7, this->syntax(), target);
|
||||
}
|
||||
|
||||
// @@protoc_insertion_point(serialize_to_array_end:google.protobuf.Method)
|
||||
return target;
|
||||
}
|
||||
@ -1111,6 +1300,12 @@ int Method::ByteSize() const {
|
||||
total_size += 1 + 1;
|
||||
}
|
||||
|
||||
// optional .google.protobuf.Syntax syntax = 7;
|
||||
if (this->syntax() != 0) {
|
||||
total_size += 1 +
|
||||
::google::protobuf::internal::WireFormatLite::EnumSize(this->syntax());
|
||||
}
|
||||
|
||||
// repeated .google.protobuf.Option options = 6;
|
||||
total_size += 1 * this->options_size();
|
||||
for (int i = 0; i < this->options_size(); i++) {
|
||||
@ -1158,6 +1353,9 @@ void Method::MergeFrom(const Method& from) {
|
||||
if (from.response_streaming() != 0) {
|
||||
set_response_streaming(from.response_streaming());
|
||||
}
|
||||
if (from.syntax() != 0) {
|
||||
set_syntax(from.syntax());
|
||||
}
|
||||
}
|
||||
|
||||
void Method::CopyFrom(const ::google::protobuf::Message& from) {
|
||||
@ -1188,6 +1386,7 @@ void Method::InternalSwap(Method* other) {
|
||||
response_type_url_.Swap(&other->response_type_url_);
|
||||
std::swap(response_streaming_, other->response_streaming_);
|
||||
options_.UnsafeArenaSwap(&other->options_);
|
||||
std::swap(syntax_, other->syntax_);
|
||||
_internal_metadata_.Swap(&other->_internal_metadata_);
|
||||
std::swap(_cached_size_, other->_cached_size_);
|
||||
}
|
||||
@ -1390,6 +1589,388 @@ Method::mutable_options() {
|
||||
return &options_;
|
||||
}
|
||||
|
||||
// optional .google.protobuf.Syntax syntax = 7;
|
||||
void Method::clear_syntax() {
|
||||
syntax_ = 0;
|
||||
}
|
||||
::google::protobuf::Syntax Method::syntax() const {
|
||||
// @@protoc_insertion_point(field_get:google.protobuf.Method.syntax)
|
||||
return static_cast< ::google::protobuf::Syntax >(syntax_);
|
||||
}
|
||||
void Method::set_syntax(::google::protobuf::Syntax value) {
|
||||
|
||||
syntax_ = value;
|
||||
// @@protoc_insertion_point(field_set:google.protobuf.Method.syntax)
|
||||
}
|
||||
|
||||
#endif // PROTOBUF_INLINE_NOT_IN_HEADERS
|
||||
|
||||
// ===================================================================
|
||||
|
||||
#ifndef _MSC_VER
|
||||
const int Mixin::kNameFieldNumber;
|
||||
const int Mixin::kRootFieldNumber;
|
||||
#endif // !_MSC_VER
|
||||
|
||||
Mixin::Mixin()
|
||||
: ::google::protobuf::Message(), _internal_metadata_(NULL) {
|
||||
SharedCtor();
|
||||
// @@protoc_insertion_point(constructor:google.protobuf.Mixin)
|
||||
}
|
||||
|
||||
void Mixin::InitAsDefaultInstance() {
|
||||
_is_default_instance_ = true;
|
||||
}
|
||||
|
||||
Mixin::Mixin(const Mixin& from)
|
||||
: ::google::protobuf::Message(),
|
||||
_internal_metadata_(NULL) {
|
||||
SharedCtor();
|
||||
MergeFrom(from);
|
||||
// @@protoc_insertion_point(copy_constructor:google.protobuf.Mixin)
|
||||
}
|
||||
|
||||
void Mixin::SharedCtor() {
|
||||
_is_default_instance_ = false;
|
||||
::google::protobuf::internal::GetEmptyString();
|
||||
_cached_size_ = 0;
|
||||
name_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
|
||||
root_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
|
||||
}
|
||||
|
||||
Mixin::~Mixin() {
|
||||
// @@protoc_insertion_point(destructor:google.protobuf.Mixin)
|
||||
SharedDtor();
|
||||
}
|
||||
|
||||
void Mixin::SharedDtor() {
|
||||
name_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
|
||||
root_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
|
||||
if (this != default_instance_) {
|
||||
}
|
||||
}
|
||||
|
||||
void Mixin::SetCachedSize(int size) const {
|
||||
GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
|
||||
_cached_size_ = size;
|
||||
GOOGLE_SAFE_CONCURRENT_WRITES_END();
|
||||
}
|
||||
const ::google::protobuf::Descriptor* Mixin::descriptor() {
|
||||
protobuf_AssignDescriptorsOnce();
|
||||
return Mixin_descriptor_;
|
||||
}
|
||||
|
||||
const Mixin& Mixin::default_instance() {
|
||||
if (default_instance_ == NULL) protobuf_AddDesc_google_2fprotobuf_2fapi_2eproto();
|
||||
return *default_instance_;
|
||||
}
|
||||
|
||||
Mixin* Mixin::default_instance_ = NULL;
|
||||
|
||||
Mixin* Mixin::New(::google::protobuf::Arena* arena) const {
|
||||
Mixin* n = new Mixin;
|
||||
if (arena != NULL) {
|
||||
arena->Own(n);
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
void Mixin::Clear() {
|
||||
name_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
|
||||
root_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
|
||||
}
|
||||
|
||||
bool Mixin::MergePartialFromCodedStream(
|
||||
::google::protobuf::io::CodedInputStream* input) {
|
||||
#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure
|
||||
::google::protobuf::uint32 tag;
|
||||
// @@protoc_insertion_point(parse_start:google.protobuf.Mixin)
|
||||
for (;;) {
|
||||
::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(127);
|
||||
tag = p.first;
|
||||
if (!p.second) goto handle_unusual;
|
||||
switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
|
||||
// optional string name = 1;
|
||||
case 1: {
|
||||
if (tag == 10) {
|
||||
DO_(::google::protobuf::internal::WireFormatLite::ReadString(
|
||||
input, this->mutable_name()));
|
||||
::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
|
||||
this->name().data(), this->name().length(),
|
||||
::google::protobuf::internal::WireFormat::PARSE,
|
||||
"google.protobuf.Mixin.name");
|
||||
} else {
|
||||
goto handle_unusual;
|
||||
}
|
||||
if (input->ExpectTag(18)) goto parse_root;
|
||||
break;
|
||||
}
|
||||
|
||||
// optional string root = 2;
|
||||
case 2: {
|
||||
if (tag == 18) {
|
||||
parse_root:
|
||||
DO_(::google::protobuf::internal::WireFormatLite::ReadString(
|
||||
input, this->mutable_root()));
|
||||
::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
|
||||
this->root().data(), this->root().length(),
|
||||
::google::protobuf::internal::WireFormat::PARSE,
|
||||
"google.protobuf.Mixin.root");
|
||||
} else {
|
||||
goto handle_unusual;
|
||||
}
|
||||
if (input->ExpectAtEnd()) goto success;
|
||||
break;
|
||||
}
|
||||
|
||||
default: {
|
||||
handle_unusual:
|
||||
if (tag == 0 ||
|
||||
::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
|
||||
::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) {
|
||||
goto success;
|
||||
}
|
||||
DO_(::google::protobuf::internal::WireFormatLite::SkipField(input, tag));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
success:
|
||||
// @@protoc_insertion_point(parse_success:google.protobuf.Mixin)
|
||||
return true;
|
||||
failure:
|
||||
// @@protoc_insertion_point(parse_failure:google.protobuf.Mixin)
|
||||
return false;
|
||||
#undef DO_
|
||||
}
|
||||
|
||||
void Mixin::SerializeWithCachedSizes(
|
||||
::google::protobuf::io::CodedOutputStream* output) const {
|
||||
// @@protoc_insertion_point(serialize_start:google.protobuf.Mixin)
|
||||
// optional string name = 1;
|
||||
if (this->name().size() > 0) {
|
||||
::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
|
||||
this->name().data(), this->name().length(),
|
||||
::google::protobuf::internal::WireFormat::SERIALIZE,
|
||||
"google.protobuf.Mixin.name");
|
||||
::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
|
||||
1, this->name(), output);
|
||||
}
|
||||
|
||||
// optional string root = 2;
|
||||
if (this->root().size() > 0) {
|
||||
::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
|
||||
this->root().data(), this->root().length(),
|
||||
::google::protobuf::internal::WireFormat::SERIALIZE,
|
||||
"google.protobuf.Mixin.root");
|
||||
::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
|
||||
2, this->root(), output);
|
||||
}
|
||||
|
||||
// @@protoc_insertion_point(serialize_end:google.protobuf.Mixin)
|
||||
}
|
||||
|
||||
::google::protobuf::uint8* Mixin::SerializeWithCachedSizesToArray(
|
||||
::google::protobuf::uint8* target) const {
|
||||
// @@protoc_insertion_point(serialize_to_array_start:google.protobuf.Mixin)
|
||||
// optional string name = 1;
|
||||
if (this->name().size() > 0) {
|
||||
::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
|
||||
this->name().data(), this->name().length(),
|
||||
::google::protobuf::internal::WireFormat::SERIALIZE,
|
||||
"google.protobuf.Mixin.name");
|
||||
target =
|
||||
::google::protobuf::internal::WireFormatLite::WriteStringToArray(
|
||||
1, this->name(), target);
|
||||
}
|
||||
|
||||
// optional string root = 2;
|
||||
if (this->root().size() > 0) {
|
||||
::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
|
||||
this->root().data(), this->root().length(),
|
||||
::google::protobuf::internal::WireFormat::SERIALIZE,
|
||||
"google.protobuf.Mixin.root");
|
||||
target =
|
||||
::google::protobuf::internal::WireFormatLite::WriteStringToArray(
|
||||
2, this->root(), target);
|
||||
}
|
||||
|
||||
// @@protoc_insertion_point(serialize_to_array_end:google.protobuf.Mixin)
|
||||
return target;
|
||||
}
|
||||
|
||||
int Mixin::ByteSize() const {
|
||||
int total_size = 0;
|
||||
|
||||
// optional string name = 1;
|
||||
if (this->name().size() > 0) {
|
||||
total_size += 1 +
|
||||
::google::protobuf::internal::WireFormatLite::StringSize(
|
||||
this->name());
|
||||
}
|
||||
|
||||
// optional string root = 2;
|
||||
if (this->root().size() > 0) {
|
||||
total_size += 1 +
|
||||
::google::protobuf::internal::WireFormatLite::StringSize(
|
||||
this->root());
|
||||
}
|
||||
|
||||
GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
|
||||
_cached_size_ = total_size;
|
||||
GOOGLE_SAFE_CONCURRENT_WRITES_END();
|
||||
return total_size;
|
||||
}
|
||||
|
||||
void Mixin::MergeFrom(const ::google::protobuf::Message& from) {
|
||||
if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
|
||||
const Mixin* source =
|
||||
::google::protobuf::internal::DynamicCastToGenerated<const Mixin>(
|
||||
&from);
|
||||
if (source == NULL) {
|
||||
::google::protobuf::internal::ReflectionOps::Merge(from, this);
|
||||
} else {
|
||||
MergeFrom(*source);
|
||||
}
|
||||
}
|
||||
|
||||
void Mixin::MergeFrom(const Mixin& from) {
|
||||
if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
|
||||
if (from.name().size() > 0) {
|
||||
|
||||
name_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.name_);
|
||||
}
|
||||
if (from.root().size() > 0) {
|
||||
|
||||
root_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.root_);
|
||||
}
|
||||
}
|
||||
|
||||
void Mixin::CopyFrom(const ::google::protobuf::Message& from) {
|
||||
if (&from == this) return;
|
||||
Clear();
|
||||
MergeFrom(from);
|
||||
}
|
||||
|
||||
void Mixin::CopyFrom(const Mixin& from) {
|
||||
if (&from == this) return;
|
||||
Clear();
|
||||
MergeFrom(from);
|
||||
}
|
||||
|
||||
bool Mixin::IsInitialized() const {
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void Mixin::Swap(Mixin* other) {
|
||||
if (other == this) return;
|
||||
InternalSwap(other);
|
||||
}
|
||||
void Mixin::InternalSwap(Mixin* other) {
|
||||
name_.Swap(&other->name_);
|
||||
root_.Swap(&other->root_);
|
||||
_internal_metadata_.Swap(&other->_internal_metadata_);
|
||||
std::swap(_cached_size_, other->_cached_size_);
|
||||
}
|
||||
|
||||
::google::protobuf::Metadata Mixin::GetMetadata() const {
|
||||
protobuf_AssignDescriptorsOnce();
|
||||
::google::protobuf::Metadata metadata;
|
||||
metadata.descriptor = Mixin_descriptor_;
|
||||
metadata.reflection = Mixin_reflection_;
|
||||
return metadata;
|
||||
}
|
||||
|
||||
#if PROTOBUF_INLINE_NOT_IN_HEADERS
|
||||
// Mixin
|
||||
|
||||
// optional string name = 1;
|
||||
void Mixin::clear_name() {
|
||||
name_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
|
||||
}
|
||||
const ::std::string& Mixin::name() const {
|
||||
// @@protoc_insertion_point(field_get:google.protobuf.Mixin.name)
|
||||
return name_.GetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
|
||||
}
|
||||
void Mixin::set_name(const ::std::string& value) {
|
||||
|
||||
name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
|
||||
// @@protoc_insertion_point(field_set:google.protobuf.Mixin.name)
|
||||
}
|
||||
void Mixin::set_name(const char* value) {
|
||||
|
||||
name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
|
||||
// @@protoc_insertion_point(field_set_char:google.protobuf.Mixin.name)
|
||||
}
|
||||
void Mixin::set_name(const char* value, size_t size) {
|
||||
|
||||
name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
|
||||
::std::string(reinterpret_cast<const char*>(value), size));
|
||||
// @@protoc_insertion_point(field_set_pointer:google.protobuf.Mixin.name)
|
||||
}
|
||||
::std::string* Mixin::mutable_name() {
|
||||
|
||||
// @@protoc_insertion_point(field_mutable:google.protobuf.Mixin.name)
|
||||
return name_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
|
||||
}
|
||||
::std::string* Mixin::release_name() {
|
||||
|
||||
return name_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
|
||||
}
|
||||
void Mixin::set_allocated_name(::std::string* name) {
|
||||
if (name != NULL) {
|
||||
|
||||
} else {
|
||||
|
||||
}
|
||||
name_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), name);
|
||||
// @@protoc_insertion_point(field_set_allocated:google.protobuf.Mixin.name)
|
||||
}
|
||||
|
||||
// optional string root = 2;
|
||||
void Mixin::clear_root() {
|
||||
root_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
|
||||
}
|
||||
const ::std::string& Mixin::root() const {
|
||||
// @@protoc_insertion_point(field_get:google.protobuf.Mixin.root)
|
||||
return root_.GetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
|
||||
}
|
||||
void Mixin::set_root(const ::std::string& value) {
|
||||
|
||||
root_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
|
||||
// @@protoc_insertion_point(field_set:google.protobuf.Mixin.root)
|
||||
}
|
||||
void Mixin::set_root(const char* value) {
|
||||
|
||||
root_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
|
||||
// @@protoc_insertion_point(field_set_char:google.protobuf.Mixin.root)
|
||||
}
|
||||
void Mixin::set_root(const char* value, size_t size) {
|
||||
|
||||
root_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
|
||||
::std::string(reinterpret_cast<const char*>(value), size));
|
||||
// @@protoc_insertion_point(field_set_pointer:google.protobuf.Mixin.root)
|
||||
}
|
||||
::std::string* Mixin::mutable_root() {
|
||||
|
||||
// @@protoc_insertion_point(field_mutable:google.protobuf.Mixin.root)
|
||||
return root_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
|
||||
}
|
||||
::std::string* Mixin::release_root() {
|
||||
|
||||
return root_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
|
||||
}
|
||||
void Mixin::set_allocated_root(::std::string* root) {
|
||||
if (root != NULL) {
|
||||
|
||||
} else {
|
||||
|
||||
}
|
||||
root_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), root);
|
||||
// @@protoc_insertion_point(field_set_allocated:google.protobuf.Mixin.root)
|
||||
}
|
||||
|
||||
#endif // PROTOBUF_INLINE_NOT_IN_HEADERS
|
||||
|
||||
// @@protoc_insertion_point(namespace_scope)
|
||||
|
@ -41,6 +41,7 @@ void protobuf_ShutdownFile_google_2fprotobuf_2fapi_2eproto();
|
||||
|
||||
class Api;
|
||||
class Method;
|
||||
class Mixin;
|
||||
|
||||
// ===================================================================
|
||||
|
||||
@ -155,6 +156,24 @@ class LIBPROTOBUF_EXPORT Api : public ::google::protobuf::Message {
|
||||
::google::protobuf::SourceContext* release_source_context();
|
||||
void set_allocated_source_context(::google::protobuf::SourceContext* source_context);
|
||||
|
||||
// repeated .google.protobuf.Mixin mixins = 6;
|
||||
int mixins_size() const;
|
||||
void clear_mixins();
|
||||
static const int kMixinsFieldNumber = 6;
|
||||
const ::google::protobuf::Mixin& mixins(int index) const;
|
||||
::google::protobuf::Mixin* mutable_mixins(int index);
|
||||
::google::protobuf::Mixin* add_mixins();
|
||||
const ::google::protobuf::RepeatedPtrField< ::google::protobuf::Mixin >&
|
||||
mixins() const;
|
||||
::google::protobuf::RepeatedPtrField< ::google::protobuf::Mixin >*
|
||||
mutable_mixins();
|
||||
|
||||
// optional .google.protobuf.Syntax syntax = 7;
|
||||
void clear_syntax();
|
||||
static const int kSyntaxFieldNumber = 7;
|
||||
::google::protobuf::Syntax syntax() const;
|
||||
void set_syntax(::google::protobuf::Syntax value);
|
||||
|
||||
// @@protoc_insertion_point(class_scope:google.protobuf.Api)
|
||||
private:
|
||||
|
||||
@ -165,6 +184,8 @@ class LIBPROTOBUF_EXPORT Api : public ::google::protobuf::Message {
|
||||
::google::protobuf::RepeatedPtrField< ::google::protobuf::Option > options_;
|
||||
::google::protobuf::internal::ArenaStringPtr version_;
|
||||
::google::protobuf::SourceContext* source_context_;
|
||||
::google::protobuf::RepeatedPtrField< ::google::protobuf::Mixin > mixins_;
|
||||
int syntax_;
|
||||
mutable int _cached_size_;
|
||||
friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fapi_2eproto();
|
||||
friend void protobuf_AssignDesc_google_2fprotobuf_2fapi_2eproto();
|
||||
@ -288,6 +309,12 @@ class LIBPROTOBUF_EXPORT Method : public ::google::protobuf::Message {
|
||||
::google::protobuf::RepeatedPtrField< ::google::protobuf::Option >*
|
||||
mutable_options();
|
||||
|
||||
// optional .google.protobuf.Syntax syntax = 7;
|
||||
void clear_syntax();
|
||||
static const int kSyntaxFieldNumber = 7;
|
||||
::google::protobuf::Syntax syntax() const;
|
||||
void set_syntax(::google::protobuf::Syntax value);
|
||||
|
||||
// @@protoc_insertion_point(class_scope:google.protobuf.Method)
|
||||
private:
|
||||
|
||||
@ -296,9 +323,10 @@ class LIBPROTOBUF_EXPORT Method : public ::google::protobuf::Message {
|
||||
::google::protobuf::internal::ArenaStringPtr name_;
|
||||
::google::protobuf::internal::ArenaStringPtr request_type_url_;
|
||||
::google::protobuf::internal::ArenaStringPtr response_type_url_;
|
||||
::google::protobuf::RepeatedPtrField< ::google::protobuf::Option > options_;
|
||||
bool request_streaming_;
|
||||
bool response_streaming_;
|
||||
int syntax_;
|
||||
::google::protobuf::RepeatedPtrField< ::google::protobuf::Option > options_;
|
||||
mutable int _cached_size_;
|
||||
friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fapi_2eproto();
|
||||
friend void protobuf_AssignDesc_google_2fprotobuf_2fapi_2eproto();
|
||||
@ -307,6 +335,101 @@ class LIBPROTOBUF_EXPORT Method : public ::google::protobuf::Message {
|
||||
void InitAsDefaultInstance();
|
||||
static Method* default_instance_;
|
||||
};
|
||||
// -------------------------------------------------------------------
|
||||
|
||||
class LIBPROTOBUF_EXPORT Mixin : public ::google::protobuf::Message {
|
||||
public:
|
||||
Mixin();
|
||||
virtual ~Mixin();
|
||||
|
||||
Mixin(const Mixin& from);
|
||||
|
||||
inline Mixin& operator=(const Mixin& from) {
|
||||
CopyFrom(from);
|
||||
return *this;
|
||||
}
|
||||
|
||||
static const ::google::protobuf::Descriptor* descriptor();
|
||||
static const Mixin& default_instance();
|
||||
|
||||
void Swap(Mixin* other);
|
||||
|
||||
// implements Message ----------------------------------------------
|
||||
|
||||
inline Mixin* New() const { return New(NULL); }
|
||||
|
||||
Mixin* New(::google::protobuf::Arena* arena) const;
|
||||
void CopyFrom(const ::google::protobuf::Message& from);
|
||||
void MergeFrom(const ::google::protobuf::Message& from);
|
||||
void CopyFrom(const Mixin& from);
|
||||
void MergeFrom(const Mixin& from);
|
||||
void Clear();
|
||||
bool IsInitialized() const;
|
||||
|
||||
int ByteSize() const;
|
||||
bool MergePartialFromCodedStream(
|
||||
::google::protobuf::io::CodedInputStream* input);
|
||||
void SerializeWithCachedSizes(
|
||||
::google::protobuf::io::CodedOutputStream* output) const;
|
||||
::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const;
|
||||
int GetCachedSize() const { return _cached_size_; }
|
||||
private:
|
||||
void SharedCtor();
|
||||
void SharedDtor();
|
||||
void SetCachedSize(int size) const;
|
||||
void InternalSwap(Mixin* other);
|
||||
private:
|
||||
inline ::google::protobuf::Arena* GetArenaNoVirtual() const {
|
||||
return _internal_metadata_.arena();
|
||||
}
|
||||
inline void* MaybeArenaPtr() const {
|
||||
return _internal_metadata_.raw_arena_ptr();
|
||||
}
|
||||
public:
|
||||
|
||||
::google::protobuf::Metadata GetMetadata() const;
|
||||
|
||||
// nested types ----------------------------------------------------
|
||||
|
||||
// accessors -------------------------------------------------------
|
||||
|
||||
// optional string name = 1;
|
||||
void clear_name();
|
||||
static const int kNameFieldNumber = 1;
|
||||
const ::std::string& name() const;
|
||||
void set_name(const ::std::string& value);
|
||||
void set_name(const char* value);
|
||||
void set_name(const char* value, size_t size);
|
||||
::std::string* mutable_name();
|
||||
::std::string* release_name();
|
||||
void set_allocated_name(::std::string* name);
|
||||
|
||||
// optional string root = 2;
|
||||
void clear_root();
|
||||
static const int kRootFieldNumber = 2;
|
||||
const ::std::string& root() const;
|
||||
void set_root(const ::std::string& value);
|
||||
void set_root(const char* value);
|
||||
void set_root(const char* value, size_t size);
|
||||
::std::string* mutable_root();
|
||||
::std::string* release_root();
|
||||
void set_allocated_root(::std::string* root);
|
||||
|
||||
// @@protoc_insertion_point(class_scope:google.protobuf.Mixin)
|
||||
private:
|
||||
|
||||
::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
|
||||
bool _is_default_instance_;
|
||||
::google::protobuf::internal::ArenaStringPtr name_;
|
||||
::google::protobuf::internal::ArenaStringPtr root_;
|
||||
mutable int _cached_size_;
|
||||
friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fapi_2eproto();
|
||||
friend void protobuf_AssignDesc_google_2fprotobuf_2fapi_2eproto();
|
||||
friend void protobuf_ShutdownFile_google_2fprotobuf_2fapi_2eproto();
|
||||
|
||||
void InitAsDefaultInstance();
|
||||
static Mixin* default_instance_;
|
||||
};
|
||||
// ===================================================================
|
||||
|
||||
|
||||
@ -498,6 +621,50 @@ inline void Api::set_allocated_source_context(::google::protobuf::SourceContext*
|
||||
// @@protoc_insertion_point(field_set_allocated:google.protobuf.Api.source_context)
|
||||
}
|
||||
|
||||
// repeated .google.protobuf.Mixin mixins = 6;
|
||||
inline int Api::mixins_size() const {
|
||||
return mixins_.size();
|
||||
}
|
||||
inline void Api::clear_mixins() {
|
||||
mixins_.Clear();
|
||||
}
|
||||
inline const ::google::protobuf::Mixin& Api::mixins(int index) const {
|
||||
// @@protoc_insertion_point(field_get:google.protobuf.Api.mixins)
|
||||
return mixins_.Get(index);
|
||||
}
|
||||
inline ::google::protobuf::Mixin* Api::mutable_mixins(int index) {
|
||||
// @@protoc_insertion_point(field_mutable:google.protobuf.Api.mixins)
|
||||
return mixins_.Mutable(index);
|
||||
}
|
||||
inline ::google::protobuf::Mixin* Api::add_mixins() {
|
||||
// @@protoc_insertion_point(field_add:google.protobuf.Api.mixins)
|
||||
return mixins_.Add();
|
||||
}
|
||||
inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::Mixin >&
|
||||
Api::mixins() const {
|
||||
// @@protoc_insertion_point(field_list:google.protobuf.Api.mixins)
|
||||
return mixins_;
|
||||
}
|
||||
inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::Mixin >*
|
||||
Api::mutable_mixins() {
|
||||
// @@protoc_insertion_point(field_mutable_list:google.protobuf.Api.mixins)
|
||||
return &mixins_;
|
||||
}
|
||||
|
||||
// optional .google.protobuf.Syntax syntax = 7;
|
||||
inline void Api::clear_syntax() {
|
||||
syntax_ = 0;
|
||||
}
|
||||
inline ::google::protobuf::Syntax Api::syntax() const {
|
||||
// @@protoc_insertion_point(field_get:google.protobuf.Api.syntax)
|
||||
return static_cast< ::google::protobuf::Syntax >(syntax_);
|
||||
}
|
||||
inline void Api::set_syntax(::google::protobuf::Syntax value) {
|
||||
|
||||
syntax_ = value;
|
||||
// @@protoc_insertion_point(field_set:google.protobuf.Api.syntax)
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
|
||||
// Method
|
||||
@ -689,9 +856,115 @@ Method::mutable_options() {
|
||||
return &options_;
|
||||
}
|
||||
|
||||
// optional .google.protobuf.Syntax syntax = 7;
|
||||
inline void Method::clear_syntax() {
|
||||
syntax_ = 0;
|
||||
}
|
||||
inline ::google::protobuf::Syntax Method::syntax() const {
|
||||
// @@protoc_insertion_point(field_get:google.protobuf.Method.syntax)
|
||||
return static_cast< ::google::protobuf::Syntax >(syntax_);
|
||||
}
|
||||
inline void Method::set_syntax(::google::protobuf::Syntax value) {
|
||||
|
||||
syntax_ = value;
|
||||
// @@protoc_insertion_point(field_set:google.protobuf.Method.syntax)
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
|
||||
// Mixin
|
||||
|
||||
// optional string name = 1;
|
||||
inline void Mixin::clear_name() {
|
||||
name_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
|
||||
}
|
||||
inline const ::std::string& Mixin::name() const {
|
||||
// @@protoc_insertion_point(field_get:google.protobuf.Mixin.name)
|
||||
return name_.GetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
|
||||
}
|
||||
inline void Mixin::set_name(const ::std::string& value) {
|
||||
|
||||
name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
|
||||
// @@protoc_insertion_point(field_set:google.protobuf.Mixin.name)
|
||||
}
|
||||
inline void Mixin::set_name(const char* value) {
|
||||
|
||||
name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
|
||||
// @@protoc_insertion_point(field_set_char:google.protobuf.Mixin.name)
|
||||
}
|
||||
inline void Mixin::set_name(const char* value, size_t size) {
|
||||
|
||||
name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
|
||||
::std::string(reinterpret_cast<const char*>(value), size));
|
||||
// @@protoc_insertion_point(field_set_pointer:google.protobuf.Mixin.name)
|
||||
}
|
||||
inline ::std::string* Mixin::mutable_name() {
|
||||
|
||||
// @@protoc_insertion_point(field_mutable:google.protobuf.Mixin.name)
|
||||
return name_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
|
||||
}
|
||||
inline ::std::string* Mixin::release_name() {
|
||||
|
||||
return name_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
|
||||
}
|
||||
inline void Mixin::set_allocated_name(::std::string* name) {
|
||||
if (name != NULL) {
|
||||
|
||||
} else {
|
||||
|
||||
}
|
||||
name_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), name);
|
||||
// @@protoc_insertion_point(field_set_allocated:google.protobuf.Mixin.name)
|
||||
}
|
||||
|
||||
// optional string root = 2;
|
||||
inline void Mixin::clear_root() {
|
||||
root_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
|
||||
}
|
||||
inline const ::std::string& Mixin::root() const {
|
||||
// @@protoc_insertion_point(field_get:google.protobuf.Mixin.root)
|
||||
return root_.GetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
|
||||
}
|
||||
inline void Mixin::set_root(const ::std::string& value) {
|
||||
|
||||
root_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
|
||||
// @@protoc_insertion_point(field_set:google.protobuf.Mixin.root)
|
||||
}
|
||||
inline void Mixin::set_root(const char* value) {
|
||||
|
||||
root_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
|
||||
// @@protoc_insertion_point(field_set_char:google.protobuf.Mixin.root)
|
||||
}
|
||||
inline void Mixin::set_root(const char* value, size_t size) {
|
||||
|
||||
root_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
|
||||
::std::string(reinterpret_cast<const char*>(value), size));
|
||||
// @@protoc_insertion_point(field_set_pointer:google.protobuf.Mixin.root)
|
||||
}
|
||||
inline ::std::string* Mixin::mutable_root() {
|
||||
|
||||
// @@protoc_insertion_point(field_mutable:google.protobuf.Mixin.root)
|
||||
return root_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
|
||||
}
|
||||
inline ::std::string* Mixin::release_root() {
|
||||
|
||||
return root_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
|
||||
}
|
||||
inline void Mixin::set_allocated_root(::std::string* root) {
|
||||
if (root != NULL) {
|
||||
|
||||
} else {
|
||||
|
||||
}
|
||||
root_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), root);
|
||||
// @@protoc_insertion_point(field_set_allocated:google.protobuf.Mixin.root)
|
||||
}
|
||||
|
||||
#endif // !PROTOBUF_INLINE_NOT_IN_HEADERS
|
||||
// -------------------------------------------------------------------
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
|
||||
|
||||
// @@protoc_insertion_point(namespace_scope)
|
||||
|
||||
|
@ -34,14 +34,15 @@ package google.protobuf;
|
||||
import "google/protobuf/source_context.proto";
|
||||
import "google/protobuf/type.proto";
|
||||
|
||||
option java_multiple_files = true;
|
||||
option java_outer_classname = "ApiProto";
|
||||
option java_package = "com.google.protobuf";
|
||||
option java_outer_classname = "ApiProto";
|
||||
option java_multiple_files = true;
|
||||
option java_generate_equals_and_hash = true;
|
||||
option objc_class_prefix = "GPB";
|
||||
|
||||
|
||||
// Api is a light-weight descriptor for a protocol buffer service.
|
||||
message Api {
|
||||
|
||||
// The fully qualified name of this api, including package name
|
||||
// followed by the api's simple name.
|
||||
string name = 1;
|
||||
@ -73,18 +74,22 @@ message Api {
|
||||
// be omitted. Zero major versions must only be used for
|
||||
// experimental, none-GA apis.
|
||||
//
|
||||
// See also: [design doc](http://go/api-versioning).
|
||||
//
|
||||
//
|
||||
string version = 4;
|
||||
|
||||
// Source context for the protocol buffer service represented by this
|
||||
// message.
|
||||
SourceContext source_context = 5;
|
||||
|
||||
// Included APIs. See [Mixin][].
|
||||
repeated Mixin mixins = 6;
|
||||
|
||||
// The source syntax of the service.
|
||||
Syntax syntax = 7;
|
||||
}
|
||||
|
||||
// Method represents a method of an api.
|
||||
message Method {
|
||||
|
||||
// The simple name of this method.
|
||||
string name = 1;
|
||||
|
||||
@ -102,4 +107,94 @@ message Method {
|
||||
|
||||
// Any metadata attached to the method.
|
||||
repeated Option options = 6;
|
||||
|
||||
// The source syntax of this method.
|
||||
Syntax syntax = 7;
|
||||
}
|
||||
|
||||
// Declares an API to be included in this API. The including API must
|
||||
// redeclare all the methods from the included API, but documentation
|
||||
// and options are inherited as follows:
|
||||
//
|
||||
// - If after comment and whitespace stripping, the documentation
|
||||
// string of the redeclared method is empty, it will be inherited
|
||||
// from the original method.
|
||||
//
|
||||
// - Each annotation belonging to the service config (http,
|
||||
// visibility) which is not set in the redeclared method will be
|
||||
// inherited.
|
||||
//
|
||||
// - If an http annotation is inherited, the path pattern will be
|
||||
// modified as follows. Any version prefix will be replaced by the
|
||||
// version of the including API plus the [root][] path if specified.
|
||||
//
|
||||
// Example of a simple mixin:
|
||||
//
|
||||
// package google.acl.v1;
|
||||
// service AccessControl {
|
||||
// // Get the underlying ACL object.
|
||||
// rpc GetAcl(GetAclRequest) returns (Acl) {
|
||||
// option (google.api.http).get = "/v1/{resource=**}:getAcl";
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// package google.storage.v2;
|
||||
// service Storage {
|
||||
// // (-- see AccessControl.GetAcl --)
|
||||
// rpc GetAcl(GetAclRequest) returns (Acl);
|
||||
//
|
||||
// // Get a data record.
|
||||
// rpc GetData(GetDataRequest) returns (Data) {
|
||||
// option (google.api.http).get = "/v2/{resource=**}";
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// Example of a mixin configuration:
|
||||
//
|
||||
// apis:
|
||||
// - name: google.storage.v2.Storage
|
||||
// mixins:
|
||||
// - name: google.acl.v1.AccessControl
|
||||
//
|
||||
// The mixin construct implies that all methods in `AccessControl` are
|
||||
// also declared with same name and request/response types in
|
||||
// `Storage`. A documentation generator or annotation processor will
|
||||
// see the effective `Storage.GetAcl` method after inherting
|
||||
// documentation and annotations as follows:
|
||||
//
|
||||
// service Storage {
|
||||
// // Get the underlying ACL object.
|
||||
// rpc GetAcl(GetAclRequest) returns (Acl) {
|
||||
// option (google.api.http).get = "/v2/{resource=**}:getAcl";
|
||||
// }
|
||||
// ...
|
||||
// }
|
||||
//
|
||||
// Note how the version in the path pattern changed from `v1` to `v2`.
|
||||
//
|
||||
// If the `root` field in the mixin is specified, it should be a
|
||||
// relative path under which inherited HTTP paths are placed. Example:
|
||||
//
|
||||
// apis:
|
||||
// - name: google.storage.v2.Storage
|
||||
// mixins:
|
||||
// - name: google.acl.v1.AccessControl
|
||||
// root: acls
|
||||
//
|
||||
// This implies the following inherited HTTP annotation:
|
||||
//
|
||||
// service Storage {
|
||||
// // Get the underlying ACL object.
|
||||
// rpc GetAcl(GetAclRequest) returns (Acl) {
|
||||
// option (google.api.http).get = "/v2/acls/{resource=**}:getAcl";
|
||||
// }
|
||||
// ...
|
||||
// }
|
||||
message Mixin {
|
||||
// The fully qualified name of the API which is included.
|
||||
string name = 1;
|
||||
|
||||
// If non-empty specifies a path under which inherited HTTP paths
|
||||
// are rooted.
|
||||
string root = 2;
|
||||
}
|
||||
|
0
src/google/protobuf/compiler/java/java_enum_lite.cc
Normal file
0
src/google/protobuf/compiler/java/java_enum_lite.cc
Normal file
0
src/google/protobuf/compiler/java/java_enum_lite.h
Normal file
0
src/google/protobuf/compiler/java/java_enum_lite.h
Normal file
@ -80,6 +80,7 @@ option objc_class_prefix = "GPB";
|
||||
// }
|
||||
//
|
||||
message Duration {
|
||||
|
||||
// Signed seconds of the span of time. Must be from -315,576,000,000
|
||||
// to +315,576,000,000 inclusive.
|
||||
int64 seconds = 1;
|
||||
|
@ -79,8 +79,8 @@ void protobuf_AddDesc_google_2fprotobuf_2fempty_2eproto() {
|
||||
|
||||
::google::protobuf::DescriptorPool::InternalAddGeneratedFile(
|
||||
"\n\033google/protobuf/empty.proto\022\017google.pr"
|
||||
"otobuf\"\007\n\005EmptyB)\n\023com.google.protobufB\n"
|
||||
"EmptyProtoP\001\242\002\003GPBb\006proto3", 106);
|
||||
"otobuf\"\007\n\005EmptyB,\n\023com.google.protobufB\n"
|
||||
"EmptyProtoP\001\240\001\001\242\002\003GPBb\006proto3", 109);
|
||||
::google::protobuf::MessageFactory::InternalRegisterGeneratedFile(
|
||||
"google/protobuf/empty.proto", &protobuf_RegisterTypes);
|
||||
Empty::default_instance_ = new Empty();
|
||||
|
@ -31,12 +31,12 @@ syntax = "proto3";
|
||||
|
||||
package google.protobuf;
|
||||
|
||||
option java_multiple_files = true;
|
||||
option java_outer_classname = "EmptyProto";
|
||||
option java_package = "com.google.protobuf";
|
||||
option java_outer_classname = "EmptyProto";
|
||||
option java_multiple_files = true;
|
||||
option java_generate_equals_and_hash = true;
|
||||
option objc_class_prefix = "GPB";
|
||||
|
||||
|
||||
// A generic empty message that you can re-use to avoid defining duplicated
|
||||
// empty messages in your APIs. A typical example is to use it as the request
|
||||
// or the response type of an API method. For instance:
|
||||
@ -45,6 +45,5 @@ option objc_class_prefix = "GPB";
|
||||
// rpc Bar(google.protobuf.Empty) returns (google.protobuf.Empty);
|
||||
// }
|
||||
//
|
||||
message Empty {
|
||||
|
||||
}
|
||||
// The JSON representation for `Empty` is empty JSON object `{}`.
|
||||
message Empty {}
|
||||
|
@ -81,8 +81,9 @@ void protobuf_AddDesc_google_2fprotobuf_2ffield_5fmask_2eproto() {
|
||||
::google::protobuf::DescriptorPool::InternalAddGeneratedFile(
|
||||
"\n google/protobuf/field_mask.proto\022\017goog"
|
||||
"le.protobuf\"\032\n\tFieldMask\022\r\n\005paths\030\001 \003(\tB"
|
||||
"F\n\023com.google.protobufB\016FieldMaskProtoP\001"
|
||||
"\242\002\003GPB\252\002\026Google.ProtocolBuffersb\006proto3", 159);
|
||||
"I\n\023com.google.protobufB\016FieldMaskProtoP\001"
|
||||
"\240\001\001\242\002\003GPB\252\002\026Google.ProtocolBuffersb\006prot"
|
||||
"o3", 162);
|
||||
::google::protobuf::MessageFactory::InternalRegisterGeneratedFile(
|
||||
"google/protobuf/field_mask.proto", &protobuf_RegisterTypes);
|
||||
FieldMask::default_instance_ = new FieldMask();
|
||||
|
@ -31,13 +31,13 @@ syntax = "proto3";
|
||||
|
||||
package google.protobuf;
|
||||
|
||||
option csharp_namespace = "Google.ProtocolBuffers";
|
||||
option java_generate_equals_and_hash = true;
|
||||
option java_multiple_files = true;
|
||||
option java_outer_classname = "FieldMaskProto";
|
||||
option java_package = "com.google.protobuf";
|
||||
option csharp_namespace = "Google.ProtocolBuffers";
|
||||
option objc_class_prefix = "GPB";
|
||||
|
||||
|
||||
// `FieldMask` represents a set of symbolic field paths, for example:
|
||||
//
|
||||
// paths: "f.a"
|
||||
@ -52,6 +52,7 @@ option objc_class_prefix = "GPB";
|
||||
// Field masks also have a custom JSON encoding (see below).
|
||||
//
|
||||
// # Field Masks in Projections
|
||||
//
|
||||
// When used in the context of a projection, a response message or
|
||||
// sub-message is filtered by the API to only contain those fields as
|
||||
// specified in the mask. For example, if the mask in the previous
|
||||
@ -97,6 +98,7 @@ option objc_class_prefix = "GPB";
|
||||
// behavior for APIs.
|
||||
//
|
||||
// # Field Masks in Update Operations
|
||||
//
|
||||
// A field mask in update operations specifies which fields of the
|
||||
// targeted resource are going to be updated. The API is required
|
||||
// to only change the values of the fields as specified in the mask
|
||||
@ -124,11 +126,13 @@ option objc_class_prefix = "GPB";
|
||||
// required to be honored by the API.
|
||||
//
|
||||
// ## Considerations for HTTP REST
|
||||
//
|
||||
// The HTTP kind of an update operation which uses a field mask must
|
||||
// be set to PATCH instead of PUT in order to satisfy HTTP semantics
|
||||
// (PUT must only be used for full updates).
|
||||
//
|
||||
// # JSON Encoding of Field Masks
|
||||
//
|
||||
// In JSON, a field mask is encoded as a single string where paths are
|
||||
// separated by a comma. Fields name in each path are converted
|
||||
// to/from lower-camel naming conventions.
|
||||
|
@ -81,8 +81,8 @@ void protobuf_AddDesc_google_2fprotobuf_2fsource_5fcontext_2eproto() {
|
||||
::google::protobuf::DescriptorPool::InternalAddGeneratedFile(
|
||||
"\n$google/protobuf/source_context.proto\022\017"
|
||||
"google.protobuf\"\"\n\rSourceContext\022\021\n\tfile"
|
||||
"_name\030\001 \001(\tB1\n\023com.google.protobufB\022Sour"
|
||||
"ceContextProtoP\001\242\002\003GPBb\006proto3", 150);
|
||||
"_name\030\001 \001(\tB4\n\023com.google.protobufB\022Sour"
|
||||
"ceContextProtoP\001\240\001\001\242\002\003GPBb\006proto3", 153);
|
||||
::google::protobuf::MessageFactory::InternalRegisterGeneratedFile(
|
||||
"google/protobuf/source_context.proto", &protobuf_RegisterTypes);
|
||||
SourceContext::default_instance_ = new SourceContext();
|
||||
|
@ -31,12 +31,12 @@ syntax = "proto3";
|
||||
|
||||
package google.protobuf;
|
||||
|
||||
option java_multiple_files = true;
|
||||
option java_outer_classname = "SourceContextProto";
|
||||
option java_package = "com.google.protobuf";
|
||||
option java_outer_classname = "SourceContextProto";
|
||||
option java_multiple_files = true;
|
||||
option java_generate_equals_and_hash = true;
|
||||
option objc_class_prefix = "GPB";
|
||||
|
||||
|
||||
// `SourceContext` represents information about the source of a
|
||||
// protobuf element, like the file in which it is defined.
|
||||
message SourceContext {
|
||||
|
@ -45,6 +45,8 @@ option objc_class_prefix = "GPB";
|
||||
// scripting languages like JS a struct is represented as an
|
||||
// object. The details of that representation are described together
|
||||
// with the proto support for the language.
|
||||
//
|
||||
// The JSON representation for `Struct` is JSON object.
|
||||
message Struct {
|
||||
// Map of dynamically typed values.
|
||||
map<string, Value> fields = 1;
|
||||
@ -54,37 +56,39 @@ message Struct {
|
||||
// null, a number, a string, a boolean, a recursive struct value, or a
|
||||
// list of values. A producer of value is expected to set one of that
|
||||
// variants, absence of any variant indicates an error.
|
||||
//
|
||||
// The JSON representation for `Value` is JSON value.
|
||||
message Value {
|
||||
// The kind of value.
|
||||
oneof kind {
|
||||
// Represents a null value.
|
||||
NullValue null_value = 1;
|
||||
|
||||
// Represents a double value.
|
||||
double number_value = 2;
|
||||
|
||||
// Represents a string value.
|
||||
string string_value = 3;
|
||||
|
||||
// Represents a boolean value.
|
||||
bool bool_value = 4;
|
||||
|
||||
// Represents a structured value.
|
||||
Struct struct_value = 5;
|
||||
|
||||
// Represents a repeated `Value`.
|
||||
ListValue list_value = 6;
|
||||
}
|
||||
}
|
||||
|
||||
// `ListValue` is a wrapper around a repeated field of values.
|
||||
message ListValue {
|
||||
// Repeated field of dynamically typed values.
|
||||
repeated Value values = 1;
|
||||
}
|
||||
|
||||
// `NullValue` is a singleton enumeration to represent the null
|
||||
// value for the `Value` type union.
|
||||
// `NullValue` is a singleton enumeration to represent the null value for the
|
||||
// `Value` type union.
|
||||
//
|
||||
// The JSON representation for `NullValue` is JSON `null`.
|
||||
enum NullValue {
|
||||
// Null value.
|
||||
NULL_VALUE = 0;
|
||||
}
|
||||
|
||||
// `ListValue` is a wrapper around a repeated field of values.
|
||||
//
|
||||
// The JSON representation for `ListValue` is JSON array.
|
||||
message ListValue {
|
||||
// Repeated field of dynamically typed values.
|
||||
repeated Value values = 1;
|
||||
}
|
||||
|
@ -35,8 +35,10 @@
|
||||
#include <google/protobuf/stubs/status.h>
|
||||
#include <google/protobuf/stubs/stringpiece.h>
|
||||
#include <google/protobuf/stubs/strutil.h>
|
||||
#include <stdio.h>
|
||||
#include <google/protobuf/stubs/int128.h>
|
||||
#include <errno.h>
|
||||
#include <sstream>
|
||||
#include <stdio.h>
|
||||
#include <vector>
|
||||
|
||||
#ifdef _WIN32
|
||||
@ -48,6 +50,9 @@
|
||||
#else
|
||||
#error "No suitable threading library available."
|
||||
#endif
|
||||
#if defined(__ANDROID__)
|
||||
#include <android/log.h>
|
||||
#endif
|
||||
|
||||
namespace google {
|
||||
namespace protobuf {
|
||||
@ -104,7 +109,43 @@ string VersionString(int version) {
|
||||
// emulates google3/base/logging.cc
|
||||
|
||||
namespace internal {
|
||||
#if defined(__ANDROID__)
|
||||
inline void DefaultLogHandler(LogLevel level, const char* filename, int line,
|
||||
const string& message) {
|
||||
#ifdef GOOGLE_PROTOBUF_MIN_LOG_LEVEL
|
||||
if (level < GOOGLE_PROTOBUF_MIN_LOG_LEVEL) {
|
||||
return;
|
||||
}
|
||||
static const char* level_names[] = {"INFO", "WARNING", "ERROR", "FATAL"};
|
||||
|
||||
static const int android_log_levels[] = {
|
||||
ANDROID_LOG_INFO, // LOG(INFO),
|
||||
ANDROID_LOG_WARN, // LOG(WARNING)
|
||||
ANDROID_LOG_ERROR, // LOG(ERROR)
|
||||
ANDROID_LOG_FATAL, // LOG(FATAL)
|
||||
};
|
||||
|
||||
// Bound the logging level.
|
||||
const int android_log_level = android_log_levels[level];
|
||||
::std::ostringstream ostr;
|
||||
ostr << "[libprotobuf " << level_names[level] << " " << filename << ":"
|
||||
<< line << "] " << message.c_str();
|
||||
|
||||
// Output the log string the Android log at the appropriate level.
|
||||
__android_log_write(android_log_level, "libprotobuf-native",
|
||||
ostr.str().c_str());
|
||||
// Also output to std::cerr.
|
||||
fprintf(stderr, "%s", ostr.str().c_str());
|
||||
fflush(stderr);
|
||||
|
||||
// Indicate termination if needed.
|
||||
if (android_log_level == ANDROID_LOG_FATAL) {
|
||||
__android_log_write(ANDROID_LOG_FATAL, "libprotobuf-native",
|
||||
"terminating.\n");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#else
|
||||
void DefaultLogHandler(LogLevel level, const char* filename, int line,
|
||||
const string& message) {
|
||||
static const char* level_names[] = { "INFO", "WARNING", "ERROR", "FATAL" };
|
||||
@ -115,6 +156,7 @@ void DefaultLogHandler(LogLevel level, const char* filename, int line,
|
||||
level_names[level], filename, line, message.c_str());
|
||||
fflush(stderr); // Needed on MSVC.
|
||||
}
|
||||
#endif
|
||||
|
||||
void NullLogHandler(LogLevel /* level */, const char* /* filename */,
|
||||
int /* line */, const string& /* message */) {
|
||||
@ -154,22 +196,19 @@ LogMessage& LogMessage::operator<<(const StringPiece& value) {
|
||||
return *this;
|
||||
}
|
||||
|
||||
LogMessage& LogMessage::operator<<(long long value) {
|
||||
message_ += SimpleItoa(value);
|
||||
return *this;
|
||||
}
|
||||
|
||||
LogMessage& LogMessage::operator<<(unsigned long long value) {
|
||||
message_ += SimpleItoa(value);
|
||||
return *this;
|
||||
}
|
||||
|
||||
LogMessage& LogMessage::operator<<(
|
||||
const ::google::protobuf::util::Status& status) {
|
||||
message_ += status.ToString();
|
||||
return *this;
|
||||
}
|
||||
|
||||
LogMessage& LogMessage::operator<<(const uint128& value) {
|
||||
std::ostringstream str;
|
||||
str << value;
|
||||
message_ += str.str();
|
||||
return *this;
|
||||
}
|
||||
|
||||
// Since this is just for logging, we don't care if the current locale changes
|
||||
// the results -- in fact, we probably prefer that. So we use snprintf()
|
||||
// instead of Simple*toa().
|
||||
@ -194,6 +233,8 @@ DECLARE_STREAM_OPERATOR(long , "%ld")
|
||||
DECLARE_STREAM_OPERATOR(unsigned long, "%lu")
|
||||
DECLARE_STREAM_OPERATOR(double , "%g" )
|
||||
DECLARE_STREAM_OPERATOR(void* , "%p" )
|
||||
DECLARE_STREAM_OPERATOR(long long , "%" GOOGLE_LL_FORMAT "d")
|
||||
DECLARE_STREAM_OPERATOR(unsigned long long, "%" GOOGLE_LL_FORMAT "u")
|
||||
#undef DECLARE_STREAM_OPERATOR
|
||||
|
||||
LogMessage::LogMessage(LogLevel level, const char* filename, int line)
|
||||
|
@ -35,6 +35,7 @@
|
||||
#ifndef GOOGLE_PROTOBUF_COMMON_H__
|
||||
#define GOOGLE_PROTOBUF_COMMON_H__
|
||||
|
||||
#include <string>
|
||||
|
||||
#include <google/protobuf/stubs/port.h>
|
||||
#include <google/protobuf/stubs/macros.h>
|
||||
@ -137,12 +138,35 @@ std::string LIBPROTOBUF_EXPORT VersionString(int version);
|
||||
// ===================================================================
|
||||
// from google3/util/utf8/public/unilib.h
|
||||
|
||||
class StringPiece;
|
||||
namespace internal {
|
||||
|
||||
// Checks if the buffer contains structurally-valid UTF-8. Implemented in
|
||||
// structurally_valid.cc.
|
||||
LIBPROTOBUF_EXPORT bool IsStructurallyValidUTF8(const char* buf, int len);
|
||||
|
||||
inline bool IsStructurallyValidUTF8(const std::string& str) {
|
||||
return IsStructurallyValidUTF8(str.data(), str.length());
|
||||
}
|
||||
|
||||
// Returns initial number of bytes of structually valid UTF-8.
|
||||
LIBPROTOBUF_EXPORT int UTF8SpnStructurallyValid(const StringPiece& str);
|
||||
|
||||
// Coerce UTF-8 byte string in src_str to be
|
||||
// a structurally-valid equal-length string by selectively
|
||||
// overwriting illegal bytes with replace_char (typically ' ' or '?').
|
||||
// replace_char must be legal printable 7-bit Ascii 0x20..0x7e.
|
||||
// src_str is read-only.
|
||||
//
|
||||
// Returns pointer to output buffer, src_str.data() if no changes were made,
|
||||
// or idst if some bytes were changed. idst is allocated by the caller
|
||||
// and must be at least as big as src_str
|
||||
//
|
||||
// Optimized for: all structurally valid and no byte copying is done.
|
||||
//
|
||||
LIBPROTOBUF_EXPORT char* UTF8CoerceToStructurallyValid(
|
||||
const StringPiece& str, char* dst, char replace_char);
|
||||
|
||||
} // namespace internal
|
||||
|
||||
|
||||
|
@ -143,6 +143,21 @@
|
||||
# define GOOGLE_PROTOBUF_HASH_SET_CLASS unordered_set
|
||||
#endif
|
||||
|
||||
#ifndef GOOGLE_PROTOBUF_HASH_NAMESPACE
|
||||
# define GOOGLE_PROTOBUF_HASH_NAMESPACE_DECLARATION_START
|
||||
# define GOOGLE_PROTOBUF_HASH_NAMESPACE_DECLARATION_END
|
||||
#elif !defined(GOOGLE_PROTOBUF_HAS_CXX11_HASH) && \
|
||||
defined(GOOGLE_PROTOBUF_HAS_TR1)
|
||||
# define GOOGLE_PROTOBUF_HASH_NAMESPACE_DECLARATION_START \
|
||||
namespace std { \
|
||||
namespace tr1 {
|
||||
# define GOOGLE_PROTOBUF_HASH_NAMESPACE_DECLARATION_END }}
|
||||
#else
|
||||
# define GOOGLE_PROTOBUF_HASH_NAMESPACE_DECLARATION_START \
|
||||
namespace GOOGLE_PROTOBUF_HASH_NAMESPACE {
|
||||
# define GOOGLE_PROTOBUF_HASH_NAMESPACE_DECLARATION_END }
|
||||
#endif
|
||||
|
||||
#undef GOOGLE_PROTOBUF_HAS_CXX11_HASH
|
||||
#undef GOOGLE_PROTOBUF_HAS_TR1
|
||||
|
||||
|
200
src/google/protobuf/stubs/int128.cc
Normal file
200
src/google/protobuf/stubs/int128.cc
Normal file
@ -0,0 +1,200 @@
|
||||
// Protocol Buffers - Google's data interchange format
|
||||
// Copyright 2008 Google Inc. All rights reserved.
|
||||
// https://developers.google.com/protocol-buffers/
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
#include <google/protobuf/stubs/int128.h>
|
||||
|
||||
#include <iomanip>
|
||||
#include <iostream> // NOLINT(readability/streams)
|
||||
#include <sstream>
|
||||
|
||||
namespace google {
|
||||
namespace protobuf {
|
||||
|
||||
const uint128_pod kuint128max = {
|
||||
static_cast<uint64>(GOOGLE_LONGLONG(0xFFFFFFFFFFFFFFFF)),
|
||||
static_cast<uint64>(GOOGLE_LONGLONG(0xFFFFFFFFFFFFFFFF))
|
||||
};
|
||||
|
||||
// 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.
|
||||
//
|
||||
// For example:
|
||||
// Given: 5 (decimal) == 101 (binary)
|
||||
// Returns: 2
|
||||
#define STEP(T, n, pos, sh) \
|
||||
do { \
|
||||
if ((n) >= (static_cast<T>(1) << (sh))) { \
|
||||
(n) = (n) >> (sh); \
|
||||
(pos) |= (sh); \
|
||||
} \
|
||||
} while (0)
|
||||
static inline int Fls64(uint64 n) {
|
||||
GOOGLE_DCHECK_NE(0, n);
|
||||
int pos = 0;
|
||||
STEP(uint64, n, pos, 0x20);
|
||||
uint32 n32 = n;
|
||||
STEP(uint32, n32, pos, 0x10);
|
||||
STEP(uint32, n32, pos, 0x08);
|
||||
STEP(uint32, n32, pos, 0x04);
|
||||
return pos + ((GOOGLE_ULONGLONG(0x3333333322221100) >> (n32 << 2)) & 0x3);
|
||||
}
|
||||
#undef STEP
|
||||
|
||||
// Like Fls64() above, but returns the 0-based position of the last set bit
|
||||
// (i.e., most significant bit) in the given uint128. The argument may not be 0.
|
||||
static inline int Fls128(uint128 n) {
|
||||
if (uint64 hi = Uint128High64(n)) {
|
||||
return Fls64(hi) + 64;
|
||||
}
|
||||
return Fls64(Uint128Low64(n));
|
||||
}
|
||||
|
||||
// Long division/modulo for uint128 implemented using the shift-subtract
|
||||
// division algorithm adapted from:
|
||||
// http://stackoverflow.com/questions/5386377/division-without-using
|
||||
void uint128::DivModImpl(uint128 dividend, uint128 divisor,
|
||||
uint128* quotient_ret, uint128* remainder_ret) {
|
||||
if (divisor == 0) {
|
||||
GOOGLE_LOG(FATAL) << "Division or mod by zero: dividend.hi=" << dividend.hi_
|
||||
<< ", lo=" << dividend.lo_;
|
||||
}
|
||||
|
||||
if (divisor > dividend) {
|
||||
*quotient_ret = 0;
|
||||
*remainder_ret = dividend;
|
||||
return;
|
||||
}
|
||||
|
||||
if (divisor == dividend) {
|
||||
*quotient_ret = 1;
|
||||
*remainder_ret = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
uint128 denominator = divisor;
|
||||
uint128 position = 1;
|
||||
uint128 quotient = 0;
|
||||
|
||||
// Left aligns the MSB of the denominator and the dividend.
|
||||
int shift = Fls128(dividend) - Fls128(denominator);
|
||||
denominator <<= shift;
|
||||
position <<= shift;
|
||||
|
||||
// Uses shift-subtract algorithm to divide dividend by denominator. The
|
||||
// remainder will be left in dividend.
|
||||
while (position > 0) {
|
||||
if (dividend >= denominator) {
|
||||
dividend -= denominator;
|
||||
quotient |= position;
|
||||
}
|
||||
position >>= 1;
|
||||
denominator >>= 1;
|
||||
}
|
||||
|
||||
*quotient_ret = quotient;
|
||||
*remainder_ret = dividend;
|
||||
}
|
||||
|
||||
uint128& uint128::operator/=(const uint128& divisor) {
|
||||
uint128 quotient = 0;
|
||||
uint128 remainder = 0;
|
||||
DivModImpl(*this, divisor, "ient, &remainder);
|
||||
*this = quotient;
|
||||
return *this;
|
||||
}
|
||||
uint128& uint128::operator%=(const uint128& divisor) {
|
||||
uint128 quotient = 0;
|
||||
uint128 remainder = 0;
|
||||
DivModImpl(*this, divisor, "ient, &remainder);
|
||||
*this = remainder;
|
||||
return *this;
|
||||
}
|
||||
|
||||
std::ostream& operator<<(std::ostream& o, const uint128& b) {
|
||||
std::ios_base::fmtflags flags = o.flags();
|
||||
|
||||
// Select a divisor which is the largest power of the base < 2^64.
|
||||
uint128 div;
|
||||
std::streamsize div_base_log;
|
||||
switch (flags & std::ios::basefield) {
|
||||
case std::ios::hex:
|
||||
div = GOOGLE_ULONGLONG(0x1000000000000000); // 16^15
|
||||
div_base_log = 15;
|
||||
break;
|
||||
case std::ios::oct:
|
||||
div = GOOGLE_ULONGLONG(01000000000000000000000); // 8^21
|
||||
div_base_log = 21;
|
||||
break;
|
||||
default: // std::ios::dec
|
||||
div = GOOGLE_ULONGLONG(10000000000000000000); // 10^19
|
||||
div_base_log = 19;
|
||||
break;
|
||||
}
|
||||
|
||||
// Now piece together the uint128 representation from three chunks of
|
||||
// the original value, each less than "div" and therefore representable
|
||||
// as a uint64.
|
||||
std::ostringstream os;
|
||||
std::ios_base::fmtflags copy_mask =
|
||||
std::ios::basefield | std::ios::showbase | std::ios::uppercase;
|
||||
os.setf(flags & copy_mask, copy_mask);
|
||||
uint128 high = b;
|
||||
uint128 low;
|
||||
uint128::DivModImpl(high, div, &high, &low);
|
||||
uint128 mid;
|
||||
uint128::DivModImpl(high, div, &high, &mid);
|
||||
if (high.lo_ != 0) {
|
||||
os << high.lo_;
|
||||
os << std::noshowbase << std::setfill('0') << std::setw(div_base_log);
|
||||
os << mid.lo_;
|
||||
os << std::setw(div_base_log);
|
||||
} else if (mid.lo_ != 0) {
|
||||
os << mid.lo_;
|
||||
os << std::noshowbase << std::setfill('0') << std::setw(div_base_log);
|
||||
}
|
||||
os << low.lo_;
|
||||
std::string rep = os.str();
|
||||
|
||||
// Add the requisite padding.
|
||||
std::streamsize width = o.width(0);
|
||||
if (width > rep.size()) {
|
||||
if ((flags & std::ios::adjustfield) == std::ios::left) {
|
||||
rep.append(width - rep.size(), o.fill());
|
||||
} else {
|
||||
rep.insert(0, width - rep.size(), o.fill());
|
||||
}
|
||||
}
|
||||
|
||||
// Stream the final representation in a single "<<" call.
|
||||
return o << rep;
|
||||
}
|
||||
|
||||
} // namespace protobuf
|
||||
} // namespace google
|
381
src/google/protobuf/stubs/int128.h
Normal file
381
src/google/protobuf/stubs/int128.h
Normal file
@ -0,0 +1,381 @@
|
||||
// Protocol Buffers - Google's data interchange format
|
||||
// Copyright 2008 Google Inc. All rights reserved.
|
||||
// https://developers.google.com/protocol-buffers/
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
#ifndef GOOGLE_PROTOBUF_STUBS_INT128_H_
|
||||
#define GOOGLE_PROTOBUF_STUBS_INT128_H_
|
||||
|
||||
#include <google/protobuf/stubs/common.h>
|
||||
|
||||
#include <iosfwd>
|
||||
|
||||
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
|
||||
|
||||
// An unsigned 128-bit integer type. Thread-compatible.
|
||||
class uint128 {
|
||||
public:
|
||||
UINT128_CONSTEXPR uint128(); // Sets to 0, but don't trust on this behavior.
|
||||
UINT128_CONSTEXPR uint128(uint64 top, uint64 bottom);
|
||||
#ifndef SWIG
|
||||
UINT128_CONSTEXPR uint128(int bottom);
|
||||
UINT128_CONSTEXPR uint128(uint32 bottom); // Top 96 bits = 0
|
||||
#endif
|
||||
UINT128_CONSTEXPR uint128(uint64 bottom); // hi_ = 0
|
||||
UINT128_CONSTEXPR uint128(const uint128_pod &val);
|
||||
|
||||
// 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);
|
||||
uint128& operator*=(const uint128& b);
|
||||
// Long division/modulo for uint128.
|
||||
uint128& operator/=(const uint128& b);
|
||||
uint128& operator%=(const uint128& b);
|
||||
uint128 operator++(int);
|
||||
uint128 operator--(int);
|
||||
uint128& operator<<=(int);
|
||||
uint128& operator>>=(int);
|
||||
uint128& operator&=(const uint128& b);
|
||||
uint128& operator|=(const uint128& b);
|
||||
uint128& operator^=(const uint128& b);
|
||||
uint128& operator++();
|
||||
uint128& operator--();
|
||||
|
||||
friend uint64 Uint128Low64(const uint128& v);
|
||||
friend uint64 Uint128High64(const uint128& v);
|
||||
|
||||
// We add "std::" to avoid including all of port.h.
|
||||
friend std::ostream& operator<<(std::ostream& o, const uint128& b);
|
||||
|
||||
private:
|
||||
static void DivModImpl(uint128 dividend, uint128 divisor,
|
||||
uint128* quotient_ret, uint128* remainder_ret);
|
||||
|
||||
// Little-endian memory order optimizations can benefit from
|
||||
// having lo_ first, hi_ last.
|
||||
// See util/endian/endian.h and Load128/Store128 for storing a uint128.
|
||||
uint64 lo_;
|
||||
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;
|
||||
};
|
||||
|
||||
extern const uint128_pod kuint128max;
|
||||
|
||||
// allow uint128 to be logged
|
||||
extern std::ostream& operator<<(std::ostream& o, const uint128& b);
|
||||
|
||||
// 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_; }
|
||||
|
||||
// TODO: perhaps it would be nice to have int128, a signed 128-bit type?
|
||||
|
||||
// --------------------------------------------------------------------------
|
||||
// Implementation details follow
|
||||
// --------------------------------------------------------------------------
|
||||
inline bool operator==(const uint128& lhs, const uint128& rhs) {
|
||||
return (Uint128Low64(lhs) == Uint128Low64(rhs) &&
|
||||
Uint128High64(lhs) == Uint128High64(rhs));
|
||||
}
|
||||
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)
|
||||
: 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)
|
||||
: lo_(bottom), hi_(0) {}
|
||||
#ifndef SWIG
|
||||
inline UINT128_CONSTEXPR uint128::uint128(uint32 bottom)
|
||||
: lo_(bottom), hi_(0) {}
|
||||
inline UINT128_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) \
|
||||
inline bool operator op(const uint128& lhs, const uint128& rhs) { \
|
||||
return (Uint128High64(lhs) == Uint128High64(rhs)) ? \
|
||||
(Uint128Low64(lhs) op Uint128Low64(rhs)) : \
|
||||
(Uint128High64(lhs) op Uint128High64(rhs)); \
|
||||
}
|
||||
|
||||
CMP128(<)
|
||||
CMP128(>)
|
||||
CMP128(>=)
|
||||
CMP128(<=)
|
||||
|
||||
#undef CMP128
|
||||
|
||||
// Unary operators
|
||||
|
||||
inline uint128 operator-(const uint128& val) {
|
||||
const uint64 hi_flip = ~Uint128High64(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 uint128(hi_flip, lo_add);
|
||||
}
|
||||
|
||||
inline bool operator!(const uint128& val) {
|
||||
return !Uint128High64(val) && !Uint128Low64(val);
|
||||
}
|
||||
|
||||
// Logical operators.
|
||||
|
||||
inline uint128 operator~(const uint128& val) {
|
||||
return uint128(~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)); \
|
||||
}
|
||||
|
||||
LOGIC128(|)
|
||||
LOGIC128(&)
|
||||
LOGIC128(^)
|
||||
|
||||
#undef LOGIC128
|
||||
|
||||
#define LOGICASSIGN128(op) \
|
||||
inline uint128& uint128::operator op(const uint128& other) { \
|
||||
hi_ op other.hi_; \
|
||||
lo_ op other.lo_; \
|
||||
return *this; \
|
||||
}
|
||||
|
||||
LOGICASSIGN128(|=)
|
||||
LOGICASSIGN128(&=)
|
||||
LOGICASSIGN128(^=)
|
||||
|
||||
#undef LOGICASSIGN128
|
||||
|
||||
// Shift operators.
|
||||
|
||||
inline uint128 operator<<(const uint128& val, int amount) {
|
||||
// uint64 shifts of >= 64 are undefined, so we will need some special-casing.
|
||||
if (amount < 64) {
|
||||
if (amount == 0) {
|
||||
return val;
|
||||
}
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
inline uint128 operator>>(const uint128& val, int amount) {
|
||||
// uint64 shifts of >= 64 are undefined, so we will need some special-casing.
|
||||
if (amount < 64) {
|
||||
if (amount == 0) {
|
||||
return val;
|
||||
}
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
inline uint128& uint128::operator<<=(int amount) {
|
||||
// uint64 shifts of >= 64 are undefined, so we will need some special-casing.
|
||||
if (amount < 64) {
|
||||
if (amount != 0) {
|
||||
hi_ = (hi_ << amount) | (lo_ >> (64 - amount));
|
||||
lo_ = lo_ << amount;
|
||||
}
|
||||
} else if (amount < 128) {
|
||||
hi_ = lo_ << (amount - 64);
|
||||
lo_ = 0;
|
||||
} else {
|
||||
hi_ = 0;
|
||||
lo_ = 0;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline uint128& uint128::operator>>=(int amount) {
|
||||
// uint64 shifts of >= 64 are undefined, so we will need some special-casing.
|
||||
if (amount < 64) {
|
||||
if (amount != 0) {
|
||||
lo_ = (lo_ >> amount) | (hi_ << (64 - amount));
|
||||
hi_ = hi_ >> amount;
|
||||
}
|
||||
} else if (amount < 128) {
|
||||
lo_ = hi_ >> (amount - 64);
|
||||
hi_ = 0;
|
||||
} else {
|
||||
lo_ = 0;
|
||||
hi_ = 0;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline uint128 operator+(const uint128& lhs, const uint128& rhs) {
|
||||
return uint128(lhs) += rhs;
|
||||
}
|
||||
|
||||
inline uint128 operator-(const uint128& lhs, const uint128& rhs) {
|
||||
return uint128(lhs) -= rhs;
|
||||
}
|
||||
|
||||
inline uint128 operator*(const uint128& lhs, const uint128& rhs) {
|
||||
return uint128(lhs) *= rhs;
|
||||
}
|
||||
|
||||
inline uint128 operator/(const uint128& lhs, const uint128& rhs) {
|
||||
return uint128(lhs) /= rhs;
|
||||
}
|
||||
|
||||
inline uint128 operator%(const uint128& lhs, const uint128& rhs) {
|
||||
return uint128(lhs) %= rhs;
|
||||
}
|
||||
|
||||
inline uint128& uint128::operator+=(const uint128& b) {
|
||||
hi_ += b.hi_;
|
||||
uint64 lolo = lo_ + b.lo_;
|
||||
if (lolo < lo_)
|
||||
++hi_;
|
||||
lo_ = lolo;
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline uint128& uint128::operator-=(const uint128& b) {
|
||||
hi_ -= b.hi_;
|
||||
if (b.lo_ > lo_)
|
||||
--hi_;
|
||||
lo_ -= b.lo_;
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline uint128& uint128::operator*=(const uint128& b) {
|
||||
uint64 a96 = hi_ >> 32;
|
||||
uint64 a64 = hi_ & 0xffffffffu;
|
||||
uint64 a32 = lo_ >> 32;
|
||||
uint64 a00 = lo_ & 0xffffffffu;
|
||||
uint64 b96 = b.hi_ >> 32;
|
||||
uint64 b64 = b.hi_ & 0xffffffffu;
|
||||
uint64 b32 = b.lo_ >> 32;
|
||||
uint64 b00 = b.lo_ & 0xffffffffu;
|
||||
// multiply [a96 .. a00] x [b96 .. b00]
|
||||
// terms higher than c96 disappear off the high side
|
||||
// terms c96 and c64 are safe to ignore carry bit
|
||||
uint64 c96 = a96 * b00 + a64 * b32 + a32 * b64 + a00 * b96;
|
||||
uint64 c64 = a64 * b00 + a32 * b32 + a00 * b64;
|
||||
this->hi_ = (c96 << 32) + c64;
|
||||
this->lo_ = 0;
|
||||
// add terms after this one at a time to capture carry
|
||||
*this += uint128(a32 * b00) << 32;
|
||||
*this += uint128(a00 * b32) << 32;
|
||||
*this += a00 * b00;
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline uint128 uint128::operator++(int) {
|
||||
uint128 tmp(*this);
|
||||
*this += 1;
|
||||
return tmp;
|
||||
}
|
||||
|
||||
inline uint128 uint128::operator--(int) {
|
||||
uint128 tmp(*this);
|
||||
*this -= 1;
|
||||
return tmp;
|
||||
}
|
||||
|
||||
inline uint128& uint128::operator++() {
|
||||
*this += 1;
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline uint128& uint128::operator--() {
|
||||
*this -= 1;
|
||||
return *this;
|
||||
}
|
||||
|
||||
} // namespace protobuf
|
||||
} // namespace google
|
||||
|
||||
#endif // GOOGLE_PROTOBUF_STUBS_INT128_H_
|
513
src/google/protobuf/stubs/int128_unittest.cc
Normal file
513
src/google/protobuf/stubs/int128_unittest.cc
Normal file
@ -0,0 +1,513 @@
|
||||
// Protocol Buffers - Google's data interchange format
|
||||
// Copyright 2008 Google Inc. All rights reserved.
|
||||
// https://developers.google.com/protocol-buffers/
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
#include <google/protobuf/stubs/int128.h>
|
||||
|
||||
#include <algorithm>
|
||||
#include <sstream>
|
||||
#include <utility>
|
||||
|
||||
#include <google/protobuf/testing/googletest.h>
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
namespace google {
|
||||
namespace protobuf {
|
||||
|
||||
TEST(Int128, AllTests) {
|
||||
uint128 zero(0);
|
||||
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);
|
||||
EXPECT_LT(one, two);
|
||||
EXPECT_GT(two, one);
|
||||
EXPECT_LT(one, big);
|
||||
EXPECT_LT(one, big);
|
||||
EXPECT_EQ(one, one_2arg);
|
||||
EXPECT_NE(one, two);
|
||||
EXPECT_GT(big, one);
|
||||
EXPECT_GE(big, two);
|
||||
EXPECT_GE(big, big_minus_one);
|
||||
EXPECT_GT(big, big_minus_one);
|
||||
EXPECT_LT(big_minus_one, big);
|
||||
EXPECT_LE(big_minus_one, big);
|
||||
EXPECT_NE(big_minus_one, big);
|
||||
EXPECT_LT(big, biggest);
|
||||
EXPECT_LE(big, biggest);
|
||||
EXPECT_GT(biggest, big);
|
||||
EXPECT_GE(biggest, big);
|
||||
EXPECT_EQ(big, ~~big);
|
||||
EXPECT_EQ(one, one | one);
|
||||
EXPECT_EQ(big, big | big);
|
||||
EXPECT_EQ(one, one | zero);
|
||||
EXPECT_EQ(one, one & one);
|
||||
EXPECT_EQ(big, big & big);
|
||||
EXPECT_EQ(zero, one & zero);
|
||||
EXPECT_EQ(zero, big & ~big);
|
||||
EXPECT_EQ(zero, one ^ one);
|
||||
EXPECT_EQ(zero, big ^ big);
|
||||
EXPECT_EQ(one, one ^ zero);
|
||||
|
||||
// Shift operators.
|
||||
EXPECT_EQ(big, big << 0);
|
||||
EXPECT_EQ(big, big >> 0);
|
||||
EXPECT_GT(big << 1, big);
|
||||
EXPECT_LT(big >> 1, big);
|
||||
EXPECT_EQ(big, (big << 10) >> 10);
|
||||
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;
|
||||
EXPECT_EQ(big << 0, big_copy <<= 0);
|
||||
big_copy = big;
|
||||
EXPECT_EQ(big >> 0, big_copy >>= 0);
|
||||
big_copy = big;
|
||||
EXPECT_EQ(big << 1, big_copy <<= 1);
|
||||
big_copy = big;
|
||||
EXPECT_EQ(big >> 1, big_copy >>= 1);
|
||||
big_copy = big;
|
||||
EXPECT_EQ(big << 10, big_copy <<= 10);
|
||||
big_copy = big;
|
||||
EXPECT_EQ(big >> 10, big_copy >>= 10);
|
||||
big_copy = big;
|
||||
EXPECT_EQ(big << 64, big_copy <<= 64);
|
||||
big_copy = big;
|
||||
EXPECT_EQ(big >> 64, big_copy >>= 64);
|
||||
big_copy = big;
|
||||
EXPECT_EQ(big << 73, big_copy <<= 73);
|
||||
big_copy = big;
|
||||
EXPECT_EQ(big >> 73, big_copy >>= 73);
|
||||
big_copy = big;
|
||||
EXPECT_EQ(big << 128, big_copy <<= 128);
|
||||
big_copy = big;
|
||||
EXPECT_EQ(big >> 128, big_copy >>= 128);
|
||||
|
||||
EXPECT_EQ(Uint128High64(biggest), kuint64max);
|
||||
EXPECT_EQ(Uint128Low64(biggest), kuint64max);
|
||||
EXPECT_EQ(zero + one, one);
|
||||
EXPECT_EQ(one + one, two);
|
||||
EXPECT_EQ(big_minus_one + one, big);
|
||||
EXPECT_EQ(one - one, zero);
|
||||
EXPECT_EQ(one - zero, one);
|
||||
EXPECT_EQ(zero - one, biggest);
|
||||
EXPECT_EQ(big - big, zero);
|
||||
EXPECT_EQ(big - one, big_minus_one);
|
||||
EXPECT_EQ(big + kuint64max, bigger);
|
||||
EXPECT_EQ(biggest + 1, zero);
|
||||
EXPECT_EQ(zero - 1, biggest);
|
||||
EXPECT_EQ(high_low - one, low_high);
|
||||
EXPECT_EQ(low_high + one, high_low);
|
||||
EXPECT_EQ(Uint128High64((uint128(1) << 64) - 1), 0);
|
||||
EXPECT_EQ(Uint128Low64((uint128(1) << 64) - 1), kuint64max);
|
||||
EXPECT_TRUE(!!one);
|
||||
EXPECT_TRUE(!!high_low);
|
||||
EXPECT_FALSE(!!zero);
|
||||
EXPECT_FALSE(!one);
|
||||
EXPECT_FALSE(!high_low);
|
||||
EXPECT_TRUE(!zero);
|
||||
EXPECT_TRUE(zero == 0);
|
||||
EXPECT_FALSE(zero != 0);
|
||||
EXPECT_FALSE(one == 0);
|
||||
EXPECT_TRUE(one != 0);
|
||||
|
||||
uint128 test = zero;
|
||||
EXPECT_EQ(++test, one);
|
||||
EXPECT_EQ(test, one);
|
||||
EXPECT_EQ(test++, one);
|
||||
EXPECT_EQ(test, two);
|
||||
EXPECT_EQ(test -= 2, zero);
|
||||
EXPECT_EQ(test, zero);
|
||||
EXPECT_EQ(test += 2, two);
|
||||
EXPECT_EQ(test, two);
|
||||
EXPECT_EQ(--test, one);
|
||||
EXPECT_EQ(test, one);
|
||||
EXPECT_EQ(test--, one);
|
||||
EXPECT_EQ(test, zero);
|
||||
EXPECT_EQ(test |= three, three);
|
||||
EXPECT_EQ(test &= one, one);
|
||||
EXPECT_EQ(test ^= three, two);
|
||||
EXPECT_EQ(test >>= 1, one);
|
||||
EXPECT_EQ(test <<= 1, two);
|
||||
|
||||
EXPECT_EQ(big, -(-big));
|
||||
EXPECT_EQ(two, -((-one) - 1));
|
||||
EXPECT_EQ(kuint128max, -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;
|
||||
EXPECT_EQ(2, v);
|
||||
}
|
||||
|
||||
TEST(Int128, Multiply) {
|
||||
uint128 a, b, c;
|
||||
|
||||
// Zero test.
|
||||
a = 0;
|
||||
b = 0;
|
||||
c = a * b;
|
||||
EXPECT_EQ(0, c);
|
||||
|
||||
// Max carries.
|
||||
a = uint128(0) - 1;
|
||||
b = uint128(0) - 1;
|
||||
c = a * b;
|
||||
EXPECT_EQ(1, c);
|
||||
|
||||
// Self-operation with max carries.
|
||||
c = uint128(0) - 1;
|
||||
c *= c;
|
||||
EXPECT_EQ(1, c);
|
||||
|
||||
// 1-bit x 1-bit.
|
||||
for (int i = 0; i < 64; ++i) {
|
||||
for (int j = 0; j < 64; ++j) {
|
||||
a = uint128(1) << i;
|
||||
b = uint128(1) << j;
|
||||
c = a * b;
|
||||
EXPECT_EQ(uint128(1) << (i+j), c);
|
||||
}
|
||||
}
|
||||
|
||||
// Verified with dc.
|
||||
a = uint128(GOOGLE_ULONGLONG(0xffffeeeeddddcccc),
|
||||
GOOGLE_ULONGLONG(0xbbbbaaaa99998888));
|
||||
b = uint128(GOOGLE_ULONGLONG(0x7777666655554444),
|
||||
GOOGLE_ULONGLONG(0x3333222211110000));
|
||||
c = a * b;
|
||||
EXPECT_EQ(uint128(GOOGLE_ULONGLONG(0x530EDA741C71D4C3),
|
||||
GOOGLE_ULONGLONG(0xBF25975319080000)), c);
|
||||
EXPECT_EQ(0, c - b * a);
|
||||
EXPECT_EQ(a*a - b*b, (a+b) * (a-b));
|
||||
|
||||
// Verified with dc.
|
||||
a = uint128(GOOGLE_ULONGLONG(0x0123456789abcdef),
|
||||
GOOGLE_ULONGLONG(0xfedcba9876543210));
|
||||
b = uint128(GOOGLE_ULONGLONG(0x02468ace13579bdf),
|
||||
GOOGLE_ULONGLONG(0xfdb97531eca86420));
|
||||
c = a * b;
|
||||
EXPECT_EQ(uint128(GOOGLE_ULONGLONG(0x97a87f4f261ba3f2),
|
||||
GOOGLE_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);
|
||||
x1 += x1;
|
||||
EXPECT_EQ(x2, x1);
|
||||
|
||||
uint128 x3(1, static_cast<uint64>(1) << 63);
|
||||
uint128 x4(3, 0);
|
||||
x3 += x3;
|
||||
EXPECT_EQ(x4, x3);
|
||||
}
|
||||
|
||||
#ifdef PROTOBUF_HAS_DEATH_TEST
|
||||
TEST(Int128, DivideByZeroCheckFails) {
|
||||
uint128 a = 0;
|
||||
uint128 b = 0;
|
||||
EXPECT_DEATH(a / b, "Division or mod by zero:");
|
||||
a = 123;
|
||||
EXPECT_DEATH(a / b, "Division or mod by zero:");
|
||||
}
|
||||
|
||||
TEST(Int128, ModByZeroCheckFails) {
|
||||
uint128 a = 0;
|
||||
uint128 b = 0;
|
||||
EXPECT_DEATH(a % b, "Division or mod by zero:");
|
||||
a = 123;
|
||||
EXPECT_DEATH(a % b, "Division or mod by zero:");
|
||||
}
|
||||
#endif // PROTOBUF_HAS_DEATH_TEST
|
||||
|
||||
TEST(Int128, DivideAndMod) {
|
||||
// a := q * b + r
|
||||
uint128 a, b, q, r;
|
||||
|
||||
// Zero test.
|
||||
a = 0;
|
||||
b = 123;
|
||||
q = a / b;
|
||||
r = a % b;
|
||||
EXPECT_EQ(0, q);
|
||||
EXPECT_EQ(0, r);
|
||||
|
||||
a = uint128(GOOGLE_ULONGLONG(0x530eda741c71d4c3),
|
||||
GOOGLE_ULONGLONG(0xbf25975319080000));
|
||||
q = uint128(GOOGLE_ULONGLONG(0x4de2cab081),
|
||||
GOOGLE_ULONGLONG(0x14c34ab4676e4bab));
|
||||
b = uint128(0x1110001);
|
||||
r = uint128(0x3eb455);
|
||||
ASSERT_EQ(a, q * b + r); // Sanity-check.
|
||||
|
||||
uint128 result_q, result_r;
|
||||
result_q = a / b;
|
||||
result_r = a % b;
|
||||
EXPECT_EQ(q, result_q);
|
||||
EXPECT_EQ(r, result_r);
|
||||
|
||||
// Try the other way around.
|
||||
swap(q, b);
|
||||
result_q = a / b;
|
||||
result_r = a % b;
|
||||
EXPECT_EQ(q, result_q);
|
||||
EXPECT_EQ(r, result_r);
|
||||
// Restore.
|
||||
swap(b, q);
|
||||
|
||||
// Dividend < divisor; result should be q:0 r:<dividend>.
|
||||
swap(a, b);
|
||||
result_q = a / b;
|
||||
result_r = a % b;
|
||||
EXPECT_EQ(0, result_q);
|
||||
EXPECT_EQ(a, result_r);
|
||||
// Try the other way around.
|
||||
swap(a, q);
|
||||
result_q = a / b;
|
||||
result_r = a % b;
|
||||
EXPECT_EQ(0, result_q);
|
||||
EXPECT_EQ(a, result_r);
|
||||
// Restore.
|
||||
swap(q, a);
|
||||
swap(b, a);
|
||||
|
||||
// Try a large remainder.
|
||||
b = a / 2 + 1;
|
||||
uint128 expected_r(GOOGLE_ULONGLONG(0x29876d3a0e38ea61),
|
||||
GOOGLE_ULONGLONG(0xdf92cba98c83ffff));
|
||||
// Sanity checks.
|
||||
ASSERT_EQ(a / 2 - 1, expected_r);
|
||||
ASSERT_EQ(a, b + expected_r);
|
||||
result_q = a / b;
|
||||
result_r = a % b;
|
||||
EXPECT_EQ(1, result_q);
|
||||
EXPECT_EQ(expected_r, result_r);
|
||||
}
|
||||
|
||||
static uint64 RandomUint64() {
|
||||
uint64 v1 = rand();
|
||||
uint64 v2 = rand();
|
||||
uint64 v3 = rand();
|
||||
return v1 * v2 + v3;
|
||||
}
|
||||
|
||||
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());
|
||||
if (b == 0) {
|
||||
continue; // Avoid a div-by-zero.
|
||||
}
|
||||
const uint128 q = a / b;
|
||||
const uint128 r = a % b;
|
||||
ASSERT_EQ(a, b * q + r);
|
||||
}
|
||||
}
|
||||
|
||||
#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));
|
||||
}
|
||||
|
||||
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
|
||||
|
||||
TEST(Int128, OStream) {
|
||||
struct {
|
||||
uint128 val;
|
||||
std::ios_base::fmtflags flags;
|
||||
std::streamsize width;
|
||||
char fill;
|
||||
const char* rep;
|
||||
} cases[] = {
|
||||
// zero with different bases
|
||||
{uint128(0), std::ios::dec, 0, '_', "0"},
|
||||
{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"},
|
||||
// just the top bit
|
||||
{uint128(GOOGLE_ULONGLONG(0x8000000000000000), 0), std::ios::dec, 0, '_',
|
||||
"170141183460469231731687303715884105728"},
|
||||
{uint128(GOOGLE_ULONGLONG(0x8000000000000000), 0), std::ios::oct, 0, '_',
|
||||
"2000000000000000000000000000000000000000000"},
|
||||
{uint128(GOOGLE_ULONGLONG(0x8000000000000000), 0), std::ios::hex, 0, '_',
|
||||
"80000000000000000000000000000000"},
|
||||
// maximum uint128 value
|
||||
{uint128(-1, -1), std::ios::dec, 0, '_',
|
||||
"340282366920938463463374607431768211455"},
|
||||
{uint128(-1, -1), std::ios::oct, 0, '_',
|
||||
"3777777777777777777777777777777777777777777"},
|
||||
{uint128(-1, -1), std::ios::hex, 0, '_',
|
||||
"ffffffffffffffffffffffffffffffff"},
|
||||
// uppercase
|
||||
{uint128(-1, -1), std::ios::hex | std::ios::uppercase, 0, '_',
|
||||
"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"},
|
||||
// showbase
|
||||
{uint128(1), std::ios::dec | std::ios::showbase, 0, '_', "1"},
|
||||
{uint128(1), std::ios::oct | std::ios::showbase, 0, '_', "01"},
|
||||
{uint128(1), std::ios::hex | std::ios::showbase, 0, '_', "0x1"},
|
||||
// showbase does nothing on zero
|
||||
{uint128(0), std::ios::dec | std::ios::showbase, 0, '_', "0"},
|
||||
{uint128(0), std::ios::oct | std::ios::showbase, 0, '_', "0"},
|
||||
{uint128(0), std::ios::hex | std::ios::showbase, 0, '_', "0"},
|
||||
// showpos does nothing on unsigned types
|
||||
{uint128(1), std::ios::dec | std::ios::showpos, 0, '_', "1"},
|
||||
// padding
|
||||
{uint128(9), std::ios::dec, 6, '_', "_____9"},
|
||||
{uint128(12345), std::ios::dec, 6, '_', "_12345"},
|
||||
// left adjustment
|
||||
{uint128(9), std::ios::dec | std::ios::left, 6, '_', "9_____"},
|
||||
{uint128(12345), std::ios::dec | std::ios::left, 6, '_', "12345_"},
|
||||
};
|
||||
for (size_t i = 0; i < GOOGLE_ARRAYSIZE(cases); ++i) {
|
||||
ostringstream os;
|
||||
os.flags(cases[i].flags);
|
||||
os.width(cases[i].width);
|
||||
os.fill(cases[i].fill);
|
||||
os << cases[i].val;
|
||||
EXPECT_EQ(cases[i].rep, os.str());
|
||||
}
|
||||
}
|
||||
} // namespace protobuf
|
||||
} // namespace google
|
@ -65,6 +65,7 @@ class StringPiece;
|
||||
namespace util {
|
||||
class Status;
|
||||
}
|
||||
class uint128;
|
||||
namespace internal {
|
||||
|
||||
class LogFinisher;
|
||||
@ -78,7 +79,7 @@ class LIBPROTOBUF_EXPORT LogMessage {
|
||||
LogMessage& operator<<(const char* value);
|
||||
LogMessage& operator<<(char value);
|
||||
LogMessage& operator<<(int value);
|
||||
LogMessage& operator<<(unsigned int value);
|
||||
LogMessage& operator<<(uint value);
|
||||
LogMessage& operator<<(long value);
|
||||
LogMessage& operator<<(unsigned long value);
|
||||
LogMessage& operator<<(long long value);
|
||||
@ -87,6 +88,7 @@ class LIBPROTOBUF_EXPORT LogMessage {
|
||||
LogMessage& operator<<(void* value);
|
||||
LogMessage& operator<<(const StringPiece& value);
|
||||
LogMessage& operator<<(const ::google::protobuf::util::Status& status);
|
||||
LogMessage& operator<<(const uint128& value);
|
||||
|
||||
private:
|
||||
friend class LogFinisher;
|
||||
|
@ -100,20 +100,12 @@ typedef unsigned __int64 uint64;
|
||||
typedef signed char int8;
|
||||
typedef short int16;
|
||||
typedef int int32;
|
||||
// NOTE: This should be "long long" for consistency with upstream, but
|
||||
// something is stacked against this particular type for 64bit hashing.
|
||||
// Switching it causes an obvious missing hash function (with an unobvious
|
||||
// cause) when building the tests.
|
||||
typedef int64_t int64;
|
||||
typedef long long int64;
|
||||
|
||||
typedef unsigned char uint8;
|
||||
typedef unsigned short uint16;
|
||||
typedef unsigned int uint32;
|
||||
// NOTE: This should be "unsigned long long" for consistency with upstream, but
|
||||
// something is stacked against this particular type for 64bit hashing.
|
||||
// Switching it causes an obvious missing hash function (with an unobvious
|
||||
// cause) when building the tests.
|
||||
typedef uint64_t uint64;
|
||||
typedef unsigned long long uint64;
|
||||
#endif
|
||||
|
||||
// long long macros to be used because gcc and vc++ use different suffixes,
|
||||
|
@ -3,6 +3,8 @@
|
||||
|
||||
#include <google/protobuf/stubs/common.h>
|
||||
|
||||
#include <google/protobuf/stubs/stringpiece.h>
|
||||
|
||||
namespace google {
|
||||
namespace protobuf {
|
||||
namespace internal {
|
||||
@ -531,6 +533,56 @@ bool IsStructurallyValidUTF8(const char* buf, int len) {
|
||||
return (bytes_consumed == len);
|
||||
}
|
||||
|
||||
int UTF8SpnStructurallyValid(const StringPiece& str) {
|
||||
if (!module_initialized_) return str.size();
|
||||
|
||||
int bytes_consumed = 0;
|
||||
UTF8GenericScanFastAscii(&utf8acceptnonsurrogates_obj,
|
||||
str.data(), str.size(), &bytes_consumed);
|
||||
return bytes_consumed;
|
||||
}
|
||||
|
||||
// Coerce UTF-8 byte string in src_str to be
|
||||
// a structurally-valid equal-length string by selectively
|
||||
// overwriting illegal bytes with replace_char (typically blank).
|
||||
// replace_char must be legal printable 7-bit Ascii 0x20..0x7e.
|
||||
// src_str is read-only. If any overwriting is needed, a modified byte string
|
||||
// is created in idst, length isrclen.
|
||||
//
|
||||
// Returns pointer to output buffer, isrc if no changes were made,
|
||||
// or idst if some bytes were changed.
|
||||
//
|
||||
// Fast case: all is structurally valid and no byte copying is done.
|
||||
//
|
||||
char* UTF8CoerceToStructurallyValid(const StringPiece& src_str,
|
||||
char* idst,
|
||||
const char replace_char) {
|
||||
const char* isrc = src_str.data();
|
||||
const int len = src_str.length();
|
||||
int n = UTF8SpnStructurallyValid(src_str);
|
||||
if (n == len) { // Normal case -- all is cool, return
|
||||
return const_cast<char*>(isrc);
|
||||
} else { // Unusual case -- copy w/o bad bytes
|
||||
const char* src = isrc;
|
||||
const char* srclimit = isrc + len;
|
||||
char* dst = idst;
|
||||
memmove(dst, src, n); // Copy initial good chunk
|
||||
src += n;
|
||||
dst += n;
|
||||
while (src < srclimit) { // src points to bogus byte or is off the end
|
||||
dst[0] = replace_char; // replace one bad byte
|
||||
src++;
|
||||
dst++;
|
||||
StringPiece str2(src, srclimit - src);
|
||||
n = UTF8SpnStructurallyValid(str2); // scan the remainder
|
||||
memmove(dst, src, n); // copy next good chunk
|
||||
src += n;
|
||||
dst += n;
|
||||
}
|
||||
}
|
||||
return idst;
|
||||
}
|
||||
|
||||
} // namespace internal
|
||||
} // namespace protobuf
|
||||
} // namespace google
|
||||
|
@ -38,7 +38,6 @@ option java_package = "com.google.protobuf";
|
||||
option csharp_namespace = "Google.ProtocolBuffers";
|
||||
option objc_class_prefix = "GPB";
|
||||
|
||||
|
||||
// A Timestamp represents a point in time independent of any time zone
|
||||
// or calendar, represented as seconds and fractions of seconds at
|
||||
// nanosecond resolution in UTC Epoch time. It is encoded using the
|
||||
@ -85,14 +84,16 @@ option objc_class_prefix = "GPB";
|
||||
// Timestamp timestamp = Timestamp.newBuilder().setSeconds(millis / 1000)
|
||||
// .setNanos((int) ((millis % 1000) * 1000000)).build();
|
||||
//
|
||||
// Example 5: Compute Timestamp from Python `datetime.datetime`.
|
||||
//
|
||||
// now = datetime.datetime.utcnow()
|
||||
// seconds = int(time.mktime(now.timetuple()))
|
||||
// nanos = now.microsecond * 1000
|
||||
// Example 5: Compute Timestamp from current time in Python.
|
||||
//
|
||||
// now = time.time()
|
||||
// seconds = int(now)
|
||||
// nanos = int((now - seconds) * 10**9)
|
||||
// timestamp = Timestamp(seconds=seconds, nanos=nanos)
|
||||
//
|
||||
message Timestamp {
|
||||
|
||||
// Represents seconds of UTC time since Unix epoch
|
||||
// 1970-01-01T00:00:00Z. Must be from from 0001-01-01T00:00:00Z to
|
||||
// 9999-12-31T23:59:59Z inclusive.
|
||||
|
@ -38,6 +38,7 @@ const ::google::protobuf::internal::GeneratedMessageReflection*
|
||||
const ::google::protobuf::Descriptor* Option_descriptor_ = NULL;
|
||||
const ::google::protobuf::internal::GeneratedMessageReflection*
|
||||
Option_reflection_ = NULL;
|
||||
const ::google::protobuf::EnumDescriptor* Syntax_descriptor_ = NULL;
|
||||
|
||||
} // namespace
|
||||
|
||||
@ -49,12 +50,13 @@ void protobuf_AssignDesc_google_2fprotobuf_2ftype_2eproto() {
|
||||
"google/protobuf/type.proto");
|
||||
GOOGLE_CHECK(file != NULL);
|
||||
Type_descriptor_ = file->message_type(0);
|
||||
static const int Type_offsets_[5] = {
|
||||
static const int Type_offsets_[6] = {
|
||||
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Type, name_),
|
||||
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Type, fields_),
|
||||
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Type, oneofs_),
|
||||
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Type, options_),
|
||||
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Type, source_context_),
|
||||
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Type, syntax_),
|
||||
};
|
||||
Type_reflection_ =
|
||||
::google::protobuf::internal::GeneratedMessageReflection::NewGeneratedMessageReflection(
|
||||
@ -68,7 +70,7 @@ void protobuf_AssignDesc_google_2fprotobuf_2ftype_2eproto() {
|
||||
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Type, _internal_metadata_),
|
||||
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Type, _is_default_instance_));
|
||||
Field_descriptor_ = file->message_type(1);
|
||||
static const int Field_offsets_[8] = {
|
||||
static const int Field_offsets_[9] = {
|
||||
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Field, kind_),
|
||||
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Field, cardinality_),
|
||||
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Field, number_),
|
||||
@ -77,6 +79,7 @@ void protobuf_AssignDesc_google_2fprotobuf_2ftype_2eproto() {
|
||||
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Field, oneof_index_),
|
||||
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Field, packed_),
|
||||
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Field, options_),
|
||||
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Field, json_name_),
|
||||
};
|
||||
Field_reflection_ =
|
||||
::google::protobuf::internal::GeneratedMessageReflection::NewGeneratedMessageReflection(
|
||||
@ -92,11 +95,12 @@ void protobuf_AssignDesc_google_2fprotobuf_2ftype_2eproto() {
|
||||
Field_Kind_descriptor_ = Field_descriptor_->enum_type(0);
|
||||
Field_Cardinality_descriptor_ = Field_descriptor_->enum_type(1);
|
||||
Enum_descriptor_ = file->message_type(2);
|
||||
static const int Enum_offsets_[4] = {
|
||||
static const int Enum_offsets_[5] = {
|
||||
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Enum, name_),
|
||||
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Enum, enumvalue_),
|
||||
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Enum, options_),
|
||||
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Enum, source_context_),
|
||||
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Enum, syntax_),
|
||||
};
|
||||
Enum_reflection_ =
|
||||
::google::protobuf::internal::GeneratedMessageReflection::NewGeneratedMessageReflection(
|
||||
@ -142,6 +146,7 @@ void protobuf_AssignDesc_google_2fprotobuf_2ftype_2eproto() {
|
||||
sizeof(Option),
|
||||
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Option, _internal_metadata_),
|
||||
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Option, _is_default_instance_));
|
||||
Syntax_descriptor_ = file->enum_type(0);
|
||||
}
|
||||
|
||||
namespace {
|
||||
@ -192,38 +197,42 @@ void protobuf_AddDesc_google_2fprotobuf_2ftype_2eproto() {
|
||||
::google::protobuf::DescriptorPool::InternalAddGeneratedFile(
|
||||
"\n\032google/protobuf/type.proto\022\017google.pro"
|
||||
"tobuf\032\031google/protobuf/any.proto\032$google"
|
||||
"/protobuf/source_context.proto\"\256\001\n\004Type\022"
|
||||
"/protobuf/source_context.proto\"\327\001\n\004Type\022"
|
||||
"\014\n\004name\030\001 \001(\t\022&\n\006fields\030\002 \003(\0132\026.google.p"
|
||||
"rotobuf.Field\022\016\n\006oneofs\030\003 \003(\t\022(\n\007options"
|
||||
"\030\004 \003(\0132\027.google.protobuf.Option\0226\n\016sourc"
|
||||
"e_context\030\005 \001(\0132\036.google.protobuf.Source"
|
||||
"Context\"\233\005\n\005Field\022)\n\004kind\030\001 \001(\0162\033.google"
|
||||
".protobuf.Field.Kind\0227\n\013cardinality\030\002 \001("
|
||||
"\0162\".google.protobuf.Field.Cardinality\022\016\n"
|
||||
"\006number\030\003 \001(\005\022\014\n\004name\030\004 \001(\t\022\020\n\010type_url\030"
|
||||
"\006 \001(\t\022\023\n\013oneof_index\030\007 \001(\005\022\016\n\006packed\030\010 \001"
|
||||
"(\010\022(\n\007options\030\t \003(\0132\027.google.protobuf.Op"
|
||||
"tion\"\270\002\n\004Kind\022\020\n\014TYPE_UNKNOWN\020\000\022\017\n\013TYPE_"
|
||||
"DOUBLE\020\001\022\016\n\nTYPE_FLOAT\020\002\022\016\n\nTYPE_INT64\020\003"
|
||||
"\022\017\n\013TYPE_UINT64\020\004\022\016\n\nTYPE_INT32\020\005\022\020\n\014TYP"
|
||||
"E_FIXED64\020\006\022\020\n\014TYPE_FIXED32\020\007\022\r\n\tTYPE_BO"
|
||||
"OL\020\010\022\017\n\013TYPE_STRING\020\t\022\020\n\014TYPE_MESSAGE\020\013\022"
|
||||
"\016\n\nTYPE_BYTES\020\014\022\017\n\013TYPE_UINT32\020\r\022\r\n\tTYPE"
|
||||
"_ENUM\020\016\022\021\n\rTYPE_SFIXED32\020\017\022\021\n\rTYPE_SFIXE"
|
||||
"D64\020\020\022\017\n\013TYPE_SINT32\020\021\022\017\n\013TYPE_SINT64\020\022\""
|
||||
"t\n\013Cardinality\022\027\n\023CARDINALITY_UNKNOWN\020\000\022"
|
||||
"\030\n\024CARDINALITY_OPTIONAL\020\001\022\030\n\024CARDINALITY"
|
||||
"_REQUIRED\020\002\022\030\n\024CARDINALITY_REPEATED\020\003\"\245\001"
|
||||
"\n\004Enum\022\014\n\004name\030\001 \001(\t\022-\n\tenumvalue\030\002 \003(\0132"
|
||||
"\032.google.protobuf.EnumValue\022(\n\007options\030\003"
|
||||
" \003(\0132\027.google.protobuf.Option\0226\n\016source_"
|
||||
"context\030\004 \001(\0132\036.google.protobuf.SourceCo"
|
||||
"ntext\"S\n\tEnumValue\022\014\n\004name\030\001 \001(\t\022\016\n\006numb"
|
||||
"er\030\002 \001(\005\022(\n\007options\030\003 \003(\0132\027.google.proto"
|
||||
"buf.Option\";\n\006Option\022\014\n\004name\030\001 \001(\t\022#\n\005va"
|
||||
"lue\030\002 \001(\0132\024.google.protobuf.AnyB(\n\023com.g"
|
||||
"oogle.protobufB\tTypeProtoP\001\242\002\003GPBb\006proto"
|
||||
"3", 1321);
|
||||
"Context\022\'\n\006syntax\030\006 \001(\0162\027.google.protobu"
|
||||
"f.Syntax\"\276\005\n\005Field\022)\n\004kind\030\001 \001(\0162\033.googl"
|
||||
"e.protobuf.Field.Kind\0227\n\013cardinality\030\002 \001"
|
||||
"(\0162\".google.protobuf.Field.Cardinality\022\016"
|
||||
"\n\006number\030\003 \001(\005\022\014\n\004name\030\004 \001(\t\022\020\n\010type_url"
|
||||
"\030\006 \001(\t\022\023\n\013oneof_index\030\007 \001(\005\022\016\n\006packed\030\010 "
|
||||
"\001(\010\022(\n\007options\030\t \003(\0132\027.google.protobuf.O"
|
||||
"ption\022\021\n\tjson_name\030\n \001(\t\"\310\002\n\004Kind\022\020\n\014TYP"
|
||||
"E_UNKNOWN\020\000\022\017\n\013TYPE_DOUBLE\020\001\022\016\n\nTYPE_FLO"
|
||||
"AT\020\002\022\016\n\nTYPE_INT64\020\003\022\017\n\013TYPE_UINT64\020\004\022\016\n"
|
||||
"\nTYPE_INT32\020\005\022\020\n\014TYPE_FIXED64\020\006\022\020\n\014TYPE_"
|
||||
"FIXED32\020\007\022\r\n\tTYPE_BOOL\020\010\022\017\n\013TYPE_STRING\020"
|
||||
"\t\022\016\n\nTYPE_GROUP\020\n\022\020\n\014TYPE_MESSAGE\020\013\022\016\n\nT"
|
||||
"YPE_BYTES\020\014\022\017\n\013TYPE_UINT32\020\r\022\r\n\tTYPE_ENU"
|
||||
"M\020\016\022\021\n\rTYPE_SFIXED32\020\017\022\021\n\rTYPE_SFIXED64\020"
|
||||
"\020\022\017\n\013TYPE_SINT32\020\021\022\017\n\013TYPE_SINT64\020\022\"t\n\013C"
|
||||
"ardinality\022\027\n\023CARDINALITY_UNKNOWN\020\000\022\030\n\024C"
|
||||
"ARDINALITY_OPTIONAL\020\001\022\030\n\024CARDINALITY_REQ"
|
||||
"UIRED\020\002\022\030\n\024CARDINALITY_REPEATED\020\003\"\316\001\n\004En"
|
||||
"um\022\014\n\004name\030\001 \001(\t\022-\n\tenumvalue\030\002 \003(\0132\032.go"
|
||||
"ogle.protobuf.EnumValue\022(\n\007options\030\003 \003(\013"
|
||||
"2\027.google.protobuf.Option\0226\n\016source_cont"
|
||||
"ext\030\004 \001(\0132\036.google.protobuf.SourceContex"
|
||||
"t\022\'\n\006syntax\030\005 \001(\0162\027.google.protobuf.Synt"
|
||||
"ax\"S\n\tEnumValue\022\014\n\004name\030\001 \001(\t\022\016\n\006number\030"
|
||||
"\002 \001(\005\022(\n\007options\030\003 \003(\0132\027.google.protobuf"
|
||||
".Option\";\n\006Option\022\014\n\004name\030\001 \001(\t\022#\n\005value"
|
||||
"\030\002 \001(\0132\024.google.protobuf.Any*.\n\006Syntax\022\021"
|
||||
"\n\rSYNTAX_PROTO2\020\000\022\021\n\rSYNTAX_PROTO3\020\001B+\n\023"
|
||||
"com.google.protobufB\tTypeProtoP\001\240\001\001\242\002\003GP"
|
||||
"Bb\006proto3", 1489);
|
||||
::google::protobuf::MessageFactory::InternalRegisterGeneratedFile(
|
||||
"google/protobuf/type.proto", &protobuf_RegisterTypes);
|
||||
Type::default_instance_ = new Type();
|
||||
@ -245,6 +254,20 @@ struct StaticDescriptorInitializer_google_2fprotobuf_2ftype_2eproto {
|
||||
protobuf_AddDesc_google_2fprotobuf_2ftype_2eproto();
|
||||
}
|
||||
} static_descriptor_initializer_google_2fprotobuf_2ftype_2eproto_;
|
||||
const ::google::protobuf::EnumDescriptor* Syntax_descriptor() {
|
||||
protobuf_AssignDescriptorsOnce();
|
||||
return Syntax_descriptor_;
|
||||
}
|
||||
bool Syntax_IsValid(int value) {
|
||||
switch(value) {
|
||||
case 0:
|
||||
case 1:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
namespace {
|
||||
|
||||
@ -264,6 +287,7 @@ const int Type::kFieldsFieldNumber;
|
||||
const int Type::kOneofsFieldNumber;
|
||||
const int Type::kOptionsFieldNumber;
|
||||
const int Type::kSourceContextFieldNumber;
|
||||
const int Type::kSyntaxFieldNumber;
|
||||
#endif // !_MSC_VER
|
||||
|
||||
Type::Type()
|
||||
@ -291,6 +315,7 @@ void Type::SharedCtor() {
|
||||
_cached_size_ = 0;
|
||||
name_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
|
||||
source_context_ = NULL;
|
||||
syntax_ = 0;
|
||||
}
|
||||
|
||||
Type::~Type() {
|
||||
@ -334,6 +359,7 @@ void Type::Clear() {
|
||||
name_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
|
||||
if (GetArenaNoVirtual() == NULL && source_context_ != NULL) delete source_context_;
|
||||
source_context_ = NULL;
|
||||
syntax_ = 0;
|
||||
fields_.Clear();
|
||||
oneofs_.Clear();
|
||||
options_.Clear();
|
||||
@ -427,6 +453,22 @@ bool Type::MergePartialFromCodedStream(
|
||||
} else {
|
||||
goto handle_unusual;
|
||||
}
|
||||
if (input->ExpectTag(48)) goto parse_syntax;
|
||||
break;
|
||||
}
|
||||
|
||||
// optional .google.protobuf.Syntax syntax = 6;
|
||||
case 6: {
|
||||
if (tag == 48) {
|
||||
parse_syntax:
|
||||
int value;
|
||||
DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
|
||||
int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>(
|
||||
input, &value)));
|
||||
set_syntax(static_cast< ::google::protobuf::Syntax >(value));
|
||||
} else {
|
||||
goto handle_unusual;
|
||||
}
|
||||
if (input->ExpectAtEnd()) goto success;
|
||||
break;
|
||||
}
|
||||
@ -493,6 +535,12 @@ void Type::SerializeWithCachedSizes(
|
||||
5, *this->source_context_, output);
|
||||
}
|
||||
|
||||
// optional .google.protobuf.Syntax syntax = 6;
|
||||
if (this->syntax() != 0) {
|
||||
::google::protobuf::internal::WireFormatLite::WriteEnum(
|
||||
6, this->syntax(), output);
|
||||
}
|
||||
|
||||
// @@protoc_insertion_point(serialize_end:google.protobuf.Type)
|
||||
}
|
||||
|
||||
@ -541,6 +589,12 @@ void Type::SerializeWithCachedSizes(
|
||||
5, *this->source_context_, target);
|
||||
}
|
||||
|
||||
// optional .google.protobuf.Syntax syntax = 6;
|
||||
if (this->syntax() != 0) {
|
||||
target = ::google::protobuf::internal::WireFormatLite::WriteEnumToArray(
|
||||
6, this->syntax(), target);
|
||||
}
|
||||
|
||||
// @@protoc_insertion_point(serialize_to_array_end:google.protobuf.Type)
|
||||
return target;
|
||||
}
|
||||
@ -562,6 +616,12 @@ int Type::ByteSize() const {
|
||||
*this->source_context_);
|
||||
}
|
||||
|
||||
// optional .google.protobuf.Syntax syntax = 6;
|
||||
if (this->syntax() != 0) {
|
||||
total_size += 1 +
|
||||
::google::protobuf::internal::WireFormatLite::EnumSize(this->syntax());
|
||||
}
|
||||
|
||||
// repeated .google.protobuf.Field fields = 2;
|
||||
total_size += 1 * this->fields_size();
|
||||
for (int i = 0; i < this->fields_size(); i++) {
|
||||
@ -615,6 +675,9 @@ void Type::MergeFrom(const Type& from) {
|
||||
if (from.has_source_context()) {
|
||||
mutable_source_context()->::google::protobuf::SourceContext::MergeFrom(from.source_context());
|
||||
}
|
||||
if (from.syntax() != 0) {
|
||||
set_syntax(from.syntax());
|
||||
}
|
||||
}
|
||||
|
||||
void Type::CopyFrom(const ::google::protobuf::Message& from) {
|
||||
@ -644,6 +707,7 @@ void Type::InternalSwap(Type* other) {
|
||||
oneofs_.UnsafeArenaSwap(&other->oneofs_);
|
||||
options_.UnsafeArenaSwap(&other->options_);
|
||||
std::swap(source_context_, other->source_context_);
|
||||
std::swap(syntax_, other->syntax_);
|
||||
_internal_metadata_.Swap(&other->_internal_metadata_);
|
||||
std::swap(_cached_size_, other->_cached_size_);
|
||||
}
|
||||
@ -853,6 +917,20 @@ void Type::clear_source_context() {
|
||||
// @@protoc_insertion_point(field_set_allocated:google.protobuf.Type.source_context)
|
||||
}
|
||||
|
||||
// optional .google.protobuf.Syntax syntax = 6;
|
||||
void Type::clear_syntax() {
|
||||
syntax_ = 0;
|
||||
}
|
||||
::google::protobuf::Syntax Type::syntax() const {
|
||||
// @@protoc_insertion_point(field_get:google.protobuf.Type.syntax)
|
||||
return static_cast< ::google::protobuf::Syntax >(syntax_);
|
||||
}
|
||||
void Type::set_syntax(::google::protobuf::Syntax value) {
|
||||
|
||||
syntax_ = value;
|
||||
// @@protoc_insertion_point(field_set:google.protobuf.Type.syntax)
|
||||
}
|
||||
|
||||
#endif // PROTOBUF_INLINE_NOT_IN_HEADERS
|
||||
|
||||
// ===================================================================
|
||||
@ -873,6 +951,7 @@ bool Field_Kind_IsValid(int value) {
|
||||
case 7:
|
||||
case 8:
|
||||
case 9:
|
||||
case 10:
|
||||
case 11:
|
||||
case 12:
|
||||
case 13:
|
||||
@ -898,6 +977,7 @@ const Field_Kind Field::TYPE_FIXED64;
|
||||
const Field_Kind Field::TYPE_FIXED32;
|
||||
const Field_Kind Field::TYPE_BOOL;
|
||||
const Field_Kind Field::TYPE_STRING;
|
||||
const Field_Kind Field::TYPE_GROUP;
|
||||
const Field_Kind Field::TYPE_MESSAGE;
|
||||
const Field_Kind Field::TYPE_BYTES;
|
||||
const Field_Kind Field::TYPE_UINT32;
|
||||
@ -944,6 +1024,7 @@ const int Field::kTypeUrlFieldNumber;
|
||||
const int Field::kOneofIndexFieldNumber;
|
||||
const int Field::kPackedFieldNumber;
|
||||
const int Field::kOptionsFieldNumber;
|
||||
const int Field::kJsonNameFieldNumber;
|
||||
#endif // !_MSC_VER
|
||||
|
||||
Field::Field()
|
||||
@ -975,6 +1056,7 @@ void Field::SharedCtor() {
|
||||
type_url_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
|
||||
oneof_index_ = 0;
|
||||
packed_ = false;
|
||||
json_name_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
|
||||
}
|
||||
|
||||
Field::~Field() {
|
||||
@ -985,6 +1067,7 @@ Field::~Field() {
|
||||
void Field::SharedDtor() {
|
||||
name_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
|
||||
type_url_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
|
||||
json_name_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
|
||||
if (this != default_instance_) {
|
||||
}
|
||||
}
|
||||
@ -1028,6 +1111,7 @@ void Field::Clear() {
|
||||
name_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
|
||||
type_url_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
|
||||
packed_ = false;
|
||||
json_name_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
|
||||
|
||||
#undef ZR_HELPER_
|
||||
#undef ZR_
|
||||
@ -1168,6 +1252,23 @@ bool Field::MergePartialFromCodedStream(
|
||||
}
|
||||
if (input->ExpectTag(74)) goto parse_loop_options;
|
||||
input->UnsafeDecrementRecursionDepth();
|
||||
if (input->ExpectTag(82)) goto parse_json_name;
|
||||
break;
|
||||
}
|
||||
|
||||
// optional string json_name = 10;
|
||||
case 10: {
|
||||
if (tag == 82) {
|
||||
parse_json_name:
|
||||
DO_(::google::protobuf::internal::WireFormatLite::ReadString(
|
||||
input, this->mutable_json_name()));
|
||||
::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
|
||||
this->json_name().data(), this->json_name().length(),
|
||||
::google::protobuf::internal::WireFormat::PARSE,
|
||||
"google.protobuf.Field.json_name");
|
||||
} else {
|
||||
goto handle_unusual;
|
||||
}
|
||||
if (input->ExpectAtEnd()) goto success;
|
||||
break;
|
||||
}
|
||||
@ -1249,6 +1350,16 @@ void Field::SerializeWithCachedSizes(
|
||||
9, this->options(i), output);
|
||||
}
|
||||
|
||||
// optional string json_name = 10;
|
||||
if (this->json_name().size() > 0) {
|
||||
::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
|
||||
this->json_name().data(), this->json_name().length(),
|
||||
::google::protobuf::internal::WireFormat::SERIALIZE,
|
||||
"google.protobuf.Field.json_name");
|
||||
::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
|
||||
10, this->json_name(), output);
|
||||
}
|
||||
|
||||
// @@protoc_insertion_point(serialize_end:google.protobuf.Field)
|
||||
}
|
||||
|
||||
@ -1311,6 +1422,17 @@ void Field::SerializeWithCachedSizes(
|
||||
9, this->options(i), target);
|
||||
}
|
||||
|
||||
// optional string json_name = 10;
|
||||
if (this->json_name().size() > 0) {
|
||||
::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
|
||||
this->json_name().data(), this->json_name().length(),
|
||||
::google::protobuf::internal::WireFormat::SERIALIZE,
|
||||
"google.protobuf.Field.json_name");
|
||||
target =
|
||||
::google::protobuf::internal::WireFormatLite::WriteStringToArray(
|
||||
10, this->json_name(), target);
|
||||
}
|
||||
|
||||
// @@protoc_insertion_point(serialize_to_array_end:google.protobuf.Field)
|
||||
return target;
|
||||
}
|
||||
@ -1363,6 +1485,13 @@ int Field::ByteSize() const {
|
||||
total_size += 1 + 1;
|
||||
}
|
||||
|
||||
// optional string json_name = 10;
|
||||
if (this->json_name().size() > 0) {
|
||||
total_size += 1 +
|
||||
::google::protobuf::internal::WireFormatLite::StringSize(
|
||||
this->json_name());
|
||||
}
|
||||
|
||||
// repeated .google.protobuf.Option options = 9;
|
||||
total_size += 1 * this->options_size();
|
||||
for (int i = 0; i < this->options_size(); i++) {
|
||||
@ -1415,6 +1544,10 @@ void Field::MergeFrom(const Field& from) {
|
||||
if (from.packed() != 0) {
|
||||
set_packed(from.packed());
|
||||
}
|
||||
if (from.json_name().size() > 0) {
|
||||
|
||||
json_name_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.json_name_);
|
||||
}
|
||||
}
|
||||
|
||||
void Field::CopyFrom(const ::google::protobuf::Message& from) {
|
||||
@ -1447,6 +1580,7 @@ void Field::InternalSwap(Field* other) {
|
||||
std::swap(oneof_index_, other->oneof_index_);
|
||||
std::swap(packed_, other->packed_);
|
||||
options_.UnsafeArenaSwap(&other->options_);
|
||||
json_name_.Swap(&other->json_name_);
|
||||
_internal_metadata_.Swap(&other->_internal_metadata_);
|
||||
std::swap(_cached_size_, other->_cached_size_);
|
||||
}
|
||||
@ -1648,6 +1782,49 @@ Field::mutable_options() {
|
||||
return &options_;
|
||||
}
|
||||
|
||||
// optional string json_name = 10;
|
||||
void Field::clear_json_name() {
|
||||
json_name_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
|
||||
}
|
||||
const ::std::string& Field::json_name() const {
|
||||
// @@protoc_insertion_point(field_get:google.protobuf.Field.json_name)
|
||||
return json_name_.GetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
|
||||
}
|
||||
void Field::set_json_name(const ::std::string& value) {
|
||||
|
||||
json_name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
|
||||
// @@protoc_insertion_point(field_set:google.protobuf.Field.json_name)
|
||||
}
|
||||
void Field::set_json_name(const char* value) {
|
||||
|
||||
json_name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
|
||||
// @@protoc_insertion_point(field_set_char:google.protobuf.Field.json_name)
|
||||
}
|
||||
void Field::set_json_name(const char* value, size_t size) {
|
||||
|
||||
json_name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
|
||||
::std::string(reinterpret_cast<const char*>(value), size));
|
||||
// @@protoc_insertion_point(field_set_pointer:google.protobuf.Field.json_name)
|
||||
}
|
||||
::std::string* Field::mutable_json_name() {
|
||||
|
||||
// @@protoc_insertion_point(field_mutable:google.protobuf.Field.json_name)
|
||||
return json_name_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
|
||||
}
|
||||
::std::string* Field::release_json_name() {
|
||||
|
||||
return json_name_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
|
||||
}
|
||||
void Field::set_allocated_json_name(::std::string* json_name) {
|
||||
if (json_name != NULL) {
|
||||
|
||||
} else {
|
||||
|
||||
}
|
||||
json_name_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), json_name);
|
||||
// @@protoc_insertion_point(field_set_allocated:google.protobuf.Field.json_name)
|
||||
}
|
||||
|
||||
#endif // PROTOBUF_INLINE_NOT_IN_HEADERS
|
||||
|
||||
// ===================================================================
|
||||
@ -1657,6 +1834,7 @@ const int Enum::kNameFieldNumber;
|
||||
const int Enum::kEnumvalueFieldNumber;
|
||||
const int Enum::kOptionsFieldNumber;
|
||||
const int Enum::kSourceContextFieldNumber;
|
||||
const int Enum::kSyntaxFieldNumber;
|
||||
#endif // !_MSC_VER
|
||||
|
||||
Enum::Enum()
|
||||
@ -1684,6 +1862,7 @@ void Enum::SharedCtor() {
|
||||
_cached_size_ = 0;
|
||||
name_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
|
||||
source_context_ = NULL;
|
||||
syntax_ = 0;
|
||||
}
|
||||
|
||||
Enum::~Enum() {
|
||||
@ -1727,6 +1906,7 @@ void Enum::Clear() {
|
||||
name_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
|
||||
if (GetArenaNoVirtual() == NULL && source_context_ != NULL) delete source_context_;
|
||||
source_context_ = NULL;
|
||||
syntax_ = 0;
|
||||
enumvalue_.Clear();
|
||||
options_.Clear();
|
||||
}
|
||||
@ -1799,6 +1979,22 @@ bool Enum::MergePartialFromCodedStream(
|
||||
} else {
|
||||
goto handle_unusual;
|
||||
}
|
||||
if (input->ExpectTag(40)) goto parse_syntax;
|
||||
break;
|
||||
}
|
||||
|
||||
// optional .google.protobuf.Syntax syntax = 5;
|
||||
case 5: {
|
||||
if (tag == 40) {
|
||||
parse_syntax:
|
||||
int value;
|
||||
DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
|
||||
int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>(
|
||||
input, &value)));
|
||||
set_syntax(static_cast< ::google::protobuf::Syntax >(value));
|
||||
} else {
|
||||
goto handle_unusual;
|
||||
}
|
||||
if (input->ExpectAtEnd()) goto success;
|
||||
break;
|
||||
}
|
||||
@ -1855,6 +2051,12 @@ void Enum::SerializeWithCachedSizes(
|
||||
4, *this->source_context_, output);
|
||||
}
|
||||
|
||||
// optional .google.protobuf.Syntax syntax = 5;
|
||||
if (this->syntax() != 0) {
|
||||
::google::protobuf::internal::WireFormatLite::WriteEnum(
|
||||
5, this->syntax(), output);
|
||||
}
|
||||
|
||||
// @@protoc_insertion_point(serialize_end:google.protobuf.Enum)
|
||||
}
|
||||
|
||||
@ -1893,6 +2095,12 @@ void Enum::SerializeWithCachedSizes(
|
||||
4, *this->source_context_, target);
|
||||
}
|
||||
|
||||
// optional .google.protobuf.Syntax syntax = 5;
|
||||
if (this->syntax() != 0) {
|
||||
target = ::google::protobuf::internal::WireFormatLite::WriteEnumToArray(
|
||||
5, this->syntax(), target);
|
||||
}
|
||||
|
||||
// @@protoc_insertion_point(serialize_to_array_end:google.protobuf.Enum)
|
||||
return target;
|
||||
}
|
||||
@ -1914,6 +2122,12 @@ int Enum::ByteSize() const {
|
||||
*this->source_context_);
|
||||
}
|
||||
|
||||
// optional .google.protobuf.Syntax syntax = 5;
|
||||
if (this->syntax() != 0) {
|
||||
total_size += 1 +
|
||||
::google::protobuf::internal::WireFormatLite::EnumSize(this->syntax());
|
||||
}
|
||||
|
||||
// repeated .google.protobuf.EnumValue enumvalue = 2;
|
||||
total_size += 1 * this->enumvalue_size();
|
||||
for (int i = 0; i < this->enumvalue_size(); i++) {
|
||||
@ -1959,6 +2173,9 @@ void Enum::MergeFrom(const Enum& from) {
|
||||
if (from.has_source_context()) {
|
||||
mutable_source_context()->::google::protobuf::SourceContext::MergeFrom(from.source_context());
|
||||
}
|
||||
if (from.syntax() != 0) {
|
||||
set_syntax(from.syntax());
|
||||
}
|
||||
}
|
||||
|
||||
void Enum::CopyFrom(const ::google::protobuf::Message& from) {
|
||||
@ -1987,6 +2204,7 @@ void Enum::InternalSwap(Enum* other) {
|
||||
enumvalue_.UnsafeArenaSwap(&other->enumvalue_);
|
||||
options_.UnsafeArenaSwap(&other->options_);
|
||||
std::swap(source_context_, other->source_context_);
|
||||
std::swap(syntax_, other->syntax_);
|
||||
_internal_metadata_.Swap(&other->_internal_metadata_);
|
||||
std::swap(_cached_size_, other->_cached_size_);
|
||||
}
|
||||
@ -2142,6 +2360,20 @@ void Enum::clear_source_context() {
|
||||
// @@protoc_insertion_point(field_set_allocated:google.protobuf.Enum.source_context)
|
||||
}
|
||||
|
||||
// optional .google.protobuf.Syntax syntax = 5;
|
||||
void Enum::clear_syntax() {
|
||||
syntax_ = 0;
|
||||
}
|
||||
::google::protobuf::Syntax Enum::syntax() const {
|
||||
// @@protoc_insertion_point(field_get:google.protobuf.Enum.syntax)
|
||||
return static_cast< ::google::protobuf::Syntax >(syntax_);
|
||||
}
|
||||
void Enum::set_syntax(::google::protobuf::Syntax value) {
|
||||
|
||||
syntax_ = value;
|
||||
// @@protoc_insertion_point(field_set:google.protobuf.Enum.syntax)
|
||||
}
|
||||
|
||||
#endif // PROTOBUF_INLINE_NOT_IN_HEADERS
|
||||
|
||||
// ===================================================================
|
||||
|
@ -57,6 +57,7 @@ enum Field_Kind {
|
||||
Field_Kind_TYPE_FIXED32 = 7,
|
||||
Field_Kind_TYPE_BOOL = 8,
|
||||
Field_Kind_TYPE_STRING = 9,
|
||||
Field_Kind_TYPE_GROUP = 10,
|
||||
Field_Kind_TYPE_MESSAGE = 11,
|
||||
Field_Kind_TYPE_BYTES = 12,
|
||||
Field_Kind_TYPE_UINT32 = 13,
|
||||
@ -106,6 +107,27 @@ inline bool Field_Cardinality_Parse(
|
||||
return ::google::protobuf::internal::ParseNamedEnum<Field_Cardinality>(
|
||||
Field_Cardinality_descriptor(), name, value);
|
||||
}
|
||||
enum Syntax {
|
||||
SYNTAX_PROTO2 = 0,
|
||||
SYNTAX_PROTO3 = 1,
|
||||
Syntax_INT_MIN_SENTINEL_DO_NOT_USE_ = ::google::protobuf::kint32min,
|
||||
Syntax_INT_MAX_SENTINEL_DO_NOT_USE_ = ::google::protobuf::kint32max
|
||||
};
|
||||
LIBPROTOBUF_EXPORT bool Syntax_IsValid(int value);
|
||||
const Syntax Syntax_MIN = SYNTAX_PROTO2;
|
||||
const Syntax Syntax_MAX = SYNTAX_PROTO3;
|
||||
const int Syntax_ARRAYSIZE = Syntax_MAX + 1;
|
||||
|
||||
LIBPROTOBUF_EXPORT const ::google::protobuf::EnumDescriptor* Syntax_descriptor();
|
||||
inline const ::std::string& Syntax_Name(Syntax value) {
|
||||
return ::google::protobuf::internal::NameOfEnum(
|
||||
Syntax_descriptor(), value);
|
||||
}
|
||||
inline bool Syntax_Parse(
|
||||
const ::std::string& name, Syntax* value) {
|
||||
return ::google::protobuf::internal::ParseNamedEnum<Syntax>(
|
||||
Syntax_descriptor(), name, value);
|
||||
}
|
||||
// ===================================================================
|
||||
|
||||
class LIBPROTOBUF_EXPORT Type : public ::google::protobuf::Message {
|
||||
@ -224,6 +246,12 @@ class LIBPROTOBUF_EXPORT Type : public ::google::protobuf::Message {
|
||||
::google::protobuf::SourceContext* release_source_context();
|
||||
void set_allocated_source_context(::google::protobuf::SourceContext* source_context);
|
||||
|
||||
// optional .google.protobuf.Syntax syntax = 6;
|
||||
void clear_syntax();
|
||||
static const int kSyntaxFieldNumber = 6;
|
||||
::google::protobuf::Syntax syntax() const;
|
||||
void set_syntax(::google::protobuf::Syntax value);
|
||||
|
||||
// @@protoc_insertion_point(class_scope:google.protobuf.Type)
|
||||
private:
|
||||
|
||||
@ -234,6 +262,7 @@ class LIBPROTOBUF_EXPORT Type : public ::google::protobuf::Message {
|
||||
::google::protobuf::RepeatedPtrField< ::std::string> oneofs_;
|
||||
::google::protobuf::RepeatedPtrField< ::google::protobuf::Option > options_;
|
||||
::google::protobuf::SourceContext* source_context_;
|
||||
int syntax_;
|
||||
mutable int _cached_size_;
|
||||
friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2ftype_2eproto();
|
||||
friend void protobuf_AssignDesc_google_2fprotobuf_2ftype_2eproto();
|
||||
@ -309,6 +338,7 @@ class LIBPROTOBUF_EXPORT Field : public ::google::protobuf::Message {
|
||||
static const Kind TYPE_FIXED32 = Field_Kind_TYPE_FIXED32;
|
||||
static const Kind TYPE_BOOL = Field_Kind_TYPE_BOOL;
|
||||
static const Kind TYPE_STRING = Field_Kind_TYPE_STRING;
|
||||
static const Kind TYPE_GROUP = Field_Kind_TYPE_GROUP;
|
||||
static const Kind TYPE_MESSAGE = Field_Kind_TYPE_MESSAGE;
|
||||
static const Kind TYPE_BYTES = Field_Kind_TYPE_BYTES;
|
||||
static const Kind TYPE_UINT32 = Field_Kind_TYPE_UINT32;
|
||||
@ -430,6 +460,17 @@ class LIBPROTOBUF_EXPORT Field : public ::google::protobuf::Message {
|
||||
::google::protobuf::RepeatedPtrField< ::google::protobuf::Option >*
|
||||
mutable_options();
|
||||
|
||||
// optional string json_name = 10;
|
||||
void clear_json_name();
|
||||
static const int kJsonNameFieldNumber = 10;
|
||||
const ::std::string& json_name() const;
|
||||
void set_json_name(const ::std::string& value);
|
||||
void set_json_name(const char* value);
|
||||
void set_json_name(const char* value, size_t size);
|
||||
::std::string* mutable_json_name();
|
||||
::std::string* release_json_name();
|
||||
void set_allocated_json_name(::std::string* json_name);
|
||||
|
||||
// @@protoc_insertion_point(class_scope:google.protobuf.Field)
|
||||
private:
|
||||
|
||||
@ -442,6 +483,7 @@ class LIBPROTOBUF_EXPORT Field : public ::google::protobuf::Message {
|
||||
::google::protobuf::int32 oneof_index_;
|
||||
::google::protobuf::internal::ArenaStringPtr type_url_;
|
||||
::google::protobuf::RepeatedPtrField< ::google::protobuf::Option > options_;
|
||||
::google::protobuf::internal::ArenaStringPtr json_name_;
|
||||
bool packed_;
|
||||
mutable int _cached_size_;
|
||||
friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2ftype_2eproto();
|
||||
@ -553,6 +595,12 @@ class LIBPROTOBUF_EXPORT Enum : public ::google::protobuf::Message {
|
||||
::google::protobuf::SourceContext* release_source_context();
|
||||
void set_allocated_source_context(::google::protobuf::SourceContext* source_context);
|
||||
|
||||
// optional .google.protobuf.Syntax syntax = 5;
|
||||
void clear_syntax();
|
||||
static const int kSyntaxFieldNumber = 5;
|
||||
::google::protobuf::Syntax syntax() const;
|
||||
void set_syntax(::google::protobuf::Syntax value);
|
||||
|
||||
// @@protoc_insertion_point(class_scope:google.protobuf.Enum)
|
||||
private:
|
||||
|
||||
@ -562,6 +610,7 @@ class LIBPROTOBUF_EXPORT Enum : public ::google::protobuf::Message {
|
||||
::google::protobuf::RepeatedPtrField< ::google::protobuf::EnumValue > enumvalue_;
|
||||
::google::protobuf::RepeatedPtrField< ::google::protobuf::Option > options_;
|
||||
::google::protobuf::SourceContext* source_context_;
|
||||
int syntax_;
|
||||
mutable int _cached_size_;
|
||||
friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2ftype_2eproto();
|
||||
friend void protobuf_AssignDesc_google_2fprotobuf_2ftype_2eproto();
|
||||
@ -968,6 +1017,20 @@ inline void Type::set_allocated_source_context(::google::protobuf::SourceContext
|
||||
// @@protoc_insertion_point(field_set_allocated:google.protobuf.Type.source_context)
|
||||
}
|
||||
|
||||
// optional .google.protobuf.Syntax syntax = 6;
|
||||
inline void Type::clear_syntax() {
|
||||
syntax_ = 0;
|
||||
}
|
||||
inline ::google::protobuf::Syntax Type::syntax() const {
|
||||
// @@protoc_insertion_point(field_get:google.protobuf.Type.syntax)
|
||||
return static_cast< ::google::protobuf::Syntax >(syntax_);
|
||||
}
|
||||
inline void Type::set_syntax(::google::protobuf::Syntax value) {
|
||||
|
||||
syntax_ = value;
|
||||
// @@protoc_insertion_point(field_set:google.protobuf.Type.syntax)
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
|
||||
// Field
|
||||
@ -1158,6 +1221,49 @@ Field::mutable_options() {
|
||||
return &options_;
|
||||
}
|
||||
|
||||
// optional string json_name = 10;
|
||||
inline void Field::clear_json_name() {
|
||||
json_name_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
|
||||
}
|
||||
inline const ::std::string& Field::json_name() const {
|
||||
// @@protoc_insertion_point(field_get:google.protobuf.Field.json_name)
|
||||
return json_name_.GetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
|
||||
}
|
||||
inline void Field::set_json_name(const ::std::string& value) {
|
||||
|
||||
json_name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
|
||||
// @@protoc_insertion_point(field_set:google.protobuf.Field.json_name)
|
||||
}
|
||||
inline void Field::set_json_name(const char* value) {
|
||||
|
||||
json_name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
|
||||
// @@protoc_insertion_point(field_set_char:google.protobuf.Field.json_name)
|
||||
}
|
||||
inline void Field::set_json_name(const char* value, size_t size) {
|
||||
|
||||
json_name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
|
||||
::std::string(reinterpret_cast<const char*>(value), size));
|
||||
// @@protoc_insertion_point(field_set_pointer:google.protobuf.Field.json_name)
|
||||
}
|
||||
inline ::std::string* Field::mutable_json_name() {
|
||||
|
||||
// @@protoc_insertion_point(field_mutable:google.protobuf.Field.json_name)
|
||||
return json_name_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
|
||||
}
|
||||
inline ::std::string* Field::release_json_name() {
|
||||
|
||||
return json_name_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
|
||||
}
|
||||
inline void Field::set_allocated_json_name(::std::string* json_name) {
|
||||
if (json_name != NULL) {
|
||||
|
||||
} else {
|
||||
|
||||
}
|
||||
json_name_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), json_name);
|
||||
// @@protoc_insertion_point(field_set_allocated:google.protobuf.Field.json_name)
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
|
||||
// Enum
|
||||
@ -1302,6 +1408,20 @@ inline void Enum::set_allocated_source_context(::google::protobuf::SourceContext
|
||||
// @@protoc_insertion_point(field_set_allocated:google.protobuf.Enum.source_context)
|
||||
}
|
||||
|
||||
// optional .google.protobuf.Syntax syntax = 5;
|
||||
inline void Enum::clear_syntax() {
|
||||
syntax_ = 0;
|
||||
}
|
||||
inline ::google::protobuf::Syntax Enum::syntax() const {
|
||||
// @@protoc_insertion_point(field_get:google.protobuf.Enum.syntax)
|
||||
return static_cast< ::google::protobuf::Syntax >(syntax_);
|
||||
}
|
||||
inline void Enum::set_syntax(::google::protobuf::Syntax value) {
|
||||
|
||||
syntax_ = value;
|
||||
// @@protoc_insertion_point(field_set:google.protobuf.Enum.syntax)
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
|
||||
// EnumValue
|
||||
@ -1506,6 +1626,11 @@ template <>
|
||||
inline const EnumDescriptor* GetEnumDescriptor< ::google::protobuf::Field_Cardinality>() {
|
||||
return ::google::protobuf::Field_Cardinality_descriptor();
|
||||
}
|
||||
template <> struct is_proto_enum< ::google::protobuf::Syntax> : ::google::protobuf::internal::true_type {};
|
||||
template <>
|
||||
inline const EnumDescriptor* GetEnumDescriptor< ::google::protobuf::Syntax>() {
|
||||
return ::google::protobuf::Syntax_descriptor();
|
||||
}
|
||||
|
||||
} // namespace protobuf
|
||||
} // namespace google
|
||||
|
@ -34,29 +34,26 @@ package google.protobuf;
|
||||
import "google/protobuf/any.proto";
|
||||
import "google/protobuf/source_context.proto";
|
||||
|
||||
option java_multiple_files = true;
|
||||
option java_outer_classname = "TypeProto";
|
||||
option java_package = "com.google.protobuf";
|
||||
option java_outer_classname = "TypeProto";
|
||||
option java_multiple_files = true;
|
||||
option java_generate_equals_and_hash = true;
|
||||
option objc_class_prefix = "GPB";
|
||||
|
||||
|
||||
// A light-weight descriptor for a proto message type.
|
||||
message Type {
|
||||
// The fully qualified message name.
|
||||
string name = 1;
|
||||
|
||||
// The list of fields.
|
||||
repeated Field fields = 2;
|
||||
|
||||
// The list of oneof definitions.
|
||||
// The list of oneofs declared in this Type
|
||||
repeated string oneofs = 3;
|
||||
|
||||
repeated string oneofs = 3; // The list of oneofs declared in this Type
|
||||
// The proto options.
|
||||
repeated Option options = 4;
|
||||
|
||||
// The source context.
|
||||
SourceContext source_context = 5;
|
||||
// The source syntax.
|
||||
Syntax syntax = 6;
|
||||
}
|
||||
|
||||
// Field represents a single field of a message type.
|
||||
@ -64,125 +61,99 @@ message Field {
|
||||
// Kind represents a basic field type.
|
||||
enum Kind {
|
||||
// Field type unknown.
|
||||
TYPE_UNKNOWN = 0;
|
||||
|
||||
TYPE_UNKNOWN = 0;
|
||||
// Field type double.
|
||||
TYPE_DOUBLE = 1;
|
||||
|
||||
TYPE_DOUBLE = 1;
|
||||
// Field type float.
|
||||
TYPE_FLOAT = 2;
|
||||
|
||||
TYPE_FLOAT = 2;
|
||||
// Field type int64.
|
||||
TYPE_INT64 = 3;
|
||||
|
||||
TYPE_INT64 = 3;
|
||||
// Field type uint64.
|
||||
TYPE_UINT64 = 4;
|
||||
|
||||
TYPE_UINT64 = 4;
|
||||
// Field type int32.
|
||||
TYPE_INT32 = 5;
|
||||
|
||||
TYPE_INT32 = 5;
|
||||
// Field type fixed64.
|
||||
TYPE_FIXED64 = 6;
|
||||
|
||||
TYPE_FIXED64 = 6;
|
||||
// Field type fixed32.
|
||||
TYPE_FIXED32 = 7;
|
||||
|
||||
TYPE_FIXED32 = 7;
|
||||
// Field type bool.
|
||||
TYPE_BOOL = 8;
|
||||
|
||||
TYPE_BOOL = 8;
|
||||
// Field type string.
|
||||
TYPE_STRING = 9;
|
||||
|
||||
TYPE_STRING = 9;
|
||||
// Field type group (deprecated proto2 type)
|
||||
TYPE_GROUP = 10;
|
||||
// Field type message.
|
||||
TYPE_MESSAGE = 11;
|
||||
|
||||
TYPE_MESSAGE = 11;
|
||||
// Field type bytes.
|
||||
TYPE_BYTES = 12;
|
||||
|
||||
TYPE_BYTES = 12;
|
||||
// Field type uint32.
|
||||
TYPE_UINT32 = 13;
|
||||
|
||||
TYPE_UINT32 = 13;
|
||||
// Field type enum.
|
||||
TYPE_ENUM = 14;
|
||||
|
||||
TYPE_ENUM = 14;
|
||||
// Field type sfixed32.
|
||||
TYPE_SFIXED32 = 15;
|
||||
|
||||
TYPE_SFIXED32 = 15;
|
||||
// Field type sfixed64.
|
||||
TYPE_SFIXED64 = 16;
|
||||
|
||||
TYPE_SFIXED64 = 16;
|
||||
// Field type sint32.
|
||||
TYPE_SINT32 = 17;
|
||||
|
||||
TYPE_SINT32 = 17;
|
||||
// Field type sint64.
|
||||
TYPE_SINT64 = 18;
|
||||
}
|
||||
TYPE_SINT64 = 18;
|
||||
};
|
||||
|
||||
// Cardinality represents whether a field is optional, required, or
|
||||
// repeated.
|
||||
enum Cardinality {
|
||||
// The field cardinality is unknown. Typically an error condition.
|
||||
CARDINALITY_UNKNOWN = 0;
|
||||
|
||||
// For optional fields.
|
||||
CARDINALITY_OPTIONAL = 1;
|
||||
|
||||
// For required fields. Not used for proto3.
|
||||
CARDINALITY_REQUIRED = 2;
|
||||
|
||||
// For repeated fields.
|
||||
CARDINALITY_REPEATED = 3;
|
||||
}
|
||||
};
|
||||
|
||||
// The field kind.
|
||||
Kind kind = 1;
|
||||
|
||||
// The field cardinality, i.e. optional/required/repeated.
|
||||
Cardinality cardinality = 2;
|
||||
|
||||
// The proto field number.
|
||||
int32 number = 3;
|
||||
|
||||
// The field name.
|
||||
string name = 4;
|
||||
|
||||
// The type URL (without the scheme) when the type is MESSAGE or ENUM,
|
||||
// such as `type.googleapis.com/google.protobuf.Empty`.
|
||||
string type_url = 6;
|
||||
|
||||
// Index in Type.oneofs. Starts at 1. Zero means no oneof mapping.
|
||||
int32 oneof_index = 7;
|
||||
|
||||
// Whether to use alternative packed wire representation.
|
||||
bool packed = 8;
|
||||
|
||||
// The proto options.
|
||||
repeated Option options = 9;
|
||||
// The JSON name for this field.
|
||||
string json_name = 10;
|
||||
}
|
||||
|
||||
// Enum type definition.
|
||||
message Enum {
|
||||
// Enum type name.
|
||||
string name = 1;
|
||||
|
||||
// Enum value definitions.
|
||||
repeated EnumValue enumvalue = 2;
|
||||
|
||||
// Proto options for the enum type.
|
||||
repeated Option options = 3;
|
||||
|
||||
// The source context.
|
||||
SourceContext source_context = 4;
|
||||
// The source syntax.
|
||||
Syntax syntax = 5;
|
||||
}
|
||||
|
||||
// Enum value definition.
|
||||
message EnumValue {
|
||||
// Enum value name.
|
||||
string name = 1;
|
||||
|
||||
// Enum value number.
|
||||
int32 number = 2;
|
||||
|
||||
// Proto options for the enum value.
|
||||
repeated Option options = 3;
|
||||
}
|
||||
@ -191,7 +162,14 @@ message EnumValue {
|
||||
message Option {
|
||||
// Proto option name.
|
||||
string name = 1;
|
||||
|
||||
// Proto option value.
|
||||
Any value = 2;
|
||||
}
|
||||
|
||||
// Syntax specifies the syntax in which a service element was defined.
|
||||
enum Syntax {
|
||||
// Syntax "proto2"
|
||||
SYNTAX_PROTO2 = 0;
|
||||
// Syntax "proto3"
|
||||
SYNTAX_PROTO3 = 1;
|
||||
}
|
||||
|
52
src/google/protobuf/unittest_mset_wire_format.proto
Normal file
52
src/google/protobuf/unittest_mset_wire_format.proto
Normal file
@ -0,0 +1,52 @@
|
||||
// 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: kenton@google.com (Kenton Varda)
|
||||
// Based on original Protocol Buffers design by
|
||||
// Sanjay Ghemawat, Jeff Dean, and others.
|
||||
//
|
||||
// This file contains messages for testing message_set_wire_format.
|
||||
|
||||
syntax = "proto2";
|
||||
package proto2_wireformat_unittest;
|
||||
|
||||
option cc_enable_arenas = true;
|
||||
option optimize_for = SPEED;
|
||||
option csharp_namespace = "Google.ProtocolBuffers.TestProtos";
|
||||
|
||||
// A message with message_set_wire_format.
|
||||
message TestMessageSet {
|
||||
option message_set_wire_format = true;
|
||||
extensions 4 to max;
|
||||
}
|
||||
|
||||
message TestMessageSetWireFormatContainer {
|
||||
optional TestMessageSet message_set = 1;
|
||||
}
|
42
src/google/protobuf/unittest_no_arena_lite.proto
Normal file
42
src/google/protobuf/unittest_no_arena_lite.proto
Normal file
@ -0,0 +1,42 @@
|
||||
// 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.
|
||||
|
||||
syntax = "proto2";
|
||||
|
||||
option optimize_for = LITE_RUNTIME;
|
||||
|
||||
// We don't put this in a package within proto2 because we need to make sure
|
||||
// that the generated code doesn't depend on being in the proto2 namespace.
|
||||
// In test_util.h we do "using namespace unittest = protobuf_unittest".
|
||||
package protobuf_unittest_no_arena;
|
||||
|
||||
message ForeignMessageLite {
|
||||
optional int32 c = 1;
|
||||
}
|
418
src/google/protobuf/util/field_mask_util.cc
Normal file
418
src/google/protobuf/util/field_mask_util.cc
Normal file
@ -0,0 +1,418 @@
|
||||
// Protocol Buffers - Google's data interchange format
|
||||
// Copyright 2008 Google Inc. All rights reserved.
|
||||
// https://developers.google.com/protocol-buffers/
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
#include <google/protobuf/util/field_mask_util.h>
|
||||
|
||||
#include <google/protobuf/stubs/strutil.h>
|
||||
#include <google/protobuf/stubs/map_util.h>
|
||||
|
||||
namespace google {
|
||||
namespace protobuf {
|
||||
namespace util {
|
||||
|
||||
using google::protobuf::FieldMask;
|
||||
|
||||
string FieldMaskUtil::ToString(const FieldMask& mask) {
|
||||
return Join(mask.paths(), ",");
|
||||
}
|
||||
|
||||
void FieldMaskUtil::FromString(const string& str, FieldMask* out) {
|
||||
out->Clear();
|
||||
vector<string> paths = Split(str, ",");
|
||||
for (int i = 0; i < paths.size(); ++i) {
|
||||
if (paths[i].empty()) continue;
|
||||
out->add_paths(paths[i]);
|
||||
}
|
||||
}
|
||||
|
||||
bool FieldMaskUtil::InternalIsValidPath(const Descriptor* descriptor,
|
||||
const string& path) {
|
||||
vector<string> parts = Split(path, ".");
|
||||
for (int i = 0; i < parts.size(); ++i) {
|
||||
const string& field_name = parts[i];
|
||||
if (descriptor == NULL) {
|
||||
return false;
|
||||
}
|
||||
const FieldDescriptor* field = descriptor->FindFieldByName(field_name);
|
||||
if (field == NULL) {
|
||||
return false;
|
||||
}
|
||||
if (!field->is_repeated() &&
|
||||
field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
|
||||
descriptor = field->message_type();
|
||||
} else {
|
||||
descriptor = NULL;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void FieldMaskUtil::InternalGetFieldMaskForAllFields(
|
||||
const Descriptor* descriptor, FieldMask* out) {
|
||||
for (int i = 0; i < descriptor->field_count(); ++i) {
|
||||
out->add_paths(descriptor->field(i)->name());
|
||||
}
|
||||
}
|
||||
|
||||
namespace {
|
||||
// A FieldMaskTree represents a FieldMask in a tree structure. For example,
|
||||
// given a FieldMask "foo.bar,foo.baz,bar.baz", the FieldMaskTree will be:
|
||||
//
|
||||
// [root] -+- foo -+- bar
|
||||
// | |
|
||||
// | +- baz
|
||||
// |
|
||||
// +- bar --- baz
|
||||
//
|
||||
// In the tree, each leaf node represents a field path.
|
||||
class FieldMaskTree {
|
||||
public:
|
||||
FieldMaskTree();
|
||||
~FieldMaskTree();
|
||||
|
||||
void MergeFromFieldMask(const FieldMask& mask);
|
||||
void MergeToFieldMask(FieldMask* mask);
|
||||
|
||||
// Add a field path into the tree. In a FieldMask, each field path matches
|
||||
// the specified field and also all its sub-fields. If the field path to
|
||||
// add is a sub-path of an existing field path in the tree (i.e., a leaf
|
||||
// node), it means the tree already matchesthe the given path so nothing will
|
||||
// be added to the tree. If the path matches an existing non-leaf node in the
|
||||
// tree, that non-leaf node will be turned into a leaf node with all its
|
||||
// children removed because the path matches all the node's children.
|
||||
void AddPath(const string& path);
|
||||
|
||||
// Calculate the intersection part of a field path with this tree and add
|
||||
// the intersection field path into out.
|
||||
void IntersectPath(const string& path, FieldMaskTree* out);
|
||||
|
||||
// Merge all fields specified by this tree from one message to another.
|
||||
void MergeMessage(const Message& source,
|
||||
const FieldMaskUtil::MergeOptions& options,
|
||||
Message* destination) {
|
||||
// Do nothing if the tree is empty.
|
||||
if (root_.children.empty()) {
|
||||
return;
|
||||
}
|
||||
MergeMessage(&root_, source, options, destination);
|
||||
}
|
||||
|
||||
private:
|
||||
struct Node {
|
||||
Node() {}
|
||||
|
||||
~Node() { ClearChildren(); }
|
||||
|
||||
void ClearChildren() {
|
||||
for (map<string, Node*>::iterator it = children.begin();
|
||||
it != children.end(); ++it) {
|
||||
delete it->second;
|
||||
}
|
||||
children.clear();
|
||||
}
|
||||
|
||||
map<string, Node*> children;
|
||||
|
||||
private:
|
||||
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(Node);
|
||||
};
|
||||
|
||||
// Merge a sub-tree to mask. This method adds the field paths represented
|
||||
// by all leaf nodes descended from "node" to mask.
|
||||
void MergeToFieldMask(const string& prefix, const Node* node, FieldMask* out);
|
||||
|
||||
// Merge all leaf nodes of a sub-tree to another tree.
|
||||
void MergeLeafNodesToTree(const string& prefix, const Node* node,
|
||||
FieldMaskTree* out);
|
||||
|
||||
// Merge all fields specified by a sub-tree from one message to another.
|
||||
void MergeMessage(const Node* node, const Message& source,
|
||||
const FieldMaskUtil::MergeOptions& options,
|
||||
Message* destination);
|
||||
|
||||
Node root_;
|
||||
|
||||
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(FieldMaskTree);
|
||||
};
|
||||
|
||||
FieldMaskTree::FieldMaskTree() {}
|
||||
|
||||
FieldMaskTree::~FieldMaskTree() {}
|
||||
|
||||
void FieldMaskTree::MergeFromFieldMask(const FieldMask& mask) {
|
||||
for (int i = 0; i < mask.paths_size(); ++i) {
|
||||
AddPath(mask.paths(i));
|
||||
}
|
||||
}
|
||||
|
||||
void FieldMaskTree::MergeToFieldMask(FieldMask* mask) {
|
||||
MergeToFieldMask("", &root_, mask);
|
||||
}
|
||||
|
||||
void FieldMaskTree::MergeToFieldMask(const string& prefix, const Node* node,
|
||||
FieldMask* out) {
|
||||
if (node->children.empty()) {
|
||||
if (prefix.empty()) {
|
||||
// This is the root node.
|
||||
return;
|
||||
}
|
||||
out->add_paths(prefix);
|
||||
return;
|
||||
}
|
||||
for (map<string, Node*>::const_iterator it = node->children.begin();
|
||||
it != node->children.end(); ++it) {
|
||||
string current_path = prefix.empty() ? it->first : prefix + "." + it->first;
|
||||
MergeToFieldMask(current_path, it->second, out);
|
||||
}
|
||||
}
|
||||
|
||||
void FieldMaskTree::AddPath(const string& path) {
|
||||
vector<string> parts = Split(path, ".");
|
||||
if (parts.empty()) {
|
||||
return;
|
||||
}
|
||||
bool new_branch = false;
|
||||
Node* node = &root_;
|
||||
for (int i = 0; i < parts.size(); ++i) {
|
||||
if (!new_branch && node != &root_ && node->children.empty()) {
|
||||
// Path matches an existing leaf node. This means the path is already
|
||||
// coverred by this tree (for example, adding "foo.bar.baz" to a tree
|
||||
// which already contains "foo.bar").
|
||||
return;
|
||||
}
|
||||
const string& node_name = parts[i];
|
||||
Node*& child = node->children[node_name];
|
||||
if (child == NULL) {
|
||||
new_branch = true;
|
||||
child = new Node();
|
||||
}
|
||||
node = child;
|
||||
}
|
||||
if (!node->children.empty()) {
|
||||
node->ClearChildren();
|
||||
}
|
||||
}
|
||||
|
||||
void FieldMaskTree::IntersectPath(const string& path, FieldMaskTree* out) {
|
||||
vector<string> parts = Split(path, ".");
|
||||
if (parts.empty()) {
|
||||
return;
|
||||
}
|
||||
const Node* node = &root_;
|
||||
for (int i = 0; i < parts.size(); ++i) {
|
||||
if (node->children.empty()) {
|
||||
if (node != &root_) {
|
||||
out->AddPath(path);
|
||||
}
|
||||
return;
|
||||
}
|
||||
const string& node_name = parts[i];
|
||||
const Node* result = FindPtrOrNull(node->children, node_name);
|
||||
if (result == NULL) {
|
||||
// No intersection found.
|
||||
return;
|
||||
}
|
||||
node = result;
|
||||
}
|
||||
// Now we found a matching node with the given path. Add all leaf nodes
|
||||
// to out.
|
||||
MergeLeafNodesToTree(path, node, out);
|
||||
}
|
||||
|
||||
void FieldMaskTree::MergeLeafNodesToTree(const string& prefix, const Node* node,
|
||||
FieldMaskTree* out) {
|
||||
if (node->children.empty()) {
|
||||
out->AddPath(prefix);
|
||||
}
|
||||
for (map<string, Node*>::const_iterator it = node->children.begin();
|
||||
it != node->children.end(); ++it) {
|
||||
string current_path = prefix.empty() ? it->first : prefix + "." + it->first;
|
||||
MergeLeafNodesToTree(current_path, it->second, out);
|
||||
}
|
||||
}
|
||||
|
||||
void FieldMaskTree::MergeMessage(const Node* node, const Message& source,
|
||||
const FieldMaskUtil::MergeOptions& options,
|
||||
Message* destination) {
|
||||
GOOGLE_DCHECK(!node->children.empty());
|
||||
const Reflection* source_reflection = source.GetReflection();
|
||||
const Reflection* destination_reflection = destination->GetReflection();
|
||||
const Descriptor* descriptor = source.GetDescriptor();
|
||||
for (map<string, Node*>::const_iterator it = node->children.begin();
|
||||
it != node->children.end(); ++it) {
|
||||
const string& field_name = it->first;
|
||||
const Node* child = it->second;
|
||||
const FieldDescriptor* field = descriptor->FindFieldByName(field_name);
|
||||
if (field == NULL) {
|
||||
GOOGLE_LOG(ERROR) << "Cannot find field \"" << field_name << "\" in message "
|
||||
<< descriptor->full_name();
|
||||
continue;
|
||||
}
|
||||
if (!child->children.empty()) {
|
||||
// Sub-paths are only allowed for singular message fields.
|
||||
if (field->is_repeated() ||
|
||||
field->cpp_type() != FieldDescriptor::CPPTYPE_MESSAGE) {
|
||||
GOOGLE_LOG(ERROR) << "Field \"" << field_name << "\" in message "
|
||||
<< descriptor->full_name()
|
||||
<< " is not a singular message field and cannot "
|
||||
<< "have sub-fields.";
|
||||
continue;
|
||||
}
|
||||
MergeMessage(child, source_reflection->GetMessage(source, field), options,
|
||||
destination_reflection->MutableMessage(destination, field));
|
||||
continue;
|
||||
}
|
||||
if (!field->is_repeated()) {
|
||||
switch (field->cpp_type()) {
|
||||
#define COPY_VALUE(TYPE, Name) \
|
||||
case FieldDescriptor::CPPTYPE_##TYPE: { \
|
||||
destination_reflection->Set##Name( \
|
||||
destination, field, source_reflection->Get##Name(source, field)); \
|
||||
break; \
|
||||
}
|
||||
COPY_VALUE(BOOL, Bool)
|
||||
COPY_VALUE(INT32, Int32)
|
||||
COPY_VALUE(INT64, Int64)
|
||||
COPY_VALUE(UINT32, UInt32)
|
||||
COPY_VALUE(UINT64, UInt64)
|
||||
COPY_VALUE(FLOAT, Float)
|
||||
COPY_VALUE(DOUBLE, Double)
|
||||
COPY_VALUE(ENUM, Enum)
|
||||
COPY_VALUE(STRING, String)
|
||||
#undef COPY_VALUE
|
||||
case FieldDescriptor::CPPTYPE_MESSAGE: {
|
||||
if (options.replace_message_fields()) {
|
||||
destination_reflection->ClearField(destination, field);
|
||||
}
|
||||
if (source_reflection->HasField(source, field)) {
|
||||
destination_reflection->MutableMessage(destination, field)
|
||||
->MergeFrom(source_reflection->GetMessage(source, field));
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (options.replace_repeated_fields()) {
|
||||
destination_reflection->ClearField(destination, field);
|
||||
}
|
||||
switch (field->cpp_type()) {
|
||||
#define COPY_REPEATED_VALUE(TYPE, Name) \
|
||||
case FieldDescriptor::CPPTYPE_##TYPE: { \
|
||||
int size = source_reflection->FieldSize(source, field); \
|
||||
for (int i = 0; i < size; ++i) { \
|
||||
destination_reflection->Add##Name( \
|
||||
destination, field, \
|
||||
source_reflection->GetRepeated##Name(source, field, i)); \
|
||||
} \
|
||||
break; \
|
||||
}
|
||||
COPY_REPEATED_VALUE(BOOL, Bool)
|
||||
COPY_REPEATED_VALUE(INT32, Int32)
|
||||
COPY_REPEATED_VALUE(INT64, Int64)
|
||||
COPY_REPEATED_VALUE(UINT32, UInt32)
|
||||
COPY_REPEATED_VALUE(UINT64, UInt64)
|
||||
COPY_REPEATED_VALUE(FLOAT, Float)
|
||||
COPY_REPEATED_VALUE(DOUBLE, Double)
|
||||
COPY_REPEATED_VALUE(ENUM, Enum)
|
||||
COPY_REPEATED_VALUE(STRING, String)
|
||||
#undef COPY_REPEATED_VALUE
|
||||
case FieldDescriptor::CPPTYPE_MESSAGE: {
|
||||
int size = source_reflection->FieldSize(source, field);
|
||||
for (int i = 0; i < size; ++i) {
|
||||
destination_reflection->AddMessage(destination, field)
|
||||
->MergeFrom(
|
||||
source_reflection->GetRepeatedMessage(source, field, i));
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
void FieldMaskUtil::ToCanonicalForm(const FieldMask& mask, FieldMask* out) {
|
||||
FieldMaskTree tree;
|
||||
tree.MergeFromFieldMask(mask);
|
||||
out->Clear();
|
||||
tree.MergeToFieldMask(out);
|
||||
}
|
||||
|
||||
void FieldMaskUtil::Union(const FieldMask& mask1, const FieldMask& mask2,
|
||||
FieldMask* out) {
|
||||
FieldMaskTree tree;
|
||||
tree.MergeFromFieldMask(mask1);
|
||||
tree.MergeFromFieldMask(mask2);
|
||||
out->Clear();
|
||||
tree.MergeToFieldMask(out);
|
||||
}
|
||||
|
||||
void FieldMaskUtil::Intersect(const FieldMask& mask1, const FieldMask& mask2,
|
||||
FieldMask* out) {
|
||||
FieldMaskTree tree, intersection;
|
||||
tree.MergeFromFieldMask(mask1);
|
||||
for (int i = 0; i < mask2.paths_size(); ++i) {
|
||||
tree.IntersectPath(mask2.paths(i), &intersection);
|
||||
}
|
||||
out->Clear();
|
||||
intersection.MergeToFieldMask(out);
|
||||
}
|
||||
|
||||
bool FieldMaskUtil::IsPathInFieldMask(const string& path,
|
||||
const FieldMask& mask) {
|
||||
for (int i = 0; i < mask.paths_size(); ++i) {
|
||||
const string& mask_path = mask.paths(i);
|
||||
if (path == mask_path) {
|
||||
return true;
|
||||
} else if (mask_path.length() < path.length()) {
|
||||
// Also check whether mask.paths(i) is a prefix of path.
|
||||
if (path.compare(0, mask_path.length() + 1, mask_path + ".") == 0) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void FieldMaskUtil::MergeMessageTo(const Message& source, const FieldMask& mask,
|
||||
const MergeOptions& options,
|
||||
Message* destination) {
|
||||
GOOGLE_CHECK(source.GetDescriptor() == destination->GetDescriptor());
|
||||
// Build a FieldMaskTree and walk through the tree to merge all specified
|
||||
// fields.
|
||||
FieldMaskTree tree;
|
||||
tree.MergeFromFieldMask(mask);
|
||||
tree.MergeMessage(source, options, destination);
|
||||
}
|
||||
|
||||
} // namespace util
|
||||
} // namespace protobuf
|
||||
} // namespace google
|
146
src/google/protobuf/util/field_mask_util.h
Normal file
146
src/google/protobuf/util/field_mask_util.h
Normal file
@ -0,0 +1,146 @@
|
||||
// Protocol Buffers - Google's data interchange format
|
||||
// Copyright 2008 Google Inc. All rights reserved.
|
||||
// https://developers.google.com/protocol-buffers/
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
#ifndef GOOGLE_PROTOBUF_UTIL_FIELD_MASK_UTIL_H__
|
||||
#define GOOGLE_PROTOBUF_UTIL_FIELD_MASK_UTIL_H__
|
||||
|
||||
#include <string>
|
||||
|
||||
#include <google/protobuf/descriptor.h>
|
||||
#include <google/protobuf/field_mask.pb.h>
|
||||
|
||||
namespace google {
|
||||
namespace protobuf {
|
||||
namespace util {
|
||||
|
||||
class LIBPROTOBUF_EXPORT FieldMaskUtil {
|
||||
typedef google::protobuf::FieldMask FieldMask;
|
||||
|
||||
public:
|
||||
// Converts FieldMask to/from string, formatted according to proto3 JSON
|
||||
// spec for FieldMask (e.g., "foo,bar,baz.quz").
|
||||
static string ToString(const FieldMask& mask);
|
||||
static void FromString(const string& str, FieldMask* out);
|
||||
|
||||
// Checks whether the given path is valid for type T.
|
||||
template <typename T>
|
||||
static bool IsValidPath(const string& path) {
|
||||
return InternalIsValidPath(T::descriptor(), path);
|
||||
}
|
||||
|
||||
// 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 (!InternalIsValidPath(T::descriptor(), mask.paths(i))) 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(const string& path, FieldMask* mask) {
|
||||
GOOGLE_CHECK(IsValidPath<T>(path));
|
||||
mask->add_paths(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 void GetFieldMaskForAllFields(FieldMask* out) {
|
||||
InternalGetFieldMaskForAllFields(T::descriptor(), 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);
|
||||
|
||||
// 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.
|
||||
static bool IsPathInFieldMask(const string& 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);
|
||||
|
||||
private:
|
||||
static bool InternalIsValidPath(const Descriptor* descriptor,
|
||||
const string& path);
|
||||
|
||||
static void InternalGetFieldMaskForAllFields(const Descriptor* descriptor,
|
||||
FieldMask* out);
|
||||
};
|
||||
|
||||
class LIBPROTOBUF_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_;
|
||||
};
|
||||
|
||||
} // namespace util
|
||||
} // namespace protobuf
|
||||
|
||||
} // namespace google
|
||||
#endif // GOOGLE_PROTOBUF_UTIL_FIELD_MASK_UTIL_H__
|
395
src/google/protobuf/util/field_mask_util_test.cc
Normal file
395
src/google/protobuf/util/field_mask_util_test.cc
Normal file
@ -0,0 +1,395 @@
|
||||
// Protocol Buffers - Google's data interchange format
|
||||
// Copyright 2008 Google Inc. All rights reserved.
|
||||
// https://developers.google.com/protocol-buffers/
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
#include <google/protobuf/util/field_mask_util.h>
|
||||
|
||||
#include <google/protobuf/field_mask.pb.h>
|
||||
#include <google/protobuf/unittest.pb.h>
|
||||
#include <google/protobuf/test_util.h>
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
namespace google {
|
||||
namespace protobuf {
|
||||
namespace util {
|
||||
namespace {
|
||||
|
||||
using protobuf_unittest::TestAllTypes;
|
||||
using protobuf_unittest::NestedTestAllTypes;
|
||||
using google::protobuf::FieldMask;
|
||||
|
||||
TEST(FieldMaskUtilTest, StringFormat) {
|
||||
FieldMask mask;
|
||||
EXPECT_EQ("", FieldMaskUtil::ToString(mask));
|
||||
mask.add_paths("foo");
|
||||
EXPECT_EQ("foo", FieldMaskUtil::ToString(mask));
|
||||
mask.add_paths("bar");
|
||||
EXPECT_EQ("foo,bar", FieldMaskUtil::ToString(mask));
|
||||
|
||||
FieldMaskUtil::FromString("", &mask);
|
||||
EXPECT_EQ(0, mask.paths_size());
|
||||
FieldMaskUtil::FromString("foo", &mask);
|
||||
EXPECT_EQ(1, mask.paths_size());
|
||||
EXPECT_EQ("foo", mask.paths(0));
|
||||
FieldMaskUtil::FromString("foo,bar", &mask);
|
||||
EXPECT_EQ(2, mask.paths_size());
|
||||
EXPECT_EQ("foo", mask.paths(0));
|
||||
EXPECT_EQ("bar", mask.paths(1));
|
||||
}
|
||||
|
||||
TEST(FieldMaskUtilTest, TestIsVaildPath) {
|
||||
EXPECT_TRUE(FieldMaskUtil::IsValidPath<TestAllTypes>("optional_int32"));
|
||||
EXPECT_FALSE(FieldMaskUtil::IsValidPath<TestAllTypes>("optional_nonexist"));
|
||||
EXPECT_TRUE(
|
||||
FieldMaskUtil::IsValidPath<TestAllTypes>("optional_nested_message.bb"));
|
||||
EXPECT_FALSE(FieldMaskUtil::IsValidPath<TestAllTypes>(
|
||||
"optional_nested_message.nonexist"));
|
||||
// FieldMask cannot be used to specify sub-fields of a repeated message.
|
||||
EXPECT_FALSE(
|
||||
FieldMaskUtil::IsValidPath<TestAllTypes>("repeated_nested_message.bb"));
|
||||
}
|
||||
|
||||
TEST(FieldMaskUtilTest, TestIsValidFieldMask) {
|
||||
FieldMask mask;
|
||||
FieldMaskUtil::FromString("optional_int32,optional_nested_message.bb", &mask);
|
||||
EXPECT_TRUE(FieldMaskUtil::IsValidFieldMask<TestAllTypes>(mask));
|
||||
|
||||
FieldMaskUtil::FromString(
|
||||
"optional_int32,optional_nested_message.bb,optional_nonexist", &mask);
|
||||
EXPECT_FALSE(FieldMaskUtil::IsValidFieldMask<TestAllTypes>(mask));
|
||||
}
|
||||
|
||||
TEST(FieldMaskUtilTest, TestGetFieldMaskForAllFields) {
|
||||
FieldMask mask;
|
||||
FieldMaskUtil::GetFieldMaskForAllFields<TestAllTypes::NestedMessage>(&mask);
|
||||
EXPECT_EQ(1, mask.paths_size());
|
||||
EXPECT_TRUE(FieldMaskUtil::IsPathInFieldMask("bb", mask));
|
||||
|
||||
FieldMaskUtil::GetFieldMaskForAllFields<TestAllTypes>(&mask);
|
||||
EXPECT_EQ(76, mask.paths_size());
|
||||
EXPECT_TRUE(FieldMaskUtil::IsPathInFieldMask("optional_int32", mask));
|
||||
EXPECT_TRUE(FieldMaskUtil::IsPathInFieldMask("optional_int64", mask));
|
||||
EXPECT_TRUE(FieldMaskUtil::IsPathInFieldMask("optional_uint32", mask));
|
||||
EXPECT_TRUE(FieldMaskUtil::IsPathInFieldMask("optional_uint64", mask));
|
||||
EXPECT_TRUE(FieldMaskUtil::IsPathInFieldMask("optional_sint32", mask));
|
||||
EXPECT_TRUE(FieldMaskUtil::IsPathInFieldMask("optional_sint64", mask));
|
||||
EXPECT_TRUE(FieldMaskUtil::IsPathInFieldMask("optional_fixed32", mask));
|
||||
EXPECT_TRUE(FieldMaskUtil::IsPathInFieldMask("optional_fixed64", mask));
|
||||
EXPECT_TRUE(FieldMaskUtil::IsPathInFieldMask("optional_sfixed32", mask));
|
||||
EXPECT_TRUE(FieldMaskUtil::IsPathInFieldMask("optional_sfixed64", mask));
|
||||
EXPECT_TRUE(FieldMaskUtil::IsPathInFieldMask("optional_float", mask));
|
||||
EXPECT_TRUE(FieldMaskUtil::IsPathInFieldMask("optional_double", mask));
|
||||
EXPECT_TRUE(FieldMaskUtil::IsPathInFieldMask("optional_bool", mask));
|
||||
EXPECT_TRUE(FieldMaskUtil::IsPathInFieldMask("optional_string", mask));
|
||||
EXPECT_TRUE(FieldMaskUtil::IsPathInFieldMask("optional_bytes", mask));
|
||||
EXPECT_TRUE(
|
||||
FieldMaskUtil::IsPathInFieldMask("optional_nested_message", mask));
|
||||
EXPECT_TRUE(
|
||||
FieldMaskUtil::IsPathInFieldMask("optional_foreign_message", mask));
|
||||
EXPECT_TRUE(
|
||||
FieldMaskUtil::IsPathInFieldMask("optional_import_message", mask));
|
||||
EXPECT_TRUE(FieldMaskUtil::IsPathInFieldMask("optional_nested_enum", mask));
|
||||
EXPECT_TRUE(FieldMaskUtil::IsPathInFieldMask("optional_foreign_enum", mask));
|
||||
EXPECT_TRUE(FieldMaskUtil::IsPathInFieldMask("optional_import_enum", mask));
|
||||
EXPECT_TRUE(FieldMaskUtil::IsPathInFieldMask("repeated_int32", mask));
|
||||
EXPECT_TRUE(FieldMaskUtil::IsPathInFieldMask("repeated_int64", mask));
|
||||
EXPECT_TRUE(FieldMaskUtil::IsPathInFieldMask("repeated_uint32", mask));
|
||||
EXPECT_TRUE(FieldMaskUtil::IsPathInFieldMask("repeated_uint64", mask));
|
||||
EXPECT_TRUE(FieldMaskUtil::IsPathInFieldMask("repeated_sint32", mask));
|
||||
EXPECT_TRUE(FieldMaskUtil::IsPathInFieldMask("repeated_sint64", mask));
|
||||
EXPECT_TRUE(FieldMaskUtil::IsPathInFieldMask("repeated_fixed32", mask));
|
||||
EXPECT_TRUE(FieldMaskUtil::IsPathInFieldMask("repeated_fixed64", mask));
|
||||
EXPECT_TRUE(FieldMaskUtil::IsPathInFieldMask("repeated_sfixed32", mask));
|
||||
EXPECT_TRUE(FieldMaskUtil::IsPathInFieldMask("repeated_sfixed64", mask));
|
||||
EXPECT_TRUE(FieldMaskUtil::IsPathInFieldMask("repeated_float", mask));
|
||||
EXPECT_TRUE(FieldMaskUtil::IsPathInFieldMask("repeated_double", mask));
|
||||
EXPECT_TRUE(FieldMaskUtil::IsPathInFieldMask("repeated_bool", mask));
|
||||
EXPECT_TRUE(FieldMaskUtil::IsPathInFieldMask("repeated_string", mask));
|
||||
EXPECT_TRUE(FieldMaskUtil::IsPathInFieldMask("repeated_bytes", mask));
|
||||
EXPECT_TRUE(
|
||||
FieldMaskUtil::IsPathInFieldMask("repeated_nested_message", mask));
|
||||
EXPECT_TRUE(
|
||||
FieldMaskUtil::IsPathInFieldMask("repeated_foreign_message", mask));
|
||||
EXPECT_TRUE(
|
||||
FieldMaskUtil::IsPathInFieldMask("repeated_import_message", mask));
|
||||
EXPECT_TRUE(FieldMaskUtil::IsPathInFieldMask("repeated_nested_enum", mask));
|
||||
EXPECT_TRUE(FieldMaskUtil::IsPathInFieldMask("repeated_foreign_enum", mask));
|
||||
EXPECT_TRUE(FieldMaskUtil::IsPathInFieldMask("repeated_import_enum", mask));
|
||||
}
|
||||
|
||||
TEST(FieldMaskUtilTest, TestToCanonicalForm) {
|
||||
FieldMask in, out;
|
||||
// Paths will be sorted.
|
||||
FieldMaskUtil::FromString("baz.quz,bar,foo", &in);
|
||||
FieldMaskUtil::ToCanonicalForm(in, &out);
|
||||
EXPECT_EQ("bar,baz.quz,foo", FieldMaskUtil::ToString(out));
|
||||
// Duplicated paths will be removed.
|
||||
FieldMaskUtil::FromString("foo,bar,foo", &in);
|
||||
FieldMaskUtil::ToCanonicalForm(in, &out);
|
||||
EXPECT_EQ("bar,foo", FieldMaskUtil::ToString(out));
|
||||
// Sub-paths of other paths will be removed.
|
||||
FieldMaskUtil::FromString("foo.b1,bar.b1,foo.b2,bar", &in);
|
||||
FieldMaskUtil::ToCanonicalForm(in, &out);
|
||||
EXPECT_EQ("bar,foo.b1,foo.b2", FieldMaskUtil::ToString(out));
|
||||
|
||||
// Test more deeply nested cases.
|
||||
FieldMaskUtil::FromString(
|
||||
"foo.bar.baz1,"
|
||||
"foo.bar.baz2.quz,"
|
||||
"foo.bar.baz2",
|
||||
&in);
|
||||
FieldMaskUtil::ToCanonicalForm(in, &out);
|
||||
EXPECT_EQ("foo.bar.baz1,foo.bar.baz2", FieldMaskUtil::ToString(out));
|
||||
FieldMaskUtil::FromString(
|
||||
"foo.bar.baz1,"
|
||||
"foo.bar.baz2,"
|
||||
"foo.bar.baz2.quz",
|
||||
&in);
|
||||
FieldMaskUtil::ToCanonicalForm(in, &out);
|
||||
EXPECT_EQ("foo.bar.baz1,foo.bar.baz2", FieldMaskUtil::ToString(out));
|
||||
FieldMaskUtil::FromString(
|
||||
"foo.bar.baz1,"
|
||||
"foo.bar.baz2,"
|
||||
"foo.bar.baz2.quz,"
|
||||
"foo.bar",
|
||||
&in);
|
||||
FieldMaskUtil::ToCanonicalForm(in, &out);
|
||||
EXPECT_EQ("foo.bar", FieldMaskUtil::ToString(out));
|
||||
FieldMaskUtil::FromString(
|
||||
"foo.bar.baz1,"
|
||||
"foo.bar.baz2,"
|
||||
"foo.bar.baz2.quz,"
|
||||
"foo",
|
||||
&in);
|
||||
FieldMaskUtil::ToCanonicalForm(in, &out);
|
||||
EXPECT_EQ("foo", FieldMaskUtil::ToString(out));
|
||||
}
|
||||
|
||||
TEST(FieldMaskUtilTest, TestUnion) {
|
||||
FieldMask mask1, mask2, out;
|
||||
// Test cases without overlapping.
|
||||
FieldMaskUtil::FromString("foo,baz", &mask1);
|
||||
FieldMaskUtil::FromString("bar,quz", &mask2);
|
||||
FieldMaskUtil::Union(mask1, mask2, &out);
|
||||
EXPECT_EQ("bar,baz,foo,quz", FieldMaskUtil::ToString(out));
|
||||
// Overlap with duplicated paths.
|
||||
FieldMaskUtil::FromString("foo,baz.bb", &mask1);
|
||||
FieldMaskUtil::FromString("baz.bb,quz", &mask2);
|
||||
FieldMaskUtil::Union(mask1, mask2, &out);
|
||||
EXPECT_EQ("baz.bb,foo,quz", FieldMaskUtil::ToString(out));
|
||||
// Overlap with paths covering some other paths.
|
||||
FieldMaskUtil::FromString("foo.bar.baz,quz", &mask1);
|
||||
FieldMaskUtil::FromString("foo.bar,bar", &mask2);
|
||||
FieldMaskUtil::Union(mask1, mask2, &out);
|
||||
EXPECT_EQ("bar,foo.bar,quz", FieldMaskUtil::ToString(out));
|
||||
}
|
||||
|
||||
TEST(FieldMaskUtilTest, TestIntersect) {
|
||||
FieldMask mask1, mask2, out;
|
||||
// Test cases without overlapping.
|
||||
FieldMaskUtil::FromString("foo,baz", &mask1);
|
||||
FieldMaskUtil::FromString("bar,quz", &mask2);
|
||||
FieldMaskUtil::Intersect(mask1, mask2, &out);
|
||||
EXPECT_EQ("", FieldMaskUtil::ToString(out));
|
||||
// Overlap with duplicated paths.
|
||||
FieldMaskUtil::FromString("foo,baz.bb", &mask1);
|
||||
FieldMaskUtil::FromString("baz.bb,quz", &mask2);
|
||||
FieldMaskUtil::Intersect(mask1, mask2, &out);
|
||||
EXPECT_EQ("baz.bb", FieldMaskUtil::ToString(out));
|
||||
// Overlap with paths covering some other paths.
|
||||
FieldMaskUtil::FromString("foo.bar.baz,quz", &mask1);
|
||||
FieldMaskUtil::FromString("foo.bar,bar", &mask2);
|
||||
FieldMaskUtil::Intersect(mask1, mask2, &out);
|
||||
EXPECT_EQ("foo.bar.baz", FieldMaskUtil::ToString(out));
|
||||
}
|
||||
|
||||
TEST(FieldMaskUtilTest, TestIspathInFieldMask) {
|
||||
FieldMask mask;
|
||||
FieldMaskUtil::FromString("foo.bar", &mask);
|
||||
EXPECT_FALSE(FieldMaskUtil::IsPathInFieldMask("", mask));
|
||||
EXPECT_FALSE(FieldMaskUtil::IsPathInFieldMask("foo", mask));
|
||||
EXPECT_TRUE(FieldMaskUtil::IsPathInFieldMask("foo.bar", mask));
|
||||
EXPECT_TRUE(FieldMaskUtil::IsPathInFieldMask("foo.bar.baz", mask));
|
||||
EXPECT_FALSE(FieldMaskUtil::IsPathInFieldMask("foo.bar0.baz", mask));
|
||||
}
|
||||
|
||||
TEST(FieldMaskUtilTest, MergeMessage) {
|
||||
TestAllTypes src, dst;
|
||||
TestUtil::SetAllFields(&src);
|
||||
FieldMaskUtil::MergeOptions options;
|
||||
|
||||
#define TEST_MERGE_ONE_PRIMITIVE_FIELD(field_name) \
|
||||
{ \
|
||||
TestAllTypes tmp; \
|
||||
tmp.set_##field_name(src.field_name()); \
|
||||
FieldMask mask; \
|
||||
mask.add_paths(#field_name); \
|
||||
dst.Clear(); \
|
||||
FieldMaskUtil::MergeMessageTo(src, mask, options, &dst); \
|
||||
EXPECT_EQ(tmp.DebugString(), dst.DebugString()); \
|
||||
}
|
||||
TEST_MERGE_ONE_PRIMITIVE_FIELD(optional_int32)
|
||||
TEST_MERGE_ONE_PRIMITIVE_FIELD(optional_int64)
|
||||
TEST_MERGE_ONE_PRIMITIVE_FIELD(optional_uint32)
|
||||
TEST_MERGE_ONE_PRIMITIVE_FIELD(optional_uint64)
|
||||
TEST_MERGE_ONE_PRIMITIVE_FIELD(optional_sint32)
|
||||
TEST_MERGE_ONE_PRIMITIVE_FIELD(optional_sint64)
|
||||
TEST_MERGE_ONE_PRIMITIVE_FIELD(optional_fixed32)
|
||||
TEST_MERGE_ONE_PRIMITIVE_FIELD(optional_fixed64)
|
||||
TEST_MERGE_ONE_PRIMITIVE_FIELD(optional_sfixed32)
|
||||
TEST_MERGE_ONE_PRIMITIVE_FIELD(optional_sfixed64)
|
||||
TEST_MERGE_ONE_PRIMITIVE_FIELD(optional_float)
|
||||
TEST_MERGE_ONE_PRIMITIVE_FIELD(optional_double)
|
||||
TEST_MERGE_ONE_PRIMITIVE_FIELD(optional_bool)
|
||||
TEST_MERGE_ONE_PRIMITIVE_FIELD(optional_string)
|
||||
TEST_MERGE_ONE_PRIMITIVE_FIELD(optional_bytes)
|
||||
TEST_MERGE_ONE_PRIMITIVE_FIELD(optional_nested_enum)
|
||||
TEST_MERGE_ONE_PRIMITIVE_FIELD(optional_foreign_enum)
|
||||
TEST_MERGE_ONE_PRIMITIVE_FIELD(optional_import_enum)
|
||||
#undef TEST_MERGE_ONE_PRIMITIVE_FIELD
|
||||
|
||||
#define TEST_MERGE_ONE_FIELD(field_name) \
|
||||
{ \
|
||||
TestAllTypes tmp; \
|
||||
*tmp.mutable_##field_name() = src.field_name(); \
|
||||
FieldMask mask; \
|
||||
mask.add_paths(#field_name); \
|
||||
dst.Clear(); \
|
||||
FieldMaskUtil::MergeMessageTo(src, mask, options, &dst); \
|
||||
EXPECT_EQ(tmp.DebugString(), dst.DebugString()); \
|
||||
}
|
||||
TEST_MERGE_ONE_FIELD(optional_nested_message)
|
||||
TEST_MERGE_ONE_FIELD(optional_foreign_message)
|
||||
TEST_MERGE_ONE_FIELD(optional_import_message)
|
||||
|
||||
TEST_MERGE_ONE_FIELD(repeated_int32)
|
||||
TEST_MERGE_ONE_FIELD(repeated_int64)
|
||||
TEST_MERGE_ONE_FIELD(repeated_uint32)
|
||||
TEST_MERGE_ONE_FIELD(repeated_uint64)
|
||||
TEST_MERGE_ONE_FIELD(repeated_sint32)
|
||||
TEST_MERGE_ONE_FIELD(repeated_sint64)
|
||||
TEST_MERGE_ONE_FIELD(repeated_fixed32)
|
||||
TEST_MERGE_ONE_FIELD(repeated_fixed64)
|
||||
TEST_MERGE_ONE_FIELD(repeated_sfixed32)
|
||||
TEST_MERGE_ONE_FIELD(repeated_sfixed64)
|
||||
TEST_MERGE_ONE_FIELD(repeated_float)
|
||||
TEST_MERGE_ONE_FIELD(repeated_double)
|
||||
TEST_MERGE_ONE_FIELD(repeated_bool)
|
||||
TEST_MERGE_ONE_FIELD(repeated_string)
|
||||
TEST_MERGE_ONE_FIELD(repeated_bytes)
|
||||
TEST_MERGE_ONE_FIELD(repeated_nested_message)
|
||||
TEST_MERGE_ONE_FIELD(repeated_foreign_message)
|
||||
TEST_MERGE_ONE_FIELD(repeated_import_message)
|
||||
TEST_MERGE_ONE_FIELD(repeated_nested_enum)
|
||||
TEST_MERGE_ONE_FIELD(repeated_foreign_enum)
|
||||
TEST_MERGE_ONE_FIELD(repeated_import_enum)
|
||||
#undef TEST_MERGE_ONE_FIELD
|
||||
|
||||
// Test merge nested fields.
|
||||
NestedTestAllTypes nested_src, nested_dst;
|
||||
nested_src.mutable_child()->mutable_payload()->set_optional_int32(1234);
|
||||
nested_src.mutable_child()
|
||||
->mutable_child()
|
||||
->mutable_payload()
|
||||
->set_optional_int32(5678);
|
||||
FieldMask mask;
|
||||
FieldMaskUtil::FromString("child.payload", &mask);
|
||||
FieldMaskUtil::MergeMessageTo(nested_src, mask, options, &nested_dst);
|
||||
EXPECT_EQ(1234, nested_dst.child().payload().optional_int32());
|
||||
EXPECT_EQ(0, nested_dst.child().child().payload().optional_int32());
|
||||
|
||||
FieldMaskUtil::FromString("child.child.payload", &mask);
|
||||
FieldMaskUtil::MergeMessageTo(nested_src, mask, options, &nested_dst);
|
||||
EXPECT_EQ(1234, nested_dst.child().payload().optional_int32());
|
||||
EXPECT_EQ(5678, nested_dst.child().child().payload().optional_int32());
|
||||
|
||||
nested_dst.Clear();
|
||||
FieldMaskUtil::FromString("child.child.payload", &mask);
|
||||
FieldMaskUtil::MergeMessageTo(nested_src, mask, options, &nested_dst);
|
||||
EXPECT_EQ(0, nested_dst.child().payload().optional_int32());
|
||||
EXPECT_EQ(5678, nested_dst.child().child().payload().optional_int32());
|
||||
|
||||
nested_dst.Clear();
|
||||
FieldMaskUtil::FromString("child", &mask);
|
||||
FieldMaskUtil::MergeMessageTo(nested_src, mask, options, &nested_dst);
|
||||
EXPECT_EQ(1234, nested_dst.child().payload().optional_int32());
|
||||
EXPECT_EQ(5678, nested_dst.child().child().payload().optional_int32());
|
||||
|
||||
// Test MergeOptions.
|
||||
|
||||
nested_dst.Clear();
|
||||
nested_dst.mutable_child()->mutable_payload()->set_optional_int64(4321);
|
||||
// Message fields will be merged by default.
|
||||
FieldMaskUtil::FromString("child.payload", &mask);
|
||||
FieldMaskUtil::MergeMessageTo(nested_src, mask, options, &nested_dst);
|
||||
EXPECT_EQ(1234, nested_dst.child().payload().optional_int32());
|
||||
EXPECT_EQ(4321, nested_dst.child().payload().optional_int64());
|
||||
// Change the behavior to replace message fields.
|
||||
options.set_replace_message_fields(true);
|
||||
FieldMaskUtil::FromString("child.payload", &mask);
|
||||
FieldMaskUtil::MergeMessageTo(nested_src, mask, options, &nested_dst);
|
||||
EXPECT_EQ(1234, nested_dst.child().payload().optional_int32());
|
||||
EXPECT_EQ(0, nested_dst.child().payload().optional_int64());
|
||||
|
||||
// By default, fields missing in source are not cleared in destination.
|
||||
options.set_replace_message_fields(false);
|
||||
nested_dst.mutable_payload();
|
||||
EXPECT_TRUE(nested_dst.has_payload());
|
||||
FieldMaskUtil::FromString("payload", &mask);
|
||||
FieldMaskUtil::MergeMessageTo(nested_src, mask, options, &nested_dst);
|
||||
EXPECT_TRUE(nested_dst.has_payload());
|
||||
// But they are cleared when replacing message fields.
|
||||
options.set_replace_message_fields(true);
|
||||
nested_dst.Clear();
|
||||
nested_dst.mutable_payload();
|
||||
FieldMaskUtil::FromString("payload", &mask);
|
||||
FieldMaskUtil::MergeMessageTo(nested_src, mask, options, &nested_dst);
|
||||
EXPECT_FALSE(nested_dst.has_payload());
|
||||
|
||||
nested_src.mutable_payload()->add_repeated_int32(1234);
|
||||
nested_dst.mutable_payload()->add_repeated_int32(5678);
|
||||
// Repeated fields will be appended by default.
|
||||
FieldMaskUtil::FromString("payload.repeated_int32", &mask);
|
||||
FieldMaskUtil::MergeMessageTo(nested_src, mask, options, &nested_dst);
|
||||
ASSERT_EQ(2, nested_dst.payload().repeated_int32_size());
|
||||
EXPECT_EQ(5678, nested_dst.payload().repeated_int32(0));
|
||||
EXPECT_EQ(1234, nested_dst.payload().repeated_int32(1));
|
||||
// Change the behavior to replace repeated fields.
|
||||
options.set_replace_repeated_fields(true);
|
||||
FieldMaskUtil::FromString("payload.repeated_int32", &mask);
|
||||
FieldMaskUtil::MergeMessageTo(nested_src, mask, options, &nested_dst);
|
||||
ASSERT_EQ(1, nested_dst.payload().repeated_int32_size());
|
||||
EXPECT_EQ(1234, nested_dst.payload().repeated_int32(0));
|
||||
}
|
||||
|
||||
|
||||
} // namespace
|
||||
} // namespace util
|
||||
} // namespace protobuf
|
||||
} // namespace google
|
68
src/google/protobuf/util/internal/testdata/oneofs.proto
vendored
Normal file
68
src/google/protobuf/util/internal/testdata/oneofs.proto
vendored
Normal file
@ -0,0 +1,68 @@
|
||||
// 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.
|
||||
|
||||
// Proto to test oneofs.
|
||||
syntax = "proto3";
|
||||
|
||||
import "google/protobuf/any.proto";
|
||||
import "google/protobuf/struct.proto";
|
||||
import "google/protobuf/timestamp.proto";
|
||||
|
||||
package google.protobuf.testing.oneofs;
|
||||
option java_package = "com.google.protobuf.testing.oneofs";
|
||||
|
||||
message OneOfsRequest {
|
||||
string value = 1;
|
||||
oneof data {
|
||||
string str_data = 2;
|
||||
int32 int_data = 3;
|
||||
// Simple message
|
||||
Data message_data = 4;
|
||||
// Well known types
|
||||
google.protobuf.Struct struct_data = 5;
|
||||
google.protobuf.Value value_data = 6;
|
||||
google.protobuf.ListValue list_value_data = 7;
|
||||
google.protobuf.Timestamp ts_data = 8;
|
||||
}
|
||||
google.protobuf.Any any_data = 19;
|
||||
}
|
||||
|
||||
message Data {
|
||||
int32 data_value = 1;
|
||||
}
|
||||
|
||||
message Response {
|
||||
string value = 1;
|
||||
}
|
||||
|
||||
service TestService {
|
||||
// Test call.
|
||||
rpc Call(OneOfsRequest) returns (Response);
|
||||
}
|
525
src/google/protobuf/util/time_util.cc
Normal file
525
src/google/protobuf/util/time_util.cc
Normal file
@ -0,0 +1,525 @@
|
||||
// Protocol Buffers - Google's data interchange format
|
||||
// Copyright 2008 Google Inc. All rights reserved.
|
||||
// https://developers.google.com/protocol-buffers/
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
#include <google/protobuf/util/time_util.h>
|
||||
|
||||
#include <google/protobuf/stubs/time.h>
|
||||
#include <google/protobuf/stubs/int128.h>
|
||||
#include <google/protobuf/stubs/strutil.h>
|
||||
#include <google/protobuf/stubs/stringprintf.h>
|
||||
#include <google/protobuf/duration.pb.h>
|
||||
#include <google/protobuf/timestamp.pb.h>
|
||||
|
||||
namespace google {
|
||||
namespace protobuf {
|
||||
namespace util {
|
||||
|
||||
using google::protobuf::Timestamp;
|
||||
using google::protobuf::Duration;
|
||||
|
||||
namespace {
|
||||
static const int kNanosPerSecond = 1000000000;
|
||||
static const int kMicrosPerSecond = 1000000;
|
||||
static const int kMillisPerSecond = 1000;
|
||||
static const int kNanosPerMillisecond = 1000000;
|
||||
static const int kMicrosPerMillisecond = 1000;
|
||||
static const int kNanosPerMicrosecond = 1000;
|
||||
static const int kSecondsPerMinute = 60; // Note that we ignore leap seconds.
|
||||
static const int kSecondsPerHour = 3600;
|
||||
static const char kTimestampFormat[] = "%E4Y-%m-%dT%H:%M:%S";
|
||||
|
||||
template <typename T>
|
||||
T CreateNormalized(int64 seconds, int64 nanos);
|
||||
|
||||
template <>
|
||||
Timestamp CreateNormalized(int64 seconds, int64 nanos) {
|
||||
// Make sure nanos is in the range.
|
||||
if (nanos <= -kNanosPerSecond || nanos >= kNanosPerSecond) {
|
||||
seconds += nanos / kNanosPerSecond;
|
||||
nanos = nanos % kNanosPerSecond;
|
||||
}
|
||||
// For Timestamp nanos should be in the range [0, 999999999]
|
||||
if (nanos < 0) {
|
||||
seconds -= 1;
|
||||
nanos += kNanosPerSecond;
|
||||
}
|
||||
GOOGLE_DCHECK(seconds >= TimeUtil::kTimestampMinSeconds &&
|
||||
seconds <= TimeUtil::kTimestampMaxSeconds);
|
||||
Timestamp result;
|
||||
result.set_seconds(seconds);
|
||||
result.set_nanos(static_cast<int32>(nanos));
|
||||
return result;
|
||||
}
|
||||
|
||||
template <>
|
||||
Duration CreateNormalized(int64 seconds, int64 nanos) {
|
||||
// Make sure nanos is in the range.
|
||||
if (nanos <= -kNanosPerSecond || nanos >= kNanosPerSecond) {
|
||||
seconds += nanos / kNanosPerSecond;
|
||||
nanos = nanos % kNanosPerSecond;
|
||||
}
|
||||
// nanos should have the same sign as seconds.
|
||||
if (seconds < 0 && nanos > 0) {
|
||||
seconds += 1;
|
||||
nanos -= kNanosPerSecond;
|
||||
} else if (seconds > 0 && nanos < 0) {
|
||||
seconds -= 1;
|
||||
nanos += kNanosPerSecond;
|
||||
}
|
||||
GOOGLE_DCHECK(seconds >= TimeUtil::kDurationMinSeconds &&
|
||||
seconds <= TimeUtil::kDurationMaxSeconds);
|
||||
Duration result;
|
||||
result.set_seconds(seconds);
|
||||
result.set_nanos(static_cast<int32>(nanos));
|
||||
return result;
|
||||
}
|
||||
|
||||
// Format nanoseconds with either 3, 6, or 9 digits depending on the required
|
||||
// precision to represent the exact value.
|
||||
string FormatNanos(int32 nanos) {
|
||||
if (nanos % kNanosPerMillisecond == 0) {
|
||||
return StringPrintf("%03d", nanos / kNanosPerMillisecond);
|
||||
} else if (nanos % kNanosPerMicrosecond == 0) {
|
||||
return StringPrintf("%06d", nanos / kNanosPerMicrosecond);
|
||||
} else {
|
||||
return StringPrintf("%09d", nanos);
|
||||
}
|
||||
}
|
||||
|
||||
string FormatTime(int64 seconds, int32 nanos) {
|
||||
return ::google::protobuf::internal::FormatTime(seconds, nanos);
|
||||
}
|
||||
|
||||
bool ParseTime(const string& value, int64* seconds, int32* nanos) {
|
||||
return ::google::protobuf::internal::ParseTime(value, seconds, nanos);
|
||||
}
|
||||
|
||||
void CurrentTime(int64* seconds, int32* nanos) {
|
||||
return ::google::protobuf::internal::GetCurrentTime(seconds, nanos);
|
||||
}
|
||||
|
||||
// Truncates the remainder part after division.
|
||||
int64 RoundTowardZero(int64 value, int64 divider) {
|
||||
int64 result = value / divider;
|
||||
int64 remainder = value % divider;
|
||||
// Before C++11, the sign of the remainder is implementation dependent if
|
||||
// any of the operands is negative. Here we try to enforce C++11's "rounded
|
||||
// toward zero" semantics. For example, for (-5) / 2 an implementation may
|
||||
// give -3 as the result with the remainder being 1. This function ensures
|
||||
// we always return -2 (closer to zero) regardless of the implementation.
|
||||
if (result < 0 && remainder > 0) {
|
||||
return result + 1;
|
||||
} else {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
} // namespace
|
||||
|
||||
string TimeUtil::ToString(const Timestamp& timestamp) {
|
||||
return FormatTime(timestamp.seconds(), timestamp.nanos());
|
||||
}
|
||||
|
||||
bool TimeUtil::FromString(const string& value, Timestamp* timestamp) {
|
||||
int64 seconds;
|
||||
int32 nanos;
|
||||
if (!ParseTime(value, &seconds, &nanos)) {
|
||||
return false;
|
||||
}
|
||||
*timestamp = CreateNormalized<Timestamp>(seconds, nanos);
|
||||
return true;
|
||||
}
|
||||
|
||||
Timestamp TimeUtil::GetCurrentTime() {
|
||||
int64 seconds;
|
||||
int32 nanos;
|
||||
CurrentTime(&seconds, &nanos);
|
||||
return CreateNormalized<Timestamp>(seconds, nanos);
|
||||
}
|
||||
|
||||
Timestamp TimeUtil::GetEpoch() { return Timestamp(); }
|
||||
|
||||
string TimeUtil::ToString(const Duration& duration) {
|
||||
string result;
|
||||
int64 seconds = duration.seconds();
|
||||
int32 nanos = duration.nanos();
|
||||
if (seconds < 0 || nanos < 0) {
|
||||
result += "-";
|
||||
seconds = -seconds;
|
||||
nanos = -nanos;
|
||||
}
|
||||
result += StringPrintf("%" GOOGLE_LL_FORMAT "d", seconds);
|
||||
if (nanos != 0) {
|
||||
result += "." + FormatNanos(nanos);
|
||||
}
|
||||
result += "s";
|
||||
return result;
|
||||
}
|
||||
|
||||
static int64 Pow(int64 x, int y) {
|
||||
int64 result = 1;
|
||||
for (int i = 0; i < y; ++i) {
|
||||
result *= x;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
bool TimeUtil::FromString(const string& value, Duration* duration) {
|
||||
if (value.length() <= 1 || value[value.length() - 1] != 's') {
|
||||
return false;
|
||||
}
|
||||
bool negative = (value[0] == '-');
|
||||
int sign_length = (negative ? 1 : 0);
|
||||
// Parse the duration value as two integers rather than a float value
|
||||
// to avoid precision loss.
|
||||
string seconds_part, nanos_part;
|
||||
size_t pos = value.find_last_of(".");
|
||||
if (pos == string::npos) {
|
||||
seconds_part = value.substr(sign_length, value.length() - 1 - sign_length);
|
||||
nanos_part = "0";
|
||||
} else {
|
||||
seconds_part = value.substr(sign_length, pos - sign_length);
|
||||
nanos_part = value.substr(pos + 1, value.length() - pos - 2);
|
||||
}
|
||||
char* end;
|
||||
int64 seconds = strto64(seconds_part.c_str(), &end, 10);
|
||||
if (end != seconds_part.c_str() + seconds_part.length()) {
|
||||
return false;
|
||||
}
|
||||
int64 nanos = strto64(nanos_part.c_str(), &end, 10);
|
||||
if (end != nanos_part.c_str() + nanos_part.length()) {
|
||||
return false;
|
||||
}
|
||||
nanos = nanos * Pow(10, 9 - nanos_part.length());
|
||||
if (negative) {
|
||||
// If a Duration is negative, both seconds and nanos should be negative.
|
||||
seconds = -seconds;
|
||||
nanos = -nanos;
|
||||
}
|
||||
duration->set_seconds(seconds);
|
||||
duration->set_nanos(static_cast<int32>(nanos));
|
||||
return true;
|
||||
}
|
||||
|
||||
Duration TimeUtil::NanosecondsToDuration(int64 nanos) {
|
||||
return CreateNormalized<Duration>(nanos / kNanosPerSecond,
|
||||
nanos % kNanosPerSecond);
|
||||
}
|
||||
|
||||
Duration TimeUtil::MicrosecondsToDuration(int64 micros) {
|
||||
return CreateNormalized<Duration>(
|
||||
micros / kMicrosPerSecond,
|
||||
(micros % kMicrosPerSecond) * kNanosPerMicrosecond);
|
||||
}
|
||||
|
||||
Duration TimeUtil::MillisecondsToDuration(int64 millis) {
|
||||
return CreateNormalized<Duration>(
|
||||
millis / kMillisPerSecond,
|
||||
(millis % kMillisPerSecond) * kNanosPerMillisecond);
|
||||
}
|
||||
|
||||
Duration TimeUtil::SecondsToDuration(int64 seconds) {
|
||||
return CreateNormalized<Duration>(seconds, 0);
|
||||
}
|
||||
|
||||
Duration TimeUtil::MinutesToDuration(int64 minutes) {
|
||||
return CreateNormalized<Duration>(minutes * kSecondsPerMinute, 0);
|
||||
}
|
||||
|
||||
Duration TimeUtil::HoursToDuration(int64 hours) {
|
||||
return CreateNormalized<Duration>(hours * kSecondsPerHour, 0);
|
||||
}
|
||||
|
||||
int64 TimeUtil::DurationToNanoseconds(const Duration& duration) {
|
||||
return duration.seconds() * kNanosPerSecond + duration.nanos();
|
||||
}
|
||||
|
||||
int64 TimeUtil::DurationToMicroseconds(const Duration& duration) {
|
||||
return duration.seconds() * kMicrosPerSecond +
|
||||
RoundTowardZero(duration.nanos(), kNanosPerMicrosecond);
|
||||
}
|
||||
|
||||
int64 TimeUtil::DurationToMilliseconds(const Duration& duration) {
|
||||
return duration.seconds() * kMillisPerSecond +
|
||||
RoundTowardZero(duration.nanos(), kNanosPerMillisecond);
|
||||
}
|
||||
|
||||
int64 TimeUtil::DurationToSeconds(const Duration& duration) {
|
||||
return duration.seconds();
|
||||
}
|
||||
|
||||
int64 TimeUtil::DurationToMinutes(const Duration& duration) {
|
||||
return RoundTowardZero(duration.seconds(), kSecondsPerMinute);
|
||||
}
|
||||
|
||||
int64 TimeUtil::DurationToHours(const Duration& duration) {
|
||||
return RoundTowardZero(duration.seconds(), kSecondsPerHour);
|
||||
}
|
||||
|
||||
Timestamp TimeUtil::NanosecondsToTimestamp(int64 nanos) {
|
||||
return CreateNormalized<Timestamp>(nanos / kNanosPerSecond,
|
||||
nanos % kNanosPerSecond);
|
||||
}
|
||||
|
||||
Timestamp TimeUtil::MicrosecondsToTimestamp(int64 micros) {
|
||||
return CreateNormalized<Timestamp>(
|
||||
micros / kMicrosPerSecond,
|
||||
micros % kMicrosPerSecond * kNanosPerMicrosecond);
|
||||
}
|
||||
|
||||
Timestamp TimeUtil::MillisecondsToTimestamp(int64 millis) {
|
||||
return CreateNormalized<Timestamp>(
|
||||
millis / kMillisPerSecond,
|
||||
millis % kMillisPerSecond * kNanosPerMillisecond);
|
||||
}
|
||||
|
||||
Timestamp TimeUtil::SecondsToTimestamp(int64 seconds) {
|
||||
return CreateNormalized<Timestamp>(seconds, 0);
|
||||
}
|
||||
|
||||
int64 TimeUtil::TimestampToNanoseconds(const Timestamp& timestamp) {
|
||||
return timestamp.seconds() * kNanosPerSecond + timestamp.nanos();
|
||||
}
|
||||
|
||||
int64 TimeUtil::TimestampToMicroseconds(const Timestamp& timestamp) {
|
||||
return timestamp.seconds() * kMicrosPerSecond +
|
||||
RoundTowardZero(timestamp.nanos(), kNanosPerMicrosecond);
|
||||
}
|
||||
|
||||
int64 TimeUtil::TimestampToMilliseconds(const Timestamp& timestamp) {
|
||||
return timestamp.seconds() * kMillisPerSecond +
|
||||
RoundTowardZero(timestamp.nanos(), kNanosPerMillisecond);
|
||||
}
|
||||
|
||||
int64 TimeUtil::TimestampToSeconds(const Timestamp& timestamp) {
|
||||
return timestamp.seconds();
|
||||
}
|
||||
|
||||
Timestamp TimeUtil::TimeTToTimestamp(time_t value) {
|
||||
return CreateNormalized<Timestamp>(static_cast<int64>(value), 0);
|
||||
}
|
||||
|
||||
time_t TimeUtil::TimestampToTimeT(const Timestamp& value) {
|
||||
return static_cast<time_t>(value.seconds());
|
||||
}
|
||||
|
||||
Timestamp TimeUtil::TimevalToTimestamp(const timeval& value) {
|
||||
return CreateNormalized<Timestamp>(value.tv_sec,
|
||||
value.tv_usec * kNanosPerMicrosecond);
|
||||
}
|
||||
|
||||
timeval TimeUtil::TimestampToTimeval(const Timestamp& value) {
|
||||
timeval result;
|
||||
result.tv_sec = value.seconds();
|
||||
result.tv_usec = RoundTowardZero(value.nanos(), kNanosPerMicrosecond);
|
||||
return result;
|
||||
}
|
||||
|
||||
Duration TimeUtil::TimevalToDuration(const timeval& value) {
|
||||
return CreateNormalized<Duration>(value.tv_sec,
|
||||
value.tv_usec * kNanosPerMicrosecond);
|
||||
}
|
||||
|
||||
timeval TimeUtil::DurationToTimeval(const Duration& value) {
|
||||
timeval result;
|
||||
result.tv_sec = value.seconds();
|
||||
result.tv_usec = RoundTowardZero(value.nanos(), kNanosPerMicrosecond);
|
||||
// timeval.tv_usec's range is [0, 1000000)
|
||||
if (result.tv_usec < 0) {
|
||||
result.tv_sec -= 1;
|
||||
result.tv_usec += kMicrosPerSecond;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
} // namespace util
|
||||
} // namespace protobuf
|
||||
|
||||
|
||||
namespace protobuf {
|
||||
namespace {
|
||||
using google::protobuf::util::kNanosPerSecond;
|
||||
using google::protobuf::util::CreateNormalized;
|
||||
|
||||
// Convert a Timestamp to uint128.
|
||||
void ToUint128(const Timestamp& value, uint128* result, bool* negative) {
|
||||
if (value.seconds() < 0) {
|
||||
*negative = true;
|
||||
*result = static_cast<uint64>(-value.seconds());
|
||||
*result = *result * kNanosPerSecond - static_cast<uint32>(value.nanos());
|
||||
} else {
|
||||
*negative = false;
|
||||
*result = static_cast<uint64>(value.seconds());
|
||||
*result = *result * kNanosPerSecond + static_cast<uint32>(value.nanos());
|
||||
}
|
||||
}
|
||||
|
||||
// Convert a Duration to uint128.
|
||||
void ToUint128(const Duration& value, uint128* result, bool* negative) {
|
||||
if (value.seconds() < 0 || value.nanos() < 0) {
|
||||
*negative = true;
|
||||
*result = static_cast<uint64>(-value.seconds());
|
||||
*result = *result * kNanosPerSecond + static_cast<uint32>(-value.nanos());
|
||||
} else {
|
||||
*negative = false;
|
||||
*result = static_cast<uint64>(value.seconds());
|
||||
*result = *result * kNanosPerSecond + static_cast<uint32>(value.nanos());
|
||||
}
|
||||
}
|
||||
|
||||
void ToTimestamp(const uint128& value, bool negative, Timestamp* timestamp) {
|
||||
int64 seconds = static_cast<int64>(Uint128Low64(value / kNanosPerSecond));
|
||||
int32 nanos = static_cast<int32>(Uint128Low64(value % kNanosPerSecond));
|
||||
if (negative) {
|
||||
seconds = -seconds;
|
||||
nanos = -nanos;
|
||||
if (nanos < 0) {
|
||||
nanos += kNanosPerSecond;
|
||||
seconds -= 1;
|
||||
}
|
||||
}
|
||||
timestamp->set_seconds(seconds);
|
||||
timestamp->set_nanos(nanos);
|
||||
}
|
||||
|
||||
void ToDuration(const uint128& value, bool negative, Duration* duration) {
|
||||
int64 seconds = static_cast<int64>(Uint128Low64(value / kNanosPerSecond));
|
||||
int32 nanos = static_cast<int32>(Uint128Low64(value % kNanosPerSecond));
|
||||
if (negative) {
|
||||
seconds = -seconds;
|
||||
nanos = -nanos;
|
||||
}
|
||||
duration->set_seconds(seconds);
|
||||
duration->set_nanos(nanos);
|
||||
}
|
||||
} // namespace
|
||||
|
||||
Duration& operator+=(Duration& d1, const Duration& d2) {
|
||||
d1 = CreateNormalized<Duration>(d1.seconds() + d2.seconds(),
|
||||
d1.nanos() + d2.nanos());
|
||||
return d1;
|
||||
}
|
||||
|
||||
Duration& operator-=(Duration& d1, const Duration& d2) { // NOLINT
|
||||
d1 = CreateNormalized<Duration>(d1.seconds() - d2.seconds(),
|
||||
d1.nanos() - d2.nanos());
|
||||
return d1;
|
||||
}
|
||||
|
||||
Duration& operator*=(Duration& d, int64 r) { // NOLINT
|
||||
bool negative;
|
||||
uint128 value;
|
||||
ToUint128(d, &value, &negative);
|
||||
if (r > 0) {
|
||||
value *= static_cast<uint64>(r);
|
||||
} else {
|
||||
negative = !negative;
|
||||
value *= static_cast<uint64>(-r);
|
||||
}
|
||||
ToDuration(value, negative, &d);
|
||||
return d;
|
||||
}
|
||||
|
||||
Duration& operator*=(Duration& d, double r) { // NOLINT
|
||||
double result = (d.seconds() * 1.0 + 1.0 * d.nanos() / kNanosPerSecond) * r;
|
||||
int64 seconds = static_cast<int64>(result);
|
||||
int32 nanos = static_cast<int32>((result - seconds) * kNanosPerSecond);
|
||||
// Note that we normalize here not just because nanos can have a different
|
||||
// sign from seconds but also that nanos can be any arbitrary value when
|
||||
// overflow happens (i.e., the result is a much larger value than what
|
||||
// int64 can represent).
|
||||
d = CreateNormalized<Duration>(seconds, nanos);
|
||||
return d;
|
||||
}
|
||||
|
||||
Duration& operator/=(Duration& d, int64 r) { // NOLINT
|
||||
bool negative;
|
||||
uint128 value;
|
||||
ToUint128(d, &value, &negative);
|
||||
if (r > 0) {
|
||||
value /= static_cast<uint64>(r);
|
||||
} else {
|
||||
negative = !negative;
|
||||
value /= static_cast<uint64>(-r);
|
||||
}
|
||||
ToDuration(value, negative, &d);
|
||||
return d;
|
||||
}
|
||||
|
||||
Duration& operator/=(Duration& d, double r) { // NOLINT
|
||||
return d *= 1.0 / r;
|
||||
}
|
||||
|
||||
Duration& operator%=(Duration& d1, const Duration& d2) { // NOLINT
|
||||
bool negative1, negative2;
|
||||
uint128 value1, value2;
|
||||
ToUint128(d1, &value1, &negative1);
|
||||
ToUint128(d2, &value2, &negative2);
|
||||
uint128 result = value1 % value2;
|
||||
// When negative values are involved in division, we round the division
|
||||
// result towards zero. With this semantics, sign of the remainder is the
|
||||
// same as the dividend. For example:
|
||||
// -5 / 10 = 0, -5 % 10 = -5
|
||||
// -5 / (-10) = 0, -5 % (-10) = -5
|
||||
// 5 / (-10) = 0, 5 % (-10) = 5
|
||||
ToDuration(result, negative1, &d1);
|
||||
return d1;
|
||||
}
|
||||
|
||||
int64 operator/(const Duration& d1, const Duration& d2) {
|
||||
bool negative1, negative2;
|
||||
uint128 value1, value2;
|
||||
ToUint128(d1, &value1, &negative1);
|
||||
ToUint128(d2, &value2, &negative2);
|
||||
int64 result = Uint128Low64(value1 / value2);
|
||||
if (negative1 != negative2) {
|
||||
result = -result;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
Timestamp& operator+=(Timestamp& t, const Duration& d) { // NOLINT
|
||||
t = CreateNormalized<Timestamp>(t.seconds() + d.seconds(),
|
||||
t.nanos() + d.nanos());
|
||||
return t;
|
||||
}
|
||||
|
||||
Timestamp& operator-=(Timestamp& t, const Duration& d) { // NOLINT
|
||||
t = CreateNormalized<Timestamp>(t.seconds() - d.seconds(),
|
||||
t.nanos() - d.nanos());
|
||||
return t;
|
||||
}
|
||||
|
||||
Duration operator-(const Timestamp& t1, const Timestamp& t2) {
|
||||
return CreateNormalized<Duration>(t1.seconds() - t2.seconds(),
|
||||
t1.nanos() - t2.nanos());
|
||||
}
|
||||
} // namespace protobuf
|
||||
|
||||
} // namespace google
|
287
src/google/protobuf/util/time_util.h
Normal file
287
src/google/protobuf/util/time_util.h
Normal file
@ -0,0 +1,287 @@
|
||||
// Protocol Buffers - Google's data interchange format
|
||||
// Copyright 2008 Google Inc. All rights reserved.
|
||||
// https://developers.google.com/protocol-buffers/
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
#ifndef GOOGLE_PROTOBUF_UTIL_TIME_UTIL_H__
|
||||
#define GOOGLE_PROTOBUF_UTIL_TIME_UTIL_H__
|
||||
|
||||
#include <sys/time.h>
|
||||
|
||||
#include <ctime>
|
||||
#include <ostream>
|
||||
#include <string>
|
||||
|
||||
#include <google/protobuf/duration.pb.h>
|
||||
#include <google/protobuf/timestamp.pb.h>
|
||||
|
||||
namespace google {
|
||||
namespace protobuf {
|
||||
namespace util {
|
||||
|
||||
class LIBPROTOBUF_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 kTimestampMinSeconds = -62135596800LL;
|
||||
// For "9999-12-31T23:59:59.999999999Z".
|
||||
static const int64 kTimestampMaxSeconds = 253402300799LL;
|
||||
static const int64 kDurationMinSeconds = -315576000000LL;
|
||||
static const int64 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 string ToString(const Timestamp& timestamp);
|
||||
static bool FromString(const 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 string ToString(const Duration& duration);
|
||||
static bool FromString(const string& value, Duration* timestamp);
|
||||
|
||||
// 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 nanos);
|
||||
static Duration MicrosecondsToDuration(int64 micros);
|
||||
static Duration MillisecondsToDuration(int64 millis);
|
||||
static Duration SecondsToDuration(int64 seconds);
|
||||
static Duration MinutesToDuration(int64 minutes);
|
||||
static Duration HoursToDuration(int64 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 DurationToNanoseconds(const Duration& duration);
|
||||
static int64 DurationToMicroseconds(const Duration& duration);
|
||||
static int64 DurationToMilliseconds(const Duration& duration);
|
||||
static int64 DurationToSeconds(const Duration& duration);
|
||||
static int64 DurationToMinutes(const Duration& duration);
|
||||
static int64 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 nanos);
|
||||
static Timestamp MicrosecondsToTimestamp(int64 micros);
|
||||
static Timestamp MillisecondsToTimestamp(int64 millis);
|
||||
static Timestamp SecondsToTimestamp(int64 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 TimestampToNanoseconds(const Timestamp& timestamp);
|
||||
static int64 TimestampToMicroseconds(const Timestamp& timestamp);
|
||||
static int64 TimestampToMilliseconds(const Timestamp& timestamp);
|
||||
static int64 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 protobuf {
|
||||
// Overloaded operators for Duration.
|
||||
//
|
||||
// Assignment operators.
|
||||
Duration& operator+=(Duration& d1, const Duration& d2); // NOLINT
|
||||
Duration& operator-=(Duration& d1, const Duration& d2); // NOLINT
|
||||
Duration& operator*=(Duration& d, int64 r); // NOLINT
|
||||
Duration& operator*=(Duration& d, double r); // NOLINT
|
||||
Duration& operator/=(Duration& d, int64 r); // NOLINT
|
||||
Duration& operator/=(Duration& d, double r); // NOLINT
|
||||
// Overload for other integer types.
|
||||
template <typename T>
|
||||
Duration& operator*=(Duration& d, T r) { // NOLINT
|
||||
int64 x = r;
|
||||
return d *= x;
|
||||
}
|
||||
template <typename T>
|
||||
Duration& operator/=(Duration& d, T r) { // NOLINT
|
||||
int64 x = r;
|
||||
return d /= x;
|
||||
}
|
||||
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;
|
||||
}
|
||||
int64 operator/(const Duration& d1, const Duration& d2);
|
||||
|
||||
inline Duration operator%(const Duration& d1, const Duration& d2) {
|
||||
Duration result = d1;
|
||||
return result %= d2;
|
||||
}
|
||||
|
||||
inline ostream& operator<<(ostream& out, const Duration& d) {
|
||||
out << google::protobuf::util::TimeUtil::ToString(d);
|
||||
return out;
|
||||
}
|
||||
|
||||
// Overloaded operators for Timestamp
|
||||
//
|
||||
// Assignement operators.
|
||||
Timestamp& operator+=(Timestamp& t, const Duration& d); // NOLINT
|
||||
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;
|
||||
}
|
||||
Duration operator-(const Timestamp& t1, const Timestamp& t2);
|
||||
|
||||
inline ostream& operator<<(ostream& out, const Timestamp& t) {
|
||||
out << google::protobuf::util::TimeUtil::ToString(t);
|
||||
return out;
|
||||
}
|
||||
|
||||
} // namespace protobuf
|
||||
|
||||
|
||||
} // namespace google
|
||||
#endif // GOOGLE_PROTOBUF_UTIL_TIME_UTIL_H__
|
380
src/google/protobuf/util/time_util_test.cc
Normal file
380
src/google/protobuf/util/time_util_test.cc
Normal file
@ -0,0 +1,380 @@
|
||||
// Protocol Buffers - Google's data interchange format
|
||||
// Copyright 2008 Google Inc. All rights reserved.
|
||||
// https://developers.google.com/protocol-buffers/
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
#include <google/protobuf/util/time_util.h>
|
||||
|
||||
#include <ctime>
|
||||
|
||||
#include <google/protobuf/timestamp.pb.h>
|
||||
#include <google/protobuf/duration.pb.h>
|
||||
#include <google/protobuf/testing/googletest.h>
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
namespace google {
|
||||
namespace protobuf {
|
||||
namespace util {
|
||||
|
||||
using google::protobuf::Timestamp;
|
||||
using google::protobuf::Duration;
|
||||
|
||||
namespace {
|
||||
|
||||
TEST(TimeUtilTest, TimestampStringFormat) {
|
||||
Timestamp begin, end;
|
||||
EXPECT_TRUE(TimeUtil::FromString("0001-01-01T00:00:00Z", &begin));
|
||||
EXPECT_EQ(TimeUtil::kTimestampMinSeconds, begin.seconds());
|
||||
EXPECT_EQ(0, begin.nanos());
|
||||
EXPECT_TRUE(TimeUtil::FromString("9999-12-31T23:59:59.999999999Z", &end));
|
||||
EXPECT_EQ(TimeUtil::kTimestampMaxSeconds, end.seconds());
|
||||
EXPECT_EQ(999999999, end.nanos());
|
||||
EXPECT_EQ("0001-01-01T00:00:00Z", TimeUtil::ToString(begin));
|
||||
EXPECT_EQ("9999-12-31T23:59:59.999999999Z", TimeUtil::ToString(end));
|
||||
|
||||
// Test negative timestamps.
|
||||
Timestamp time = TimeUtil::NanosecondsToTimestamp(-1);
|
||||
EXPECT_EQ(-1, time.seconds());
|
||||
// Timestamp's nano part is always non-negative.
|
||||
EXPECT_EQ(999999999, time.nanos());
|
||||
EXPECT_EQ("1969-12-31T23:59:59.999999999Z", TimeUtil::ToString(time));
|
||||
|
||||
// Generated output should contain 3, 6, or 9 fractional digits.
|
||||
EXPECT_EQ("1970-01-01T00:00:00Z",
|
||||
TimeUtil::ToString(TimeUtil::NanosecondsToTimestamp(0)));
|
||||
EXPECT_EQ("1970-01-01T00:00:00.010Z",
|
||||
TimeUtil::ToString(TimeUtil::NanosecondsToTimestamp(10000000)));
|
||||
EXPECT_EQ("1970-01-01T00:00:00.000010Z",
|
||||
TimeUtil::ToString(TimeUtil::NanosecondsToTimestamp(10000)));
|
||||
EXPECT_EQ("1970-01-01T00:00:00.000000010Z",
|
||||
TimeUtil::ToString(TimeUtil::NanosecondsToTimestamp(10)));
|
||||
|
||||
// Parsing accepts an fractional digits as long as they fit into nano
|
||||
// precision.
|
||||
EXPECT_TRUE(TimeUtil::FromString("1970-01-01T00:00:00.1Z", &time));
|
||||
EXPECT_EQ(100000000, TimeUtil::TimestampToNanoseconds(time));
|
||||
EXPECT_TRUE(TimeUtil::FromString("1970-01-01T00:00:00.0001Z", &time));
|
||||
EXPECT_EQ(100000, TimeUtil::TimestampToNanoseconds(time));
|
||||
EXPECT_TRUE(TimeUtil::FromString("1970-01-01T00:00:00.0000001Z", &time));
|
||||
EXPECT_EQ(100, TimeUtil::TimestampToNanoseconds(time));
|
||||
|
||||
// Also accpets offsets.
|
||||
EXPECT_TRUE(TimeUtil::FromString("1970-01-01T00:00:00-08:00", &time));
|
||||
EXPECT_EQ(8 * 3600, TimeUtil::TimestampToSeconds(time));
|
||||
}
|
||||
|
||||
TEST(TimeUtilTest, DurationStringFormat) {
|
||||
Timestamp begin, end;
|
||||
EXPECT_TRUE(TimeUtil::FromString("0001-01-01T00:00:00Z", &begin));
|
||||
EXPECT_TRUE(TimeUtil::FromString("9999-12-31T23:59:59.999999999Z", &end));
|
||||
|
||||
EXPECT_EQ("315537897599.999999999s", TimeUtil::ToString(end - begin));
|
||||
EXPECT_EQ(999999999, (end - begin).nanos());
|
||||
EXPECT_EQ("-315537897599.999999999s", TimeUtil::ToString(begin - end));
|
||||
EXPECT_EQ(-999999999, (begin - end).nanos());
|
||||
|
||||
// Generated output should contain 3, 6, or 9 fractional digits.
|
||||
EXPECT_EQ("1s", TimeUtil::ToString(TimeUtil::SecondsToDuration(1)));
|
||||
EXPECT_EQ("0.010s", TimeUtil::ToString(TimeUtil::MillisecondsToDuration(10)));
|
||||
EXPECT_EQ("0.000010s",
|
||||
TimeUtil::ToString(TimeUtil::MicrosecondsToDuration(10)));
|
||||
EXPECT_EQ("0.000000010s",
|
||||
TimeUtil::ToString(TimeUtil::NanosecondsToDuration(10)));
|
||||
|
||||
// Parsing accepts an fractional digits as long as they fit into nano
|
||||
// precision.
|
||||
Duration d;
|
||||
EXPECT_TRUE(TimeUtil::FromString("0.1s", &d));
|
||||
EXPECT_EQ(100, TimeUtil::DurationToMilliseconds(d));
|
||||
EXPECT_TRUE(TimeUtil::FromString("0.0001s", &d));
|
||||
EXPECT_EQ(100, TimeUtil::DurationToMicroseconds(d));
|
||||
EXPECT_TRUE(TimeUtil::FromString("0.0000001s", &d));
|
||||
EXPECT_EQ(100, TimeUtil::DurationToNanoseconds(d));
|
||||
|
||||
// Duration must support range from -315,576,000,000s to +315576000000s
|
||||
// which includes negative values.
|
||||
EXPECT_TRUE(TimeUtil::FromString("315576000000.999999999s", &d));
|
||||
EXPECT_EQ(315576000000LL, d.seconds());
|
||||
EXPECT_EQ(999999999, d.nanos());
|
||||
EXPECT_TRUE(TimeUtil::FromString("-315576000000.999999999s", &d));
|
||||
EXPECT_EQ(-315576000000LL, d.seconds());
|
||||
EXPECT_EQ(-999999999, d.nanos());
|
||||
}
|
||||
|
||||
TEST(TimeUtilTest, GetEpoch) {
|
||||
EXPECT_EQ(0, TimeUtil::TimestampToNanoseconds(TimeUtil::GetEpoch()));
|
||||
}
|
||||
|
||||
TEST(TimeUtilTest, DurationIntegerConversion) {
|
||||
EXPECT_EQ("0.000000001s",
|
||||
TimeUtil::ToString(TimeUtil::NanosecondsToDuration(1)));
|
||||
EXPECT_EQ("-0.000000001s",
|
||||
TimeUtil::ToString(TimeUtil::NanosecondsToDuration(-1)));
|
||||
EXPECT_EQ("0.000001s",
|
||||
TimeUtil::ToString(TimeUtil::MicrosecondsToDuration(1)));
|
||||
EXPECT_EQ("-0.000001s",
|
||||
TimeUtil::ToString(TimeUtil::MicrosecondsToDuration(-1)));
|
||||
EXPECT_EQ("0.001s", TimeUtil::ToString(TimeUtil::MillisecondsToDuration(1)));
|
||||
EXPECT_EQ("-0.001s",
|
||||
TimeUtil::ToString(TimeUtil::MillisecondsToDuration(-1)));
|
||||
EXPECT_EQ("1s", TimeUtil::ToString(TimeUtil::SecondsToDuration(1)));
|
||||
EXPECT_EQ("-1s", TimeUtil::ToString(TimeUtil::SecondsToDuration(-1)));
|
||||
EXPECT_EQ("60s", TimeUtil::ToString(TimeUtil::MinutesToDuration(1)));
|
||||
EXPECT_EQ("-60s", TimeUtil::ToString(TimeUtil::MinutesToDuration(-1)));
|
||||
EXPECT_EQ("3600s", TimeUtil::ToString(TimeUtil::HoursToDuration(1)));
|
||||
EXPECT_EQ("-3600s", TimeUtil::ToString(TimeUtil::HoursToDuration(-1)));
|
||||
|
||||
EXPECT_EQ(
|
||||
1, TimeUtil::DurationToNanoseconds(TimeUtil::NanosecondsToDuration(1)));
|
||||
EXPECT_EQ(
|
||||
-1, TimeUtil::DurationToNanoseconds(TimeUtil::NanosecondsToDuration(-1)));
|
||||
EXPECT_EQ(
|
||||
1, TimeUtil::DurationToMicroseconds(TimeUtil::MicrosecondsToDuration(1)));
|
||||
EXPECT_EQ(-1, TimeUtil::DurationToMicroseconds(
|
||||
TimeUtil::MicrosecondsToDuration(-1)));
|
||||
EXPECT_EQ(
|
||||
1, TimeUtil::DurationToMilliseconds(TimeUtil::MillisecondsToDuration(1)));
|
||||
EXPECT_EQ(-1, TimeUtil::DurationToMilliseconds(
|
||||
TimeUtil::MillisecondsToDuration(-1)));
|
||||
EXPECT_EQ(1, TimeUtil::DurationToSeconds(TimeUtil::SecondsToDuration(1)));
|
||||
EXPECT_EQ(-1, TimeUtil::DurationToSeconds(TimeUtil::SecondsToDuration(-1)));
|
||||
EXPECT_EQ(1, TimeUtil::DurationToMinutes(TimeUtil::MinutesToDuration(1)));
|
||||
EXPECT_EQ(-1, TimeUtil::DurationToMinutes(TimeUtil::MinutesToDuration(-1)));
|
||||
EXPECT_EQ(1, TimeUtil::DurationToHours(TimeUtil::HoursToDuration(1)));
|
||||
EXPECT_EQ(-1, TimeUtil::DurationToHours(TimeUtil::HoursToDuration(-1)));
|
||||
|
||||
// Test truncation behavior.
|
||||
EXPECT_EQ(1, TimeUtil::DurationToMicroseconds(
|
||||
TimeUtil::NanosecondsToDuration(1999)));
|
||||
// For negative values, Duration will be rounded towards 0.
|
||||
EXPECT_EQ(-1, TimeUtil::DurationToMicroseconds(
|
||||
TimeUtil::NanosecondsToDuration(-1999)));
|
||||
}
|
||||
|
||||
TEST(TestUtilTest, TimestampIntegerConversion) {
|
||||
EXPECT_EQ("1970-01-01T00:00:00.000000001Z",
|
||||
TimeUtil::ToString(TimeUtil::NanosecondsToTimestamp(1)));
|
||||
EXPECT_EQ("1969-12-31T23:59:59.999999999Z",
|
||||
TimeUtil::ToString(TimeUtil::NanosecondsToTimestamp(-1)));
|
||||
EXPECT_EQ("1970-01-01T00:00:00.000001Z",
|
||||
TimeUtil::ToString(TimeUtil::MicrosecondsToTimestamp(1)));
|
||||
EXPECT_EQ("1969-12-31T23:59:59.999999Z",
|
||||
TimeUtil::ToString(TimeUtil::MicrosecondsToTimestamp(-1)));
|
||||
EXPECT_EQ("1970-01-01T00:00:00.001Z",
|
||||
TimeUtil::ToString(TimeUtil::MillisecondsToTimestamp(1)));
|
||||
EXPECT_EQ("1969-12-31T23:59:59.999Z",
|
||||
TimeUtil::ToString(TimeUtil::MillisecondsToTimestamp(-1)));
|
||||
EXPECT_EQ("1970-01-01T00:00:01Z",
|
||||
TimeUtil::ToString(TimeUtil::SecondsToTimestamp(1)));
|
||||
EXPECT_EQ("1969-12-31T23:59:59Z",
|
||||
TimeUtil::ToString(TimeUtil::SecondsToTimestamp(-1)));
|
||||
|
||||
EXPECT_EQ(
|
||||
1, TimeUtil::TimestampToNanoseconds(TimeUtil::NanosecondsToTimestamp(1)));
|
||||
EXPECT_EQ(-1, TimeUtil::TimestampToNanoseconds(
|
||||
TimeUtil::NanosecondsToTimestamp(-1)));
|
||||
EXPECT_EQ(1, TimeUtil::TimestampToMicroseconds(
|
||||
TimeUtil::MicrosecondsToTimestamp(1)));
|
||||
EXPECT_EQ(-1, TimeUtil::TimestampToMicroseconds(
|
||||
TimeUtil::MicrosecondsToTimestamp(-1)));
|
||||
EXPECT_EQ(1, TimeUtil::TimestampToMilliseconds(
|
||||
TimeUtil::MillisecondsToTimestamp(1)));
|
||||
EXPECT_EQ(-1, TimeUtil::TimestampToMilliseconds(
|
||||
TimeUtil::MillisecondsToTimestamp(-1)));
|
||||
EXPECT_EQ(1, TimeUtil::TimestampToSeconds(TimeUtil::SecondsToTimestamp(1)));
|
||||
EXPECT_EQ(-1, TimeUtil::TimestampToSeconds(TimeUtil::SecondsToTimestamp(-1)));
|
||||
|
||||
// Test truncation behavior.
|
||||
EXPECT_EQ(1, TimeUtil::TimestampToMicroseconds(
|
||||
TimeUtil::NanosecondsToTimestamp(1999)));
|
||||
// For negative values, Timestamp will be rounded down.
|
||||
// For example, "1969-12-31T23:59:59.5Z" (i.e., -0.5s) rounded to seconds
|
||||
// will be "1969-12-31T23:59:59Z" (i.e., -1s) rather than
|
||||
// "1970-01-01T00:00:00Z" (i.e., 0s).
|
||||
EXPECT_EQ(-2, TimeUtil::TimestampToMicroseconds(
|
||||
TimeUtil::NanosecondsToTimestamp(-1999)));
|
||||
}
|
||||
|
||||
TEST(TimeUtilTest, TimeTConversion) {
|
||||
time_t value = time(NULL);
|
||||
EXPECT_EQ(value,
|
||||
TimeUtil::TimestampToTimeT(TimeUtil::TimeTToTimestamp(value)));
|
||||
EXPECT_EQ(
|
||||
1, TimeUtil::TimestampToTimeT(TimeUtil::MillisecondsToTimestamp(1999)));
|
||||
}
|
||||
|
||||
TEST(TimeUtilTest, TimevalConversion) {
|
||||
timeval value = TimeUtil::TimestampToTimeval(
|
||||
TimeUtil::NanosecondsToTimestamp(1999999999));
|
||||
EXPECT_EQ(1, value.tv_sec);
|
||||
EXPECT_EQ(999999, value.tv_usec);
|
||||
value = TimeUtil::TimestampToTimeval(
|
||||
TimeUtil::NanosecondsToTimestamp(-1999999999));
|
||||
EXPECT_EQ(-2, value.tv_sec);
|
||||
EXPECT_EQ(0, value.tv_usec);
|
||||
|
||||
value =
|
||||
TimeUtil::DurationToTimeval(TimeUtil::NanosecondsToDuration(1999999999));
|
||||
EXPECT_EQ(1, value.tv_sec);
|
||||
EXPECT_EQ(999999, value.tv_usec);
|
||||
value =
|
||||
TimeUtil::DurationToTimeval(TimeUtil::NanosecondsToDuration(-1999999999));
|
||||
EXPECT_EQ(-2, value.tv_sec);
|
||||
EXPECT_EQ(1, value.tv_usec);
|
||||
}
|
||||
|
||||
TEST(TimeUtilTest, DurationOperators) {
|
||||
Duration one_second = TimeUtil::SecondsToDuration(1);
|
||||
Duration one_nano = TimeUtil::NanosecondsToDuration(1);
|
||||
|
||||
// Test +/-
|
||||
Duration a = one_second;
|
||||
a += one_second;
|
||||
a -= one_nano;
|
||||
EXPECT_EQ("1.999999999s", TimeUtil::ToString(a));
|
||||
Duration b = -a;
|
||||
EXPECT_EQ("-1.999999999s", TimeUtil::ToString(b));
|
||||
EXPECT_EQ("3.999999998s", TimeUtil::ToString(a + a));
|
||||
EXPECT_EQ("0s", TimeUtil::ToString(a + b));
|
||||
EXPECT_EQ("0s", TimeUtil::ToString(b + a));
|
||||
EXPECT_EQ("-3.999999998s", TimeUtil::ToString(b + b));
|
||||
EXPECT_EQ("3.999999998s", TimeUtil::ToString(a - b));
|
||||
EXPECT_EQ("0s", TimeUtil::ToString(a - a));
|
||||
EXPECT_EQ("0s", TimeUtil::ToString(b - b));
|
||||
EXPECT_EQ("-3.999999998s", TimeUtil::ToString(b - a));
|
||||
|
||||
// Test *
|
||||
EXPECT_EQ(a + a, a * 2);
|
||||
EXPECT_EQ(b + b, a * (-2));
|
||||
EXPECT_EQ(b + b, b * 2);
|
||||
EXPECT_EQ(a + a, b * (-2));
|
||||
EXPECT_EQ("0.999999999s", TimeUtil::ToString(a * 0.5));
|
||||
EXPECT_EQ("-0.999999999s", TimeUtil::ToString(b * 0.5));
|
||||
// Multiplication should not overflow if the result fits into the supported
|
||||
// range of Duration (intermediate result may be larger than int64).
|
||||
EXPECT_EQ("315575999684.424s",
|
||||
TimeUtil::ToString((one_second - one_nano) * 315576000000LL));
|
||||
EXPECT_EQ("-315575999684.424s",
|
||||
TimeUtil::ToString((one_nano - one_second) * 315576000000LL));
|
||||
EXPECT_EQ("-315575999684.424s",
|
||||
TimeUtil::ToString((one_second - one_nano) * (-315576000000LL)));
|
||||
|
||||
// Test / and %
|
||||
EXPECT_EQ("0.999999999s", TimeUtil::ToString(a / 2));
|
||||
EXPECT_EQ("-0.999999999s", TimeUtil::ToString(b / 2));
|
||||
Duration large = TimeUtil::SecondsToDuration(315576000000LL) - one_nano;
|
||||
// We have to handle division with values beyond 64 bits.
|
||||
EXPECT_EQ("0.999999999s", TimeUtil::ToString(large / 315576000000LL));
|
||||
EXPECT_EQ("-0.999999999s", TimeUtil::ToString((-large) / 315576000000LL));
|
||||
EXPECT_EQ("-0.999999999s", TimeUtil::ToString(large / (-315576000000LL)));
|
||||
Duration large2 = large + one_nano;
|
||||
EXPECT_EQ(large, large % large2);
|
||||
EXPECT_EQ(-large, (-large) % large2);
|
||||
EXPECT_EQ(large, large % (-large2));
|
||||
EXPECT_EQ(one_nano, large2 % large);
|
||||
EXPECT_EQ(-one_nano, (-large2) % large);
|
||||
EXPECT_EQ(one_nano, large2 % (-large));
|
||||
// Some corner cases about negative values.
|
||||
//
|
||||
// (-5) / 2 = -2, remainder = -1
|
||||
// (-5) / (-2) = 2, remainder = -1
|
||||
a = TimeUtil::NanosecondsToDuration(-5);
|
||||
EXPECT_EQ(TimeUtil::NanosecondsToDuration(-2), a / 2);
|
||||
EXPECT_EQ(TimeUtil::NanosecondsToDuration(2), a / (-2));
|
||||
b = TimeUtil::NanosecondsToDuration(2);
|
||||
EXPECT_EQ(-2, a / b);
|
||||
EXPECT_EQ(TimeUtil::NanosecondsToDuration(-1), a % b);
|
||||
EXPECT_EQ(2, a / (-b));
|
||||
EXPECT_EQ(TimeUtil::NanosecondsToDuration(-1), a % (-b));
|
||||
|
||||
// Test relational operators.
|
||||
EXPECT_TRUE(one_nano < one_second);
|
||||
EXPECT_FALSE(one_second < one_second);
|
||||
EXPECT_FALSE(one_second < one_nano);
|
||||
EXPECT_FALSE(-one_nano < -one_second);
|
||||
EXPECT_FALSE(-one_second < -one_second);
|
||||
EXPECT_TRUE(-one_second < -one_nano);
|
||||
EXPECT_TRUE(-one_nano < one_nano);
|
||||
EXPECT_FALSE(one_nano < -one_nano);
|
||||
|
||||
EXPECT_FALSE(one_nano > one_second);
|
||||
EXPECT_FALSE(one_nano > one_nano);
|
||||
EXPECT_TRUE(one_second > one_nano);
|
||||
|
||||
EXPECT_FALSE(one_nano >= one_second);
|
||||
EXPECT_TRUE(one_nano >= one_nano);
|
||||
EXPECT_TRUE(one_second >= one_nano);
|
||||
|
||||
EXPECT_TRUE(one_nano <= one_second);
|
||||
EXPECT_TRUE(one_nano <= one_nano);
|
||||
EXPECT_FALSE(one_second <= one_nano);
|
||||
|
||||
EXPECT_TRUE(one_nano == one_nano);
|
||||
EXPECT_FALSE(one_nano == one_second);
|
||||
|
||||
EXPECT_FALSE(one_nano != one_nano);
|
||||
EXPECT_TRUE(one_nano != one_second);
|
||||
}
|
||||
|
||||
TEST(TimeUtilTest, TimestampOperators) {
|
||||
Timestamp begin, end;
|
||||
EXPECT_TRUE(TimeUtil::FromString("0001-01-01T00:00:00Z", &begin));
|
||||
EXPECT_TRUE(TimeUtil::FromString("9999-12-31T23:59:59.999999999Z", &end));
|
||||
Duration d = end - begin;
|
||||
EXPECT_TRUE(end == begin + d);
|
||||
EXPECT_TRUE(end == d + begin);
|
||||
EXPECT_TRUE(begin == end - d);
|
||||
|
||||
// Test relational operators
|
||||
Timestamp t1 = begin + d / 4;
|
||||
Timestamp t2 = end - d / 4;
|
||||
EXPECT_TRUE(t1 < t2);
|
||||
EXPECT_FALSE(t1 < t1);
|
||||
EXPECT_FALSE(t2 < t1);
|
||||
EXPECT_FALSE(t1 > t2);
|
||||
EXPECT_FALSE(t1 > t1);
|
||||
EXPECT_TRUE(t2 > t1);
|
||||
EXPECT_FALSE(t1 >= t2);
|
||||
EXPECT_TRUE(t1 >= t1);
|
||||
EXPECT_TRUE(t2 >= t1);
|
||||
EXPECT_TRUE(t1 <= t2);
|
||||
EXPECT_TRUE(t1 <= t1);
|
||||
EXPECT_FALSE(t2 <= t1);
|
||||
|
||||
EXPECT_FALSE(t1 == t2);
|
||||
EXPECT_TRUE(t1 == t1);
|
||||
EXPECT_FALSE(t2 == t1);
|
||||
EXPECT_TRUE(t1 != t2);
|
||||
EXPECT_FALSE(t1 != t1);
|
||||
EXPECT_TRUE(t2 != t1);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace util
|
||||
} // namespace protobuf
|
||||
} // namespace google
|
@ -262,9 +262,9 @@ void protobuf_AddDesc_google_2fprotobuf_2fwrappers_2eproto() {
|
||||
"e\030\001 \001(\004\"\033\n\nInt32Value\022\r\n\005value\030\001 \001(\005\"\034\n\013"
|
||||
"UInt32Value\022\r\n\005value\030\001 \001(\r\"\032\n\tBoolValue\022"
|
||||
"\r\n\005value\030\001 \001(\010\"\034\n\013StringValue\022\r\n\005value\030\001"
|
||||
" \001(\t\"\033\n\nBytesValue\022\r\n\005value\030\001 \001(\014BE\n\023com"
|
||||
".google.protobufB\rWrappersProtoP\001\242\002\003GPB\252"
|
||||
"\002\026Google.ProtocolBuffersb\006proto3", 392);
|
||||
" \001(\t\"\033\n\nBytesValue\022\r\n\005value\030\001 \001(\014BH\n\023com"
|
||||
".google.protobufB\rWrappersProtoP\001\240\001\001\242\002\003G"
|
||||
"PB\252\002\026Google.ProtocolBuffersb\006proto3", 395);
|
||||
::google::protobuf::MessageFactory::InternalRegisterGeneratedFile(
|
||||
"google/protobuf/wrappers.proto", &protobuf_RegisterTypes);
|
||||
DoubleValue::default_instance_ = new DoubleValue();
|
||||
|
@ -37,62 +37,80 @@ syntax = "proto3";
|
||||
|
||||
package google.protobuf;
|
||||
|
||||
option csharp_namespace = "Google.ProtocolBuffers";
|
||||
option java_generate_equals_and_hash = true;
|
||||
option java_multiple_files = true;
|
||||
option java_outer_classname = "WrappersProto";
|
||||
option java_package = "com.google.protobuf";
|
||||
option csharp_namespace = "Google.ProtocolBuffers";
|
||||
option objc_class_prefix = "GPB";
|
||||
|
||||
|
||||
// Wrapper message for double.
|
||||
// Wrapper message for `double`.
|
||||
//
|
||||
// The JSON representation for `DoubleValue` is JSON number.
|
||||
message DoubleValue {
|
||||
// The double value.
|
||||
double value = 1;
|
||||
}
|
||||
|
||||
// Wrapper message for float.
|
||||
// Wrapper message for `float`.
|
||||
//
|
||||
// The JSON representation for `FloatValue` is JSON number.
|
||||
message FloatValue {
|
||||
// The float value.
|
||||
float value = 1;
|
||||
}
|
||||
|
||||
// Wrapper message for int64.
|
||||
// Wrapper message for `int64`.
|
||||
//
|
||||
// The JSON representation for `Int64Value` is JSON string.
|
||||
message Int64Value {
|
||||
// The int64 value.
|
||||
int64 value = 1;
|
||||
}
|
||||
|
||||
// Wrapper message for uint64.
|
||||
// Wrapper message for `uint64`.
|
||||
//
|
||||
// The JSON representation for `UInt64Value` is JSON string.
|
||||
message UInt64Value {
|
||||
// The uint64 value.
|
||||
uint64 value = 1;
|
||||
}
|
||||
|
||||
// Wrapper message for int32.
|
||||
// Wrapper message for `int32`.
|
||||
//
|
||||
// The JSON representation for `Int32Value` is JSON number.
|
||||
message Int32Value {
|
||||
// The int32 value.
|
||||
int32 value = 1;
|
||||
}
|
||||
|
||||
// Wrapper message for uint32.
|
||||
// Wrapper message for `uint32`.
|
||||
//
|
||||
// The JSON representation for `UInt32Value` is JSON number.
|
||||
message UInt32Value {
|
||||
// The uint32 value.
|
||||
uint32 value = 1;
|
||||
}
|
||||
|
||||
// Wrapper message for bool.
|
||||
// Wrapper message for `bool`.
|
||||
//
|
||||
// The JSON representation for `BoolValue` is JSON `true` and `false`.
|
||||
message BoolValue {
|
||||
// The bool value.
|
||||
bool value = 1;
|
||||
}
|
||||
|
||||
// Wrapper message for string.
|
||||
// Wrapper message for `string`.
|
||||
//
|
||||
// The JSON representation for `StringValue` is JSON string.
|
||||
message StringValue {
|
||||
// The string value.
|
||||
string value = 1;
|
||||
}
|
||||
|
||||
// Wrapper message for bytes.
|
||||
// Wrapper message for `bytes`.
|
||||
//
|
||||
// The JSON representation for `BytesValue` is JSON string.
|
||||
message BytesValue {
|
||||
// The bytes value.
|
||||
bytes value = 1;
|
||||
|
@ -133,11 +133,6 @@ done
|
||||
# Update bazel BUILD files.
|
||||
################################################################################
|
||||
|
||||
BAZEL_BUILD=./BUILD
|
||||
[ -f "$BAZEL_BUILD" ] || {
|
||||
echo "Cannot find: $BAZEL_BUILD"
|
||||
exit 1
|
||||
}
|
||||
set_bazel_value() {
|
||||
local FILENAME=$1
|
||||
local VARNAME=$2
|
||||
@ -169,14 +164,19 @@ set_bazel_value() {
|
||||
}
|
||||
|
||||
|
||||
BAZEL_BUILD=./BUILD
|
||||
BAZEL_PREFIX="src/"
|
||||
set_bazel_value $BAZEL_BUILD protobuf_lite_srcs $BAZEL_PREFIX $LIBPROTOBUF_LITE_SOURCES
|
||||
set_bazel_value $BAZEL_BUILD protobuf_srcs $BAZEL_PREFIX $LIBPROTOBUF_SOURCES
|
||||
set_bazel_value $BAZEL_BUILD protoc_lib_srcs $BAZEL_PREFIX $LIBPROTOC_SOURCES
|
||||
set_bazel_value $BAZEL_BUILD lite_test_protos "" $LITE_PROTOS
|
||||
set_bazel_value $BAZEL_BUILD well_known_protos "" $WKT_PROTOS
|
||||
set_bazel_value $BAZEL_BUILD test_protos "" $PROTOS
|
||||
set_bazel_value $BAZEL_BUILD common_test_srcs $BAZEL_PREFIX $COMMON_TEST_SOURCES
|
||||
set_bazel_value $BAZEL_BUILD test_srcs $BAZEL_PREFIX $TEST_SOURCES
|
||||
set_bazel_value $BAZEL_BUILD test_plugin_srcs $BAZEL_PREFIX $TEST_PLUGIN_SOURCES
|
||||
if [ -f "$BAZEL_BUILD" ]; then
|
||||
set_bazel_value $BAZEL_BUILD protobuf_lite_srcs $BAZEL_PREFIX $LIBPROTOBUF_LITE_SOURCES
|
||||
set_bazel_value $BAZEL_BUILD protobuf_srcs $BAZEL_PREFIX $LIBPROTOBUF_SOURCES
|
||||
set_bazel_value $BAZEL_BUILD protoc_lib_srcs $BAZEL_PREFIX $LIBPROTOC_SOURCES
|
||||
set_bazel_value $BAZEL_BUILD lite_test_protos "" $LITE_PROTOS
|
||||
set_bazel_value $BAZEL_BUILD well_known_protos "" $WKT_PROTOS
|
||||
set_bazel_value $BAZEL_BUILD test_protos "" $PROTOS
|
||||
set_bazel_value $BAZEL_BUILD common_test_srcs $BAZEL_PREFIX $COMMON_TEST_SOURCES
|
||||
set_bazel_value $BAZEL_BUILD test_srcs $BAZEL_PREFIX $TEST_SOURCES
|
||||
set_bazel_value $BAZEL_BUILD test_plugin_srcs $BAZEL_PREFIX $TEST_PLUGIN_SOURCES
|
||||
else
|
||||
echo "Skipped BUILD file update."
|
||||
fi
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user