diff options
231 files changed, 3710 insertions, 3529 deletions
diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md new file mode 100644 index 00000000..2f6d0263 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -0,0 +1,28 @@ +--- +name: Bug report +about: Create a report to help us improve + +--- + +**What version of protobuf and what language are you using?** +Version: master/v3.6.0/v3.5.0 etc. +Language: C++/Java/Python/C#/Ruby/PHP/Objective-C/Javascript + +**What operating system (Linux, Windows, ...) and version?** + +**What runtime / compiler are you using (e.g., python version or gcc version)** + +**What did you do?** +Steps to reproduce the behavior: +1. Go to '...' +2. Click on '....' +3. Scroll down to '....' +4. See error + +**What did you expect to see** + +**What did you see instead?** + +Make sure you include information that can help us debug (full error message, exception listing, stack trace, logs). + +**Anything else we should know about your project / environment** diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md new file mode 100644 index 00000000..722db4ce --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature_request.md @@ -0,0 +1,18 @@ +--- +name: Feature request +about: Suggest an idea for this project + +--- + +**What language does this apply to?** +If it's a proto syntax change, is it for proto2 or proto3? +If it's about generated code change, what programming language? + +**Describe the problem you are trying to solve.** + +**Describe the solution you'd like** + +**Describe alternatives you've considered** + +**Additional context** +Add any other context or screenshots about the feature request here. diff --git a/.github/ISSUE_TEMPLATE/question.md b/.github/ISSUE_TEMPLATE/question.md new file mode 100644 index 00000000..bfa6ddea --- /dev/null +++ b/.github/ISSUE_TEMPLATE/question.md @@ -0,0 +1,7 @@ +--- +name: Question +about: Questions and troubleshooting + +--- + + @@ -186,3 +186,6 @@ cmake/cmake-build-debug/ # Common build subdirectories. ./.build/ ./_build/ + +# Visual Studio 2017 +.vs diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 74d4ea7b..00000000 --- a/.travis.yml +++ /dev/null @@ -1,90 +0,0 @@ -# Everything is driven by the test.sh, so the language doesn't really -# matter, it just controls the default install/script/etc. steps on -# travis. -language: cpp -script: ./tests.sh $CONFIG - -# The test matrix is manually built to cover a mix of linux and macOS -# hosted setups; this lets some extra settings be done specific to each -# host/language instead of forcing common values on all the tests. -matrix: - include: - # ----------------------------------------------------------------- - # macOS hosted tests for Objective-C - - - os: osx - env: CONFIG=objectivec_osx - osx_image: xcode9.3 - language: objective-c - # iOS build log was starting to choke travis UI, so split to cover the - # Xcode Debug and Release Configurations independently. - - os: osx - env: CONFIG=objectivec_ios_debug - osx_image: xcode9.3 - language: objective-c - - os: osx - env: CONFIG=objectivec_ios_release - osx_image: xcode9.3 - language: objective-c - - os: osx - env: CONFIG=objectivec_cocoapods_integration - osx_image: xcode9.3 - language: objective-c - - # ----------------------------------------------------------------- - # macOS hosted tests for other languages. - - - os: osx - env: CONFIG=cpp - - os: osx - env: CONFIG=cpp_distcheck - - os: osx - env: CONFIG=javascript - - os: osx - env: CONFIG=python - - os: osx - env: CONFIG=python_cpp - - os: osx - env: CONFIG=php5.6_mac - - os: osx - env: CONFIG=php7.0_mac - - # ----------------------------------------------------------------- - # Linux hosted tests - - # The dotnet environment requires Ubuntu 14.04 or 16.04. This - # configuration is effectively an "extra" one, outside the - # autogenerated matrix. - - os: linux - env: CONFIG=csharp - language: csharp - dist: trusty - dotnet: 2.0.3 - mono: none - # Install the .NET Core 1.0 runtime as that's what we test against - addons: - apt: - sources: - - sourceline: 'deb [arch=amd64] https://packages.microsoft.com/repos/microsoft-ubuntu-trusty-prod trusty main' - key_url: 'https://packages.microsoft.com/keys/microsoft.asc' - packages: - - dotnet-sharedframework-microsoft.netcore.app-1.0.5 - # This test is kept on travis because it doesn't play nicely with other - # tests on jenkins running in parallel. - - os: linux - env: CONFIG=cpp_distcheck - # The Java compatibility test currently only runs on Linux because it will - # fetch pre-built Linux protoc binaries in the test. - - os: linux - env: CONFIG=java_compatibility - sudo: required - dist: trusty - # The Python compatibility test currently only runs on Linux because it will - # fetch pre-built Linux protoc binaries in the test. - - os: linux - env: CONFIG=python_compatibility - sudo: required - dist: trusty - -notifications: - email: false @@ -1,4 +1,4 @@ -# Bazel (http://bazel.io/) BUILD file for Protobuf. +# Bazel (https://bazel.build/) BUILD file for Protobuf. licenses(["notice"]) @@ -22,7 +22,20 @@ config_setting( MSVC_COPTS = [ "/DHAVE_PTHREAD", "/wd4018", # -Wno-sign-compare + "/wd4065", # switch statement contains 'default' but no 'case' labels + "/wd4146", # unary minus operator applied to unsigned type, result still unsigned + "/wd4244", # 'conversion' conversion from 'type1' to 'type2', possible loss of data + "/wd4251", # 'identifier' : class 'type' needs to have dll-interface to be used by clients of class 'type2' + "/wd4267", # 'var' : conversion from 'size_t' to 'type', possible loss of data + "/wd4305", # 'identifier' : truncation from 'type1' to 'type2' + "/wd4307", # 'operator' : integral constant overflow + "/wd4309", # 'conversion' : truncation of constant value + "/wd4334", # 'operator' : result of 32-bit shift implicitly converted to 64 bits (was 64-bit shift intended?) + "/wd4355", # 'this' : used in base member initializer list + "/wd4506", # no definition for inline function 'function' "/wd4514", # -Wno-unused-function + "/wd4800", # 'type' : forcing value to bool 'true' or 'false' (performance warning) + "/wd4996", # The compiler encountered a deprecated declaration. ] COPTS = select({ @@ -30,12 +43,12 @@ COPTS = select({ "//conditions:default": [ "-DHAVE_PTHREAD", "-Wall", - "-Wwrite-strings", "-Woverloaded-virtual", "-Wno-sign-compare", "-Wno-unused-function", # Prevents ISO C++ const string assignment warnings for pyext sources. "-Wno-writable-strings", + "-Wno-write-strings", ], }) @@ -54,7 +67,10 @@ config_setting( # Android and MSVC builds do not need to link in a separate pthread library. LINK_OPTS = select({ ":android": [], - ":msvc": [], + ":msvc": [ + # Suppress linker warnings about files with no symbols defined. + "-ignore:4221", + ], "//conditions:default": ["-lpthread", "-lm"], }) @@ -306,8 +322,6 @@ cc_library( "src/google/protobuf/compiler/java/java_generator.cc", "src/google/protobuf/compiler/java/java_generator_factory.cc", "src/google/protobuf/compiler/java/java_helpers.cc", - "src/google/protobuf/compiler/java/java_lazy_message_field.cc", - "src/google/protobuf/compiler/java/java_lazy_message_field_lite.cc", "src/google/protobuf/compiler/java/java_map_field.cc", "src/google/protobuf/compiler/java/java_map_field_lite.cc", "src/google/protobuf/compiler/java/java_message.cc", @@ -347,7 +361,25 @@ cc_library( ], copts = COPTS, includes = ["src/"], - linkopts = LINK_OPTS, + linkopts = LINK_OPTS + select({ + ":msvc": [ + # Linking to setargv.obj makes the default command line argument + # parser expand wildcards, so the main method's argv will contain the + # expanded list instead of the wildcards. + # + # Adding dummy "-DEFAULTLIB:kernel32.lib", because: + # - Microsoft ships this object file next to default libraries + # - but this file is not a library, just a precompiled object + # - "-WHOLEARCHIVE" and "-DEFAULTLIB" only accept library, + # not precompiled object. + # - Bazel would assume linkopt that does not start with "-" or "$" + # as a label to a target, so we add a harmless "-DEFAULTLIB:kernel32.lib" + # before "setargv.obj". + # See https://msdn.microsoft.com/en-us/library/8bch7bkk.aspx + "-DEFAULTLIB:kernel32.lib setargv.obj", + ], + "//conditions:default": [], + }), visibility = ["//visibility:public"], deps = [":protobuf"], ) @@ -610,6 +642,7 @@ py_library( name = "python_srcs", srcs = glob( [ + "python/google/__init__.py", "python/google/protobuf/*.py", "python/google/protobuf/**/*.py", ], @@ -658,6 +691,7 @@ cc_binary( linkstatic = 1, deps = [ ":protobuf", + ":proto_api", ] + select({ "//conditions:default": [], ":use_fast_cpp_protos": ["//external:python_headers"], @@ -800,6 +834,15 @@ internal_protobuf_py_tests( deps = [":python_tests"], ) +cc_library( + name = "proto_api", + hdrs = ["python/google/protobuf/proto_api.h"], + deps = [ + "//external:python_headers", + ], + visibility = ["//visibility:public"], +) + proto_lang_toolchain( name = "cc_toolchain", command_line = "--cpp_out=$(OUT)", @@ -889,9 +932,41 @@ OBJC_SRCS = [ objc_library( name = "objectivec", hdrs = OBJC_HDRS + OBJC_PRIVATE_HDRS, + copts = [ + "-Wno-vla", + ], includes = [ "objectivec", ], non_arc_srcs = OBJC_SRCS, visibility = ["//visibility:public"], ) + +################################################################################ +# Test generated proto support +################################################################################ + +genrule( + name = "generated_protos", + srcs = ["src/google/protobuf/unittest_import.proto"], + outs = ["unittest_gen.proto"], + cmd = "cat $(SRCS) | sed 's|google/|src/google/|' > $(OUTS)" +) + +proto_library( + name = "generated_protos_proto", + srcs = [ + "unittest_gen.proto", + "src/google/protobuf/unittest_import_public.proto", + ], +) + +py_proto_library( + name = "generated_protos_py", + srcs = [ + "unittest_gen.proto", + "src/google/protobuf/unittest_import_public.proto", + ], + default_runtime = "", + protoc = ":protoc", +) diff --git a/Makefile.am b/Makefile.am index ae4ac858..24f520c6 100644 --- a/Makefile.am +++ b/Makefile.am @@ -51,6 +51,7 @@ pkgconfig_DATA = protobuf.pc protobuf-lite.pc csharp_EXTRA_DIST= \ csharp/.gitignore \ csharp/CHANGES.txt \ + csharp/Google.Protobuf.Tools.targets \ csharp/Google.Protobuf.Tools.nuspec \ csharp/README.md \ csharp/build_packages.bat \ @@ -804,6 +805,7 @@ python_EXTRA_DIST= \ python/google/protobuf/message.py \ python/google/protobuf/message_factory.py \ python/google/protobuf/python_protobuf.h \ + python/google/protobuf/proto_api.h \ python/google/protobuf/proto_builder.py \ python/google/protobuf/pyext/README \ python/google/protobuf/pyext/__init__.py \ @@ -933,6 +935,7 @@ js_EXTRA_DIST= \ js/commonjs/import_test.js \ js/commonjs/jasmine.json \ js/commonjs/rewrite_tests_for_commonjs.js \ + js/commonjs/strict_test.js \ js/commonjs/test6/test6.proto \ js/commonjs/test7/test7.proto \ js/compatibility_tests/v3.0.0/binary/arith_test.js \ @@ -1004,6 +1007,8 @@ js_EXTRA_DIST= \ js/test4.proto \ js/test5.proto \ js/test8.proto \ + js/test9.proto \ + js/test10.proto \ js/test_bootstrap.js \ js/testbinary.proto \ js/testempty.proto @@ -1036,6 +1041,7 @@ EXTRA_DIST = $(@DIST_LANG@_EXTRA_DIST) \ cmake/protobuf.pc.cmake \ cmake/protoc.cmake \ cmake/tests.cmake \ + cmake/version.rc.in \ editors/README.txt \ editors/proto.vim \ editors/protobuf-mode.el \ @@ -60,7 +60,7 @@ how to install protobuf runtime for that specific language: | Objective-C | [objectivec](objectivec) | | [![Build status](https://storage.googleapis.com/protobuf-kokoro-results/status-badge/macos-objectivec_cocoapods_integration.png)](https://fusion.corp.google.com/projectanalysis/current/KOKORO/prod:protobuf%2Fgithub%2Fmaster%2Fmacos%2Fobjectivec_cocoapods_integration%2Fcontinuous)<br/>[![Build status](https://storage.googleapis.com/protobuf-kokoro-results/status-badge/macos-objectivec_ios_debug.png)](https://fusion.corp.google.com/projectanalysis/current/KOKORO/prod:protobuf%2Fgithub%2Fmaster%2Fmacos%2Fobjectivec_ios_debug%2Fcontinuous)<br/>[![Build status](https://storage.googleapis.com/protobuf-kokoro-results/status-badge/macos-objectivec_ios_release.png)](https://fusion.corp.google.com/projectanalysis/current/KOKORO/prod:protobuf%2Fgithub%2Fmaster%2Fmacos%2Fobjectivec_ios_release%2Fcontinuous)<br/>[![Build status](https://storage.googleapis.com/protobuf-kokoro-results/status-badge/macos-objectivec_osx.png)](https://fusion.corp.google.com/projectanalysis/current/KOKORO/prod:protobuf%2Fgithub%2Fmaster%2Fmacos%2Fobjectivec_osx%2Fcontinuous) | | | C# | [csharp](csharp) | [![Build status](https://storage.googleapis.com/protobuf-kokoro-results/status-badge/linux-csharp.png)](https://fusion.corp.google.com/projectanalysis/current/KOKORO/prod:protobuf%2Fgithub%2Fmaster%2Fubuntu%2Fcsharp%2Fcontinuous) | | [![Build status](https://ci.appveyor.com/api/projects/status/73ctee6ua4w2ruin?svg=true)](https://ci.appveyor.com/project/protobuf/protobuf) | | JavaScript | [js](js) | [![Build status](https://storage.googleapis.com/protobuf-kokoro-results/status-badge/linux-javascript.png)](https://fusion.corp.google.com/projectanalysis/current/KOKORO/prod:protobuf%2Fgithub%2Fmaster%2Fubuntu%2Fjavascript%2Fcontinuous) | [![Build status](https://storage.googleapis.com/protobuf-kokoro-results/status-badge/macos-javascript.png)](https://fusion.corp.google.com/projectanalysis/current/KOKORO/prod:protobuf%2Fgithub%2Fmaster%2Fmacos%2Fjavascript%2Fcontinuous) | | -| Ruby | [ruby](ruby) | [![Build status](https://storage.googleapis.com/protobuf-kokoro-results/status-badge/linux-ruby_all.png)](https://fusion.corp.google.com/projectanalysis/current/KOKORO/prod:protobuf%2Fgithub%2Fmaster%2Fubuntu%2Fruby_all%2Fcontinuous) | [![Build status](https://storage.googleapis.com/protobuf-kokoro-results/status-badge/macos-ruby21.png)](https://fusion.corp.google.com/projectanalysis/current/KOKORO/prod:protobuf%2Fgithub%2Fmaster%2Fmacos%2Fruby21%2Fcontinuous)<br/>[![Build status](https://storage.googleapis.com/protobuf-kokoro-results/status-badge/macos-ruby22.png)](https://fusion.corp.google.com/projectanalysis/current/KOKORO/prod:protobuf%2Fgithub%2Fmaster%2Fmacos%2Fruby22%2Fcontinuous)<br/>[![Build status](https://storage.googleapis.com/protobuf-kokoro-results/status-badge/macos-jruby.png)](https://fusion.corp.google.com/projectanalysis/current/KOKORO/prod:protobuf%2Fgithub%2Fmaster%2Fmacos%2Fjruby%2Fcontinuous) | | +| Ruby | [ruby](ruby) | [![Build status](https://storage.googleapis.com/protobuf-kokoro-results/status-badge/linux-ruby_all.png)](https://fusion.corp.google.com/projectanalysis/current/KOKORO/prod:protobuf%2Fgithub%2Fmaster%2Fubuntu%2Fruby_all%2Fcontinuous) | [![Build status](https://storage.googleapis.com/protobuf-kokoro-results/status-badge/macos-ruby21.png)](https://fusion.corp.google.com/projectanalysis/current/KOKORO/prod:protobuf%2Fgithub%2Fmaster%2Fmacos%2Fruby21%2Fcontinuous)<br/>[![Build status](https://storage.googleapis.com/protobuf-kokoro-results/status-badge/macos-ruby22.png)](https://fusion.corp.google.com/projectanalysis/current/KOKORO/prod:protobuf%2Fgithub%2Fmaster%2Fmacos%2Fruby22%2Fcontinuous) | | | Go | [golang/protobuf](https://github.com/golang/protobuf) | | | | | PHP | [php](php) | [![Build status](https://storage.googleapis.com/protobuf-kokoro-results/status-badge/linux-php_all.png)](https://fusion.corp.google.com/projectanalysis/current/KOKORO/prod:protobuf%2Fgithub%2Fmaster%2Fubuntu%2Fphp_all%2Fcontinuous)<br/>[![Build status](https://storage.googleapis.com/protobuf-kokoro-results/status-badge/linux-32-bit.png)](https://fusion.corp.google.com/projectanalysis/current/KOKORO/prod:protobuf%2Fgithub%2Fmaster%2Fubuntu%2F32-bit%2Fcontinuous) | [![Build status](https://storage.googleapis.com/protobuf-kokoro-results/status-badge/macos-php5.6_mac.png)](https://fusion.corp.google.com/projectanalysis/current/KOKORO/prod:protobuf%2Fgithub%2Fmaster%2Fmacos%2Fphp5.6_mac%2Fcontinuous)<br/>[![Build status](https://storage.googleapis.com/protobuf-kokoro-results/status-badge/macos-php7.0_mac.png)](https://fusion.corp.google.com/projectanalysis/current/KOKORO/prod:protobuf%2Fgithub%2Fmaster%2Fmacos%2Fphp7.0_mac%2Fcontinuous) | | | Dart | [dart-lang/protobuf](https://github.com/dart-lang/protobuf) | | | | @@ -1,16 +1,24 @@ workspace(name = "com_google_protobuf") +load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive") new_local_repository( name = "submodule_gmock", path = "third_party/googletest", - build_file = "third_party/googletest/BUILD.bazel" + build_file = "@//:third_party/googletest/BUILD.bazel" ) -new_http_archive( +http_archive( name = "six_archive", - build_file = "six.BUILD", + build_file = "@//:six.BUILD", sha256 = "105f8d68616f8248e24bf0e9372ef04d3cc10104f1980f54d57b2ce73a5ad56a", - url = "https://pypi.python.org/packages/source/s/six/six-1.10.0.tar.gz#md5=34eed507548117b2ab523ab14b2f8b55", + urls = ["https://pypi.python.org/packages/source/s/six/six-1.10.0.tar.gz#md5=34eed507548117b2ab523ab14b2f8b55"], +) + +http_archive( + name = "bazel_skylib", + sha256 = "bbccf674aa441c266df9894182d80de104cabd19be98be002f6d478aaa31574d", + strip_prefix = "bazel-skylib-2169ae1c374aab4a09aa90e65efe1a3aad4e279b", + urls = ["https://github.com/bazelbuild/bazel-skylib/archive/2169ae1c374aab4a09aa90e65efe1a3aad4e279b.tar.gz"], ) bind( diff --git a/appveyor.bat b/appveyor.bat index e59ebccc..29ec4922 100644 --- a/appveyor.bat +++ b/appveyor.bat @@ -1,11 +1,23 @@ setlocal +IF %platform%==MinGW GOTO build_mingw IF %language%==cpp GOTO build_cpp IF %language%==csharp GOTO build_csharp -echo Unsupported language %language%. Exiting. +echo Unsupported language %language% and platform %platform%. Exiting. goto :error +:build_mingw +echo Building MinGW +set PATH=C:\mingw-w64\x86_64-7.2.0-posix-seh-rt_v5-rev1\mingw64\bin;%PATH:C:\Program Files\Git\usr\bin;=% +mkdir build_mingw +cd build_mingw +cmake -G "%generator%" -Dprotobuf_BUILD_SHARED_LIBS=%BUILD_DLL% -Dprotobuf_UNICODE=%UNICODE% -Dprotobuf_BUILD_TESTS=0 ../cmake +mingw32-make -j8 all || goto error +rem cd %configuration% +rem tests.exe || goto error +goto :EOF + :build_cpp echo Building C++ mkdir build_msvc diff --git a/appveyor.yml b/appveyor.yml index 9644e066..91f737a8 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -1,22 +1,29 @@ -platform: - - Win64 - configuration: - Debug environment: matrix: - - language: cpp + # Only test few combinations: "Visual Studio 2015 (14) + Win64/MinGW + Debug + DLL". We can + # test more combinations but AppVeyor just takes too long to finish (each + # combination takes ~15mins). + - platform: MinGW + language: cpp + image: Visual Studio 2015 + + - platform: Win64 + language: cpp image: Visual Studio 2015 BUILD_DLL: ON UNICODE: ON - - language: cpp + - platform: Win64 + language: cpp image: Visual Studio 2017 BUILD_DLL: OFF UNICODE: ON - - language: csharp + - platform: Win64 + language: csharp image: Visual Studio 2017 # Our build scripts run tests automatically; we don't want AppVeyor @@ -27,6 +34,7 @@ install: - git submodule update --init --recursive before_build: + - if %platform%==MinGW set generator=MinGW Makefiles - if %platform%==Win32 set generator=Visual Studio 14 - if %platform%==Win64 set generator=Visual Studio 14 Win64 - if %platform%==Win32 set vcplatform=Win32 diff --git a/benchmarks/Makefile.am b/benchmarks/Makefile.am index 3ae14ffb..4f7df646 100644 --- a/benchmarks/Makefile.am +++ b/benchmarks/Makefile.am @@ -36,7 +36,7 @@ protoc_middleman2: make_tmp_dir $(top_srcdir)/src/protoc$(EXEEXT) $(benchmarks_ oldpwd=`pwd` && ( cd $(srcdir) && $$oldpwd/../src/protoc$(EXEEXT) -I. -I$(top_srcdir)/src --cpp_out=$$oldpwd/cpp --java_out=$$oldpwd/tmp/java/src/main/java --python_out=$$oldpwd/tmp $(benchmarks_protoc_inputs_proto2) ) touch protoc_middleman2 -all_data = $$(find $(srcdir) -type f -name "dataset.*.pb" -not -path "./tmp/*") +all_data = $$(find $$(cd $(srcdir) && pwd) -type f -name "dataset.*.pb" -not -path "$$(cd $(srcdir) && pwd)/tmp/*") ############# CPP RULES ############## @@ -90,8 +90,7 @@ $(benchmarks_protoc_outputs_proto2_header): protoc_middleman2 initialize_submodule: oldpwd=`pwd` - cd $(top_srcdir)/third_party - git submodule update --init -r + cd $(top_srcdir) && git submodule update --init -r third_party/benchmark cd $(top_srcdir)/third_party/benchmark && cmake -DCMAKE_BUILD_TYPE=Release && make cd $$oldpwd touch initialize_submodule @@ -127,8 +126,10 @@ java_benchmark_testing_files = \ java/src/main/java/com/google/protobuf/ProtoCaliperBenchmark.java javac_middleman: $(java_benchmark_testing_files) protoc_middleman protoc_middleman2 - cp -r $(srcdir)/java tmp && cd tmp/java && mvn clean compile assembly:single - cd ../.. + cp -r $(srcdir)/java tmp + mkdir -p tmp/java/lib + cp $(top_srcdir)/java/core/target/*.jar tmp/java/lib/protobuf-java.jar + cd tmp/java && mvn clean compile assembly:single -Dprotobuf.version=$(PACKAGE_VERSION) && cd ../.. @touch javac_middleman java-benchmark: javac_middleman @@ -138,10 +139,10 @@ java-benchmark: javac_middleman @echo 'conf=()' >> java-benchmark @echo 'data_files=""' >> java-benchmark @echo 'for arg in $$@; do if [[ $${arg:0:1} == "-" ]]; then conf+=($$arg); else data_files+="$$arg,"; fi; done' >> java-benchmark - @echo 'java -cp '"tmp/java/target/*.jar"' com.google.caliper.runner.CaliperMain com.google.protobuf.ProtoCaliperBenchmark -i runtime '"\\" >> java-benchmark - @echo '-b serializeToByteString,serializeToByteArray,serializeToMemoryStream,'"\\" >> java-benchmark - @echo 'deserializeFromByteString,deserializeFromByteArray,deserializeFromMemoryStream '"\\" >> java-benchmark - @echo '-DdataFile=$${data_files:0:-1} $${conf[*]}' >> java-benchmark + @echo 'java -cp '\"tmp/java/target/*:$(top_srcdir)/java/core/target/*:$(top_srcdir)/java/util/target/*\"" \\" >>java-benchmark + @echo ' com.google.caliper.runner.CaliperMain com.google.protobuf.ProtoCaliperBenchmark -i runtime '"\\" >> java-benchmark + @echo ' -b serializeToByteArray,serializeToMemoryStream,deserializeFromByteArray,deserializeFromMemoryStream '"\\" >> java-benchmark + @echo ' -DdataFile=$${data_files:0:-1} $${conf[*]}' >> java-benchmark @chmod +x java-benchmark java: protoc_middleman protoc_middleman2 java-benchmark @@ -180,8 +181,8 @@ nodist_libbenchmark_messages_la_SOURCES = \ python-pure-python-benchmark: python_add_init @echo "Writing shortcut script python-pure-python-benchmark..." @echo '#! /bin/bash' > python-pure-python-benchmark - @echo export LD_LIBRARY_PATH=$(top_srcdir)/src/libprotobuf.la >> python-pure-python-benchmark - @echo export DYLD_LIBRARY_PATH=$(top_srcdir)/src/libprotobuf.la >> python-pure-python-benchmark + @echo export LD_LIBRARY_PATH=$(top_srcdir)/src/.libs >> python-pure-python-benchmark + @echo export DYLD_LIBRARY_PATH=$(top_srcdir)/src/.libs >> python-pure-python-benchmark @echo export PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION=\'python\' >> python-pure-python-benchmark @echo cp $(srcdir)/python/py_benchmark.py tmp >> python-pure-python-benchmark @echo python tmp/py_benchmark.py '$$@' >> python-pure-python-benchmark @@ -190,8 +191,8 @@ python-pure-python-benchmark: python_add_init python-cpp-reflection-benchmark: python_add_init @echo "Writing shortcut script python-cpp-reflection-benchmark..." @echo '#! /bin/bash' > python-cpp-reflection-benchmark - @echo export LD_LIBRARY_PATH=$(top_srcdir)/src/libprotobuf.la >> python-cpp-reflection-benchmark - @echo export DYLD_LIBRARY_PATH=$(top_srcdir)/src/libprotobuf.la >> python-cpp-reflection-benchmark + @echo export LD_LIBRARY_PATH=$(top_srcdir)/src/.libs >> python-cpp-reflection-benchmark + @echo export DYLD_LIBRARY_PATH=$(top_srcdir)/src/.libs >> python-cpp-reflection-benchmark @echo export PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION=\'cpp\' >> python-cpp-reflection-benchmark @echo cp $(srcdir)/python/py_benchmark.py tmp >> python-cpp-reflection-benchmark @echo python tmp/py_benchmark.py '$$@' >> python-cpp-reflection-benchmark @@ -200,8 +201,8 @@ python-cpp-reflection-benchmark: python_add_init python-cpp-generated-code-benchmark: python_add_init libbenchmark_messages.la @echo "Writing shortcut script python-cpp-generated-code-benchmark..." @echo '#! /bin/bash' > python-cpp-generated-code-benchmark - @echo export LD_LIBRARY_PATH=$(top_srcdir)/src/libprotobuf.la >> python-cpp-generated-code-benchmark - @echo export DYLD_LIBRARY_PATH=$(top_srcdir)/src/libprotobuf.la >> python-cpp-generated-code-benchmark + @echo export LD_LIBRARY_PATH=$(top_srcdir)/src/.libs >> python-cpp-generated-code-benchmark + @echo export DYLD_LIBRARY_PATH=$(top_srcdir)/src/.libs >> python-cpp-generated-code-benchmark @echo export PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION=\'cpp\' >> python-cpp-generated-code-benchmark @echo cp $(srcdir)/python/py_benchmark.py tmp >> python-cpp-generated-code-benchmark @echo python tmp/py_benchmark.py --cpp_generated '$$@' >> python-cpp-generated-code-benchmark @@ -348,11 +349,11 @@ gogo_proto_middleman: protoc-gen-gogoproto oldpwd=`pwd` && ( cd $(srcdir) && $$oldpwd/../src/protoc$(EXEEXT) -I$(srcdir) -I$(top_srcdir) --plugin=protoc-gen-gogoproto --gogoproto_out=$$oldpwd/tmp/gogo_proto $(benchmarks_protoc_inputs) $(benchmarks_protoc_inputs_benchmark_wrapper) $(benchmarks_protoc_inputs_proto2) ) touch gogo_proto_middleman -new_data = $$(for data in $(all_data); do echo "tmp$${data\#$(srcdir)}"; done | xargs) +gogo_data = $$(for data in $(all_data); do echo "tmp/gogo_data$${data\#$(srcdir)}"; done | xargs) generate_gogo_data: protoc_middleman protoc_middleman2 gogo-data-scrubber - mkdir -p `dirname $(new_data)` - ./gogo-data-scrubber $(all_data) $(new_data) + mkdir -p `dirname $(gogo_data)` + ./gogo-data-scrubber $(all_data) $(gogo_data) touch generate_gogo_data make_tmp_dir_gogo: @@ -407,8 +408,6 @@ gogoslick_protoc_middleman: make_tmp_dir_gogo $(top_srcdir)/src/protoc$(EXEEXT) oldpwd=`pwd` && ( cd $(srcdir)/tmp/gogo_proto && $$oldpwd/../src/protoc$(EXEEXT) -I. -I$$oldpwd/$(top_srcdir)/src --gogoslick_out=$$oldpwd/tmp/gogoslick $(benchmarks_protoc_inputs_proto2_message4) ) touch gogoslick_protoc_middleman -gogo_data = $$(find . -type f -name "dataset.*.pb" -path "./tmp/*") - generate-gogo-benchmark-code: @echo '#! /bin/bash' > generate-gogo-benchmark-code @echo 'cp $(srcdir)/go/go_benchmark_test.go tmp/$$1/benchmark_code/$$1_benchmark1_test.go' >> generate-gogo-benchmark-code @@ -452,7 +451,7 @@ gogoslick: gogoslick_protoc_middleman generate_gogo_data gogo-benchmark generat ############ UTIL RULES BEGIN ############ -bin_PROGRAMS += protoc-gen-gogoproto gogo-data-scrubber +bin_PROGRAMS += protoc-gen-gogoproto gogo-data-scrubber protoc-gen-proto2_to_proto3 proto3-data-stripper protoc_gen_gogoproto_LDADD = $(top_srcdir)/src/libprotobuf.la $(top_srcdir)/src/libprotoc.la protoc_gen_gogoproto_SOURCES = util/protoc-gen-gogoproto.cc @@ -467,9 +466,86 @@ nodist_gogo_data_scrubber_SOURCES = \ $(benchmarks_protoc_outputs_proto2) \ $(benchmarks_protoc_outputs_proto2_header) \ $(benchmarks_protoc_outputs_header) + +protoc_gen_proto2_to_proto3_LDADD = $(top_srcdir)/src/libprotobuf.la $(top_srcdir)/src/libprotoc.la +protoc_gen_proto2_to_proto3_SOURCES = util/protoc-gen-proto2_to_proto3.cc +protoc_gen_proto2_to_proto3_CPPFLAGS = -I$(top_srcdir)/src -I$(srcdir)/cpp -I$(srcdir)/util + +proto3_data_stripper_LDADD = $(top_srcdir)/src/libprotobuf.la +proto3_data_stripper_SOURCES = util/proto3_data_stripper.cc +proto3_data_stripper_CPPFLAGS = -I$(top_srcdir)/src -I$(srcdir)/cpp -I$(srcdir)/util +util/proto3_data_stripper-proto3_data_stripper.$(OBJEXT): $(benchmarks_protoc_outputs) $(benchmarks_protoc_outputs_proto2) $(benchmarks_protoc_outputs_header) $(benchmarks_protoc_outputs_proto2_header) +nodist_proto3_data_stripper_SOURCES = \ + $(benchmarks_protoc_outputs) \ + $(benchmarks_protoc_outputs_proto2) \ + $(benchmarks_protoc_outputs_proto2_header) \ + $(benchmarks_protoc_outputs_header) + ############ UTIL RULES END ############ +############ PROTO3 PREPARATION BEGIN ############# + +proto3_proto_middleman: protoc-gen-proto2_to_proto3 + mkdir -p "tmp/proto3_proto" + oldpwd=`pwd` && ( cd $(srcdir) && $$oldpwd/../src/protoc$(EXEEXT) -I$(srcdir) -I$(top_srcdir) --plugin=protoc-gen-proto2_to_proto3 --proto2_to_proto3_out=$$oldpwd/tmp/proto3_proto $(benchmarks_protoc_inputs) $(benchmarks_protoc_inputs_benchmark_wrapper) $(benchmarks_protoc_inputs_proto2) ) + touch proto3_proto_middleman + +full_srcdir = $$(cd $(srcdir) && pwd) +proto3_data = $$(for data in $(all_data); do echo $(full_srcdir)"/tmp/proto3_data$${data\#$(full_srcdir)}"; done | xargs) + +generate_proto3_data: protoc_middleman protoc_middleman2 proto3-data-stripper + mkdir -p `dirname $(proto3_data)` + ./proto3-data-stripper $(all_data) $(proto3_data) + touch generate_proto3_data + +############ PROTO3 PREPARATION END ############# + +############ PHP RULES BEGIN ################# + +proto3_middleman_php: proto3_proto_middleman + mkdir -p "tmp/php" + oldpwd=`pwd` && ( cd tmp/proto3_proto && $$oldpwd/../src/protoc$(EXEEXT) -I$(srcdir) -I$(top_srcdir) --php_out=$$oldpwd/tmp/php $(benchmarks_protoc_inputs) $(benchmarks_protoc_inputs_benchmark_wrapper) $(benchmarks_protoc_inputs_proto2) ) + touch proto3_middleman_php + +php-benchmark: proto3_middleman_php generate_proto3_data + mkdir -p "tmp/php/Google/Protobuf/Benchmark" && cp php/PhpBenchmark.php "tmp/php/Google/Protobuf/Benchmark" + cp php/autoload.php "tmp/php" + @echo "Writing shortcut script php-benchmark..." + @echo '#! /bin/bash' > php-benchmark + @echo 'export PROTOBUF_PHP_SRCDIR="$$(cd $(top_srcdir) && pwd)/php/src"' >> php-benchmark + @echo 'cd tmp/php' >> php-benchmark + @echo 'export CURRENT_DIR=$$(pwd)' >> php-benchmark + @echo 'php -d auto_prepend_file="autoload.php" -d include_path="$$(pwd)" Google/Protobuf/Benchmark/PhpBenchmark.php $$@' >> php-benchmark + @echo 'cd ../..' >> php-benchmark + @chmod +x php-benchmark + +php: php-benchmark proto3_middleman_php + ./php-benchmark $(proto3_data) + +php_c_extension: + cd $(top_srcdir)/php/ext/google/protobuf && ./configure CFLAGS='-O3' && make -j8 + +php-c-benchmark: proto3_middleman_php generate_proto3_data php_c_extension php_c_extension + mkdir -p "tmp/php/Google/Protobuf/Benchmark" && cp php/PhpBenchmark.php "tmp/php/Google/Protobuf/Benchmark" + cp php/autoload.php "tmp/php" + @echo "Writing shortcut script php-c-benchmark..." + @echo '#! /bin/bash' > php-c-benchmark + @echo 'export PROTOBUF_PHP_SRCDIR="$$(cd $(top_srcdir) && pwd)/php/src"' >> php-c-benchmark + @echo 'export PROTOBUF_PHP_EXTDIR="$$PROTOBUF_PHP_SRCDIR/../ext/google/protobuf/modules"' >> php-c-benchmark + @echo 'echo "$$PROTOBUF_PHP_EXTDIR/protobuf.so"' >> php-c-benchmark + @echo 'cd tmp/php' >> php-c-benchmark + @echo 'export CURRENT_DIR=$$(pwd)' >> php-c-benchmark + @echo 'php -d auto_prepend_file="autoload.php" -d include_path="$$(pwd)" -d extension="$$PROTOBUF_PHP_EXTDIR/protobuf.so" Google/Protobuf/Benchmark/PhpBenchmark.php $$@' >> php-c-benchmark + @echo 'cd ../..' >> php-c-benchmark + @chmod +x php-c-benchmark + +php_c: php-c-benchmark proto3_middleman_php + ./php-c-benchmark $(proto3_data) + + +############ PHP RULES END ################# + MAINTAINERCLEANFILES = \ Makefile.in @@ -512,8 +588,14 @@ CLEANFILES = \ gogoslick_protoc_middleman \ gogoslick \ gogo-benchmark \ - gogo/cpp_no_group/cpp_benchmark.* + gogo/cpp_no_group/cpp_benchmark.* \ + proto3_proto_middleman \ + generate_proto3_data \ + php-benchmark \ + php-c-benchmark \ + proto3_middleman_php clean-local: -rm -rf tmp/* + diff --git a/benchmarks/README.md b/benchmarks/README.md index 21cd7352..91b80a92 100644 --- a/benchmarks/README.md +++ b/benchmarks/README.md @@ -5,7 +5,7 @@ This directory contains benchmarking schemas and data sets that you can use to test a variety of performance scenarios against your protobuf language runtime. If you are looking for performance numbers of officially support languages, see [here]( -https://github.com/google/protobuf/blob/master/docs/Performance.md) +https://github.com/google/protobuf/blob/master/docs/performance.md) ## Prerequisite @@ -58,6 +58,10 @@ $ export PATH=$PATH:$(go env GOPATH)/bin The first command installs `protoc-gen-go` into the `bin` directory in your local `GOPATH`. The second command adds the `bin` directory to your `PATH` so that `protoc` can locate the plugin later. +### PHP +PHP benchmark's requirement is the same as PHP protobuf's requirements. The benchmark will automaticly +include PHP protobuf's src and build the c extension if required. + ### Big data There's some optional big testing data which is not included in the directory @@ -120,6 +124,18 @@ $ make python-cpp-generated-code $ make go ``` + +### PHP +We have two version of php protobuf implemention: pure php, php with c extension. To run these version benchmark, you need to: +#### Pure PHP +``` +$ make php +``` +#### PHP with c extension +``` +$ make php_c +``` + To run a specific dataset or run with specific options: ### Java: @@ -167,6 +183,18 @@ $ make go-benchmark $ ./go-benchmark $(specific generated dataset file name) [go testing options] ``` +### PHP +#### Pure PHP +``` +$ make php-benchmark +$ ./php-benchmark $(specific generated dataset file name) +``` +#### PHP with c extension +``` +$ make php-c-benchmark +$ ./php-c-benchmark $(specific generated dataset file name) +``` + ## Benchmark datasets diff --git a/benchmarks/java/pom.xml b/benchmarks/java/pom.xml index c2cd78a1..570bd664 100755..100644 --- a/benchmarks/java/pom.xml +++ b/benchmarks/java/pom.xml @@ -14,7 +14,10 @@ <dependency> <groupId>com.google.protobuf</groupId> <artifactId>protobuf-java</artifactId> - <version>3.5.0</version> + <version>${protobuf.version}</version> + <type>jar</type> + <scope>system</scope> + <systemPath>${project.basedir}/lib/protobuf-java.jar</systemPath> </dependency> <dependency> <groupId>com.google.caliper</groupId> diff --git a/benchmarks/java/src/main/java/com/google/protobuf/ProtoCaliperBenchmark.java b/benchmarks/java/src/main/java/com/google/protobuf/ProtoCaliperBenchmark.java index 94568aea..c766d74e 100755..100644 --- a/benchmarks/java/src/main/java/com/google/protobuf/ProtoCaliperBenchmark.java +++ b/benchmarks/java/src/main/java/com/google/protobuf/ProtoCaliperBenchmark.java @@ -5,6 +5,7 @@ import com.google.caliper.BeforeExperiment; import com.google.caliper.AfterExperiment; import com.google.caliper.Benchmark; import com.google.caliper.Param; +import com.google.caliper.api.VmOptions; import com.google.protobuf.ByteString; import com.google.protobuf.CodedOutputStream; import com.google.protobuf.ExtensionRegistry; @@ -22,6 +23,12 @@ import java.io.RandomAccessFile; import java.util.ArrayList; import java.util.List; +// Caliper set CICompilerCount to 1 for making sure compilation doesn't run in parallel with itself, +// This makes TieredCompilation not working. We just disable TieredCompilation by default. In master +// branch this has been disabled by default in caliper: +// https://github.com/google/caliper/blob/master/caliper-runner/src/main/java/com/google/caliper/runner/target/Jvm.java#L38:14 +// But this haven't been added into most recent release. +@VmOptions("-XX:-TieredCompilation") public class ProtoCaliperBenchmark { public enum BenchmarkMessageType { GOOGLE_MESSAGE1_PROTO3 { @@ -152,18 +159,6 @@ public class ProtoCaliperBenchmark { @Benchmark - void serializeToByteString(int reps) throws IOException { - if (sampleMessageList.size() == 0) { - return; - } - for (int i = 0; i < reps; i++) { - for (int j = 0; j < sampleMessageList.size(); j++) { - sampleMessageList.get(j).toByteString(); - } - } - } - - @Benchmark void serializeToByteArray(int reps) throws IOException { if (sampleMessageList.size() == 0) { return; @@ -189,19 +184,6 @@ public class ProtoCaliperBenchmark { } @Benchmark - void deserializeFromByteString(int reps) throws IOException { - if (inputStringList.size() == 0) { - return; - } - for (int i = 0; i < reps; i++) { - for (int j = 0; j < inputStringList.size(); j++) { - benchmarkMessageType.getDefaultInstance().getParserForType().parseFrom( - inputStringList.get(j), extensions); - } - } - } - - @Benchmark void deserializeFromByteArray(int reps) throws IOException { if (inputDataList.size() == 0) { return; diff --git a/benchmarks/php/PhpBenchmark.php b/benchmarks/php/PhpBenchmark.php new file mode 100644 index 00000000..058940d1 --- /dev/null +++ b/benchmarks/php/PhpBenchmark.php @@ -0,0 +1,157 @@ +<?php + +namespace Google\Protobuf\Benchmark; + +const NAME = "PhpBenchmark.php"; + +function _require_all($dir, &$prefix) { + // require all php files + foreach (glob("$dir/*") as $path) { + if (preg_match('/\.php$/', $path) && + substr($path, -strlen(NAME)) != NAME) { + require_once(substr($path, strlen($prefix) + 1)); + } elseif (is_dir($path)) { + _require_all($path, $prefix); + } + } +} +// include all file +foreach (explode(PATH_SEPARATOR, get_include_path()) as $one_include_path) { + _require_all($one_include_path, $one_include_path); +} + +use Benchmarks\BenchmarkDataset; + +class BenchmarkMethod +{ + // $args[0]: dataset + // $args[1]: message class + static function parse(&$args) { + $payloads = $args[0]->getPayload(); + for ($i = $payloads->count() - 1; $i >= 0; $i--) { + (new $args[1]())->mergeFromString($payloads->offsetGet($i)); + } + } + + // $args: array of message + static function serialize(&$args) { + foreach ($args as &$temp_message) { + $temp_message->serializeToString(); + } + } +} + +class Benchmark +{ + private $benchmark_name; + private $args; + private $benchmark_time; + private $total_bytes; + private $coefficient; + + public function __construct($benchmark_name, $args, $total_bytes, + $benchmark_time = 5.0) { + $this->args = $args; + $this->benchmark_name = $benchmark_name; + $this->benchmark_time = $benchmark_time; + $this->total_bytes = $total_bytes; + $this->coefficient = pow (10, 0) / pow(2, 20); + } + + public function runBenchmark() { + $t = $this->runBenchmarkWithTimes(1); + $times = ceil($this->benchmark_time / $t); + return $this->total_bytes * $times / + $this->runBenchmarkWithTimes($times) * + $this->coefficient; + } + + private function runBenchmarkWithTimes($times) { + $st = microtime(true); + for ($i = 0; $i < $times; $i++) { + call_user_func_array($this->benchmark_name, array(&$this->args)); + } + $en = microtime(true); + return $en - $st; + } +} + +function getMessageName(&$dataset) { + switch ($dataset->getMessageName()) { + case "benchmarks.proto3.GoogleMessage1": + return "\Benchmarks\Proto3\GoogleMessage1"; + case "benchmarks.proto2.GoogleMessage1": + return "\Benchmarks\Proto2\GoogleMessage1"; + case "benchmarks.proto2.GoogleMessage2": + return "\Benchmarks\Proto2\GoogleMessage2"; + case "benchmarks.google_message3.GoogleMessage3": + return "\Benchmarks\Google_message3\GoogleMessage3"; + case "benchmarks.google_message4.GoogleMessage4": + return "\Benchmarks\Google_message4\GoogleMessage4"; + default: + exit("Message " . $dataset->getMessageName() . " not found !"); + } +} + +function runBenchmark($file) { + $datafile = fopen($file, "r") or die("Unable to open file " . $file); + $bytes = fread($datafile, filesize($file)); + $dataset = new BenchmarkDataset(NULL); + $dataset->mergeFromString($bytes); + $message_name = getMessageName($dataset); + $message_list = array(); + $total_bytes = 0; + $payloads = $dataset->getPayload(); + for ($i = $payloads->count() - 1; $i >= 0; $i--) { + $new_message = new $message_name(); + $new_message->mergeFromString($payloads->offsetGet($i)); + array_push($message_list, $new_message); + $total_bytes += strlen($payloads->offsetGet($i)); + } + + $parse_benchmark = new Benchmark( + "\Google\Protobuf\Benchmark\BenchmarkMethod::parse", + array($dataset, $message_name), $total_bytes); + $serialize_benchmark = new Benchmark( + "\Google\Protobuf\Benchmark\BenchmarkMethod::serialize", + $message_list, $total_bytes); + + return array( + "filename" => $file, + "benchmarks" => array( + "parse_php" => $parse_benchmark->runBenchmark(), + "serailize_php" => $serialize_benchmark->runBenchmark() + ), + "message_name" => $dataset->getMessageName() + ); +} + +// main +$json_output = false; +$results = array(); +foreach ($argv as $index => $arg) { + if ($index == 0) { + continue; + } + if ($arg == "--json") { + $json_output = true; + continue; + } else { + array_push($results, runBenchmark($arg)); + } +} + +if ($json_output) { + print json_encode($results); +} else { + print "PHP protobuf benchmark result:\n\n"; + foreach ($results as $result) { + printf("result for test data file: %s\n", $result["filename"]); + foreach ($result["benchmarks"] as $benchmark => $throughput) { + printf(" Throughput for benchmark %s: %.2f MB/s\n", + $benchmark, $throughput); + } + } +} + +?> diff --git a/benchmarks/php/autoload.php b/benchmarks/php/autoload.php new file mode 100644 index 00000000..52a8741f --- /dev/null +++ b/benchmarks/php/autoload.php @@ -0,0 +1,25 @@ +<?php + +define("GOOGLE_INTERNAL_NAMESPACE", "Google\\Protobuf\\Internal\\"); +define("GOOGLE_NAMESPACE", "Google\\Protobuf\\"); +define("GOOGLE_GPBMETADATA_NAMESPACE", "GPBMetadata\\Google\\Protobuf\\"); +define("BENCHMARK_NAMESPACE", "Benchmarks"); +define("BENCHMARK_GPBMETADATA_NAMESPACE", "GPBMetadata\\Benchmarks"); + +function protobuf_autoloader_impl($class, $prefix, $include_path) { + $length = strlen($prefix); + if ((substr($class, 0, $length) === $prefix)) { + $path = $include_path . '/' . implode('/', array_map('ucwords', explode('\\', $class))) . '.php'; + include_once $path; + } +} + +function protobuf_autoloader($class) { + protobuf_autoloader_impl($class, GOOGLE_INTERNAL_NAMESPACE, getenv('PROTOBUF_PHP_SRCDIR')); + protobuf_autoloader_impl($class, GOOGLE_NAMESPACE, getenv('PROTOBUF_PHP_SRCDIR')); + protobuf_autoloader_impl($class, GOOGLE_GPBMETADATA_NAMESPACE, getenv('PROTOBUF_PHP_SRCDIR')); + protobuf_autoloader_impl($class, BENCHMARK_NAMESPACE, getenv('CURRENT_DIR')); + protobuf_autoloader_impl($class, BENCHMARK_GPBMETADATA_NAMESPACE, getenv('CURRENT_DIR')); +} + +spl_autoload_register('protobuf_autoloader'); diff --git a/benchmarks/python/py_benchmark.py b/benchmarks/python/py_benchmark.py index 6942d208..e86b61e7 100755 --- a/benchmarks/python/py_benchmark.py +++ b/benchmarks/python/py_benchmark.py @@ -1,3 +1,4 @@ +from __future__ import print_function import sys import os import timeit @@ -138,15 +139,15 @@ if __name__ == "__main__": results.append(run_one_test(file)) if args.json != "no": - print json.dumps(results) + print(json.dumps(results)) else: for result in results: - print "Message %s of dataset file %s" % \ - (result["message_name"], result["filename"]) - print "Average time for parse_from_benchmark: %.2f ns" % \ + print("Message %s of dataset file %s" % \ + (result["message_name"], result["filename"])) + print("Average time for parse_from_benchmark: %.2f ns" % \ (result["benchmarks"][ \ - args.behavior_prefix + "_parse_from_benchmark"]) - print "Average time for serialize_to_benchmark: %.2f ns" % \ + args.behavior_prefix + "_parse_from_benchmark"])) + print("Average time for serialize_to_benchmark: %.2f ns" % \ (result["benchmarks"][ \ - args.behavior_prefix + "_serialize_to_benchmark"]) - print "" + args.behavior_prefix + "_serialize_to_benchmark"])) + print("") diff --git a/benchmarks/util/big_query_utils.py b/benchmarks/util/big_query_utils.py index 14105aa6..aea55bbd 100755 --- a/benchmarks/util/big_query_utils.py +++ b/benchmarks/util/big_query_utils.py @@ -1,5 +1,6 @@ #!/usr/bin/env python2.7 +from __future__ import print_function import argparse import json import uuid @@ -37,11 +38,11 @@ def create_dataset(biq_query, project_id, dataset_id): dataset_req.execute(num_retries=NUM_RETRIES) except HttpError as http_error: if http_error.resp.status == 409: - print 'Warning: The dataset %s already exists' % dataset_id + print('Warning: The dataset %s already exists' % dataset_id) else: # Note: For more debugging info, print "http_error.content" - print 'Error in creating dataset: %s. Err: %s' % (dataset_id, - http_error) + print('Error in creating dataset: %s. Err: %s' % (dataset_id, + http_error)) is_success = False return is_success @@ -109,13 +110,13 @@ def create_table2(big_query, table_req = big_query.tables().insert( projectId=project_id, datasetId=dataset_id, body=body) res = table_req.execute(num_retries=NUM_RETRIES) - print 'Successfully created %s "%s"' % (res['kind'], res['id']) + print('Successfully created %s "%s"' % (res['kind'], res['id'])) except HttpError as http_error: if http_error.resp.status == 409: - print 'Warning: Table %s already exists' % table_id + print('Warning: Table %s already exists' % table_id) else: - print 'Error in creating table: %s. Err: %s' % (table_id, - http_error) + print('Error in creating table: %s. Err: %s' % (table_id, + http_error)) is_success = False return is_success @@ -141,9 +142,9 @@ def patch_table(big_query, project_id, dataset_id, table_id, fields_schema): tableId=table_id, body=body) res = table_req.execute(num_retries=NUM_RETRIES) - print 'Successfully patched %s "%s"' % (res['kind'], res['id']) + print('Successfully patched %s "%s"' % (res['kind'], res['id'])) except HttpError as http_error: - print 'Error in creating table: %s. Err: %s' % (table_id, http_error) + print('Error in creating table: %s. Err: %s' % (table_id, http_error)) is_success = False return is_success @@ -159,10 +160,10 @@ def insert_rows(big_query, project_id, dataset_id, table_id, rows_list): body=body) res = insert_req.execute(num_retries=NUM_RETRIES) if res.get('insertErrors', None): - print 'Error inserting rows! Response: %s' % res + print('Error inserting rows! Response: %s' % res) is_success = False except HttpError as http_error: - print 'Error inserting rows to the table %s' % table_id + print('Error inserting rows to the table %s' % table_id) is_success = False return is_success @@ -176,8 +177,8 @@ def sync_query_job(big_query, project_id, query, timeout=5000): projectId=project_id, body=query_data).execute(num_retries=NUM_RETRIES) except HttpError as http_error: - print 'Query execute job failed with error: %s' % http_error - print http_error.content + print('Query execute job failed with error: %s' % http_error) + print(http_error.content) return query_job diff --git a/benchmarks/util/data_proto2_to_proto3_util.h b/benchmarks/util/data_proto2_to_proto3_util.h new file mode 100644 index 00000000..5eea8509 --- /dev/null +++ b/benchmarks/util/data_proto2_to_proto3_util.h @@ -0,0 +1,64 @@ +#ifndef PROTOBUF_BENCHMARKS_UTIL_DATA_PROTO2_TO_PROTO3_UTIL_H_ +#define PROTOBUF_BENCHMARKS_UTIL_DATA_PROTO2_TO_PROTO3_UTIL_H_ + +#include "google/protobuf/message.h" +#include "google/protobuf/descriptor.h" + +using google::protobuf::FieldDescriptor; +using google::protobuf::Message; +using google::protobuf::Reflection; + +namespace google { +namespace protobuf { +namespace util { + +class DataStripper { + public: + void StripMessage(Message *message) { + std::vector<const FieldDescriptor*> set_fields; + const Reflection* reflection = message->GetReflection(); + reflection->ListFields(*message, &set_fields); + + for (size_t i = 0; i < set_fields.size(); i++) { + const FieldDescriptor* field = set_fields[i]; + if (ShouldBeClear(field)) { + reflection->ClearField(message, field); + continue; + } + if (field->type() == FieldDescriptor::TYPE_MESSAGE) { + if (field->is_repeated()) { + for (int j = 0; j < reflection->FieldSize(*message, field); j++) { + StripMessage(reflection->MutableRepeatedMessage(message, field, j)); + } + } else { + StripMessage(reflection->MutableMessage(message, field)); + } + } + } + + reflection->MutableUnknownFields(message)->Clear(); + } + private: + virtual bool ShouldBeClear(const FieldDescriptor *field) = 0; +}; + +class GogoDataStripper : public DataStripper { + private: + virtual bool ShouldBeClear(const FieldDescriptor *field) { + return field->type() == FieldDescriptor::TYPE_GROUP; + } +}; + +class Proto3DataStripper : public DataStripper { + private: + virtual bool ShouldBeClear(const FieldDescriptor *field) { + return field->type() == FieldDescriptor::TYPE_GROUP || + field->is_extension(); + } +}; + +} // namespace util +} // namespace protobuf +} // namespace google + +#endif // PROTOBUF_BENCHMARKS_UTIL_DATA_PROTO2_TO_PROTO3_UTIL_H_ diff --git a/benchmarks/util/gogo_data_scrubber.cc b/benchmarks/util/gogo_data_scrubber.cc index fb9af6e2..9ef57b0d 100644 --- a/benchmarks/util/gogo_data_scrubber.cc +++ b/benchmarks/util/gogo_data_scrubber.cc @@ -4,43 +4,11 @@ #include "datasets/google_message2/benchmark_message2.pb.h" #include "datasets/google_message3/benchmark_message3.pb.h" #include "datasets/google_message4/benchmark_message4.pb.h" - -#include "google/protobuf/message.h" -#include "google/protobuf/descriptor.h" +#include "data_proto2_to_proto3_util.h" #include <fstream> -using google::protobuf::FieldDescriptor; -using google::protobuf::Message; -using google::protobuf::Reflection; - - -class DataGroupStripper { - public: - static void StripMessage(Message *message) { - std::vector<const FieldDescriptor*> set_fields; - const Reflection* reflection = message->GetReflection(); - reflection->ListFields(*message, &set_fields); - - for (size_t i = 0; i < set_fields.size(); i++) { - const FieldDescriptor* field = set_fields[i]; - if (field->type() == FieldDescriptor::TYPE_GROUP) { - reflection->ClearField(message, field); - } - if (field->type() == FieldDescriptor::TYPE_MESSAGE) { - if (field->is_repeated()) { - for (int j = 0; j < reflection->FieldSize(*message, field); j++) { - StripMessage(reflection->MutableRepeatedMessage(message, field, j)); - } - } else { - StripMessage(reflection->MutableMessage(message, field)); - } - } - } - - reflection->MutableUnknownFields(message)->Clear(); - } -}; +using google::protobuf::util::GogoDataStripper; std::string ReadFile(const std::string& name) { std::ifstream file(name.c_str()); @@ -91,7 +59,8 @@ int main(int argc, char *argv[]) { for (int i = 0; i < dataset.payload_size(); i++) { message->ParseFromString(dataset.payload(i)); - DataGroupStripper::StripMessage(message); + GogoDataStripper stripper; + stripper.StripMessage(message); dataset.set_payload(i, message->SerializeAsString()); } diff --git a/benchmarks/util/proto3_data_stripper.cc b/benchmarks/util/proto3_data_stripper.cc new file mode 100644 index 00000000..3096c4c1 --- /dev/null +++ b/benchmarks/util/proto3_data_stripper.cc @@ -0,0 +1,74 @@ +#include "benchmarks.pb.h" +#include "datasets/google_message1/proto2/benchmark_message1_proto2.pb.h" +#include "datasets/google_message1/proto3/benchmark_message1_proto3.pb.h" +#include "datasets/google_message2/benchmark_message2.pb.h" +#include "datasets/google_message3/benchmark_message3.pb.h" +#include "datasets/google_message4/benchmark_message4.pb.h" +#include "data_proto2_to_proto3_util.h" + +#include <fstream> + +using google::protobuf::util::Proto3DataStripper; + +std::string ReadFile(const std::string& name) { + std::ifstream file(name.c_str()); + GOOGLE_CHECK(file.is_open()) << "Couldn't find file '" + << name + << "', please make sure you are running this command from the benchmarks" + << " directory.\n"; + return std::string((std::istreambuf_iterator<char>(file)), + std::istreambuf_iterator<char>()); +} + +int main(int argc, char *argv[]) { + if (argc % 2 == 0 || argc == 1) { + std::cerr << "Usage: [input_files] [output_file_names] where " << + "input_files are one to one mapping to output_file_names." << + std::endl; + return 1; + } + + for (int i = argc / 2; i > 0; i--) { + const std::string &input_file = argv[i]; + const std::string &output_file = argv[i + argc / 2]; + + std::cerr << "Generating " << input_file + << " to " << output_file << std::endl; + benchmarks::BenchmarkDataset dataset; + Message* message; + std::string dataset_payload = ReadFile(input_file); + GOOGLE_CHECK(dataset.ParseFromString(dataset_payload)) + << "Can' t parse data file " << input_file; + + if (dataset.message_name() == "benchmarks.proto3.GoogleMessage1") { + message = new benchmarks::proto3::GoogleMessage1; + } else if (dataset.message_name() == "benchmarks.proto2.GoogleMessage1") { + message = new benchmarks::proto2::GoogleMessage1; + } else if (dataset.message_name() == "benchmarks.proto2.GoogleMessage2") { + message = new benchmarks::proto2::GoogleMessage2; + } else if (dataset.message_name() == + "benchmarks.google_message3.GoogleMessage3") { + message = new benchmarks::google_message3::GoogleMessage3; + } else if (dataset.message_name() == + "benchmarks.google_message4.GoogleMessage4") { + message = new benchmarks::google_message4::GoogleMessage4; + } else { + std::cerr << "Unknown message type: " << dataset.message_name(); + exit(1); + } + + for (int i = 0; i < dataset.payload_size(); i++) { + message->ParseFromString(dataset.payload(i)); + Proto3DataStripper stripper; + stripper.StripMessage(message); + dataset.set_payload(i, message->SerializeAsString()); + } + + std::ofstream ofs(output_file); + ofs << dataset.SerializeAsString(); + ofs.close(); + } + + + return 0; +} diff --git a/benchmarks/util/protoc-gen-gogoproto.cc b/benchmarks/util/protoc-gen-gogoproto.cc index bfa6a5e5..9c1b3d04 100644 --- a/benchmarks/util/protoc-gen-gogoproto.cc +++ b/benchmarks/util/protoc-gen-gogoproto.cc @@ -12,7 +12,7 @@ using google::protobuf::FileDescriptor; using google::protobuf::DescriptorPool; using google::protobuf::io::Printer; using google::protobuf::util::SchemaGroupStripper; -using google::protobuf::util::SchemaAddZeroEnumValue; +using google::protobuf::util::EnumScrubber; namespace google { namespace protobuf { @@ -74,7 +74,7 @@ class GoGoProtoGenerator : public CodeGenerator { file->CopyTo(&new_file); SchemaGroupStripper::StripFile(file, &new_file); - SchemaAddZeroEnumValue enum_scrubber; + EnumScrubber enum_scrubber; enum_scrubber.ScrubFile(&new_file); string filename = file->name(); diff --git a/benchmarks/util/protoc-gen-proto2_to_proto3.cc b/benchmarks/util/protoc-gen-proto2_to_proto3.cc new file mode 100644 index 00000000..d0a89023 --- /dev/null +++ b/benchmarks/util/protoc-gen-proto2_to_proto3.cc @@ -0,0 +1,115 @@ +#include "google/protobuf/compiler/code_generator.h" +#include "google/protobuf/io/zero_copy_stream.h" +#include "google/protobuf/io/printer.h" +#include "google/protobuf/descriptor.h" +#include "google/protobuf/descriptor.pb.h" +#include "schema_proto2_to_proto3_util.h" + +#include "google/protobuf/compiler/plugin.h" + +using google::protobuf::FileDescriptorProto; +using google::protobuf::FileDescriptor; +using google::protobuf::DescriptorPool; +using google::protobuf::io::Printer; +using google::protobuf::util::SchemaGroupStripper; +using google::protobuf::util::EnumScrubber; +using google::protobuf::util::ExtensionStripper; +using google::protobuf::util::FieldScrubber; + +namespace google { +namespace protobuf { +namespace compiler { + +namespace { + +string StripProto(string filename) { + return filename.substr(0, filename.rfind(".proto")); +} + +DescriptorPool* GetPool() { + static DescriptorPool *pool = new DescriptorPool(); + return pool; +} + +} // namespace + +class Proto2ToProto3Generator final : public CodeGenerator { + public: + bool GenerateAll(const std::vector<const FileDescriptor*>& files, + const string& parameter, + GeneratorContext* context, + string* error) const { + for (int i = 0; i < files.size(); i++) { + for (auto file : files) { + if (CanGenerate(file)) { + Generate(file, parameter, context, error); + break; + } + } + } + + return true; + } + + bool Generate(const FileDescriptor* file, + const string& parameter, + GeneratorContext* context, + string* error) const { + FileDescriptorProto new_file; + file->CopyTo(&new_file); + SchemaGroupStripper::StripFile(file, &new_file); + + EnumScrubber enum_scrubber; + enum_scrubber.ScrubFile(&new_file); + ExtensionStripper::StripFile(&new_file); + FieldScrubber::ScrubFile(&new_file); + new_file.set_syntax("proto3"); + + string filename = file->name(); + string basename = StripProto(filename); + + std::vector<std::pair<string,string>> option_pairs; + ParseGeneratorParameter(parameter, &option_pairs); + + std::unique_ptr<google::protobuf::io::ZeroCopyOutputStream> output( + context->Open(basename + ".proto")); + string content = GetPool()->BuildFile(new_file)->DebugString(); + Printer printer(output.get(), '$'); + printer.WriteRaw(content.c_str(), content.size()); + + return true; + } + private: + bool CanGenerate(const FileDescriptor* file) const { + if (GetPool()->FindFileByName(file->name()) != nullptr) { + return false; + } + for (int j = 0; j < file->dependency_count(); j++) { + if (GetPool()->FindFileByName(file->dependency(j)->name()) == nullptr) { + return false; + } + } + for (int j = 0; j < file->public_dependency_count(); j++) { + if (GetPool()->FindFileByName( + file->public_dependency(j)->name()) == nullptr) { + return false; + } + } + for (int j = 0; j < file->weak_dependency_count(); j++) { + if (GetPool()->FindFileByName( + file->weak_dependency(j)->name()) == nullptr) { + return false; + } + } + return true; + } +}; + +} // namespace compiler +} // namespace protobuf +} // namespace google + +int main(int argc, char* argv[]) { + google::protobuf::compiler::Proto2ToProto3Generator generator; + return google::protobuf::compiler::PluginMain(argc, argv, &generator); +} diff --git a/benchmarks/util/run_and_upload.py b/benchmarks/util/result_parser.py index ae22a668..a843923a 100755 --- a/benchmarks/util/run_and_upload.py +++ b/benchmarks/util/result_parser.py @@ -1,45 +1,34 @@ -import argparse -import os -import re -import copy -import uuid -import calendar -import time -import big_query_utils -import datetime -import json # This import depends on the automake rule protoc_middleman, please make sure # protoc_middleman has been built before run this file. -import os.path, sys +import json +import re +import os.path +# BEGIN OPENSOURCE +import sys sys.path.append(os.path.join(os.path.dirname(os.path.realpath(__file__)), os.pardir)) +# END OPENSOURCE import tmp.benchmarks_pb2 as benchmarks_pb2 -from click.types import STRING - -_PROJECT_ID = 'grpc-testing' -_DATASET = 'protobuf_benchmark_result' -_TABLE = 'opensource_result_v1' -_NOW = "%d%02d%02d" % (datetime.datetime.now().year, - datetime.datetime.now().month, - datetime.datetime.now().day) -file_size_map = {} +__file_size_map = {} -def get_data_size(file_name): - if file_name in file_size_map: - return file_size_map[file_name] +def __get_data_size(filename): + if filename[0] != '/': + filename = os.path.dirname(os.path.abspath(__file__)) + "/../" + filename + if filename in __file_size_map: + return __file_size_map[filename] benchmark_dataset = benchmarks_pb2.BenchmarkDataset() benchmark_dataset.ParseFromString( - open(os.path.dirname(os.path.abspath(__file__)) + "/../" + file_name).read()) + open(filename).read()) size = 0 count = 0 for payload in benchmark_dataset.payload: size += len(payload) count += 1 - file_size_map[file_name] = (size, 1.0 * size / count) + __file_size_map[filename] = (size, 1.0 * size / count) return size, 1.0 * size / count -def extract_file_name(file_name): +def __extract_file_name(file_name): name_list = re.split("[/\.]", file_name) short_file_name = "" for name in name_list: @@ -48,15 +37,12 @@ def extract_file_name(file_name): return short_file_name -cpp_result = [] -python_result = [] -java_result = [] -go_result = [] +__results = [] # CPP results example: -# [ -# "benchmarks": [ +# [ +# "benchmarks": [ # { # "bytes_per_second": int, # "cpu_time": int, @@ -64,12 +50,11 @@ go_result = [] # "time_unit: string, # ... # }, -# ... +# ... # ], -# ... +# ... # ] -def parse_cpp_result(filename): - global cpp_result +def __parse_cpp_result(filename): if filename == "": return if filename[0] != '/': @@ -80,31 +65,32 @@ def parse_cpp_result(filename): data_filename = "".join( re.split("(_parse_|_serialize)", benchmark["name"])[0]) behavior = benchmark["name"][len(data_filename) + 1:] - cpp_result.append({ + if data_filename[:2] == "BM": + data_filename = data_filename[3:] + __results.append({ "language": "cpp", - "dataFileName": data_filename, + "dataFilename": data_filename, "behavior": behavior, "throughput": benchmark["bytes_per_second"] / 2.0 ** 20 }) # Python results example: -# [ -# [ +# [ +# [ # { # "filename": string, # "benchmarks": { -# behavior: results, +# behavior: results, # ... # }, # "message_name": STRING # }, -# ... +# ... # ], #pure-python -# ... +# ... # ] -def parse_python_result(filename): - global python_result +def __parse_python_result(filename): if filename == "": return if filename[0] != '/': @@ -113,11 +99,11 @@ def parse_python_result(filename): results_list = json.loads(f.read()) for results in results_list: for result in results: - _, avg_size = get_data_size(result["filename"]) + _, avg_size = __get_data_size(result["filename"]) for behavior in result["benchmarks"]: - python_result.append({ + __results.append({ "language": "python", - "dataFileName": extract_file_name(result["filename"]), + "dataFilename": __extract_file_name(result["filename"]), "behavior": behavior, "throughput": avg_size / result["benchmarks"][behavior] * 1e9 / 2 ** 20 @@ -125,7 +111,7 @@ def parse_python_result(filename): # Java results example: -# [ +# [ # { # "id": string, # "instrumentSpec": {...}, @@ -151,12 +137,11 @@ def parse_python_result(filename): # }, # ... # } -# -# }, -# ... +# +# }, +# ... # ] -def parse_java_result(filename): - global average_bytes_per_message, java_result +def __parse_java_result(filename): if filename == "": return if filename[0] != '/': @@ -170,13 +155,13 @@ def parse_java_result(filename): total_weight += measurement["weight"] total_value += measurement["value"]["magnitude"] avg_time = total_value * 1.0 / total_weight - total_size, _ = get_data_size( + total_size, _ = __get_data_size( result["scenario"]["benchmarkSpec"]["parameters"]["dataFile"]) - java_result.append({ + __results.append({ "language": "java", "throughput": total_size / avg_time * 1e9 / 2 ** 20, "behavior": result["scenario"]["benchmarkSpec"]["methodName"], - "dataFileName": extract_file_name( + "dataFilename": __extract_file_name( result["scenario"]["benchmarkSpec"]["parameters"]["dataFile"]) }) @@ -192,8 +177,7 @@ def parse_java_result(filename): # Benchmark/.././datasets/google_message2/dataset.google_message2.pb/Merge-12 300 4108632 ns/op # PASS # ok _/usr/local/google/home/yilunchong/mygit/protobuf/benchmarks 124.173s -def parse_go_result(filename): - global go_result +def __parse_go_result(filename): if filename == "": return if filename[0] != '/': @@ -206,85 +190,29 @@ def parse_go_result(filename): first_slash_index = result_list[0].find('/') last_slash_index = result_list[0].rfind('/') full_filename = result_list[0][first_slash_index+4:last_slash_index] # delete ../ prefix - total_bytes, _ = get_data_size(full_filename) + total_bytes, _ = __get_data_size(full_filename) behavior_with_suffix = result_list[0][last_slash_index+1:] last_dash = behavior_with_suffix.rfind("-") if last_dash == -1: behavior = behavior_with_suffix else: behavior = behavior_with_suffix[:last_dash] - go_result.append({ - "dataFilename": extract_file_name(full_filename), + __results.append({ + "dataFilename": __extract_file_name(full_filename), "throughput": total_bytes / float(result_list[2]) * 1e9 / 2 ** 20, "behavior": behavior, "language": "go" }) - -def get_metadata(): - build_number = os.getenv('BUILD_NUMBER') - build_url = os.getenv('BUILD_URL') - job_name = os.getenv('JOB_NAME') - git_commit = os.getenv('GIT_COMMIT') - # actual commit is the actual head of PR that is getting tested - git_actual_commit = os.getenv('ghprbActualCommit') - - utc_timestamp = str(calendar.timegm(time.gmtime())) - metadata = {'created': utc_timestamp} - - if build_number: - metadata['buildNumber'] = build_number - if build_url: - metadata['buildUrl'] = build_url - if job_name: - metadata['jobName'] = job_name - if git_commit: - metadata['gitCommit'] = git_commit - if git_actual_commit: - metadata['gitActualCommit'] = git_actual_commit - - return metadata - - -def upload_result(result_list, metadata): - for result in result_list: - new_result = copy.deepcopy(result) - new_result['metadata'] = metadata - bq = big_query_utils.create_big_query() - row = big_query_utils.make_row(str(uuid.uuid4()), new_result) - if not big_query_utils.insert_rows(bq, _PROJECT_ID, _DATASET, - _TABLE + "$" + _NOW, - [row]): - print 'Error when uploading result', new_result - - -if __name__ == "__main__": - parser = argparse.ArgumentParser() - parser.add_argument("-cpp", "--cpp_input_file", - help="The CPP benchmark result file's name", - default="") - parser.add_argument("-java", "--java_input_file", - help="The Java benchmark result file's name", - default="") - parser.add_argument("-python", "--python_input_file", - help="The Python benchmark result file's name", - default="") - parser.add_argument("-go", "--go_input_file", - help="The golang benchmark result file's name", - default="") - args = parser.parse_args() - - parse_cpp_result(args.cpp_input_file) - parse_python_result(args.python_input_file) - parse_java_result(args.java_input_file) - parse_go_result(args.go_input_file) - - metadata = get_metadata() - print "uploading cpp results..." - upload_result(cpp_result, metadata) - print "uploading java results..." - upload_result(java_result, metadata) - print "uploading python results..." - upload_result(python_result, metadata) - print "uploading go results..." - upload_result(go_result, metadata) +def get_result_from_file(cpp_file="", java_file="", python_file="", go_file=""): + results = {} + if cpp_file != "": + __parse_cpp_result(cpp_file) + if java_file != "": + __parse_java_result(java_file) + if python_file != "": + __parse_python_result(python_file) + if go_file != "": + __parse_go_result(go_file) + + return __results
\ No newline at end of file diff --git a/benchmarks/util/result_uploader.py b/benchmarks/util/result_uploader.py new file mode 100755 index 00000000..a667da02 --- /dev/null +++ b/benchmarks/util/result_uploader.py @@ -0,0 +1,94 @@ +from __future__ import print_function +from __future__ import absolute_import +import argparse +import os +import re +import copy +import uuid +import calendar +import time +import datetime + +from util import big_query_utils +from util import result_parser + +_PROJECT_ID = 'grpc-testing' +_DATASET = 'protobuf_benchmark_result' +_TABLE = 'opensource_result_v2' +_NOW = "%d%02d%02d" % (datetime.datetime.now().year, + datetime.datetime.now().month, + datetime.datetime.now().day) + +_INITIAL_TIME = calendar.timegm(time.gmtime()) + +def get_metadata(): + build_number = os.getenv('BUILD_NUMBER') + build_url = os.getenv('BUILD_URL') + job_name = os.getenv('JOB_NAME') + git_commit = os.getenv('GIT_COMMIT') + # actual commit is the actual head of PR that is getting tested + git_actual_commit = os.getenv('ghprbActualCommit') + + utc_timestamp = str(calendar.timegm(time.gmtime())) + metadata = {'created': utc_timestamp} + + if build_number: + metadata['buildNumber'] = build_number + if build_url: + metadata['buildUrl'] = build_url + if job_name: + metadata['jobName'] = job_name + if git_commit: + metadata['gitCommit'] = git_commit + if git_actual_commit: + metadata['gitActualCommit'] = git_actual_commit + + return metadata + + +def upload_result(result_list, metadata): + for result in result_list: + new_result = {} + new_result["metric"] = "throughput" + new_result["value"] = result["throughput"] + new_result["unit"] = "MB/s" + new_result["test"] = "protobuf_benchmark" + new_result["product_name"] = "protobuf" + labels_string = "" + for key in result: + labels_string += ",|%s:%s|" % (key, result[key]) + new_result["labels"] = labels_string[1:] + new_result["timestamp"] = _INITIAL_TIME + + bq = big_query_utils.create_big_query() + row = big_query_utils.make_row(str(uuid.uuid4()), new_result) + if not big_query_utils.insert_rows(bq, _PROJECT_ID, _DATASET, + _TABLE + "$" + _NOW, + [row]): + print('Error when uploading result', new_result) + + +if __name__ == "__main__": + parser = argparse.ArgumentParser() + parser.add_argument("-cpp", "--cpp_input_file", + help="The CPP benchmark result file's name", + default="") + parser.add_argument("-java", "--java_input_file", + help="The Java benchmark result file's name", + default="") + parser.add_argument("-python", "--python_input_file", + help="The Python benchmark result file's name", + default="") + parser.add_argument("-go", "--go_input_file", + help="The golang benchmark result file's name", + default="") + args = parser.parse_args() + + metadata = get_metadata() + print("uploading results...") + upload_result(result_parser.get_result_from_file( + cpp_file=args.cpp_input_file, + java_file=args.java_input_file, + python_file=args.python_input_file, + go_file=args.go_input_file + ), metadata)
\ No newline at end of file diff --git a/benchmarks/util/schema_proto2_to_proto3_util.h b/benchmarks/util/schema_proto2_to_proto3_util.h index 089012dd..0079f6f1 100644 --- a/benchmarks/util/schema_proto2_to_proto3_util.h +++ b/benchmarks/util/schema_proto2_to_proto3_util.h @@ -74,10 +74,10 @@ class SchemaGroupStripper { }; -class SchemaAddZeroEnumValue { +class EnumScrubber { public: - SchemaAddZeroEnumValue() + EnumScrubber() : total_added_(0) { } @@ -130,6 +130,63 @@ class SchemaAddZeroEnumValue { int total_added_; }; +class ExtensionStripper { + public: + static void StripFile(FileDescriptorProto *file) { + for (int i = 0; i < file->mutable_message_type()->size(); i++) { + StripMessage(file->mutable_message_type(i)); + } + file->mutable_extension()->Clear(); + } + private: + static void StripMessage(DescriptorProto *message_type) { + message_type->mutable_extension()->Clear(); + message_type->clear_extension_range(); + for (int i = 0; i < message_type->mutable_nested_type()->size(); i++) { + StripMessage(message_type->mutable_nested_type(i)); + } + } +}; + + +class FieldScrubber { + public: + static void ScrubFile(FileDescriptorProto *file) { + for (int i = 0; i < file->mutable_message_type()->size(); i++) { + ScrubMessage(file->mutable_message_type(i)); + } + for (int i = 0; i < file->mutable_extension()->size(); i++) { + file->mutable_extension(i)->clear_default_value(); + if (ShouldClearLabel(file->mutable_extension(i))) { + file->mutable_extension(i)->clear_label(); + } + } + } + private: + static bool ShouldClearLabel(const FieldDescriptorProto *field) { + return field->label() == FieldDescriptorProto::LABEL_REQUIRED; + } + + static void ScrubMessage(DescriptorProto *message_type) { + message_type->mutable_extension()->Clear(); + for (int i = 0; i < message_type->mutable_extension()->size(); i++) { + message_type->mutable_extension(i)->clear_default_value(); + if (ShouldClearLabel(message_type->mutable_extension(i))) { + message_type->mutable_extension(i)->clear_label(); + } + } + for (int i = 0; i < message_type->mutable_field()->size(); i++) { + message_type->mutable_field(i)->clear_default_value(); + if (ShouldClearLabel(message_type->mutable_field(i))) { + message_type->mutable_field(i)->clear_label(); + } + } + for (int i = 0; i < message_type->mutable_nested_type()->size(); i++) { + ScrubMessage(message_type->mutable_nested_type(i)); + } + } +}; + } // namespace util } // namespace protobuf } // namespace google diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt index 02174e96..ece39f7f 100644 --- a/cmake/CMakeLists.txt +++ b/cmake/CMakeLists.txt @@ -7,7 +7,11 @@ endif() # CMake policies cmake_policy(SET CMP0022 NEW) - +# On MacOS use @rpath/ for target's install name prefix path +if (POLICY CMP0042) + cmake_policy(SET CMP0042 NEW) +endif () +# Clear VERSION variables when no VERSION is given to project() if(POLICY CMP0048) cmake_policy(SET CMP0048 NEW) endif() @@ -166,12 +170,23 @@ if (MSVC) add_definitions(/bigobj) string(REPLACE "/" "\\" PROTOBUF_SOURCE_WIN32_PATH ${protobuf_SOURCE_DIR}) string(REPLACE "/" "\\" PROTOBUF_BINARY_WIN32_PATH ${protobuf_BINARY_DIR}) + string(REPLACE "." "," protobuf_RC_FILEVERSION "${protobuf_VERSION}") configure_file(extract_includes.bat.in extract_includes.bat) # Suppress linker warnings about files with no symbols defined. set(CMAKE_STATIC_LINKER_FLAGS /ignore:4221) + + # Configure Resource Compiler + enable_language(RC) + # use English language (0x409) in resource compiler + set(rc_flags "/l0x409") + # fix rc.exe invocations because of usage of add_definitions() + set(CMAKE_RC_COMPILE_OBJECT "<CMAKE_RC_COMPILER> ${rc_flags} <DEFINES> /fo<OBJECT> <SOURCE>") + + configure_file(version.rc.in ${CMAKE_CURRENT_BINARY_DIR}/version.rc @ONLY) endif (MSVC) + get_filename_component(protobuf_source_dir ${protobuf_SOURCE_DIR} PATH) include_directories( diff --git a/cmake/install.cmake b/cmake/install.cmake index 82036cb6..9b2ae93c 100644 --- a/cmake/install.cmake +++ b/cmake/install.cmake @@ -15,6 +15,13 @@ foreach(_library ${_protobuf_libraries}) PROPERTY INTERFACE_INCLUDE_DIRECTORIES $<BUILD_INTERFACE:${protobuf_source_dir}/src> $<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>) + if (UNIX AND NOT APPLE) + set_property(TARGET ${_library} + PROPERTY INSTALL_RPATH "$ORIGIN") + elseif (APPLE) + set_property(TARGET ${_library} + PROPERTY INSTALL_RPATH "@loader_path") + endif() install(TARGETS ${_library} EXPORT protobuf-targets RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT ${_library} LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT ${_library} @@ -24,6 +31,13 @@ endforeach() if (protobuf_BUILD_PROTOC_BINARIES) install(TARGETS protoc EXPORT protobuf-targets RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT protoc) + if (UNIX AND NOT APPLE) + set_property(TARGET protoc + PROPERTY INSTALL_RPATH "$ORIGIN/../lib") + elseif (APPLE) + set_property(TARGET protoc + PROPERTY INSTALL_RPATH "@loader_path/../lib") + endif() endif (protobuf_BUILD_PROTOC_BINARIES) install(FILES ${CMAKE_CURRENT_BINARY_DIR}/protobuf.pc ${CMAKE_CURRENT_BINARY_DIR}/protobuf-lite.pc DESTINATION "${CMAKE_INSTALL_LIBDIR}/pkgconfig") diff --git a/cmake/libprotobuf-lite.cmake b/cmake/libprotobuf-lite.cmake index 911fce5e..1d0b0b84 100644 --- a/cmake/libprotobuf-lite.cmake +++ b/cmake/libprotobuf-lite.cmake @@ -48,8 +48,14 @@ set(libprotobuf_lite_includes ${protobuf_source_dir}/src/google/protobuf/wire_format_lite.h ) +if (MSVC) +set(libprotobuf_lite_rc_files + ${CMAKE_CURRENT_BINARY_DIR}/version.rc +) +endif() + add_library(libprotobuf-lite ${protobuf_SHARED_OR_STATIC} - ${libprotobuf_lite_files} ${libprotobuf_lite_includes}) + ${libprotobuf_lite_files} ${libprotobuf_lite_includes} ${libprotobuf_lite_rc_files}) target_link_libraries(libprotobuf-lite ${CMAKE_THREAD_LIBS_INIT}) target_include_directories(libprotobuf-lite PUBLIC ${protobuf_source_dir}/src) if(MSVC AND protobuf_BUILD_SHARED_LIBS) diff --git a/cmake/libprotobuf.cmake b/cmake/libprotobuf.cmake index 65d05c19..bd570be7 100644 --- a/cmake/libprotobuf.cmake +++ b/cmake/libprotobuf.cmake @@ -112,8 +112,14 @@ set(libprotobuf_includes ${protobuf_source_dir}/src/google/protobuf/wrappers.pb.h ) +if (MSVC) +set(libprotobuf_rc_files + ${CMAKE_CURRENT_BINARY_DIR}/version.rc +) +endif() + add_library(libprotobuf ${protobuf_SHARED_OR_STATIC} - ${libprotobuf_lite_files} ${libprotobuf_files} ${libprotobuf_includes}) + ${libprotobuf_lite_files} ${libprotobuf_files} ${libprotobuf_includes} ${libprotobuf_rc_files}) target_link_libraries(libprotobuf ${CMAKE_THREAD_LIBS_INIT}) if(protobuf_WITH_ZLIB) target_link_libraries(libprotobuf ${ZLIB_LIBRARIES}) diff --git a/cmake/libprotoc.cmake b/cmake/libprotoc.cmake index 58568bb2..a9f5c36d 100644 --- a/cmake/libprotoc.cmake +++ b/cmake/libprotoc.cmake @@ -44,8 +44,6 @@ set(libprotoc_files ${protobuf_source_dir}/src/google/protobuf/compiler/java/java_generator.cc ${protobuf_source_dir}/src/google/protobuf/compiler/java/java_generator_factory.cc ${protobuf_source_dir}/src/google/protobuf/compiler/java/java_helpers.cc - ${protobuf_source_dir}/src/google/protobuf/compiler/java/java_lazy_message_field.cc - ${protobuf_source_dir}/src/google/protobuf/compiler/java/java_lazy_message_field_lite.cc ${protobuf_source_dir}/src/google/protobuf/compiler/java/java_map_field.cc ${protobuf_source_dir}/src/google/protobuf/compiler/java/java_map_field_lite.cc ${protobuf_source_dir}/src/google/protobuf/compiler/java/java_message.cc @@ -128,8 +126,6 @@ set(libprotoc_headers ${protobuf_source_dir}/src/google/protobuf/compiler/java/java_file.h ${protobuf_source_dir}/src/google/protobuf/compiler/java/java_generator_factory.h ${protobuf_source_dir}/src/google/protobuf/compiler/java/java_helpers.h - ${protobuf_source_dir}/src/google/protobuf/compiler/java/java_lazy_message_field.h - ${protobuf_source_dir}/src/google/protobuf/compiler/java/java_lazy_message_field_lite.h ${protobuf_source_dir}/src/google/protobuf/compiler/java/java_map_field.h ${protobuf_source_dir}/src/google/protobuf/compiler/java/java_map_field_lite.h ${protobuf_source_dir}/src/google/protobuf/compiler/java/java_message.h @@ -168,7 +164,7 @@ set(libprotoc_rc_files endif() add_library(libprotoc ${protobuf_SHARED_OR_STATIC} - ${libprotoc_files} ${libprotoc_headers}) + ${libprotoc_files} ${libprotoc_headers} ${libprotoc_rc_files}) target_link_libraries(libprotoc libprotobuf) if(MSVC AND protobuf_BUILD_SHARED_LIBS) target_compile_definitions(libprotoc diff --git a/cmake/protobuf-config.cmake.in b/cmake/protobuf-config.cmake.in index acedcc7a..69d63e3e 100644 --- a/cmake/protobuf-config.cmake.in +++ b/cmake/protobuf-config.cmake.in @@ -11,7 +11,7 @@ function(protobuf_generate) include(CMakeParseArguments) set(_options APPEND_PATH) - set(_singleargs LANGUAGE OUT_VAR EXPORT_MACRO) + set(_singleargs LANGUAGE OUT_VAR EXPORT_MACRO PROTOC_OUT_DIR) if(COMMAND target_sources) list(APPEND _singleargs TARGET) endif() @@ -34,15 +34,19 @@ function(protobuf_generate) endif() string(TOLOWER ${protobuf_generate_LANGUAGE} protobuf_generate_LANGUAGE) + if(NOT protobuf_generate_PROTOC_OUT_DIR) + set(protobuf_generate_PROTOC_OUT_DIR ${CMAKE_CURRENT_BINARY_DIR}) + endif() + if(protobuf_generate_EXPORT_MACRO AND protobuf_generate_LANGUAGE STREQUAL cpp) set(_dll_export_decl "dllexport_decl=${protobuf_generate_EXPORT_MACRO}:") endif() - if(NOT protobuf_GENERATE_EXTENSIONS) + if(NOT protobuf_generate_GENERATE_EXTENSIONS) if(protobuf_generate_LANGUAGE STREQUAL cpp) - set(protobuf_GENERATE_EXTENSIONS .pb.h .pb.cc) + set(protobuf_generate_GENERATE_EXTENSIONS .pb.h .pb.cc) elseif(protobuf_generate_LANGUAGE STREQUAL python) - set(protobuf_GENERATE_EXTENSIONS _pb2.py) + set(protobuf_generate_GENERATE_EXTENSIONS _pb2.py) else() message(SEND_ERROR "Error: protobuf_generate given unknown Language ${LANGUAGE}, please provide a value for GENERATE_EXTENSIONS") return() @@ -88,19 +92,21 @@ function(protobuf_generate) set(_generated_srcs_all) foreach(_proto ${protobuf_generate_PROTOS}) get_filename_component(_abs_file ${_proto} ABSOLUTE) + get_filename_component(_abs_dir ${_abs_file} DIRECTORY) get_filename_component(_basename ${_proto} NAME_WE) + file(RELATIVE_PATH _rel_dir ${CMAKE_CURRENT_SOURCE_DIR} ${_abs_dir}) set(_generated_srcs) - foreach(_ext ${protobuf_GENERATE_EXTENSIONS}) - list(APPEND _generated_srcs "${CMAKE_CURRENT_BINARY_DIR}/${_basename}${_ext}") + foreach(_ext ${protobuf_generate_GENERATE_EXTENSIONS}) + list(APPEND _generated_srcs "${protobuf_generate_PROTOC_OUT_DIR}/${_rel_dir}/${_basename}${_ext}") endforeach() list(APPEND _generated_srcs_all ${_generated_srcs}) add_custom_command( OUTPUT ${_generated_srcs} COMMAND protobuf::protoc - ARGS --${protobuf_generate_LANGUAGE}_out ${_dll_export_decl}${CMAKE_CURRENT_BINARY_DIR} ${_protobuf_include_path} ${_abs_file} - DEPENDS ${ABS_FIL} protobuf::protoc + ARGS --${protobuf_generate_LANGUAGE}_out ${_dll_export_decl}${protobuf_generate_PROTOC_OUT_DIR}/${_rel_dir} ${_protobuf_include_path} ${_abs_file} + DEPENDS ${_abs_file} protobuf::protoc COMMENT "Running ${protobuf_generate_LANGUAGE} protocol buffer compiler on ${_proto}" VERBATIM ) endforeach() diff --git a/cmake/protoc.cmake b/cmake/protoc.cmake index 5777b16e..bb160f47 100644 --- a/cmake/protoc.cmake +++ b/cmake/protoc.cmake @@ -2,6 +2,15 @@ set(protoc_files ${protobuf_source_dir}/src/google/protobuf/compiler/main.cc ) -add_executable(protoc ${protoc_files}) +if (MSVC) +set(protoc_rc_files + ${CMAKE_CURRENT_BINARY_DIR}/version.rc +) +endif() + +add_executable(protoc ${protoc_files} ${protoc_rc_files}) target_link_libraries(protoc libprotobuf libprotoc) add_executable(protobuf::protoc ALIAS protoc) + +set_target_properties(protoc PROPERTIES + VERSION ${protobuf_VERSION}) diff --git a/cmake/tests.cmake b/cmake/tests.cmake index ec790e33..603d7e95 100644 --- a/cmake/tests.cmake +++ b/cmake/tests.cmake @@ -204,6 +204,17 @@ if(protobuf_ABSOLUTE_TEST_PLUGIN_PATH) add_compile_options(-DGOOGLE_PROTOBUF_TEST_PLUGIN_PATH="$<TARGET_FILE:test_plugin>") endif() +if(MINGW) + set_source_files_properties(${tests_files} PROPERTIES COMPILE_FLAGS "-Wno-narrowing") + + # required for tests on MinGW Win64 + if (CMAKE_SIZEOF_VOID_P EQUAL 8) + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,--stack,16777216") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wa,-mbig-obj") + endif() + +endif() + add_executable(tests ${tests_files} ${common_test_files} ${tests_proto_files} ${lite_test_proto_files}) target_link_libraries(tests libprotoc libprotobuf gmock_main) diff --git a/cmake/version.rc.in b/cmake/version.rc.in new file mode 100644 index 00000000..cbce1e53 --- /dev/null +++ b/cmake/version.rc.in @@ -0,0 +1,45 @@ +#define VS_FF_DEBUG 0x1L +#define VS_VERSION_INFO 0x1L +#define VS_FFI_FILEFLAGSMASK 0x17L +#define VER_PRIVATEBUILD 0x0L +#define VER_PRERELEASE 0x0L +#define VOS__WINDOWS32 0x4L +#define VFT_DLL 0x2L +#define VFT2_UNKNOWN 0x0L + +#ifndef DEBUG +#define VER_DEBUG 0 +#else +#define VER_DEBUG VS_FF_DEBUG +#endif + + +VS_VERSION_INFO VERSIONINFO + FILEVERSION @protobuf_RC_FILEVERSION@,0 + PRODUCTVERSION @protobuf_RC_FILEVERSION@,0 + FILEFLAGSMASK VS_FFI_FILEFLAGSMASK + FILEFLAGS VER_DEBUG + FILEOS VOS__WINDOWS32 + FILETYPE VFT_DLL +BEGIN + BLOCK "VarFileInfo" + BEGIN + // English language (0x409) and the Windows Unicode codepage (1200) + VALUE "Translation", 0x409, 1200 + END + BLOCK "StringFileInfo" + BEGIN + BLOCK "040904b0" + BEGIN + VALUE "FileDescription", "Compiled with @CMAKE_CXX_COMPILER_ID@ @CMAKE_CXX_COMPILER_VERSION@\0" + VALUE "ProductVersion", "@protobuf_VERSION@\0" + VALUE "FileVersion", "@protobuf_VERSION@\0" + VALUE "InternalName", "protobuf\0" + VALUE "ProductName", "Protocol Buffers - Google's Data Interchange Format\0" + VALUE "CompanyName", "Google Inc.\0" + VALUE "LegalCopyright", "Copyright 2008 Google Inc. All rights reserved.\0" + VALUE "Licence", "BSD\0" + VALUE "Info", "https://developers.google.com/protocol-buffers/\0" + END + END +END diff --git a/configure.ac b/configure.ac index 7d668276..8e1c308c 100644 --- a/configure.ac +++ b/configure.ac @@ -190,7 +190,7 @@ AM_CONDITIONAL([HAVE_PTHREAD], [test "x$ax_pthread_ok" = "xyes"]) AC_CXX_STL_HASH case "$target_os" in - mingw* | cygwin* | win* | aix*) + mingw* | cygwin* | win* | aix* | *android* ) ;; *) # Need to link against rt on Solaris diff --git a/conformance/ConformanceJava.java b/conformance/ConformanceJava.java index 596d113a..dcdc27e3 100644 --- a/conformance/ConformanceJava.java +++ b/conformance/ConformanceJava.java @@ -235,8 +235,12 @@ class ConformanceJava { try { TestMessagesProto3.TestAllTypesProto3.Builder builder = TestMessagesProto3.TestAllTypesProto3.newBuilder(); - JsonFormat.parser().usingTypeRegistry(typeRegistry) - .merge(request.getJsonPayload(), builder); + JsonFormat.Parser parser = JsonFormat.parser().usingTypeRegistry(typeRegistry); + if (request.getTestCategory() + == Conformance.TestCategory.JSON_IGNORE_UNKNOWN_PARSING_TEST) { + parser = parser.ignoringUnknownFields(); + } + parser.merge(request.getJsonPayload(), builder); testMessage = builder.build(); } catch (InvalidProtocolBufferException e) { return Conformance.ConformanceResponse.newBuilder().setParseError(e.getMessage()).build(); diff --git a/conformance/README.md b/conformance/README.md index 971fe8f6..a5419bf0 100644 --- a/conformance/README.md +++ b/conformance/README.md @@ -1,8 +1,6 @@ Protocol Buffers - Google's data interchange format =================================================== -[![Build Status](https://travis-ci.org/google/protobuf.svg?branch=master)](https://travis-ci.org/google/protobuf) - Copyright 2008 Google Inc. This directory contains conformance tests for testing completeness and diff --git a/conformance/conformance.proto b/conformance/conformance.proto index 525140e9..d838e578 100644 --- a/conformance/conformance.proto +++ b/conformance/conformance.proto @@ -57,6 +57,17 @@ enum WireFormat { JSON = 2; } +enum TestCategory { + BINARY_TEST = 0; // Test binary wire format. + JSON_TEST = 1; // Test json wire format. + // Similar to JSON_TEST. However, during parsing json, testee should ignore + // unknown fields. This feature is optional. Each implementation can descide + // whether to support it. See + // https://developers.google.com/protocol-buffers/docs/proto3#json_options + // for more detail. + JSON_IGNORE_UNKNOWN_PARSING_TEST = 2; +} + // Represents a single test case's input. The testee should: // // 1. parse this proto (which should always succeed) @@ -82,6 +93,11 @@ message ConformanceRequest { // protobuf_test_messages.proto3.TestAllTypesProto3 or // protobuf_test_messages.proto2.TestAllTypesProto2. string message_type = 4; + + // Each test is given a specific test category. Some category may need spedific + // support in testee programs. Refer to the defintion of TestCategory for + // more information. + TestCategory test_category = 5; } // Represents a single test case's output. diff --git a/conformance/conformance_cpp.cc b/conformance/conformance_cpp.cc index 97ae1a7a..ac2f6dea 100644 --- a/conformance/conformance_cpp.cc +++ b/conformance/conformance_cpp.cc @@ -46,6 +46,7 @@ using google::protobuf::DescriptorPool; using google::protobuf::Message; using google::protobuf::MessageFactory; using google::protobuf::util::BinaryToJsonString; +using google::protobuf::util::JsonParseOptions; using google::protobuf::util::JsonToBinaryString; using google::protobuf::util::NewTypeResolverForDescriptorPool; using google::protobuf::util::Status; @@ -112,8 +113,13 @@ void DoTest(const ConformanceRequest& request, ConformanceResponse* response) { case ConformanceRequest::kJsonPayload: { string proto_binary; + JsonParseOptions options; + options.ignore_unknown_fields = + (request.test_category() == + conformance::JSON_IGNORE_UNKNOWN_PARSING_TEST); Status status = JsonToBinaryString(type_resolver, *type_url, - request.json_payload(), &proto_binary); + request.json_payload(), &proto_binary, + options); if (!status.ok()) { response->set_parse_error(string("Parse error: ") + status.error_message().as_string()); diff --git a/conformance/conformance_php.php b/conformance/conformance_php.php index 85fe3d03..799cc3e3 100755 --- a/conformance/conformance_php.php +++ b/conformance/conformance_php.php @@ -3,6 +3,7 @@ require_once("Conformance/WireFormat.php"); require_once("Conformance/ConformanceResponse.php"); require_once("Conformance/ConformanceRequest.php"); +require_once("Conformance/TestCategory.php"); require_once("Protobuf_test_messages/Proto3/ForeignMessage.php"); require_once("Protobuf_test_messages/Proto3/ForeignEnum.php"); require_once("Protobuf_test_messages/Proto3/TestAllTypesProto3.php"); @@ -12,6 +13,7 @@ require_once("Protobuf_test_messages/Proto3/TestAllTypesProto3/NestedEnum.php"); require_once("GPBMetadata/Conformance.php"); require_once("GPBMetadata/Google/Protobuf/TestMessagesProto3.php"); +use \Conformance\TestCategory; use \Conformance\WireFormat; if (!ini_get("date.timezone")) { @@ -39,8 +41,12 @@ function doTest($request) trigger_error("Protobuf request doesn't have specific payload type", E_USER_ERROR); } } elseif ($request->getPayload() == "json_payload") { + $ignore_json_unknown = + ($request->getTestCategory() == + TestCategory::JSON_IGNORE_UNKNOWN_PARSING_TEST); try { - $test_message->mergeFromJsonString($request->getJsonPayload()); + $test_message->mergeFromJsonString($request->getJsonPayload(), + $ignore_json_unknown); } catch (Exception $e) { $response->setParseError($e->getMessage()); return $response; diff --git a/conformance/conformance_python.py b/conformance/conformance_python.py index c5ba2467..876642bc 100755 --- a/conformance/conformance_python.py +++ b/conformance/conformance_python.py @@ -78,7 +78,11 @@ def do_test(request): elif request.WhichOneof('payload') == 'json_payload': try: - json_format.Parse(request.json_payload, test_message) + ignore_unknown_fields = \ + request.test_category == \ + conformance_pb2.JSON_IGNORE_UNKNOWN_PARSING_TEST + json_format.Parse(request.json_payload, test_message, + ignore_unknown_fields) except Exception as e: response.parse_error = str(e) return response diff --git a/conformance/conformance_test.cc b/conformance/conformance_test.cc index 22bbbfb3..74342b68 100644 --- a/conformance/conformance_test.cc +++ b/conformance/conformance_test.cc @@ -191,6 +191,81 @@ string UpperCase(string str) { namespace google { namespace protobuf { +ConformanceTestSuite::ConformanceRequestSetting::ConformanceRequestSetting( + ConformanceLevel level, conformance::WireFormat input_format, + conformance::WireFormat output_format, + conformance::TestCategory test_category, + bool is_proto3, + const string& test_name, const string& input) + : level_(level), is_proto3_(is_proto3) { + auto newTestMessage = [&is_proto3]() { + Message* newMessage; + if (is_proto3) { + newMessage = new TestAllTypesProto3; + } else { + newMessage = new TestAllTypesProto2; + } + return newMessage; + }; + + string input_format_string; + string output_format_string; + string rname = is_proto3 ? ".Proto3" : ".Proto2"; + + switch (input_format) { + case conformance::PROTOBUF: { + request_.set_protobuf_payload(input); + input_format_string = ".ProtobufInput."; + break; + } + + case conformance::JSON: { + request_.set_json_payload(input); + input_format_string = ".JsonInput."; + break; + } + + default: + GOOGLE_LOG(FATAL) << "Unspecified input format"; + } + + switch (output_format) { + case conformance::PROTOBUF: { + output_format_string = ".ProtobufOutput"; + break; + } + + case conformance::JSON: { + output_format_string = ".JsonOutput"; + break; + } + + default: + GOOGLE_LOG(FATAL) << "Unspecified output format"; + } + + request_.set_test_category(test_category); + + test_name_ = ConformanceLevelToString(level) + rname + + input_format_string + test_name + + output_format_string; + + if (is_proto3) { + request_.set_message_type("protobuf_test_messages.proto3.TestAllTypesProto3"); + } else { + request_.set_message_type("protobuf_test_messages.proto2.TestAllTypesProto2"); + } + request_.set_requested_output_format(output_format); +} + +Message* ConformanceTestSuite::ConformanceRequestSetting::GetTestMessage() const { + if (is_proto3_) { + return new TestAllTypesProto3(); + } else { + return new TestAllTypesProto2(); + } +} + void ConformanceTestSuite::ReportSuccess(const string& test_name) { if (expected_to_fail_.erase(test_name) != 0) { StringAppendF(&output_, @@ -273,75 +348,36 @@ void ConformanceTestSuite::RunTest(const string& test_name, } void ConformanceTestSuite::RunValidInputTest( - const string& test_name, ConformanceLevel level, const string& input, - WireFormat input_format, const string& equivalent_text_format, - WireFormat requested_output, bool isProto3) { - auto newTestMessage = [&isProto3]() { - Message* newMessage; - if (isProto3) { - newMessage = new TestAllTypesProto3; - } else { - newMessage = new TestAllTypesProto2; - } - return newMessage; - }; - Message* reference_message = newTestMessage(); + const ConformanceRequestSetting& setting, + const string& equivalent_text_format) { + Message* reference_message = setting.GetTestMessage(); GOOGLE_CHECK( TextFormat::ParseFromString(equivalent_text_format, reference_message)) - << "Failed to parse data for test case: " << test_name + << "Failed to parse data for test case: " << setting.GetTestName() << ", data: " << equivalent_text_format; const string equivalent_wire_format = reference_message->SerializeAsString(); - RunValidBinaryInputTest(test_name, level, input, input_format, - equivalent_wire_format, requested_output, isProto3); + RunValidBinaryInputTest(setting, equivalent_wire_format); } void ConformanceTestSuite::RunValidBinaryInputTest( - const string& test_name, ConformanceLevel level, const string& input, - WireFormat input_format, const string& equivalent_wire_format, - WireFormat requested_output, bool isProto3) { - auto newTestMessage = [&isProto3]() { - Message* newMessage; - if (isProto3) { - newMessage = new TestAllTypesProto3; - } else { - newMessage = new TestAllTypesProto2; - } - return newMessage; - }; - Message* reference_message = newTestMessage(); + const ConformanceRequestSetting& setting, + const string& equivalent_wire_format) { + const string& test_name = setting.GetTestName(); + ConformanceLevel level = setting.GetLevel(); + + Message* reference_message = setting.GetTestMessage(); GOOGLE_CHECK( reference_message->ParseFromString(equivalent_wire_format)) << "Failed to parse wire data for test case: " << test_name; - ConformanceRequest request; + const ConformanceRequest& request = setting.GetRequest(); ConformanceResponse response; - switch (input_format) { - case conformance::PROTOBUF: { - request.set_protobuf_payload(input); - if (isProto3) { - request.set_message_type("protobuf_test_messages.proto3.TestAllTypesProto3"); - } else { - request.set_message_type("protobuf_test_messages.proto2.TestAllTypesProto2"); - } - break; - } - - case conformance::JSON: { - request.set_message_type("protobuf_test_messages.proto3.TestAllTypesProto3"); - request.set_json_payload(input); - break; - } - - default: - GOOGLE_LOG(FATAL) << "Unspecified input format"; - } - - request.set_requested_output_format(requested_output); - RunTest(test_name, request, &response); - Message *test_message = newTestMessage(); + Message* test_message = setting.GetTestMessage(); + + WireFormat requested_output = request.requested_output_format(); switch (response.result_case()) { case ConformanceResponse::RESULT_NOT_SET: @@ -432,6 +468,7 @@ void ConformanceTestSuite::ExpectParseFailureForProtoWithProtoVersion ( ConformanceRequest request; ConformanceResponse response; request.set_protobuf_payload(proto); + request.set_test_category(conformance::BINARY_TEST); if (isProto3) { request.set_message_type("protobuf_test_messages.proto3.TestAllTypesProto3"); } else { @@ -476,56 +513,66 @@ void ConformanceTestSuite::ExpectHardParseFailureForProto( void ConformanceTestSuite::RunValidJsonTest( const string& test_name, ConformanceLevel level, const string& input_json, const string& equivalent_text_format) { - RunValidInputTest( - ConformanceLevelToString(level) + ".Proto3.JsonInput." + test_name + - ".ProtobufOutput", level, input_json, conformance::JSON, - equivalent_text_format, conformance::PROTOBUF, true); - RunValidInputTest( - ConformanceLevelToString(level) + ".Proto3.JsonInput." + test_name + - ".JsonOutput", level, input_json, conformance::JSON, - equivalent_text_format, conformance::JSON, true); + ConformanceRequestSetting setting1( + level, conformance::JSON, conformance::PROTOBUF, + conformance::JSON_TEST, + true, test_name, input_json); + RunValidInputTest(setting1, equivalent_text_format); + + ConformanceRequestSetting setting2( + level, conformance::JSON, conformance::JSON, + conformance::JSON_TEST, + true, test_name, input_json); + RunValidInputTest(setting2, equivalent_text_format); } void ConformanceTestSuite::RunValidJsonTestWithProtobufInput( const string& test_name, ConformanceLevel level, const TestAllTypesProto3& input, const string& equivalent_text_format) { - RunValidInputTest( - ConformanceLevelToString(level) + ".Proto3" + ".ProtobufInput." + test_name + - ".JsonOutput", level, input.SerializeAsString(), conformance::PROTOBUF, - equivalent_text_format, conformance::JSON, true); + ConformanceRequestSetting setting( + level, conformance::PROTOBUF, conformance::JSON, + conformance::JSON_TEST, + true, test_name, input.SerializeAsString()); + RunValidInputTest(setting, equivalent_text_format); +} + +void ConformanceTestSuite::RunValidJsonIgnoreUnknownTest( + const string& test_name, ConformanceLevel level, const string& input_json, + const string& equivalent_text_format) { + ConformanceRequestSetting setting( + level, conformance::JSON, conformance::PROTOBUF, + conformance::JSON_IGNORE_UNKNOWN_PARSING_TEST, + true, test_name, input_json); + RunValidInputTest(setting, equivalent_text_format); } void ConformanceTestSuite::RunValidProtobufTest( const string& test_name, ConformanceLevel level, const string& input_protobuf, const string& equivalent_text_format, bool isProto3) { - string rname = ".Proto3"; - if (!isProto3) { - rname = ".Proto2"; - } - RunValidInputTest( - ConformanceLevelToString(level) + rname + ".ProtobufInput." + test_name + - ".ProtobufOutput", level, input_protobuf, conformance::PROTOBUF, - equivalent_text_format, conformance::PROTOBUF, isProto3); + ConformanceRequestSetting setting1( + level, conformance::PROTOBUF, conformance::PROTOBUF, + conformance::BINARY_TEST, + isProto3, test_name, input_protobuf); + RunValidInputTest(setting1, equivalent_text_format); + if (isProto3) { - RunValidInputTest( - ConformanceLevelToString(level) + rname + ".ProtobufInput." + test_name + - ".JsonOutput", level, input_protobuf, conformance::PROTOBUF, - equivalent_text_format, conformance::JSON, isProto3); + ConformanceRequestSetting setting2( + level, conformance::PROTOBUF, conformance::JSON, + conformance::BINARY_TEST, + true, test_name, input_protobuf); + RunValidInputTest(setting2, equivalent_text_format); } } void ConformanceTestSuite::RunValidBinaryProtobufTest( const string& test_name, ConformanceLevel level, const string& input_protobuf, bool isProto3) { - string rname = ".Proto3"; - if (!isProto3) { - rname = ".Proto2"; - } - RunValidBinaryInputTest( - ConformanceLevelToString(level) + rname + ".ProtobufInput." + test_name + - ".ProtobufOutput", level, input_protobuf, conformance::PROTOBUF, - input_protobuf, conformance::PROTOBUF, isProto3); + ConformanceRequestSetting setting( + level, conformance::PROTOBUF, conformance::PROTOBUF, + conformance::BINARY_TEST, + isProto3, test_name, input_protobuf); + RunValidBinaryInputTest(setting, input_protobuf); } void ConformanceTestSuite::RunValidProtobufTestWithMessage( @@ -2535,6 +2582,43 @@ bool ConformanceTestSuite::RunSuite(ConformanceTestRunner* runner, } )"); + RunValidJsonIgnoreUnknownTest( + "IgnoreUnknownJsonNumber", REQUIRED, + R"({ + "unknown": 1 + })", + ""); + RunValidJsonIgnoreUnknownTest( + "IgnoreUnknownJsonString", REQUIRED, + R"({ + "unknown": "a" + })", + ""); + RunValidJsonIgnoreUnknownTest( + "IgnoreUnknownJsonTrue", REQUIRED, + R"({ + "unknown": true + })", + ""); + RunValidJsonIgnoreUnknownTest( + "IgnoreUnknownJsonFalse", REQUIRED, + R"({ + "unknown": false + })", + ""); + RunValidJsonIgnoreUnknownTest( + "IgnoreUnknownJsonNull", REQUIRED, + R"({ + "unknown": null + })", + ""); + RunValidJsonIgnoreUnknownTest( + "IgnoreUnknownJsonObject", REQUIRED, + R"({ + "unknown": {"a": 1} + })", + ""); + bool ok = true; if (!CheckSetEmpty(expected_to_fail_, "nonexistent_tests.txt", "These tests were listed in the failure list, but they " diff --git a/conformance/conformance_test.h b/conformance/conformance_test.h index 2649f8b2..2044896f 100644 --- a/conformance/conformance_test.h +++ b/conformance/conformance_test.h @@ -44,6 +44,7 @@ #include <google/protobuf/util/type_resolver.h> #include <google/protobuf/wire_format_lite.h> +#include "conformance.pb.h" #include "third_party/jsoncpp/json.h" namespace conformance { @@ -146,7 +147,38 @@ class ConformanceTestSuite { REQUIRED = 0, RECOMMENDED = 1, }; - string ConformanceLevelToString(ConformanceLevel level); + + class ConformanceRequestSetting { + public: + ConformanceRequestSetting( + ConformanceLevel level, conformance::WireFormat input_format, + conformance::WireFormat output_format, + conformance::TestCategory test_category, + bool is_proto3, + const string& test_name, const string& input); + + Message* GetTestMessage() const; + + const string& GetTestName() const { + return test_name_; + } + + const conformance::ConformanceRequest& GetRequest() const { + return request_; + } + + const ConformanceLevel GetLevel() const { + return level_; + } + + private: + ConformanceLevel level_; + bool is_proto3_; + string test_name_; + conformance::ConformanceRequest request_; + }; + + static string ConformanceLevelToString(ConformanceLevel level); void ReportSuccess(const std::string& test_name); void ReportFailure(const string& test_name, @@ -160,24 +192,17 @@ class ConformanceTestSuite { void RunTest(const std::string& test_name, const conformance::ConformanceRequest& request, conformance::ConformanceResponse* response); - void RunValidInputTest(const string& test_name, - ConformanceLevel level, - const string& input, - conformance::WireFormat input_format, - const string& equivalent_text_format, - conformance::WireFormat requested_output, - bool isProto3); - void RunValidBinaryInputTest(const string& test_name, - ConformanceLevel level, - const string& input, - conformance::WireFormat input_format, - const string& equivalent_wire_format, - conformance::WireFormat requested_output, - bool isProto3); + void RunValidInputTest(const ConformanceRequestSetting& setting, + const string& equivalent_text_format); + void RunValidBinaryInputTest(const ConformanceRequestSetting& setting, + const string& equivalent_wire_format); void RunValidJsonTest(const string& test_name, ConformanceLevel level, const string& input_json, const string& equivalent_text_format); + void RunValidJsonIgnoreUnknownTest( + const string& test_name, ConformanceLevel level, const string& input_json, + const string& equivalent_text_format); void RunValidJsonTestWithProtobufInput( const string& test_name, ConformanceLevel level, diff --git a/conformance/failure_list_php_c.txt b/conformance/failure_list_php_c.txt index 088708e9..5f7c0c8d 100644 --- a/conformance/failure_list_php_c.txt +++ b/conformance/failure_list_php_c.txt @@ -1,8 +1,8 @@ Recommended.FieldMaskNumbersDontRoundTrip.JsonOutput Recommended.FieldMaskPathsDontRoundTrip.JsonOutput Recommended.FieldMaskTooManyUnderscore.JsonOutput -Recommended.Proto3.JsonInput.BoolFieldIntegerOne -Recommended.Proto3.JsonInput.BoolFieldIntegerZero +Recommended.Proto3.JsonInput.BytesFieldBase64Url.JsonOutput +Recommended.Proto3.JsonInput.BytesFieldBase64Url.ProtobufOutput Recommended.Proto3.JsonInput.DurationHas3FractionalDigits.Validator Recommended.Proto3.JsonInput.DurationHas6FractionalDigits.Validator Recommended.Proto3.JsonInput.DurationHas9FractionalDigits.Validator @@ -10,20 +10,19 @@ Recommended.Proto3.JsonInput.DurationHasZeroFractionalDigit.Validator Recommended.Proto3.JsonInput.Int64FieldBeString.Validator Recommended.Proto3.JsonInput.MapFieldValueIsNull Recommended.Proto3.JsonInput.OneofZeroBytes.JsonOutput -Recommended.Proto3.JsonInput.OneofZeroBytes.ProtobufOutput -Recommended.Proto3.JsonInput.OneofZeroString.JsonOutput -Recommended.Proto3.JsonInput.OneofZeroString.ProtobufOutput Recommended.Proto3.JsonInput.RepeatedFieldMessageElementIsNull Recommended.Proto3.JsonInput.RepeatedFieldPrimitiveElementIsNull Recommended.Proto3.JsonInput.StringEndsWithEscapeChar Recommended.Proto3.JsonInput.StringFieldSurrogateInWrongOrder Recommended.Proto3.JsonInput.StringFieldUnpairedHighSurrogate Recommended.Proto3.JsonInput.StringFieldUnpairedLowSurrogate +Recommended.Proto3.JsonInput.TimestampHas3FractionalDigits.Validator +Recommended.Proto3.JsonInput.TimestampHas6FractionalDigits.Validator +Recommended.Proto3.JsonInput.TimestampHas9FractionalDigits.Validator +Recommended.Proto3.JsonInput.TimestampHasZeroFractionalDigit.Validator +Recommended.Proto3.JsonInput.TimestampZeroNormalized.Validator Recommended.Proto3.JsonInput.Uint64FieldBeString.Validator Recommended.Proto3.ProtobufInput.OneofZeroBytes.JsonOutput -Recommended.Proto3.ProtobufInput.OneofZeroBytes.ProtobufOutput -Recommended.Proto3.ProtobufInput.OneofZeroString.JsonOutput -Recommended.Proto3.ProtobufInput.OneofZeroString.ProtobufOutput Required.DurationProtoInputTooLarge.JsonOutput Required.DurationProtoInputTooSmall.JsonOutput Required.Proto3.JsonInput.Any.JsonOutput @@ -47,63 +46,23 @@ Required.Proto3.JsonInput.AnyWithValueForInteger.ProtobufOutput Required.Proto3.JsonInput.AnyWithValueForJsonObject.JsonOutput Required.Proto3.JsonInput.AnyWithValueForJsonObject.ProtobufOutput Required.Proto3.JsonInput.BoolMapField.JsonOutput -Required.Proto3.JsonInput.DoubleFieldInfinity.JsonOutput -Required.Proto3.JsonInput.DoubleFieldInfinity.ProtobufOutput Required.Proto3.JsonInput.DoubleFieldMaxNegativeValue.JsonOutput Required.Proto3.JsonInput.DoubleFieldMaxNegativeValue.ProtobufOutput -Required.Proto3.JsonInput.DoubleFieldMaxPositiveValue.JsonOutput -Required.Proto3.JsonInput.DoubleFieldMaxPositiveValue.ProtobufOutput -Required.Proto3.JsonInput.DoubleFieldMinNegativeValue.JsonOutput -Required.Proto3.JsonInput.DoubleFieldMinNegativeValue.ProtobufOutput Required.Proto3.JsonInput.DoubleFieldMinPositiveValue.JsonOutput Required.Proto3.JsonInput.DoubleFieldMinPositiveValue.ProtobufOutput Required.Proto3.JsonInput.DoubleFieldNan.JsonOutput -Required.Proto3.JsonInput.DoubleFieldNan.ProtobufOutput -Required.Proto3.JsonInput.DoubleFieldNegativeInfinity.JsonOutput -Required.Proto3.JsonInput.DoubleFieldNegativeInfinity.ProtobufOutput -Required.Proto3.JsonInput.DoubleFieldQuotedValue.JsonOutput -Required.Proto3.JsonInput.DoubleFieldQuotedValue.ProtobufOutput Required.Proto3.JsonInput.DurationMaxValue.JsonOutput Required.Proto3.JsonInput.DurationMaxValue.ProtobufOutput Required.Proto3.JsonInput.DurationMinValue.JsonOutput Required.Proto3.JsonInput.DurationMinValue.ProtobufOutput Required.Proto3.JsonInput.DurationRepeatedValue.JsonOutput Required.Proto3.JsonInput.DurationRepeatedValue.ProtobufOutput -Required.Proto3.JsonInput.EnumFieldNumericValueNonZero.JsonOutput -Required.Proto3.JsonInput.EnumFieldNumericValueNonZero.ProtobufOutput -Required.Proto3.JsonInput.EnumFieldNumericValueZero.JsonOutput -Required.Proto3.JsonInput.EnumFieldNumericValueZero.ProtobufOutput -Required.Proto3.JsonInput.EnumFieldUnknownValue.Validator Required.Proto3.JsonInput.FieldMask.JsonOutput Required.Proto3.JsonInput.FieldMask.ProtobufOutput Required.Proto3.JsonInput.FloatFieldInfinity.JsonOutput -Required.Proto3.JsonInput.FloatFieldInfinity.ProtobufOutput Required.Proto3.JsonInput.FloatFieldNan.JsonOutput -Required.Proto3.JsonInput.FloatFieldNan.ProtobufOutput Required.Proto3.JsonInput.FloatFieldNegativeInfinity.JsonOutput -Required.Proto3.JsonInput.FloatFieldNegativeInfinity.ProtobufOutput -Required.Proto3.JsonInput.FloatFieldQuotedValue.JsonOutput -Required.Proto3.JsonInput.FloatFieldQuotedValue.ProtobufOutput -Required.Proto3.JsonInput.FloatFieldTooLarge -Required.Proto3.JsonInput.FloatFieldTooSmall -Required.Proto3.JsonInput.Int32FieldExponentialFormat.JsonOutput -Required.Proto3.JsonInput.Int32FieldExponentialFormat.ProtobufOutput -Required.Proto3.JsonInput.Int32FieldFloatTrailingZero.JsonOutput -Required.Proto3.JsonInput.Int32FieldFloatTrailingZero.ProtobufOutput -Required.Proto3.JsonInput.Int32FieldMaxFloatValue.JsonOutput -Required.Proto3.JsonInput.Int32FieldMaxFloatValue.ProtobufOutput -Required.Proto3.JsonInput.Int32FieldMinFloatValue.JsonOutput -Required.Proto3.JsonInput.Int32FieldMinFloatValue.ProtobufOutput -Required.Proto3.JsonInput.Int32FieldStringValue.JsonOutput -Required.Proto3.JsonInput.Int32FieldStringValue.ProtobufOutput -Required.Proto3.JsonInput.Int32FieldStringValueEscaped.JsonOutput -Required.Proto3.JsonInput.Int32FieldStringValueEscaped.ProtobufOutput -Required.Proto3.JsonInput.Int64FieldMaxValue.JsonOutput -Required.Proto3.JsonInput.Int64FieldMaxValue.ProtobufOutput -Required.Proto3.JsonInput.Int64FieldMinValue.JsonOutput -Required.Proto3.JsonInput.Int64FieldMinValue.ProtobufOutput -Required.Proto3.JsonInput.MessageField.JsonOutput -Required.Proto3.JsonInput.MessageField.ProtobufOutput +Required.Proto3.JsonInput.OneofFieldDuplicate Required.Proto3.JsonInput.OptionalBoolWrapper.JsonOutput Required.Proto3.JsonInput.OptionalBoolWrapper.ProtobufOutput Required.Proto3.JsonInput.OptionalBytesWrapper.JsonOutput @@ -130,8 +89,6 @@ Required.Proto3.JsonInput.RepeatedBytesWrapper.JsonOutput Required.Proto3.JsonInput.RepeatedBytesWrapper.ProtobufOutput Required.Proto3.JsonInput.RepeatedDoubleWrapper.JsonOutput Required.Proto3.JsonInput.RepeatedDoubleWrapper.ProtobufOutput -Required.Proto3.JsonInput.RepeatedFieldWrongElementTypeExpectingMessagesGotInt -Required.Proto3.JsonInput.RepeatedFieldWrongElementTypeExpectingStringsGotInt Required.Proto3.JsonInput.RepeatedFloatWrapper.JsonOutput Required.Proto3.JsonInput.RepeatedFloatWrapper.ProtobufOutput Required.Proto3.JsonInput.RepeatedInt32Wrapper.JsonOutput @@ -146,7 +103,6 @@ Required.Proto3.JsonInput.RepeatedUint64Wrapper.JsonOutput Required.Proto3.JsonInput.RepeatedUint64Wrapper.ProtobufOutput Required.Proto3.JsonInput.StringFieldEscape.JsonOutput Required.Proto3.JsonInput.StringFieldEscape.ProtobufOutput -Required.Proto3.JsonInput.StringFieldNotAString Required.Proto3.JsonInput.StringFieldSurrogatePair.JsonOutput Required.Proto3.JsonInput.StringFieldSurrogatePair.ProtobufOutput Required.Proto3.JsonInput.StringFieldUnicodeEscape.JsonOutput @@ -155,10 +111,16 @@ Required.Proto3.JsonInput.StringFieldUnicodeEscapeWithLowercaseHexLetters.JsonOu Required.Proto3.JsonInput.StringFieldUnicodeEscapeWithLowercaseHexLetters.ProtobufOutput Required.Proto3.JsonInput.Struct.JsonOutput Required.Proto3.JsonInput.Struct.ProtobufOutput -Required.Proto3.JsonInput.Uint32FieldMaxFloatValue.JsonOutput -Required.Proto3.JsonInput.Uint32FieldMaxFloatValue.ProtobufOutput -Required.Proto3.JsonInput.Uint64FieldMaxValue.JsonOutput -Required.Proto3.JsonInput.Uint64FieldMaxValue.ProtobufOutput +Required.Proto3.JsonInput.TimestampMaxValue.JsonOutput +Required.Proto3.JsonInput.TimestampMaxValue.ProtobufOutput +Required.Proto3.JsonInput.TimestampMinValue.JsonOutput +Required.Proto3.JsonInput.TimestampMinValue.ProtobufOutput +Required.Proto3.JsonInput.TimestampRepeatedValue.JsonOutput +Required.Proto3.JsonInput.TimestampRepeatedValue.ProtobufOutput +Required.Proto3.JsonInput.TimestampWithNegativeOffset.JsonOutput +Required.Proto3.JsonInput.TimestampWithNegativeOffset.ProtobufOutput +Required.Proto3.JsonInput.TimestampWithPositiveOffset.JsonOutput +Required.Proto3.JsonInput.TimestampWithPositiveOffset.ProtobufOutput Required.Proto3.JsonInput.ValueAcceptBool.JsonOutput Required.Proto3.JsonInput.ValueAcceptBool.ProtobufOutput Required.Proto3.JsonInput.ValueAcceptFloat.JsonOutput @@ -167,6 +129,8 @@ Required.Proto3.JsonInput.ValueAcceptInteger.JsonOutput Required.Proto3.JsonInput.ValueAcceptInteger.ProtobufOutput Required.Proto3.JsonInput.ValueAcceptList.JsonOutput Required.Proto3.JsonInput.ValueAcceptList.ProtobufOutput +Required.Proto3.JsonInput.ValueAcceptListWithNull.JsonOutput +Required.Proto3.JsonInput.ValueAcceptListWithNull.ProtobufOutput Required.Proto3.JsonInput.ValueAcceptNull.JsonOutput Required.Proto3.JsonInput.ValueAcceptNull.ProtobufOutput Required.Proto3.JsonInput.ValueAcceptObject.JsonOutput diff --git a/conformance/failure_list_ruby.txt b/conformance/failure_list_ruby.txt index b2683372..2d09acd4 100644 --- a/conformance/failure_list_ruby.txt +++ b/conformance/failure_list_ruby.txt @@ -135,3 +135,9 @@ Required.Proto3.ProtobufInput.FloatFieldNormalizeSignalingNan.JsonOutput Required.Proto3.ProtobufInput.ValidDataRepeated.FLOAT.JsonOutput Required.TimestampProtoInputTooLarge.JsonOutput Required.TimestampProtoInputTooSmall.JsonOutput +Required.Proto3.JsonInput.IgnoreUnknownJsonFalse.ProtobufOutput +Required.Proto3.JsonInput.IgnoreUnknownJsonNull.ProtobufOutput +Required.Proto3.JsonInput.IgnoreUnknownJsonNumber.ProtobufOutput +Required.Proto3.JsonInput.IgnoreUnknownJsonObject.ProtobufOutput +Required.Proto3.JsonInput.IgnoreUnknownJsonString.ProtobufOutput +Required.Proto3.JsonInput.IgnoreUnknownJsonTrue.ProtobufOutput diff --git a/csharp/Google.Protobuf.Tools.nuspec b/csharp/Google.Protobuf.Tools.nuspec index 8a0d61e1..901d5ce9 100644 --- a/csharp/Google.Protobuf.Tools.nuspec +++ b/csharp/Google.Protobuf.Tools.nuspec @@ -33,5 +33,7 @@ <file src="..\src\google\protobuf\timestamp.proto" target="tools\google\protobuf" /> <file src="..\src\google\protobuf\type.proto" target="tools\google\protobuf" /> <file src="..\src\google\protobuf\wrappers.proto" target="tools\google\protobuf" /> + <file src="Google.Protobuf.Tools.targets" target="buildCrossTargeting" /> + <file src="Google.Protobuf.Tools.targets" target="build" /> </files> </package> diff --git a/csharp/Google.Protobuf.Tools.targets b/csharp/Google.Protobuf.Tools.targets new file mode 100644 index 00000000..682e11b0 --- /dev/null +++ b/csharp/Google.Protobuf.Tools.targets @@ -0,0 +1,11 @@ +<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <PropertyGroup>
+ <protoc_tools>$([System.IO.Path]::GetFullPath('$(MSBuildThisFileDirectory)/../tools/'))</protoc_tools>
+ <protoc_linux64>$([System.IO.Path]::GetFullPath('$(protoc_tools)/linux_x64/protoc'))</protoc_linux64>
+ <protoc_linux86>$([System.IO.Path]::GetFullPath('$(protoc_tools)/linux_x86/protoc'))</protoc_linux86>
+ <protoc_macosx64>$([System.IO.Path]::GetFullPath('$(protoc_tools)/macosx_x64/protoc'))</protoc_macosx64>
+ <protoc_macosx86>$([System.IO.Path]::GetFullPath('$(protoc_tools)/macosx_x86/protoc'))</protoc_macosx86>
+ <protoc_windows64>$([System.IO.Path]::GetFullPath('$(protoc_tools)/windows_x64/protoc.exe'))</protoc_windows64>
+ <protoc_windows86>$([System.IO.Path]::GetFullPath('$(protoc_tools)/windows_x86/protoc.exe'))</protoc_windows86>
+ </PropertyGroup>
+</Project>
diff --git a/csharp/build_packages.bat b/csharp/build_packages.bat index d7205659..8157bbab 100644 --- a/csharp/build_packages.bat +++ b/csharp/build_packages.bat @@ -1,7 +1,7 @@ @rem Builds Google.Protobuf NuGet packages dotnet restore src/Google.Protobuf.sln -dotnet pack -c Release src/Google.Protobuf.sln || goto :error +dotnet pack -c Release src/Google.Protobuf.sln /p:SourceLinkCreate=true || goto :error goto :EOF diff --git a/csharp/global.json b/csharp/global.json index 5ab775b9..080dcb94 100644 --- a/csharp/global.json +++ b/csharp/global.json @@ -1,5 +1,5 @@ { "sdk": { - "version": "2.0.3" + "version": "2.1.3" } } diff --git a/csharp/src/Google.Protobuf.Conformance/Conformance.cs b/csharp/src/Google.Protobuf.Conformance/Conformance.cs index f6118ea2..6ca52c32 100644 --- a/csharp/src/Google.Protobuf.Conformance/Conformance.cs +++ b/csharp/src/Google.Protobuf.Conformance/Conformance.cs @@ -24,21 +24,24 @@ namespace Conformance { static ConformanceReflection() { byte[] descriptorData = global::System.Convert.FromBase64String( string.Concat( - "ChFjb25mb3JtYW5jZS5wcm90bxILY29uZm9ybWFuY2UiowEKEkNvbmZvcm1h", + "ChFjb25mb3JtYW5jZS5wcm90bxILY29uZm9ybWFuY2Ui1QEKEkNvbmZvcm1h", "bmNlUmVxdWVzdBIaChBwcm90b2J1Zl9wYXlsb2FkGAEgASgMSAASFgoManNv", "bl9wYXlsb2FkGAIgASgJSAASOAoXcmVxdWVzdGVkX291dHB1dF9mb3JtYXQY", "AyABKA4yFy5jb25mb3JtYW5jZS5XaXJlRm9ybWF0EhQKDG1lc3NhZ2VfdHlw", - "ZRgEIAEoCUIJCgdwYXlsb2FkIrEBChNDb25mb3JtYW5jZVJlc3BvbnNlEhUK", - "C3BhcnNlX2Vycm9yGAEgASgJSAASGQoPc2VyaWFsaXplX2Vycm9yGAYgASgJ", - "SAASFwoNcnVudGltZV9lcnJvchgCIAEoCUgAEhoKEHByb3RvYnVmX3BheWxv", - "YWQYAyABKAxIABIWCgxqc29uX3BheWxvYWQYBCABKAlIABIRCgdza2lwcGVk", - "GAUgASgJSABCCAoGcmVzdWx0KjUKCldpcmVGb3JtYXQSDwoLVU5TUEVDSUZJ", - "RUQQABIMCghQUk9UT0JVRhABEggKBEpTT04QAkIhCh9jb20uZ29vZ2xlLnBy", - "b3RvYnVmLmNvbmZvcm1hbmNlYgZwcm90bzM=")); + "ZRgEIAEoCRIwCg10ZXN0X2NhdGVnb3J5GAUgASgOMhkuY29uZm9ybWFuY2Uu", + "VGVzdENhdGVnb3J5QgkKB3BheWxvYWQisQEKE0NvbmZvcm1hbmNlUmVzcG9u", + "c2USFQoLcGFyc2VfZXJyb3IYASABKAlIABIZCg9zZXJpYWxpemVfZXJyb3IY", + "BiABKAlIABIXCg1ydW50aW1lX2Vycm9yGAIgASgJSAASGgoQcHJvdG9idWZf", + "cGF5bG9hZBgDIAEoDEgAEhYKDGpzb25fcGF5bG9hZBgEIAEoCUgAEhEKB3Nr", + "aXBwZWQYBSABKAlIAEIICgZyZXN1bHQqNQoKV2lyZUZvcm1hdBIPCgtVTlNQ", + "RUNJRklFRBAAEgwKCFBST1RPQlVGEAESCAoESlNPThACKlQKDFRlc3RDYXRl", + "Z29yeRIPCgtCSU5BUllfVEVTVBAAEg0KCUpTT05fVEVTVBABEiQKIEpTT05f", + "SUdOT1JFX1VOS05PV05fUEFSU0lOR19URVNUEAJCIQofY29tLmdvb2dsZS5w", + "cm90b2J1Zi5jb25mb3JtYW5jZWIGcHJvdG8z")); descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData, new pbr::FileDescriptor[] { }, - new pbr::GeneratedClrTypeInfo(new[] {typeof(global::Conformance.WireFormat), }, new pbr::GeneratedClrTypeInfo[] { - new pbr::GeneratedClrTypeInfo(typeof(global::Conformance.ConformanceRequest), global::Conformance.ConformanceRequest.Parser, new[]{ "ProtobufPayload", "JsonPayload", "RequestedOutputFormat", "MessageType" }, new[]{ "Payload" }, null, null), + new pbr::GeneratedClrTypeInfo(new[] {typeof(global::Conformance.WireFormat), typeof(global::Conformance.TestCategory), }, new pbr::GeneratedClrTypeInfo[] { + new pbr::GeneratedClrTypeInfo(typeof(global::Conformance.ConformanceRequest), global::Conformance.ConformanceRequest.Parser, new[]{ "ProtobufPayload", "JsonPayload", "RequestedOutputFormat", "MessageType", "TestCategory" }, new[]{ "Payload" }, null, null), new pbr::GeneratedClrTypeInfo(typeof(global::Conformance.ConformanceResponse), global::Conformance.ConformanceResponse.Parser, new[]{ "ParseError", "SerializeError", "RuntimeError", "ProtobufPayload", "JsonPayload", "Skipped" }, new[]{ "Result" }, null, null) })); } @@ -52,6 +55,25 @@ namespace Conformance { [pbr::OriginalName("JSON")] Json = 2, } + public enum TestCategory { + /// <summary> + /// Test binary wire format. + /// </summary> + [pbr::OriginalName("BINARY_TEST")] BinaryTest = 0, + /// <summary> + /// Test json wire format. + /// </summary> + [pbr::OriginalName("JSON_TEST")] JsonTest = 1, + /// <summary> + /// Similar to JSON_TEST. However, during parsing json, testee should ignore + /// unknown fields. This feature is optional. Each implementation can descide + /// whether to support it. See + /// https://developers.google.com/protocol-buffers/docs/proto3#json_options + /// for more detail. + /// </summary> + [pbr::OriginalName("JSON_IGNORE_UNKNOWN_PARSING_TEST")] JsonIgnoreUnknownParsingTest = 2, + } + #endregion #region Messages @@ -89,6 +111,7 @@ namespace Conformance { public ConformanceRequest(ConformanceRequest other) : this() { requestedOutputFormat_ = other.requestedOutputFormat_; messageType_ = other.messageType_; + testCategory_ = other.testCategory_; switch (other.PayloadCase) { case PayloadOneofCase.ProtobufPayload: ProtobufPayload = other.ProtobufPayload; @@ -158,6 +181,22 @@ namespace Conformance { } } + /// <summary>Field number for the "test_category" field.</summary> + public const int TestCategoryFieldNumber = 5; + private global::Conformance.TestCategory testCategory_ = 0; + /// <summary> + /// Each test is given a specific test category. Some category may need spedific + /// support in testee programs. Refer to the defintion of TestCategory for + /// more information. + /// </summary> + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public global::Conformance.TestCategory TestCategory { + get { return testCategory_; } + set { + testCategory_ = value; + } + } + private object payload_; /// <summary>Enum of possible cases for the "payload" oneof.</summary> public enum PayloadOneofCase { @@ -194,6 +233,7 @@ namespace Conformance { if (JsonPayload != other.JsonPayload) return false; if (RequestedOutputFormat != other.RequestedOutputFormat) return false; if (MessageType != other.MessageType) return false; + if (TestCategory != other.TestCategory) return false; if (PayloadCase != other.PayloadCase) return false; return Equals(_unknownFields, other._unknownFields); } @@ -205,6 +245,7 @@ namespace Conformance { if (payloadCase_ == PayloadOneofCase.JsonPayload) hash ^= JsonPayload.GetHashCode(); if (RequestedOutputFormat != 0) hash ^= RequestedOutputFormat.GetHashCode(); if (MessageType.Length != 0) hash ^= MessageType.GetHashCode(); + if (TestCategory != 0) hash ^= TestCategory.GetHashCode(); hash ^= (int) payloadCase_; if (_unknownFields != null) { hash ^= _unknownFields.GetHashCode(); @@ -235,6 +276,10 @@ namespace Conformance { output.WriteRawTag(34); output.WriteString(MessageType); } + if (TestCategory != 0) { + output.WriteRawTag(40); + output.WriteEnum((int) TestCategory); + } if (_unknownFields != null) { _unknownFields.WriteTo(output); } @@ -255,6 +300,9 @@ namespace Conformance { if (MessageType.Length != 0) { size += 1 + pb::CodedOutputStream.ComputeStringSize(MessageType); } + if (TestCategory != 0) { + size += 1 + pb::CodedOutputStream.ComputeEnumSize((int) TestCategory); + } if (_unknownFields != null) { size += _unknownFields.CalculateSize(); } @@ -272,6 +320,9 @@ namespace Conformance { if (other.MessageType.Length != 0) { MessageType = other.MessageType; } + if (other.TestCategory != 0) { + TestCategory = other.TestCategory; + } switch (other.PayloadCase) { case PayloadOneofCase.ProtobufPayload: ProtobufPayload = other.ProtobufPayload; @@ -308,6 +359,10 @@ namespace Conformance { MessageType = input.ReadString(); break; } + case 40: { + testCategory_ = (global::Conformance.TestCategory) input.ReadEnum(); + break; + } } } } diff --git a/csharp/src/Google.Protobuf.Conformance/Program.cs b/csharp/src/Google.Protobuf.Conformance/Program.cs index 96dc354e..1eac00be 100644 --- a/csharp/src/Google.Protobuf.Conformance/Program.cs +++ b/csharp/src/Google.Protobuf.Conformance/Program.cs @@ -87,6 +87,9 @@ namespace Google.Protobuf.Conformance switch (request.PayloadCase) { case ConformanceRequest.PayloadOneofCase.JsonPayload: + if (request.TestCategory == global::Conformance.TestCategory.JsonIgnoreUnknownParsingTest) { + return new ConformanceResponse { Skipped = "CSharp doesn't support skipping unknown fields in json parsing." }; + } var parser = new JsonParser(new JsonParser.Settings(20, typeRegistry)); message = parser.Parse<ProtobufTestMessages.Proto3.TestAllTypesProto3>(request.JsonPayload); break; diff --git a/csharp/src/Google.Protobuf.Test/ByteStringTest.cs b/csharp/src/Google.Protobuf.Test/ByteStringTest.cs index afdd491f..afdd491f 100755..100644 --- a/csharp/src/Google.Protobuf.Test/ByteStringTest.cs +++ b/csharp/src/Google.Protobuf.Test/ByteStringTest.cs diff --git a/csharp/src/Google.Protobuf.Test/CodedInputStreamTest.cs b/csharp/src/Google.Protobuf.Test/CodedInputStreamTest.cs index 8795fa65..8795fa65 100755..100644 --- a/csharp/src/Google.Protobuf.Test/CodedInputStreamTest.cs +++ b/csharp/src/Google.Protobuf.Test/CodedInputStreamTest.cs diff --git a/csharp/src/Google.Protobuf.Test/Compatibility/StreamExtensionsTest.cs b/csharp/src/Google.Protobuf.Test/Compatibility/StreamExtensionsTest.cs index 48c0725f..48c0725f 100755..100644 --- a/csharp/src/Google.Protobuf.Test/Compatibility/StreamExtensionsTest.cs +++ b/csharp/src/Google.Protobuf.Test/Compatibility/StreamExtensionsTest.cs diff --git a/csharp/src/Google.Protobuf.Test/Compatibility/TypeExtensionsTest.cs b/csharp/src/Google.Protobuf.Test/Compatibility/TypeExtensionsTest.cs index abbe3c95..abbe3c95 100755..100644 --- a/csharp/src/Google.Protobuf.Test/Compatibility/TypeExtensionsTest.cs +++ b/csharp/src/Google.Protobuf.Test/Compatibility/TypeExtensionsTest.cs diff --git a/csharp/src/Google.Protobuf.Test/FieldCodecTest.cs b/csharp/src/Google.Protobuf.Test/FieldCodecTest.cs index 77641163..77641163 100755..100644 --- a/csharp/src/Google.Protobuf.Test/FieldCodecTest.cs +++ b/csharp/src/Google.Protobuf.Test/FieldCodecTest.cs diff --git a/csharp/src/Google.Protobuf.Test/WellKnownTypes/TimestampTest.cs b/csharp/src/Google.Protobuf.Test/WellKnownTypes/TimestampTest.cs index 9ecd24c6..b8c07ef5 100644 --- a/csharp/src/Google.Protobuf.Test/WellKnownTypes/TimestampTest.cs +++ b/csharp/src/Google.Protobuf.Test/WellKnownTypes/TimestampTest.cs @@ -111,5 +111,106 @@ namespace Google.Protobuf.WellKnownTypes var duration = new Timestamp { Seconds = 1, Nanos = -1 }; Assert.AreEqual("{ \"@warning\": \"Invalid Timestamp\", \"seconds\": \"1\", \"nanos\": -1 }", duration.ToString()); } + + [Test] + public void Comparability() + { + Timestamp + a = null, + b = new Timestamp { Seconds = 1, Nanos = 1 }, + c = new Timestamp { Seconds = 1, Nanos = 10 }, + d = new Timestamp { Seconds = 10, Nanos = 1 }, + e = new Timestamp { Seconds = 10, Nanos = 10 }; + + Assert.IsTrue(b.CompareTo(a) > 0); // null is always first (according to default behavior of Array.Sort) + Assert.IsTrue(b.CompareTo(b) == 0); + Assert.IsTrue(b.CompareTo(b.Clone()) == 0); + Assert.IsTrue(b.CompareTo(c) < 0); + Assert.IsTrue(b.CompareTo(d) < 0); + Assert.IsTrue(b.CompareTo(e) < 0); + + Assert.IsTrue(c.CompareTo(a) > 0); + Assert.IsTrue(c.CompareTo(b) > 0); + Assert.IsTrue(c.CompareTo(c) == 0); + Assert.IsTrue(c.CompareTo(c.Clone()) == 0); + Assert.IsTrue(c.CompareTo(d) < 0); + Assert.IsTrue(c.CompareTo(e) < 0); + + Assert.IsTrue(d.CompareTo(a) > 0); + Assert.IsTrue(d.CompareTo(b) > 0); + Assert.IsTrue(d.CompareTo(c) > 0); + Assert.IsTrue(d.CompareTo(d) == 0); + Assert.IsTrue(d.CompareTo(d.Clone()) == 0); + Assert.IsTrue(d.CompareTo(e) < 0); + + Assert.IsTrue(e.CompareTo(a) > 0); + Assert.IsTrue(e.CompareTo(b) > 0); + Assert.IsTrue(e.CompareTo(c) > 0); + Assert.IsTrue(e.CompareTo(d) > 0); + Assert.IsTrue(e.CompareTo(e) == 0); + Assert.IsTrue(e.CompareTo(e.Clone()) == 0); + } + + + [Test] + public void ComparabilityOperators() + { + Timestamp + a = null, + b = new Timestamp { Seconds = 1, Nanos = 1 }, + c = new Timestamp { Seconds = 1, Nanos = 10 }, + d = new Timestamp { Seconds = 10, Nanos = 1 }, + e = new Timestamp { Seconds = 10, Nanos = 10 }; + +#pragma warning disable CS1718 // Comparison made to same variable + Assert.IsTrue(b > a); + Assert.IsTrue(b == b); + Assert.IsTrue(b == b.Clone()); + Assert.IsTrue(b < c); + Assert.IsTrue(b < d); + Assert.IsTrue(b < e); + + Assert.IsTrue(c > a); + Assert.IsTrue(c > b); + Assert.IsTrue(c == c); + Assert.IsTrue(c == c.Clone()); + Assert.IsTrue(c < d); + Assert.IsTrue(c < e); + + Assert.IsTrue(d > a); + Assert.IsTrue(d > b); + Assert.IsTrue(d > c); + Assert.IsTrue(d == d); + Assert.IsTrue(d == d.Clone()); + Assert.IsTrue(d < e); + + Assert.IsTrue(e > a); + Assert.IsTrue(e > b); + Assert.IsTrue(e > c); + Assert.IsTrue(e > d); + Assert.IsTrue(e == e); + Assert.IsTrue(e == e.Clone()); + + Assert.IsTrue(b >= a); + Assert.IsTrue(b <= c); + Assert.IsTrue(b <= d); + Assert.IsTrue(b <= e); + + Assert.IsTrue(c >= a); + Assert.IsTrue(c >= b); + Assert.IsTrue(c <= d); + Assert.IsTrue(c <= e); + + Assert.IsTrue(d >= a); + Assert.IsTrue(d >= b); + Assert.IsTrue(d >= c); + Assert.IsTrue(d <= e); + + Assert.IsTrue(e >= a); + Assert.IsTrue(e >= b); + Assert.IsTrue(e >= c); + Assert.IsTrue(e >= d); +#pragma warning restore CS1718 // Comparison made to same variable + } } } diff --git a/csharp/src/Google.Protobuf/ByteString.cs b/csharp/src/Google.Protobuf/ByteString.cs index 4abdb718..4abdb718 100755..100644 --- a/csharp/src/Google.Protobuf/ByteString.cs +++ b/csharp/src/Google.Protobuf/ByteString.cs diff --git a/csharp/src/Google.Protobuf/Collections/RepeatedField.cs b/csharp/src/Google.Protobuf/Collections/RepeatedField.cs index c18b63e2..c18b63e2 100755..100644 --- a/csharp/src/Google.Protobuf/Collections/RepeatedField.cs +++ b/csharp/src/Google.Protobuf/Collections/RepeatedField.cs diff --git a/csharp/src/Google.Protobuf/Compatibility/PropertyInfoExtensions.cs b/csharp/src/Google.Protobuf/Compatibility/PropertyInfoExtensions.cs index 95a02c72..95a02c72 100755..100644 --- a/csharp/src/Google.Protobuf/Compatibility/PropertyInfoExtensions.cs +++ b/csharp/src/Google.Protobuf/Compatibility/PropertyInfoExtensions.cs diff --git a/csharp/src/Google.Protobuf/Compatibility/StreamExtensions.cs b/csharp/src/Google.Protobuf/Compatibility/StreamExtensions.cs index bf4bf220..bf4bf220 100755..100644 --- a/csharp/src/Google.Protobuf/Compatibility/StreamExtensions.cs +++ b/csharp/src/Google.Protobuf/Compatibility/StreamExtensions.cs diff --git a/csharp/src/Google.Protobuf/Compatibility/TypeExtensions.cs b/csharp/src/Google.Protobuf/Compatibility/TypeExtensions.cs index 2f237138..2f237138 100755..100644 --- a/csharp/src/Google.Protobuf/Compatibility/TypeExtensions.cs +++ b/csharp/src/Google.Protobuf/Compatibility/TypeExtensions.cs diff --git a/csharp/src/Google.Protobuf/Google.Protobuf.csproj b/csharp/src/Google.Protobuf/Google.Protobuf.csproj index 11bc03d1..a056b435 100644 --- a/csharp/src/Google.Protobuf/Google.Protobuf.csproj +++ b/csharp/src/Google.Protobuf/Google.Protobuf.csproj @@ -17,8 +17,6 @@ <PackageLicenseUrl>https://github.com/google/protobuf/blob/master/LICENSE</PackageLicenseUrl> <RepositoryType>git</RepositoryType> <RepositoryUrl>https://github.com/google/protobuf.git</RepositoryUrl> - <IncludeSymbols>true</IncludeSymbols> - <IncludeSource>true</IncludeSource> </PropertyGroup> <!-- @@ -30,4 +28,8 @@ <TargetFrameworks>netstandard1.0</TargetFrameworks> </PropertyGroup> + <ItemGroup> + <PackageReference Include="SourceLink.Create.CommandLine" Version="2.7.6" PrivateAssets="All" /> + </ItemGroup> + </Project> diff --git a/csharp/src/Google.Protobuf/JsonFormatter.cs b/csharp/src/Google.Protobuf/JsonFormatter.cs index 4ae10d8b..4ae10d8b 100755..100644 --- a/csharp/src/Google.Protobuf/JsonFormatter.cs +++ b/csharp/src/Google.Protobuf/JsonFormatter.cs diff --git a/csharp/src/Google.Protobuf/Reflection/MessageDescriptor.cs b/csharp/src/Google.Protobuf/Reflection/MessageDescriptor.cs index 86942acc..86942acc 100755..100644 --- a/csharp/src/Google.Protobuf/Reflection/MessageDescriptor.cs +++ b/csharp/src/Google.Protobuf/Reflection/MessageDescriptor.cs diff --git a/csharp/src/Google.Protobuf/WellKnownTypes/FieldMaskPartial.cs b/csharp/src/Google.Protobuf/WellKnownTypes/FieldMaskPartial.cs index 4b0670f6..4b0670f6 100755..100644 --- a/csharp/src/Google.Protobuf/WellKnownTypes/FieldMaskPartial.cs +++ b/csharp/src/Google.Protobuf/WellKnownTypes/FieldMaskPartial.cs diff --git a/csharp/src/Google.Protobuf/WellKnownTypes/TimestampPartial.cs b/csharp/src/Google.Protobuf/WellKnownTypes/TimestampPartial.cs index aa403473..a9251974 100644 --- a/csharp/src/Google.Protobuf/WellKnownTypes/TimestampPartial.cs +++ b/csharp/src/Google.Protobuf/WellKnownTypes/TimestampPartial.cs @@ -36,7 +36,7 @@ using System.Text; namespace Google.Protobuf.WellKnownTypes { - public partial class Timestamp : ICustomDiagnosticMessage + public partial class Timestamp : ICustomDiagnosticMessage, IComparable<Timestamp> { private static readonly DateTime UnixEpoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc); // Constants determined programmatically, but then hard-coded so they can be constant expressions. @@ -223,6 +223,109 @@ namespace Google.Protobuf.WellKnownTypes } /// <summary> + /// Given another timestamp, returns 0 if the timestamps are equivalent, -1 if this timestamp precedes the other, and 1 otherwise + /// </summary> + /// <remarks> + /// Make sure the timestamps are normalized. Comparing non-normalized timestamps is not specified and may give unexpected results. + /// </remarks> + /// <param name="other">Timestamp to compare</param> + /// <returns>an integer indicating whether this timestamp precedes or follows the other</returns> + public int CompareTo(Timestamp other) + { + return other == null ? 1 + : Seconds < other.Seconds ? -1 + : Seconds > other.Seconds ? 1 + : Nanos < other.Nanos ? -1 + : Nanos > other.Nanos ? 1 + : 0; + } + + /// <summary> + /// Compares two timestamps and returns whether the first is less than (chronologically precedes) the second + /// </summary> + /// <remarks> + /// Make sure the timestamps are normalized. Comparing non-normalized timestamps is not specified and may give unexpected results. + /// </remarks> + /// <param name="a"></param> + /// <param name="b"></param> + /// <returns>true if a precedes b</returns> + public static bool operator <(Timestamp a, Timestamp b) + { + return a.CompareTo(b) < 0; + } + + /// <summary> + /// Compares two timestamps and returns whether the first is greater than (chronologically follows) the second + /// </summary> + /// <remarks> + /// Make sure the timestamps are normalized. Comparing non-normalized timestamps is not specified and may give unexpected results. + /// </remarks> + /// <param name="a"></param> + /// <param name="b"></param> + /// <returns>true if a follows b</returns> + public static bool operator >(Timestamp a, Timestamp b) + { + return a.CompareTo(b) > 0; + } + + /// <summary> + /// Compares two timestamps and returns whether the first is less than (chronologically precedes) the second + /// </summary> + /// <remarks> + /// Make sure the timestamps are normalized. Comparing non-normalized timestamps is not specified and may give unexpected results. + /// </remarks> + /// <param name="a"></param> + /// <param name="b"></param> + /// <returns>true if a precedes b</returns> + public static bool operator <=(Timestamp a, Timestamp b) + { + return a.CompareTo(b) <= 0; + } + + /// <summary> + /// Compares two timestamps and returns whether the first is greater than (chronologically follows) the second + /// </summary> + /// <remarks> + /// Make sure the timestamps are normalized. Comparing non-normalized timestamps is not specified and may give unexpected results. + /// </remarks> + /// <param name="a"></param> + /// <param name="b"></param> + /// <returns>true if a follows b</returns> + public static bool operator >=(Timestamp a, Timestamp b) + { + return a.CompareTo(b) >= 0; + } + + + /// <summary> + /// Returns whether two timestamps are equivalent + /// </summary> + /// <remarks> + /// Make sure the timestamps are normalized. Comparing non-normalized timestamps is not specified and may give unexpected results. + /// </remarks> + /// <param name="a"></param> + /// <param name="b"></param> + /// <returns>true if the two timestamps refer to the same nanosecond</returns> + public static bool operator ==(Timestamp a, Timestamp b) + { + return ReferenceEquals(a, b) || (a is null ? (b is null ? true : false) : a.Equals(b)); + } + + /// <summary> + /// Returns whether two timestamps differ + /// </summary> + /// <remarks> + /// Make sure the timestamps are normalized. Comparing non-normalized timestamps is not specified and may give unexpected results. + /// </remarks> + /// <param name="a"></param> + /// <param name="b"></param> + /// <returns>true if the two timestamps differ</returns> + public static bool operator !=(Timestamp a, Timestamp b) + { + return !(a == b); + } + + /// <summary> /// Returns a string representation of this <see cref="Timestamp"/> for diagnostic purposes. /// </summary> /// <remarks> diff --git a/docs/options.md b/docs/options.md new file mode 100644 index 00000000..529cce5d --- /dev/null +++ b/docs/options.md @@ -0,0 +1,190 @@ +# Protobuf Global Extension Registry + +This file contains a global registry of known extensions for descriptor.proto, +so that any developer who wishes to use multiple 3rd party projects, each with +their own extensions, can be confident that there won't be collisions in +extension numbers. + +If you need an extension number for your custom option (see [custom options]( +https://developers.google.com/protocol-buffers/docs/proto#customoptions)), +please [send us a pull request](https://github.com/google/protobuf/pulls) to +add an entry to this doc, or [create an issue](https://github.com/google/protobuf/issues) +with info about your project (name and website) so we can add an entry for you. + +## Existing Registered Extensions + +1. C# port of protocol buffers + * Website: http://github.com/jskeet/dotnet-protobufs + * Extensions: 1000 + +1. Perl/XS port of protocol buffers + * Website: http://code.google.com/p/protobuf-perlxs + * Extensions: 1001 + +1. Objective-C port of protocol buffers + * Website: http://code.google.com/p/protobuf-objc + * Extensions: 1002 + +1. Google Wave Federation Protocol open-source release (FedOne) + * Website: http://code.google.com/p/wave-protocol + * Extensions: 1003 + +1. PHP code generator plugin + * Website: ??? + * Extensions: 1004 + +1. GWT code generator plugin (third-party!) + * Website: http://code.google.com/p/protobuf-gwt/ + * Extensions: 1005 + +1. Unix Domain RPC code generator plugin + * Website: http://go/udrpc + * Extensions: 1006 + +1. Object-C generator plugin (Plausible Labs) + * Website: http://www.plausible.coop + * Extensions: 1007 + +1. TBD (code42.com) + * Website: ??? + * Extensions: 1008 + +1. Goby Underwater Autonomy Project + * Website: https://launchpad.net/goby + * Extensions: 1009 + +1. Nanopb + * Website: http://kapsi.fi/~jpa/nanopb + * Extensions: 1010 + +1. Bluefin AUV Communication Extensions + * Website: http://www.bluefinrobotics.com + * Extensions: 1011 + +1. Dynamic Compact Control Language + * Website: https://launchpad.net/dccl + * Extensions: 1012 + +1. ScaleOut StateServer® Native C++ API + * Website: http://www.scaleoutsoftware.com + * Extensions: 1013 + +1. FoundationDB SQL Layer + * Website: https://github.com/FoundationDB/sql-layer + * Extensions: 1014 + +1. Fender + * Website: https://github.com/hassox/fender + * Extensions: 1015 + +1. Vortex + * Website: http://www.prismtech.com/vortex + * Extensions: 1016 + +1. tresorit + * Website: https://tresorit.com/ + * Extensions: 1017 + +1. CRIU (Checkpoint Restore In Userspace) + * Website: http://criu.org/Main_Page + * Extensions: 1018 + +1. protobuf-c + * Website: https://github.com/protobuf-c/protobuf-c + * Extensions: 1019 + +1. ScalePB + * Website: http://trueaccord.github.io/ScalaPB/ + * Extensions: 1020 + +1. protoc-gen-bq-schema + * Website: https://github.com/GoogleCloudPlatform/protoc-gen-bq-schema + * Extensions: 1021 + +1. grpc-gateway + * Website: https://github.com/gengo/grpc-gateway + * Extensions: 1022 + +1. Certificate Transparency + * Website: https://github.com/google/certificate-transparency + * Extensions: 1023 + +1. JUNOS Router Telemetry + * Website: http://www.juniper.net + * Extensions: 1024 + +1. Spine Event Engine + * Website: https://github.com/SpineEventEngine/core-java + * Extensions: 1025 + +1. Aruba cloud platform + * Website: ??? + * Extensions: 1026 -> 1030 + +1. Voltha + * Website: ??? + * Extensions: 1031 -> 1033 + +1. gator + * Website: ??? + * Extensions: 1034 + +1. protoc-gen-flowtypes + * Website: https://github.com/tmc/grpcutil/tree/master/protoc-gen-flowtypes + * Extensions: 1035 + +1. ProfaneDB + * Website: https://gitlab.com/ProfaneDB/ProfaneDB + * Extensions: 1036 + +1. protobuf-net + * Website: https://github.com/mgravell/protobuf-net + * Extensions: 1037 + +1. FICO / StreamEngine + * Website: http://www.fico.com/ + * Extensions: 1038 + +1. GopherJS + * Website: https://github.com/johanbrandhorst/protobuf + * Extensions: 1039 + +1. ygot + * Website: https://github.com/openconfig/ygot + * Extensions: 1040 + +1. go-grpcmw + * Website: https://github.com/MarquisIO/go-grpcmw + * Extensions: 1041 + +1. grpc-gateway protoc-gen-swagger + * Website: https://github.com/grpc-ecosystem/grpc-gateway + * Extensions: 1042 + +1. AN Message + * Website: TBD + * Extensions: 1043 + +1. protofire + * Website: https://github.com/ribrdb/protofire + * Extensions: 1044 + +1. Gravity + * Website: https://github.com/aphysci/gravity + * Extensions: 1045 + +1. SEMI Standards – I&C Technical Committee + * Website: http://downloads.semi.org/web/wstdsbal.nsf/9c2b317e76523cca88257641005a47f5/88a5863a580e323088256e7b00707489!OpenDocument + * Extensions: 1046 + +1. Elixir plugin + * Website: https://github.com/tony612/grpc-elixir + * Extensions: 1047 + +1. API client generators + * Website: ??? + * Extensions: 1048-1056 + +1. Netifi Proteus + * Website: https://github.com/netifi-proteus + * Extensions: 1057 diff --git a/docs/performance.md b/docs/performance.md index 6a5316c8..3bca58af 100644 --- a/docs/performance.md +++ b/docs/performance.md @@ -1,4 +1,4 @@ -# Protobuf Perforamcne +# Protobuf Performance This benchmark result is tested on workstation with processor of Intel® Xeon® Processor E5-2630 and 32GB RAM This table contains 3 languages' results: diff --git a/docs/third_party.md b/docs/third_party.md index 3f267dde..f710b51a 100644 --- a/docs/third_party.md +++ b/docs/third_party.md @@ -23,8 +23,10 @@ These are projects we know about implementing Protocol Buffers for other program * C#: https://silentorbit.com/protobuf/ * C#/.NET/WCF/VB: http://code.google.com/p/protobuf-net/ * Clojure: http://github.com/ninjudd/clojure-protobuf +* Clojure: https://github.com/clojusc/protobuf * Common Lisp: http://github.com/ndantam/s-protobuf * Common Lisp: http://github.com/brown/protobuf +* D: https://github.com/dcarp/protobuf-d * D: https://github.com/msoucy/dproto * D: http://256.makerslocal.org/wiki/index.php/ProtocolBuffer * D: https://github.com/opticron/ProtocolBuffer @@ -39,6 +41,7 @@ These are projects we know about implementing Protocol Buffers for other program * Erlang: https://code.google.com/p/protoc-gen-erl/ * Erlang: https://github.com/basho/erlang_protobuffs * Erlang: https://github.com/tomas-abrahamsson/gpb +* GDScript: https://github.com/oniksan/godobuf (Godot v3 engine plugin) * Go: https://github.com/golang/protobuf (Google-official implementation) * Go: https://github.com/akunspy/gopbuf * Go: https://github.com/gogo/protobuf @@ -87,7 +90,7 @@ These are projects we know about implementing Protocol Buffers for other program * Scala: http://github.com/jeffplaisance/scala-protobuf * Scala: http://code.google.com/p/protobuf-scala * Scala: https://github.com/SandroGrzicic/ScalaBuff -* Scala: http://trueaccord.github.io/ScalaPB/ +* Scala: https://scalapb.github.io * Swift: https://github.com/alexeyxo/protobuf-swift * Swift: https://github.com/apple/swift-protobuf/ * Vala: https://launchpad.net/protobuf-vala @@ -125,6 +128,8 @@ GRPC (http://www.grpc.io/) is Google's RPC implementation for Protocol Buffers. * https://github.com/johanbrandhorst/protobuf (GopherJS) * https://github.com/awakesecurity/gRPC-haskell (Haskell) * https://github.com/Yeolar/raster (C++) +* https://github.com/jnordberg/wsrpc (JavaScript Node.js/Browser) +* https://github.com/ppissias/xsrpcj (Java) ## Other Utilities diff --git a/generate_changelog.py b/generate_changelog.py index d90a9b70..8e5bf423 100755 --- a/generate_changelog.py +++ b/generate_changelog.py @@ -20,11 +20,10 @@ languages = [ ]), Language("Java", [ "java", - "javanano", - "src/google/protobuf/compiler/cpp", + "src/google/protobuf/compiler/java", ]), Language("Python", [ - "javanano", + "python", "src/google/protobuf/compiler/python", ]), Language("JavaScript", [ diff --git a/java/core/pom.xml b/java/core/pom.xml index 067749c6..0c0fd8ff 100644 --- a/java/core/pom.xml +++ b/java/core/pom.xml @@ -135,6 +135,7 @@ <Bundle-DocURL>https://developers.google.com/protocol-buffers/</Bundle-DocURL> <Bundle-SymbolicName>com.google.protobuf</Bundle-SymbolicName> <Export-Package>com.google.protobuf;version=${project.version}</Export-Package> + <Import-Package>sun.misc;resolution:=optional,*</Import-Package> </instructions> </configuration> </plugin> diff --git a/java/core/src/main/java/com/google/protobuf/GeneratedMessageLite.java b/java/core/src/main/java/com/google/protobuf/GeneratedMessageLite.java index df01547e..1e122d16 100644 --- a/java/core/src/main/java/com/google/protobuf/GeneratedMessageLite.java +++ b/java/core/src/main/java/com/google/protobuf/GeneratedMessageLite.java @@ -1407,7 +1407,7 @@ public abstract class GeneratedMessageLite< /** * A serialized (serializable) form of the generated message. Stores the - * message as a class name and a byte array. + * message as a class and a byte array. */ protected static final class SerializedForm implements Serializable { @@ -1417,6 +1417,9 @@ public abstract class GeneratedMessageLite< private static final long serialVersionUID = 0L; + // since v3.6.1 + private final Class<?> messageClass; + // only included for backwards compatibility before messageClass was added private final String messageClassName; private final byte[] asBytes; @@ -1425,7 +1428,8 @@ public abstract class GeneratedMessageLite< * @param regularForm the message to serialize */ SerializedForm(MessageLite regularForm) { - messageClassName = regularForm.getClass().getName(); + messageClass = regularForm.getClass(); + messageClassName = messageClass.getName(); asBytes = regularForm.toByteArray(); } @@ -1437,7 +1441,7 @@ public abstract class GeneratedMessageLite< @SuppressWarnings("unchecked") protected Object readResolve() throws ObjectStreamException { try { - Class<?> messageClass = Class.forName(messageClassName); + Class<?> messageClass = resolveMessageClass(); java.lang.reflect.Field defaultInstanceField = messageClass.getDeclaredField("DEFAULT_INSTANCE"); defaultInstanceField.setAccessible(true); @@ -1464,7 +1468,7 @@ public abstract class GeneratedMessageLite< @Deprecated private Object readResolveFallback() throws ObjectStreamException { try { - Class<?> messageClass = Class.forName(messageClassName); + Class<?> messageClass = resolveMessageClass(); java.lang.reflect.Field defaultInstanceField = messageClass.getDeclaredField("defaultInstance"); defaultInstanceField.setAccessible(true); @@ -1484,6 +1488,10 @@ public abstract class GeneratedMessageLite< throw new RuntimeException("Unable to understand proto buffer", e); } } + + private Class<?> resolveMessageClass() throws ClassNotFoundException { + return messageClass != null ? messageClass : Class.forName(messageClassName); + } } /** diff --git a/java/core/src/main/java/com/google/protobuf/UnsafeUtil.java b/java/core/src/main/java/com/google/protobuf/UnsafeUtil.java index c9e2904b..d84ef3c5 100644 --- a/java/core/src/main/java/com/google/protobuf/UnsafeUtil.java +++ b/java/core/src/main/java/com/google/protobuf/UnsafeUtil.java @@ -33,7 +33,6 @@ package com.google.protobuf; import java.lang.reflect.Field; import java.nio.Buffer; import java.nio.ByteBuffer; -import java.nio.ByteOrder; import java.security.AccessController; import java.security.PrivilegedExceptionAction; import java.util.logging.Level; @@ -72,8 +71,6 @@ final class UnsafeUtil { private static final long BUFFER_ADDRESS_OFFSET = fieldOffset(bufferAddressField()); - private static final long STRING_VALUE_OFFSET = fieldOffset(stringValueField()); - private UnsafeUtil() {} static boolean hasUnsafeArrayOperations() { @@ -149,10 +146,6 @@ final class UnsafeUtil { return MEMORY_ACCESSOR.getObject(target, offset); } - static void putObject(Object target, long offset, Object value) { - MEMORY_ACCESSOR.putObject(target, offset, value); - } - static byte getByte(byte[] target, long index) { return MEMORY_ACCESSOR.getByte(target, BYTE_ARRAY_BASE_OFFSET + index); } @@ -262,26 +255,6 @@ final class UnsafeUtil { return MEMORY_ACCESSOR.getLong(buffer, BUFFER_ADDRESS_OFFSET); } - /** - * Returns a new {@link String} backed by the given {@code chars}. The char array should not - * be mutated any more after calling this function. - */ - static String moveToString(char[] chars) { - if (STRING_VALUE_OFFSET == -1) { - // In the off-chance that this JDK does not implement String as we'd expect, just do a copy. - return new String(chars); - } - final String str; - try { - str = (String) UNSAFE.allocateInstance(String.class); - } catch (InstantiationException e) { - // This should never happen, but return a copy as a fallback just in case. - return new String(chars); - } - putObject(str, STRING_VALUE_OFFSET, chars); - return str; - } - static Object getStaticObject(Field field) { return MEMORY_ACCESSOR.getStaticObject(field); } diff --git a/java/core/src/main/java/com/google/protobuf/Utf8.java b/java/core/src/main/java/com/google/protobuf/Utf8.java index 6968abb3..de75fe6b 100644 --- a/java/core/src/main/java/com/google/protobuf/Utf8.java +++ b/java/core/src/main/java/com/google/protobuf/Utf8.java @@ -1474,10 +1474,7 @@ final class Utf8 { } } - if (resultPos < resultArr.length) { - resultArr = Arrays.copyOf(resultArr, resultPos); - } - return UnsafeUtil.moveToString(resultArr); + return new String(resultArr, 0, resultPos); } @Override @@ -1553,10 +1550,7 @@ final class Utf8 { } } - if (resultPos < resultArr.length) { - resultArr = Arrays.copyOf(resultArr, resultPos); - } - return UnsafeUtil.moveToString(resultArr); + return new String(resultArr, 0, resultPos); } @Override diff --git a/java/core/src/test/java/com/google/protobuf/GeneratedMessageTest.java b/java/core/src/test/java/com/google/protobuf/GeneratedMessageTest.java index c9ebe7f5..4021f5ab 100644 --- a/java/core/src/test/java/com/google/protobuf/GeneratedMessageTest.java +++ b/java/core/src/test/java/com/google/protobuf/GeneratedMessageTest.java @@ -32,6 +32,7 @@ package com.google.protobuf; import com.google.protobuf.Descriptors.Descriptor; import com.google.protobuf.Descriptors.FieldDescriptor; +import com.google.protobuf.Int32Value; import com.google.protobuf.test.UnittestImport; import protobuf_unittest.EnumWithNoOuter; import protobuf_unittest.MessageWithNoOuter; @@ -853,6 +854,75 @@ public class GeneratedMessageTest extends TestCase { assertEquals(expected, actual); } + public void testDeserializeWithoutClassField() throws Exception { + // serialized form for version <=3.6.0 + // just includes messageClassName and asBytes + + // Int32Value.newBuilder().setValue(123).build() + byte[] int32ValueBytes = new byte[]{ + -84, -19, 0, 5, 115, 114, 0, 55, 99, 111, 109, 46, 103, 111, 111, + 103, 108, 101, 46, 112, 114, 111, 116, 111, 98, 117, 102, 46, 71, + 101, 110, 101, 114, 97, 116, 101, 100, 77, 101, 115, 115, 97, 103, + 101, 76, 105, 116, 101, 36, 83, 101, 114, 105, 97, 108, 105, 122, + 101, 100, 70, 111, 114, 109, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 2, 91, + 0, 7, 97, 115, 66, 121, 116, 101, 115, 116, 0, 2, 91, 66, 76, 0, + 16, 109, 101, 115, 115, 97, 103, 101, 67, 108, 97, 115, 115, 78, + 97, 109, 101, 116, 0, 18, 76, 106, 97, 118, 97, 47, 108, 97, 110, + 103, 47, 83, 116, 114, 105, 110, 103, 59, 120, 112, 117, 114, 0, + 2, 91, 66, -84, -13, 23, -8, 6, 8, 84, -32, 2, 0, 0, 120, 112, 0, + 0, 0, 2, 8, 123, 116, 0, 30, 99, 111, 109, 46, 103, 111, 111, 103, + 108, 101, 46, 112, 114, 111, 116, 111, 98, 117, 102, 46, 73, 110, + 116, 51, 50, 86, 97, 108, 117, 101 + }; + + ByteArrayInputStream bais = new ByteArrayInputStream(int32ValueBytes); + ObjectInputStream in = new ObjectInputStream(bais); + Int32Value int32Value = (Int32Value) in.readObject(); + assertEquals(123, int32Value.getValue()); + } + + public void testDeserializeWithClassField() throws Exception { + // serialized form for version > 3.6.0 + // includes messageClass, messageClassName (for compatibility), and asBytes + + // Int32Value.newBuilder().setValue(123).build() + byte[] int32ValueBytes = new byte[]{ + -84, -19, 0, 5, 115, 114, 0, 55, 99, 111, 109, 46, 103, 111, 111, + 103, 108, 101, 46, 112, 114, 111, 116, 111, 98, 117, 102, 46, 71, + 101, 110, 101, 114, 97, 116, 101, 100, 77, 101, 115, 115, 97, 103, + 101, 76, 105, 116, 101, 36, 83, 101, 114, 105, 97, 108, 105, 122, + 101, 100, 70, 111, 114, 109, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 3, 91, + 0, 7, 97, 115, 66, 121, 116, 101, 115, 116, 0, 2, 91, 66, 76, 0, + 12, 109, 101, 115, 115, 97, 103, 101, 67, 108, 97, 115, 115, 116, + 0, 17, 76, 106, 97, 118, 97, 47, 108, 97, 110, 103, 47, 67, 108, + 97, 115, 115, 59, 76, 0, 16, 109, 101, 115, 115, 97, 103, 101, 67, + 108, 97, 115, 115, 78, 97, 109, 101, 116, 0, 18, 76, 106, 97, 118, + 97, 47, 108, 97, 110, 103, 47, 83, 116, 114, 105, 110, 103, 59, + 120, 112, 117, 114, 0, 2, 91, 66, -84, -13, 23, -8, 6, 8, 84, -32, + 2, 0, 0, 120, 112, 0, 0, 0, 2, 8, 123, 118, 114, 0, 30, 99, 111, + 109, 46, 103, 111, 111, 103, 108, 101, 46, 112, 114, 111, 116, 111, + 98, 117, 102, 46, 73, 110, 116, 51, 50, 86, 97, 108, 117, 101, 0, 0, + 0, 0, 0, 0, 0, 0, 2, 0, 2, 66, 0, 21, 109, 101, 109, 111, 105, 122, + 101, 100, 73, 115, 73, 110, 105, 116, 105, 97, 108, 105, 122, 101, + 100, 73, 0, 6, 118, 97, 108, 117, 101, 95, 120, 114, 0, 38, 99, 111, + 109, 46, 103, 111, 111, 103, 108, 101, 46, 112, 114, 111, 116, 111, + 98, 117, 102, 46, 71, 101, 110, 101, 114, 97, 116, 101, 100, 77, + 101, 115, 115, 97, 103, 101, 86, 51, 0, 0, 0, 0, 0, 0, 0, 1, 2, 0, + 1, 76, 0, 13, 117, 110, 107, 110, 111, 119, 110, 70, 105, 101, 108, + 100, 115, 116, 0, 37, 76, 99, 111, 109, 47, 103, 111, 111, 103, 108, + 101, 47, 112, 114, 111, 116, 111, 98, 117, 102, 47, 85, 110, 107, + 110, 111, 119, 110, 70, 105, 101, 108, 100, 83, 101, 116, 59, 120, + 112, 116, 0, 30, 99, 111, 109, 46, 103, 111, 111, 103, 108, 101, 46, + 112, 114, 111, 116, 111, 98, 117, 102, 46, 73, 110, 116, 51, 50, 86, + 97, 108, 117, 101 + }; + + ByteArrayInputStream bais = new ByteArrayInputStream(int32ValueBytes); + ObjectInputStream in = new ObjectInputStream(bais); + Int32Value int32Value = (Int32Value) in.readObject(); + assertEquals(123, int32Value.getValue()); + } + public void testEnumValues() { assertEquals(TestAllTypes.NestedEnum.BAR_VALUE, TestAllTypes.NestedEnum.BAR.getNumber()); assertEquals(TestAllTypes.NestedEnum.BAZ_VALUE, TestAllTypes.NestedEnum.BAZ.getNumber()); diff --git a/java/util/src/main/java/com/google/protobuf/util/JsonFormat.java b/java/util/src/main/java/com/google/protobuf/util/JsonFormat.java index 7f69ee68..a1e2d9c0 100644 --- a/java/util/src/main/java/com/google/protobuf/util/JsonFormat.java +++ b/java/util/src/main/java/com/google/protobuf/util/JsonFormat.java @@ -50,6 +50,7 @@ import com.google.protobuf.Descriptors.Descriptor; import com.google.protobuf.Descriptors.EnumDescriptor; import com.google.protobuf.Descriptors.EnumValueDescriptor; import com.google.protobuf.Descriptors.FieldDescriptor; +import com.google.protobuf.Descriptors.FieldDescriptor.Type; import com.google.protobuf.Descriptors.FileDescriptor; import com.google.protobuf.Descriptors.OneofDescriptor; import com.google.protobuf.DoubleValue; @@ -1539,7 +1540,11 @@ public class JsonFormat { Object key = parseFieldValue(keyField, new JsonPrimitive(entry.getKey()), entryBuilder); Object value = parseFieldValue(valueField, entry.getValue(), entryBuilder); if (value == null) { - throw new InvalidProtocolBufferException("Map value cannot be null."); + if(ignoringUnknownFields && valueField.getType() == Type.ENUM) { + continue; + } else { + throw new InvalidProtocolBufferException("Map value cannot be null."); + } } entryBuilder.setField(keyField, key); entryBuilder.setField(valueField, value); @@ -1557,8 +1562,12 @@ public class JsonFormat { for (int i = 0; i < array.size(); ++i) { Object value = parseFieldValue(field, array.get(i), builder); if (value == null) { - throw new InvalidProtocolBufferException( - "Repeated field elements cannot be null in field: " + field.getFullName()); + if(ignoringUnknownFields && field.getType() == Type.ENUM) { + continue; + } else { + throw new InvalidProtocolBufferException( + "Repeated field elements cannot be null in field: " + field.getFullName()); + } } builder.addRepeatedField(field, value); } @@ -1748,7 +1757,7 @@ public class JsonFormat { // an exception later. } - if (result == null) { + if (result == null && !ignoringUnknownFields) { throw new InvalidProtocolBufferException( "Invalid enum value: " + value + " for enum type: " + enumDescriptor.getFullName()); } diff --git a/java/util/src/test/java/com/google/protobuf/util/JsonFormatTest.java b/java/util/src/test/java/com/google/protobuf/util/JsonFormatTest.java index 6ef08508..ede8de7a 100644 --- a/java/util/src/test/java/com/google/protobuf/util/JsonFormatTest.java +++ b/java/util/src/test/java/com/google/protobuf/util/JsonFormatTest.java @@ -70,7 +70,6 @@ import java.io.StringReader; import java.math.BigDecimal; import java.math.BigInteger; import java.util.Collections; -import java.util.HashMap; import java.util.HashSet; import java.util.Locale; import java.util.Set; @@ -162,6 +161,10 @@ public class JsonFormatTest extends TestCase { JsonFormat.parser().merge(json, builder); } + private void mergeFromJsonIgnoringUnknownFields(String json, Message.Builder builder) throws IOException { + JsonFormat.parser().ignoringUnknownFields().merge(json, builder); + } + public void testAllFields() throws Exception { TestAllTypes.Builder builder = TestAllTypes.newBuilder(); setAllFields(builder); @@ -669,10 +672,22 @@ public class JsonFormatTest extends TestCase { + "}", builder); fail(); + } catch (InvalidProtocolBufferException e) { // Exception expected. } } + + public void testMapEnumNullValueIsIgnored() throws Exception { + TestMap.Builder builder = TestMap.newBuilder(); + mergeFromJsonIgnoringUnknownFields( + "{\n" + + " \"int32ToEnumMap\": {\"1\": null}\n" + + "}", + builder); + TestMap map = builder.build(); + assertEquals(0, map.getInt32ToEnumMapMap().entrySet().size()); + } public void testParserAcceptNonQuotedObjectKey() throws Exception { TestMap.Builder builder = TestMap.newBuilder(); @@ -1173,7 +1188,40 @@ public class JsonFormatTest extends TestCase { String json = "{\n" + " \"unknownField\": \"XXX\"\n" + "}"; JsonFormat.parser().ignoringUnknownFields().merge(json, builder); } - + + public void testParserIgnoringUnknownEnums() throws Exception { + TestAllTypes.Builder builder = TestAllTypes.newBuilder(); + String json = "{\n" + " \"optionalNestedEnum\": \"XXX\"\n" + "}"; + JsonFormat.parser().ignoringUnknownFields().merge(json, builder); + assertEquals(0, builder.getOptionalNestedEnumValue()); + } + + public void testUnknownEnumMap() throws Exception { + TestMap.Builder builder = TestMap.newBuilder(); + JsonFormat.parser().ignoringUnknownFields().merge( + "{\n" + + " \"int32ToEnumMap\": {1: XXX, 2: FOO}" + + "}", + builder); + + assertEquals(NestedEnum.FOO, builder.getInt32ToEnumMapMap().get(2)); + assertEquals(1, builder.getInt32ToEnumMapMap().size()); + } + + public void testRepeatedUnknownEnum() throws Exception { + TestAllTypes.Builder builder = TestAllTypes.newBuilder(); + JsonFormat.parser().ignoringUnknownFields().merge( + "{\n" + + " \"repeatedNestedEnum\": [XXX, FOO, BAR, BAZ]" + + "}", + builder); + + assertEquals(NestedEnum.FOO, builder.getRepeatedNestedEnum(0)); + assertEquals(NestedEnum.BAR, builder.getRepeatedNestedEnum(1)); + assertEquals(NestedEnum.BAZ, builder.getRepeatedNestedEnum(2)); + assertEquals(3, builder.getRepeatedNestedEnumList().size()); + } + public void testParserIntegerEnumValue() throws Exception { TestAllTypes.Builder actualBuilder = TestAllTypes.newBuilder(); mergeFromJson("{\n" + " \"optionalNestedEnum\": 2\n" + "}", actualBuilder); diff --git a/js/README.md b/js/README.md index ef0d4b19..97fa7e29 100644 --- a/js/README.md +++ b/js/README.md @@ -1,7 +1,7 @@ Protocol Buffers - Google's data interchange format =================================================== -[![Build Status](https://travis-ci.org/google/protobuf.svg?branch=master)](https://travis-ci.org/google/protobuf) +[![Build status](https://storage.googleapis.com/protobuf-kokoro-results/status-badge/linux-javascript.png)](https://fusion.corp.google.com/projectanalysis/current/KOKORO/prod:protobuf%2Fgithub%2Fmaster%2Fubuntu%2Fjavascript%2Fcontinuous) [![Build status](https://storage.googleapis.com/protobuf-kokoro-results/status-badge/macos-javascript.png)](https://fusion.corp.google.com/projectanalysis/current/KOKORO/prod:protobuf%2Fgithub%2Fmaster%2Fmacos%2Fjavascript%2Fcontinuous) Copyright 2008 Google Inc. @@ -144,6 +144,7 @@ Some examples: The `import_style` option is left to the default, which is `closure`. - `--js_out=import_style=commonjs,binary:protos`: this contains the options `import_style=commonjs` and `binary` and outputs to the directory `protos`. + `import_style=commonjs_strict` doesn't expose the output on the global scope. API === diff --git a/js/commonjs/strict_test.js b/js/commonjs/strict_test.js new file mode 100644 index 00000000..46458c10 --- /dev/null +++ b/js/commonjs/strict_test.js @@ -0,0 +1,67 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2016 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. + +// Test suite is written using Jasmine -- see http://jasmine.github.io/ + + + +var googleProtobuf = require('google-protobuf'); +var asserts = require('closure_asserts_commonjs'); +var global = Function('return this')(); + +// Bring asserts into the global namespace. +googleProtobuf.object.extend(global, asserts); + +var test9_pb = require('./test9_pb'); +var test10_pb = require('./test10_pb'); + +describe('Strict test suite', function() { + it('testImportedMessage', function() { + var simple1 = new test9_pb.jspb.exttest.strict.nine.Simple9() + var simple2 = new test9_pb.jspb.exttest.strict.nine.Simple9() + assertObjectEquals(simple1.toObject(), simple2.toObject()); + }); + + it('testGlobalScopePollution', function() { + assertObjectEquals(global.jspb.exttest, undefined); + }); + + describe('with imports', function() { + it('testImportedMessage', function() { + var simple1 = new test10_pb.jspb.exttest.strict.ten.Simple10() + var simple2 = new test10_pb.jspb.exttest.strict.ten.Simple10() + assertObjectEquals(simple1.toObject(), simple2.toObject()); + }); + + it('testGlobalScopePollution', function() { + assertObjectEquals(global.jspb.exttest, undefined); + }); + }); +}); diff --git a/js/gulpfile.js b/js/gulpfile.js index fc9559f9..709c5cf9 100644 --- a/js/gulpfile.js +++ b/js/gulpfile.js @@ -41,6 +41,12 @@ var group2Protos = [ 'commonjs/test7/test7.proto', ]; +var group3Protos = [ + 'test9.proto', + 'test10.proto' +]; + + gulp.task('genproto_well_known_types_closure', function (cb) { exec(protoc + ' --js_out=one_output_file_per_input_file,binary:. -I ../src -I . ' + wellKnownTypes.join(' '), function (err, stdout, stderr) { @@ -112,6 +118,15 @@ gulp.task('genproto_wellknowntypes', function (cb) { cb(err); }); }); +gulp.task('genproto_group3_commonjs_strict', function (cb) { + exec('mkdir -p commonjs_out && ' + protoc + ' --js_out=import_style=commonjs_strict,binary:commonjs_out -I ../src -I commonjs -I . ' + group3Protos.join(' '), + function (err, stdout, stderr) { + console.log(stdout); + console.log(stderr); + cb(err); + }); +}); + function getClosureBuilderCommand(exportsFile, outputFile) { return './node_modules/google-closure-library/closure/bin/build/closurebuilder.py ' + @@ -159,7 +174,7 @@ gulp.task('commonjs_testdeps', function (cb) { }); }); -gulp.task('make_commonjs_out', ['dist', 'genproto_well_known_types_commonjs', 'genproto_group1_commonjs', 'genproto_group2_commonjs', 'genproto_commonjs_wellknowntypes', 'commonjs_asserts', 'commonjs_testdeps'], function (cb) { +gulp.task('make_commonjs_out', ['dist', 'genproto_well_known_types_commonjs', 'genproto_group1_commonjs', 'genproto_group2_commonjs', 'genproto_commonjs_wellknowntypes', 'commonjs_asserts', 'commonjs_testdeps', 'genproto_group3_commonjs_strict'], function (cb) { // TODO(haberman): minify this more aggressively. // Will require proper externs/exports. var cmd = "mkdir -p commonjs_out/binary && mkdir -p commonjs_out/test_node_modules && "; @@ -174,6 +189,7 @@ gulp.task('make_commonjs_out', ['dist', 'genproto_well_known_types_commonjs', 'g exec(cmd + 'cp commonjs/jasmine.json commonjs_out/jasmine.json && ' + 'cp google-protobuf.js commonjs_out/test_node_modules && ' + + 'cp commonjs/strict_test.js commonjs_out/strict_test.js &&' + 'cp commonjs/import_test.js commonjs_out/import_test.js', function (err, stdout, stderr) { console.log(stdout); diff --git a/src/google/protobuf/compiler/js/well_known_types/timestamp.js b/js/test10.proto index b7e43f19..9fa5256c 100644 --- a/src/google/protobuf/compiler/js/well_known_types/timestamp.js +++ b/js/test10.proto @@ -28,26 +28,12 @@ // (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 code will be inserted into generated code for - * google/protobuf/timestamp.proto. */ +syntax = "proto3"; -/** - * Returns a JavaScript 'Date' object corresponding to this Timestamp. - * @return {!Date} - */ -proto.google.protobuf.Timestamp.prototype.toDate = function() { - var seconds = this.getSeconds(); - var nanos = this.getNanos(); +package jspb.exttest.strict.ten; - return new Date((seconds * 1000) + (nanos / 1000000)); -}; +import "test9.proto"; - -/** - * Sets the value of this Timestamp object to be the given Date. - * @param {!Date} value The value to set. - */ -proto.google.protobuf.Timestamp.prototype.fromDate = function(value) { - this.setSeconds(Math.floor(value.getTime() / 1000)); - this.setNanos(value.getMilliseconds() * 1000000); -}; +message Simple10 { + jspb.exttest.strict.nine.Simple9 a = 1; +} diff --git a/src/google/protobuf/compiler/js/well_known_types/any.js b/js/test9.proto index d7ca6e3a..9f680852 100644 --- a/src/google/protobuf/compiler/js/well_known_types/any.js +++ b/js/test9.proto @@ -28,53 +28,12 @@ // (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 code will be inserted into generated code for - * google/protobuf/any.proto. */ +syntax = "proto2"; -/** - * Returns the type name contained in this instance, if any. - * @return {string|undefined} - */ -proto.google.protobuf.Any.prototype.getTypeName = function() { - return this.getTypeUrl().split('/').pop(); -}; +package jspb.exttest.strict.nine; - -/** - * Packs the given message instance into this Any. - * @param {!Uint8Array} serialized The serialized data to pack. - * @param {string} name The type name of this message object. - * @param {string=} opt_typeUrlPrefix the type URL prefix. - */ -proto.google.protobuf.Any.prototype.pack = function(serialized, name, - opt_typeUrlPrefix) { - if (!opt_typeUrlPrefix) { - opt_typeUrlPrefix = 'type.googleapis.com/'; - } - - if (opt_typeUrlPrefix.substr(-1) != '/') { - this.setTypeUrl(opt_typeUrlPrefix + '/' + name); - } else { - this.setTypeUrl(opt_typeUrlPrefix + name); - } - - this.setValue(serialized); -}; - - -/** - * @template T - * Unpacks this Any into the given message object. - * @param {function(Uint8Array):T} deserialize Function that will deserialize - * the binary data properly. - * @param {string} name The expected type name of this message object. - * @return {?T} If the name matched the expected name, returns the deserialized - * object, otherwise returns null. - */ -proto.google.protobuf.Any.prototype.unpack = function(deserialize, name) { - if (this.getTypeName() == name) { - return deserialize(this.getValue_asU8()); - } else { - return null; - } -}; +message Simple9 { + required string a_string = 1; + repeated string a_repeated_string = 2; + optional bool a_boolean = 3; +} diff --git a/kokoro/linux/benchmark/build.sh b/kokoro/linux/benchmark/build.sh index 750c3e5c..3463ba9b 100755 --- a/kokoro/linux/benchmark/build.sh +++ b/kokoro/linux/benchmark/build.sh @@ -27,8 +27,8 @@ cd $oldpwd ./configure CXXFLAGS="-fPIC -O2" make -j8 cd python -python setup.py -q build --cpp_implementation -pip install . +python setup.py build --cpp_implementation +pip install . --user # build and run Python benchmark @@ -41,10 +41,10 @@ echo "benchmarking pure python..." ./python-pure-python-benchmark --json --behavior_prefix="pure-python-benchmark" $datasets >> tmp/python_result.json echo "," >> "tmp/python_result.json" echo "benchmarking python cpp reflection..." -env LD_PRELOAD="$oldpwd/gperftools/.libs/libtcmalloc.so" ./python-cpp-reflection-benchmark --json --behavior_prefix="cpp-reflection-benchmark" $datasets >> tmp/python_result.json +env LD_PRELOAD="$oldpwd/gperftools/.libs/libtcmalloc.so" LD_LIBRARY_PATH="$oldpwd/src/.libs" ./python-cpp-reflection-benchmark --json --behavior_prefix="cpp-reflection-benchmark" $datasets >> tmp/python_result.json echo "," >> "tmp/python_result.json" echo "benchmarking python cpp generated code..." -env LD_PRELOAD="$oldpwd/gperftools/.libs/libtcmalloc.so" ./python-cpp-generated-code-benchmark --json --behavior_prefix="cpp-generated-code-benchmark" $datasets >> tmp/python_result.json +env LD_PRELOAD="$oldpwd/gperftools/.libs/libtcmalloc.so" LD_LIBRARY_PATH="$oldpwd/src/.libs" ./python-cpp-generated-code-benchmark --json --behavior_prefix="cpp-generated-code-benchmark" $datasets >> tmp/python_result.json echo "]" >> "tmp/python_result.json" cd $oldpwd @@ -52,6 +52,11 @@ cd $oldpwd ./configure make clean && make -j8 +# build Java protobuf +cd java +mvn package +cd .. + # build CPP benchmark cd benchmarks mv tmp/python_result.json . && make clean && make -j8 cpp-benchmark && mv python_result.json tmp @@ -81,7 +86,7 @@ echo "benchmarking java..." # upload result to bq make python_add_init -python util/run_and_upload.py -cpp="../tmp/cpp_result.json" -java="../tmp/java_result.json" \ +env LD_LIBRARY_PATH="$oldpwd/src/.libs" python -m util.result_uploader -cpp="../tmp/cpp_result.json" -java="../tmp/java_result.json" \ -python="../tmp/python_result.json" -go="../tmp/go_result.txt" cd $oldpwd diff --git a/kokoro/linux/prepare_build_linux_rc b/kokoro/linux/prepare_build_linux_rc index f64ea952..d9b3bec3 100644 --- a/kokoro/linux/prepare_build_linux_rc +++ b/kokoro/linux/prepare_build_linux_rc @@ -7,7 +7,7 @@ sudo sh -c 'echo "deb [arch=amd64] https://packages.microsoft.com/repos/microsof sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys EB3E94ADBE1229CF sudo apt-get update # We use the .NET Core SDK 2.x to build... -sudo apt-get install -y dotnet-sdk-2.0.3 +sudo apt-get install -y dotnet-sdk-2.1.3 # But we also need the 1.x framework to test against, as we # target netstandard1.x sudo apt-get install -y dotnet-sharedframework-microsoft.netcore.app-1.0.5 diff --git a/kokoro/macos/jruby/build.sh b/kokoro/macos/jruby/build.sh deleted file mode 100755 index c82eaebf..00000000 --- a/kokoro/macos/jruby/build.sh +++ /dev/null @@ -1,11 +0,0 @@ -#!/bin/bash -# -# Build file to set up and run tests - -# Change to repo root -cd $(dirname $0)/../../.. - -# Prepare worker environment to run tests -source kokoro/macos/prepare_build_macos_rc - -./tests.sh jruby diff --git a/kokoro/macos/jruby/continuous.cfg b/kokoro/macos/jruby/continuous.cfg deleted file mode 100644 index f1310fd3..00000000 --- a/kokoro/macos/jruby/continuous.cfg +++ /dev/null @@ -1,5 +0,0 @@ -# Config file for running tests in Kokoro - -# Location of the build script in repository -build_file: "protobuf/kokoro/macos/jruby/build.sh" -timeout_mins: 1440 diff --git a/kokoro/macos/jruby/presubmit.cfg b/kokoro/macos/jruby/presubmit.cfg deleted file mode 100644 index f1310fd3..00000000 --- a/kokoro/macos/jruby/presubmit.cfg +++ /dev/null @@ -1,5 +0,0 @@ -# Config file for running tests in Kokoro - -# Location of the build script in repository -build_file: "protobuf/kokoro/macos/jruby/build.sh" -timeout_mins: 1440 diff --git a/kokoro/release/csharp/windows/build_nuget.bat b/kokoro/release/csharp/windows/build_nuget.bat new file mode 100644 index 00000000..5da1e136 --- /dev/null +++ b/kokoro/release/csharp/windows/build_nuget.bat @@ -0,0 +1,5 @@ +@rem enter repo root +cd /d %~dp0\..\..\..\.. + +cd csharp +call build_packages.bat diff --git a/kokoro/release/csharp/windows/release.cfg b/kokoro/release/csharp/windows/release.cfg new file mode 100644 index 00000000..f508c65b --- /dev/null +++ b/kokoro/release/csharp/windows/release.cfg @@ -0,0 +1,11 @@ +# Config file for running tests in Kokoro + +# Location of the build script in repository +build_file: "protobuf/kokoro/release/csharp/windows/build_nuget.bat" +timeout_mins: 60 + +action { + define_artifacts { + regex: "**/*.nupkg" + } +} diff --git a/objectivec/GPBDescriptor.h b/objectivec/GPBDescriptor.h index 651f4de0..292bce13 100644 --- a/objectivec/GPBDescriptor.h +++ b/objectivec/GPBDescriptor.h @@ -223,9 +223,12 @@ typedef NS_ENUM(uint8_t, GPBFieldType) { /** * Returns the enum value name for the given raw enum. * + * Note that there can be more than one name corresponding to a given value + * if the allow_alias option is used. + * * @param number The raw enum value. * - * @return The name of the enum value passed, or nil if not valid. + * @return The first name that matches the enum value passed, or nil if not valid. **/ - (nullable NSString *)enumNameForValue:(int32_t)number; @@ -244,7 +247,7 @@ typedef NS_ENUM(uint8_t, GPBFieldType) { * * @param number The raw enum value. * - * @return The text format name for the raw enum value, or nil if not valid. + * @return The first text format name which matches the enum value, or nil if not valid. **/ - (nullable NSString *)textFormatNameForValue:(int32_t)number; @@ -258,6 +261,33 @@ typedef NS_ENUM(uint8_t, GPBFieldType) { **/ - (BOOL)getValue:(nullable int32_t *)outValue forEnumTextFormatName:(NSString *)textFormatName; +/** + * Gets the number of defined enum names. + * + * @return Count of the number of enum names, including any aliases. + */ +@property(nonatomic, readonly) uint32_t enumNameCount; + +/** + * Gets the enum name corresponding to the given index. + * + * @param index Index into the available names. The defined range is from 0 + * to self.enumNameCount - 1. + * + * @returns The enum name at the given index, or nil if the index is out of range. + */ +- (nullable NSString *)getEnumNameForIndex:(uint32_t)index; + +/** + * Gets the enum text format name corresponding to the given index. + * + * @param index Index into the available names. The defined range is from 0 + * to self.enumNameCount - 1. + * + * @returns The text format name at the given index, or nil if the index is out of range. + */ +- (nullable NSString *)getEnumTextFormatNameForIndex:(uint32_t)index; + @end /** diff --git a/objectivec/GPBDescriptor.m b/objectivec/GPBDescriptor.m index 4b39c63b..ad46ef4f 100644 --- a/objectivec/GPBDescriptor.m +++ b/objectivec/GPBDescriptor.m @@ -830,13 +830,9 @@ uint32_t GPBFieldAlternateTag(GPBFieldDescriptor *self) { } - (NSString *)enumNameForValue:(int32_t)number { - if (nameOffsets_ == NULL) [self calcValueNameOffsets]; - for (uint32_t i = 0; i < valueCount_; ++i) { if (values_[i] == number) { - const char *valueName = valueNames_ + nameOffsets_[i]; - NSString *fullName = [NSString stringWithFormat:@"%@_%s", name_, valueName]; - return fullName; + return [self getEnumNameForIndex:i]; } } return nil; @@ -886,8 +882,6 @@ uint32_t GPBFieldAlternateTag(GPBFieldDescriptor *self) { } - (NSString *)textFormatNameForValue:(int32_t)number { - if (nameOffsets_ == NULL) [self calcValueNameOffsets]; - // Find the EnumValue descriptor and its index. BOOL foundIt = NO; uint32_t valueDescriptorIndex; @@ -902,16 +896,39 @@ uint32_t GPBFieldAlternateTag(GPBFieldDescriptor *self) { if (!foundIt) { return nil; } + return [self getEnumTextFormatNameForIndex:valueDescriptorIndex]; +} + +- (uint32_t)enumNameCount { + return valueCount_; +} + +- (NSString *)getEnumNameForIndex:(uint32_t)index { + if (nameOffsets_ == NULL) [self calcValueNameOffsets]; + if (index >= valueCount_) { + return nil; + } + const char *valueName = valueNames_ + nameOffsets_[index]; + NSString *fullName = [NSString stringWithFormat:@"%@_%s", name_, valueName]; + return fullName; +} + +- (NSString *)getEnumTextFormatNameForIndex:(uint32_t)index { + if (nameOffsets_ == NULL) [self calcValueNameOffsets]; + + if (index >= valueCount_) { + return nil; + } NSString *result = nil; // Naming adds an underscore between enum name and value name, skip that also. - const char *valueName = valueNames_ + nameOffsets_[valueDescriptorIndex]; + const char *valueName = valueNames_ + nameOffsets_[index]; NSString *shortName = @(valueName); // See if it is in the map of special format handling. if (extraTextFormatInfo_) { result = GPBDecodeTextFormatName(extraTextFormatInfo_, - (int32_t)valueDescriptorIndex, shortName); + (int32_t)index, shortName); } // Logic here needs to match what objectivec_enum.cc does in the proto // compiler. diff --git a/objectivec/README.md b/objectivec/README.md index a02df33f..528f5472 100644 --- a/objectivec/README.md +++ b/objectivec/README.md @@ -1,7 +1,7 @@ Protocol Buffers - Google's data interchange format =================================================== -[![Build Status](https://travis-ci.org/google/protobuf.svg?branch=master)](https://travis-ci.org/google/protobuf) +[![Build status](https://storage.googleapis.com/protobuf-kokoro-results/status-badge/macos-objectivec_cocoapods_integration.png)](https://fusion.corp.google.com/projectanalysis/current/KOKORO/prod:protobuf%2Fgithub%2Fmaster%2Fmacos%2Fobjectivec_cocoapods_integration%2Fcontinuous) [![Build status](https://storage.googleapis.com/protobuf-kokoro-results/status-badge/macos-objectivec_ios_debug.png)](https://fusion.corp.google.com/projectanalysis/current/KOKORO/prod:protobuf%2Fgithub%2Fmaster%2Fmacos%2Fobjectivec_ios_debug%2Fcontinuous) [![Build status](https://storage.googleapis.com/protobuf-kokoro-results/status-badge/macos-objectivec_ios_release.png)](https://fusion.corp.google.com/projectanalysis/current/KOKORO/prod:protobuf%2Fgithub%2Fmaster%2Fmacos%2Fobjectivec_ios_release%2Fcontinuous) [![Build status](https://storage.googleapis.com/protobuf-kokoro-results/status-badge/macos-objectivec_osx.png)](https://fusion.corp.google.com/projectanalysis/current/KOKORO/prod:protobuf%2Fgithub%2Fmaster%2Fmacos%2Fobjectivec_osx%2Fcontinuous) Copyright 2008 Google Inc. @@ -20,9 +20,10 @@ The Objective C implementation requires: Installation ------------ -The full distribution pulled from github includes the sources for both the -compiler (protoc) and the runtime (this directory). To build the compiler -and run the runtime tests, you can use: +The distribution pulled from github includes the sources for both the +compiler (protoc) and the runtime (this directory). After cloning the distribution +and needed submodules ([see the src directory's README](../src/README.md)), +to build the compiler and run the runtime tests, you can use: $ objectivec/DevTools/full_mac_build.sh diff --git a/objectivec/Tests/GPBDescriptorTests.m b/objectivec/Tests/GPBDescriptorTests.m index 199ea655..d47cc30f 100644 --- a/objectivec/Tests/GPBDescriptorTests.m +++ b/objectivec/Tests/GPBDescriptorTests.m @@ -190,6 +190,63 @@ XCTAssertFalse([descriptor getValue:&value forEnumTextFormatName:@"Unknown"]); } +- (void)testEnumDescriptorIntrospection { + GPBEnumDescriptor *descriptor = TestAllTypes_NestedEnum_EnumDescriptor(); + + XCTAssertEqual(descriptor.enumNameCount, 4U); + XCTAssertEqualObjects([descriptor getEnumNameForIndex:0], + @"TestAllTypes_NestedEnum_Foo"); + XCTAssertEqualObjects([descriptor getEnumTextFormatNameForIndex:0], @"FOO"); + XCTAssertEqualObjects([descriptor getEnumNameForIndex:1], + @"TestAllTypes_NestedEnum_Bar"); + XCTAssertEqualObjects([descriptor getEnumTextFormatNameForIndex:1], @"BAR"); + XCTAssertEqualObjects([descriptor getEnumNameForIndex:2], + @"TestAllTypes_NestedEnum_Baz"); + XCTAssertEqualObjects([descriptor getEnumTextFormatNameForIndex:2], @"BAZ"); + XCTAssertEqualObjects([descriptor getEnumNameForIndex:3], + @"TestAllTypes_NestedEnum_Neg"); + XCTAssertEqualObjects([descriptor getEnumTextFormatNameForIndex:3], @"NEG"); +} + +- (void)testEnumDescriptorIntrospectionWithAlias { + GPBEnumDescriptor *descriptor = TestEnumWithDupValue_EnumDescriptor(); + NSString *enumName; + int32_t value; + + XCTAssertEqual(descriptor.enumNameCount, 5U); + + enumName = [descriptor getEnumNameForIndex:0]; + XCTAssertEqualObjects(enumName, @"TestEnumWithDupValue_Foo1"); + XCTAssertTrue([descriptor getValue:&value forEnumName:enumName]); + XCTAssertEqual(value, 1); + XCTAssertEqualObjects([descriptor getEnumTextFormatNameForIndex:0], @"FOO1"); + + enumName = [descriptor getEnumNameForIndex:1]; + XCTAssertEqualObjects(enumName, @"TestEnumWithDupValue_Bar1"); + XCTAssertTrue([descriptor getValue:&value forEnumName:enumName]); + XCTAssertEqual(value, 2); + XCTAssertEqualObjects([descriptor getEnumTextFormatNameForIndex:1], @"BAR1"); + + enumName = [descriptor getEnumNameForIndex:2]; + XCTAssertEqualObjects(enumName, @"TestEnumWithDupValue_Baz"); + XCTAssertTrue([descriptor getValue:&value forEnumName:enumName]); + XCTAssertEqual(value, 3); + XCTAssertEqualObjects([descriptor getEnumTextFormatNameForIndex:2], @"BAZ"); + + enumName = [descriptor getEnumNameForIndex:3]; + XCTAssertEqualObjects(enumName, @"TestEnumWithDupValue_Foo2"); + XCTAssertTrue([descriptor getValue:&value forEnumName:enumName]); + XCTAssertEqual(value, 1); + XCTAssertEqualObjects([descriptor getEnumTextFormatNameForIndex:3], @"FOO2"); + + enumName = [descriptor getEnumNameForIndex:4]; + XCTAssertEqualObjects(enumName, @"TestEnumWithDupValue_Bar2"); + XCTAssertTrue([descriptor getValue:&value forEnumName:enumName]); + XCTAssertEqual(value, 2); + XCTAssertEqualObjects([descriptor getEnumTextFormatNameForIndex:4], @"BAR2"); + +} + - (void)testEnumValueValidator { GPBDescriptor *descriptor = [TestAllTypes descriptor]; GPBFieldDescriptor *fieldDescriptor = diff --git a/objectivec/Tests/GPBTestUtilities.m b/objectivec/Tests/GPBTestUtilities.m index ebccaac9..0362bdde 100644 --- a/objectivec/Tests/GPBTestUtilities.m +++ b/objectivec/Tests/GPBTestUtilities.m @@ -85,7 +85,7 @@ const uint32_t kGPBDefaultRepeatCount = 2; NSLog(@"Wrote data file to %@", path); #else // Kill off the unused variable warning. - dataToWrite = dataToWrite; + (void)dataToWrite; #endif return data; } diff --git a/php/README.md b/php/README.md index da7884ea..967250a7 100644 --- a/php/README.md +++ b/php/README.md @@ -36,7 +36,7 @@ To install the c extension, the following tools are needed: On Ubuntu, you can install them with: ``` -sudo apt-get install php-pear php5-dev autoconf automake libtool make gcc +sudo apt-get install -y php-pear php5-dev autoconf automake libtool make gcc ``` On other platforms, please use the corresponding package managing tool to install them before proceeding. diff --git a/php/composer.json b/php/composer.json index 34e0447c..20f6a45e 100644 --- a/php/composer.json +++ b/php/composer.json @@ -9,13 +9,20 @@ "php": ">=5.5.0" }, "require-dev": { - "phpunit/phpunit": ">=4.8.0" + "phpunit/phpunit": "^5|^4.8.0" }, "autoload": { "psr-4": { "Google\\Protobuf\\": "src/Google/Protobuf", - "GPBMetadata\\Google\\Protobuf\\": "src/GPBMetadata/Google/Protobuf", + "GPBMetadata\\Google\\Protobuf\\": "src/GPBMetadata/Google/Protobuf" + } + }, + "autoload-dev": { + "psr-4": { "": "tests/generated" } + }, + "scripts": { + "test": "(cd tests && rm -rf generated && mkdir -p generated && ../../src/protoc --php_out=generated proto/empty/echo.proto proto/test.proto proto/test_include.proto proto/test_no_namespace.proto proto/test_prefix.proto proto/test_php_namespace.proto proto/test_empty_php_namespace.proto proto/test_reserved_enum_lower.proto proto/test_reserved_enum_upper.proto proto/test_reserved_enum_value_lower.proto proto/test_reserved_enum_value_upper.proto proto/test_reserved_message_lower.proto proto/test_reserved_message_upper.proto proto/test_service.proto proto/test_service_namespace.proto proto/test_descriptors.proto) && (cd ../src && ./protoc --php_out=../php/tests/generated -I../php/tests -I. ../php/tests/proto/test_import_descriptor_proto.proto) && vendor/bin/phpunit" } } diff --git a/php/ext/google/protobuf/encode_decode.c b/php/ext/google/protobuf/encode_decode.c index de13dfa8..899b99f0 100644 --- a/php/ext/google/protobuf/encode_decode.c +++ b/php/ext/google/protobuf/encode_decode.c @@ -1587,8 +1587,11 @@ PHP_METHOD(Message, mergeFromJsonString) { char *data = NULL; PHP_PROTO_SIZE data_len; + zend_bool ignore_json_unknown = false; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &data, &data_len) == + if (zend_parse_parameters( + ZEND_NUM_ARGS() TSRMLS_CC, "s|b", &data, &data_len, + &ignore_json_unknown) == FAILURE) { return; } @@ -1607,7 +1610,7 @@ PHP_METHOD(Message, mergeFromJsonString) { stackenv_init(&se, "Error occurred during parsing: %s"); upb_sink_reset(&sink, get_fill_handlers(desc), msg); - parser = upb_json_parser_create(&se.env, method, &sink); + parser = upb_json_parser_create(&se.env, method, &sink, ignore_json_unknown); upb_bufsrc_putbuf(data, data_len, upb_json_parser_input(parser)); stackenv_uninit(&se); diff --git a/php/ext/google/protobuf/message.c b/php/ext/google/protobuf/message.c index 76b97eef..0efe090d 100644 --- a/php/ext/google/protobuf/message.c +++ b/php/ext/google/protobuf/message.c @@ -30,6 +30,7 @@ #include <php.h> #include <stdlib.h> +#include <inttypes.h> #include "protobuf.h" #include "utf8.h" @@ -1251,28 +1252,62 @@ PHP_METHOD(Timestamp, fromDateTime) { return; } - // Get timestamp from Datetime object. - zval retval; - zval function_name; - int64_t timestamp; + int64_t timestamp_seconds; + { + zval retval; + zval function_name; #if PHP_MAJOR_VERSION < 7 - INIT_ZVAL(retval); - INIT_ZVAL(function_name); + INIT_ZVAL(retval); + INIT_ZVAL(function_name); #endif - PHP_PROTO_ZVAL_STRING(&function_name, "date_timestamp_get", 1); + PHP_PROTO_ZVAL_STRING(&function_name, "date_timestamp_get", 1); - if (call_user_function(EG(function_table), NULL, &function_name, &retval, 1, - ZVAL_PTR_TO_CACHED_PTR(datetime) TSRMLS_CC) == FAILURE) { - zend_error(E_ERROR, "Cannot get timestamp from DateTime."); - return; + if (call_user_function(EG(function_table), NULL, &function_name, &retval, 1, + ZVAL_PTR_TO_CACHED_PTR(datetime) TSRMLS_CC) == FAILURE) { + zend_error(E_ERROR, "Cannot get timestamp from DateTime."); + return; + } + + protobuf_convert_to_int64(&retval, ×tamp_seconds); + + zval_dtor(&retval); + zval_dtor(&function_name); } - protobuf_convert_to_int64(&retval, ×tamp); + int64_t timestamp_micros; + { + zval retval; + zval function_name; + zval format_string; - zval_dtor(&retval); - zval_dtor(&function_name); +#if PHP_MAJOR_VERSION < 7 + INIT_ZVAL(retval); + INIT_ZVAL(function_name); + INIT_ZVAL(format_string); +#endif + + PHP_PROTO_ZVAL_STRING(&function_name, "date_format", 1); + PHP_PROTO_ZVAL_STRING(&format_string, "u", 1); + + CACHED_VALUE params[2] = { + ZVAL_PTR_TO_CACHED_VALUE(datetime), + ZVAL_TO_CACHED_VALUE(format_string), + }; + + if (call_user_function(EG(function_table), NULL, &function_name, &retval, + ARRAY_SIZE(params), params TSRMLS_CC) == FAILURE) { + zend_error(E_ERROR, "Cannot format DateTime."); + return; + } + + protobuf_convert_to_int64(&retval, ×tamp_micros); + + zval_dtor(&retval); + zval_dtor(&function_name); + zval_dtor(&format_string); + } // Set seconds MessageHeader* self = UNBOX(MessageHeader, getThis()); @@ -1280,13 +1315,13 @@ PHP_METHOD(Timestamp, fromDateTime) { upb_msgdef_ntofz(self->descriptor->msgdef, "seconds"); void* storage = message_data(self); void* memory = slot_memory(self->descriptor->layout, storage, field); - *(int64_t*)memory = timestamp; + *(int64_t*)memory = timestamp_seconds; // Set nanos field = upb_msgdef_ntofz(self->descriptor->msgdef, "nanos"); storage = message_data(self); memory = slot_memory(self->descriptor->layout, storage, field); - *(int32_t*)memory = 0; + *(int32_t*)memory = timestamp_micros * 1000; RETURN_NULL(); } @@ -1305,38 +1340,41 @@ PHP_METHOD(Timestamp, toDateTime) { memory = slot_memory(self->descriptor->layout, storage, field); int32_t nanos = *(int32_t*)memory; - // Get formated time string. - char formated_time[50]; - time_t raw_time = seconds; - struct tm *utc_time = gmtime(&raw_time); - strftime(formated_time, sizeof(formated_time), "%Y-%m-%dT%H:%M:%SUTC", - utc_time); + // Get formatted time string. + char formatted_time[32]; + snprintf(formatted_time, sizeof(formatted_time), "%" PRId64 ".%06" PRId32, + seconds, nanos / 1000); // Create Datetime object. zval datetime; - zval formated_time_php; zval function_name; - int64_t timestamp = 0; + zval format_string; + zval formatted_time_php; #if PHP_MAJOR_VERSION < 7 INIT_ZVAL(function_name); - INIT_ZVAL(formated_time_php); + INIT_ZVAL(format_string); + INIT_ZVAL(formatted_time_php); #endif - PHP_PROTO_ZVAL_STRING(&function_name, "date_create", 1); - PHP_PROTO_ZVAL_STRING(&formated_time_php, formated_time, 1); + PHP_PROTO_ZVAL_STRING(&function_name, "date_create_from_format", 1); + PHP_PROTO_ZVAL_STRING(&format_string, "U.u", 1); + PHP_PROTO_ZVAL_STRING(&formatted_time_php, formatted_time, 1); - CACHED_VALUE params[1] = {ZVAL_TO_CACHED_VALUE(formated_time_php)}; + CACHED_VALUE params[2] = { + ZVAL_TO_CACHED_VALUE(format_string), + ZVAL_TO_CACHED_VALUE(formatted_time_php), + }; - if (call_user_function(EG(function_table), NULL, - &function_name, &datetime, 1, - params TSRMLS_CC) == FAILURE) { + if (call_user_function(EG(function_table), NULL, &function_name, &datetime, + ARRAY_SIZE(params), params TSRMLS_CC) == FAILURE) { zend_error(E_ERROR, "Cannot create DateTime."); return; } - zval_dtor(&formated_time_php); zval_dtor(&function_name); + zval_dtor(&format_string); + zval_dtor(&formatted_time_php); #if PHP_MAJOR_VERSION < 7 zval* datetime_ptr = &datetime; diff --git a/php/ext/google/protobuf/protobuf.h b/php/ext/google/protobuf/protobuf.h index 48072a4f..9cb36dc2 100644 --- a/php/ext/google/protobuf/protobuf.h +++ b/php/ext/google/protobuf/protobuf.h @@ -42,6 +42,10 @@ #define MAX_LENGTH_OF_INT64 20 #define SIZEOF_INT64 8 +/* From Chromium. */ +#define ARRAY_SIZE(x) \ + ((sizeof(x)/sizeof(0[x])) / ((size_t)(!(sizeof(x) % sizeof(0[x]))))) + // ----------------------------------------------------------------------------- // PHP7 Wrappers // ---------------------------------------------------------------------------- diff --git a/php/ext/google/protobuf/upb.c b/php/ext/google/protobuf/upb.c index e01f3bfd..4644430e 100644 --- a/php/ext/google/protobuf/upb.c +++ b/php/ext/google/protobuf/upb.c @@ -14344,6 +14344,9 @@ struct upb_json_parser { /* Intermediate result of parsing a unicode escape sequence. */ uint32_t digit; + + /* Whether to proceed if unknown field is met. */ + bool ignore_json_unknown; }; struct upb_json_parsermethod { @@ -14864,6 +14867,11 @@ static bool end_number(upb_json_parser *p, const char *ptr) { return false; } + if (p->top->f == NULL) { + multipart_end(p); + return true; + } + return parse_number(p, false); } @@ -15016,6 +15024,10 @@ static bool parse_number(upb_json_parser *p, bool is_quoted) { static bool parser_putbool(upb_json_parser *p, bool val) { bool ok; + if (p->top->f == NULL) { + return true; + } + if (upb_fielddef_type(p->top->f) != UPB_TYPE_BOOL) { upb_status_seterrf(&p->status, "Boolean value specified for non-bool field: %s", @@ -15031,7 +15043,10 @@ static bool parser_putbool(upb_json_parser *p, bool val) { } static bool start_stringval(upb_json_parser *p) { - UPB_ASSERT(p->top->f); + if (p->top->f == NULL) { + multipart_startaccum(p); + return true; + } if (upb_fielddef_isstring(p->top->f)) { upb_jsonparser_frame *inner; @@ -15082,6 +15097,11 @@ static bool start_stringval(upb_json_parser *p) { static bool end_stringval(upb_json_parser *p) { bool ok = true; + if (p->top->f == NULL) { + multipart_end(p); + return true; + } + switch (upb_fielddef_type(p->top->f)) { case UPB_TYPE_BYTES: if (!base64_push(p, getsel_for_handlertype(p, UPB_HANDLER_STRING), @@ -15273,6 +15293,10 @@ static bool handle_mapentry(upb_json_parser *p) { static bool end_membername(upb_json_parser *p) { UPB_ASSERT(!p->top->f); + if (!p->top->m) { + return true; + } + if (p->top->is_map) { return handle_mapentry(p); } else { @@ -15285,9 +15309,10 @@ static bool end_membername(upb_json_parser *p) { multipart_end(p); return true; + } else if (p->ignore_json_unknown) { + multipart_end(p); + return true; } else { - /* TODO(haberman): Ignore unknown fields if requested/configured to do - * so. */ upb_status_seterrf(&p->status, "No such field: %.*s\n", (int)len, buf); upb_env_reporterror(p->env, &p->status); return false; @@ -15319,7 +15344,18 @@ static void end_member(upb_json_parser *p) { } static bool start_subobject(upb_json_parser *p) { - UPB_ASSERT(p->top->f); + if (p->top->f == NULL) { + upb_jsonparser_frame *inner; + if (!check_stack(p)) return false; + + inner = p->top + 1; + inner->m = NULL; + inner->f = NULL; + inner->is_map = false; + inner->is_mapentry = false; + p->top = inner; + return true; + } if (upb_fielddef_ismap(p->top->f)) { upb_jsonparser_frame *inner; @@ -15378,9 +15414,12 @@ static void end_subobject(upb_json_parser *p) { upb_sink_endseq(&p->top->sink, sel); } else { upb_selector_t sel; + bool is_unknown = p->top->m == NULL; p->top--; - sel = getsel_for_handlertype(p, UPB_HANDLER_ENDSUBMSG); - upb_sink_endsubmsg(&p->top->sink, sel); + if (!is_unknown) { + sel = getsel_for_handlertype(p, UPB_HANDLER_ENDSUBMSG); + upb_sink_endsubmsg(&p->top->sink, sel); + } } } @@ -15462,11 +15501,11 @@ static void end_object(upb_json_parser *p) { * final state once, when the closing '"' is seen. */ -#line 1310 "upb/json/parser.rl" +#line 1349 "upb/json/parser.rl" -#line 1222 "upb/json/parser.c" +#line 1261 "upb/json/parser.c" static const char _json_actions[] = { 0, 1, 0, 1, 2, 1, 3, 1, 5, 1, 6, 1, 7, 1, 8, 1, @@ -15615,7 +15654,7 @@ static const int json_en_value_machine = 27; static const int json_en_main = 1; -#line 1313 "upb/json/parser.rl" +#line 1352 "upb/json/parser.rl" size_t parse(void *closure, const void *hd, const char *buf, size_t size, const upb_bufhandle *handle) { @@ -15637,7 +15676,7 @@ size_t parse(void *closure, const void *hd, const char *buf, size_t size, capture_resume(parser, buf); -#line 1393 "upb/json/parser.c" +#line 1432 "upb/json/parser.c" { int _klen; unsigned int _trans; @@ -15712,118 +15751,118 @@ _match: switch ( *_acts++ ) { case 0: -#line 1225 "upb/json/parser.rl" +#line 1264 "upb/json/parser.rl" { p--; {cs = stack[--top]; goto _again;} } break; case 1: -#line 1226 "upb/json/parser.rl" +#line 1265 "upb/json/parser.rl" { p--; {stack[top++] = cs; cs = 10; goto _again;} } break; case 2: -#line 1230 "upb/json/parser.rl" +#line 1269 "upb/json/parser.rl" { start_text(parser, p); } break; case 3: -#line 1231 "upb/json/parser.rl" +#line 1270 "upb/json/parser.rl" { CHECK_RETURN_TOP(end_text(parser, p)); } break; case 4: -#line 1237 "upb/json/parser.rl" +#line 1276 "upb/json/parser.rl" { start_hex(parser); } break; case 5: -#line 1238 "upb/json/parser.rl" +#line 1277 "upb/json/parser.rl" { hexdigit(parser, p); } break; case 6: -#line 1239 "upb/json/parser.rl" +#line 1278 "upb/json/parser.rl" { CHECK_RETURN_TOP(end_hex(parser)); } break; case 7: -#line 1245 "upb/json/parser.rl" +#line 1284 "upb/json/parser.rl" { CHECK_RETURN_TOP(escape(parser, p)); } break; case 8: -#line 1251 "upb/json/parser.rl" +#line 1290 "upb/json/parser.rl" { p--; {cs = stack[--top]; goto _again;} } break; case 9: -#line 1254 "upb/json/parser.rl" +#line 1293 "upb/json/parser.rl" { {stack[top++] = cs; cs = 19; goto _again;} } break; case 10: -#line 1256 "upb/json/parser.rl" +#line 1295 "upb/json/parser.rl" { p--; {stack[top++] = cs; cs = 27; goto _again;} } break; case 11: -#line 1261 "upb/json/parser.rl" +#line 1300 "upb/json/parser.rl" { start_member(parser); } break; case 12: -#line 1262 "upb/json/parser.rl" +#line 1301 "upb/json/parser.rl" { CHECK_RETURN_TOP(end_membername(parser)); } break; case 13: -#line 1265 "upb/json/parser.rl" +#line 1304 "upb/json/parser.rl" { end_member(parser); } break; case 14: -#line 1271 "upb/json/parser.rl" +#line 1310 "upb/json/parser.rl" { start_object(parser); } break; case 15: -#line 1274 "upb/json/parser.rl" +#line 1313 "upb/json/parser.rl" { end_object(parser); } break; case 16: -#line 1280 "upb/json/parser.rl" +#line 1319 "upb/json/parser.rl" { CHECK_RETURN_TOP(start_array(parser)); } break; case 17: -#line 1284 "upb/json/parser.rl" +#line 1323 "upb/json/parser.rl" { end_array(parser); } break; case 18: -#line 1289 "upb/json/parser.rl" +#line 1328 "upb/json/parser.rl" { start_number(parser, p); } break; case 19: -#line 1290 "upb/json/parser.rl" +#line 1329 "upb/json/parser.rl" { CHECK_RETURN_TOP(end_number(parser, p)); } break; case 20: -#line 1292 "upb/json/parser.rl" +#line 1331 "upb/json/parser.rl" { CHECK_RETURN_TOP(start_stringval(parser)); } break; case 21: -#line 1293 "upb/json/parser.rl" +#line 1332 "upb/json/parser.rl" { CHECK_RETURN_TOP(end_stringval(parser)); } break; case 22: -#line 1295 "upb/json/parser.rl" +#line 1334 "upb/json/parser.rl" { CHECK_RETURN_TOP(parser_putbool(parser, true)); } break; case 23: -#line 1297 "upb/json/parser.rl" +#line 1336 "upb/json/parser.rl" { CHECK_RETURN_TOP(parser_putbool(parser, false)); } break; case 24: -#line 1299 "upb/json/parser.rl" +#line 1338 "upb/json/parser.rl" { /* null value */ } break; case 25: -#line 1301 "upb/json/parser.rl" +#line 1340 "upb/json/parser.rl" { CHECK_RETURN_TOP(start_subobject(parser)); } break; case 26: -#line 1302 "upb/json/parser.rl" +#line 1341 "upb/json/parser.rl" { end_subobject(parser); } break; case 27: -#line 1307 "upb/json/parser.rl" +#line 1346 "upb/json/parser.rl" { p--; {cs = stack[--top]; goto _again;} } break; -#line 1579 "upb/json/parser.c" +#line 1618 "upb/json/parser.c" } } @@ -15836,7 +15875,7 @@ _again: _out: {} } -#line 1334 "upb/json/parser.rl" +#line 1373 "upb/json/parser.rl" if (p != pe) { upb_status_seterrf(&parser->status, "Parse error at '%.*s'\n", pe - p, p); @@ -15877,13 +15916,13 @@ static void json_parser_reset(upb_json_parser *p) { /* Emit Ragel initialization of the parser. */ -#line 1633 "upb/json/parser.c" +#line 1672 "upb/json/parser.c" { cs = json_start; top = 0; } -#line 1374 "upb/json/parser.rl" +#line 1413 "upb/json/parser.rl" p->current_state = cs; p->parser_top = top; accumulate_clear(p); @@ -15970,7 +16009,8 @@ static void add_jsonname_table(upb_json_parsermethod *m, const upb_msgdef* md) { upb_json_parser *upb_json_parser_create(upb_env *env, const upb_json_parsermethod *method, - upb_sink *output) { + upb_sink *output, + bool ignore_json_unknown) { #ifndef NDEBUG const size_t size_before = upb_env_bytesallocated(env); #endif @@ -15989,6 +16029,8 @@ upb_json_parser *upb_json_parser_create(upb_env *env, p->top->m = upb_handlers_msgdef(output->handlers); set_name_table(p, p->top); + p->ignore_json_unknown = ignore_json_unknown; + /* If this fails, uncomment and increase the value in parser.h. */ /* fprintf(stderr, "%zd\n", upb_env_bytesallocated(env) - size_before); */ UPB_ASSERT_DEBUGVAR(upb_env_bytesallocated(env) - size_before <= diff --git a/php/ext/google/protobuf/upb.h b/php/ext/google/protobuf/upb.h index a263db30..180f4715 100644 --- a/php/ext/google/protobuf/upb.h +++ b/php/ext/google/protobuf/upb.h @@ -9457,7 +9457,7 @@ UPB_DECLARE_DERIVED_TYPE(upb::json::ParserMethod, upb::RefCounted, class upb::json::Parser { public: static Parser* Create(Environment* env, const ParserMethod* method, - Sink* output); + Sink* output, bool ignore_json_unknown); BytesSink* input(); @@ -9491,7 +9491,8 @@ UPB_BEGIN_EXTERN_C upb_json_parser* upb_json_parser_create(upb_env* e, const upb_json_parsermethod* m, - upb_sink* output); + upb_sink* output, + bool ignore_json_unknown); upb_bytessink *upb_json_parser_input(upb_json_parser *p); upb_json_parsermethod* upb_json_parsermethod_new(const upb_msgdef* md, @@ -9511,8 +9512,8 @@ UPB_END_EXTERN_C namespace upb { namespace json { inline Parser* Parser::Create(Environment* env, const ParserMethod* method, - Sink* output) { - return upb_json_parser_create(env, method, output); + Sink* output, bool ignore_json_unknown) { + return upb_json_parser_create(env, method, output, ignore_json_unknown); } inline BytesSink* Parser::input() { return upb_json_parser_input(this); diff --git a/php/src/Google/Protobuf/Internal/GPBJsonWire.php b/php/src/Google/Protobuf/Internal/GPBJsonWire.php index 9ae57ab3..43f4745d 100644 --- a/php/src/Google/Protobuf/Internal/GPBJsonWire.php +++ b/php/src/Google/Protobuf/Internal/GPBJsonWire.php @@ -226,7 +226,7 @@ class GPBJsonWire $output->writeRaw("\"", 1); break; case GPBType::STRING: - $value = json_encode($value); + $value = json_encode($value, JSON_UNESCAPED_UNICODE); $output->writeRaw($value, strlen($value)); break; // case GPBType::GROUP: diff --git a/php/src/Google/Protobuf/Internal/Message.php b/php/src/Google/Protobuf/Internal/Message.php index 73ac375e..8ff141ca 100644 --- a/php/src/Google/Protobuf/Internal/Message.php +++ b/php/src/Google/Protobuf/Internal/Message.php @@ -1563,7 +1563,7 @@ class Message } break; case GPBType::STRING: - $value = json_encode($value); + $value = json_encode($value, JSON_UNESCAPED_UNICODE); $size += strlen($value); break; case GPBType::BYTES: diff --git a/php/src/Google/Protobuf/Timestamp.php b/php/src/Google/Protobuf/Timestamp.php index e21f3231..6d26f6c5 100644 --- a/php/src/Google/Protobuf/Timestamp.php +++ b/php/src/Google/Protobuf/Timestamp.php @@ -55,7 +55,9 @@ use Google\Protobuf\Internal\GPBUtil; * {hour}, {min}, and {sec} are zero-padded to two digits each. The fractional * seconds, which can go up to 9 digits (i.e. up to 1 nanosecond resolution), * are optional. The "Z" suffix indicates the timezone ("UTC"); the timezone - * is required, though only UTC (as indicated by "Z") is presently supported. + * is required. A proto3 JSON serializer should always use UTC (as indicated by + * "Z") when printing the Timestamp type and a proto3 JSON parser should be + * able to accept both UTC and other timezones (as indicated by an offset). * For example, "2017-01-15T01:30:15.01Z" encodes 15.01 seconds past * 01:30 UTC on January 15, 2017. * In JavaScript, one can convert a Date object to this format using the @@ -64,8 +66,8 @@ use Google\Protobuf\Internal\GPBUtil; * to this format using [`strftime`](https://docs.python.org/2/library/time.html#time.strftime) * with the time format spec '%Y-%m-%dT%H:%M:%S.%fZ'. Likewise, in Java, one * can use the Joda Time's [`ISODateTimeFormat.dateTime()`]( - * http://www.joda.org/joda-time/apidocs/org/joda/time/format/ISODateTimeFormat.html#dateTime--) - * to obtain a formatter capable of generating timestamps in this format. + * http://www.joda.org/joda-time/apidocs/org/joda/time/format/ISODateTimeFormat.html#dateTime-- + * ) to obtain a formatter capable of generating timestamps in this format. * * Generated from protobuf message <code>google.protobuf.Timestamp</code> */ @@ -180,18 +182,19 @@ class Timestamp extends \Google\Protobuf\Internal\Message */ public function fromDateTime(\DateTime $datetime) { - $this->seconds = $datetime->format('U'); - $this->nanos = 0; + $this->seconds = $datetime->getTimestamp(); + $this->nanos = 1000 * $datetime->format('u'); } /** - * Converts Timestamp to PHP DateTime. Nano second is ignored. + * Converts Timestamp to PHP DateTime. * * @return \DateTime $datetime */ public function toDateTime() { - return \DateTime::createFromFormat('U', $this->seconds); + $time = sprintf('%s.%06d', $this->seconds, $this->nanos / 1000); + return \DateTime::createFromFormat('U.u', $time); } } diff --git a/php/tests/compatibility_test.sh b/php/tests/compatibility_test.sh index b377d85c..c4d6325d 100755 --- a/php/tests/compatibility_test.sh +++ b/php/tests/compatibility_test.sh @@ -124,6 +124,7 @@ sed -i.bak '/php_implementation_test.php/d' phpunit.xml sed -i.bak '/generated_phpdoc_test.php/d' phpunit.xml sed -i.bak 's/generated_phpdoc_test.php//g' tests/test.sh sed -i.bak '/memory_leak_test.php/d' tests/test.sh +sed -i.bak '/^ public function testTimestamp()$/,/^ }$/d' tests/well_known_test.php for t in "${tests[@]}" do remove_error_test tests/$t diff --git a/php/tests/memory_leak_test.php b/php/tests/memory_leak_test.php index 4e3874b7..f3bcb963 100644 --- a/php/tests/memory_leak_test.php +++ b/php/tests/memory_leak_test.php @@ -152,7 +152,7 @@ date_default_timezone_set('UTC'); $from = new DateTime('2011-01-01T15:03:01.012345UTC'); $timestamp->fromDateTime($from); assert($from->format('U') == $timestamp->getSeconds()); -assert(0 == $timestamp->getNanos()); +assert(1000 * $from->format('u') == $timestamp->getNanos()); $to = $timestamp->toDateTime(); assert(\DateTime::class == get_class($to)); diff --git a/php/tests/undefined_test.php b/php/tests/undefined_test.php index f8444571..935d8be7 100644 --- a/php/tests/undefined_test.php +++ b/php/tests/undefined_test.php @@ -909,7 +909,7 @@ class UndefinedTest extends PHPUnit_Framework_TestCase /** * @expectedException PHPUnit_Framework_Error */ - public function testMessageSetNullFail() + public function testMessageSetNullFailMap() { $arr = new MapField(GPBType::INT32, GPBType::MESSAGE, TestMessage::class); diff --git a/php/tests/well_known_test.php b/php/tests/well_known_test.php index 1e8c4f42..9f2661fa 100644 --- a/php/tests/well_known_test.php +++ b/php/tests/well_known_test.php @@ -312,11 +312,12 @@ class WellKnownTest extends TestBase { $from = new DateTime('2011-01-01T15:03:01.012345UTC'); $timestamp->fromDateTime($from); $this->assertEquals($from->format('U'), $timestamp->getSeconds()); - $this->assertSame(0, $timestamp->getNanos()); + $this->assertEquals(1000 * $from->format('u'), $timestamp->getNanos()); $to = $timestamp->toDateTime(); $this->assertSame(\DateTime::class, get_class($to)); $this->assertSame($from->format('U'), $to->format('U')); + $this->assertSame($from->format('u'), $to->format('u')); } public function testType() diff --git a/protobuf.bzl b/protobuf.bzl index 78f19c62..67d61d7b 100644 --- a/protobuf.bzl +++ b/protobuf.bzl @@ -1,3 +1,5 @@ +load("@bazel_skylib//:lib.bzl", "versions") + def _GetPath(ctx, path): if ctx.label.workspace_root: return ctx.label.workspace_root + '/' + path @@ -72,7 +74,7 @@ def _proto_gen_impl(ctx): deps = [] deps += ctx.files.srcs source_dir = _SourceDir(ctx) - gen_dir = _GenDir(ctx) + gen_dir = _GenDir(ctx).rstrip('/') if source_dir: import_flags = ["-I" + source_dir, "-I" + gen_dir] else: @@ -82,37 +84,83 @@ def _proto_gen_impl(ctx): import_flags += dep.proto.import_flags deps += dep.proto.deps - args = [] - if ctx.attr.gen_cc: - args += ["--cpp_out=" + gen_dir] - if ctx.attr.gen_py: - args += ["--python_out=" + gen_dir] - - inputs = srcs + deps - if ctx.executable.plugin: - plugin = ctx.executable.plugin - lang = ctx.attr.plugin_language - if not lang and plugin.basename.startswith('protoc-gen-'): - lang = plugin.basename[len('protoc-gen-'):] - if not lang: - fail("cannot infer the target language of plugin", "plugin_language") - - outdir = gen_dir - if ctx.attr.plugin_options: - outdir = ",".join(ctx.attr.plugin_options) + ":" + outdir - args += ["--plugin=protoc-gen-%s=%s" % (lang, plugin.path)] - args += ["--%s_out=%s" % (lang, outdir)] - inputs += [plugin] - - if args: - ctx.action( - inputs=inputs, - outputs=ctx.outputs.outs, - arguments=args + import_flags + [s.path for s in srcs], - executable=ctx.executable.protoc, - mnemonic="ProtoCompile", - use_default_shell_env=True, - ) + if not ctx.attr.gen_cc and not ctx.attr.gen_py and not ctx.executable.plugin: + return struct( + proto=struct( + srcs=srcs, + import_flags=import_flags, + deps=deps, + ), + ) + + for src in srcs: + args = [] + + in_gen_dir = src.root.path == gen_dir + if in_gen_dir: + import_flags_real = [] + for f in depset(import_flags): + path = f.replace('-I', '') + import_flags_real.append('-I$(realpath -s %s)' % path) + + outs = [] + use_grpc_plugin = (ctx.attr.plugin_language == "grpc" and ctx.attr.plugin) + path_tpl = "$(realpath %s)" if in_gen_dir else "%s" + if ctx.attr.gen_cc: + args += [("--cpp_out=" + path_tpl) % gen_dir] + outs.extend(_CcOuts([src.basename], use_grpc_plugin=use_grpc_plugin)) + if ctx.attr.gen_py: + args += [("--python_out=" + path_tpl) % gen_dir] + outs.extend(_PyOuts([src.basename], use_grpc_plugin=use_grpc_plugin)) + + outs = [ctx.actions.declare_file(out, sibling=src) for out in outs] + inputs = [src] + deps + if ctx.executable.plugin: + plugin = ctx.executable.plugin + lang = ctx.attr.plugin_language + if not lang and plugin.basename.startswith('protoc-gen-'): + lang = plugin.basename[len('protoc-gen-'):] + if not lang: + fail("cannot infer the target language of plugin", "plugin_language") + + outdir = "." if in_gen_dir else gen_dir + + if ctx.attr.plugin_options: + outdir = ",".join(ctx.attr.plugin_options) + ":" + outdir + args += [("--plugin=protoc-gen-%s=" + path_tpl) % (lang, plugin.path)] + args += ["--%s_out=%s" % (lang, outdir)] + inputs += [plugin] + + if not in_gen_dir: + ctx.action( + inputs=inputs, + outputs=outs, + arguments=args + import_flags + [src.path], + executable=ctx.executable.protoc, + mnemonic="ProtoCompile", + use_default_shell_env=True, + ) + else: + for out in outs: + orig_command = " ".join( + ["$(realpath %s)" % ctx.executable.protoc.path] + args + + import_flags_real + ["-I.", src.basename]) + command = ";".join([ + 'CMD="%s"' % orig_command, + "cd %s" % src.dirname, + "${CMD}", + "cd -", + ]) + generated_out = '/'.join([gen_dir, out.basename]) + if generated_out != out.path: + command += ";mv %s %s" % (generated_out, out.path) + ctx.action( + inputs=inputs + [ctx.executable.protoc], + outputs=[out], + command=command, + mnemonic="ProtoCompile", + use_default_shell_env=True, + ) return struct( proto=struct( @@ -266,8 +314,8 @@ def internal_gen_well_known_protos_java(srcs): Args: srcs: the well known protos """ - root = Label("%s//protobuf_java" % (REPOSITORY_NAME)).workspace_root - pkg = PACKAGE_NAME + "/" if PACKAGE_NAME else "" + root = Label("%s//protobuf_java" % (native.repository_name())).workspace_root + pkg = native.package_name() + "/" if native.package_name() else "" if root == "": include = " -I%ssrc " % pkg else: @@ -411,7 +459,4 @@ def check_protobuf_required_bazel_version(): This ensures bazel supports our approach to proto_library() depending on a copied filegroup. (Fixed in bazel 0.5.4) """ - expected = apple_common.dotted_version("0.5.4") - current = apple_common.dotted_version(native.bazel_version) - if current.compare_to(expected) < 0: - fail("Bazel must be newer than 0.5.4") + versions.check(minimum_bazel_version = "0.5.4") diff --git a/protoc-artifacts/README.md b/protoc-artifacts/README.md index 9b148891..1131a89e 100644 --- a/protoc-artifacts/README.md +++ b/protoc-artifacts/README.md @@ -119,7 +119,9 @@ target directory layout: protoc.exe + x86_32 protoc.exe - + macos + + aarch_64 + protoc.exe + + osx + x86_64 protoc.exe + x86_32 @@ -137,7 +139,7 @@ Use the following command to deploy artifacts for the host platform to a staging repository. ``` -$ mvn clean deploy -P release +$ mvn deploy -P release ``` It creates a new staging repository. Go to diff --git a/python/README.md b/python/README.md index 4c194297..3eb78e56 100644 --- a/python/README.md +++ b/python/README.md @@ -1,7 +1,7 @@ Protocol Buffers - Google's data interchange format =================================================== -[![Build Status](https://travis-ci.org/google/protobuf.svg?branch=master)](https://travis-ci.org/google/protobuf) +[![Build status](https://storage.googleapis.com/protobuf-kokoro-results/status-badge/linux-python.png)](https://fusion.corp.google.com/projectanalysis/current/KOKORO/prod:protobuf%2Fgithub%2Fmaster%2Fubuntu%2Fpython%2Fcontinuous) [![Build status](https://storage.googleapis.com/protobuf-kokoro-results/status-badge/linux-python_compatibility.png)](https://fusion.corp.google.com/projectanalysis/current/KOKORO/prod:protobuf%2Fgithub%2Fmaster%2Fubuntu%2Fpython_compatibility%2Fcontinuous) [![Build status](https://storage.googleapis.com/protobuf-kokoro-results/status-badge/linux-python_cpp.png)](https://fusion.corp.google.com/projectanalysis/current/KOKORO/prod:protobuf%2Fgithub%2Fmaster%2Fubuntu%2Fpython_cpp%2Fcontinuous) [![Build status](https://storage.googleapis.com/protobuf-kokoro-results/status-badge/macos-python.png)](https://fusion.corp.google.com/projectanalysis/current/KOKORO/prod:protobuf%2Fgithub%2Fmaster%2Fmacos%2Fpython%2Fcontinuous) [![Build status](https://storage.googleapis.com/protobuf-kokoro-results/status-badge/macos-python_cpp.png)](https://fusion.corp.google.com/projectanalysis/current/KOKORO/prod:protobuf%2Fgithub%2Fmaster%2Fmacos%2Fpython_cpp%2Fcontinuous) Copyright 2008 Google Inc. @@ -30,7 +30,7 @@ join the Protocol Buffers discussion list and let us know! Installation ============ -1) Make sure you have Python 2.6 or newer. If in doubt, run: +1) Make sure you have Python 2.7 or newer. If in doubt, run: $ python -V diff --git a/python/google/protobuf/internal/json_format_test.py b/python/google/protobuf/internal/json_format_test.py index d891dce1..7f649406 100644 --- a/python/google/protobuf/internal/json_format_test.py +++ b/python/google/protobuf/internal/json_format_test.py @@ -791,9 +791,6 @@ class JsonFormatTest(JsonFormatBase): json_format.Parse(text, parsed_message, ignore_unknown_fields=True) def testDuplicateField(self): - # Duplicate key check is not supported for python2.6 - if sys.version_info < (2, 7): - return self.CheckError('{"int32Value": 1,\n"int32Value":2}', 'Failed to load JSON: duplicate key int32Value.') diff --git a/python/google/protobuf/json_format.py b/python/google/protobuf/json_format.py index 8d338d3e..58c94a47 100644 --- a/python/google/protobuf/json_format.py +++ b/python/google/protobuf/json_format.py @@ -396,11 +396,7 @@ def Parse(text, message, ignore_unknown_fields=False): """ if not isinstance(text, six.text_type): text = text.decode('utf-8') try: - if sys.version_info < (2, 7): - # object_pair_hook is not supported before python2.7 - js = json.loads(text) - else: - js = json.loads(text, object_pairs_hook=_DuplicateChecker) + js = json.loads(text, object_pairs_hook=_DuplicateChecker) except ValueError as e: raise ParseError('Failed to load JSON: {0}.'.format(str(e))) return ParseDict(js, message, ignore_unknown_fields) diff --git a/python/google/protobuf/proto_api.h b/python/google/protobuf/proto_api.h new file mode 100644 index 00000000..5c076d23 --- /dev/null +++ b/python/google/protobuf/proto_api.h @@ -0,0 +1,92 @@ +// 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 can be included by other C++ libraries, typically extension modules +// which want to interact with the Python Messages coming from the "cpp" +// implementation of protocol buffers. +// +// Usage: +// Declare a (probably static) variable to hold the API: +// const PyProto_API* py_proto_api; +// In some initialization function, write: +// py_proto_api = static_cast<const PyProto_API*>(PyCapsule_Import( +// PyProtoAPICapsuleName(), 0)); +// if (!py_proto_api) { ...handle ImportError... } +// Then use the methods of the returned class: +// py_proto_api->GetMessagePointer(...); + +#ifndef PYTHON_GOOGLE_PROTOBUF_PROTO_API_H__ +#define PYTHON_GOOGLE_PROTOBUF_PROTO_API_H__ + +#include <Python.h> + +namespace google { +namespace protobuf { + +class Message; + +namespace python { + +// Note on the implementation: +// This API is designed after +// https://docs.python.org/3/extending/extending.html#providing-a-c-api-for-an-extension-module +// The class below contains no mutable state, and all methods are "const"; +// we use a C++ class instead of a C struct with functions pointers just because +// the code looks more readable. +struct PyProto_API { + // The API object is created at initialization time and never freed. + // This destructor is never called. + virtual ~PyProto_API() {} + + // Operations on Messages. + + // If the passed object is a Python Message, returns its internal pointer. + // Otherwise, returns NULL with an exception set. + virtual const Message* GetMessagePointer(PyObject* msg) const = 0; + + // If the passed object is a Python Message, returns a mutable pointer. + // Otherwise, returns NULL with an exception set. + // This function will succeed only if there are no other Python objects + // pointing to the message, like submessages or repeated containers. + // With the current implementation, only empty messages are in this case. + virtual Message* GetMutableMessagePointer(PyObject* msg) const = 0; +}; + +inline const char* PyProtoAPICapsuleName() { + static const char kCapsuleName[] = + "google.protobuf.pyext._message.proto_API"; + return kCapsuleName; +} + +} // namespace python +} // namespace protobuf +} // namespace google + +#endif // PYTHON_GOOGLE_PROTOBUF_PROTO_API_H__ diff --git a/python/google/protobuf/pyext/descriptor.cc b/python/google/protobuf/pyext/descriptor.cc index 8af0cb12..19a1c38a 100644 --- a/python/google/protobuf/pyext/descriptor.cc +++ b/python/google/protobuf/pyext/descriptor.cc @@ -56,7 +56,7 @@ #endif #define PyString_AsStringAndSize(ob, charpp, sizep) \ (PyUnicode_Check(ob)? \ - ((*(charpp) = PyUnicode_AsUTF8AndSize(ob, (sizep))) == NULL? -1: 0): \ + ((*(charpp) = const_cast<char*>(PyUnicode_AsUTF8AndSize(ob, (sizep)))) == NULL? -1: 0): \ PyBytes_AsStringAndSize(ob, (charpp), (sizep))) #endif diff --git a/python/google/protobuf/pyext/descriptor_containers.cc b/python/google/protobuf/pyext/descriptor_containers.cc index bc007f7e..0153664f 100644 --- a/python/google/protobuf/pyext/descriptor_containers.cc +++ b/python/google/protobuf/pyext/descriptor_containers.cc @@ -66,7 +66,7 @@ #endif #define PyString_AsStringAndSize(ob, charpp, sizep) \ (PyUnicode_Check(ob)? \ - ((*(charpp) = PyUnicode_AsUTF8AndSize(ob, (sizep))) == NULL? -1: 0): \ + ((*(charpp) = const_cast<char*>(PyUnicode_AsUTF8AndSize(ob, (sizep)))) == NULL? -1: 0): \ PyBytes_AsStringAndSize(ob, (charpp), (sizep))) #endif diff --git a/python/google/protobuf/pyext/descriptor_pool.cc b/python/google/protobuf/pyext/descriptor_pool.cc index 95882aeb..962accc6 100644 --- a/python/google/protobuf/pyext/descriptor_pool.cc +++ b/python/google/protobuf/pyext/descriptor_pool.cc @@ -48,7 +48,7 @@ #endif #define PyString_AsStringAndSize(ob, charpp, sizep) \ (PyUnicode_Check(ob)? \ - ((*(charpp) = PyUnicode_AsUTF8AndSize(ob, (sizep))) == NULL? -1: 0): \ + ((*(charpp) = const_cast<char*>(PyUnicode_AsUTF8AndSize(ob, (sizep)))) == NULL? -1: 0): \ PyBytes_AsStringAndSize(ob, (charpp), (sizep))) #endif diff --git a/python/google/protobuf/pyext/extension_dict.cc b/python/google/protobuf/pyext/extension_dict.cc index 018b5c2c..174c5470 100644 --- a/python/google/protobuf/pyext/extension_dict.cc +++ b/python/google/protobuf/pyext/extension_dict.cc @@ -53,7 +53,7 @@ #endif #define PyString_AsStringAndSize(ob, charpp, sizep) \ (PyUnicode_Check(ob)? \ - ((*(charpp) = PyUnicode_AsUTF8AndSize(ob, (sizep))) == NULL? -1: 0): \ + ((*(charpp) = const_cast<char*>(PyUnicode_AsUTF8AndSize(ob, (sizep)))) == NULL? -1: 0): \ PyBytes_AsStringAndSize(ob, (charpp), (sizep))) #endif diff --git a/python/google/protobuf/pyext/message.cc b/python/google/protobuf/pyext/message.cc index 5893533a..b2984509 100644 --- a/python/google/protobuf/pyext/message.cc +++ b/python/google/protobuf/pyext/message.cc @@ -79,7 +79,7 @@ (PyUnicode_Check(ob)? PyUnicode_AsUTF8(ob): PyBytes_AsString(ob)) #define PyString_AsStringAndSize(ob, charpp, sizep) \ (PyUnicode_Check(ob)? \ - ((*(charpp) = PyUnicode_AsUTF8AndSize(ob, (sizep))) == NULL? -1: 0): \ + ((*(charpp) = const_cast<char*>(PyUnicode_AsUTF8AndSize(ob, (sizep)))) == NULL? -1: 0): \ PyBytes_AsStringAndSize(ob, (charpp), (sizep))) #endif #endif @@ -1529,7 +1529,7 @@ PyObject* HasField(CMessage* self, PyObject* arg) { return NULL; } #else - field_name = PyUnicode_AsUTF8AndSize(arg, &size); + field_name = const_cast<char*>(PyUnicode_AsUTF8AndSize(arg, &size)); if (!field_name) { return NULL; } @@ -2866,17 +2866,38 @@ const Message* (*GetCProtoInsidePyProtoPtr)(PyObject* msg); Message* (*MutableCProtoInsidePyProtoPtr)(PyObject* msg); static const Message* GetCProtoInsidePyProtoImpl(PyObject* msg) { + const Message* message = PyMessage_GetMessagePointer(msg); + if (message == NULL) { + PyErr_Clear(); + return NULL; + } + return message; +} + +static Message* MutableCProtoInsidePyProtoImpl(PyObject* msg) { + Message* message = PyMessage_GetMutableMessagePointer(msg); + if (message == NULL) { + PyErr_Clear(); + return NULL; + } + return message; +} + +const Message* PyMessage_GetMessagePointer(PyObject* msg) { if (!PyObject_TypeCheck(msg, &CMessage_Type)) { + PyErr_SetString(PyExc_TypeError, "Not a Message instance"); return NULL; } CMessage* cmsg = reinterpret_cast<CMessage*>(msg); return cmsg->message; } -static Message* MutableCProtoInsidePyProtoImpl(PyObject* msg) { +Message* PyMessage_GetMutableMessagePointer(PyObject* msg) { if (!PyObject_TypeCheck(msg, &CMessage_Type)) { + PyErr_SetString(PyExc_TypeError, "Not a Message instance"); return NULL; } + CMessage* cmsg = reinterpret_cast<CMessage*>(msg); if ((cmsg->composite_fields && PyDict_Size(cmsg->composite_fields) != 0) || (cmsg->extensions != NULL && @@ -2885,6 +2906,9 @@ static Message* MutableCProtoInsidePyProtoImpl(PyObject* msg) { // the underlying C++ message back to the CMessage (e.g. removed repeated // composite containers). We only allow direct mutation of the underlying // C++ message if there is no child data in the CMessage. + PyErr_SetString(PyExc_ValueError, + "Cannot reliably get a mutable pointer " + "to a message with extra references"); return NULL; } cmessage::AssureWritable(cmsg); diff --git a/python/google/protobuf/pyext/message.h b/python/google/protobuf/pyext/message.h index 72bcfa83..d754e62a 100644 --- a/python/google/protobuf/pyext/message.h +++ b/python/google/protobuf/pyext/message.h @@ -341,6 +341,9 @@ bool CheckFieldBelongsToMessage(const FieldDescriptor* field_descriptor, extern PyObject* PickleError_class; +const Message* PyMessage_GetMessagePointer(PyObject* msg); +Message* PyMessage_GetMutableMessagePointer(PyObject* msg); + bool InitProto2MessageModule(PyObject *m); #if LANG_CXX11 diff --git a/python/google/protobuf/pyext/message_module.cc b/python/google/protobuf/pyext/message_module.cc index 7c4df47f..8c933866 100644 --- a/python/google/protobuf/pyext/message_module.cc +++ b/python/google/protobuf/pyext/message_module.cc @@ -31,9 +31,26 @@ #include <Python.h> #include <google/protobuf/pyext/message.h> +#include <google/protobuf/proto_api.h> #include <google/protobuf/message_lite.h> +namespace { + +// C++ API. Clients get at this via proto_api.h +struct ApiImplementation : google::protobuf::python::PyProto_API { + const google::protobuf::Message* + GetMessagePointer(PyObject* msg) const override { + return google::protobuf::python::PyMessage_GetMessagePointer(msg); + } + google::protobuf::Message* + GetMutableMessagePointer(PyObject* msg) const override { + return google::protobuf::python::PyMessage_GetMutableMessagePointer(msg); + } +}; + +} // namespace + static PyObject* GetPythonProto3PreserveUnknownsDefault( PyObject* /*m*/, PyObject* /*args*/) { if (google::protobuf::internal::GetProto3PreserveUnknownsDefault()) { @@ -113,6 +130,15 @@ extern "C" { Py_DECREF(m); return INITFUNC_ERRORVAL; } + + // Adds the C++ API + if (PyObject* api = + PyCapsule_New(new ApiImplementation(), + google::protobuf::python::PyProtoAPICapsuleName(), NULL)) { + PyModule_AddObject(m, "proto_API", api); + } else { + return INITFUNC_ERRORVAL; + } #if PY_MAJOR_VERSION >= 3 return m; diff --git a/python/setup.py b/python/setup.py index a9df075e..5ec4dcbd 100755 --- a/python/setup.py +++ b/python/setup.py @@ -44,6 +44,7 @@ def GetVersion(): with open(os.path.join('google', 'protobuf', '__init__.py')) as version_file: exec(version_file.read(), globals()) + global __version__ return __version__ @@ -148,10 +149,9 @@ class build_py(_build_py): class test_conformance(_build_py): target = 'test_python' def run(self): - if sys.version_info >= (2, 7): - # Python 2.6 dodges these extra failures. - os.environ["CONFORMANCE_PYTHON_EXTRA_FAILURES"] = ( - "--failure_list failure_list_python-post26.txt") + # Python 2.6 dodges these extra failures. + os.environ["CONFORMANCE_PYTHON_EXTRA_FAILURES"] = ( + "--failure_list failure_list_python-post26.txt") cmd = 'cd ../conformance && make %s' % (test_conformance.target) status = subprocess.check_call(cmd, shell=True) @@ -185,6 +185,7 @@ if __name__ == '__main__': extra_compile_args.append('-Wno-write-strings') extra_compile_args.append('-Wno-invalid-offsetof') extra_compile_args.append('-Wno-sign-compare') + extra_compile_args.append('-std=c++11') # https://github.com/Theano/Theano/issues/4926 if sys.platform == 'win32': @@ -201,12 +202,6 @@ if __name__ == '__main__': if "clang" in os.popen('$CC --version 2> /dev/null').read(): extra_compile_args.append('-Wno-shorten-64-to-32') - v, _, _ = platform.mac_ver() - if v: - extra_compile_args.append('-std=c++11') - elif os.getenv('KOKORO_BUILD_NUMBER') or os.getenv('KOKORO_BUILD_ID'): - extra_compile_args.append('-std=c++11') - if warnings_as_errors in sys.argv: extra_compile_args.append('-Werror') sys.argv.remove(warnings_as_errors) diff --git a/python/stubout.py b/python/stubout.py index aee4f2da..ba391045 100755 --- a/python/stubout.py +++ b/python/stubout.py @@ -17,6 +17,9 @@ # This file is used for testing. The original is at: # http://code.google.com/p/pymox/ +import inspect + + class StubOutForTesting: """Sample Usage: You want os.path.exists() to always return true during testing. diff --git a/ruby/ext/google/protobuf_c/defs.c b/ruby/ext/google/protobuf_c/defs.c index d9d2ebac..9fe04503 100644 --- a/ruby/ext/google/protobuf_c/defs.c +++ b/ruby/ext/google/protobuf_c/defs.c @@ -812,7 +812,7 @@ VALUE FieldDescriptor_submsg_name_set(VALUE _self, VALUE value) { upb_fielddef* mut_def = check_field_notfrozen(self->fielddef); const char* str = get_str(value); if (!upb_fielddef_hassubdef(self->fielddef)) { - rb_raise(rb_eTypeError, "FieldDescriptor does not have subdef."); + rb_raise(cTypeError, "FieldDescriptor does not have subdef."); } CHECK_UPB(upb_fielddef_setsubdefname(mut_def, str, &status), "Error setting submessage name"); @@ -854,7 +854,7 @@ VALUE FieldDescriptor_get(VALUE _self, VALUE msg_rb) { MessageHeader* msg; TypedData_Get_Struct(msg_rb, MessageHeader, &Message_type, msg); if (msg->descriptor->msgdef != upb_fielddef_containingtype(self->fielddef)) { - rb_raise(rb_eTypeError, "get method called on wrong message type"); + rb_raise(cTypeError, "get method called on wrong message type"); } return layout_get(msg->descriptor->layout, Message_data(msg), self->fielddef); } @@ -872,7 +872,7 @@ VALUE FieldDescriptor_set(VALUE _self, VALUE msg_rb, VALUE value) { MessageHeader* msg; TypedData_Get_Struct(msg_rb, MessageHeader, &Message_type, msg); if (msg->descriptor->msgdef != upb_fielddef_containingtype(self->fielddef)) { - rb_raise(rb_eTypeError, "set method called on wrong message type"); + rb_raise(cTypeError, "set method called on wrong message type"); } layout_set(msg->descriptor->layout, Message_data(msg), self->fielddef, value); return Qnil; @@ -1713,7 +1713,7 @@ static void validate_msgdef(const upb_msgdef* msgdef) { upb_msg_field_next(&it)) { const upb_fielddef* field = upb_msg_iter_field(&it); if (upb_fielddef_label(field) == UPB_LABEL_REQUIRED) { - rb_raise(rb_eTypeError, "Required fields are unsupported in proto3."); + rb_raise(cTypeError, "Required fields are unsupported in proto3."); } } } @@ -1723,7 +1723,7 @@ static void validate_enumdef(const upb_enumdef* enumdef) { // value.) const char* lookup = upb_enumdef_iton(enumdef, 0); if (lookup == NULL) { - rb_raise(rb_eTypeError, + rb_raise(cTypeError, "Enum definition does not contain a value for '0'."); } } diff --git a/ruby/ext/google/protobuf_c/encode_decode.c b/ruby/ext/google/protobuf_c/encode_decode.c index 9fa4bfd9..d5842051 100644 --- a/ruby/ext/google/protobuf_c/encode_decode.c +++ b/ruby/ext/google/protobuf_c/encode_decode.c @@ -963,13 +963,15 @@ static void putary(VALUE ary, const upb_fielddef *f, upb_sink *sink, if (ary == Qnil) return; + size = NUM2INT(RepeatedField_length(ary)); + if (size == 0 && !emit_defaults) return; + upb_sink_startseq(sink, getsel(f, UPB_HANDLER_STARTSEQ), &subsink); if (upb_fielddef_isprimitive(f)) { sel = getsel(f, upb_handlers_getprimitivehandlertype(f)); } - size = NUM2INT(RepeatedField_length(ary)); for (int i = 0; i < size; i++) { void* memory = RepeatedField_index_native(ary, i); switch (type) { diff --git a/ruby/ext/google/protobuf_c/message.c b/ruby/ext/google/protobuf_c/message.c index 63a61baf..721c1112 100644 --- a/ruby/ext/google/protobuf_c/message.c +++ b/ruby/ext/google/protobuf_c/message.c @@ -256,6 +256,10 @@ int Message_initialize_kwarg(VALUE key, VALUE val, VALUE _self) { "Unknown field name '%s' in initialization map entry.", name); } + if (TYPE(val) == T_NIL) { + return 0; + } + if (is_map_field(f)) { VALUE map; @@ -631,7 +635,7 @@ VALUE build_module_from_enumdesc(EnumDescriptor* enumdesc) { const char* name = upb_enum_iter_name(&it); int32_t value = upb_enum_iter_number(&it); if (name[0] < 'A' || name[0] > 'Z') { - rb_raise(rb_eTypeError, + rb_raise(cTypeError, "Enum value '%s' does not start with an uppercase letter " "as is required for Ruby constants.", name); diff --git a/ruby/ext/google/protobuf_c/protobuf.c b/ruby/ext/google/protobuf_c/protobuf.c index db696426..fe6bb406 100644 --- a/ruby/ext/google/protobuf_c/protobuf.c +++ b/ruby/ext/google/protobuf_c/protobuf.c @@ -41,6 +41,7 @@ VALUE upb_def_to_ruby_obj_map; VALUE cError; VALUE cParseError; +VALUE cTypeError; void add_def_obj(const void* def, VALUE value) { rb_hash_aset(upb_def_to_ruby_obj_map, ULL2NUM((intptr_t)def), value); @@ -102,6 +103,7 @@ void Init_protobuf_c() { cError = rb_const_get(protobuf, rb_intern("Error")); cParseError = rb_const_get(protobuf, rb_intern("ParseError")); + cTypeError = rb_const_get(protobuf, rb_intern("TypeError")); rb_define_singleton_method(protobuf, "discard_unknown", Google_Protobuf_discard_unknown, 1); diff --git a/ruby/ext/google/protobuf_c/protobuf.h b/ruby/ext/google/protobuf_c/protobuf.h index 5266aa8d..3e5c0520 100644 --- a/ruby/ext/google/protobuf_c/protobuf.h +++ b/ruby/ext/google/protobuf_c/protobuf.h @@ -161,6 +161,7 @@ extern VALUE cBuilder; extern VALUE cError; extern VALUE cParseError; +extern VALUE cTypeError; // We forward-declare all of the Ruby method implementations here because we // sometimes call the methods directly across .c files, rather than going diff --git a/ruby/ext/google/protobuf_c/storage.c b/ruby/ext/google/protobuf_c/storage.c index 5d842b74..163b2f81 100644 --- a/ruby/ext/google/protobuf_c/storage.c +++ b/ruby/ext/google/protobuf_c/storage.c @@ -96,7 +96,7 @@ static bool is_ruby_num(VALUE value) { void native_slot_check_int_range_precision(upb_fieldtype_t type, VALUE val) { if (!is_ruby_num(val)) { - rb_raise(rb_eTypeError, "Expected number type for integral field."); + rb_raise(cTypeError, "Expected number type for integral field."); } // NUM2{INT,UINT,LL,ULL} macros do the appropriate range checks on upper @@ -153,13 +153,13 @@ void native_slot_set_value_and_case(upb_fieldtype_t type, VALUE type_class, switch (type) { case UPB_TYPE_FLOAT: if (!is_ruby_num(value)) { - rb_raise(rb_eTypeError, "Expected number type for float field."); + rb_raise(cTypeError, "Expected number type for float field."); } DEREF(memory, float) = NUM2DBL(value); break; case UPB_TYPE_DOUBLE: if (!is_ruby_num(value)) { - rb_raise(rb_eTypeError, "Expected number type for double field."); + rb_raise(cTypeError, "Expected number type for double field."); } DEREF(memory, double) = NUM2DBL(value); break; @@ -170,7 +170,7 @@ void native_slot_set_value_and_case(upb_fieldtype_t type, VALUE type_class, } else if (value == Qfalse) { val = 0; } else { - rb_raise(rb_eTypeError, "Invalid argument for boolean field."); + rb_raise(cTypeError, "Invalid argument for boolean field."); } DEREF(memory, int8_t) = val; break; @@ -179,7 +179,7 @@ void native_slot_set_value_and_case(upb_fieldtype_t type, VALUE type_class, if (CLASS_OF(value) == rb_cSymbol) { value = rb_funcall(value, rb_intern("to_s"), 0); } else if (CLASS_OF(value) != rb_cString) { - rb_raise(rb_eTypeError, "Invalid argument for string field."); + rb_raise(cTypeError, "Invalid argument for string field."); } DEREF(memory, VALUE) = native_slot_encode_and_freeze_string(type, value); @@ -187,7 +187,7 @@ void native_slot_set_value_and_case(upb_fieldtype_t type, VALUE type_class, case UPB_TYPE_BYTES: { if (CLASS_OF(value) != rb_cString) { - rb_raise(rb_eTypeError, "Invalid argument for string field."); + rb_raise(cTypeError, "Invalid argument for string field."); } DEREF(memory, VALUE) = native_slot_encode_and_freeze_string(type, value); @@ -197,7 +197,7 @@ void native_slot_set_value_and_case(upb_fieldtype_t type, VALUE type_class, if (CLASS_OF(value) == CLASS_OF(Qnil)) { value = Qnil; } else if (CLASS_OF(value) != type_class) { - rb_raise(rb_eTypeError, + rb_raise(cTypeError, "Invalid type %s to assign to submessage field.", rb_class2name(CLASS_OF(value))); } @@ -209,7 +209,7 @@ void native_slot_set_value_and_case(upb_fieldtype_t type, VALUE type_class, if (TYPE(value) == T_STRING) { value = rb_funcall(value, rb_intern("to_sym"), 0); } else if (!is_ruby_num(value) && TYPE(value) != T_SYMBOL) { - rb_raise(rb_eTypeError, + rb_raise(cTypeError, "Expected number or symbol type for enum field."); } if (TYPE(value) == T_SYMBOL) { @@ -598,18 +598,18 @@ static void check_repeated_field_type(VALUE val, const upb_fielddef* field) { if (!RB_TYPE_P(val, T_DATA) || !RTYPEDDATA_P(val) || RTYPEDDATA_TYPE(val) != &RepeatedField_type) { - rb_raise(rb_eTypeError, "Expected repeated field array"); + rb_raise(cTypeError, "Expected repeated field array"); } self = ruby_to_RepeatedField(val); if (self->field_type != upb_fielddef_type(field)) { - rb_raise(rb_eTypeError, "Repeated field array has wrong element type"); + rb_raise(cTypeError, "Repeated field array has wrong element type"); } - if (self->field_type == UPB_TYPE_MESSAGE) { + if (self->field_type == UPB_TYPE_MESSAGE) { if (self->field_type_class != Descriptor_msgclass(get_def_obj(upb_fielddef_subdef(field)))) { - rb_raise(rb_eTypeError, + rb_raise(cTypeError, "Repeated field array has wrong message class"); } } @@ -618,7 +618,7 @@ static void check_repeated_field_type(VALUE val, const upb_fielddef* field) { if (self->field_type == UPB_TYPE_ENUM) { if (self->field_type_class != EnumDescriptor_enummodule(get_def_obj(upb_fielddef_subdef(field)))) { - rb_raise(rb_eTypeError, + rb_raise(cTypeError, "Repeated field array has wrong enum class"); } } @@ -631,21 +631,21 @@ static void check_map_field_type(VALUE val, const upb_fielddef* field) { if (!RB_TYPE_P(val, T_DATA) || !RTYPEDDATA_P(val) || RTYPEDDATA_TYPE(val) != &Map_type) { - rb_raise(rb_eTypeError, "Expected Map instance"); + rb_raise(cTypeError, "Expected Map instance"); } self = ruby_to_Map(val); if (self->key_type != upb_fielddef_type(key_field)) { - rb_raise(rb_eTypeError, "Map key type does not match field's key type"); + rb_raise(cTypeError, "Map key type does not match field's key type"); } if (self->value_type != upb_fielddef_type(value_field)) { - rb_raise(rb_eTypeError, "Map value type does not match field's value type"); + rb_raise(cTypeError, "Map value type does not match field's value type"); } if (upb_fielddef_type(value_field) == UPB_TYPE_MESSAGE || upb_fielddef_type(value_field) == UPB_TYPE_ENUM) { if (self->value_type_class != get_def_obj(upb_fielddef_subdef(value_field))) { - rb_raise(rb_eTypeError, + rb_raise(cTypeError, "Map value type has wrong message/enum class"); } } diff --git a/ruby/lib/google/protobuf.rb b/ruby/lib/google/protobuf.rb index 4a805e88..e20a584e 100644 --- a/ruby/lib/google/protobuf.rb +++ b/ruby/lib/google/protobuf.rb @@ -37,6 +37,7 @@ module Google module Protobuf class Error < StandardError; end class ParseError < Error; end + class TypeError < ::TypeError; end end end diff --git a/ruby/lib/google/protobuf/well_known_types.rb b/ruby/lib/google/protobuf/well_known_types.rb index 921ddbc0..2ee65bc2 100644 --- a/ruby/lib/google/protobuf/well_known_types.rb +++ b/ruby/lib/google/protobuf/well_known_types.rb @@ -39,6 +39,12 @@ module Google module Protobuf Any.class_eval do + def self.pack(msg, type_url_prefix='type.googleapis.com/') + any = self.new + any.pack(msg, type_url_prefix) + any + end + def pack(msg, type_url_prefix='type.googleapis.com/') if type_url_prefix.empty? or type_url_prefix[-1] != '/' then self.type_url = "#{type_url_prefix}/#{msg.class.descriptor.name}" @@ -149,6 +155,8 @@ module Google Struct.class_eval do def [](key) self.fields[key].to_ruby + rescue NoMethodError + nil end def []=(key, value) @@ -170,6 +178,10 @@ module Google hash.each { |key, val| ret[key] = val } ret end + + def has_key?(key) + self.fields.has_key?(key) + end end ListValue.class_eval do diff --git a/ruby/src/main/java/com/google/protobuf/jruby/RubyMessage.java b/ruby/src/main/java/com/google/protobuf/jruby/RubyMessage.java index 07558fbc..c3a0d81c 100644 --- a/ruby/src/main/java/com/google/protobuf/jruby/RubyMessage.java +++ b/ruby/src/main/java/com/google/protobuf/jruby/RubyMessage.java @@ -86,6 +86,8 @@ public class RubyMessage extends RubyObject { throw runtime.newTypeError("Expected string or symbols as hash keys in initialization map."); final Descriptors.FieldDescriptor fieldDescriptor = findField(context, key); + if (value.isNil()) return; + if (Utils.isMapEntry(fieldDescriptor)) { if (!(value instanceof RubyHash)) throw runtime.newArgumentError("Expected Hash object as initializer value for map field '" + key.asJavaString() + "'."); diff --git a/ruby/tests/basic.rb b/ruby/tests/basic.rb index d151022e..f174402b 100644 --- a/ruby/tests/basic.rb +++ b/ruby/tests/basic.rb @@ -212,6 +212,15 @@ module BasicTest assert_equal ['foo', 'bar'], m.repeated_string end + def test_ctor_nil_args + m = TestMessage.new(:optional_enum => nil, :optional_int32 => nil, :optional_string => nil, :optional_msg => nil) + + assert_equal :Default, m.optional_enum + assert_equal 0, m.optional_int32 + assert_equal "", m.optional_string + assert_nil m.optional_msg + end + def test_embeddedmsg_hash_init m = TestEmbeddedMessageParent.new(:child_msg => {sub_child: {optional_int32: 1}}, :number => 2, @@ -283,31 +292,36 @@ module BasicTest def test_type_errors m = TestMessage.new - assert_raise TypeError do + e = assert_raise Google::Protobuf::TypeError do m.optional_int32 = "hello" end - assert_raise TypeError do + + # Google::Protobuf::TypeError should inherit from TypeError for backwards compatibility + # TODO: This can be removed when we can safely migrate to Google::Protobuf::TypeError + assert_true e.is_a?(::TypeError) + + assert_raise Google::Protobuf::TypeError do m.optional_string = 42 end - assert_raise TypeError do + assert_raise Google::Protobuf::TypeError do m.optional_string = nil end - assert_raise TypeError do + assert_raise Google::Protobuf::TypeError do m.optional_bool = 42 end - assert_raise TypeError do + assert_raise Google::Protobuf::TypeError do m.optional_msg = TestMessage.new # expects TestMessage2 end - assert_raise TypeError do + assert_raise Google::Protobuf::TypeError do m.repeated_int32 = [] # needs RepeatedField end - assert_raise TypeError do + assert_raise Google::Protobuf::TypeError do m.repeated_int32.push "hello" end - assert_raise TypeError do + assert_raise Google::Protobuf::TypeError do m.repeated_msg.push TestMessage.new end end @@ -375,7 +389,7 @@ module BasicTest assert l.pop == 9 assert l == [5, 2, 3, 4, 7, 8] - assert_raise TypeError do + assert_raise Google::Protobuf::TypeError do m = TestMessage.new l.push m end @@ -425,10 +439,10 @@ module BasicTest l = Google::Protobuf::RepeatedField.new(:message, TestMessage) l.push TestMessage.new assert l.count == 1 - assert_raise TypeError do + assert_raise Google::Protobuf::TypeError do l.push TestMessage2.new end - assert_raise TypeError do + assert_raise Google::Protobuf::TypeError do l.push 42 end @@ -577,7 +591,7 @@ module BasicTest assert_raise RangeError do m[0x8000_0000] = 1 end - assert_raise TypeError do + assert_raise Google::Protobuf::TypeError do m["asdf"] = 1 end @@ -586,7 +600,7 @@ module BasicTest assert_raise RangeError do m[0x1_0000_0000_0000_0000] = 1 end - assert_raise TypeError do + assert_raise Google::Protobuf::TypeError do m["asdf"] = 1 end @@ -611,10 +625,10 @@ module BasicTest m = Google::Protobuf::Map.new(:bool, :int32) m[true] = 1 m[false] = 2 - assert_raise TypeError do + assert_raise Google::Protobuf::TypeError do m[1] = 1 end - assert_raise TypeError do + assert_raise Google::Protobuf::TypeError do m["asdf"] = 1 end @@ -641,7 +655,7 @@ module BasicTest def test_map_msg_enum_valuetypes m = Google::Protobuf::Map.new(:string, :message, TestMessage) m["asdf"] = TestMessage.new - assert_raise TypeError do + assert_raise Google::Protobuf::TypeError do m["jkl;"] = TestMessage2.new end @@ -708,17 +722,17 @@ module BasicTest m.map_string_msg.delete("c") assert m.map_string_msg == { "a" => TestMessage2.new(:foo => 1) } - assert_raise TypeError do + assert_raise Google::Protobuf::TypeError do m.map_string_msg["e"] = TestMessage.new # wrong value type end # ensure nothing was added by the above assert m.map_string_msg == { "a" => TestMessage2.new(:foo => 1) } m.map_string_int32 = Google::Protobuf::Map.new(:string, :int32) - assert_raise TypeError do + assert_raise Google::Protobuf::TypeError do m.map_string_int32 = Google::Protobuf::Map.new(:string, :int64) end - assert_raise TypeError do + assert_raise Google::Protobuf::TypeError do m.map_string_int32 = {} end @@ -1017,7 +1031,7 @@ module BasicTest def test_def_errors s = Google::Protobuf::DescriptorPool.new - assert_raise TypeError do + assert_raise Google::Protobuf::TypeError do s.build do # enum with no default (integer value 0) add_enum "MyEnum" do @@ -1025,7 +1039,7 @@ module BasicTest end end end - assert_raise TypeError do + assert_raise Google::Protobuf::TypeError do s.build do # message with required field (unsupported in proto3) add_message "MyMessage" do @@ -1261,6 +1275,10 @@ module BasicTest Foo.encode_json(Foo.new(bar: bar, baz: [baz1, baz2])) end + def test_json_empty + assert TestMessage.encode_json(TestMessage.new) == '{}' + end + def test_json_emit_defaults # TODO: Fix JSON in JRuby version. return if RUBY_PLATFORM == "java" diff --git a/ruby/tests/well_known_types_test.rb b/ruby/tests/well_known_types_test.rb index bd24c328..f35f7b13 100644 --- a/ruby/tests/well_known_types_test.rb +++ b/ruby/tests/well_known_types_test.rb @@ -60,6 +60,9 @@ class TestWellKnownTypes < Test::Unit::TestCase assert_equal(Google::Protobuf::ListValue.from_a(sublist), struct["sublist"]) + assert_equal true, struct.has_key?("null") + assert_equal false, struct.has_key?("missing_key") + should_equal = { "number" => 12345, "boolean-true" => true, @@ -82,6 +85,9 @@ class TestWellKnownTypes < Test::Unit::TestCase # to_h returns a fully-flattened Ruby structure (Hash and Array). assert_equal(should_equal, struct.to_h) + # Test that we can safely access a missing key + assert_equal(nil, struct["missing_key"]) + # Test that we can assign Struct and ListValue directly. struct["substruct"] = Google::Protobuf::Struct.from_hash(substruct) struct["sublist"] = Google::Protobuf::ListValue.from_a(sublist) @@ -120,11 +126,17 @@ class TestWellKnownTypes < Test::Unit::TestCase end def test_any - any = Google::Protobuf::Any.new ts = Google::Protobuf::Timestamp.new(seconds: 12345, nanos: 6789) + + any = Google::Protobuf::Any.new any.pack(ts) assert any.is(Google::Protobuf::Timestamp) assert_equal ts, any.unpack(Google::Protobuf::Timestamp) + + any = Google::Protobuf::Any.pack(ts) + + assert any.is(Google::Protobuf::Timestamp) + assert_equal ts, any.unpack(Google::Protobuf::Timestamp) end end diff --git a/src/Makefile.am b/src/Makefile.am index 4bb77452..9f829bf6 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -367,10 +367,6 @@ libprotoc_la_SOURCES = \ google/protobuf/compiler/java/java_generator_factory.h \ google/protobuf/compiler/java/java_helpers.cc \ google/protobuf/compiler/java/java_helpers.h \ - google/protobuf/compiler/java/java_lazy_message_field.cc \ - google/protobuf/compiler/java/java_lazy_message_field.h \ - google/protobuf/compiler/java/java_lazy_message_field_lite.cc\ - google/protobuf/compiler/java/java_lazy_message_field_lite.h \ google/protobuf/compiler/java/java_map_field.cc \ google/protobuf/compiler/java/java_map_field.h \ google/protobuf/compiler/java/java_map_field_lite.cc \ @@ -876,7 +872,7 @@ no_warning_test.cc: no_warning_test_LDADD = $(PTHREAD_LIBS) libprotobuf.la libprotoc.la no_warning_test_CXXFLAGS = $(PTHREAD_CFLAGS) $(PTHREAD_DEF) $(ZLIB_DEF) \ - -Wall -Wextra -Werror -Wno-unused-parameter + -Wall -Wextra -Werror -Wno-unused-parameter -Og nodist_no_warning_test_SOURCES = no_warning_test.cc $(protoc_outputs) TESTS = protobuf-test protobuf-lazy-descriptor-test protobuf-lite-test \ diff --git a/src/README.md b/src/README.md index 3cbeb3e6..4ca9a02a 100644 --- a/src/README.md +++ b/src/README.md @@ -1,7 +1,7 @@ Protocol Buffers - Google's data interchange format =================================================== -[![Build Status](https://travis-ci.org/google/protobuf.svg?branch=master)](https://travis-ci.org/google/protobuf) [![Build status](https://ci.appveyor.com/api/projects/status/73ctee6ua4w2ruin?svg=true)](https://ci.appveyor.com/project/protobuf/protobuf) +[![Build status](https://storage.googleapis.com/protobuf-kokoro-results/status-badge/linux-cpp_distcheck.png)](https://fusion.corp.google.com/projectanalysis/current/KOKORO/prod:protobuf%2Fgithub%2Fmaster%2Fubuntu%2Fcpp_distcheck%2Fcontinuous) [![Build status](https://storage.googleapis.com/protobuf-kokoro-results/status-badge/macos-cpp.png)](https://fusion.corp.google.com/projectanalysis/current/KOKORO/prod:protobuf%2Fgithub%2Fmaster%2Fmacos%2Fcpp%2Fcontinuous) [![Build status](https://storage.googleapis.com/protobuf-kokoro-results/status-badge/macos-cpp_distcheck.png)](https://fusion.corp.google.com/projectanalysis/current/KOKORO/prod:protobuf%2Fgithub%2Fmaster%2Fmacos%2Fcpp_distcheck%2Fcontinuous) [![Build status](https://ci.appveyor.com/api/projects/status/73ctee6ua4w2ruin?svg=true)](https://ci.appveyor.com/project/protobuf/protobuf) Copyright 2008 Google Inc. diff --git a/src/google/protobuf/any.pb.cc b/src/google/protobuf/any.pb.cc index 9d632efe..d0fc2905 100644 --- a/src/google/protobuf/any.pb.cc +++ b/src/google/protobuf/any.pb.cc @@ -66,14 +66,14 @@ static ::google::protobuf::Message const * const file_default_instances[] = { reinterpret_cast<const ::google::protobuf::Message*>(&::google::protobuf::_Any_default_instance_), }; -void protobuf_AssignDescriptors() { +static void protobuf_AssignDescriptors() { AddDescriptors(); AssignDescriptors( "google/protobuf/any.proto", schemas, file_default_instances, TableStruct::offsets, file_level_metadata, NULL, NULL); } -void protobuf_AssignDescriptorsOnce() { +static void protobuf_AssignDescriptorsOnce() { static ::google::protobuf::internal::once_flag once; ::google::protobuf::internal::call_once(once, protobuf_AssignDescriptors); } @@ -84,7 +84,7 @@ void protobuf_RegisterTypes(const ::std::string&) { ::google::protobuf::internal::RegisterAllTypes(file_level_metadata, 1); } -void AddDescriptorsImpl() { +static void AddDescriptorsImpl() { InitDefaults(); static const char descriptor[] GOOGLE_PROTOBUF_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold) = { "\n\031google/protobuf/any.proto\022\017google.prot" diff --git a/src/google/protobuf/api.pb.cc b/src/google/protobuf/api.pb.cc index e0a249d0..273307c7 100644 --- a/src/google/protobuf/api.pb.cc +++ b/src/google/protobuf/api.pb.cc @@ -149,14 +149,14 @@ static ::google::protobuf::Message const * const file_default_instances[] = { reinterpret_cast<const ::google::protobuf::Message*>(&::google::protobuf::_Mixin_default_instance_), }; -void protobuf_AssignDescriptors() { +static void protobuf_AssignDescriptors() { AddDescriptors(); AssignDescriptors( "google/protobuf/api.proto", schemas, file_default_instances, TableStruct::offsets, file_level_metadata, NULL, NULL); } -void protobuf_AssignDescriptorsOnce() { +static void protobuf_AssignDescriptorsOnce() { static ::google::protobuf::internal::once_flag once; ::google::protobuf::internal::call_once(once, protobuf_AssignDescriptors); } @@ -167,7 +167,7 @@ void protobuf_RegisterTypes(const ::std::string&) { ::google::protobuf::internal::RegisterAllTypes(file_level_metadata, 3); } -void AddDescriptorsImpl() { +static void AddDescriptorsImpl() { InitDefaults(); static const char descriptor[] GOOGLE_PROTOBUF_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold) = { "\n\031google/protobuf/api.proto\022\017google.prot" @@ -414,7 +414,7 @@ bool Api::MergePartialFromCodedStream( case 7: { if (static_cast< ::google::protobuf::uint8>(tag) == static_cast< ::google::protobuf::uint8>(56u /* 56 & 0xFF */)) { - int value; + int value = 0; DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>( input, &value))); @@ -947,7 +947,7 @@ bool Method::MergePartialFromCodedStream( case 7: { if (static_cast< ::google::protobuf::uint8>(tag) == static_cast< ::google::protobuf::uint8>(56u /* 56 & 0xFF */)) { - int value; + int value = 0; DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>( input, &value))); diff --git a/src/google/protobuf/arena.cc b/src/google/protobuf/arena.cc index c117c9e5..c117c9e5 100755..100644 --- a/src/google/protobuf/arena.cc +++ b/src/google/protobuf/arena.cc diff --git a/src/google/protobuf/arenastring.h b/src/google/protobuf/arenastring.h index 168fc972..168fc972 100755..100644 --- a/src/google/protobuf/arenastring.h +++ b/src/google/protobuf/arenastring.h diff --git a/src/google/protobuf/compiler/cpp/cpp_bootstrap_unittest.cc b/src/google/protobuf/compiler/cpp/cpp_bootstrap_unittest.cc index 4e150fe3..24f1fe45 100644 --- a/src/google/protobuf/compiler/cpp/cpp_bootstrap_unittest.cc +++ b/src/google/protobuf/compiler/cpp/cpp_bootstrap_unittest.cc @@ -95,7 +95,7 @@ class MockGeneratorContext : public GeneratorContext { string actual_contents; GOOGLE_CHECK_OK( - File::GetContents(TestSourceDir() + "/" + physical_filename, + File::GetContentsAsText(TestSourceDir() + "/" + physical_filename, &actual_contents, true)); EXPECT_TRUE(actual_contents == *expected_contents) << physical_filename diff --git a/src/google/protobuf/compiler/cpp/cpp_enum_field.cc b/src/google/protobuf/compiler/cpp/cpp_enum_field.cc index 50c7b5f3..828d0be5 100644 --- a/src/google/protobuf/compiler/cpp/cpp_enum_field.cc +++ b/src/google/protobuf/compiler/cpp/cpp_enum_field.cc @@ -128,7 +128,7 @@ GenerateCopyConstructorCode(io::Printer* printer) const { void EnumFieldGenerator:: GenerateMergeFromCodedStream(io::Printer* printer) const { printer->Print(variables_, - "int value;\n" + "int value = 0;\n" "DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<\n" " int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>(\n" " input, &value)));\n"); @@ -334,7 +334,7 @@ void RepeatedEnumFieldGenerator:: GenerateMergeFromCodedStream(io::Printer* printer) const { // Don't use ReadRepeatedPrimitive here so that the enum can be validated. printer->Print(variables_, - "int value;\n" + "int value = 0;\n" "DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<\n" " int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>(\n" " input, &value)));\n"); @@ -399,7 +399,7 @@ GenerateMergeFromCodedStreamWithPacking(io::Printer* printer) const { "::google::protobuf::io::CodedInputStream::Limit limit = " "input->PushLimit(static_cast<int>(length));\n" "while (input->BytesUntilLimit() > 0) {\n" - " int value;\n" + " int value = 0;\n" " DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<\n" " int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>(\n" " input, &value)));\n"); diff --git a/src/google/protobuf/compiler/cpp/cpp_file.cc b/src/google/protobuf/compiler/cpp/cpp_file.cc index 42525687..02f360bb 100644 --- a/src/google/protobuf/compiler/cpp/cpp_file.cc +++ b/src/google/protobuf/compiler/cpp/cpp_file.cc @@ -791,7 +791,7 @@ void FileGenerator::GenerateReflectionInitializationCode(io::Printer* printer) { // AssignDescriptors(). All later times, waits for the first call to // complete and then returns. printer->Print( - "void protobuf_AssignDescriptors() {\n" + "static void protobuf_AssignDescriptors() {\n" // Make sure the file has found its way into the pool. If a descriptor // is requested *during* static init then AddDescriptors() may not have // been called yet, so we call it manually. Note that it's fine if @@ -812,7 +812,7 @@ void FileGenerator::GenerateReflectionInitializationCode(io::Printer* printer) { printer->Print( "}\n" "\n" - "void protobuf_AssignDescriptorsOnce() {\n" + "static void protobuf_AssignDescriptorsOnce() {\n" " static ::google::protobuf::internal::once_flag once;\n" " ::google::protobuf::internal::call_once(once, protobuf_AssignDescriptors);\n" "}\n" @@ -850,7 +850,7 @@ void FileGenerator::GenerateReflectionInitializationCode(io::Printer* printer) { // Now generate the AddDescriptors() function. printer->Print( - "void AddDescriptorsImpl() {\n" + "static void AddDescriptorsImpl() {\n" " InitDefaults();\n"); printer->Indent(); diff --git a/src/google/protobuf/compiler/cpp/cpp_message.cc b/src/google/protobuf/compiler/cpp/cpp_message.cc index 8c2336af..778fc406 100644 --- a/src/google/protobuf/compiler/cpp/cpp_message.cc +++ b/src/google/protobuf/compiler/cpp/cpp_message.cc @@ -2280,7 +2280,7 @@ GenerateArenaDestructorCode(io::Printer* printer) { "classname", classname_); } else { printer->Print( - "void $classname$::RegisterArenaDtor(::google::protobuf::Arena* arena) {\n" + "void $classname$::RegisterArenaDtor(::google::protobuf::Arena*) {\n" "}\n", "classname", classname_); } diff --git a/src/google/protobuf/compiler/csharp/csharp_bootstrap_unittest.cc b/src/google/protobuf/compiler/csharp/csharp_bootstrap_unittest.cc index 8c38e52f..33c56198 100644 --- a/src/google/protobuf/compiler/csharp/csharp_bootstrap_unittest.cc +++ b/src/google/protobuf/compiler/csharp/csharp_bootstrap_unittest.cc @@ -90,7 +90,7 @@ class MockGeneratorContext : public GeneratorContext { string actual_contents; GOOGLE_CHECK_OK( - File::GetContents(TestSourceDir() + "/" + physical_filename, + File::GetContentsAsText(TestSourceDir() + "/" + physical_filename, &actual_contents, true)) << "Unable to get " << physical_filename; EXPECT_TRUE(actual_contents == *expected_contents) diff --git a/src/google/protobuf/compiler/csharp/csharp_helpers.cc b/src/google/protobuf/compiler/csharp/csharp_helpers.cc index 5bca1ffa..04b61074 100644 --- a/src/google/protobuf/compiler/csharp/csharp_helpers.cc +++ b/src/google/protobuf/compiler/csharp/csharp_helpers.cc @@ -169,7 +169,7 @@ std::string UnderscoresToCamelCase(const std::string& input, } } // Add a trailing "_" if the name should be altered. - if (input[input.size() - 1] == '#') { + if (input.size() > 0 && input[input.size() - 1] == '#') { result += '_'; } return result; diff --git a/src/google/protobuf/compiler/importer.cc b/src/google/protobuf/compiler/importer.cc index c3831e72..58498aaa 100644 --- a/src/google/protobuf/compiler/importer.cc +++ b/src/google/protobuf/compiler/importer.cc @@ -103,7 +103,7 @@ class SourceTreeDescriptorDatabase::SingleFileErrorCollector bool had_errors() { return had_errors_; } // implements ErrorCollector --------------------------------------- - void AddError(int line, int column, const string& message) { + void AddError(int line, int column, const string& message) override { if (multi_file_error_collector_ != NULL) { multi_file_error_collector_->AddError(filename_, line, column, message); } diff --git a/src/google/protobuf/compiler/importer.h b/src/google/protobuf/compiler/importer.h index a4ffcf87..bf6d3de3 100644 --- a/src/google/protobuf/compiler/importer.h +++ b/src/google/protobuf/compiler/importer.h @@ -96,12 +96,13 @@ class LIBPROTOBUF_EXPORT SourceTreeDescriptorDatabase : public DescriptorDatabas } // implements DescriptorDatabase ----------------------------------- - bool FindFileByName(const string& filename, FileDescriptorProto* output); + bool FindFileByName(const string& filename, + FileDescriptorProto* output) override; bool FindFileContainingSymbol(const string& symbol_name, - FileDescriptorProto* output); + FileDescriptorProto*output) override; bool FindFileContainingExtension(const string& containing_type, int field_number, - FileDescriptorProto* output); + FileDescriptorProto* output) override; private: class SingleFileErrorCollector; @@ -119,13 +120,13 @@ class LIBPROTOBUF_EXPORT SourceTreeDescriptorDatabase : public DescriptorDatabas const string& element_name, const Message* descriptor, ErrorLocation location, - const string& message); + const string& message) override; virtual void AddWarning(const string& filename, const string& element_name, const Message* descriptor, ErrorLocation location, - const string& message); + const string& message) override; private: SourceTreeDescriptorDatabase* owner_; @@ -293,9 +294,9 @@ class LIBPROTOBUF_EXPORT DiskSourceTree : public SourceTree { bool VirtualFileToDiskFile(const string& virtual_file, string* disk_file); // implements SourceTree ------------------------------------------- - virtual io::ZeroCopyInputStream* Open(const string& filename); + virtual io::ZeroCopyInputStream* Open(const string& filename) override; - virtual string GetLastErrorMessage(); + virtual string GetLastErrorMessage() override; private: struct Mapping { diff --git a/src/google/protobuf/compiler/java/java_enum_field.cc b/src/google/protobuf/compiler/java/java_enum_field.cc index 0686ea0f..ef64d88b 100644 --- a/src/google/protobuf/compiler/java/java_enum_field.cc +++ b/src/google/protobuf/compiler/java/java_enum_field.cc @@ -305,11 +305,15 @@ GenerateBuildingCode(io::Printer* printer) const { if (SupportFieldPresence(descriptor_->file())) { printer->Print(variables_, "if ($get_has_field_bit_from_local$) {\n" + " result.$name$_ = $name$_;\n" " $set_has_field_bit_to_local$;\n" + "} else {\n" + " result.$name$_ = $default_number$;\n" "}\n"); + } else { + printer->Print(variables_, + "result.$name$_ = $name$_;\n"); } - printer->Print(variables_, - "result.$name$_ = $name$_;\n"); } void ImmutableEnumFieldGenerator:: diff --git a/src/google/protobuf/compiler/java/java_lazy_message_field.cc b/src/google/protobuf/compiler/java/java_lazy_message_field.cc deleted file mode 100644 index abf8e55c..00000000 --- a/src/google/protobuf/compiler/java/java_lazy_message_field.cc +++ /dev/null @@ -1,814 +0,0 @@ -// 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: niwasaki@google.com (Naoki Iwasaki) -// Based on original Protocol Buffers design by -// Sanjay Ghemawat, Jeff Dean, and others. - -#include <google/protobuf/compiler/java/java_context.h> -#include <google/protobuf/compiler/java/java_lazy_message_field.h> -#include <google/protobuf/compiler/java/java_doc_comment.h> -#include <google/protobuf/compiler/java/java_helpers.h> -#include <google/protobuf/io/printer.h> - -namespace google { -namespace protobuf { -namespace compiler { -namespace java { - -ImmutableLazyMessageFieldGenerator:: -ImmutableLazyMessageFieldGenerator( - const FieldDescriptor* descriptor, - int messageBitIndex, - int builderBitIndex, - Context* context) - : ImmutableMessageFieldGenerator( - descriptor, messageBitIndex, builderBitIndex, context) { -} - -ImmutableLazyMessageFieldGenerator::~ImmutableLazyMessageFieldGenerator() {} - -void ImmutableLazyMessageFieldGenerator:: -GenerateMembers(io::Printer* printer) const { - printer->Print(variables_, - "private com.google.protobuf.LazyFieldLite $name$_ =\n" - " new com.google.protobuf.LazyFieldLite();\n"); - - PrintExtraFieldInfo(variables_, printer); - WriteFieldDocComment(printer, descriptor_); - printer->Print(variables_, - "$deprecation$public boolean has$capitalized_name$() {\n" - " return $get_has_field_bit_message$;\n" - "}\n"); - WriteFieldDocComment(printer, descriptor_); - - printer->Print(variables_, - "$deprecation$public $type$ get$capitalized_name$() {\n" - " return ($type$) $name$_.getValue($type$.getDefaultInstance());\n" - "}\n"); - WriteFieldDocComment(printer, descriptor_); - printer->Print(variables_, - "$deprecation$public $type$OrBuilder get$capitalized_name$OrBuilder() {\n" - " return $name$_;\n" - "}\n"); -} - -void ImmutableLazyMessageFieldGenerator:: -GenerateBuilderMembers(io::Printer* printer) const { - // When using nested-builders, the code initially works just like the - // non-nested builder case. It only creates a nested builder lazily on - // demand and then forever delegates to it after creation. - - printer->Print(variables_, - "private com.google.protobuf.LazyFieldLite $name$_ =\n" - " new com.google.protobuf.LazyFieldLite();\n"); - - printer->Print(variables_, - // If this builder is non-null, it is used and the other fields are - // ignored. - "private com.google.protobuf.SingleFieldBuilder$ver$<\n" - " $type$, $type$.Builder, $type$OrBuilder> $name$Builder_;" - "\n"); - - // The comments above the methods below are based on a hypothetical - // field of type "Field" called "Field". - - // boolean hasField() - WriteFieldDocComment(printer, descriptor_); - printer->Print(variables_, - "$deprecation$public boolean has$capitalized_name$() {\n" - " return $get_has_field_bit_builder$;\n" - "}\n"); - - printer->Print(variables_, - "$deprecation$public $type$ get$capitalized_name$() {\n" - " return ($type$) $name$_.getValue($type$.getDefaultInstance());\n" - "}\n"); - - // Field.Builder setField(Field value) - WriteFieldDocComment(printer, descriptor_); - PrintNestedBuilderFunction(printer, - "$deprecation$public Builder set$capitalized_name$($type$ value)", - - "if (value == null) {\n" - " throw new NullPointerException();\n" - "}\n" - "$name$_.setValue(value);\n" - "$on_changed$\n", - - NULL, // Lazy fields are supported only for lite-runtime. - - "$set_has_field_bit_builder$;\n" - "return this;\n"); - - // Field.Builder setField(Field.Builder builderForValue) - WriteFieldDocComment(printer, descriptor_); - PrintNestedBuilderFunction(printer, - "$deprecation$public Builder set$capitalized_name$(\n" - " $type$.Builder builderForValue)", - - "$name$_.setValue(builderForValue.build());\n" - "$on_changed$\n", - - NULL, - - "$set_has_field_bit_builder$;\n" - "return this;\n"); - - // Field.Builder mergeField(Field value) - WriteFieldDocComment(printer, descriptor_); - PrintNestedBuilderFunction(printer, - "$deprecation$public Builder merge$capitalized_name$($type$ value)", - - "if ($get_has_field_bit_builder$ &&\n" - " !$name$_.containsDefaultInstance()) {\n" - " $name$_.setValue(\n" - " $type$.newBuilder(\n" - " get$capitalized_name$()).mergeFrom(value).buildPartial());\n" - "} else {\n" - " $name$_.setValue(value);\n" - "}\n" - "$on_changed$\n", - - NULL, - - "$set_has_field_bit_builder$;\n" - "return this;\n"); - - // Field.Builder clearField() - WriteFieldDocComment(printer, descriptor_); - PrintNestedBuilderFunction(printer, - "$deprecation$public Builder clear$capitalized_name$()", - - "$name$_.clear();\n" - "$on_changed$\n", - - NULL, - - "$clear_has_field_bit_builder$;\n" - "return this;\n"); - - WriteFieldDocComment(printer, descriptor_); - printer->Print(variables_, - "$deprecation$public $type$.Builder get$capitalized_name$Builder() {\n" - " $set_has_field_bit_builder$;\n" - " $on_changed$\n" - " return get$capitalized_name$FieldBuilder().getBuilder();\n" - "}\n"); - WriteFieldDocComment(printer, descriptor_); - printer->Print(variables_, - "$deprecation$public $type$OrBuilder get$capitalized_name$OrBuilder() {\n" - " if ($name$Builder_ != null) {\n" - " return $name$Builder_.getMessageOrBuilder();\n" - " } else {\n" - " return $name$_;\n" - " }\n" - "}\n"); - WriteFieldDocComment(printer, descriptor_); - printer->Print(variables_, - "private com.google.protobuf.SingleFieldBuilder$ver$<\n" - " $type$, $type$.Builder, $type$OrBuilder> \n" - " get$capitalized_name$FieldBuilder() {\n" - " if ($name$Builder_ == null) {\n" - " $name$Builder_ = new com.google.protobuf.SingleFieldBuilder$ver$<\n" - " $type$, $type$.Builder, $type$OrBuilder>(\n" - " $name$_,\n" - " getParentForChildren(),\n" - " isClean());\n" - " $name$_ = null;\n" - " }\n" - " return $name$Builder_;\n" - "}\n"); -} - - -void ImmutableLazyMessageFieldGenerator:: -GenerateInitializationCode(io::Printer* printer) const { - printer->Print(variables_, "$name$_.clear();\n"); -} - -void ImmutableLazyMessageFieldGenerator:: -GenerateBuilderClearCode(io::Printer* printer) const { - printer->Print(variables_, "$name$_.clear();\n"); - printer->Print(variables_, "$clear_has_field_bit_builder$;\n"); -} - -void ImmutableLazyMessageFieldGenerator:: -GenerateMergingCode(io::Printer* printer) const { - printer->Print(variables_, - "if (other.has$capitalized_name$()) {\n" - " $name$_.merge(other.$name$_);\n" - " $set_has_field_bit_builder$;\n" - "}\n"); -} - -void ImmutableLazyMessageFieldGenerator:: -GenerateBuildingCode(io::Printer* printer) const { - printer->Print(variables_, - "if ($get_has_field_bit_from_local$) {\n" - " $set_has_field_bit_to_local$;\n" - "}\n"); - - printer->Print(variables_, - "result.$name$_.set(\n" - " $name$_);\n"); -} - -void ImmutableLazyMessageFieldGenerator:: -GenerateParsingCode(io::Printer* printer) const { - printer->Print(variables_, - "$name$_.setByteString(input.readBytes(), extensionRegistry);\n"); - printer->Print(variables_, - "$set_has_field_bit_message$;\n"); -} - -void ImmutableLazyMessageFieldGenerator:: -GenerateSerializationCode(io::Printer* printer) const { - // Do not de-serialize lazy fields. - printer->Print(variables_, - "if ($get_has_field_bit_message$) {\n" - " output.writeBytes($number$, $name$_.toByteString());\n" - "}\n"); -} - -void ImmutableLazyMessageFieldGenerator:: -GenerateSerializedSizeCode(io::Printer* printer) const { - printer->Print(variables_, - "if ($get_has_field_bit_message$) {\n" - " size += com.google.protobuf.CodedOutputStream\n" - " .computeLazyFieldSize($number$, $name$_);\n" - "}\n"); -} - -// =================================================================== - -ImmutableLazyMessageOneofFieldGenerator:: -ImmutableLazyMessageOneofFieldGenerator(const FieldDescriptor* descriptor, - int messageBitIndex, - int builderBitIndex, - Context* context) - : ImmutableLazyMessageFieldGenerator( - descriptor, messageBitIndex, builderBitIndex, context) { - const OneofGeneratorInfo* info = - context->GetOneofGeneratorInfo(descriptor->containing_oneof()); - SetCommonOneofVariables(descriptor, info, &variables_); - variables_["lazy_type"] = "com.google.protobuf.LazyFieldLite"; -} - -ImmutableLazyMessageOneofFieldGenerator:: -~ImmutableLazyMessageOneofFieldGenerator() {} - -void ImmutableLazyMessageOneofFieldGenerator:: -GenerateMembers(io::Printer* printer) const { - PrintExtraFieldInfo(variables_, printer); - WriteFieldDocComment(printer, descriptor_); - - printer->Print(variables_, - "$deprecation$public boolean has$capitalized_name$() {\n" - " return $has_oneof_case_message$;\n" - "}\n"); - WriteFieldDocComment(printer, descriptor_); - - printer->Print(variables_, - "$deprecation$public $type$ get$capitalized_name$() {\n" - " if ($has_oneof_case_message$) {\n" - " return ($type$) (($lazy_type$) $oneof_name$_).getValue(\n" - " $type$.getDefaultInstance());\n" - " }\n" - " return $type$.getDefaultInstance();\n" - "}\n"); -} - -void ImmutableLazyMessageOneofFieldGenerator:: -GenerateBuilderMembers(io::Printer* printer) const { - // boolean hasField() - WriteFieldDocComment(printer, descriptor_); - printer->Print(variables_, - "$deprecation$public boolean has$capitalized_name$() {\n" - " return $has_oneof_case_message$;\n" - "}\n"); - - printer->Print(variables_, - "$deprecation$public $type$ get$capitalized_name$() {\n" - " if ($has_oneof_case_message$) {\n" - " return ($type$) (($lazy_type$) $oneof_name$_).getValue(\n" - " $type$.getDefaultInstance());\n" - " }\n" - " return $type$.getDefaultInstance();\n" - "}\n"); - - // Field.Builder setField(Field value) - WriteFieldDocComment(printer, descriptor_); - PrintNestedBuilderFunction(printer, - "$deprecation$public Builder set$capitalized_name$($type$ value)", - - "if (value == null) {\n" - " throw new NullPointerException();\n" - "}\n" - "if (!($has_oneof_case_message$)) {\n" - " $oneof_name$_ = new $lazy_type$();\n" - " $set_oneof_case_message$;\n" - "}\n" - "(($lazy_type$) $oneof_name$_).setValue(value);\n" - "$on_changed$\n", - - NULL, // Lazy fields are supported only for lite-runtime. - - "return this;\n"); - - // Field.Builder setField(Field.Builder builderForValue) - WriteFieldDocComment(printer, descriptor_); - PrintNestedBuilderFunction(printer, - "$deprecation$public Builder set$capitalized_name$(\n" - " $type$.Builder builderForValue)", - - "if (!($has_oneof_case_message$)) {\n" - " $oneof_name$_ = new $lazy_type$();\n" - " $set_oneof_case_message$;\n" - "}\n" - "(($lazy_type$) $oneof_name$_).setValue(builderForValue.build());\n" - "$on_changed$\n", - - NULL, - - "return this;\n"); - - // Field.Builder mergeField(Field value) - WriteFieldDocComment(printer, descriptor_); - PrintNestedBuilderFunction(printer, - "$deprecation$public Builder merge$capitalized_name$($type$ value)", - - "if ($has_oneof_case_message$ &&\n" - " !(($lazy_type$) $oneof_name$_).containsDefaultInstance()) {\n" - " (($lazy_type$) $oneof_name$_).setValue(\n" - " $type$.newBuilder(\n" - " get$capitalized_name$()).mergeFrom(value).buildPartial());\n" - "} else {\n" - " if (!($has_oneof_case_message$)) {\n" - " $oneof_name$_ = new $lazy_type$();\n" - " $set_oneof_case_message$;\n" - " }\n" - " (($lazy_type$) $oneof_name$_).setValue(value);\n" - "}\n" - "$on_changed$\n", - - NULL, - - "return this;\n"); - - // Field.Builder clearField() - WriteFieldDocComment(printer, descriptor_); - PrintNestedBuilderFunction(printer, - "$deprecation$public Builder clear$capitalized_name$()", - - "if ($has_oneof_case_message$) {\n" - " $clear_oneof_case_message$;\n" - " $oneof_name$_ = null;\n" - " $on_changed$\n" - "}\n", - - NULL, - - "return this;\n"); -} - -void ImmutableLazyMessageOneofFieldGenerator:: -GenerateMergingCode(io::Printer* printer) const { - printer->Print(variables_, - "if (!($has_oneof_case_message$)) {\n" - " $oneof_name$_ = new $lazy_type$();\n" - "}\n" - "(($lazy_type$) $oneof_name$_).merge(\n" - " ($lazy_type$) other.$oneof_name$_);\n" - "$set_oneof_case_message$;\n"); -} - -void ImmutableLazyMessageOneofFieldGenerator:: -GenerateBuildingCode(io::Printer* printer) const { - printer->Print(variables_, - "if ($has_oneof_case_message$) {\n"); - printer->Indent(); - - printer->Print(variables_, - "result.$oneof_name$_ = new $lazy_type$();\n" - "(($lazy_type$) result.$oneof_name$_).set(\n" - " (($lazy_type$) $oneof_name$_));\n"); - printer->Outdent(); - printer->Print("}\n"); -} - -void ImmutableLazyMessageOneofFieldGenerator:: -GenerateParsingCode(io::Printer* printer) const { - printer->Print(variables_, - "if (!($has_oneof_case_message$)) {\n" - " $oneof_name$_ = new $lazy_type$();\n" - "}\n" - "(($lazy_type$) $oneof_name$_).setByteString(\n" - " input.readBytes(), extensionRegistry);\n" - "$set_oneof_case_message$;\n"); -} - -void ImmutableLazyMessageOneofFieldGenerator:: -GenerateSerializationCode(io::Printer* printer) const { - // Do not de-serialize lazy fields. - printer->Print(variables_, - "if ($has_oneof_case_message$) {\n" - " output.writeBytes(\n" - " $number$, (($lazy_type$) $oneof_name$_).toByteString());\n" - "}\n"); -} - -void ImmutableLazyMessageOneofFieldGenerator:: -GenerateSerializedSizeCode(io::Printer* printer) const { - printer->Print(variables_, - "if ($has_oneof_case_message$) {\n" - " size += com.google.protobuf.CodedOutputStream\n" - " .computeLazyFieldSize($number$, ($lazy_type$) $oneof_name$_);\n" - "}\n"); -} - -// =================================================================== - -RepeatedImmutableLazyMessageFieldGenerator:: -RepeatedImmutableLazyMessageFieldGenerator( - const FieldDescriptor* descriptor, - int messageBitIndex, - int builderBitIndex, - Context* context) - : RepeatedImmutableMessageFieldGenerator( - descriptor, messageBitIndex, builderBitIndex, context) { -} - - -RepeatedImmutableLazyMessageFieldGenerator:: -~RepeatedImmutableLazyMessageFieldGenerator() {} - -void RepeatedImmutableLazyMessageFieldGenerator:: -GenerateMembers(io::Printer* printer) const { - printer->Print(variables_, - "private java.util.List<com.google.protobuf.LazyFieldLite> $name$_;\n"); - PrintExtraFieldInfo(variables_, printer); - WriteFieldDocComment(printer, descriptor_); - printer->Print(variables_, - "$deprecation$public java.util.List<$type$>\n" - " get$capitalized_name$List() {\n" - " java.util.List<$type$> list =\n" - " new java.util.ArrayList<$type$>($name$_.size());\n" - " for (com.google.protobuf.LazyFieldLite lf : $name$_) {\n" - " list.add(($type$) lf.getValue($type$.getDefaultInstance()));\n" - " }\n" - " return list;\n" - "}\n"); - WriteFieldDocComment(printer, descriptor_); - printer->Print(variables_, - "$deprecation$public java.util.List<? extends $type$OrBuilder>\n" - " get$capitalized_name$OrBuilderList() {\n" - " return get$capitalized_name$List();\n" - "}\n"); - WriteFieldDocComment(printer, descriptor_); - printer->Print(variables_, - "$deprecation$public int get$capitalized_name$Count() {\n" - " return $name$_.size();\n" - "}\n"); - WriteFieldDocComment(printer, descriptor_); - printer->Print(variables_, - "$deprecation$public $type$ get$capitalized_name$(int index) {\n" - " return ($type$)\n" - " $name$_.get(index).getValue($type$.getDefaultInstance());\n" - "}\n"); - WriteFieldDocComment(printer, descriptor_); - printer->Print(variables_, - "$deprecation$public $type$OrBuilder get$capitalized_name$OrBuilder(\n" - " int index) {\n" - " return ($type$OrBuilder)\n" - " $name$_.get(index).getValue($type$.getDefaultInstance());\n" - "}\n"); -} - -void RepeatedImmutableLazyMessageFieldGenerator:: -GenerateBuilderMembers(io::Printer* printer) const { - // When using nested-builders, the code initially works just like the - // non-nested builder case. It only creates a nested builder lazily on - // demand and then forever delegates to it after creation. - - printer->Print(variables_, - "private java.util.List<com.google.protobuf.LazyFieldLite> $name$_ =\n" - " java.util.Collections.emptyList();\n" - - "private void ensure$capitalized_name$IsMutable() {\n" - " if (!$get_mutable_bit_builder$) {\n" - " $name$_ =\n" - " new java.util.ArrayList<com.google.protobuf.LazyFieldLite>(\n" - " $name$_);\n" - " $set_mutable_bit_builder$;\n" - " }\n" - "}\n" - "\n"); - - printer->Print(variables_, - // If this builder is non-null, it is used and the other fields are - // ignored. - "private com.google.protobuf.RepeatedFieldBuilder$ver$<\n" - " $type$, $type$.Builder, $type$OrBuilder> $name$Builder_;\n" - "\n"); - - // The comments above the methods below are based on a hypothetical - // repeated field of type "Field" called "RepeatedField". - - // List<Field> getRepeatedFieldList() - WriteFieldDocComment(printer, descriptor_); - PrintNestedBuilderFunction(printer, - "$deprecation$public java.util.List<$type$> get$capitalized_name$List()", - - "java.util.List<$type$> list =\n" - " new java.util.ArrayList<$type$>($name$_.size());\n" - "for (com.google.protobuf.LazyFieldLite lf : $name$_) {\n" - " list.add(($type$) lf.getValue($type$.getDefaultInstance()));\n" - "}\n" - "return java.util.Collections.unmodifiableList(list);\n", - - "return $name$Builder_.getMessageList();\n", - - NULL); - - // int getRepeatedFieldCount() - WriteFieldDocComment(printer, descriptor_); - PrintNestedBuilderFunction(printer, - "$deprecation$public int get$capitalized_name$Count()", - - "return $name$_.size();\n", - "return $name$Builder_.getCount();\n", - - NULL); - - // Field getRepeatedField(int index) - WriteFieldDocComment(printer, descriptor_); - PrintNestedBuilderFunction(printer, - "$deprecation$public $type$ get$capitalized_name$(int index)", - - "return ($type$) $name$_.get(index).getValue(\n" - " $type$.getDefaultInstance());\n", - - "return $name$Builder_.getMessage(index);\n", - - NULL); - - // Builder setRepeatedField(int index, Field value) - WriteFieldDocComment(printer, descriptor_); - PrintNestedBuilderFunction(printer, - "$deprecation$public Builder set$capitalized_name$(\n" - " int index, $type$ value)", - "if (value == null) {\n" - " throw new NullPointerException();\n" - "}\n" - "ensure$capitalized_name$IsMutable();\n" - "$name$_.set(index, com.google.protobuf.LazyFieldLite.fromValue(value));\n" - "$on_changed$\n", - "$name$Builder_.setMessage(index, value);\n", - "return this;\n"); - - // Builder setRepeatedField(int index, Field.Builder builderForValue) - WriteFieldDocComment(printer, descriptor_); - PrintNestedBuilderFunction(printer, - "$deprecation$public Builder set$capitalized_name$(\n" - " int index, $type$.Builder builderForValue)", - - "ensure$capitalized_name$IsMutable();\n" - "$name$_.set(index, com.google.protobuf.LazyFieldLite.fromValue(\n" - " builderForValue.build()));\n" - "$on_changed$\n", - - "$name$Builder_.setMessage(index, builderForValue.build());\n", - - "return this;\n"); - - // Builder addRepeatedField(Field value) - WriteFieldDocComment(printer, descriptor_); - PrintNestedBuilderFunction(printer, - "$deprecation$public Builder add$capitalized_name$($type$ value)", - - "if (value == null) {\n" - " throw new NullPointerException();\n" - "}\n" - "ensure$capitalized_name$IsMutable();\n" - "$name$_.add(com.google.protobuf.LazyFieldLite.fromValue(value));\n" - - "$on_changed$\n", - - "$name$Builder_.addMessage(value);\n", - - "return this;\n"); - - // Builder addRepeatedField(int index, Field value) - WriteFieldDocComment(printer, descriptor_); - PrintNestedBuilderFunction(printer, - "$deprecation$public Builder add$capitalized_name$(\n" - " int index, $type$ value)", - - "if (value == null) {\n" - " throw new NullPointerException();\n" - "}\n" - "ensure$capitalized_name$IsMutable();\n" - "$name$_.add(index, com.google.protobuf.LazyFieldLite.fromValue(value));\n" - "$on_changed$\n", - - "$name$Builder_.addMessage(index, value);\n", - - "return this;\n"); - - // Builder addRepeatedField(Field.Builder builderForValue) - WriteFieldDocComment(printer, descriptor_); - PrintNestedBuilderFunction(printer, - "$deprecation$public Builder add$capitalized_name$(\n" - " $type$.Builder builderForValue)", - - "ensure$capitalized_name$IsMutable();\n" - "$name$_.add(com.google.protobuf.LazyFieldLite.fromValue(\n" - " builderForValue.build()));\n" - "$on_changed$\n", - - "$name$Builder_.addMessage(builderForValue.build());\n", - - "return this;\n"); - - // Builder addRepeatedField(int index, Field.Builder builderForValue) - WriteFieldDocComment(printer, descriptor_); - PrintNestedBuilderFunction(printer, - "$deprecation$public Builder add$capitalized_name$(\n" - " int index, $type$.Builder builderForValue)", - - "ensure$capitalized_name$IsMutable();\n" - "$name$_.add(index, com.google.protobuf.LazyFieldLite.fromValue(\n" - " builderForValue.build()));\n" - "$on_changed$\n", - - "$name$Builder_.addMessage(index, builderForValue.build());\n", - - "return this;\n"); - - // Builder addAllRepeatedField(Iterable<Field> values) - WriteFieldDocComment(printer, descriptor_); - PrintNestedBuilderFunction(printer, - "$deprecation$public Builder addAll$capitalized_name$(\n" - " java.lang.Iterable<? extends $type$> values)", - - "ensure$capitalized_name$IsMutable();\n" - "for (com.google.protobuf.MessageLite v : values) {\n" - " $name$_.add(com.google.protobuf.LazyFieldLite.fromValue(v));\n" - "}\n" - "$on_changed$\n", - - "$name$Builder_.addAllMessages(values);\n", - - "return this;\n"); - - // Builder clearAllRepeatedField() - WriteFieldDocComment(printer, descriptor_); - PrintNestedBuilderFunction(printer, - "$deprecation$public Builder clear$capitalized_name$()", - - "$name$_ = java.util.Collections.emptyList();\n" - "$clear_mutable_bit_builder$;\n" - "$on_changed$\n", - - "$name$Builder_.clear();\n", - - "return this;\n"); - - // Builder removeRepeatedField(int index) - WriteFieldDocComment(printer, descriptor_); - PrintNestedBuilderFunction(printer, - "$deprecation$public Builder remove$capitalized_name$(int index)", - - "ensure$capitalized_name$IsMutable();\n" - "$name$_.remove(index);\n" - "$on_changed$\n", - - "$name$Builder_.remove(index);\n", - - "return this;\n"); - - WriteFieldDocComment(printer, descriptor_); - printer->Print(variables_, - "$deprecation$public $type$.Builder get$capitalized_name$Builder(\n" - " int index) {\n" - " return get$capitalized_name$FieldBuilder().getBuilder(index);\n" - "}\n"); - - WriteFieldDocComment(printer, descriptor_); - printer->Print(variables_, - "$deprecation$public $type$OrBuilder get$capitalized_name$OrBuilder(\n" - " int index) {\n" - " if ($name$Builder_ == null) {\n" - " return $name$_.get(index);" - " } else {\n" - " return $name$Builder_.getMessageOrBuilder(index);\n" - " }\n" - "}\n"); - - WriteFieldDocComment(printer, descriptor_); - printer->Print(variables_, - "$deprecation$public java.util.List<? extends $type$OrBuilder> \n" - " get$capitalized_name$OrBuilderList() {\n" - " if ($name$Builder_ != null) {\n" - " return $name$Builder_.getMessageOrBuilderList();\n" - " } else {\n" - " return java.util.Collections.unmodifiableList($name$_);\n" - " }\n" - "}\n"); - - WriteFieldDocComment(printer, descriptor_); - printer->Print(variables_, - "$deprecation$public $type$.Builder add$capitalized_name$Builder() {\n" - " return get$capitalized_name$FieldBuilder().addBuilder(\n" - " $type$.getDefaultInstance());\n" - "}\n"); - WriteFieldDocComment(printer, descriptor_); - printer->Print(variables_, - "$deprecation$public $type$.Builder add$capitalized_name$Builder(\n" - " int index) {\n" - " return get$capitalized_name$FieldBuilder().addBuilder(\n" - " index, $type$.getDefaultInstance());\n" - "}\n"); - WriteFieldDocComment(printer, descriptor_); - printer->Print(variables_, - "$deprecation$public java.util.List<$type$.Builder> \n" - " get$capitalized_name$BuilderList() {\n" - " return get$capitalized_name$FieldBuilder().getBuilderList();\n" - "}\n" - "private com.google.protobuf.RepeatedFieldBuilder$ver$<\n" - " $type$, $type$.Builder, $type$OrBuilder> \n" - " get$capitalized_name$FieldBuilder() {\n" - " if ($name$Builder_ == null) {\n" - " $name$Builder_ = new com.google.protobuf.RepeatedFieldBuilder$ver$<\n" - " $type$, $type$.Builder, $type$OrBuilder>(\n" - " $name$_,\n" - " $get_mutable_bit_builder$,\n" - " getParentForChildren(),\n" - " isClean());\n" - " $name$_ = null;\n" - " }\n" - " return $name$Builder_;\n" - "}\n"); -} - -void RepeatedImmutableLazyMessageFieldGenerator:: -GenerateParsingCode(io::Printer* printer) const { - printer->Print(variables_, - "if (!$get_mutable_bit_parser$) {\n" - " $name$_ =\n" - " new java.util.ArrayList<com.google.protobuf.LazyFieldLite>();\n" - " $set_mutable_bit_parser$;\n" - "}\n" - "$name$_.add(new com.google.protobuf.LazyFieldLite(\n" - " extensionRegistry, input.readBytes()));\n"); -} - -void RepeatedImmutableLazyMessageFieldGenerator:: -GenerateSerializationCode(io::Printer* printer) const { - printer->Print(variables_, - "for (int i = 0; i < $name$_.size(); i++) {\n" - " output.writeBytes($number$, $name$_.get(i).toByteString());\n" - "}\n"); -} - -void RepeatedImmutableLazyMessageFieldGenerator:: -GenerateSerializedSizeCode(io::Printer* printer) const { - printer->Print(variables_, - "for (int i = 0; i < $name$_.size(); i++) {\n" - " size += com.google.protobuf.CodedOutputStream\n" - " .computeLazyFieldSize($number$, $name$_.get(i));\n" - "}\n"); -} - -} // namespace java -} // namespace compiler -} // namespace protobuf -} // namespace google diff --git a/src/google/protobuf/compiler/java/java_lazy_message_field.h b/src/google/protobuf/compiler/java/java_lazy_message_field.h deleted file mode 100644 index b1b7f282..00000000 --- a/src/google/protobuf/compiler/java/java_lazy_message_field.h +++ /dev/null @@ -1,121 +0,0 @@ -// 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: niwasaki@google.com (Naoki Iwasaki) -// Based on original Protocol Buffers design by -// Sanjay Ghemawat, Jeff Dean, and others. - -#ifndef GOOGLE_PROTOBUF_COMPILER_JAVA_LAZY_MESSAGE_FIELD_H__ -#define GOOGLE_PROTOBUF_COMPILER_JAVA_LAZY_MESSAGE_FIELD_H__ - -#include <google/protobuf/compiler/java/java_field.h> -#include <google/protobuf/compiler/java/java_message_field.h> - -namespace google { -namespace protobuf { - namespace compiler { - namespace java { - class Context; // context.h - } - } -} - -namespace protobuf { -namespace compiler { -namespace java { - -class ImmutableLazyMessageFieldGenerator - : public ImmutableMessageFieldGenerator { - public: - explicit ImmutableLazyMessageFieldGenerator( - const FieldDescriptor* descriptor, int messageBitIndex, - int builderBitIndex, Context* context); - ~ImmutableLazyMessageFieldGenerator(); - - // overroads ImmutableMessageFieldGenerator --------------------------------- - void GenerateMembers(io::Printer* printer) const; - void GenerateBuilderMembers(io::Printer* printer) const; - void GenerateInitializationCode(io::Printer* printer) const; - void GenerateBuilderClearCode(io::Printer* printer) const; - void GenerateMergingCode(io::Printer* printer) const; - void GenerateBuildingCode(io::Printer* printer) const; - void GenerateParsingCode(io::Printer* printer) const; - void GenerateSerializationCode(io::Printer* printer) const; - void GenerateSerializedSizeCode(io::Printer* printer) const; - - private: - GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ImmutableLazyMessageFieldGenerator); -}; - -class ImmutableLazyMessageOneofFieldGenerator - : public ImmutableLazyMessageFieldGenerator { - public: - ImmutableLazyMessageOneofFieldGenerator( - const FieldDescriptor* descriptor, int messageBitIndex, - int builderBitIndex, Context* context); - ~ImmutableLazyMessageOneofFieldGenerator(); - - void GenerateMembers(io::Printer* printer) const; - void GenerateBuilderMembers(io::Printer* printer) const; - void GenerateMergingCode(io::Printer* printer) const; - void GenerateBuildingCode(io::Printer* printer) const; - void GenerateParsingCode(io::Printer* printer) const; - void GenerateSerializationCode(io::Printer* printer) const; - void GenerateSerializedSizeCode(io::Printer* printer) const; - - private: - GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ImmutableLazyMessageOneofFieldGenerator); -}; - -class RepeatedImmutableLazyMessageFieldGenerator - : public RepeatedImmutableMessageFieldGenerator { - public: - explicit RepeatedImmutableLazyMessageFieldGenerator( - const FieldDescriptor* descriptor, int messageBitIndex, - int builderBitIndex, Context* context); - ~RepeatedImmutableLazyMessageFieldGenerator(); - - // overroads RepeatedImmutableMessageFieldGenerator ------------------------- - void GenerateMembers(io::Printer* printer) const; - void GenerateBuilderMembers(io::Printer* printer) const; - void GenerateParsingCode(io::Printer* printer) const; - void GenerateSerializationCode(io::Printer* printer) const; - void GenerateSerializedSizeCode(io::Printer* printer) const; - - private: - GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(RepeatedImmutableLazyMessageFieldGenerator); -}; - -} // namespace java -} // namespace compiler -} // namespace protobuf - -} // namespace google -#endif // GOOGLE_PROTOBUF_COMPILER_JAVA_LAZY_MESSAGE_FIELD_H__ diff --git a/src/google/protobuf/compiler/java/java_lazy_message_field_lite.cc b/src/google/protobuf/compiler/java/java_lazy_message_field_lite.cc deleted file mode 100644 index 51bb11f1..00000000 --- a/src/google/protobuf/compiler/java/java_lazy_message_field_lite.cc +++ /dev/null @@ -1,725 +0,0 @@ -// 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: niwasaki@google.com (Naoki Iwasaki) -// Based on original Protocol Buffers design by -// Sanjay Ghemawat, Jeff Dean, and others. - -#include <google/protobuf/compiler/java/java_context.h> -#include <google/protobuf/compiler/java/java_lazy_message_field_lite.h> -#include <google/protobuf/compiler/java/java_doc_comment.h> -#include <google/protobuf/compiler/java/java_helpers.h> -#include <google/protobuf/io/printer.h> - -namespace google { -namespace protobuf { -namespace compiler { -namespace java { - -ImmutableLazyMessageFieldLiteGenerator:: -ImmutableLazyMessageFieldLiteGenerator( - const FieldDescriptor* descriptor, - int messageBitIndex, - int builderBitIndex, - Context* context) - : ImmutableMessageFieldLiteGenerator( - descriptor, messageBitIndex, builderBitIndex, context) { -} - -ImmutableLazyMessageFieldLiteGenerator:: -~ImmutableLazyMessageFieldLiteGenerator() {} - -void ImmutableLazyMessageFieldLiteGenerator:: -GenerateMembers(io::Printer* printer) const { - printer->Print(variables_, - "private com.google.protobuf.LazyFieldLite $name$_;"); - - PrintExtraFieldInfo(variables_, printer); - WriteFieldDocComment(printer, descriptor_); - if (SupportFieldPresence(descriptor_->file())) { - printer->Print(variables_, - "$deprecation$public boolean has$capitalized_name$() {\n" - " return $get_has_field_bit_message$;\n" - "}\n"); - } else { - printer->Print(variables_, - "$deprecation$public boolean has$capitalized_name$() {\n" - " return $name$_ != null;\n" - "}\n"); - } - - WriteFieldDocComment(printer, descriptor_); - printer->Print(variables_, - "$deprecation$public $type$ get$capitalized_name$() {\n" - " if ($name$_ == null) {\n" - " return $type$.getDefaultInstance();\n" - " }\n" - " return ($type$) $name$_.getValue($type$.getDefaultInstance());\n" - "}\n"); - - // Field.Builder setField(Field value) - WriteFieldDocComment(printer, descriptor_); - printer->Print(variables_, - "private void set$capitalized_name$($type$ value) {\n" - " if (value == null) {\n" - " throw new NullPointerException();\n" - " }\n" - " if ($name$_ == null) {\n" - " $name$_ = new com.google.protobuf.LazyFieldLite();\n" - " }\n" - " $name$_.setValue(value);\n" - " $set_has_field_bit_message$\n" - "}\n"); - - // Field.Builder setField(Field.Builder builderForValue) - WriteFieldDocComment(printer, descriptor_); - printer->Print(variables_, - "private void set$capitalized_name$(\n" - " $type$.Builder builderForValue) {\n" - " if ($name$_ == null) {\n" - " $name$_ = new com.google.protobuf.LazyFieldLite();\n" - " }\n" - " $name$_.setValue(builderForValue.build());\n" - " $set_has_field_bit_message$\n" - "}\n"); - - // Field.Builder mergeField(Field value) - WriteFieldDocComment(printer, descriptor_); - printer->Print(variables_, - "private void merge$capitalized_name$($type$ value) {\n" - " if (has$capitalized_name$() &&\n" - " !$name$_.containsDefaultInstance()) {\n" - " $name$_.setValue(\n" - " $type$.newBuilder(\n" - " get$capitalized_name$()).mergeFrom(value).buildPartial());\n" - " } else {\n" - " if ($name$_ == null) {\n" - " $name$_ = new com.google.protobuf.LazyFieldLite();\n" - " }\n" - " $name$_.setValue(value);\n" - " $set_has_field_bit_message$\n" - " }\n" - "}\n"); - - // Field.Builder clearField() - WriteFieldDocComment(printer, descriptor_); - printer->Print(variables_, - "private void clear$capitalized_name$() {\n" - " $name$_ = null;\n" - " $clear_has_field_bit_message$;\n" - "}\n"); -} - -void ImmutableLazyMessageFieldLiteGenerator:: -GenerateBuilderMembers(io::Printer* printer) const { - // The comments above the methods below are based on a hypothetical - // field of type "Field" called "Field". - - // boolean hasField() - WriteFieldDocComment(printer, descriptor_); - printer->Print(variables_, - "$deprecation$public boolean has$capitalized_name$() {\n" - " return instance.has$capitalized_name$();\n" - "}\n"); - - WriteFieldDocComment(printer, descriptor_); - printer->Print(variables_, - "$deprecation$public $type$ get$capitalized_name$() {\n" - " return instance.get$capitalized_name$();\n" - "}\n"); - - // Field.Builder setField(Field value) - WriteFieldDocComment(printer, descriptor_); - printer->Print(variables_, - "$deprecation$public Builder set$capitalized_name$($type$ value) {\n" - " copyOnWrite();\n" - " instance.set$capitalized_name$(value);\n" - " return this;\n" - "}\n"); - - // Field.Builder setField(Field.Builder builderForValue) - WriteFieldDocComment(printer, descriptor_); - printer->Print(variables_, - "$deprecation$public Builder set$capitalized_name$(\n" - " $type$.Builder builderForValue) {\n" - " copyOnWrite();\n" - " instance.set$capitalized_name$(builderForValue);\n" - " return this;\n" - "}\n"); - - // Field.Builder mergeField(Field value) - WriteFieldDocComment(printer, descriptor_); - printer->Print(variables_, - "$deprecation$public Builder merge$capitalized_name$($type$ value) {\n" - " copyOnWrite();\n" - " instance.merge$capitalized_name$(value);\n" - " return this;\n" - "}\n"); - - // Field.Builder clearField() - WriteFieldDocComment(printer, descriptor_); - printer->Print(variables_, - "$deprecation$public Builder clear$capitalized_name$() {\n" - " copyOnWrite();\n" - " instance.clear$capitalized_name$();\n" - " return this;\n" - "}\n"); -} - - -void ImmutableLazyMessageFieldLiteGenerator:: -GenerateInitializationCode(io::Printer* printer) const {} - -void ImmutableLazyMessageFieldLiteGenerator:: -GenerateVisitCode(io::Printer* printer) const { - printer->Print(variables_, - "$name$_ = visitor.visitLazyMessage($name$_, other.$name$_);\n"); -} - -void ImmutableLazyMessageFieldLiteGenerator:: -GenerateParsingCode(io::Printer* printer) const { - printer->Print(variables_, - "if ($name$_ == null) {\n" - " $name$_ = new com.google.protobuf.LazyFieldLite();\n" - "}\n" - "$name$_.mergeFrom(input, extensionRegistry);\n"); - printer->Print(variables_, - "$set_has_field_bit_message$\n"); -} - -void ImmutableLazyMessageFieldLiteGenerator:: -GenerateSerializationCode(io::Printer* printer) const { - // Do not de-serialize lazy fields. - printer->Print(variables_, - "if (has$capitalized_name$()) {\n" - " output.writeBytes($number$, $name$_.toByteString());\n" - "}\n"); -} - -void ImmutableLazyMessageFieldLiteGenerator:: -GenerateSerializedSizeCode(io::Printer* printer) const { - printer->Print(variables_, - "if (has$capitalized_name$()) {\n" - " size += com.google.protobuf.CodedOutputStream\n" - " .computeLazyFieldSize($number$, $name$_);\n" - "}\n"); -} - - -// =================================================================== - -ImmutableLazyMessageOneofFieldLiteGenerator:: -ImmutableLazyMessageOneofFieldLiteGenerator(const FieldDescriptor* descriptor, - int messageBitIndex, - int builderBitIndex, - Context* context) - : ImmutableLazyMessageFieldLiteGenerator( - descriptor, messageBitIndex, builderBitIndex, context) { - const OneofGeneratorInfo* info = - context->GetOneofGeneratorInfo(descriptor->containing_oneof()); - SetCommonOneofVariables(descriptor, info, &variables_); - variables_["lazy_type"] = "com.google.protobuf.LazyFieldLite"; -} - -ImmutableLazyMessageOneofFieldLiteGenerator:: -~ImmutableLazyMessageOneofFieldLiteGenerator() {} - -void ImmutableLazyMessageOneofFieldLiteGenerator:: -GenerateMembers(io::Printer* printer) const { - PrintExtraFieldInfo(variables_, printer); - WriteFieldDocComment(printer, descriptor_); - - printer->Print(variables_, - "$deprecation$public boolean has$capitalized_name$() {\n" - " return $has_oneof_case_message$;\n" - "}\n"); - WriteFieldDocComment(printer, descriptor_); - - printer->Print(variables_, - "$deprecation$public $type$ get$capitalized_name$() {\n" - " if ($has_oneof_case_message$) {\n" - " return ($type$) (($lazy_type$) $oneof_name$_).getValue(\n" - " $type$.getDefaultInstance());\n" - " }\n" - " return $type$.getDefaultInstance();\n" - "}\n"); - - // Field.Builder setField(Field value) - WriteFieldDocComment(printer, descriptor_); - printer->Print(variables_, - "private void set$capitalized_name$($type$ value) {\n" - " if (value == null) {\n" - " throw new NullPointerException();\n" - " }\n" - " if (!($has_oneof_case_message$)) {\n" - " $oneof_name$_ = new $lazy_type$();\n" - " $set_oneof_case_message$;\n" - " }\n" - " (($lazy_type$) $oneof_name$_).setValue(value);\n" - "}\n"); - - // Field.Builder setField(Field.Builder builderForValue) - WriteFieldDocComment(printer, descriptor_); - printer->Print(variables_, - "private void set$capitalized_name$(\n" - " $type$.Builder builderForValue) {\n" - " if (!($has_oneof_case_message$)) {\n" - " $oneof_name$_ = new $lazy_type$();\n" - " $set_oneof_case_message$;\n" - " }\n" - " (($lazy_type$) $oneof_name$_).setValue(builderForValue.build());\n" - "}\n"); - - // Field.Builder mergeField(Field value) - WriteFieldDocComment(printer, descriptor_); - printer->Print(variables_, - "private void merge$capitalized_name$($type$ value) {\n" - " if ($has_oneof_case_message$ &&\n" - " !(($lazy_type$) $oneof_name$_).containsDefaultInstance()) {\n" - " (($lazy_type$) $oneof_name$_).setValue(\n" - " $type$.newBuilder(\n" - " get$capitalized_name$()).mergeFrom(value).buildPartial());\n" - " } else {\n" - " if (!($has_oneof_case_message$)) {\n" - " $oneof_name$_ = new $lazy_type$();\n" - " $set_oneof_case_message$;\n" - " }\n" - " (($lazy_type$) $oneof_name$_).setValue(value);\n" - " }\n" - "}\n"); - - // Field.Builder clearField() - WriteFieldDocComment(printer, descriptor_); - printer->Print(variables_, - "private void clear$capitalized_name$() {\n" - " if ($has_oneof_case_message$) {\n" - " $clear_oneof_case_message$;\n" - " $oneof_name$_ = null;\n" - " }\n" - "}\n"); -} - -void ImmutableLazyMessageOneofFieldLiteGenerator:: -GenerateBuilderMembers(io::Printer* printer) const { - // boolean hasField() - WriteFieldDocComment(printer, descriptor_); - printer->Print(variables_, - "$deprecation$public boolean has$capitalized_name$() {\n" - " return instance.has$capitalized_name$();\n" - "}\n"); - - printer->Print(variables_, - "$deprecation$public $type$ get$capitalized_name$() {\n" - " return instance.get$capitalized_name$();\n" - "}\n"); - - // Field.Builder setField(Field value) - WriteFieldDocComment(printer, descriptor_); - printer->Print(variables_, - "$deprecation$public Builder set$capitalized_name$($type$ value) {\n" - " copyOnWrite();\n" - " instance.set$capitalized_name$(value);\n" - " return this;\n" - "}\n"); - - // Field.Builder setField(Field.Builder builderForValue) - WriteFieldDocComment(printer, descriptor_); - printer->Print(variables_, - "$deprecation$public Builder set$capitalized_name$(\n" - " $type$.Builder builderForValue) {\n" - " copyOnWrite();\n" - " instance.set$capitalized_name$(builderForValue);\n" - " return this;\n" - "}\n"); - - // Field.Builder mergeField(Field value) - WriteFieldDocComment(printer, descriptor_); - printer->Print(variables_, - "$deprecation$public Builder merge$capitalized_name$($type$ value) {\n" - " copyOnWrite();\n" - " instance.merge$capitalized_name$(value);\n" - " return this;\n" - "}\n"); - - // Field.Builder clearField() - WriteFieldDocComment(printer, descriptor_); - printer->Print(variables_, - "$deprecation$public Builder clear$capitalized_name$() {\n" - " copyOnWrite();\n" - " instance.clear$capitalized_name$();\n" - " return this;\n" - "}\n"); -} - -void ImmutableLazyMessageOneofFieldLiteGenerator:: -GenerateVisitCode(io::Printer* printer) const { - printer->Print(variables_, - "$oneof_name$_ = visitor.visitOneofLazyMessage(\n" - " $has_oneof_case_message$,\n" - " ($lazy_type$) $oneof_name$_,\n" - " ($lazy_type$) other.$oneof_name$_);\n"); -} - -void ImmutableLazyMessageOneofFieldLiteGenerator:: -GenerateParsingCode(io::Printer* printer) const { - printer->Print(variables_, - "if (!($has_oneof_case_message$)) {\n" - " $oneof_name$_ = new $lazy_type$();\n" - "}\n" - "(($lazy_type$) $oneof_name$_).mergeFrom(input, extensionRegistry);\n" - "$set_oneof_case_message$;\n"); -} - -void ImmutableLazyMessageOneofFieldLiteGenerator:: -GenerateSerializationCode(io::Printer* printer) const { - // Do not de-serialize lazy fields. - printer->Print(variables_, - "if ($has_oneof_case_message$) {\n" - " output.writeBytes(\n" - " $number$, (($lazy_type$) $oneof_name$_).toByteString());\n" - "}\n"); -} - -void ImmutableLazyMessageOneofFieldLiteGenerator:: -GenerateSerializedSizeCode(io::Printer* printer) const { - printer->Print(variables_, - "if ($has_oneof_case_message$) {\n" - " size += com.google.protobuf.CodedOutputStream\n" - " .computeLazyFieldSize($number$, ($lazy_type$) $oneof_name$_);\n" - "}\n"); -} - - -// =================================================================== - -RepeatedImmutableLazyMessageFieldLiteGenerator:: -RepeatedImmutableLazyMessageFieldLiteGenerator( - const FieldDescriptor* descriptor, - int messageBitIndex, - int builderBitIndex, - Context* context) - : RepeatedImmutableMessageFieldLiteGenerator( - descriptor, messageBitIndex, builderBitIndex, context) { -} - - -RepeatedImmutableLazyMessageFieldLiteGenerator:: -~RepeatedImmutableLazyMessageFieldLiteGenerator() {} - -void RepeatedImmutableLazyMessageFieldLiteGenerator:: -GenerateMembers(io::Printer* printer) const { - printer->Print(variables_, - "private com.google.protobuf.Internal.ProtobufList<\n" - " com.google.protobuf.LazyFieldLite> $name$_;\n"); - PrintExtraFieldInfo(variables_, printer); - WriteFieldDocComment(printer, descriptor_); - printer->Print(variables_, - "$deprecation$public java.util.List<$type$>\n" - " get$capitalized_name$List() {\n" - " java.util.List<$type$> list =\n" - " new java.util.ArrayList<$type$>($name$_.size());\n" - " for (com.google.protobuf.LazyFieldLite lf : $name$_) {\n" - " list.add(($type$) lf.getValue($type$.getDefaultInstance()));\n" - " }\n" - " return java.util.Collections.unmodifiableList(list);\n" - "}\n"); - WriteFieldDocComment(printer, descriptor_); - printer->Print(variables_, - "$deprecation$public java.util.List<? extends $type$OrBuilder>\n" - " get$capitalized_name$OrBuilderList() {\n" - " return get$capitalized_name$List();\n" - "}\n"); - WriteFieldDocComment(printer, descriptor_); - printer->Print(variables_, - "$deprecation$public int get$capitalized_name$Count() {\n" - " return $name$_.size();\n" - "}\n"); - WriteFieldDocComment(printer, descriptor_); - printer->Print(variables_, - "$deprecation$public $type$ get$capitalized_name$(int index) {\n" - " return ($type$)\n" - " $name$_.get(index).getValue($type$.getDefaultInstance());\n" - "}\n"); - WriteFieldDocComment(printer, descriptor_); - printer->Print(variables_, - "$deprecation$public $type$OrBuilder get$capitalized_name$OrBuilder(\n" - " int index) {\n" - " return ($type$OrBuilder)\n" - " $name$_.get(index).getValue($type$.getDefaultInstance());\n" - "}\n"); - - printer->Print(variables_, - "private void ensure$capitalized_name$IsMutable() {\n" - " if (!$is_mutable$) {\n" - " $name$_ =\n" - " com.google.protobuf.GeneratedMessageLite.mutableCopy($name$_);\n" - " }\n" - "}\n" - "\n"); - - // Builder setRepeatedField(int index, Field value) - WriteFieldDocComment(printer, descriptor_); - printer->Print(variables_, - "private void set$capitalized_name$(\n" - " int index, $type$ value) {\n" - " if (value == null) {\n" - " throw new NullPointerException();\n" - " }\n" - " ensure$capitalized_name$IsMutable();\n" - " $name$_.set(\n" - " index, com.google.protobuf.LazyFieldLite.fromValue(value));\n" - "}\n"); - - // Builder setRepeatedField(int index, Field.Builder builderForValue) - WriteFieldDocComment(printer, descriptor_); - printer->Print(variables_, - "private void set$capitalized_name$(\n" - " int index, $type$.Builder builderForValue) {\n" - " ensure$capitalized_name$IsMutable();\n" - " $name$_.set(index, com.google.protobuf.LazyFieldLite.fromValue(\n" - " builderForValue.build()));\n" - "}\n"); - - // Builder addRepeatedField(Field value) - WriteFieldDocComment(printer, descriptor_); - printer->Print(variables_, - "private void add$capitalized_name$($type$ value) {\n" - " if (value == null) {\n" - " throw new NullPointerException();\n" - " }\n" - " ensure$capitalized_name$IsMutable();\n" - " $name$_.add(com.google.protobuf.LazyFieldLite.fromValue(value));\n" - "}\n"); - - // Builder addRepeatedField(int index, Field value) - WriteFieldDocComment(printer, descriptor_); - printer->Print(variables_, - "private void add$capitalized_name$(\n" - " int index, $type$ value) {\n" - " if (value == null) {\n" - " throw new NullPointerException();\n" - " }\n" - " ensure$capitalized_name$IsMutable();\n" - " $name$_.add(\n" - " index, com.google.protobuf.LazyFieldLite.fromValue(value));\n" - "}\n"); - - // Builder addRepeatedField(Field.Builder builderForValue) - WriteFieldDocComment(printer, descriptor_); - printer->Print(variables_, - "private void add$capitalized_name$(\n" - " $type$.Builder builderForValue) {\n" - " ensure$capitalized_name$IsMutable();\n" - " $name$_.add(com.google.protobuf.LazyFieldLite.fromValue(\n" - " builderForValue.build()));\n" - "}\n"); - - // Builder addRepeatedField(int index, Field.Builder builderForValue) - WriteFieldDocComment(printer, descriptor_); - printer->Print(variables_, - "private void add$capitalized_name$(\n" - " int index, $type$.Builder builderForValue) {\n" - " ensure$capitalized_name$IsMutable();\n" - " $name$_.add(index, com.google.protobuf.LazyFieldLite.fromValue(\n" - " builderForValue.build()));\n" - "}\n"); - - // Builder addAllRepeatedField(Iterable<Field> values) - WriteFieldDocComment(printer, descriptor_); - printer->Print(variables_, - "private void addAll$capitalized_name$(\n" - " java.lang.Iterable<? extends $type$> values) {\n" - " ensure$capitalized_name$IsMutable();\n" - " for (com.google.protobuf.MessageLite v : values) {\n" - " $name$_.add(com.google.protobuf.LazyFieldLite.fromValue(v));\n" - " }\n" - "}\n"); - - // Builder clearAllRepeatedField() - WriteFieldDocComment(printer, descriptor_); - printer->Print(variables_, - "private void clear$capitalized_name$() {\n" - " $name$_ = emptyProtobufList();\n" - "}\n"); - - // Builder removeRepeatedField(int index) - WriteFieldDocComment(printer, descriptor_); - printer->Print(variables_, - "private void remove$capitalized_name$(int index) {\n" - " ensure$capitalized_name$IsMutable();\n" - " $name$_.remove(index);\n" - "}\n"); -} - -void RepeatedImmutableLazyMessageFieldLiteGenerator:: -GenerateBuilderMembers(io::Printer* printer) const { - // List<Field> getRepeatedFieldList() - WriteFieldDocComment(printer, descriptor_); - printer->Print(variables_, - "$deprecation$public java.util.List<$type$> get$capitalized_name$List() {\n" - " return java.util.Collections.unmodifiableList(\n" - " instance.get$capitalized_name$List());\n" - "}\n"); - - // int getRepeatedFieldCount() - WriteFieldDocComment(printer, descriptor_); - printer->Print(variables_, - "$deprecation$public int get$capitalized_name$Count() {\n" - " return instance.get$capitalized_name$Count();\n" - "}\n"); - - // Field getRepeatedField(int index) - WriteFieldDocComment(printer, descriptor_); - printer->Print(variables_, - "$deprecation$public $type$ get$capitalized_name$(int index) {\n" - " return instance.get$capitalized_name$(index);\n" - "}\n"); - - // Builder setRepeatedField(int index, Field value) - WriteFieldDocComment(printer, descriptor_); - printer->Print(variables_, - "$deprecation$public Builder set$capitalized_name$(\n" - " int index, $type$ value) {\n" - " copyOnWrite();\n" - " instance.set$capitalized_name$(index, value);\n" - " return this;\n" - "}\n"); - - // Builder setRepeatedField(int index, Field.Builder builderForValue) - WriteFieldDocComment(printer, descriptor_); - printer->Print(variables_, - "$deprecation$public Builder set$capitalized_name$(\n" - " int index, $type$.Builder builderForValue) {\n" - " copyOnWrite();\n" - " instance.set$capitalized_name$(index, builderForValue);\n" - " return this;\n" - "}\n"); - - // Builder addRepeatedField(Field value) - WriteFieldDocComment(printer, descriptor_); - printer->Print(variables_, - "$deprecation$public Builder add$capitalized_name$($type$ value) {\n" - " copyOnWrite();\n" - " instance.add$capitalized_name$(value);\n" - " return this;\n" - "}\n"); - - // Builder addRepeatedField(int index, Field value) - WriteFieldDocComment(printer, descriptor_); - printer->Print(variables_, - "$deprecation$public Builder add$capitalized_name$(\n" - " int index, $type$ value) {\n" - " copyOnWrite();\n" - " instance.add$capitalized_name$(index, value);\n" - " return this;\n" - "}\n"); - - // Builder addRepeatedField(Field.Builder builderForValue) - WriteFieldDocComment(printer, descriptor_); - printer->Print(variables_, - "$deprecation$public Builder add$capitalized_name$(\n" - " $type$.Builder builderForValue) {\n" - " copyOnWrite();\n" - " instance.add$capitalized_name$(builderForValue);\n" - " return this;\n" - "}\n"); - - // Builder addRepeatedField(int index, Field.Builder builderForValue) - WriteFieldDocComment(printer, descriptor_); - printer->Print(variables_, - "$deprecation$public Builder add$capitalized_name$(\n" - " int index, $type$.Builder builderForValue) {\n" - " copyOnWrite();\n" - " instance.add$capitalized_name$(index, builderForValue);\n" - " return this;\n" - "}\n"); - - // Builder addAllRepeatedField(Iterable<Field> values) - WriteFieldDocComment(printer, descriptor_); - printer->Print(variables_, - "$deprecation$public Builder addAll$capitalized_name$(\n" - " java.lang.Iterable<? extends $type$> values) {\n" - " copyOnWrite();\n" - " instance.addAll$capitalized_name$(values);\n" - " return this;\n" - "}\n"); - - // Builder clearAllRepeatedField() - WriteFieldDocComment(printer, descriptor_); - printer->Print(variables_, - "$deprecation$public Builder clear$capitalized_name$() {\n" - " copyOnWrite();\n" - " instance.clear$capitalized_name$();\n" - " return this;\n" - "}\n"); - - // Builder removeRepeatedField(int index) - WriteFieldDocComment(printer, descriptor_); - printer->Print(variables_, - "$deprecation$public Builder remove$capitalized_name$(int index) {\n" - " copyOnWrite();\n" - " instance.remove$capitalized_name$(index);\n" - " return this;\n" - "}\n"); -} - -void RepeatedImmutableLazyMessageFieldLiteGenerator:: -GenerateParsingCode(io::Printer* printer) const { - printer->Print(variables_, - "if (!$is_mutable$) {\n" - " $name$_ =\n" - " com.google.protobuf.GeneratedMessageLite.mutableCopy($name$_);\n" - "}\n" - "$name$_.add(new com.google.protobuf.LazyFieldLite(\n" - " extensionRegistry, input.readBytes()));\n"); -} - -void RepeatedImmutableLazyMessageFieldLiteGenerator:: -GenerateSerializationCode(io::Printer* printer) const { - printer->Print(variables_, - "for (int i = 0; i < $name$_.size(); i++) {\n" - " output.writeBytes($number$, $name$_.get(i).toByteString());\n" - "}\n"); -} - -void RepeatedImmutableLazyMessageFieldLiteGenerator:: -GenerateSerializedSizeCode(io::Printer* printer) const { - printer->Print(variables_, - "for (int i = 0; i < $name$_.size(); i++) {\n" - " size += com.google.protobuf.CodedOutputStream\n" - " .computeLazyFieldSize($number$, $name$_.get(i));\n" - "}\n"); -} - - -} // namespace java -} // namespace compiler -} // namespace protobuf -} // namespace google diff --git a/src/google/protobuf/compiler/java/java_lazy_message_field_lite.h b/src/google/protobuf/compiler/java/java_lazy_message_field_lite.h deleted file mode 100644 index 65b84fbc..00000000 --- a/src/google/protobuf/compiler/java/java_lazy_message_field_lite.h +++ /dev/null @@ -1,121 +0,0 @@ -// 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: niwasaki@google.com (Naoki Iwasaki) -// Based on original Protocol Buffers design by -// Sanjay Ghemawat, Jeff Dean, and others. - -#ifndef GOOGLE_PROTOBUF_COMPILER_JAVA_LAZY_MESSAGE_FIELD_LITE_H__ -#define GOOGLE_PROTOBUF_COMPILER_JAVA_LAZY_MESSAGE_FIELD_LITE_H__ - -#include <google/protobuf/compiler/java/java_field.h> -#include <google/protobuf/compiler/java/java_message_field_lite.h> - -namespace google { -namespace protobuf { - namespace compiler { - namespace java { - class Context; // context.h - } - } -} - -namespace protobuf { -namespace compiler { -namespace java { - -class ImmutableLazyMessageFieldLiteGenerator - : public ImmutableMessageFieldLiteGenerator { - public: - explicit ImmutableLazyMessageFieldLiteGenerator( - const FieldDescriptor* descriptor, int messageBitIndex, - int builderBitIndex, Context* context); - ~ImmutableLazyMessageFieldLiteGenerator(); - - // overroads ImmutableMessageFieldLiteGenerator ------------------------------ - void GenerateMembers(io::Printer* printer) const; - void GenerateBuilderMembers(io::Printer* printer) const; - void GenerateInitializationCode(io::Printer* printer) const; - void GenerateVisitCode(io::Printer* printer) const; - void GenerateParsingCode(io::Printer* printer) const; - void GenerateSerializationCode(io::Printer* printer) const; - void GenerateSerializedSizeCode(io::Printer* printer) const; - - - private: - GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ImmutableLazyMessageFieldLiteGenerator); -}; - -class ImmutableLazyMessageOneofFieldLiteGenerator - : public ImmutableLazyMessageFieldLiteGenerator { - public: - ImmutableLazyMessageOneofFieldLiteGenerator( - const FieldDescriptor* descriptor, int messageBitIndex, - int builderBitIndex, Context* context); - ~ImmutableLazyMessageOneofFieldLiteGenerator(); - - void GenerateMembers(io::Printer* printer) const; - void GenerateBuilderMembers(io::Printer* printer) const; - void GenerateVisitCode(io::Printer* printer) const; - void GenerateParsingCode(io::Printer* printer) const; - void GenerateSerializationCode(io::Printer* printer) const; - void GenerateSerializedSizeCode(io::Printer* printer) const; - - - private: - GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ImmutableLazyMessageOneofFieldLiteGenerator); -}; - -class RepeatedImmutableLazyMessageFieldLiteGenerator - : public RepeatedImmutableMessageFieldLiteGenerator { - public: - explicit RepeatedImmutableLazyMessageFieldLiteGenerator( - const FieldDescriptor* descriptor, int messageBitIndex, - int builderBitIndex, Context* context); - ~RepeatedImmutableLazyMessageFieldLiteGenerator(); - - // overroads RepeatedImmutableMessageFieldLiteGenerator ---------------------- - void GenerateMembers(io::Printer* printer) const; - void GenerateBuilderMembers(io::Printer* printer) const; - void GenerateParsingCode(io::Printer* printer) const; - void GenerateSerializationCode(io::Printer* printer) const; - void GenerateSerializedSizeCode(io::Printer* printer) const; - - - private: - GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(RepeatedImmutableLazyMessageFieldLiteGenerator); -}; - -} // namespace java -} // namespace compiler -} // namespace protobuf - -} // namespace google -#endif // GOOGLE_PROTOBUF_COMPILER_JAVA_LAZY_MESSAGE_FIELD_LITE_H__ diff --git a/src/google/protobuf/compiler/java/java_message_field.cc b/src/google/protobuf/compiler/java/java_message_field.cc index baa7f872..bda4fcc0 100644 --- a/src/google/protobuf/compiler/java/java_message_field.cc +++ b/src/google/protobuf/compiler/java/java_message_field.cc @@ -255,7 +255,7 @@ GenerateBuilderMembers(io::Printer* printer) const { bool support_field_presence = SupportFieldPresence(descriptor_->file()); printer->Print(variables_, - "private $type$ $name$_ = null;\n"); + "private $type$ $name$_;\n"); printer->Print(variables_, // If this builder is non-null, it is used and the other fields are @@ -444,15 +444,20 @@ void ImmutableMessageFieldGenerator:: GenerateBuildingCode(io::Printer* printer) const { if (SupportFieldPresence(descriptor_->file())) { printer->Print(variables_, - "if ($get_has_field_bit_from_local$) {\n" - " $set_has_field_bit_to_local$;\n" - "}\n"); + "if ($get_has_field_bit_from_local$) {\n"); + printer->Indent(); + PrintNestedBuilderCondition(printer, + "result.$name$_ = $name$_;\n", + "result.$name$_ = $name$Builder_.build();\n"); + printer->Outdent(); + printer->Print(variables_, + " $set_has_field_bit_to_local$;\n" + "}\n"); + } else { + PrintNestedBuilderCondition(printer, + "result.$name$_ = $name$_;\n", + "result.$name$_ = $name$Builder_.build();\n"); } - - PrintNestedBuilderCondition(printer, - "result.$name$_ = $name$_;\n", - - "result.$name$_ = $name$Builder_.build();\n"); } void ImmutableMessageFieldGenerator:: diff --git a/src/google/protobuf/compiler/java/java_primitive_field.cc b/src/google/protobuf/compiler/java/java_primitive_field.cc index 71ee0992..e6ce69c7 100644 --- a/src/google/protobuf/compiler/java/java_primitive_field.cc +++ b/src/google/protobuf/compiler/java/java_primitive_field.cc @@ -264,7 +264,9 @@ GenerateFieldBuilderInitializationCode(io::Printer* printer) const { void ImmutablePrimitiveFieldGenerator:: GenerateInitializationCode(io::Printer* printer) const { - printer->Print(variables_, "$name$_ = $default$;\n"); + if (!IsDefaultValueJavaDefault(descriptor_)) { + printer->Print(variables_, "$name$_ = $default$;\n"); + } } void ImmutablePrimitiveFieldGenerator:: @@ -294,11 +296,21 @@ GenerateBuildingCode(io::Printer* printer) const { if (SupportFieldPresence(descriptor_->file())) { printer->Print(variables_, "if ($get_has_field_bit_from_local$) {\n" - " $set_has_field_bit_to_local$;\n" - "}\n"); + " result.$name$_ = $name$_;\n" + " $set_has_field_bit_to_local$;\n"); + if (IsDefaultValueJavaDefault(descriptor_)) { + printer->Print(variables_, + "}\n"); + } else { + printer->Print(variables_, + "} else {\n" + " result.$name$_ = $default$;\n" + "}\n"); + } + } else { + printer->Print(variables_, + "result.$name$_ = $name$_;\n"); } - printer->Print(variables_, - "result.$name$_ = $name$_;\n"); } void ImmutablePrimitiveFieldGenerator:: diff --git a/src/google/protobuf/compiler/java/java_string_field.cc b/src/google/protobuf/compiler/java/java_string_field.cc index 2b6e9381..b08febc0 100644 --- a/src/google/protobuf/compiler/java/java_string_field.cc +++ b/src/google/protobuf/compiler/java/java_string_field.cc @@ -405,11 +405,15 @@ GenerateBuildingCode(io::Printer* printer) const { if (SupportFieldPresence(descriptor_->file())) { printer->Print(variables_, "if ($get_has_field_bit_from_local$) {\n" + " result.$name$_ = $name$_;\n" " $set_has_field_bit_to_local$;\n" + "} else {\n" + " result.$name$_ = $default$;\n" "}\n"); + } else { + printer->Print(variables_, + "result.$name$_ = $name$_;\n"); } - printer->Print(variables_, - "result.$name$_ = $name$_;\n"); } void ImmutableStringFieldGenerator:: diff --git a/src/google/protobuf/compiler/js/js_generator.cc b/src/google/protobuf/compiler/js/js_generator.cc index b5771f26..45b906f5 100755..100644 --- a/src/google/protobuf/compiler/js/js_generator.cc +++ b/src/google/protobuf/compiler/js/js_generator.cc @@ -276,7 +276,8 @@ string GetEnumPath(const GeneratorOptions& options, string MaybeCrossFileRef(const GeneratorOptions& options, const FileDescriptor* from_file, const Descriptor* to_message) { - if (options.import_style == GeneratorOptions::kImportCommonJs && + if ((options.import_style == GeneratorOptions::kImportCommonJs || + options.import_style == GeneratorOptions::kImportCommonJsStrict) && from_file != to_message->file()) { // Cross-file ref in CommonJS needs to use the module alias instead of // the global name. @@ -1675,8 +1676,19 @@ void Generator::GenerateProvides(const GeneratorOptions& options, // // // Later generated code expects foo.bar = {} to exist: // foo.bar.Baz = function() { /* ... */ } - printer->Print("goog.exportSymbol('$name$', null, global);\n", "name", - *it); + + // Do not use global scope in strict mode + if (options.import_style == GeneratorOptions::kImportCommonJsStrict) { + string namespaceObject = *it; + // Remove "proto." from the namespace object + GOOGLE_CHECK(namespaceObject.compare(0, 6, "proto.") == 0); + namespaceObject.erase(0, 6); + printer->Print("goog.exportSymbol('$name$', null, proto);\n", "name", + namespaceObject); + } else { + printer->Print("goog.exportSymbol('$name$', null, global);\n", "name", + *it); + } } } } @@ -3325,6 +3337,8 @@ bool GeneratorOptions::ParseFromOptions( import_style = kImportClosure; } else if (options[i].second == "commonjs") { import_style = kImportCommonJs; + } else if (options[i].second == "commonjs_strict") { + import_style = kImportCommonJsStrict; } else if (options[i].second == "browser") { import_style = kImportBrowser; } else if (options[i].second == "es6") { @@ -3434,15 +3448,23 @@ void Generator::GenerateFile(const GeneratorOptions& options, GenerateHeader(options, printer); // Generate "require" statements. - if (options.import_style == GeneratorOptions::kImportCommonJs) { + if ((options.import_style == GeneratorOptions::kImportCommonJs || + options.import_style == GeneratorOptions::kImportCommonJsStrict)) { printer->Print("var jspb = require('google-protobuf');\n"); printer->Print("var goog = jspb;\n"); - printer->Print("var global = Function('return this')();\n\n"); + + // Do not use global scope in strict mode + if (options.import_style == GeneratorOptions::kImportCommonJsStrict) { + printer->Print("var proto = {};\n\n"); + } else { + printer->Print("var global = Function('return this')();\n\n"); + } for (int i = 0; i < file->dependency_count(); i++) { const string& name = file->dependency(i)->name(); printer->Print( - "var $alias$ = require('$file$');\n", + "var $alias$ = require('$file$');\n" + "goog.object.extend(proto, $alias$);\n", "alias", ModuleAlias(name), "file", GetRootPath(file->name(), name) + GetJSFilename(options, name)); @@ -3481,9 +3503,13 @@ void Generator::GenerateFile(const GeneratorOptions& options, GenerateExtension(options, printer, *it); } - if (options.import_style == GeneratorOptions::kImportCommonJs) { + // if provided is empty, do not export anything + if (options.import_style == GeneratorOptions::kImportCommonJs && !provided.empty()) { printer->Print("goog.object.extend(exports, $package$);\n", "package", GetFilePath(options, file)); + } else if(options.import_style == GeneratorOptions::kImportCommonJsStrict) { + printer->Print("goog.object.extend(exports, proto);\n", + "package", GetFilePath(options, file)); } // Emit well-known type methods. diff --git a/src/google/protobuf/compiler/js/js_generator.h b/src/google/protobuf/compiler/js/js_generator.h index 3cc60e22..b50ef7fd 100755..100644 --- a/src/google/protobuf/compiler/js/js_generator.h +++ b/src/google/protobuf/compiler/js/js_generator.h @@ -63,10 +63,11 @@ struct GeneratorOptions { bool binary; // What style of imports should be used. enum ImportStyle { - kImportClosure, // goog.require() - kImportCommonJs, // require() - kImportBrowser, // no import statements - kImportEs6, // import { member } from '' + kImportClosure, // goog.require() + kImportCommonJs, // require() + kImportCommonJsStrict, // require() with no global export + kImportBrowser, // no import statements + kImportEs6, // import { member } from '' } import_style; GeneratorOptions() diff --git a/src/google/protobuf/compiler/js/well_known_types/struct.js b/src/google/protobuf/compiler/js/well_known_types/struct.js deleted file mode 100644 index 30e3d02a..00000000 --- a/src/google/protobuf/compiler/js/well_known_types/struct.js +++ /dev/null @@ -1,168 +0,0 @@ -// 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 code will be inserted into generated code for - * google/protobuf/struct.proto. */ - -/** - * Typedef representing plain JavaScript values that can go into a - * Struct. - * @typedef {null|number|string|boolean|Array|Object} - */ -proto.google.protobuf.JavaScriptValue; - - -/** - * Converts this Value object to a plain JavaScript value. - * @return {?proto.google.protobuf.JavaScriptValue} a plain JavaScript - * value representing this Struct. - */ -proto.google.protobuf.Value.prototype.toJavaScript = function() { - var kindCase = proto.google.protobuf.Value.KindCase; - switch (this.getKindCase()) { - case kindCase.NULL_VALUE: - return null; - case kindCase.NUMBER_VALUE: - return this.getNumberValue(); - case kindCase.STRING_VALUE: - return this.getStringValue(); - case kindCase.BOOL_VALUE: - return this.getBoolValue(); - case kindCase.STRUCT_VALUE: - return this.getStructValue().toJavaScript(); - case kindCase.LIST_VALUE: - return this.getListValue().toJavaScript(); - default: - throw new Error('Unexpected struct type'); - } -}; - - -/** - * Converts this JavaScript value to a new Value proto. - * @param {!proto.google.protobuf.JavaScriptValue} value The value to - * convert. - * @return {!proto.google.protobuf.Value} The newly constructed value. - */ -proto.google.protobuf.Value.fromJavaScript = function(value) { - var ret = new proto.google.protobuf.Value(); - switch (goog.typeOf(value)) { - case 'string': - ret.setStringValue(/** @type {string} */ (value)); - break; - case 'number': - ret.setNumberValue(/** @type {number} */ (value)); - break; - case 'boolean': - ret.setBoolValue(/** @type {boolean} */ (value)); - break; - case 'null': - ret.setNullValue(proto.google.protobuf.NullValue.NULL_VALUE); - break; - case 'array': - ret.setListValue(proto.google.protobuf.ListValue.fromJavaScript( - /** @type{!Array} */ (value))); - break; - case 'object': - ret.setStructValue(proto.google.protobuf.Struct.fromJavaScript( - /** @type{!Object} */ (value))); - break; - default: - throw new Error('Unexpected struct type.'); - } - - return ret; -}; - - -/** - * Converts this ListValue object to a plain JavaScript array. - * @return {!Array} a plain JavaScript array representing this List. - */ -proto.google.protobuf.ListValue.prototype.toJavaScript = function() { - var ret = []; - var values = this.getValuesList(); - - for (var i = 0; i < values.length; i++) { - ret[i] = values[i].toJavaScript(); - } - - return ret; -}; - - -/** - * Constructs a ListValue protobuf from this plain JavaScript array. - * @param {!Array} array a plain JavaScript array - * @return {proto.google.protobuf.ListValue} a new ListValue object - */ -proto.google.protobuf.ListValue.fromJavaScript = function(array) { - var ret = new proto.google.protobuf.ListValue(); - - for (var i = 0; i < array.length; i++) { - ret.addValues(proto.google.protobuf.Value.fromJavaScript(array[i])); - } - - return ret; -}; - - -/** - * Converts this Struct object to a plain JavaScript object. - * @return {!Object<string, !proto.google.protobuf.JavaScriptValue>} a plain - * JavaScript object representing this Struct. - */ -proto.google.protobuf.Struct.prototype.toJavaScript = function() { - var ret = {}; - - this.getFieldsMap().forEach(function(value, key) { - ret[key] = value.toJavaScript(); - }); - - return ret; -}; - - -/** - * Constructs a Struct protobuf from this plain JavaScript object. - * @param {!Object} obj a plain JavaScript object - * @return {proto.google.protobuf.Struct} a new Struct object - */ -proto.google.protobuf.Struct.fromJavaScript = function(obj) { - var ret = new proto.google.protobuf.Struct(); - var map = ret.getFieldsMap(); - - for (var property in obj) { - var val = obj[property]; - map.set(property, proto.google.protobuf.Value.fromJavaScript(val)); - } - - return ret; -}; diff --git a/src/google/protobuf/compiler/plugin.pb.cc b/src/google/protobuf/compiler/plugin.pb.cc index ef52def3..20aa82c7 100644 --- a/src/google/protobuf/compiler/plugin.pb.cc +++ b/src/google/protobuf/compiler/plugin.pb.cc @@ -183,14 +183,14 @@ static ::google::protobuf::Message const * const file_default_instances[] = { reinterpret_cast<const ::google::protobuf::Message*>(&::google::protobuf::compiler::_CodeGeneratorResponse_default_instance_), }; -void protobuf_AssignDescriptors() { +static void protobuf_AssignDescriptors() { AddDescriptors(); AssignDescriptors( "google/protobuf/compiler/plugin.proto", schemas, file_default_instances, TableStruct::offsets, file_level_metadata, NULL, NULL); } -void protobuf_AssignDescriptorsOnce() { +static void protobuf_AssignDescriptorsOnce() { static ::google::protobuf::internal::once_flag once; ::google::protobuf::internal::call_once(once, protobuf_AssignDescriptors); } @@ -201,7 +201,7 @@ void protobuf_RegisterTypes(const ::std::string&) { ::google::protobuf::internal::RegisterAllTypes(file_level_metadata, 4); } -void AddDescriptorsImpl() { +static void AddDescriptorsImpl() { InitDefaults(); static const char descriptor[] GOOGLE_PROTOBUF_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold) = { "\n%google/protobuf/compiler/plugin.proto\022" diff --git a/src/google/protobuf/compiler/ruby/ruby_generator_unittest.cc b/src/google/protobuf/compiler/ruby/ruby_generator_unittest.cc index 1aabe8aa..8454a5c5 100644 --- a/src/google/protobuf/compiler/ruby/ruby_generator_unittest.cc +++ b/src/google/protobuf/compiler/ruby/ruby_generator_unittest.cc @@ -90,12 +90,12 @@ TEST(RubyGeneratorTest, GeneratorTest) { // Load the generated output and compare to the expected result. string output; - GOOGLE_CHECK_OK(File::GetContents( + GOOGLE_CHECK_OK(File::GetContentsAsText( TestTempDir() + "/ruby_generated_code_pb.rb", &output, true)); string expected_output; - GOOGLE_CHECK_OK(File::GetContents( + GOOGLE_CHECK_OK(File::GetContentsAsText( ruby_tests + "/ruby_generated_code_pb.rb", &expected_output, true)); diff --git a/src/google/protobuf/descriptor.cc b/src/google/protobuf/descriptor.cc index fc3a9c77..fd003994 100644 --- a/src/google/protobuf/descriptor.cc +++ b/src/google/protobuf/descriptor.cc @@ -406,9 +406,10 @@ typedef std::pair<const EnumDescriptor*, int> EnumIntPair; template<typename PairType> struct PointerIntegerPairHash { size_t operator()(const PairType& p) const { - // FIXME(kenton): What is the best way to compute this hash? I have - // no idea! This seems a bit better than an XOR. - return reinterpret_cast<intptr_t>(p.first) * ((1 << 16) - 1) + p.second; + static const size_t prime1 = 16777499; + static const size_t prime2 = 16777619; + return reinterpret_cast<size_t>(p.first) * prime1 ^ + static_cast<size_t>(p.second) * prime2; } #ifdef _MSC_VER @@ -424,11 +425,10 @@ struct PointerIntegerPairHash { struct PointerStringPairHash { size_t operator()(const PointerStringPair& p) const { - // FIXME(kenton): What is the best way to compute this hash? I have - // no idea! This seems a bit better than an XOR. + static const size_t prime = 16777619; hash<const char*> cstring_hash; - return reinterpret_cast<intptr_t>(p.first) * ((1 << 16) - 1) + - cstring_hash(p.second); + return reinterpret_cast<size_t>(p.first) * prime ^ + static_cast<size_t>(cstring_hash(p.second)); } #ifdef _MSC_VER @@ -6906,7 +6906,7 @@ class DescriptorBuilder::OptionInterpreter::AggregateOptionFinder DescriptorBuilder* builder_; virtual const FieldDescriptor* FindExtension( - Message* message, const string& name) const { + Message* message, const string& name) const override { assert_mutex_held(builder_->pool_); const Descriptor* descriptor = message->GetDescriptor(); Symbol result = builder_->LookupSymbolNoPlaceholder( @@ -6944,7 +6944,7 @@ class AggregateErrorCollector : public io::ErrorCollector { string error_; virtual void AddError(int /* line */, int /* column */, - const string& message) { + const string& message) override { if (!error_.empty()) { error_ += "; "; } @@ -6952,7 +6952,7 @@ class AggregateErrorCollector : public io::ErrorCollector { } virtual void AddWarning(int /* line */, int /* column */, - const string& /* message */) { + const string& /* message */) override { // Ignore warnings } }; diff --git a/src/google/protobuf/descriptor.pb.cc b/src/google/protobuf/descriptor.pb.cc index 59b04aba..f3522ec1 100644 --- a/src/google/protobuf/descriptor.pb.cc +++ b/src/google/protobuf/descriptor.pb.cc @@ -1077,14 +1077,14 @@ static ::google::protobuf::Message const * const file_default_instances[] = { reinterpret_cast<const ::google::protobuf::Message*>(&::google::protobuf::_GeneratedCodeInfo_default_instance_), }; -void protobuf_AssignDescriptors() { +static void protobuf_AssignDescriptors() { AddDescriptors(); AssignDescriptors( "google/protobuf/descriptor.proto", schemas, file_default_instances, TableStruct::offsets, file_level_metadata, file_level_enum_descriptors, NULL); } -void protobuf_AssignDescriptorsOnce() { +static void protobuf_AssignDescriptorsOnce() { static ::google::protobuf::internal::once_flag once; ::google::protobuf::internal::call_once(once, protobuf_AssignDescriptors); } @@ -1095,7 +1095,7 @@ void protobuf_RegisterTypes(const ::std::string&) { ::google::protobuf::internal::RegisterAllTypes(file_level_metadata, 27); } -void AddDescriptorsImpl() { +static void AddDescriptorsImpl() { InitDefaults(); static const char descriptor[] GOOGLE_PROTOBUF_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold) = { "\n google/protobuf/descriptor.proto\022\017goog" @@ -1487,7 +1487,7 @@ void FileDescriptorSet::ArenaDtor(void* object) { FileDescriptorSet* _this = reinterpret_cast< FileDescriptorSet* >(object); (void)_this; } -void FileDescriptorSet::RegisterArenaDtor(::google::protobuf::Arena* arena) { +void FileDescriptorSet::RegisterArenaDtor(::google::protobuf::Arena*) { } void FileDescriptorSet::SetCachedSize(int size) const { _cached_size_.Set(size); @@ -1840,7 +1840,7 @@ void FileDescriptorProto::ArenaDtor(void* object) { FileDescriptorProto* _this = reinterpret_cast< FileDescriptorProto* >(object); (void)_this; } -void FileDescriptorProto::RegisterArenaDtor(::google::protobuf::Arena* arena) { +void FileDescriptorProto::RegisterArenaDtor(::google::protobuf::Arena*) { } void FileDescriptorProto::SetCachedSize(int size) const { _cached_size_.Set(size); @@ -2642,7 +2642,7 @@ void DescriptorProto_ExtensionRange::ArenaDtor(void* object) { DescriptorProto_ExtensionRange* _this = reinterpret_cast< DescriptorProto_ExtensionRange* >(object); (void)_this; } -void DescriptorProto_ExtensionRange::RegisterArenaDtor(::google::protobuf::Arena* arena) { +void DescriptorProto_ExtensionRange::RegisterArenaDtor(::google::protobuf::Arena*) { } void DescriptorProto_ExtensionRange::SetCachedSize(int size) const { _cached_size_.Set(size); @@ -2994,7 +2994,7 @@ void DescriptorProto_ReservedRange::ArenaDtor(void* object) { DescriptorProto_ReservedRange* _this = reinterpret_cast< DescriptorProto_ReservedRange* >(object); (void)_this; } -void DescriptorProto_ReservedRange::RegisterArenaDtor(::google::protobuf::Arena* arena) { +void DescriptorProto_ReservedRange::RegisterArenaDtor(::google::protobuf::Arena*) { } void DescriptorProto_ReservedRange::SetCachedSize(int size) const { _cached_size_.Set(size); @@ -3350,7 +3350,7 @@ void DescriptorProto::ArenaDtor(void* object) { DescriptorProto* _this = reinterpret_cast< DescriptorProto* >(object); (void)_this; } -void DescriptorProto::RegisterArenaDtor(::google::protobuf::Arena* arena) { +void DescriptorProto::RegisterArenaDtor(::google::protobuf::Arena*) { } void DescriptorProto::SetCachedSize(int size) const { _cached_size_.Set(size); @@ -4032,7 +4032,7 @@ void ExtensionRangeOptions::ArenaDtor(void* object) { ExtensionRangeOptions* _this = reinterpret_cast< ExtensionRangeOptions* >(object); (void)_this; } -void ExtensionRangeOptions::RegisterArenaDtor(::google::protobuf::Arena* arena) { +void ExtensionRangeOptions::RegisterArenaDtor(::google::protobuf::Arena*) { } void ExtensionRangeOptions::SetCachedSize(int size) const { _cached_size_.Set(size); @@ -4390,7 +4390,7 @@ void FieldDescriptorProto::ArenaDtor(void* object) { FieldDescriptorProto* _this = reinterpret_cast< FieldDescriptorProto* >(object); (void)_this; } -void FieldDescriptorProto::RegisterArenaDtor(::google::protobuf::Arena* arena) { +void FieldDescriptorProto::RegisterArenaDtor(::google::protobuf::Arena*) { } void FieldDescriptorProto::SetCachedSize(int size) const { _cached_size_.Set(size); @@ -4507,7 +4507,7 @@ bool FieldDescriptorProto::MergePartialFromCodedStream( case 4: { if (static_cast< ::google::protobuf::uint8>(tag) == static_cast< ::google::protobuf::uint8>(32u /* 32 & 0xFF */)) { - int value; + int value = 0; DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>( input, &value))); @@ -4527,7 +4527,7 @@ bool FieldDescriptorProto::MergePartialFromCodedStream( case 5: { if (static_cast< ::google::protobuf::uint8>(tag) == static_cast< ::google::protobuf::uint8>(40u /* 40 & 0xFF */)) { - int value; + int value = 0; DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>( input, &value))); @@ -5120,7 +5120,7 @@ void OneofDescriptorProto::ArenaDtor(void* object) { OneofDescriptorProto* _this = reinterpret_cast< OneofDescriptorProto* >(object); (void)_this; } -void OneofDescriptorProto::RegisterArenaDtor(::google::protobuf::Arena* arena) { +void OneofDescriptorProto::RegisterArenaDtor(::google::protobuf::Arena*) { } void OneofDescriptorProto::SetCachedSize(int size) const { _cached_size_.Set(size); @@ -5450,7 +5450,7 @@ void EnumDescriptorProto_EnumReservedRange::ArenaDtor(void* object) { EnumDescriptorProto_EnumReservedRange* _this = reinterpret_cast< EnumDescriptorProto_EnumReservedRange* >(object); (void)_this; } -void EnumDescriptorProto_EnumReservedRange::RegisterArenaDtor(::google::protobuf::Arena* arena) { +void EnumDescriptorProto_EnumReservedRange::RegisterArenaDtor(::google::protobuf::Arena*) { } void EnumDescriptorProto_EnumReservedRange::SetCachedSize(int size) const { _cached_size_.Set(size); @@ -5791,7 +5791,7 @@ void EnumDescriptorProto::ArenaDtor(void* object) { EnumDescriptorProto* _this = reinterpret_cast< EnumDescriptorProto* >(object); (void)_this; } -void EnumDescriptorProto::RegisterArenaDtor(::google::protobuf::Arena* arena) { +void EnumDescriptorProto::RegisterArenaDtor(::google::protobuf::Arena*) { } void EnumDescriptorProto::SetCachedSize(int size) const { _cached_size_.Set(size); @@ -6283,7 +6283,7 @@ void EnumValueDescriptorProto::ArenaDtor(void* object) { EnumValueDescriptorProto* _this = reinterpret_cast< EnumValueDescriptorProto* >(object); (void)_this; } -void EnumValueDescriptorProto::RegisterArenaDtor(::google::protobuf::Arena* arena) { +void EnumValueDescriptorProto::RegisterArenaDtor(::google::protobuf::Arena*) { } void EnumValueDescriptorProto::SetCachedSize(int size) const { _cached_size_.Set(size); @@ -6676,7 +6676,7 @@ void ServiceDescriptorProto::ArenaDtor(void* object) { ServiceDescriptorProto* _this = reinterpret_cast< ServiceDescriptorProto* >(object); (void)_this; } -void ServiceDescriptorProto::RegisterArenaDtor(::google::protobuf::Arena* arena) { +void ServiceDescriptorProto::RegisterArenaDtor(::google::protobuf::Arena*) { } void ServiceDescriptorProto::SetCachedSize(int size) const { _cached_size_.Set(size); @@ -7096,7 +7096,7 @@ void MethodDescriptorProto::ArenaDtor(void* object) { MethodDescriptorProto* _this = reinterpret_cast< MethodDescriptorProto* >(object); (void)_this; } -void MethodDescriptorProto::RegisterArenaDtor(::google::protobuf::Arena* arena) { +void MethodDescriptorProto::RegisterArenaDtor(::google::protobuf::Arena*) { } void MethodDescriptorProto::SetCachedSize(int size) const { _cached_size_.Set(size); @@ -7694,7 +7694,7 @@ void FileOptions::ArenaDtor(void* object) { FileOptions* _this = reinterpret_cast< FileOptions* >(object); (void)_this; } -void FileOptions::RegisterArenaDtor(::google::protobuf::Arena* arena) { +void FileOptions::RegisterArenaDtor(::google::protobuf::Arena*) { } void FileOptions::SetCachedSize(int size) const { _cached_size_.Set(size); @@ -7814,7 +7814,7 @@ bool FileOptions::MergePartialFromCodedStream( case 9: { if (static_cast< ::google::protobuf::uint8>(tag) == static_cast< ::google::protobuf::uint8>(72u /* 72 & 0xFF */)) { - int value; + int value = 0; DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>( input, &value))); @@ -8885,7 +8885,7 @@ void MessageOptions::ArenaDtor(void* object) { MessageOptions* _this = reinterpret_cast< MessageOptions* >(object); (void)_this; } -void MessageOptions::RegisterArenaDtor(::google::protobuf::Arena* arena) { +void MessageOptions::RegisterArenaDtor(::google::protobuf::Arena*) { } void MessageOptions::SetCachedSize(int size) const { _cached_size_.Set(size); @@ -9329,7 +9329,7 @@ void FieldOptions::ArenaDtor(void* object) { FieldOptions* _this = reinterpret_cast< FieldOptions* >(object); (void)_this; } -void FieldOptions::RegisterArenaDtor(::google::protobuf::Arena* arena) { +void FieldOptions::RegisterArenaDtor(::google::protobuf::Arena*) { } void FieldOptions::SetCachedSize(int size) const { _cached_size_.Set(size); @@ -9377,7 +9377,7 @@ bool FieldOptions::MergePartialFromCodedStream( case 1: { if (static_cast< ::google::protobuf::uint8>(tag) == static_cast< ::google::protobuf::uint8>(8u /* 8 & 0xFF */)) { - int value; + int value = 0; DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>( input, &value))); @@ -9439,7 +9439,7 @@ bool FieldOptions::MergePartialFromCodedStream( case 6: { if (static_cast< ::google::protobuf::uint8>(tag) == static_cast< ::google::protobuf::uint8>(48u /* 48 & 0xFF */)) { - int value; + int value = 0; DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>( input, &value))); @@ -9848,7 +9848,7 @@ void OneofOptions::ArenaDtor(void* object) { OneofOptions* _this = reinterpret_cast< OneofOptions* >(object); (void)_this; } -void OneofOptions::RegisterArenaDtor(::google::protobuf::Arena* arena) { +void OneofOptions::RegisterArenaDtor(::google::protobuf::Arena*) { } void OneofOptions::SetCachedSize(int size) const { _cached_size_.Set(size); @@ -10145,7 +10145,7 @@ void EnumOptions::ArenaDtor(void* object) { EnumOptions* _this = reinterpret_cast< EnumOptions* >(object); (void)_this; } -void EnumOptions::RegisterArenaDtor(::google::protobuf::Arena* arena) { +void EnumOptions::RegisterArenaDtor(::google::protobuf::Arena*) { } void EnumOptions::SetCachedSize(int size) const { _cached_size_.Set(size); @@ -10514,7 +10514,7 @@ void EnumValueOptions::ArenaDtor(void* object) { EnumValueOptions* _this = reinterpret_cast< EnumValueOptions* >(object); (void)_this; } -void EnumValueOptions::RegisterArenaDtor(::google::protobuf::Arena* arena) { +void EnumValueOptions::RegisterArenaDtor(::google::protobuf::Arena*) { } void EnumValueOptions::SetCachedSize(int size) const { _cached_size_.Set(size); @@ -10842,7 +10842,7 @@ void ServiceOptions::ArenaDtor(void* object) { ServiceOptions* _this = reinterpret_cast< ServiceOptions* >(object); (void)_this; } -void ServiceOptions::RegisterArenaDtor(::google::protobuf::Arena* arena) { +void ServiceOptions::RegisterArenaDtor(::google::protobuf::Arena*) { } void ServiceOptions::SetCachedSize(int size) const { _cached_size_.Set(size); @@ -11175,7 +11175,7 @@ void MethodOptions::ArenaDtor(void* object) { MethodOptions* _this = reinterpret_cast< MethodOptions* >(object); (void)_this; } -void MethodOptions::RegisterArenaDtor(::google::protobuf::Arena* arena) { +void MethodOptions::RegisterArenaDtor(::google::protobuf::Arena*) { } void MethodOptions::SetCachedSize(int size) const { _cached_size_.Set(size); @@ -11237,7 +11237,7 @@ bool MethodOptions::MergePartialFromCodedStream( case 34: { if (static_cast< ::google::protobuf::uint8>(tag) == static_cast< ::google::protobuf::uint8>(16u /* 272 & 0xFF */)) { - int value; + int value = 0; DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>( input, &value))); @@ -11559,7 +11559,7 @@ void UninterpretedOption_NamePart::ArenaDtor(void* object) { UninterpretedOption_NamePart* _this = reinterpret_cast< UninterpretedOption_NamePart* >(object); (void)_this; } -void UninterpretedOption_NamePart::RegisterArenaDtor(::google::protobuf::Arena* arena) { +void UninterpretedOption_NamePart::RegisterArenaDtor(::google::protobuf::Arena*) { } void UninterpretedOption_NamePart::SetCachedSize(int size) const { _cached_size_.Set(size); @@ -11924,7 +11924,7 @@ void UninterpretedOption::ArenaDtor(void* object) { UninterpretedOption* _this = reinterpret_cast< UninterpretedOption* >(object); (void)_this; } -void UninterpretedOption::RegisterArenaDtor(::google::protobuf::Arena* arena) { +void UninterpretedOption::RegisterArenaDtor(::google::protobuf::Arena*) { } void UninterpretedOption::SetCachedSize(int size) const { _cached_size_.Set(size); @@ -12473,7 +12473,7 @@ void SourceCodeInfo_Location::ArenaDtor(void* object) { SourceCodeInfo_Location* _this = reinterpret_cast< SourceCodeInfo_Location* >(object); (void)_this; } -void SourceCodeInfo_Location::RegisterArenaDtor(::google::protobuf::Arena* arena) { +void SourceCodeInfo_Location::RegisterArenaDtor(::google::protobuf::Arena*) { } void SourceCodeInfo_Location::SetCachedSize(int size) const { _cached_size_.Set(size); @@ -12979,7 +12979,7 @@ void SourceCodeInfo::ArenaDtor(void* object) { SourceCodeInfo* _this = reinterpret_cast< SourceCodeInfo* >(object); (void)_this; } -void SourceCodeInfo::RegisterArenaDtor(::google::protobuf::Arena* arena) { +void SourceCodeInfo::RegisterArenaDtor(::google::protobuf::Arena*) { } void SourceCodeInfo::SetCachedSize(int size) const { _cached_size_.Set(size); @@ -13258,7 +13258,7 @@ void GeneratedCodeInfo_Annotation::ArenaDtor(void* object) { GeneratedCodeInfo_Annotation* _this = reinterpret_cast< GeneratedCodeInfo_Annotation* >(object); (void)_this; } -void GeneratedCodeInfo_Annotation::RegisterArenaDtor(::google::protobuf::Arena* arena) { +void GeneratedCodeInfo_Annotation::RegisterArenaDtor(::google::protobuf::Arena*) { } void GeneratedCodeInfo_Annotation::SetCachedSize(int size) const { _cached_size_.Set(size); @@ -13676,7 +13676,7 @@ void GeneratedCodeInfo::ArenaDtor(void* object) { GeneratedCodeInfo* _this = reinterpret_cast< GeneratedCodeInfo* >(object); (void)_this; } -void GeneratedCodeInfo::RegisterArenaDtor(::google::protobuf::Arena* arena) { +void GeneratedCodeInfo::RegisterArenaDtor(::google::protobuf::Arena*) { } void GeneratedCodeInfo::SetCachedSize(int size) const { _cached_size_.Set(size); diff --git a/src/google/protobuf/descriptor_database.h b/src/google/protobuf/descriptor_database.h index d61f2a6a..07523660 100644 --- a/src/google/protobuf/descriptor_database.h +++ b/src/google/protobuf/descriptor_database.h @@ -142,7 +142,7 @@ class LIBPROTOBUF_EXPORT DescriptorDatabase { class LIBPROTOBUF_EXPORT SimpleDescriptorDatabase : public DescriptorDatabase { public: SimpleDescriptorDatabase(); - ~SimpleDescriptorDatabase(); + ~SimpleDescriptorDatabase() override; // Adds the FileDescriptorProto to the database, making a copy. The object // can be deleted after Add() returns. Returns false if the file conflicted @@ -155,14 +155,14 @@ class LIBPROTOBUF_EXPORT SimpleDescriptorDatabase : public DescriptorDatabase { // implements DescriptorDatabase ----------------------------------- bool FindFileByName(const string& filename, - FileDescriptorProto* output); + FileDescriptorProto* output) override; bool FindFileContainingSymbol(const string& symbol_name, - FileDescriptorProto* output); + FileDescriptorProto* output) override; bool FindFileContainingExtension(const string& containing_type, int field_number, - FileDescriptorProto* output); + FileDescriptorProto* output) override; bool FindAllExtensionNumbers(const string& extendee_type, - std::vector<int>* output); + std::vector<int>* output) override; private: // So that it can use DescriptorIndex. @@ -280,7 +280,7 @@ class LIBPROTOBUF_EXPORT SimpleDescriptorDatabase : public DescriptorDatabase { class LIBPROTOBUF_EXPORT EncodedDescriptorDatabase : public DescriptorDatabase { public: EncodedDescriptorDatabase(); - ~EncodedDescriptorDatabase(); + ~EncodedDescriptorDatabase() override; // Adds the FileDescriptorProto to the database. The descriptor is provided // in encoded form. The database does not make a copy of the bytes, nor @@ -300,14 +300,14 @@ class LIBPROTOBUF_EXPORT EncodedDescriptorDatabase : public DescriptorDatabase { // implements DescriptorDatabase ----------------------------------- bool FindFileByName(const string& filename, - FileDescriptorProto* output); + FileDescriptorProto* output) override; bool FindFileContainingSymbol(const string& symbol_name, - FileDescriptorProto* output); + FileDescriptorProto* output) override; bool FindFileContainingExtension(const string& containing_type, int field_number, - FileDescriptorProto* output); + FileDescriptorProto* output) override; bool FindAllExtensionNumbers(const string& extendee_type, - std::vector<int>* output); + std::vector<int>* output) override; private: SimpleDescriptorDatabase::DescriptorIndex<std::pair<const void*, int> > @@ -326,18 +326,18 @@ class LIBPROTOBUF_EXPORT EncodedDescriptorDatabase : public DescriptorDatabase { class LIBPROTOBUF_EXPORT DescriptorPoolDatabase : public DescriptorDatabase { public: explicit DescriptorPoolDatabase(const DescriptorPool& pool); - ~DescriptorPoolDatabase(); + ~DescriptorPoolDatabase() override; // implements DescriptorDatabase ----------------------------------- bool FindFileByName(const string& filename, - FileDescriptorProto* output); + FileDescriptorProto* output) override; bool FindFileContainingSymbol(const string& symbol_name, - FileDescriptorProto* output); + FileDescriptorProto* output) override; bool FindFileContainingExtension(const string& containing_type, int field_number, - FileDescriptorProto* output); + FileDescriptorProto* output) override; bool FindAllExtensionNumbers(const string& extendee_type, - std::vector<int>* output); + std::vector<int>* output) override; private: const DescriptorPool& pool_; @@ -356,20 +356,20 @@ class LIBPROTOBUF_EXPORT MergedDescriptorDatabase : public DescriptorDatabase { // DescriptorDatabases need to stick around. explicit MergedDescriptorDatabase( const std::vector<DescriptorDatabase*>& sources); - ~MergedDescriptorDatabase(); + ~MergedDescriptorDatabase() override; // implements DescriptorDatabase ----------------------------------- bool FindFileByName(const string& filename, - FileDescriptorProto* output); + FileDescriptorProto* output) override; bool FindFileContainingSymbol(const string& symbol_name, - FileDescriptorProto* output); + FileDescriptorProto* output) override; bool FindFileContainingExtension(const string& containing_type, int field_number, - FileDescriptorProto* output); + FileDescriptorProto* output) override; // Merges the results of calling all databases. Returns true iff any // of the databases returned true. bool FindAllExtensionNumbers(const string& extendee_type, - std::vector<int>* output); + std::vector<int>* output) override; private: diff --git a/src/google/protobuf/duration.pb.cc b/src/google/protobuf/duration.pb.cc index ddc063db..e8417a78 100644 --- a/src/google/protobuf/duration.pb.cc +++ b/src/google/protobuf/duration.pb.cc @@ -66,14 +66,14 @@ static ::google::protobuf::Message const * const file_default_instances[] = { reinterpret_cast<const ::google::protobuf::Message*>(&::google::protobuf::_Duration_default_instance_), }; -void protobuf_AssignDescriptors() { +static void protobuf_AssignDescriptors() { AddDescriptors(); AssignDescriptors( "google/protobuf/duration.proto", schemas, file_default_instances, TableStruct::offsets, file_level_metadata, NULL, NULL); } -void protobuf_AssignDescriptorsOnce() { +static void protobuf_AssignDescriptorsOnce() { static ::google::protobuf::internal::once_flag once; ::google::protobuf::internal::call_once(once, protobuf_AssignDescriptors); } @@ -84,7 +84,7 @@ void protobuf_RegisterTypes(const ::std::string&) { ::google::protobuf::internal::RegisterAllTypes(file_level_metadata, 1); } -void AddDescriptorsImpl() { +static void AddDescriptorsImpl() { InitDefaults(); static const char descriptor[] GOOGLE_PROTOBUF_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold) = { "\n\036google/protobuf/duration.proto\022\017google" @@ -167,7 +167,7 @@ void Duration::ArenaDtor(void* object) { Duration* _this = reinterpret_cast< Duration* >(object); (void)_this; } -void Duration::RegisterArenaDtor(::google::protobuf::Arena* arena) { +void Duration::RegisterArenaDtor(::google::protobuf::Arena*) { } void Duration::SetCachedSize(int size) const { _cached_size_.Set(size); diff --git a/src/google/protobuf/dynamic_message.cc b/src/google/protobuf/dynamic_message.cc index ceedf500..8ad112ce 100644 --- a/src/google/protobuf/dynamic_message.cc +++ b/src/google/protobuf/dynamic_message.cc @@ -258,14 +258,14 @@ class DynamicMessage : public Message { // implements Message ---------------------------------------------- - Message* New() const; - Message* New(::google::protobuf::Arena* arena) const; - ::google::protobuf::Arena* GetArena() const { return arena_; } + Message* New() const override; + Message* New(::google::protobuf::Arena* arena) const override; + ::google::protobuf::Arena* GetArena() const override { return arena_; } - int GetCachedSize() const; - void SetCachedSize(int size) const; + int GetCachedSize() const override; + void SetCachedSize(int size) const override; - Metadata GetMetadata() const; + Metadata GetMetadata() const override; // We actually allocate more memory than sizeof(*this) when this // class's memory is allocated via the global operator new. Thus, we need to diff --git a/src/google/protobuf/dynamic_message.h b/src/google/protobuf/dynamic_message.h index d84cc8af..940d5e15 100644 --- a/src/google/protobuf/dynamic_message.h +++ b/src/google/protobuf/dynamic_message.h @@ -115,7 +115,7 @@ class LIBPROTOBUF_EXPORT DynamicMessageFactory : public MessageFactory { // outlive the DynamicMessageFactory. // // The method is thread-safe. - const Message* GetPrototype(const Descriptor* type); + const Message* GetPrototype(const Descriptor* type) override; private: const DescriptorPool* pool_; diff --git a/src/google/protobuf/empty.pb.cc b/src/google/protobuf/empty.pb.cc index 9b53c546..163a4f6a 100644 --- a/src/google/protobuf/empty.pb.cc +++ b/src/google/protobuf/empty.pb.cc @@ -64,14 +64,14 @@ static ::google::protobuf::Message const * const file_default_instances[] = { reinterpret_cast<const ::google::protobuf::Message*>(&::google::protobuf::_Empty_default_instance_), }; -void protobuf_AssignDescriptors() { +static void protobuf_AssignDescriptors() { AddDescriptors(); AssignDescriptors( "google/protobuf/empty.proto", schemas, file_default_instances, TableStruct::offsets, file_level_metadata, NULL, NULL); } -void protobuf_AssignDescriptorsOnce() { +static void protobuf_AssignDescriptorsOnce() { static ::google::protobuf::internal::once_flag once; ::google::protobuf::internal::call_once(once, protobuf_AssignDescriptors); } @@ -82,7 +82,7 @@ void protobuf_RegisterTypes(const ::std::string&) { ::google::protobuf::internal::RegisterAllTypes(file_level_metadata, 1); } -void AddDescriptorsImpl() { +static void AddDescriptorsImpl() { InitDefaults(); static const char descriptor[] GOOGLE_PROTOBUF_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold) = { "\n\033google/protobuf/empty.proto\022\017google.pr" @@ -156,7 +156,7 @@ void Empty::ArenaDtor(void* object) { Empty* _this = reinterpret_cast< Empty* >(object); (void)_this; } -void Empty::RegisterArenaDtor(::google::protobuf::Arena* arena) { +void Empty::RegisterArenaDtor(::google::protobuf::Arena*) { } void Empty::SetCachedSize(int size) const { _cached_size_.Set(size); diff --git a/src/google/protobuf/extension_set.h b/src/google/protobuf/extension_set.h index a1535baa..04d0e62c 100644 --- a/src/google/protobuf/extension_set.h +++ b/src/google/protobuf/extension_set.h @@ -134,7 +134,7 @@ class LIBPROTOBUF_EXPORT GeneratedExtensionFinder : public ExtensionFinder { virtual ~GeneratedExtensionFinder() {} // Returns true and fills in *output if found, otherwise returns false. - virtual bool Find(int number, ExtensionInfo* output); + virtual bool Find(int number, ExtensionInfo* output) override; private: const MessageLite* containing_type_; diff --git a/src/google/protobuf/extension_set_heavy.cc b/src/google/protobuf/extension_set_heavy.cc index a3c84167..372aea57 100644 --- a/src/google/protobuf/extension_set_heavy.cc +++ b/src/google/protobuf/extension_set_heavy.cc @@ -85,9 +85,9 @@ class DescriptorPoolExtensionFinder : public ExtensionFinder { MessageFactory* factory, const Descriptor* containing_type) : pool_(pool), factory_(factory), containing_type_(containing_type) {} - virtual ~DescriptorPoolExtensionFinder() {} + virtual ~DescriptorPoolExtensionFinder() override {} - virtual bool Find(int number, ExtensionInfo* output); + virtual bool Find(int number, ExtensionInfo* output) override; private: const DescriptorPool* pool_; diff --git a/src/google/protobuf/field_mask.pb.cc b/src/google/protobuf/field_mask.pb.cc index 000fa8d3..2ce061d9 100644 --- a/src/google/protobuf/field_mask.pb.cc +++ b/src/google/protobuf/field_mask.pb.cc @@ -65,14 +65,14 @@ static ::google::protobuf::Message const * const file_default_instances[] = { reinterpret_cast<const ::google::protobuf::Message*>(&::google::protobuf::_FieldMask_default_instance_), }; -void protobuf_AssignDescriptors() { +static void protobuf_AssignDescriptors() { AddDescriptors(); AssignDescriptors( "google/protobuf/field_mask.proto", schemas, file_default_instances, TableStruct::offsets, file_level_metadata, NULL, NULL); } -void protobuf_AssignDescriptorsOnce() { +static void protobuf_AssignDescriptorsOnce() { static ::google::protobuf::internal::once_flag once; ::google::protobuf::internal::call_once(once, protobuf_AssignDescriptors); } @@ -83,7 +83,7 @@ void protobuf_RegisterTypes(const ::std::string&) { ::google::protobuf::internal::RegisterAllTypes(file_level_metadata, 1); } -void AddDescriptorsImpl() { +static void AddDescriptorsImpl() { InitDefaults(); static const char descriptor[] GOOGLE_PROTOBUF_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold) = { "\n google/protobuf/field_mask.proto\022\017goog" diff --git a/src/google/protobuf/generated_message_reflection.h b/src/google/protobuf/generated_message_reflection.h index 31f249b6..28a023b6 100644 --- a/src/google/protobuf/generated_message_reflection.h +++ b/src/google/protobuf/generated_message_reflection.h @@ -304,199 +304,208 @@ class GeneratedMessageReflection final : public Reflection { const DescriptorPool* pool, MessageFactory* factory); - ~GeneratedMessageReflection(); + + ~GeneratedMessageReflection() override; // implements Reflection ------------------------------------------- - const UnknownFieldSet& GetUnknownFields(const Message& message) const; - UnknownFieldSet* MutableUnknownFields(Message* message) const; + const UnknownFieldSet& GetUnknownFields( + const Message& message) const override; + UnknownFieldSet* MutableUnknownFields(Message* message) const override; - size_t SpaceUsedLong(const Message& message) const; + size_t SpaceUsedLong(const Message& message) const override; - bool HasField(const Message& message, const FieldDescriptor* field) const; - int FieldSize(const Message& message, const FieldDescriptor* field) const; - void ClearField(Message* message, const FieldDescriptor* field) const; + bool HasField(const Message& message, + const FieldDescriptor* field) const override; + int FieldSize(const Message& message, + const FieldDescriptor* field) const override; + void ClearField(Message* message, + const FieldDescriptor* field) const override; bool HasOneof(const Message& message, - const OneofDescriptor* oneof_descriptor) const; - void ClearOneof(Message* message, const OneofDescriptor* field) const; - void RemoveLast(Message* message, const FieldDescriptor* field) const; - Message* ReleaseLast(Message* message, const FieldDescriptor* field) const; - void Swap(Message* message1, Message* message2) const; + const OneofDescriptor* oneof_descriptor) const override; + void ClearOneof(Message* message, + const OneofDescriptor* field) const override; + void RemoveLast(Message* message, + const FieldDescriptor* field) const override; + Message* ReleaseLast(Message* message, + const FieldDescriptor* field) const override; + void Swap(Message* message1, Message* message2) const override; void SwapFields(Message* message1, Message* message2, - const std::vector<const FieldDescriptor*>& fields) const; + const std::vector<const FieldDescriptor*>& fields) const override; void SwapElements(Message* message, const FieldDescriptor* field, - int index1, int index2) const; + int index1, int index2) const override; void ListFields(const Message& message, - std::vector<const FieldDescriptor*>* output) const; - + std::vector<const FieldDescriptor*>* output) const override; int32 GetInt32 (const Message& message, - const FieldDescriptor* field) const; + const FieldDescriptor* field) const override; int64 GetInt64 (const Message& message, - const FieldDescriptor* field) const; + const FieldDescriptor* field) const override; uint32 GetUInt32(const Message& message, - const FieldDescriptor* field) const; + const FieldDescriptor* field) const override; uint64 GetUInt64(const Message& message, - const FieldDescriptor* field) const; + const FieldDescriptor* field) const override; float GetFloat (const Message& message, - const FieldDescriptor* field) const; + const FieldDescriptor* field) const override; double GetDouble(const Message& message, - const FieldDescriptor* field) const; + const FieldDescriptor* field) const override; bool GetBool (const Message& message, - const FieldDescriptor* field) const; + const FieldDescriptor* field) const override; string GetString(const Message& message, - const FieldDescriptor* field) const; + const FieldDescriptor* field) const override; const string& GetStringReference(const Message& message, const FieldDescriptor* field, - string* scratch) const; - const EnumValueDescriptor* GetEnum(const Message& message, - const FieldDescriptor* field) const; + string* scratch) const override; + const EnumValueDescriptor* GetEnum( + const Message& message, const FieldDescriptor* field) const override; int GetEnumValue(const Message& message, - const FieldDescriptor* field) const; + const FieldDescriptor* field) const override; const Message& GetMessage(const Message& message, const FieldDescriptor* field, - MessageFactory* factory = NULL) const; + MessageFactory* factory = NULL) const override; const FieldDescriptor* GetOneofFieldDescriptor( const Message& message, - const OneofDescriptor* oneof_descriptor) const; + const OneofDescriptor* oneof_descriptor) const override; private: bool ContainsMapKey(const Message& message, const FieldDescriptor* field, - const MapKey& key) const; + const MapKey& key) const override; bool InsertOrLookupMapValue(Message* message, const FieldDescriptor* field, const MapKey& key, - MapValueRef* val) const; + MapValueRef* val) const override; bool DeleteMapValue(Message* message, const FieldDescriptor* field, - const MapKey& key) const; + const MapKey& key) const override; MapIterator MapBegin( Message* message, - const FieldDescriptor* field) const; + const FieldDescriptor* field) const override; MapIterator MapEnd( Message* message, - const FieldDescriptor* field) const; - int MapSize(const Message& message, const FieldDescriptor* field) const; + const FieldDescriptor* field) const override; + int MapSize(const Message& message, + const FieldDescriptor* field) const override; public: void SetInt32 (Message* message, - const FieldDescriptor* field, int32 value) const; + const FieldDescriptor* field, int32 value) const override; void SetInt64 (Message* message, - const FieldDescriptor* field, int64 value) const; + const FieldDescriptor* field, int64 value) const override; void SetUInt32(Message* message, - const FieldDescriptor* field, uint32 value) const; + const FieldDescriptor* field, uint32 value) const override; void SetUInt64(Message* message, - const FieldDescriptor* field, uint64 value) const; + const FieldDescriptor* field, uint64 value) const override; void SetFloat (Message* message, - const FieldDescriptor* field, float value) const; + const FieldDescriptor* field, float value) const override; void SetDouble(Message* message, - const FieldDescriptor* field, double value) const; + const FieldDescriptor* field, double value) const override; void SetBool (Message* message, - const FieldDescriptor* field, bool value) const; + const FieldDescriptor* field, bool value) const override; void SetString(Message* message, const FieldDescriptor* field, - const string& value) const; + const string& value) const override; void SetEnum (Message* message, const FieldDescriptor* field, - const EnumValueDescriptor* value) const; + const EnumValueDescriptor* value) const override; void SetEnumValue(Message* message, const FieldDescriptor* field, - int value) const; + int value) const override; Message* MutableMessage(Message* message, const FieldDescriptor* field, - MessageFactory* factory = NULL) const; + MessageFactory* factory = NULL) const override; void SetAllocatedMessage(Message* message, Message* sub_message, - const FieldDescriptor* field) const; + const FieldDescriptor* field) const override; Message* ReleaseMessage(Message* message, const FieldDescriptor* field, - MessageFactory* factory = NULL) const; - - int32 GetRepeatedInt32 (const Message& message, - const FieldDescriptor* field, int index) const; - int64 GetRepeatedInt64 (const Message& message, - const FieldDescriptor* field, int index) const; - uint32 GetRepeatedUInt32(const Message& message, - const FieldDescriptor* field, int index) const; - uint64 GetRepeatedUInt64(const Message& message, - const FieldDescriptor* field, int index) const; - float GetRepeatedFloat (const Message& message, - const FieldDescriptor* field, int index) const; - double GetRepeatedDouble(const Message& message, - const FieldDescriptor* field, int index) const; - bool GetRepeatedBool (const Message& message, - const FieldDescriptor* field, int index) const; - string GetRepeatedString(const Message& message, - const FieldDescriptor* field, int index) const; - const string& GetRepeatedStringReference(const Message& message, + MessageFactory* factory = NULL) const override; + + int32 GetRepeatedInt32(const Message& message, const FieldDescriptor* field, + int index) const override; + int64 GetRepeatedInt64(const Message& message, const FieldDescriptor* field, + int index) const override; + uint32 GetRepeatedUInt32(const Message& message, const FieldDescriptor* field, + int index) const override; + uint64 GetRepeatedUInt64(const Message& message, const FieldDescriptor* field, + int index) const override; + float GetRepeatedFloat(const Message& message, const FieldDescriptor* field, + int index) const override; + double GetRepeatedDouble(const Message& message, const FieldDescriptor* field, + int index) const override; + bool GetRepeatedBool(const Message& message, const FieldDescriptor* field, + int index) const override; + string GetRepeatedString(const Message& message, const FieldDescriptor* field, + int index) const override; + const string &GetRepeatedStringReference(const Message& message, const FieldDescriptor* field, - int index, string* scratch) const; + int index, + string* scratch) const override; const EnumValueDescriptor* GetRepeatedEnum(const Message& message, const FieldDescriptor* field, - int index) const; - int GetRepeatedEnumValue(const Message& message, - const FieldDescriptor* field, - int index) const; - const Message& GetRepeatedMessage(const Message& message, + int index) const override; + int GetRepeatedEnumValue(const Message& message, const FieldDescriptor* field, + int index) const override; + const Message &GetRepeatedMessage(const Message& message, const FieldDescriptor* field, - int index) const; + int index) const override; // Set the value of a field. - void SetRepeatedInt32 (Message* message, - const FieldDescriptor* field, int index, int32 value) const; - void SetRepeatedInt64 (Message* message, - const FieldDescriptor* field, int index, int64 value) const; - void SetRepeatedUInt32(Message* message, - const FieldDescriptor* field, int index, uint32 value) const; - void SetRepeatedUInt64(Message* message, - const FieldDescriptor* field, int index, uint64 value) const; - void SetRepeatedFloat (Message* message, - const FieldDescriptor* field, int index, float value) const; - void SetRepeatedDouble(Message* message, - const FieldDescriptor* field, int index, double value) const; - void SetRepeatedBool (Message* message, - const FieldDescriptor* field, int index, bool value) const; - void SetRepeatedString(Message* message, - const FieldDescriptor* field, int index, - const string& value) const; + void SetRepeatedInt32(Message* message, const FieldDescriptor* field, + int index, int32 value) const override; + void SetRepeatedInt64(Message* message, const FieldDescriptor* field, + int index, int64 value) const override; + void SetRepeatedUInt32(Message* message, const FieldDescriptor* field, + int index, uint32 value) const override; + void SetRepeatedUInt64(Message* message, const FieldDescriptor* field, + int index, uint64 value) const override; + void SetRepeatedFloat(Message* message, const FieldDescriptor* field, + int index, float value) const override; + void SetRepeatedDouble(Message* message, const FieldDescriptor* field, + int index, double value) const override; + void SetRepeatedBool(Message* message, const FieldDescriptor* field, + int index, bool value) const override; + void SetRepeatedString(Message* message, const FieldDescriptor* field, + int index, const string &value) const override; void SetRepeatedEnum(Message* message, const FieldDescriptor* field, - int index, const EnumValueDescriptor* value) const; + int index, + const EnumValueDescriptor* value) const override; void SetRepeatedEnumValue(Message* message, const FieldDescriptor* field, - int index, int value) const; + int index, int value) const override; // Get a mutable pointer to a field with a message type. Message* MutableRepeatedMessage(Message* message, const FieldDescriptor* field, - int index) const; + int index) const override; void AddInt32 (Message* message, - const FieldDescriptor* field, int32 value) const; + const FieldDescriptor* field, int32 value) const override; void AddInt64 (Message* message, - const FieldDescriptor* field, int64 value) const; + const FieldDescriptor* field, int64 value) const override; void AddUInt32(Message* message, - const FieldDescriptor* field, uint32 value) const; + const FieldDescriptor* field, uint32 value) const override; void AddUInt64(Message* message, - const FieldDescriptor* field, uint64 value) const; + const FieldDescriptor* field, uint64 value) const override; void AddFloat (Message* message, - const FieldDescriptor* field, float value) const; + const FieldDescriptor* field, float value) const override; void AddDouble(Message* message, - const FieldDescriptor* field, double value) const; + const FieldDescriptor* field, double value) const override; void AddBool (Message* message, - const FieldDescriptor* field, bool value) const; - void AddString(Message* message, - const FieldDescriptor* field, const string& value) const; + const FieldDescriptor* field, bool value) const override; + void AddString(Message* message, const FieldDescriptor* field, + const string& value) const override; void AddEnum(Message* message, const FieldDescriptor* field, - const EnumValueDescriptor* value) const; + const EnumValueDescriptor* value) const override; void AddEnumValue(Message* message, const FieldDescriptor* field, - int value) const; + int value) const override; Message* AddMessage(Message* message, const FieldDescriptor* field, - MessageFactory* factory = NULL) const; + MessageFactory* factory = NULL) const override; void AddAllocatedMessage( Message* message, const FieldDescriptor* field, - Message* new_entry) const; + Message* new_entry) const override; - const FieldDescriptor* FindKnownExtensionByName(const string& name) const; - const FieldDescriptor* FindKnownExtensionByNumber(int number) const; + const FieldDescriptor* FindKnownExtensionByName( + const string& name) const override; + const FieldDescriptor* FindKnownExtensionByNumber(int number) const override; - bool SupportsUnknownEnumValues() const; + bool SupportsUnknownEnumValues() const override; // This value for arena_offset_ indicates that there is no arena pointer in // this message (e.g., old generated code). @@ -514,19 +523,19 @@ class GeneratedMessageReflection final : public Reflection { protected: void* MutableRawRepeatedField( Message* message, const FieldDescriptor* field, FieldDescriptor::CppType, - int ctype, const Descriptor* desc) const; + int ctype, const Descriptor* desc) const override; const void* GetRawRepeatedField( const Message& message, const FieldDescriptor* field, FieldDescriptor::CppType, int ctype, - const Descriptor* desc) const; + const Descriptor* desc) const override; - virtual MessageFactory* GetMessageFactory() const; + virtual MessageFactory* GetMessageFactory() const override; virtual void* RepeatedFieldData( Message* message, const FieldDescriptor* field, FieldDescriptor::CppType cpp_type, - const Descriptor* message_type) const; + const Descriptor* message_type) const override; private: friend class google::protobuf::flat::MetadataBuilder; @@ -661,7 +670,7 @@ class GeneratedMessageReflection final : public Reflection { const FieldDescriptor* field) const; internal::MapFieldBase* MapData( - Message* message, const FieldDescriptor* field) const; + Message* message, const FieldDescriptor* field) const override; friend inline // inline so nobody can call this function. void diff --git a/src/google/protobuf/generated_message_util.h b/src/google/protobuf/generated_message_util.h index 04f68a6e..76b81242 100644 --- a/src/google/protobuf/generated_message_util.h +++ b/src/google/protobuf/generated_message_util.h @@ -206,7 +206,7 @@ struct SerializationTable { }; LIBPROTOBUF_EXPORT void SerializeInternal(const uint8* base, const FieldMetadata* table, - int num_fields, ::google::protobuf::io::CodedOutputStream* output); + int32 num_fields, ::google::protobuf::io::CodedOutputStream* output); inline void TableSerialize(const ::google::protobuf::MessageLite& msg, const SerializationTable* table, @@ -224,7 +224,7 @@ inline void TableSerialize(const ::google::protobuf::MessageLite& msg, } uint8* SerializeInternalToArray(const uint8* base, const FieldMetadata* table, - int num_fields, bool is_deterministic, + int32 num_fields, bool is_deterministic, uint8* buffer); inline uint8* TableSerializeToArray(const ::google::protobuf::MessageLite& msg, diff --git a/src/google/protobuf/io/gzip_stream.h b/src/google/protobuf/io/gzip_stream.h index 15b02fe3..df1a446e 100644 --- a/src/google/protobuf/io/gzip_stream.h +++ b/src/google/protobuf/io/gzip_stream.h @@ -118,7 +118,7 @@ class LIBPROTOBUF_EXPORT GzipOutputStream : public ZeroCopyOutputStream { ZLIB = 2, }; - struct Options { + struct LIBPROTOBUF_EXPORT Options { // Defaults to GZIP. Format format; diff --git a/src/google/protobuf/io/zero_copy_stream_impl.h b/src/google/protobuf/io/zero_copy_stream_impl.h index ea978bfb..ef9fc9d2 100644 --- a/src/google/protobuf/io/zero_copy_stream_impl.h +++ b/src/google/protobuf/io/zero_copy_stream_impl.h @@ -87,24 +87,24 @@ class LIBPROTOBUF_EXPORT FileInputStream : public ZeroCopyInputStream { int GetErrno() { return copying_input_.GetErrno(); } // implements ZeroCopyInputStream ---------------------------------- - bool Next(const void** data, int* size); - void BackUp(int count); - bool Skip(int count); - int64 ByteCount() const; + bool Next(const void** data, int* size) override; + void BackUp(int count) override; + bool Skip(int count) override; + int64 ByteCount() const override; private: class LIBPROTOBUF_EXPORT CopyingFileInputStream : public CopyingInputStream { public: CopyingFileInputStream(int file_descriptor); - ~CopyingFileInputStream(); + ~CopyingFileInputStream() override; bool Close(); void SetCloseOnDelete(bool value) { close_on_delete_ = value; } int GetErrno() { return errno_; } // implements CopyingInputStream --------------------------------- - int Read(void* buffer, int size); - int Skip(int count); + int Read(void* buffer, int size) override; + int Skip(int count) override; private: // The file descriptor. @@ -144,7 +144,7 @@ class LIBPROTOBUF_EXPORT FileOutputStream : public ZeroCopyOutputStream { // that should be returned by Next(). Otherwise, a reasonable default // is used. explicit FileOutputStream(int file_descriptor, int block_size = -1); - ~FileOutputStream(); + ~FileOutputStream() override; // Flushes any buffers and closes the underlying file. Returns false if // an error occurs during the process; use GetErrno() to examine the error. @@ -170,22 +170,22 @@ class LIBPROTOBUF_EXPORT FileOutputStream : public ZeroCopyOutputStream { int GetErrno() { return copying_output_.GetErrno(); } // implements ZeroCopyOutputStream --------------------------------- - bool Next(void** data, int* size); - void BackUp(int count); - int64 ByteCount() const; + bool Next(void** data, int* size) override; + void BackUp(int count) override; + int64 ByteCount() const override; private: class LIBPROTOBUF_EXPORT CopyingFileOutputStream : public CopyingOutputStream { public: CopyingFileOutputStream(int file_descriptor); - ~CopyingFileOutputStream(); + ~CopyingFileOutputStream() override; bool Close(); void SetCloseOnDelete(bool value) { close_on_delete_ = value; } int GetErrno() { return errno_; } // implements CopyingOutputStream -------------------------------- - bool Write(const void* buffer, int size); + bool Write(const void* buffer, int size) override; private: // The file descriptor. @@ -220,19 +220,19 @@ class LIBPROTOBUF_EXPORT IstreamInputStream : public ZeroCopyInputStream { explicit IstreamInputStream(std::istream* stream, int block_size = -1); // implements ZeroCopyInputStream ---------------------------------- - bool Next(const void** data, int* size); - void BackUp(int count); - bool Skip(int count); - int64 ByteCount() const; + bool Next(const void** data, int* size) override; + void BackUp(int count) override; + bool Skip(int count) override; + int64 ByteCount() const override; private: class LIBPROTOBUF_EXPORT CopyingIstreamInputStream : public CopyingInputStream { public: CopyingIstreamInputStream(std::istream* input); - ~CopyingIstreamInputStream(); + ~CopyingIstreamInputStream() override; // implements CopyingInputStream --------------------------------- - int Read(void* buffer, int size); + int Read(void* buffer, int size) override; // (We use the default implementation of Skip().) private: @@ -261,21 +261,21 @@ class LIBPROTOBUF_EXPORT OstreamOutputStream : public ZeroCopyOutputStream { // that should be returned by Next(). Otherwise, a reasonable default // is used. explicit OstreamOutputStream(std::ostream* stream, int block_size = -1); - ~OstreamOutputStream(); + ~OstreamOutputStream() override; // implements ZeroCopyOutputStream --------------------------------- - bool Next(void** data, int* size); - void BackUp(int count); - int64 ByteCount() const; + bool Next(void** data, int* size) override; + void BackUp(int count) override; + int64 ByteCount() const override; private: class LIBPROTOBUF_EXPORT CopyingOstreamOutputStream : public CopyingOutputStream { public: CopyingOstreamOutputStream(std::ostream* output); - ~CopyingOstreamOutputStream(); + ~CopyingOstreamOutputStream() override; // implements CopyingOutputStream -------------------------------- - bool Write(const void* buffer, int size); + bool Write(const void* buffer, int size) override; private: // The stream. @@ -304,12 +304,13 @@ class LIBPROTOBUF_EXPORT ConcatenatingInputStream : public ZeroCopyInputStream { // All streams passed in as well as the array itself must remain valid // until the ConcatenatingInputStream is destroyed. ConcatenatingInputStream(ZeroCopyInputStream* const streams[], int count); + ~ConcatenatingInputStream() override = default; // implements ZeroCopyInputStream ---------------------------------- - bool Next(const void** data, int* size); - void BackUp(int count); - bool Skip(int count); - int64 ByteCount() const; + bool Next(const void** data, int* size) override; + void BackUp(int count) override; + bool Skip(int count) override; + int64 ByteCount() const override; private: @@ -329,13 +330,13 @@ class LIBPROTOBUF_EXPORT ConcatenatingInputStream : public ZeroCopyInputStream { class LIBPROTOBUF_EXPORT LimitingInputStream : public ZeroCopyInputStream { public: LimitingInputStream(ZeroCopyInputStream* input, int64 limit); - ~LimitingInputStream(); + ~LimitingInputStream() override; // implements ZeroCopyInputStream ---------------------------------- - bool Next(const void** data, int* size); - void BackUp(int count); - bool Skip(int count); - int64 ByteCount() const; + bool Next(const void** data, int* size) override; + void BackUp(int count) override; + bool Skip(int count) override; + int64 ByteCount() const override; private: diff --git a/src/google/protobuf/io/zero_copy_stream_impl_lite.h b/src/google/protobuf/io/zero_copy_stream_impl_lite.h index 29f63bf0..38b6cde6 100644 --- a/src/google/protobuf/io/zero_copy_stream_impl_lite.h +++ b/src/google/protobuf/io/zero_copy_stream_impl_lite.h @@ -70,12 +70,13 @@ class LIBPROTOBUF_EXPORT ArrayInputStream : public ZeroCopyInputStream { // useful for testing; in production you would probably never want to set // it. ArrayInputStream(const void* data, int size, int block_size = -1); + ~ArrayInputStream() override = default; // implements ZeroCopyInputStream ---------------------------------- - bool Next(const void** data, int* size); - void BackUp(int count); - bool Skip(int count); - int64 ByteCount() const; + bool Next(const void** data, int* size) override; + void BackUp(int count) override; + bool Skip(int count) override; + int64 ByteCount() const override; private: @@ -103,11 +104,12 @@ class LIBPROTOBUF_EXPORT ArrayOutputStream : public ZeroCopyOutputStream { // useful for testing; in production you would probably never want to set // it. ArrayOutputStream(void* data, int size, int block_size = -1); + ~ArrayOutputStream() override = default; // implements ZeroCopyOutputStream --------------------------------- - bool Next(void** data, int* size); - void BackUp(int count); - int64 ByteCount() const; + bool Next(void** data, int* size) override; + void BackUp(int count) override; + int64 ByteCount() const override; private: uint8* const data_; // The byte array. @@ -136,11 +138,12 @@ class LIBPROTOBUF_EXPORT StringOutputStream : public ZeroCopyOutputStream { // the first call to Next() will return at least n bytes of buffer // space. explicit StringOutputStream(string* target); + ~StringOutputStream() override = default; // implements ZeroCopyOutputStream --------------------------------- - bool Next(void** data, int* size); - void BackUp(int count); - int64 ByteCount() const; + bool Next(void** data, int* size) override; + void BackUp(int count) override; + int64 ByteCount() const override; protected: void SetString(string* target); @@ -205,17 +208,17 @@ class LIBPROTOBUF_EXPORT CopyingInputStreamAdaptor : public ZeroCopyInputStream // copying_stream unless SetOwnsCopyingStream(true) is called. explicit CopyingInputStreamAdaptor(CopyingInputStream* copying_stream, int block_size = -1); - ~CopyingInputStreamAdaptor(); + ~CopyingInputStreamAdaptor() override; // Call SetOwnsCopyingStream(true) to tell the CopyingInputStreamAdaptor to // delete the underlying CopyingInputStream when it is destroyed. void SetOwnsCopyingStream(bool value) { owns_copying_stream_ = value; } // implements ZeroCopyInputStream ---------------------------------- - bool Next(const void** data, int* size); - void BackUp(int count); - bool Skip(int count); - int64 ByteCount() const; + bool Next(const void** data, int* size) override; + void BackUp(int count) override; + bool Skip(int count) override; + int64 ByteCount() const override; private: // Insures that buffer_ is not NULL. @@ -288,7 +291,7 @@ class LIBPROTOBUF_EXPORT CopyingOutputStreamAdaptor : public ZeroCopyOutputStrea // is used. explicit CopyingOutputStreamAdaptor(CopyingOutputStream* copying_stream, int block_size = -1); - ~CopyingOutputStreamAdaptor(); + ~CopyingOutputStreamAdaptor() override; // Writes all pending data to the underlying stream. Returns false if a // write error occurred on the underlying stream. (The underlying @@ -300,9 +303,9 @@ class LIBPROTOBUF_EXPORT CopyingOutputStreamAdaptor : public ZeroCopyOutputStrea void SetOwnsCopyingStream(bool value) { owns_copying_stream_ = value; } // implements ZeroCopyOutputStream --------------------------------- - bool Next(void** data, int* size); - void BackUp(int count); - int64 ByteCount() const; + bool Next(void** data, int* size) override; + void BackUp(int count) override; + int64 ByteCount() const override; private: // Write the current buffer, if it is present. diff --git a/src/google/protobuf/map_entry.h b/src/google/protobuf/map_entry.h index 801def97..f170f97b 100644 --- a/src/google/protobuf/map_entry.h +++ b/src/google/protobuf/map_entry.h @@ -95,6 +95,19 @@ class MapEntry typedef void InternalArenaConstructable_; typedef void DestructorSkippable_; + typedef typename MapEntryImpl< + Derived, Message, Key, Value, kKeyFieldType, kValueFieldType, + default_enum_value>::KeyTypeHandler KeyTypeHandler; + typedef typename MapEntryImpl< + Derived, Message, Key, Value, kKeyFieldType, kValueFieldType, + default_enum_value>::ValueTypeHandler ValueTypeHandler; + size_t SpaceUsedLong() const override { + size_t size = sizeof(Derived); + size += KeyTypeHandler::SpaceUsedInMapEntryLong(this->key_); + size += ValueTypeHandler::SpaceUsedInMapEntryLong(this->value_); + return size; + } + InternalMetadataWithArena _internal_metadata_; private: diff --git a/src/google/protobuf/map_entry_lite.h b/src/google/protobuf/map_entry_lite.h index 85a0bed7..01c734bc 100644 --- a/src/google/protobuf/map_entry_lite.h +++ b/src/google/protobuf/map_entry_lite.h @@ -177,13 +177,13 @@ class MapEntryImpl : public Base { // MapEntryImpl is for implementation only and this function isn't called // anywhere. Just provide a fake implementation here for MessageLite. - string GetTypeName() const { return ""; } + string GetTypeName() const override { return ""; } - void CheckTypeAndMergeFrom(const MessageLite& other) { + void CheckTypeAndMergeFrom(const MessageLite& other) override { MergeFromInternal(*::google::protobuf::down_cast<const Derived*>(&other)); } - bool MergePartialFromCodedStream(::google::protobuf::io::CodedInputStream* input) { + bool MergePartialFromCodedStream(::google::protobuf::io::CodedInputStream* input) override { uint32 tag; for (;;) { @@ -224,7 +224,7 @@ class MapEntryImpl : public Base { } } - size_t ByteSizeLong() const { + size_t ByteSizeLong() const override { size_t size = 0; size += has_key() ? kTagSize + static_cast<size_t>(KeyTypeHandler::ByteSize(key())) : 0; @@ -233,13 +233,13 @@ class MapEntryImpl : public Base { return size; } - void SerializeWithCachedSizes(::google::protobuf::io::CodedOutputStream* output) const { + void SerializeWithCachedSizes(::google::protobuf::io::CodedOutputStream* output) const override { KeyTypeHandler::Write(kKeyFieldNumber, key(), output); ValueTypeHandler::Write(kValueFieldNumber, value(), output); } ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(bool deterministic, - ::google::protobuf::uint8* output) const { + ::google::protobuf::uint8* output) const override { output = KeyTypeHandler::InternalWriteToArray(kKeyFieldNumber, key(), deterministic, output); output = ValueTypeHandler::InternalWriteToArray(kValueFieldNumber, value(), @@ -249,7 +249,7 @@ class MapEntryImpl : public Base { // Don't override SerializeWithCachedSizesToArray. Use MessageLite's. - int GetCachedSize() const { + int GetCachedSize() const override { int size = 0; size += has_key() ? static_cast<int>(kTagSize) + KeyTypeHandler::GetCachedSize(key()) @@ -260,25 +260,18 @@ class MapEntryImpl : public Base { return size; } - bool IsInitialized() const { return ValueTypeHandler::IsInitialized(value_); } + bool IsInitialized() const override { return ValueTypeHandler::IsInitialized(value_); } - Base* New() const { + Base* New() const override { Derived* entry = new Derived; return entry; } - Base* New(Arena* arena) const { + Base* New(Arena* arena) const override { Derived* entry = Arena::CreateMessage<Derived>(arena); return entry; } - size_t SpaceUsedLong() const { - size_t size = sizeof(Derived); - size += KeyTypeHandler::SpaceUsedInMapEntryLong(key_); - size += ValueTypeHandler::SpaceUsedInMapEntryLong(value_); - return size; - } - protected: // We can't declare this function directly here as it would hide the other // overload (const Message&). @@ -298,7 +291,7 @@ class MapEntryImpl : public Base { } public: - void Clear() { + void Clear() override { KeyTypeHandler::Clear(&key_, GetArenaNoVirtual()); ValueTypeHandler::ClearMaybeByDefaultEnum( &value_, GetArenaNoVirtual(), default_enum_value); @@ -312,7 +305,7 @@ class MapEntryImpl : public Base { ValueTypeHandler::AssignDefaultValue(&d->value_); } - Arena* GetArena() const { + Arena* GetArena() const override { return GetArenaNoVirtual(); } @@ -466,8 +459,8 @@ class MapEntryImpl : public Base { BaseClass::set_has_key(); BaseClass::set_has_value(); } - inline const KeyMapEntryAccessorType& key() const { return key_; } - inline const ValueMapEntryAccessorType& value() const { return value_; } + inline const KeyMapEntryAccessorType &key() const override { return key_; } + inline const ValueMapEntryAccessorType& value() const override { return value_; } private: const Key& key_; diff --git a/src/google/protobuf/map_field.h b/src/google/protobuf/map_field.h index 494401e1..44ca29b3 100644 --- a/src/google/protobuf/map_field.h +++ b/src/google/protobuf/map_field.h @@ -181,10 +181,10 @@ class TypeDefinedMapFieldBase : public MapFieldBase { public: TypeDefinedMapFieldBase() {} explicit TypeDefinedMapFieldBase(Arena* arena) : MapFieldBase(arena) {} - ~TypeDefinedMapFieldBase() {} - void MapBegin(MapIterator* map_iter) const; - void MapEnd(MapIterator* map_iter) const; - bool EqualIterator(const MapIterator& a, const MapIterator& b) const; + ~TypeDefinedMapFieldBase() override {} + void MapBegin(MapIterator* map_iter) const override; + void MapEnd(MapIterator* map_iter) const override; + bool EqualIterator(const MapIterator& a, const MapIterator& b) const override; virtual const Map<Key, T>& GetMap() const = 0; virtual Map<Key, T>* MutableMap() = 0; @@ -194,11 +194,11 @@ class TypeDefinedMapFieldBase : public MapFieldBase { const MapIterator* map_iter) const; private: - void InitializeIterator(MapIterator* map_iter) const; - void DeleteIterator(MapIterator* map_iter) const; + void InitializeIterator(MapIterator* map_iter) const override; + void DeleteIterator(MapIterator* map_iter) const override; void CopyIterator(MapIterator* this_iteratorm, - const MapIterator& that_iterator) const; - void IncreaseIterator(MapIterator* map_iter) const; + const MapIterator& that_iterator) const override; + void IncreaseIterator(MapIterator* map_iter) const override; virtual void SetMapIteratorValue(MapIterator* map_iter) const = 0; GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(TypeDefinedMapFieldBase); @@ -243,16 +243,16 @@ class MapField : public TypeDefinedMapFieldBase<Key, T> { : TypeDefinedMapFieldBase<Key, T>(arena), impl_(arena) {} // Implement MapFieldBase - bool ContainsMapKey(const MapKey& map_key) const; - bool InsertOrLookupMapValue(const MapKey& map_key, MapValueRef* val); - bool DeleteMapValue(const MapKey& map_key); + bool ContainsMapKey(const MapKey& map_key) const override; + bool InsertOrLookupMapValue(const MapKey& map_key, MapValueRef* val) override; + bool DeleteMapValue(const MapKey& map_key) override; - const Map<Key, T>& GetMap() const { + const Map<Key, T>& GetMap() const override { MapFieldBase::SyncMapWithRepeatedField(); return impl_.GetMap(); } - Map<Key, T>* MutableMap() { + Map<Key, T>* MutableMap() override { MapFieldBase::SyncMapWithRepeatedField(); Map<Key, T>* result = impl_.MutableMap(); MapFieldBase::SetMapDirty(); @@ -260,7 +260,7 @@ class MapField : public TypeDefinedMapFieldBase<Key, T> { } // Convenient methods for generated message implementation. - int size() const; + int size() const override; void Clear(); void MergeFrom(const MapField& other); void Swap(MapField* other); @@ -285,12 +285,13 @@ class MapField : public TypeDefinedMapFieldBase<Key, T> { typedef void InternalArenaConstructable_; typedef void DestructorSkippable_; + // Implements MapFieldBase - void SyncRepeatedFieldWithMapNoLock() const; - void SyncMapWithRepeatedFieldNoLock() const; - size_t SpaceUsedExcludingSelfNoLock() const; + void SyncRepeatedFieldWithMapNoLock() const override; + void SyncMapWithRepeatedFieldNoLock() const override; + size_t SpaceUsedExcludingSelfNoLock() const override; - void SetMapIteratorValue(MapIterator* map_iter) const; + void SetMapIteratorValue(MapIterator* map_iter) const override; friend class ::google::protobuf::Arena; friend class MapFieldStateTest; // For testing, it needs raw access to impl_ @@ -311,27 +312,27 @@ class LIBPROTOBUF_EXPORT DynamicMapField: public TypeDefinedMapFieldBase<MapKey, public: explicit DynamicMapField(const Message* default_entry); DynamicMapField(const Message* default_entry, Arena* arena); - ~DynamicMapField(); + ~DynamicMapField() override; // Implement MapFieldBase - bool ContainsMapKey(const MapKey& map_key) const; - bool InsertOrLookupMapValue(const MapKey& map_key, MapValueRef* val); - bool DeleteMapValue(const MapKey& map_key); + bool ContainsMapKey(const MapKey& map_key) const override; + bool InsertOrLookupMapValue(const MapKey& map_key, MapValueRef* val) override; + bool DeleteMapValue(const MapKey& map_key) override; - const Map<MapKey, MapValueRef>& GetMap() const; - Map<MapKey, MapValueRef>* MutableMap(); + const Map<MapKey, MapValueRef>& GetMap() const override; + Map<MapKey, MapValueRef>* MutableMap() override; - int size() const; + int size() const override; private: Map<MapKey, MapValueRef> map_; const Message* default_entry_; // Implements MapFieldBase - void SyncRepeatedFieldWithMapNoLock() const; - void SyncMapWithRepeatedFieldNoLock() const; - size_t SpaceUsedExcludingSelfNoLock() const; - void SetMapIteratorValue(MapIterator* map_iter) const; + void SyncRepeatedFieldWithMapNoLock() const override; + void SyncMapWithRepeatedFieldNoLock() const override; + size_t SpaceUsedExcludingSelfNoLock() const override; + void SetMapIteratorValue(MapIterator* map_iter) const override; GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(DynamicMapField); }; diff --git a/src/google/protobuf/map_test.cc b/src/google/protobuf/map_test.cc index 829a60ff..51fde2ce 100644 --- a/src/google/protobuf/map_test.cc +++ b/src/google/protobuf/map_test.cc @@ -3183,7 +3183,7 @@ TEST(TextFormatMapTest, Sorted) { tester.SetMapFieldsViaReflection(&message); string expected_text; - GOOGLE_CHECK_OK(File::GetContents( + GOOGLE_CHECK_OK(File::GetContentsAsText( TestSourceDir() + "/google/protobuf/" "testdata/map_test_data.txt", diff --git a/src/google/protobuf/message.cc b/src/google/protobuf/message.cc index 9b758080..a536615a 100644 --- a/src/google/protobuf/message.cc +++ b/src/google/protobuf/message.cc @@ -269,7 +269,7 @@ class GeneratedMessageFactory : public MessageFactory { void RegisterType(const Descriptor* descriptor, const Message* prototype); // implements MessageFactory --------------------------------------- - const Message* GetPrototype(const Descriptor* type); + const Message* GetPrototype(const Descriptor* type) override; private: // Only written at static init time, so does not require locking. diff --git a/src/google/protobuf/message.h b/src/google/protobuf/message.h index f3d1a58a..4bdda3ad 100644 --- a/src/google/protobuf/message.h +++ b/src/google/protobuf/message.h @@ -196,12 +196,12 @@ class LIBPROTOBUF_EXPORT Message : public MessageLite { // Construct a new instance of the same type. Ownership is passed to the // caller. (This is also defined in MessageLite, but is defined again here // for return-type covariance.) - virtual Message* New() const = 0; + virtual Message* New() const override = 0; // Construct a new instance on the arena. Ownership is passed to the caller // if arena is a NULL. Default implementation allows for API compatibility // during the Arena transition. - virtual Message* New(::google::protobuf::Arena* arena) const { + virtual Message* New(::google::protobuf::Arena* arena) const override { Message* message = New(); if (arena != NULL) { arena->Own(message); @@ -233,7 +233,7 @@ class LIBPROTOBUF_EXPORT Message : public MessageLite { // Like FindInitializationErrors, but joins all the strings, delimited by // commas, and returns them. - string InitializationErrorString() const; + string InitializationErrorString() const override; // Clears all unknown fields from this message and all embedded messages. // Normally, if unknown tag numbers are encountered when parsing a message, @@ -305,13 +305,13 @@ class LIBPROTOBUF_EXPORT Message : public MessageLite { // These methods are pure-virtual in MessageLite, but Message provides // reflection-based default implementations. - virtual string GetTypeName() const; - virtual void Clear(); - virtual bool IsInitialized() const; - virtual void CheckTypeAndMergeFrom(const MessageLite& other); - virtual bool MergePartialFromCodedStream(io::CodedInputStream* input); - virtual size_t ByteSizeLong() const; - virtual void SerializeWithCachedSizes(io::CodedOutputStream* output) const; + virtual string GetTypeName() const override; + virtual void Clear() override; + virtual bool IsInitialized() const override; + virtual void CheckTypeAndMergeFrom(const MessageLite& other) override; + virtual bool MergePartialFromCodedStream(io::CodedInputStream* input) override; + virtual size_t ByteSizeLong() const override; + virtual void SerializeWithCachedSizes(io::CodedOutputStream* output) const override; private: // This is called only by the default implementation of ByteSize(), to diff --git a/src/google/protobuf/message_lite.cc b/src/google/protobuf/message_lite.cc index 123b142d..65af7cea 100644 --- a/src/google/protobuf/message_lite.cc +++ b/src/google/protobuf/message_lite.cc @@ -316,7 +316,11 @@ bool MessageLite::SerializeToArray(void* data, int size) const { } bool MessageLite::SerializePartialToArray(void* data, int size) const { - int byte_size = ByteSizeLong(); + size_t byte_size = ByteSizeLong(); + if (byte_size > INT_MAX) { + GOOGLE_LOG(ERROR) << "Exceeded maximum protobuf size of 2GB: " << size; + return false; + } if (size < byte_size) return false; uint8* start = reinterpret_cast<uint8*>(data); uint8* end = SerializeWithCachedSizesToArray(start); diff --git a/src/google/protobuf/reflection.h b/src/google/protobuf/reflection.h index 5d0fc42b..5d0fc42b 100755..100644 --- a/src/google/protobuf/reflection.h +++ b/src/google/protobuf/reflection.h diff --git a/src/google/protobuf/reflection_internal.h b/src/google/protobuf/reflection_internal.h index fcb42471..840d611f 100644 --- a/src/google/protobuf/reflection_internal.h +++ b/src/google/protobuf/reflection_internal.h @@ -43,32 +43,32 @@ namespace internal { // corresponding random-access methods. class RandomAccessRepeatedFieldAccessor : public RepeatedFieldAccessor { public: - virtual ~RandomAccessRepeatedFieldAccessor() {} + virtual ~RandomAccessRepeatedFieldAccessor() override {} - virtual Iterator* BeginIterator(const Field* data) const { + virtual Iterator* BeginIterator(const Field* data) const override { return PositionToIterator(0); } - virtual Iterator* EndIterator(const Field* data) const { + virtual Iterator* EndIterator(const Field* data) const override { return PositionToIterator(this->Size(data)); } virtual Iterator* CopyIterator(const Field* data, - const Iterator* iterator) const { + const Iterator* iterator) const override { return const_cast<Iterator*>(iterator); } virtual Iterator* AdvanceIterator(const Field* data, - Iterator* iterator) const { + Iterator* iterator) const override { return PositionToIterator(IteratorToPosition(iterator) + 1); } virtual bool EqualsIterator(const Field* data, - const Iterator* a, - const Iterator* b) const { + const Iterator* a, + const Iterator* b) const override { return a == b; } - virtual void DeleteIterator(const Field* data, Iterator* iterator) const { + virtual void DeleteIterator(const Field* data, Iterator* iterator) const override { } virtual const Value* GetIteratorValue(const Field* data, - const Iterator* iterator, - Value* scratch_space) const { + const Iterator* iterator, + Value* scratch_space) const override { return Get(data, static_cast<int>(IteratorToPosition(iterator)), scratch_space); } @@ -88,30 +88,30 @@ template<typename T> class RepeatedFieldWrapper : public RandomAccessRepeatedFieldAccessor { public: RepeatedFieldWrapper() {} - virtual ~RepeatedFieldWrapper() {} - virtual bool IsEmpty(const Field* data) const { + virtual ~RepeatedFieldWrapper() override {} + virtual bool IsEmpty(const Field* data) const override { return GetRepeatedField(data)->empty(); } - virtual int Size(const Field* data) const { + virtual int Size(const Field* data) const override { return GetRepeatedField(data)->size(); } virtual const Value* Get(const Field* data, int index, - Value* scratch_space) const { + Value* scratch_space) const override { return ConvertFromT(GetRepeatedField(data)->Get(index), scratch_space); } - virtual void Clear(Field* data) const { + virtual void Clear(Field* data) const override { MutableRepeatedField(data)->Clear(); } - virtual void Set(Field* data, int index, const Value* value) const { + virtual void Set(Field* data, int index, const Value* value) const override { MutableRepeatedField(data)->Set(index, ConvertToT(value)); } - virtual void Add(Field* data, const Value* value) const { + virtual void Add(Field* data, const Value* value) const override { MutableRepeatedField(data)->Add(ConvertToT(value)); } - virtual void RemoveLast(Field* data) const { + virtual void RemoveLast(Field* data) const override { MutableRepeatedField(data)->RemoveLast(); } - virtual void SwapElements(Field* data, int index1, int index2) const { + virtual void SwapElements(Field* data, int index1, int index2) const override { MutableRepeatedField(data)->SwapElements(index1, index2); } @@ -144,31 +144,31 @@ class RepeatedPtrFieldWrapper : public RandomAccessRepeatedFieldAccessor { public: RepeatedPtrFieldWrapper() {} virtual ~RepeatedPtrFieldWrapper() {} - virtual bool IsEmpty(const Field* data) const { + virtual bool IsEmpty(const Field* data) const override { return GetRepeatedField(data)->empty(); } - virtual int Size(const Field* data) const { + virtual int Size(const Field* data) const override { return GetRepeatedField(data)->size(); } virtual const Value* Get(const Field* data, int index, - Value* scratch_space) const { + Value* scratch_space) const override { return ConvertFromT(GetRepeatedField(data)->Get(index), scratch_space); } - virtual void Clear(Field* data) const { + virtual void Clear(Field* data) const override { MutableRepeatedField(data)->Clear(); } - virtual void Set(Field* data, int index, const Value* value) const { + virtual void Set(Field* data, int index, const Value* value) const override { ConvertToT(value, MutableRepeatedField(data)->Mutable(index)); } - virtual void Add(Field* data, const Value* value) const { + virtual void Add(Field* data, const Value* value) const override { T* allocated = New(value); ConvertToT(value, allocated); MutableRepeatedField(data)->AddAllocated(allocated); } - virtual void RemoveLast(Field* data) const { + virtual void RemoveLast(Field* data) const override { MutableRepeatedField(data)->RemoveLast(); } - virtual void SwapElements(Field* data, int index1, int index2) const { + virtual void SwapElements(Field* data, int index1, int index2) const override { MutableRepeatedField(data)->SwapElements(index1, index2); } @@ -205,38 +205,38 @@ class RepeatedPtrFieldWrapper : public RandomAccessRepeatedFieldAccessor { class MapFieldAccessor : public RandomAccessRepeatedFieldAccessor { public: MapFieldAccessor() {} - virtual ~MapFieldAccessor() {} - virtual bool IsEmpty(const Field* data) const { + virtual ~MapFieldAccessor() override {} + virtual bool IsEmpty(const Field* data) const override { return GetRepeatedField(data)->empty(); } - virtual int Size(const Field* data) const { + virtual int Size(const Field* data) const override { return GetRepeatedField(data)->size(); } virtual const Value* Get(const Field* data, int index, - Value* scratch_space) const { + Value* scratch_space) const override { return ConvertFromEntry(GetRepeatedField(data)->Get(index), scratch_space); } - virtual void Clear(Field* data) const { + virtual void Clear(Field* data) const override { MutableRepeatedField(data)->Clear(); } - virtual void Set(Field* data, int index, const Value* value) const { + virtual void Set(Field* data, int index, const Value* value) const override { ConvertToEntry(value, MutableRepeatedField(data)->Mutable(index)); } - virtual void Add(Field* data, const Value* value) const { + virtual void Add(Field* data, const Value* value) const override { Message* allocated = New(value); ConvertToEntry(value, allocated); MutableRepeatedField(data)->AddAllocated(allocated); } - virtual void RemoveLast(Field* data) const { + virtual void RemoveLast(Field* data) const override { MutableRepeatedField(data)->RemoveLast(); } - virtual void SwapElements(Field* data, int index1, int index2) const { + virtual void SwapElements(Field* data, int index1, int index2) const override { MutableRepeatedField(data)->SwapElements(index1, index2); } virtual void Swap( Field* data, const internal::RepeatedFieldAccessor* other_mutator, - Field* other_data) const { + Field* other_data) const override { GOOGLE_CHECK(this == other_mutator); MutableRepeatedField(data)->Swap(MutableRepeatedField(other_data)); } @@ -276,11 +276,11 @@ class RepeatedFieldPrimitiveAccessor : public RepeatedFieldWrapper<T> { public: RepeatedFieldPrimitiveAccessor() {} - virtual ~RepeatedFieldPrimitiveAccessor() {} + virtual ~RepeatedFieldPrimitiveAccessor() override {} virtual void Swap( Field* data, const internal::RepeatedFieldAccessor* other_mutator, - Field* other_data) const { + Field* other_data) const override { // Currently RepeatedFieldPrimitiveAccessor is the only implementation of // RepeatedFieldAccessor for primitive types. As we are using singletons // for these accessors, here "other_mutator" must be "this". @@ -289,11 +289,11 @@ class RepeatedFieldPrimitiveAccessor : public RepeatedFieldWrapper<T> { } protected: - virtual T ConvertToT(const Value* value) const { + virtual T ConvertToT(const Value* value) const override { return *static_cast<const T*>(value); } virtual const Value* ConvertFromT(const T& value, - Value* scratch_space) const { + Value* scratch_space) const override { return static_cast<const Value*>(&value); } }; @@ -307,11 +307,11 @@ class RepeatedPtrFieldStringAccessor : public RepeatedPtrFieldWrapper<string> { public: RepeatedPtrFieldStringAccessor() {} - virtual ~RepeatedPtrFieldStringAccessor() {} + virtual ~RepeatedPtrFieldStringAccessor() override {} virtual void Swap( Field* data, const internal::RepeatedFieldAccessor* other_mutator, - Field* other_data) const { + Field* other_data) const override { if (this == other_mutator) { MutableRepeatedField(data)->Swap(MutableRepeatedField(other_data)); } else { @@ -330,14 +330,14 @@ class RepeatedPtrFieldStringAccessor : public RepeatedPtrFieldWrapper<string> { } protected: - virtual string* New(const Value*) const { + virtual string* New(const Value*) const override { return new string(); } - virtual void ConvertToT(const Value* value, string* result) const { + virtual void ConvertToT(const Value* value, string* result) const override { *result = *static_cast<const string*>(value); } virtual const Value* ConvertFromT(const string& value, - Value* scratch_space) const { + Value* scratch_space) const override { return static_cast<const Value*>(&value); } }; @@ -350,24 +350,24 @@ class RepeatedPtrFieldMessageAccessor public: RepeatedPtrFieldMessageAccessor() {} - virtual ~RepeatedPtrFieldMessageAccessor() {} + virtual ~RepeatedPtrFieldMessageAccessor() override {} virtual void Swap( Field* data, const internal::RepeatedFieldAccessor* other_mutator, - Field* other_data) const { + Field* other_data) const override { GOOGLE_CHECK(this == other_mutator); MutableRepeatedField(data)->Swap(MutableRepeatedField(other_data)); } protected: - virtual Message* New(const Value* value) const { + virtual Message* New(const Value* value) const override { return static_cast<const Message*>(value)->New(); } - virtual void ConvertToT(const Value* value, Message* result) const { + virtual void ConvertToT(const Value* value, Message* result) const override { result->CopyFrom(*static_cast<const Message*>(value)); } virtual const Value* ConvertFromT(const Message& value, - Value* scratch_space) const { + Value* scratch_space) const override { return static_cast<const Value*>(&value); } }; diff --git a/src/google/protobuf/repeated_field.h b/src/google/protobuf/repeated_field.h index b47ea994..79682b69 100644 --- a/src/google/protobuf/repeated_field.h +++ b/src/google/protobuf/repeated_field.h @@ -466,7 +466,7 @@ class LIBPROTOBUF_EXPORT RepeatedPtrFieldBase { protected: template <typename TypeHandler> void Add(typename TypeHandler::Type&& value, - std::enable_if<TypeHandler::Moveable>* dummy = NULL); + typename std::enable_if<TypeHandler::Moveable>::type* dummy = NULL); template <typename TypeHandler> void RemoveLast(); @@ -705,13 +705,13 @@ void GenericTypeHandler<string>::Merge(const string& from, // Declarations of the specialization as we cannot define them here, as the // header that defines ProtocolMessage depends on types defined in this header. #define DECLARE_SPECIALIZATIONS_FOR_BASE_PROTO_TYPES(TypeName) \ - template<> \ + template<> LIBPROTOBUF_EXPORT \ TypeName* GenericTypeHandler<TypeName>::NewFromPrototype( \ const TypeName* prototype, google::protobuf::Arena* arena); \ - template<> \ + template<> LIBPROTOBUF_EXPORT \ google::protobuf::Arena* GenericTypeHandler<TypeName>::GetArena( \ TypeName* value); \ - template<> \ + template<> LIBPROTOBUF_EXPORT \ void* GenericTypeHandler<TypeName>::GetMaybeArenaPointer( \ TypeName* value); @@ -1541,7 +1541,7 @@ inline typename TypeHandler::Type* RepeatedPtrFieldBase::Add( template <typename TypeHandler> inline void RepeatedPtrFieldBase::Add( typename TypeHandler::Type&& value, - std::enable_if<TypeHandler::Moveable>*) { + typename std::enable_if<TypeHandler::Moveable>::type*) { if (rep_ != NULL && current_size_ < rep_->allocated_size) { *cast<TypeHandler>(rep_->elements[current_size_++]) = std::move(value); return; diff --git a/src/google/protobuf/source_context.pb.cc b/src/google/protobuf/source_context.pb.cc index 739172f8..af93e6b2 100644 --- a/src/google/protobuf/source_context.pb.cc +++ b/src/google/protobuf/source_context.pb.cc @@ -65,14 +65,14 @@ static ::google::protobuf::Message const * const file_default_instances[] = { reinterpret_cast<const ::google::protobuf::Message*>(&::google::protobuf::_SourceContext_default_instance_), }; -void protobuf_AssignDescriptors() { +static void protobuf_AssignDescriptors() { AddDescriptors(); AssignDescriptors( "google/protobuf/source_context.proto", schemas, file_default_instances, TableStruct::offsets, file_level_metadata, NULL, NULL); } -void protobuf_AssignDescriptorsOnce() { +static void protobuf_AssignDescriptorsOnce() { static ::google::protobuf::internal::once_flag once; ::google::protobuf::internal::call_once(once, protobuf_AssignDescriptors); } @@ -83,7 +83,7 @@ void protobuf_RegisterTypes(const ::std::string&) { ::google::protobuf::internal::RegisterAllTypes(file_level_metadata, 1); } -void AddDescriptorsImpl() { +static void AddDescriptorsImpl() { InitDefaults(); static const char descriptor[] GOOGLE_PROTOBUF_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold) = { "\n$google/protobuf/source_context.proto\022\017" diff --git a/src/google/protobuf/struct.pb.cc b/src/google/protobuf/struct.pb.cc index 8f2d4848..ead81689 100644 --- a/src/google/protobuf/struct.pb.cc +++ b/src/google/protobuf/struct.pb.cc @@ -140,14 +140,14 @@ static ::google::protobuf::Message const * const file_default_instances[] = { reinterpret_cast<const ::google::protobuf::Message*>(&::google::protobuf::_ListValue_default_instance_), }; -void protobuf_AssignDescriptors() { +static void protobuf_AssignDescriptors() { AddDescriptors(); AssignDescriptors( "google/protobuf/struct.proto", schemas, file_default_instances, TableStruct::offsets, file_level_metadata, file_level_enum_descriptors, NULL); } -void protobuf_AssignDescriptorsOnce() { +static void protobuf_AssignDescriptorsOnce() { static ::google::protobuf::internal::once_flag once; ::google::protobuf::internal::call_once(once, protobuf_AssignDescriptors); } @@ -158,7 +158,7 @@ void protobuf_RegisterTypes(const ::std::string&) { ::google::protobuf::internal::RegisterAllTypes(file_level_metadata, 4); } -void AddDescriptorsImpl() { +static void AddDescriptorsImpl() { InitDefaults(); static const char descriptor[] GOOGLE_PROTOBUF_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold) = { "\n\034google/protobuf/struct.proto\022\017google.p" @@ -277,7 +277,7 @@ void Struct::ArenaDtor(void* object) { Struct* _this = reinterpret_cast< Struct* >(object); (void)_this; } -void Struct::RegisterArenaDtor(::google::protobuf::Arena* arena) { +void Struct::RegisterArenaDtor(::google::protobuf::Arena*) { } void Struct::SetCachedSize(int size) const { _cached_size_.Set(size); @@ -730,7 +730,7 @@ void Value::ArenaDtor(void* object) { Value* _this = reinterpret_cast< Value* >(object); (void)_this; } -void Value::RegisterArenaDtor(::google::protobuf::Arena* arena) { +void Value::RegisterArenaDtor(::google::protobuf::Arena*) { } void Value::SetCachedSize(int size) const { _cached_size_.Set(size); @@ -810,7 +810,7 @@ bool Value::MergePartialFromCodedStream( case 1: { if (static_cast< ::google::protobuf::uint8>(tag) == static_cast< ::google::protobuf::uint8>(8u /* 8 & 0xFF */)) { - int value; + int value = 0; DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>( input, &value))); @@ -1225,7 +1225,7 @@ void ListValue::ArenaDtor(void* object) { ListValue* _this = reinterpret_cast< ListValue* >(object); (void)_this; } -void ListValue::RegisterArenaDtor(::google::protobuf::Arena* arena) { +void ListValue::RegisterArenaDtor(::google::protobuf::Arena*) { } void ListValue::SetCachedSize(int size) const { _cached_size_.Set(size); diff --git a/src/google/protobuf/stubs/bytestream.h b/src/google/protobuf/stubs/bytestream.h index 86510d14..cfa19f29 100644 --- a/src/google/protobuf/stubs/bytestream.h +++ b/src/google/protobuf/stubs/bytestream.h @@ -57,7 +57,6 @@ #include <google/protobuf/stubs/stringpiece.h> class CordByteSink; -class MemBlock; namespace google { namespace protobuf { @@ -162,7 +161,7 @@ class LIBPROTOBUF_EXPORT ByteSource { class LIBPROTOBUF_EXPORT UncheckedArrayByteSink : public ByteSink { public: explicit UncheckedArrayByteSink(char* dest) : dest_(dest) {} - virtual void Append(const char* data, size_t n); + virtual void Append(const char* data, size_t n) override; // Returns the current output pointer so that a caller can see how many bytes // were produced. @@ -190,7 +189,7 @@ class LIBPROTOBUF_EXPORT UncheckedArrayByteSink : public ByteSink { class LIBPROTOBUF_EXPORT CheckedArrayByteSink : public ByteSink { public: CheckedArrayByteSink(char* outbuf, size_t capacity); - virtual void Append(const char* bytes, size_t n); + virtual void Append(const char* bytes, size_t n) override; // Returns the number of bytes actually written to the sink. size_t NumberOfBytesWritten() const { return size_; } @@ -227,7 +226,7 @@ class LIBPROTOBUF_EXPORT GrowingArrayByteSink : public strings::ByteSink { public: explicit GrowingArrayByteSink(size_t estimated_size); virtual ~GrowingArrayByteSink(); - virtual void Append(const char* bytes, size_t n); + virtual void Append(const char* bytes, size_t n) override; // Returns the allocated buffer, and sets nbytes to its size. The caller takes // ownership of the buffer and must delete it with delete[]. @@ -256,7 +255,7 @@ class LIBPROTOBUF_EXPORT GrowingArrayByteSink : public strings::ByteSink { class LIBPROTOBUF_EXPORT StringByteSink : public ByteSink { public: explicit StringByteSink(string* dest) : dest_(dest) {} - virtual void Append(const char* data, size_t n); + virtual void Append(const char* data, size_t n) override; private: string* dest_; @@ -273,7 +272,7 @@ class LIBPROTOBUF_EXPORT StringByteSink : public ByteSink { class LIBPROTOBUF_EXPORT NullByteSink : public ByteSink { public: NullByteSink() {} - virtual void Append(const char *data, size_t n) {} + virtual void Append(const char *data, size_t n) override {} private: GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(NullByteSink); @@ -296,9 +295,9 @@ class LIBPROTOBUF_EXPORT ArrayByteSource : public ByteSource { public: explicit ArrayByteSource(StringPiece s) : input_(s) {} - virtual size_t Available() const; - virtual StringPiece Peek(); - virtual void Skip(size_t n); + virtual size_t Available() const override; + virtual StringPiece Peek() override; + virtual void Skip(size_t n) override; private: StringPiece input_; @@ -328,13 +327,13 @@ class LIBPROTOBUF_EXPORT LimitByteSource : public ByteSource { // Returns at most "limit" bytes from "source". LimitByteSource(ByteSource* source, size_t limit); - virtual size_t Available() const; - virtual StringPiece Peek(); - virtual void Skip(size_t n); + virtual size_t Available() const override; + virtual StringPiece Peek() override; + virtual void Skip(size_t n) override; // We override CopyTo so that we can forward to the underlying source, in // case it has an efficient implementation of CopyTo. - virtual void CopyTo(ByteSink* sink, size_t n); + virtual void CopyTo(ByteSink* sink, size_t n) override; private: ByteSource* source_; diff --git a/src/google/protobuf/stubs/callback.h b/src/google/protobuf/stubs/callback.h index 6888f136..dae972f2 100644 --- a/src/google/protobuf/stubs/callback.h +++ b/src/google/protobuf/stubs/callback.h @@ -125,7 +125,7 @@ class LIBPROTOBUF_EXPORT FunctionClosure0 : public Closure { : function_(function), self_deleting_(self_deleting) {} ~FunctionClosure0(); - void Run() { + void Run() override { bool needs_delete = self_deleting_; // read in case callback deletes function_(); if (needs_delete) delete this; @@ -145,7 +145,7 @@ class MethodClosure0 : public Closure { : object_(object), method_(method), self_deleting_(self_deleting) {} ~MethodClosure0() {} - void Run() { + void Run() override { bool needs_delete = self_deleting_; // read in case callback deletes (object_->*method_)(); if (needs_delete) delete this; @@ -168,7 +168,7 @@ class FunctionClosure1 : public Closure { arg1_(arg1) {} ~FunctionClosure1() {} - void Run() { + void Run() override { bool needs_delete = self_deleting_; // read in case callback deletes function_(arg1_); if (needs_delete) delete this; @@ -191,7 +191,7 @@ class MethodClosure1 : public Closure { arg1_(arg1) {} ~MethodClosure1() {} - void Run() { + void Run() override { bool needs_delete = self_deleting_; // read in case callback deletes (object_->*method_)(arg1_); if (needs_delete) delete this; @@ -215,7 +215,7 @@ class FunctionClosure2 : public Closure { arg1_(arg1), arg2_(arg2) {} ~FunctionClosure2() {} - void Run() { + void Run() override { bool needs_delete = self_deleting_; // read in case callback deletes function_(arg1_, arg2_); if (needs_delete) delete this; @@ -239,7 +239,7 @@ class MethodClosure2 : public Closure { arg1_(arg1), arg2_(arg2) {} ~MethodClosure2() {} - void Run() { + void Run() override { bool needs_delete = self_deleting_; // read in case callback deletes (object_->*method_)(arg1_, arg2_); if (needs_delete) delete this; @@ -262,7 +262,7 @@ class FunctionResultCallback_0_0 : public ResultCallback<R> { : function_(function), self_deleting_(self_deleting) {} ~FunctionResultCallback_0_0() {} - R Run() { + R Run() override { bool needs_delete = self_deleting_; // read in case callback deletes R result = function_(); if (needs_delete) delete this; @@ -284,7 +284,7 @@ class FunctionResultCallback_1_0 : public ResultCallback<R> { : function_(function), self_deleting_(self_deleting), p1_(p1) {} ~FunctionResultCallback_1_0() {} - R Run() { + R Run() override { bool needs_delete = self_deleting_; // read in case callback deletes R result = function_(p1_); if (needs_delete) delete this; @@ -306,7 +306,7 @@ class FunctionResultCallback_0_1 : public ResultCallback1<R, Arg1> { : function_(function), self_deleting_(self_deleting) {} ~FunctionResultCallback_0_1() {} - R Run(Arg1 a1) { + R Run(Arg1 a1) override { bool needs_delete = self_deleting_; // read in case callback deletes R result = function_(a1); if (needs_delete) delete this; @@ -328,7 +328,7 @@ class FunctionResultCallback_1_1 : public ResultCallback1<R, A1> { : function_(function), self_deleting_(self_deleting), p1_(p1) {} ~FunctionResultCallback_1_1() {} - R Run(A1 a1) { + R Run(A1 a1) override { bool needs_delete = self_deleting_; // read in case callback deletes R result = function_(p1_, a1); if (needs_delete) delete this; @@ -387,7 +387,7 @@ class MethodResultCallback_5_2 : public ResultCallback2<R, A1, A2> { p5_(p5) {} ~MethodResultCallback_5_2() {} - R Run(A1 a1, A2 a2) { + R Run(A1 a1, A2 a2) override { bool needs_delete = self_deleting_; R result = (object_->*method_)(p1_, p2_, p3_, p4_, p5_, a1, a2); if (needs_delete) delete this; diff --git a/src/google/protobuf/stubs/common.cc b/src/google/protobuf/stubs/common.cc index 6544c6ed..6544c6ed 100755..100644 --- a/src/google/protobuf/stubs/common.cc +++ b/src/google/protobuf/stubs/common.cc diff --git a/src/google/protobuf/stubs/common.h b/src/google/protobuf/stubs/common.h index d35377ae..585e0128 100644 --- a/src/google/protobuf/stubs/common.h +++ b/src/google/protobuf/stubs/common.h @@ -206,7 +206,7 @@ LIBPROTOBUF_EXPORT void OnShutdownRun(void (*f)(const void*), const void* arg); template <typename T> T* OnShutdownDelete(T* p) { - OnShutdownRun([](const void* p) { delete static_cast<const T*>(p); }, p); + OnShutdownRun([](const void* pp) { delete static_cast<const T*>(pp); }, p); return p; } diff --git a/src/google/protobuf/stubs/int128.cc b/src/google/protobuf/stubs/int128.cc index a5090801..7b993e8f 100644 --- a/src/google/protobuf/stubs/int128.cc +++ b/src/google/protobuf/stubs/int128.cc @@ -76,52 +76,36 @@ static inline int Fls128(uint128 n) { 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) { + } else if (dividend < divisor) { *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; + } else { + int dividend_bit_length = Fls128(dividend); + int divisor_bit_length = Fls128(divisor); + int difference = dividend_bit_length - divisor_bit_length; + uint128 quotient = 0; + while (difference >= 0) { + quotient <<= 1; + uint128 shifted_divisor = divisor << difference; + if (shifted_divisor <= dividend) { + dividend -= shifted_divisor; + quotient += 1; + } + difference -= 1; } - position >>= 1; - denominator >>= 1; + //record the final quotient and remainder + *quotient_ret = quotient; + *remainder_ret = dividend; } - - *quotient_ret = quotient; - *remainder_ret = dividend; } + uint128& uint128::operator/=(const uint128& divisor) { uint128 quotient = 0; uint128 remainder = 0; diff --git a/src/google/protobuf/stubs/mutex.h b/src/google/protobuf/stubs/mutex.h index b9b7d2e1..47edb7a3 100644 --- a/src/google/protobuf/stubs/mutex.h +++ b/src/google/protobuf/stubs/mutex.h @@ -34,6 +34,18 @@ #include <google/protobuf/stubs/macros.h> +// Define thread-safety annotations for use below, if we are building with +// Clang. +#if defined(__clang__) && !defined(SWIG) +#define GOOGLE_PROTOBUF_ACQUIRE(...) \ + __attribute__((acquire_capability(__VA_ARGS__))) +#define GOOGLE_PROTOBUF_RELEASE(...) \ + __attribute__((release_capability(__VA_ARGS__))) +#else +#define GOOGLE_PROTOBUF_ACQUIRE(...) +#define GOOGLE_PROTOBUF_RELEASE(...) +#endif + // =================================================================== // emulates google3/base/mutex.h namespace google { @@ -48,8 +60,8 @@ namespace internal { class LIBPROTOBUF_EXPORT WrappedMutex { public: WrappedMutex() = default; - void Lock() { mu_.lock(); } - void Unlock() { mu_.unlock(); } + void Lock() GOOGLE_PROTOBUF_ACQUIRE() { mu_.lock(); } + void Unlock() GOOGLE_PROTOBUF_RELEASE() { mu_.unlock(); } // Crash if this Mutex is not held exclusively by this thread. // May fail to crash when it should; will never crash when it should not. void AssertHeld() const {} @@ -123,8 +135,10 @@ using internal::ReaderMutexLock; using internal::WriterMutexLock; using internal::MutexLockMaybe; - } // namespace protobuf } // namespace google +#undef GOOGLE_PROTOBUF_ACQUIRE +#undef GOOGLE_PROTOBUF_RELEASE + #endif // GOOGLE_PROTOBUF_STUBS_MUTEX_H_ diff --git a/src/google/protobuf/stubs/platform_macros.h b/src/google/protobuf/stubs/platform_macros.h index c3a64dd2..ce1b1e36 100644 --- a/src/google/protobuf/stubs/platform_macros.h +++ b/src/google/protobuf/stubs/platform_macros.h @@ -56,7 +56,7 @@ #elif defined(__aarch64__) #define GOOGLE_PROTOBUF_ARCH_AARCH64 1 #define GOOGLE_PROTOBUF_ARCH_64_BIT 1 -#elif defined(__MIPSEL__) +#elif defined(__mips__) #if defined(__LP64__) #define GOOGLE_PROTOBUF_ARCH_MIPS64 1 #define GOOGLE_PROTOBUF_ARCH_64_BIT 1 @@ -99,6 +99,7 @@ GOOGLE_PROTOBUF_PLATFORM_ERROR #if defined(__APPLE__) #define GOOGLE_PROTOBUF_OS_APPLE +#include <Availability.h> #include <TargetConditionals.h> #if TARGET_OS_IPHONE #define GOOGLE_PROTOBUF_OS_IPHONE @@ -125,4 +126,9 @@ GOOGLE_PROTOBUF_PLATFORM_ERROR #define GOOGLE_PROTOBUF_NO_THREADLOCAL #endif +#if defined(__MAC_OS_X_VERSION_MIN_REQUIRED) && __MAC_OS_X_VERSION_MIN_REQUIRED < 1070 +// __thread keyword requires at least 10.7 +#define GOOGLE_PROTOBUF_NO_THREADLOCAL +#endif + #endif // GOOGLE_PROTOBUF_PLATFORM_MACROS_H_ diff --git a/src/google/protobuf/stubs/port.h b/src/google/protobuf/stubs/port.h index 6b52305f..3aa6403b 100644 --- a/src/google/protobuf/stubs/port.h +++ b/src/google/protobuf/stubs/port.h @@ -382,10 +382,14 @@ inline void GOOGLE_UNALIGNED_STORE64(void *p, uint64 v) { #elif !defined(__GLIBC__) && !defined(__BIONIC__) && !defined(__CYGWIN__) +#ifndef bswap_16 static inline uint16 bswap_16(uint16 x) { return static_cast<uint16>(((x & 0xFF) << 8) | ((x & 0xFF00) >> 8)); } #define bswap_16(x) bswap_16(x) +#endif + +#ifndef bswap_32 static inline uint32 bswap_32(uint32 x) { return (((x & 0xFF) << 24) | ((x & 0xFF00) << 8) | @@ -393,6 +397,9 @@ static inline uint32 bswap_32(uint32 x) { ((x & 0xFF000000) >> 24)); } #define bswap_32(x) bswap_32(x) +#endif + +#ifndef bswap_64 static inline uint64 bswap_64(uint64 x) { return (((x & GOOGLE_ULONGLONG(0xFF)) << 56) | ((x & GOOGLE_ULONGLONG(0xFF00)) << 40) | @@ -404,6 +411,7 @@ static inline uint64 bswap_64(uint64 x) { ((x & GOOGLE_ULONGLONG(0xFF00000000000000)) >> 56)); } #define bswap_64(x) bswap_64(x) +#endif #endif diff --git a/src/google/protobuf/testing/file.cc b/src/google/protobuf/testing/file.cc index 26cb0a67..def92a00 100644 --- a/src/google/protobuf/testing/file.cc +++ b/src/google/protobuf/testing/file.cc @@ -69,9 +69,9 @@ bool File::Exists(const string& name) { return access(name.c_str(), F_OK) == 0; } -bool File::ReadFileToString(const string& name, string* output) { +bool File::ReadFileToString(const string& name, string* output, bool text_mode) { char buffer[1024]; - FILE* file = fopen(name.c_str(), "rb"); + FILE* file = fopen(name.c_str(), text_mode ? "rt" : "rb"); if (file == NULL) return false; while (true) { diff --git a/src/google/protobuf/testing/file.h b/src/google/protobuf/testing/file.h index 2f63f80e..45989967 100644 --- a/src/google/protobuf/testing/file.h +++ b/src/google/protobuf/testing/file.h @@ -50,7 +50,7 @@ class File { // Read an entire file to a string. Return true if successful, false // otherwise. - static bool ReadFileToString(const string& name, string* output); + static bool ReadFileToString(const string& name, string* output, bool text_mode = false); // Same as above, but crash on failure. static void ReadFileToStringOrDie(const string& name, string* output); @@ -85,6 +85,11 @@ class File { return ReadFileToString(name, output); } + static bool GetContentsAsText( + const string& name, string* output, bool /*is_default*/) { + return ReadFileToString(name, output, true); + } + static bool SetContents( const string& name, const string& contents, bool /*is_default*/) { return WriteStringToFile(contents, name); diff --git a/src/google/protobuf/text_format.cc b/src/google/protobuf/text_format.cc index 0965fd7a..a9c062eb 100644 --- a/src/google/protobuf/text_format.cc +++ b/src/google/protobuf/text_format.cc @@ -1138,13 +1138,13 @@ label_skip_parsing: explicit ParserErrorCollector(TextFormat::Parser::ParserImpl* parser) : parser_(parser) { } - virtual ~ParserErrorCollector() { } + ~ParserErrorCollector() override { } - virtual void AddError(int line, int column, const string& message) { + void AddError(int line, int column, const string& message) override { parser_->ReportError(line, column, message); } - virtual void AddWarning(int line, int column, const string& message) { + void AddWarning(int line, int column, const string& message) override { parser_->ReportWarning(line, column, message); } @@ -1444,7 +1444,7 @@ namespace { // A BaseTextGenerator that writes to a string. class StringBaseTextGenerator : public TextFormat::BaseTextGenerator { public: - void Print(const char* text, size_t size) { output_.append(text, size); } + void Print(const char* text, size_t size) override { output_.append(text, size); } // Some compilers do not support ref-qualifiers even in C++11 mode. // Disable the optimization for now and revisit it later. @@ -1642,37 +1642,37 @@ class FieldValuePrinterWrapper : public TextFormat::FastFieldValuePrinter { delegate_.reset(delegate); } - void PrintBool(bool val, TextFormat::BaseTextGenerator* generator) const { + void PrintBool(bool val, TextFormat::BaseTextGenerator* generator) const override { generator->PrintString(delegate_->PrintBool(val)); } - void PrintInt32(int32 val, TextFormat::BaseTextGenerator* generator) const { + void PrintInt32(int32 val, TextFormat::BaseTextGenerator* generator) const override { generator->PrintString(delegate_->PrintInt32(val)); } - void PrintUInt32(uint32 val, TextFormat::BaseTextGenerator* generator) const { + void PrintUInt32(uint32 val, TextFormat::BaseTextGenerator* generator) const override { generator->PrintString(delegate_->PrintUInt32(val)); } - void PrintInt64(int64 val, TextFormat::BaseTextGenerator* generator) const { + void PrintInt64(int64 val, TextFormat::BaseTextGenerator* generator) const override { generator->PrintString(delegate_->PrintInt64(val)); } - void PrintUInt64(uint64 val, TextFormat::BaseTextGenerator* generator) const { + void PrintUInt64(uint64 val, TextFormat::BaseTextGenerator* generator) const override { generator->PrintString(delegate_->PrintUInt64(val)); } - void PrintFloat(float val, TextFormat::BaseTextGenerator* generator) const { + void PrintFloat(float val, TextFormat::BaseTextGenerator* generator) const override { generator->PrintString(delegate_->PrintFloat(val)); } - void PrintDouble(double val, TextFormat::BaseTextGenerator* generator) const { + void PrintDouble(double val, TextFormat::BaseTextGenerator* generator) const override { generator->PrintString(delegate_->PrintDouble(val)); } void PrintString(const string& val, - TextFormat::BaseTextGenerator* generator) const { + TextFormat::BaseTextGenerator* generator) const override { generator->PrintString(delegate_->PrintString(val)); } void PrintBytes(const string& val, - TextFormat::BaseTextGenerator* generator) const { + TextFormat::BaseTextGenerator* generator) const override { generator->PrintString(delegate_->PrintBytes(val)); } void PrintEnum(int32 val, const string& name, - TextFormat::BaseTextGenerator* generator) const { + TextFormat::BaseTextGenerator* generator) const override { generator->PrintString(delegate_->PrintEnum(val, name)); } void PrintFieldName(const Message& message, int field_index, int field_count, @@ -1684,19 +1684,19 @@ class FieldValuePrinterWrapper : public TextFormat::FastFieldValuePrinter { } void PrintFieldName(const Message& message, const Reflection* reflection, const FieldDescriptor* field, - TextFormat::BaseTextGenerator* generator) const { + TextFormat::BaseTextGenerator* generator) const override { generator->PrintString( delegate_->PrintFieldName(message, reflection, field)); } void PrintMessageStart(const Message& message, int field_index, int field_count, bool single_line_mode, - TextFormat::BaseTextGenerator* generator) const { + TextFormat::BaseTextGenerator* generator) const override { generator->PrintString(delegate_->PrintMessageStart( message, field_index, field_count, single_line_mode)); } void PrintMessageEnd(const Message& message, int field_index, int field_count, bool single_line_mode, - TextFormat::BaseTextGenerator* generator) const { + TextFormat::BaseTextGenerator* generator) const override { generator->PrintString(delegate_->PrintMessageEnd( message, field_index, field_count, single_line_mode)); } @@ -1710,13 +1710,13 @@ class FastFieldValuePrinterUtf8Escaping : public TextFormat::FastFieldValuePrinter { public: void PrintString(const string& val, - TextFormat::BaseTextGenerator* generator) const { + TextFormat::BaseTextGenerator* generator) const override { generator->PrintLiteral("\""); generator->PrintString(strings::Utf8SafeCEscape(val)); generator->PrintLiteral("\""); } void PrintBytes(const string& val, - TextFormat::BaseTextGenerator* generator) const { + TextFormat::BaseTextGenerator* generator) const override { return FastFieldValuePrinter::PrintString(val, generator); } }; diff --git a/src/google/protobuf/text_format_unittest.cc b/src/google/protobuf/text_format_unittest.cc index 544c37e2..b0ea5783 100644 --- a/src/google/protobuf/text_format_unittest.cc +++ b/src/google/protobuf/text_format_unittest.cc @@ -77,7 +77,7 @@ const string kEscapeTestStringEscaped = class TextFormatTest : public testing::Test { public: static void SetUpTestCase() { - GOOGLE_CHECK_OK(File::GetContents( + GOOGLE_CHECK_OK(File::GetContentsAsText( TestSourceDir() + "/google/protobuf/" "testdata/text_format_unittest_data_oneof_implemented.txt", @@ -99,7 +99,7 @@ string TextFormatTest::static_proto_debug_string_; class TextFormatExtensionsTest : public testing::Test { public: static void SetUpTestCase() { - GOOGLE_CHECK_OK(File::GetContents(TestSourceDir() + + GOOGLE_CHECK_OK(File::GetContentsAsText(TestSourceDir() + "/google/protobuf/testdata/" "text_format_unittest_extensions_data.txt", &static_proto_debug_string_, true)); @@ -574,6 +574,11 @@ class CompactRepeatedFieldPrinter : public TextFormat::FastFieldValuePrinter { generator->PrintString(field->name()); } } + // To prevent compiler complaining about Woverloaded-virtual + void PrintFieldName(const Message& message, + const Reflection* reflection, + const FieldDescriptor* field, + TextFormat::BaseTextGenerator* generator) const override {} void PrintMessageStart( const Message& message, int field_index, int field_count, bool single_line_mode, diff --git a/src/google/protobuf/timestamp.pb.cc b/src/google/protobuf/timestamp.pb.cc index 8e6b5f23..4269031f 100644 --- a/src/google/protobuf/timestamp.pb.cc +++ b/src/google/protobuf/timestamp.pb.cc @@ -66,14 +66,14 @@ static ::google::protobuf::Message const * const file_default_instances[] = { reinterpret_cast<const ::google::protobuf::Message*>(&::google::protobuf::_Timestamp_default_instance_), }; -void protobuf_AssignDescriptors() { +static void protobuf_AssignDescriptors() { AddDescriptors(); AssignDescriptors( "google/protobuf/timestamp.proto", schemas, file_default_instances, TableStruct::offsets, file_level_metadata, NULL, NULL); } -void protobuf_AssignDescriptorsOnce() { +static void protobuf_AssignDescriptorsOnce() { static ::google::protobuf::internal::once_flag once; ::google::protobuf::internal::call_once(once, protobuf_AssignDescriptors); } @@ -84,7 +84,7 @@ void protobuf_RegisterTypes(const ::std::string&) { ::google::protobuf::internal::RegisterAllTypes(file_level_metadata, 1); } -void AddDescriptorsImpl() { +static void AddDescriptorsImpl() { InitDefaults(); static const char descriptor[] GOOGLE_PROTOBUF_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold) = { "\n\037google/protobuf/timestamp.proto\022\017googl" @@ -167,7 +167,7 @@ void Timestamp::ArenaDtor(void* object) { Timestamp* _this = reinterpret_cast< Timestamp* >(object); (void)_this; } -void Timestamp::RegisterArenaDtor(::google::protobuf::Arena* arena) { +void Timestamp::RegisterArenaDtor(::google::protobuf::Arena*) { } void Timestamp::SetCachedSize(int size) const { _cached_size_.Set(size); diff --git a/src/google/protobuf/type.pb.cc b/src/google/protobuf/type.pb.cc index 130af52a..72679df8 100644 --- a/src/google/protobuf/type.pb.cc +++ b/src/google/protobuf/type.pb.cc @@ -219,14 +219,14 @@ static ::google::protobuf::Message const * const file_default_instances[] = { reinterpret_cast<const ::google::protobuf::Message*>(&::google::protobuf::_Option_default_instance_), }; -void protobuf_AssignDescriptors() { +static void protobuf_AssignDescriptors() { AddDescriptors(); AssignDescriptors( "google/protobuf/type.proto", schemas, file_default_instances, TableStruct::offsets, file_level_metadata, file_level_enum_descriptors, NULL); } -void protobuf_AssignDescriptorsOnce() { +static void protobuf_AssignDescriptorsOnce() { static ::google::protobuf::internal::once_flag once; ::google::protobuf::internal::call_once(once, protobuf_AssignDescriptors); } @@ -237,7 +237,7 @@ void protobuf_RegisterTypes(const ::std::string&) { ::google::protobuf::internal::RegisterAllTypes(file_level_metadata, 5); } -void AddDescriptorsImpl() { +static void AddDescriptorsImpl() { InitDefaults(); static const char descriptor[] GOOGLE_PROTOBUF_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold) = { "\n\032google/protobuf/type.proto\022\017google.pro" @@ -492,7 +492,7 @@ void Type::ArenaDtor(void* object) { Type* _this = reinterpret_cast< Type* >(object); (void)_this; } -void Type::RegisterArenaDtor(::google::protobuf::Arena* arena) { +void Type::RegisterArenaDtor(::google::protobuf::Arena*) { } void Type::SetCachedSize(int size) const { _cached_size_.Set(size); @@ -609,7 +609,7 @@ bool Type::MergePartialFromCodedStream( case 6: { if (static_cast< ::google::protobuf::uint8>(tag) == static_cast< ::google::protobuf::uint8>(48u /* 48 & 0xFF */)) { - int value; + int value = 0; DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>( input, &value))); @@ -1014,7 +1014,7 @@ void Field::ArenaDtor(void* object) { Field* _this = reinterpret_cast< Field* >(object); (void)_this; } -void Field::RegisterArenaDtor(::google::protobuf::Arena* arena) { +void Field::RegisterArenaDtor(::google::protobuf::Arena*) { } void Field::SetCachedSize(int size) const { _cached_size_.Set(size); @@ -1061,7 +1061,7 @@ bool Field::MergePartialFromCodedStream( case 1: { if (static_cast< ::google::protobuf::uint8>(tag) == static_cast< ::google::protobuf::uint8>(8u /* 8 & 0xFF */)) { - int value; + int value = 0; DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>( input, &value))); @@ -1076,7 +1076,7 @@ bool Field::MergePartialFromCodedStream( case 2: { if (static_cast< ::google::protobuf::uint8>(tag) == static_cast< ::google::protobuf::uint8>(16u /* 16 & 0xFF */)) { - int value; + int value = 0; DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>( input, &value))); @@ -1698,7 +1698,7 @@ void Enum::ArenaDtor(void* object) { Enum* _this = reinterpret_cast< Enum* >(object); (void)_this; } -void Enum::RegisterArenaDtor(::google::protobuf::Arena* arena) { +void Enum::RegisterArenaDtor(::google::protobuf::Arena*) { } void Enum::SetCachedSize(int size) const { _cached_size_.Set(size); @@ -1797,7 +1797,7 @@ bool Enum::MergePartialFromCodedStream( case 5: { if (static_cast< ::google::protobuf::uint8>(tag) == static_cast< ::google::protobuf::uint8>(40u /* 40 & 0xFF */)) { - int value; + int value = 0; DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>( input, &value))); @@ -2140,7 +2140,7 @@ void EnumValue::ArenaDtor(void* object) { EnumValue* _this = reinterpret_cast< EnumValue* >(object); (void)_this; } -void EnumValue::RegisterArenaDtor(::google::protobuf::Arena* arena) { +void EnumValue::RegisterArenaDtor(::google::protobuf::Arena*) { } void EnumValue::SetCachedSize(int size) const { _cached_size_.Set(size); @@ -2520,7 +2520,7 @@ void Option::ArenaDtor(void* object) { Option* _this = reinterpret_cast< Option* >(object); (void)_this; } -void Option::RegisterArenaDtor(::google::protobuf::Arena* arena) { +void Option::RegisterArenaDtor(::google::protobuf::Arena*) { } void Option::SetCachedSize(int size) const { _cached_size_.Set(size); diff --git a/src/google/protobuf/util/field_comparator.h b/src/google/protobuf/util/field_comparator.h index 27ef4c77..63e89fb7 100644 --- a/src/google/protobuf/util/field_comparator.h +++ b/src/google/protobuf/util/field_comparator.h @@ -110,14 +110,14 @@ class LIBPROTOBUF_EXPORT DefaultFieldComparator : public FieldComparator { // Creates new comparator with float comparison set to EXACT. DefaultFieldComparator(); - virtual ~DefaultFieldComparator(); + ~DefaultFieldComparator() override; - virtual ComparisonResult Compare( + ComparisonResult Compare( const google::protobuf::Message& message_1, const google::protobuf::Message& message_2, const google::protobuf::FieldDescriptor* field, int index_1, int index_2, - const google::protobuf::util::FieldContext* field_context); + const google::protobuf::util::FieldContext* field_context) override; void set_float_comparison(FloatComparison float_comparison) { float_comparison_ = float_comparison; diff --git a/src/google/protobuf/util/internal/default_value_objectwriter.h b/src/google/protobuf/util/internal/default_value_objectwriter.h index 6e71f9c8..7d245c9c 100644 --- a/src/google/protobuf/util/internal/default_value_objectwriter.h +++ b/src/google/protobuf/util/internal/default_value_objectwriter.h @@ -83,37 +83,37 @@ class LIBPROTOBUF_EXPORT DefaultValueObjectWriter : public ObjectWriter { virtual ~DefaultValueObjectWriter(); // ObjectWriter methods. - virtual DefaultValueObjectWriter* StartObject(StringPiece name); + virtual DefaultValueObjectWriter* StartObject(StringPiece name) override; - virtual DefaultValueObjectWriter* EndObject(); + virtual DefaultValueObjectWriter* EndObject() override; - virtual DefaultValueObjectWriter* StartList(StringPiece name); + virtual DefaultValueObjectWriter* StartList(StringPiece name) override; - virtual DefaultValueObjectWriter* EndList(); + virtual DefaultValueObjectWriter* EndList() override; - virtual DefaultValueObjectWriter* RenderBool(StringPiece name, bool value); + virtual DefaultValueObjectWriter* RenderBool(StringPiece name, bool value) override; - virtual DefaultValueObjectWriter* RenderInt32(StringPiece name, int32 value); + virtual DefaultValueObjectWriter* RenderInt32(StringPiece name, int32 value) override; virtual DefaultValueObjectWriter* RenderUint32(StringPiece name, - uint32 value); + uint32 value) override; - virtual DefaultValueObjectWriter* RenderInt64(StringPiece name, int64 value); + virtual DefaultValueObjectWriter* RenderInt64(StringPiece name, int64 value) override; virtual DefaultValueObjectWriter* RenderUint64(StringPiece name, - uint64 value); + uint64 value) override; virtual DefaultValueObjectWriter* RenderDouble(StringPiece name, - double value); + double value) override; - virtual DefaultValueObjectWriter* RenderFloat(StringPiece name, float value); + virtual DefaultValueObjectWriter* RenderFloat(StringPiece name, float value) override; virtual DefaultValueObjectWriter* RenderString(StringPiece name, - StringPiece value); + StringPiece value) override; virtual DefaultValueObjectWriter* RenderBytes(StringPiece name, - StringPiece value); + StringPiece value) override; - virtual DefaultValueObjectWriter* RenderNull(StringPiece name); + virtual DefaultValueObjectWriter* RenderNull(StringPiece name) override; // Register the callback for scrubbing of fields. Owership of // field_scrub_callback pointer is also transferred to this class diff --git a/src/google/protobuf/util/internal/error_listener.h b/src/google/protobuf/util/internal/error_listener.h index a19bd3f7..e3baa224 100644 --- a/src/google/protobuf/util/internal/error_listener.h +++ b/src/google/protobuf/util/internal/error_listener.h @@ -76,16 +76,16 @@ class LIBPROTOBUF_EXPORT ErrorListener { class LIBPROTOBUF_EXPORT NoopErrorListener : public ErrorListener { public: NoopErrorListener() {} - virtual ~NoopErrorListener() {} + virtual ~NoopErrorListener() override {} virtual void InvalidName(const LocationTrackerInterface& loc, - StringPiece invalid_name, StringPiece message) {} + StringPiece invalid_name, StringPiece message) override {} - virtual void InvalidValue(const LocationTrackerInterface& loc, - StringPiece type_name, StringPiece value) {} + virtual void InvalidValue(const LocationTrackerInterface &loc, StringPiece type_name, + StringPiece value) override {} - virtual void MissingField(const LocationTrackerInterface& loc, - StringPiece missing_name) {} + virtual void MissingField(const LocationTrackerInterface &loc, + StringPiece missing_name) override {} private: GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(NoopErrorListener); diff --git a/src/google/protobuf/util/internal/json_objectwriter.h b/src/google/protobuf/util/internal/json_objectwriter.h index 81644dab..4c25b465 100644 --- a/src/google/protobuf/util/internal/json_objectwriter.h +++ b/src/google/protobuf/util/internal/json_objectwriter.h @@ -94,20 +94,20 @@ class LIBPROTOBUF_EXPORT JsonObjectWriter : public StructuredObjectWriter { virtual ~JsonObjectWriter(); // ObjectWriter methods. - virtual JsonObjectWriter* StartObject(StringPiece name); - virtual JsonObjectWriter* EndObject(); - virtual JsonObjectWriter* StartList(StringPiece name); - virtual JsonObjectWriter* EndList(); - virtual JsonObjectWriter* RenderBool(StringPiece name, bool value); - virtual JsonObjectWriter* RenderInt32(StringPiece name, int32 value); - virtual JsonObjectWriter* RenderUint32(StringPiece name, uint32 value); - virtual JsonObjectWriter* RenderInt64(StringPiece name, int64 value); - virtual JsonObjectWriter* RenderUint64(StringPiece name, uint64 value); - virtual JsonObjectWriter* RenderDouble(StringPiece name, double value); - virtual JsonObjectWriter* RenderFloat(StringPiece name, float value); - virtual JsonObjectWriter* RenderString(StringPiece name, StringPiece value); - virtual JsonObjectWriter* RenderBytes(StringPiece name, StringPiece value); - virtual JsonObjectWriter* RenderNull(StringPiece name); + virtual JsonObjectWriter* StartObject(StringPiece name) override; + virtual JsonObjectWriter* EndObject() override; + virtual JsonObjectWriter* StartList(StringPiece name) override; + virtual JsonObjectWriter* EndList() override; + virtual JsonObjectWriter* RenderBool(StringPiece name, bool value) override; + virtual JsonObjectWriter* RenderInt32(StringPiece name, int32 value) override; + virtual JsonObjectWriter* RenderUint32(StringPiece name, uint32 value) override; + virtual JsonObjectWriter* RenderInt64(StringPiece name, int64 value) override; + virtual JsonObjectWriter* RenderUint64(StringPiece name, uint64 value) override; + virtual JsonObjectWriter* RenderDouble(StringPiece name, double value) override; + virtual JsonObjectWriter* RenderFloat(StringPiece name, float value) override; + virtual JsonObjectWriter* RenderString(StringPiece name, StringPiece value) override; + virtual JsonObjectWriter* RenderBytes(StringPiece name, StringPiece value) override; + virtual JsonObjectWriter* RenderNull(StringPiece name) override; virtual JsonObjectWriter* RenderNullAsEmpty(StringPiece name); void set_use_websafe_base64_for_bytes(bool value) { @@ -143,17 +143,17 @@ class LIBPROTOBUF_EXPORT JsonObjectWriter : public StructuredObjectWriter { GOOGLE_DISALLOW_IMPLICIT_CONSTRUCTORS(Element); }; - virtual Element* element() { return element_.get(); } + Element* element() override { return element_.get(); } private: class LIBPROTOBUF_EXPORT ByteSinkWrapper : public strings::ByteSink { public: explicit ByteSinkWrapper(google::protobuf::io::CodedOutputStream* stream) : stream_(stream) {} - virtual ~ByteSinkWrapper() {} + ~ByteSinkWrapper() override {} // ByteSink methods. - virtual void Append(const char* bytes, size_t n) { + void Append(const char* bytes, size_t n) override { stream_->WriteRaw(bytes, n); } diff --git a/src/google/protobuf/util/internal/object_location_tracker.h b/src/google/protobuf/util/internal/object_location_tracker.h index 8586cecc..f9b90bc4 100644 --- a/src/google/protobuf/util/internal/object_location_tracker.h +++ b/src/google/protobuf/util/internal/object_location_tracker.h @@ -47,10 +47,10 @@ class ObjectLocationTracker : public LocationTrackerInterface { // Creates an empty location tracker. ObjectLocationTracker() {} - virtual ~ObjectLocationTracker() {} + ~ObjectLocationTracker() override {} // Returns empty because nothing is tracked. - virtual string ToString() const { return ""; } + string ToString() const override { return ""; } private: GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ObjectLocationTracker); diff --git a/src/google/protobuf/util/internal/proto_writer.h b/src/google/protobuf/util/internal/proto_writer.h index 28496963..5bdafcc9 100644 --- a/src/google/protobuf/util/internal/proto_writer.h +++ b/src/google/protobuf/util/internal/proto_writer.h @@ -78,7 +78,7 @@ class LIBPROTOBUF_EXPORT ProtoWriter : public StructuredObjectWriter { // Constructor. Does not take ownership of any parameter passed in. ProtoWriter(TypeResolver* type_resolver, const google::protobuf::Type& type, strings::ByteSink* output, ErrorListener* listener); - virtual ~ProtoWriter(); + virtual ~ProtoWriter() override; // ObjectWriter methods. ProtoWriter* StartObject(StringPiece name) override; @@ -110,7 +110,7 @@ class LIBPROTOBUF_EXPORT ProtoWriter : public StructuredObjectWriter { return RenderDataPiece(name, DataPiece(value, use_strict_base64_decoding())); } - virtual ProtoWriter* RenderBytes(StringPiece name, StringPiece value) { + ProtoWriter* RenderBytes(StringPiece name, StringPiece value) override { return RenderDataPiece( name, DataPiece(value, false, use_strict_base64_decoding())); } @@ -163,7 +163,7 @@ class LIBPROTOBUF_EXPORT ProtoWriter : public StructuredObjectWriter { ProtoElement(ProtoElement* parent, const google::protobuf::Field* field, const google::protobuf::Type& type, bool is_list); - virtual ~ProtoElement() {} + virtual ~ProtoElement() override {} // Called just before the destructor for clean up: // - reports any missing required fields @@ -183,9 +183,9 @@ class LIBPROTOBUF_EXPORT ProtoWriter : public StructuredObjectWriter { void RegisterField(const google::protobuf::Field* field); // To report location on error messages. - virtual string ToString() const; + virtual string ToString() const override; - virtual ProtoElement* parent() const { + virtual ProtoElement* parent() const override { return static_cast<ProtoElement*>(BaseElement::parent()); } diff --git a/src/google/protobuf/util/internal/protostream_objectsource.cc b/src/google/protobuf/util/internal/protostream_objectsource.cc index 56e6db12..b0d86c17 100644 --- a/src/google/protobuf/util/internal/protostream_objectsource.cc +++ b/src/google/protobuf/util/internal/protostream_objectsource.cc @@ -648,6 +648,13 @@ Status ProtoStreamObjectSource::RenderAny(const ProtoStreamObjectSource* os, // using a nested ProtoStreamObjectSource using our nested type information. ProtoStreamObjectSource nested_os(&in_stream, os->typeinfo_, *nested_type); + // TODO(htuch): This is somewhat fragile, since new options may be omitted. + // We should probably do this via the constructor or some object grouping + // options. + nested_os.set_use_lower_camel_for_enums(os->use_lower_camel_for_enums_); + nested_os.set_use_ints_for_enums(os->use_ints_for_enums_); + nested_os.set_preserve_proto_field_names(os->preserve_proto_field_names_); + // We manually call start and end object here so we can inject the @type. ow->StartObject(field_name); ow->RenderString("@type", type_url); diff --git a/src/google/protobuf/util/internal/protostream_objectsource.h b/src/google/protobuf/util/internal/protostream_objectsource.h index b56efdf4..acd081d9 100644 --- a/src/google/protobuf/util/internal/protostream_objectsource.h +++ b/src/google/protobuf/util/internal/protostream_objectsource.h @@ -78,9 +78,9 @@ class LIBPROTOBUF_EXPORT ProtoStreamObjectSource : public ObjectSource { TypeResolver* type_resolver, const google::protobuf::Type& type); - virtual ~ProtoStreamObjectSource(); + virtual ~ProtoStreamObjectSource() override; - virtual util::Status NamedWriteTo(StringPiece name, ObjectWriter* ow) const; + virtual util::Status NamedWriteTo(StringPiece name, ObjectWriter* ow) const override; // Sets whether or not to use lowerCamelCase casing for enum values. If set to // false, enum values are output without any case conversions. diff --git a/src/google/protobuf/util/internal/protostream_objectsource_test.cc b/src/google/protobuf/util/internal/protostream_objectsource_test.cc index df790728..4d86b856 100644 --- a/src/google/protobuf/util/internal/protostream_objectsource_test.cc +++ b/src/google/protobuf/util/internal/protostream_objectsource_test.cc @@ -100,6 +100,7 @@ class ProtostreamObjectSourceTest ow_(&mock_), use_lower_camel_for_enums_(false), use_ints_for_enums_(false), + use_preserve_proto_field_names_(false), add_trailing_zeros_(false), render_unknown_enum_values_(true) { helper_.ResetTypeInfo(Book::descriptor(), Proto3Message::descriptor()); @@ -123,6 +124,7 @@ class ProtostreamObjectSourceTest helper_.NewProtoSource(&in_stream, GetTypeUrl(descriptor))); if (use_lower_camel_for_enums_) os->set_use_lower_camel_for_enums(true); if (use_ints_for_enums_) os->set_use_ints_for_enums(true); + if (use_preserve_proto_field_names_) os->set_preserve_proto_field_names(true); os->set_max_recursion_depth(64); return os->WriteTo(&mock_); } @@ -272,6 +274,8 @@ class ProtostreamObjectSourceTest void UseIntsForEnums() { use_ints_for_enums_ = true; } + void UsePreserveProtoFieldNames() { use_preserve_proto_field_names_ = true; } + void AddTrailingZeros() { add_trailing_zeros_ = true; } void SetRenderUnknownEnumValues(bool value) { @@ -284,6 +288,7 @@ class ProtostreamObjectSourceTest ExpectingObjectWriter ow_; bool use_lower_camel_for_enums_; bool use_ints_for_enums_; + bool use_preserve_proto_field_names_; bool add_trailing_zeros_; bool render_unknown_enum_values_; }; @@ -536,6 +541,16 @@ TEST_P(ProtostreamObjectSourceTest, UseIntsForEnumsTest) { DoTest(book, Book::descriptor()); } +TEST_P(ProtostreamObjectSourceTest, UsePreserveProtoFieldNames) { + Book book; + book.set_snake_field("foo"); + + UsePreserveProtoFieldNames(); + + ow_.StartObject("")->RenderString("snake_field", "foo")->EndObject(); + DoTest(book, Book::descriptor()); +} + TEST_P(ProtostreamObjectSourceTest, UnknownEnumAreDroppedWhenRenderUnknownEnumValuesIsUnset) { Proto3Message message; @@ -769,6 +784,69 @@ TEST_P(ProtostreamObjectSourceAnysTest, BasicAny) { DoTest(out, AnyOut::descriptor()); } +TEST_P(ProtostreamObjectSourceAnysTest, LowerCamelEnumOutputSnakeCase) { + AnyOut out; + ::google::protobuf::Any* any = out.mutable_any(); + + Book book; + book.set_type(Book::arts_and_photography); + any->PackFrom(book); + + UseLowerCamelForEnums(); + + ow_.StartObject("") + ->StartObject("any") + ->RenderString("@type", + "type.googleapis.com/google.protobuf.testing.Book") + ->RenderString("type", "artsAndPhotography") + ->EndObject() + ->EndObject(); + + DoTest(out, AnyOut::descriptor()); +} + +TEST_P(ProtostreamObjectSourceAnysTest, UseIntsForEnumsTest) { + AnyOut out; + ::google::protobuf::Any* any = out.mutable_any(); + + Book book; + book.set_type(Book::ACTION_AND_ADVENTURE); + any->PackFrom(book); + + UseIntsForEnums(); + + ow_.StartObject("") + ->StartObject("any") + ->RenderString("@type", + "type.googleapis.com/google.protobuf.testing.Book") + ->RenderInt32("type", 3) + ->EndObject() + ->EndObject(); + + DoTest(out, AnyOut::descriptor()); +} + +TEST_P(ProtostreamObjectSourceAnysTest, UsePreserveProtoFieldNames) { + AnyOut out; + ::google::protobuf::Any* any = out.mutable_any(); + + Book book; + book.set_snake_field("foo"); + any->PackFrom(book); + + UsePreserveProtoFieldNames(); + + ow_.StartObject("") + ->StartObject("any") + ->RenderString("@type", + "type.googleapis.com/google.protobuf.testing.Book") + ->RenderString("snake_field", "foo") + ->EndObject() + ->EndObject(); + + DoTest(out, AnyOut::descriptor()); +} + TEST_P(ProtostreamObjectSourceAnysTest, RecursiveAny) { AnyOut out; ::google::protobuf::Any* any = out.mutable_any(); diff --git a/src/google/protobuf/util/internal/protostream_objectwriter.cc b/src/google/protobuf/util/internal/protostream_objectwriter.cc index 2edfd075..a1a7030a 100644 --- a/src/google/protobuf/util/internal/protostream_objectwriter.cc +++ b/src/google/protobuf/util/internal/protostream_objectwriter.cc @@ -534,7 +534,7 @@ ProtoStreamObjectWriter* ProtoStreamObjectWriter::StartObject( Push("", Item::MESSAGE, false, false); ProtoWriter::RenderDataPiece("key", DataPiece(name, use_strict_base64_decoding())); - Push("value", Item::MESSAGE, true, false); + Push("value", IsAny(*Lookup("value")) ? Item::ANY : Item::MESSAGE, true, false); // Make sure we are valid so far after starting map fields. if (invalid_depth() > 0) return this; diff --git a/src/google/protobuf/util/internal/protostream_objectwriter.h b/src/google/protobuf/util/internal/protostream_objectwriter.h index c33a4639..d9bb432e 100644 --- a/src/google/protobuf/util/internal/protostream_objectwriter.h +++ b/src/google/protobuf/util/internal/protostream_objectwriter.h @@ -112,18 +112,18 @@ class LIBPROTOBUF_EXPORT ProtoStreamObjectWriter : public ProtoWriter { strings::ByteSink* output, ErrorListener* listener, const ProtoStreamObjectWriter::Options& options = ProtoStreamObjectWriter::Options::Defaults()); - virtual ~ProtoStreamObjectWriter(); + virtual ~ProtoStreamObjectWriter() override; // ObjectWriter methods. - virtual ProtoStreamObjectWriter* StartObject(StringPiece name); - virtual ProtoStreamObjectWriter* EndObject(); - virtual ProtoStreamObjectWriter* StartList(StringPiece name); - virtual ProtoStreamObjectWriter* EndList(); + virtual ProtoStreamObjectWriter* StartObject(StringPiece name) override; + virtual ProtoStreamObjectWriter* EndObject() override; + virtual ProtoStreamObjectWriter* StartList(StringPiece name) override; + virtual ProtoStreamObjectWriter* EndList() override; // Renders a DataPiece 'value' into a field whose wire type is determined // from the given field 'name'. virtual ProtoStreamObjectWriter* RenderDataPiece(StringPiece name, - const DataPiece& value); + const DataPiece& value) override; protected: // Function that renders a well known type with modified behavior. @@ -263,7 +263,7 @@ class LIBPROTOBUF_EXPORT ProtoStreamObjectWriter : public ProtoWriter { // Constructor for a field of a message. Item(Item* parent, ItemType item_type, bool is_placeholder, bool is_list); - virtual ~Item() {} + virtual ~Item() override {} // These functions return true if the element type is corresponding to the // type in function name. @@ -272,7 +272,7 @@ class LIBPROTOBUF_EXPORT ProtoStreamObjectWriter : public ProtoWriter { AnyWriter* any() const { return any_.get(); } - virtual Item* parent() const { + virtual Item* parent() const override { return static_cast<Item*>(BaseElement::parent()); } diff --git a/src/google/protobuf/util/internal/protostream_objectwriter_test.cc b/src/google/protobuf/util/internal/protostream_objectwriter_test.cc index 7f0df567..9c50e7dd 100644 --- a/src/google/protobuf/util/internal/protostream_objectwriter_test.cc +++ b/src/google/protobuf/util/internal/protostream_objectwriter_test.cc @@ -1679,6 +1679,22 @@ TEST_P(ProtoStreamObjectWriterMapTest, RepeatedMapKeyTest) { ->EndObject(); } +TEST_P(ProtoStreamObjectWriterMapTest, AnyInMap) { + MapIn mm; + google::protobuf::DoubleValue d; + d.set_value(40.2); + (*mm.mutable_map_any())["foo"].PackFrom(d); + ow_->StartObject("") + ->StartObject("map_any") + ->StartObject("foo") + ->RenderString("@type", "type.googleapis.com/google.protobuf.DoubleValue") + ->RenderDouble("value", 40.2) + ->EndObject() + ->EndObject() + ->EndObject(); + CheckOutput(mm); +} + class ProtoStreamObjectWriterAnyTest : public BaseProtoStreamObjectWriterTest { protected: ProtoStreamObjectWriterAnyTest() { diff --git a/src/google/protobuf/util/internal/testdata/books.proto b/src/google/protobuf/util/internal/testdata/books.proto index 5630cc78..5e08a291 100644 --- a/src/google/protobuf/util/internal/testdata/books.proto +++ b/src/google/protobuf/util/internal/testdata/books.proto @@ -69,6 +69,9 @@ message Book { } optional Type type = 11; + // Useful for testing JSON snake/camel-case conversions. + optional string snake_field = 12; + extensions 200 to 499; } diff --git a/src/google/protobuf/util/internal/testdata/maps.proto b/src/google/protobuf/util/internal/testdata/maps.proto index 0f381b32..765254ea 100644 --- a/src/google/protobuf/util/internal/testdata/maps.proto +++ b/src/google/protobuf/util/internal/testdata/maps.proto @@ -32,6 +32,8 @@ syntax = "proto3"; package google.protobuf.testing; +import "google/protobuf/any.proto"; + // Top-level test cases proto used by MarshallingTest. See description // at the top of the class MarshallingTest for details on how to write // test cases. @@ -103,6 +105,7 @@ message MapIn { string other = 1; repeated string things = 2; map<string, string> map_input = 3; + map<string, google.protobuf.Any> map_any = 4; } message MapOut { diff --git a/src/google/protobuf/util/internal/type_info.cc b/src/google/protobuf/util/internal/type_info.cc index 3847b179..e32e71d0 100644 --- a/src/google/protobuf/util/internal/type_info.cc +++ b/src/google/protobuf/util/internal/type_info.cc @@ -59,7 +59,7 @@ class TypeInfoForTypeResolver : public TypeInfo { } virtual util::StatusOr<const google::protobuf::Type*> ResolveTypeUrl( - StringPiece type_url) const { + StringPiece type_url) const override { std::map<StringPiece, StatusOrType>::iterator it = cached_types_.find(type_url); if (it != cached_types_.end()) { @@ -79,13 +79,13 @@ class TypeInfoForTypeResolver : public TypeInfo { } virtual const google::protobuf::Type* GetTypeByTypeUrl( - StringPiece type_url) const { + StringPiece type_url) const override { StatusOrType result = ResolveTypeUrl(type_url); return result.ok() ? result.ValueOrDie() : NULL; } virtual const google::protobuf::Enum* GetEnumByTypeUrl( - StringPiece type_url) const { + StringPiece type_url) const override { std::map<StringPiece, StatusOrEnum>::iterator it = cached_enums_.find(type_url); if (it != cached_enums_.end()) { @@ -105,8 +105,10 @@ class TypeInfoForTypeResolver : public TypeInfo { return result.ok() ? result.ValueOrDie() : NULL; } + virtual const google::protobuf::Field* FindField( - const google::protobuf::Type* type, StringPiece camel_case_name) const { + const google::protobuf::Type* type, + StringPiece camel_case_name) const override { std::map<const google::protobuf::Type*, CamelCaseNameTable>::const_iterator it = indexed_types_.find(type); const CamelCaseNameTable& camel_case_name_table = diff --git a/src/google/protobuf/util/json_util.cc b/src/google/protobuf/util/json_util.cc index f81a7a30..7a7f299f 100644 --- a/src/google/protobuf/util/json_util.cc +++ b/src/google/protobuf/util/json_util.cc @@ -119,19 +119,21 @@ util::Status BinaryToJsonString(TypeResolver* resolver, namespace { class StatusErrorListener : public converter::ErrorListener { public: + StatusErrorListener() {} - virtual ~StatusErrorListener() {} + virtual ~StatusErrorListener() override {} util::Status GetStatus() { return status_; } virtual void InvalidName(const converter::LocationTrackerInterface& loc, - StringPiece unknown_name, StringPiece message) { + StringPiece unknown_name, StringPiece message) override { status_ = util::Status(util::error::INVALID_ARGUMENT, - loc.ToString() + ": " + string(message)); + loc.ToString() + ": invalid name " + + string(unknown_name) + ": " + string(message)); } virtual void InvalidValue(const converter::LocationTrackerInterface& loc, - StringPiece type_name, StringPiece value) { + StringPiece type_name, StringPiece value) override { status_ = util::Status(util::error::INVALID_ARGUMENT, loc.ToString() + ": invalid value " + string(value) + @@ -139,7 +141,7 @@ class StatusErrorListener : public converter::ErrorListener { } virtual void MissingField(const converter::LocationTrackerInterface& loc, - StringPiece missing_name) { + StringPiece missing_name) override { status_ = util::Status( util::error::INVALID_ARGUMENT, loc.ToString() + ": missing field " + string(missing_name)); diff --git a/src/google/protobuf/util/json_util.h b/src/google/protobuf/util/json_util.h index b1c69813..e7868307 100644 --- a/src/google/protobuf/util/json_util.h +++ b/src/google/protobuf/util/json_util.h @@ -182,7 +182,7 @@ class LIBPROTOBUF_EXPORT ZeroCopyStreamByteSink : public strings::ByteSink { : stream_(stream), buffer_(NULL), buffer_size_(0) {} ~ZeroCopyStreamByteSink(); - virtual void Append(const char* bytes, size_t len); + virtual void Append(const char* bytes, size_t len) override; private: io::ZeroCopyOutputStream* stream_; diff --git a/src/google/protobuf/util/json_util_test.cc b/src/google/protobuf/util/json_util_test.cc index ed9092df..a2a84b57 100644 --- a/src/google/protobuf/util/json_util_test.cc +++ b/src/google/protobuf/util/json_util_test.cc @@ -284,7 +284,7 @@ TEST_F(JsonUtilTest, ParsePrimitiveMapIn) { JsonPrintOptions print_options; print_options.always_print_primitive_fields = true; JsonParseOptions parse_options; - EXPECT_EQ("{\"other\":\"\",\"things\":[],\"mapInput\":{}}", + EXPECT_EQ("{\"other\":\"\",\"things\":[],\"mapInput\":{},\"mapAny\":{}}", ToJson(message, print_options)); MapIn other; ASSERT_TRUE(FromJson(ToJson(message, print_options), &other, parse_options)); diff --git a/src/google/protobuf/util/message_differencer.cc b/src/google/protobuf/util/message_differencer.cc index 9842f64c..7d3976f8 100644 --- a/src/google/protobuf/util/message_differencer.cc +++ b/src/google/protobuf/util/message_differencer.cc @@ -90,7 +90,7 @@ class MessageDifferencer::MultipleFieldsMapKeyComparator virtual bool IsMatch( const Message& message1, const Message& message2, - const std::vector<SpecificField>& parent_fields) const { + const std::vector<SpecificField>& parent_fields) const override { for (int i = 0; i < key_field_paths_.size(); ++i) { if (!IsMatchInternal(message1, message2, parent_fields, key_field_paths_[i], 0)) { diff --git a/src/google/protobuf/util/message_differencer.h b/src/google/protobuf/util/message_differencer.h index bbcf8498..b3e65515 100644 --- a/src/google/protobuf/util/message_differencer.h +++ b/src/google/protobuf/util/message_differencer.h @@ -597,7 +597,7 @@ class LIBPROTOBUF_EXPORT MessageDifferencer { public: explicit StreamReporter(io::ZeroCopyOutputStream* output); explicit StreamReporter(io::Printer* printer); // delimiter '$' - virtual ~StreamReporter(); + virtual ~StreamReporter() override; // When set to true, the stream reporter will also output aggregates nodes // (i.e. messages and groups) whose subfields have been modified. When @@ -607,32 +607,33 @@ class LIBPROTOBUF_EXPORT MessageDifferencer { } // The following are implementations of the methods described above. + virtual void ReportAdded(const Message& message1, const Message& message2, - const std::vector<SpecificField>& field_path); + const std::vector<SpecificField>& field_path) override; virtual void ReportDeleted(const Message& message1, const Message& message2, - const std::vector<SpecificField>& field_path); + const std::vector<SpecificField>& field_path) override; virtual void ReportModified(const Message& message1, const Message& message2, - const std::vector<SpecificField>& field_path); + const std::vector<SpecificField>& field_path) override; virtual void ReportMoved(const Message& message1, const Message& message2, - const std::vector<SpecificField>& field_path); + const std::vector<SpecificField>& field_path) override; virtual void ReportMatched(const Message& message1, const Message& message2, - const std::vector<SpecificField>& field_path); + const std::vector<SpecificField>& field_path) override; virtual void ReportIgnored(const Message& message1, const Message& message2, - const std::vector<SpecificField>& field_path); + const std::vector<SpecificField>& field_path) override; - virtual void ReportUnknownFieldIgnored( + void ReportUnknownFieldIgnored( const Message& message1, const Message& message2, - const std::vector<SpecificField>& field_path); + const std::vector<SpecificField>& field_path) override; protected: // Prints the specified path of fields to the buffer. message is used to @@ -681,7 +682,7 @@ class LIBPROTOBUF_EXPORT MessageDifferencer { public: explicit MapEntryKeyComparator(MessageDifferencer* message_differencer); virtual bool IsMatch(const Message& message1, const Message& message2, - const std::vector<SpecificField>& parent_fields) const; + const std::vector<SpecificField>& parent_fields) const override; private: MessageDifferencer* message_differencer_; diff --git a/src/google/protobuf/util/message_differencer_unittest.cc b/src/google/protobuf/util/message_differencer_unittest.cc index a263d983..a263d983 100755..100644 --- a/src/google/protobuf/util/message_differencer_unittest.cc +++ b/src/google/protobuf/util/message_differencer_unittest.cc diff --git a/src/google/protobuf/util/type_resolver_util.cc b/src/google/protobuf/util/type_resolver_util.cc index a69ed58c..aa48ef60 100644 --- a/src/google/protobuf/util/type_resolver_util.cc +++ b/src/google/protobuf/util/type_resolver_util.cc @@ -60,7 +60,7 @@ class DescriptorPoolTypeResolver : public TypeResolver { const DescriptorPool* pool) : url_prefix_(url_prefix), pool_(pool) {} - Status ResolveMessageType(const string& type_url, Type* type) { + Status ResolveMessageType(const string& type_url, Type* type) override { string type_name; Status status = ParseTypeUrl(type_url, &type_name); if (!status.ok()) { @@ -75,7 +75,7 @@ class DescriptorPoolTypeResolver : public TypeResolver { return Status(); } - Status ResolveEnumType(const string& type_url, Enum* enum_type) { + Status ResolveEnumType(const string& type_url, Enum* enum_type) override { string type_name; Status status = ParseTypeUrl(type_url, &type_name); if (!status.ok()) { diff --git a/src/google/protobuf/wire_format.h b/src/google/protobuf/wire_format.h index d602d214..36f4a0bb 100644 --- a/src/google/protobuf/wire_format.h +++ b/src/google/protobuf/wire_format.h @@ -260,12 +260,12 @@ class LIBPROTOBUF_EXPORT UnknownFieldSetFieldSkipper : public FieldSkipper { public: UnknownFieldSetFieldSkipper(UnknownFieldSet* unknown_fields) : unknown_fields_(unknown_fields) {} - virtual ~UnknownFieldSetFieldSkipper() {} + virtual ~UnknownFieldSetFieldSkipper() override {} // implements FieldSkipper ----------------------------------------- - virtual bool SkipField(io::CodedInputStream* input, uint32 tag); - virtual bool SkipMessage(io::CodedInputStream* input); - virtual void SkipUnknownEnum(int field_number, int value); + virtual bool SkipField(io::CodedInputStream* input, uint32 tag) override; + virtual bool SkipMessage(io::CodedInputStream* input) override; + virtual void SkipUnknownEnum(int field_number, int value) override; protected: UnknownFieldSet* unknown_fields_; diff --git a/src/google/protobuf/wire_format_lite.h b/src/google/protobuf/wire_format_lite.h index 77eaa9a6..2244b35d 100644 --- a/src/google/protobuf/wire_format_lite.h +++ b/src/google/protobuf/wire_format_lite.h @@ -763,9 +763,9 @@ class LIBPROTOBUF_EXPORT CodedOutputStreamFieldSkipper : public FieldSkipper { virtual ~CodedOutputStreamFieldSkipper() {} // implements FieldSkipper ----------------------------------------- - virtual bool SkipField(io::CodedInputStream* input, uint32 tag); - virtual bool SkipMessage(io::CodedInputStream* input); - virtual void SkipUnknownEnum(int field_number, int value); + virtual bool SkipField(io::CodedInputStream* input, uint32 tag) override; + virtual bool SkipMessage(io::CodedInputStream* input) override; + virtual void SkipUnknownEnum(int field_number, int value) override; protected: io::CodedOutputStream* unknown_fields_; diff --git a/src/google/protobuf/wrappers.pb.cc b/src/google/protobuf/wrappers.pb.cc index ffd905f5..8f254b82 100644 --- a/src/google/protobuf/wrappers.pb.cc +++ b/src/google/protobuf/wrappers.pb.cc @@ -289,14 +289,14 @@ static ::google::protobuf::Message const * const file_default_instances[] = { reinterpret_cast<const ::google::protobuf::Message*>(&::google::protobuf::_BytesValue_default_instance_), }; -void protobuf_AssignDescriptors() { +static void protobuf_AssignDescriptors() { AddDescriptors(); AssignDescriptors( "google/protobuf/wrappers.proto", schemas, file_default_instances, TableStruct::offsets, file_level_metadata, NULL, NULL); } -void protobuf_AssignDescriptorsOnce() { +static void protobuf_AssignDescriptorsOnce() { static ::google::protobuf::internal::once_flag once; ::google::protobuf::internal::call_once(once, protobuf_AssignDescriptors); } @@ -307,7 +307,7 @@ void protobuf_RegisterTypes(const ::std::string&) { ::google::protobuf::internal::RegisterAllTypes(file_level_metadata, 9); } -void AddDescriptorsImpl() { +static void AddDescriptorsImpl() { InitDefaults(); static const char descriptor[] GOOGLE_PROTOBUF_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold) = { "\n\036google/protobuf/wrappers.proto\022\017google" @@ -391,7 +391,7 @@ void DoubleValue::ArenaDtor(void* object) { DoubleValue* _this = reinterpret_cast< DoubleValue* >(object); (void)_this; } -void DoubleValue::RegisterArenaDtor(::google::protobuf::Arena* arena) { +void DoubleValue::RegisterArenaDtor(::google::protobuf::Arena*) { } void DoubleValue::SetCachedSize(int size) const { _cached_size_.Set(size); @@ -642,7 +642,7 @@ void FloatValue::ArenaDtor(void* object) { FloatValue* _this = reinterpret_cast< FloatValue* >(object); (void)_this; } -void FloatValue::RegisterArenaDtor(::google::protobuf::Arena* arena) { +void FloatValue::RegisterArenaDtor(::google::protobuf::Arena*) { } void FloatValue::SetCachedSize(int size) const { _cached_size_.Set(size); @@ -893,7 +893,7 @@ void Int64Value::ArenaDtor(void* object) { Int64Value* _this = reinterpret_cast< Int64Value* >(object); (void)_this; } -void Int64Value::RegisterArenaDtor(::google::protobuf::Arena* arena) { +void Int64Value::RegisterArenaDtor(::google::protobuf::Arena*) { } void Int64Value::SetCachedSize(int size) const { _cached_size_.Set(size); @@ -1146,7 +1146,7 @@ void UInt64Value::ArenaDtor(void* object) { UInt64Value* _this = reinterpret_cast< UInt64Value* >(object); (void)_this; } -void UInt64Value::RegisterArenaDtor(::google::protobuf::Arena* arena) { +void UInt64Value::RegisterArenaDtor(::google::protobuf::Arena*) { } void UInt64Value::SetCachedSize(int size) const { _cached_size_.Set(size); @@ -1399,7 +1399,7 @@ void Int32Value::ArenaDtor(void* object) { Int32Value* _this = reinterpret_cast< Int32Value* >(object); (void)_this; } -void Int32Value::RegisterArenaDtor(::google::protobuf::Arena* arena) { +void Int32Value::RegisterArenaDtor(::google::protobuf::Arena*) { } void Int32Value::SetCachedSize(int size) const { _cached_size_.Set(size); @@ -1652,7 +1652,7 @@ void UInt32Value::ArenaDtor(void* object) { UInt32Value* _this = reinterpret_cast< UInt32Value* >(object); (void)_this; } -void UInt32Value::RegisterArenaDtor(::google::protobuf::Arena* arena) { +void UInt32Value::RegisterArenaDtor(::google::protobuf::Arena*) { } void UInt32Value::SetCachedSize(int size) const { _cached_size_.Set(size); @@ -1905,7 +1905,7 @@ void BoolValue::ArenaDtor(void* object) { BoolValue* _this = reinterpret_cast< BoolValue* >(object); (void)_this; } -void BoolValue::RegisterArenaDtor(::google::protobuf::Arena* arena) { +void BoolValue::RegisterArenaDtor(::google::protobuf::Arena*) { } void BoolValue::SetCachedSize(int size) const { _cached_size_.Set(size); @@ -2161,7 +2161,7 @@ void StringValue::ArenaDtor(void* object) { StringValue* _this = reinterpret_cast< StringValue* >(object); (void)_this; } -void StringValue::RegisterArenaDtor(::google::protobuf::Arena* arena) { +void StringValue::RegisterArenaDtor(::google::protobuf::Arena*) { } void StringValue::SetCachedSize(int size) const { _cached_size_.Set(size); @@ -2433,7 +2433,7 @@ void BytesValue::ArenaDtor(void* object) { BytesValue* _this = reinterpret_cast< BytesValue* >(object); (void)_this; } -void BytesValue::RegisterArenaDtor(::google::protobuf::Arena* arena) { +void BytesValue::RegisterArenaDtor(::google::protobuf::Arena*) { } void BytesValue::SetCachedSize(int size) const { _cached_size_.Set(size); @@ -507,18 +507,21 @@ build_php7.1() { phpunit popd pushd conformance - # TODO(teboring): Add it back - # make test_php + make test_php popd } build_php7.1_c() { + ENABLE_CONFORMANCE_TEST=$1 use_php 7.1 wget https://phar.phpunit.de/phpunit-5.6.0.phar -O /usr/bin/phpunit cd php/tests && /bin/bash ./test.sh 7.1 && cd ../.. - pushd conformance - # make test_php_c - popd + if [ "$ENABLE_CONFORMANCE_TEST" = "true" ] + then + pushd conformance + make test_php_c + popd + fi } build_php7.1_zts_c() { @@ -538,7 +541,7 @@ build_php_all_32() { build_php5.5_c build_php5.6_c build_php7.0_c - build_php7.1_c + build_php7.1_c $1 build_php5.5_zts_c build_php5.6_zts_c build_php7.0_zts_c @@ -546,7 +549,7 @@ build_php_all_32() { } build_php_all() { - build_php_all_32 + build_php_all_32 true build_php_compatibility } |