Squashed 'libs/protobuf/' content from commit fcd3b9a85
git-subtree-dir: libs/protobuf git-subtree-split: fcd3b9a85ef36e46643dc30176cea1a7ad62e02b
This commit is contained in:
4
.bazelignore
Normal file
4
.bazelignore
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
# These are fetched as external repositories.
|
||||||
|
third_party/abseil-cpp
|
||||||
|
third_party/googletest
|
||||||
|
_build/
|
||||||
35
.bazelrc
Normal file
35
.bazelrc
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
build --cxxopt=-std=c++14 --host_cxxopt=-std=c++14
|
||||||
|
|
||||||
|
build:dbg --compilation_mode=dbg
|
||||||
|
|
||||||
|
build:opt --compilation_mode=opt
|
||||||
|
|
||||||
|
build:san-common --config=dbg --strip=never --copt=-O0 --copt=-fno-omit-frame-pointer
|
||||||
|
|
||||||
|
build:asan --config=san-common --copt=-fsanitize=address --linkopt=-fsanitize=address
|
||||||
|
build:asan --copt=-DADDRESS_SANITIZER=1
|
||||||
|
# ASAN hits ODR violations with shared linkage due to rules_proto.
|
||||||
|
build:asan --dynamic_mode=off
|
||||||
|
|
||||||
|
build:msan --config=san-common --copt=-fsanitize=memory --linkopt=-fsanitize=memory
|
||||||
|
build:msan --copt=-fsanitize-memory-track-origins
|
||||||
|
build:msan --copt=-fsanitize-memory-use-after-dtor
|
||||||
|
build:msan --action_env=MSAN_OPTIONS=poison_in_dtor=1
|
||||||
|
build:msan --copt=-DMEMORY_SANITIZER=1
|
||||||
|
|
||||||
|
# Use our instrumented LLVM libc++ in Kokoro.
|
||||||
|
build:kokoro-msan --config=msan
|
||||||
|
build:kokoro-msan --linkopt=-L/opt/libcxx_msan/lib
|
||||||
|
build:kokoro-msan --linkopt=-Wl,-rpath,/opt/libcxx_msan/lib
|
||||||
|
build:kokoro-msan --cxxopt=-stdlib=libc++ --linkopt=-stdlib=libc++
|
||||||
|
|
||||||
|
|
||||||
|
build:tsan --config=san-common --copt=-fsanitize=thread --linkopt=-fsanitize=thread
|
||||||
|
build:tsan --copt=-DTHREAD_SANITIZER=1
|
||||||
|
|
||||||
|
build:ubsan --config=san-common --copt=-fsanitize=undefined --linkopt=-fsanitize=undefined
|
||||||
|
build:ubsan --action_env=UBSAN_OPTIONS=halt_on_error=1:print_stacktrace=1
|
||||||
|
build:ubsan --copt=-DUNDEFINED_SANITIZER=1
|
||||||
|
# Workaround for the fact that Bazel links with $CC, not $CXX
|
||||||
|
# https://github.com/bazelbuild/bazel/issues/11122#issuecomment-613746748
|
||||||
|
build:ubsan --copt=-fno-sanitize=function --copt=-fno-sanitize=vptr
|
||||||
39
.github/ISSUE_TEMPLATE/bug_report.md
vendored
Normal file
39
.github/ISSUE_TEMPLATE/bug_report.md
vendored
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
---
|
||||||
|
name: Bug report
|
||||||
|
about: Create a report to help us improve
|
||||||
|
title: ''
|
||||||
|
labels: 'untriaged'
|
||||||
|
assignees: ''
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
<!--
|
||||||
|
|
||||||
|
NOTE: this form is for bug reports only.
|
||||||
|
For questions or troubleshooting, please post on the protobuf mailing list:
|
||||||
|
https://groups.google.com/forum/#!forum/protobuf
|
||||||
|
Stack Overflow is also a useful if unofficial resource https://stackoverflow.com/questions/tagged/protocol-buffers
|
||||||
|
-->
|
||||||
|
|
||||||
|
**What version of protobuf and what language are you using?**
|
||||||
|
Version: main/v3.6.0/v3.5.0 etc. (NOTE: please try updating to the latest version of protoc/runtime possible beforehand to attempt to resolve your problem)
|
||||||
|
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**
|
||||||
28
.github/ISSUE_TEMPLATE/feature_request.md
vendored
Normal file
28
.github/ISSUE_TEMPLATE/feature_request.md
vendored
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
---
|
||||||
|
name: Feature request
|
||||||
|
about: Suggest an idea for this project
|
||||||
|
title: ''
|
||||||
|
labels: 'untriaged'
|
||||||
|
assignees: ''
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
<!--
|
||||||
|
|
||||||
|
NOTE: this form is for feature requests (including cleanup requests) only. For questions or troubleshooting, please see the protobuf mailing list: https://groups.google.com/forum/#!forum/protobuf
|
||||||
|
|
||||||
|
-->
|
||||||
|
|
||||||
|
|
||||||
|
**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.
|
||||||
18
.github/mergeable.yml
vendored
Normal file
18
.github/mergeable.yml
vendored
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
mergeable:
|
||||||
|
pull_requests:
|
||||||
|
label:
|
||||||
|
and:
|
||||||
|
- must_exclude:
|
||||||
|
regex: '^disposition/DO NOT MERGE'
|
||||||
|
message: 'Pull request marked not mergeable'
|
||||||
|
- or:
|
||||||
|
- and:
|
||||||
|
- must_include:
|
||||||
|
regex: 'release notes: yes'
|
||||||
|
message: 'Include release notes: yes'
|
||||||
|
- must_include:
|
||||||
|
regex: '^(autotools|bazel|c#|c\+\+|cleanup|cmake|conformance tests|integration|go|java|javascript|objective-c|php|protoc|python|ruby|kotlin)'
|
||||||
|
message: 'at least a language label (e.g., c++, java, python). Or apply one of the following labels: autotools, bazel, cmake, cleanup, conformance tests, integration, protoc.'
|
||||||
|
- must_include:
|
||||||
|
regex: 'release notes: no'
|
||||||
|
message: 'Include release notes: no'
|
||||||
16
.github/workflows/codespell.yml
vendored
Normal file
16
.github/workflows/codespell.yml
vendored
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
# GitHub Action to automate the identification of common misspellings in text files.
|
||||||
|
# https://github.com/codespell-project/actions-codespell
|
||||||
|
# https://github.com/codespell-project/codespell
|
||||||
|
name: codespell
|
||||||
|
on: [push, pull_request]
|
||||||
|
jobs:
|
||||||
|
codespell:
|
||||||
|
name: Check for spelling errors
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
- uses: codespell-project/actions-codespell@master
|
||||||
|
with:
|
||||||
|
check_filenames: true
|
||||||
|
skip: ./.git,./conformance/third_party,*.snk,*.pb,*.pb.cc,*.pb.h,./src/google/protobuf/testdata,./objectivec/Tests,./python/compatibility_tests/v2.5.0/tests/google/protobuf/internal,./.github/workflows/codespell.yml
|
||||||
|
ignore_words_list: "alow,alse,ba,chec,cleare,copyable,cloneable,dedup,dur,errorprone,falsy,files',fo,fundementals,hel,importd,inout,leapyear,nd,nin,ois,ons,parseable,process',ro,te,testof,ue,unparseable,wasn,wee,gae,keyserver,objext,od,optin,streem,sur,falsy"
|
||||||
29
.github/workflows/generated_cmake.yml
vendored
Normal file
29
.github/workflows/generated_cmake.yml
vendored
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
name: Generate CMake File Lists
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- main
|
||||||
|
- '[0-9]+.x'
|
||||||
|
# The 21.x branch predates support for auto-generation of the CMake file
|
||||||
|
# lists, so we make sure to exclude it.
|
||||||
|
- '!21.x'
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
cmake:
|
||||||
|
if: github.repository == 'protocolbuffers/protobuf'
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
|
strategy:
|
||||||
|
fail-fast: false # Don't cancel all jobs if one fails.
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v3
|
||||||
|
with:
|
||||||
|
# Note: this token has an expiration date, so if the workflow starts
|
||||||
|
# failing then you may need to generate a fresh token.
|
||||||
|
token: ${{ secrets.BOT_ACCESS_TOKEN }}
|
||||||
|
- name: Configure name and email address in Git
|
||||||
|
run: cd ${{ github.workspace }} && git config user.name "Protobuf Team Bot" && git config user.email "protobuf-team-bot@google.com"
|
||||||
|
- name: Commit and push update
|
||||||
|
run: cd ${{ github.workspace }} && ./cmake/push_auto_update.sh
|
||||||
36
.github/workflows/objc_cocoapods.yml
vendored
Normal file
36
.github/workflows/objc_cocoapods.yml
vendored
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
name: 'ObjC CocoaPods'
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
paths:
|
||||||
|
- '.github/workflows/objc_cocoapods.yml'
|
||||||
|
- 'Protobuf.podspec'
|
||||||
|
- 'objectivec/**'
|
||||||
|
- '!objectivec/DevTools/**'
|
||||||
|
- '!objectivec/ProtocolBuffers_*.xcodeproj/**'
|
||||||
|
- '!objectivec/Tests/**'
|
||||||
|
pull_request:
|
||||||
|
paths:
|
||||||
|
- '.github/workflows/objc_cocoapods.yml'
|
||||||
|
- 'Protobuf.podspec'
|
||||||
|
- 'objectivec/**'
|
||||||
|
- '!objectivec/DevTools/**'
|
||||||
|
- '!objectivec/ProtocolBuffers_*.xcodeproj/**'
|
||||||
|
- '!objectivec/Tests/**'
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
pod-lib-lint:
|
||||||
|
runs-on: macos-latest
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
PLATFORM: ["ios", "macos", "tvos", "watchos"]
|
||||||
|
CONFIGURATION: ["Debug", "Release"]
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
- name: Pod lib lint
|
||||||
|
run: |
|
||||||
|
pod lib lint --verbose \
|
||||||
|
--configuration=${{ matrix.CONFIGURATION }} \
|
||||||
|
--platforms=${{ matrix.PLATFORM }} \
|
||||||
|
Protobuf.podspec
|
||||||
43
.github/workflows/php-ext.yml
vendored
Normal file
43
.github/workflows/php-ext.yml
vendored
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
name: PHP extension
|
||||||
|
|
||||||
|
on:
|
||||||
|
- push
|
||||||
|
- pull_request
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build-php:
|
||||||
|
name: Build PHP extension
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
container: ${{ matrix.php-image }}
|
||||||
|
strategy:
|
||||||
|
matrix:
|
||||||
|
php-image:
|
||||||
|
- php:7.4-cli
|
||||||
|
- php:8.1-cli
|
||||||
|
steps:
|
||||||
|
- name: Install git
|
||||||
|
run: |
|
||||||
|
apt-get update -q
|
||||||
|
apt-get install -qy --no-install-recommends git
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v3
|
||||||
|
with:
|
||||||
|
submodules: recursive
|
||||||
|
- name: Prepare source code
|
||||||
|
run: |
|
||||||
|
rm -rf "$GITHUB_WORKSPACE/php/ext/google/protobuf/third_party"
|
||||||
|
cp -r "$GITHUB_WORKSPACE/third_party" "$GITHUB_WORKSPACE/php/ext/google/protobuf"
|
||||||
|
cp "$GITHUB_WORKSPACE/LICENSE" "$GITHUB_WORKSPACE/php/ext/google/protobuf"
|
||||||
|
- name: Create package
|
||||||
|
run: |
|
||||||
|
cd /tmp
|
||||||
|
rm -rf protobuf-*.tgz
|
||||||
|
pecl package "$GITHUB_WORKSPACE/php/ext/google/protobuf/package.xml"
|
||||||
|
- name: Compile extension
|
||||||
|
run: |
|
||||||
|
cd /tmp
|
||||||
|
MAKE="make -j$(nproc)" pecl install protobuf-*.tgz
|
||||||
|
- name: Enable extension
|
||||||
|
run: docker-php-ext-enable protobuf
|
||||||
|
- name: Inspect extension
|
||||||
|
run: php --ri protobuf
|
||||||
210
.gitignore
vendored
Normal file
210
.gitignore
vendored
Normal file
@@ -0,0 +1,210 @@
|
|||||||
|
# CMake-generated files
|
||||||
|
.ninja_deps
|
||||||
|
.ninja_logs
|
||||||
|
cmake/protobuf/*.cmake
|
||||||
|
cmake_install.cmake
|
||||||
|
CMakeCache.txt
|
||||||
|
CTestTestfile.cmake
|
||||||
|
CMakeFiles/*
|
||||||
|
Testing/Temporary/*
|
||||||
|
|
||||||
|
/core
|
||||||
|
/protoc
|
||||||
|
/test_plugin
|
||||||
|
/tests
|
||||||
|
/lite-test
|
||||||
|
/protoc-*.*
|
||||||
|
|
||||||
|
# downloaded files
|
||||||
|
/gmock
|
||||||
|
|
||||||
|
# in-tree configure-generated files
|
||||||
|
/config.h
|
||||||
|
config.log
|
||||||
|
config.status
|
||||||
|
|
||||||
|
libtool
|
||||||
|
protobuf-lite.pc
|
||||||
|
protobuf.pc
|
||||||
|
.deps
|
||||||
|
stamp-h1
|
||||||
|
|
||||||
|
# in-tree build products
|
||||||
|
*.o
|
||||||
|
*.lo
|
||||||
|
*.la
|
||||||
|
*.so
|
||||||
|
*.a
|
||||||
|
|
||||||
|
.dirstamp
|
||||||
|
|
||||||
|
any_test.pb.*
|
||||||
|
map*unittest.pb.*
|
||||||
|
unittest*.pb.*
|
||||||
|
src/google/protobuf/compiler/cpp/test*.pb.*
|
||||||
|
src/google/protobuf/util/**/*.pb.cc
|
||||||
|
src/google/protobuf/util/**/*.pb.h
|
||||||
|
|
||||||
|
*.pyc
|
||||||
|
*.egg-info
|
||||||
|
*_pb2.py
|
||||||
|
python/**/*.egg
|
||||||
|
python/.eggs/
|
||||||
|
python/.tox
|
||||||
|
python/build/
|
||||||
|
python/docs/_build/
|
||||||
|
|
||||||
|
src/js_embed
|
||||||
|
|
||||||
|
# vim generated
|
||||||
|
*.swp
|
||||||
|
|
||||||
|
# Generated test scaffolding
|
||||||
|
src/no_warning_test.cc
|
||||||
|
src/no-warning-test
|
||||||
|
src/protobuf*-test
|
||||||
|
src/test_plugin
|
||||||
|
src/testzip.*
|
||||||
|
src/zcg*zip
|
||||||
|
ar-lib
|
||||||
|
|
||||||
|
test-driver
|
||||||
|
compile
|
||||||
|
|
||||||
|
src/**/*.log
|
||||||
|
src/**/*.trs
|
||||||
|
|
||||||
|
# JavaBuild output.
|
||||||
|
java/**/target
|
||||||
|
java/.idea
|
||||||
|
java/**/*.iml
|
||||||
|
|
||||||
|
# Windows native output.
|
||||||
|
cmake/build
|
||||||
|
build_msvc
|
||||||
|
# Directories suggested by cmake/README.md
|
||||||
|
/debug/
|
||||||
|
/solution/
|
||||||
|
/release/
|
||||||
|
|
||||||
|
# NuGet packages: we want the repository configuration, but not the
|
||||||
|
# packages themselves.
|
||||||
|
/csharp/src/packages/*/
|
||||||
|
|
||||||
|
# OS X's Finder creates these for state about opened windows/etc.
|
||||||
|
**/.DS_Store
|
||||||
|
|
||||||
|
# Cocoapods artifacts
|
||||||
|
# Podfile.lock and the workspace file are tracked, to ease deleting them. That's
|
||||||
|
# needed to trigger "pod install" to rerun the preinstall commands.
|
||||||
|
Pods/
|
||||||
|
|
||||||
|
# Conformance test output
|
||||||
|
conformance/.libs/
|
||||||
|
conformance/com/
|
||||||
|
conformance/conformance-cpp
|
||||||
|
conformance/conformance-csharp
|
||||||
|
conformance/conformance-java
|
||||||
|
conformance/conformance-objc
|
||||||
|
conformance/conformance-test-runner
|
||||||
|
conformance/conformance.pb.cc
|
||||||
|
conformance/conformance.pb.h
|
||||||
|
conformance/Conformance.pbobjc.h
|
||||||
|
conformance/Conformance.pbobjc.m
|
||||||
|
conformance/conformance_pb.js
|
||||||
|
conformance/conformance_pb.rb
|
||||||
|
conformance/core
|
||||||
|
conformance/failing_tests.txt
|
||||||
|
conformance/google/
|
||||||
|
conformance/google-protobuf/
|
||||||
|
conformance/javac_middleman
|
||||||
|
conformance/lite/
|
||||||
|
conformance/nonexistent_tests.txt
|
||||||
|
conformance/protoc_middleman
|
||||||
|
conformance/succeeding_tests.txt
|
||||||
|
conformance/Conformance/
|
||||||
|
conformance/GPBMetadata/
|
||||||
|
conformance/Google/
|
||||||
|
conformance/Protobuf_test_messages/
|
||||||
|
conformance/conformance-php
|
||||||
|
conformance/conformance-php-c
|
||||||
|
conformance/*.class
|
||||||
|
|
||||||
|
# php test output
|
||||||
|
composer.lock
|
||||||
|
php/.phpunit.result.cache
|
||||||
|
php/tests/.phpunit.result.cache
|
||||||
|
php/tests/generated/
|
||||||
|
php/tests/old_protoc
|
||||||
|
php/tests/phpunit-9.phar
|
||||||
|
php/tests/protobuf/
|
||||||
|
php/tests/core
|
||||||
|
php/tests/vgcore*
|
||||||
|
php/tests/multirequest.result
|
||||||
|
php/tests/nohup.out
|
||||||
|
php/tests/.phpunit.result.cache
|
||||||
|
php/tests/phpunit-*
|
||||||
|
php/ext/google/protobuf/.libs/
|
||||||
|
php/ext/google/protobuf/Makefile.fragments
|
||||||
|
php/ext/google/protobuf/Makefile.global
|
||||||
|
php/ext/google/protobuf/Makefile.objects
|
||||||
|
php/ext/google/protobuf/acinclude.m4
|
||||||
|
php/ext/google/protobuf/build/
|
||||||
|
php/ext/google/protobuf/bundled_php.c
|
||||||
|
php/ext/google/protobuf/config.h
|
||||||
|
php/ext/google/protobuf/config.h.in~
|
||||||
|
php/ext/google/protobuf/config.nice
|
||||||
|
php/ext/google/protobuf/configure.ac
|
||||||
|
php/ext/google/protobuf/configure.in
|
||||||
|
php/ext/google/protobuf/mkinstalldirs
|
||||||
|
php/ext/google/protobuf/run-tests.php
|
||||||
|
php/ext/google/protobuf/third_party/
|
||||||
|
vendor/
|
||||||
|
|
||||||
|
# Ignore the bazel symlinks
|
||||||
|
/bazel-*
|
||||||
|
|
||||||
|
# ruby test output
|
||||||
|
ruby/tests/basic_test_pb.rb
|
||||||
|
ruby/tests/basic_test_proto2_pb.rb
|
||||||
|
ruby/tests/generated_code_pb.rb
|
||||||
|
ruby/tests/test_import_pb.rb
|
||||||
|
ruby/tests/test_ruby_package_pb.rb
|
||||||
|
ruby/tests/generated_code_proto2_pb.rb
|
||||||
|
ruby/tests/multi_level_nesting_test_pb.rb
|
||||||
|
ruby/tests/test_import_proto2_pb.rb
|
||||||
|
ruby/tests/test_ruby_package_proto2_pb.rb
|
||||||
|
ruby/Gemfile.lock
|
||||||
|
ruby/compatibility_tests/v3.0.0/protoc
|
||||||
|
ruby/compatibility_tests/v3.0.0/tests/generated_code_pb.rb
|
||||||
|
ruby/compatibility_tests/v3.0.0/tests/test_import_pb.rb
|
||||||
|
|
||||||
|
# IntelliJ CLion Config files and build output
|
||||||
|
cmake/.idea
|
||||||
|
cmake/cmake-build-debug/
|
||||||
|
|
||||||
|
# Common build subdirectories.
|
||||||
|
.build/
|
||||||
|
_build/
|
||||||
|
|
||||||
|
# Visual Studio 2017
|
||||||
|
.vs
|
||||||
|
|
||||||
|
# Visual Studio Code
|
||||||
|
/.vscode/
|
||||||
|
|
||||||
|
# IntelliJ
|
||||||
|
.idea
|
||||||
|
*.iml
|
||||||
|
|
||||||
|
# Eclipse
|
||||||
|
**/.settings
|
||||||
|
**/.project
|
||||||
|
**/.classpath
|
||||||
|
|
||||||
|
# BenchmarkDotNet
|
||||||
|
BenchmarkDotNet.Artifacts/
|
||||||
|
|
||||||
|
# Clangd uses these common ephemeral files
|
||||||
|
.cache
|
||||||
|
compile_commands.json
|
||||||
14
.gitmodules
vendored
Normal file
14
.gitmodules
vendored
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
[submodule "third_party/googletest"]
|
||||||
|
path = third_party/googletest
|
||||||
|
url = https://github.com/google/googletest.git
|
||||||
|
ignore = dirty
|
||||||
|
[submodule "third_party/abseil-cpp"]
|
||||||
|
path = third_party/abseil-cpp
|
||||||
|
url = https://github.com/abseil/abseil-cpp.git
|
||||||
|
branch = lts_2022_06_23
|
||||||
|
[submodule "third_party/jsoncpp"]
|
||||||
|
path = third_party/jsoncpp
|
||||||
|
url = https://github.com/open-source-parsers/jsoncpp.git
|
||||||
|
[submodule "third_party/utf8_range"]
|
||||||
|
path = third_party/utf8_range
|
||||||
|
url = https://github.com/protocolbuffers/utf8_range.git
|
||||||
22
.readthedocs.yml
Normal file
22
.readthedocs.yml
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
# .readthedocs.yml
|
||||||
|
# Read the Docs configuration file
|
||||||
|
# See https://docs.readthedocs.io/en/stable/config-file/v2.html for details
|
||||||
|
|
||||||
|
# Required
|
||||||
|
version: 2
|
||||||
|
|
||||||
|
sphinx:
|
||||||
|
configuration: python/docs/conf.py
|
||||||
|
fail_on_warning: false
|
||||||
|
|
||||||
|
# Setup build requirements for docs.
|
||||||
|
# Use conda so that we can install the latest libprotobuf package without
|
||||||
|
# having to build from scratch just for docs builds.
|
||||||
|
conda:
|
||||||
|
environment: python/docs/environment.yml
|
||||||
|
|
||||||
|
python:
|
||||||
|
version: 3.7
|
||||||
|
install:
|
||||||
|
- method: setuptools
|
||||||
|
path: python
|
||||||
580
BUILD.bazel
Normal file
580
BUILD.bazel
Normal file
@@ -0,0 +1,580 @@
|
|||||||
|
# Bazel (https://bazel.build/) BUILD file for Protobuf.
|
||||||
|
|
||||||
|
load("@rules_cc//cc:defs.bzl", "cc_binary", "cc_library", "cc_proto_library")
|
||||||
|
load("@rules_pkg//:mappings.bzl", "pkg_files", "strip_prefix")
|
||||||
|
load("@rules_proto//proto:defs.bzl", "proto_lang_toolchain", "proto_library")
|
||||||
|
load("@rules_java//java:defs.bzl", "java_lite_proto_library", "java_proto_library")
|
||||||
|
load("//build_defs:cpp_opts.bzl", "COPTS", "LINK_OPTS", "PROTOC_LINK_OPTS")
|
||||||
|
load(":protobuf.bzl", "internal_objc_proto_library", "internal_php_proto_library", "internal_py_proto_library", "internal_ruby_proto_library")
|
||||||
|
|
||||||
|
licenses(["notice"])
|
||||||
|
|
||||||
|
exports_files(["LICENSE"])
|
||||||
|
|
||||||
|
################################################################################
|
||||||
|
# Well Known Types Proto Library Rules
|
||||||
|
#
|
||||||
|
# https://developers.google.com/protocol-buffers/docs/reference/google.protobuf
|
||||||
|
################################################################################
|
||||||
|
# These proto_library rules can be used with one of the language specific proto
|
||||||
|
# library rules i.e. java_proto_library:
|
||||||
|
#
|
||||||
|
# java_proto_library(
|
||||||
|
# name = "any_java_proto",
|
||||||
|
# deps = ["@com_google_protobuf//:any_proto"],
|
||||||
|
# )
|
||||||
|
################################################################################
|
||||||
|
|
||||||
|
alias(
|
||||||
|
name = "any_proto",
|
||||||
|
actual = "//src/google/protobuf:any_proto",
|
||||||
|
visibility = ["//visibility:public"],
|
||||||
|
)
|
||||||
|
|
||||||
|
alias(
|
||||||
|
name = "api_proto",
|
||||||
|
actual = "//src/google/protobuf:api_proto",
|
||||||
|
visibility = ["//visibility:public"],
|
||||||
|
)
|
||||||
|
|
||||||
|
alias(
|
||||||
|
name = "duration_proto",
|
||||||
|
actual = "//src/google/protobuf:duration_proto",
|
||||||
|
visibility = ["//visibility:public"],
|
||||||
|
)
|
||||||
|
|
||||||
|
alias(
|
||||||
|
name = "empty_proto",
|
||||||
|
actual = "//src/google/protobuf:empty_proto",
|
||||||
|
visibility = ["//visibility:public"],
|
||||||
|
)
|
||||||
|
|
||||||
|
alias(
|
||||||
|
name = "field_mask_proto",
|
||||||
|
actual = "//src/google/protobuf:field_mask_proto",
|
||||||
|
visibility = ["//visibility:public"],
|
||||||
|
)
|
||||||
|
|
||||||
|
alias(
|
||||||
|
name = "source_context_proto",
|
||||||
|
actual = "//src/google/protobuf:source_context_proto",
|
||||||
|
visibility = ["//visibility:public"],
|
||||||
|
)
|
||||||
|
|
||||||
|
alias(
|
||||||
|
name = "struct_proto",
|
||||||
|
actual = "//src/google/protobuf:struct_proto",
|
||||||
|
visibility = ["//visibility:public"],
|
||||||
|
)
|
||||||
|
|
||||||
|
alias(
|
||||||
|
name = "timestamp_proto",
|
||||||
|
actual = "//src/google/protobuf:timestamp_proto",
|
||||||
|
visibility = ["//visibility:public"],
|
||||||
|
)
|
||||||
|
|
||||||
|
alias(
|
||||||
|
name = "type_proto",
|
||||||
|
actual = "//src/google/protobuf:type_proto",
|
||||||
|
visibility = ["//visibility:public"],
|
||||||
|
)
|
||||||
|
|
||||||
|
alias(
|
||||||
|
name = "wrappers_proto",
|
||||||
|
actual = "//src/google/protobuf:wrappers_proto",
|
||||||
|
visibility = ["//visibility:public"],
|
||||||
|
)
|
||||||
|
|
||||||
|
# Source files: these are aliases to a filegroup, not a `proto_library`.
|
||||||
|
#
|
||||||
|
# (This is _probably_ not what you want.)
|
||||||
|
alias(
|
||||||
|
name = "lite_well_known_protos",
|
||||||
|
actual = "//src/google/protobuf:well_known_type_protos", # filegroup
|
||||||
|
visibility = ["//visibility:public"],
|
||||||
|
)
|
||||||
|
|
||||||
|
alias(
|
||||||
|
name = "well_known_type_protos",
|
||||||
|
actual = "//src/google/protobuf:well_known_type_protos", # filegroup
|
||||||
|
visibility = ["//visibility:public"],
|
||||||
|
)
|
||||||
|
|
||||||
|
# Built-in runtime protos: these are part of protobuf's internal
|
||||||
|
# implementation, but are not Well-Known Types.
|
||||||
|
|
||||||
|
alias(
|
||||||
|
name = "descriptor_proto",
|
||||||
|
actual = "//src/google/protobuf:descriptor_proto", # proto_library
|
||||||
|
visibility = ["//visibility:public"],
|
||||||
|
)
|
||||||
|
|
||||||
|
alias(
|
||||||
|
name = "descriptor_proto_srcs",
|
||||||
|
actual = "//src/google/protobuf:descriptor_proto_srcs", # filegroup
|
||||||
|
visibility = ["//visibility:public"],
|
||||||
|
)
|
||||||
|
|
||||||
|
alias(
|
||||||
|
name = "compiler_plugin_proto",
|
||||||
|
actual = "//src/google/protobuf/compiler:plugin_proto", # proto_library
|
||||||
|
visibility = ["//visibility:public"],
|
||||||
|
)
|
||||||
|
|
||||||
|
cc_library(
|
||||||
|
name = "cc_wkt_protos",
|
||||||
|
deprecation = "Only for backward compatibility. Do not use.",
|
||||||
|
visibility = ["//visibility:public"],
|
||||||
|
)
|
||||||
|
|
||||||
|
# Source protos that are typically part of the protobuf runtime.
|
||||||
|
#
|
||||||
|
# DEPRECATED: Prefer :well_known_type_protos for the Well-Known Types
|
||||||
|
# (https://developers.google.com/protocol-buffers/docs/reference/google.protobuf)
|
||||||
|
# or :descriptor_proto(_srcs) for descriptor.proto (source), or
|
||||||
|
# :compiler_plugin_proto for compiler/plugin.proto.
|
||||||
|
filegroup(
|
||||||
|
name = "well_known_protos",
|
||||||
|
srcs = [
|
||||||
|
":descriptor_proto_srcs",
|
||||||
|
":well_known_type_protos",
|
||||||
|
"//src/google/protobuf/compiler:plugin.proto",
|
||||||
|
],
|
||||||
|
deprecation = "Prefer :well_known_type_protos instead.",
|
||||||
|
visibility = ["//visibility:public"],
|
||||||
|
)
|
||||||
|
|
||||||
|
internal_ruby_proto_library(
|
||||||
|
name = "well_known_ruby_protos",
|
||||||
|
srcs = [":well_known_protos"],
|
||||||
|
includes = ["src"],
|
||||||
|
visibility = [
|
||||||
|
"//conformance:__pkg__",
|
||||||
|
"//ruby:__subpackages__",
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
|
################################################################################
|
||||||
|
# Protocol Buffers Compiler
|
||||||
|
################################################################################
|
||||||
|
|
||||||
|
cc_binary(
|
||||||
|
name = "protoc",
|
||||||
|
copts = COPTS,
|
||||||
|
linkopts = LINK_OPTS + PROTOC_LINK_OPTS,
|
||||||
|
visibility = ["//visibility:public"],
|
||||||
|
deps = ["//src/google/protobuf/compiler:protoc_lib"],
|
||||||
|
)
|
||||||
|
|
||||||
|
################################################################################
|
||||||
|
# C++ runtime
|
||||||
|
################################################################################
|
||||||
|
|
||||||
|
# The "lite" runtime works for .proto files that specify the option:
|
||||||
|
# optimize_for = LITE_RUNTIME;
|
||||||
|
#
|
||||||
|
# The lite runtime does not include the `Reflection` APIs (including
|
||||||
|
# `Descriptor` and related types) or Well-Known Types.
|
||||||
|
#
|
||||||
|
# See also:
|
||||||
|
# https://developers.google.com/protocol-buffers/docs/reference/cpp-generated#message
|
||||||
|
# https://developers.google.com/protocol-buffers/docs/reference/google.protobuf
|
||||||
|
alias(
|
||||||
|
name = "protobuf_lite",
|
||||||
|
actual = "//src/google/protobuf:protobuf_lite",
|
||||||
|
visibility = ["//visibility:public"],
|
||||||
|
)
|
||||||
|
|
||||||
|
cc_library(
|
||||||
|
name = "protobuf",
|
||||||
|
hdrs = glob([
|
||||||
|
"src/**/*.h",
|
||||||
|
"src/**/*.inc",
|
||||||
|
]),
|
||||||
|
copts = COPTS,
|
||||||
|
include_prefix = "google/protobuf/io",
|
||||||
|
linkopts = LINK_OPTS,
|
||||||
|
visibility = ["//visibility:public"],
|
||||||
|
deps = [
|
||||||
|
"//src/google/protobuf",
|
||||||
|
"//src/google/protobuf/compiler:importer",
|
||||||
|
"//src/google/protobuf/util:delimited_message_util",
|
||||||
|
"//src/google/protobuf/util:differencer",
|
||||||
|
"//src/google/protobuf/util:field_mask_util",
|
||||||
|
"//src/google/protobuf/util:json_util",
|
||||||
|
"//src/google/protobuf/util:time_util",
|
||||||
|
"//src/google/protobuf/util:type_resolver_util",
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
|
# This provides just the header files for use in projects that need to build
|
||||||
|
# shared libraries for dynamic loading. This target is available until Bazel
|
||||||
|
# adds native support for such use cases.
|
||||||
|
# TODO(keveman): Remove this target once the support gets added to Bazel.
|
||||||
|
alias(
|
||||||
|
name = "protobuf_headers",
|
||||||
|
actual = "//src/google/protobuf:protobuf_headers",
|
||||||
|
visibility = ["//visibility:public"],
|
||||||
|
)
|
||||||
|
|
||||||
|
alias(
|
||||||
|
name = "json",
|
||||||
|
actual = "//src/google/protobuf/json",
|
||||||
|
visibility = ["//visibility:public"],
|
||||||
|
)
|
||||||
|
|
||||||
|
################################################################################
|
||||||
|
# Java support
|
||||||
|
################################################################################
|
||||||
|
|
||||||
|
alias(
|
||||||
|
name = "protobuf_java",
|
||||||
|
actual = "//java/core",
|
||||||
|
visibility = ["//visibility:public"],
|
||||||
|
)
|
||||||
|
|
||||||
|
alias(
|
||||||
|
name = "protobuf_javalite",
|
||||||
|
actual = "//java/lite",
|
||||||
|
visibility = ["//visibility:public"],
|
||||||
|
)
|
||||||
|
|
||||||
|
alias(
|
||||||
|
name = "protobuf_java_util",
|
||||||
|
actual = "//java/util",
|
||||||
|
visibility = ["//visibility:public"],
|
||||||
|
)
|
||||||
|
|
||||||
|
alias(
|
||||||
|
name = "java_toolchain",
|
||||||
|
actual = "//java/core:toolchain",
|
||||||
|
visibility = ["//visibility:public"],
|
||||||
|
)
|
||||||
|
|
||||||
|
alias(
|
||||||
|
name = "javalite_toolchain",
|
||||||
|
actual = "//java/lite:toolchain",
|
||||||
|
visibility = ["//visibility:public"],
|
||||||
|
)
|
||||||
|
|
||||||
|
################################################################################
|
||||||
|
# Python support
|
||||||
|
################################################################################
|
||||||
|
|
||||||
|
alias(
|
||||||
|
name = "protobuf_python",
|
||||||
|
actual = "//python:protobuf_python",
|
||||||
|
visibility = ["//visibility:public"],
|
||||||
|
)
|
||||||
|
|
||||||
|
alias(
|
||||||
|
name = "python_srcs",
|
||||||
|
actual = "//python:python_srcs",
|
||||||
|
visibility = ["@upb//:__subpackages__"],
|
||||||
|
)
|
||||||
|
|
||||||
|
alias(
|
||||||
|
name = "python_test_srcs",
|
||||||
|
actual = "//python:python_test_srcs",
|
||||||
|
visibility = ["@upb//:__subpackages__"],
|
||||||
|
)
|
||||||
|
|
||||||
|
alias(
|
||||||
|
name = "well_known_types_py_pb2",
|
||||||
|
actual = "//python:well_known_types_py_pb2",
|
||||||
|
visibility = ["//visibility:public"],
|
||||||
|
)
|
||||||
|
|
||||||
|
alias(
|
||||||
|
name = "python_common_test_protos",
|
||||||
|
actual = "//python:python_common_test_protos",
|
||||||
|
visibility = ["//visibility:public"],
|
||||||
|
)
|
||||||
|
|
||||||
|
alias(
|
||||||
|
name = "python_specific_test_protos",
|
||||||
|
actual = "//python:python_specific_test_protos",
|
||||||
|
visibility = ["//visibility:public"],
|
||||||
|
)
|
||||||
|
|
||||||
|
proto_lang_toolchain(
|
||||||
|
name = "cc_toolchain",
|
||||||
|
blacklisted_protos = [
|
||||||
|
"@com_google_protobuf//:compiler_plugin_proto",
|
||||||
|
"@com_google_protobuf//:descriptor_proto",
|
||||||
|
],
|
||||||
|
command_line = "--cpp_out=$(OUT)",
|
||||||
|
runtime = ":protobuf",
|
||||||
|
visibility = ["//visibility:public"],
|
||||||
|
)
|
||||||
|
|
||||||
|
################################################################################
|
||||||
|
# Objective-C support
|
||||||
|
################################################################################
|
||||||
|
|
||||||
|
alias(
|
||||||
|
name = "objectivec",
|
||||||
|
actual = "//objectivec",
|
||||||
|
tags = ["manual"],
|
||||||
|
visibility = ["//visibility:public"],
|
||||||
|
)
|
||||||
|
|
||||||
|
alias(
|
||||||
|
name = "protobuf_objc",
|
||||||
|
actual = "//objectivec",
|
||||||
|
tags = ["manual"],
|
||||||
|
visibility = ["//visibility:public"],
|
||||||
|
)
|
||||||
|
|
||||||
|
################################################################################
|
||||||
|
# Test protos
|
||||||
|
################################################################################
|
||||||
|
|
||||||
|
alias(
|
||||||
|
name = "lite_test_proto_srcs",
|
||||||
|
actual = "//src/google/protobuf:lite_test_proto_srcs", # proto_library
|
||||||
|
visibility = ["//:__subpackages__"],
|
||||||
|
)
|
||||||
|
|
||||||
|
alias(
|
||||||
|
name = "lite_test_protos",
|
||||||
|
actual = "//src/google/protobuf:lite_test_protos", # proto_library
|
||||||
|
visibility = ["//:__subpackages__"],
|
||||||
|
)
|
||||||
|
|
||||||
|
alias(
|
||||||
|
name = "test_proto_srcs",
|
||||||
|
actual = "//src/google/protobuf:test_proto_srcs", # filegroup
|
||||||
|
visibility = ["//:__subpackages__"],
|
||||||
|
)
|
||||||
|
|
||||||
|
alias(
|
||||||
|
name = "test_protos",
|
||||||
|
actual = "//src/google/protobuf:test_protos", # proto_library
|
||||||
|
visibility = ["//:__subpackages__"],
|
||||||
|
)
|
||||||
|
|
||||||
|
# Validate generated proto source inputs:
|
||||||
|
|
||||||
|
genrule(
|
||||||
|
name = "generated_protos",
|
||||||
|
testonly = 1,
|
||||||
|
srcs = ["//src/google/protobuf:test_proto_srcs"],
|
||||||
|
outs = ["unittest_gen_import.proto"],
|
||||||
|
cmd = "cat src/google/protobuf/unittest_import.proto > $@",
|
||||||
|
)
|
||||||
|
|
||||||
|
proto_library(
|
||||||
|
name = "generated_protos_proto",
|
||||||
|
testonly = 1,
|
||||||
|
srcs = [":generated_protos"],
|
||||||
|
deps = ["//src/google/protobuf:generic_test_protos"],
|
||||||
|
)
|
||||||
|
|
||||||
|
internal_py_proto_library(
|
||||||
|
name = "generated_protos_py",
|
||||||
|
testonly = 1,
|
||||||
|
srcs = [":generated_protos"],
|
||||||
|
default_runtime = "",
|
||||||
|
protoc = ":protoc",
|
||||||
|
deps = ["//python:python_common_test_protos"],
|
||||||
|
)
|
||||||
|
|
||||||
|
################################################################################
|
||||||
|
# Conformance tests
|
||||||
|
################################################################################
|
||||||
|
|
||||||
|
cc_proto_library(
|
||||||
|
name = "test_messages_proto2_cc_proto",
|
||||||
|
visibility = [
|
||||||
|
"//conformance:__pkg__",
|
||||||
|
"//src:__subpackages__",
|
||||||
|
],
|
||||||
|
deps = ["//src/google/protobuf:test_messages_proto2_proto"],
|
||||||
|
)
|
||||||
|
|
||||||
|
cc_proto_library(
|
||||||
|
name = "test_messages_proto3_cc_proto",
|
||||||
|
visibility = [
|
||||||
|
"//conformance:__pkg__",
|
||||||
|
"//src:__subpackages__",
|
||||||
|
],
|
||||||
|
deps = ["//src/google/protobuf:test_messages_proto3_proto"],
|
||||||
|
)
|
||||||
|
|
||||||
|
java_proto_library(
|
||||||
|
name = "test_messages_proto2_java_proto",
|
||||||
|
visibility = [
|
||||||
|
"//conformance:__pkg__",
|
||||||
|
"//java:__subpackages__",
|
||||||
|
],
|
||||||
|
deps = ["//src/google/protobuf:test_messages_proto2_proto"],
|
||||||
|
)
|
||||||
|
|
||||||
|
java_proto_library(
|
||||||
|
name = "test_messages_proto3_java_proto",
|
||||||
|
visibility = [
|
||||||
|
"//conformance:__pkg__",
|
||||||
|
"//java:__subpackages__",
|
||||||
|
],
|
||||||
|
deps = ["//src/google/protobuf:test_messages_proto3_proto"],
|
||||||
|
)
|
||||||
|
|
||||||
|
java_lite_proto_library(
|
||||||
|
name = "test_messages_proto2_java_proto_lite",
|
||||||
|
visibility = [
|
||||||
|
"//conformance:__pkg__",
|
||||||
|
"//java:__subpackages__",
|
||||||
|
],
|
||||||
|
deps = ["//src/google/protobuf:test_messages_proto2_proto"],
|
||||||
|
)
|
||||||
|
|
||||||
|
java_lite_proto_library(
|
||||||
|
name = "test_messages_proto3_java_proto_lite",
|
||||||
|
visibility = [
|
||||||
|
"//conformance:__pkg__",
|
||||||
|
"//java:__subpackages__",
|
||||||
|
],
|
||||||
|
deps = ["//src/google/protobuf:test_messages_proto3_proto"],
|
||||||
|
)
|
||||||
|
|
||||||
|
internal_objc_proto_library(
|
||||||
|
name = "test_messages_proto2_objc_proto",
|
||||||
|
testonly = 1,
|
||||||
|
srcs = ["//src/google/protobuf:test_messages_proto2.proto"],
|
||||||
|
includes = ["src/google/protobuf"],
|
||||||
|
visibility = [
|
||||||
|
"//conformance:__pkg__",
|
||||||
|
"//objectivec:__subpackages__",
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
|
internal_objc_proto_library(
|
||||||
|
name = "test_messages_proto3_objc_proto",
|
||||||
|
testonly = 1,
|
||||||
|
srcs = ["//src/google/protobuf:test_messages_proto3.proto"],
|
||||||
|
includes = [
|
||||||
|
"src/google/protobuf",
|
||||||
|
# The above must come first.
|
||||||
|
"src",
|
||||||
|
],
|
||||||
|
proto_deps = [":well_known_protos"],
|
||||||
|
visibility = [
|
||||||
|
"//conformance:__pkg__",
|
||||||
|
"//objectivec:__subpackages__",
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
|
internal_php_proto_library(
|
||||||
|
name = "test_messages_proto3_php_proto",
|
||||||
|
testonly = 1,
|
||||||
|
srcs = ["//src/google/protobuf:test_messages_proto3.proto"],
|
||||||
|
outs = [
|
||||||
|
"GPBMetadata/TestMessagesProto3.php",
|
||||||
|
"Protobuf_test_messages/Proto3/EnumOnlyProto3.php",
|
||||||
|
"Protobuf_test_messages/Proto3/EnumOnlyProto3/PBBool.php",
|
||||||
|
"Protobuf_test_messages/Proto3/ForeignEnum.php",
|
||||||
|
"Protobuf_test_messages/Proto3/ForeignMessage.php",
|
||||||
|
"Protobuf_test_messages/Proto3/NullHypothesisProto3.php",
|
||||||
|
"Protobuf_test_messages/Proto3/TestAllTypesProto3.php",
|
||||||
|
"Protobuf_test_messages/Proto3/TestAllTypesProto3/AliasedEnum.php",
|
||||||
|
"Protobuf_test_messages/Proto3/TestAllTypesProto3/NestedEnum.php",
|
||||||
|
"Protobuf_test_messages/Proto3/TestAllTypesProto3/NestedMessage.php",
|
||||||
|
],
|
||||||
|
includes = [
|
||||||
|
"src/google/protobuf",
|
||||||
|
# The above must come first.
|
||||||
|
"src",
|
||||||
|
],
|
||||||
|
proto_deps = [":well_known_protos"],
|
||||||
|
visibility = [
|
||||||
|
"//conformance:__pkg__",
|
||||||
|
"//php:__subpackages__",
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
|
internal_ruby_proto_library(
|
||||||
|
name = "test_messages_proto2_ruby_proto",
|
||||||
|
testonly = 1,
|
||||||
|
srcs = ["//src/google/protobuf:test_messages_proto2.proto"],
|
||||||
|
includes = ["src/google/protobuf"],
|
||||||
|
visibility = [
|
||||||
|
"//conformance:__pkg__",
|
||||||
|
"//ruby:__subpackages__",
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
|
internal_ruby_proto_library(
|
||||||
|
name = "test_messages_proto3_ruby_proto",
|
||||||
|
testonly = 1,
|
||||||
|
srcs = ["//src/google/protobuf:test_messages_proto3.proto"],
|
||||||
|
includes = [
|
||||||
|
"src/google/protobuf",
|
||||||
|
# The above must come first.
|
||||||
|
"src",
|
||||||
|
],
|
||||||
|
proto_deps = [":well_known_protos"],
|
||||||
|
visibility = [
|
||||||
|
"//conformance:__pkg__",
|
||||||
|
"//ruby:__subpackages__",
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
|
filegroup(
|
||||||
|
name = "bzl_srcs",
|
||||||
|
srcs = glob(["**/*.bzl"]),
|
||||||
|
visibility = ["//visibility:public"],
|
||||||
|
)
|
||||||
|
|
||||||
|
################################################################################
|
||||||
|
# Packaging rules
|
||||||
|
################################################################################
|
||||||
|
|
||||||
|
# Files included in all source distributions
|
||||||
|
pkg_files(
|
||||||
|
name = "common_dist_files",
|
||||||
|
srcs = glob(
|
||||||
|
[
|
||||||
|
"*.bzl",
|
||||||
|
"cmake/*.cmake",
|
||||||
|
"cmake/*.in",
|
||||||
|
"editors/*",
|
||||||
|
],
|
||||||
|
allow_empty = True,
|
||||||
|
) + [
|
||||||
|
"BUILD.bazel",
|
||||||
|
"CHANGES.txt",
|
||||||
|
"CMakeLists.txt",
|
||||||
|
"CONTRIBUTORS.txt",
|
||||||
|
"LICENSE",
|
||||||
|
"README.md",
|
||||||
|
"WORKSPACE",
|
||||||
|
"cmake/CMakeLists.txt",
|
||||||
|
"cmake/README.md",
|
||||||
|
"cmake/update_file_lists.sh",
|
||||||
|
"generate_descriptor_proto.sh",
|
||||||
|
"maven_install.json",
|
||||||
|
"//third_party:BUILD.bazel",
|
||||||
|
"//third_party:zlib.BUILD",
|
||||||
|
],
|
||||||
|
strip_prefix = strip_prefix.from_root(""),
|
||||||
|
visibility = ["//pkg:__pkg__"],
|
||||||
|
)
|
||||||
|
|
||||||
|
# Additional files for C#
|
||||||
|
pkg_files(
|
||||||
|
name = "csharp_dist_files",
|
||||||
|
srcs = [
|
||||||
|
"global.json",
|
||||||
|
],
|
||||||
|
visibility = ["//pkg:__pkg__"],
|
||||||
|
)
|
||||||
|
|
||||||
|
# Additional files for ObjC
|
||||||
|
pkg_files(
|
||||||
|
name = "objectivec_dist_files",
|
||||||
|
srcs = [
|
||||||
|
"Protobuf.podspec",
|
||||||
|
],
|
||||||
|
visibility = ["//pkg:__pkg__"],
|
||||||
|
)
|
||||||
3533
CHANGES.txt
Normal file
3533
CHANGES.txt
Normal file
File diff suppressed because it is too large
Load Diff
397
CMakeLists.txt
Normal file
397
CMakeLists.txt
Normal file
@@ -0,0 +1,397 @@
|
|||||||
|
# Minimum CMake required
|
||||||
|
cmake_minimum_required(VERSION 3.5)
|
||||||
|
|
||||||
|
if(protobuf_VERBOSE)
|
||||||
|
message(STATUS "Protocol Buffers Configuring...")
|
||||||
|
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()
|
||||||
|
# MSVC runtime library flags are selected by an abstraction.
|
||||||
|
if(POLICY CMP0091)
|
||||||
|
cmake_policy(SET CMP0091 NEW)
|
||||||
|
endif()
|
||||||
|
# Honor visibility properties for all target types.
|
||||||
|
if(POLICY CMP0063)
|
||||||
|
cmake_policy(SET CMP0063 NEW)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# Project
|
||||||
|
project(protobuf C CXX)
|
||||||
|
|
||||||
|
if(protobuf_DEPRECATED_CMAKE_SUBDIRECTORY_USAGE)
|
||||||
|
if(CMAKE_PROJECT_NAME STREQUAL "protobuf")
|
||||||
|
get_filename_component(CMAKE_SOURCE_DIR ${CMAKE_SOURCE_DIR} DIRECTORY)
|
||||||
|
endif()
|
||||||
|
get_filename_component(CMAKE_CURRENT_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR} DIRECTORY)
|
||||||
|
get_filename_component(PROJECT_SOURCE_DIR ${PROJECT_SOURCE_DIR} DIRECTORY)
|
||||||
|
get_filename_component(protobuf_SOURCE_DIR ${protobuf_SOURCE_DIR} DIRECTORY)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# Add C++14 flags
|
||||||
|
if(NOT CMAKE_CXX_STANDARD)
|
||||||
|
set(CMAKE_CXX_STANDARD 14)
|
||||||
|
endif()
|
||||||
|
if(CYGWIN)
|
||||||
|
string(REGEX_MATCH "-std=gnu\\+\\+([0-9]+)" _protobuf_CXX_STD "${CMAKE_CXX_FLAGS}")
|
||||||
|
endif()
|
||||||
|
if(NOT _protobuf_CXX_STD)
|
||||||
|
set(_protobuf_CXX_STD "${CMAKE_CXX_STANDARD}")
|
||||||
|
endif()
|
||||||
|
if(_protobuf_CXX_STD LESS "14")
|
||||||
|
message(FATAL_ERROR "Protocol Buffers requires at least C++14, but is configured for C++${_protobuf_CXX_STD}")
|
||||||
|
endif()
|
||||||
|
if(CYGWIN)
|
||||||
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=gnu++${_protobuf_CXX_STD}")
|
||||||
|
else()
|
||||||
|
set(CMAKE_CXX_STANDARD ${_protobuf_CXX_STD})
|
||||||
|
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||||
|
set(CMAKE_CXX_EXTENSIONS OFF)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# For -fvisibility=hidden and -fvisibility-inlines-hidden
|
||||||
|
set(CMAKE_C_VISIBILITY_PRESET hidden)
|
||||||
|
set(CMAKE_CXX_VISIBILITY_PRESET hidden)
|
||||||
|
set(CMAKE_VISIBILITY_INLINES_HIDDEN ON)
|
||||||
|
|
||||||
|
# The Intel compiler isn't able to deal with noinline member functions of
|
||||||
|
# template classes defined in headers. As such it spams the output with
|
||||||
|
# warning #2196: routine is both "inline" and "noinline"
|
||||||
|
# This silences that warning.
|
||||||
|
if (CMAKE_CXX_COMPILER_ID MATCHES Intel)
|
||||||
|
string(APPEND CMAKE_CXX_FLAGS " -diag-disable=2196")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# Options
|
||||||
|
option(protobuf_INSTALL "Install protobuf binaries and files" ON)
|
||||||
|
if(WITH_PROTOC)
|
||||||
|
set(protobuf_PROTOC_EXE ${WITH_PROTOC} CACHE FILEPATH "Protocol Buffer Compiler executable" FORCE)
|
||||||
|
endif()
|
||||||
|
option(protobuf_BUILD_TESTS "Build tests" ON)
|
||||||
|
option(protobuf_BUILD_CONFORMANCE "Build conformance tests" OFF)
|
||||||
|
option(protobuf_BUILD_EXAMPLES "Build examples" OFF)
|
||||||
|
option(protobuf_BUILD_PROTOBUF_BINARIES "Build protobuf libraries and protoc compiler" ON)
|
||||||
|
option(protobuf_BUILD_PROTOC_BINARIES "Build libprotoc and protoc compiler" ON)
|
||||||
|
option(protobuf_BUILD_LIBPROTOC "Build libprotoc" OFF)
|
||||||
|
option(protobuf_DISABLE_RTTI "Remove runtime type information in the binaries" OFF)
|
||||||
|
option(protobuf_TEST_XML_OUTDIR "Output directory for XML logs from tests." "")
|
||||||
|
if (BUILD_SHARED_LIBS)
|
||||||
|
set(protobuf_BUILD_SHARED_LIBS_DEFAULT ON)
|
||||||
|
else (BUILD_SHARED_LIBS)
|
||||||
|
set(protobuf_BUILD_SHARED_LIBS_DEFAULT OFF)
|
||||||
|
endif (BUILD_SHARED_LIBS)
|
||||||
|
option(protobuf_BUILD_SHARED_LIBS "Build Shared Libraries" ${protobuf_BUILD_SHARED_LIBS_DEFAULT})
|
||||||
|
include(CMakeDependentOption)
|
||||||
|
cmake_dependent_option(protobuf_MSVC_STATIC_RUNTIME "Link static runtime libraries" ON
|
||||||
|
"NOT protobuf_BUILD_SHARED_LIBS" OFF)
|
||||||
|
set(protobuf_WITH_ZLIB_DEFAULT ON)
|
||||||
|
option(protobuf_WITH_ZLIB "Build with zlib support" ${protobuf_WITH_ZLIB_DEFAULT})
|
||||||
|
set(protobuf_DEBUG_POSTFIX "d"
|
||||||
|
CACHE STRING "Default debug postfix")
|
||||||
|
mark_as_advanced(protobuf_DEBUG_POSTFIX)
|
||||||
|
# User options
|
||||||
|
include(${protobuf_SOURCE_DIR}/cmake/protobuf-options.cmake)
|
||||||
|
|
||||||
|
if (protobuf_BUILD_SHARED_LIBS)
|
||||||
|
# This is necessary for linking in Abseil.
|
||||||
|
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
|
||||||
|
endif ()
|
||||||
|
|
||||||
|
# Version metadata
|
||||||
|
set(protobuf_VERSION_STRING "3.21.4")
|
||||||
|
set(protobuf_DESCRIPTION "Protocol Buffers")
|
||||||
|
set(protobuf_CONTACT "protobuf@googlegroups.com")
|
||||||
|
|
||||||
|
# Overrides for option dependencies
|
||||||
|
if (protobuf_BUILD_PROTOC_BINARIES OR protobuf_BUILD_TESTS)
|
||||||
|
set(protobuf_BUILD_LIBPROTOC ON)
|
||||||
|
endif ()
|
||||||
|
if (NOT protobuf_BUILD_PROTOBUF_BINARIES)
|
||||||
|
set(protobuf_INSTALL OFF)
|
||||||
|
endif()
|
||||||
|
# Parse version tweaks
|
||||||
|
set(protobuf_VERSION_REGEX "^([0-9]+)\\.([0-9]+)\\.([0-9]+)([-]rc[-]|\\.)?([0-9]*)$")
|
||||||
|
string(REGEX REPLACE "${protobuf_VERSION_REGEX}" "\\1"
|
||||||
|
protobuf_VERSION_MAJOR "${protobuf_VERSION_STRING}")
|
||||||
|
string(REGEX REPLACE "${protobuf_VERSION_REGEX}" "\\2"
|
||||||
|
protobuf_VERSION_MINOR "${protobuf_VERSION_STRING}")
|
||||||
|
string(REGEX REPLACE "${protobuf_VERSION_REGEX}" "\\3"
|
||||||
|
protobuf_VERSION_PATCH "${protobuf_VERSION_STRING}")
|
||||||
|
string(REGEX REPLACE "${protobuf_VERSION_REGEX}" "\\5"
|
||||||
|
protobuf_VERSION_PRERELEASE "${protobuf_VERSION_STRING}")
|
||||||
|
|
||||||
|
message(STATUS "${protobuf_VERSION_PRERELEASE}")
|
||||||
|
|
||||||
|
# Package version
|
||||||
|
set(protobuf_VERSION
|
||||||
|
"${protobuf_VERSION_MAJOR}.${protobuf_VERSION_MINOR}.${protobuf_VERSION_PATCH}")
|
||||||
|
|
||||||
|
if(protobuf_VERSION_PRERELEASE)
|
||||||
|
set(protobuf_VERSION "${protobuf_VERSION}.${protobuf_VERSION_PRERELEASE}")
|
||||||
|
else()
|
||||||
|
set(protobuf_VERSION "${protobuf_VERSION}.0")
|
||||||
|
endif()
|
||||||
|
message(STATUS "${protobuf_VERSION}")
|
||||||
|
|
||||||
|
if(protobuf_VERBOSE)
|
||||||
|
message(STATUS "Configuration script parsing status [")
|
||||||
|
message(STATUS " Description : ${protobuf_DESCRIPTION}")
|
||||||
|
message(STATUS " Version : ${protobuf_VERSION} (${protobuf_VERSION_STRING})")
|
||||||
|
message(STATUS " Contact : ${protobuf_CONTACT}")
|
||||||
|
message(STATUS "]")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
add_definitions(-DGOOGLE_PROTOBUF_CMAKE_BUILD)
|
||||||
|
|
||||||
|
if (protobuf_DISABLE_RTTI)
|
||||||
|
add_definitions(-DGOOGLE_PROTOBUF_NO_RTTI=1)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/cmaketest.map
|
||||||
|
"{
|
||||||
|
global:
|
||||||
|
main;
|
||||||
|
local:
|
||||||
|
*;
|
||||||
|
};")
|
||||||
|
# CheckLinkerFlag module available in CMake >=3.18.
|
||||||
|
if(${CMAKE_VERSION} VERSION_GREATER 3.18 OR ${CMAKE_VERSION} VERSION_EQUAL 3.18)
|
||||||
|
include(CheckLinkerFlag)
|
||||||
|
check_linker_flag(CXX -Wl,--version-script=${CMAKE_CURRENT_BINARY_DIR}/cmaketest.map protobuf_HAVE_LD_VERSION_SCRIPT)
|
||||||
|
else()
|
||||||
|
include(CheckCXXSourceCompiles)
|
||||||
|
set(OLD_CMAKE_REQUIRED_FLAGS ${CMAKE_REQUIRED_FLAGS})
|
||||||
|
set(CMAKE_REQUIRED_FLAGS ${CMAKE_REQUIRED_FLAGS} -Wl,--version-script=${CMAKE_CURRENT_BINARY_DIR}/cmaketest.map)
|
||||||
|
check_cxx_source_compiles("
|
||||||
|
int main() {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
" protobuf_HAVE_LD_VERSION_SCRIPT)
|
||||||
|
set(CMAKE_REQUIRED_FLAGS ${OLD_CMAKE_REQUIRED_FLAGS})
|
||||||
|
endif()
|
||||||
|
file(REMOVE ${CMAKE_CURRENT_BINARY_DIR}/cmaketest.map)
|
||||||
|
|
||||||
|
find_package(Threads REQUIRED)
|
||||||
|
|
||||||
|
# We can install dependencies from submodules if we're running
|
||||||
|
# CMake v3.13 or newer.
|
||||||
|
if(CMAKE_VERSION VERSION_LESS 3.13)
|
||||||
|
set(_protobuf_INSTALL_SUPPORTED_FROM_MODULE OFF)
|
||||||
|
else()
|
||||||
|
set(_protobuf_INSTALL_SUPPORTED_FROM_MODULE ON)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
set(_protobuf_FIND_ZLIB)
|
||||||
|
if (protobuf_WITH_ZLIB)
|
||||||
|
find_package(ZLIB)
|
||||||
|
if (ZLIB_FOUND)
|
||||||
|
set(HAVE_ZLIB 1)
|
||||||
|
# FindZLIB module define ZLIB_INCLUDE_DIRS variable
|
||||||
|
# Set ZLIB_INCLUDE_DIRECTORIES for compatible
|
||||||
|
set(ZLIB_INCLUDE_DIRECTORIES ${ZLIB_INCLUDE_DIRECTORIES} ${ZLIB_INCLUDE_DIRS})
|
||||||
|
# Using imported target if exists
|
||||||
|
if (TARGET ZLIB::ZLIB)
|
||||||
|
set(ZLIB_LIBRARIES ZLIB::ZLIB)
|
||||||
|
set(_protobuf_FIND_ZLIB "if(NOT ZLIB_FOUND)\n find_package(ZLIB)\nendif()")
|
||||||
|
endif (TARGET ZLIB::ZLIB)
|
||||||
|
else (ZLIB_FOUND)
|
||||||
|
set(HAVE_ZLIB 0)
|
||||||
|
# Explicitly set these to empty (override NOT_FOUND) so cmake doesn't
|
||||||
|
# complain when we use them later.
|
||||||
|
set(ZLIB_INCLUDE_DIRECTORIES)
|
||||||
|
set(ZLIB_LIBRARIES)
|
||||||
|
endif (ZLIB_FOUND)
|
||||||
|
endif (protobuf_WITH_ZLIB)
|
||||||
|
|
||||||
|
if (HAVE_ZLIB)
|
||||||
|
add_definitions(-DHAVE_ZLIB)
|
||||||
|
endif (HAVE_ZLIB)
|
||||||
|
|
||||||
|
# We need to link with libatomic on systems that do not have builtin atomics, or
|
||||||
|
# don't have builtin support for 8 byte atomics
|
||||||
|
set(protobuf_LINK_LIBATOMIC false)
|
||||||
|
if (NOT MSVC)
|
||||||
|
include(CheckCXXSourceCompiles)
|
||||||
|
set(OLD_CMAKE_REQUIRED_FLAGS ${CMAKE_REQUIRED_FLAGS})
|
||||||
|
set(CMAKE_REQUIRED_FLAGS ${CMAKE_REQUIRED_FLAGS} -std=c++14)
|
||||||
|
check_cxx_source_compiles("
|
||||||
|
#include <atomic>
|
||||||
|
int main() {
|
||||||
|
return std::atomic<int64_t>{};
|
||||||
|
}
|
||||||
|
" protobuf_HAVE_BUILTIN_ATOMICS)
|
||||||
|
if (NOT protobuf_HAVE_BUILTIN_ATOMICS)
|
||||||
|
set(protobuf_LINK_LIBATOMIC true)
|
||||||
|
endif (NOT protobuf_HAVE_BUILTIN_ATOMICS)
|
||||||
|
set(CMAKE_REQUIRED_FLAGS ${OLD_CMAKE_REQUIRED_FLAGS})
|
||||||
|
endif (NOT MSVC)
|
||||||
|
|
||||||
|
if (protobuf_BUILD_SHARED_LIBS)
|
||||||
|
set(protobuf_SHARED_OR_STATIC "SHARED")
|
||||||
|
else (protobuf_BUILD_SHARED_LIBS)
|
||||||
|
set(protobuf_SHARED_OR_STATIC "STATIC")
|
||||||
|
# The CMAKE_<LANG>_FLAGS(_<BUILD_TYPE>)? is meant to be user controlled.
|
||||||
|
# Prior to CMake 3.15, the MSVC runtime library was pushed into the same flags
|
||||||
|
# making programmatic control difficult. Prefer the functionality in newer
|
||||||
|
# CMake versions when available.
|
||||||
|
if(${CMAKE_VERSION} VERSION_GREATER 3.15 OR ${CMAKE_VERSION} VERSION_EQUAL 3.15)
|
||||||
|
if (protobuf_MSVC_STATIC_RUNTIME)
|
||||||
|
set(CMAKE_MSVC_RUNTIME_LIBRARY MultiThreaded$<$<CONFIG:Debug>:Debug>)
|
||||||
|
else()
|
||||||
|
set(CMAKE_MSVC_RUNTIME_LIBRARY MultiThreaded$<$<CONFIG:Debug>:Debug>DLL)
|
||||||
|
endif()
|
||||||
|
else()
|
||||||
|
# In case we are building static libraries, link also the runtime library statically
|
||||||
|
# so that MSVCR*.DLL is not required at runtime.
|
||||||
|
# https://msdn.microsoft.com/en-us/library/2kzt1wy3.aspx
|
||||||
|
# This is achieved by replacing msvc option /MD with /MT and /MDd with /MTd
|
||||||
|
# http://www.cmake.org/Wiki/CMake_FAQ#How_can_I_build_my_MSVC_application_with_a_static_runtime.3F
|
||||||
|
if (MSVC AND protobuf_MSVC_STATIC_RUNTIME)
|
||||||
|
foreach(flag_var
|
||||||
|
CMAKE_CXX_FLAGS CMAKE_CXX_FLAGS_DEBUG CMAKE_CXX_FLAGS_RELEASE
|
||||||
|
CMAKE_CXX_FLAGS_MINSIZEREL CMAKE_CXX_FLAGS_RELWITHDEBINFO)
|
||||||
|
if(${flag_var} MATCHES "/MD")
|
||||||
|
string(REGEX REPLACE "/MD" "/MT" ${flag_var} "${${flag_var}}")
|
||||||
|
endif(${flag_var} MATCHES "/MD")
|
||||||
|
endforeach(flag_var)
|
||||||
|
endif (MSVC AND protobuf_MSVC_STATIC_RUNTIME)
|
||||||
|
endif()
|
||||||
|
endif (protobuf_BUILD_SHARED_LIBS)
|
||||||
|
|
||||||
|
if (MSVC)
|
||||||
|
if (CMAKE_CXX_COMPILER_ID STREQUAL "MSVC")
|
||||||
|
# Build with multiple processes
|
||||||
|
add_compile_options(/MP)
|
||||||
|
endif()
|
||||||
|
# Set source file and execution character sets to UTF-8
|
||||||
|
add_compile_options(/utf-8)
|
||||||
|
# MSVC warning suppressions
|
||||||
|
add_compile_options(
|
||||||
|
/wd4065 # switch statement contains 'default' but no 'case' labels
|
||||||
|
/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'
|
||||||
|
/wd4800 # 'type' : forcing value to bool 'true' or 'false' (performance warning)
|
||||||
|
/wd4996 # The compiler encountered a deprecated declaration.
|
||||||
|
)
|
||||||
|
# Allow big object
|
||||||
|
add_compile_options(/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}")
|
||||||
|
|
||||||
|
# Suppress linker warnings about files with no symbols defined.
|
||||||
|
string(APPEND CMAKE_STATIC_LINKER_FLAGS " /ignore:4221")
|
||||||
|
|
||||||
|
# use English language (0x409) in resource compiler
|
||||||
|
string(APPEND CMAKE_RC_FLAGS " -l0x409")
|
||||||
|
|
||||||
|
# Generate the version.rc file used elsewhere.
|
||||||
|
configure_file(${protobuf_SOURCE_DIR}/cmake/version.rc.in ${CMAKE_CURRENT_BINARY_DIR}/version.rc @ONLY)
|
||||||
|
set(protobuf_version_rc_file ${CMAKE_CURRENT_BINARY_DIR}/version.rc)
|
||||||
|
|
||||||
|
# Add the "lib" prefix for generated .lib outputs.
|
||||||
|
set(LIB_PREFIX lib)
|
||||||
|
else (MSVC)
|
||||||
|
# No version.rc file.
|
||||||
|
set(protobuf_version_rc_file)
|
||||||
|
|
||||||
|
# When building with "make", "lib" prefix will be added automatically by
|
||||||
|
# the build tool.
|
||||||
|
set(LIB_PREFIX)
|
||||||
|
endif (MSVC)
|
||||||
|
|
||||||
|
include_directories(
|
||||||
|
${ZLIB_INCLUDE_DIRECTORIES}
|
||||||
|
${protobuf_BINARY_DIR}
|
||||||
|
${protobuf_SOURCE_DIR}/src)
|
||||||
|
|
||||||
|
if (protobuf_UNICODE)
|
||||||
|
add_definitions(-DUNICODE -D_UNICODE)
|
||||||
|
endif (protobuf_UNICODE)
|
||||||
|
|
||||||
|
set(protobuf_ABSL_PROVIDER "module" CACHE STRING "Provider of absl library")
|
||||||
|
set_property(CACHE protobuf_ABSL_PROVIDER PROPERTY STRINGS "module" "package")
|
||||||
|
|
||||||
|
include(${protobuf_SOURCE_DIR}/cmake/abseil-cpp.cmake)
|
||||||
|
|
||||||
|
if (protobuf_BUILD_PROTOBUF_BINARIES)
|
||||||
|
include(${protobuf_SOURCE_DIR}/cmake/libprotobuf-lite.cmake)
|
||||||
|
if (NOT DEFINED protobuf_LIB_PROTOBUF_LITE)
|
||||||
|
set(protobuf_LIB_PROTOBUF_LITE libprotobuf-lite)
|
||||||
|
endif ()
|
||||||
|
include(${protobuf_SOURCE_DIR}/cmake/libprotobuf.cmake)
|
||||||
|
if (NOT DEFINED protobuf_LIB_PROTOBUF)
|
||||||
|
set(protobuf_LIB_PROTOBUF libprotobuf)
|
||||||
|
endif ()
|
||||||
|
if (protobuf_BUILD_LIBPROTOC)
|
||||||
|
include(${protobuf_SOURCE_DIR}/cmake/libprotoc.cmake)
|
||||||
|
if (NOT DEFINED protobuf_LIB_PROTOC)
|
||||||
|
set(protobuf_LIB_PROTOC libprotoc)
|
||||||
|
endif ()
|
||||||
|
endif ()
|
||||||
|
if (protobuf_BUILD_PROTOC_BINARIES)
|
||||||
|
include(${protobuf_SOURCE_DIR}/cmake/protoc.cmake)
|
||||||
|
if (NOT DEFINED protobuf_PROTOC_EXE)
|
||||||
|
set(protobuf_PROTOC_EXE protoc)
|
||||||
|
endif ()
|
||||||
|
endif ()
|
||||||
|
else ()
|
||||||
|
find_package(Protobuf NO_MODULE)
|
||||||
|
if (Protobuf_FOUND)
|
||||||
|
set(protobuf_PROTOC_EXE protobuf::protoc)
|
||||||
|
set(protobuf_LIB_PROTOC protobuf::libprotoc)
|
||||||
|
set(protobuf_LIB_PROTOBUF protobuf::libprotobuf)
|
||||||
|
set(protobuf_LIB_PROTOBUF_LITE protobuf::libprotobuf-lite)
|
||||||
|
message(STATUS "CMake installation of Protobuf found.")
|
||||||
|
endif ()
|
||||||
|
endif ()
|
||||||
|
|
||||||
|
# Ensure we have a protoc executable and protobuf libraries if we need one
|
||||||
|
if (protobuf_BUILD_TESTS OR protobuf_BUILD_CONFORMANCE OR protobuf_BUILD_EXAMPLES)
|
||||||
|
if (NOT DEFINED protobuf_PROTOC_EXE)
|
||||||
|
find_program(protobuf_PROTOC_EXE protoc REQUIRED)
|
||||||
|
message(STATUS "Found system ${protobuf_PROTOC_EXE}.")
|
||||||
|
endif ()
|
||||||
|
if(protobuf_VERBOSE)
|
||||||
|
message(STATUS "Using protoc : ${protobuf_PROTOC_EXE}")
|
||||||
|
message(STATUS "Using libprotobuf : ${protobuf_LIB_PROTOBUF}")
|
||||||
|
message(STATUS "Using libprotobuf-lite : ${protobuf_LIB_PROTOBUF_LITE}")
|
||||||
|
message(STATUS "Using libprotoc : ${protobuf_LIB_PROTOC}")
|
||||||
|
endif(protobuf_VERBOSE)
|
||||||
|
endif ()
|
||||||
|
|
||||||
|
if (protobuf_BUILD_TESTS)
|
||||||
|
enable_testing()
|
||||||
|
include(${protobuf_SOURCE_DIR}/cmake/tests.cmake)
|
||||||
|
endif (protobuf_BUILD_TESTS)
|
||||||
|
|
||||||
|
if (protobuf_BUILD_CONFORMANCE)
|
||||||
|
include(${protobuf_SOURCE_DIR}/cmake/conformance.cmake)
|
||||||
|
endif (protobuf_BUILD_CONFORMANCE)
|
||||||
|
|
||||||
|
if (protobuf_INSTALL)
|
||||||
|
include(${protobuf_SOURCE_DIR}/cmake/install.cmake)
|
||||||
|
endif (protobuf_INSTALL)
|
||||||
|
|
||||||
|
if (protobuf_BUILD_EXAMPLES)
|
||||||
|
include(${protobuf_SOURCE_DIR}/cmake/examples.cmake)
|
||||||
|
endif (protobuf_BUILD_EXAMPLES)
|
||||||
|
|
||||||
|
if(protobuf_VERBOSE)
|
||||||
|
message(STATUS "Protocol Buffers Configuring done")
|
||||||
|
endif(protobuf_VERBOSE)
|
||||||
120
CONTRIBUTING.md
Normal file
120
CONTRIBUTING.md
Normal file
@@ -0,0 +1,120 @@
|
|||||||
|
# Contributing to Protocol Buffers
|
||||||
|
|
||||||
|
We welcome some types of contributions to protocol buffers. This doc describes the
|
||||||
|
process to contribute patches to protobuf and the general guidelines we
|
||||||
|
expect contributors to follow.
|
||||||
|
|
||||||
|
## What We Accept
|
||||||
|
|
||||||
|
* Bug fixes with unit tests demonstrating the problem are very welcome.
|
||||||
|
We also appreciate bug reports, even when they don't come with a patch.
|
||||||
|
Bug fixes without tests are usually not accepted.
|
||||||
|
* New APIs and features with adequate test coverage and documentation
|
||||||
|
may be accepted if they do not compromise backwards
|
||||||
|
compatibility. However there's a fairly high bar of usefulness a new public
|
||||||
|
method must clear before it will be accepted. Features that are fine in
|
||||||
|
isolation are often rejected because they don't have enough impact to justify the
|
||||||
|
conceptual burden and ongoing maintenance cost. It's best to file an issue
|
||||||
|
and get agreement from maintainers on the value of a new feature before
|
||||||
|
working on a PR.
|
||||||
|
* Performance optimizations may be accepted if they have convincing benchmarks that demonstrate
|
||||||
|
an improvement and they do not significantly increase complexity.
|
||||||
|
* Changes to existing APIs are almost never accepted. Stability and
|
||||||
|
backwards compatibility are paramount. In the unlikely event a breaking change
|
||||||
|
is required, it must usually be implemented in google3 first.
|
||||||
|
* Changes to the wire and text formats are never accepted. Any breaking change
|
||||||
|
to these formats would have to be implemented as a completely new format.
|
||||||
|
We cannot begin generating protos that cannot be parsed by existing code.
|
||||||
|
|
||||||
|
## Before You Start
|
||||||
|
|
||||||
|
We accept patches in the form of github pull requests. If you are new to
|
||||||
|
github, please read [How to create github pull requests](https://help.github.com/articles/about-pull-requests/)
|
||||||
|
first.
|
||||||
|
|
||||||
|
### Contributor License Agreements
|
||||||
|
|
||||||
|
Contributions to this project must be accompanied by a Contributor License
|
||||||
|
Agreement. You (or your employer) retain the copyright to your contribution,
|
||||||
|
this simply gives us permission to use and redistribute your contributions
|
||||||
|
as part of the project.
|
||||||
|
|
||||||
|
* If you are an individual writing original source code and you're sure you
|
||||||
|
own the intellectual property, then you'll need to sign an [individual CLA](https://cla.developers.google.com/about/google-individual?csw=1).
|
||||||
|
* If you work for a company that wants to allow you to contribute your work,
|
||||||
|
then you'll need to sign a [corporate CLA](https://cla.developers.google.com/about/google-corporate?csw=1).
|
||||||
|
|
||||||
|
### Coding Style
|
||||||
|
|
||||||
|
This project follows [Google’s Coding Style Guides](https://github.com/google/styleguide).
|
||||||
|
Before sending out your pull request, please familiarize yourself with the
|
||||||
|
corresponding style guides and make sure the proposed code change is style
|
||||||
|
conforming.
|
||||||
|
|
||||||
|
## Contributing Process
|
||||||
|
|
||||||
|
Most pull requests should go to the main branch and the change will be
|
||||||
|
included in the next major/minor version release (e.g., 3.6.0 release). If you
|
||||||
|
need to include a bug fix in a patch release (e.g., 3.5.2), make sure it’s
|
||||||
|
already merged to main, and then create a pull request cherry-picking the
|
||||||
|
commits from main branch to the release branch (e.g., branch 3.5.x).
|
||||||
|
|
||||||
|
For each pull request, a protobuf team member will be assigned to review the
|
||||||
|
pull request. For minor cleanups, the pull request may be merged right away
|
||||||
|
after an initial review. For larger changes, you will likely receive multiple
|
||||||
|
rounds of comments and it may take some time to complete. We will try to keep
|
||||||
|
our response time within 7-days but if you don’t get any response in a few
|
||||||
|
days, feel free to comment on the threads to get our attention. We also expect
|
||||||
|
you to respond to our comments within a reasonable amount of time. If we don’t
|
||||||
|
hear from you for 2 weeks or longer, we may close the pull request. You can
|
||||||
|
still send the pull request again once you have time to work on it.
|
||||||
|
|
||||||
|
Once a pull request is merged, we will take care of the rest and get it into
|
||||||
|
the final release.
|
||||||
|
|
||||||
|
## Pull Request Guidelines
|
||||||
|
|
||||||
|
* If you are a Googler, it is preferable to first create an internal CL and
|
||||||
|
have it reviewed and submitted. The code propagation process will deliver the
|
||||||
|
change to GitHub.
|
||||||
|
* Create small PRs that are narrowly focused on addressing a single concern.
|
||||||
|
We often receive PRs that are trying to fix several things at a time, but if
|
||||||
|
only one fix is considered acceptable, nothing gets merged and both author's
|
||||||
|
& reviewer's time is wasted. Create more PRs to address different concerns and
|
||||||
|
everyone will be happy.
|
||||||
|
* For speculative changes, consider opening an issue and discussing it first.
|
||||||
|
If you are suggesting a behavioral or API change, make sure you get explicit
|
||||||
|
support from a protobuf team member before sending us the pull request.
|
||||||
|
* Provide a good PR description as a record of what change is being made and
|
||||||
|
why it was made. Link to a GitHub issue if it exists.
|
||||||
|
* Don't fix code style and formatting unless you are already changing that
|
||||||
|
line to address an issue. PRs with irrelevant changes won't be merged. If
|
||||||
|
you do want to fix formatting or style, do that in a separate PR.
|
||||||
|
* Unless your PR is trivial, you should expect there will be reviewer comments
|
||||||
|
that you'll need to address before merging. We expect you to be reasonably
|
||||||
|
responsive to those comments, otherwise the PR will be closed after 2-3 weeks
|
||||||
|
of inactivity.
|
||||||
|
* Maintain clean commit history and use meaningful commit messages. PRs with
|
||||||
|
messy commit history are difficult to review and won't be merged. Use rebase
|
||||||
|
-i upstream/main to curate your commit history and/or to bring in latest
|
||||||
|
changes from main (but avoid rebasing in the middle of a code review).
|
||||||
|
* Keep your PR up to date with upstream/main (if there are merge conflicts,
|
||||||
|
we can't really merge your change).
|
||||||
|
* All tests need to be passing before your change can be merged. We recommend
|
||||||
|
you run tests locally before creating your PR to catch breakages early on.
|
||||||
|
Ultimately, the green signal will be provided by our testing infrastructure.
|
||||||
|
The reviewer will help you if there are test failures that seem not related
|
||||||
|
to the change you are making.
|
||||||
|
|
||||||
|
## Reviewer Guidelines
|
||||||
|
|
||||||
|
* Make sure that all tests are passing before approval.
|
||||||
|
* Apply the "release notes: yes" label if the pull request's description should
|
||||||
|
be included in the next release (e.g., any new feature / bug fix).
|
||||||
|
Apply the "release notes: no" label if the pull request's description should
|
||||||
|
not be included in the next release (e.g., refactoring changes that does not
|
||||||
|
change behavior, integration from Google internal, updating tests, etc.).
|
||||||
|
* Apply the appropriate language label (e.g., C++, Java, Python, etc.) to the
|
||||||
|
pull request. This will make it easier to identify which languages the pull
|
||||||
|
request affects, allowing us to better identify appropriate reviewer, create
|
||||||
|
a better release note, and make it easier to identify issues in the future.
|
||||||
107
CONTRIBUTORS.txt
Normal file
107
CONTRIBUTORS.txt
Normal file
@@ -0,0 +1,107 @@
|
|||||||
|
This file contains a list of people who have made large contributions
|
||||||
|
to the public version of Protocol Buffers.
|
||||||
|
|
||||||
|
Original Protocol Buffers design and implementation:
|
||||||
|
Sanjay Ghemawat <sanjay@google.com>
|
||||||
|
Jeff Dean <jeff@google.com>
|
||||||
|
Daniel Dulitz <daniel@google.com>
|
||||||
|
Craig Silverstein
|
||||||
|
Paul Haahr <haahr@google.com>
|
||||||
|
Corey Anderson <corin@google.com>
|
||||||
|
(and many others)
|
||||||
|
|
||||||
|
Proto2 C++ and Java primary author:
|
||||||
|
Kenton Varda <kenton@google.com>
|
||||||
|
|
||||||
|
Proto2 Python primary authors:
|
||||||
|
Will Robinson <robinson@google.com>
|
||||||
|
Petar Petrov <petar@google.com>
|
||||||
|
|
||||||
|
Java Nano primary authors:
|
||||||
|
Brian Duff <bduff@google.com>
|
||||||
|
Tom Chao <chaot@google.com>
|
||||||
|
Max Cai <maxtroy@google.com>
|
||||||
|
Ulas Kirazci <ulas@google.com>
|
||||||
|
|
||||||
|
Large code contributions:
|
||||||
|
Jason Hsueh <jasonh@google.com>
|
||||||
|
Joseph Schorr <jschorr@google.com>
|
||||||
|
Wenbo Zhu <wenboz@google.com>
|
||||||
|
|
||||||
|
Large quantity of code reviews:
|
||||||
|
Scott Bruce <sbruce@google.com>
|
||||||
|
Frank Yellin
|
||||||
|
Neal Norwitz <nnorwitz@google.com>
|
||||||
|
Jeffrey Yasskin <jyasskin@google.com>
|
||||||
|
Ambrose Feinstein <ambrose@google.com>
|
||||||
|
|
||||||
|
Documentation:
|
||||||
|
Lisa Carey <lcarey@google.com>
|
||||||
|
|
||||||
|
Maven packaging:
|
||||||
|
Gregory Kick <gak@google.com>
|
||||||
|
|
||||||
|
Patch contributors:
|
||||||
|
Kevin Ko <kevin.s.ko@gmail.com>
|
||||||
|
* Small patch to handle trailing slashes in --proto_path flag.
|
||||||
|
Johan Euphrosine <proppy@aminche.com>
|
||||||
|
* Small patch to fix Python CallMethod().
|
||||||
|
Ulrich Kunitz <kune@deine-taler.de>
|
||||||
|
* Small optimizations to Python serialization.
|
||||||
|
Leandro Lucarella <llucax@gmail.com>
|
||||||
|
* VI syntax highlighting tweaks.
|
||||||
|
* Fix compiler to not make output executable.
|
||||||
|
Dilip Joseph <dilip.antony.joseph@gmail.com>
|
||||||
|
* Heuristic detection of sub-messages when printing unknown fields in
|
||||||
|
text format.
|
||||||
|
Brian Atkinson <nairb774@gmail.com>
|
||||||
|
* Added @Override annotation to generated Java code where appropriate.
|
||||||
|
Vincent Choinière <Choiniere.Vincent@hydro.qc.ca>
|
||||||
|
* Tru64 support.
|
||||||
|
Monty Taylor <monty.taylor@gmail.com>
|
||||||
|
* Solaris 10 + Sun Studio fixes.
|
||||||
|
Alek Storm <alek.storm@gmail.com>
|
||||||
|
* Slicing support for repeated scalar fields for the Python API.
|
||||||
|
Oleg Smolsky <oleg.smolsky@gmail.com>
|
||||||
|
* MS Visual Studio error format option.
|
||||||
|
* Detect unordered_map in stl_hash.m4.
|
||||||
|
Brian Olson <brianolson@google.com>
|
||||||
|
* gzip/zlib I/O support.
|
||||||
|
Michael Poole <mdpoole@troilus.org>
|
||||||
|
* Fixed warnings about generated constructors not explicitly initializing
|
||||||
|
all fields (only present with certain compiler settings).
|
||||||
|
* Added generation of field number constants.
|
||||||
|
Wink Saville <wink@google.com>
|
||||||
|
* Fixed initialization ordering problem in logging code.
|
||||||
|
Will Pierce <willp@nuclei.com>
|
||||||
|
* Small patch improving performance of in Python serialization.
|
||||||
|
Alexandre Vassalotti <alexandre@peadrop.com>
|
||||||
|
* Emacs mode for Protocol Buffers (editors/protobuf-mode.el).
|
||||||
|
Scott Stafford <scott.stafford@gmail.com>
|
||||||
|
* Added Swap(), SwapElements(), and RemoveLast() to Reflection interface.
|
||||||
|
Alexander Melnikov <alm@sibmail.ru>
|
||||||
|
* HPUX support.
|
||||||
|
Oliver Jowett <oliver.jowett@gmail.com>
|
||||||
|
* Detect whether zlib is new enough in configure script.
|
||||||
|
* Fixes for Solaris 10 32/64-bit confusion.
|
||||||
|
Evan Jones <evanj@mit.edu>
|
||||||
|
* Optimize Java serialization code when writing a small message to a stream.
|
||||||
|
* Optimize Java serialization of strings so that UTF-8 encoding happens only
|
||||||
|
once per string per serialization call.
|
||||||
|
* Clean up some Java warnings.
|
||||||
|
* Fix bug with permanent callbacks that delete themselves when run.
|
||||||
|
Michael Kucharski <m.kucharski@gmail.com>
|
||||||
|
* Added CodedInputStream.getTotalBytesRead().
|
||||||
|
Kacper Kowalik <xarthisius.kk@gmail.com>
|
||||||
|
* Fixed m4/acx_pthread.m4 problem for some Linux distributions.
|
||||||
|
William Orr <will@worrbase.com>
|
||||||
|
* Fixed detection of sched_yield on Solaris.
|
||||||
|
* Added atomicops for Solaris
|
||||||
|
Andrew Paprocki <andrew@ishiboo.com>
|
||||||
|
* Fixed minor IBM xlC compiler build issues
|
||||||
|
* Added atomicops for AIX (POWER)
|
||||||
|
Nipunn Koorapati <nipunn1313@gmail.com>
|
||||||
|
* Provide a type alias field ValueType on EnumTypeWrapper
|
||||||
|
* Match service argument names to abstract interface
|
||||||
|
|
||||||
|
|
||||||
32
LICENSE
Normal file
32
LICENSE
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
Copyright 2008 Google Inc. All rights reserved.
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
Code generated by the Protocol Buffer compiler is owned by the owner
|
||||||
|
of the input file used when generating it. This code is not
|
||||||
|
standalone and requires a support library to be linked with it. This
|
||||||
|
support library is itself covered by the above license.
|
||||||
40
Protobuf-C++.podspec
Normal file
40
Protobuf-C++.podspec
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
Pod::Spec.new do |s|
|
||||||
|
s.name = 'Protobuf-C++'
|
||||||
|
s.version = '3.21.8'
|
||||||
|
s.summary = 'Protocol Buffers v3 runtime library for C++.'
|
||||||
|
s.homepage = 'https://github.com/google/protobuf'
|
||||||
|
s.license = 'BSD-3-Clause'
|
||||||
|
s.authors = { 'The Protocol Buffers contributors' => 'protobuf@googlegroups.com' }
|
||||||
|
s.cocoapods_version = '>= 1.0'
|
||||||
|
|
||||||
|
s.source = { :git => 'https://github.com/google/protobuf.git',
|
||||||
|
:tag => "v#{s.version}" }
|
||||||
|
|
||||||
|
s.source_files = 'src/google/protobuf/*.{h,cc,inc}',
|
||||||
|
'src/google/protobuf/stubs/*.{h,cc}',
|
||||||
|
'src/google/protobuf/io/*.{h,cc}',
|
||||||
|
'src/google/protobuf/util/*.{h,cc}'
|
||||||
|
|
||||||
|
# Excluding all the tests in the directories above
|
||||||
|
s.exclude_files = 'src/google/**/*_test.{h,cc,inc}',
|
||||||
|
'src/google/**/*_unittest.{h,cc}',
|
||||||
|
'src/google/protobuf/test_util*.{h,cc}',
|
||||||
|
'src/google/protobuf/map_lite_test_util.{h,cc}',
|
||||||
|
'src/google/protobuf/map_test_util*.{h,cc,inc}',
|
||||||
|
'src/google/protobuf/reflection_tester.{h,cc}'
|
||||||
|
|
||||||
|
s.header_mappings_dir = 'src'
|
||||||
|
|
||||||
|
s.ios.deployment_target = '7.0'
|
||||||
|
s.osx.deployment_target = '10.9'
|
||||||
|
s.tvos.deployment_target = '9.0'
|
||||||
|
s.watchos.deployment_target = '2.0'
|
||||||
|
|
||||||
|
s.pod_target_xcconfig = {
|
||||||
|
# Do not let src/google/protobuf/stubs/time.h override system API
|
||||||
|
'USE_HEADERMAP' => 'NO',
|
||||||
|
'ALWAYS_SEARCH_USER_PATHS' => 'NO',
|
||||||
|
'HEADER_SEARCH_PATHS' => '"$(PODS_TARGET_SRCROOT)/src"'
|
||||||
|
}
|
||||||
|
|
||||||
|
end
|
||||||
50
Protobuf.podspec
Normal file
50
Protobuf.podspec
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
# This file describes to Cocoapods how to integrate the Objective-C runtime into a dependent
|
||||||
|
# project.
|
||||||
|
# Despite this file being specific to Objective-C, it needs to be on the root of the repository.
|
||||||
|
# Otherwise, Cocoapods gives trouble like not picking up the license file correctly, or not letting
|
||||||
|
# dependent projects use the :git notation to refer to the library.
|
||||||
|
Pod::Spec.new do |s|
|
||||||
|
s.name = 'Protobuf'
|
||||||
|
s.version = '3.21.8'
|
||||||
|
s.summary = 'Protocol Buffers v.3 runtime library for Objective-C.'
|
||||||
|
s.homepage = 'https://github.com/protocolbuffers/protobuf'
|
||||||
|
s.license = 'BSD-3-Clause'
|
||||||
|
s.authors = { 'The Protocol Buffers contributors' => 'protobuf@googlegroups.com' }
|
||||||
|
s.cocoapods_version = '>= 1.0'
|
||||||
|
|
||||||
|
s.source = { :git => 'https://github.com/protocolbuffers/protobuf.git',
|
||||||
|
:tag => "v#{s.version}" }
|
||||||
|
|
||||||
|
s.source_files = 'objectivec/*.{h,m}',
|
||||||
|
'objectivec/google/protobuf/Any.pbobjc.h',
|
||||||
|
'objectivec/google/protobuf/Api.pbobjc.h',
|
||||||
|
'objectivec/google/protobuf/Duration.pbobjc.h',
|
||||||
|
'objectivec/google/protobuf/Empty.pbobjc.h',
|
||||||
|
'objectivec/google/protobuf/FieldMask.pbobjc.h',
|
||||||
|
'objectivec/google/protobuf/SourceContext.pbobjc.h',
|
||||||
|
'objectivec/google/protobuf/Struct.pbobjc.h',
|
||||||
|
'objectivec/google/protobuf/Timestamp.pbobjc.h',
|
||||||
|
'objectivec/google/protobuf/Type.pbobjc.h',
|
||||||
|
'objectivec/google/protobuf/Wrappers.pbobjc.h'
|
||||||
|
# The following would cause duplicate symbol definitions. GPBProtocolBuffers is expected to be
|
||||||
|
# left out, as it's an umbrella implementation file.
|
||||||
|
s.exclude_files = 'objectivec/GPBProtocolBuffers.m'
|
||||||
|
|
||||||
|
# Set a CPP symbol so the code knows to use framework imports.
|
||||||
|
s.user_target_xcconfig = { 'GCC_PREPROCESSOR_DEFINITIONS' => '$(inherited) GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS=1' }
|
||||||
|
s.pod_target_xcconfig = { 'GCC_PREPROCESSOR_DEFINITIONS' => '$(inherited) GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS=1' }
|
||||||
|
|
||||||
|
s.ios.deployment_target = '10.0'
|
||||||
|
s.osx.deployment_target = '10.12'
|
||||||
|
s.tvos.deployment_target = '12.0'
|
||||||
|
s.watchos.deployment_target = '6.0'
|
||||||
|
s.requires_arc = false
|
||||||
|
|
||||||
|
# The unittest need the generate sources from the testing related .proto
|
||||||
|
# files. So to add a `test_spec`, there would also need to be something like a
|
||||||
|
# `script_phases` to generate them, but there would also need to be a way to
|
||||||
|
# ensure `protoc` had be built. Another option would be to move to a model
|
||||||
|
# where the needed files are always generated and checked in. Neither of these
|
||||||
|
# seem that great at the moment, so the tests have *not* been wired into here
|
||||||
|
# at this time.
|
||||||
|
end
|
||||||
91
README.md
Normal file
91
README.md
Normal file
@@ -0,0 +1,91 @@
|
|||||||
|
Protocol Buffers - Google's data interchange format
|
||||||
|
===================================================
|
||||||
|
|
||||||
|
Copyright 2008 Google Inc.
|
||||||
|
|
||||||
|
https://developers.google.com/protocol-buffers/
|
||||||
|
|
||||||
|
Overview
|
||||||
|
--------
|
||||||
|
|
||||||
|
Protocol Buffers (a.k.a., protobuf) are Google's language-neutral,
|
||||||
|
platform-neutral, extensible mechanism for serializing structured data. You
|
||||||
|
can find [protobuf's documentation on the Google Developers site](https://developers.google.com/protocol-buffers/).
|
||||||
|
|
||||||
|
This README file contains protobuf installation instructions. To install
|
||||||
|
protobuf, you need to install the protocol compiler (used to compile .proto
|
||||||
|
files) and the protobuf runtime for your chosen programming language.
|
||||||
|
|
||||||
|
Protocol Compiler Installation
|
||||||
|
------------------------------
|
||||||
|
|
||||||
|
The protocol compiler is written in C++. If you are using C++, please follow
|
||||||
|
the [C++ Installation Instructions](src/README.md) to install protoc along
|
||||||
|
with the C++ runtime.
|
||||||
|
|
||||||
|
For non-C++ users, the simplest way to install the protocol compiler is to
|
||||||
|
download a pre-built binary from our release page:
|
||||||
|
|
||||||
|
[https://github.com/protocolbuffers/protobuf/releases](https://github.com/protocolbuffers/protobuf/releases)
|
||||||
|
|
||||||
|
In the downloads section of each release, you can find pre-built binaries in
|
||||||
|
zip packages: protoc-$VERSION-$PLATFORM.zip. It contains the protoc binary
|
||||||
|
as well as a set of standard .proto files distributed along with protobuf.
|
||||||
|
|
||||||
|
If you are looking for an old version that is not available in the release
|
||||||
|
page, check out the maven repo here:
|
||||||
|
|
||||||
|
[https://repo1.maven.org/maven2/com/google/protobuf/protoc/](https://repo1.maven.org/maven2/com/google/protobuf/protoc/)
|
||||||
|
|
||||||
|
These pre-built binaries are only provided for released versions. If you want
|
||||||
|
to use the github main version at HEAD, or you need to modify protobuf code,
|
||||||
|
or you are using C++, it's recommended to build your own protoc binary from
|
||||||
|
source.
|
||||||
|
|
||||||
|
If you would like to build protoc binary from source, see the [C++ Installation Instructions](src/README.md).
|
||||||
|
|
||||||
|
Protobuf Runtime Installation
|
||||||
|
-----------------------------
|
||||||
|
|
||||||
|
Protobuf supports several different programming languages. For each programming
|
||||||
|
language, you can find instructions in the corresponding source directory about
|
||||||
|
how to install protobuf runtime for that specific language:
|
||||||
|
|
||||||
|
| Language | Source |
|
||||||
|
|--------------------------------------|-------------------------------------------------------------|
|
||||||
|
| C++ (include C++ runtime and protoc) | [src](src) |
|
||||||
|
| Java | [java](java) |
|
||||||
|
| Python | [python](python) |
|
||||||
|
| Objective-C | [objectivec](objectivec) |
|
||||||
|
| C# | [csharp](csharp) |
|
||||||
|
| Ruby | [ruby](ruby) |
|
||||||
|
| Go | [protocolbuffers/protobuf-go](https://github.com/protocolbuffers/protobuf-go)|
|
||||||
|
| PHP | [php](php) |
|
||||||
|
| Dart | [dart-lang/protobuf](https://github.com/dart-lang/protobuf) |
|
||||||
|
| Javascript | [protocolbuffers/protobuf-javascript](https://github.com/protocolbuffers/protobuf-javascript)|
|
||||||
|
|
||||||
|
Quick Start
|
||||||
|
-----------
|
||||||
|
|
||||||
|
The best way to learn how to use protobuf is to follow the tutorials in our
|
||||||
|
developer guide:
|
||||||
|
|
||||||
|
https://developers.google.com/protocol-buffers/docs/tutorials
|
||||||
|
|
||||||
|
If you want to learn from code examples, take a look at the examples in the
|
||||||
|
[examples](examples) directory.
|
||||||
|
|
||||||
|
Documentation
|
||||||
|
-------------
|
||||||
|
|
||||||
|
The complete documentation for Protocol Buffers is available via the
|
||||||
|
web at:
|
||||||
|
|
||||||
|
https://developers.google.com/protocol-buffers/
|
||||||
|
|
||||||
|
Developer Community
|
||||||
|
-------------------
|
||||||
|
|
||||||
|
To be alerted to upcoming changes in Protocol Buffers and connect with protobuf developers and users,
|
||||||
|
[join the Google Group](https://groups.google.com/g/protobuf).
|
||||||
|
|
||||||
4
SECURITY.md
Normal file
4
SECURITY.md
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
To report security concerns or vulnerabilities within protobuf, please use
|
||||||
|
Google's official channel for reporting these.
|
||||||
|
|
||||||
|
https://www.google.com/appserve/security-bugs/m2/new
|
||||||
89
WORKSPACE
Normal file
89
WORKSPACE
Normal file
@@ -0,0 +1,89 @@
|
|||||||
|
workspace(name = "com_google_protobuf")
|
||||||
|
|
||||||
|
load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
|
||||||
|
|
||||||
|
local_repository(
|
||||||
|
name = "com_google_protobuf_examples",
|
||||||
|
path = "examples",
|
||||||
|
)
|
||||||
|
|
||||||
|
http_archive(
|
||||||
|
name = "com_google_googletest",
|
||||||
|
sha256 = "ea54c9845568cb31c03f2eddc7a40f7f83912d04ab977ff50ec33278119548dd",
|
||||||
|
strip_prefix = "googletest-4c9a3bb62bf3ba1f1010bf96f9c8ed767b363774",
|
||||||
|
urls = [
|
||||||
|
"https://github.com/google/googletest/archive/4c9a3bb62bf3ba1f1010bf96f9c8ed767b363774.tar.gz",
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
|
http_archive(
|
||||||
|
name = "com_googlesource_code_re2",
|
||||||
|
sha256 = "906d0df8ff48f8d3a00a808827f009a840190f404559f649cb8e4d7143255ef9",
|
||||||
|
strip_prefix = "re2-a276a8c738735a0fe45a6ee590fe2df69bcf4502",
|
||||||
|
urls = ["https://github.com/google/re2/archive/a276a8c738735a0fe45a6ee590fe2df69bcf4502.zip"], # 2022-04-08
|
||||||
|
)
|
||||||
|
|
||||||
|
# Bazel platform rules.
|
||||||
|
http_archive(
|
||||||
|
name = "platforms",
|
||||||
|
sha256 = "a879ea428c6d56ab0ec18224f976515948822451473a80d06c2e50af0bbe5121",
|
||||||
|
strip_prefix = "platforms-da5541f26b7de1dc8e04c075c99df5351742a4a2",
|
||||||
|
urls = ["https://github.com/bazelbuild/platforms/archive/da5541f26b7de1dc8e04c075c99df5351742a4a2.zip"], # 2022-05-27
|
||||||
|
)
|
||||||
|
|
||||||
|
# Load common dependencies.
|
||||||
|
load("//:protobuf_deps.bzl", "PROTOBUF_MAVEN_ARTIFACTS", "protobuf_deps")
|
||||||
|
protobuf_deps()
|
||||||
|
|
||||||
|
load("@rules_jvm_external//:defs.bzl", "maven_install")
|
||||||
|
|
||||||
|
maven_install(
|
||||||
|
artifacts = PROTOBUF_MAVEN_ARTIFACTS,
|
||||||
|
# For updating instructions, see:
|
||||||
|
# https://github.com/bazelbuild/rules_jvm_external#updating-maven_installjson
|
||||||
|
maven_install_json = "//:maven_install.json",
|
||||||
|
repositories = [
|
||||||
|
"https://repo1.maven.org/maven2",
|
||||||
|
"https://repo.maven.apache.org/maven2",
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
|
load("@maven//:defs.bzl", "pinned_maven_install")
|
||||||
|
|
||||||
|
pinned_maven_install()
|
||||||
|
|
||||||
|
# For `cc_proto_blacklist_test` and `build_test`.
|
||||||
|
load("@bazel_skylib//:workspace.bzl", "bazel_skylib_workspace")
|
||||||
|
|
||||||
|
load("@rules_python//python:pip.bzl", "pip_install")
|
||||||
|
|
||||||
|
pip_install(
|
||||||
|
name="pip_deps",
|
||||||
|
requirements = "//python:requirements.txt"
|
||||||
|
)
|
||||||
|
|
||||||
|
bazel_skylib_workspace()
|
||||||
|
|
||||||
|
load("@rules_pkg//:deps.bzl", "rules_pkg_dependencies")
|
||||||
|
rules_pkg_dependencies()
|
||||||
|
|
||||||
|
# For `kt_jvm_library`
|
||||||
|
load("@io_bazel_rules_kotlin//kotlin:repositories.bzl", "kotlin_repositories")
|
||||||
|
kotlin_repositories()
|
||||||
|
|
||||||
|
load("@io_bazel_rules_kotlin//kotlin:core.bzl", "kt_register_toolchains")
|
||||||
|
kt_register_toolchains()
|
||||||
|
|
||||||
|
load("@upb//bazel:workspace_deps.bzl", "upb_deps")
|
||||||
|
upb_deps()
|
||||||
|
|
||||||
|
load("@upb//bazel:system_python.bzl", "system_python")
|
||||||
|
system_python(name = "local_config_python")
|
||||||
|
|
||||||
|
load("@utf8_range//:workspace_deps.bzl", "utf8_range_deps")
|
||||||
|
utf8_range_deps()
|
||||||
|
|
||||||
|
bind(
|
||||||
|
name = "python_headers",
|
||||||
|
actual = "@local_config_python//:python_headers",
|
||||||
|
)
|
||||||
48
appveyor.bat
Normal file
48
appveyor.bat
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
setlocal
|
||||||
|
|
||||||
|
IF %platform%==MinGW GOTO build_mingw
|
||||||
|
IF %language%==cpp GOTO build_cpp
|
||||||
|
IF %language%==csharp GOTO build_csharp
|
||||||
|
|
||||||
|
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
|
||||||
|
cd build_msvc
|
||||||
|
cmake -G "%generator%" -Dprotobuf_BUILD_SHARED_LIBS=%BUILD_DLL% -Dprotobuf_UNICODE=%UNICODE% ../cmake
|
||||||
|
msbuild protobuf.sln /p:Platform=%vcplatform% /logger:"C:\Program Files\AppVeyor\BuildAgent\Appveyor.MSBuildLogger.dll" || goto error
|
||||||
|
cd %configuration%
|
||||||
|
tests.exe || goto error
|
||||||
|
goto :EOF
|
||||||
|
|
||||||
|
:build_csharp
|
||||||
|
echo Building C#
|
||||||
|
cd csharp\src
|
||||||
|
REM The platform environment variable is implicitly used by msbuild;
|
||||||
|
REM we don't want it.
|
||||||
|
set platform=
|
||||||
|
dotnet restore
|
||||||
|
dotnet build -c %configuration% || goto error
|
||||||
|
|
||||||
|
echo Testing C#
|
||||||
|
dotnet test -c %configuration% -f netcoreapp3.1 Google.Protobuf.Test\Google.Protobuf.Test.csproj || goto error
|
||||||
|
dotnet test -c %configuration% -f net451 Google.Protobuf.Test\Google.Protobuf.Test.csproj || goto error
|
||||||
|
|
||||||
|
goto :EOF
|
||||||
|
|
||||||
|
:error
|
||||||
|
echo Failed!
|
||||||
|
EXIT /b %ERRORLEVEL%
|
||||||
47
appveyor.yml
Normal file
47
appveyor.yml
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
configuration:
|
||||||
|
- Debug
|
||||||
|
|
||||||
|
environment:
|
||||||
|
matrix:
|
||||||
|
# Only test few combinations: "Visual Studio 2017 (15) + 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 2017
|
||||||
|
|
||||||
|
- platform: Win64
|
||||||
|
language: cpp
|
||||||
|
image: Visual Studio 2017
|
||||||
|
BUILD_DLL: ON
|
||||||
|
UNICODE: ON
|
||||||
|
|
||||||
|
- platform: Win64
|
||||||
|
language: cpp
|
||||||
|
image: Visual Studio 2017
|
||||||
|
BUILD_DLL: OFF
|
||||||
|
UNICODE: ON
|
||||||
|
|
||||||
|
- platform: Win64
|
||||||
|
language: csharp
|
||||||
|
image: Visual Studio 2017
|
||||||
|
|
||||||
|
# Our build scripts run tests automatically; we don't want AppVeyor
|
||||||
|
# to try to detect them itself.
|
||||||
|
test: off
|
||||||
|
|
||||||
|
install:
|
||||||
|
- git submodule update --init --recursive
|
||||||
|
|
||||||
|
before_build:
|
||||||
|
- if %platform%==MinGW set generator=MinGW Makefiles
|
||||||
|
- if %platform%==Win32 set generator=Visual Studio 15
|
||||||
|
- if %platform%==Win64 set generator=Visual Studio 15 Win64
|
||||||
|
- if %platform%==Win32 set vcplatform=Win32
|
||||||
|
- if %platform%==Win64 set vcplatform=x64
|
||||||
|
|
||||||
|
build_script:
|
||||||
|
- CALL appveyor.bat
|
||||||
|
|
||||||
|
skip_commits:
|
||||||
|
message: /.*\[skip appveyor\].*/
|
||||||
183
build_defs/BUILD.bazel
Normal file
183
build_defs/BUILD.bazel
Normal file
@@ -0,0 +1,183 @@
|
|||||||
|
# Internal Starlark definitions for Protobuf.
|
||||||
|
|
||||||
|
load("@rules_cc//cc:defs.bzl", starlark_cc_proto_library = "cc_proto_library")
|
||||||
|
load("@rules_pkg//:mappings.bzl", "pkg_files", "strip_prefix")
|
||||||
|
load(":cc_proto_blacklist_test.bzl", "cc_proto_blacklist_test")
|
||||||
|
load(":compiler_config_setting.bzl", "create_compiler_config_setting")
|
||||||
|
|
||||||
|
package(
|
||||||
|
default_visibility = [
|
||||||
|
# Public, but Protobuf only visibility.
|
||||||
|
"//:__subpackages__",
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
|
create_compiler_config_setting(
|
||||||
|
name = "config_msvc",
|
||||||
|
value = "msvc-cl",
|
||||||
|
)
|
||||||
|
|
||||||
|
config_setting(
|
||||||
|
name = "aarch64",
|
||||||
|
values = {"cpu": "linux-aarch_64"},
|
||||||
|
)
|
||||||
|
|
||||||
|
config_setting(
|
||||||
|
name = "x86_64",
|
||||||
|
values = {"cpu": "linux-x86_64"},
|
||||||
|
)
|
||||||
|
|
||||||
|
# Android NDK builds can specify different crosstool_top flags to choose which
|
||||||
|
# STL they use for C++. We need these multiple variants to catch all of those
|
||||||
|
# versions of crosstool_top and reliably detect Android.
|
||||||
|
#
|
||||||
|
# For more info on the various crosstool_tops used by NDK Bazel builds, see:
|
||||||
|
# https://docs.bazel.build/versions/master/android-ndk.html#configuring-the-stl
|
||||||
|
|
||||||
|
config_setting(
|
||||||
|
name = "config_android",
|
||||||
|
values = {
|
||||||
|
"crosstool_top": "//external:android/crosstool",
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
config_setting(
|
||||||
|
name = "config_android-stlport",
|
||||||
|
values = {
|
||||||
|
"crosstool_top": "@androidndk//:toolchain-stlport",
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
config_setting(
|
||||||
|
name = "config_android-libcpp",
|
||||||
|
values = {
|
||||||
|
"crosstool_top": "@androidndk//:toolchain-libcpp",
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
config_setting(
|
||||||
|
name = "config_android-gnu-libstdcpp",
|
||||||
|
values = {
|
||||||
|
"crosstool_top": "@androidndk//:toolchain-gnu-libstdcpp",
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
config_setting(
|
||||||
|
name = "config_android-default",
|
||||||
|
values = {
|
||||||
|
"crosstool_top": "@androidndk//:default_crosstool",
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
config_setting(
|
||||||
|
name = "config_win32",
|
||||||
|
values = {
|
||||||
|
"cpu": "win32",
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
config_setting(
|
||||||
|
name = "config_win64",
|
||||||
|
values = {
|
||||||
|
"cpu": "win64",
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
# Internal testing:
|
||||||
|
|
||||||
|
starlark_cc_proto_library(
|
||||||
|
name = "any_cc_proto",
|
||||||
|
visibility = ["//visibility:private"],
|
||||||
|
deps = ["//:any_proto"],
|
||||||
|
)
|
||||||
|
|
||||||
|
starlark_cc_proto_library(
|
||||||
|
name = "api_cc_proto",
|
||||||
|
visibility = ["//visibility:private"],
|
||||||
|
deps = ["//:api_proto"],
|
||||||
|
)
|
||||||
|
|
||||||
|
starlark_cc_proto_library(
|
||||||
|
name = "compiler_plugin_cc_proto",
|
||||||
|
visibility = ["//visibility:private"],
|
||||||
|
deps = ["//:compiler_plugin_proto"],
|
||||||
|
)
|
||||||
|
|
||||||
|
starlark_cc_proto_library(
|
||||||
|
name = "descriptor_cc_proto",
|
||||||
|
visibility = ["//visibility:private"],
|
||||||
|
deps = ["//:descriptor_proto"],
|
||||||
|
)
|
||||||
|
|
||||||
|
starlark_cc_proto_library(
|
||||||
|
name = "duration_cc_proto",
|
||||||
|
visibility = ["//visibility:private"],
|
||||||
|
deps = ["//:duration_proto"],
|
||||||
|
)
|
||||||
|
|
||||||
|
starlark_cc_proto_library(
|
||||||
|
name = "empty_cc_proto",
|
||||||
|
visibility = ["//visibility:private"],
|
||||||
|
deps = ["//:empty_proto"],
|
||||||
|
)
|
||||||
|
|
||||||
|
starlark_cc_proto_library(
|
||||||
|
name = "field_mask_cc_proto",
|
||||||
|
visibility = ["//visibility:private"],
|
||||||
|
deps = ["//:field_mask_proto"],
|
||||||
|
)
|
||||||
|
|
||||||
|
starlark_cc_proto_library(
|
||||||
|
name = "source_context_cc_proto",
|
||||||
|
visibility = ["//visibility:private"],
|
||||||
|
deps = ["//:source_context_proto"],
|
||||||
|
)
|
||||||
|
|
||||||
|
starlark_cc_proto_library(
|
||||||
|
name = "struct_cc_proto",
|
||||||
|
visibility = ["//visibility:private"],
|
||||||
|
deps = ["//:struct_proto"],
|
||||||
|
)
|
||||||
|
|
||||||
|
starlark_cc_proto_library(
|
||||||
|
name = "timestamp_cc_proto",
|
||||||
|
visibility = ["//visibility:private"],
|
||||||
|
deps = ["//:timestamp_proto"],
|
||||||
|
)
|
||||||
|
|
||||||
|
starlark_cc_proto_library(
|
||||||
|
name = "type_cc_proto",
|
||||||
|
visibility = ["//visibility:private"],
|
||||||
|
deps = ["//:type_proto"],
|
||||||
|
)
|
||||||
|
|
||||||
|
starlark_cc_proto_library(
|
||||||
|
name = "wrappers_cc_proto",
|
||||||
|
visibility = ["//visibility:private"],
|
||||||
|
deps = ["//:wrappers_proto"],
|
||||||
|
)
|
||||||
|
|
||||||
|
cc_proto_blacklist_test(
|
||||||
|
name = "cc_proto_blacklist_test",
|
||||||
|
deps = [
|
||||||
|
":any_cc_proto",
|
||||||
|
":api_cc_proto",
|
||||||
|
":compiler_plugin_cc_proto",
|
||||||
|
":descriptor_cc_proto",
|
||||||
|
":duration_cc_proto",
|
||||||
|
":empty_cc_proto",
|
||||||
|
":field_mask_cc_proto",
|
||||||
|
":source_context_cc_proto",
|
||||||
|
":struct_cc_proto",
|
||||||
|
":timestamp_cc_proto",
|
||||||
|
":type_cc_proto",
|
||||||
|
":wrappers_cc_proto",
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
|
pkg_files(
|
||||||
|
name = "dist_files",
|
||||||
|
srcs = glob(["*"]),
|
||||||
|
strip_prefix = strip_prefix.from_root(""),
|
||||||
|
visibility = ["//pkg:__pkg__"],
|
||||||
|
)
|
||||||
56
build_defs/arch_tests.bzl
Normal file
56
build_defs/arch_tests.bzl
Normal file
@@ -0,0 +1,56 @@
|
|||||||
|
"""Generated unittests to verify that a binary is built for the expected architecture."""
|
||||||
|
|
||||||
|
load("//build_defs:internal_shell.bzl", "inline_sh_test")
|
||||||
|
|
||||||
|
def _arch_test_impl(
|
||||||
|
name,
|
||||||
|
platform,
|
||||||
|
file_platform,
|
||||||
|
bazel_binaries = [],
|
||||||
|
system_binaries = [],
|
||||||
|
**kwargs):
|
||||||
|
"""Bazel rule to verify that a Bazel or system binary is built for the aarch64 architecture.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
name: the name of the test.
|
||||||
|
platform: a diagnostic name for this architecture.
|
||||||
|
file_platform: the expected output of `file`.
|
||||||
|
bazel_binaries: a set of binary targets to inspect.
|
||||||
|
system_binaries: a set of paths to system executables to inspect.
|
||||||
|
**kwargs: other keyword arguments that are passed to the test.
|
||||||
|
"""
|
||||||
|
|
||||||
|
inline_sh_test(
|
||||||
|
name = name,
|
||||||
|
tools = bazel_binaries,
|
||||||
|
cmd = """
|
||||||
|
for binary in "$(rootpaths %s) %s"; do
|
||||||
|
(file -L $$binary | grep -q "%s") \
|
||||||
|
|| (echo "Test binary is not an %s binary: "; file -L $$binary; exit 1)
|
||||||
|
done
|
||||||
|
""" % (
|
||||||
|
" ".join(bazel_binaries),
|
||||||
|
" ".join(system_binaries),
|
||||||
|
file_platform,
|
||||||
|
platform,
|
||||||
|
),
|
||||||
|
target_compatible_with = select({
|
||||||
|
"//build_defs:" + platform: [],
|
||||||
|
"//conditions:default": ["@platforms//:incompatible"],
|
||||||
|
}),
|
||||||
|
**kwargs
|
||||||
|
)
|
||||||
|
|
||||||
|
def aarch64_test(**kwargs):
|
||||||
|
_arch_test_impl(
|
||||||
|
platform = "aarch64",
|
||||||
|
file_platform = "ELF 64-bit LSB executable, ARM aarch64",
|
||||||
|
**kwargs
|
||||||
|
)
|
||||||
|
|
||||||
|
def x86_64_test(**kwargs):
|
||||||
|
_arch_test_impl(
|
||||||
|
platform = "x86_64",
|
||||||
|
file_platform = "ELF 64-bit LSB executable, ARM x86_64",
|
||||||
|
**kwargs
|
||||||
|
)
|
||||||
38
build_defs/cc_proto_blacklist_test.bzl
Normal file
38
build_defs/cc_proto_blacklist_test.bzl
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
"""Contains a unittest to verify that `cc_proto_library` does not generate code for blacklisted `.proto` sources (i.e. WKPs)."""
|
||||||
|
|
||||||
|
load("@bazel_skylib//lib:unittest.bzl", "asserts", "unittest")
|
||||||
|
|
||||||
|
def _cc_proto_blacklist_test_impl(ctx):
|
||||||
|
"""Verifies that there are no C++ compile actions for Well-Known-Protos.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
ctx: The rule context.
|
||||||
|
|
||||||
|
Returns: A (not further specified) sequence of providers.
|
||||||
|
"""
|
||||||
|
|
||||||
|
env = unittest.begin(ctx)
|
||||||
|
|
||||||
|
for dep in ctx.attr.deps:
|
||||||
|
files = dep.files.to_list()
|
||||||
|
asserts.equals(
|
||||||
|
env,
|
||||||
|
[],
|
||||||
|
files,
|
||||||
|
"Expected that target '{}' does not provide files, got {}".format(
|
||||||
|
dep.label,
|
||||||
|
len(files),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
return unittest.end(env)
|
||||||
|
|
||||||
|
cc_proto_blacklist_test = unittest.make(
|
||||||
|
impl = _cc_proto_blacklist_test_impl,
|
||||||
|
attrs = {
|
||||||
|
"deps": attr.label_list(
|
||||||
|
mandatory = True,
|
||||||
|
providers = [CcInfo],
|
||||||
|
),
|
||||||
|
},
|
||||||
|
)
|
||||||
23
build_defs/compiler_config_setting.bzl
Normal file
23
build_defs/compiler_config_setting.bzl
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
"""Creates config_setting that allows selecting based on 'compiler' value."""
|
||||||
|
|
||||||
|
def create_compiler_config_setting(name, value, visibility = None):
|
||||||
|
# The "do_not_use_tools_cpp_compiler_present" attribute exists to
|
||||||
|
# distinguish between older versions of Bazel that do not support
|
||||||
|
# "@bazel_tools//tools/cpp:compiler" flag_value, and newer ones that do.
|
||||||
|
# In the future, the only way to select on the compiler will be through
|
||||||
|
# flag_values{"@bazel_tools//tools/cpp:compiler"} and the else branch can
|
||||||
|
# be removed.
|
||||||
|
if hasattr(cc_common, "do_not_use_tools_cpp_compiler_present"):
|
||||||
|
native.config_setting(
|
||||||
|
name = name,
|
||||||
|
flag_values = {
|
||||||
|
"@bazel_tools//tools/cpp:compiler": value,
|
||||||
|
},
|
||||||
|
visibility = visibility,
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
native.config_setting(
|
||||||
|
name = name,
|
||||||
|
values = {"compiler": value},
|
||||||
|
visibility = visibility,
|
||||||
|
)
|
||||||
47
build_defs/cpp_opts.bzl
Normal file
47
build_defs/cpp_opts.bzl
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
"""C++ compile/link options for Protobuf libraries."""
|
||||||
|
|
||||||
|
COPTS = select({
|
||||||
|
"//build_defs:config_msvc": [
|
||||||
|
"/wd4065", # switch statement contains 'default' but no 'case' labels
|
||||||
|
"/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'
|
||||||
|
"/wd4800", # 'type' : forcing value to bool 'true' or 'false' (performance warning)
|
||||||
|
"/wd4996", # The compiler encountered a deprecated declaration.
|
||||||
|
],
|
||||||
|
"//conditions:default": [
|
||||||
|
"-DHAVE_ZLIB",
|
||||||
|
"-Woverloaded-virtual",
|
||||||
|
"-Wno-sign-compare",
|
||||||
|
"-Werror",
|
||||||
|
],
|
||||||
|
})
|
||||||
|
# Android and MSVC builds do not need to link in a separate pthread library.
|
||||||
|
LINK_OPTS = select({
|
||||||
|
"//build_defs:config_android": [],
|
||||||
|
"//build_defs:config_android-stlport": [],
|
||||||
|
"//build_defs:config_android-libcpp": [],
|
||||||
|
"//build_defs:config_android-gnu-libstdcpp": [],
|
||||||
|
"//build_defs:config_android-default": [],
|
||||||
|
"//build_defs:config_msvc": [
|
||||||
|
# Suppress linker warnings about files with no symbols defined.
|
||||||
|
"-ignore:4221",
|
||||||
|
],
|
||||||
|
"//conditions:default": [
|
||||||
|
"-lpthread",
|
||||||
|
"-lm",
|
||||||
|
],
|
||||||
|
})
|
||||||
|
|
||||||
|
# When cross-compiling for Windows we need to statically link pthread and the C++ library.
|
||||||
|
PROTOC_LINK_OPTS = select({
|
||||||
|
"//build_defs:config_win32": ["-static"],
|
||||||
|
"//build_defs:config_win64": ["-static"],
|
||||||
|
"//conditions:default": [],
|
||||||
|
})
|
||||||
93
build_defs/internal_shell.bzl
Normal file
93
build_defs/internal_shell.bzl
Normal file
@@ -0,0 +1,93 @@
|
|||||||
|
"""
|
||||||
|
Internal tools to migrate shell commands to Bazel as an intermediate step
|
||||||
|
to wider Bazelification.
|
||||||
|
"""
|
||||||
|
|
||||||
|
def inline_sh_binary(
|
||||||
|
name,
|
||||||
|
srcs = [],
|
||||||
|
tools = [],
|
||||||
|
deps = [],
|
||||||
|
cmd = "",
|
||||||
|
testonly = None,
|
||||||
|
**kwargs):
|
||||||
|
"""Bazel rule to wrap up an inline bash script in a binary.
|
||||||
|
|
||||||
|
This is most useful as a stop-gap solution for migrating off Autotools.
|
||||||
|
These binaries are likely to be non-hermetic, with implicit system
|
||||||
|
dependencies.
|
||||||
|
|
||||||
|
NOTE: the rule is only an internal workaround. The interface may change and
|
||||||
|
the rule may be removed when everything is properly "Bazelified".
|
||||||
|
|
||||||
|
Args:
|
||||||
|
name: the name of the inline_sh_binary.
|
||||||
|
srcs: the files used directly by the script.
|
||||||
|
tools: the executable tools used directly by the script. Any target used
|
||||||
|
with rootpath/execpath/location must be declared here or in `srcs`.
|
||||||
|
deps: a list of dependency labels that are required to run this binary.
|
||||||
|
cmd: the inline sh command to run.
|
||||||
|
**kwargs: other keyword arguments that are passed to sh_binary.
|
||||||
|
testonly: common rule attribute (see:
|
||||||
|
https://bazel.build/reference/be/common-definitions#common-attributes)
|
||||||
|
"""
|
||||||
|
|
||||||
|
native.genrule(
|
||||||
|
name = name + "_genrule",
|
||||||
|
srcs = srcs,
|
||||||
|
exec_tools = tools,
|
||||||
|
outs = [name + ".sh"],
|
||||||
|
cmd = "cat <<'EOF' >$(OUTS)\n#!/bin/bash -exu\n%s\nEOF\n" % cmd,
|
||||||
|
testonly = testonly,
|
||||||
|
visibility = ["//visibility:private"],
|
||||||
|
)
|
||||||
|
|
||||||
|
native.sh_binary(
|
||||||
|
name = name,
|
||||||
|
srcs = [name + "_genrule"],
|
||||||
|
data = srcs + tools + deps,
|
||||||
|
testonly = testonly,
|
||||||
|
**kwargs
|
||||||
|
)
|
||||||
|
|
||||||
|
def inline_sh_test(
|
||||||
|
name,
|
||||||
|
srcs = [],
|
||||||
|
tools = [],
|
||||||
|
deps = [],
|
||||||
|
cmd = "",
|
||||||
|
**kwargs):
|
||||||
|
"""Bazel rule to wrap up an inline bash script in a test.
|
||||||
|
|
||||||
|
This is most useful as a stop-gap solution for migrating off Autotools.
|
||||||
|
These tests are likely to be non-hermetic, with implicit system dependencies.
|
||||||
|
|
||||||
|
NOTE: the rule is only an internal workaround. The interface may change and
|
||||||
|
the rule may be removed when everything is properly "Bazelified".
|
||||||
|
|
||||||
|
Args:
|
||||||
|
name: the name of the inline_sh_binary.
|
||||||
|
srcs: the files used directly by the script.
|
||||||
|
tools: the executable tools used directly by the script. Any target used
|
||||||
|
with rootpath/execpath/location must be declared here or in `srcs`.
|
||||||
|
deps: a list of dependency labels that are required to run this binary.
|
||||||
|
cmd: the inline sh command to run.
|
||||||
|
**kwargs: other keyword arguments that are passed to sh_binary.
|
||||||
|
https://bazel.build/reference/be/common-definitions#common-attributes)
|
||||||
|
"""
|
||||||
|
|
||||||
|
native.genrule(
|
||||||
|
name = name + "_genrule",
|
||||||
|
srcs = srcs,
|
||||||
|
exec_tools = tools,
|
||||||
|
outs = [name + ".sh"],
|
||||||
|
cmd = "cat <<'EOF' >$(OUTS)\n#!/bin/bash -exu\n%s\nEOF\n" % cmd,
|
||||||
|
visibility = ["//visibility:private"],
|
||||||
|
)
|
||||||
|
|
||||||
|
native.sh_test(
|
||||||
|
name = name,
|
||||||
|
srcs = [name + "_genrule"],
|
||||||
|
data = srcs + tools + deps,
|
||||||
|
**kwargs
|
||||||
|
)
|
||||||
9
cmake/CMakeLists.txt
Normal file
9
cmake/CMakeLists.txt
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
cmake_minimum_required(VERSION 3.5)
|
||||||
|
|
||||||
|
message(WARNING "Calling of cmake with source directory set to \"cmake\" subdirectory of Protocol Buffers project is deprecated. Top-level directory of Protocol Buffers project should be used instead.")
|
||||||
|
|
||||||
|
project(protobuf C CXX)
|
||||||
|
|
||||||
|
set(protobuf_DEPRECATED_CMAKE_SUBDIRECTORY_USAGE TRUE)
|
||||||
|
|
||||||
|
include(../CMakeLists.txt)
|
||||||
395
cmake/README.md
Normal file
395
cmake/README.md
Normal file
@@ -0,0 +1,395 @@
|
|||||||
|
This directory contains *CMake* files that can be used to build protobuf.
|
||||||
|
|
||||||
|
You need to have [CMake](http://www.cmake.org) and
|
||||||
|
[Git](http://git-scm.com) installed on your computer before proceeding. We
|
||||||
|
currently support CMake 3.5 and newer on both [Windows](#windows-builds) and
|
||||||
|
[Linux](#linux-builds).
|
||||||
|
|
||||||
|
Most of the instructions will be given using CMake's command-line interface, but
|
||||||
|
the same actions can be performed using appropriate GUI tools.
|
||||||
|
|
||||||
|
# Windows Builds
|
||||||
|
|
||||||
|
On Windows, you can build the project from *Command Prompt* and using an
|
||||||
|
*Visual Studio* IDE. You will also need to have
|
||||||
|
[Visual Studio](https://www.visualstudio.com) installed on your computer before
|
||||||
|
proceeding.
|
||||||
|
|
||||||
|
## Environment Setup
|
||||||
|
|
||||||
|
Open the appropriate *Command Prompt* from the *Start* menu.
|
||||||
|
|
||||||
|
For example *x86 Native Tools Command Prompt for VS 2019*:
|
||||||
|
|
||||||
|
C:\Program Files (x86)\Microsoft Visual Studio\2019\Professional>
|
||||||
|
|
||||||
|
Change to your working directory:
|
||||||
|
|
||||||
|
C:\Program Files (x86)\Microsoft Visual Studio\2019\Professional>cd C:\Path\to
|
||||||
|
C:\Path\to>
|
||||||
|
|
||||||
|
Where *C:\Path\to* is path to your real working directory.
|
||||||
|
|
||||||
|
Create a folder where protobuf headers/libraries/binaries will be installed after built:
|
||||||
|
|
||||||
|
C:\Path\to>mkdir install
|
||||||
|
|
||||||
|
If *cmake* command is not available from *Command Prompt*, add it to system *PATH* variable:
|
||||||
|
|
||||||
|
C:\Path\to>set PATH=%PATH%;C:\Program Files (x86)\CMake\bin
|
||||||
|
|
||||||
|
If *git* command is not available from *Command Prompt*, add it to system *PATH* variable:
|
||||||
|
|
||||||
|
C:\Path\to>set PATH=%PATH%;C:\Program Files\Git\cmd
|
||||||
|
|
||||||
|
Optionally, you will want to download [ninja](https://ninja-build.org/) and add it to your *PATH* variable.
|
||||||
|
|
||||||
|
C:\Path\to>set PATH=%PATH%;C:\tools\ninja
|
||||||
|
|
||||||
|
Good. Now you are ready to continue.
|
||||||
|
|
||||||
|
## Getting Sources
|
||||||
|
|
||||||
|
You can get the latest stable source packages from the release page:
|
||||||
|
|
||||||
|
https://github.com/protocolbuffers/protobuf/releases/latest
|
||||||
|
|
||||||
|
For example: if you only need C++, download `protobuf-cpp-[VERSION].tar.gz`; if
|
||||||
|
you need C++ and Java, download `protobuf-java-[VERSION].tar.gz` (every package
|
||||||
|
contains C++ source already); if you need C++ and multiple other languages,
|
||||||
|
download `protobuf-all-[VERSION].tar.gz`.
|
||||||
|
|
||||||
|
Or you can use git to clone from protobuf git repository.
|
||||||
|
|
||||||
|
C:\Path\to> mkdir src & cd src
|
||||||
|
C:\Path\to\src> git clone -b [release_tag] https://github.com/protocolbuffers/protobuf.git
|
||||||
|
|
||||||
|
Where *[release_tag]* is a git tag like *v3.0.0-beta-1* or a branch name like *main*
|
||||||
|
if you want to get the latest code.
|
||||||
|
|
||||||
|
Go to the project folder:
|
||||||
|
|
||||||
|
C:\Path\to\src> cd protobuf
|
||||||
|
C:\Path\to\src\protobuf>
|
||||||
|
|
||||||
|
Remember to update any submodules if you are using git clone (you can skip this
|
||||||
|
step if you are using a release .tar.gz or .zip package):
|
||||||
|
|
||||||
|
```console
|
||||||
|
C:\Path\to\src\protobuf> git submodule update --init --recursive
|
||||||
|
```
|
||||||
|
|
||||||
|
Good. Now you are ready for *CMake* configuration.
|
||||||
|
|
||||||
|
## CMake Configuration
|
||||||
|
|
||||||
|
*CMake* supports a lot of different
|
||||||
|
[generators](http://www.cmake.org/cmake/help/latest/manual/cmake-generators.7.html)
|
||||||
|
for various native build systems.
|
||||||
|
|
||||||
|
Of most interest to Windows programmers are the following:
|
||||||
|
|
||||||
|
* [Visual Studio](http://www.cmake.org/cmake/help/latest/manual/cmake-generators.7.html#visual-studio-generators)
|
||||||
|
This generates a Visual Studio solution for the project.
|
||||||
|
|
||||||
|
* [Ninja](https://cmake.org/cmake/help/latest/manual/cmake-generators.7.html#ninja-generator)
|
||||||
|
This uses the external tool [Ninja](https://ninja-build.org/) to build. It is the fastest solution available.
|
||||||
|
|
||||||
|
Note that as of Visual Studio 2015, Visual Studio includes
|
||||||
|
[support for opening directly CMake-based projects](https://docs.microsoft.com/en-us/cpp/build/cmake-projects-in-visual-studio).
|
||||||
|
|
||||||
|
It is considered good practice not to build CMake projects in the source tree but in a separate folder.
|
||||||
|
|
||||||
|
Create a temporary *build* folder and change your working directory to it:
|
||||||
|
|
||||||
|
mkdir C:\Path\to\build\protobuf
|
||||||
|
cd C:\Path\to\build\protobuf
|
||||||
|
C:\Path\to\build\protobuf>
|
||||||
|
|
||||||
|
The *Makefile* and *Ninja* generators can build the project in only one configuration, so you need to build
|
||||||
|
a separate folder for each configuration.
|
||||||
|
|
||||||
|
To use *Debug* configuration using *Ninja*:
|
||||||
|
|
||||||
|
C:\Path\to\build\protobuf>mkdir debug & cd debug
|
||||||
|
C:\Path\to\build\protobuf\debug>cmake -G "Ninja" ^
|
||||||
|
-DCMAKE_BUILD_TYPE=Debug ^
|
||||||
|
-DCMAKE_INSTALL_PREFIX=C:\Path\to\install ^
|
||||||
|
C:\Path\to\src\protobuf
|
||||||
|
|
||||||
|
It will generate *Ninja* build scripts in current directory.
|
||||||
|
|
||||||
|
The *Visual Studio* generator is multi-configuration: it will generate a single *.sln* file that can be used for both *Debug* and *Release*:
|
||||||
|
|
||||||
|
C:\Path\to\build\protobuf>mkdir solution & cd solution
|
||||||
|
C:\Path\to\build\protobuf\solution>cmake -G "Visual Studio 16 2019" ^
|
||||||
|
-DCMAKE_INSTALL_PREFIX=C:\Path\to\install ^
|
||||||
|
C:\Path\to\src\protobuf
|
||||||
|
|
||||||
|
It will generate *Visual Studio* solution file *protobuf.sln* in current directory.
|
||||||
|
|
||||||
|
### Unit Tests
|
||||||
|
|
||||||
|
Unit tests are being built along with the rest of protobuf. The unit tests require Google Mock (now a part of Google Test).
|
||||||
|
|
||||||
|
A copy of [Google Test](https://github.com/google/googletest) is included as a Git submodule in the `third-party/googletest` folder.
|
||||||
|
(You do need to initialize the Git submodules as explained above.)
|
||||||
|
|
||||||
|
Alternately, you may want to use protobuf in a larger set-up, you may want to use that standard CMake approach where
|
||||||
|
you build and install a shared copy of Google Test.
|
||||||
|
|
||||||
|
After you've built and installed your Google Test copy, you need add the following definition to your *cmake* command line
|
||||||
|
during the configuration step: `-Dprotobuf_USE_EXTERNAL_GTEST=ON`.
|
||||||
|
This will cause the standard CMake `find_package(GTest REQUIRED)` to be used.
|
||||||
|
|
||||||
|
[find_package](https://cmake.org/cmake/help/latest/command/find_package.html) will search in a default location,
|
||||||
|
which on Windows is *C:\Program Files*. This is most likely not what you want. You will want instead to search for
|
||||||
|
Google Test in your project's root directory (i.e. the same directory you've passed to `CMAKE_INSTALL_PREFIX` when
|
||||||
|
building Google Test). For this, you need to set the `CMAKE_PREFIX_PATH` CMake variable. (There are other ways in CMake,
|
||||||
|
see the [manual](https://cmake.org/cmake/help/latest/command/find_package.html) for details.)
|
||||||
|
|
||||||
|
For example:
|
||||||
|
|
||||||
|
C:\Path\to\build\protobuf>mkdir solution & cd solution
|
||||||
|
C:\Path\to\build\protobuf\solution>cmake -G "Visual Studio 16 2019" ^
|
||||||
|
-DCMAKE_INSTALL_PREFIX=C:\Path\to\install ^
|
||||||
|
-DCMAKE_PREFIX_PATH=C:\Path\to\my_big_project ^
|
||||||
|
-Dprotobuf_USE_EXTERNAL_GTEST=ON ^
|
||||||
|
C:\Path\to\src\protobuf
|
||||||
|
|
||||||
|
In most cases, `CMAKE_PREFIX_PATH` and `CMAKE_INSTALL_PREFIX` will point to the same directory.
|
||||||
|
|
||||||
|
To disable testing completely, you need to add the following argument to you *cmake* command line: `-Dprotobuf_BUILD_TESTS=OFF`.
|
||||||
|
|
||||||
|
For example:
|
||||||
|
|
||||||
|
C:\Path\to\build\protobuf\solution>cmake -G "Visual Studio 16 2019" ^
|
||||||
|
-DCMAKE_INSTALL_PREFIX=C:\Path\to\install ^
|
||||||
|
-Dprotobuf_BUILD_TESTS=OFF ^
|
||||||
|
C:\Path\to\src\protobuf
|
||||||
|
|
||||||
|
## Compiling
|
||||||
|
|
||||||
|
The standard way to compile a *CMake* project is `cmake --build <directory>`.
|
||||||
|
|
||||||
|
|
||||||
|
Note that if your generator supports multiple configurations, you will probably want to specify which one to build:
|
||||||
|
|
||||||
|
cmake --build C:\Path\to\build\protobuf\solution --config Release
|
||||||
|
|
||||||
|
You can also run directly the build tool you've configured:
|
||||||
|
|
||||||
|
C:\Path\to\build\protobuf\debug>ninja
|
||||||
|
|
||||||
|
And wait for the compilation to finish.
|
||||||
|
|
||||||
|
If you prefer to use the IDE:
|
||||||
|
|
||||||
|
* Open the generated protobuf.sln file in Microsoft Visual Studio.
|
||||||
|
* Choose "Debug" or "Release" configuration as desired.
|
||||||
|
* From the Build menu, choose "Build Solution".
|
||||||
|
|
||||||
|
And wait for the compilation to finish.
|
||||||
|
|
||||||
|
## Testing
|
||||||
|
|
||||||
|
To run unit-tests, first you must compile protobuf as described above.
|
||||||
|
Then run:
|
||||||
|
|
||||||
|
C:\Path\to\protobuf\cmake\build\release>ctest --progress --output-on-failure
|
||||||
|
|
||||||
|
You can also build the `check` target (not idiomatic CMake usage, though):
|
||||||
|
|
||||||
|
C:\Path\to\protobuf\cmake\build\release>cmake --build . --target check
|
||||||
|
|
||||||
|
or
|
||||||
|
|
||||||
|
C:\Path\to\build\protobuf\release>ninja check
|
||||||
|
|
||||||
|
You can also build project *check* from Visual Studio solution.
|
||||||
|
Yes, it may sound strange, but it works.
|
||||||
|
|
||||||
|
You should see output similar to:
|
||||||
|
|
||||||
|
Running main() from gmock_main.cc
|
||||||
|
[==========] Running 1546 tests from 165 test cases.
|
||||||
|
|
||||||
|
...
|
||||||
|
|
||||||
|
[==========] 1546 tests from 165 test cases ran. (2529 ms total)
|
||||||
|
[ PASSED ] 1546 tests.
|
||||||
|
|
||||||
|
To run specific tests, you need to pass some command line arguments to the test program itself:
|
||||||
|
|
||||||
|
C:\Path\to\build\protobuf\release>tests.exe --gtest_filter=AnyTest*
|
||||||
|
Running main() from gmock_main.cc
|
||||||
|
Note: Google Test filter = AnyTest*
|
||||||
|
[==========] Running 3 tests from 1 test case.
|
||||||
|
[----------] Global test environment set-up.
|
||||||
|
[----------] 3 tests from AnyTest
|
||||||
|
[ RUN ] AnyTest.TestPackAndUnpack
|
||||||
|
[ OK ] AnyTest.TestPackAndUnpack (0 ms)
|
||||||
|
[ RUN ] AnyTest.TestPackAndUnpackAny
|
||||||
|
[ OK ] AnyTest.TestPackAndUnpackAny (0 ms)
|
||||||
|
[ RUN ] AnyTest.TestIs
|
||||||
|
[ OK ] AnyTest.TestIs (0 ms)
|
||||||
|
[----------] 3 tests from AnyTest (1 ms total)
|
||||||
|
|
||||||
|
[----------] Global test environment tear-down
|
||||||
|
[==========] 3 tests from 1 test case ran. (2 ms total)
|
||||||
|
[ PASSED ] 3 tests.
|
||||||
|
|
||||||
|
Note that the tests must be run from the source folder.
|
||||||
|
|
||||||
|
If all tests are passed, safely continue.
|
||||||
|
|
||||||
|
## Installing
|
||||||
|
|
||||||
|
To install protobuf to the *install* folder you've specified in the configuration step, you need to build the `install` target:
|
||||||
|
|
||||||
|
cmake --build C:\Path\to\build\protobuf\solution --config Release --target install
|
||||||
|
|
||||||
|
Or if you prefer:
|
||||||
|
|
||||||
|
C:\Path\to\build\protobuf\debug>ninja install
|
||||||
|
|
||||||
|
You can also build project *INSTALL* from Visual Studio solution.
|
||||||
|
It sounds not so strange and it works.
|
||||||
|
|
||||||
|
This will create the following folders under the *install* location:
|
||||||
|
* bin - that contains protobuf *protoc.exe* compiler;
|
||||||
|
* include - that contains C++ headers and protobuf *.proto files;
|
||||||
|
* lib - that contains linking libraries and *CMake* configuration files for *protobuf* package.
|
||||||
|
|
||||||
|
Now you can if needed:
|
||||||
|
* Copy the contents of the include directory to wherever you want to put headers.
|
||||||
|
* Copy protoc.exe wherever you put build tools (probably somewhere in your PATH).
|
||||||
|
* Copy linking libraries libprotobuf[d].lib, libprotobuf-lite[d].lib, and libprotoc[d].lib wherever you put libraries.
|
||||||
|
|
||||||
|
To avoid conflicts between the MSVC debug and release runtime libraries, when
|
||||||
|
compiling a debug build of your application, you may need to link against a
|
||||||
|
debug build of libprotobufd.lib with "d" postfix. Similarly, release builds should link against
|
||||||
|
release libprotobuf.lib library.
|
||||||
|
|
||||||
|
## DLLs vs. static linking
|
||||||
|
|
||||||
|
Static linking is now the default for the Protocol Buffer libraries. Due to
|
||||||
|
issues with Win32's use of a separate heap for each DLL, as well as binary
|
||||||
|
compatibility issues between different versions of MSVC's STL library, it is
|
||||||
|
recommended that you use static linkage only. However, it is possible to
|
||||||
|
build libprotobuf and libprotoc as DLLs if you really want. To do this,
|
||||||
|
do the following:
|
||||||
|
|
||||||
|
* Add an additional flag `-Dprotobuf_BUILD_SHARED_LIBS=ON` when invoking cmake
|
||||||
|
* Follow the same steps as described in the above section.
|
||||||
|
* When compiling your project, make sure to `#define PROTOBUF_USE_DLLS`.
|
||||||
|
|
||||||
|
When distributing your software to end users, we strongly recommend that you
|
||||||
|
do NOT install libprotobuf.dll or libprotoc.dll to any shared location.
|
||||||
|
Instead, keep these libraries next to your binaries, in your application's
|
||||||
|
own install directory. C++ makes it very difficult to maintain binary
|
||||||
|
compatibility between releases, so it is likely that future versions of these
|
||||||
|
libraries will *not* be usable as drop-in replacements.
|
||||||
|
|
||||||
|
If your project is itself a DLL intended for use by third-party software, we
|
||||||
|
recommend that you do NOT expose protocol buffer objects in your library's
|
||||||
|
public interface, and that you statically link protocol buffers into your
|
||||||
|
library.
|
||||||
|
|
||||||
|
## ZLib support
|
||||||
|
|
||||||
|
If you want to include GzipInputStream and GzipOutputStream
|
||||||
|
(google/protobuf/io/gzip_stream.h) in libprotobuf, you will need to do a few
|
||||||
|
additional steps.
|
||||||
|
|
||||||
|
Obtain a copy of the zlib library. The pre-compiled DLL at zlib.net works.
|
||||||
|
You need prepare it:
|
||||||
|
|
||||||
|
* Make sure zlib's two headers are in your `C:\Path\to\install\include` path
|
||||||
|
* Make sure zlib's linking libraries (*.lib file) is in your
|
||||||
|
`C:\Path\to\install\lib` library path.
|
||||||
|
|
||||||
|
You can also compile it from source by yourself.
|
||||||
|
|
||||||
|
Getting sources:
|
||||||
|
|
||||||
|
C:\Path\to\src>git clone -b v1.2.8 https://github.com/madler/zlib.git
|
||||||
|
C:\Path\to\src>cd zlib
|
||||||
|
|
||||||
|
Compiling and Installing:
|
||||||
|
|
||||||
|
C:\Path\to\src\zlib>mkdir C:\Path\to\build\zlib & cd C:\Path\to\build\zlib
|
||||||
|
C:\Path\to\build\zlib>mkdir release & cd release
|
||||||
|
C:\Path\to\build\zlib\release>cmake -G "Ninja" -DCMAKE_BUILD_TYPE=Release ^
|
||||||
|
-DCMAKE_INSTALL_PREFIX=C:\Path\to\install C:\Path\to\src\zlib
|
||||||
|
C:\Path\to\src\zlib\build\release>cmake --build . --target install
|
||||||
|
|
||||||
|
You can make *debug* version or use *Visual Studio* generator also as before for the
|
||||||
|
protobuf project.
|
||||||
|
|
||||||
|
Now add *bin* folder from *install* to system *PATH*:
|
||||||
|
|
||||||
|
C:\Path\to>set PATH=%PATH%;C:\Path\to\install\bin
|
||||||
|
|
||||||
|
You need reconfigure protobuf with flag `-Dprotobuf_WITH_ZLIB=ON` when invoking cmake.
|
||||||
|
|
||||||
|
Note that if you have compiled ZLIB yourself, as stated above,
|
||||||
|
further disable the option `-Dprotobuf_MSVC_STATIC_RUNTIME=OFF`.
|
||||||
|
|
||||||
|
If it reports NOTFOUND for zlib_include or zlib_lib, you might haven't put
|
||||||
|
the headers or the .lib file in the right directory.
|
||||||
|
|
||||||
|
If you already have ZLIB library and headers at some other location on your system then alternatively you can define following configuration flags to locate them:
|
||||||
|
|
||||||
|
-DZLIB_INCLUDE_DIR=<path to dir containing zlib headers>
|
||||||
|
-DZLIB_LIB=<path to dir containing zlib>
|
||||||
|
|
||||||
|
Build and testing protobuf as usual.
|
||||||
|
|
||||||
|
## Notes on Compiler Warnings
|
||||||
|
|
||||||
|
The following warnings have been disabled while building the protobuf libraries
|
||||||
|
and compiler. You may have to disable some of them in your own project as
|
||||||
|
well, or live with them.
|
||||||
|
|
||||||
|
* C4244 - Conversion from 'type1' to 'type2', possible loss of data.
|
||||||
|
* C4251 - 'identifier' : class 'type' needs to have dll-interface to be used by
|
||||||
|
clients of class 'type2'
|
||||||
|
* C4267 - Conversion from 'size_t' to 'type', possible loss of data.
|
||||||
|
* C4305 - 'identifier' : truncation from 'type1' to 'type2'
|
||||||
|
* C4355 - 'this' : used in base member initializer list
|
||||||
|
* C4800 - 'type' : forcing value to bool 'true' or 'false' (performance warning)
|
||||||
|
* C4996 - 'function': was declared deprecated
|
||||||
|
|
||||||
|
C4251 is of particular note, if you are compiling the Protocol Buffer library
|
||||||
|
as a DLL (see previous section). The protocol buffer library uses templates in
|
||||||
|
its public interfaces. MSVC does not provide any reasonable way to export
|
||||||
|
template classes from a DLL. However, in practice, it appears that exporting
|
||||||
|
templates is not necessary anyway. Since the complete definition of any
|
||||||
|
template is available in the header files, anyone importing the DLL will just
|
||||||
|
end up compiling instances of the templates into their own binary. The
|
||||||
|
Protocol Buffer implementation does not rely on static template members being
|
||||||
|
unique, so there should be no problem with this, but MSVC prints warning
|
||||||
|
nevertheless. So, we disable it. Unfortunately, this warning will also be
|
||||||
|
produced when compiling code which merely uses protocol buffers, meaning you
|
||||||
|
may have to disable it in your code too.
|
||||||
|
|
||||||
|
# Linux Builds
|
||||||
|
|
||||||
|
Building with CMake works very similarly on Linux. Instead of Visual Studio,
|
||||||
|
you will need to have gcc or clang installed to handle the C++ builds. CMake
|
||||||
|
will generate Makefiles by default, but can also be configured to use Ninja. To
|
||||||
|
build Protobuf, you will need to run (from the source directory):
|
||||||
|
|
||||||
|
cmake .
|
||||||
|
cmake --build . --parallel 10
|
||||||
|
|
||||||
|
Protobuf can be tested and installed with CMake:
|
||||||
|
|
||||||
|
ctest --verbose
|
||||||
|
sudo cmake --install .
|
||||||
|
|
||||||
|
or directly with the generated Makefiles:
|
||||||
|
|
||||||
|
make VERBOSE=1 test
|
||||||
|
sudo make install
|
||||||
58
cmake/abseil-cpp.cmake
Normal file
58
cmake/abseil-cpp.cmake
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
# Setup our dependency on Abseil.
|
||||||
|
|
||||||
|
set(ABSL_PROPAGATE_CXX_STD ON)
|
||||||
|
|
||||||
|
if(TARGET absl::strings)
|
||||||
|
# If Abseil is included already, skip including it.
|
||||||
|
# (https://github.com/protocolbuffers/protobuf/issues/10435)
|
||||||
|
elseif(protobuf_ABSL_PROVIDER STREQUAL "module")
|
||||||
|
if(NOT ABSL_ROOT_DIR)
|
||||||
|
set(ABSL_ROOT_DIR ${CMAKE_CURRENT_SOURCE_DIR}/third_party/abseil-cpp)
|
||||||
|
endif()
|
||||||
|
if(EXISTS "${ABSL_ROOT_DIR}/CMakeLists.txt")
|
||||||
|
if(protobuf_INSTALL)
|
||||||
|
# When protobuf_INSTALL is enabled and Abseil will be built as a module,
|
||||||
|
# Abseil will be installed along with protobuf for convenience.
|
||||||
|
set(ABSL_ENABLE_INSTALL ON)
|
||||||
|
endif()
|
||||||
|
add_subdirectory(${ABSL_ROOT_DIR} third_party/abseil-cpp)
|
||||||
|
else()
|
||||||
|
message(WARNING "protobuf_ABSL_PROVIDER is \"module\" but ABSL_ROOT_DIR is wrong")
|
||||||
|
endif()
|
||||||
|
if(protobuf_INSTALL AND NOT _protobuf_INSTALL_SUPPORTED_FROM_MODULE)
|
||||||
|
message(WARNING "protobuf_INSTALL will be forced to FALSE because protobuf_ABSL_PROVIDER is \"module\" and CMake version (${CMAKE_VERSION}) is less than 3.13.")
|
||||||
|
set(protobuf_INSTALL FALSE)
|
||||||
|
endif()
|
||||||
|
elseif(protobuf_ABSL_PROVIDER STREQUAL "package")
|
||||||
|
# Use "CONFIG" as there is no built-in cmake module for absl.
|
||||||
|
find_package(absl REQUIRED CONFIG)
|
||||||
|
endif()
|
||||||
|
set(_protobuf_FIND_ABSL "if(NOT TARGET absl::strings)\n find_package(absl CONFIG)\nendif()")
|
||||||
|
|
||||||
|
set(protobuf_ABSL_USED_TARGETS
|
||||||
|
absl::algorithm
|
||||||
|
absl::base
|
||||||
|
absl::bind_front
|
||||||
|
absl::bits
|
||||||
|
absl::cleanup
|
||||||
|
absl::cord
|
||||||
|
absl::core_headers
|
||||||
|
absl::debugging
|
||||||
|
absl::dynamic_annotations
|
||||||
|
absl::flags
|
||||||
|
absl::flat_hash_map
|
||||||
|
absl::flat_hash_set
|
||||||
|
absl::function_ref
|
||||||
|
absl::hash
|
||||||
|
absl::layout
|
||||||
|
absl::memory
|
||||||
|
absl::optional
|
||||||
|
absl::span
|
||||||
|
absl::status
|
||||||
|
absl::statusor
|
||||||
|
absl::strings
|
||||||
|
absl::synchronization
|
||||||
|
absl::time
|
||||||
|
absl::utility
|
||||||
|
absl::variant
|
||||||
|
)
|
||||||
89
cmake/conformance.cmake
Normal file
89
cmake/conformance.cmake
Normal file
@@ -0,0 +1,89 @@
|
|||||||
|
|
||||||
|
if (NOT EXISTS "${protobuf_SOURCE_DIR}/third_party/jsoncpp/CMakeLists.txt")
|
||||||
|
message(FATAL_ERROR
|
||||||
|
"Cannot find third_party/jsoncpp directory that's needed to "
|
||||||
|
"build conformance tests. If you use git, make sure you have cloned "
|
||||||
|
"submodules:\n"
|
||||||
|
" git submodule update --init --recursive\n"
|
||||||
|
"If instead you want to skip them, run cmake with:\n"
|
||||||
|
" cmake -Dprotobuf_BUILD_CONFORMANCE=OFF\n")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
add_custom_command(
|
||||||
|
OUTPUT
|
||||||
|
${protobuf_SOURCE_DIR}/conformance/conformance.pb.h
|
||||||
|
${protobuf_SOURCE_DIR}/conformance/conformance.pb.cc
|
||||||
|
DEPENDS ${protobuf_PROTOC_EXE} ${protobuf_SOURCE_DIR}/conformance/conformance.proto
|
||||||
|
COMMAND ${protobuf_PROTOC_EXE} ${protobuf_SOURCE_DIR}/conformance/conformance.proto
|
||||||
|
--proto_path=${protobuf_SOURCE_DIR}/conformance
|
||||||
|
--cpp_out=${protobuf_SOURCE_DIR}/conformance
|
||||||
|
)
|
||||||
|
|
||||||
|
add_custom_command(
|
||||||
|
OUTPUT
|
||||||
|
${protobuf_SOURCE_DIR}/src/google/protobuf/test_messages_proto3.pb.h
|
||||||
|
${protobuf_SOURCE_DIR}/src/google/protobuf/test_messages_proto3.pb.cc
|
||||||
|
${protobuf_SOURCE_DIR}/src/google/protobuf/test_messages_proto2.pb.h
|
||||||
|
${protobuf_SOURCE_DIR}/src/google/protobuf/test_messages_proto2.pb.cc
|
||||||
|
DEPENDS ${protobuf_PROTOC_EXE} ${protobuf_SOURCE_DIR}/src/google/protobuf/test_messages_proto3.proto
|
||||||
|
${protobuf_PROTOC_EXE} ${protobuf_SOURCE_DIR}/src/google/protobuf/test_messages_proto2.proto
|
||||||
|
COMMAND ${protobuf_PROTOC_EXE} ${protobuf_SOURCE_DIR}/src/google/protobuf/test_messages_proto3.proto
|
||||||
|
${protobuf_SOURCE_DIR}/src/google/protobuf/test_messages_proto2.proto
|
||||||
|
--proto_path=${protobuf_SOURCE_DIR}/src
|
||||||
|
--cpp_out=${protobuf_SOURCE_DIR}/src
|
||||||
|
)
|
||||||
|
|
||||||
|
add_executable(conformance_test_runner
|
||||||
|
${protobuf_SOURCE_DIR}/conformance/binary_json_conformance_suite.cc
|
||||||
|
${protobuf_SOURCE_DIR}/conformance/binary_json_conformance_suite.h
|
||||||
|
${protobuf_SOURCE_DIR}/conformance/conformance.pb.h
|
||||||
|
${protobuf_SOURCE_DIR}/conformance/conformance.pb.cc
|
||||||
|
${protobuf_SOURCE_DIR}/conformance/conformance_test.cc
|
||||||
|
${protobuf_SOURCE_DIR}/conformance/conformance_test_runner.cc
|
||||||
|
${protobuf_SOURCE_DIR}/conformance/conformance_test_main.cc
|
||||||
|
${protobuf_SOURCE_DIR}/conformance/text_format_conformance_suite.cc
|
||||||
|
${protobuf_SOURCE_DIR}/conformance/text_format_conformance_suite.h
|
||||||
|
${protobuf_SOURCE_DIR}/src/google/protobuf/test_messages_proto2.pb.h
|
||||||
|
${protobuf_SOURCE_DIR}/src/google/protobuf/test_messages_proto2.pb.cc
|
||||||
|
${protobuf_SOURCE_DIR}/src/google/protobuf/test_messages_proto3.pb.h
|
||||||
|
${protobuf_SOURCE_DIR}/src/google/protobuf/test_messages_proto3.pb.cc
|
||||||
|
)
|
||||||
|
|
||||||
|
add_executable(conformance_cpp
|
||||||
|
${protobuf_SOURCE_DIR}/conformance/conformance.pb.h
|
||||||
|
${protobuf_SOURCE_DIR}/conformance/conformance.pb.cc
|
||||||
|
${protobuf_SOURCE_DIR}/conformance/conformance_cpp.cc
|
||||||
|
${protobuf_SOURCE_DIR}/src/google/protobuf/test_messages_proto2.pb.h
|
||||||
|
${protobuf_SOURCE_DIR}/src/google/protobuf/test_messages_proto2.pb.cc
|
||||||
|
${protobuf_SOURCE_DIR}/src/google/protobuf/test_messages_proto3.pb.h
|
||||||
|
${protobuf_SOURCE_DIR}/src/google/protobuf/test_messages_proto3.pb.cc
|
||||||
|
)
|
||||||
|
|
||||||
|
target_include_directories(
|
||||||
|
conformance_test_runner
|
||||||
|
PUBLIC ${protobuf_SOURCE_DIR} ${protobuf_SOURCE_DIR}/conformance)
|
||||||
|
|
||||||
|
target_include_directories(
|
||||||
|
conformance_cpp
|
||||||
|
PUBLIC ${protobuf_SOURCE_DIR})
|
||||||
|
|
||||||
|
target_include_directories(conformance_test_runner PRIVATE ${ABSL_ROOT_DIR})
|
||||||
|
target_include_directories(conformance_cpp PRIVATE ${ABSL_ROOT_DIR})
|
||||||
|
|
||||||
|
target_link_libraries(conformance_test_runner ${protobuf_LIB_PROTOBUF})
|
||||||
|
target_link_libraries(conformance_test_runner ${protobuf_ABSL_USED_TARGETS})
|
||||||
|
target_link_libraries(conformance_cpp ${protobuf_LIB_PROTOBUF})
|
||||||
|
target_link_libraries(conformance_cpp ${protobuf_ABSL_USED_TARGETS})
|
||||||
|
|
||||||
|
add_test(NAME conformance_cpp_test
|
||||||
|
COMMAND ${CMAKE_CURRENT_BINARY_DIR}/conformance_test_runner
|
||||||
|
--failure_list ${protobuf_SOURCE_DIR}/conformance/failure_list_cpp.txt
|
||||||
|
--text_format_failure_list ${protobuf_SOURCE_DIR}/conformance/text_format_failure_list_cpp.txt
|
||||||
|
--output_dir ${protobuf_TEST_XML_OUTDIR}
|
||||||
|
${CMAKE_CURRENT_BINARY_DIR}/conformance_cpp
|
||||||
|
DEPENDS conformance_test_runner conformance_cpp)
|
||||||
|
|
||||||
|
set(JSONCPP_WITH_TESTS OFF CACHE BOOL "Disable tests")
|
||||||
|
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/third_party/jsoncpp third_party/jsoncpp)
|
||||||
|
target_include_directories(conformance_test_runner PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/third_party/jsoncpp/include)
|
||||||
|
target_link_libraries(conformance_test_runner jsoncpp_lib)
|
||||||
57
cmake/examples.cmake
Normal file
57
cmake/examples.cmake
Normal file
@@ -0,0 +1,57 @@
|
|||||||
|
if(protobuf_VERBOSE)
|
||||||
|
message(STATUS "Protocol Buffers Examples Configuring...")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
get_filename_component(examples_dir "${protobuf_SOURCE_DIR}/examples" ABSOLUTE)
|
||||||
|
|
||||||
|
if(protobuf_VERBOSE)
|
||||||
|
message(STATUS "Protocol Buffers Examples Configuring done")
|
||||||
|
endif()
|
||||||
|
include(ExternalProject)
|
||||||
|
|
||||||
|
# Internal utility function: Create a custom target representing a build of examples with custom options.
|
||||||
|
function(add_examples_build NAME)
|
||||||
|
|
||||||
|
ExternalProject_Add(${NAME}
|
||||||
|
PREFIX ${NAME}
|
||||||
|
SOURCE_DIR "${examples_dir}"
|
||||||
|
BINARY_DIR ${NAME}
|
||||||
|
STAMP_DIR ${NAME}/logs
|
||||||
|
INSTALL_COMMAND "" #Skip
|
||||||
|
LOG_CONFIGURE 1
|
||||||
|
CMAKE_CACHE_ARGS "-DCMAKE_BUILD_TYPE:STRING=${CMAKE_BUILD_TYPE}"
|
||||||
|
"-Dprotobuf_VERBOSE:BOOL=${protobuf_VERBOSE}"
|
||||||
|
${ARGN}
|
||||||
|
)
|
||||||
|
set_property(TARGET ${NAME} PROPERTY FOLDER "Examples")
|
||||||
|
set_property(TARGET ${NAME} PROPERTY EXCLUDE_FROM_ALL TRUE)
|
||||||
|
endfunction()
|
||||||
|
|
||||||
|
# Add examples as an external project.
|
||||||
|
# sub_directory cannot be used because the find_package(protobuf) call would cause failures with redefined targets.
|
||||||
|
add_examples_build(examples "-Dprotobuf_DIR:PATH=${CMAKE_BINARY_DIR}/${CMAKE_INSTALL_CMAKEDIR}")
|
||||||
|
add_dependencies(examples ${protobuf_LIB_PROTOBUF} ${protobuf_PROTOC_EXE})
|
||||||
|
|
||||||
|
option(protobuf_BUILD_EXAMPLES_MULTITEST "Build Examples in multiple configurations. Useful for testing." OFF)
|
||||||
|
mark_as_advanced(protobuf_BUILD_EXAMPLES_MULTITEST)
|
||||||
|
if(protobuf_BUILD_EXAMPLES_MULTITEST)
|
||||||
|
set_property(GLOBAL PROPERTY USE_FOLDERS ON)
|
||||||
|
|
||||||
|
#Build using the legacy compatibility module.
|
||||||
|
add_examples_build(examples-legacy
|
||||||
|
"-Dprotobuf_DIR:PATH=${CMAKE_BINARY_DIR}/${CMAKE_INSTALL_CMAKEDIR}"
|
||||||
|
"-Dprotobuf_MODULE_COMPATIBLE:BOOL=TRUE"
|
||||||
|
)
|
||||||
|
add_dependencies(examples-legacy ${protobuf_LIB_PROTOBUF} ${protobuf_PROTOC_EXE})
|
||||||
|
|
||||||
|
#Build using the installed library.
|
||||||
|
add_examples_build(examples-installed
|
||||||
|
"-Dprotobuf_DIR:PATH=${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_CMAKEDIR}"
|
||||||
|
)
|
||||||
|
|
||||||
|
#Build using the installed library in legacy compatibility mode.
|
||||||
|
add_examples_build(examples-installed-legacy
|
||||||
|
"-Dprotobuf_DIR:PATH=${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_CMAKEDIR}"
|
||||||
|
"-Dprotobuf_MODULE_COMPATIBLE:BOOL=TRUE"
|
||||||
|
)
|
||||||
|
endif()
|
||||||
115
cmake/install.cmake
Normal file
115
cmake/install.cmake
Normal file
@@ -0,0 +1,115 @@
|
|||||||
|
include(GNUInstallDirs)
|
||||||
|
|
||||||
|
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/cmake/protobuf.pc.cmake
|
||||||
|
${CMAKE_CURRENT_BINARY_DIR}/protobuf.pc @ONLY)
|
||||||
|
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/cmake/protobuf-lite.pc.cmake
|
||||||
|
${CMAKE_CURRENT_BINARY_DIR}/protobuf-lite.pc @ONLY)
|
||||||
|
|
||||||
|
set(_protobuf_libraries libprotobuf-lite libprotobuf)
|
||||||
|
if (protobuf_BUILD_LIBPROTOC)
|
||||||
|
list(APPEND _protobuf_libraries libprotoc)
|
||||||
|
endif (protobuf_BUILD_LIBPROTOC)
|
||||||
|
|
||||||
|
foreach(_library ${_protobuf_libraries})
|
||||||
|
set_property(TARGET ${_library}
|
||||||
|
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}
|
||||||
|
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT ${_library})
|
||||||
|
endforeach()
|
||||||
|
|
||||||
|
if (protobuf_BUILD_PROTOC_BINARIES)
|
||||||
|
install(TARGETS protoc EXPORT protobuf-targets
|
||||||
|
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT protoc
|
||||||
|
BUNDLE DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT protoc)
|
||||||
|
if (UNIX AND NOT APPLE)
|
||||||
|
set_property(TARGET protoc
|
||||||
|
PROPERTY INSTALL_RPATH "$ORIGIN/../${CMAKE_INSTALL_LIBDIR}")
|
||||||
|
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")
|
||||||
|
|
||||||
|
include(${protobuf_SOURCE_DIR}/src/file_lists.cmake)
|
||||||
|
set(protobuf_HEADERS
|
||||||
|
${libprotobuf_hdrs}
|
||||||
|
${libprotoc_hdrs}
|
||||||
|
${wkt_protos_files}
|
||||||
|
${descriptor_proto_proto_srcs}
|
||||||
|
${plugin_proto_proto_srcs}
|
||||||
|
)
|
||||||
|
foreach(_header ${protobuf_HEADERS})
|
||||||
|
string(REPLACE "${protobuf_SOURCE_DIR}/src" "" _header ${_header})
|
||||||
|
get_filename_component(_extract_from "${protobuf_SOURCE_DIR}/src/${_header}" ABSOLUTE)
|
||||||
|
get_filename_component(_extract_name ${_header} NAME)
|
||||||
|
get_filename_component(_extract_to "${CMAKE_INSTALL_INCLUDEDIR}/${_header}" DIRECTORY)
|
||||||
|
install(FILES "${_extract_from}"
|
||||||
|
DESTINATION "${_extract_to}"
|
||||||
|
COMPONENT protobuf-headers
|
||||||
|
RENAME "${_extract_name}")
|
||||||
|
endforeach()
|
||||||
|
|
||||||
|
# Install configuration
|
||||||
|
set(_install_cmakedir_desc "Directory relative to CMAKE_INSTALL to install the cmake configuration files")
|
||||||
|
set(_build_cmakedir_desc "Directory relative to CMAKE_CURRENT_BINARY_DIR for cmake configuration files")
|
||||||
|
set(_exampledir_desc "Directory relative to CMAKE_INSTALL_DATA to install examples")
|
||||||
|
set(_protobuf_subdir_desc "Subdirectory in which to install cmake configuration files")
|
||||||
|
if(NOT MSVC)
|
||||||
|
set(protobuf_CMAKE_SUBDIR "cmake/protobuf" CACHE STRING "${_protobuf_subdir_desc}")
|
||||||
|
set(CMAKE_INSTALL_CMAKEDIR "${CMAKE_INSTALL_LIBDIR}/${protobuf_CMAKE_SUBDIR}" CACHE STRING "${_install_cmakedir_desc}")
|
||||||
|
set(CMAKE_INSTALL_EXAMPLEDIR "${CMAKE_INSTALL_DATADIR}/protobuf/examples" CACHE STRING "${_exampledir_desc}")
|
||||||
|
else()
|
||||||
|
set(protobuf_CMAKE_SUBDIR "cmake" CACHE STRING "${_protobuf_subdir_desc}")
|
||||||
|
set(CMAKE_INSTALL_CMAKEDIR "cmake" CACHE STRING "${_cmakedir_desc}")
|
||||||
|
set(CMAKE_INSTALL_EXAMPLEDIR "examples" CACHE STRING "${_exampledir_desc}")
|
||||||
|
endif()
|
||||||
|
set(CMAKE_BUILD_CMAKEDIR "${CMAKE_CURRENT_BINARY_DIR}/${protobuf_CMAKE_SUBDIR}" CACHE STRING "${_build_cmakedir_desc}")
|
||||||
|
mark_as_advanced(protobuf_CMAKE_SUBDIR)
|
||||||
|
mark_as_advanced(CMAKE_BUILD_CMAKEDIR)
|
||||||
|
mark_as_advanced(CMAKE_INSTALL_CMAKEDIR)
|
||||||
|
mark_as_advanced(CMAKE_INSTALL_EXAMPLEDIR)
|
||||||
|
|
||||||
|
configure_file(${protobuf_SOURCE_DIR}/cmake/protobuf-config.cmake.in
|
||||||
|
${CMAKE_BUILD_CMAKEDIR}/protobuf-config.cmake @ONLY)
|
||||||
|
configure_file(${protobuf_SOURCE_DIR}/cmake/protobuf-config-version.cmake.in
|
||||||
|
${CMAKE_BUILD_CMAKEDIR}/protobuf-config-version.cmake @ONLY)
|
||||||
|
configure_file(${protobuf_SOURCE_DIR}/cmake/protobuf-module.cmake.in
|
||||||
|
${CMAKE_BUILD_CMAKEDIR}/protobuf-module.cmake @ONLY)
|
||||||
|
configure_file(${protobuf_SOURCE_DIR}/cmake/protobuf-options.cmake
|
||||||
|
${CMAKE_BUILD_CMAKEDIR}/protobuf-options.cmake @ONLY)
|
||||||
|
configure_file(${protobuf_SOURCE_DIR}/cmake/protobuf-generate.cmake
|
||||||
|
${CMAKE_BUILD_CMAKEDIR}/protobuf-generate.cmake @ONLY)
|
||||||
|
|
||||||
|
# Allows the build directory to be used as a find directory.
|
||||||
|
|
||||||
|
install(EXPORT protobuf-targets
|
||||||
|
DESTINATION "${CMAKE_INSTALL_CMAKEDIR}"
|
||||||
|
NAMESPACE protobuf::
|
||||||
|
COMPONENT protobuf-export
|
||||||
|
)
|
||||||
|
|
||||||
|
install(DIRECTORY ${CMAKE_BUILD_CMAKEDIR}/
|
||||||
|
DESTINATION "${CMAKE_INSTALL_CMAKEDIR}"
|
||||||
|
COMPONENT protobuf-export
|
||||||
|
PATTERN protobuf-targets.cmake EXCLUDE
|
||||||
|
)
|
||||||
|
|
||||||
|
option(protobuf_INSTALL_EXAMPLES "Install the examples folder" OFF)
|
||||||
|
if(protobuf_INSTALL_EXAMPLES)
|
||||||
|
install(DIRECTORY examples/
|
||||||
|
DESTINATION "${CMAKE_INSTALL_EXAMPLEDIR}"
|
||||||
|
COMPONENT protobuf-examples)
|
||||||
|
endif()
|
||||||
36
cmake/libprotobuf-lite.cmake
Normal file
36
cmake/libprotobuf-lite.cmake
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
# CMake definitions for libprotobuf_lite (the "lite" C++ protobuf runtime).
|
||||||
|
|
||||||
|
include(${protobuf_SOURCE_DIR}/src/file_lists.cmake)
|
||||||
|
|
||||||
|
add_library(libprotobuf-lite ${protobuf_SHARED_OR_STATIC}
|
||||||
|
${libprotobuf_lite_srcs}
|
||||||
|
${libprotobuf_lite_hdrs}
|
||||||
|
${protobuf_version_rc_file})
|
||||||
|
if(protobuf_HAVE_LD_VERSION_SCRIPT)
|
||||||
|
if(${CMAKE_VERSION} VERSION_GREATER 3.13 OR ${CMAKE_VERSION} VERSION_EQUAL 3.13)
|
||||||
|
target_link_options(libprotobuf-lite PRIVATE -Wl,--version-script=${protobuf_SOURCE_DIR}/src/libprotobuf-lite.map)
|
||||||
|
elseif(protobuf_BUILD_SHARED_LIBS)
|
||||||
|
target_link_libraries(libprotobuf-lite PRIVATE -Wl,--version-script=${protobuf_SOURCE_DIR}/src/libprotobuf-lite.map)
|
||||||
|
endif()
|
||||||
|
set_target_properties(libprotobuf-lite PROPERTIES
|
||||||
|
LINK_DEPENDS ${protobuf_SOURCE_DIR}/src/libprotobuf-lite.map)
|
||||||
|
endif()
|
||||||
|
target_link_libraries(libprotobuf-lite PRIVATE ${CMAKE_THREAD_LIBS_INIT})
|
||||||
|
if(protobuf_LINK_LIBATOMIC)
|
||||||
|
target_link_libraries(libprotobuf-lite PRIVATE atomic)
|
||||||
|
endif()
|
||||||
|
if(${CMAKE_SYSTEM_NAME} STREQUAL "Android")
|
||||||
|
target_link_libraries(libprotobuf-lite PRIVATE log)
|
||||||
|
endif()
|
||||||
|
target_include_directories(libprotobuf-lite PUBLIC ${protobuf_SOURCE_DIR}/src)
|
||||||
|
target_link_libraries(libprotobuf-lite PUBLIC ${protobuf_ABSL_USED_TARGETS})
|
||||||
|
if(protobuf_BUILD_SHARED_LIBS)
|
||||||
|
target_compile_definitions(libprotobuf-lite
|
||||||
|
PUBLIC PROTOBUF_USE_DLLS
|
||||||
|
PRIVATE LIBPROTOBUF_EXPORTS)
|
||||||
|
endif()
|
||||||
|
set_target_properties(libprotobuf-lite PROPERTIES
|
||||||
|
VERSION ${protobuf_VERSION}
|
||||||
|
OUTPUT_NAME ${LIB_PREFIX}protobuf-lite
|
||||||
|
DEBUG_POSTFIX "${protobuf_DEBUG_POSTFIX}")
|
||||||
|
add_library(protobuf::libprotobuf-lite ALIAS libprotobuf-lite)
|
||||||
39
cmake/libprotobuf.cmake
Normal file
39
cmake/libprotobuf.cmake
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
# CMake definitions for libprotobuf (the "full" C++ protobuf runtime).
|
||||||
|
|
||||||
|
include(${protobuf_SOURCE_DIR}/src/file_lists.cmake)
|
||||||
|
|
||||||
|
add_library(libprotobuf ${protobuf_SHARED_OR_STATIC}
|
||||||
|
${libprotobuf_srcs}
|
||||||
|
${libprotobuf_hdrs}
|
||||||
|
${protobuf_version_rc_file})
|
||||||
|
if(protobuf_HAVE_LD_VERSION_SCRIPT)
|
||||||
|
if(${CMAKE_VERSION} VERSION_GREATER 3.13 OR ${CMAKE_VERSION} VERSION_EQUAL 3.13)
|
||||||
|
target_link_options(libprotobuf PRIVATE -Wl,--version-script=${protobuf_SOURCE_DIR}/src/libprotobuf.map)
|
||||||
|
elseif(protobuf_BUILD_SHARED_LIBS)
|
||||||
|
target_link_libraries(libprotobuf PRIVATE -Wl,--version-script=${protobuf_SOURCE_DIR}/src/libprotobuf.map)
|
||||||
|
endif()
|
||||||
|
set_target_properties(libprotobuf PROPERTIES
|
||||||
|
LINK_DEPENDS ${protobuf_SOURCE_DIR}/src/libprotobuf.map)
|
||||||
|
endif()
|
||||||
|
target_link_libraries(libprotobuf PRIVATE ${CMAKE_THREAD_LIBS_INIT})
|
||||||
|
if(protobuf_WITH_ZLIB)
|
||||||
|
target_link_libraries(libprotobuf PRIVATE ${ZLIB_LIBRARIES})
|
||||||
|
endif()
|
||||||
|
if(protobuf_LINK_LIBATOMIC)
|
||||||
|
target_link_libraries(libprotobuf PRIVATE atomic)
|
||||||
|
endif()
|
||||||
|
if(${CMAKE_SYSTEM_NAME} STREQUAL "Android")
|
||||||
|
target_link_libraries(libprotobuf PRIVATE log)
|
||||||
|
endif()
|
||||||
|
target_include_directories(libprotobuf PUBLIC ${protobuf_SOURCE_DIR}/src)
|
||||||
|
target_link_libraries(libprotobuf PUBLIC ${protobuf_ABSL_USED_TARGETS})
|
||||||
|
if(protobuf_BUILD_SHARED_LIBS)
|
||||||
|
target_compile_definitions(libprotobuf
|
||||||
|
PUBLIC PROTOBUF_USE_DLLS
|
||||||
|
PRIVATE LIBPROTOBUF_EXPORTS)
|
||||||
|
endif()
|
||||||
|
set_target_properties(libprotobuf PROPERTIES
|
||||||
|
VERSION ${protobuf_VERSION}
|
||||||
|
OUTPUT_NAME ${LIB_PREFIX}protobuf
|
||||||
|
DEBUG_POSTFIX "${protobuf_DEBUG_POSTFIX}")
|
||||||
|
add_library(protobuf::libprotobuf ALIAS libprotobuf)
|
||||||
30
cmake/libprotoc.cmake
Normal file
30
cmake/libprotoc.cmake
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
# CMake definitions for libprotoc (the protobuf compiler library).
|
||||||
|
|
||||||
|
include(${protobuf_SOURCE_DIR}/src/file_lists.cmake)
|
||||||
|
|
||||||
|
add_library(libprotoc ${protobuf_SHARED_OR_STATIC}
|
||||||
|
${libprotoc_srcs}
|
||||||
|
${libprotoc_hdrs}
|
||||||
|
${protobuf_version_rc_file})
|
||||||
|
if(protobuf_HAVE_LD_VERSION_SCRIPT)
|
||||||
|
if(${CMAKE_VERSION} VERSION_GREATER 3.13 OR ${CMAKE_VERSION} VERSION_EQUAL 3.13)
|
||||||
|
target_link_options(libprotoc PRIVATE -Wl,--version-script=${protobuf_SOURCE_DIR}/src/libprotoc.map)
|
||||||
|
elseif(protobuf_BUILD_SHARED_LIBS)
|
||||||
|
target_link_libraries(libprotoc PRIVATE -Wl,--version-script=${protobuf_SOURCE_DIR}/src/libprotoc.map)
|
||||||
|
endif()
|
||||||
|
set_target_properties(libprotoc PROPERTIES
|
||||||
|
LINK_DEPENDS ${protobuf_SOURCE_DIR}/src/libprotoc.map)
|
||||||
|
endif()
|
||||||
|
target_link_libraries(libprotoc PRIVATE libprotobuf)
|
||||||
|
target_link_libraries(libprotoc PUBLIC ${protobuf_ABSL_USED_TARGETS})
|
||||||
|
if(protobuf_BUILD_SHARED_LIBS)
|
||||||
|
target_compile_definitions(libprotoc
|
||||||
|
PUBLIC PROTOBUF_USE_DLLS
|
||||||
|
PRIVATE LIBPROTOC_EXPORTS)
|
||||||
|
endif()
|
||||||
|
set_target_properties(libprotoc PROPERTIES
|
||||||
|
COMPILE_DEFINITIONS LIBPROTOC_EXPORTS
|
||||||
|
VERSION ${protobuf_VERSION}
|
||||||
|
OUTPUT_NAME ${LIB_PREFIX}protoc
|
||||||
|
DEBUG_POSTFIX "${protobuf_DEBUG_POSTFIX}")
|
||||||
|
add_library(protobuf::libprotoc ALIAS libprotoc)
|
||||||
60
cmake/protobuf-config-version.cmake.in
Normal file
60
cmake/protobuf-config-version.cmake.in
Normal file
@@ -0,0 +1,60 @@
|
|||||||
|
set(PACKAGE_VERSION "@protobuf_VERSION@")
|
||||||
|
set(${PACKAGE_FIND_NAME}_VERSION_PRERELEASE "@protobuf_VERSION_PRERELEASE@" PARENT_SCOPE)
|
||||||
|
|
||||||
|
# Prerelease versions cannot be passed in directly via the find_package command,
|
||||||
|
# so we allow users to specify it in a variable
|
||||||
|
if(NOT DEFINED "${PACKAGE_FIND_NAME}_FIND_VERSION_PRERELEASE")
|
||||||
|
set("${${PACKAGE_FIND_NAME}_FIND_VERSION_PRERELEASE}" "")
|
||||||
|
else()
|
||||||
|
set(PACKAGE_FIND_VERSION ${PACKAGE_FIND_VERSION}-${${PACKAGE_FIND_NAME}_FIND_VERSION_PRERELEASE})
|
||||||
|
endif()
|
||||||
|
set(PACKAGE_FIND_VERSION_PRERELEASE "${${PACKAGE_FIND_NAME}_FIND_VERSION_PRERELEASE}")
|
||||||
|
|
||||||
|
# VERSION_EQUAL ignores the prerelease strings, so we use STREQUAL.
|
||||||
|
if(PACKAGE_FIND_VERSION STREQUAL PACKAGE_VERSION)
|
||||||
|
set(PACKAGE_VERSION_EXACT TRUE)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
set(PACKAGE_VERSION_COMPATIBLE TRUE) #Assume true until shown otherwise
|
||||||
|
|
||||||
|
if(PACKAGE_FIND_VERSION) #Only perform version checks if one is given
|
||||||
|
if(NOT PACKAGE_FIND_VERSION_MAJOR EQUAL "@protobuf_VERSION_MAJOR@")
|
||||||
|
set(PACKAGE_VERSION_COMPATIBLE FALSE)
|
||||||
|
elseif(PACKAGE_FIND_VERSION VERSION_GREATER PACKAGE_VERSION)
|
||||||
|
set(PACKAGE_VERSION_COMPATIBLE FALSE)
|
||||||
|
elseif(PACKAGE_FIND_VERSION VERSION_EQUAL PACKAGE_VERSION)
|
||||||
|
# Do not match prerelease versions to non-prerelease version requests.
|
||||||
|
if(NOT "@protobuf_VERSION_PRERELEASE@" STREQUAL "" AND PACKAGE_FIND_VERSION_PRERELEASE STREQUAL "")
|
||||||
|
message(AUTHOR_WARNING "To use this prerelease version of ${PACKAGE_FIND_NAME}, set ${PACKAGE_FIND_NAME}_FIND_VERSION_PRERELEASE to '@protobuf_VERSION_PRERELEASE@' or greater.")
|
||||||
|
set(PACKAGE_VERSION_COMPATIBLE FALSE)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# Not robustly SemVer compliant, but protobuf never uses '.' separated prerelease identifiers.
|
||||||
|
if(PACKAGE_FIND_VERSION_PRERELEASE STRGREATER "@protobuf_VERSION_PRERELEASE@")
|
||||||
|
set(PACKAGE_VERSION_COMPATIBLE FALSE)
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# Check and save build options used to create this package
|
||||||
|
macro(_check_and_save_build_option OPTION VALUE)
|
||||||
|
if(DEFINED ${PACKAGE_FIND_NAME}_${OPTION} AND
|
||||||
|
NOT ${PACKAGE_FIND_NAME}_${OPTION} STREQUAL ${VALUE})
|
||||||
|
set(PACKAGE_VERSION_UNSUITABLE TRUE)
|
||||||
|
endif()
|
||||||
|
set(${PACKAGE_FIND_NAME}_${OPTION} ${VALUE} PARENT_SCOPE)
|
||||||
|
endmacro()
|
||||||
|
_check_and_save_build_option(WITH_ZLIB @protobuf_WITH_ZLIB@)
|
||||||
|
_check_and_save_build_option(MSVC_STATIC_RUNTIME @protobuf_MSVC_STATIC_RUNTIME@)
|
||||||
|
_check_and_save_build_option(BUILD_SHARED_LIBS @protobuf_BUILD_SHARED_LIBS@)
|
||||||
|
|
||||||
|
# if the installed or the using project don't have CMAKE_SIZEOF_VOID_P set, ignore it:
|
||||||
|
if(CMAKE_SIZEOF_VOID_P AND "@CMAKE_SIZEOF_VOID_P@")
|
||||||
|
# check that the installed version has the same 32/64bit-ness as the one which is currently searching:
|
||||||
|
if(NOT CMAKE_SIZEOF_VOID_P EQUAL "@CMAKE_SIZEOF_VOID_P@")
|
||||||
|
math(EXPR installedBits "@CMAKE_SIZEOF_VOID_P@ * 8")
|
||||||
|
set(PACKAGE_VERSION "${PACKAGE_VERSION} (${installedBits}bit)")
|
||||||
|
set(PACKAGE_VERSION_UNSUITABLE TRUE)
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
|
||||||
17
cmake/protobuf-config.cmake.in
Normal file
17
cmake/protobuf-config.cmake.in
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
# User options
|
||||||
|
include("${CMAKE_CURRENT_LIST_DIR}/protobuf-options.cmake")
|
||||||
|
|
||||||
|
# Depend packages
|
||||||
|
@_protobuf_FIND_ZLIB@
|
||||||
|
@_protobuf_FIND_ABSL@
|
||||||
|
|
||||||
|
# Imported targets
|
||||||
|
include("${CMAKE_CURRENT_LIST_DIR}/protobuf-targets.cmake")
|
||||||
|
|
||||||
|
# protobuf-generate function
|
||||||
|
include("${CMAKE_CURRENT_LIST_DIR}/protobuf-generate.cmake")
|
||||||
|
|
||||||
|
# CMake FindProtobuf module compatible file
|
||||||
|
if(protobuf_MODULE_COMPATIBLE)
|
||||||
|
include("${CMAKE_CURRENT_LIST_DIR}/protobuf-module.cmake")
|
||||||
|
endif()
|
||||||
155
cmake/protobuf-generate.cmake
Normal file
155
cmake/protobuf-generate.cmake
Normal file
@@ -0,0 +1,155 @@
|
|||||||
|
function(protobuf_generate)
|
||||||
|
include(CMakeParseArguments)
|
||||||
|
|
||||||
|
set(_options APPEND_PATH)
|
||||||
|
set(_singleargs LANGUAGE OUT_VAR EXPORT_MACRO PROTOC_OUT_DIR PLUGIN PLUGIN_OPTIONS DEPENDENCIES)
|
||||||
|
if(COMMAND target_sources)
|
||||||
|
list(APPEND _singleargs TARGET)
|
||||||
|
endif()
|
||||||
|
set(_multiargs PROTOS IMPORT_DIRS GENERATE_EXTENSIONS PROTOC_OPTIONS)
|
||||||
|
|
||||||
|
cmake_parse_arguments(protobuf_generate "${_options}" "${_singleargs}" "${_multiargs}" "${ARGN}")
|
||||||
|
|
||||||
|
if(NOT protobuf_generate_PROTOS AND NOT protobuf_generate_TARGET)
|
||||||
|
message(SEND_ERROR "Error: protobuf_generate called without any targets or source files")
|
||||||
|
return()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(NOT protobuf_generate_OUT_VAR AND NOT protobuf_generate_TARGET)
|
||||||
|
message(SEND_ERROR "Error: protobuf_generate called without a target or output variable")
|
||||||
|
return()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(NOT protobuf_generate_LANGUAGE)
|
||||||
|
set(protobuf_generate_LANGUAGE cpp)
|
||||||
|
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()
|
||||||
|
|
||||||
|
foreach(_option ${_dll_export_decl} ${protobuf_generate_PLUGIN_OPTIONS})
|
||||||
|
# append comma - not using CMake lists and string replacement as users
|
||||||
|
# might have semicolons in options
|
||||||
|
if(_plugin_options)
|
||||||
|
set( _plugin_options "${_plugin_options},")
|
||||||
|
endif()
|
||||||
|
set(_plugin_options "${_plugin_options}${_option}")
|
||||||
|
endforeach()
|
||||||
|
|
||||||
|
if(protobuf_generate_PLUGIN)
|
||||||
|
set(_plugin "--plugin=${protobuf_generate_PLUGIN}")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(NOT protobuf_generate_GENERATE_EXTENSIONS)
|
||||||
|
if(protobuf_generate_LANGUAGE STREQUAL cpp)
|
||||||
|
set(protobuf_generate_GENERATE_EXTENSIONS .pb.h .pb.cc)
|
||||||
|
elseif(protobuf_generate_LANGUAGE STREQUAL python)
|
||||||
|
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()
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(protobuf_generate_TARGET)
|
||||||
|
get_target_property(_source_list ${protobuf_generate_TARGET} SOURCES)
|
||||||
|
foreach(_file ${_source_list})
|
||||||
|
if(_file MATCHES "proto$")
|
||||||
|
list(APPEND protobuf_generate_PROTOS ${_file})
|
||||||
|
endif()
|
||||||
|
endforeach()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(NOT protobuf_generate_PROTOS)
|
||||||
|
message(SEND_ERROR "Error: protobuf_generate could not find any .proto files")
|
||||||
|
return()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(protobuf_generate_APPEND_PATH)
|
||||||
|
# Create an include path for each file specified
|
||||||
|
foreach(_file ${protobuf_generate_PROTOS})
|
||||||
|
get_filename_component(_abs_file ${_file} ABSOLUTE)
|
||||||
|
get_filename_component(_abs_dir ${_abs_file} DIRECTORY)
|
||||||
|
list(FIND _protobuf_include_path ${_abs_dir} _contains_already)
|
||||||
|
if(${_contains_already} EQUAL -1)
|
||||||
|
list(APPEND _protobuf_include_path -I ${_abs_dir})
|
||||||
|
endif()
|
||||||
|
endforeach()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
foreach(DIR ${protobuf_generate_IMPORT_DIRS})
|
||||||
|
get_filename_component(ABS_PATH ${DIR} ABSOLUTE)
|
||||||
|
list(FIND _protobuf_include_path ${ABS_PATH} _contains_already)
|
||||||
|
if(${_contains_already} EQUAL -1)
|
||||||
|
list(APPEND _protobuf_include_path -I ${ABS_PATH})
|
||||||
|
endif()
|
||||||
|
endforeach()
|
||||||
|
|
||||||
|
if(NOT _protobuf_include_path)
|
||||||
|
set(_protobuf_include_path -I ${CMAKE_CURRENT_SOURCE_DIR})
|
||||||
|
endif()
|
||||||
|
|
||||||
|
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(_file_full_name ${_proto} NAME)
|
||||||
|
string(FIND "${_file_full_name}" "." _file_last_ext_pos REVERSE)
|
||||||
|
string(SUBSTRING "${_file_full_name}" 0 ${_file_last_ext_pos} _basename)
|
||||||
|
|
||||||
|
set(_suitable_include_found FALSE)
|
||||||
|
foreach(DIR ${_protobuf_include_path})
|
||||||
|
if(NOT DIR STREQUAL "-I")
|
||||||
|
file(RELATIVE_PATH _rel_dir ${DIR} ${_abs_dir})
|
||||||
|
string(FIND "${_rel_dir}" "../" _is_in_parent_folder)
|
||||||
|
if (NOT ${_is_in_parent_folder} EQUAL 0)
|
||||||
|
set(_suitable_include_found TRUE)
|
||||||
|
break()
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
endforeach()
|
||||||
|
|
||||||
|
if(NOT _suitable_include_found)
|
||||||
|
message(SEND_ERROR "Error: protobuf_generate could not find any correct proto include directory.")
|
||||||
|
return()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
set(_generated_srcs)
|
||||||
|
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})
|
||||||
|
|
||||||
|
set(_comment "Running ${protobuf_generate_LANGUAGE} protocol buffer compiler on ${_proto}")
|
||||||
|
if(protobuf_generate_PROTOC_OPTIONS)
|
||||||
|
set(_comment "${_comment}, protoc-options: ${protobuf_generate_PROTOC_OPTIONS}")
|
||||||
|
endif()
|
||||||
|
if(_plugin_options)
|
||||||
|
set(_comment "${_comment}, plugin-options: ${_plugin_options}")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
add_custom_command(
|
||||||
|
OUTPUT ${_generated_srcs}
|
||||||
|
COMMAND protobuf::protoc
|
||||||
|
ARGS ${protobuf_generate_PROTOC_OPTIONS} --${protobuf_generate_LANGUAGE}_out ${_plugin_options}:${protobuf_generate_PROTOC_OUT_DIR} ${_plugin} ${_protobuf_include_path} ${_abs_file}
|
||||||
|
DEPENDS ${_abs_file} protobuf::protoc ${protobuf_generate_DEPENDENCIES}
|
||||||
|
COMMENT ${_comment}
|
||||||
|
VERBATIM )
|
||||||
|
endforeach()
|
||||||
|
|
||||||
|
set_source_files_properties(${_generated_srcs_all} PROPERTIES GENERATED TRUE)
|
||||||
|
if(protobuf_generate_OUT_VAR)
|
||||||
|
set(${protobuf_generate_OUT_VAR} ${_generated_srcs_all} PARENT_SCOPE)
|
||||||
|
endif()
|
||||||
|
if(protobuf_generate_TARGET)
|
||||||
|
target_sources(${protobuf_generate_TARGET} PRIVATE ${_generated_srcs_all})
|
||||||
|
endif()
|
||||||
|
|
||||||
|
endfunction()
|
||||||
11
cmake/protobuf-lite.pc.cmake
Normal file
11
cmake/protobuf-lite.pc.cmake
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
prefix=@CMAKE_INSTALL_PREFIX@
|
||||||
|
exec_prefix=@CMAKE_INSTALL_PREFIX@
|
||||||
|
libdir=@CMAKE_INSTALL_FULL_LIBDIR@
|
||||||
|
includedir=@CMAKE_INSTALL_FULL_INCLUDEDIR@
|
||||||
|
|
||||||
|
Name: Protocol Buffers
|
||||||
|
Description: Google's Data Interchange Format
|
||||||
|
Version: @protobuf_VERSION@
|
||||||
|
Libs: -L${libdir} -lprotobuf-lite @CMAKE_THREAD_LIBS_INIT@
|
||||||
|
Cflags: -I${includedir}
|
||||||
|
Conflicts: protobuf
|
||||||
189
cmake/protobuf-module.cmake.in
Normal file
189
cmake/protobuf-module.cmake.in
Normal file
@@ -0,0 +1,189 @@
|
|||||||
|
# This file contains backwards compatibility patches for various legacy functions and variables
|
||||||
|
# Functions
|
||||||
|
|
||||||
|
function(PROTOBUF_GENERATE_CPP SRCS HDRS)
|
||||||
|
cmake_parse_arguments(protobuf_generate_cpp "" "EXPORT_MACRO" "" ${ARGN})
|
||||||
|
|
||||||
|
set(_proto_files "${protobuf_generate_cpp_UNPARSED_ARGUMENTS}")
|
||||||
|
if(NOT _proto_files)
|
||||||
|
message(SEND_ERROR "Error: PROTOBUF_GENERATE_CPP() called without any proto files")
|
||||||
|
return()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(PROTOBUF_GENERATE_CPP_APPEND_PATH)
|
||||||
|
set(_append_arg APPEND_PATH)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(DEFINED Protobuf_IMPORT_DIRS)
|
||||||
|
set(_import_arg IMPORT_DIRS ${Protobuf_IMPORT_DIRS})
|
||||||
|
endif()
|
||||||
|
|
||||||
|
set(_outvar)
|
||||||
|
protobuf_generate(${_append_arg} LANGUAGE cpp EXPORT_MACRO ${protobuf_generate_cpp_EXPORT_MACRO} OUT_VAR _outvar ${_import_arg} PROTOS ${_proto_files})
|
||||||
|
|
||||||
|
set(${SRCS})
|
||||||
|
set(${HDRS})
|
||||||
|
foreach(_file ${_outvar})
|
||||||
|
if(_file MATCHES "cc$")
|
||||||
|
list(APPEND ${SRCS} ${_file})
|
||||||
|
else()
|
||||||
|
list(APPEND ${HDRS} ${_file})
|
||||||
|
endif()
|
||||||
|
endforeach()
|
||||||
|
set(${SRCS} ${${SRCS}} PARENT_SCOPE)
|
||||||
|
set(${HDRS} ${${HDRS}} PARENT_SCOPE)
|
||||||
|
endfunction()
|
||||||
|
|
||||||
|
function(PROTOBUF_GENERATE_PYTHON SRCS)
|
||||||
|
if(NOT ARGN)
|
||||||
|
message(SEND_ERROR "Error: PROTOBUF_GENERATE_PYTHON() called without any proto files")
|
||||||
|
return()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(PROTOBUF_GENERATE_CPP_APPEND_PATH)
|
||||||
|
set(_append_arg APPEND_PATH)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(DEFINED Protobuf_IMPORT_DIRS)
|
||||||
|
set(_import_arg IMPORT_DIRS ${Protobuf_IMPORT_DIRS})
|
||||||
|
endif()
|
||||||
|
|
||||||
|
set(_outvar)
|
||||||
|
protobuf_generate(${_append_arg} LANGUAGE python OUT_VAR _outvar ${_import_arg} PROTOS ${ARGN})
|
||||||
|
set(${SRCS} ${_outvar} PARENT_SCOPE)
|
||||||
|
endfunction()
|
||||||
|
|
||||||
|
# Environment
|
||||||
|
|
||||||
|
# Backwards compatibility
|
||||||
|
# Define camel case versions of input variables
|
||||||
|
foreach(UPPER
|
||||||
|
PROTOBUF_SRC_ROOT_FOLDER
|
||||||
|
PROTOBUF_IMPORT_DIRS
|
||||||
|
PROTOBUF_DEBUG
|
||||||
|
PROTOBUF_LIBRARY
|
||||||
|
PROTOBUF_PROTOC_LIBRARY
|
||||||
|
PROTOBUF_INCLUDE_DIR
|
||||||
|
PROTOBUF_PROTOC_EXECUTABLE
|
||||||
|
PROTOBUF_LIBRARY_DEBUG
|
||||||
|
PROTOBUF_PROTOC_LIBRARY_DEBUG
|
||||||
|
PROTOBUF_LITE_LIBRARY
|
||||||
|
PROTOBUF_LITE_LIBRARY_DEBUG
|
||||||
|
)
|
||||||
|
if (DEFINED ${UPPER})
|
||||||
|
string(REPLACE "PROTOBUF_" "Protobuf_" Camel ${UPPER})
|
||||||
|
if (NOT DEFINED ${Camel})
|
||||||
|
set(${Camel} ${${UPPER}})
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
endforeach()
|
||||||
|
|
||||||
|
if(DEFINED Protobuf_SRC_ROOT_FOLDER)
|
||||||
|
message(AUTHOR_WARNING "Variable Protobuf_SRC_ROOT_FOLDER defined, but not"
|
||||||
|
" used in CONFIG mode")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
include(SelectLibraryConfigurations)
|
||||||
|
|
||||||
|
# Internal function: search for normal library as well as a debug one
|
||||||
|
# if the debug one is specified also include debug/optimized keywords
|
||||||
|
# in *_LIBRARIES variable
|
||||||
|
function(_protobuf_find_libraries name filename)
|
||||||
|
if(${name}_LIBRARIES)
|
||||||
|
# Use result recorded by a previous call.
|
||||||
|
elseif(${name}_LIBRARY)
|
||||||
|
# Honor cache entry used by CMake 3.5 and lower.
|
||||||
|
set(${name}_LIBRARIES "${${name}_LIBRARY}" PARENT_SCOPE)
|
||||||
|
elseif(TARGET protobuf::lib${filename})
|
||||||
|
get_target_property(${name}_LIBRARY_RELEASE protobuf::lib${filename}
|
||||||
|
LOCATION_RELEASE)
|
||||||
|
get_target_property(${name}_LIBRARY_RELWITHDEBINFO protobuf::lib${filename}
|
||||||
|
LOCATION_RELWITHDEBINFO)
|
||||||
|
get_target_property(${name}_LIBRARY_MINSIZEREL protobuf::lib${filename}
|
||||||
|
LOCATION_MINSIZEREL)
|
||||||
|
get_target_property(${name}_LIBRARY_DEBUG protobuf::lib${filename}
|
||||||
|
LOCATION_DEBUG)
|
||||||
|
|
||||||
|
select_library_configurations(${name})
|
||||||
|
set(${name}_LIBRARY ${${name}_LIBRARY} PARENT_SCOPE)
|
||||||
|
set(${name}_LIBRARIES ${${name}_LIBRARIES} PARENT_SCOPE)
|
||||||
|
endif()
|
||||||
|
endfunction()
|
||||||
|
|
||||||
|
#
|
||||||
|
# Main.
|
||||||
|
#
|
||||||
|
|
||||||
|
# By default have PROTOBUF_GENERATE_CPP macro pass -I to protoc
|
||||||
|
# for each directory where a proto file is referenced.
|
||||||
|
if(NOT DEFINED PROTOBUF_GENERATE_CPP_APPEND_PATH)
|
||||||
|
set(PROTOBUF_GENERATE_CPP_APPEND_PATH TRUE)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# The Protobuf library
|
||||||
|
_protobuf_find_libraries(Protobuf protobuf)
|
||||||
|
|
||||||
|
# The Protobuf Lite library
|
||||||
|
_protobuf_find_libraries(Protobuf_LITE protobuf-lite)
|
||||||
|
|
||||||
|
# The Protobuf Protoc Library
|
||||||
|
_protobuf_find_libraries(Protobuf_PROTOC protoc)
|
||||||
|
|
||||||
|
# Set the include directory
|
||||||
|
get_target_property(Protobuf_INCLUDE_DIRS protobuf::libprotobuf
|
||||||
|
INTERFACE_INCLUDE_DIRECTORIES)
|
||||||
|
|
||||||
|
# Set the protoc Executable
|
||||||
|
if(NOT Protobuf_PROTOC_EXECUTABLE AND TARGET protobuf::protoc)
|
||||||
|
get_target_property(Protobuf_PROTOC_EXECUTABLE protobuf::protoc
|
||||||
|
IMPORTED_LOCATION_RELEASE)
|
||||||
|
if(NOT EXISTS "${Protobuf_PROTOC_EXECUTABLE}")
|
||||||
|
get_target_property(Protobuf_PROTOC_EXECUTABLE protobuf::protoc
|
||||||
|
IMPORTED_LOCATION_RELWITHDEBINFO)
|
||||||
|
endif()
|
||||||
|
if(NOT EXISTS "${Protobuf_PROTOC_EXECUTABLE}")
|
||||||
|
get_target_property(Protobuf_PROTOC_EXECUTABLE protobuf::protoc
|
||||||
|
IMPORTED_LOCATION_MINSIZEREL)
|
||||||
|
endif()
|
||||||
|
if(NOT EXISTS "${Protobuf_PROTOC_EXECUTABLE}")
|
||||||
|
get_target_property(Protobuf_PROTOC_EXECUTABLE protobuf::protoc
|
||||||
|
IMPORTED_LOCATION_DEBUG)
|
||||||
|
endif()
|
||||||
|
if(NOT EXISTS "${Protobuf_PROTOC_EXECUTABLE}")
|
||||||
|
get_target_property(Protobuf_PROTOC_EXECUTABLE protobuf::protoc
|
||||||
|
IMPORTED_LOCATION_NOCONFIG)
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# Version info variable
|
||||||
|
set(Protobuf_VERSION "@protobuf_VERSION@")
|
||||||
|
|
||||||
|
include(FindPackageHandleStandardArgs)
|
||||||
|
FIND_PACKAGE_HANDLE_STANDARD_ARGS(Protobuf
|
||||||
|
REQUIRED_VARS Protobuf_PROTOC_EXECUTABLE Protobuf_LIBRARIES Protobuf_INCLUDE_DIRS
|
||||||
|
VERSION_VAR Protobuf_VERSION
|
||||||
|
)
|
||||||
|
|
||||||
|
# Backwards compatibility
|
||||||
|
# Define upper case versions of output variables
|
||||||
|
foreach(Camel
|
||||||
|
Protobuf_VERSION
|
||||||
|
Protobuf_SRC_ROOT_FOLDER
|
||||||
|
Protobuf_IMPORT_DIRS
|
||||||
|
Protobuf_DEBUG
|
||||||
|
Protobuf_INCLUDE_DIRS
|
||||||
|
Protobuf_LIBRARIES
|
||||||
|
Protobuf_PROTOC_LIBRARIES
|
||||||
|
Protobuf_LITE_LIBRARIES
|
||||||
|
Protobuf_LIBRARY
|
||||||
|
Protobuf_PROTOC_LIBRARY
|
||||||
|
Protobuf_INCLUDE_DIR
|
||||||
|
Protobuf_PROTOC_EXECUTABLE
|
||||||
|
Protobuf_LIBRARY_DEBUG
|
||||||
|
Protobuf_PROTOC_LIBRARY_DEBUG
|
||||||
|
Protobuf_LITE_LIBRARY
|
||||||
|
Protobuf_LITE_LIBRARY_DEBUG
|
||||||
|
)
|
||||||
|
string(TOUPPER ${Camel} UPPER)
|
||||||
|
set(${UPPER} ${${Camel}})
|
||||||
|
endforeach()
|
||||||
7
cmake/protobuf-options.cmake
Normal file
7
cmake/protobuf-options.cmake
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
# Verbose output
|
||||||
|
option(protobuf_VERBOSE "Enable for verbose output" OFF)
|
||||||
|
mark_as_advanced(protobuf_VERBOSE)
|
||||||
|
|
||||||
|
# FindProtobuf module compatible
|
||||||
|
option(protobuf_MODULE_COMPATIBLE "CMake built-in FindProtobuf.cmake module compatible" OFF)
|
||||||
|
mark_as_advanced(protobuf_MODULE_COMPATIBLE)
|
||||||
11
cmake/protobuf.pc.cmake
Normal file
11
cmake/protobuf.pc.cmake
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
prefix=@CMAKE_INSTALL_PREFIX@
|
||||||
|
exec_prefix=@CMAKE_INSTALL_PREFIX@
|
||||||
|
libdir=@CMAKE_INSTALL_FULL_LIBDIR@
|
||||||
|
includedir=@CMAKE_INSTALL_FULL_INCLUDEDIR@
|
||||||
|
|
||||||
|
Name: Protocol Buffers
|
||||||
|
Description: Google's Data Interchange Format
|
||||||
|
Version: @protobuf_VERSION@
|
||||||
|
Libs: -L${libdir} -lprotobuf @CMAKE_THREAD_LIBS_INIT@
|
||||||
|
Cflags: -I${includedir}
|
||||||
|
Conflicts: protobuf-lite
|
||||||
14
cmake/protoc.cmake
Normal file
14
cmake/protoc.cmake
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
set(protoc_files
|
||||||
|
${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/main.cc
|
||||||
|
)
|
||||||
|
|
||||||
|
add_executable(protoc ${protoc_files} ${protobuf_version_rc_file})
|
||||||
|
target_link_libraries(protoc
|
||||||
|
libprotoc
|
||||||
|
libprotobuf
|
||||||
|
${protobuf_ABSL_USED_TARGETS}
|
||||||
|
)
|
||||||
|
add_executable(protobuf::protoc ALIAS protoc)
|
||||||
|
|
||||||
|
set_target_properties(protoc PROPERTIES
|
||||||
|
VERSION ${protobuf_VERSION})
|
||||||
41
cmake/push_auto_update.sh
Executable file
41
cmake/push_auto_update.sh
Executable file
@@ -0,0 +1,41 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# This script updates the CMake file lists (i.e. src/file_lists.cmake), commits
|
||||||
|
# the resulting change, and pushes it. This does not do anything useful when
|
||||||
|
# run manually, but should be run by our GitHub action instead.
|
||||||
|
|
||||||
|
set -ex
|
||||||
|
|
||||||
|
# Exit early if the previous commit was made by the bot. This reduces the risk
|
||||||
|
# of a bug causing an infinite loop of auto-generated commits.
|
||||||
|
if (git log -1 --pretty=format:'%an' | grep -q "Protobuf Team Bot"); then
|
||||||
|
echo "Previous commit was authored by bot"
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
$(dirname -- "$0")/update_file_lists.sh
|
||||||
|
|
||||||
|
# Try to determine the most recent pull request number.
|
||||||
|
title=$(git log -1 --pretty='%s')
|
||||||
|
pr_from_merge=$(echo "$title" | sed -n 's/^Merge pull request #\([0-9]\+\).*/\1/p')
|
||||||
|
pr_from_squash=$(echo "$title" | sed -n 's/^.*(#\([0-9]\+\))$/\1/p')
|
||||||
|
|
||||||
|
pr=""
|
||||||
|
if [ ! -z "$pr_from_merge" ]; then
|
||||||
|
pr="$pr_from_merge"
|
||||||
|
elif [ ! -z "$pr_from_squash" ]; then
|
||||||
|
pr="$pr_from_squash"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ ! -z "$pr" ]; then
|
||||||
|
commit_message="Auto-generate CMake file lists after PR #$pr"
|
||||||
|
else
|
||||||
|
# If we are unable to determine the pull request number, we fall back on this
|
||||||
|
# default commit message. Typically this should not occur, but could happen
|
||||||
|
# if a pull request was merged via a rebase.
|
||||||
|
commit_message="Auto-generate CMake file lists"
|
||||||
|
fi
|
||||||
|
|
||||||
|
git add -A
|
||||||
|
git diff --staged --quiet || git commit -am "$commit_message"
|
||||||
|
git push
|
||||||
209
cmake/tests.cmake
Normal file
209
cmake/tests.cmake
Normal file
@@ -0,0 +1,209 @@
|
|||||||
|
option(protobuf_USE_EXTERNAL_GTEST "Use external Google Test (i.e. not the one in third_party/googletest)" OFF)
|
||||||
|
|
||||||
|
option(protobuf_REMOVE_INSTALLED_HEADERS
|
||||||
|
"Remove local headers so that installed ones are used instead" OFF)
|
||||||
|
|
||||||
|
option(protobuf_ABSOLUTE_TEST_PLUGIN_PATH
|
||||||
|
"Using absolute test_plugin path in tests" ON)
|
||||||
|
mark_as_advanced(protobuf_ABSOLUTE_TEST_PLUGIN_PATH)
|
||||||
|
|
||||||
|
if (protobuf_USE_EXTERNAL_GTEST)
|
||||||
|
find_package(GTest REQUIRED)
|
||||||
|
else()
|
||||||
|
if (NOT EXISTS "${protobuf_SOURCE_DIR}/third_party/googletest/CMakeLists.txt")
|
||||||
|
message(FATAL_ERROR
|
||||||
|
"Cannot find third_party/googletest directory that's needed to "
|
||||||
|
"build tests. If you use git, make sure you have cloned submodules:\n"
|
||||||
|
" git submodule update --init --recursive\n"
|
||||||
|
"If instead you want to skip tests, run cmake with:\n"
|
||||||
|
" cmake -Dprotobuf_BUILD_TESTS=OFF\n")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
set(googlemock_source_dir "${protobuf_SOURCE_DIR}/third_party/googletest/googlemock")
|
||||||
|
set(googletest_source_dir "${protobuf_SOURCE_DIR}/third_party/googletest/googletest")
|
||||||
|
include_directories(
|
||||||
|
${googlemock_source_dir}
|
||||||
|
${googletest_source_dir}
|
||||||
|
${googletest_source_dir}/include
|
||||||
|
${googlemock_source_dir}/include
|
||||||
|
)
|
||||||
|
|
||||||
|
add_library(gmock STATIC
|
||||||
|
"${googlemock_source_dir}/src/gmock-all.cc"
|
||||||
|
"${googletest_source_dir}/src/gtest-all.cc"
|
||||||
|
)
|
||||||
|
target_link_libraries(gmock ${CMAKE_THREAD_LIBS_INIT})
|
||||||
|
add_library(gmock_main STATIC "${googlemock_source_dir}/src/gmock_main.cc")
|
||||||
|
target_link_libraries(gmock_main gmock)
|
||||||
|
|
||||||
|
add_library(GTest::gmock ALIAS gmock)
|
||||||
|
add_library(GTest::gmock_main ALIAS gmock_main)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
include(${protobuf_SOURCE_DIR}/src/file_lists.cmake)
|
||||||
|
|
||||||
|
set(lite_test_protos
|
||||||
|
${protobuf_lite_test_protos_files}
|
||||||
|
)
|
||||||
|
|
||||||
|
set(tests_protos
|
||||||
|
${protobuf_test_protos_files}
|
||||||
|
${compiler_test_protos_files}
|
||||||
|
${util_test_protos_files}
|
||||||
|
)
|
||||||
|
|
||||||
|
macro(compile_proto_file filename)
|
||||||
|
string(REPLACE .proto .pb.h pb_hdr ${filename})
|
||||||
|
string(REPLACE .proto .pb.cc pb_src ${filename})
|
||||||
|
add_custom_command(
|
||||||
|
OUTPUT ${pb_hdr} ${pb_src}
|
||||||
|
DEPENDS ${protobuf_PROTOC_EXE} ${filename}
|
||||||
|
COMMAND ${protobuf_PROTOC_EXE} ${filename}
|
||||||
|
--proto_path=${protobuf_SOURCE_DIR}/src
|
||||||
|
--cpp_out=${protobuf_SOURCE_DIR}/src
|
||||||
|
--experimental_allow_proto3_optional
|
||||||
|
)
|
||||||
|
endmacro(compile_proto_file)
|
||||||
|
|
||||||
|
set(lite_test_proto_files)
|
||||||
|
foreach(proto_file ${lite_test_protos})
|
||||||
|
compile_proto_file(${proto_file})
|
||||||
|
set(lite_test_proto_files ${lite_test_proto_files} ${pb_src} ${pb_hdr})
|
||||||
|
endforeach(proto_file)
|
||||||
|
|
||||||
|
set(tests_proto_files)
|
||||||
|
foreach(proto_file ${tests_protos})
|
||||||
|
compile_proto_file(${proto_file})
|
||||||
|
set(tests_proto_files ${tests_proto_files} ${pb_src} ${pb_hdr})
|
||||||
|
endforeach(proto_file)
|
||||||
|
|
||||||
|
add_library(protobuf-lite-test-common STATIC
|
||||||
|
${lite_test_util_srcs} ${lite_test_proto_files})
|
||||||
|
target_include_directories(protobuf-lite-test-common PRIVATE ${ABSL_ROOT_DIR})
|
||||||
|
target_link_libraries(protobuf-lite-test-common
|
||||||
|
${protobuf_LIB_PROTOBUF_LITE} ${protobuf_ABSL_USED_TARGETS} GTest::gmock)
|
||||||
|
|
||||||
|
set(common_test_files
|
||||||
|
${test_util_hdrs}
|
||||||
|
${test_util_srcs}
|
||||||
|
${common_test_hdrs}
|
||||||
|
${common_test_srcs}
|
||||||
|
)
|
||||||
|
|
||||||
|
add_library(protobuf-test-common STATIC
|
||||||
|
${common_test_files} ${tests_proto_files})
|
||||||
|
target_include_directories(protobuf-test-common PRIVATE ${ABSL_ROOT_DIR})
|
||||||
|
target_link_libraries(protobuf-test-common
|
||||||
|
${protobuf_LIB_PROTOBUF} ${protobuf_ABSL_USED_TARGETS} GTest::gmock)
|
||||||
|
|
||||||
|
set(tests_files
|
||||||
|
${protobuf_test_files}
|
||||||
|
${compiler_test_files}
|
||||||
|
${annotation_test_util_srcs}
|
||||||
|
${io_test_files}
|
||||||
|
${util_test_files}
|
||||||
|
${stubs_test_files}
|
||||||
|
)
|
||||||
|
|
||||||
|
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()
|
||||||
|
|
||||||
|
if(protobuf_TEST_XML_OUTDIR)
|
||||||
|
if(NOT "${protobuf_TEST_XML_OUTDIR}" MATCHES "[/\\]$")
|
||||||
|
string(APPEND protobuf_TEST_XML_OUTDIR "/")
|
||||||
|
endif()
|
||||||
|
set(protobuf_GTEST_ARGS "--gtest_output=xml:${protobuf_TEST_XML_OUTDIR}")
|
||||||
|
else()
|
||||||
|
set(protobuf_GTEST_ARGS)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
add_executable(tests ${tests_files})
|
||||||
|
if (MSVC)
|
||||||
|
target_compile_options(tests PRIVATE
|
||||||
|
/wd4146 # unary minus operator applied to unsigned type, result still unsigned
|
||||||
|
)
|
||||||
|
endif()
|
||||||
|
target_link_libraries(tests protobuf-lite-test-common protobuf-test-common ${protobuf_LIB_PROTOC} ${protobuf_LIB_PROTOBUF} GTest::gmock_main)
|
||||||
|
|
||||||
|
set(test_plugin_files
|
||||||
|
${test_plugin_files}
|
||||||
|
${common_test_hdrs}
|
||||||
|
${common_test_srcs}
|
||||||
|
)
|
||||||
|
|
||||||
|
add_executable(test_plugin ${test_plugin_files})
|
||||||
|
target_include_directories(test_plugin PRIVATE ${ABSL_ROOT_DIR})
|
||||||
|
target_link_libraries(test_plugin
|
||||||
|
${protobuf_LIB_PROTOC}
|
||||||
|
${protobuf_LIB_PROTOBUF}
|
||||||
|
${protobuf_ABSL_USED_TARGETS}
|
||||||
|
GTest::gmock
|
||||||
|
)
|
||||||
|
|
||||||
|
add_executable(lite-test ${protobuf_lite_test_files})
|
||||||
|
target_link_libraries(lite-test protobuf-lite-test-common ${protobuf_LIB_PROTOBUF_LITE} GTest::gmock_main)
|
||||||
|
|
||||||
|
add_test(NAME lite-test
|
||||||
|
COMMAND lite-test ${protobuf_GTEST_ARGS})
|
||||||
|
|
||||||
|
add_custom_target(check
|
||||||
|
COMMAND tests
|
||||||
|
DEPENDS tests lite-test test_plugin
|
||||||
|
WORKING_DIRECTORY ${protobuf_SOURCE_DIR})
|
||||||
|
|
||||||
|
add_test(NAME check
|
||||||
|
COMMAND tests ${protobuf_GTEST_ARGS})
|
||||||
|
|
||||||
|
# For test purposes, remove headers that should already be installed. This
|
||||||
|
# prevents accidental conflicts and also version skew (since local headers take
|
||||||
|
# precedence over installed headers).
|
||||||
|
add_custom_target(save-installed-headers)
|
||||||
|
add_custom_target(remove-installed-headers)
|
||||||
|
add_custom_target(restore-installed-headers)
|
||||||
|
|
||||||
|
file(GLOB_RECURSE _local_hdrs
|
||||||
|
"${PROJECT_SOURCE_DIR}/src/*.h"
|
||||||
|
"${PROJECT_SOURCE_DIR}/src/*.inc")
|
||||||
|
|
||||||
|
# Exclude the bootstrapping that are directly used by tests.
|
||||||
|
set(_exclude_hdrs
|
||||||
|
"${protobuf_SOURCE_DIR}/src/google/protobuf/descriptor.pb.h"
|
||||||
|
"${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/plugin.pb.h")
|
||||||
|
|
||||||
|
# Exclude test library headers.
|
||||||
|
list(APPEND _exclude_hdrs ${test_util_hdrs} ${lite_test_util_hdrs} ${common_test_hdrs}
|
||||||
|
${compiler_test_utils_hdrs})
|
||||||
|
foreach(_hdr ${_exclude_hdrs})
|
||||||
|
list(REMOVE_ITEM _local_hdrs ${_hdr})
|
||||||
|
endforeach()
|
||||||
|
|
||||||
|
foreach(_hdr ${_local_hdrs})
|
||||||
|
string(REPLACE "${protobuf_SOURCE_DIR}/src" "" _file ${_hdr})
|
||||||
|
set(_tmp_file "${CMAKE_BINARY_DIR}/tmp-install-test/${_file}")
|
||||||
|
add_custom_command(TARGET remove-installed-headers PRE_BUILD
|
||||||
|
COMMAND ${CMAKE_COMMAND} -E remove -f "${_hdr}")
|
||||||
|
add_custom_command(TARGET save-installed-headers PRE_BUILD
|
||||||
|
COMMAND ${CMAKE_COMMAND} -E
|
||||||
|
copy "${_hdr}" "${_tmp_file}" || true)
|
||||||
|
add_custom_command(TARGET restore-installed-headers PRE_BUILD
|
||||||
|
COMMAND ${CMAKE_COMMAND} -E
|
||||||
|
copy "${_tmp_file}" "${_hdr}")
|
||||||
|
endforeach()
|
||||||
|
|
||||||
|
add_dependencies(remove-installed-headers save-installed-headers)
|
||||||
|
if(protobuf_REMOVE_INSTALLED_HEADERS)
|
||||||
|
# Make sure we remove all the headers *before* any codegen occurs.
|
||||||
|
add_dependencies(${protobuf_PROTOC_EXE} remove-installed-headers)
|
||||||
|
endif()
|
||||||
8
cmake/update_file_lists.sh
Executable file
8
cmake/update_file_lists.sh
Executable file
@@ -0,0 +1,8 @@
|
|||||||
|
#!/bin/bash -u
|
||||||
|
|
||||||
|
# This script generates file lists from Bazel for CMake.
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
bazel build //pkg:gen_src_file_lists
|
||||||
|
cp -v bazel-bin/pkg/src_file_lists.cmake src/file_lists.cmake
|
||||||
45
cmake/version.rc.in
Normal file
45
cmake/version.rc.in
Normal file
@@ -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@
|
||||||
|
PRODUCTVERSION @protobuf_RC_FILEVERSION@
|
||||||
|
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
|
||||||
370
conformance/BUILD.bazel
Normal file
370
conformance/BUILD.bazel
Normal file
@@ -0,0 +1,370 @@
|
|||||||
|
# Conformance testing for Protobuf.
|
||||||
|
|
||||||
|
load("@rules_cc//cc:defs.bzl", "cc_binary", "cc_library", "cc_proto_library", "objc_library")
|
||||||
|
load("//:protobuf.bzl", "internal_csharp_proto_library", "internal_objc_proto_library", "internal_php_proto_library", "internal_py_proto_library", "internal_ruby_proto_library")
|
||||||
|
load("//build_defs:internal_shell.bzl", "inline_sh_binary")
|
||||||
|
load(
|
||||||
|
"@rules_pkg//:mappings.bzl",
|
||||||
|
"pkg_attributes",
|
||||||
|
"pkg_filegroup",
|
||||||
|
"pkg_files",
|
||||||
|
"strip_prefix",
|
||||||
|
)
|
||||||
|
|
||||||
|
exports_files([
|
||||||
|
"bazel_conformance_test_runner.sh",
|
||||||
|
"failure_list_cpp.txt",
|
||||||
|
"failure_list_csharp.txt",
|
||||||
|
"failure_list_java.txt",
|
||||||
|
"failure_list_java_lite.txt",
|
||||||
|
"failure_list_objc.txt",
|
||||||
|
"failure_list_php.txt",
|
||||||
|
"failure_list_php_c.txt",
|
||||||
|
"failure_list_python.txt",
|
||||||
|
"failure_list_python_cpp.txt",
|
||||||
|
"failure_list_ruby.txt",
|
||||||
|
"failure_list_jruby.txt",
|
||||||
|
"text_format_failure_list_cpp.txt",
|
||||||
|
"text_format_failure_list_csharp.txt",
|
||||||
|
"text_format_failure_list_java.txt",
|
||||||
|
"text_format_failure_list_java_lite.txt",
|
||||||
|
"text_format_failure_list_php.txt",
|
||||||
|
"text_format_failure_list_php_c.txt",
|
||||||
|
"text_format_failure_list_python.txt",
|
||||||
|
"text_format_failure_list_python_cpp.txt",
|
||||||
|
"text_format_failure_list_ruby.txt",
|
||||||
|
"text_format_failure_list_jruby.txt",
|
||||||
|
])
|
||||||
|
|
||||||
|
cc_proto_library(
|
||||||
|
name = "test_messages_proto2_proto_cc",
|
||||||
|
deps = ["//src/google/protobuf:test_messages_proto2_proto"],
|
||||||
|
)
|
||||||
|
|
||||||
|
cc_proto_library(
|
||||||
|
name = "test_messages_proto3_proto_cc",
|
||||||
|
deps = ["//src/google/protobuf:test_messages_proto3_proto"],
|
||||||
|
)
|
||||||
|
|
||||||
|
proto_library(
|
||||||
|
name = "conformance_proto",
|
||||||
|
srcs = ["conformance.proto"],
|
||||||
|
visibility = ["//visibility:public"],
|
||||||
|
)
|
||||||
|
|
||||||
|
cc_proto_library(
|
||||||
|
name = "conformance_cc_proto",
|
||||||
|
deps = [":conformance_proto"],
|
||||||
|
)
|
||||||
|
|
||||||
|
internal_csharp_proto_library(
|
||||||
|
name = "conformance_csharp_proto",
|
||||||
|
srcs = ["conformance.proto"],
|
||||||
|
visibility = [
|
||||||
|
"//csharp:__subpackages__",
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
|
java_proto_library(
|
||||||
|
name = "conformance_java_proto",
|
||||||
|
visibility = [
|
||||||
|
"//java:__subpackages__",
|
||||||
|
],
|
||||||
|
deps = [":conformance_proto"],
|
||||||
|
)
|
||||||
|
|
||||||
|
java_lite_proto_library(
|
||||||
|
name = "conformance_java_proto_lite",
|
||||||
|
visibility = [
|
||||||
|
"//java:__subpackages__",
|
||||||
|
],
|
||||||
|
deps = [":conformance_proto"],
|
||||||
|
)
|
||||||
|
|
||||||
|
internal_objc_proto_library(
|
||||||
|
name = "conformance_objc_proto",
|
||||||
|
srcs = ["conformance.proto"],
|
||||||
|
visibility = [
|
||||||
|
"//conformance:__pkg__",
|
||||||
|
"//objc:__pkg__",
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
|
internal_py_proto_library(
|
||||||
|
name = "conformance_py_proto",
|
||||||
|
srcs = ["conformance.proto"],
|
||||||
|
srcs_version = "PY2AND3",
|
||||||
|
visibility = [
|
||||||
|
"//python:__subpackages__",
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
|
internal_php_proto_library(
|
||||||
|
name = "conformance_php_proto",
|
||||||
|
srcs = ["conformance.proto"],
|
||||||
|
outs = [
|
||||||
|
"Conformance/ConformanceRequest.php",
|
||||||
|
"Conformance/ConformanceResponse.php",
|
||||||
|
"Conformance/FailureSet.php",
|
||||||
|
"Conformance/JspbEncodingConfig.php",
|
||||||
|
"Conformance/TestCategory.php",
|
||||||
|
"Conformance/WireFormat.php",
|
||||||
|
"GPBMetadata/Conformance.php",
|
||||||
|
],
|
||||||
|
visibility = [
|
||||||
|
"//conformance:__pkg__",
|
||||||
|
"//php:__pkg__",
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
|
internal_ruby_proto_library(
|
||||||
|
name = "conformance_ruby_proto",
|
||||||
|
srcs = ["conformance.proto"],
|
||||||
|
visibility = [
|
||||||
|
"//conformance:__pkg__",
|
||||||
|
"//ruby:__pkg__",
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
|
cc_library(
|
||||||
|
name = "conformance_test",
|
||||||
|
srcs = [
|
||||||
|
"conformance_test.cc",
|
||||||
|
"conformance_test_runner.cc",
|
||||||
|
],
|
||||||
|
hdrs = [
|
||||||
|
"conformance_test.h",
|
||||||
|
],
|
||||||
|
includes = ["."],
|
||||||
|
deps = [
|
||||||
|
":conformance_cc_proto",
|
||||||
|
"@com_google_absl//absl/strings",
|
||||||
|
"@com_google_absl//absl/strings:str_format",
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
|
cc_library(
|
||||||
|
name = "binary_json_conformance_suite",
|
||||||
|
srcs = ["binary_json_conformance_suite.cc"],
|
||||||
|
hdrs = ["binary_json_conformance_suite.h"],
|
||||||
|
deps = [
|
||||||
|
":conformance_test",
|
||||||
|
"@jsoncpp//:jsoncpp",
|
||||||
|
":test_messages_proto2_proto_cc",
|
||||||
|
":test_messages_proto3_proto_cc",
|
||||||
|
"@com_google_absl//absl/status",
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
|
cc_library(
|
||||||
|
name = "text_format_conformance_suite",
|
||||||
|
srcs = ["text_format_conformance_suite.cc"],
|
||||||
|
hdrs = ["text_format_conformance_suite.h"],
|
||||||
|
deps = [
|
||||||
|
":conformance_test",
|
||||||
|
":test_messages_proto2_proto_cc",
|
||||||
|
":test_messages_proto3_proto_cc",
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
|
cc_binary(
|
||||||
|
name = "conformance_test_runner",
|
||||||
|
srcs = ["conformance_test_main.cc"],
|
||||||
|
visibility = ["//visibility:public"],
|
||||||
|
deps = [
|
||||||
|
":binary_json_conformance_suite",
|
||||||
|
":conformance_test",
|
||||||
|
":text_format_conformance_suite",
|
||||||
|
"@com_google_absl//absl/strings:str_format",
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
|
cc_binary(
|
||||||
|
name = "conformance_cpp",
|
||||||
|
testonly = 1,
|
||||||
|
srcs = ["conformance_cpp.cc"],
|
||||||
|
visibility = ["//src:__subpackages__"],
|
||||||
|
deps = [
|
||||||
|
":conformance_cc_proto",
|
||||||
|
"//:protobuf",
|
||||||
|
"//:test_messages_proto2_cc_proto",
|
||||||
|
"//:test_messages_proto3_cc_proto",
|
||||||
|
"@com_google_absl//absl/status",
|
||||||
|
"@com_google_absl//absl/status:statusor",
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
|
java_binary(
|
||||||
|
name = "conformance_java",
|
||||||
|
testonly = 1,
|
||||||
|
srcs = ["ConformanceJava.java"],
|
||||||
|
main_class = "ConformanceJava",
|
||||||
|
visibility = [
|
||||||
|
"//java:__subpackages__",
|
||||||
|
],
|
||||||
|
deps = [
|
||||||
|
":conformance_java_proto",
|
||||||
|
"//:protobuf_java",
|
||||||
|
"//:protobuf_java_util",
|
||||||
|
"//:test_messages_proto2_java_proto",
|
||||||
|
"//:test_messages_proto3_java_proto",
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
|
java_binary(
|
||||||
|
name = "conformance_java_lite",
|
||||||
|
testonly = 1,
|
||||||
|
srcs = ["ConformanceJavaLite.java"],
|
||||||
|
main_class = "ConformanceJavaLite",
|
||||||
|
visibility = [
|
||||||
|
"//java:__subpackages__",
|
||||||
|
],
|
||||||
|
deps = [
|
||||||
|
":conformance_java_proto_lite",
|
||||||
|
"//:protobuf_java_util",
|
||||||
|
"//:protobuf_javalite",
|
||||||
|
"//:test_messages_proto2_java_proto_lite",
|
||||||
|
"//:test_messages_proto3_java_proto_lite",
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
|
py_binary(
|
||||||
|
name = "conformance_python",
|
||||||
|
testonly = 1,
|
||||||
|
srcs = ["conformance_python.py"],
|
||||||
|
imports = [
|
||||||
|
"..",
|
||||||
|
"../python",
|
||||||
|
],
|
||||||
|
srcs_version = "PY2AND3",
|
||||||
|
visibility = ["//python:__subpackages__"],
|
||||||
|
deps = [
|
||||||
|
":conformance_py_proto",
|
||||||
|
"//:protobuf_python",
|
||||||
|
"//python:test_messages_proto2_py_proto",
|
||||||
|
"//python:test_messages_proto3_py_proto",
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
|
inline_sh_binary(
|
||||||
|
name = "conformance_php",
|
||||||
|
testonly = 1,
|
||||||
|
srcs = [
|
||||||
|
"autoload.php",
|
||||||
|
"conformance_php.php",
|
||||||
|
],
|
||||||
|
cmd = """
|
||||||
|
php -d include_path=conformance:src/google/protobuf \\
|
||||||
|
-d auto_prepend_file=$(rootpath autoload.php) \\
|
||||||
|
$(rootpath conformance_php.php)
|
||||||
|
""",
|
||||||
|
visibility = ["//php:__subpackages__"],
|
||||||
|
deps = [
|
||||||
|
":conformance_php_proto",
|
||||||
|
"//:test_messages_proto3_php_proto",
|
||||||
|
"//php:source_files",
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
|
inline_sh_binary(
|
||||||
|
name = "conformance_php_c",
|
||||||
|
testonly = 1,
|
||||||
|
srcs = [
|
||||||
|
"conformance_php.php",
|
||||||
|
"//php:extension",
|
||||||
|
],
|
||||||
|
cmd = """
|
||||||
|
php -dextension=$(rootpath //php:extension) \\
|
||||||
|
-d include_path=conformance:src/google/protobuf \\
|
||||||
|
$(rootpath conformance_php.php)
|
||||||
|
""",
|
||||||
|
visibility = ["//php:__subpackages__"],
|
||||||
|
deps = [
|
||||||
|
":conformance_php_proto",
|
||||||
|
"//:test_messages_proto3_php_proto",
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
|
inline_sh_binary(
|
||||||
|
name = "conformance_csharp",
|
||||||
|
testonly = 1,
|
||||||
|
srcs = ["//csharp/src/Google.Protobuf.Conformance:conformance_dll"],
|
||||||
|
cmd = "dotnet $(rootpath //csharp/src/Google.Protobuf.Conformance:conformance_dll)",
|
||||||
|
visibility = ["//csharp:__subpackages__"],
|
||||||
|
deps = [
|
||||||
|
"//csharp/src/Google.Protobuf.Conformance:conformance_runfiles",
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
|
objc_library(
|
||||||
|
name = "conformance_objc_lib",
|
||||||
|
testonly = 1,
|
||||||
|
non_arc_srcs = ["conformance_objc.m"],
|
||||||
|
# See https://github.com/bazelbuild/bazel/issues/12897.
|
||||||
|
tags = ["manual"],
|
||||||
|
deps = [
|
||||||
|
":conformance_objc_proto",
|
||||||
|
"//:test_messages_proto2_objc_proto",
|
||||||
|
"//:test_messages_proto3_objc_proto",
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
|
cc_binary(
|
||||||
|
name = "conformance_objc",
|
||||||
|
testonly = 1,
|
||||||
|
# See https://github.com/bazelbuild/bazel/issues/12897.
|
||||||
|
tags = ["manual"],
|
||||||
|
visibility = ["//objectivec:__subpackages__"],
|
||||||
|
deps = [":conformance_objc_lib"],
|
||||||
|
)
|
||||||
|
|
||||||
|
inline_sh_binary(
|
||||||
|
name = "conformance_ruby",
|
||||||
|
testonly = 1,
|
||||||
|
srcs = ["conformance_ruby.rb"],
|
||||||
|
cmd = "RUBYLIB=ruby/lib:conformance:src $(rootpath conformance_ruby.rb)",
|
||||||
|
visibility = ["//ruby:__subpackages__"],
|
||||||
|
deps = [
|
||||||
|
":conformance_ruby_proto",
|
||||||
|
"//:test_messages_proto2_ruby_proto",
|
||||||
|
"//:test_messages_proto3_ruby_proto",
|
||||||
|
"//:well_known_ruby_protos",
|
||||||
|
"//ruby:protobuf",
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
|
################################################################################
|
||||||
|
# Distribution files
|
||||||
|
################################################################################
|
||||||
|
|
||||||
|
filegroup(
|
||||||
|
name = "all_files",
|
||||||
|
srcs = glob(["**/*"]),
|
||||||
|
visibility = ["//src/google/protobuf/compiler/csharp:__pkg__"],
|
||||||
|
)
|
||||||
|
|
||||||
|
pkg_files(
|
||||||
|
name = "dist_files",
|
||||||
|
srcs = glob(
|
||||||
|
["**/*"],
|
||||||
|
exclude = [
|
||||||
|
# Handled by dist_scripts:
|
||||||
|
"bazel_conformance_test_runner.sh",
|
||||||
|
|
||||||
|
# The following are not in autotools dist:
|
||||||
|
"autoload.php",
|
||||||
|
"failure_list_jruby.txt",
|
||||||
|
"update_failure_list.py",
|
||||||
|
],
|
||||||
|
),
|
||||||
|
strip_prefix = strip_prefix.from_root(""),
|
||||||
|
visibility = ["//pkg:__pkg__"],
|
||||||
|
)
|
||||||
|
|
||||||
|
pkg_filegroup(
|
||||||
|
name = "all_dist_files",
|
||||||
|
srcs = [
|
||||||
|
":dist_files",
|
||||||
|
],
|
||||||
|
visibility = ["//pkg:__pkg__"],
|
||||||
|
)
|
||||||
418
conformance/ConformanceJava.java
Normal file
418
conformance/ConformanceJava.java
Normal file
@@ -0,0 +1,418 @@
|
|||||||
|
// Protocol Buffers - Google's data interchange format
|
||||||
|
// Copyright 2008 Google Inc. All rights reserved.
|
||||||
|
// https://developers.google.com/protocol-buffers/
|
||||||
|
//
|
||||||
|
// Redistribution and use in source and binary forms, with or without
|
||||||
|
// modification, are permitted provided that the following conditions are
|
||||||
|
// met:
|
||||||
|
//
|
||||||
|
// * Redistributions of source code must retain the above copyright
|
||||||
|
// notice, this list of conditions and the following disclaimer.
|
||||||
|
// * Redistributions in binary form must reproduce the above
|
||||||
|
// copyright notice, this list of conditions and the following disclaimer
|
||||||
|
// in the documentation and/or other materials provided with the
|
||||||
|
// distribution.
|
||||||
|
// * Neither the name of Google Inc. nor the names of its
|
||||||
|
// contributors may be used to endorse or promote products derived from
|
||||||
|
// this software without specific prior written permission.
|
||||||
|
//
|
||||||
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
import com.google.protobuf.AbstractMessage;
|
||||||
|
import com.google.protobuf.ByteString;
|
||||||
|
import com.google.protobuf.CodedInputStream;
|
||||||
|
import com.google.protobuf.ExtensionRegistry;
|
||||||
|
import com.google.protobuf.InvalidProtocolBufferException;
|
||||||
|
import com.google.protobuf.Parser;
|
||||||
|
import com.google.protobuf.TextFormat;
|
||||||
|
import com.google.protobuf.conformance.Conformance;
|
||||||
|
import com.google.protobuf.util.JsonFormat;
|
||||||
|
import com.google.protobuf.util.JsonFormat.TypeRegistry;
|
||||||
|
import com.google.protobuf_test_messages.proto2.TestMessagesProto2;
|
||||||
|
import com.google.protobuf_test_messages.proto2.TestMessagesProto2.TestAllTypesProto2;
|
||||||
|
import com.google.protobuf_test_messages.proto3.TestMessagesProto3;
|
||||||
|
import com.google.protobuf_test_messages.proto3.TestMessagesProto3.TestAllTypesProto3;
|
||||||
|
import java.nio.ByteBuffer;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
|
||||||
|
class ConformanceJava {
|
||||||
|
private int testCount = 0;
|
||||||
|
private TypeRegistry typeRegistry;
|
||||||
|
|
||||||
|
private boolean readFromStdin(byte[] buf, int len) throws Exception {
|
||||||
|
int ofs = 0;
|
||||||
|
while (len > 0) {
|
||||||
|
int read = System.in.read(buf, ofs, len);
|
||||||
|
if (read == -1) {
|
||||||
|
return false; // EOF
|
||||||
|
}
|
||||||
|
ofs += read;
|
||||||
|
len -= read;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void writeToStdout(byte[] buf) throws Exception {
|
||||||
|
System.out.write(buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Returns -1 on EOF (the actual values will always be positive).
|
||||||
|
private int readLittleEndianIntFromStdin() throws Exception {
|
||||||
|
byte[] buf = new byte[4];
|
||||||
|
if (!readFromStdin(buf, 4)) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return (buf[0] & 0xff)
|
||||||
|
| ((buf[1] & 0xff) << 8)
|
||||||
|
| ((buf[2] & 0xff) << 16)
|
||||||
|
| ((buf[3] & 0xff) << 24);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void writeLittleEndianIntToStdout(int val) throws Exception {
|
||||||
|
byte[] buf = new byte[4];
|
||||||
|
buf[0] = (byte) val;
|
||||||
|
buf[1] = (byte) (val >> 8);
|
||||||
|
buf[2] = (byte) (val >> 16);
|
||||||
|
buf[3] = (byte) (val >> 24);
|
||||||
|
writeToStdout(buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
private enum BinaryDecoderType {
|
||||||
|
BTYE_STRING_DECODER,
|
||||||
|
BYTE_ARRAY_DECODER,
|
||||||
|
ARRAY_BYTE_BUFFER_DECODER,
|
||||||
|
READONLY_ARRAY_BYTE_BUFFER_DECODER,
|
||||||
|
DIRECT_BYTE_BUFFER_DECODER,
|
||||||
|
READONLY_DIRECT_BYTE_BUFFER_DECODER,
|
||||||
|
INPUT_STREAM_DECODER;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class BinaryDecoder<T extends AbstractMessage> {
|
||||||
|
public T decode(
|
||||||
|
ByteString bytes, BinaryDecoderType type, Parser<T> parser, ExtensionRegistry extensions)
|
||||||
|
throws InvalidProtocolBufferException {
|
||||||
|
switch (type) {
|
||||||
|
case BTYE_STRING_DECODER:
|
||||||
|
case BYTE_ARRAY_DECODER:
|
||||||
|
return parser.parseFrom(bytes, extensions);
|
||||||
|
case ARRAY_BYTE_BUFFER_DECODER:
|
||||||
|
{
|
||||||
|
ByteBuffer buffer = ByteBuffer.allocate(bytes.size());
|
||||||
|
bytes.copyTo(buffer);
|
||||||
|
buffer.flip();
|
||||||
|
return parser.parseFrom(CodedInputStream.newInstance(buffer), extensions);
|
||||||
|
}
|
||||||
|
case READONLY_ARRAY_BYTE_BUFFER_DECODER:
|
||||||
|
{
|
||||||
|
return parser.parseFrom(
|
||||||
|
CodedInputStream.newInstance(bytes.asReadOnlyByteBuffer()), extensions);
|
||||||
|
}
|
||||||
|
case DIRECT_BYTE_BUFFER_DECODER:
|
||||||
|
{
|
||||||
|
ByteBuffer buffer = ByteBuffer.allocateDirect(bytes.size());
|
||||||
|
bytes.copyTo(buffer);
|
||||||
|
buffer.flip();
|
||||||
|
return parser.parseFrom(CodedInputStream.newInstance(buffer), extensions);
|
||||||
|
}
|
||||||
|
case READONLY_DIRECT_BYTE_BUFFER_DECODER:
|
||||||
|
{
|
||||||
|
ByteBuffer buffer = ByteBuffer.allocateDirect(bytes.size());
|
||||||
|
bytes.copyTo(buffer);
|
||||||
|
buffer.flip();
|
||||||
|
return parser.parseFrom(
|
||||||
|
CodedInputStream.newInstance(buffer.asReadOnlyBuffer()), extensions);
|
||||||
|
}
|
||||||
|
case INPUT_STREAM_DECODER:
|
||||||
|
{
|
||||||
|
return parser.parseFrom(bytes.newInput(), extensions);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private <T extends AbstractMessage> T parseBinary(
|
||||||
|
ByteString bytes, Parser<T> parser, ExtensionRegistry extensions)
|
||||||
|
throws InvalidProtocolBufferException {
|
||||||
|
ArrayList<T> messages = new ArrayList<>();
|
||||||
|
ArrayList<InvalidProtocolBufferException> exceptions = new ArrayList<>();
|
||||||
|
|
||||||
|
for (int i = 0; i < BinaryDecoderType.values().length; i++) {
|
||||||
|
messages.add(null);
|
||||||
|
exceptions.add(null);
|
||||||
|
}
|
||||||
|
if (messages.isEmpty()) {
|
||||||
|
throw new RuntimeException("binary decoder types missing");
|
||||||
|
}
|
||||||
|
|
||||||
|
BinaryDecoder<T> decoder = new BinaryDecoder<>();
|
||||||
|
|
||||||
|
boolean hasMessage = false;
|
||||||
|
boolean hasException = false;
|
||||||
|
for (int i = 0; i < BinaryDecoderType.values().length; ++i) {
|
||||||
|
try {
|
||||||
|
// = BinaryDecoderType.values()[i].parseProto3(bytes);
|
||||||
|
messages.set(i, decoder.decode(bytes, BinaryDecoderType.values()[i], parser, extensions));
|
||||||
|
hasMessage = true;
|
||||||
|
} catch (InvalidProtocolBufferException e) {
|
||||||
|
exceptions.set(i, e);
|
||||||
|
hasException = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hasMessage && hasException) {
|
||||||
|
StringBuilder sb =
|
||||||
|
new StringBuilder("Binary decoders disagreed on whether the payload was valid.\n");
|
||||||
|
for (int i = 0; i < BinaryDecoderType.values().length; ++i) {
|
||||||
|
sb.append(BinaryDecoderType.values()[i].name());
|
||||||
|
if (messages.get(i) != null) {
|
||||||
|
sb.append(" accepted the payload.\n");
|
||||||
|
} else {
|
||||||
|
sb.append(" rejected the payload.\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
throw new RuntimeException(sb.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hasException) {
|
||||||
|
// We do not check if exceptions are equal. Different implementations may return different
|
||||||
|
// exception messages. Throw an arbitrary one out instead.
|
||||||
|
InvalidProtocolBufferException exception = null;
|
||||||
|
for (InvalidProtocolBufferException e : exceptions) {
|
||||||
|
if (exception != null) {
|
||||||
|
exception.addSuppressed(e);
|
||||||
|
} else {
|
||||||
|
exception = e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
throw exception;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fast path comparing all the messages with the first message, assuming equality being
|
||||||
|
// symmetric and transitive.
|
||||||
|
boolean allEqual = true;
|
||||||
|
for (int i = 1; i < messages.size(); ++i) {
|
||||||
|
if (!messages.get(0).equals(messages.get(i))) {
|
||||||
|
allEqual = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Slow path: compare and find out all unequal pairs.
|
||||||
|
if (!allEqual) {
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
for (int i = 0; i < messages.size() - 1; ++i) {
|
||||||
|
for (int j = i + 1; j < messages.size(); ++j) {
|
||||||
|
if (!messages.get(i).equals(messages.get(j))) {
|
||||||
|
sb.append(BinaryDecoderType.values()[i].name())
|
||||||
|
.append(" and ")
|
||||||
|
.append(BinaryDecoderType.values()[j].name())
|
||||||
|
.append(" parsed the payload differently.\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
throw new RuntimeException(sb.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
return messages.get(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Conformance.ConformanceResponse doTest(Conformance.ConformanceRequest request) {
|
||||||
|
AbstractMessage testMessage;
|
||||||
|
String messageType = request.getMessageType();
|
||||||
|
boolean isProto3 =
|
||||||
|
messageType.equals("protobuf_test_messages.proto3.TestAllTypesProto3");
|
||||||
|
boolean isProto2 =
|
||||||
|
messageType.equals("protobuf_test_messages.proto2.TestAllTypesProto2");
|
||||||
|
|
||||||
|
switch (request.getPayloadCase()) {
|
||||||
|
case PROTOBUF_PAYLOAD:
|
||||||
|
{
|
||||||
|
if (isProto3) {
|
||||||
|
try {
|
||||||
|
ExtensionRegistry extensions = ExtensionRegistry.newInstance();
|
||||||
|
TestMessagesProto3.registerAllExtensions(extensions);
|
||||||
|
testMessage =
|
||||||
|
parseBinary(
|
||||||
|
request.getProtobufPayload(), TestAllTypesProto3.parser(), extensions);
|
||||||
|
} catch (InvalidProtocolBufferException e) {
|
||||||
|
return Conformance.ConformanceResponse.newBuilder()
|
||||||
|
.setParseError(e.getMessage())
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
} else if (isProto2) {
|
||||||
|
try {
|
||||||
|
ExtensionRegistry extensions = ExtensionRegistry.newInstance();
|
||||||
|
TestMessagesProto2.registerAllExtensions(extensions);
|
||||||
|
testMessage =
|
||||||
|
parseBinary(
|
||||||
|
request.getProtobufPayload(), TestAllTypesProto2.parser(), extensions);
|
||||||
|
} catch (InvalidProtocolBufferException e) {
|
||||||
|
return Conformance.ConformanceResponse.newBuilder()
|
||||||
|
.setParseError(e.getMessage())
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
throw new IllegalArgumentException(
|
||||||
|
"Protobuf request has unexpected payload type: " + messageType);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case JSON_PAYLOAD:
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
JsonFormat.Parser parser = JsonFormat.parser().usingTypeRegistry(typeRegistry);
|
||||||
|
if (request.getTestCategory()
|
||||||
|
== Conformance.TestCategory.JSON_IGNORE_UNKNOWN_PARSING_TEST) {
|
||||||
|
parser = parser.ignoringUnknownFields();
|
||||||
|
}
|
||||||
|
if (isProto3) {
|
||||||
|
TestMessagesProto3.TestAllTypesProto3.Builder builder =
|
||||||
|
TestMessagesProto3.TestAllTypesProto3.newBuilder();
|
||||||
|
parser.merge(request.getJsonPayload(), builder);
|
||||||
|
testMessage = builder.build();
|
||||||
|
} else if (isProto2) {
|
||||||
|
TestMessagesProto2.TestAllTypesProto2.Builder builder =
|
||||||
|
TestMessagesProto2.TestAllTypesProto2.newBuilder();
|
||||||
|
parser.merge(request.getJsonPayload(), builder);
|
||||||
|
testMessage = builder.build();
|
||||||
|
} else {
|
||||||
|
throw new IllegalArgumentException(
|
||||||
|
"Protobuf request has unexpected payload type: " + messageType);
|
||||||
|
}
|
||||||
|
} catch (InvalidProtocolBufferException e) {
|
||||||
|
return Conformance.ConformanceResponse.newBuilder()
|
||||||
|
.setParseError(e.getMessage())
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case TEXT_PAYLOAD:
|
||||||
|
{
|
||||||
|
if (isProto3) {
|
||||||
|
try {
|
||||||
|
TestMessagesProto3.TestAllTypesProto3.Builder builder =
|
||||||
|
TestMessagesProto3.TestAllTypesProto3.newBuilder();
|
||||||
|
TextFormat.merge(request.getTextPayload(), builder);
|
||||||
|
testMessage = builder.build();
|
||||||
|
} catch (TextFormat.ParseException e) {
|
||||||
|
return Conformance.ConformanceResponse.newBuilder()
|
||||||
|
.setParseError(e.getMessage())
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
} else if (isProto2) {
|
||||||
|
try {
|
||||||
|
TestMessagesProto2.TestAllTypesProto2.Builder builder =
|
||||||
|
TestMessagesProto2.TestAllTypesProto2.newBuilder();
|
||||||
|
TextFormat.merge(request.getTextPayload(), builder);
|
||||||
|
testMessage = builder.build();
|
||||||
|
} catch (TextFormat.ParseException e) {
|
||||||
|
return Conformance.ConformanceResponse.newBuilder()
|
||||||
|
.setParseError(e.getMessage())
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
throw new IllegalArgumentException(
|
||||||
|
"Protobuf request has unexpected payload type: " + messageType);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case PAYLOAD_NOT_SET:
|
||||||
|
{
|
||||||
|
throw new IllegalArgumentException("Request didn't have payload.");
|
||||||
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
{
|
||||||
|
throw new IllegalArgumentException("Unexpected payload case.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (request.getRequestedOutputFormat()) {
|
||||||
|
case UNSPECIFIED:
|
||||||
|
throw new IllegalArgumentException("Unspecified output format.");
|
||||||
|
|
||||||
|
case PROTOBUF:
|
||||||
|
{
|
||||||
|
ByteString messageString = testMessage.toByteString();
|
||||||
|
return Conformance.ConformanceResponse.newBuilder()
|
||||||
|
.setProtobufPayload(messageString)
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
case JSON:
|
||||||
|
try {
|
||||||
|
return Conformance.ConformanceResponse.newBuilder()
|
||||||
|
.setJsonPayload(
|
||||||
|
JsonFormat.printer().usingTypeRegistry(typeRegistry).print(testMessage))
|
||||||
|
.build();
|
||||||
|
} catch (InvalidProtocolBufferException | IllegalArgumentException e) {
|
||||||
|
return Conformance.ConformanceResponse.newBuilder()
|
||||||
|
.setSerializeError(e.getMessage())
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
case TEXT_FORMAT:
|
||||||
|
return Conformance.ConformanceResponse.newBuilder()
|
||||||
|
.setTextPayload(TextFormat.printer().printToString(testMessage))
|
||||||
|
.build();
|
||||||
|
|
||||||
|
default:
|
||||||
|
{
|
||||||
|
throw new IllegalArgumentException("Unexpected request output.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean doTestIo() throws Exception {
|
||||||
|
int bytes = readLittleEndianIntFromStdin();
|
||||||
|
|
||||||
|
if (bytes == -1) {
|
||||||
|
return false; // EOF
|
||||||
|
}
|
||||||
|
|
||||||
|
byte[] serializedInput = new byte[bytes];
|
||||||
|
|
||||||
|
if (!readFromStdin(serializedInput, bytes)) {
|
||||||
|
throw new RuntimeException("Unexpected EOF from test program.");
|
||||||
|
}
|
||||||
|
|
||||||
|
Conformance.ConformanceRequest request =
|
||||||
|
Conformance.ConformanceRequest.parseFrom(serializedInput);
|
||||||
|
Conformance.ConformanceResponse response = doTest(request);
|
||||||
|
byte[] serializedOutput = response.toByteArray();
|
||||||
|
|
||||||
|
writeLittleEndianIntToStdout(serializedOutput.length);
|
||||||
|
writeToStdout(serializedOutput);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void run() throws Exception {
|
||||||
|
typeRegistry =
|
||||||
|
TypeRegistry.newBuilder()
|
||||||
|
.add(TestMessagesProto3.TestAllTypesProto3.getDescriptor())
|
||||||
|
.build();
|
||||||
|
while (doTestIo()) {
|
||||||
|
this.testCount++;
|
||||||
|
}
|
||||||
|
|
||||||
|
System.err.println(
|
||||||
|
"ConformanceJava: received EOF from test runner after " + this.testCount + " tests");
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void main(String[] args) throws Exception {
|
||||||
|
new ConformanceJava().run();
|
||||||
|
}
|
||||||
|
}
|
||||||
351
conformance/ConformanceJavaLite.java
Normal file
351
conformance/ConformanceJavaLite.java
Normal file
@@ -0,0 +1,351 @@
|
|||||||
|
// 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.
|
||||||
|
|
||||||
|
import com.google.protobuf.ByteString;
|
||||||
|
import com.google.protobuf.CodedInputStream;
|
||||||
|
import com.google.protobuf.ExtensionRegistryLite;
|
||||||
|
import com.google.protobuf.InvalidProtocolBufferException;
|
||||||
|
import com.google.protobuf.MessageLite;
|
||||||
|
import com.google.protobuf.Parser;
|
||||||
|
import com.google.protobuf.conformance.Conformance;
|
||||||
|
import com.google.protobuf_test_messages.proto2.TestMessagesProto2;
|
||||||
|
import com.google.protobuf_test_messages.proto2.TestMessagesProto2.TestAllTypesProto2;
|
||||||
|
import com.google.protobuf_test_messages.proto3.TestMessagesProto3;
|
||||||
|
import com.google.protobuf_test_messages.proto3.TestMessagesProto3.TestAllTypesProto3;
|
||||||
|
import java.nio.ByteBuffer;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
|
||||||
|
class ConformanceJavaLite {
|
||||||
|
private int testCount = 0;
|
||||||
|
|
||||||
|
private boolean readFromStdin(byte[] buf, int len) throws Exception {
|
||||||
|
int ofs = 0;
|
||||||
|
while (len > 0) {
|
||||||
|
int read = System.in.read(buf, ofs, len);
|
||||||
|
if (read == -1) {
|
||||||
|
return false; // EOF
|
||||||
|
}
|
||||||
|
ofs += read;
|
||||||
|
len -= read;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void writeToStdout(byte[] buf) throws Exception {
|
||||||
|
System.out.write(buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Returns -1 on EOF (the actual values will always be positive).
|
||||||
|
private int readLittleEndianIntFromStdin() throws Exception {
|
||||||
|
byte[] buf = new byte[4];
|
||||||
|
if (!readFromStdin(buf, 4)) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return (buf[0] & 0xff)
|
||||||
|
| ((buf[1] & 0xff) << 8)
|
||||||
|
| ((buf[2] & 0xff) << 16)
|
||||||
|
| ((buf[3] & 0xff) << 24);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void writeLittleEndianIntToStdout(int val) throws Exception {
|
||||||
|
byte[] buf = new byte[4];
|
||||||
|
buf[0] = (byte) val;
|
||||||
|
buf[1] = (byte) (val >> 8);
|
||||||
|
buf[2] = (byte) (val >> 16);
|
||||||
|
buf[3] = (byte) (val >> 24);
|
||||||
|
writeToStdout(buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
private enum BinaryDecoderType {
|
||||||
|
BTYE_STRING_DECODER,
|
||||||
|
BYTE_ARRAY_DECODER,
|
||||||
|
ARRAY_BYTE_BUFFER_DECODER,
|
||||||
|
READONLY_ARRAY_BYTE_BUFFER_DECODER,
|
||||||
|
DIRECT_BYTE_BUFFER_DECODER,
|
||||||
|
READONLY_DIRECT_BYTE_BUFFER_DECODER,
|
||||||
|
INPUT_STREAM_DECODER;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class BinaryDecoder<T extends MessageLite> {
|
||||||
|
public T decode(
|
||||||
|
ByteString bytes,
|
||||||
|
BinaryDecoderType type,
|
||||||
|
Parser<T> parser,
|
||||||
|
ExtensionRegistryLite extensions)
|
||||||
|
throws InvalidProtocolBufferException {
|
||||||
|
switch (type) {
|
||||||
|
case BTYE_STRING_DECODER:
|
||||||
|
case BYTE_ARRAY_DECODER:
|
||||||
|
return parser.parseFrom(bytes, extensions);
|
||||||
|
case ARRAY_BYTE_BUFFER_DECODER:
|
||||||
|
{
|
||||||
|
ByteBuffer buffer = ByteBuffer.allocate(bytes.size());
|
||||||
|
bytes.copyTo(buffer);
|
||||||
|
buffer.flip();
|
||||||
|
return parser.parseFrom(CodedInputStream.newInstance(buffer), extensions);
|
||||||
|
}
|
||||||
|
case READONLY_ARRAY_BYTE_BUFFER_DECODER:
|
||||||
|
{
|
||||||
|
return parser.parseFrom(
|
||||||
|
CodedInputStream.newInstance(bytes.asReadOnlyByteBuffer()), extensions);
|
||||||
|
}
|
||||||
|
case DIRECT_BYTE_BUFFER_DECODER:
|
||||||
|
{
|
||||||
|
ByteBuffer buffer = ByteBuffer.allocateDirect(bytes.size());
|
||||||
|
bytes.copyTo(buffer);
|
||||||
|
buffer.flip();
|
||||||
|
return parser.parseFrom(CodedInputStream.newInstance(buffer), extensions);
|
||||||
|
}
|
||||||
|
case READONLY_DIRECT_BYTE_BUFFER_DECODER:
|
||||||
|
{
|
||||||
|
ByteBuffer buffer = ByteBuffer.allocateDirect(bytes.size());
|
||||||
|
bytes.copyTo(buffer);
|
||||||
|
buffer.flip();
|
||||||
|
return parser.parseFrom(
|
||||||
|
CodedInputStream.newInstance(buffer.asReadOnlyBuffer()), extensions);
|
||||||
|
}
|
||||||
|
case INPUT_STREAM_DECODER:
|
||||||
|
{
|
||||||
|
return parser.parseFrom(bytes.newInput(), extensions);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private <T extends MessageLite> T parseBinary(
|
||||||
|
ByteString bytes, Parser<T> parser, ExtensionRegistryLite extensions)
|
||||||
|
throws InvalidProtocolBufferException {
|
||||||
|
ArrayList<T> messages = new ArrayList<>();
|
||||||
|
ArrayList<InvalidProtocolBufferException> exceptions = new ArrayList<>();
|
||||||
|
|
||||||
|
for (int i = 0; i < BinaryDecoderType.values().length; i++) {
|
||||||
|
messages.add(null);
|
||||||
|
exceptions.add(null);
|
||||||
|
}
|
||||||
|
if (messages.isEmpty()) {
|
||||||
|
throw new RuntimeException("binary decoder types missing");
|
||||||
|
}
|
||||||
|
|
||||||
|
BinaryDecoder<T> decoder = new BinaryDecoder<>();
|
||||||
|
|
||||||
|
boolean hasMessage = false;
|
||||||
|
boolean hasException = false;
|
||||||
|
for (int i = 0; i < BinaryDecoderType.values().length; ++i) {
|
||||||
|
try {
|
||||||
|
messages.set(i, decoder.decode(bytes, BinaryDecoderType.values()[i], parser, extensions));
|
||||||
|
hasMessage = true;
|
||||||
|
} catch (InvalidProtocolBufferException e) {
|
||||||
|
exceptions.set(i, e);
|
||||||
|
hasException = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hasMessage && hasException) {
|
||||||
|
StringBuilder sb =
|
||||||
|
new StringBuilder("Binary decoders disagreed on whether the payload was valid.\n");
|
||||||
|
for (int i = 0; i < BinaryDecoderType.values().length; ++i) {
|
||||||
|
sb.append(BinaryDecoderType.values()[i].name());
|
||||||
|
if (messages.get(i) != null) {
|
||||||
|
sb.append(" accepted the payload.\n");
|
||||||
|
} else {
|
||||||
|
sb.append(" rejected the payload.\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
throw new RuntimeException(sb.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hasException) {
|
||||||
|
// We do not check if exceptions are equal. Different implementations may return different
|
||||||
|
// exception messages. Throw an arbitrary one out instead.
|
||||||
|
InvalidProtocolBufferException exception = null;
|
||||||
|
for (InvalidProtocolBufferException e : exceptions) {
|
||||||
|
if (exception != null) {
|
||||||
|
exception.addSuppressed(e);
|
||||||
|
} else {
|
||||||
|
exception = e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
throw exception;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fast path comparing all the messages with the first message, assuming equality being
|
||||||
|
// symmetric and transitive.
|
||||||
|
boolean allEqual = true;
|
||||||
|
for (int i = 1; i < messages.size(); ++i) {
|
||||||
|
if (!messages.get(0).equals(messages.get(i))) {
|
||||||
|
allEqual = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Slow path: compare and find out all unequal pairs.
|
||||||
|
if (!allEqual) {
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
for (int i = 0; i < messages.size() - 1; ++i) {
|
||||||
|
for (int j = i + 1; j < messages.size(); ++j) {
|
||||||
|
if (!messages.get(i).equals(messages.get(j))) {
|
||||||
|
sb.append(BinaryDecoderType.values()[i].name())
|
||||||
|
.append(" and ")
|
||||||
|
.append(BinaryDecoderType.values()[j].name())
|
||||||
|
.append(" parsed the payload differently.\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
throw new RuntimeException(sb.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
return messages.get(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Conformance.ConformanceResponse doTest(Conformance.ConformanceRequest request) {
|
||||||
|
com.google.protobuf.MessageLite testMessage;
|
||||||
|
boolean isProto3 =
|
||||||
|
request.getMessageType().equals("protobuf_test_messages.proto3.TestAllTypesProto3");
|
||||||
|
boolean isProto2 =
|
||||||
|
request.getMessageType().equals("protobuf_test_messages.proto2.TestAllTypesProto2");
|
||||||
|
|
||||||
|
switch (request.getPayloadCase()) {
|
||||||
|
case PROTOBUF_PAYLOAD:
|
||||||
|
{
|
||||||
|
if (isProto3) {
|
||||||
|
try {
|
||||||
|
ExtensionRegistryLite extensions = ExtensionRegistryLite.newInstance();
|
||||||
|
TestMessagesProto3.registerAllExtensions(extensions);
|
||||||
|
testMessage =
|
||||||
|
parseBinary(
|
||||||
|
request.getProtobufPayload(), TestAllTypesProto3.parser(), extensions);
|
||||||
|
} catch (InvalidProtocolBufferException e) {
|
||||||
|
return Conformance.ConformanceResponse.newBuilder()
|
||||||
|
.setParseError(e.getMessage())
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
} else if (isProto2) {
|
||||||
|
try {
|
||||||
|
ExtensionRegistryLite extensions = ExtensionRegistryLite.newInstance();
|
||||||
|
TestMessagesProto2.registerAllExtensions(extensions);
|
||||||
|
testMessage =
|
||||||
|
parseBinary(
|
||||||
|
request.getProtobufPayload(), TestAllTypesProto2.parser(), extensions);
|
||||||
|
} catch (InvalidProtocolBufferException e) {
|
||||||
|
return Conformance.ConformanceResponse.newBuilder()
|
||||||
|
.setParseError(e.getMessage())
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
throw new RuntimeException("Protobuf request doesn't have specific payload type.");
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case JSON_PAYLOAD:
|
||||||
|
{
|
||||||
|
return Conformance.ConformanceResponse.newBuilder()
|
||||||
|
.setSkipped("Lite runtime does not support JSON format.")
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
case TEXT_PAYLOAD:
|
||||||
|
{
|
||||||
|
return Conformance.ConformanceResponse.newBuilder()
|
||||||
|
.setSkipped("Lite runtime does not support Text format.")
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
case PAYLOAD_NOT_SET:
|
||||||
|
{
|
||||||
|
throw new RuntimeException("Request didn't have payload.");
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
{
|
||||||
|
throw new RuntimeException("Unexpected payload case.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (request.getRequestedOutputFormat()) {
|
||||||
|
case UNSPECIFIED:
|
||||||
|
throw new RuntimeException("Unspecified output format.");
|
||||||
|
|
||||||
|
case PROTOBUF:
|
||||||
|
return Conformance.ConformanceResponse.newBuilder()
|
||||||
|
.setProtobufPayload(testMessage.toByteString())
|
||||||
|
.build();
|
||||||
|
|
||||||
|
case JSON:
|
||||||
|
return Conformance.ConformanceResponse.newBuilder()
|
||||||
|
.setSkipped("Lite runtime does not support JSON format.")
|
||||||
|
.build();
|
||||||
|
|
||||||
|
case TEXT_FORMAT:
|
||||||
|
return Conformance.ConformanceResponse.newBuilder()
|
||||||
|
.setSkipped("Lite runtime does not support Text format.")
|
||||||
|
.build();
|
||||||
|
default:
|
||||||
|
{
|
||||||
|
throw new RuntimeException("Unexpected request output.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean doTestIo() throws Exception {
|
||||||
|
int bytes = readLittleEndianIntFromStdin();
|
||||||
|
|
||||||
|
if (bytes == -1) {
|
||||||
|
return false; // EOF
|
||||||
|
}
|
||||||
|
|
||||||
|
byte[] serializedInput = new byte[bytes];
|
||||||
|
|
||||||
|
if (!readFromStdin(serializedInput, bytes)) {
|
||||||
|
throw new RuntimeException("Unexpected EOF from test program.");
|
||||||
|
}
|
||||||
|
|
||||||
|
Conformance.ConformanceRequest request =
|
||||||
|
Conformance.ConformanceRequest.parseFrom(serializedInput);
|
||||||
|
Conformance.ConformanceResponse response = doTest(request);
|
||||||
|
byte[] serializedOutput = response.toByteArray();
|
||||||
|
|
||||||
|
writeLittleEndianIntToStdout(serializedOutput.length);
|
||||||
|
writeToStdout(serializedOutput);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void run() throws Exception {
|
||||||
|
while (doTestIo()) {
|
||||||
|
this.testCount++;
|
||||||
|
}
|
||||||
|
|
||||||
|
System.err.println(
|
||||||
|
"ConformanceJavaLite: received EOF from test runner after " + this.testCount + " tests");
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void main(String[] args) throws Exception {
|
||||||
|
new ConformanceJavaLite().run();
|
||||||
|
}
|
||||||
|
}
|
||||||
104
conformance/README.md
Normal file
104
conformance/README.md
Normal file
@@ -0,0 +1,104 @@
|
|||||||
|
Protocol Buffers - Google's data interchange format
|
||||||
|
===================================================
|
||||||
|
|
||||||
|
Copyright 2008 Google Inc.
|
||||||
|
|
||||||
|
This directory contains conformance tests for testing completeness and
|
||||||
|
correctness of Protocol Buffers implementations. These tests are designed
|
||||||
|
to be easy to run against any Protocol Buffers implementation.
|
||||||
|
|
||||||
|
This directory contains the tester process `conformance-test`, which
|
||||||
|
contains all of the tests themselves. Then separate programs written
|
||||||
|
in whatever language you want to test communicate with the tester
|
||||||
|
program over a pipe.
|
||||||
|
|
||||||
|
If you're not using Bazel to run these tests, make sure you build the C++
|
||||||
|
tester code beforehand, e.g. from the base directory:
|
||||||
|
|
||||||
|
$ cmake . -Dprotobuf_BUILD_CONFORMANCE=ON && cmake --build .
|
||||||
|
|
||||||
|
This will produce a `conformance_test_runner` binary that can be used to run
|
||||||
|
conformance tests on any executable. Pass it `--help` for more information.
|
||||||
|
|
||||||
|
Running the tests for C++
|
||||||
|
-------------------------
|
||||||
|
|
||||||
|
To run the tests against the C++ implementation, run:
|
||||||
|
|
||||||
|
$ bazel test //src:conformance_test
|
||||||
|
|
||||||
|
Or alternatively with CMake:
|
||||||
|
|
||||||
|
$ ctest -R conformance_cpp_test
|
||||||
|
|
||||||
|
Running the tests for other languages
|
||||||
|
-------------------------------------
|
||||||
|
|
||||||
|
All of the languages in the Protobuf source tree are set up to run conformance
|
||||||
|
tests using similar patterns. You can either use Bazel to run the
|
||||||
|
`conformance_test` target defined in the language's root `BUILD.bazel` file,
|
||||||
|
or create an executable for a custom test and pass it to
|
||||||
|
`conformance_test_runner`.
|
||||||
|
|
||||||
|
Note: CMake can be used to build the conformance test runner, but not any of
|
||||||
|
the conformance test executables outside C++. So if you aren't using Bazel
|
||||||
|
you'll need to create the executable you pass to `conformance_test_runner` via
|
||||||
|
some alternate build system.
|
||||||
|
|
||||||
|
While we plan to model all our supported languages more completely in Bazel,
|
||||||
|
today some of them are a bit tricky to run. Below is a list of the commands
|
||||||
|
(and prerequisites) to run each language's conformance tests.
|
||||||
|
|
||||||
|
Java:
|
||||||
|
|
||||||
|
$ bazel test //java/core:conformance_test //java/lite:conformance_test
|
||||||
|
|
||||||
|
Python:
|
||||||
|
|
||||||
|
$ bazel test //python:conformance_test
|
||||||
|
|
||||||
|
Python C++:
|
||||||
|
|
||||||
|
$ bazel test //python:conformance_test_cpp --define=use_fast_cpp_protos=true
|
||||||
|
|
||||||
|
C#:
|
||||||
|
|
||||||
|
$ `which dotnet || echo "You must have dotnet installed!"
|
||||||
|
$ `bazel test //csharp:conformance_test \
|
||||||
|
--action_env=DOTNET_CLI_TELEMETRY_OPTOUT=1 --test_env=DOTNET_CLI_HOME=~ \
|
||||||
|
--action_env=DOTNET_SYSTEM_GLOBALIZATION_INVARIANT=1
|
||||||
|
|
||||||
|
Objective-c (Mac only):
|
||||||
|
|
||||||
|
$ `bazel test //objectivec:conformance_test --macos_minimum_os=10.9
|
||||||
|
|
||||||
|
Ruby:
|
||||||
|
|
||||||
|
$ [[ $(ruby --version) == "ruby"* ]] || echo "Select a C Ruby!"
|
||||||
|
$ bazel test //ruby:conformance_test --define=ruby_platform=c \
|
||||||
|
--action_env=PATH --action_env=GEM_PATH --action_env=GEM_HOME
|
||||||
|
|
||||||
|
JRuby:
|
||||||
|
|
||||||
|
$ [[ $(ruby --version) == "jruby"* ]] || echo "Switch to Java Ruby!"
|
||||||
|
$ bazel test //ruby:conformance_test_jruby --define=ruby_platform=java \
|
||||||
|
--action_env=PATH --action_env=GEM_PATH --action_env=GEM_HOME
|
||||||
|
|
||||||
|
Testing other Protocol Buffer implementations
|
||||||
|
---------------------------------------------
|
||||||
|
|
||||||
|
To run these tests against a new Protocol Buffers implementation, write a
|
||||||
|
program in your language that uses the protobuf implementation you want
|
||||||
|
to test. This program should implement the testing protocol defined in
|
||||||
|
[conformance.proto](https://github.com/protocolbuffers/protobuf/blob/main/conformance/conformance.proto).
|
||||||
|
This is designed to be as easy as possible: the C++ version is only
|
||||||
|
150 lines and is a good example for what this program should look like
|
||||||
|
(see [conformance_cpp.cc](https://github.com/protocolbuffers/protobuf/blob/main/conformance/conformance_cpp.cc)).
|
||||||
|
The program only needs to be able to read from stdin and write to stdout.
|
||||||
|
|
||||||
|
Portability
|
||||||
|
-----------
|
||||||
|
|
||||||
|
Note that the test runner currently does not work on Windows. Patches
|
||||||
|
to fix this are welcome! (But please get in touch first to settle on
|
||||||
|
a general implementation strategy).
|
||||||
21
conformance/autoload.php
Normal file
21
conformance/autoload.php
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
define("GOOGLE_INTERNAL_NAMESPACE", "Google\\Protobuf\\Internal\\");
|
||||||
|
define("GOOGLE_NAMESPACE", "Google\\Protobuf\\");
|
||||||
|
define("GOOGLE_GPBMETADATA_NAMESPACE", "GPBMetadata\\Google\\Protobuf\\");
|
||||||
|
|
||||||
|
function protobuf_autoloader_impl($class, $prefix) {
|
||||||
|
$length = strlen($prefix);
|
||||||
|
if ((substr($class, 0, $length) === $prefix)) {
|
||||||
|
$path = 'php/src/' . implode('/', array_map('ucwords', explode('\\', $class))) . '.php';
|
||||||
|
include_once $path;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function protobuf_autoloader($class) {
|
||||||
|
protobuf_autoloader_impl($class, GOOGLE_INTERNAL_NAMESPACE);
|
||||||
|
protobuf_autoloader_impl($class, GOOGLE_NAMESPACE);
|
||||||
|
protobuf_autoloader_impl($class, GOOGLE_GPBMETADATA_NAMESPACE);
|
||||||
|
}
|
||||||
|
|
||||||
|
spl_autoload_register('protobuf_autoloader');
|
||||||
60
conformance/bazel_conformance_test_runner.sh
Executable file
60
conformance/bazel_conformance_test_runner.sh
Executable file
@@ -0,0 +1,60 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# This is an internal file that should only be called from Bazel rules. For
|
||||||
|
# custom conformance tests outside of Bazel use CMAKE with
|
||||||
|
# -Dprotobuf_BUILD_CONFORMANCE=ON to build the test runner.
|
||||||
|
|
||||||
|
set -x
|
||||||
|
echo $@
|
||||||
|
|
||||||
|
set -euo pipefail
|
||||||
|
# --- begin runfiles.bash initialization ---
|
||||||
|
if [[ ! -d "${RUNFILES_DIR:-/dev/null}" && ! -f "${RUNFILES_MANIFEST_FILE:-/dev/null}" ]]; then
|
||||||
|
if [[ -f "$0.runfiles_manifest" ]]; then
|
||||||
|
export RUNFILES_MANIFEST_FILE="$0.runfiles_manifest"
|
||||||
|
elif [[ -f "$0.runfiles/MANIFEST" ]]; then
|
||||||
|
export RUNFILES_MANIFEST_FILE="$0.runfiles/MANIFEST"
|
||||||
|
elif [[ -f "$0.runfiles/bazel_tools/tools/bash/runfiles/runfiles.bash" ]]; then
|
||||||
|
export RUNFILES_DIR="$0.runfiles"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
if [[ -f "${RUNFILES_DIR:-/dev/null}/bazel_tools/tools/bash/runfiles/runfiles.bash" ]]; then
|
||||||
|
source "${RUNFILES_DIR}/bazel_tools/tools/bash/runfiles/runfiles.bash"
|
||||||
|
elif [[ -f "${RUNFILES_MANIFEST_FILE:-/dev/null}" ]]; then
|
||||||
|
source "$(grep -m1 "^bazel_tools/tools/bash/runfiles/runfiles.bash " \
|
||||||
|
"$RUNFILES_MANIFEST_FILE" | cut -d ' ' -f 2-)"
|
||||||
|
else
|
||||||
|
echo >&2 "ERROR: cannot find @bazel_tools//tools/bash/runfiles:runfiles.bash"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
# --- end runfiles.bash initialization ---
|
||||||
|
|
||||||
|
TESTEE=unset
|
||||||
|
FAILURE_LIST=unset
|
||||||
|
TEXT_FORMAT_FAILURE_LIST=unset
|
||||||
|
|
||||||
|
while [[ -n "$@" ]]; do
|
||||||
|
arg="$1"; shift
|
||||||
|
val="$1"; shift
|
||||||
|
case "$arg" in
|
||||||
|
"--testee") TESTEE="$val" ;;
|
||||||
|
"--failure_list") FAILURE_LIST="$val" ;;
|
||||||
|
"--text_format_failure_list") TEXT_FORMAT_FAILURE_LIST="$val" ;;
|
||||||
|
*) echo "Flag $arg is not recognized." && exit 1 ;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
conformance_test_runner=$(rlocation com_google_protobuf/conformance/conformance_test_runner)
|
||||||
|
conformance_testee=$(rlocation $TESTEE)
|
||||||
|
args=(--enforce_recommended)
|
||||||
|
|
||||||
|
failure_list=$(rlocation $FAILURE_LIST) || unset
|
||||||
|
if [ -n "$failure_list" ] ; then
|
||||||
|
args+=(--failure_list $failure_list)
|
||||||
|
fi
|
||||||
|
|
||||||
|
text_format_failure_list=$(rlocation $TEXT_FORMAT_FAILURE_LIST) || unset
|
||||||
|
if [ -n "$text_format_failure_list" ]; then
|
||||||
|
args+=(--text_format_failure_list $text_format_failure_list)
|
||||||
|
fi
|
||||||
|
|
||||||
|
$conformance_test_runner "${args[@]}" $conformance_testee
|
||||||
3479
conformance/binary_json_conformance_suite.cc
Normal file
3479
conformance/binary_json_conformance_suite.cc
Normal file
File diff suppressed because it is too large
Load Diff
164
conformance/binary_json_conformance_suite.h
Normal file
164
conformance/binary_json_conformance_suite.h
Normal file
@@ -0,0 +1,164 @@
|
|||||||
|
// Protocol Buffers - Google's data interchange format
|
||||||
|
// Copyright 2008 Google Inc. All rights reserved.
|
||||||
|
// https://developers.google.com/protocol-buffers/
|
||||||
|
//
|
||||||
|
// Redistribution and use in source and binary forms, with or without
|
||||||
|
// modification, are permitted provided that the following conditions are
|
||||||
|
// met:
|
||||||
|
//
|
||||||
|
// * Redistributions of source code must retain the above copyright
|
||||||
|
// notice, this list of conditions and the following disclaimer.
|
||||||
|
// * Redistributions in binary form must reproduce the above
|
||||||
|
// copyright notice, this list of conditions and the following disclaimer
|
||||||
|
// in the documentation and/or other materials provided with the
|
||||||
|
// distribution.
|
||||||
|
// * Neither the name of Google Inc. nor the names of its
|
||||||
|
// contributors may be used to endorse or promote products derived from
|
||||||
|
// this software without specific prior written permission.
|
||||||
|
//
|
||||||
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
#ifndef CONFORMANCE_BINARY_JSON_CONFORMANCE_SUITE_H
|
||||||
|
#define CONFORMANCE_BINARY_JSON_CONFORMANCE_SUITE_H
|
||||||
|
|
||||||
|
#include "google/protobuf/descriptor.h"
|
||||||
|
#include "json/json.h"
|
||||||
|
#include "conformance_test.h"
|
||||||
|
|
||||||
|
namespace google {
|
||||||
|
namespace protobuf {
|
||||||
|
|
||||||
|
class BinaryAndJsonConformanceSuite : public ConformanceTestSuite {
|
||||||
|
public:
|
||||||
|
BinaryAndJsonConformanceSuite() {}
|
||||||
|
|
||||||
|
private:
|
||||||
|
void RunSuiteImpl() override;
|
||||||
|
void RunBinaryPerformanceTests();
|
||||||
|
void RunJsonPerformanceTests();
|
||||||
|
void RunJsonTests();
|
||||||
|
void RunJsonTestsForFieldNameConvention();
|
||||||
|
void RunJsonTestsForNonRepeatedTypes();
|
||||||
|
void RunJsonTestsForRepeatedTypes();
|
||||||
|
void RunJsonTestsForNullTypes();
|
||||||
|
void RunJsonTestsForWrapperTypes();
|
||||||
|
void RunJsonTestsForFieldMask();
|
||||||
|
void RunJsonTestsForStruct();
|
||||||
|
void RunJsonTestsForValue();
|
||||||
|
void RunJsonTestsForAny();
|
||||||
|
void RunValidJsonTest(const std::string& test_name, ConformanceLevel level,
|
||||||
|
const std::string& input_json,
|
||||||
|
const std::string& equivalent_text_format);
|
||||||
|
void RunValidJsonTest(const std::string& test_name, ConformanceLevel level,
|
||||||
|
const std::string& input_json,
|
||||||
|
const std::string& equivalent_text_format,
|
||||||
|
bool is_proto3);
|
||||||
|
void RunValidJsonTestWithMessage(const std::string& test_name,
|
||||||
|
ConformanceLevel level,
|
||||||
|
const std::string& input_json,
|
||||||
|
const std::string& equivalent_text_forma,
|
||||||
|
const Message& prototype);
|
||||||
|
void RunValidJsonTestWithProtobufInput(
|
||||||
|
const std::string& test_name, ConformanceLevel level,
|
||||||
|
const protobuf_test_messages::proto3::TestAllTypesProto3& input,
|
||||||
|
const std::string& equivalent_text_format);
|
||||||
|
void RunValidJsonIgnoreUnknownTest(const std::string& test_name,
|
||||||
|
ConformanceLevel level,
|
||||||
|
const std::string& input_json,
|
||||||
|
const std::string& equivalent_text_format);
|
||||||
|
void RunValidProtobufTest(const std::string& test_name,
|
||||||
|
ConformanceLevel level,
|
||||||
|
const std::string& input_protobuf,
|
||||||
|
const std::string& equivalent_text_format,
|
||||||
|
bool is_proto3);
|
||||||
|
void RunValidBinaryProtobufTest(const std::string& test_name,
|
||||||
|
ConformanceLevel level,
|
||||||
|
const std::string& input_protobuf,
|
||||||
|
bool is_proto3);
|
||||||
|
void RunValidBinaryProtobufTest(const std::string& test_name,
|
||||||
|
ConformanceLevel level,
|
||||||
|
const std::string& input_protobuf,
|
||||||
|
const std::string& expected_protobuf,
|
||||||
|
bool is_proto3);
|
||||||
|
void RunBinaryPerformanceMergeMessageWithField(const std::string& test_name,
|
||||||
|
const std::string& field_proto,
|
||||||
|
bool is_proto3);
|
||||||
|
|
||||||
|
void RunValidProtobufTestWithMessage(
|
||||||
|
const std::string& test_name, ConformanceLevel level,
|
||||||
|
const Message* input, const std::string& equivalent_text_format,
|
||||||
|
bool is_proto3);
|
||||||
|
|
||||||
|
bool ParseJsonResponse(
|
||||||
|
const conformance::ConformanceResponse& response,
|
||||||
|
Message* test_message);
|
||||||
|
bool ParseResponse(
|
||||||
|
const conformance::ConformanceResponse& response,
|
||||||
|
const ConformanceRequestSetting& setting,
|
||||||
|
Message* test_message) override;
|
||||||
|
|
||||||
|
typedef std::function<bool(const Json::Value&)> Validator;
|
||||||
|
void RunValidJsonTestWithValidator(const std::string& test_name,
|
||||||
|
ConformanceLevel level,
|
||||||
|
const std::string& input_json,
|
||||||
|
const Validator& validator,
|
||||||
|
bool is_proto3);
|
||||||
|
void ExpectParseFailureForJson(const std::string& test_name,
|
||||||
|
ConformanceLevel level,
|
||||||
|
const std::string& input_json);
|
||||||
|
void ExpectSerializeFailureForJson(const std::string& test_name,
|
||||||
|
ConformanceLevel level,
|
||||||
|
const std::string& text_format);
|
||||||
|
void ExpectParseFailureForProtoWithProtoVersion(const std::string& proto,
|
||||||
|
const std::string& test_name,
|
||||||
|
ConformanceLevel level,
|
||||||
|
bool is_proto3);
|
||||||
|
void ExpectParseFailureForProto(const std::string& proto,
|
||||||
|
const std::string& test_name,
|
||||||
|
ConformanceLevel level);
|
||||||
|
void ExpectHardParseFailureForProto(const std::string& proto,
|
||||||
|
const std::string& test_name,
|
||||||
|
ConformanceLevel level);
|
||||||
|
void TestPrematureEOFForType(google::protobuf::FieldDescriptor::Type type);
|
||||||
|
void TestIllegalTags();
|
||||||
|
template <class MessageType>
|
||||||
|
void TestOneofMessage (MessageType &message,
|
||||||
|
bool is_proto3);
|
||||||
|
template <class MessageType>
|
||||||
|
void TestUnknownMessage (MessageType &message,
|
||||||
|
bool is_proto3);
|
||||||
|
void TestValidDataForType(
|
||||||
|
google::protobuf::FieldDescriptor::Type,
|
||||||
|
std::vector<std::pair<std::string, std::string>> values);
|
||||||
|
void TestValidDataForRepeatedScalarMessage();
|
||||||
|
void TestValidDataForMapType(google::protobuf::FieldDescriptor::Type,
|
||||||
|
google::protobuf::FieldDescriptor::Type);
|
||||||
|
void TestValidDataForOneofType(google::protobuf::FieldDescriptor::Type);
|
||||||
|
void TestMergeOneofMessage();
|
||||||
|
void TestOverwriteMessageValueMap();
|
||||||
|
void TestBinaryPerformanceForAlternatingUnknownFields();
|
||||||
|
void TestBinaryPerformanceMergeMessageWithRepeatedFieldForType(
|
||||||
|
google::protobuf::FieldDescriptor::Type);
|
||||||
|
void TestBinaryPerformanceMergeMessageWithUnknownFieldForType(
|
||||||
|
google::protobuf::FieldDescriptor::Type);
|
||||||
|
void TestJsonPerformanceMergeMessageWithRepeatedFieldForType(
|
||||||
|
google::protobuf::FieldDescriptor::Type, std::string field_value);
|
||||||
|
|
||||||
|
std::unique_ptr<google::protobuf::util::TypeResolver> type_resolver_;
|
||||||
|
std::string type_url_;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace protobuf
|
||||||
|
} // namespace google
|
||||||
|
|
||||||
|
#endif // CONFORMANCE_BINARY_JSON_CONFORMANCE_SUITE_H
|
||||||
180
conformance/conformance.proto
Normal file
180
conformance/conformance.proto
Normal file
@@ -0,0 +1,180 @@
|
|||||||
|
// Protocol Buffers - Google's data interchange format
|
||||||
|
// Copyright 2008 Google Inc. All rights reserved.
|
||||||
|
// https://developers.google.com/protocol-buffers/
|
||||||
|
//
|
||||||
|
// Redistribution and use in source and binary forms, with or without
|
||||||
|
// modification, are permitted provided that the following conditions are
|
||||||
|
// met:
|
||||||
|
//
|
||||||
|
// * Redistributions of source code must retain the above copyright
|
||||||
|
// notice, this list of conditions and the following disclaimer.
|
||||||
|
// * Redistributions in binary form must reproduce the above
|
||||||
|
// copyright notice, this list of conditions and the following disclaimer
|
||||||
|
// in the documentation and/or other materials provided with the
|
||||||
|
// distribution.
|
||||||
|
// * Neither the name of Google Inc. nor the names of its
|
||||||
|
// contributors may be used to endorse or promote products derived from
|
||||||
|
// this software without specific prior written permission.
|
||||||
|
//
|
||||||
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
syntax = "proto3";
|
||||||
|
|
||||||
|
package conformance;
|
||||||
|
|
||||||
|
option java_package = "com.google.protobuf.conformance";
|
||||||
|
option objc_class_prefix = "Conformance";
|
||||||
|
|
||||||
|
// This defines the conformance testing protocol. This protocol exists between
|
||||||
|
// the conformance test suite itself and the code being tested. For each test,
|
||||||
|
// the suite will send a ConformanceRequest message and expect a
|
||||||
|
// ConformanceResponse message.
|
||||||
|
//
|
||||||
|
// You can either run the tests in two different ways:
|
||||||
|
//
|
||||||
|
// 1. in-process (using the interface in conformance_test.h).
|
||||||
|
//
|
||||||
|
// 2. as a sub-process communicating over a pipe. Information about how to
|
||||||
|
// do this is in conformance_test_runner.cc.
|
||||||
|
//
|
||||||
|
// Pros/cons of the two approaches:
|
||||||
|
//
|
||||||
|
// - running as a sub-process is much simpler for languages other than C/C++.
|
||||||
|
//
|
||||||
|
// - running as a sub-process may be more tricky in unusual environments like
|
||||||
|
// iOS apps, where fork/stdin/stdout are not available.
|
||||||
|
|
||||||
|
enum WireFormat {
|
||||||
|
UNSPECIFIED = 0;
|
||||||
|
PROTOBUF = 1;
|
||||||
|
JSON = 2;
|
||||||
|
JSPB = 3; // Google internal only. Opensource testees just skip it.
|
||||||
|
TEXT_FORMAT = 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
enum TestCategory {
|
||||||
|
UNSPECIFIED_TEST = 0;
|
||||||
|
BINARY_TEST = 1; // Test binary wire format.
|
||||||
|
JSON_TEST = 2; // Test json wire format.
|
||||||
|
// Similar to JSON_TEST. However, during parsing json, testee should ignore
|
||||||
|
// unknown fields. This feature is optional. Each implementation can decide
|
||||||
|
// whether to support it. See
|
||||||
|
// https://developers.google.com/protocol-buffers/docs/proto3#json_options
|
||||||
|
// for more detail.
|
||||||
|
JSON_IGNORE_UNKNOWN_PARSING_TEST = 3;
|
||||||
|
// Test jspb wire format. Google internal only. Opensource testees just skip
|
||||||
|
// it.
|
||||||
|
JSPB_TEST = 4;
|
||||||
|
// Test text format. For cpp, java and python, testees can already deal with
|
||||||
|
// this type. Testees of other languages can simply skip it.
|
||||||
|
TEXT_FORMAT_TEST = 5;
|
||||||
|
}
|
||||||
|
|
||||||
|
// The conformance runner will request a list of failures as the first request.
|
||||||
|
// This will be known by message_type == "conformance.FailureSet", a conformance
|
||||||
|
// test should return a serialized FailureSet in protobuf_payload.
|
||||||
|
message FailureSet {
|
||||||
|
repeated string failure = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Represents a single test case's input. The testee should:
|
||||||
|
//
|
||||||
|
// 1. parse this proto (which should always succeed)
|
||||||
|
// 2. parse the protobuf or JSON payload in "payload" (which may fail)
|
||||||
|
// 3. if the parse succeeded, serialize the message in the requested format.
|
||||||
|
message ConformanceRequest {
|
||||||
|
// The payload (whether protobuf of JSON) is always for a
|
||||||
|
// protobuf_test_messages.proto3.TestAllTypes proto (as defined in
|
||||||
|
// src/google/protobuf/proto3_test_messages.proto).
|
||||||
|
oneof payload {
|
||||||
|
bytes protobuf_payload = 1;
|
||||||
|
string json_payload = 2;
|
||||||
|
// Google internal only. Opensource testees just skip it.
|
||||||
|
string jspb_payload = 7;
|
||||||
|
string text_payload = 8;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Which format should the testee serialize its message to?
|
||||||
|
WireFormat requested_output_format = 3;
|
||||||
|
|
||||||
|
// The full name for the test message to use; for the moment, either:
|
||||||
|
// protobuf_test_messages.proto3.TestAllTypesProto3 or
|
||||||
|
// protobuf_test_messages.google.protobuf.TestAllTypesProto2.
|
||||||
|
string message_type = 4;
|
||||||
|
|
||||||
|
// Each test is given a specific test category. Some category may need
|
||||||
|
// specific support in testee programs. Refer to the definition of
|
||||||
|
// TestCategory for more information.
|
||||||
|
TestCategory test_category = 5;
|
||||||
|
|
||||||
|
// Specify details for how to encode jspb.
|
||||||
|
JspbEncodingConfig jspb_encoding_options = 6;
|
||||||
|
|
||||||
|
// This can be used in json and text format. If true, testee should print
|
||||||
|
// unknown fields instead of ignore. This feature is optional.
|
||||||
|
bool print_unknown_fields = 9;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Represents a single test case's output.
|
||||||
|
message ConformanceResponse {
|
||||||
|
oneof result {
|
||||||
|
// This string should be set to indicate parsing failed. The string can
|
||||||
|
// provide more information about the parse error if it is available.
|
||||||
|
//
|
||||||
|
// Setting this string does not necessarily mean the testee failed the
|
||||||
|
// test. Some of the test cases are intentionally invalid input.
|
||||||
|
string parse_error = 1;
|
||||||
|
|
||||||
|
// If the input was successfully parsed but errors occurred when
|
||||||
|
// serializing it to the requested output format, set the error message in
|
||||||
|
// this field.
|
||||||
|
string serialize_error = 6;
|
||||||
|
|
||||||
|
// This should be set if the test program timed out. The string should
|
||||||
|
// provide more information about what the child process was doing when it
|
||||||
|
// was killed.
|
||||||
|
string timeout_error = 9;
|
||||||
|
|
||||||
|
// This should be set if some other error occurred. This will always
|
||||||
|
// indicate that the test failed. The string can provide more information
|
||||||
|
// about the failure.
|
||||||
|
string runtime_error = 2;
|
||||||
|
|
||||||
|
// If the input was successfully parsed and the requested output was
|
||||||
|
// protobuf, serialize it to protobuf and set it in this field.
|
||||||
|
bytes protobuf_payload = 3;
|
||||||
|
|
||||||
|
// If the input was successfully parsed and the requested output was JSON,
|
||||||
|
// serialize to JSON and set it in this field.
|
||||||
|
string json_payload = 4;
|
||||||
|
|
||||||
|
// For when the testee skipped the test, likely because a certain feature
|
||||||
|
// wasn't supported, like JSON input/output.
|
||||||
|
string skipped = 5;
|
||||||
|
|
||||||
|
// If the input was successfully parsed and the requested output was JSPB,
|
||||||
|
// serialize to JSPB and set it in this field. JSPB is google internal only
|
||||||
|
// format. Opensource testees can just skip it.
|
||||||
|
string jspb_payload = 7;
|
||||||
|
|
||||||
|
// If the input was successfully parsed and the requested output was
|
||||||
|
// TEXT_FORMAT, serialize to TEXT_FORMAT and set it in this field.
|
||||||
|
string text_payload = 8;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Encoding options for jspb format.
|
||||||
|
message JspbEncodingConfig {
|
||||||
|
// Encode the value field of Any as jspb array if true, otherwise binary.
|
||||||
|
bool use_jspb_array_any_format = 1;
|
||||||
|
}
|
||||||
274
conformance/conformance_cpp.cc
Normal file
274
conformance/conformance_cpp.cc
Normal file
@@ -0,0 +1,274 @@
|
|||||||
|
// Protocol Buffers - Google's data interchange format
|
||||||
|
// Copyright 2008 Google Inc. All rights reserved.
|
||||||
|
// https://developers.google.com/protocol-buffers/
|
||||||
|
//
|
||||||
|
// Redistribution and use in source and binary forms, with or without
|
||||||
|
// modification, are permitted provided that the following conditions are
|
||||||
|
// met:
|
||||||
|
//
|
||||||
|
// * Redistributions of source code must retain the above copyright
|
||||||
|
// notice, this list of conditions and the following disclaimer.
|
||||||
|
// * Redistributions in binary form must reproduce the above
|
||||||
|
// copyright notice, this list of conditions and the following disclaimer
|
||||||
|
// in the documentation and/or other materials provided with the
|
||||||
|
// distribution.
|
||||||
|
// * Neither the name of Google Inc. nor the names of its
|
||||||
|
// contributors may be used to endorse or promote products derived from
|
||||||
|
// this software without specific prior written permission.
|
||||||
|
//
|
||||||
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
#include <errno.h>
|
||||||
|
#include <stdarg.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
#include <string>
|
||||||
|
#include <utility>
|
||||||
|
|
||||||
|
#include "google/protobuf/stubs/logging.h"
|
||||||
|
#include "google/protobuf/stubs/common.h"
|
||||||
|
#include "google/protobuf/message.h"
|
||||||
|
#include "google/protobuf/text_format.h"
|
||||||
|
#include "google/protobuf/util/json_util.h"
|
||||||
|
#include "google/protobuf/util/type_resolver_util.h"
|
||||||
|
#include "absl/status/status.h"
|
||||||
|
#include "absl/status/statusor.h"
|
||||||
|
#include "conformance/conformance.pb.h"
|
||||||
|
#include "conformance/conformance.pb.h"
|
||||||
|
#include "google/protobuf/test_messages_proto2.pb.h"
|
||||||
|
#include "google/protobuf/test_messages_proto3.pb.h"
|
||||||
|
#include "google/protobuf/test_messages_proto3.pb.h"
|
||||||
|
#include "google/protobuf/util/type_resolver.h"
|
||||||
|
#include "google/protobuf/stubs/status_macros.h"
|
||||||
|
|
||||||
|
// Must be included last.
|
||||||
|
#include "google/protobuf/port_def.inc"
|
||||||
|
|
||||||
|
namespace google {
|
||||||
|
namespace protobuf {
|
||||||
|
namespace {
|
||||||
|
using ::conformance::ConformanceRequest;
|
||||||
|
using ::conformance::ConformanceResponse;
|
||||||
|
using ::google::protobuf::util::BinaryToJsonString;
|
||||||
|
using ::google::protobuf::util::JsonParseOptions;
|
||||||
|
using ::google::protobuf::util::JsonToBinaryString;
|
||||||
|
using ::google::protobuf::util::NewTypeResolverForDescriptorPool;
|
||||||
|
using ::google::protobuf::util::TypeResolver;
|
||||||
|
using ::protobuf_test_messages::proto2::TestAllTypesProto2;
|
||||||
|
using ::protobuf_test_messages::proto3::TestAllTypesProto3;
|
||||||
|
|
||||||
|
absl::Status ReadFd(int fd, char* buf, size_t len) {
|
||||||
|
while (len > 0) {
|
||||||
|
ssize_t bytes_read = read(fd, buf, len);
|
||||||
|
|
||||||
|
if (bytes_read == 0) {
|
||||||
|
return absl::DataLossError("unexpected EOF");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bytes_read < 0) {
|
||||||
|
return absl::ErrnoToStatus(errno, "error reading from test runner");
|
||||||
|
}
|
||||||
|
|
||||||
|
len -= bytes_read;
|
||||||
|
buf += bytes_read;
|
||||||
|
}
|
||||||
|
return absl::OkStatus();
|
||||||
|
}
|
||||||
|
|
||||||
|
absl::Status WriteFd(int fd, const void* buf, size_t len) {
|
||||||
|
if (static_cast<size_t>(write(fd, buf, len)) != len) {
|
||||||
|
return absl::ErrnoToStatus(errno, "error reading to test runner");
|
||||||
|
}
|
||||||
|
return absl::OkStatus();
|
||||||
|
}
|
||||||
|
|
||||||
|
class Harness {
|
||||||
|
public:
|
||||||
|
Harness() {
|
||||||
|
google::protobuf::LinkMessageReflection<TestAllTypesProto2>();
|
||||||
|
google::protobuf::LinkMessageReflection<TestAllTypesProto3>();
|
||||||
|
|
||||||
|
resolver_.reset(NewTypeResolverForDescriptorPool(
|
||||||
|
"type.googleapis.com", DescriptorPool::generated_pool()));
|
||||||
|
type_url_ = absl::StrCat("type.googleapis.com/",
|
||||||
|
TestAllTypesProto3::GetDescriptor()->full_name());
|
||||||
|
}
|
||||||
|
|
||||||
|
absl::StatusOr<ConformanceResponse> RunTest(
|
||||||
|
const ConformanceRequest& request);
|
||||||
|
|
||||||
|
// Returns Ok(true) if we're done processing requests.
|
||||||
|
absl::StatusOr<bool> ServeConformanceRequest();
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool verbose_ = false;
|
||||||
|
std::unique_ptr<TypeResolver> resolver_;
|
||||||
|
std::string type_url_;
|
||||||
|
};
|
||||||
|
|
||||||
|
absl::StatusOr<ConformanceResponse> Harness::RunTest(
|
||||||
|
const ConformanceRequest& request) {
|
||||||
|
const Descriptor* descriptor =
|
||||||
|
DescriptorPool::generated_pool()->FindMessageTypeByName(
|
||||||
|
request.message_type());
|
||||||
|
if (descriptor == nullptr) {
|
||||||
|
return absl::NotFoundError(
|
||||||
|
absl::StrCat("No such message type: ", request.message_type()));
|
||||||
|
}
|
||||||
|
|
||||||
|
std::unique_ptr<Message> test_message(
|
||||||
|
MessageFactory::generated_factory()->GetPrototype(descriptor)->New());
|
||||||
|
ConformanceResponse response;
|
||||||
|
|
||||||
|
switch (request.payload_case()) {
|
||||||
|
case ConformanceRequest::kProtobufPayload: {
|
||||||
|
if (!test_message->ParseFromString(request.protobuf_payload())) {
|
||||||
|
response.set_parse_error("parse error (no more details available)");
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case ConformanceRequest::kJsonPayload: {
|
||||||
|
JsonParseOptions options;
|
||||||
|
options.ignore_unknown_fields =
|
||||||
|
(request.test_category() ==
|
||||||
|
conformance::JSON_IGNORE_UNKNOWN_PARSING_TEST);
|
||||||
|
|
||||||
|
std::string proto_binary;
|
||||||
|
absl::Status status =
|
||||||
|
JsonToBinaryString(resolver_.get(), type_url_, request.json_payload(),
|
||||||
|
&proto_binary, options);
|
||||||
|
if (!status.ok()) {
|
||||||
|
response.set_parse_error(
|
||||||
|
absl::StrCat("parse error: ", status.message()));
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!test_message->ParseFromString(proto_binary)) {
|
||||||
|
response.set_runtime_error(
|
||||||
|
"parsing JSON generated invalid proto output");
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case ConformanceRequest::kTextPayload: {
|
||||||
|
if (!TextFormat::ParseFromString(request.text_payload(),
|
||||||
|
test_message.get())) {
|
||||||
|
response.set_parse_error("parse error (no more details available)");
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case ConformanceRequest::PAYLOAD_NOT_SET:
|
||||||
|
return absl::InvalidArgumentError("request didn't have payload");
|
||||||
|
|
||||||
|
default:
|
||||||
|
return absl::InvalidArgumentError(
|
||||||
|
absl::StrCat("unknown payload type", request.payload_case()));
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (request.requested_output_format()) {
|
||||||
|
case conformance::UNSPECIFIED:
|
||||||
|
return absl::InvalidArgumentError("unspecified output format");
|
||||||
|
|
||||||
|
case conformance::PROTOBUF: {
|
||||||
|
GOOGLE_CHECK(
|
||||||
|
test_message->SerializeToString(response.mutable_protobuf_payload()));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case conformance::JSON: {
|
||||||
|
std::string proto_binary;
|
||||||
|
GOOGLE_CHECK(test_message->SerializeToString(&proto_binary));
|
||||||
|
absl::Status status =
|
||||||
|
BinaryToJsonString(resolver_.get(), type_url_, proto_binary,
|
||||||
|
response.mutable_json_payload());
|
||||||
|
if (!status.ok()) {
|
||||||
|
response.set_serialize_error(absl::StrCat(
|
||||||
|
"failed to serialize JSON output: ", status.message()));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case conformance::TEXT_FORMAT: {
|
||||||
|
TextFormat::Printer printer;
|
||||||
|
printer.SetHideUnknownFields(!request.print_unknown_fields());
|
||||||
|
GOOGLE_CHECK(printer.PrintToString(*test_message,
|
||||||
|
response.mutable_text_payload()));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
return absl::InvalidArgumentError(absl::StrCat(
|
||||||
|
"unknown output format", request.requested_output_format()));
|
||||||
|
}
|
||||||
|
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
|
||||||
|
absl::StatusOr<bool> Harness::ServeConformanceRequest() {
|
||||||
|
uint32_t in_len;
|
||||||
|
if (!ReadFd(STDIN_FILENO, reinterpret_cast<char*>(&in_len), sizeof(in_len))
|
||||||
|
.ok()) {
|
||||||
|
// EOF means we're done.
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string serialized_input;
|
||||||
|
serialized_input.resize(in_len);
|
||||||
|
RETURN_IF_ERROR(ReadFd(STDIN_FILENO, &serialized_input[0], in_len));
|
||||||
|
|
||||||
|
ConformanceRequest request;
|
||||||
|
GOOGLE_CHECK(request.ParseFromString(serialized_input));
|
||||||
|
|
||||||
|
absl::StatusOr<ConformanceResponse> response = RunTest(request);
|
||||||
|
RETURN_IF_ERROR(response.status());
|
||||||
|
|
||||||
|
std::string serialized_output;
|
||||||
|
response->SerializeToString(&serialized_output);
|
||||||
|
|
||||||
|
uint32_t out_len = static_cast<uint32_t>(serialized_output.size());
|
||||||
|
RETURN_IF_ERROR(WriteFd(STDOUT_FILENO, &out_len, sizeof(out_len)));
|
||||||
|
RETURN_IF_ERROR(WriteFd(STDOUT_FILENO, serialized_output.data(), out_len));
|
||||||
|
|
||||||
|
if (verbose_) {
|
||||||
|
GOOGLE_LOG(INFO) << "conformance-cpp: request=" << request.ShortDebugString()
|
||||||
|
<< ", response=" << response->ShortDebugString();
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} // namespace
|
||||||
|
} // namespace protobuf
|
||||||
|
} // namespace google
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
google::protobuf::Harness harness;
|
||||||
|
int total_runs = 0;
|
||||||
|
while (true) {
|
||||||
|
auto is_done = harness.ServeConformanceRequest();
|
||||||
|
if (!is_done.ok()) {
|
||||||
|
GOOGLE_LOG(FATAL) << is_done.status();
|
||||||
|
}
|
||||||
|
if (*is_done) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
total_runs++;
|
||||||
|
}
|
||||||
|
GOOGLE_LOG(INFO) << "conformance-cpp: received EOF from test runner after "
|
||||||
|
<< total_runs << " tests";
|
||||||
|
}
|
||||||
212
conformance/conformance_objc.m
Normal file
212
conformance/conformance_objc.m
Normal file
@@ -0,0 +1,212 @@
|
|||||||
|
// Protocol Buffers - Google's data interchange format
|
||||||
|
// Copyright 2015 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.
|
||||||
|
|
||||||
|
#import <Foundation/Foundation.h>
|
||||||
|
|
||||||
|
#import "Conformance.pbobjc.h"
|
||||||
|
#import "google/protobuf/TestMessagesProto2.pbobjc.h"
|
||||||
|
#import "google/protobuf/TestMessagesProto3.pbobjc.h"
|
||||||
|
|
||||||
|
static void Die(NSString *format, ...) __dead2;
|
||||||
|
|
||||||
|
static BOOL verbose = NO;
|
||||||
|
static int32_t testCount = 0;
|
||||||
|
|
||||||
|
static void Die(NSString *format, ...) {
|
||||||
|
va_list args;
|
||||||
|
va_start(args, format);
|
||||||
|
NSString *msg = [[NSString alloc] initWithFormat:format arguments:args];
|
||||||
|
NSLog(@"%@", msg);
|
||||||
|
va_end(args);
|
||||||
|
[msg release];
|
||||||
|
exit(66);
|
||||||
|
}
|
||||||
|
|
||||||
|
static NSData *CheckedReadDataOfLength(NSFileHandle *handle, NSUInteger numBytes) {
|
||||||
|
NSData *data = [handle readDataOfLength:numBytes];
|
||||||
|
NSUInteger dataLen = data.length;
|
||||||
|
if (dataLen == 0) {
|
||||||
|
return nil; // EOF.
|
||||||
|
}
|
||||||
|
if (dataLen != numBytes) {
|
||||||
|
Die(@"Failed to read the request length (%d), only got: %@", numBytes, data);
|
||||||
|
}
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
static ConformanceResponse *DoTest(ConformanceRequest *request) {
|
||||||
|
ConformanceResponse *response = [ConformanceResponse message];
|
||||||
|
GPBMessage *testMessage = nil;
|
||||||
|
|
||||||
|
switch (request.payloadOneOfCase) {
|
||||||
|
case ConformanceRequest_Payload_OneOfCase_GPBUnsetOneOfCase:
|
||||||
|
response.runtimeError =
|
||||||
|
[NSString stringWithFormat:@"Request didn't have a payload: %@", request];
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ConformanceRequest_Payload_OneOfCase_ProtobufPayload: {
|
||||||
|
Class msgClass = nil;
|
||||||
|
if ([request.messageType isEqual:@"protobuf_test_messages.proto3.TestAllTypesProto3"]) {
|
||||||
|
msgClass = [Proto3TestAllTypesProto3 class];
|
||||||
|
} else if ([request.messageType
|
||||||
|
isEqual:@"protobuf_test_messages.proto2.TestAllTypesProto2"]) {
|
||||||
|
msgClass = [Proto2TestAllTypesProto2 class];
|
||||||
|
} else {
|
||||||
|
response.runtimeError =
|
||||||
|
[NSString stringWithFormat:@"Protobuf request had an unknown message_type: %@",
|
||||||
|
request.messageType];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
NSError *error = nil;
|
||||||
|
testMessage = [msgClass parseFromData:request.protobufPayload error:&error];
|
||||||
|
if (!testMessage) {
|
||||||
|
response.parseError = [NSString stringWithFormat:@"Parse error: %@", error];
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case ConformanceRequest_Payload_OneOfCase_JsonPayload:
|
||||||
|
response.skipped = @"ObjC doesn't support parsing JSON";
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ConformanceRequest_Payload_OneOfCase_JspbPayload:
|
||||||
|
response.skipped = @"ConformanceRequest had a jspb_payload ConformanceRequest.payload;"
|
||||||
|
" those aren't supposed to happen with opensource.";
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ConformanceRequest_Payload_OneOfCase_TextPayload:
|
||||||
|
response.skipped = @"ObjC doesn't support parsing TextFormat";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (testMessage) {
|
||||||
|
switch (request.requestedOutputFormat) {
|
||||||
|
case ConformanceWireFormat_GPBUnrecognizedEnumeratorValue:
|
||||||
|
case ConformanceWireFormat_Unspecified:
|
||||||
|
response.runtimeError =
|
||||||
|
[NSString stringWithFormat:@"Unrecognized/unspecified output format: %@", request];
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ConformanceWireFormat_Protobuf:
|
||||||
|
response.protobufPayload = testMessage.data;
|
||||||
|
if (!response.protobufPayload) {
|
||||||
|
response.serializeError =
|
||||||
|
[NSString stringWithFormat:@"Failed to make data from: %@", testMessage];
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ConformanceWireFormat_Json:
|
||||||
|
response.skipped = @"ObjC doesn't support generating JSON";
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ConformanceWireFormat_Jspb:
|
||||||
|
response.skipped =
|
||||||
|
@"ConformanceRequest had a requested_output_format of JSPB WireFormat; that"
|
||||||
|
" isn't supposed to happen with opensource.";
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ConformanceWireFormat_TextFormat:
|
||||||
|
// ObjC only has partial objc generation, so don't attempt any tests that need
|
||||||
|
// support.
|
||||||
|
response.skipped = @"ObjC doesn't support generating TextFormat";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint32_t UInt32FromLittleEndianData(NSData *data) {
|
||||||
|
if (data.length != sizeof(uint32_t)) {
|
||||||
|
Die(@"Data not the right size for uint32_t: %@", data);
|
||||||
|
}
|
||||||
|
uint32_t value;
|
||||||
|
memcpy(&value, data.bytes, sizeof(uint32_t));
|
||||||
|
return CFSwapInt32LittleToHost(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
static NSData *UInt32ToLittleEndianData(uint32_t num) {
|
||||||
|
uint32_t value = CFSwapInt32HostToLittle(num);
|
||||||
|
return [NSData dataWithBytes:&value length:sizeof(uint32_t)];
|
||||||
|
}
|
||||||
|
|
||||||
|
static BOOL DoTestIo(NSFileHandle *input, NSFileHandle *output) {
|
||||||
|
// See conformance_test_runner.cc for the wire format.
|
||||||
|
NSData *data = CheckedReadDataOfLength(input, sizeof(uint32_t));
|
||||||
|
if (!data) {
|
||||||
|
// EOF.
|
||||||
|
return NO;
|
||||||
|
}
|
||||||
|
uint32_t numBytes = UInt32FromLittleEndianData(data);
|
||||||
|
data = CheckedReadDataOfLength(input, numBytes);
|
||||||
|
if (!data) {
|
||||||
|
Die(@"Failed to read request");
|
||||||
|
}
|
||||||
|
|
||||||
|
NSError *error = nil;
|
||||||
|
ConformanceRequest *request = [ConformanceRequest parseFromData:data error:&error];
|
||||||
|
if (!request) {
|
||||||
|
Die(@"Failed to parse the message data: %@", error);
|
||||||
|
}
|
||||||
|
|
||||||
|
ConformanceResponse *response = DoTest(request);
|
||||||
|
if (!response) {
|
||||||
|
Die(@"Failed to make a reply from %@", request);
|
||||||
|
}
|
||||||
|
|
||||||
|
data = response.data;
|
||||||
|
[output writeData:UInt32ToLittleEndianData((int32_t)data.length)];
|
||||||
|
[output writeData:data];
|
||||||
|
|
||||||
|
if (verbose) {
|
||||||
|
NSLog(@"Request: %@", request);
|
||||||
|
NSLog(@"Response: %@", response);
|
||||||
|
}
|
||||||
|
|
||||||
|
++testCount;
|
||||||
|
return YES;
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, const char *argv[]) {
|
||||||
|
@autoreleasepool {
|
||||||
|
NSFileHandle *input = [[NSFileHandle fileHandleWithStandardInput] retain];
|
||||||
|
NSFileHandle *output = [[NSFileHandle fileHandleWithStandardOutput] retain];
|
||||||
|
|
||||||
|
BOOL notDone = YES;
|
||||||
|
while (notDone) {
|
||||||
|
@autoreleasepool {
|
||||||
|
notDone = DoTestIo(input, output);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
NSLog(@"Received EOF from test runner after %d tests, exiting.", testCount);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
120
conformance/conformance_php.php
Normal file
120
conformance/conformance_php.php
Normal file
@@ -0,0 +1,120 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
require_once("Conformance/WireFormat.php");
|
||||||
|
require_once("Conformance/ConformanceResponse.php");
|
||||||
|
require_once("Conformance/ConformanceRequest.php");
|
||||||
|
require_once("Conformance/FailureSet.php");
|
||||||
|
require_once("Conformance/JspbEncodingConfig.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");
|
||||||
|
require_once("Protobuf_test_messages/Proto3/TestAllTypesProto3/AliasedEnum.php");
|
||||||
|
require_once("Protobuf_test_messages/Proto3/TestAllTypesProto3/NestedMessage.php");
|
||||||
|
require_once("Protobuf_test_messages/Proto3/TestAllTypesProto3/NestedEnum.php");
|
||||||
|
|
||||||
|
require_once("GPBMetadata/Conformance.php");
|
||||||
|
require_once("GPBMetadata/TestMessagesProto3.php");
|
||||||
|
|
||||||
|
use \Conformance\TestCategory;
|
||||||
|
use \Conformance\WireFormat;
|
||||||
|
|
||||||
|
if (!ini_get("date.timezone")) {
|
||||||
|
ini_set("date.timezone", "UTC");
|
||||||
|
}
|
||||||
|
|
||||||
|
$test_count = 0;
|
||||||
|
|
||||||
|
function doTest($request)
|
||||||
|
{
|
||||||
|
$test_message = new \Protobuf_test_messages\Proto3\TestAllTypesProto3();
|
||||||
|
$response = new \Conformance\ConformanceResponse();
|
||||||
|
if ($request->getPayload() == "protobuf_payload") {
|
||||||
|
if ($request->getMessageType() == "conformance.FailureSet") {
|
||||||
|
$response->setProtobufPayload("");
|
||||||
|
return $response;
|
||||||
|
} elseif ($request->getMessageType() == "protobuf_test_messages.proto3.TestAllTypesProto3") {
|
||||||
|
try {
|
||||||
|
$test_message->mergeFromString($request->getProtobufPayload());
|
||||||
|
} catch (Exception $e) {
|
||||||
|
$response->setParseError($e->getMessage());
|
||||||
|
return $response;
|
||||||
|
}
|
||||||
|
} elseif ($request->getMessageType() == "protobuf_test_messages.proto2.TestAllTypesProto2") {
|
||||||
|
$response->setSkipped("PHP doesn't support proto2");
|
||||||
|
return $response;
|
||||||
|
} else {
|
||||||
|
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(),
|
||||||
|
$ignore_json_unknown);
|
||||||
|
} catch (Exception $e) {
|
||||||
|
$response->setParseError($e->getMessage());
|
||||||
|
return $response;
|
||||||
|
}
|
||||||
|
} elseif ($request->getPayload() == "text_payload") {
|
||||||
|
$response->setSkipped("PHP doesn't support text format yet");
|
||||||
|
return $response;
|
||||||
|
} else {
|
||||||
|
trigger_error("Request didn't have payload.", E_USER_ERROR);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($request->getRequestedOutputFormat() == WireFormat::UNSPECIFIED) {
|
||||||
|
trigger_error("Unspecified output format.", E_USER_ERROR);
|
||||||
|
} elseif ($request->getRequestedOutputFormat() == WireFormat::PROTOBUF) {
|
||||||
|
$response->setProtobufPayload($test_message->serializeToString());
|
||||||
|
} elseif ($request->getRequestedOutputFormat() == WireFormat::JSON) {
|
||||||
|
try {
|
||||||
|
$response->setJsonPayload($test_message->serializeToJsonString());
|
||||||
|
} catch (Exception $e) {
|
||||||
|
$response->setSerializeError($e->getMessage());
|
||||||
|
return $response;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $response;
|
||||||
|
}
|
||||||
|
|
||||||
|
function doTestIO()
|
||||||
|
{
|
||||||
|
$length_bytes = fread(STDIN, 4);
|
||||||
|
if (strlen($length_bytes) == 0) {
|
||||||
|
return false; # EOF
|
||||||
|
} elseif (strlen($length_bytes) != 4) {
|
||||||
|
fwrite(STDERR, "I/O error\n");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
$length = unpack("V", $length_bytes)[1];
|
||||||
|
$serialized_request = fread(STDIN, $length);
|
||||||
|
if (strlen($serialized_request) != $length) {
|
||||||
|
trigger_error("I/O error", E_USER_ERROR);
|
||||||
|
}
|
||||||
|
|
||||||
|
$request = new \Conformance\ConformanceRequest();
|
||||||
|
$request->mergeFromString($serialized_request);
|
||||||
|
|
||||||
|
$response = doTest($request);
|
||||||
|
|
||||||
|
$serialized_response = $response->serializeToString();
|
||||||
|
fwrite(STDOUT, pack("V", strlen($serialized_response)));
|
||||||
|
fwrite(STDOUT, $serialized_response);
|
||||||
|
|
||||||
|
$GLOBALS['test_count'] += 1;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
while(true){
|
||||||
|
if (!doTestIO()) {
|
||||||
|
fprintf(STDERR,
|
||||||
|
"conformance_php: received EOF from test runner " .
|
||||||
|
"after %d tests, exiting\n", $test_count);
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
}
|
||||||
213
conformance/conformance_python.py
Executable file
213
conformance/conformance_python.py
Executable file
@@ -0,0 +1,213 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
# 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.
|
||||||
|
|
||||||
|
"""A conformance test implementation for the Python protobuf library.
|
||||||
|
|
||||||
|
See conformance.proto for more information.
|
||||||
|
"""
|
||||||
|
|
||||||
|
import struct
|
||||||
|
import sys
|
||||||
|
import os
|
||||||
|
from google.protobuf import json_format
|
||||||
|
from google.protobuf import message
|
||||||
|
from google.protobuf import test_messages_proto3_pb2
|
||||||
|
from google.protobuf import test_messages_proto2_pb2
|
||||||
|
from google.protobuf import text_format
|
||||||
|
from conformance import conformance_pb2
|
||||||
|
|
||||||
|
sys.stdout = os.fdopen(sys.stdout.fileno(), 'wb', 0)
|
||||||
|
sys.stdin = os.fdopen(sys.stdin.fileno(), 'rb', 0)
|
||||||
|
|
||||||
|
test_count = 0
|
||||||
|
verbose = False
|
||||||
|
|
||||||
|
class ProtocolError(Exception):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def do_test(request):
|
||||||
|
response = conformance_pb2.ConformanceResponse()
|
||||||
|
|
||||||
|
if request.message_type == "conformance.FailureSet":
|
||||||
|
failure_set = conformance_pb2.FailureSet()
|
||||||
|
failures = []
|
||||||
|
# TODO(gerbens): Remove, this is a hack to detect if the old vs new
|
||||||
|
# parser is used by the cpp code. Relying on a bug in the old parser.
|
||||||
|
hack_proto = test_messages_proto2_pb2.TestAllTypesProto2()
|
||||||
|
old_parser = True
|
||||||
|
try:
|
||||||
|
hack_proto.ParseFromString(b"\322\002\001")
|
||||||
|
except message.DecodeError as e:
|
||||||
|
old_parser = False
|
||||||
|
if old_parser:
|
||||||
|
# the string above is one of the failing conformance test strings of the
|
||||||
|
# old parser. If we succeed the c++ implementation is using the old
|
||||||
|
# parser so we add the list of failing conformance tests.
|
||||||
|
failures = [
|
||||||
|
"Required.Proto3.ProtobufInput.PrematureEofInDelimitedDataForKnownNonRepeatedValue.MESSAGE",
|
||||||
|
"Required.Proto3.ProtobufInput.PrematureEofInDelimitedDataForKnownRepeatedValue.MESSAGE",
|
||||||
|
"Required.Proto3.ProtobufInput.PrematureEofInPackedField.BOOL",
|
||||||
|
"Required.Proto3.ProtobufInput.PrematureEofInPackedField.DOUBLE",
|
||||||
|
"Required.Proto3.ProtobufInput.PrematureEofInPackedField.ENUM",
|
||||||
|
"Required.Proto3.ProtobufInput.PrematureEofInPackedField.FIXED32",
|
||||||
|
"Required.Proto3.ProtobufInput.PrematureEofInPackedField.FIXED64",
|
||||||
|
"Required.Proto3.ProtobufInput.PrematureEofInPackedField.FLOAT",
|
||||||
|
"Required.Proto3.ProtobufInput.PrematureEofInPackedField.INT32",
|
||||||
|
"Required.Proto3.ProtobufInput.PrematureEofInPackedField.INT64",
|
||||||
|
"Required.Proto3.ProtobufInput.PrematureEofInPackedField.SFIXED32",
|
||||||
|
"Required.Proto3.ProtobufInput.PrematureEofInPackedField.SFIXED64",
|
||||||
|
"Required.Proto3.ProtobufInput.PrematureEofInPackedField.SINT32",
|
||||||
|
"Required.Proto3.ProtobufInput.PrematureEofInPackedField.SINT64",
|
||||||
|
"Required.Proto3.ProtobufInput.PrematureEofInPackedField.UINT32",
|
||||||
|
"Required.Proto3.ProtobufInput.PrematureEofInPackedField.UINT64",
|
||||||
|
"Required.Proto2.ProtobufInput.PrematureEofInDelimitedDataForKnownNonRepeatedValue.MESSAGE",
|
||||||
|
"Required.Proto2.ProtobufInput.PrematureEofInDelimitedDataForKnownRepeatedValue.MESSAGE",
|
||||||
|
"Required.Proto2.ProtobufInput.PrematureEofInPackedField.BOOL",
|
||||||
|
"Required.Proto2.ProtobufInput.PrematureEofInPackedField.DOUBLE",
|
||||||
|
"Required.Proto2.ProtobufInput.PrematureEofInPackedField.ENUM",
|
||||||
|
"Required.Proto2.ProtobufInput.PrematureEofInPackedField.FIXED32",
|
||||||
|
"Required.Proto2.ProtobufInput.PrematureEofInPackedField.FIXED64",
|
||||||
|
"Required.Proto2.ProtobufInput.PrematureEofInPackedField.FLOAT",
|
||||||
|
"Required.Proto2.ProtobufInput.PrematureEofInPackedField.INT32",
|
||||||
|
"Required.Proto2.ProtobufInput.PrematureEofInPackedField.INT64",
|
||||||
|
"Required.Proto2.ProtobufInput.PrematureEofInPackedField.SFIXED32",
|
||||||
|
"Required.Proto2.ProtobufInput.PrematureEofInPackedField.SFIXED64",
|
||||||
|
"Required.Proto2.ProtobufInput.PrematureEofInPackedField.SINT32",
|
||||||
|
"Required.Proto2.ProtobufInput.PrematureEofInPackedField.SINT64",
|
||||||
|
"Required.Proto2.ProtobufInput.PrematureEofInPackedField.UINT32",
|
||||||
|
"Required.Proto2.ProtobufInput.PrematureEofInPackedField.UINT64",
|
||||||
|
]
|
||||||
|
for x in failures:
|
||||||
|
failure_set.failure.append(x)
|
||||||
|
response.protobuf_payload = failure_set.SerializeToString()
|
||||||
|
return response
|
||||||
|
|
||||||
|
isProto3 = (request.message_type == "protobuf_test_messages.proto3.TestAllTypesProto3")
|
||||||
|
isJson = (request.WhichOneof('payload') == 'json_payload')
|
||||||
|
isProto2 = (request.message_type == "protobuf_test_messages.proto2.TestAllTypesProto2")
|
||||||
|
|
||||||
|
if (not isProto3) and (not isJson) and (not isProto2):
|
||||||
|
raise ProtocolError("Protobuf request doesn't have specific payload type")
|
||||||
|
|
||||||
|
test_message = test_messages_proto2_pb2.TestAllTypesProto2() if isProto2 else \
|
||||||
|
test_messages_proto3_pb2.TestAllTypesProto3()
|
||||||
|
|
||||||
|
try:
|
||||||
|
if request.WhichOneof('payload') == 'protobuf_payload':
|
||||||
|
try:
|
||||||
|
test_message.ParseFromString(request.protobuf_payload)
|
||||||
|
except message.DecodeError as e:
|
||||||
|
response.parse_error = str(e)
|
||||||
|
return response
|
||||||
|
|
||||||
|
elif request.WhichOneof('payload') == 'json_payload':
|
||||||
|
try:
|
||||||
|
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
|
||||||
|
|
||||||
|
elif request.WhichOneof('payload') == 'text_payload':
|
||||||
|
try:
|
||||||
|
text_format.Parse(request.text_payload, test_message)
|
||||||
|
except Exception as e:
|
||||||
|
response.parse_error = str(e)
|
||||||
|
return response
|
||||||
|
|
||||||
|
else:
|
||||||
|
raise ProtocolError("Request didn't have payload.")
|
||||||
|
|
||||||
|
if request.requested_output_format == conformance_pb2.UNSPECIFIED:
|
||||||
|
raise ProtocolError("Unspecified output format")
|
||||||
|
|
||||||
|
elif request.requested_output_format == conformance_pb2.PROTOBUF:
|
||||||
|
response.protobuf_payload = test_message.SerializeToString()
|
||||||
|
|
||||||
|
elif request.requested_output_format == conformance_pb2.JSON:
|
||||||
|
try:
|
||||||
|
response.json_payload = json_format.MessageToJson(test_message)
|
||||||
|
except Exception as e:
|
||||||
|
response.serialize_error = str(e)
|
||||||
|
return response
|
||||||
|
|
||||||
|
elif request.requested_output_format == conformance_pb2.TEXT_FORMAT:
|
||||||
|
response.text_payload = text_format.MessageToString(
|
||||||
|
test_message, print_unknown_fields=request.print_unknown_fields)
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
response.runtime_error = str(e)
|
||||||
|
|
||||||
|
return response
|
||||||
|
|
||||||
|
def do_test_io():
|
||||||
|
length_bytes = sys.stdin.read(4)
|
||||||
|
if len(length_bytes) == 0:
|
||||||
|
return False # EOF
|
||||||
|
elif len(length_bytes) != 4:
|
||||||
|
raise IOError("I/O error")
|
||||||
|
|
||||||
|
# "I" is "unsigned int", so this depends on running on a platform with
|
||||||
|
# 32-bit "unsigned int" type. The Python struct module unfortunately
|
||||||
|
# has no format specifier for uint32_t.
|
||||||
|
length = struct.unpack("<I", length_bytes)[0]
|
||||||
|
serialized_request = sys.stdin.read(length)
|
||||||
|
if len(serialized_request) != length:
|
||||||
|
raise IOError("I/O error")
|
||||||
|
|
||||||
|
request = conformance_pb2.ConformanceRequest()
|
||||||
|
request.ParseFromString(serialized_request)
|
||||||
|
|
||||||
|
response = do_test(request)
|
||||||
|
|
||||||
|
serialized_response = response.SerializeToString()
|
||||||
|
sys.stdout.write(struct.pack("<I", len(serialized_response)))
|
||||||
|
sys.stdout.write(serialized_response)
|
||||||
|
sys.stdout.flush()
|
||||||
|
|
||||||
|
if verbose:
|
||||||
|
sys.stderr.write("conformance_python: request=%s, response=%s\n" % (
|
||||||
|
request.ShortDebugString().c_str(),
|
||||||
|
response.ShortDebugString().c_str()))
|
||||||
|
|
||||||
|
global test_count
|
||||||
|
test_count += 1
|
||||||
|
|
||||||
|
return True
|
||||||
|
|
||||||
|
while True:
|
||||||
|
if not do_test_io():
|
||||||
|
sys.stderr.write("conformance_python: received EOF from test runner " +
|
||||||
|
"after %s tests, exiting\n" % (test_count))
|
||||||
|
sys.exit(0)
|
||||||
146
conformance/conformance_ruby.rb
Executable file
146
conformance/conformance_ruby.rb
Executable file
@@ -0,0 +1,146 @@
|
|||||||
|
#!/usr/bin/env ruby
|
||||||
|
#
|
||||||
|
# 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.
|
||||||
|
|
||||||
|
require 'conformance_pb'
|
||||||
|
require 'google/protobuf/test_messages_proto3_pb'
|
||||||
|
require 'google/protobuf/test_messages_proto2_pb'
|
||||||
|
|
||||||
|
$test_count = 0
|
||||||
|
$verbose = false
|
||||||
|
|
||||||
|
def do_test(request)
|
||||||
|
test_message = ProtobufTestMessages::Proto3::TestAllTypesProto3.new
|
||||||
|
response = Conformance::ConformanceResponse.new
|
||||||
|
descriptor = Google::Protobuf::DescriptorPool.generated_pool.lookup(request.message_type)
|
||||||
|
|
||||||
|
unless descriptor
|
||||||
|
response.skipped = "Unknown message type: " + request.message_type
|
||||||
|
end
|
||||||
|
|
||||||
|
begin
|
||||||
|
case request.payload
|
||||||
|
when :protobuf_payload
|
||||||
|
begin
|
||||||
|
test_message = descriptor.msgclass.decode(request.protobuf_payload)
|
||||||
|
rescue Google::Protobuf::ParseError => err
|
||||||
|
response.parse_error = err.message.encode('utf-8')
|
||||||
|
return response
|
||||||
|
end
|
||||||
|
|
||||||
|
when :json_payload
|
||||||
|
begin
|
||||||
|
options = {}
|
||||||
|
if request.test_category == :JSON_IGNORE_UNKNOWN_PARSING_TEST
|
||||||
|
options[:ignore_unknown_fields] = true
|
||||||
|
end
|
||||||
|
test_message = descriptor.msgclass.decode_json(request.json_payload, options)
|
||||||
|
rescue Google::Protobuf::ParseError => err
|
||||||
|
response.parse_error = err.message.encode('utf-8')
|
||||||
|
return response
|
||||||
|
end
|
||||||
|
|
||||||
|
when :text_payload
|
||||||
|
begin
|
||||||
|
response.skipped = "Ruby doesn't support text format"
|
||||||
|
return response
|
||||||
|
end
|
||||||
|
|
||||||
|
when nil
|
||||||
|
fail "Request didn't have payload"
|
||||||
|
end
|
||||||
|
|
||||||
|
case request.requested_output_format
|
||||||
|
when :UNSPECIFIED
|
||||||
|
fail 'Unspecified output format'
|
||||||
|
|
||||||
|
when :PROTOBUF
|
||||||
|
begin
|
||||||
|
response.protobuf_payload = test_message.to_proto
|
||||||
|
rescue Google::Protobuf::ParseError => err
|
||||||
|
response.serialize_error = err.message.encode('utf-8')
|
||||||
|
end
|
||||||
|
|
||||||
|
when :JSON
|
||||||
|
begin
|
||||||
|
response.json_payload = test_message.to_json
|
||||||
|
rescue Google::Protobuf::ParseError => err
|
||||||
|
response.serialize_error = err.message.encode('utf-8')
|
||||||
|
end
|
||||||
|
|
||||||
|
when nil
|
||||||
|
fail "Request didn't have requested output format"
|
||||||
|
end
|
||||||
|
rescue StandardError => err
|
||||||
|
response.runtime_error = err.message.encode('utf-8')
|
||||||
|
end
|
||||||
|
|
||||||
|
response
|
||||||
|
end
|
||||||
|
|
||||||
|
# Returns true if the test ran successfully, false on legitimate EOF.
|
||||||
|
# If EOF is encountered in an unexpected place, raises IOError.
|
||||||
|
def do_test_io
|
||||||
|
length_bytes = STDIN.read(4)
|
||||||
|
return false if length_bytes.nil?
|
||||||
|
|
||||||
|
length = length_bytes.unpack('V').first
|
||||||
|
serialized_request = STDIN.read(length)
|
||||||
|
if serialized_request.nil? || serialized_request.length != length
|
||||||
|
fail IOError
|
||||||
|
end
|
||||||
|
|
||||||
|
request = Conformance::ConformanceRequest.decode(serialized_request)
|
||||||
|
|
||||||
|
response = do_test(request)
|
||||||
|
|
||||||
|
serialized_response = Conformance::ConformanceResponse.encode(response)
|
||||||
|
STDOUT.write([serialized_response.length].pack('V'))
|
||||||
|
STDOUT.write(serialized_response)
|
||||||
|
STDOUT.flush
|
||||||
|
|
||||||
|
if $verbose
|
||||||
|
STDERR.puts("conformance_ruby: request=#{request.to_json}, " \
|
||||||
|
"response=#{response.to_json}\n")
|
||||||
|
end
|
||||||
|
|
||||||
|
$test_count += 1
|
||||||
|
|
||||||
|
true
|
||||||
|
end
|
||||||
|
|
||||||
|
loop do
|
||||||
|
unless do_test_io
|
||||||
|
STDERR.puts('conformance_ruby: received EOF from test runner ' \
|
||||||
|
"after #{$test_count} tests, exiting")
|
||||||
|
break
|
||||||
|
end
|
||||||
|
end
|
||||||
519
conformance/conformance_test.cc
Normal file
519
conformance/conformance_test.cc
Normal file
@@ -0,0 +1,519 @@
|
|||||||
|
// Protocol Buffers - Google's data interchange format
|
||||||
|
// Copyright 2008 Google Inc. All rights reserved.
|
||||||
|
// https://developers.google.com/protocol-buffers/
|
||||||
|
//
|
||||||
|
// Redistribution and use in source and binary forms, with or without
|
||||||
|
// modification, are permitted provided that the following conditions are
|
||||||
|
// met:
|
||||||
|
//
|
||||||
|
// * Redistributions of source code must retain the above copyright
|
||||||
|
// notice, this list of conditions and the following disclaimer.
|
||||||
|
// * Redistributions in binary form must reproduce the above
|
||||||
|
// copyright notice, this list of conditions and the following disclaimer
|
||||||
|
// in the documentation and/or other materials provided with the
|
||||||
|
// distribution.
|
||||||
|
// * Neither the name of Google Inc. nor the names of its
|
||||||
|
// contributors may be used to endorse or promote products derived from
|
||||||
|
// this software without specific prior written permission.
|
||||||
|
//
|
||||||
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
#include "conformance_test.h"
|
||||||
|
|
||||||
|
#include <stdarg.h>
|
||||||
|
|
||||||
|
#include <fstream>
|
||||||
|
#include <set>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#include "google/protobuf/message.h"
|
||||||
|
#include "google/protobuf/text_format.h"
|
||||||
|
#include "google/protobuf/util/field_comparator.h"
|
||||||
|
#include "google/protobuf/util/json_util.h"
|
||||||
|
#include "google/protobuf/util/message_differencer.h"
|
||||||
|
#include "absl/strings/str_cat.h"
|
||||||
|
#include "absl/strings/str_format.h"
|
||||||
|
#include "conformance/conformance.pb.h"
|
||||||
|
#include "conformance/conformance.pb.h"
|
||||||
|
|
||||||
|
using conformance::ConformanceRequest;
|
||||||
|
using conformance::ConformanceResponse;
|
||||||
|
using conformance::WireFormat;
|
||||||
|
using google::protobuf::TextFormat;
|
||||||
|
using google::protobuf::util::DefaultFieldComparator;
|
||||||
|
using google::protobuf::util::MessageDifferencer;
|
||||||
|
using std::string;
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
static string ToOctString(const string& binary_string) {
|
||||||
|
string oct_string;
|
||||||
|
for (size_t i = 0; i < binary_string.size(); i++) {
|
||||||
|
uint8_t c = binary_string.at(i);
|
||||||
|
uint8_t high = c / 64;
|
||||||
|
uint8_t mid = (c % 64) / 8;
|
||||||
|
uint8_t low = c % 8;
|
||||||
|
oct_string.push_back('\\');
|
||||||
|
oct_string.push_back('0' + high);
|
||||||
|
oct_string.push_back('0' + mid);
|
||||||
|
oct_string.push_back('0' + low);
|
||||||
|
}
|
||||||
|
return oct_string;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
namespace google {
|
||||||
|
namespace protobuf {
|
||||||
|
|
||||||
|
ConformanceTestSuite::ConformanceRequestSetting::ConformanceRequestSetting(
|
||||||
|
ConformanceLevel level,
|
||||||
|
conformance::WireFormat input_format,
|
||||||
|
conformance::WireFormat output_format,
|
||||||
|
conformance::TestCategory test_category,
|
||||||
|
const Message& prototype_message,
|
||||||
|
const string& test_name, const string& input)
|
||||||
|
: level_(level),
|
||||||
|
input_format_(input_format),
|
||||||
|
output_format_(output_format),
|
||||||
|
prototype_message_(prototype_message),
|
||||||
|
prototype_message_for_compare_(prototype_message.New()),
|
||||||
|
test_name_(test_name) {
|
||||||
|
switch (input_format) {
|
||||||
|
case conformance::PROTOBUF: {
|
||||||
|
request_.set_protobuf_payload(input);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case conformance::JSON: {
|
||||||
|
request_.set_json_payload(input);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case conformance::JSPB: {
|
||||||
|
request_.set_jspb_payload(input);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case conformance::TEXT_FORMAT: {
|
||||||
|
request_.set_text_payload(input);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
GOOGLE_LOG(FATAL) << "Unspecified input format";
|
||||||
|
}
|
||||||
|
|
||||||
|
request_.set_test_category(test_category);
|
||||||
|
|
||||||
|
request_.set_message_type(prototype_message.GetDescriptor()->full_name());
|
||||||
|
request_.set_requested_output_format(output_format);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::unique_ptr<Message>
|
||||||
|
ConformanceTestSuite::ConformanceRequestSetting::NewTestMessage() const {
|
||||||
|
return std::unique_ptr<Message>(prototype_message_for_compare_->New());
|
||||||
|
}
|
||||||
|
|
||||||
|
string ConformanceTestSuite::ConformanceRequestSetting::
|
||||||
|
GetTestName() const {
|
||||||
|
string rname =
|
||||||
|
prototype_message_.GetDescriptor()->file()->syntax() ==
|
||||||
|
FileDescriptor::SYNTAX_PROTO3 ? "Proto3" : "Proto2";
|
||||||
|
|
||||||
|
return absl::StrCat(ConformanceLevelToString(level_), ".", rname, ".",
|
||||||
|
InputFormatString(input_format_), ".", test_name_, ".",
|
||||||
|
OutputFormatString(output_format_));
|
||||||
|
}
|
||||||
|
|
||||||
|
string ConformanceTestSuite::ConformanceRequestSetting::
|
||||||
|
ConformanceLevelToString(
|
||||||
|
ConformanceLevel level) const {
|
||||||
|
switch (level) {
|
||||||
|
case REQUIRED: return "Required";
|
||||||
|
case RECOMMENDED: return "Recommended";
|
||||||
|
}
|
||||||
|
GOOGLE_LOG(FATAL) << "Unknown value: " << level;
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
string ConformanceTestSuite::ConformanceRequestSetting::
|
||||||
|
InputFormatString(conformance::WireFormat format) const {
|
||||||
|
switch (format) {
|
||||||
|
case conformance::PROTOBUF:
|
||||||
|
return "ProtobufInput";
|
||||||
|
case conformance::JSON:
|
||||||
|
return "JsonInput";
|
||||||
|
case conformance::TEXT_FORMAT:
|
||||||
|
return "TextFormatInput";
|
||||||
|
default:
|
||||||
|
GOOGLE_LOG(FATAL) << "Unspecified output format";
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
string ConformanceTestSuite::ConformanceRequestSetting::
|
||||||
|
OutputFormatString(conformance::WireFormat format) const {
|
||||||
|
switch (format) {
|
||||||
|
case conformance::PROTOBUF:
|
||||||
|
return "ProtobufOutput";
|
||||||
|
case conformance::JSON:
|
||||||
|
return "JsonOutput";
|
||||||
|
case conformance::TEXT_FORMAT:
|
||||||
|
return "TextFormatOutput";
|
||||||
|
default:
|
||||||
|
GOOGLE_LOG(FATAL) << "Unspecified output format";
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
void ConformanceTestSuite::TruncateDebugPayload(string* payload) {
|
||||||
|
if (payload != nullptr && payload->size() > 200) {
|
||||||
|
payload->resize(200);
|
||||||
|
payload->append("...(truncated)");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const ConformanceRequest ConformanceTestSuite::TruncateRequest(
|
||||||
|
const ConformanceRequest& request) {
|
||||||
|
ConformanceRequest debug_request(request);
|
||||||
|
switch (debug_request.payload_case()) {
|
||||||
|
case ConformanceRequest::kProtobufPayload:
|
||||||
|
TruncateDebugPayload(debug_request.mutable_protobuf_payload());
|
||||||
|
break;
|
||||||
|
case ConformanceRequest::kJsonPayload:
|
||||||
|
TruncateDebugPayload(debug_request.mutable_json_payload());
|
||||||
|
break;
|
||||||
|
case ConformanceRequest::kTextPayload:
|
||||||
|
TruncateDebugPayload(debug_request.mutable_text_payload());
|
||||||
|
break;
|
||||||
|
case ConformanceRequest::kJspbPayload:
|
||||||
|
TruncateDebugPayload(debug_request.mutable_jspb_payload());
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
// Do nothing.
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return debug_request;
|
||||||
|
}
|
||||||
|
|
||||||
|
const ConformanceResponse ConformanceTestSuite::TruncateResponse(
|
||||||
|
const ConformanceResponse& response) {
|
||||||
|
ConformanceResponse debug_response(response);
|
||||||
|
switch (debug_response.result_case()) {
|
||||||
|
case ConformanceResponse::kProtobufPayload:
|
||||||
|
TruncateDebugPayload(debug_response.mutable_protobuf_payload());
|
||||||
|
break;
|
||||||
|
case ConformanceResponse::kJsonPayload:
|
||||||
|
TruncateDebugPayload(debug_response.mutable_json_payload());
|
||||||
|
break;
|
||||||
|
case ConformanceResponse::kTextPayload:
|
||||||
|
TruncateDebugPayload(debug_response.mutable_text_payload());
|
||||||
|
break;
|
||||||
|
case ConformanceResponse::kJspbPayload:
|
||||||
|
TruncateDebugPayload(debug_response.mutable_jspb_payload());
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
// Do nothing.
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return debug_response;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ConformanceTestSuite::ReportSuccess(const string& test_name) {
|
||||||
|
if (expected_to_fail_.erase(test_name) != 0) {
|
||||||
|
absl::StrAppendFormat(
|
||||||
|
&output_,
|
||||||
|
"ERROR: test %s is in the failure list, but test succeeded. "
|
||||||
|
"Remove it from the failure list.\n",
|
||||||
|
test_name);
|
||||||
|
unexpected_succeeding_tests_.insert(test_name);
|
||||||
|
}
|
||||||
|
successes_++;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ConformanceTestSuite::ReportFailure(const string& test_name,
|
||||||
|
ConformanceLevel level,
|
||||||
|
const ConformanceRequest& request,
|
||||||
|
const ConformanceResponse& response,
|
||||||
|
absl::string_view message) {
|
||||||
|
if (expected_to_fail_.erase(test_name) == 1) {
|
||||||
|
expected_failures_++;
|
||||||
|
if (!verbose_)
|
||||||
|
return;
|
||||||
|
} else if (level == RECOMMENDED && !enforce_recommended_) {
|
||||||
|
absl::StrAppendFormat(&output_, "WARNING, test=%s: ", test_name);
|
||||||
|
} else {
|
||||||
|
absl::StrAppendFormat(&output_, "ERROR, test=%s: ", test_name);
|
||||||
|
unexpected_failing_tests_.insert(test_name);
|
||||||
|
}
|
||||||
|
|
||||||
|
absl::StrAppendFormat(&output_, "%s, request=%s, response=%s\n", message,
|
||||||
|
TruncateRequest(request).ShortDebugString(),
|
||||||
|
TruncateResponse(response).ShortDebugString());
|
||||||
|
}
|
||||||
|
|
||||||
|
void ConformanceTestSuite::ReportSkip(const string& test_name,
|
||||||
|
const ConformanceRequest& request,
|
||||||
|
const ConformanceResponse& response) {
|
||||||
|
if (verbose_) {
|
||||||
|
absl::StrAppendFormat(
|
||||||
|
&output_, "SKIPPED, test=%s request=%s, response=%s\n", test_name,
|
||||||
|
request.ShortDebugString(), response.ShortDebugString());
|
||||||
|
}
|
||||||
|
skipped_.insert(test_name);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ConformanceTestSuite::RunValidInputTest(
|
||||||
|
const ConformanceRequestSetting& setting,
|
||||||
|
const string& equivalent_text_format) {
|
||||||
|
std::unique_ptr<Message> reference_message(setting.NewTestMessage());
|
||||||
|
GOOGLE_CHECK(TextFormat::ParseFromString(equivalent_text_format,
|
||||||
|
reference_message.get()))
|
||||||
|
<< "Failed to parse data for test case: " << setting.GetTestName()
|
||||||
|
<< ", data: " << equivalent_text_format;
|
||||||
|
const string equivalent_wire_format = reference_message->SerializeAsString();
|
||||||
|
RunValidBinaryInputTest(setting, equivalent_wire_format);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ConformanceTestSuite::RunValidBinaryInputTest(
|
||||||
|
const ConformanceRequestSetting& setting,
|
||||||
|
const string& equivalent_wire_format, bool require_same_wire_format) {
|
||||||
|
const ConformanceRequest& request = setting.GetRequest();
|
||||||
|
ConformanceResponse response;
|
||||||
|
RunTest(setting.GetTestName(), request, &response);
|
||||||
|
VerifyResponse(setting, equivalent_wire_format, response, true,
|
||||||
|
require_same_wire_format);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ConformanceTestSuite::VerifyResponse(
|
||||||
|
const ConformanceRequestSetting& setting,
|
||||||
|
const string& equivalent_wire_format, const ConformanceResponse& response,
|
||||||
|
bool need_report_success, bool require_same_wire_format) {
|
||||||
|
std::unique_ptr<Message> test_message(setting.NewTestMessage());
|
||||||
|
const ConformanceRequest& request = setting.GetRequest();
|
||||||
|
const string& test_name = setting.GetTestName();
|
||||||
|
ConformanceLevel level = setting.GetLevel();
|
||||||
|
std::unique_ptr<Message> reference_message = setting.NewTestMessage();
|
||||||
|
|
||||||
|
GOOGLE_CHECK(reference_message->ParseFromString(equivalent_wire_format))
|
||||||
|
<< "Failed to parse wire data for test case: " << test_name;
|
||||||
|
|
||||||
|
switch (response.result_case()) {
|
||||||
|
case ConformanceResponse::RESULT_NOT_SET:
|
||||||
|
ReportFailure(test_name, level, request, response,
|
||||||
|
"Response didn't have any field in the Response.");
|
||||||
|
return;
|
||||||
|
|
||||||
|
case ConformanceResponse::kParseError:
|
||||||
|
case ConformanceResponse::kTimeoutError:
|
||||||
|
case ConformanceResponse::kRuntimeError:
|
||||||
|
case ConformanceResponse::kSerializeError:
|
||||||
|
ReportFailure(test_name, level, request, response,
|
||||||
|
"Failed to parse input or produce output.");
|
||||||
|
return;
|
||||||
|
|
||||||
|
case ConformanceResponse::kSkipped:
|
||||||
|
ReportSkip(test_name, request, response);
|
||||||
|
return;
|
||||||
|
|
||||||
|
default:
|
||||||
|
if (!ParseResponse(response, setting, test_message.get())) return;
|
||||||
|
}
|
||||||
|
|
||||||
|
MessageDifferencer differencer;
|
||||||
|
DefaultFieldComparator field_comparator;
|
||||||
|
field_comparator.set_treat_nan_as_equal(true);
|
||||||
|
differencer.set_field_comparator(&field_comparator);
|
||||||
|
string differences;
|
||||||
|
differencer.ReportDifferencesToString(&differences);
|
||||||
|
|
||||||
|
bool check = false;
|
||||||
|
|
||||||
|
if (require_same_wire_format) {
|
||||||
|
GOOGLE_DCHECK_EQ(response.result_case(), ConformanceResponse::kProtobufPayload);
|
||||||
|
const string& protobuf_payload = response.protobuf_payload();
|
||||||
|
check = equivalent_wire_format == protobuf_payload;
|
||||||
|
differences = absl::StrCat("Expect: ", ToOctString(equivalent_wire_format),
|
||||||
|
", but got: ", ToOctString(protobuf_payload));
|
||||||
|
} else {
|
||||||
|
check = differencer.Compare(*reference_message, *test_message);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (check) {
|
||||||
|
if (need_report_success) {
|
||||||
|
ReportSuccess(test_name);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
ReportFailure(
|
||||||
|
test_name, level, request, response,
|
||||||
|
absl::StrCat("Output was not equivalent to reference message: ",
|
||||||
|
differences));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ConformanceTestSuite::RunTest(const string& test_name,
|
||||||
|
const ConformanceRequest& request,
|
||||||
|
ConformanceResponse* response) {
|
||||||
|
if (test_names_.insert(test_name).second == false) {
|
||||||
|
GOOGLE_LOG(FATAL) << "Duplicated test name: " << test_name;
|
||||||
|
}
|
||||||
|
|
||||||
|
string serialized_request;
|
||||||
|
string serialized_response;
|
||||||
|
request.SerializeToString(&serialized_request);
|
||||||
|
|
||||||
|
runner_->RunTest(test_name, serialized_request, &serialized_response);
|
||||||
|
|
||||||
|
if (!response->ParseFromString(serialized_response)) {
|
||||||
|
response->Clear();
|
||||||
|
response->set_runtime_error("response proto could not be parsed.");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (verbose_) {
|
||||||
|
absl::StrAppendFormat(
|
||||||
|
&output_, "conformance test: name=%s, request=%s, response=%s\n",
|
||||||
|
test_name, TruncateRequest(request).ShortDebugString(),
|
||||||
|
TruncateResponse(*response).ShortDebugString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ConformanceTestSuite::CheckSetEmpty(
|
||||||
|
const std::set<string>& set_to_check,
|
||||||
|
const std::string& write_to_file,
|
||||||
|
const std::string& msg) {
|
||||||
|
if (set_to_check.empty()) {
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
absl::StrAppendFormat(&output_, "\n");
|
||||||
|
absl::StrAppendFormat(&output_, "%s\n\n", msg);
|
||||||
|
for (absl::string_view v : set_to_check) {
|
||||||
|
absl::StrAppendFormat(&output_, " %s\n", v);
|
||||||
|
}
|
||||||
|
absl::StrAppendFormat(&output_, "\n");
|
||||||
|
|
||||||
|
if (!write_to_file.empty()) {
|
||||||
|
std::string full_filename;
|
||||||
|
const std::string* filename = &write_to_file;
|
||||||
|
if (!output_dir_.empty()) {
|
||||||
|
full_filename = output_dir_;
|
||||||
|
if (*output_dir_.rbegin() != '/') {
|
||||||
|
full_filename.push_back('/');
|
||||||
|
}
|
||||||
|
full_filename += write_to_file;
|
||||||
|
filename = &full_filename;
|
||||||
|
}
|
||||||
|
std::ofstream os(*filename);
|
||||||
|
if (os) {
|
||||||
|
for (absl::string_view v : set_to_check) {
|
||||||
|
os << v << "\n";
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
absl::StrAppendFormat(&output_, "Failed to open file: %s\n", *filename);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
string ConformanceTestSuite::WireFormatToString(
|
||||||
|
WireFormat wire_format) {
|
||||||
|
switch (wire_format) {
|
||||||
|
case conformance::PROTOBUF:
|
||||||
|
return "PROTOBUF";
|
||||||
|
case conformance::JSON:
|
||||||
|
return "JSON";
|
||||||
|
case conformance::JSPB:
|
||||||
|
return "JSPB";
|
||||||
|
case conformance::TEXT_FORMAT:
|
||||||
|
return "TEXT_FORMAT";
|
||||||
|
case conformance::UNSPECIFIED:
|
||||||
|
return "UNSPECIFIED";
|
||||||
|
default:
|
||||||
|
GOOGLE_LOG(FATAL) << "unknown wire type: " << wire_format;
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
void ConformanceTestSuite::AddExpectedFailedTest(const std::string& test_name) {
|
||||||
|
expected_to_fail_.insert(test_name);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ConformanceTestSuite::RunSuite(ConformanceTestRunner* runner,
|
||||||
|
std::string* output, const string& filename,
|
||||||
|
conformance::FailureSet* failure_list) {
|
||||||
|
runner_ = runner;
|
||||||
|
successes_ = 0;
|
||||||
|
expected_failures_ = 0;
|
||||||
|
skipped_.clear();
|
||||||
|
test_names_.clear();
|
||||||
|
unexpected_failing_tests_.clear();
|
||||||
|
unexpected_succeeding_tests_.clear();
|
||||||
|
|
||||||
|
output_ = "\nCONFORMANCE TEST BEGIN ====================================\n\n";
|
||||||
|
|
||||||
|
failure_list_filename_ = filename;
|
||||||
|
expected_to_fail_.clear();
|
||||||
|
for (const string& failure : failure_list->failure()) {
|
||||||
|
AddExpectedFailedTest(failure);
|
||||||
|
}
|
||||||
|
RunSuiteImpl();
|
||||||
|
|
||||||
|
bool ok = true;
|
||||||
|
if (!CheckSetEmpty(expected_to_fail_, "nonexistent_tests.txt",
|
||||||
|
"These tests were listed in the failure list, but they "
|
||||||
|
"don't exist. Remove them from the failure list by "
|
||||||
|
"running:\n"
|
||||||
|
" ./update_failure_list.py " + failure_list_filename_ +
|
||||||
|
" --remove nonexistent_tests.txt")) {
|
||||||
|
ok = false;
|
||||||
|
}
|
||||||
|
if (!CheckSetEmpty(unexpected_failing_tests_, "failing_tests.txt",
|
||||||
|
"These tests failed. If they can't be fixed right now, "
|
||||||
|
"you can add them to the failure list so the overall "
|
||||||
|
"suite can succeed. Add them to the failure list by "
|
||||||
|
"running:\n"
|
||||||
|
" ./update_failure_list.py " + failure_list_filename_ +
|
||||||
|
" --add failing_tests.txt")) {
|
||||||
|
ok = false;
|
||||||
|
}
|
||||||
|
if (!CheckSetEmpty(unexpected_succeeding_tests_, "succeeding_tests.txt",
|
||||||
|
"These tests succeeded, even though they were listed in "
|
||||||
|
"the failure list. Remove them from the failure list "
|
||||||
|
"by running:\n"
|
||||||
|
" ./update_failure_list.py " + failure_list_filename_ +
|
||||||
|
" --remove succeeding_tests.txt")) {
|
||||||
|
ok = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (verbose_) {
|
||||||
|
CheckSetEmpty(skipped_, "",
|
||||||
|
"These tests were skipped (probably because support for some "
|
||||||
|
"features is not implemented)");
|
||||||
|
}
|
||||||
|
|
||||||
|
absl::StrAppendFormat(&output_,
|
||||||
|
"CONFORMANCE SUITE %s: %d successes, %zu skipped, "
|
||||||
|
"%d expected failures, %zu unexpected failures.\n",
|
||||||
|
ok ? "PASSED" : "FAILED", successes_, skipped_.size(),
|
||||||
|
expected_failures_, unexpected_failing_tests_.size());
|
||||||
|
absl::StrAppendFormat(&output_, "\n");
|
||||||
|
|
||||||
|
output->assign(output_);
|
||||||
|
|
||||||
|
return ok;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace protobuf
|
||||||
|
} // namespace google
|
||||||
341
conformance/conformance_test.h
Normal file
341
conformance/conformance_test.h
Normal file
@@ -0,0 +1,341 @@
|
|||||||
|
// 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 defines a protocol for running the conformance test suite
|
||||||
|
// in-process. In other words, the suite itself will run in the same process as
|
||||||
|
// the code under test.
|
||||||
|
//
|
||||||
|
// For pros and cons of this approach, please see conformance.proto.
|
||||||
|
|
||||||
|
#ifndef CONFORMANCE_CONFORMANCE_TEST_H
|
||||||
|
#define CONFORMANCE_CONFORMANCE_TEST_H
|
||||||
|
|
||||||
|
#include <functional>
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include "google/protobuf/descriptor.h"
|
||||||
|
#include "google/protobuf/wire_format_lite.h"
|
||||||
|
#include "google/protobuf/util/type_resolver.h"
|
||||||
|
#include "conformance/conformance.pb.h"
|
||||||
|
|
||||||
|
namespace conformance {
|
||||||
|
class ConformanceRequest;
|
||||||
|
class ConformanceResponse;
|
||||||
|
} // namespace conformance
|
||||||
|
|
||||||
|
namespace protobuf_test_messages {
|
||||||
|
namespace proto3 {
|
||||||
|
class TestAllTypesProto3;
|
||||||
|
} // namespace proto3
|
||||||
|
} // namespace protobuf_test_messages
|
||||||
|
|
||||||
|
namespace google {
|
||||||
|
namespace protobuf {
|
||||||
|
|
||||||
|
class ConformanceTestSuite;
|
||||||
|
|
||||||
|
class ConformanceTestRunner {
|
||||||
|
public:
|
||||||
|
virtual ~ConformanceTestRunner() {}
|
||||||
|
|
||||||
|
// Call to run a single conformance test.
|
||||||
|
//
|
||||||
|
// "input" is a serialized conformance.ConformanceRequest.
|
||||||
|
// "output" should be set to a serialized conformance.ConformanceResponse.
|
||||||
|
//
|
||||||
|
// If there is any error in running the test itself, set "runtime_error" in
|
||||||
|
// the response.
|
||||||
|
virtual void RunTest(const std::string& test_name,
|
||||||
|
const std::string& input,
|
||||||
|
std::string* output) = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Test runner that spawns the process being tested and communicates with it
|
||||||
|
// over a pipe.
|
||||||
|
class ForkPipeRunner : public ConformanceTestRunner {
|
||||||
|
public:
|
||||||
|
// Note: Run() doesn't take ownership of the pointers inside suites.
|
||||||
|
static int Run(int argc, char *argv[],
|
||||||
|
const std::vector<ConformanceTestSuite*>& suites);
|
||||||
|
|
||||||
|
ForkPipeRunner(const std::string& executable,
|
||||||
|
const std::vector<std::string>& executable_args,
|
||||||
|
bool performance)
|
||||||
|
: child_pid_(-1),
|
||||||
|
executable_(executable),
|
||||||
|
executable_args_(executable_args),
|
||||||
|
performance_(performance) {}
|
||||||
|
|
||||||
|
explicit ForkPipeRunner(const std::string& executable)
|
||||||
|
: child_pid_(-1), executable_(executable) {}
|
||||||
|
|
||||||
|
virtual ~ForkPipeRunner() {}
|
||||||
|
|
||||||
|
void RunTest(const std::string& test_name,
|
||||||
|
const std::string& request,
|
||||||
|
std::string* response);
|
||||||
|
|
||||||
|
private:
|
||||||
|
void SpawnTestProgram();
|
||||||
|
|
||||||
|
void CheckedWrite(int fd, const void *buf, size_t len);
|
||||||
|
bool TryRead(int fd, void *buf, size_t len);
|
||||||
|
void CheckedRead(int fd, void *buf, size_t len);
|
||||||
|
|
||||||
|
int write_fd_;
|
||||||
|
int read_fd_;
|
||||||
|
pid_t child_pid_;
|
||||||
|
std::string executable_;
|
||||||
|
const std::vector<std::string> executable_args_;
|
||||||
|
bool performance_;
|
||||||
|
std::string current_test_name_;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Class representing the test suite itself. To run it, implement your own
|
||||||
|
// class derived from ConformanceTestRunner, class derived from
|
||||||
|
// ConformanceTestSuite and then write code like:
|
||||||
|
//
|
||||||
|
// class MyConformanceTestSuite : public ConformanceTestSuite {
|
||||||
|
// public:
|
||||||
|
// void RunSuiteImpl() {
|
||||||
|
// // INSERT ACTUAL TESTS.
|
||||||
|
// }
|
||||||
|
// };
|
||||||
|
//
|
||||||
|
// class MyConformanceTestRunner : public ConformanceTestRunner {
|
||||||
|
// public:
|
||||||
|
// static int Run(int argc, char *argv[],
|
||||||
|
// ConformanceTestSuite* suite);
|
||||||
|
//
|
||||||
|
// private:
|
||||||
|
// virtual void RunTest(...) {
|
||||||
|
// // INSERT YOUR FRAMEWORK-SPECIFIC CODE HERE.
|
||||||
|
// }
|
||||||
|
// };
|
||||||
|
//
|
||||||
|
// int main() {
|
||||||
|
// MyConformanceTestSuite suite;
|
||||||
|
// MyConformanceTestRunner::Run(argc, argv, &suite);
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
class ConformanceTestSuite {
|
||||||
|
public:
|
||||||
|
ConformanceTestSuite()
|
||||||
|
: verbose_(false),
|
||||||
|
performance_(false),
|
||||||
|
enforce_recommended_(false),
|
||||||
|
failure_list_flag_name_("--failure_list") {}
|
||||||
|
virtual ~ConformanceTestSuite() {}
|
||||||
|
|
||||||
|
void SetPerformance(bool performance) { performance_ = performance; }
|
||||||
|
void SetVerbose(bool verbose) { verbose_ = verbose; }
|
||||||
|
|
||||||
|
// Whether to require the testee to pass RECOMMENDED tests. By default failing
|
||||||
|
// a RECOMMENDED test case will not fail the entire suite but will only
|
||||||
|
// generated a warning. If this flag is set to true, RECOMMENDED tests will
|
||||||
|
// be treated the same way as REQUIRED tests and failing a RECOMMENDED test
|
||||||
|
// case will cause the entire test suite to fail as well. An implementation
|
||||||
|
// can enable this if it wants to be strictly conforming to protobuf spec.
|
||||||
|
// See the comments about ConformanceLevel below to learn more about the
|
||||||
|
// difference between REQUIRED and RECOMMENDED test cases.
|
||||||
|
void SetEnforceRecommended(bool value) {
|
||||||
|
enforce_recommended_ = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Gets the flag name to the failure list file.
|
||||||
|
// By default, this would return --failure_list
|
||||||
|
std::string GetFailureListFlagName() { return failure_list_flag_name_; }
|
||||||
|
|
||||||
|
void SetFailureListFlagName(const std::string& failure_list_flag_name) {
|
||||||
|
failure_list_flag_name_ = failure_list_flag_name;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sets the path of the output directory.
|
||||||
|
void SetOutputDir(const char* output_dir) {
|
||||||
|
output_dir_ = output_dir;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Run all the conformance tests against the given test runner.
|
||||||
|
// Test output will be stored in "output".
|
||||||
|
//
|
||||||
|
// Returns true if the set of failing tests was exactly the same as the
|
||||||
|
// failure list.
|
||||||
|
// The filename here is *only* used to create/format useful error messages for
|
||||||
|
// how to update the failure list. We do NOT read this file at all.
|
||||||
|
bool RunSuite(ConformanceTestRunner* runner, std::string* output,
|
||||||
|
const std::string& filename,
|
||||||
|
conformance::FailureSet* failure_list);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
// Test cases are classified into a few categories:
|
||||||
|
// REQUIRED: the test case must be passed for an implementation to be
|
||||||
|
// interoperable with other implementations. For example, a
|
||||||
|
// parser implementation must accept both packed and unpacked
|
||||||
|
// form of repeated primitive fields.
|
||||||
|
// RECOMMENDED: the test case is not required for the implementation to
|
||||||
|
// be interoperable with other implementations, but is
|
||||||
|
// recommended for best performance and compatibility. For
|
||||||
|
// example, a proto3 serializer should serialize repeated
|
||||||
|
// primitive fields in packed form, but an implementation
|
||||||
|
// failing to do so will still be able to communicate with
|
||||||
|
// other implementations.
|
||||||
|
enum ConformanceLevel {
|
||||||
|
REQUIRED = 0,
|
||||||
|
RECOMMENDED = 1,
|
||||||
|
};
|
||||||
|
|
||||||
|
class ConformanceRequestSetting {
|
||||||
|
public:
|
||||||
|
ConformanceRequestSetting(ConformanceLevel level,
|
||||||
|
conformance::WireFormat input_format,
|
||||||
|
conformance::WireFormat output_format,
|
||||||
|
conformance::TestCategory test_category,
|
||||||
|
const Message& prototype_message,
|
||||||
|
const std::string& test_name,
|
||||||
|
const std::string& input);
|
||||||
|
virtual ~ConformanceRequestSetting() {}
|
||||||
|
|
||||||
|
std::unique_ptr<Message> NewTestMessage() const;
|
||||||
|
|
||||||
|
std::string GetTestName() const;
|
||||||
|
|
||||||
|
const conformance::ConformanceRequest& GetRequest() const {
|
||||||
|
return request_;
|
||||||
|
}
|
||||||
|
|
||||||
|
const ConformanceLevel GetLevel() const {
|
||||||
|
return level_;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string ConformanceLevelToString(ConformanceLevel level) const;
|
||||||
|
|
||||||
|
void SetPrintUnknownFields(bool print_unknown_fields) {
|
||||||
|
request_.set_print_unknown_fields(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetPrototypeMessageForCompare(const Message& message) {
|
||||||
|
prototype_message_for_compare_.reset(message.New());
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual std::string InputFormatString(conformance::WireFormat format) const;
|
||||||
|
virtual std::string OutputFormatString(
|
||||||
|
conformance::WireFormat format) const;
|
||||||
|
conformance::ConformanceRequest request_;
|
||||||
|
|
||||||
|
private:
|
||||||
|
ConformanceLevel level_;
|
||||||
|
::conformance::WireFormat input_format_;
|
||||||
|
::conformance::WireFormat output_format_;
|
||||||
|
const Message& prototype_message_;
|
||||||
|
std::unique_ptr<Message> prototype_message_for_compare_;
|
||||||
|
std::string test_name_;
|
||||||
|
};
|
||||||
|
|
||||||
|
bool CheckSetEmpty(const std::set<std::string>& set_to_check,
|
||||||
|
const std::string& write_to_file, const std::string& msg);
|
||||||
|
std::string WireFormatToString(conformance::WireFormat wire_format);
|
||||||
|
|
||||||
|
// Parse payload in the response to the given message. Returns true on
|
||||||
|
// success.
|
||||||
|
virtual bool ParseResponse(
|
||||||
|
const conformance::ConformanceResponse& response,
|
||||||
|
const ConformanceRequestSetting& setting,
|
||||||
|
Message* test_message) = 0;
|
||||||
|
|
||||||
|
void VerifyResponse(const ConformanceRequestSetting& setting,
|
||||||
|
const std::string& equivalent_wire_format,
|
||||||
|
const conformance::ConformanceResponse& response,
|
||||||
|
bool need_report_success, bool require_same_wire_format);
|
||||||
|
|
||||||
|
void TruncateDebugPayload(std::string* payload);
|
||||||
|
const conformance::ConformanceRequest TruncateRequest(
|
||||||
|
const conformance::ConformanceRequest& request);
|
||||||
|
const conformance::ConformanceResponse TruncateResponse(
|
||||||
|
const conformance::ConformanceResponse& response);
|
||||||
|
|
||||||
|
void ReportSuccess(const std::string& test_name);
|
||||||
|
void ReportFailure(const std::string& test_name, ConformanceLevel level,
|
||||||
|
const conformance::ConformanceRequest& request,
|
||||||
|
const conformance::ConformanceResponse& response,
|
||||||
|
absl::string_view message);
|
||||||
|
void ReportSkip(const std::string& test_name,
|
||||||
|
const conformance::ConformanceRequest& request,
|
||||||
|
const conformance::ConformanceResponse& response);
|
||||||
|
|
||||||
|
void RunValidInputTest(const ConformanceRequestSetting& setting,
|
||||||
|
const std::string& equivalent_text_format);
|
||||||
|
void RunValidBinaryInputTest(const ConformanceRequestSetting& setting,
|
||||||
|
const std::string& equivalent_wire_format,
|
||||||
|
bool require_same_wire_format = false);
|
||||||
|
|
||||||
|
void RunTest(const std::string& test_name,
|
||||||
|
const conformance::ConformanceRequest& request,
|
||||||
|
conformance::ConformanceResponse* response);
|
||||||
|
|
||||||
|
void AddExpectedFailedTest(const std::string& test_name);
|
||||||
|
|
||||||
|
virtual void RunSuiteImpl() = 0;
|
||||||
|
|
||||||
|
ConformanceTestRunner* runner_;
|
||||||
|
int successes_;
|
||||||
|
int expected_failures_;
|
||||||
|
bool verbose_;
|
||||||
|
bool performance_;
|
||||||
|
bool enforce_recommended_;
|
||||||
|
std::string output_;
|
||||||
|
std::string output_dir_;
|
||||||
|
std::string failure_list_flag_name_;
|
||||||
|
std::string failure_list_filename_;
|
||||||
|
|
||||||
|
// The set of test names that are expected to fail in this run, but haven't
|
||||||
|
// failed yet.
|
||||||
|
std::set<std::string> expected_to_fail_;
|
||||||
|
|
||||||
|
// The set of test names that have been run. Used to ensure that there are no
|
||||||
|
// duplicate names in the suite.
|
||||||
|
std::set<std::string> test_names_;
|
||||||
|
|
||||||
|
// The set of tests that failed, but weren't expected to.
|
||||||
|
std::set<std::string> unexpected_failing_tests_;
|
||||||
|
|
||||||
|
// The set of tests that succeeded, but weren't expected to.
|
||||||
|
std::set<std::string> unexpected_succeeding_tests_;
|
||||||
|
|
||||||
|
// The set of tests that the testee opted out of;
|
||||||
|
std::set<std::string> skipped_;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace protobuf
|
||||||
|
} // namespace google
|
||||||
|
|
||||||
|
#endif // CONFORMANCE_CONFORMANCE_TEST_H
|
||||||
40
conformance/conformance_test_main.cc
Normal file
40
conformance/conformance_test_main.cc
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
// Protocol Buffers - Google's data interchange format
|
||||||
|
// Copyright 2008 Google Inc. All rights reserved.
|
||||||
|
// https://developers.google.com/protocol-buffers/
|
||||||
|
//
|
||||||
|
// Redistribution and use in source and binary forms, with or without
|
||||||
|
// modification, are permitted provided that the following conditions are
|
||||||
|
// met:
|
||||||
|
//
|
||||||
|
// * Redistributions of source code must retain the above copyright
|
||||||
|
// notice, this list of conditions and the following disclaimer.
|
||||||
|
// * Redistributions in binary form must reproduce the above
|
||||||
|
// copyright notice, this list of conditions and the following disclaimer
|
||||||
|
// in the documentation and/or other materials provided with the
|
||||||
|
// distribution.
|
||||||
|
// * Neither the name of Google Inc. nor the names of its
|
||||||
|
// contributors may be used to endorse or promote products derived from
|
||||||
|
// this software without specific prior written permission.
|
||||||
|
//
|
||||||
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
#include "binary_json_conformance_suite.h"
|
||||||
|
#include "conformance_test.h"
|
||||||
|
#include "text_format_conformance_suite.h"
|
||||||
|
|
||||||
|
int main(int argc, char *argv[]) {
|
||||||
|
google::protobuf::BinaryAndJsonConformanceSuite binary_and_json_suite;
|
||||||
|
google::protobuf::TextFormatConformanceTestSuite text_format_suite;
|
||||||
|
return google::protobuf::ForkPipeRunner::Run(
|
||||||
|
argc, argv, {&binary_and_json_suite, &text_format_suite});
|
||||||
|
}
|
||||||
389
conformance/conformance_test_runner.cc
Normal file
389
conformance/conformance_test_runner.cc
Normal file
@@ -0,0 +1,389 @@
|
|||||||
|
// Protocol Buffers - Google's data interchange format
|
||||||
|
// Copyright 2008 Google Inc. All rights reserved.
|
||||||
|
// https://developers.google.com/protocol-buffers/
|
||||||
|
//
|
||||||
|
// Redistribution and use in source and binary forms, with or without
|
||||||
|
// modification, are permitted provided that the following conditions are
|
||||||
|
// met:
|
||||||
|
//
|
||||||
|
// * Redistributions of source code must retain the above copyright
|
||||||
|
// notice, this list of conditions and the following disclaimer.
|
||||||
|
// * Redistributions in binary form must reproduce the above
|
||||||
|
// copyright notice, this list of conditions and the following disclaimer
|
||||||
|
// in the documentation and/or other materials provided with the
|
||||||
|
// distribution.
|
||||||
|
// * Neither the name of Google Inc. nor the names of its
|
||||||
|
// contributors may be used to endorse or promote products derived from
|
||||||
|
// this software without specific prior written permission.
|
||||||
|
//
|
||||||
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
// This file contains a program for running the test suite in a separate
|
||||||
|
// process. The other alternative is to run the suite in-process. See
|
||||||
|
// conformance.proto for pros/cons of these two options.
|
||||||
|
//
|
||||||
|
// This program will fork the process under test and communicate with it over
|
||||||
|
// its stdin/stdout:
|
||||||
|
//
|
||||||
|
// +--------+ pipe +----------+
|
||||||
|
// | tester | <------> | testee |
|
||||||
|
// | | | |
|
||||||
|
// | C++ | | any lang |
|
||||||
|
// +--------+ +----------+
|
||||||
|
//
|
||||||
|
// The tester contains all of the test cases and their expected output.
|
||||||
|
// The testee is a simple program written in the target language that reads
|
||||||
|
// each test case and attempts to produce acceptable output for it.
|
||||||
|
//
|
||||||
|
// Every test consists of a ConformanceRequest/ConformanceResponse
|
||||||
|
// request/reply pair. The protocol on the pipe is simply:
|
||||||
|
//
|
||||||
|
// 1. tester sends 4-byte length N (little endian)
|
||||||
|
// 2. tester sends N bytes representing a ConformanceRequest proto
|
||||||
|
// 3. testee sends 4-byte length M (little endian)
|
||||||
|
// 4. testee sends M bytes representing a ConformanceResponse proto
|
||||||
|
|
||||||
|
#include <errno.h>
|
||||||
|
#include <signal.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/wait.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
#include <cstdlib>
|
||||||
|
#include <fstream>
|
||||||
|
#include <future>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include "absl/strings/str_format.h"
|
||||||
|
#include "conformance/conformance.pb.h"
|
||||||
|
#include "conformance_test.h"
|
||||||
|
|
||||||
|
using conformance::ConformanceResponse;
|
||||||
|
using google::protobuf::ConformanceTestSuite;
|
||||||
|
using std::string;
|
||||||
|
using std::vector;
|
||||||
|
|
||||||
|
#define STRINGIFY(x) #x
|
||||||
|
#define TOSTRING(x) STRINGIFY(x)
|
||||||
|
#define GOOGLE_CHECK_SYSCALL(call) \
|
||||||
|
if (call < 0) { \
|
||||||
|
perror(#call " " __FILE__ ":" TOSTRING(__LINE__)); \
|
||||||
|
exit(1); \
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace google {
|
||||||
|
namespace protobuf {
|
||||||
|
|
||||||
|
void ParseFailureList(const char *filename,
|
||||||
|
conformance::FailureSet *failure_list) {
|
||||||
|
std::ifstream infile(filename);
|
||||||
|
|
||||||
|
if (!infile.is_open()) {
|
||||||
|
fprintf(stderr, "Couldn't open failure list file: %s\n", filename);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (string line; getline(infile, line);) {
|
||||||
|
// Remove whitespace.
|
||||||
|
line.erase(std::remove_if(line.begin(), line.end(), ::isspace), line.end());
|
||||||
|
|
||||||
|
// Remove comments.
|
||||||
|
line = line.substr(0, line.find("#"));
|
||||||
|
|
||||||
|
if (!line.empty()) {
|
||||||
|
failure_list->add_failure(line);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void UsageError() {
|
||||||
|
fprintf(stderr, "Usage: conformance-test-runner [options] <test-program>\n");
|
||||||
|
fprintf(stderr, "\n");
|
||||||
|
fprintf(stderr, "Options:\n");
|
||||||
|
fprintf(stderr,
|
||||||
|
" --failure_list <filename> Use to specify list of tests\n");
|
||||||
|
fprintf(stderr,
|
||||||
|
" that are expected to fail. File\n");
|
||||||
|
fprintf(stderr,
|
||||||
|
" should contain one test name per\n");
|
||||||
|
fprintf(stderr,
|
||||||
|
" line. Use '#' for comments.\n");
|
||||||
|
fprintf(stderr,
|
||||||
|
" --text_format_failure_list <filename> Use to specify list \n");
|
||||||
|
fprintf(stderr,
|
||||||
|
" of tests that are expected to \n");
|
||||||
|
fprintf(stderr, " fail in the \n");
|
||||||
|
fprintf(stderr,
|
||||||
|
" text_format_conformance_suite. \n");
|
||||||
|
fprintf(stderr,
|
||||||
|
" File should contain one test name \n");
|
||||||
|
fprintf(stderr,
|
||||||
|
" per line. Use '#' for comments.\n");
|
||||||
|
|
||||||
|
fprintf(stderr,
|
||||||
|
" --enforce_recommended Enforce that recommended test\n");
|
||||||
|
fprintf(stderr,
|
||||||
|
" cases are also passing. Specify\n");
|
||||||
|
fprintf(stderr,
|
||||||
|
" this flag if you want to be\n");
|
||||||
|
fprintf(stderr,
|
||||||
|
" strictly conforming to protobuf\n");
|
||||||
|
fprintf(stderr, " spec.\n");
|
||||||
|
fprintf(stderr,
|
||||||
|
" --output_dir <dirname> Directory to write\n"
|
||||||
|
" output files.\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ForkPipeRunner::RunTest(const std::string &test_name,
|
||||||
|
const std::string &request,
|
||||||
|
std::string *response) {
|
||||||
|
if (child_pid_ < 0) {
|
||||||
|
SpawnTestProgram();
|
||||||
|
}
|
||||||
|
current_test_name_ = test_name;
|
||||||
|
|
||||||
|
uint32_t len = request.size();
|
||||||
|
CheckedWrite(write_fd_, &len, sizeof(uint32_t));
|
||||||
|
CheckedWrite(write_fd_, request.c_str(), request.size());
|
||||||
|
|
||||||
|
if (!TryRead(read_fd_, &len, sizeof(uint32_t))) {
|
||||||
|
// We failed to read from the child, assume a crash and try to reap.
|
||||||
|
GOOGLE_LOG(INFO) << "Trying to reap child, pid=" << child_pid_;
|
||||||
|
|
||||||
|
int status = 0;
|
||||||
|
waitpid(child_pid_, &status, WEXITED);
|
||||||
|
|
||||||
|
string error_msg;
|
||||||
|
conformance::ConformanceResponse response_obj;
|
||||||
|
if (WIFEXITED(status)) {
|
||||||
|
if (WEXITSTATUS(status) == 0) {
|
||||||
|
absl::StrAppendFormat(&error_msg,
|
||||||
|
"child timed out, killed by signal %d",
|
||||||
|
WTERMSIG(status));
|
||||||
|
response_obj.set_timeout_error(error_msg);
|
||||||
|
} else {
|
||||||
|
absl::StrAppendFormat(&error_msg, "child exited, status=%d",
|
||||||
|
WEXITSTATUS(status));
|
||||||
|
response_obj.set_runtime_error(error_msg);
|
||||||
|
}
|
||||||
|
} else if (WIFSIGNALED(status)) {
|
||||||
|
absl::StrAppendFormat(&error_msg, "child killed by signal %d",
|
||||||
|
WTERMSIG(status));
|
||||||
|
}
|
||||||
|
GOOGLE_LOG(INFO) << error_msg;
|
||||||
|
child_pid_ = -1;
|
||||||
|
|
||||||
|
response_obj.SerializeToString(response);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
response->resize(len);
|
||||||
|
CheckedRead(read_fd_, (void *)response->c_str(), len);
|
||||||
|
}
|
||||||
|
|
||||||
|
int ForkPipeRunner::Run(int argc, char *argv[],
|
||||||
|
const std::vector<ConformanceTestSuite *> &suites) {
|
||||||
|
if (suites.empty()) {
|
||||||
|
fprintf(stderr, "No test suites found.\n");
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
bool all_ok = true;
|
||||||
|
for (ConformanceTestSuite *suite : suites) {
|
||||||
|
string program;
|
||||||
|
std::vector<string> program_args;
|
||||||
|
string failure_list_filename;
|
||||||
|
conformance::FailureSet failure_list;
|
||||||
|
|
||||||
|
bool performance = false;
|
||||||
|
for (int arg = 1; arg < argc; ++arg) {
|
||||||
|
if (strcmp(argv[arg], suite->GetFailureListFlagName().c_str()) == 0) {
|
||||||
|
if (++arg == argc) UsageError();
|
||||||
|
failure_list_filename = argv[arg];
|
||||||
|
ParseFailureList(argv[arg], &failure_list);
|
||||||
|
} else if (strcmp(argv[arg], "--performance") == 0) {
|
||||||
|
performance = true;
|
||||||
|
suite->SetPerformance(true);
|
||||||
|
} else if (strcmp(argv[arg], "--verbose") == 0) {
|
||||||
|
suite->SetVerbose(true);
|
||||||
|
} else if (strcmp(argv[arg], "--enforce_recommended") == 0) {
|
||||||
|
suite->SetEnforceRecommended(true);
|
||||||
|
} else if (strcmp(argv[arg], "--output_dir") == 0) {
|
||||||
|
if (++arg == argc) UsageError();
|
||||||
|
suite->SetOutputDir(argv[arg]);
|
||||||
|
} else if (argv[arg][0] == '-') {
|
||||||
|
bool recognized_flag = false;
|
||||||
|
for (ConformanceTestSuite *suite : suites) {
|
||||||
|
if (strcmp(argv[arg], suite->GetFailureListFlagName().c_str()) == 0) {
|
||||||
|
if (++arg == argc) UsageError();
|
||||||
|
recognized_flag = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!recognized_flag) {
|
||||||
|
fprintf(stderr, "Unknown option: %s\n", argv[arg]);
|
||||||
|
UsageError();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
program += argv[arg++];
|
||||||
|
while (arg < argc) {
|
||||||
|
program_args.push_back(argv[arg]);
|
||||||
|
arg++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ForkPipeRunner runner(program, program_args, performance);
|
||||||
|
|
||||||
|
std::string output;
|
||||||
|
all_ok = all_ok && suite->RunSuite(&runner, &output, failure_list_filename,
|
||||||
|
&failure_list);
|
||||||
|
|
||||||
|
fwrite(output.c_str(), 1, output.size(), stderr);
|
||||||
|
}
|
||||||
|
return all_ok ? EXIT_SUCCESS : EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO(haberman): make this work on Windows, instead of using these
|
||||||
|
// UNIX-specific APIs.
|
||||||
|
//
|
||||||
|
// There is a platform-agnostic API in
|
||||||
|
// src/google/protobuf/compiler/subprocess.h
|
||||||
|
//
|
||||||
|
// However that API only supports sending a single message to the subprocess.
|
||||||
|
// We really want to be able to send messages and receive responses one at a
|
||||||
|
// time:
|
||||||
|
//
|
||||||
|
// 1. Spawning a new process for each test would take way too long for thousands
|
||||||
|
// of tests and subprocesses like java that can take 100ms or more to start
|
||||||
|
// up.
|
||||||
|
//
|
||||||
|
// 2. Sending all the tests in one big message and receiving all results in one
|
||||||
|
// big message would take away our visibility about which test(s) caused a
|
||||||
|
// crash or other fatal error. It would also give us only a single failure
|
||||||
|
// instead of all of them.
|
||||||
|
void ForkPipeRunner::SpawnTestProgram() {
|
||||||
|
int toproc_pipe_fd[2];
|
||||||
|
int fromproc_pipe_fd[2];
|
||||||
|
if (pipe(toproc_pipe_fd) < 0 || pipe(fromproc_pipe_fd) < 0) {
|
||||||
|
perror("pipe");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
pid_t pid = fork();
|
||||||
|
if (pid < 0) {
|
||||||
|
perror("fork");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pid) {
|
||||||
|
// Parent.
|
||||||
|
GOOGLE_CHECK_SYSCALL(close(toproc_pipe_fd[0]));
|
||||||
|
GOOGLE_CHECK_SYSCALL(close(fromproc_pipe_fd[1]));
|
||||||
|
write_fd_ = toproc_pipe_fd[1];
|
||||||
|
read_fd_ = fromproc_pipe_fd[0];
|
||||||
|
child_pid_ = pid;
|
||||||
|
} else {
|
||||||
|
// Child.
|
||||||
|
GOOGLE_CHECK_SYSCALL(close(STDIN_FILENO));
|
||||||
|
GOOGLE_CHECK_SYSCALL(close(STDOUT_FILENO));
|
||||||
|
GOOGLE_CHECK_SYSCALL(dup2(toproc_pipe_fd[0], STDIN_FILENO));
|
||||||
|
GOOGLE_CHECK_SYSCALL(dup2(fromproc_pipe_fd[1], STDOUT_FILENO));
|
||||||
|
|
||||||
|
GOOGLE_CHECK_SYSCALL(close(toproc_pipe_fd[0]));
|
||||||
|
GOOGLE_CHECK_SYSCALL(close(fromproc_pipe_fd[1]));
|
||||||
|
GOOGLE_CHECK_SYSCALL(close(toproc_pipe_fd[1]));
|
||||||
|
GOOGLE_CHECK_SYSCALL(close(fromproc_pipe_fd[0]));
|
||||||
|
|
||||||
|
std::unique_ptr<char[]> executable(new char[executable_.size() + 1]);
|
||||||
|
memcpy(executable.get(), executable_.c_str(), executable_.size());
|
||||||
|
executable[executable_.size()] = '\0';
|
||||||
|
|
||||||
|
std::vector<const char *> argv;
|
||||||
|
argv.push_back(executable.get());
|
||||||
|
GOOGLE_LOG(INFO) << argv[0];
|
||||||
|
for (size_t i = 0; i < executable_args_.size(); ++i) {
|
||||||
|
argv.push_back(executable_args_[i].c_str());
|
||||||
|
GOOGLE_LOG(INFO) << executable_args_[i];
|
||||||
|
}
|
||||||
|
argv.push_back(nullptr);
|
||||||
|
// Never returns.
|
||||||
|
GOOGLE_CHECK_SYSCALL(execv(executable.get(), const_cast<char **>(argv.data())));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ForkPipeRunner::CheckedWrite(int fd, const void *buf, size_t len) {
|
||||||
|
if (static_cast<size_t>(write(fd, buf, len)) != len) {
|
||||||
|
GOOGLE_LOG(FATAL) << current_test_name_
|
||||||
|
<< ": error writing to test program: " << strerror(errno);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ForkPipeRunner::TryRead(int fd, void *buf, size_t len) {
|
||||||
|
size_t ofs = 0;
|
||||||
|
while (len > 0) {
|
||||||
|
std::future<ssize_t> future = std::async(
|
||||||
|
std::launch::async,
|
||||||
|
[](int fd, void *buf, size_t ofs, size_t len) {
|
||||||
|
return read(fd, (char *)buf + ofs, len);
|
||||||
|
},
|
||||||
|
fd, buf, ofs, len);
|
||||||
|
std::future_status status;
|
||||||
|
if (performance_) {
|
||||||
|
status = future.wait_for(std::chrono::seconds(5));
|
||||||
|
if (status == std::future_status::timeout) {
|
||||||
|
GOOGLE_LOG(ERROR) << current_test_name_ << ": timeout from test program";
|
||||||
|
kill(child_pid_, SIGQUIT);
|
||||||
|
// TODO(sandyzhang): Only log in flag-guarded mode, since reading output
|
||||||
|
// from SIGQUIT is slow and verbose.
|
||||||
|
std::vector<char> err;
|
||||||
|
err.resize(5000);
|
||||||
|
ssize_t err_bytes_read;
|
||||||
|
size_t err_ofs = 0;
|
||||||
|
do {
|
||||||
|
err_bytes_read =
|
||||||
|
read(fd, (void *)&err[err_ofs], err.size() - err_ofs);
|
||||||
|
err_ofs += err_bytes_read;
|
||||||
|
} while (err_bytes_read > 0 && err_ofs < err.size());
|
||||||
|
GOOGLE_LOG(ERROR) << "child_pid_=" << child_pid_ << " SIGQUIT: \n" << &err[0];
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
future.wait();
|
||||||
|
}
|
||||||
|
ssize_t bytes_read = future.get();
|
||||||
|
if (bytes_read == 0) {
|
||||||
|
GOOGLE_LOG(ERROR) << current_test_name_ << ": unexpected EOF from test program";
|
||||||
|
return false;
|
||||||
|
} else if (bytes_read < 0) {
|
||||||
|
GOOGLE_LOG(ERROR) << current_test_name_
|
||||||
|
<< ": error reading from test program: " << strerror(errno);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
len -= bytes_read;
|
||||||
|
ofs += bytes_read;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ForkPipeRunner::CheckedRead(int fd, void *buf, size_t len) {
|
||||||
|
if (!TryRead(fd, buf, len)) {
|
||||||
|
GOOGLE_LOG(FATAL) << current_test_name_
|
||||||
|
<< ": error reading from test program: " << strerror(errno);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace protobuf
|
||||||
|
} // namespace google
|
||||||
48
conformance/defs.bzl
Normal file
48
conformance/defs.bzl
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
"""Starlark definitions for Protobuf conformance tests.
|
||||||
|
|
||||||
|
PLEASE DO NOT DEPEND ON THE CONTENTS OF THIS FILE, IT IS UNSTABLE.
|
||||||
|
"""
|
||||||
|
|
||||||
|
def conformance_test(
|
||||||
|
name,
|
||||||
|
testee,
|
||||||
|
failure_list = None,
|
||||||
|
text_format_failure_list = None,
|
||||||
|
**kwargs):
|
||||||
|
"""Conformance test runner.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
name: the name for the test.
|
||||||
|
testee: a conformance test client binary.
|
||||||
|
failure_list: a text file with known failures, one per line.
|
||||||
|
text_format_failure_list: a text file with known failures (one per line)
|
||||||
|
for the text format conformance suite.
|
||||||
|
**kwargs: common arguments to pass to sh_test.
|
||||||
|
"""
|
||||||
|
args = ["--testee %s" % _strip_bazel(testee)]
|
||||||
|
failure_lists = []
|
||||||
|
if failure_list:
|
||||||
|
args = args + ["--failure_list %s" % _strip_bazel(failure_list)]
|
||||||
|
failure_lists = failure_lists + [failure_list]
|
||||||
|
if text_format_failure_list:
|
||||||
|
args = args + ["--text_format_failure_list %s" % _strip_bazel(text_format_failure_list)]
|
||||||
|
failure_lists = failure_lists + [text_format_failure_list]
|
||||||
|
|
||||||
|
native.sh_test(
|
||||||
|
name = name,
|
||||||
|
srcs = ["//conformance:bazel_conformance_test_runner.sh"],
|
||||||
|
data = [testee] + failure_lists + [
|
||||||
|
"//conformance:conformance_test_runner",
|
||||||
|
],
|
||||||
|
args = args,
|
||||||
|
deps = [
|
||||||
|
"@bazel_tools//tools/bash/runfiles",
|
||||||
|
],
|
||||||
|
tags = ["conformance"],
|
||||||
|
**kwargs
|
||||||
|
)
|
||||||
|
|
||||||
|
def _strip_bazel(testee):
|
||||||
|
if testee.startswith("//"):
|
||||||
|
testee = testee.replace("//", "com_google_protobuf/")
|
||||||
|
return testee.replace(":", "/")
|
||||||
35
conformance/failure_list_cpp.txt
Normal file
35
conformance/failure_list_cpp.txt
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
# This is the list of conformance tests that are known to fail for the C++
|
||||||
|
# implementation right now. These should be fixed.
|
||||||
|
#
|
||||||
|
# By listing them here we can keep tabs on which ones are failing and be sure
|
||||||
|
# that we don't introduce regressions in other tests.
|
||||||
|
#
|
||||||
|
# TODO(haberman): insert links to corresponding bugs tracking the issue.
|
||||||
|
# Should we use GitHub issues or the Google-internal bug tracker?
|
||||||
|
|
||||||
|
Recommended.FieldMaskNumbersDontRoundTrip.JsonOutput
|
||||||
|
Recommended.FieldMaskPathsDontRoundTrip.JsonOutput
|
||||||
|
Recommended.FieldMaskTooManyUnderscore.JsonOutput
|
||||||
|
Recommended.Proto3.JsonInput.BoolFieldDoubleQuotedFalse
|
||||||
|
Recommended.Proto3.JsonInput.BoolFieldDoubleQuotedTrue
|
||||||
|
Recommended.Proto3.JsonInput.FieldMaskInvalidCharacter
|
||||||
|
Recommended.Proto3.JsonInput.FieldNameDuplicate
|
||||||
|
Recommended.Proto3.JsonInput.FieldNameDuplicateDifferentCasing1
|
||||||
|
Recommended.Proto3.JsonInput.FieldNameDuplicateDifferentCasing2
|
||||||
|
Recommended.Proto3.JsonInput.FieldNameNotQuoted
|
||||||
|
Recommended.Proto3.JsonInput.MapFieldValueIsNull
|
||||||
|
Recommended.Proto3.JsonInput.RepeatedFieldMessageElementIsNull
|
||||||
|
Recommended.Proto3.JsonInput.RepeatedFieldPrimitiveElementIsNull
|
||||||
|
Recommended.Proto3.JsonInput.RepeatedFieldTrailingComma
|
||||||
|
Recommended.Proto3.JsonInput.RepeatedFieldTrailingCommaWithNewlines
|
||||||
|
Recommended.Proto3.JsonInput.RepeatedFieldTrailingCommaWithSpace
|
||||||
|
Recommended.Proto3.JsonInput.RepeatedFieldTrailingCommaWithSpaceCommaSpace
|
||||||
|
Recommended.Proto3.JsonInput.StringFieldSingleQuoteBoth
|
||||||
|
Recommended.Proto3.JsonInput.StringFieldSingleQuoteKey
|
||||||
|
Recommended.Proto3.JsonInput.StringFieldSingleQuoteValue
|
||||||
|
Recommended.Proto3.JsonInput.StringFieldUppercaseEscapeLetter
|
||||||
|
Recommended.Proto3.JsonInput.TrailingCommaInAnObject
|
||||||
|
Recommended.Proto3.JsonInput.TrailingCommaInAnObjectWithNewlines
|
||||||
|
Recommended.Proto3.JsonInput.TrailingCommaInAnObjectWithSpace
|
||||||
|
Recommended.Proto3.JsonInput.TrailingCommaInAnObjectWithSpaceCommaSpace
|
||||||
|
Recommended.Proto2.JsonInput.FieldNameExtension.Validator
|
||||||
7
conformance/failure_list_csharp.txt
Normal file
7
conformance/failure_list_csharp.txt
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
Recommended.Proto2.JsonInput.FieldNameExtension.Validator
|
||||||
|
Recommended.Proto3.JsonInput.BytesFieldBase64Url.JsonOutput
|
||||||
|
Recommended.Proto3.JsonInput.BytesFieldBase64Url.ProtobufOutput
|
||||||
|
Required.Proto3.JsonInput.OneofFieldNullFirst.JsonOutput
|
||||||
|
Required.Proto3.JsonInput.OneofFieldNullFirst.ProtobufOutput
|
||||||
|
Required.Proto3.JsonInput.OneofFieldNullSecond.JsonOutput
|
||||||
|
Required.Proto3.JsonInput.OneofFieldNullSecond.ProtobufOutput
|
||||||
44
conformance/failure_list_java.txt
Normal file
44
conformance/failure_list_java.txt
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
# This is the list of conformance tests that are known to fail for the Java
|
||||||
|
# implementation right now. These should be fixed.
|
||||||
|
#
|
||||||
|
# By listing them here we can keep tabs on which ones are failing and be sure
|
||||||
|
# that we don't introduce regressions in other tests.
|
||||||
|
|
||||||
|
Recommended.FieldMaskNumbersDontRoundTrip.JsonOutput
|
||||||
|
Recommended.FieldMaskPathsDontRoundTrip.JsonOutput
|
||||||
|
Recommended.FieldMaskTooManyUnderscore.JsonOutput
|
||||||
|
Recommended.Proto3.JsonInput.BoolFieldAllCapitalFalse
|
||||||
|
Recommended.Proto3.JsonInput.BoolFieldAllCapitalTrue
|
||||||
|
Recommended.Proto3.JsonInput.BoolFieldCamelCaseFalse
|
||||||
|
Recommended.Proto3.JsonInput.BoolFieldCamelCaseTrue
|
||||||
|
Recommended.Proto3.JsonInput.BoolFieldDoubleQuotedFalse
|
||||||
|
Recommended.Proto3.JsonInput.BoolFieldDoubleQuotedTrue
|
||||||
|
Recommended.Proto3.JsonInput.BoolMapFieldKeyNotQuoted
|
||||||
|
Recommended.Proto3.JsonInput.DoubleFieldInfinityNotQuoted
|
||||||
|
Recommended.Proto3.JsonInput.DoubleFieldNanNotQuoted
|
||||||
|
Recommended.Proto3.JsonInput.DoubleFieldNegativeInfinityNotQuoted
|
||||||
|
Recommended.Proto3.JsonInput.FieldMaskInvalidCharacter
|
||||||
|
Recommended.Proto3.JsonInput.FieldNameDuplicate
|
||||||
|
Recommended.Proto3.JsonInput.FieldNameNotQuoted
|
||||||
|
Recommended.Proto3.JsonInput.FloatFieldInfinityNotQuoted
|
||||||
|
Recommended.Proto3.JsonInput.FloatFieldNanNotQuoted
|
||||||
|
Recommended.Proto3.JsonInput.FloatFieldNegativeInfinityNotQuoted
|
||||||
|
Recommended.Proto3.JsonInput.Int32MapFieldKeyNotQuoted
|
||||||
|
Recommended.Proto3.JsonInput.Int64MapFieldKeyNotQuoted
|
||||||
|
Recommended.Proto3.JsonInput.JsonWithComments
|
||||||
|
Recommended.Proto3.JsonInput.StringFieldSingleQuoteBoth
|
||||||
|
Recommended.Proto3.JsonInput.StringFieldSingleQuoteKey
|
||||||
|
Recommended.Proto3.JsonInput.StringFieldSingleQuoteValue
|
||||||
|
Recommended.Proto3.JsonInput.StringFieldSurrogateInWrongOrder
|
||||||
|
Recommended.Proto3.JsonInput.StringFieldUnpairedHighSurrogate
|
||||||
|
Recommended.Proto3.JsonInput.StringFieldUnpairedLowSurrogate
|
||||||
|
Recommended.Proto3.JsonInput.Uint32MapFieldKeyNotQuoted
|
||||||
|
Recommended.Proto3.JsonInput.Uint64MapFieldKeyNotQuoted
|
||||||
|
Recommended.Proto2.JsonInput.FieldNameExtension.Validator
|
||||||
|
Required.Proto3.JsonInput.EnumFieldNotQuoted
|
||||||
|
Required.Proto3.JsonInput.Int32FieldLeadingZero
|
||||||
|
Required.Proto3.JsonInput.Int32FieldNegativeWithLeadingZero
|
||||||
|
Required.Proto3.JsonInput.Int32FieldPlusSign
|
||||||
|
Required.Proto3.JsonInput.RepeatedFieldWrongElementTypeExpectingStringsGotBool
|
||||||
|
Required.Proto3.JsonInput.RepeatedFieldWrongElementTypeExpectingStringsGotInt
|
||||||
|
Required.Proto3.JsonInput.StringFieldNotAString
|
||||||
10
conformance/failure_list_java_lite.txt
Normal file
10
conformance/failure_list_java_lite.txt
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
# This is the list of conformance tests that are known to fail for the Java
|
||||||
|
# implementation right now. These should be fixed.
|
||||||
|
#
|
||||||
|
# By listing them here we can keep tabs on which ones are failing and be sure
|
||||||
|
# that we don't introduce regressions in other tests.
|
||||||
|
|
||||||
|
Required.Proto3.ProtobufInput.PrematureEofInDelimitedDataForKnownNonRepeatedValue.MESSAGE
|
||||||
|
Required.Proto3.ProtobufInput.PrematureEofInDelimitedDataForKnownRepeatedValue.MESSAGE
|
||||||
|
Required.Proto2.ProtobufInput.PrematureEofInDelimitedDataForKnownNonRepeatedValue.MESSAGE
|
||||||
|
Required.Proto2.ProtobufInput.PrematureEofInDelimitedDataForKnownRepeatedValue.MESSAGE
|
||||||
95
conformance/failure_list_jruby.txt
Normal file
95
conformance/failure_list_jruby.txt
Normal file
@@ -0,0 +1,95 @@
|
|||||||
|
Recommended.FieldMaskNumbersDontRoundTrip.JsonOutput
|
||||||
|
Recommended.FieldMaskPathsDontRoundTrip.JsonOutput
|
||||||
|
Recommended.FieldMaskTooManyUnderscore.JsonOutput
|
||||||
|
Recommended.Proto2.JsonInput.FieldNameExtension.Validator
|
||||||
|
Recommended.Proto2.ProtobufInput.ValidDataRepeated.BOOL.PackedInput.PackedOutput.ProtobufOutput
|
||||||
|
Recommended.Proto2.ProtobufInput.ValidDataRepeated.BOOL.UnpackedInput.PackedOutput.ProtobufOutput
|
||||||
|
Recommended.Proto2.ProtobufInput.ValidDataRepeated.DOUBLE.PackedInput.PackedOutput.ProtobufOutput
|
||||||
|
Recommended.Proto2.ProtobufInput.ValidDataRepeated.DOUBLE.UnpackedInput.PackedOutput.ProtobufOutput
|
||||||
|
Recommended.Proto2.ProtobufInput.ValidDataRepeated.ENUM.PackedInput.PackedOutput.ProtobufOutput
|
||||||
|
Recommended.Proto2.ProtobufInput.ValidDataRepeated.ENUM.UnpackedInput.PackedOutput.ProtobufOutput
|
||||||
|
Recommended.Proto2.ProtobufInput.ValidDataRepeated.FIXED32.PackedInput.PackedOutput.ProtobufOutput
|
||||||
|
Recommended.Proto2.ProtobufInput.ValidDataRepeated.FIXED32.UnpackedInput.PackedOutput.ProtobufOutput
|
||||||
|
Recommended.Proto2.ProtobufInput.ValidDataRepeated.FIXED64.PackedInput.PackedOutput.ProtobufOutput
|
||||||
|
Recommended.Proto2.ProtobufInput.ValidDataRepeated.FIXED64.UnpackedInput.PackedOutput.ProtobufOutput
|
||||||
|
Recommended.Proto2.ProtobufInput.ValidDataRepeated.FLOAT.PackedInput.PackedOutput.ProtobufOutput
|
||||||
|
Recommended.Proto2.ProtobufInput.ValidDataRepeated.FLOAT.UnpackedInput.PackedOutput.ProtobufOutput
|
||||||
|
Recommended.Proto2.ProtobufInput.ValidDataRepeated.INT32.PackedInput.PackedOutput.ProtobufOutput
|
||||||
|
Recommended.Proto2.ProtobufInput.ValidDataRepeated.INT32.UnpackedInput.PackedOutput.ProtobufOutput
|
||||||
|
Recommended.Proto2.ProtobufInput.ValidDataRepeated.INT64.PackedInput.PackedOutput.ProtobufOutput
|
||||||
|
Recommended.Proto2.ProtobufInput.ValidDataRepeated.INT64.UnpackedInput.PackedOutput.ProtobufOutput
|
||||||
|
Recommended.Proto2.ProtobufInput.ValidDataRepeated.SFIXED32.PackedInput.PackedOutput.ProtobufOutput
|
||||||
|
Recommended.Proto2.ProtobufInput.ValidDataRepeated.SFIXED32.UnpackedInput.PackedOutput.ProtobufOutput
|
||||||
|
Recommended.Proto2.ProtobufInput.ValidDataRepeated.SFIXED64.PackedInput.PackedOutput.ProtobufOutput
|
||||||
|
Recommended.Proto2.ProtobufInput.ValidDataRepeated.SFIXED64.UnpackedInput.PackedOutput.ProtobufOutput
|
||||||
|
Recommended.Proto2.ProtobufInput.ValidDataRepeated.SINT32.PackedInput.PackedOutput.ProtobufOutput
|
||||||
|
Recommended.Proto2.ProtobufInput.ValidDataRepeated.SINT32.UnpackedInput.PackedOutput.ProtobufOutput
|
||||||
|
Recommended.Proto2.ProtobufInput.ValidDataRepeated.SINT64.PackedInput.PackedOutput.ProtobufOutput
|
||||||
|
Recommended.Proto2.ProtobufInput.ValidDataRepeated.SINT64.UnpackedInput.PackedOutput.ProtobufOutput
|
||||||
|
Recommended.Proto2.ProtobufInput.ValidDataRepeated.UINT32.PackedInput.PackedOutput.ProtobufOutput
|
||||||
|
Recommended.Proto2.ProtobufInput.ValidDataRepeated.UINT32.UnpackedInput.PackedOutput.ProtobufOutput
|
||||||
|
Recommended.Proto2.ProtobufInput.ValidDataRepeated.UINT64.PackedInput.PackedOutput.ProtobufOutput
|
||||||
|
Recommended.Proto2.ProtobufInput.ValidDataRepeated.UINT64.UnpackedInput.PackedOutput.ProtobufOutput
|
||||||
|
Recommended.Proto3.JsonInput.BoolFieldAllCapitalFalse
|
||||||
|
Recommended.Proto3.JsonInput.BoolFieldAllCapitalTrue
|
||||||
|
Recommended.Proto3.JsonInput.BoolFieldCamelCaseFalse
|
||||||
|
Recommended.Proto3.JsonInput.BoolFieldCamelCaseTrue
|
||||||
|
Recommended.Proto3.JsonInput.BoolFieldDoubleQuotedFalse
|
||||||
|
Recommended.Proto3.JsonInput.BoolFieldDoubleQuotedTrue
|
||||||
|
Recommended.Proto3.JsonInput.BoolMapFieldKeyNotQuoted
|
||||||
|
Recommended.Proto3.JsonInput.DoubleFieldInfinityNotQuoted
|
||||||
|
Recommended.Proto3.JsonInput.DoubleFieldNanNotQuoted
|
||||||
|
Recommended.Proto3.JsonInput.DoubleFieldNegativeInfinityNotQuoted
|
||||||
|
Recommended.Proto3.JsonInput.FieldMaskInvalidCharacter
|
||||||
|
Recommended.Proto3.JsonInput.FieldNameDuplicate
|
||||||
|
Recommended.Proto3.JsonInput.FieldNameNotQuoted
|
||||||
|
Recommended.Proto3.JsonInput.FloatFieldInfinityNotQuoted
|
||||||
|
Recommended.Proto3.JsonInput.FloatFieldNanNotQuoted
|
||||||
|
Recommended.Proto3.JsonInput.FloatFieldNegativeInfinityNotQuoted
|
||||||
|
Recommended.Proto3.JsonInput.Int32MapFieldKeyNotQuoted
|
||||||
|
Recommended.Proto3.JsonInput.Int64MapFieldKeyNotQuoted
|
||||||
|
Recommended.Proto3.JsonInput.JsonWithComments
|
||||||
|
Recommended.Proto3.JsonInput.StringFieldSingleQuoteBoth
|
||||||
|
Recommended.Proto3.JsonInput.StringFieldSingleQuoteKey
|
||||||
|
Recommended.Proto3.JsonInput.StringFieldSingleQuoteValue
|
||||||
|
Recommended.Proto3.JsonInput.StringFieldSurrogateInWrongOrder
|
||||||
|
Recommended.Proto3.JsonInput.StringFieldUnpairedHighSurrogate
|
||||||
|
Recommended.Proto3.JsonInput.StringFieldUnpairedLowSurrogate
|
||||||
|
Recommended.Proto3.JsonInput.Uint32MapFieldKeyNotQuoted
|
||||||
|
Recommended.Proto3.JsonInput.Uint64MapFieldKeyNotQuoted
|
||||||
|
Recommended.Proto3.ProtobufInput.ValidDataOneofBinary.MESSAGE.Merge.ProtobufOutput
|
||||||
|
Recommended.Proto3.ProtobufInput.ValidDataRepeated.BOOL.PackedInput.UnpackedOutput.ProtobufOutput
|
||||||
|
Recommended.Proto3.ProtobufInput.ValidDataRepeated.BOOL.UnpackedInput.UnpackedOutput.ProtobufOutput
|
||||||
|
Recommended.Proto3.ProtobufInput.ValidDataRepeated.DOUBLE.PackedInput.UnpackedOutput.ProtobufOutput
|
||||||
|
Recommended.Proto3.ProtobufInput.ValidDataRepeated.DOUBLE.UnpackedInput.UnpackedOutput.ProtobufOutput
|
||||||
|
Recommended.Proto3.ProtobufInput.ValidDataRepeated.ENUM.PackedInput.UnpackedOutput.ProtobufOutput
|
||||||
|
Recommended.Proto3.ProtobufInput.ValidDataRepeated.ENUM.UnpackedInput.UnpackedOutput.ProtobufOutput
|
||||||
|
Recommended.Proto3.ProtobufInput.ValidDataRepeated.FIXED32.PackedInput.UnpackedOutput.ProtobufOutput
|
||||||
|
Recommended.Proto3.ProtobufInput.ValidDataRepeated.FIXED32.UnpackedInput.UnpackedOutput.ProtobufOutput
|
||||||
|
Recommended.Proto3.ProtobufInput.ValidDataRepeated.FIXED64.PackedInput.UnpackedOutput.ProtobufOutput
|
||||||
|
Recommended.Proto3.ProtobufInput.ValidDataRepeated.FIXED64.UnpackedInput.UnpackedOutput.ProtobufOutput
|
||||||
|
Recommended.Proto3.ProtobufInput.ValidDataRepeated.FLOAT.PackedInput.UnpackedOutput.ProtobufOutput
|
||||||
|
Recommended.Proto3.ProtobufInput.ValidDataRepeated.FLOAT.UnpackedInput.UnpackedOutput.ProtobufOutput
|
||||||
|
Recommended.Proto3.ProtobufInput.ValidDataRepeated.INT32.PackedInput.UnpackedOutput.ProtobufOutput
|
||||||
|
Recommended.Proto3.ProtobufInput.ValidDataRepeated.INT32.UnpackedInput.UnpackedOutput.ProtobufOutput
|
||||||
|
Recommended.Proto3.ProtobufInput.ValidDataRepeated.INT64.PackedInput.UnpackedOutput.ProtobufOutput
|
||||||
|
Recommended.Proto3.ProtobufInput.ValidDataRepeated.INT64.UnpackedInput.UnpackedOutput.ProtobufOutput
|
||||||
|
Recommended.Proto3.ProtobufInput.ValidDataRepeated.SFIXED32.PackedInput.UnpackedOutput.ProtobufOutput
|
||||||
|
Recommended.Proto3.ProtobufInput.ValidDataRepeated.SFIXED32.UnpackedInput.UnpackedOutput.ProtobufOutput
|
||||||
|
Recommended.Proto3.ProtobufInput.ValidDataRepeated.SFIXED64.PackedInput.UnpackedOutput.ProtobufOutput
|
||||||
|
Recommended.Proto3.ProtobufInput.ValidDataRepeated.SFIXED64.UnpackedInput.UnpackedOutput.ProtobufOutput
|
||||||
|
Recommended.Proto3.ProtobufInput.ValidDataRepeated.SINT32.PackedInput.UnpackedOutput.ProtobufOutput
|
||||||
|
Recommended.Proto3.ProtobufInput.ValidDataRepeated.SINT32.UnpackedInput.UnpackedOutput.ProtobufOutput
|
||||||
|
Recommended.Proto3.ProtobufInput.ValidDataRepeated.SINT64.PackedInput.UnpackedOutput.ProtobufOutput
|
||||||
|
Recommended.Proto3.ProtobufInput.ValidDataRepeated.SINT64.UnpackedInput.UnpackedOutput.ProtobufOutput
|
||||||
|
Recommended.Proto3.ProtobufInput.ValidDataRepeated.UINT32.PackedInput.UnpackedOutput.ProtobufOutput
|
||||||
|
Recommended.Proto3.ProtobufInput.ValidDataRepeated.UINT32.UnpackedInput.UnpackedOutput.ProtobufOutput
|
||||||
|
Recommended.Proto3.ProtobufInput.ValidDataRepeated.UINT64.PackedInput.UnpackedOutput.ProtobufOutput
|
||||||
|
Recommended.Proto3.ProtobufInput.ValidDataRepeated.UINT64.UnpackedInput.UnpackedOutput.ProtobufOutput
|
||||||
|
Required.Proto3.JsonInput.EnumFieldNotQuoted
|
||||||
|
Required.Proto3.JsonInput.Int32FieldLeadingZero
|
||||||
|
Required.Proto3.JsonInput.Int32FieldNegativeWithLeadingZero
|
||||||
|
Required.Proto3.JsonInput.Int32FieldPlusSign
|
||||||
|
Required.Proto3.JsonInput.RepeatedFieldWrongElementTypeExpectingStringsGotBool
|
||||||
|
Required.Proto3.JsonInput.RepeatedFieldWrongElementTypeExpectingStringsGotInt
|
||||||
|
Required.Proto3.JsonInput.StringFieldNotAString
|
||||||
2
conformance/failure_list_objc.txt
Normal file
2
conformance/failure_list_objc.txt
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
# JSON input or output tests are skipped (in conformance_objc.m) as mobile
|
||||||
|
# platforms don't support JSON wire format to avoid code bloat.
|
||||||
32
conformance/failure_list_php.txt
Normal file
32
conformance/failure_list_php.txt
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
Recommended.FieldMaskNumbersDontRoundTrip.JsonOutput
|
||||||
|
Recommended.FieldMaskPathsDontRoundTrip.JsonOutput
|
||||||
|
Recommended.FieldMaskTooManyUnderscore.JsonOutput
|
||||||
|
Recommended.Proto2.JsonInput.FieldNameExtension.Validator
|
||||||
|
Recommended.Proto3.JsonInput.BytesFieldBase64Url.JsonOutput
|
||||||
|
Recommended.Proto3.JsonInput.BytesFieldBase64Url.ProtobufOutput
|
||||||
|
Recommended.Proto3.JsonInput.FieldMaskInvalidCharacter
|
||||||
|
Recommended.Proto3.ProtobufInput.ValidDataOneofBinary.MESSAGE.Merge.ProtobufOutput
|
||||||
|
Required.Proto2.JsonInput.StoresDefaultPrimitive.Validator
|
||||||
|
Required.Proto3.JsonInput.DoubleFieldTooSmall
|
||||||
|
Required.Proto3.JsonInput.DurationNegativeNanos.JsonOutput
|
||||||
|
Required.Proto3.JsonInput.DurationNegativeNanos.ProtobufOutput
|
||||||
|
Required.Proto3.JsonInput.FloatFieldTooLarge
|
||||||
|
Required.Proto3.JsonInput.FloatFieldTooSmall
|
||||||
|
Required.Proto3.JsonInput.Int32FieldNotInteger
|
||||||
|
Required.Proto3.JsonInput.Int64FieldNotInteger
|
||||||
|
Required.Proto3.JsonInput.OneofFieldDuplicate
|
||||||
|
Required.Proto3.JsonInput.OneofFieldNullSecond.JsonOutput
|
||||||
|
Required.Proto3.JsonInput.OneofFieldNullSecond.ProtobufOutput
|
||||||
|
Required.Proto3.JsonInput.RepeatedFieldWrongElementTypeExpectingStringsGotInt
|
||||||
|
Required.Proto3.JsonInput.RepeatedListValue.JsonOutput
|
||||||
|
Required.Proto3.JsonInput.RepeatedListValue.ProtobufOutput
|
||||||
|
Required.Proto3.JsonInput.StringFieldNotAString
|
||||||
|
Required.Proto3.JsonInput.Uint32FieldNotInteger
|
||||||
|
Required.Proto3.JsonInput.Uint64FieldNotInteger
|
||||||
|
Required.Proto3.ProtobufInput.RepeatedScalarMessageMerge.JsonOutput
|
||||||
|
Required.Proto3.ProtobufInput.RepeatedScalarMessageMerge.ProtobufOutput
|
||||||
|
Required.Proto3.ProtobufInput.ValidDataOneof.MESSAGE.Merge.JsonOutput
|
||||||
|
Required.Proto3.ProtobufInput.ValidDataOneof.MESSAGE.Merge.ProtobufOutput
|
||||||
|
Required.Proto3.ProtobufInput.ValidDataRepeated.FLOAT.PackedInput.JsonOutput
|
||||||
|
Required.Proto3.ProtobufInput.ValidDataRepeated.FLOAT.UnpackedInput.JsonOutput
|
||||||
|
Required.Proto3.ProtobufInput.ValidDataScalar.FLOAT[2].JsonOutput
|
||||||
2
conformance/failure_list_php_c.txt
Normal file
2
conformance/failure_list_php_c.txt
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
Recommended.Proto2.JsonInput.FieldNameExtension.Validator
|
||||||
|
Required.Proto2.JsonInput.StoresDefaultPrimitive.Validator
|
||||||
2
conformance/failure_list_python-post26.txt
Normal file
2
conformance/failure_list_python-post26.txt
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
JsonInput.StringFieldSurrogateInWrongOrder
|
||||||
|
JsonInput.StringFieldUnpairedHighSurrogate
|
||||||
0
conformance/failure_list_python.txt
Normal file
0
conformance/failure_list_python.txt
Normal file
8
conformance/failure_list_python_cpp.txt
Normal file
8
conformance/failure_list_python_cpp.txt
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
# This is the list of conformance tests that are known to fail for the
|
||||||
|
# Python/C++ implementation right now. These should be fixed.
|
||||||
|
#
|
||||||
|
# By listing them here we can keep tabs on which ones are failing and be sure
|
||||||
|
# that we don't introduce regressions in other tests.
|
||||||
|
#
|
||||||
|
# TODO(haberman): insert links to corresponding bugs tracking the issue.
|
||||||
|
# Should we use GitHub issues or the Google-internal bug tracker?
|
||||||
58
conformance/failure_list_ruby.txt
Normal file
58
conformance/failure_list_ruby.txt
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
Recommended.Proto2.JsonInput.FieldNameExtension.Validator
|
||||||
|
Recommended.Proto2.ProtobufInput.ValidDataRepeated.BOOL.PackedInput.PackedOutput.ProtobufOutput
|
||||||
|
Recommended.Proto2.ProtobufInput.ValidDataRepeated.BOOL.UnpackedInput.PackedOutput.ProtobufOutput
|
||||||
|
Recommended.Proto2.ProtobufInput.ValidDataRepeated.DOUBLE.PackedInput.PackedOutput.ProtobufOutput
|
||||||
|
Recommended.Proto2.ProtobufInput.ValidDataRepeated.DOUBLE.UnpackedInput.PackedOutput.ProtobufOutput
|
||||||
|
Recommended.Proto2.ProtobufInput.ValidDataRepeated.ENUM.PackedInput.PackedOutput.ProtobufOutput
|
||||||
|
Recommended.Proto2.ProtobufInput.ValidDataRepeated.ENUM.UnpackedInput.PackedOutput.ProtobufOutput
|
||||||
|
Recommended.Proto2.ProtobufInput.ValidDataRepeated.FIXED32.PackedInput.PackedOutput.ProtobufOutput
|
||||||
|
Recommended.Proto2.ProtobufInput.ValidDataRepeated.FIXED32.UnpackedInput.PackedOutput.ProtobufOutput
|
||||||
|
Recommended.Proto2.ProtobufInput.ValidDataRepeated.FIXED64.PackedInput.PackedOutput.ProtobufOutput
|
||||||
|
Recommended.Proto2.ProtobufInput.ValidDataRepeated.FIXED64.UnpackedInput.PackedOutput.ProtobufOutput
|
||||||
|
Recommended.Proto2.ProtobufInput.ValidDataRepeated.FLOAT.PackedInput.PackedOutput.ProtobufOutput
|
||||||
|
Recommended.Proto2.ProtobufInput.ValidDataRepeated.FLOAT.UnpackedInput.PackedOutput.ProtobufOutput
|
||||||
|
Recommended.Proto2.ProtobufInput.ValidDataRepeated.INT32.PackedInput.PackedOutput.ProtobufOutput
|
||||||
|
Recommended.Proto2.ProtobufInput.ValidDataRepeated.INT32.UnpackedInput.PackedOutput.ProtobufOutput
|
||||||
|
Recommended.Proto2.ProtobufInput.ValidDataRepeated.INT64.PackedInput.PackedOutput.ProtobufOutput
|
||||||
|
Recommended.Proto2.ProtobufInput.ValidDataRepeated.INT64.UnpackedInput.PackedOutput.ProtobufOutput
|
||||||
|
Recommended.Proto2.ProtobufInput.ValidDataRepeated.SFIXED32.PackedInput.PackedOutput.ProtobufOutput
|
||||||
|
Recommended.Proto2.ProtobufInput.ValidDataRepeated.SFIXED32.UnpackedInput.PackedOutput.ProtobufOutput
|
||||||
|
Recommended.Proto2.ProtobufInput.ValidDataRepeated.SFIXED64.PackedInput.PackedOutput.ProtobufOutput
|
||||||
|
Recommended.Proto2.ProtobufInput.ValidDataRepeated.SFIXED64.UnpackedInput.PackedOutput.ProtobufOutput
|
||||||
|
Recommended.Proto2.ProtobufInput.ValidDataRepeated.SINT32.PackedInput.PackedOutput.ProtobufOutput
|
||||||
|
Recommended.Proto2.ProtobufInput.ValidDataRepeated.SINT32.UnpackedInput.PackedOutput.ProtobufOutput
|
||||||
|
Recommended.Proto2.ProtobufInput.ValidDataRepeated.SINT64.PackedInput.PackedOutput.ProtobufOutput
|
||||||
|
Recommended.Proto2.ProtobufInput.ValidDataRepeated.SINT64.UnpackedInput.PackedOutput.ProtobufOutput
|
||||||
|
Recommended.Proto2.ProtobufInput.ValidDataRepeated.UINT32.PackedInput.PackedOutput.ProtobufOutput
|
||||||
|
Recommended.Proto2.ProtobufInput.ValidDataRepeated.UINT32.UnpackedInput.PackedOutput.ProtobufOutput
|
||||||
|
Recommended.Proto2.ProtobufInput.ValidDataRepeated.UINT64.PackedInput.PackedOutput.ProtobufOutput
|
||||||
|
Recommended.Proto2.ProtobufInput.ValidDataRepeated.UINT64.UnpackedInput.PackedOutput.ProtobufOutput
|
||||||
|
Recommended.Proto3.ProtobufInput.ValidDataOneofBinary.MESSAGE.Merge.ProtobufOutput
|
||||||
|
Recommended.Proto3.ProtobufInput.ValidDataRepeated.BOOL.PackedInput.UnpackedOutput.ProtobufOutput
|
||||||
|
Recommended.Proto3.ProtobufInput.ValidDataRepeated.BOOL.UnpackedInput.UnpackedOutput.ProtobufOutput
|
||||||
|
Recommended.Proto3.ProtobufInput.ValidDataRepeated.DOUBLE.PackedInput.UnpackedOutput.ProtobufOutput
|
||||||
|
Recommended.Proto3.ProtobufInput.ValidDataRepeated.DOUBLE.UnpackedInput.UnpackedOutput.ProtobufOutput
|
||||||
|
Recommended.Proto3.ProtobufInput.ValidDataRepeated.ENUM.PackedInput.UnpackedOutput.ProtobufOutput
|
||||||
|
Recommended.Proto3.ProtobufInput.ValidDataRepeated.ENUM.UnpackedInput.UnpackedOutput.ProtobufOutput
|
||||||
|
Recommended.Proto3.ProtobufInput.ValidDataRepeated.FIXED32.PackedInput.UnpackedOutput.ProtobufOutput
|
||||||
|
Recommended.Proto3.ProtobufInput.ValidDataRepeated.FIXED32.UnpackedInput.UnpackedOutput.ProtobufOutput
|
||||||
|
Recommended.Proto3.ProtobufInput.ValidDataRepeated.FIXED64.PackedInput.UnpackedOutput.ProtobufOutput
|
||||||
|
Recommended.Proto3.ProtobufInput.ValidDataRepeated.FIXED64.UnpackedInput.UnpackedOutput.ProtobufOutput
|
||||||
|
Recommended.Proto3.ProtobufInput.ValidDataRepeated.FLOAT.PackedInput.UnpackedOutput.ProtobufOutput
|
||||||
|
Recommended.Proto3.ProtobufInput.ValidDataRepeated.FLOAT.UnpackedInput.UnpackedOutput.ProtobufOutput
|
||||||
|
Recommended.Proto3.ProtobufInput.ValidDataRepeated.INT32.PackedInput.UnpackedOutput.ProtobufOutput
|
||||||
|
Recommended.Proto3.ProtobufInput.ValidDataRepeated.INT32.UnpackedInput.UnpackedOutput.ProtobufOutput
|
||||||
|
Recommended.Proto3.ProtobufInput.ValidDataRepeated.INT64.PackedInput.UnpackedOutput.ProtobufOutput
|
||||||
|
Recommended.Proto3.ProtobufInput.ValidDataRepeated.INT64.UnpackedInput.UnpackedOutput.ProtobufOutput
|
||||||
|
Recommended.Proto3.ProtobufInput.ValidDataRepeated.SFIXED32.PackedInput.UnpackedOutput.ProtobufOutput
|
||||||
|
Recommended.Proto3.ProtobufInput.ValidDataRepeated.SFIXED32.UnpackedInput.UnpackedOutput.ProtobufOutput
|
||||||
|
Recommended.Proto3.ProtobufInput.ValidDataRepeated.SFIXED64.PackedInput.UnpackedOutput.ProtobufOutput
|
||||||
|
Recommended.Proto3.ProtobufInput.ValidDataRepeated.SFIXED64.UnpackedInput.UnpackedOutput.ProtobufOutput
|
||||||
|
Recommended.Proto3.ProtobufInput.ValidDataRepeated.SINT32.PackedInput.UnpackedOutput.ProtobufOutput
|
||||||
|
Recommended.Proto3.ProtobufInput.ValidDataRepeated.SINT32.UnpackedInput.UnpackedOutput.ProtobufOutput
|
||||||
|
Recommended.Proto3.ProtobufInput.ValidDataRepeated.SINT64.PackedInput.UnpackedOutput.ProtobufOutput
|
||||||
|
Recommended.Proto3.ProtobufInput.ValidDataRepeated.SINT64.UnpackedInput.UnpackedOutput.ProtobufOutput
|
||||||
|
Recommended.Proto3.ProtobufInput.ValidDataRepeated.UINT32.PackedInput.UnpackedOutput.ProtobufOutput
|
||||||
|
Recommended.Proto3.ProtobufInput.ValidDataRepeated.UINT32.UnpackedInput.UnpackedOutput.ProtobufOutput
|
||||||
|
Recommended.Proto3.ProtobufInput.ValidDataRepeated.UINT64.PackedInput.UnpackedOutput.ProtobufOutput
|
||||||
|
Recommended.Proto3.ProtobufInput.ValidDataRepeated.UINT64.UnpackedInput.UnpackedOutput.ProtobufOutput
|
||||||
558
conformance/text_format_conformance_suite.cc
Normal file
558
conformance/text_format_conformance_suite.cc
Normal file
@@ -0,0 +1,558 @@
|
|||||||
|
// Protocol Buffers - Google's data interchange format
|
||||||
|
// Copyright 2008 Google Inc. All rights reserved.
|
||||||
|
// https://developers.google.com/protocol-buffers/
|
||||||
|
//
|
||||||
|
// Redistribution and use in source and binary forms, with or without
|
||||||
|
// modification, are permitted provided that the following conditions are
|
||||||
|
// met:
|
||||||
|
//
|
||||||
|
// * Redistributions of source code must retain the above copyright
|
||||||
|
// notice, this list of conditions and the following disclaimer.
|
||||||
|
// * Redistributions in binary form must reproduce the above
|
||||||
|
// copyright notice, this list of conditions and the following disclaimer
|
||||||
|
// in the documentation and/or other materials provided with the
|
||||||
|
// distribution.
|
||||||
|
// * Neither the name of Google Inc. nor the names of its
|
||||||
|
// contributors may be used to endorse or promote products derived from
|
||||||
|
// this software without specific prior written permission.
|
||||||
|
//
|
||||||
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
#include "text_format_conformance_suite.h"
|
||||||
|
|
||||||
|
#include "google/protobuf/any.pb.h"
|
||||||
|
#include "google/protobuf/text_format.h"
|
||||||
|
#include "conformance_test.h"
|
||||||
|
#include "google/protobuf/test_messages_proto2.pb.h"
|
||||||
|
#include "google/protobuf/test_messages_proto3.pb.h"
|
||||||
|
|
||||||
|
namespace proto2_messages = protobuf_test_messages::proto2;
|
||||||
|
|
||||||
|
using conformance::ConformanceRequest;
|
||||||
|
using conformance::ConformanceResponse;
|
||||||
|
using conformance::WireFormat;
|
||||||
|
using google::protobuf::Message;
|
||||||
|
using google::protobuf::TextFormat;
|
||||||
|
using proto2_messages::TestAllTypesProto2;
|
||||||
|
using proto2_messages::UnknownToTestAllTypes;
|
||||||
|
using protobuf_test_messages::proto3::TestAllTypesProto3;
|
||||||
|
using std::string;
|
||||||
|
|
||||||
|
namespace google {
|
||||||
|
namespace protobuf {
|
||||||
|
|
||||||
|
// The number of repetitions to use for performance tests.
|
||||||
|
// Corresponds approx to 500KB wireformat bytes.
|
||||||
|
static const size_t kPerformanceRepeatCount = 50000;
|
||||||
|
|
||||||
|
TextFormatConformanceTestSuite::TextFormatConformanceTestSuite() {
|
||||||
|
SetFailureListFlagName("--text_format_failure_list");
|
||||||
|
}
|
||||||
|
|
||||||
|
bool TextFormatConformanceTestSuite::ParseTextFormatResponse(
|
||||||
|
const ConformanceResponse& response,
|
||||||
|
const ConformanceRequestSetting& setting, Message* test_message) {
|
||||||
|
TextFormat::Parser parser;
|
||||||
|
const ConformanceRequest& request = setting.GetRequest();
|
||||||
|
if (request.print_unknown_fields()) {
|
||||||
|
parser.AllowFieldNumber(true);
|
||||||
|
}
|
||||||
|
if (!parser.ParseFromString(response.text_payload(), test_message)) {
|
||||||
|
GOOGLE_LOG(ERROR) << "INTERNAL ERROR: internal text->protobuf transcode "
|
||||||
|
<< "yielded unparseable proto. Text payload: "
|
||||||
|
<< response.text_payload();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool TextFormatConformanceTestSuite::ParseResponse(
|
||||||
|
const ConformanceResponse& response,
|
||||||
|
const ConformanceRequestSetting& setting, Message* test_message) {
|
||||||
|
const ConformanceRequest& request = setting.GetRequest();
|
||||||
|
WireFormat requested_output = request.requested_output_format();
|
||||||
|
const string& test_name = setting.GetTestName();
|
||||||
|
ConformanceLevel level = setting.GetLevel();
|
||||||
|
|
||||||
|
switch (response.result_case()) {
|
||||||
|
case ConformanceResponse::kProtobufPayload: {
|
||||||
|
if (requested_output != conformance::PROTOBUF) {
|
||||||
|
ReportFailure(test_name, level, request, response,
|
||||||
|
absl::StrCat("Test was asked for ",
|
||||||
|
WireFormatToString(requested_output),
|
||||||
|
" output but provided PROTOBUF instead."));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!test_message->ParseFromString(response.protobuf_payload())) {
|
||||||
|
ReportFailure(test_name, level, request, response,
|
||||||
|
"Protobuf output we received from test was unparseable.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case ConformanceResponse::kTextPayload: {
|
||||||
|
if (requested_output != conformance::TEXT_FORMAT) {
|
||||||
|
ReportFailure(
|
||||||
|
test_name, level, request, response,
|
||||||
|
absl::StrCat("Test was asked for ",
|
||||||
|
WireFormatToString(requested_output),
|
||||||
|
" output but provided TEXT_FORMAT instead."));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!ParseTextFormatResponse(response, setting, test_message)) {
|
||||||
|
ReportFailure(
|
||||||
|
test_name, level, request, response,
|
||||||
|
"TEXT_FORMAT output we received from test was unparseable.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
GOOGLE_LOG(FATAL) << test_name
|
||||||
|
<< ": unknown payload type: " << response.result_case();
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void TextFormatConformanceTestSuite::ExpectParseFailure(const string& test_name,
|
||||||
|
ConformanceLevel level,
|
||||||
|
const string& input) {
|
||||||
|
TestAllTypesProto3 prototype;
|
||||||
|
// We don't expect output, but if the program erroneously accepts the protobuf
|
||||||
|
// we let it send its response as this. We must not leave it unspecified.
|
||||||
|
ConformanceRequestSetting setting(
|
||||||
|
level, conformance::TEXT_FORMAT, conformance::TEXT_FORMAT,
|
||||||
|
conformance::TEXT_FORMAT_TEST, prototype, test_name, input);
|
||||||
|
const ConformanceRequest& request = setting.GetRequest();
|
||||||
|
ConformanceResponse response;
|
||||||
|
string effective_test_name =
|
||||||
|
absl::StrCat(setting.ConformanceLevelToString(level),
|
||||||
|
".Proto3.TextFormatInput.", test_name);
|
||||||
|
|
||||||
|
RunTest(effective_test_name, request, &response);
|
||||||
|
if (response.result_case() == ConformanceResponse::kParseError) {
|
||||||
|
ReportSuccess(effective_test_name);
|
||||||
|
} else if (response.result_case() == ConformanceResponse::kSkipped) {
|
||||||
|
ReportSkip(effective_test_name, request, response);
|
||||||
|
} else {
|
||||||
|
ReportFailure(effective_test_name, level, request, response,
|
||||||
|
"Should have failed to parse, but didn't.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void TextFormatConformanceTestSuite::RunValidTextFormatTest(
|
||||||
|
const string& test_name, ConformanceLevel level, const string& input_text) {
|
||||||
|
TestAllTypesProto3 prototype;
|
||||||
|
RunValidTextFormatTestWithMessage(test_name, level, input_text, prototype);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TextFormatConformanceTestSuite::RunValidTextFormatTestProto2(
|
||||||
|
const string& test_name, ConformanceLevel level, const string& input_text) {
|
||||||
|
TestAllTypesProto2 prototype;
|
||||||
|
RunValidTextFormatTestWithMessage(test_name, level, input_text, prototype);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TextFormatConformanceTestSuite::RunValidTextFormatTestWithExpected(
|
||||||
|
const string& test_name, ConformanceLevel level, const string& input_text,
|
||||||
|
const string& expected_text) {
|
||||||
|
TestAllTypesProto3 prototype;
|
||||||
|
RunValidTextFormatTestWithMessage(test_name, level, input_text, expected_text,
|
||||||
|
prototype);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TextFormatConformanceTestSuite::RunValidTextFormatTestProto2WithExpected(
|
||||||
|
const string& test_name, ConformanceLevel level, const string& input_text,
|
||||||
|
const string& expected_text) {
|
||||||
|
TestAllTypesProto2 prototype;
|
||||||
|
RunValidTextFormatTestWithMessage(test_name, level, input_text, expected_text,
|
||||||
|
prototype);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TextFormatConformanceTestSuite::RunValidTextFormatTestWithMessage(
|
||||||
|
const string& test_name, ConformanceLevel level, const string& input_text,
|
||||||
|
const Message& prototype) {
|
||||||
|
ConformanceRequestSetting setting1(
|
||||||
|
level, conformance::TEXT_FORMAT, conformance::PROTOBUF,
|
||||||
|
conformance::TEXT_FORMAT_TEST, prototype, test_name, input_text);
|
||||||
|
RunValidInputTest(setting1, input_text);
|
||||||
|
ConformanceRequestSetting setting2(
|
||||||
|
level, conformance::TEXT_FORMAT, conformance::TEXT_FORMAT,
|
||||||
|
conformance::TEXT_FORMAT_TEST, prototype, test_name, input_text);
|
||||||
|
RunValidInputTest(setting2, input_text);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TextFormatConformanceTestSuite::RunValidTextFormatTestWithMessage(
|
||||||
|
const string& test_name, ConformanceLevel level, const string& input_text,
|
||||||
|
const string& expected_text, const Message& prototype) {
|
||||||
|
ConformanceRequestSetting setting1(
|
||||||
|
level, conformance::TEXT_FORMAT, conformance::PROTOBUF,
|
||||||
|
conformance::TEXT_FORMAT_TEST, prototype, test_name, input_text);
|
||||||
|
RunValidInputTest(setting1, expected_text);
|
||||||
|
ConformanceRequestSetting setting2(
|
||||||
|
level, conformance::TEXT_FORMAT, conformance::TEXT_FORMAT,
|
||||||
|
conformance::TEXT_FORMAT_TEST, prototype, test_name, input_text);
|
||||||
|
RunValidInputTest(setting2, expected_text);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TextFormatConformanceTestSuite::RunValidUnknownTextFormatTest(
|
||||||
|
const string& test_name, const Message& message) {
|
||||||
|
string serialized_input;
|
||||||
|
message.SerializeToString(&serialized_input);
|
||||||
|
TestAllTypesProto3 prototype;
|
||||||
|
ConformanceRequestSetting setting1(
|
||||||
|
RECOMMENDED, conformance::PROTOBUF, conformance::TEXT_FORMAT,
|
||||||
|
conformance::TEXT_FORMAT_TEST, prototype, test_name + "_Drop",
|
||||||
|
serialized_input);
|
||||||
|
setting1.SetPrototypeMessageForCompare(message);
|
||||||
|
RunValidBinaryInputTest(setting1, "");
|
||||||
|
|
||||||
|
ConformanceRequestSetting setting2(
|
||||||
|
RECOMMENDED, conformance::PROTOBUF, conformance::TEXT_FORMAT,
|
||||||
|
conformance::TEXT_FORMAT_TEST, prototype, test_name + "_Print",
|
||||||
|
serialized_input);
|
||||||
|
setting2.SetPrototypeMessageForCompare(message);
|
||||||
|
setting2.SetPrintUnknownFields(true);
|
||||||
|
RunValidBinaryInputTest(setting2, serialized_input);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TextFormatConformanceTestSuite::RunSuiteImpl() {
|
||||||
|
if (!performance_) {
|
||||||
|
RunValidTextFormatTest("HelloWorld", REQUIRED,
|
||||||
|
"optional_string: 'Hello, World!'");
|
||||||
|
// Integer fields.
|
||||||
|
RunValidTextFormatTest("Int32FieldMaxValue", REQUIRED,
|
||||||
|
"optional_int32: 2147483647");
|
||||||
|
RunValidTextFormatTest("Int32FieldMinValue", REQUIRED,
|
||||||
|
"optional_int32: -2147483648");
|
||||||
|
RunValidTextFormatTest("Uint32FieldMaxValue", REQUIRED,
|
||||||
|
"optional_uint32: 4294967295");
|
||||||
|
RunValidTextFormatTest("Int64FieldMaxValue", REQUIRED,
|
||||||
|
"optional_int64: 9223372036854775807");
|
||||||
|
RunValidTextFormatTest("Int64FieldMinValue", REQUIRED,
|
||||||
|
"optional_int64: -9223372036854775808");
|
||||||
|
RunValidTextFormatTest("Uint64FieldMaxValue", REQUIRED,
|
||||||
|
"optional_uint64: 18446744073709551615");
|
||||||
|
|
||||||
|
// Parsers reject out-of-bound integer values.
|
||||||
|
ExpectParseFailure("Int32FieldTooLarge", REQUIRED,
|
||||||
|
"optional_int32: 2147483648");
|
||||||
|
ExpectParseFailure("Int32FieldTooSmall", REQUIRED,
|
||||||
|
"optional_int32: -2147483649");
|
||||||
|
ExpectParseFailure("Uint32FieldTooLarge", REQUIRED,
|
||||||
|
"optional_uint32: 4294967296");
|
||||||
|
ExpectParseFailure("Int64FieldTooLarge", REQUIRED,
|
||||||
|
"optional_int64: 9223372036854775808");
|
||||||
|
ExpectParseFailure("Int64FieldTooSmall", REQUIRED,
|
||||||
|
"optional_int64: -9223372036854775809");
|
||||||
|
ExpectParseFailure("Uint64FieldTooLarge", REQUIRED,
|
||||||
|
"optional_uint64: 18446744073709551616");
|
||||||
|
|
||||||
|
// Floating point fields
|
||||||
|
RunValidTextFormatTest("FloatField", REQUIRED, "optional_float: 3.192837");
|
||||||
|
RunValidTextFormatTest("FloatFieldWithVeryPreciseNumber", REQUIRED,
|
||||||
|
"optional_float: 3.123456789123456789");
|
||||||
|
RunValidTextFormatTest("FloatFieldMaxValue", REQUIRED,
|
||||||
|
"optional_float: 3.4028235e+38");
|
||||||
|
RunValidTextFormatTest("FloatFieldMinValue", REQUIRED,
|
||||||
|
"optional_float: 1.17549e-38");
|
||||||
|
RunValidTextFormatTest("FloatFieldNaNValue", REQUIRED,
|
||||||
|
"optional_float: NaN");
|
||||||
|
RunValidTextFormatTest("FloatFieldPosInfValue", REQUIRED,
|
||||||
|
"optional_float: inf");
|
||||||
|
RunValidTextFormatTest("FloatFieldNegInfValue", REQUIRED,
|
||||||
|
"optional_float: -inf");
|
||||||
|
RunValidTextFormatTest("FloatFieldWithInt32Max", REQUIRED,
|
||||||
|
"optional_float: 4294967296");
|
||||||
|
RunValidTextFormatTest("FloatFieldLargerThanInt64", REQUIRED,
|
||||||
|
"optional_float: 9223372036854775808");
|
||||||
|
RunValidTextFormatTest("FloatFieldTooLarge", REQUIRED,
|
||||||
|
"optional_float: 3.4028235e+39");
|
||||||
|
RunValidTextFormatTest("FloatFieldTooSmall", REQUIRED,
|
||||||
|
"optional_float: 1.17549e-39");
|
||||||
|
RunValidTextFormatTest("FloatFieldLargerThanUint64", REQUIRED,
|
||||||
|
"optional_float: 18446744073709551616");
|
||||||
|
|
||||||
|
// String literals x {Strings, Bytes}
|
||||||
|
for (const auto& field_type : std::vector<std::string>{"String", "Bytes"}) {
|
||||||
|
const std::string field_name =
|
||||||
|
field_type == "String" ? "optional_string" : "optional_bytes";
|
||||||
|
RunValidTextFormatTest(
|
||||||
|
absl::StrCat("StringLiteralConcat", field_type), REQUIRED,
|
||||||
|
absl::StrCat(field_name, ": 'first' \"second\"\n'third'"));
|
||||||
|
RunValidTextFormatTest(
|
||||||
|
absl::StrCat("StringLiteralBasicEscapes", field_type), REQUIRED,
|
||||||
|
absl::StrCat(field_name, ": '\\a\\b\\f\\n\\r\\t\\v\\?\\\\\\'\\\"'"));
|
||||||
|
RunValidTextFormatTest(
|
||||||
|
absl::StrCat("StringLiteralOctalEscapes", field_type), REQUIRED,
|
||||||
|
absl::StrCat(field_name, ": '\\341\\210\\264'"));
|
||||||
|
RunValidTextFormatTest(
|
||||||
|
absl::StrCat("StringLiteralHexEscapes", field_type), REQUIRED,
|
||||||
|
absl::StrCat(field_name, ": '\\xe1\\x88\\xb4'"));
|
||||||
|
RunValidTextFormatTest(
|
||||||
|
absl::StrCat("StringLiteralShortUnicodeEscape", field_type),
|
||||||
|
RECOMMENDED, absl::StrCat(field_name, ": '\\u1234'"));
|
||||||
|
RunValidTextFormatTest(
|
||||||
|
absl::StrCat("StringLiteralLongUnicodeEscapes", field_type),
|
||||||
|
RECOMMENDED, absl::StrCat(field_name, ": '\\U00001234\\U00010437'"));
|
||||||
|
// String literals don't include line feeds.
|
||||||
|
ExpectParseFailure(
|
||||||
|
absl::StrCat("StringLiteralIncludesLF", field_type), REQUIRED,
|
||||||
|
absl::StrCat(field_name, ": 'first line\nsecond line'"));
|
||||||
|
// Unicode escapes don't include code points that lie beyond the planes
|
||||||
|
// (> 0x10ffff).
|
||||||
|
ExpectParseFailure(
|
||||||
|
absl::StrCat("StringLiteralLongUnicodeEscapeTooLarge", field_type),
|
||||||
|
REQUIRED, absl::StrCat(field_name, ": '\\U00110000'"));
|
||||||
|
// Unicode escapes don't include surrogates.
|
||||||
|
ExpectParseFailure(
|
||||||
|
absl::StrCat("StringLiteralShortUnicodeEscapeSurrogatePair",
|
||||||
|
field_type),
|
||||||
|
RECOMMENDED, absl::StrCat(field_name, ": '\\ud801\\udc37'"));
|
||||||
|
ExpectParseFailure(
|
||||||
|
absl::StrCat("StringLiteralShortUnicodeEscapeSurrogateFirstOnly",
|
||||||
|
field_type),
|
||||||
|
RECOMMENDED, absl::StrCat(field_name, ": '\\ud800'"));
|
||||||
|
ExpectParseFailure(
|
||||||
|
absl::StrCat("StringLiteralShortUnicodeEscapeSurrogateSecondOnly",
|
||||||
|
field_type),
|
||||||
|
RECOMMENDED, absl::StrCat(field_name, ": '\\udc00'"));
|
||||||
|
ExpectParseFailure(
|
||||||
|
absl::StrCat("StringLiteralLongUnicodeEscapeSurrogateFirstOnly",
|
||||||
|
field_type),
|
||||||
|
RECOMMENDED, absl::StrCat(field_name, ": '\\U0000d800'"));
|
||||||
|
ExpectParseFailure(
|
||||||
|
absl::StrCat("StringLiteralLongUnicodeEscapeSurrogateSecondOnly",
|
||||||
|
field_type),
|
||||||
|
RECOMMENDED, absl::StrCat(field_name, ": '\\U0000dc00'"));
|
||||||
|
ExpectParseFailure(
|
||||||
|
absl::StrCat("StringLiteralLongUnicodeEscapeSurrogatePair",
|
||||||
|
field_type),
|
||||||
|
RECOMMENDED, absl::StrCat(field_name, ": '\\U0000d801\\U00000dc37'"));
|
||||||
|
ExpectParseFailure(
|
||||||
|
absl::StrCat("StringLiteralUnicodeEscapeSurrogatePairLongShort",
|
||||||
|
field_type),
|
||||||
|
RECOMMENDED, absl::StrCat(field_name, ": '\\U0000d801\\udc37'"));
|
||||||
|
ExpectParseFailure(
|
||||||
|
absl::StrCat("StringLiteralUnicodeEscapeSurrogatePairShortLong",
|
||||||
|
field_type),
|
||||||
|
RECOMMENDED, absl::StrCat(field_name, ": '\\ud801\\U0000dc37'"));
|
||||||
|
|
||||||
|
// The following method depend on the type of field, as strings have extra
|
||||||
|
// validation.
|
||||||
|
const auto test_method =
|
||||||
|
field_type == "String"
|
||||||
|
? &TextFormatConformanceTestSuite::ExpectParseFailure
|
||||||
|
: &TextFormatConformanceTestSuite::RunValidTextFormatTest;
|
||||||
|
|
||||||
|
// String fields reject invalid UTF-8 byte sequences; bytes fields don't.
|
||||||
|
(this->*test_method)(absl::StrCat(field_type, "FieldBadUTF8Octal"),
|
||||||
|
REQUIRED, absl::StrCat(field_name, ": '\\300'"));
|
||||||
|
(this->*test_method)(absl::StrCat(field_type, "FieldBadUTF8Hex"),
|
||||||
|
REQUIRED, absl::StrCat(field_name, ": '\\xc0'"));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Group fields
|
||||||
|
RunValidTextFormatTestProto2("GroupFieldNoColon", REQUIRED,
|
||||||
|
"Data { group_int32: 1 }");
|
||||||
|
RunValidTextFormatTestProto2("GroupFieldWithColon", REQUIRED,
|
||||||
|
"Data: { group_int32: 1 }");
|
||||||
|
RunValidTextFormatTestProto2("GroupFieldEmpty", REQUIRED, "Data {}");
|
||||||
|
|
||||||
|
// Unknown Fields
|
||||||
|
UnknownToTestAllTypes message;
|
||||||
|
// Unable to print unknown Fixed32/Fixed64 fields as if they are known.
|
||||||
|
// Fixed32/Fixed64 fields are not added in the tests.
|
||||||
|
message.set_optional_int32(123);
|
||||||
|
message.set_optional_string("hello");
|
||||||
|
message.set_optional_bool(true);
|
||||||
|
RunValidUnknownTextFormatTest("ScalarUnknownFields", message);
|
||||||
|
|
||||||
|
message.Clear();
|
||||||
|
message.mutable_nested_message()->set_c(111);
|
||||||
|
RunValidUnknownTextFormatTest("MessageUnknownFields", message);
|
||||||
|
|
||||||
|
message.Clear();
|
||||||
|
message.mutable_optionalgroup()->set_a(321);
|
||||||
|
RunValidUnknownTextFormatTest("GroupUnknownFields", message);
|
||||||
|
|
||||||
|
message.add_repeated_int32(1);
|
||||||
|
message.add_repeated_int32(2);
|
||||||
|
message.add_repeated_int32(3);
|
||||||
|
RunValidUnknownTextFormatTest("RepeatedUnknownFields", message);
|
||||||
|
|
||||||
|
// Any fields
|
||||||
|
RunValidTextFormatTest("AnyField", REQUIRED,
|
||||||
|
R"(
|
||||||
|
optional_any: {
|
||||||
|
[type.googleapis.com/protobuf_test_messages.proto3.TestAllTypesProto3] {
|
||||||
|
optional_int32: 12345
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)");
|
||||||
|
RunValidTextFormatTest("AnyFieldWithRawBytes", REQUIRED,
|
||||||
|
R"(
|
||||||
|
optional_any: {
|
||||||
|
type_url: "type.googleapis.com/protobuf_test_messages.proto3.TestAllTypesProto3"
|
||||||
|
value: "\b\271`"
|
||||||
|
}
|
||||||
|
)");
|
||||||
|
ExpectParseFailure("AnyFieldWithInvalidType", REQUIRED,
|
||||||
|
R"(
|
||||||
|
optional_any: {
|
||||||
|
[type.googleapis.com/unknown] {
|
||||||
|
optional_int32: 12345
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)");
|
||||||
|
|
||||||
|
// Map fields
|
||||||
|
TestAllTypesProto3 prototype;
|
||||||
|
(*prototype.mutable_map_string_string())["c"] = "value";
|
||||||
|
(*prototype.mutable_map_string_string())["b"] = "value";
|
||||||
|
(*prototype.mutable_map_string_string())["a"] = "value";
|
||||||
|
RunValidTextFormatTestWithMessage("AlphabeticallySortedMapStringKeys",
|
||||||
|
REQUIRED,
|
||||||
|
R"(
|
||||||
|
map_string_string {
|
||||||
|
key: "a"
|
||||||
|
value: "value"
|
||||||
|
}
|
||||||
|
map_string_string {
|
||||||
|
key: "b"
|
||||||
|
value: "value"
|
||||||
|
}
|
||||||
|
map_string_string {
|
||||||
|
key: "c"
|
||||||
|
value: "value"
|
||||||
|
}
|
||||||
|
)",
|
||||||
|
prototype);
|
||||||
|
|
||||||
|
prototype.Clear();
|
||||||
|
(*prototype.mutable_map_int32_int32())[3] = 0;
|
||||||
|
(*prototype.mutable_map_int32_int32())[2] = 0;
|
||||||
|
(*prototype.mutable_map_int32_int32())[1] = 0;
|
||||||
|
RunValidTextFormatTestWithMessage("AlphabeticallySortedMapIntKeys",
|
||||||
|
REQUIRED,
|
||||||
|
R"(
|
||||||
|
map_int32_int32 {
|
||||||
|
key: 1
|
||||||
|
value: 0
|
||||||
|
}
|
||||||
|
map_int32_int32 {
|
||||||
|
key: 2
|
||||||
|
value: 0
|
||||||
|
}
|
||||||
|
map_int32_int32 {
|
||||||
|
key: 3
|
||||||
|
value: 0
|
||||||
|
}
|
||||||
|
)",
|
||||||
|
prototype);
|
||||||
|
|
||||||
|
prototype.Clear();
|
||||||
|
(*prototype.mutable_map_bool_bool())[true] = false;
|
||||||
|
(*prototype.mutable_map_bool_bool())[false] = false;
|
||||||
|
RunValidTextFormatTestWithMessage("AlphabeticallySortedMapBoolKeys",
|
||||||
|
REQUIRED,
|
||||||
|
R"(
|
||||||
|
map_bool_bool {
|
||||||
|
key: false
|
||||||
|
value: false
|
||||||
|
}
|
||||||
|
map_bool_bool {
|
||||||
|
key: true
|
||||||
|
value: false
|
||||||
|
}
|
||||||
|
)",
|
||||||
|
prototype);
|
||||||
|
|
||||||
|
prototype.Clear();
|
||||||
|
ConformanceRequestSetting setting_map(
|
||||||
|
REQUIRED, conformance::TEXT_FORMAT, conformance::PROTOBUF,
|
||||||
|
conformance::TEXT_FORMAT_TEST, prototype, "DuplicateMapKey", R"(
|
||||||
|
map_string_nested_message {
|
||||||
|
key: "duplicate"
|
||||||
|
value: { a: 123 }
|
||||||
|
}
|
||||||
|
map_string_nested_message {
|
||||||
|
key: "duplicate"
|
||||||
|
value: { corecursive: {} }
|
||||||
|
}
|
||||||
|
)");
|
||||||
|
// The last-specified value will be retained in a parsed map
|
||||||
|
RunValidInputTest(setting_map, R"(
|
||||||
|
map_string_nested_message {
|
||||||
|
key: "duplicate"
|
||||||
|
value: { corecursive: {} }
|
||||||
|
}
|
||||||
|
)");
|
||||||
|
}
|
||||||
|
// Flag control performance tests to keep them internal and opt-in only
|
||||||
|
if (performance_) {
|
||||||
|
RunTextFormatPerformanceTests();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void TextFormatConformanceTestSuite::RunTextFormatPerformanceTests() {
|
||||||
|
TestTextFormatPerformanceMergeMessageWithRepeatedField("Bool",
|
||||||
|
"repeated_bool: true");
|
||||||
|
TestTextFormatPerformanceMergeMessageWithRepeatedField(
|
||||||
|
"Double", "repeated_double: 123");
|
||||||
|
TestTextFormatPerformanceMergeMessageWithRepeatedField(
|
||||||
|
"Int32", "repeated_uint32: 123");
|
||||||
|
TestTextFormatPerformanceMergeMessageWithRepeatedField(
|
||||||
|
"Int64", "repeated_uint64: 123");
|
||||||
|
TestTextFormatPerformanceMergeMessageWithRepeatedField(
|
||||||
|
"String", R"(repeated_string: "foo")");
|
||||||
|
TestTextFormatPerformanceMergeMessageWithRepeatedField(
|
||||||
|
"Bytes", R"(repeated_bytes: "foo")");
|
||||||
|
}
|
||||||
|
|
||||||
|
// This is currently considered valid input by some languages but not others
|
||||||
|
void TextFormatConformanceTestSuite::
|
||||||
|
TestTextFormatPerformanceMergeMessageWithRepeatedField(
|
||||||
|
const string& test_type_name, const string& message_field) {
|
||||||
|
string recursive_message = "recursive_message { " + message_field + " }";
|
||||||
|
|
||||||
|
string input;
|
||||||
|
for (size_t i = 0; i < kPerformanceRepeatCount; i++) {
|
||||||
|
input.append(recursive_message);
|
||||||
|
}
|
||||||
|
|
||||||
|
string expected = "recursive_message { ";
|
||||||
|
for (size_t i = 0; i < kPerformanceRepeatCount; i++) {
|
||||||
|
expected.append(message_field + " ");
|
||||||
|
}
|
||||||
|
expected.append("}");
|
||||||
|
|
||||||
|
RunValidTextFormatTestProto2WithExpected(
|
||||||
|
"TestTextFormatPerformanceMergeMessageWithRepeatedField" +
|
||||||
|
test_type_name + "Proto2",
|
||||||
|
RECOMMENDED, input, expected);
|
||||||
|
RunValidTextFormatTestWithExpected(
|
||||||
|
"TestTextFormatPerformanceMergeMessageWithRepeatedField" +
|
||||||
|
test_type_name + "Proto3",
|
||||||
|
RECOMMENDED, input, expected);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace protobuf
|
||||||
|
} // namespace google
|
||||||
85
conformance/text_format_conformance_suite.h
Normal file
85
conformance/text_format_conformance_suite.h
Normal file
@@ -0,0 +1,85 @@
|
|||||||
|
// Protocol Buffers - Google's data interchange format
|
||||||
|
// Copyright 2008 Google Inc. All rights reserved.
|
||||||
|
// https://developers.google.com/protocol-buffers/
|
||||||
|
//
|
||||||
|
// Redistribution and use in source and binary forms, with or without
|
||||||
|
// modification, are permitted provided that the following conditions are
|
||||||
|
// met:
|
||||||
|
//
|
||||||
|
// * Redistributions of source code must retain the above copyright
|
||||||
|
// notice, this list of conditions and the following disclaimer.
|
||||||
|
// * Redistributions in binary form must reproduce the above
|
||||||
|
// copyright notice, this list of conditions and the following disclaimer
|
||||||
|
// in the documentation and/or other materials provided with the
|
||||||
|
// distribution.
|
||||||
|
// * Neither the name of Google Inc. nor the names of its
|
||||||
|
// contributors may be used to endorse or promote products derived from
|
||||||
|
// this software without specific prior written permission.
|
||||||
|
//
|
||||||
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
#ifndef TEXT_FORMAT_CONFORMANCE_SUITE_H_
|
||||||
|
#define TEXT_FORMAT_CONFORMANCE_SUITE_H_
|
||||||
|
|
||||||
|
#include "conformance_test.h"
|
||||||
|
|
||||||
|
namespace google {
|
||||||
|
namespace protobuf {
|
||||||
|
|
||||||
|
class TextFormatConformanceTestSuite : public ConformanceTestSuite {
|
||||||
|
public:
|
||||||
|
TextFormatConformanceTestSuite();
|
||||||
|
|
||||||
|
private:
|
||||||
|
void RunSuiteImpl() override;
|
||||||
|
void RunTextFormatPerformanceTests();
|
||||||
|
void RunValidTextFormatTest(const std::string& test_name,
|
||||||
|
ConformanceLevel level, const std::string& input);
|
||||||
|
void RunValidTextFormatTestProto2(const std::string& test_name,
|
||||||
|
ConformanceLevel level,
|
||||||
|
const std::string& input);
|
||||||
|
void RunValidTextFormatTestWithExpected(const std::string& test_name,
|
||||||
|
ConformanceLevel level,
|
||||||
|
const std::string& input,
|
||||||
|
const std::string& expected);
|
||||||
|
void RunValidTextFormatTestProto2WithExpected(const std::string& test_name,
|
||||||
|
ConformanceLevel level,
|
||||||
|
const std::string& input,
|
||||||
|
const std::string& expected);
|
||||||
|
void RunValidTextFormatTestWithMessage(const std::string& test_name,
|
||||||
|
ConformanceLevel level,
|
||||||
|
const std::string& input_text,
|
||||||
|
const Message& prototype);
|
||||||
|
void RunValidTextFormatTestWithMessage(const std::string& test_name,
|
||||||
|
ConformanceLevel level,
|
||||||
|
const std::string& input_text,
|
||||||
|
const std::string& expected_text,
|
||||||
|
const Message& prototype);
|
||||||
|
void RunValidUnknownTextFormatTest(const std::string& test_name,
|
||||||
|
const Message& message);
|
||||||
|
void ExpectParseFailure(const std::string& test_name, ConformanceLevel level,
|
||||||
|
const std::string& input);
|
||||||
|
bool ParseTextFormatResponse(const conformance::ConformanceResponse& response,
|
||||||
|
const ConformanceRequestSetting& setting,
|
||||||
|
Message* test_message);
|
||||||
|
bool ParseResponse(const conformance::ConformanceResponse& response,
|
||||||
|
const ConformanceRequestSetting& setting,
|
||||||
|
Message* test_message) override;
|
||||||
|
void TestTextFormatPerformanceMergeMessageWithRepeatedField(
|
||||||
|
const std::string& test_type_name, const std::string& message_field);
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace protobuf
|
||||||
|
} // namespace google
|
||||||
|
|
||||||
|
#endif // TEXT_FORMAT_CONFORMANCE_SUITE_H_
|
||||||
20
conformance/text_format_failure_list_cpp.txt
Normal file
20
conformance/text_format_failure_list_cpp.txt
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
Recommended.Proto3.TextFormatInput.StringLiteralLongUnicodeEscapeSurrogateFirstOnlyBytes
|
||||||
|
Recommended.Proto3.TextFormatInput.StringLiteralLongUnicodeEscapeSurrogateFirstOnlyString
|
||||||
|
Recommended.Proto3.TextFormatInput.StringLiteralLongUnicodeEscapeSurrogatePairBytes
|
||||||
|
Recommended.Proto3.TextFormatInput.StringLiteralLongUnicodeEscapeSurrogatePairString
|
||||||
|
Recommended.Proto3.TextFormatInput.StringLiteralLongUnicodeEscapeSurrogateSecondOnlyBytes
|
||||||
|
Recommended.Proto3.TextFormatInput.StringLiteralLongUnicodeEscapeSurrogateSecondOnlyString
|
||||||
|
Recommended.Proto3.TextFormatInput.StringLiteralShortUnicodeEscapeSurrogateFirstOnlyBytes
|
||||||
|
Recommended.Proto3.TextFormatInput.StringLiteralShortUnicodeEscapeSurrogateFirstOnlyString
|
||||||
|
Recommended.Proto3.TextFormatInput.StringLiteralShortUnicodeEscapeSurrogatePairBytes
|
||||||
|
Recommended.Proto3.TextFormatInput.StringLiteralShortUnicodeEscapeSurrogatePairString
|
||||||
|
Recommended.Proto3.TextFormatInput.StringLiteralShortUnicodeEscapeSurrogateSecondOnlyBytes
|
||||||
|
Recommended.Proto3.TextFormatInput.StringLiteralShortUnicodeEscapeSurrogateSecondOnlyString
|
||||||
|
Recommended.Proto3.TextFormatInput.StringLiteralUnicodeEscapeSurrogatePairLongShortBytes
|
||||||
|
Recommended.Proto3.TextFormatInput.StringLiteralUnicodeEscapeSurrogatePairLongShortString
|
||||||
|
Recommended.Proto3.TextFormatInput.StringLiteralUnicodeEscapeSurrogatePairShortLongBytes
|
||||||
|
Recommended.Proto3.TextFormatInput.StringLiteralUnicodeEscapeSurrogatePairShortLongString
|
||||||
|
Required.Proto3.TextFormatInput.StringFieldBadUTF8Hex
|
||||||
|
Required.Proto3.TextFormatInput.StringFieldBadUTF8Octal
|
||||||
|
Required.Proto3.TextFormatInput.StringLiteralLongUnicodeEscapeTooLargeBytes
|
||||||
|
Required.Proto3.TextFormatInput.StringLiteralLongUnicodeEscapeTooLargeString
|
||||||
8
conformance/text_format_failure_list_csharp.txt
Normal file
8
conformance/text_format_failure_list_csharp.txt
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
Recommended.Proto3.ProtobufInput.GroupUnknownFields_Drop.TextFormatOutput
|
||||||
|
Recommended.Proto3.ProtobufInput.GroupUnknownFields_Print.TextFormatOutput
|
||||||
|
Recommended.Proto3.ProtobufInput.MessageUnknownFields_Drop.TextFormatOutput
|
||||||
|
Recommended.Proto3.ProtobufInput.MessageUnknownFields_Print.TextFormatOutput
|
||||||
|
Recommended.Proto3.ProtobufInput.RepeatedUnknownFields_Drop.TextFormatOutput
|
||||||
|
Recommended.Proto3.ProtobufInput.RepeatedUnknownFields_Print.TextFormatOutput
|
||||||
|
Recommended.Proto3.ProtobufInput.ScalarUnknownFields_Drop.TextFormatOutput
|
||||||
|
Recommended.Proto3.ProtobufInput.ScalarUnknownFields_Print.TextFormatOutput
|
||||||
9
conformance/text_format_failure_list_java.txt
Normal file
9
conformance/text_format_failure_list_java.txt
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
Recommended.Proto3.ProtobufInput.GroupUnknownFields_Drop.TextFormatOutput
|
||||||
|
Recommended.Proto3.ProtobufInput.MessageUnknownFields_Drop.TextFormatOutput
|
||||||
|
Recommended.Proto3.ProtobufInput.RepeatedUnknownFields_Drop.TextFormatOutput
|
||||||
|
Recommended.Proto3.ProtobufInput.ScalarUnknownFields_Drop.TextFormatOutput
|
||||||
|
Required.Proto3.TextFormatInput.AnyField.ProtobufOutput
|
||||||
|
Required.Proto3.TextFormatInput.AnyField.TextFormatOutput
|
||||||
|
|
||||||
|
Required.Proto3.TextFormatInput.StringFieldBadUTF8Hex
|
||||||
|
Required.Proto3.TextFormatInput.StringFieldBadUTF8Octal
|
||||||
5
conformance/text_format_failure_list_java_lite.txt
Normal file
5
conformance/text_format_failure_list_java_lite.txt
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
# This is the list of conformance tests that are known to fail for the Java
|
||||||
|
# Lite TextFormat implementation right now. These should be fixed.
|
||||||
|
#
|
||||||
|
# By listing them here we can keep tabs on which ones are failing and be sure
|
||||||
|
# that we don't introduce regressions in other tests.
|
||||||
8
conformance/text_format_failure_list_jruby.txt
Normal file
8
conformance/text_format_failure_list_jruby.txt
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
Recommended.Proto3.ProtobufInput.GroupUnknownFields_Drop.TextFormatOutput
|
||||||
|
Recommended.Proto3.ProtobufInput.GroupUnknownFields_Print.TextFormatOutput
|
||||||
|
Recommended.Proto3.ProtobufInput.MessageUnknownFields_Drop.TextFormatOutput
|
||||||
|
Recommended.Proto3.ProtobufInput.MessageUnknownFields_Print.TextFormatOutput
|
||||||
|
Recommended.Proto3.ProtobufInput.RepeatedUnknownFields_Drop.TextFormatOutput
|
||||||
|
Recommended.Proto3.ProtobufInput.RepeatedUnknownFields_Print.TextFormatOutput
|
||||||
|
Recommended.Proto3.ProtobufInput.ScalarUnknownFields_Drop.TextFormatOutput
|
||||||
|
Recommended.Proto3.ProtobufInput.ScalarUnknownFields_Print.TextFormatOutput
|
||||||
8
conformance/text_format_failure_list_php.txt
Normal file
8
conformance/text_format_failure_list_php.txt
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
Recommended.Proto3.ProtobufInput.GroupUnknownFields_Drop.TextFormatOutput
|
||||||
|
Recommended.Proto3.ProtobufInput.GroupUnknownFields_Print.TextFormatOutput
|
||||||
|
Recommended.Proto3.ProtobufInput.MessageUnknownFields_Drop.TextFormatOutput
|
||||||
|
Recommended.Proto3.ProtobufInput.MessageUnknownFields_Print.TextFormatOutput
|
||||||
|
Recommended.Proto3.ProtobufInput.RepeatedUnknownFields_Drop.TextFormatOutput
|
||||||
|
Recommended.Proto3.ProtobufInput.RepeatedUnknownFields_Print.TextFormatOutput
|
||||||
|
Recommended.Proto3.ProtobufInput.ScalarUnknownFields_Drop.TextFormatOutput
|
||||||
|
Recommended.Proto3.ProtobufInput.ScalarUnknownFields_Print.TextFormatOutput
|
||||||
34
conformance/text_format_failure_list_python.txt
Normal file
34
conformance/text_format_failure_list_python.txt
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
# This is the list of text format conformance tests that are known to fail right
|
||||||
|
# now.
|
||||||
|
# TODO: These should be fixed.
|
||||||
|
Required.Proto3.TextFormatInput.FloatFieldMaxValue.ProtobufOutput
|
||||||
|
Required.Proto3.TextFormatInput.FloatFieldMaxValue.TextFormatOutput
|
||||||
|
|
||||||
|
Recommended.Proto3.TextFormatInput.StringLiteralLongUnicodeEscapeSurrogateFirstOnlyBytes
|
||||||
|
Recommended.Proto3.TextFormatInput.StringLiteralLongUnicodeEscapeSurrogateFirstOnlyString
|
||||||
|
Recommended.Proto3.TextFormatInput.StringLiteralLongUnicodeEscapeSurrogatePairBytes
|
||||||
|
Recommended.Proto3.TextFormatInput.StringLiteralLongUnicodeEscapeSurrogatePairString
|
||||||
|
Recommended.Proto3.TextFormatInput.StringLiteralLongUnicodeEscapeSurrogateSecondOnlyBytes
|
||||||
|
Recommended.Proto3.TextFormatInput.StringLiteralLongUnicodeEscapeSurrogateSecondOnlyString
|
||||||
|
Recommended.Proto3.TextFormatInput.StringLiteralLongUnicodeEscapesBytes.ProtobufOutput
|
||||||
|
Recommended.Proto3.TextFormatInput.StringLiteralLongUnicodeEscapesBytes.TextFormatOutput
|
||||||
|
Recommended.Proto3.TextFormatInput.StringLiteralLongUnicodeEscapesString.ProtobufOutput
|
||||||
|
Recommended.Proto3.TextFormatInput.StringLiteralLongUnicodeEscapesString.TextFormatOutput
|
||||||
|
Recommended.Proto3.TextFormatInput.StringLiteralShortUnicodeEscapeBytes.ProtobufOutput
|
||||||
|
Recommended.Proto3.TextFormatInput.StringLiteralShortUnicodeEscapeBytes.TextFormatOutput
|
||||||
|
Recommended.Proto3.TextFormatInput.StringLiteralShortUnicodeEscapeString.ProtobufOutput
|
||||||
|
Recommended.Proto3.TextFormatInput.StringLiteralShortUnicodeEscapeString.TextFormatOutput
|
||||||
|
Recommended.Proto3.TextFormatInput.StringLiteralShortUnicodeEscapeSurrogateFirstOnlyBytes
|
||||||
|
Recommended.Proto3.TextFormatInput.StringLiteralShortUnicodeEscapeSurrogateFirstOnlyString
|
||||||
|
Recommended.Proto3.TextFormatInput.StringLiteralShortUnicodeEscapeSurrogatePairBytes
|
||||||
|
Recommended.Proto3.TextFormatInput.StringLiteralShortUnicodeEscapeSurrogatePairString
|
||||||
|
Recommended.Proto3.TextFormatInput.StringLiteralShortUnicodeEscapeSurrogateSecondOnlyBytes
|
||||||
|
Recommended.Proto3.TextFormatInput.StringLiteralShortUnicodeEscapeSurrogateSecondOnlyString
|
||||||
|
Recommended.Proto3.TextFormatInput.StringLiteralUnicodeEscapeSurrogatePairLongShortBytes
|
||||||
|
Recommended.Proto3.TextFormatInput.StringLiteralUnicodeEscapeSurrogatePairLongShortString
|
||||||
|
Recommended.Proto3.TextFormatInput.StringLiteralUnicodeEscapeSurrogatePairShortLongBytes
|
||||||
|
Recommended.Proto3.TextFormatInput.StringLiteralUnicodeEscapeSurrogatePairShortLongString
|
||||||
|
Required.Proto3.TextFormatInput.StringLiteralBasicEscapesBytes.ProtobufOutput
|
||||||
|
Required.Proto3.TextFormatInput.StringLiteralBasicEscapesBytes.TextFormatOutput
|
||||||
|
Required.Proto3.TextFormatInput.StringLiteralBasicEscapesString.ProtobufOutput
|
||||||
|
Required.Proto3.TextFormatInput.StringLiteralBasicEscapesString.TextFormatOutput
|
||||||
28
conformance/text_format_failure_list_python_cpp.txt
Normal file
28
conformance/text_format_failure_list_python_cpp.txt
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
Recommended.Proto3.TextFormatInput.StringLiteralLongUnicodeEscapeSurrogateFirstOnlyBytes
|
||||||
|
Recommended.Proto3.TextFormatInput.StringLiteralLongUnicodeEscapeSurrogateFirstOnlyString
|
||||||
|
Recommended.Proto3.TextFormatInput.StringLiteralLongUnicodeEscapeSurrogatePairBytes
|
||||||
|
Recommended.Proto3.TextFormatInput.StringLiteralLongUnicodeEscapeSurrogatePairString
|
||||||
|
Recommended.Proto3.TextFormatInput.StringLiteralLongUnicodeEscapeSurrogateSecondOnlyBytes
|
||||||
|
Recommended.Proto3.TextFormatInput.StringLiteralLongUnicodeEscapeSurrogateSecondOnlyString
|
||||||
|
Recommended.Proto3.TextFormatInput.StringLiteralLongUnicodeEscapesBytes.ProtobufOutput
|
||||||
|
Recommended.Proto3.TextFormatInput.StringLiteralLongUnicodeEscapesBytes.TextFormatOutput
|
||||||
|
Recommended.Proto3.TextFormatInput.StringLiteralLongUnicodeEscapesString.ProtobufOutput
|
||||||
|
Recommended.Proto3.TextFormatInput.StringLiteralLongUnicodeEscapesString.TextFormatOutput
|
||||||
|
Recommended.Proto3.TextFormatInput.StringLiteralShortUnicodeEscapeBytes.ProtobufOutput
|
||||||
|
Recommended.Proto3.TextFormatInput.StringLiteralShortUnicodeEscapeBytes.TextFormatOutput
|
||||||
|
Recommended.Proto3.TextFormatInput.StringLiteralShortUnicodeEscapeString.ProtobufOutput
|
||||||
|
Recommended.Proto3.TextFormatInput.StringLiteralShortUnicodeEscapeString.TextFormatOutput
|
||||||
|
Recommended.Proto3.TextFormatInput.StringLiteralShortUnicodeEscapeSurrogateFirstOnlyBytes
|
||||||
|
Recommended.Proto3.TextFormatInput.StringLiteralShortUnicodeEscapeSurrogateFirstOnlyString
|
||||||
|
Recommended.Proto3.TextFormatInput.StringLiteralShortUnicodeEscapeSurrogatePairBytes
|
||||||
|
Recommended.Proto3.TextFormatInput.StringLiteralShortUnicodeEscapeSurrogatePairString
|
||||||
|
Recommended.Proto3.TextFormatInput.StringLiteralShortUnicodeEscapeSurrogateSecondOnlyBytes
|
||||||
|
Recommended.Proto3.TextFormatInput.StringLiteralShortUnicodeEscapeSurrogateSecondOnlyString
|
||||||
|
Recommended.Proto3.TextFormatInput.StringLiteralUnicodeEscapeSurrogatePairLongShortBytes
|
||||||
|
Recommended.Proto3.TextFormatInput.StringLiteralUnicodeEscapeSurrogatePairLongShortString
|
||||||
|
Recommended.Proto3.TextFormatInput.StringLiteralUnicodeEscapeSurrogatePairShortLongBytes
|
||||||
|
Recommended.Proto3.TextFormatInput.StringLiteralUnicodeEscapeSurrogatePairShortLongString
|
||||||
|
Required.Proto3.TextFormatInput.StringLiteralBasicEscapesBytes.ProtobufOutput
|
||||||
|
Required.Proto3.TextFormatInput.StringLiteralBasicEscapesBytes.TextFormatOutput
|
||||||
|
Required.Proto3.TextFormatInput.StringLiteralBasicEscapesString.ProtobufOutput
|
||||||
|
Required.Proto3.TextFormatInput.StringLiteralBasicEscapesString.TextFormatOutput
|
||||||
8
conformance/text_format_failure_list_ruby.txt
Normal file
8
conformance/text_format_failure_list_ruby.txt
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
Recommended.Proto3.ProtobufInput.GroupUnknownFields_Drop.TextFormatOutput
|
||||||
|
Recommended.Proto3.ProtobufInput.GroupUnknownFields_Print.TextFormatOutput
|
||||||
|
Recommended.Proto3.ProtobufInput.MessageUnknownFields_Drop.TextFormatOutput
|
||||||
|
Recommended.Proto3.ProtobufInput.MessageUnknownFields_Print.TextFormatOutput
|
||||||
|
Recommended.Proto3.ProtobufInput.RepeatedUnknownFields_Drop.TextFormatOutput
|
||||||
|
Recommended.Proto3.ProtobufInput.RepeatedUnknownFields_Print.TextFormatOutput
|
||||||
|
Recommended.Proto3.ProtobufInput.ScalarUnknownFields_Drop.TextFormatOutput
|
||||||
|
Recommended.Proto3.ProtobufInput.ScalarUnknownFields_Print.TextFormatOutput
|
||||||
73
conformance/update_failure_list.py
Executable file
73
conformance/update_failure_list.py
Executable file
@@ -0,0 +1,73 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
# 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.
|
||||||
|
|
||||||
|
"""Script to update a failure list file to add/remove failures.
|
||||||
|
|
||||||
|
This is sort of like comm(1), except it recognizes comments and ignores them.
|
||||||
|
"""
|
||||||
|
|
||||||
|
import argparse
|
||||||
|
|
||||||
|
parser = argparse.ArgumentParser(
|
||||||
|
description='Adds/removes failures from the failure list.')
|
||||||
|
parser.add_argument('filename', type=str, help='failure list file to update')
|
||||||
|
parser.add_argument('--add', dest='add_list', action='append')
|
||||||
|
parser.add_argument('--remove', dest='remove_list', action='append')
|
||||||
|
|
||||||
|
args = parser.parse_args()
|
||||||
|
|
||||||
|
add_set = set()
|
||||||
|
remove_set = set()
|
||||||
|
|
||||||
|
for add_file in (args.add_list or []):
|
||||||
|
with open(add_file) as f:
|
||||||
|
for line in f:
|
||||||
|
add_set.add(line)
|
||||||
|
|
||||||
|
for remove_file in (args.remove_list or []):
|
||||||
|
with open(remove_file) as f:
|
||||||
|
for line in f:
|
||||||
|
if line in add_set:
|
||||||
|
raise Exception("Asked to both add and remove test: " + line)
|
||||||
|
remove_set.add(line.strip())
|
||||||
|
|
||||||
|
add_list = sorted(add_set, reverse=True)
|
||||||
|
|
||||||
|
with open(args.filename) as in_file:
|
||||||
|
existing_list = in_file.read()
|
||||||
|
|
||||||
|
with open(args.filename, "w") as f:
|
||||||
|
for line in existing_list.splitlines(True):
|
||||||
|
test = line.split("#")[0].strip()
|
||||||
|
while len(add_list) > 0 and test > add_list[-1]:
|
||||||
|
f.write(add_list.pop())
|
||||||
|
if test not in remove_set:
|
||||||
|
f.write(line)
|
||||||
20
csharp/.editorconfig
Normal file
20
csharp/.editorconfig
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
# Remove the line below if you want to inherit .editorconfig settings from higher directories
|
||||||
|
root = true
|
||||||
|
|
||||||
|
# C# files
|
||||||
|
[*.cs]
|
||||||
|
|
||||||
|
#### Core EditorConfig Options ####
|
||||||
|
|
||||||
|
# Indentation and spacing
|
||||||
|
indent_size = 4
|
||||||
|
indent_style = space
|
||||||
|
tab_width = 4
|
||||||
|
|
||||||
|
# New line preferences
|
||||||
|
end_of_line = lf
|
||||||
|
insert_final_newline = false
|
||||||
|
trim_trailing_whitespace = true
|
||||||
|
|
||||||
|
[*.cs]
|
||||||
|
csharp_space_after_cast = true
|
||||||
35
csharp/.gitignore
vendored
Normal file
35
csharp/.gitignore
vendored
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
# Output
|
||||||
|
bin
|
||||||
|
obj
|
||||||
|
project.lock.json
|
||||||
|
TestResult.xml
|
||||||
|
|
||||||
|
# Possibly legacy now?
|
||||||
|
mono/bin
|
||||||
|
mono/tmp
|
||||||
|
mono/protoc
|
||||||
|
build_output
|
||||||
|
build_temp
|
||||||
|
build/msbuild*.log
|
||||||
|
lib/Microsoft.Silverlight.Testing
|
||||||
|
lib/NUnit
|
||||||
|
|
||||||
|
#
|
||||||
|
# Untracked files
|
||||||
|
#
|
||||||
|
.vs
|
||||||
|
.cr
|
||||||
|
*.user
|
||||||
|
*.suo
|
||||||
|
*.nupkg
|
||||||
|
_ReSharper.*
|
||||||
|
*.sln.cache
|
||||||
|
mono/TestResult.xml
|
||||||
|
mono/.libs
|
||||||
|
mono/*.exe
|
||||||
|
mono/*.dll
|
||||||
|
lib/protoc.exe
|
||||||
|
*.ncrunch*
|
||||||
|
|
||||||
|
# Benchmark output
|
||||||
|
BenchmarkDotNet.Artifacts/
|
||||||
112
csharp/BUILD.bazel
Normal file
112
csharp/BUILD.bazel
Normal file
@@ -0,0 +1,112 @@
|
|||||||
|
# Protobuf C# runtime
|
||||||
|
#
|
||||||
|
# See also code generation logic under /src/google/protobuf/compiler/csharp.
|
||||||
|
|
||||||
|
load("@rules_pkg//:mappings.bzl", "pkg_files", "strip_prefix")
|
||||||
|
load("//:protobuf.bzl", "internal_csharp_proto_library")
|
||||||
|
load("//build_defs:internal_shell.bzl", "inline_sh_test")
|
||||||
|
load("//conformance:defs.bzl", "conformance_test")
|
||||||
|
|
||||||
|
################################################################################
|
||||||
|
# Tests
|
||||||
|
################################################################################
|
||||||
|
|
||||||
|
conformance_test(
|
||||||
|
name = "conformance_test",
|
||||||
|
failure_list = "//conformance:failure_list_csharp.txt",
|
||||||
|
testee = "//conformance:conformance_csharp",
|
||||||
|
text_format_failure_list = "//conformance:text_format_failure_list_csharp.txt",
|
||||||
|
)
|
||||||
|
|
||||||
|
################################################################################
|
||||||
|
# CSharp Runtime
|
||||||
|
################################################################################
|
||||||
|
|
||||||
|
filegroup(
|
||||||
|
name = "srcs",
|
||||||
|
srcs = glob([
|
||||||
|
"keys/*",
|
||||||
|
"protos/*",
|
||||||
|
"src/**/*.cs*", # .cs and .csproj
|
||||||
|
], exclude = [
|
||||||
|
# Exclude generated files.
|
||||||
|
"src/*/obj/**/*"
|
||||||
|
]) + [
|
||||||
|
"src/Directory.Build.props",
|
||||||
|
"src/Google.Protobuf.Test/testprotos.pb",
|
||||||
|
"src/Google.Protobuf.sln",
|
||||||
|
],
|
||||||
|
visibility = [
|
||||||
|
"//csharp:__subpackages__",
|
||||||
|
"//conformance:__subpackages__"
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
|
filegroup(
|
||||||
|
name = "wkt_cs_srcs",
|
||||||
|
srcs = [
|
||||||
|
"src/Google.Protobuf/Reflection/Descriptor.cs",
|
||||||
|
"src/Google.Protobuf/WellKnownTypes/Any.cs",
|
||||||
|
"src/Google.Protobuf/WellKnownTypes/Api.cs",
|
||||||
|
"src/Google.Protobuf/WellKnownTypes/Duration.cs",
|
||||||
|
"src/Google.Protobuf/WellKnownTypes/Empty.cs",
|
||||||
|
"src/Google.Protobuf/WellKnownTypes/FieldMask.cs",
|
||||||
|
"src/Google.Protobuf/WellKnownTypes/SourceContext.cs",
|
||||||
|
"src/Google.Protobuf/WellKnownTypes/Struct.cs",
|
||||||
|
"src/Google.Protobuf/WellKnownTypes/Timestamp.cs",
|
||||||
|
"src/Google.Protobuf/WellKnownTypes/Type.cs",
|
||||||
|
"src/Google.Protobuf/WellKnownTypes/Wrappers.cs",
|
||||||
|
],
|
||||||
|
visibility = ["//src/google/protobuf/compiler/csharp:__pkg__"],
|
||||||
|
)
|
||||||
|
|
||||||
|
inline_sh_test(
|
||||||
|
name = "tests",
|
||||||
|
srcs = [
|
||||||
|
":srcs",
|
||||||
|
"src/Google.Protobuf.sln",
|
||||||
|
"//csharp/src/Google.Protobuf.Conformance:srcs",
|
||||||
|
],
|
||||||
|
cmd = """
|
||||||
|
pushd `dirname $(location src/Google.Protobuf.sln)`/..
|
||||||
|
dotnet restore src/Google.Protobuf.sln
|
||||||
|
dotnet build -c Release src/Google.Protobuf.sln
|
||||||
|
dotnet test -c Release -f netcoreapp3.1 src/Google.Protobuf.Test/Google.Protobuf.Test.csproj
|
||||||
|
popd
|
||||||
|
""",
|
||||||
|
)
|
||||||
|
|
||||||
|
################################################################################
|
||||||
|
# Distribution files
|
||||||
|
################################################################################
|
||||||
|
|
||||||
|
pkg_files(
|
||||||
|
name = "dist_files",
|
||||||
|
srcs = [
|
||||||
|
":srcs",
|
||||||
|
".editorconfig",
|
||||||
|
".gitignore",
|
||||||
|
"BUILD.bazel",
|
||||||
|
"CHANGES.txt",
|
||||||
|
"Google.Protobuf.Tools.nuspec",
|
||||||
|
"Google.Protobuf.Tools.targets",
|
||||||
|
"NuGet.Config",
|
||||||
|
"README.md",
|
||||||
|
"build_packages.bat",
|
||||||
|
"build_release.sh",
|
||||||
|
"build_tools.sh",
|
||||||
|
"buildall.bat",
|
||||||
|
"buildall.sh",
|
||||||
|
"generate_protos.sh",
|
||||||
|
"install_dotnet_sdk.ps1",
|
||||||
|
"//csharp/src/Google.Protobuf.Conformance:dist_files",
|
||||||
|
],
|
||||||
|
strip_prefix = strip_prefix.from_root(""),
|
||||||
|
visibility = ["//pkg:__pkg__"],
|
||||||
|
)
|
||||||
|
|
||||||
|
sh_binary(
|
||||||
|
name = "release",
|
||||||
|
srcs = ["build_release.sh"],
|
||||||
|
args = ["$(location build_release.sh)"],
|
||||||
|
)
|
||||||
148
csharp/CHANGES.txt
Normal file
148
csharp/CHANGES.txt
Normal file
@@ -0,0 +1,148 @@
|
|||||||
|
===============================================================================
|
||||||
|
Welcome to the C# port of Google Protocol Buffers, written by Jon Skeet
|
||||||
|
(skeet@pobox.com) based on the work of many talented people.
|
||||||
|
|
||||||
|
===============================================================================
|
||||||
|
RELEASE NOTES - Code imported into Google's main protobuf repository
|
||||||
|
===============================================================================
|
||||||
|
|
||||||
|
Everything below note this represents history of protobuf-csharp-port project
|
||||||
|
before the code was merged into csharp/ subtree of GitHub google/protobuf
|
||||||
|
repository.
|
||||||
|
Frozen legacy version of the original project is available in
|
||||||
|
https://github.com/jskeet/protobuf-csharp-port.
|
||||||
|
|
||||||
|
===============================================================================
|
||||||
|
RELEASE NOTES - Version 2.4.1.555
|
||||||
|
===============================================================================
|
||||||
|
|
||||||
|
Changes:
|
||||||
|
- Upgrade solution format to Visual Studio 2012.
|
||||||
|
- Add the ability to print a builder (not just a message)
|
||||||
|
- TextGenerator introduces a new overload of PrintTo
|
||||||
|
- Munge protoc's error format into a VS-C#-compatible output format.
|
||||||
|
- Work to make ProtoGen clone that acts as a protoc.exe plugin.
|
||||||
|
- Added the AllowPartiallyTrustedCallers attribute
|
||||||
|
- Optimized enum parsing.
|
||||||
|
|
||||||
|
Fixes:
|
||||||
|
- Fix for bug in limited input stream's Position, Introduced Position on
|
||||||
|
output stream
|
||||||
|
- Fix for writing a character to a JSON output overflows allocated buffer
|
||||||
|
- Optimize FromBase64String to return Empty when presented with empty string.
|
||||||
|
- Use string.Concat instead of operator to avoid potential import problems
|
||||||
|
- Issue 81: quoting for NUnit parameters.
|
||||||
|
- Issue 56: NuGet package is noisy
|
||||||
|
- Issue 70: Portable library project has some invalid Nunit-based code.
|
||||||
|
- Issue 71: CodedInputStream.ReadBytes go to slow path unnecessarily
|
||||||
|
- Issue 84: warning CS0219: The variable `size' is assigned but never used
|
||||||
|
|
||||||
|
===============================================================================
|
||||||
|
RELEASE NOTES - Version 2.4.1.521
|
||||||
|
===============================================================================
|
||||||
|
|
||||||
|
Changes:
|
||||||
|
- Add generated_code_attributes option, defaulted to false
|
||||||
|
- Added support for Portable library
|
||||||
|
- Added 'Unsafe' static type in ByteString to allow direct buffer access
|
||||||
|
|
||||||
|
Fixes:
|
||||||
|
- Issue 50: The XML serializer will fail to deserialize a message with empty
|
||||||
|
child message
|
||||||
|
- Issue 45: Use of 'item' as a field name causes AmbiguousMatchException
|
||||||
|
- Issue 49: Generated nested static Types class should be partial
|
||||||
|
- Issue 38: Disable CLSCompliant warnings (3021)
|
||||||
|
- Issue 40: proto_path does not work for command-line file names
|
||||||
|
- Issue 54: should retire all bytes in buffer (bufferSize)
|
||||||
|
- Issue 43: Fix to correct identical 'umbrella_classname' options from trying
|
||||||
|
to write to the same filename.
|
||||||
|
|
||||||
|
===============================================================================
|
||||||
|
RELEASE NOTES - Version 2.4.1.473
|
||||||
|
===============================================================================
|
||||||
|
|
||||||
|
Features:
|
||||||
|
- Added option service_generator_type to control service generation with
|
||||||
|
NONE, GENERIC, INTERFACE, or IRPCDISPATCH
|
||||||
|
- Added interfaces IRpcDispatch and IRpcServerStub to provide for blocking
|
||||||
|
services and implementations.
|
||||||
|
- Added ProtoGen.exe command-line argument "--protoc_dir=" to specify the
|
||||||
|
location of protoc.exe.
|
||||||
|
- Extracted interfaces for ICodedInputStream and ICodedOutputStream to allow
|
||||||
|
custom implementation of writers with both speed and size optimizations.
|
||||||
|
- Addition of the "Google.ProtoBuffers.Serialization" assembly to support
|
||||||
|
reading and writing messages to/from XML, JSON, IDictionary<,> and others.
|
||||||
|
- Several performance related fixes and tweeks
|
||||||
|
- Issue 3: Add option to mark generated code with attribute
|
||||||
|
- Issue 20: Support for decorating classes [Serializable]
|
||||||
|
- Issue 21: Decorate fields with [deprecated=true] as [System.Obsolete]
|
||||||
|
- Issue 22: Reusable Builder classes
|
||||||
|
- Issue 24: Support for using Json/Xml formats with ICodedInputStream
|
||||||
|
- Issue 25: Added support for NuGet packages
|
||||||
|
- Issue 31: Upgraded protoc.exe and descriptor to 2.4.1
|
||||||
|
|
||||||
|
Fixes:
|
||||||
|
- Issue 13: Message with Field same name as message causes uncompilable .cs
|
||||||
|
- Issue 16: Does not integrate well with other tooling
|
||||||
|
- Issue 19: Support for negative enum values
|
||||||
|
- Issue 26: AddRange in GeneratedBuilder iterates twice.
|
||||||
|
- Issue 27: Remove XML documentation output from test projects to clear
|
||||||
|
warnings/errors.
|
||||||
|
- Issue 28: Circular message dependencies result in null default values for
|
||||||
|
Message fields.
|
||||||
|
- Issue 29: Message classes generated have a public default constructor. You
|
||||||
|
can disable private ctor generation with the option generate_private_ctor.
|
||||||
|
- Issue 35: Fixed a bug in ProtoGen handling of arguments with trailing \
|
||||||
|
- Big-endian support for float, and double on Silverlight
|
||||||
|
- Packed and Unpacked parsing allow for all repeated, as per version 2.3
|
||||||
|
- Fix for leaving Builder a public ctor on internal classes for use with
|
||||||
|
generic "where T: new()" constraints.
|
||||||
|
|
||||||
|
Other:
|
||||||
|
- Changed the code signing key to a privately held key
|
||||||
|
- Reformatted all code and line-endings to C# defaults
|
||||||
|
- Reworking of performance benchmarks to produce reliable results, option /v2
|
||||||
|
- Issue 34: Silverlight assemblies are now unit tested
|
||||||
|
|
||||||
|
===============================================================================
|
||||||
|
RELEASE NOTES - Version 2.3.0.277
|
||||||
|
===============================================================================
|
||||||
|
|
||||||
|
Features:
|
||||||
|
- Added cls_compliance option to generate attributes indicating
|
||||||
|
non-CLS-compliance.
|
||||||
|
- Added file_extension option to control the generated output file's extension.
|
||||||
|
- Added umbrella_namespace option to place the umbrella class into a nested
|
||||||
|
namespace to address issues with proto files having the same name as a
|
||||||
|
message it contains.
|
||||||
|
- Added output_directory option to set the output path for the source file(s).
|
||||||
|
- Added ignore_google_protobuf option to avoid generating code for includes
|
||||||
|
from the google.protobuf package.
|
||||||
|
- Added the LITE framework (Google.ProtoBuffersLite.dll) and the ability to
|
||||||
|
generate code with "option optimize_for = LITE_RUNTIME;".
|
||||||
|
- Added ability to invoke protoc.exe from within ProtoGen.exe.
|
||||||
|
- Upgraded to protoc.exe (2.3) compiler.
|
||||||
|
|
||||||
|
Fixes:
|
||||||
|
- Issue 9: Class cannot be static and sealed error
|
||||||
|
- Issue 12: default value for enumerate fields must be filled out
|
||||||
|
|
||||||
|
Other:
|
||||||
|
- Rewrite of build using MSbuild instead of NAnt
|
||||||
|
- Moved to NUnit Version 2.2.8.0
|
||||||
|
- Changed to using secure .snk for releases
|
||||||
|
|
||||||
|
===============================================================================
|
||||||
|
RELEASE NOTES - Version 0.9.1
|
||||||
|
===============================================================================
|
||||||
|
|
||||||
|
Fixes:
|
||||||
|
- issue 10: Incorrect encoding of packed fields when serialized
|
||||||
|
|
||||||
|
===============================================================================
|
||||||
|
RELEASE NOTES - Version 0.9.0
|
||||||
|
===============================================================================
|
||||||
|
|
||||||
|
- Initial release
|
||||||
|
|
||||||
|
===============================================================================
|
||||||
38
csharp/Google.Protobuf.Tools.nuspec
Normal file
38
csharp/Google.Protobuf.Tools.nuspec
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<package>
|
||||||
|
<metadata>
|
||||||
|
<id>Google.Protobuf.Tools</id>
|
||||||
|
<title>Google Protocol Buffers tools</title>
|
||||||
|
<summary>Tools for Protocol Buffers - Google's data interchange format.</summary>
|
||||||
|
<description>See project site for more info.</description>
|
||||||
|
<version>3.21.8</version>
|
||||||
|
<authors>Google Inc.</authors>
|
||||||
|
<owners>protobuf-packages</owners>
|
||||||
|
<licenseUrl>https://github.com/protocolbuffers/protobuf/blob/main/LICENSE</licenseUrl>
|
||||||
|
<projectUrl>https://github.com/protocolbuffers/protobuf</projectUrl>
|
||||||
|
<requireLicenseAcceptance>false</requireLicenseAcceptance>
|
||||||
|
<releaseNotes>Tools for Protocol Buffers</releaseNotes>
|
||||||
|
<copyright>Copyright 2015, Google Inc.</copyright>
|
||||||
|
<tags>Protocol Buffers Binary Serialization Format Google proto proto3</tags>
|
||||||
|
</metadata>
|
||||||
|
<files>
|
||||||
|
<file src="protoc\windows_x86\protoc.exe" target="tools\windows_x86\protoc.exe"/>
|
||||||
|
<file src="protoc\windows_x64\protoc.exe" target="tools\windows_x64\protoc.exe"/>
|
||||||
|
<file src="protoc\linux_x86\protoc" target="tools\linux_x86\protoc"/>
|
||||||
|
<file src="protoc\linux_x64\protoc" target="tools\linux_x64\protoc"/>
|
||||||
|
<file src="protoc\macosx_x64\protoc" target="tools\macosx_x64\protoc"/>
|
||||||
|
<file src="..\src\google\protobuf\any.proto" target="tools\google\protobuf"/>
|
||||||
|
<file src="..\src\google\protobuf\api.proto" target="tools\google\protobuf"/>
|
||||||
|
<file src="..\src\google\protobuf\descriptor.proto" target="tools\google\protobuf"/>
|
||||||
|
<file src="..\src\google\protobuf\duration.proto" target="tools\google\protobuf"/>
|
||||||
|
<file src="..\src\google\protobuf\empty.proto" target="tools\google\protobuf"/>
|
||||||
|
<file src="..\src\google\protobuf\field_mask.proto" target="tools\google\protobuf"/>
|
||||||
|
<file src="..\src\google\protobuf\source_context.proto" target="tools\google\protobuf"/>
|
||||||
|
<file src="..\src\google\protobuf\struct.proto" target="tools\google\protobuf"/>
|
||||||
|
<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>
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user