Merge pull request #6 from grpc/master

Sync with grpc
pull/22032/head
Zhanghui Mao 5 years ago committed by GitHub
commit 9177d84da3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 2
      .github/ISSUE_TEMPLATE/bug_report.md
  2. 2
      .github/ISSUE_TEMPLATE/cleanup_request.md
  3. 2
      .github/ISSUE_TEMPLATE/feature_request.md
  4. 2
      .github/pull_request_template.md
  5. 7
      BUILD
  6. 10
      BUILD.gn
  7. 215
      CMakeLists.txt
  8. 286
      Makefile
  9. 68
      build.yaml
  10. 4
      config.m4
  11. 4
      config.w32
  12. 286
      doc/xds-test-descriptions.md
  13. 1
      gRPC-C++.podspec
  14. 6
      gRPC-Core.podspec
  15. 6
      grpc.gemspec
  16. 18
      grpc.gyp
  17. 7
      include/grpc/impl/codegen/port_platform.h
  18. 8
      include/grpc/impl/codegen/sync.h
  19. 36
      include/grpc/impl/codegen/sync_abseil.h
  20. 3
      include/grpc/module.modulemap
  21. 26
      include/grpc/support/sync_abseil.h
  22. 133
      include/grpcpp/generic/generic_stub_impl.h
  23. 37
      include/grpcpp/impl/codegen/completion_queue_impl.h
  24. 5
      include/grpcpp/server_impl.h
  25. 6
      package.xml
  26. 64
      src/core/ext/transport/inproc/inproc_transport.cc
  27. 114
      src/core/lib/gpr/sync_abseil.cc
  28. 13
      src/core/lib/gpr/sync_posix.cc
  29. 6
      src/core/lib/gpr/sync_windows.cc
  30. 94
      src/core/lib/json/json.cc
  31. 82
      src/core/lib/json/json.h
  32. 328
      src/core/lib/json/json_reader.cc
  33. 825
      src/core/lib/json/json_reader_new.cc
  34. 212
      src/core/lib/json/json_writer.cc
  35. 336
      src/core/lib/json/json_writer_new.cc
  36. 2
      src/core/lib/security/credentials/alts/check_gcp_environment.cc
  37. 106
      src/cpp/client/generic_stub.cc
  38. 6
      src/cpp/common/completion_queue_cc.cc
  39. 15
      src/cpp/server/server_builder.cc
  40. 12
      src/cpp/server/server_cc.cc
  41. 4
      src/python/grpcio/grpc_core_dependencies.py
  42. 2
      src/python/grpcio_tests/tests_aio/unit/metadata_test.py
  43. 2
      templates/tools/dockerfile/python_deps.include
  44. 4
      templates/tools/dockerfile/test/sanity/Dockerfile.template
  45. 15
      test/core/end2end/fuzzers/BUILD
  46. 1206
      test/core/end2end/fuzzers/api_fuzzer.cc
  47. 27
      test/core/end2end/fuzzers/api_fuzzer.dictionary
  48. BIN
      test/core/end2end/fuzzers/api_fuzzer_corpus/00.bin
  49. BIN
      test/core/end2end/fuzzers/api_fuzzer_corpus/001ea98069c10f808c281da9bbdd84cc05c3bad1
  50. BIN
      test/core/end2end/fuzzers/api_fuzzer_corpus/0077816beb340a2ef87cc57c18e0ce0d1e6e23fc
  51. BIN
      test/core/end2end/fuzzers/api_fuzzer_corpus/008d276f01f9371a5956cccf2eeeadb790728a84
  52. BIN
      test/core/end2end/fuzzers/api_fuzzer_corpus/00a1b8e686014202baacdc052a38d392dff11432
  53. BIN
      test/core/end2end/fuzzers/api_fuzzer_corpus/00ba96baafa4595f2d41c2fcf0a27f4e9be5c44d
  54. BIN
      test/core/end2end/fuzzers/api_fuzzer_corpus/00c7c2cc7f90842e766645310e4a439e7b188473
  55. BIN
      test/core/end2end/fuzzers/api_fuzzer_corpus/00f89898cb8f3e3c20e7be1d8c7a1544fb81ea5e
  56. 1
      test/core/end2end/fuzzers/api_fuzzer_corpus/01.bin
  57. BIN
      test/core/end2end/fuzzers/api_fuzzer_corpus/0159f564d91869bc07239f5551a493c2845a4524
  58. BIN
      test/core/end2end/fuzzers/api_fuzzer_corpus/0163bae995fe67a902eabf9f2644726d4767184c
  59. BIN
      test/core/end2end/fuzzers/api_fuzzer_corpus/0170e921ff5d052b228a26529116ea47fe9d3f0b
  60. BIN
      test/core/end2end/fuzzers/api_fuzzer_corpus/0173fb5c52d97d0d63266a529bf2f6442894b0c6
  61. BIN
      test/core/end2end/fuzzers/api_fuzzer_corpus/01a344a0256386cc8abb8dcb65cb55e1244f7f97
  62. BIN
      test/core/end2end/fuzzers/api_fuzzer_corpus/01c59f0a030fa11c4af1b7c0cc85846e9ef3f6b9
  63. BIN
      test/core/end2end/fuzzers/api_fuzzer_corpus/01f52e31dfffdab89d83acd39925c3dd81baa76f
  64. 1
      test/core/end2end/fuzzers/api_fuzzer_corpus/02.bin
  65. BIN
      test/core/end2end/fuzzers/api_fuzzer_corpus/020d06c319b6e511021d21316ba283bca9b40dc9
  66. BIN
      test/core/end2end/fuzzers/api_fuzzer_corpus/0211f960c2da343c3cde6406e650d73278e01e47
  67. BIN
      test/core/end2end/fuzzers/api_fuzzer_corpus/0236f28708dcc2e044d67ecf93539ce6c33a727a
  68. BIN
      test/core/end2end/fuzzers/api_fuzzer_corpus/0242a9f4d4fafc96ee9ed762b610e3c68d6efdec
  69. BIN
      test/core/end2end/fuzzers/api_fuzzer_corpus/02434dcdaca96b9eacee76eb351e99f015eaa05e
  70. BIN
      test/core/end2end/fuzzers/api_fuzzer_corpus/02c3cf8d52fbc43f89b5f516a17cea23b68fc8d5
  71. 1
      test/core/end2end/fuzzers/api_fuzzer_corpus/03.bin
  72. BIN
      test/core/end2end/fuzzers/api_fuzzer_corpus/0302b90625ac9f61f45b45d043fda23b5472d711
  73. BIN
      test/core/end2end/fuzzers/api_fuzzer_corpus/032744b59cafd3320cc932ad39926a9bc92f589e
  74. BIN
      test/core/end2end/fuzzers/api_fuzzer_corpus/0385c7b41263419e25a4342fbfc44fbd65eb2ed5
  75. BIN
      test/core/end2end/fuzzers/api_fuzzer_corpus/039c25bc070936901fc95f63ce9cc3058158fb6d
  76. BIN
      test/core/end2end/fuzzers/api_fuzzer_corpus/03eb66a763e065772bbb09e9a55baf081814ff25
  77. 1
      test/core/end2end/fuzzers/api_fuzzer_corpus/04.bin
  78. BIN
      test/core/end2end/fuzzers/api_fuzzer_corpus/0433cabb8c28820bda0a6eac35d17d120f1b6865
  79. BIN
      test/core/end2end/fuzzers/api_fuzzer_corpus/0452ea591951af85724608917fda16926dad7451
  80. BIN
      test/core/end2end/fuzzers/api_fuzzer_corpus/0468ab4bf4f7e10b680f43efae4bf9686834d220
  81. BIN
      test/core/end2end/fuzzers/api_fuzzer_corpus/04a5f10d2ebc712cf13c05b5ed0fafb31b42737c
  82. BIN
      test/core/end2end/fuzzers/api_fuzzer_corpus/04d93c9df413717f71abd091592b5238afb799e8
  83. BIN
      test/core/end2end/fuzzers/api_fuzzer_corpus/04e01f399f194434b2b724877df64828e8f52c14
  84. 1
      test/core/end2end/fuzzers/api_fuzzer_corpus/05.bin
  85. BIN
      test/core/end2end/fuzzers/api_fuzzer_corpus/0539bf31b2310091ce30d0123142d63589939105
  86. BIN
      test/core/end2end/fuzzers/api_fuzzer_corpus/053b47093c2145d00b8d53ea58b80afcc876109b
  87. BIN
      test/core/end2end/fuzzers/api_fuzzer_corpus/0542a0e5aeb1658cc965724bfced56770569263b
  88. BIN
      test/core/end2end/fuzzers/api_fuzzer_corpus/056e56878b249c7fd0b95576b352ab2f4d46582e
  89. BIN
      test/core/end2end/fuzzers/api_fuzzer_corpus/0598f8881c26b7e9562cdc4c3f86749dd49598d6
  90. BIN
      test/core/end2end/fuzzers/api_fuzzer_corpus/05dee1c3847f2bca29bd14ed701ce64999b298b2
  91. 1
      test/core/end2end/fuzzers/api_fuzzer_corpus/06.bin
  92. BIN
      test/core/end2end/fuzzers/api_fuzzer_corpus/064d3beeef29a647deb1b345426ea7212de71cfe
  93. BIN
      test/core/end2end/fuzzers/api_fuzzer_corpus/064d50aee4416ccf32f4e4fe7b770b7802265ffe
  94. BIN
      test/core/end2end/fuzzers/api_fuzzer_corpus/066e7fcb68e83b432c414f63f6de73e5f5099e49
  95. BIN
      test/core/end2end/fuzzers/api_fuzzer_corpus/067298a97640cc5e212647864d21bc1fa6bb7e75
  96. BIN
      test/core/end2end/fuzzers/api_fuzzer_corpus/06a298ad14533924c9fcb2df0d462c44a206f64b
  97. BIN
      test/core/end2end/fuzzers/api_fuzzer_corpus/06b63ac01c261518e291461fb4707cb29d74e9c5
  98. BIN
      test/core/end2end/fuzzers/api_fuzzer_corpus/06c714e289673cf982ce2ac0670707a15f2ac5ea
  99. BIN
      test/core/end2end/fuzzers/api_fuzzer_corpus/06d20c59bcbeb0deff39619455a713691191bccd
  100. BIN
      test/core/end2end/fuzzers/api_fuzzer_corpus/06eced19ea6819d7b0855c62da49a193b50067ab
  101. Some files were not shown because too many files have changed in this diff Show More

@ -2,7 +2,7 @@
name: Report a bug
about: Create a report to help us improve
labels: kind/bug, priority/P2
assignees: donnadionne
assignees: markdroth
---

@ -2,7 +2,7 @@
name: Request a cleanup
about: Suggest a cleanup in our repository
labels: kind/internal cleanup, priority/P2
assignees: donnadionne
assignees: markdroth
---

@ -2,7 +2,7 @@
name: Request a feature
about: Suggest an idea for this project
labels: kind/enhancement, priority/P2
assignees: donnadionne
assignees: markdroth
---

@ -8,4 +8,4 @@ If you know who should review your pull request, please remove the mentioning be
-->
@donnadionne
@markdroth

@ -98,6 +98,7 @@ GPR_PUBLIC_HDRS = [
"include/grpc/support/port_platform.h",
"include/grpc/support/string_util.h",
"include/grpc/support/sync.h",
"include/grpc/support/sync_abseil.h",
"include/grpc/support/sync_custom.h",
"include/grpc/support/sync_generic.h",
"include/grpc/support/sync_posix.h",
@ -134,7 +135,6 @@ GRPCXX_SRCS = [
"src/cpp/client/create_channel_internal.cc",
"src/cpp/client/create_channel_posix.cc",
"src/cpp/client/credentials_cc.cc",
"src/cpp/client/generic_stub.cc",
"src/cpp/common/alarm.cc",
"src/cpp/common/channel_arguments.cc",
"src/cpp/common/channel_filter.cc",
@ -510,6 +510,7 @@ grpc_cc_library(
"src/core/lib/gpr/string_util_windows.cc",
"src/core/lib/gpr/string_windows.cc",
"src/core/lib/gpr/sync.cc",
"src/core/lib/gpr/sync_abseil.cc",
"src/core/lib/gpr/sync_posix.cc",
"src/core/lib/gpr/sync_windows.cc",
"src/core/lib/gpr/time.cc",
@ -588,6 +589,7 @@ grpc_cc_library(
"include/grpc/impl/codegen/log.h",
"include/grpc/impl/codegen/port_platform.h",
"include/grpc/impl/codegen/sync.h",
"include/grpc/impl/codegen/sync_abseil.h",
"include/grpc/impl/codegen/sync_custom.h",
"include/grpc/impl/codegen/sync_generic.h",
"include/grpc/impl/codegen/sync_posix.h",
@ -804,11 +806,8 @@ grpc_cc_library(
"src/core/lib/iomgr/wakeup_fd_pipe.cc",
"src/core/lib/iomgr/wakeup_fd_posix.cc",
"src/core/lib/iomgr/work_serializer.cc",
"src/core/lib/json/json.cc",
"src/core/lib/json/json_reader.cc",
"src/core/lib/json/json_reader_new.cc",
"src/core/lib/json/json_writer.cc",
"src/core/lib/json/json_writer_new.cc",
"src/core/lib/slice/b64.cc",
"src/core/lib/slice/percent_encoding.cc",
"src/core/lib/slice/slice.cc",

@ -66,6 +66,7 @@ config("grpc_config") {
"include/grpc/impl/codegen/log.h",
"include/grpc/impl/codegen/port_platform.h",
"include/grpc/impl/codegen/sync.h",
"include/grpc/impl/codegen/sync_abseil.h",
"include/grpc/impl/codegen/sync_custom.h",
"include/grpc/impl/codegen/sync_generic.h",
"include/grpc/impl/codegen/sync_posix.h",
@ -81,6 +82,7 @@ config("grpc_config") {
"include/grpc/support/port_platform.h",
"include/grpc/support/string_util.h",
"include/grpc/support/sync.h",
"include/grpc/support/sync_abseil.h",
"include/grpc/support/sync_custom.h",
"include/grpc/support/sync_generic.h",
"include/grpc/support/sync_posix.h",
@ -114,6 +116,7 @@ config("grpc_config") {
"src/core/lib/gpr/string_windows.cc",
"src/core/lib/gpr/string_windows.h",
"src/core/lib/gpr/sync.cc",
"src/core/lib/gpr/sync_abseil.cc",
"src/core/lib/gpr/sync_posix.cc",
"src/core/lib/gpr/sync_windows.cc",
"src/core/lib/gpr/time.cc",
@ -199,6 +202,7 @@ config("grpc_config") {
"include/grpc/impl/codegen/slice.h",
"include/grpc/impl/codegen/status.h",
"include/grpc/impl/codegen/sync.h",
"include/grpc/impl/codegen/sync_abseil.h",
"include/grpc/impl/codegen/sync_custom.h",
"include/grpc/impl/codegen/sync_generic.h",
"include/grpc/impl/codegen/sync_posix.h",
@ -715,12 +719,9 @@ config("grpc_config") {
"src/core/lib/iomgr/wakeup_fd_posix.h",
"src/core/lib/iomgr/work_serializer.cc",
"src/core/lib/iomgr/work_serializer.h",
"src/core/lib/json/json.cc",
"src/core/lib/json/json.h",
"src/core/lib/json/json_reader.cc",
"src/core/lib/json/json_reader_new.cc",
"src/core/lib/json/json_writer.cc",
"src/core/lib/json/json_writer_new.cc",
"src/core/lib/security/context/security_context.cc",
"src/core/lib/security/context/security_context.h",
"src/core/lib/security/credentials/alts/alts_credentials.cc",
@ -1054,6 +1055,7 @@ config("grpc_config") {
"include/grpc/impl/codegen/slice.h",
"include/grpc/impl/codegen/status.h",
"include/grpc/impl/codegen/sync.h",
"include/grpc/impl/codegen/sync_abseil.h",
"include/grpc/impl/codegen/sync_custom.h",
"include/grpc/impl/codegen/sync_generic.h",
"include/grpc/impl/codegen/sync_posix.h",
@ -1073,6 +1075,7 @@ config("grpc_config") {
"include/grpc/support/port_platform.h",
"include/grpc/support/string_util.h",
"include/grpc/support/sync.h",
"include/grpc/support/sync_abseil.h",
"include/grpc/support/sync_custom.h",
"include/grpc/support/sync_generic.h",
"include/grpc/support/sync_posix.h",
@ -1399,7 +1402,6 @@ config("grpc_config") {
"src/cpp/client/create_channel_internal.h",
"src/cpp/client/create_channel_posix.cc",
"src/cpp/client/credentials_cc.cc",
"src/cpp/client/generic_stub.cc",
"src/cpp/client/insecure_credentials.cc",
"src/cpp/client/secure_credentials.cc",
"src/cpp/client/secure_credentials.h",

@ -526,7 +526,6 @@ if(gRPC_BUILD_TESTS)
add_dependencies(buildtests_c init_test)
add_dependencies(buildtests_c inproc_callback_test)
add_dependencies(buildtests_c invalid_call_argument_test)
add_dependencies(buildtests_c json_test)
add_dependencies(buildtests_c lame_client_test)
add_dependencies(buildtests_c load_file_test)
add_dependencies(buildtests_c message_compress_test)
@ -655,7 +654,6 @@ if(gRPC_BUILD_TESTS)
add_dependencies(buildtests_c h2_uds_nosec_test)
endif()
add_dependencies(buildtests_c alts_credentials_fuzzer_one_entry)
add_dependencies(buildtests_c api_fuzzer_one_entry)
add_dependencies(buildtests_c client_fuzzer_one_entry)
add_dependencies(buildtests_c hpack_parser_fuzzer_test_one_entry)
add_dependencies(buildtests_c http_request_fuzzer_test_one_entry)
@ -826,7 +824,7 @@ if(gRPC_BUILD_TESTS)
if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX)
add_dependencies(buildtests_cxx json_run_localhost)
endif()
add_dependencies(buildtests_cxx json_test_new)
add_dependencies(buildtests_cxx json_test)
add_dependencies(buildtests_cxx message_allocator_end2end_test)
add_dependencies(buildtests_cxx metrics_client)
add_dependencies(buildtests_cxx mock_test)
@ -899,6 +897,12 @@ if(gRPC_BUILD_TESTS)
endif()
add_dependencies(buildtests_cxx xds_bootstrap_test)
add_dependencies(buildtests_cxx xds_end2end_test)
if(_gRPC_PLATFORM_LINUX)
add_dependencies(buildtests_cxx xds_interop_client)
endif()
if(_gRPC_PLATFORM_LINUX)
add_dependencies(buildtests_cxx xds_interop_server)
endif()
add_dependencies(buildtests_cxx bad_streaming_id_bad_client_test)
add_dependencies(buildtests_cxx badreq_bad_client_test)
add_dependencies(buildtests_cxx connection_prefix_bad_client_test)
@ -1124,11 +1128,8 @@ add_library(alts_test_util
src/core/lib/iomgr/wakeup_fd_pipe.cc
src/core/lib/iomgr/wakeup_fd_posix.cc
src/core/lib/iomgr/work_serializer.cc
src/core/lib/json/json.cc
src/core/lib/json/json_reader.cc
src/core/lib/json/json_reader_new.cc
src/core/lib/json/json_writer.cc
src/core/lib/json/json_writer_new.cc
src/core/lib/slice/b64.cc
src/core/lib/slice/percent_encoding.cc
src/core/lib/slice/slice.cc
@ -1285,6 +1286,7 @@ foreach(_hdr
include/grpc/support/port_platform.h
include/grpc/support/string_util.h
include/grpc/support/sync.h
include/grpc/support/sync_abseil.h
include/grpc/support/sync_custom.h
include/grpc/support/sync_generic.h
include/grpc/support/sync_posix.h
@ -1301,6 +1303,7 @@ foreach(_hdr
include/grpc/impl/codegen/log.h
include/grpc/impl/codegen/port_platform.h
include/grpc/impl/codegen/sync.h
include/grpc/impl/codegen/sync_abseil.h
include/grpc/impl/codegen/sync_custom.h
include/grpc/impl/codegen/sync_generic.h
include/grpc/impl/codegen/sync_posix.h
@ -1383,6 +1386,7 @@ add_library(gpr
src/core/lib/gpr/string_util_windows.cc
src/core/lib/gpr/string_windows.cc
src/core/lib/gpr/sync.cc
src/core/lib/gpr/sync_abseil.cc
src/core/lib/gpr/sync_posix.cc
src/core/lib/gpr/sync_windows.cc
src/core/lib/gpr/time.cc
@ -1457,6 +1461,7 @@ foreach(_hdr
include/grpc/support/port_platform.h
include/grpc/support/string_util.h
include/grpc/support/sync.h
include/grpc/support/sync_abseil.h
include/grpc/support/sync_custom.h
include/grpc/support/sync_generic.h
include/grpc/support/sync_posix.h
@ -1473,6 +1478,7 @@ foreach(_hdr
include/grpc/impl/codegen/log.h
include/grpc/impl/codegen/port_platform.h
include/grpc/impl/codegen/sync.h
include/grpc/impl/codegen/sync_abseil.h
include/grpc/impl/codegen/sync_custom.h
include/grpc/impl/codegen/sync_generic.h
include/grpc/impl/codegen/sync_posix.h
@ -1614,11 +1620,8 @@ add_library(grpc
src/core/lib/iomgr/wakeup_fd_pipe.cc
src/core/lib/iomgr/wakeup_fd_posix.cc
src/core/lib/iomgr/work_serializer.cc
src/core/lib/json/json.cc
src/core/lib/json/json_reader.cc
src/core/lib/json/json_reader_new.cc
src/core/lib/json/json_writer.cc
src/core/lib/json/json_writer_new.cc
src/core/lib/slice/b64.cc
src/core/lib/slice/percent_encoding.cc
src/core/lib/slice/slice.cc
@ -1944,6 +1947,7 @@ foreach(_hdr
include/grpc/impl/codegen/log.h
include/grpc/impl/codegen/port_platform.h
include/grpc/impl/codegen/sync.h
include/grpc/impl/codegen/sync_abseil.h
include/grpc/impl/codegen/sync_custom.h
include/grpc/impl/codegen/sync_generic.h
include/grpc/impl/codegen/sync_posix.h
@ -2100,11 +2104,8 @@ add_library(grpc_cronet
src/core/lib/iomgr/wakeup_fd_pipe.cc
src/core/lib/iomgr/wakeup_fd_posix.cc
src/core/lib/iomgr/work_serializer.cc
src/core/lib/json/json.cc
src/core/lib/json/json_reader.cc
src/core/lib/json/json_reader_new.cc
src/core/lib/json/json_writer.cc
src/core/lib/json/json_writer_new.cc
src/core/lib/slice/b64.cc
src/core/lib/slice/percent_encoding.cc
src/core/lib/slice/slice.cc
@ -2357,6 +2358,7 @@ foreach(_hdr
include/grpc/impl/codegen/log.h
include/grpc/impl/codegen/port_platform.h
include/grpc/impl/codegen/sync.h
include/grpc/impl/codegen/sync_abseil.h
include/grpc/impl/codegen/sync_custom.h
include/grpc/impl/codegen/sync_generic.h
include/grpc/impl/codegen/sync_posix.h
@ -2531,11 +2533,8 @@ add_library(grpc_test_util
src/core/lib/iomgr/wakeup_fd_pipe.cc
src/core/lib/iomgr/wakeup_fd_posix.cc
src/core/lib/iomgr/work_serializer.cc
src/core/lib/json/json.cc
src/core/lib/json/json_reader.cc
src/core/lib/json/json_reader_new.cc
src/core/lib/json/json_writer.cc
src/core/lib/json/json_writer_new.cc
src/core/lib/slice/b64.cc
src/core/lib/slice/percent_encoding.cc
src/core/lib/slice/slice.cc
@ -2694,6 +2693,7 @@ foreach(_hdr
include/grpc/support/port_platform.h
include/grpc/support/string_util.h
include/grpc/support/sync.h
include/grpc/support/sync_abseil.h
include/grpc/support/sync_custom.h
include/grpc/support/sync_generic.h
include/grpc/support/sync_posix.h
@ -2710,6 +2710,7 @@ foreach(_hdr
include/grpc/impl/codegen/log.h
include/grpc/impl/codegen/port_platform.h
include/grpc/impl/codegen/sync.h
include/grpc/impl/codegen/sync_abseil.h
include/grpc/impl/codegen/sync_custom.h
include/grpc/impl/codegen/sync_generic.h
include/grpc/impl/codegen/sync_posix.h
@ -2876,11 +2877,8 @@ add_library(grpc_test_util_unsecure
src/core/lib/iomgr/wakeup_fd_pipe.cc
src/core/lib/iomgr/wakeup_fd_posix.cc
src/core/lib/iomgr/work_serializer.cc
src/core/lib/json/json.cc
src/core/lib/json/json_reader.cc
src/core/lib/json/json_reader_new.cc
src/core/lib/json/json_writer.cc
src/core/lib/json/json_writer_new.cc
src/core/lib/slice/b64.cc
src/core/lib/slice/percent_encoding.cc
src/core/lib/slice/slice.cc
@ -3039,6 +3037,7 @@ foreach(_hdr
include/grpc/support/port_platform.h
include/grpc/support/string_util.h
include/grpc/support/sync.h
include/grpc/support/sync_abseil.h
include/grpc/support/sync_custom.h
include/grpc/support/sync_generic.h
include/grpc/support/sync_posix.h
@ -3055,6 +3054,7 @@ foreach(_hdr
include/grpc/impl/codegen/log.h
include/grpc/impl/codegen/port_platform.h
include/grpc/impl/codegen/sync.h
include/grpc/impl/codegen/sync_abseil.h
include/grpc/impl/codegen/sync_custom.h
include/grpc/impl/codegen/sync_generic.h
include/grpc/impl/codegen/sync_posix.h
@ -3197,11 +3197,8 @@ add_library(grpc_unsecure
src/core/lib/iomgr/wakeup_fd_pipe.cc
src/core/lib/iomgr/wakeup_fd_posix.cc
src/core/lib/iomgr/work_serializer.cc
src/core/lib/json/json.cc
src/core/lib/json/json_reader.cc
src/core/lib/json/json_reader_new.cc
src/core/lib/json/json_writer.cc
src/core/lib/json/json_writer_new.cc
src/core/lib/slice/b64.cc
src/core/lib/slice/percent_encoding.cc
src/core/lib/slice/slice.cc
@ -3450,6 +3447,7 @@ foreach(_hdr
include/grpc/impl/codegen/log.h
include/grpc/impl/codegen/port_platform.h
include/grpc/impl/codegen/sync.h
include/grpc/impl/codegen/sync_abseil.h
include/grpc/impl/codegen/sync_custom.h
include/grpc/impl/codegen/sync_generic.h
include/grpc/impl/codegen/sync_posix.h
@ -3696,7 +3694,6 @@ add_library(grpc++
src/cpp/client/create_channel_internal.cc
src/cpp/client/create_channel_posix.cc
src/cpp/client/credentials_cc.cc
src/cpp/client/generic_stub.cc
src/cpp/common/alarm.cc
src/cpp/common/channel_arguments.cc
src/cpp/common/channel_filter.cc
@ -3901,6 +3898,7 @@ foreach(_hdr
include/grpc/support/port_platform.h
include/grpc/support/string_util.h
include/grpc/support/sync.h
include/grpc/support/sync_abseil.h
include/grpc/support/sync_custom.h
include/grpc/support/sync_generic.h
include/grpc/support/sync_posix.h
@ -3917,6 +3915,7 @@ foreach(_hdr
include/grpc/impl/codegen/log.h
include/grpc/impl/codegen/port_platform.h
include/grpc/impl/codegen/sync.h
include/grpc/impl/codegen/sync_abseil.h
include/grpc/impl/codegen/sync_custom.h
include/grpc/impl/codegen/sync_generic.h
include/grpc/impl/codegen/sync_posix.h
@ -4600,6 +4599,7 @@ foreach(_hdr
include/grpc/impl/codegen/log.h
include/grpc/impl/codegen/port_platform.h
include/grpc/impl/codegen/sync.h
include/grpc/impl/codegen/sync_abseil.h
include/grpc/impl/codegen/sync_custom.h
include/grpc/impl/codegen/sync_generic.h
include/grpc/impl/codegen/sync_posix.h
@ -4797,6 +4797,7 @@ foreach(_hdr
include/grpc/impl/codegen/log.h
include/grpc/impl/codegen/port_platform.h
include/grpc/impl/codegen/sync.h
include/grpc/impl/codegen/sync_abseil.h
include/grpc/impl/codegen/sync_custom.h
include/grpc/impl/codegen/sync_generic.h
include/grpc/impl/codegen/sync_posix.h
@ -4830,7 +4831,6 @@ add_library(grpc++_unsecure
src/cpp/client/create_channel_internal.cc
src/cpp/client/create_channel_posix.cc
src/cpp/client/credentials_cc.cc
src/cpp/client/generic_stub.cc
src/cpp/common/alarm.cc
src/cpp/common/channel_arguments.cc
src/cpp/common/channel_filter.cc
@ -5034,6 +5034,7 @@ foreach(_hdr
include/grpc/support/port_platform.h
include/grpc/support/string_util.h
include/grpc/support/sync.h
include/grpc/support/sync_abseil.h
include/grpc/support/sync_custom.h
include/grpc/support/sync_generic.h
include/grpc/support/sync_posix.h
@ -5050,6 +5051,7 @@ foreach(_hdr
include/grpc/impl/codegen/log.h
include/grpc/impl/codegen/port_platform.h
include/grpc/impl/codegen/sync.h
include/grpc/impl/codegen/sync_abseil.h
include/grpc/impl/codegen/sync_custom.h
include/grpc/impl/codegen/sync_generic.h
include/grpc/impl/codegen/sync_posix.h
@ -8550,33 +8552,6 @@ target_link_libraries(invalid_call_argument_test
)
endif()
if(gRPC_BUILD_TESTS)
add_executable(json_test
test/core/json/json_test.cc
)
target_include_directories(json_test
PRIVATE
${CMAKE_CURRENT_SOURCE_DIR}
${CMAKE_CURRENT_SOURCE_DIR}/include
${_gRPC_ADDRESS_SORTING_INCLUDE_DIR}
${_gRPC_SSL_INCLUDE_DIR}
${_gRPC_UPB_GENERATED_DIR}
${_gRPC_UPB_GRPC_GENERATED_DIR}
${_gRPC_UPB_INCLUDE_DIR}
${_gRPC_ZLIB_INCLUDE_DIR}
)
target_link_libraries(json_test
${_gRPC_ALLTARGETS_LIBRARIES}
grpc_test_util
grpc
gpr
)
endif()
if(gRPC_BUILD_TESTS)
@ -14018,13 +13993,13 @@ endif()
endif()
if(gRPC_BUILD_TESTS)
add_executable(json_test_new
test/core/json/json_test_new.cc
add_executable(json_test
test/core/json/json_test.cc
third_party/googletest/googletest/src/gtest-all.cc
third_party/googletest/googlemock/src/gmock-all.cc
)
target_include_directories(json_test_new
target_include_directories(json_test
PRIVATE
${CMAKE_CURRENT_SOURCE_DIR}
${CMAKE_CURRENT_SOURCE_DIR}/include
@ -14041,7 +14016,7 @@ target_include_directories(json_test_new
${_gRPC_PROTO_GENS_DIR}
)
target_link_libraries(json_test_new
target_link_libraries(json_test
${_gRPC_PROTOBUF_LIBRARIES}
${_gRPC_ALLTARGETS_LIBRARIES}
grpc_test_util
@ -16197,6 +16172,110 @@ target_link_libraries(xds_end2end_test
)
endif()
if(gRPC_BUILD_TESTS)
if(_gRPC_PLATFORM_LINUX)
add_executable(xds_interop_client
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/empty.pb.cc
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/empty.grpc.pb.cc
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/empty.pb.h
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/empty.grpc.pb.h
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/messages.pb.cc
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/messages.grpc.pb.cc
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/messages.pb.h
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/messages.grpc.pb.h
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/test.pb.cc
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/test.grpc.pb.cc
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/test.pb.h
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/test.grpc.pb.h
test/cpp/interop/xds_interop_client.cc
third_party/googletest/googletest/src/gtest-all.cc
third_party/googletest/googlemock/src/gmock-all.cc
)
target_include_directories(xds_interop_client
PRIVATE
${CMAKE_CURRENT_SOURCE_DIR}
${CMAKE_CURRENT_SOURCE_DIR}/include
${_gRPC_ADDRESS_SORTING_INCLUDE_DIR}
${_gRPC_SSL_INCLUDE_DIR}
${_gRPC_UPB_GENERATED_DIR}
${_gRPC_UPB_GRPC_GENERATED_DIR}
${_gRPC_UPB_INCLUDE_DIR}
${_gRPC_ZLIB_INCLUDE_DIR}
third_party/googletest/googletest/include
third_party/googletest/googletest
third_party/googletest/googlemock/include
third_party/googletest/googlemock
${_gRPC_PROTO_GENS_DIR}
)
target_link_libraries(xds_interop_client
${_gRPC_PROTOBUF_LIBRARIES}
${_gRPC_ALLTARGETS_LIBRARIES}
grpc++_test_config
grpc_test_util
grpc++
grpc
gpr
${_gRPC_GFLAGS_LIBRARIES}
)
endif()
endif()
if(gRPC_BUILD_TESTS)
if(_gRPC_PLATFORM_LINUX)
add_executable(xds_interop_server
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/empty.pb.cc
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/empty.grpc.pb.cc
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/empty.pb.h
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/empty.grpc.pb.h
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/messages.pb.cc
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/messages.grpc.pb.cc
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/messages.pb.h
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/messages.grpc.pb.h
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/test.pb.cc
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/test.grpc.pb.cc
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/test.pb.h
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/test.grpc.pb.h
test/cpp/interop/xds_interop_server.cc
third_party/googletest/googletest/src/gtest-all.cc
third_party/googletest/googlemock/src/gmock-all.cc
)
target_include_directories(xds_interop_server
PRIVATE
${CMAKE_CURRENT_SOURCE_DIR}
${CMAKE_CURRENT_SOURCE_DIR}/include
${_gRPC_ADDRESS_SORTING_INCLUDE_DIR}
${_gRPC_SSL_INCLUDE_DIR}
${_gRPC_UPB_GENERATED_DIR}
${_gRPC_UPB_GRPC_GENERATED_DIR}
${_gRPC_UPB_INCLUDE_DIR}
${_gRPC_ZLIB_INCLUDE_DIR}
third_party/googletest/googletest/include
third_party/googletest/googletest
third_party/googletest/googlemock/include
third_party/googletest/googlemock
${_gRPC_PROTO_GENS_DIR}
)
target_link_libraries(xds_interop_server
${_gRPC_PROTOBUF_LIBRARIES}
${_gRPC_ALLTARGETS_LIBRARIES}
grpc++_test_config
grpc_test_util
grpc++
grpc
gpr
${_gRPC_GFLAGS_LIBRARIES}
)
endif()
endif()
if(gRPC_BUILD_TESTS)
@ -18097,34 +18176,6 @@ target_link_libraries(alts_credentials_fuzzer_one_entry
)
endif()
if(gRPC_BUILD_TESTS)
add_executable(api_fuzzer_one_entry
test/core/end2end/fuzzers/api_fuzzer.cc
test/core/util/one_corpus_entry_fuzzer.cc
)
target_include_directories(api_fuzzer_one_entry
PRIVATE
${CMAKE_CURRENT_SOURCE_DIR}
${CMAKE_CURRENT_SOURCE_DIR}/include
${_gRPC_ADDRESS_SORTING_INCLUDE_DIR}
${_gRPC_SSL_INCLUDE_DIR}
${_gRPC_UPB_GENERATED_DIR}
${_gRPC_UPB_GRPC_GENERATED_DIR}
${_gRPC_UPB_INCLUDE_DIR}
${_gRPC_ZLIB_INCLUDE_DIR}
)
target_link_libraries(api_fuzzer_one_entry
${_gRPC_ALLTARGETS_LIBRARIES}
grpc_test_util
grpc
gpr
)
endif()
if(gRPC_BUILD_TESTS)

@ -1010,7 +1010,6 @@ algorithm_test: $(BINDIR)/$(CONFIG)/algorithm_test
alloc_test: $(BINDIR)/$(CONFIG)/alloc_test
alpn_test: $(BINDIR)/$(CONFIG)/alpn_test
alts_credentials_fuzzer: $(BINDIR)/$(CONFIG)/alts_credentials_fuzzer
api_fuzzer: $(BINDIR)/$(CONFIG)/api_fuzzer
arena_test: $(BINDIR)/$(CONFIG)/arena_test
avl_test: $(BINDIR)/$(CONFIG)/avl_test
bad_server_response_test: $(BINDIR)/$(CONFIG)/bad_server_response_test
@ -1095,7 +1094,6 @@ init_test: $(BINDIR)/$(CONFIG)/init_test
inproc_callback_test: $(BINDIR)/$(CONFIG)/inproc_callback_test
invalid_call_argument_test: $(BINDIR)/$(CONFIG)/invalid_call_argument_test
json_fuzzer_test: $(BINDIR)/$(CONFIG)/json_fuzzer_test
json_test: $(BINDIR)/$(CONFIG)/json_test
lame_client_test: $(BINDIR)/$(CONFIG)/lame_client_test
load_file_test: $(BINDIR)/$(CONFIG)/load_file_test
low_level_ping_pong_benchmark: $(BINDIR)/$(CONFIG)/low_level_ping_pong_benchmark
@ -1256,7 +1254,7 @@ interop_client: $(BINDIR)/$(CONFIG)/interop_client
interop_server: $(BINDIR)/$(CONFIG)/interop_server
interop_test: $(BINDIR)/$(CONFIG)/interop_test
json_run_localhost: $(BINDIR)/$(CONFIG)/json_run_localhost
json_test_new: $(BINDIR)/$(CONFIG)/json_test_new
json_test: $(BINDIR)/$(CONFIG)/json_test
message_allocator_end2end_test: $(BINDIR)/$(CONFIG)/message_allocator_end2end_test
metrics_client: $(BINDIR)/$(CONFIG)/metrics_client
mock_test: $(BINDIR)/$(CONFIG)/mock_test
@ -1311,6 +1309,8 @@ work_serializer_test: $(BINDIR)/$(CONFIG)/work_serializer_test
writes_per_rpc_test: $(BINDIR)/$(CONFIG)/writes_per_rpc_test
xds_bootstrap_test: $(BINDIR)/$(CONFIG)/xds_bootstrap_test
xds_end2end_test: $(BINDIR)/$(CONFIG)/xds_end2end_test
xds_interop_client: $(BINDIR)/$(CONFIG)/xds_interop_client
xds_interop_server: $(BINDIR)/$(CONFIG)/xds_interop_server
public_headers_must_be_c89: $(BINDIR)/$(CONFIG)/public_headers_must_be_c89
boringssl_ssl_test: $(BINDIR)/$(CONFIG)/boringssl_ssl_test
boringssl_crypto_test: $(BINDIR)/$(CONFIG)/boringssl_crypto_test
@ -1373,7 +1373,6 @@ address_sorting_test_unsecure: $(BINDIR)/$(CONFIG)/address_sorting_test_unsecure
address_sorting_test: $(BINDIR)/$(CONFIG)/address_sorting_test
cancel_ares_query_test: $(BINDIR)/$(CONFIG)/cancel_ares_query_test
alts_credentials_fuzzer_one_entry: $(BINDIR)/$(CONFIG)/alts_credentials_fuzzer_one_entry
api_fuzzer_one_entry: $(BINDIR)/$(CONFIG)/api_fuzzer_one_entry
client_fuzzer_one_entry: $(BINDIR)/$(CONFIG)/client_fuzzer_one_entry
hpack_parser_fuzzer_test_one_entry: $(BINDIR)/$(CONFIG)/hpack_parser_fuzzer_test_one_entry
http_request_fuzzer_test_one_entry: $(BINDIR)/$(CONFIG)/http_request_fuzzer_test_one_entry
@ -1527,7 +1526,6 @@ buildtests_c: privatelibs_c \
$(BINDIR)/$(CONFIG)/init_test \
$(BINDIR)/$(CONFIG)/inproc_callback_test \
$(BINDIR)/$(CONFIG)/invalid_call_argument_test \
$(BINDIR)/$(CONFIG)/json_test \
$(BINDIR)/$(CONFIG)/lame_client_test \
$(BINDIR)/$(CONFIG)/load_file_test \
$(BINDIR)/$(CONFIG)/message_compress_test \
@ -1614,7 +1612,6 @@ buildtests_c: privatelibs_c \
$(BINDIR)/$(CONFIG)/h2_sockpair_1byte_nosec_test \
$(BINDIR)/$(CONFIG)/h2_uds_nosec_test \
$(BINDIR)/$(CONFIG)/alts_credentials_fuzzer_one_entry \
$(BINDIR)/$(CONFIG)/api_fuzzer_one_entry \
$(BINDIR)/$(CONFIG)/client_fuzzer_one_entry \
$(BINDIR)/$(CONFIG)/hpack_parser_fuzzer_test_one_entry \
$(BINDIR)/$(CONFIG)/http_request_fuzzer_test_one_entry \
@ -1727,7 +1724,7 @@ buildtests_cxx: privatelibs_cxx \
$(BINDIR)/$(CONFIG)/interop_server \
$(BINDIR)/$(CONFIG)/interop_test \
$(BINDIR)/$(CONFIG)/json_run_localhost \
$(BINDIR)/$(CONFIG)/json_test_new \
$(BINDIR)/$(CONFIG)/json_test \
$(BINDIR)/$(CONFIG)/message_allocator_end2end_test \
$(BINDIR)/$(CONFIG)/metrics_client \
$(BINDIR)/$(CONFIG)/mock_test \
@ -1782,6 +1779,8 @@ buildtests_cxx: privatelibs_cxx \
$(BINDIR)/$(CONFIG)/writes_per_rpc_test \
$(BINDIR)/$(CONFIG)/xds_bootstrap_test \
$(BINDIR)/$(CONFIG)/xds_end2end_test \
$(BINDIR)/$(CONFIG)/xds_interop_client \
$(BINDIR)/$(CONFIG)/xds_interop_server \
$(BINDIR)/$(CONFIG)/boringssl_ssl_test \
$(BINDIR)/$(CONFIG)/boringssl_crypto_test \
$(BINDIR)/$(CONFIG)/bad_streaming_id_bad_client_test \
@ -1903,7 +1902,7 @@ buildtests_cxx: privatelibs_cxx \
$(BINDIR)/$(CONFIG)/interop_server \
$(BINDIR)/$(CONFIG)/interop_test \
$(BINDIR)/$(CONFIG)/json_run_localhost \
$(BINDIR)/$(CONFIG)/json_test_new \
$(BINDIR)/$(CONFIG)/json_test \
$(BINDIR)/$(CONFIG)/message_allocator_end2end_test \
$(BINDIR)/$(CONFIG)/metrics_client \
$(BINDIR)/$(CONFIG)/mock_test \
@ -1958,6 +1957,8 @@ buildtests_cxx: privatelibs_cxx \
$(BINDIR)/$(CONFIG)/writes_per_rpc_test \
$(BINDIR)/$(CONFIG)/xds_bootstrap_test \
$(BINDIR)/$(CONFIG)/xds_end2end_test \
$(BINDIR)/$(CONFIG)/xds_interop_client \
$(BINDIR)/$(CONFIG)/xds_interop_server \
$(BINDIR)/$(CONFIG)/bad_streaming_id_bad_client_test \
$(BINDIR)/$(CONFIG)/badreq_bad_client_test \
$(BINDIR)/$(CONFIG)/connection_prefix_bad_client_test \
@ -2139,8 +2140,6 @@ test_c: buildtests_c
$(Q) $(BINDIR)/$(CONFIG)/inproc_callback_test || ( echo test inproc_callback_test failed ; exit 1 )
$(E) "[RUN] Testing invalid_call_argument_test"
$(Q) $(BINDIR)/$(CONFIG)/invalid_call_argument_test || ( echo test invalid_call_argument_test failed ; exit 1 )
$(E) "[RUN] Testing json_test"
$(Q) $(BINDIR)/$(CONFIG)/json_test || ( echo test json_test failed ; exit 1 )
$(E) "[RUN] Testing lame_client_test"
$(Q) $(BINDIR)/$(CONFIG)/lame_client_test || ( echo test lame_client_test failed ; exit 1 )
$(E) "[RUN] Testing load_file_test"
@ -2417,8 +2416,8 @@ test_cxx: buildtests_cxx
$(Q) $(BINDIR)/$(CONFIG)/inproc_sync_unary_ping_pong_test || ( echo test inproc_sync_unary_ping_pong_test failed ; exit 1 )
$(E) "[RUN] Testing interop_test"
$(Q) $(BINDIR)/$(CONFIG)/interop_test || ( echo test interop_test failed ; exit 1 )
$(E) "[RUN] Testing json_test_new"
$(Q) $(BINDIR)/$(CONFIG)/json_test_new || ( echo test json_test_new failed ; exit 1 )
$(E) "[RUN] Testing json_test"
$(Q) $(BINDIR)/$(CONFIG)/json_test || ( echo test json_test failed ; exit 1 )
$(E) "[RUN] Testing message_allocator_end2end_test"
$(Q) $(BINDIR)/$(CONFIG)/message_allocator_end2end_test || ( echo test message_allocator_end2end_test failed ; exit 1 )
$(E) "[RUN] Testing mock_test"
@ -3638,11 +3637,8 @@ LIBALTS_TEST_UTIL_SRC = \
src/core/lib/iomgr/wakeup_fd_pipe.cc \
src/core/lib/iomgr/wakeup_fd_posix.cc \
src/core/lib/iomgr/work_serializer.cc \
src/core/lib/json/json.cc \
src/core/lib/json/json_reader.cc \
src/core/lib/json/json_reader_new.cc \
src/core/lib/json/json_writer.cc \
src/core/lib/json/json_writer_new.cc \
src/core/lib/slice/b64.cc \
src/core/lib/slice/percent_encoding.cc \
src/core/lib/slice/slice.cc \
@ -3763,6 +3759,7 @@ PUBLIC_HEADERS_C += \
include/grpc/support/port_platform.h \
include/grpc/support/string_util.h \
include/grpc/support/sync.h \
include/grpc/support/sync_abseil.h \
include/grpc/support/sync_custom.h \
include/grpc/support/sync_generic.h \
include/grpc/support/sync_posix.h \
@ -3779,6 +3776,7 @@ PUBLIC_HEADERS_C += \
include/grpc/impl/codegen/log.h \
include/grpc/impl/codegen/port_platform.h \
include/grpc/impl/codegen/sync.h \
include/grpc/impl/codegen/sync_abseil.h \
include/grpc/impl/codegen/sync_custom.h \
include/grpc/impl/codegen/sync_generic.h \
include/grpc/impl/codegen/sync_posix.h \
@ -3886,6 +3884,7 @@ LIBGPR_SRC = \
src/core/lib/gpr/string_util_windows.cc \
src/core/lib/gpr/string_windows.cc \
src/core/lib/gpr/sync.cc \
src/core/lib/gpr/sync_abseil.cc \
src/core/lib/gpr/sync_posix.cc \
src/core/lib/gpr/sync_windows.cc \
src/core/lib/gpr/time.cc \
@ -3919,6 +3918,7 @@ PUBLIC_HEADERS_C += \
include/grpc/support/port_platform.h \
include/grpc/support/string_util.h \
include/grpc/support/sync.h \
include/grpc/support/sync_abseil.h \
include/grpc/support/sync_custom.h \
include/grpc/support/sync_generic.h \
include/grpc/support/sync_posix.h \
@ -3935,6 +3935,7 @@ PUBLIC_HEADERS_C += \
include/grpc/impl/codegen/log.h \
include/grpc/impl/codegen/port_platform.h \
include/grpc/impl/codegen/sync.h \
include/grpc/impl/codegen/sync_abseil.h \
include/grpc/impl/codegen/sync_custom.h \
include/grpc/impl/codegen/sync_generic.h \
include/grpc/impl/codegen/sync_posix.h \
@ -4096,11 +4097,8 @@ LIBGRPC_SRC = \
src/core/lib/iomgr/wakeup_fd_pipe.cc \
src/core/lib/iomgr/wakeup_fd_posix.cc \
src/core/lib/iomgr/work_serializer.cc \
src/core/lib/json/json.cc \
src/core/lib/json/json_reader.cc \
src/core/lib/json/json_reader_new.cc \
src/core/lib/json/json_writer.cc \
src/core/lib/json/json_writer_new.cc \
src/core/lib/slice/b64.cc \
src/core/lib/slice/percent_encoding.cc \
src/core/lib/slice/slice.cc \
@ -4383,6 +4381,7 @@ PUBLIC_HEADERS_C += \
include/grpc/impl/codegen/log.h \
include/grpc/impl/codegen/port_platform.h \
include/grpc/impl/codegen/sync.h \
include/grpc/impl/codegen/sync_abseil.h \
include/grpc/impl/codegen/sync_custom.h \
include/grpc/impl/codegen/sync_generic.h \
include/grpc/impl/codegen/sync_posix.h \
@ -4574,11 +4573,8 @@ LIBGRPC_CRONET_SRC = \
src/core/lib/iomgr/wakeup_fd_pipe.cc \
src/core/lib/iomgr/wakeup_fd_posix.cc \
src/core/lib/iomgr/work_serializer.cc \
src/core/lib/json/json.cc \
src/core/lib/json/json_reader.cc \
src/core/lib/json/json_reader_new.cc \
src/core/lib/json/json_writer.cc \
src/core/lib/json/json_writer_new.cc \
src/core/lib/slice/b64.cc \
src/core/lib/slice/percent_encoding.cc \
src/core/lib/slice/slice.cc \
@ -4788,6 +4784,7 @@ PUBLIC_HEADERS_C += \
include/grpc/impl/codegen/log.h \
include/grpc/impl/codegen/port_platform.h \
include/grpc/impl/codegen/sync.h \
include/grpc/impl/codegen/sync_abseil.h \
include/grpc/impl/codegen/sync_custom.h \
include/grpc/impl/codegen/sync_generic.h \
include/grpc/impl/codegen/sync_posix.h \
@ -4996,11 +4993,8 @@ LIBGRPC_TEST_UTIL_SRC = \
src/core/lib/iomgr/wakeup_fd_pipe.cc \
src/core/lib/iomgr/wakeup_fd_posix.cc \
src/core/lib/iomgr/work_serializer.cc \
src/core/lib/json/json.cc \
src/core/lib/json/json_reader.cc \
src/core/lib/json/json_reader_new.cc \
src/core/lib/json/json_writer.cc \
src/core/lib/json/json_writer_new.cc \
src/core/lib/slice/b64.cc \
src/core/lib/slice/percent_encoding.cc \
src/core/lib/slice/slice.cc \
@ -5121,6 +5115,7 @@ PUBLIC_HEADERS_C += \
include/grpc/support/port_platform.h \
include/grpc/support/string_util.h \
include/grpc/support/sync.h \
include/grpc/support/sync_abseil.h \
include/grpc/support/sync_custom.h \
include/grpc/support/sync_generic.h \
include/grpc/support/sync_posix.h \
@ -5137,6 +5132,7 @@ PUBLIC_HEADERS_C += \
include/grpc/impl/codegen/log.h \
include/grpc/impl/codegen/port_platform.h \
include/grpc/impl/codegen/sync.h \
include/grpc/impl/codegen/sync_abseil.h \
include/grpc/impl/codegen/sync_custom.h \
include/grpc/impl/codegen/sync_generic.h \
include/grpc/impl/codegen/sync_posix.h \
@ -5327,11 +5323,8 @@ LIBGRPC_TEST_UTIL_UNSECURE_SRC = \
src/core/lib/iomgr/wakeup_fd_pipe.cc \
src/core/lib/iomgr/wakeup_fd_posix.cc \
src/core/lib/iomgr/work_serializer.cc \
src/core/lib/json/json.cc \
src/core/lib/json/json_reader.cc \
src/core/lib/json/json_reader_new.cc \
src/core/lib/json/json_writer.cc \
src/core/lib/json/json_writer_new.cc \
src/core/lib/slice/b64.cc \
src/core/lib/slice/percent_encoding.cc \
src/core/lib/slice/slice.cc \
@ -5452,6 +5445,7 @@ PUBLIC_HEADERS_C += \
include/grpc/support/port_platform.h \
include/grpc/support/string_util.h \
include/grpc/support/sync.h \
include/grpc/support/sync_abseil.h \
include/grpc/support/sync_custom.h \
include/grpc/support/sync_generic.h \
include/grpc/support/sync_posix.h \
@ -5468,6 +5462,7 @@ PUBLIC_HEADERS_C += \
include/grpc/impl/codegen/log.h \
include/grpc/impl/codegen/port_platform.h \
include/grpc/impl/codegen/sync.h \
include/grpc/impl/codegen/sync_abseil.h \
include/grpc/impl/codegen/sync_custom.h \
include/grpc/impl/codegen/sync_generic.h \
include/grpc/impl/codegen/sync_posix.h \
@ -5621,11 +5616,8 @@ LIBGRPC_UNSECURE_SRC = \
src/core/lib/iomgr/wakeup_fd_pipe.cc \
src/core/lib/iomgr/wakeup_fd_posix.cc \
src/core/lib/iomgr/work_serializer.cc \
src/core/lib/json/json.cc \
src/core/lib/json/json_reader.cc \
src/core/lib/json/json_reader_new.cc \
src/core/lib/json/json_writer.cc \
src/core/lib/json/json_writer_new.cc \
src/core/lib/slice/b64.cc \
src/core/lib/slice/percent_encoding.cc \
src/core/lib/slice/slice.cc \
@ -5832,6 +5824,7 @@ PUBLIC_HEADERS_C += \
include/grpc/impl/codegen/log.h \
include/grpc/impl/codegen/port_platform.h \
include/grpc/impl/codegen/sync.h \
include/grpc/impl/codegen/sync_abseil.h \
include/grpc/impl/codegen/sync_custom.h \
include/grpc/impl/codegen/sync_generic.h \
include/grpc/impl/codegen/sync_posix.h \
@ -6084,7 +6077,6 @@ LIBGRPC++_SRC = \
src/cpp/client/create_channel_internal.cc \
src/cpp/client/create_channel_posix.cc \
src/cpp/client/credentials_cc.cc \
src/cpp/client/generic_stub.cc \
src/cpp/common/alarm.cc \
src/cpp/common/channel_arguments.cc \
src/cpp/common/channel_filter.cc \
@ -6250,6 +6242,7 @@ PUBLIC_HEADERS_CXX += \
include/grpc/support/port_platform.h \
include/grpc/support/string_util.h \
include/grpc/support/sync.h \
include/grpc/support/sync_abseil.h \
include/grpc/support/sync_custom.h \
include/grpc/support/sync_generic.h \
include/grpc/support/sync_posix.h \
@ -6266,6 +6259,7 @@ PUBLIC_HEADERS_CXX += \
include/grpc/impl/codegen/log.h \
include/grpc/impl/codegen/port_platform.h \
include/grpc/impl/codegen/sync.h \
include/grpc/impl/codegen/sync_abseil.h \
include/grpc/impl/codegen/sync_custom.h \
include/grpc/impl/codegen/sync_generic.h \
include/grpc/impl/codegen/sync_posix.h \
@ -6939,6 +6933,7 @@ PUBLIC_HEADERS_CXX += \
include/grpc/impl/codegen/log.h \
include/grpc/impl/codegen/port_platform.h \
include/grpc/impl/codegen/sync.h \
include/grpc/impl/codegen/sync_abseil.h \
include/grpc/impl/codegen/sync_custom.h \
include/grpc/impl/codegen/sync_generic.h \
include/grpc/impl/codegen/sync_posix.h \
@ -7119,6 +7114,7 @@ PUBLIC_HEADERS_CXX += \
include/grpc/impl/codegen/log.h \
include/grpc/impl/codegen/port_platform.h \
include/grpc/impl/codegen/sync.h \
include/grpc/impl/codegen/sync_abseil.h \
include/grpc/impl/codegen/sync_custom.h \
include/grpc/impl/codegen/sync_generic.h \
include/grpc/impl/codegen/sync_posix.h \
@ -7192,7 +7188,6 @@ LIBGRPC++_UNSECURE_SRC = \
src/cpp/client/create_channel_internal.cc \
src/cpp/client/create_channel_posix.cc \
src/cpp/client/credentials_cc.cc \
src/cpp/client/generic_stub.cc \
src/cpp/common/alarm.cc \
src/cpp/common/channel_arguments.cc \
src/cpp/common/channel_filter.cc \
@ -7358,6 +7353,7 @@ PUBLIC_HEADERS_CXX += \
include/grpc/support/port_platform.h \
include/grpc/support/string_util.h \
include/grpc/support/sync.h \
include/grpc/support/sync_abseil.h \
include/grpc/support/sync_custom.h \
include/grpc/support/sync_generic.h \
include/grpc/support/sync_posix.h \
@ -7374,6 +7370,7 @@ PUBLIC_HEADERS_CXX += \
include/grpc/impl/codegen/log.h \
include/grpc/impl/codegen/port_platform.h \
include/grpc/impl/codegen/sync.h \
include/grpc/impl/codegen/sync_abseil.h \
include/grpc/impl/codegen/sync_custom.h \
include/grpc/impl/codegen/sync_generic.h \
include/grpc/impl/codegen/sync_posix.h \
@ -9283,38 +9280,6 @@ endif
endif
API_FUZZER_SRC = \
test/core/end2end/fuzzers/api_fuzzer.cc \
API_FUZZER_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(API_FUZZER_SRC))))
ifeq ($(NO_SECURE),true)
# You can't build secure targets if you don't have OpenSSL.
$(BINDIR)/$(CONFIG)/api_fuzzer: openssl_dep_error
else
$(BINDIR)/$(CONFIG)/api_fuzzer: $(API_FUZZER_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a
$(E) "[LD] Linking $@"
$(Q) mkdir -p `dirname $@`
$(Q) $(LDXX) $(LDFLAGS) $(API_FUZZER_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -lFuzzer -o $(BINDIR)/$(CONFIG)/api_fuzzer
endif
$(OBJDIR)/$(CONFIG)/test/core/end2end/fuzzers/api_fuzzer.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a
deps_api_fuzzer: $(API_FUZZER_OBJS:.o=.dep)
ifneq ($(NO_SECURE),true)
ifneq ($(NO_DEPS),true)
-include $(API_FUZZER_OBJS:.o=.dep)
endif
endif
ARENA_TEST_SRC = \
test/core/gpr/arena_test.cc \
@ -12021,38 +11986,6 @@ endif
endif
JSON_TEST_SRC = \
test/core/json/json_test.cc \
JSON_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(JSON_TEST_SRC))))
ifeq ($(NO_SECURE),true)
# You can't build secure targets if you don't have OpenSSL.
$(BINDIR)/$(CONFIG)/json_test: openssl_dep_error
else
$(BINDIR)/$(CONFIG)/json_test: $(JSON_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a
$(E) "[LD] Linking $@"
$(Q) mkdir -p `dirname $@`
$(Q) $(LDXX) $(LDFLAGS) $(JSON_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/json_test
endif
$(OBJDIR)/$(CONFIG)/test/core/json/json_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a
deps_json_test: $(JSON_TEST_OBJS:.o=.dep)
ifneq ($(NO_SECURE),true)
ifneq ($(NO_DEPS),true)
-include $(JSON_TEST_OBJS:.o=.dep)
endif
endif
LAME_CLIENT_TEST_SRC = \
test/core/surface/lame_client_test.cc \
@ -18367,15 +18300,15 @@ endif
endif
JSON_TEST_NEW_SRC = \
test/core/json/json_test_new.cc \
JSON_TEST_SRC = \
test/core/json/json_test.cc \
JSON_TEST_NEW_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(JSON_TEST_NEW_SRC))))
JSON_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(JSON_TEST_SRC))))
ifeq ($(NO_SECURE),true)
# You can't build secure targets if you don't have OpenSSL.
$(BINDIR)/$(CONFIG)/json_test_new: openssl_dep_error
$(BINDIR)/$(CONFIG)/json_test: openssl_dep_error
else
@ -18386,26 +18319,26 @@ ifeq ($(NO_PROTOBUF),true)
# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.5.0+.
$(BINDIR)/$(CONFIG)/json_test_new: protobuf_dep_error
$(BINDIR)/$(CONFIG)/json_test: protobuf_dep_error
else
$(BINDIR)/$(CONFIG)/json_test_new: $(PROTOBUF_DEP) $(JSON_TEST_NEW_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a
$(BINDIR)/$(CONFIG)/json_test: $(PROTOBUF_DEP) $(JSON_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a
$(E) "[LD] Linking $@"
$(Q) mkdir -p `dirname $@`
$(Q) $(LDXX) $(LDFLAGS) $(JSON_TEST_NEW_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/json_test_new
$(Q) $(LDXX) $(LDFLAGS) $(JSON_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/json_test
endif
endif
$(OBJDIR)/$(CONFIG)/test/core/json/json_test_new.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a
$(OBJDIR)/$(CONFIG)/test/core/json/json_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a
deps_json_test_new: $(JSON_TEST_NEW_OBJS:.o=.dep)
deps_json_test: $(JSON_TEST_OBJS:.o=.dep)
ifneq ($(NO_SECURE),true)
ifneq ($(NO_DEPS),true)
-include $(JSON_TEST_NEW_OBJS:.o=.dep)
-include $(JSON_TEST_OBJS:.o=.dep)
endif
endif
@ -20822,6 +20755,112 @@ endif
$(OBJDIR)/$(CONFIG)/test/cpp/end2end/xds_end2end_test.o: $(GENDIR)/src/proto/grpc/testing/xds/ads_for_test.pb.cc $(GENDIR)/src/proto/grpc/testing/xds/ads_for_test.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/xds/cds_for_test.pb.cc $(GENDIR)/src/proto/grpc/testing/xds/cds_for_test.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/xds/eds_for_test.pb.cc $(GENDIR)/src/proto/grpc/testing/xds/eds_for_test.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/xds/lds_rds_for_test.pb.cc $(GENDIR)/src/proto/grpc/testing/xds/lds_rds_for_test.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/xds/lrs_for_test.pb.cc $(GENDIR)/src/proto/grpc/testing/xds/lrs_for_test.grpc.pb.cc
XDS_INTEROP_CLIENT_SRC = \
$(GENDIR)/src/proto/grpc/testing/empty.pb.cc $(GENDIR)/src/proto/grpc/testing/empty.grpc.pb.cc \
$(GENDIR)/src/proto/grpc/testing/messages.pb.cc $(GENDIR)/src/proto/grpc/testing/messages.grpc.pb.cc \
$(GENDIR)/src/proto/grpc/testing/test.pb.cc $(GENDIR)/src/proto/grpc/testing/test.grpc.pb.cc \
test/cpp/interop/xds_interop_client.cc \
XDS_INTEROP_CLIENT_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(XDS_INTEROP_CLIENT_SRC))))
ifeq ($(NO_SECURE),true)
# You can't build secure targets if you don't have OpenSSL.
$(BINDIR)/$(CONFIG)/xds_interop_client: openssl_dep_error
else
ifeq ($(NO_PROTOBUF),true)
# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.5.0+.
$(BINDIR)/$(CONFIG)/xds_interop_client: protobuf_dep_error
else
$(BINDIR)/$(CONFIG)/xds_interop_client: $(PROTOBUF_DEP) $(XDS_INTEROP_CLIENT_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a
$(E) "[LD] Linking $@"
$(Q) mkdir -p `dirname $@`
$(Q) $(LDXX) $(LDFLAGS) $(XDS_INTEROP_CLIENT_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/xds_interop_client
endif
endif
$(OBJDIR)/$(CONFIG)/src/proto/grpc/testing/empty.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a
$(OBJDIR)/$(CONFIG)/src/proto/grpc/testing/messages.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a
$(OBJDIR)/$(CONFIG)/src/proto/grpc/testing/test.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a
$(OBJDIR)/$(CONFIG)/test/cpp/interop/xds_interop_client.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a
deps_xds_interop_client: $(XDS_INTEROP_CLIENT_OBJS:.o=.dep)
ifneq ($(NO_SECURE),true)
ifneq ($(NO_DEPS),true)
-include $(XDS_INTEROP_CLIENT_OBJS:.o=.dep)
endif
endif
$(OBJDIR)/$(CONFIG)/test/cpp/interop/xds_interop_client.o: $(GENDIR)/src/proto/grpc/testing/empty.pb.cc $(GENDIR)/src/proto/grpc/testing/empty.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/messages.pb.cc $(GENDIR)/src/proto/grpc/testing/messages.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/test.pb.cc $(GENDIR)/src/proto/grpc/testing/test.grpc.pb.cc
XDS_INTEROP_SERVER_SRC = \
$(GENDIR)/src/proto/grpc/testing/empty.pb.cc $(GENDIR)/src/proto/grpc/testing/empty.grpc.pb.cc \
$(GENDIR)/src/proto/grpc/testing/messages.pb.cc $(GENDIR)/src/proto/grpc/testing/messages.grpc.pb.cc \
$(GENDIR)/src/proto/grpc/testing/test.pb.cc $(GENDIR)/src/proto/grpc/testing/test.grpc.pb.cc \
test/cpp/interop/xds_interop_server.cc \
XDS_INTEROP_SERVER_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(XDS_INTEROP_SERVER_SRC))))
ifeq ($(NO_SECURE),true)
# You can't build secure targets if you don't have OpenSSL.
$(BINDIR)/$(CONFIG)/xds_interop_server: openssl_dep_error
else
ifeq ($(NO_PROTOBUF),true)
# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.5.0+.
$(BINDIR)/$(CONFIG)/xds_interop_server: protobuf_dep_error
else
$(BINDIR)/$(CONFIG)/xds_interop_server: $(PROTOBUF_DEP) $(XDS_INTEROP_SERVER_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a
$(E) "[LD] Linking $@"
$(Q) mkdir -p `dirname $@`
$(Q) $(LDXX) $(LDFLAGS) $(XDS_INTEROP_SERVER_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/xds_interop_server
endif
endif
$(OBJDIR)/$(CONFIG)/src/proto/grpc/testing/empty.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a
$(OBJDIR)/$(CONFIG)/src/proto/grpc/testing/messages.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a
$(OBJDIR)/$(CONFIG)/src/proto/grpc/testing/test.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a
$(OBJDIR)/$(CONFIG)/test/cpp/interop/xds_interop_server.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a
deps_xds_interop_server: $(XDS_INTEROP_SERVER_OBJS:.o=.dep)
ifneq ($(NO_SECURE),true)
ifneq ($(NO_DEPS),true)
-include $(XDS_INTEROP_SERVER_OBJS:.o=.dep)
endif
endif
$(OBJDIR)/$(CONFIG)/test/cpp/interop/xds_interop_server.o: $(GENDIR)/src/proto/grpc/testing/empty.pb.cc $(GENDIR)/src/proto/grpc/testing/empty.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/messages.pb.cc $(GENDIR)/src/proto/grpc/testing/messages.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/test.pb.cc $(GENDIR)/src/proto/grpc/testing/test.grpc.pb.cc
PUBLIC_HEADERS_MUST_BE_C89_SRC = \
test/core/surface/public_headers_must_be_c89.c \
@ -22929,41 +22968,6 @@ endif
endif
API_FUZZER_ONE_ENTRY_SRC = \
test/core/end2end/fuzzers/api_fuzzer.cc \
test/core/util/one_corpus_entry_fuzzer.cc \
API_FUZZER_ONE_ENTRY_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(API_FUZZER_ONE_ENTRY_SRC))))
ifeq ($(NO_SECURE),true)
# You can't build secure targets if you don't have OpenSSL.
$(BINDIR)/$(CONFIG)/api_fuzzer_one_entry: openssl_dep_error
else
$(BINDIR)/$(CONFIG)/api_fuzzer_one_entry: $(API_FUZZER_ONE_ENTRY_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a
$(E) "[LD] Linking $@"
$(Q) mkdir -p `dirname $@`
$(Q) $(LDXX) $(LDFLAGS) $(API_FUZZER_ONE_ENTRY_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/api_fuzzer_one_entry
endif
$(OBJDIR)/$(CONFIG)/test/core/end2end/fuzzers/api_fuzzer.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a
$(OBJDIR)/$(CONFIG)/test/core/util/one_corpus_entry_fuzzer.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a
deps_api_fuzzer_one_entry: $(API_FUZZER_ONE_ENTRY_OBJS:.o=.dep)
ifneq ($(NO_SECURE),true)
ifneq ($(NO_DEPS),true)
-include $(API_FUZZER_ONE_ENTRY_OBJS:.o=.dep)
endif
endif
CLIENT_FUZZER_ONE_ENTRY_SRC = \
test/core/end2end/fuzzers/client_fuzzer.cc \
test/core/util/one_corpus_entry_fuzzer.cc \

@ -248,6 +248,7 @@ filegroups:
- src/core/lib/gpr/string_util_windows.cc
- src/core/lib/gpr/string_windows.cc
- src/core/lib/gpr/sync.cc
- src/core/lib/gpr/sync_abseil.cc
- src/core/lib/gpr/sync_posix.cc
- src/core/lib/gpr/sync_windows.cc
- src/core/lib/gpr/time.cc
@ -287,6 +288,7 @@ filegroups:
- include/grpc/support/port_platform.h
- include/grpc/support/string_util.h
- include/grpc/support/sync.h
- include/grpc/support/sync_abseil.h
- include/grpc/support/sync_custom.h
- include/grpc/support/sync_generic.h
- include/grpc/support/sync_posix.h
@ -337,6 +339,7 @@ filegroups:
- include/grpc/impl/codegen/log.h
- include/grpc/impl/codegen/port_platform.h
- include/grpc/impl/codegen/sync.h
- include/grpc/impl/codegen/sync_abseil.h
- include/grpc/impl/codegen/sync_custom.h
- include/grpc/impl/codegen/sync_generic.h
- include/grpc/impl/codegen/sync_posix.h
@ -595,7 +598,6 @@ filegroups:
- src/cpp/client/create_channel_internal.cc
- src/cpp/client/create_channel_posix.cc
- src/cpp/client/credentials_cc.cc
- src/cpp/client/generic_stub.cc
- src/cpp/common/alarm.cc
- src/cpp/common/channel_arguments.cc
- src/cpp/common/channel_filter.cc
@ -770,11 +772,8 @@ filegroups:
- src/core/lib/iomgr/wakeup_fd_pipe.cc
- src/core/lib/iomgr/wakeup_fd_posix.cc
- src/core/lib/iomgr/work_serializer.cc
- src/core/lib/json/json.cc
- src/core/lib/json/json_reader.cc
- src/core/lib/json/json_reader_new.cc
- src/core/lib/json/json_writer.cc
- src/core/lib/json/json_writer_new.cc
- src/core/lib/slice/b64.cc
- src/core/lib/slice/percent_encoding.cc
- src/core/lib/slice/slice.cc
@ -2346,19 +2345,6 @@ targets:
corpus_dirs:
- test/core/security/corpus/alts_credentials_corpus
maxlen: 2048
- name: api_fuzzer
build: fuzzer
language: c
src:
- test/core/end2end/fuzzers/api_fuzzer.cc
deps:
- grpc_test_util
- grpc
- gpr
corpus_dirs:
- test/core/end2end/fuzzers/api_fuzzer_corpus
dict: test/core/end2end/fuzzers/api_fuzzer.dictionary
maxlen: 2048
- name: arena_test
cpu_cost: 10
build: test
@ -3302,16 +3288,6 @@ targets:
corpus_dirs:
- test/core/json/corpus
maxlen: 512
- name: json_test
build: test
language: c
src:
- test/core/json/json_test.cc
deps:
- grpc_test_util
- grpc
- gpr
uses_polling: false
- name: lame_client_test
build: test
language: c
@ -5396,12 +5372,12 @@ targets:
- mac
- linux
- posix
- name: json_test_new
- name: json_test
gtest: true
build: test
language: c++
src:
- test/core/json/json_test_new.cc
- test/core/json/json_test.cc
deps:
- grpc_test_util
- grpc
@ -6133,6 +6109,40 @@ targets:
- grpc++
- grpc
- gpr
- name: xds_interop_client
build: test
run: false
language: c++
src:
- src/proto/grpc/testing/empty.proto
- src/proto/grpc/testing/messages.proto
- src/proto/grpc/testing/test.proto
- test/cpp/interop/xds_interop_client.cc
deps:
- grpc++_test_config
- grpc_test_util
- grpc++
- grpc
- gpr
platforms:
- linux
- name: xds_interop_server
build: test
run: false
language: c++
src:
- src/proto/grpc/testing/empty.proto
- src/proto/grpc/testing/messages.proto
- src/proto/grpc/testing/test.proto
- test/cpp/interop/xds_interop_server.cc
deps:
- grpc++_test_config
- grpc_test_util
- grpc++
- grpc
- gpr
platforms:
- linux
- name: public_headers_must_be_c89
build: test
language: c89

@ -230,6 +230,7 @@ if test "$PHP_GRPC" != "no"; then
src/core/lib/gpr/string_util_windows.cc \
src/core/lib/gpr/string_windows.cc \
src/core/lib/gpr/sync.cc \
src/core/lib/gpr/sync_abseil.cc \
src/core/lib/gpr/sync_posix.cc \
src/core/lib/gpr/sync_windows.cc \
src/core/lib/gpr/time.cc \
@ -345,11 +346,8 @@ if test "$PHP_GRPC" != "no"; then
src/core/lib/iomgr/wakeup_fd_pipe.cc \
src/core/lib/iomgr/wakeup_fd_posix.cc \
src/core/lib/iomgr/work_serializer.cc \
src/core/lib/json/json.cc \
src/core/lib/json/json_reader.cc \
src/core/lib/json/json_reader_new.cc \
src/core/lib/json/json_writer.cc \
src/core/lib/json/json_writer_new.cc \
src/core/lib/profiling/basic_timers.cc \
src/core/lib/profiling/stap_timers.cc \
src/core/lib/security/context/security_context.cc \

@ -199,6 +199,7 @@ if (PHP_GRPC != "no") {
"src\\core\\lib\\gpr\\string_util_windows.cc " +
"src\\core\\lib\\gpr\\string_windows.cc " +
"src\\core\\lib\\gpr\\sync.cc " +
"src\\core\\lib\\gpr\\sync_abseil.cc " +
"src\\core\\lib\\gpr\\sync_posix.cc " +
"src\\core\\lib\\gpr\\sync_windows.cc " +
"src\\core\\lib\\gpr\\time.cc " +
@ -314,11 +315,8 @@ if (PHP_GRPC != "no") {
"src\\core\\lib\\iomgr\\wakeup_fd_pipe.cc " +
"src\\core\\lib\\iomgr\\wakeup_fd_posix.cc " +
"src\\core\\lib\\iomgr\\work_serializer.cc " +
"src\\core\\lib\\json\\json.cc " +
"src\\core\\lib\\json\\json_reader.cc " +
"src\\core\\lib\\json\\json_reader_new.cc " +
"src\\core\\lib\\json\\json_writer.cc " +
"src\\core\\lib\\json\\json_writer_new.cc " +
"src\\core\\lib\\profiling\\basic_timers.cc " +
"src\\core\\lib\\profiling\\stap_timers.cc " +
"src\\core\\lib\\security\\context\\security_context.cc " +

@ -0,0 +1,286 @@
# xDS (Load-Balancing) Interop Test Case Descriptions
Client and server use [test.proto](../src/proto/grpc/testing/test.proto).
## Server
The code for the xDS test server can be found at:
[Java](https://github.com/grpc/grpc-java/blob/master/interop-testing/src/main/java/io/grpc/testing/integration/XdsTestServer.java) (other language implementations are in progress).
Server should accept these arguments:
* --port=PORT
* The port the server will run on.
## Client
The base behavior of the xDS test client is to send a constant QPS of unary
messages and record the remote-peer distribution of the responses. Further, the
client must expose an implementation of the `LoadBalancerStatsService` gRPC
service to allow the test driver to validate the load balancing behavior for a
particular test case (see below for more details).
The code for the xDS test client can be at:
[Java](https://github.com/grpc/grpc-java/blob/master/interop-testing/src/main/java/io/grpc/testing/integration/XdsTestClient.java) (other language implementations are in progress).
Clients should accept these arguments:
* --num_channels=CHANNELS
* The number of channels to create to the server.
* --qps=QPS
* The QPS per channel.
* --server=HOSTNAME:PORT
* The server host to connect to. For example, "localhost:8080"
* --stats_port=PORT
* The port for to expose the client's `LoadBalancerStatsService`
implementation.
## Test Driver
Note that, unlike our other interop tests, neither the client nor the server has
any notion of which of the following test scenarios is under test. Instead, a
separate test driver is responsible for configuring the load balancer and the
server backends, running the client, and then querying the client's
`LoadBalancerStatsService` to validate load balancer behavior for each of the
tests described below.
## LoadBalancerStatsService
The service is defined as:
```
message LoadBalancerStatsRequest {
// Request stats for the next num_rpcs sent by client.
int32 num_rpcs = 1;
// If num_rpcs have not completed within timeout_sec, return partial results.
int32 timeout_sec = 2;
}
message LoadBalancerStatsResponse {
// The number of completed RPCs for each peer.
map<string, int32> rpcs_by_peer = 1;
// The number of RPCs that failed to record a remote peer.
int32 num_failures = 2;
}
service LoadBalancerStatsService {
// Gets the backend distribution for RPCs sent by a test client.
rpc GetClientStats(LoadBalancerStatsRequest)
returns (LoadBalancerStatsResponse) {}
}
```
Note that the `LoadBalancerStatsResponse` contains the remote peer distribution
of the next `num_rpcs` *sent* by the client after receiving the
`LoadBalancerStatsRequest`. It is important that the remote peer distribution be
recorded for a block of consecutive outgoing RPCs, to validate the intended
distribution from the load balancer, rather than just looking at the next
`num_rpcs` responses received from backends, as different backends may respond
at different rates.
## Test Cases
### ping_pong
This test verifies that every backend receives traffic.
Client parameters:
1. --num_channels=1
1. --qps=10
Load balancer configuration:
1. 4 backends are created in a single managed instance group (MIG).
Test driver asserts:
1. All backends receive at least one RPC
### round_robin
This test verifies that RPCs are evenly routed according to an unweighted round
robin policy.
Client parameters:
1. --num_channels=1
1. --qps=10
Load balancer configuration:
1. 4 backends are created in a single MIG.
Test driver asserts that:
1. Once all backends receive at least one RPC, the following 100 RPCs are
evenly distributed across the 4 backends.
### backends_restart
This test verifies that the load balancer will resume sending traffic to a set
of backends that is stopped and then resumed.
Client parameters:
1. --num_channels=1
1. --qps=10
Load balancer configuration:
1. 4 backends are created in a single MIG.
Test driver asserts:
1. All backends receive at least one RPC.
The test driver records the peer distribution for a subsequent block of 100 RPCs
then stops the backends.
Test driver asserts:
1. No RPCs from the client are successful.
The test driver resumes the backends.
Test driver asserts:
1. Once all backends receive at least one RPC, the distribution for a block of
100 RPCs is the same as the distribution recorded prior to restart.
### secondary_locality_gets_requests_on_primary_failure
This test verifies that backends in a secondary locality receive traffic when
all backends in the primary locality fail.
Client parameters:
1. --num_channels=1
1. --qps=10
Load balancer configuration:
1. The primary MIG with 2 backends in the same zone as the client
1. The secondary MIG with 2 backends in a different zone
Test driver asserts:
1. All backends in the primary locality receive at least 1 RPC.
1. No backends in the secondary locality receive RPCs.
The test driver stops the backends in the primary locality.
Test driver asserts:
1. All backends in the secondary locality receive at least 1 RPC.
The test driver resumes the backends in the primary locality.
Test driver asserts:
1. All backends in the primary locality receive at least 1 RPC.
1. No backends in the secondary locality receive RPCs.
### secondary_locality_gets_no_requests_on_partial_primary_failure
This test verifies that backends in a failover locality do not receive traffic
when at least one of the backends in the primary locality remain healthy.
**Note:** Future TD features may change the expected behavior and require
changes to this test case.
Client parameters:
1. --num_channels=1
1. --qps=10
Load balancer configuration:
1. The primary MIG with 2 backends in the same zone as the client
1. The secondary MIG with 2 backends in a different zone
Test driver asserts:
1. All backends in the primary locality receive at least 1 RPC.
1. No backends in the secondary locality receive RPCs.
The test driver stops one of the backends in the primary locality.
Test driver asserts:
1. All backends in the primary locality receive at least 1 RPC.
1. No backends in the secondary locality receive RPCs.
### new_instance_group_receives_traffic
This test verifies that new instance groups added to a backend service in the
same zone receive traffic.
Client parameters:
1. --num_channels=1
1. --qps=10
Load balancer configuration:
1. One MIG with two backends, using rate balancing mode.
Test driver asserts:
1. All backends receive at least one RPC.
The test driver adds a new MIG with two backends in the same zone.
Test driver asserts:
1. All backends in each MIG receive at least one RPC.
### remove_instance_group
This test verifies that a remaining instance group can successfully serve RPCs
after removal of another instance group in the same zone.
Client parameters:
1. --num_channels=1
1. --qps=10
Load balancer configuration:
1. Two MIGs with two backends each, using rate balancing mode.
Test driver asserts:
1. All backends receive at least one RPC.
The test driver removes one MIG.
Test driver asserts:
1. All RPCs are directed to the two remaining backends (no RPC failures).
### change_backend_service
This test verifies that the backend service can be replaced and traffic routed
to the new backends.
Client parameters:
1. --num_channels=1
1. --qps=10
Load balancer configuration:
1. One MIG with two backends
Test driver asserts:
1. All backends receive at least one RPC.
The test driver creates a new backend service containing a MIG with two backends
and changes the TD URL map to point to this new backend service.
Test driver asserts:
1. All RPCs are directed to the new backend service.

@ -591,7 +591,6 @@ Pod::Spec.new do |s|
'src/cpp/client/create_channel_internal.h',
'src/cpp/client/create_channel_posix.cc',
'src/cpp/client/credentials_cc.cc',
'src/cpp/client/generic_stub.cc',
'src/cpp/client/insecure_credentials.cc',
'src/cpp/client/secure_credentials.cc',
'src/cpp/client/secure_credentials.h',

@ -139,6 +139,7 @@ Pod::Spec.new do |s|
'include/grpc/impl/codegen/slice.h',
'include/grpc/impl/codegen/status.h',
'include/grpc/impl/codegen/sync.h',
'include/grpc/impl/codegen/sync_abseil.h',
'include/grpc/impl/codegen/sync_custom.h',
'include/grpc/impl/codegen/sync_generic.h',
'include/grpc/impl/codegen/sync_posix.h',
@ -158,6 +159,7 @@ Pod::Spec.new do |s|
'include/grpc/support/port_platform.h',
'include/grpc/support/string_util.h',
'include/grpc/support/sync.h',
'include/grpc/support/sync_abseil.h',
'include/grpc/support/sync_custom.h',
'include/grpc/support/sync_generic.h',
'include/grpc/support/sync_posix.h',
@ -531,6 +533,7 @@ Pod::Spec.new do |s|
'src/core/lib/gpr/string_windows.cc',
'src/core/lib/gpr/string_windows.h',
'src/core/lib/gpr/sync.cc',
'src/core/lib/gpr/sync_abseil.cc',
'src/core/lib/gpr/sync_posix.cc',
'src/core/lib/gpr/sync_windows.cc',
'src/core/lib/gpr/time.cc',
@ -750,12 +753,9 @@ Pod::Spec.new do |s|
'src/core/lib/iomgr/wakeup_fd_posix.h',
'src/core/lib/iomgr/work_serializer.cc',
'src/core/lib/iomgr/work_serializer.h',
'src/core/lib/json/json.cc',
'src/core/lib/json/json.h',
'src/core/lib/json/json_reader.cc',
'src/core/lib/json/json_reader_new.cc',
'src/core/lib/json/json_writer.cc',
'src/core/lib/json/json_writer_new.cc',
'src/core/lib/profiling/basic_timers.cc',
'src/core/lib/profiling/stap_timers.cc',
'src/core/lib/profiling/timers.h',

@ -73,6 +73,7 @@ Gem::Specification.new do |s|
s.files += %w( include/grpc/impl/codegen/slice.h )
s.files += %w( include/grpc/impl/codegen/status.h )
s.files += %w( include/grpc/impl/codegen/sync.h )
s.files += %w( include/grpc/impl/codegen/sync_abseil.h )
s.files += %w( include/grpc/impl/codegen/sync_custom.h )
s.files += %w( include/grpc/impl/codegen/sync_generic.h )
s.files += %w( include/grpc/impl/codegen/sync_posix.h )
@ -92,6 +93,7 @@ Gem::Specification.new do |s|
s.files += %w( include/grpc/support/port_platform.h )
s.files += %w( include/grpc/support/string_util.h )
s.files += %w( include/grpc/support/sync.h )
s.files += %w( include/grpc/support/sync_abseil.h )
s.files += %w( include/grpc/support/sync_custom.h )
s.files += %w( include/grpc/support/sync_generic.h )
s.files += %w( include/grpc/support/sync_posix.h )
@ -453,6 +455,7 @@ Gem::Specification.new do |s|
s.files += %w( src/core/lib/gpr/string_windows.cc )
s.files += %w( src/core/lib/gpr/string_windows.h )
s.files += %w( src/core/lib/gpr/sync.cc )
s.files += %w( src/core/lib/gpr/sync_abseil.cc )
s.files += %w( src/core/lib/gpr/sync_posix.cc )
s.files += %w( src/core/lib/gpr/sync_windows.cc )
s.files += %w( src/core/lib/gpr/time.cc )
@ -672,12 +675,9 @@ Gem::Specification.new do |s|
s.files += %w( src/core/lib/iomgr/wakeup_fd_posix.h )
s.files += %w( src/core/lib/iomgr/work_serializer.cc )
s.files += %w( src/core/lib/iomgr/work_serializer.h )
s.files += %w( src/core/lib/json/json.cc )
s.files += %w( src/core/lib/json/json.h )
s.files += %w( src/core/lib/json/json_reader.cc )
s.files += %w( src/core/lib/json/json_reader_new.cc )
s.files += %w( src/core/lib/json/json_writer.cc )
s.files += %w( src/core/lib/json/json_writer_new.cc )
s.files += %w( src/core/lib/profiling/basic_timers.cc )
s.files += %w( src/core/lib/profiling/stap_timers.cc )
s.files += %w( src/core/lib/profiling/timers.h )

@ -317,11 +317,8 @@
'src/core/lib/iomgr/wakeup_fd_pipe.cc',
'src/core/lib/iomgr/wakeup_fd_posix.cc',
'src/core/lib/iomgr/work_serializer.cc',
'src/core/lib/json/json.cc',
'src/core/lib/json/json_reader.cc',
'src/core/lib/json/json_reader_new.cc',
'src/core/lib/json/json_writer.cc',
'src/core/lib/json/json_writer_new.cc',
'src/core/lib/slice/b64.cc',
'src/core/lib/slice/percent_encoding.cc',
'src/core/lib/slice/slice.cc',
@ -469,6 +466,7 @@
'src/core/lib/gpr/string_util_windows.cc',
'src/core/lib/gpr/string_windows.cc',
'src/core/lib/gpr/sync.cc',
'src/core/lib/gpr/sync_abseil.cc',
'src/core/lib/gpr/sync_posix.cc',
'src/core/lib/gpr/sync_windows.cc',
'src/core/lib/gpr/time.cc',
@ -617,11 +615,8 @@
'src/core/lib/iomgr/wakeup_fd_pipe.cc',
'src/core/lib/iomgr/wakeup_fd_posix.cc',
'src/core/lib/iomgr/work_serializer.cc',
'src/core/lib/json/json.cc',
'src/core/lib/json/json_reader.cc',
'src/core/lib/json/json_reader_new.cc',
'src/core/lib/json/json_writer.cc',
'src/core/lib/json/json_writer_new.cc',
'src/core/lib/slice/b64.cc',
'src/core/lib/slice/percent_encoding.cc',
'src/core/lib/slice/slice.cc',
@ -1042,11 +1037,8 @@
'src/core/lib/iomgr/wakeup_fd_pipe.cc',
'src/core/lib/iomgr/wakeup_fd_posix.cc',
'src/core/lib/iomgr/work_serializer.cc',
'src/core/lib/json/json.cc',
'src/core/lib/json/json_reader.cc',
'src/core/lib/json/json_reader_new.cc',
'src/core/lib/json/json_writer.cc',
'src/core/lib/json/json_writer_new.cc',
'src/core/lib/slice/b64.cc',
'src/core/lib/slice/percent_encoding.cc',
'src/core/lib/slice/slice.cc',
@ -1307,11 +1299,8 @@
'src/core/lib/iomgr/wakeup_fd_pipe.cc',
'src/core/lib/iomgr/wakeup_fd_posix.cc',
'src/core/lib/iomgr/work_serializer.cc',
'src/core/lib/json/json.cc',
'src/core/lib/json/json_reader.cc',
'src/core/lib/json/json_reader_new.cc',
'src/core/lib/json/json_writer.cc',
'src/core/lib/json/json_writer_new.cc',
'src/core/lib/slice/b64.cc',
'src/core/lib/slice/percent_encoding.cc',
'src/core/lib/slice/slice.cc',
@ -1548,11 +1537,8 @@
'src/core/lib/iomgr/wakeup_fd_pipe.cc',
'src/core/lib/iomgr/wakeup_fd_posix.cc',
'src/core/lib/iomgr/work_serializer.cc',
'src/core/lib/json/json.cc',
'src/core/lib/json/json_reader.cc',
'src/core/lib/json/json_reader_new.cc',
'src/core/lib/json/json_writer.cc',
'src/core/lib/json/json_writer_new.cc',
'src/core/lib/slice/b64.cc',
'src/core/lib/slice/percent_encoding.cc',
'src/core/lib/slice/slice.cc',
@ -1820,7 +1806,6 @@
'src/cpp/client/create_channel_internal.cc',
'src/cpp/client/create_channel_posix.cc',
'src/cpp/client/credentials_cc.cc',
'src/cpp/client/generic_stub.cc',
'src/cpp/common/alarm.cc',
'src/cpp/common/channel_arguments.cc',
'src/cpp/common/channel_filter.cc',
@ -1992,7 +1977,6 @@
'src/cpp/client/create_channel_internal.cc',
'src/cpp/client/create_channel_posix.cc',
'src/cpp/client/credentials_cc.cc',
'src/cpp/client/generic_stub.cc',
'src/cpp/common/alarm.cc',
'src/cpp/common/channel_arguments.cc',
'src/cpp/common/channel_filter.cc',

@ -34,6 +34,13 @@
#define GRPC_USE_ABSL 1
#endif
/*
* Defines GPR_ABSEIL_SYNC to use synchronization features from Abseil
*/
#ifndef GPR_ABSEIL_SYNC
/* #define GPR_ABSEIL_SYNC 1 */
#endif
/* Get windows.h included everywhere (we need it) */
#if defined(_WIN64) || defined(WIN64) || defined(_WIN32) || defined(WIN32)
#ifndef WIN32_LEAN_AND_MEAN

@ -46,12 +46,14 @@ extern "C" {
#include <grpc/impl/codegen/sync_generic.h>
#if defined(GPR_POSIX_SYNC)
#if defined(GPR_CUSTOM_SYNC)
#include <grpc/impl/codegen/sync_custom.h>
#elif defined(GPR_ABSEIL_SYNC)
#include <grpc/impl/codegen/sync_abseil.h>
#elif defined(GPR_POSIX_SYNC)
#include <grpc/impl/codegen/sync_posix.h>
#elif defined(GPR_WINDOWS)
#include <grpc/impl/codegen/sync_windows.h>
#elif defined(GPR_CUSTOM_SYNC)
#include <grpc/impl/codegen/sync_custom.h>
#else
#error Unable to determine platform for sync
#endif

@ -0,0 +1,36 @@
/*
*
* Copyright 2020 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
#ifndef GRPC_IMPL_CODEGEN_SYNC_ABSEIL_H
#define GRPC_IMPL_CODEGEN_SYNC_ABSEIL_H
#include <grpc/impl/codegen/port_platform.h>
#include <grpc/impl/codegen/sync_generic.h>
#ifdef GPR_ABSEIL_SYNC
typedef intptr_t gpr_mu;
typedef intptr_t gpr_cv;
typedef int32_t gpr_once;
#define GPR_ONCE_INIT 0
#endif
#endif /* GRPC_IMPL_CODEGEN_SYNC_ABSEIL_H */

@ -10,6 +10,7 @@ framework module grpc {
header "support/port_platform.h"
header "support/string_util.h"
header "support/sync.h"
header "support/sync_abseil.h"
header "support/sync_generic.h"
header "support/thd_id.h"
header "support/time.h"
@ -20,6 +21,7 @@ framework module grpc {
header "impl/codegen/log.h"
header "impl/codegen/port_platform.h"
header "impl/codegen/sync.h"
header "impl/codegen/sync_abseil.h"
header "impl/codegen/sync_generic.h"
header "impl/codegen/byte_buffer.h"
header "impl/codegen/byte_buffer_reader.h"
@ -36,6 +38,7 @@ framework module grpc {
header "impl/codegen/log.h"
header "impl/codegen/port_platform.h"
header "impl/codegen/sync.h"
header "impl/codegen/sync_abseil.h"
header "impl/codegen/sync_generic.h"
header "grpc_security.h"
header "byte_buffer.h"

@ -0,0 +1,26 @@
/*
*
* Copyright 2020 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
#ifndef GRPC_SUPPORT_SYNC_ABSEIL_H
#define GRPC_SUPPORT_SYNC_ABSEIL_H
#include <grpc/support/port_platform.h>
#include <grpc/impl/codegen/sync_abseil.h>
#endif /* GRPC_SUPPORT_SYNC_ABSEIL_H */

@ -22,6 +22,7 @@
#include <functional>
#include <grpcpp/client_context.h>
#include <grpcpp/impl/rpc_method.h>
#include <grpcpp/support/async_stream_impl.h>
#include <grpcpp/support/async_unary_call_impl.h>
#include <grpcpp/support/byte_buffer.h>
@ -38,28 +39,39 @@ typedef ::grpc_impl::ClientAsyncResponseReader<ByteBuffer>
namespace grpc_impl {
class CompletionQueue;
/// Generic stubs provide a type-unsafe interface to call gRPC methods
/// by name.
class GenericStub final {
/// Generic stubs provide a type-unaware interface to call gRPC methods
/// by name. In practice, the Request and Response types should be basic
/// types like grpc::ByteBuffer or proto::MessageLite (the base protobuf).
template <class RequestType, class ResponseType>
class TemplatedGenericStub final {
public:
explicit GenericStub(std::shared_ptr<grpc::ChannelInterface> channel)
explicit TemplatedGenericStub(std::shared_ptr<grpc::ChannelInterface> channel)
: channel_(channel) {}
/// Setup a call to a named method \a method using \a context, but don't
/// start it. Let it be started explicitly with StartCall and a tag.
/// The return value only indicates whether or not registration of the call
/// succeeded (i.e. the call won't proceed if the return value is nullptr).
std::unique_ptr<grpc::GenericClientAsyncReaderWriter> PrepareCall(
grpc::ClientContext* context, const grpc::string& method,
CompletionQueue* cq);
std::unique_ptr<ClientAsyncReaderWriter<RequestType, ResponseType>>
PrepareCall(ClientContext* context, const grpc::string& method,
CompletionQueue* cq) {
return CallInternal(channel_.get(), context, method, cq, false, nullptr);
}
/// Setup a unary call to a named method \a method using \a context, and don't
/// start it. Let it be started explicitly with StartCall.
/// The return value only indicates whether or not registration of the call
/// succeeded (i.e. the call won't proceed if the return value is nullptr).
std::unique_ptr<grpc::GenericClientAsyncResponseReader> PrepareUnaryCall(
grpc_impl::ClientContext* context, const grpc::string& method,
const grpc::ByteBuffer& request, CompletionQueue* cq);
std::unique_ptr<ClientAsyncResponseReader<ResponseType>> PrepareUnaryCall(
ClientContext* context, const grpc::string& method,
const RequestType& request, CompletionQueue* cq) {
return std::unique_ptr<ClientAsyncResponseReader<ResponseType>>(
internal::ClientAsyncResponseReaderFactory<ResponseType>::Create(
channel_.get(), cq,
grpc::internal::RpcMethod(method.c_str(),
grpc::internal::RpcMethod::NORMAL_RPC),
context, request, false));
}
/// DEPRECATED for multi-threaded use
/// Begin a call to a named method \a method using \a context.
@ -67,15 +79,17 @@ class GenericStub final {
/// (i.e, initial metadata has been sent).
/// The return value only indicates whether or not registration of the call
/// succeeded (i.e. the call won't proceed if the return value is nullptr).
std::unique_ptr<grpc::GenericClientAsyncReaderWriter> Call(
grpc_impl::ClientContext* context, const grpc::string& method,
CompletionQueue* cq, void* tag);
std::unique_ptr<ClientAsyncReaderWriter<RequestType, ResponseType>> Call(
ClientContext* context, const grpc::string& method, CompletionQueue* cq,
void* tag) {
return CallInternal(channel_.get(), context, method, cq, true, tag);
}
#ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
/// Setup and start a unary call to a named method \a method using
/// \a context and specifying the \a request and \a response buffers.
void UnaryCall(grpc_impl::ClientContext* context, const grpc::string& method,
const grpc::ByteBuffer* request, grpc::ByteBuffer* response,
void UnaryCall(ClientContext* context, const grpc::string& method,
const RequestType* request, ResponseType* response,
std::function<void(grpc::Status)> on_completion) {
UnaryCallInternal(context, method, request, response,
std::move(on_completion));
@ -85,11 +99,9 @@ class GenericStub final {
/// \a context and specifying the \a request and \a response buffers.
/// Like any other reactor-based RPC, it will not be activated until
/// StartCall is invoked on its reactor.
void PrepareUnaryCall(grpc_impl::ClientContext* context,
const grpc::string& method,
const grpc::ByteBuffer* request,
grpc::ByteBuffer* response,
grpc_impl::ClientUnaryReactor* reactor) {
void PrepareUnaryCall(ClientContext* context, const grpc::string& method,
const RequestType* request, ResponseType* response,
ClientUnaryReactor* reactor) {
PrepareUnaryCallInternal(context, method, request, response, reactor);
}
@ -97,9 +109,8 @@ class GenericStub final {
/// \a reactor . Like any other bidi streaming RPC, it will not be activated
/// until StartCall is invoked on its reactor.
void PrepareBidiStreamingCall(
grpc_impl::ClientContext* context, const grpc::string& method,
grpc_impl::ClientBidiReactor<grpc::ByteBuffer, grpc::ByteBuffer>*
reactor) {
ClientContext* context, const grpc::string& method,
ClientBidiReactor<RequestType, ResponseType>* reactor) {
PrepareBidiStreamingCallInternal(context, method, reactor);
}
#endif
@ -109,13 +120,12 @@ class GenericStub final {
/// they are no longer experimental
class experimental_type {
public:
explicit experimental_type(GenericStub* stub) : stub_(stub) {}
explicit experimental_type(TemplatedGenericStub* stub) : stub_(stub) {}
/// Setup and start a unary call to a named method \a method using
/// \a context and specifying the \a request and \a response buffers.
void UnaryCall(grpc_impl::ClientContext* context,
const grpc::string& method, const grpc::ByteBuffer* request,
grpc::ByteBuffer* response,
void UnaryCall(ClientContext* context, const grpc::string& method,
const RequestType* request, ResponseType* response,
std::function<void(grpc::Status)> on_completion) {
stub_->UnaryCallInternal(context, method, request, response,
std::move(on_completion));
@ -125,11 +135,9 @@ class GenericStub final {
/// \a context and specifying the \a request and \a response buffers.
/// Like any other reactor-based RPC, it will not be activated until
/// StartCall is invoked on its reactor.
void PrepareUnaryCall(grpc_impl::ClientContext* context,
const grpc::string& method,
const grpc::ByteBuffer* request,
grpc::ByteBuffer* response,
grpc_impl::ClientUnaryReactor* reactor) {
void PrepareUnaryCall(ClientContext* context, const grpc::string& method,
const RequestType* request, ResponseType* response,
ClientUnaryReactor* reactor) {
stub_->PrepareUnaryCallInternal(context, method, request, response,
reactor);
}
@ -138,14 +146,13 @@ class GenericStub final {
/// \a reactor . Like any other bidi streaming RPC, it will not be activated
/// until StartCall is invoked on its reactor.
void PrepareBidiStreamingCall(
grpc_impl::ClientContext* context, const grpc::string& method,
grpc_impl::ClientBidiReactor<grpc::ByteBuffer, grpc::ByteBuffer>*
reactor) {
ClientContext* context, const grpc::string& method,
ClientBidiReactor<RequestType, ResponseType>* reactor) {
stub_->PrepareBidiStreamingCallInternal(context, method, reactor);
}
private:
GenericStub* stub_;
TemplatedGenericStub* stub_;
};
/// NOTE: The function experimental() is not stable public API. It is a view
@ -156,24 +163,54 @@ class GenericStub final {
private:
std::shared_ptr<grpc::ChannelInterface> channel_;
void UnaryCallInternal(grpc_impl::ClientContext* context,
const grpc::string& method,
const grpc::ByteBuffer* request,
grpc::ByteBuffer* response,
std::function<void(grpc::Status)> on_completion);
void UnaryCallInternal(ClientContext* context, const grpc::string& method,
const RequestType* request, ResponseType* response,
std::function<void(grpc::Status)> on_completion) {
internal::CallbackUnaryCall(
channel_.get(),
grpc::internal::RpcMethod(method.c_str(),
grpc::internal::RpcMethod::NORMAL_RPC),
context, request, response, std::move(on_completion));
}
void PrepareUnaryCallInternal(grpc_impl::ClientContext* context,
void PrepareUnaryCallInternal(ClientContext* context,
const grpc::string& method,
const grpc::ByteBuffer* request,
grpc::ByteBuffer* response,
grpc_impl::ClientUnaryReactor* reactor);
const RequestType* request,
ResponseType* response,
ClientUnaryReactor* reactor) {
internal::ClientCallbackUnaryFactory::Create<RequestType, ResponseType>(
channel_.get(),
grpc::internal::RpcMethod(method.c_str(),
grpc::internal::RpcMethod::NORMAL_RPC),
context, request, response, reactor);
}
void PrepareBidiStreamingCallInternal(
grpc_impl::ClientContext* context, const grpc::string& method,
grpc_impl::ClientBidiReactor<grpc::ByteBuffer, grpc::ByteBuffer>*
reactor);
ClientContext* context, const grpc::string& method,
ClientBidiReactor<RequestType, ResponseType>* reactor) {
internal::ClientCallbackReaderWriterFactory<RequestType, ResponseType>::
Create(channel_.get(),
grpc::internal::RpcMethod(
method.c_str(), grpc::internal::RpcMethod::BIDI_STREAMING),
context, reactor);
}
std::unique_ptr<ClientAsyncReaderWriter<RequestType, ResponseType>>
CallInternal(grpc::ChannelInterface* channel, ClientContext* context,
const grpc::string& method, CompletionQueue* cq, bool start,
void* tag) {
return std::unique_ptr<ClientAsyncReaderWriter<RequestType, ResponseType>>(
internal::ClientAsyncReaderWriterFactory<RequestType, ResponseType>::
Create(
channel, cq,
grpc::internal::RpcMethod(
method.c_str(), grpc::internal::RpcMethod::BIDI_STREAMING),
context, start, tag));
}
};
typedef TemplatedGenericStub<grpc::ByteBuffer, grpc::ByteBuffer> GenericStub;
} // namespace grpc_impl
#endif // GRPCPP_GENERIC_GENERIC_STUB_IMPL_H

@ -32,11 +32,14 @@
#ifndef GRPCPP_IMPL_CODEGEN_COMPLETION_QUEUE_IMPL_H
#define GRPCPP_IMPL_CODEGEN_COMPLETION_QUEUE_IMPL_H
#include <list>
#include <grpc/impl/codegen/atm.h>
#include <grpcpp/impl/codegen/completion_queue_tag.h>
#include <grpcpp/impl/codegen/core_codegen_interface.h>
#include <grpcpp/impl/codegen/grpc_library.h>
#include <grpcpp/impl/codegen/status.h>
#include <grpcpp/impl/codegen/sync.h>
#include <grpcpp/impl/codegen/time.h>
struct grpc_completion_queue;
@ -250,6 +253,11 @@ class CompletionQueue : private ::grpc::GrpcLibraryCodegen {
}
private:
// Friends for access to server registration lists that enable checking and
// logging on shutdown
friend class ::grpc_impl::ServerBuilder;
friend class ::grpc_impl::Server;
// Friend synchronous wrappers so that they can access Pluck(), which is
// a semi-private API geared towards the synchronous implementation.
template <class R>
@ -274,7 +282,6 @@ class CompletionQueue : private ::grpc::GrpcLibraryCodegen {
friend class ::grpc_impl::internal::TemplatedBidiStreamingHandler;
template <::grpc::StatusCode code>
friend class ::grpc_impl::internal::ErrorMethodHandler;
friend class ::grpc_impl::Server;
friend class ::grpc_impl::ServerContextBase;
friend class ::grpc::ServerInterface;
template <class InputMessage, class OutputMessage>
@ -379,13 +386,39 @@ class CompletionQueue : private ::grpc::GrpcLibraryCodegen {
}
}
void RegisterServer(const Server* server) {
#ifndef NDEBUG
grpc::internal::MutexLock l(&server_list_mutex_);
server_list_.push_back(server);
#endif
}
void UnregisterServer(const Server* server) {
#ifndef NDEBUG
grpc::internal::MutexLock l(&server_list_mutex_);
server_list_.remove(server);
#endif
}
bool ServerListEmpty() const {
#ifndef NDEBUG
grpc::internal::MutexLock l(&server_list_mutex_);
return server_list_.empty();
#endif
return true;
}
grpc_completion_queue* cq_; // owned
gpr_atm avalanches_in_flight_;
// List of servers associated with this CQ. Even though this is only used with
// NDEBUG, instantiate it in all cases since otherwise the size will be
// inconsistent.
mutable grpc::internal::Mutex server_list_mutex_;
std::list<const Server*> server_list_ /* GUARDED_BY(server_list_mutex_) */;
};
/// A specific type of completion queue used by the processing of notifications
/// by servers. Instantiated by \a ServerBuilder.
/// by servers. Instantiated by \a ServerBuilder or Server (for health checker).
class ServerCompletionQueue : public CompletionQueue {
public:
bool IsFrequentlyPolled() { return polling_type_ != GRPC_CQ_NON_LISTENING; }

@ -385,6 +385,11 @@ class Server : public grpc::ServerInterface, private grpc::GrpcLibraryCodegen {
// shutdown callback tag (invoked when the CQ is fully shutdown).
// It is protected by mu_
CompletionQueue* callback_cq_ = nullptr;
// List of CQs passed in by user that must be Shutdown only after Server is
// Shutdown. Even though this is only used with NDEBUG, instantiate it in all
// cases since otherwise the size will be inconsistent.
std::vector<CompletionQueue*> cq_list_;
};
} // namespace grpc_impl

@ -56,6 +56,7 @@
<file baseinstalldir="/" name="include/grpc/impl/codegen/slice.h" role="src" />
<file baseinstalldir="/" name="include/grpc/impl/codegen/status.h" role="src" />
<file baseinstalldir="/" name="include/grpc/impl/codegen/sync.h" role="src" />
<file baseinstalldir="/" name="include/grpc/impl/codegen/sync_abseil.h" role="src" />
<file baseinstalldir="/" name="include/grpc/impl/codegen/sync_custom.h" role="src" />
<file baseinstalldir="/" name="include/grpc/impl/codegen/sync_generic.h" role="src" />
<file baseinstalldir="/" name="include/grpc/impl/codegen/sync_posix.h" role="src" />
@ -75,6 +76,7 @@
<file baseinstalldir="/" name="include/grpc/support/port_platform.h" role="src" />
<file baseinstalldir="/" name="include/grpc/support/string_util.h" role="src" />
<file baseinstalldir="/" name="include/grpc/support/sync.h" role="src" />
<file baseinstalldir="/" name="include/grpc/support/sync_abseil.h" role="src" />
<file baseinstalldir="/" name="include/grpc/support/sync_custom.h" role="src" />
<file baseinstalldir="/" name="include/grpc/support/sync_generic.h" role="src" />
<file baseinstalldir="/" name="include/grpc/support/sync_posix.h" role="src" />
@ -436,6 +438,7 @@
<file baseinstalldir="/" name="src/core/lib/gpr/string_windows.cc" role="src" />
<file baseinstalldir="/" name="src/core/lib/gpr/string_windows.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/gpr/sync.cc" role="src" />
<file baseinstalldir="/" name="src/core/lib/gpr/sync_abseil.cc" role="src" />
<file baseinstalldir="/" name="src/core/lib/gpr/sync_posix.cc" role="src" />
<file baseinstalldir="/" name="src/core/lib/gpr/sync_windows.cc" role="src" />
<file baseinstalldir="/" name="src/core/lib/gpr/time.cc" role="src" />
@ -655,12 +658,9 @@
<file baseinstalldir="/" name="src/core/lib/iomgr/wakeup_fd_posix.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/iomgr/work_serializer.cc" role="src" />
<file baseinstalldir="/" name="src/core/lib/iomgr/work_serializer.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/json/json.cc" role="src" />
<file baseinstalldir="/" name="src/core/lib/json/json.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/json/json_reader.cc" role="src" />
<file baseinstalldir="/" name="src/core/lib/json/json_reader_new.cc" role="src" />
<file baseinstalldir="/" name="src/core/lib/json/json_writer.cc" role="src" />
<file baseinstalldir="/" name="src/core/lib/json/json_writer_new.cc" role="src" />
<file baseinstalldir="/" name="src/core/lib/profiling/basic_timers.cc" role="src" />
<file baseinstalldir="/" name="src/core/lib/profiling/stap_timers.cc" role="src" />
<file baseinstalldir="/" name="src/core/lib/profiling/timers.h" role="src" />

@ -51,7 +51,8 @@ grpc_slice g_fake_auth_value;
struct inproc_stream;
bool cancel_stream_locked(inproc_stream* s, grpc_error* error);
void op_state_machine(void* arg, grpc_error* error);
void maybe_process_ops_locked(inproc_stream* s, grpc_error* error);
void op_state_machine_locked(inproc_stream* s, grpc_error* error);
void log_metadata(const grpc_metadata_batch* md_batch, bool is_client,
bool is_initial);
grpc_error* fill_in_metadata(inproc_stream* s,
@ -130,8 +131,6 @@ struct inproc_stream {
grpc_metadata_batch_init(&to_read_initial_md);
grpc_metadata_batch_init(&to_read_trailing_md);
GRPC_CLOSURE_INIT(&op_closure, op_state_machine, this,
grpc_schedule_on_exec_ctx);
grpc_metadata_batch_init(&write_buffer_initial_md);
grpc_metadata_batch_init(&write_buffer_trailing_md);
@ -186,6 +185,7 @@ struct inproc_stream {
if (cs->write_buffer_cancel_error != GRPC_ERROR_NONE) {
cancel_other_error = cs->write_buffer_cancel_error;
cs->write_buffer_cancel_error = GRPC_ERROR_NONE;
maybe_process_ops_locked(this, cancel_other_error);
}
gpr_mu_unlock(&t->mu->mu);
@ -235,8 +235,6 @@ struct inproc_stream {
grpc_metadata_batch to_read_trailing_md;
bool to_read_trailing_md_filled = false;
bool ops_needed = false;
bool op_closure_scheduled = false;
grpc_closure op_closure;
// Write buffer used only during gap at init time when client-side
// stream is set up but server side stream is not yet set up
grpc_metadata_batch write_buffer_initial_md;
@ -396,12 +394,10 @@ void complete_if_batch_end_locked(inproc_stream* s, grpc_error* error,
}
}
void maybe_schedule_op_closure_locked(inproc_stream* s, grpc_error* error) {
if (s && s->ops_needed && !s->op_closure_scheduled) {
grpc_core::ExecCtx::Run(DEBUG_LOCATION, &s->op_closure,
GRPC_ERROR_REF(error));
s->op_closure_scheduled = true;
void maybe_process_ops_locked(inproc_stream* s, grpc_error* error) {
if (s && (error != GRPC_ERROR_NONE || s->ops_needed)) {
s->ops_needed = false;
op_state_machine_locked(s, error);
}
}
@ -429,7 +425,7 @@ void fail_helper_locked(inproc_stream* s, grpc_error* error) {
if (other->cancel_other_error == GRPC_ERROR_NONE) {
other->cancel_other_error = GRPC_ERROR_REF(error);
}
maybe_schedule_op_closure_locked(other, error);
maybe_process_ops_locked(other, error);
} else if (s->write_buffer_cancel_error == GRPC_ERROR_NONE) {
s->write_buffer_cancel_error = GRPC_ERROR_REF(error);
}
@ -587,23 +583,17 @@ void message_transfer_locked(inproc_stream* sender, inproc_stream* receiver) {
sender->send_message_op = nullptr;
}
void op_state_machine(void* arg, grpc_error* error) {
void op_state_machine_locked(inproc_stream* s, grpc_error* error) {
// This function gets called when we have contents in the unprocessed reads
// Get what we want based on our ops wanted
// Schedule our appropriate closures
// and then return to ops_needed state if still needed
// Since this is a closure directly invoked by the combiner, it should not
// unref the error parameter explicitly; the combiner will do that implicitly
grpc_error* new_err = GRPC_ERROR_NONE;
bool needs_close = false;
INPROC_LOG(GPR_INFO, "op_state_machine %p", arg);
inproc_stream* s = static_cast<inproc_stream*>(arg);
gpr_mu* mu = &s->t->mu->mu; // keep aside in case s gets closed
gpr_mu_lock(mu);
s->op_closure_scheduled = false;
INPROC_LOG(GPR_INFO, "op_state_machine %p", s);
// cancellation takes precedence
inproc_stream* other = s->other_side;
@ -621,7 +611,7 @@ void op_state_machine(void* arg, grpc_error* error) {
if (s->send_message_op && other) {
if (other->recv_message_op) {
message_transfer_locked(s, other);
maybe_schedule_op_closure_locked(other, GRPC_ERROR_NONE);
maybe_process_ops_locked(other, GRPC_ERROR_NONE);
} else if (!s->t->is_client && s->trailing_md_sent) {
// A server send will never be matched if the server already sent status
s->send_message_op->payload->send_message.send_message.reset();
@ -679,7 +669,7 @@ void op_state_machine(void* arg, grpc_error* error) {
needs_close = true;
}
}
maybe_schedule_op_closure_locked(other, GRPC_ERROR_NONE);
maybe_process_ops_locked(other, GRPC_ERROR_NONE);
complete_if_batch_end_locked(
s, GRPC_ERROR_NONE, s->send_trailing_md_op,
"op_state_machine scheduling send-trailing-metadata-on-complete");
@ -741,7 +731,7 @@ void op_state_machine(void* arg, grpc_error* error) {
if (s->recv_message_op) {
if (other && other->send_message_op) {
message_transfer_locked(other, s);
maybe_schedule_op_closure_locked(other, GRPC_ERROR_NONE);
maybe_process_ops_locked(other, GRPC_ERROR_NONE);
}
}
if (s->to_read_trailing_md_filled) {
@ -808,7 +798,7 @@ void op_state_machine(void* arg, grpc_error* error) {
s->recv_trailing_md_op->on_complete,
GRPC_ERROR_REF(new_err));
s->recv_trailing_md_op = nullptr;
needs_close = true;
needs_close = s->trailing_md_sent;
} else {
INPROC_LOG(GPR_INFO,
"op_state_machine %p server needs to delay handling "
@ -860,7 +850,6 @@ done:
close_other_side_locked(s, "op_state_machine");
close_stream_locked(s);
}
gpr_mu_unlock(mu);
GRPC_ERROR_UNREF(new_err);
}
@ -870,7 +859,9 @@ bool cancel_stream_locked(inproc_stream* s, grpc_error* error) {
if (s->cancel_self_error == GRPC_ERROR_NONE) {
ret = true;
s->cancel_self_error = GRPC_ERROR_REF(error);
maybe_schedule_op_closure_locked(s, s->cancel_self_error);
// Catch current value of other before it gets closed off
inproc_stream* other = s->other_side;
maybe_process_ops_locked(s, s->cancel_self_error);
// Send trailing md to the other side indicating cancellation, even if we
// already have
s->trailing_md_sent = true;
@ -878,7 +869,6 @@ bool cancel_stream_locked(inproc_stream* s, grpc_error* error) {
grpc_metadata_batch cancel_md;
grpc_metadata_batch_init(&cancel_md);
inproc_stream* other = s->other_side;
grpc_metadata_batch* dest = (other == nullptr)
? &s->write_buffer_trailing_md
: &other->to_read_trailing_md;
@ -891,7 +881,7 @@ bool cancel_stream_locked(inproc_stream* s, grpc_error* error) {
if (other->cancel_other_error == GRPC_ERROR_NONE) {
other->cancel_other_error = GRPC_ERROR_REF(s->cancel_self_error);
}
maybe_schedule_op_closure_locked(other, other->cancel_other_error);
maybe_process_ops_locked(other, other->cancel_other_error);
} else if (s->write_buffer_cancel_error == GRPC_ERROR_NONE) {
s->write_buffer_cancel_error = GRPC_ERROR_REF(s->cancel_self_error);
}
@ -969,8 +959,6 @@ void perform_stream_op(grpc_transport* gt, grpc_stream* gs,
op->recv_trailing_metadata ? " recv_trailing_metadata" : "");
}
bool needs_close = false;
inproc_stream* other = s->other_side;
if (error == GRPC_ERROR_NONE &&
(op->send_initial_metadata || op->send_trailing_metadata)) {
@ -991,7 +979,7 @@ void perform_stream_op(grpc_transport* gt, grpc_stream* gs,
INPROC_LOG(GPR_INFO, "Extra initial metadata %p", s);
error = GRPC_ERROR_CREATE_FROM_STATIC_STRING("Extra initial metadata");
} else {
if (!other || !other->closed) {
if (!s->other_side_closed) {
fill_in_metadata(
s, op->payload->send_initial_metadata.send_initial_metadata,
op->payload->send_initial_metadata.send_initial_metadata_flags,
@ -1005,7 +993,7 @@ void perform_stream_op(grpc_transport* gt, grpc_stream* gs,
s->initial_md_sent = true;
}
}
maybe_schedule_op_closure_locked(other, error);
maybe_process_ops_locked(other, error);
}
}
@ -1013,7 +1001,7 @@ void perform_stream_op(grpc_transport* gt, grpc_stream* gs,
(op->send_message || op->send_trailing_metadata ||
op->recv_initial_metadata || op->recv_message ||
op->recv_trailing_metadata)) {
// Mark ops that need to be processed by the closure
// Mark ops that need to be processed by the state machine
if (op->send_message) {
s->send_message_op = op;
}
@ -1030,7 +1018,7 @@ void perform_stream_op(grpc_transport* gt, grpc_stream* gs,
s->recv_trailing_md_op = op;
}
// We want to initiate the closure if:
// We want to initiate the state machine if:
// 1. We want to send a message and the other side wants to receive
// 2. We want to send trailing metadata and there isn't an unmatched send
// or the other side wants trailing metadata
@ -1044,11 +1032,7 @@ void perform_stream_op(grpc_transport* gt, grpc_stream* gs,
(op->recv_initial_metadata && s->to_read_initial_md_filled) ||
(op->recv_message && other && other->send_message_op != nullptr) ||
(s->to_read_trailing_md_filled || s->trailing_md_recvd)) {
if (!s->op_closure_scheduled) {
grpc_core::ExecCtx::Run(DEBUG_LOCATION, &s->op_closure,
GRPC_ERROR_NONE);
s->op_closure_scheduled = true;
}
op_state_machine_locked(s, error);
} else {
s->ops_needed = true;
}
@ -1103,10 +1087,6 @@ void perform_stream_op(grpc_transport* gt, grpc_stream* gs,
error);
grpc_core::ExecCtx::Run(DEBUG_LOCATION, on_complete, GRPC_ERROR_REF(error));
}
if (needs_close) {
close_other_side_locked(s, "perform_stream_op:other_side");
close_stream_locked(s);
}
gpr_mu_unlock(mu);
GRPC_ERROR_UNREF(error);
}

@ -0,0 +1,114 @@
/*
*
* Copyright 2020 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
#include <grpc/support/port_platform.h>
#if defined(GPR_ABSEIL_SYNC) && !defined(GPR_CUSTOM_SYNC)
#include <grpc/support/alloc.h>
#include <errno.h>
#include <grpc/support/log.h>
#include <grpc/support/sync.h>
#include <grpc/support/time.h>
#include <time.h>
#include "src/core/lib/profiling/timers.h"
#include "absl/base/call_once.h"
#include "absl/synchronization/mutex.h"
#include "absl/time/clock.h"
#include "absl/time/time.h"
#ifdef GPR_LOW_LEVEL_COUNTERS
gpr_atm gpr_mu_locks = 0;
gpr_atm gpr_counter_atm_cas = 0;
gpr_atm gpr_counter_atm_add = 0;
#endif
void gpr_mu_init(gpr_mu* mu) {
static_assert(sizeof(gpr_mu) == sizeof(absl::Mutex),
"gpr_mu and Mutex must be the same size");
new (mu) absl::Mutex;
}
void gpr_mu_destroy(gpr_mu* mu) {
reinterpret_cast<absl::Mutex*>(mu)->~Mutex();
}
void gpr_mu_lock(gpr_mu* mu) ABSL_NO_THREAD_SAFETY_ANALYSIS {
GPR_TIMER_SCOPE("gpr_mu_lock", 0);
reinterpret_cast<absl::Mutex*>(mu)->Lock();
}
void gpr_mu_unlock(gpr_mu* mu) ABSL_NO_THREAD_SAFETY_ANALYSIS {
GPR_TIMER_SCOPE("gpr_mu_unlock", 0);
reinterpret_cast<absl::Mutex*>(mu)->Unlock();
}
int gpr_mu_trylock(gpr_mu* mu) {
GPR_TIMER_SCOPE("gpr_mu_trylock", 0);
int ret = reinterpret_cast<absl::Mutex*>(mu)->TryLock() == true;
return ret;
}
/*----------------------------------------*/
void gpr_cv_init(gpr_cv* cv) {
static_assert(sizeof(gpr_cv) == sizeof(absl::CondVar),
"gpr_cv and CondVar must be the same size");
new (cv) absl::CondVar;
}
void gpr_cv_destroy(gpr_cv* cv) {
reinterpret_cast<absl::CondVar*>(cv)->~CondVar();
}
int gpr_cv_wait(gpr_cv* cv, gpr_mu* mu, gpr_timespec abs_deadline) {
GPR_TIMER_SCOPE("gpr_cv_wait", 0);
if (gpr_time_cmp(abs_deadline, gpr_inf_future(abs_deadline.clock_type)) ==
0) {
reinterpret_cast<absl::CondVar*>(cv)->Wait(
reinterpret_cast<absl::Mutex*>(mu));
return 0;
}
abs_deadline = gpr_convert_clock_type(abs_deadline, GPR_CLOCK_REALTIME);
timespec ts = {static_cast<decltype(ts.tv_sec)>(abs_deadline.tv_sec),
static_cast<decltype(ts.tv_nsec)>(abs_deadline.tv_nsec)};
int ret = reinterpret_cast<absl::CondVar*>(cv)->WaitWithDeadline(
reinterpret_cast<absl::Mutex*>(mu),
absl::TimeFromTimespec(ts)) == true;
return ret;
}
void gpr_cv_signal(gpr_cv* cv) {
GPR_TIMER_MARK("gpr_cv_signal", 0);
reinterpret_cast<absl::CondVar*>(cv)->Signal();
}
void gpr_cv_broadcast(gpr_cv* cv) {
GPR_TIMER_MARK("gpr_cv_broadcast", 0);
reinterpret_cast<absl::CondVar*>(cv)->SignalAll();
}
/*----------------------------------------*/
void gpr_once_init(gpr_once* once, void (*init_function)(void)) {
absl::call_once(*reinterpret_cast<absl::once_flag*>(once), init_function);
}
#endif /* defined(GPR_ABSEIL_SYNC) && !defined(GPR_CUSTOM_SYNC) */

@ -18,15 +18,17 @@
#include <grpc/support/port_platform.h>
#include <grpc/support/alloc.h>
#ifdef GPR_POSIX_SYNC
#if defined(GPR_POSIX_SYNC) && !defined(GPR_ABSEIL_SYNC) && \
!defined(GPR_CUSTOM_SYNC)
#include <errno.h>
#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
#include <grpc/support/sync.h>
#include <grpc/support/time.h>
#include <errno.h>
#include <time.h>
#include "src/core/lib/profiling/timers.h"
#ifdef GPR_LOW_LEVEL_COUNTERS
@ -170,4 +172,5 @@ void gpr_once_init(gpr_once* once, void (*init_function)(void)) {
GPR_ASSERT(pthread_once(once, init_function) == 0);
}
#endif /* GRP_POSIX_SYNC */
#endif /* defined(GPR_POSIX_SYNC) && !defined(GPR_ABSEIL_SYNC) && \
!defined(GPR_CUSTOM_SYNC) */

@ -20,7 +20,8 @@
#include <grpc/support/port_platform.h>
#ifdef GPR_WINDOWS
#if defined(GPR_WINDOWS) && !defined(GPR_ABSEIL_SYNC) && \
!defined(GPR_CUSTOM_SYNC)
#include <grpc/support/log.h>
#include <grpc/support/sync.h>
@ -115,4 +116,5 @@ void gpr_once_init(gpr_once* once, void (*init_function)(void)) {
InitOnceExecuteOnce(once, run_once_func, &arg, &dummy);
}
#endif /* GPR_WINDOWS */
#endif /* defined(GPR_WINDOWS) && !defined(GPR_ABSEIL_SYNC) && \
!defined(GPR_CUSTOM_SYNC) */

@ -1,94 +0,0 @@
/*
*
* Copyright 2015 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
#include <grpc/support/port_platform.h>
#include <inttypes.h>
#include <string.h>
#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
#include <grpc/support/string_util.h>
#include "src/core/lib/json/json.h"
grpc_json* grpc_json_create(grpc_json_type type) {
grpc_json* json = static_cast<grpc_json*>(gpr_zalloc(sizeof(*json)));
json->type = type;
return json;
}
void grpc_json_destroy(grpc_json* json) {
if (json == nullptr) return;
while (json->child) {
grpc_json_destroy(json->child);
}
if (json->next) {
json->next->prev = json->prev;
}
if (json->prev) {
json->prev->next = json->next;
} else if (json->parent) {
json->parent->child = json->next;
}
if (json->owns_value) {
gpr_free((void*)json->value);
}
gpr_free(json);
}
grpc_json* grpc_json_link_child(grpc_json* parent, grpc_json* child,
grpc_json* sibling) {
// link child up to parent
child->parent = parent;
// first child case.
if (parent->child == nullptr) {
GPR_ASSERT(sibling == nullptr);
parent->child = child;
return child;
}
if (sibling == nullptr) {
sibling = parent->child;
}
// always find the right most sibling.
while (sibling->next != nullptr) {
sibling = sibling->next;
}
sibling->next = child;
return child;
}
grpc_json* grpc_json_create_child(grpc_json* sibling, grpc_json* parent,
const char* key, const char* value,
grpc_json_type type, bool owns_value) {
grpc_json* child = grpc_json_create(type);
grpc_json_link_child(parent, child, sibling);
child->owns_value = owns_value;
child->value = value;
child->key = key;
return child;
}
grpc_json* grpc_json_add_number_string_child(grpc_json* parent, grpc_json* it,
const char* name, int64_t num) {
char* num_str;
gpr_asprintf(&num_str, "%" PRId64, num);
return grpc_json_create_child(it, parent, name, num_str, GRPC_JSON_STRING,
true);
}

@ -236,86 +236,4 @@ class Json {
} // namespace grpc_core
/* The various json types. */
typedef enum {
GRPC_JSON_OBJECT,
GRPC_JSON_ARRAY,
GRPC_JSON_STRING,
GRPC_JSON_NUMBER,
GRPC_JSON_TRUE,
GRPC_JSON_FALSE,
GRPC_JSON_NULL,
GRPC_JSON_TOP_LEVEL
} grpc_json_type;
/* A tree-like structure to hold json values. The key and value pointers
* are not owned by it.
*/
typedef struct grpc_json {
struct grpc_json* next;
struct grpc_json* prev;
struct grpc_json* child;
struct grpc_json* parent;
grpc_json_type type;
const char* key;
const char* value;
/* if set, destructor will free value */
bool owns_value;
} grpc_json;
/* The next two functions are going to parse the input string, and
* modify it in the process, in order to use its space to store
* all of the keys and values for the returned object tree.
*
* They assume UTF-8 input stream, and will output UTF-8 encoded
* strings in the tree. The input stream's UTF-8 isn't validated,
* as in, what you input is what you get as an output.
*
* All the keys and values in the grpc_json objects will be strings
* pointing at your input buffer.
*
* Delete the allocated tree afterward using grpc_json_destroy().
*/
grpc_json* grpc_json_parse_string_with_len(char* input, size_t size);
grpc_json* grpc_json_parse_string(char* input);
/* This function will create a new string using gpr_realloc, and will
* deserialize the grpc_json tree into it. It'll be zero-terminated,
* but will be allocated in chunks of 256 bytes.
*
* The indent parameter controls the way the output is formatted.
* If indent is 0, then newlines will be suppressed as well, and the
* output will be condensed at its maximum.
*/
char* grpc_json_dump_to_string(const grpc_json* json, int indent);
/* Use these to create or delete a grpc_json object.
* Deletion is recursive. We will not attempt to free any of the strings
* in any of the objects of that tree, unless the boolean, owns_value,
* is true.
*/
grpc_json* grpc_json_create(grpc_json_type type);
void grpc_json_destroy(grpc_json* json);
/* Links the child json object into the parent's json tree. If the parent
* already has children, then passing in the most recently added child as the
* sibling parameter is an optimization. For if sibling is NULL, this function
* will manually traverse the tree in order to find the right most sibling.
*/
grpc_json* grpc_json_link_child(grpc_json* parent, grpc_json* child,
grpc_json* sibling);
/* Creates a child json object into the parent's json tree then links it in
* as described above. */
grpc_json* grpc_json_create_child(grpc_json* sibling, grpc_json* parent,
const char* key, const char* value,
grpc_json_type type, bool owns_value);
/* Creates a child json string object from the integer num, then links the
json object into the parent's json tree */
grpc_json* grpc_json_add_number_string_child(grpc_json* parent, grpc_json* it,
const char* name, int64_t num);
#endif /* GRPC_CORE_LIB_JSON_JSON_H */

@ -21,16 +21,20 @@
#include <string.h>
#include <grpc/support/log.h>
#include <grpc/support/string_util.h>
#include "src/core/lib/json/json.h"
#define GRPC_JSON_MAX_DEPTH 255
#define GRPC_JSON_MAX_ERRORS 16
namespace grpc_core {
namespace {
class JsonReader {
public:
static grpc_json* Parse(char* input, size_t size);
static grpc_error* Parse(StringView input, Json* output);
private:
enum class Status {
@ -76,61 +80,51 @@ class JsonReader {
*/
static constexpr uint32_t GRPC_JSON_READ_CHAR_EOF = 0x7ffffff0;
JsonReader(char* input, size_t size)
: input_(reinterpret_cast<uint8_t*>(input)),
remaining_input_(size),
string_ptr_(input_) {
StringClear();
}
explicit JsonReader(StringView input)
: original_input_(reinterpret_cast<const uint8_t*>(input.data())),
input_(original_input_),
remaining_input_(input.size()) {}
Status Run();
uint32_t ReadChar();
bool IsComplete();
size_t CurrentIndex() const { return input_ - original_input_ - 1; }
void StringClear();
void StringAddChar(uint32_t c);
void StringAddUtf32(uint32_t c);
uint32_t ReadChar();
grpc_json* CreateAndLink(grpc_json_type type);
void ContainerBegins(grpc_json_type type);
grpc_json_type ContainerEnds();
Json* CreateAndLinkValue();
bool StartContainer(Json::Type type);
void EndContainer();
void SetKey();
void SetString();
bool SetNumber();
void SetTrue();
void SetFalse();
void SetNull();
bool IsComplete();
Status Run();
State state_ = State::GRPC_JSON_STATE_VALUE_BEGIN;
const uint8_t* original_input_;
const uint8_t* input_;
size_t remaining_input_;
int depth_ = 0;
int in_object_ = 0;
int in_array_ = 0;
int escaped_string_was_key_ = 0;
int container_just_begun_ = 0;
State state_ = State::GRPC_JSON_STATE_VALUE_BEGIN;
bool escaped_string_was_key_ = false;
bool container_just_begun_ = false;
uint16_t unicode_char_ = 0;
uint16_t unicode_high_surrogate_ = 0;
std::vector<grpc_error*> errors_;
bool truncated_errors_ = false;
grpc_json* top_ = nullptr;
grpc_json* current_container_ = nullptr;
grpc_json* current_value_ = nullptr;
uint8_t* input_;
size_t remaining_input_;
uint8_t* string_ptr_;
uint8_t* key_ = nullptr;
uint8_t* string_ = nullptr;
};
Json root_value_;
std::vector<Json*> stack_;
void JsonReader::StringClear() {
if (string_ != nullptr) {
GPR_ASSERT(string_ptr_ < input_);
*string_ptr_++ = 0;
}
string_ = string_ptr_;
}
std::string key_;
std::string string_;
};
void JsonReader::StringAddChar(uint32_t c) {
GPR_ASSERT(string_ptr_ < input_);
GPR_ASSERT(c <= 0xff);
*string_ptr_++ = static_cast<uint8_t>(c);
string_.push_back(static_cast<uint8_t>(c));
}
void JsonReader::StringAddUtf32(uint32_t c) {
@ -162,8 +156,8 @@ void JsonReader::StringAddUtf32(uint32_t c) {
uint32_t JsonReader::ReadChar() {
if (remaining_input_ == 0) return GRPC_JSON_READ_CHAR_EOF;
uint32_t r = *input_++;
remaining_input_--;
const uint32_t r = *input_++;
--remaining_input_;
if (r == 0) {
remaining_input_ = 0;
return GRPC_JSON_READ_CHAR_EOF;
@ -171,71 +165,98 @@ uint32_t JsonReader::ReadChar() {
return r;
}
/* Helper function to create a new grpc_json object and link it into
* our tree-in-progress inside our opaque structure.
*/
grpc_json* JsonReader::CreateAndLink(grpc_json_type type) {
grpc_json* json = grpc_json_create(type);
json->parent = current_container_;
json->prev = current_value_;
current_value_ = json;
if (json->prev) {
json->prev->next = json;
}
if (json->parent) {
if (!json->parent->child) {
json->parent->child = json;
Json* JsonReader::CreateAndLinkValue() {
Json* value;
if (stack_.empty()) {
value = &root_value_;
} else {
Json* parent = stack_.back();
if (parent->type() == Json::Type::OBJECT) {
if (parent->object_value().find(key_) != parent->object_value().end()) {
if (errors_.size() == GRPC_JSON_MAX_ERRORS) {
truncated_errors_ = true;
} else {
char* msg;
gpr_asprintf(&msg, "duplicate key \"%s\" at index %" PRIuPTR,
key_.c_str(), CurrentIndex());
errors_.push_back(GRPC_ERROR_CREATE_FROM_COPIED_STRING(msg));
gpr_free(msg);
}
}
value = &(*parent->mutable_object())[std::move(key_)];
} else {
GPR_ASSERT(parent->type() == Json::Type::ARRAY);
parent->mutable_array()->emplace_back();
value = &parent->mutable_array()->back();
}
if (json->parent->type == GRPC_JSON_OBJECT) {
json->key = reinterpret_cast<char*>(key_);
}
return value;
}
bool JsonReader::StartContainer(Json::Type type) {
if (stack_.size() == GRPC_JSON_MAX_DEPTH) {
if (errors_.size() == GRPC_JSON_MAX_ERRORS) {
truncated_errors_ = true;
} else {
char* msg;
gpr_asprintf(&msg, "exceeded max stack depth (%d) at index %" PRIuPTR,
GRPC_JSON_MAX_DEPTH, CurrentIndex());
errors_.push_back(GRPC_ERROR_CREATE_FROM_COPIED_STRING(msg));
gpr_free(msg);
}
return false;
}
if (top_ == nullptr) {
top_ = json;
Json* value = CreateAndLinkValue();
if (type == Json::Type::OBJECT) {
*value = Json::Object();
} else {
GPR_ASSERT(type == Json::Type::ARRAY);
*value = Json::Array();
}
return json;
stack_.push_back(value);
return true;
}
void JsonReader::ContainerBegins(grpc_json_type type) {
GPR_ASSERT(type == GRPC_JSON_ARRAY || type == GRPC_JSON_OBJECT);
grpc_json* container = CreateAndLink(type);
current_container_ = container;
current_value_ = nullptr;
void JsonReader::EndContainer() {
GPR_ASSERT(!stack_.empty());
stack_.pop_back();
}
grpc_json_type JsonReader::ContainerEnds() {
grpc_json_type container_type = GRPC_JSON_TOP_LEVEL;
GPR_ASSERT(current_container_);
current_value_ = current_container_;
current_container_ = current_container_->parent;
if (current_container_ != nullptr) {
container_type = current_container_->type;
}
return container_type;
void JsonReader::SetKey() {
key_ = std::move(string_);
string_.clear();
}
void JsonReader::SetKey() { key_ = string_; }
void JsonReader::SetString() {
grpc_json* json = CreateAndLink(GRPC_JSON_STRING);
json->value = reinterpret_cast<char*>(string_);
Json* value = CreateAndLinkValue();
*value = std::move(string_);
string_.clear();
}
bool JsonReader::SetNumber() {
grpc_json* json = CreateAndLink(GRPC_JSON_NUMBER);
json->value = reinterpret_cast<char*>(string_);
Json* value = CreateAndLinkValue();
*value = Json(std::move(string_), /*is_number=*/true);
string_.clear();
return true;
}
void JsonReader::SetTrue() { CreateAndLink(GRPC_JSON_TRUE); }
void JsonReader::SetTrue() {
Json* value = CreateAndLinkValue();
*value = true;
string_.clear();
}
void JsonReader::SetFalse() { CreateAndLink(GRPC_JSON_FALSE); }
void JsonReader::SetFalse() {
Json* value = CreateAndLinkValue();
*value = false;
string_.clear();
}
void JsonReader::SetNull() { CreateAndLink(GRPC_JSON_NULL); }
void JsonReader::SetNull() { CreateAndLinkValue(); }
bool JsonReader::IsComplete() {
return (depth_ == 0 && (state_ == State::GRPC_JSON_STATE_END ||
state_ == State::GRPC_JSON_STATE_VALUE_END));
return (stack_.empty() && (state_ == State::GRPC_JSON_STATE_END ||
state_ == State::GRPC_JSON_STATE_VALUE_END));
}
/* Call this function to start parsing the input. It will return the following:
@ -246,7 +267,7 @@ bool JsonReader::IsComplete() {
* internal state.
*/
JsonReader::Status JsonReader::Run() {
uint32_t c, success;
uint32_t c;
/* This state-machine is a strict implementation of ECMA-404 */
while (true) {
@ -277,8 +298,9 @@ JsonReader::Status JsonReader::Run() {
case State::GRPC_JSON_STATE_OBJECT_KEY_STRING:
case State::GRPC_JSON_STATE_VALUE_STRING:
if (c != ' ') return Status::GRPC_JSON_PARSE_ERROR;
if (unicode_high_surrogate_ != 0)
if (unicode_high_surrogate_ != 0) {
return Status::GRPC_JSON_PARSE_ERROR;
}
StringAddChar(c);
break;
@ -286,9 +308,7 @@ JsonReader::Status JsonReader::Run() {
case State::GRPC_JSON_STATE_VALUE_NUMBER_WITH_DECIMAL:
case State::GRPC_JSON_STATE_VALUE_NUMBER_ZERO:
case State::GRPC_JSON_STATE_VALUE_NUMBER_EPM:
success = static_cast<uint32_t>(SetNumber());
if (!success) return Status::GRPC_JSON_PARSE_ERROR;
StringClear();
if (!SetNumber()) return Status::GRPC_JSON_PARSE_ERROR;
state_ = State::GRPC_JSON_STATE_VALUE_END;
break;
@ -314,16 +334,16 @@ JsonReader::Status JsonReader::Run() {
case State::GRPC_JSON_STATE_VALUE_NUMBER_WITH_DECIMAL:
case State::GRPC_JSON_STATE_VALUE_NUMBER_ZERO:
case State::GRPC_JSON_STATE_VALUE_NUMBER_EPM:
if (depth_ == 0) {
if (stack_.empty()) {
return Status::GRPC_JSON_PARSE_ERROR;
} else if (c == '}' &&
stack_.back()->type() != Json::Type::OBJECT) {
return Status::GRPC_JSON_PARSE_ERROR;
} else if ((c == '}') && !in_object_) {
return Status::GRPC_JSON_PARSE_ERROR;
} else if ((c == ']') && !in_array_) {
} else if (c == ']' && stack_.back()->type() != Json::Type::ARRAY) {
return Status::GRPC_JSON_PARSE_ERROR;
}
success = static_cast<uint32_t>(SetNumber());
if (!success) return Status::GRPC_JSON_PARSE_ERROR;
StringClear();
if (!SetNumber()) return Status::GRPC_JSON_PARSE_ERROR;
state_ = State::GRPC_JSON_STATE_VALUE_END;
/* The missing break here is intentional. */
/* fallthrough */
@ -335,48 +355,38 @@ JsonReader::Status JsonReader::Run() {
if (state_ != State::GRPC_JSON_STATE_VALUE_END) {
return Status::GRPC_JSON_PARSE_ERROR;
}
if (in_object_) {
if (!stack_.empty() &&
stack_.back()->type() == Json::Type::OBJECT) {
state_ = State::GRPC_JSON_STATE_OBJECT_KEY_BEGIN;
} else if (in_array_) {
} else if (!stack_.empty() &&
stack_.back()->type() == Json::Type::ARRAY) {
state_ = State::GRPC_JSON_STATE_VALUE_BEGIN;
} else {
return Status::GRPC_JSON_PARSE_ERROR;
}
} else {
if (depth_-- == 0) return Status::GRPC_JSON_PARSE_ERROR;
if ((c == '}') && !in_object_) {
if (stack_.empty()) {
return Status::GRPC_JSON_PARSE_ERROR;
}
if ((c == '}') &&
(state_ == State::GRPC_JSON_STATE_OBJECT_KEY_BEGIN) &&
if (c == '}' && stack_.back()->type() != Json::Type::OBJECT) {
return Status::GRPC_JSON_PARSE_ERROR;
}
if (c == '}' &&
state_ == State::GRPC_JSON_STATE_OBJECT_KEY_BEGIN &&
!container_just_begun_) {
return Status::GRPC_JSON_PARSE_ERROR;
}
if ((c == ']') && !in_array_)
if (c == ']' && stack_.back()->type() != Json::Type::ARRAY) {
return Status::GRPC_JSON_PARSE_ERROR;
if ((c == ']') &&
(state_ == State::GRPC_JSON_STATE_VALUE_BEGIN) &&
}
if (c == ']' && state_ == State::GRPC_JSON_STATE_VALUE_BEGIN &&
!container_just_begun_) {
return Status::GRPC_JSON_PARSE_ERROR;
}
state_ = State::GRPC_JSON_STATE_VALUE_END;
switch (ContainerEnds()) {
case GRPC_JSON_OBJECT:
in_object_ = 1;
in_array_ = 0;
break;
case GRPC_JSON_ARRAY:
in_object_ = 0;
in_array_ = 1;
break;
case GRPC_JSON_TOP_LEVEL:
GPR_ASSERT(depth_ == 0);
in_object_ = 0;
in_array_ = 0;
state_ = State::GRPC_JSON_STATE_END;
break;
default:
GPR_UNREACHABLE_CODE(return Status::GRPC_JSON_INTERNAL_ERROR);
EndContainer();
if (stack_.empty()) {
state_ = State::GRPC_JSON_STATE_END;
}
}
break;
@ -390,12 +400,12 @@ JsonReader::Status JsonReader::Run() {
case '\\':
switch (state_) {
case State::GRPC_JSON_STATE_OBJECT_KEY_STRING:
escaped_string_was_key_ = 1;
escaped_string_was_key_ = true;
state_ = State::GRPC_JSON_STATE_STRING_ESCAPE;
break;
case State::GRPC_JSON_STATE_VALUE_STRING:
escaped_string_was_key_ = 0;
escaped_string_was_key_ = false;
state_ = State::GRPC_JSON_STATE_STRING_ESCAPE;
break;
@ -417,7 +427,7 @@ JsonReader::Status JsonReader::Run() {
break;
default:
container_just_begun_ = 0;
container_just_begun_ = false;
switch (state_) {
case State::GRPC_JSON_STATE_OBJECT_KEY_BEGIN:
if (c != '"') return Status::GRPC_JSON_PARSE_ERROR;
@ -431,7 +441,6 @@ JsonReader::Status JsonReader::Run() {
if (c == '"') {
state_ = State::GRPC_JSON_STATE_OBJECT_KEY_END;
SetKey();
StringClear();
} else {
if (c < 32) return Status::GRPC_JSON_PARSE_ERROR;
StringAddChar(c);
@ -445,7 +454,6 @@ JsonReader::Status JsonReader::Run() {
if (c == '"') {
state_ = State::GRPC_JSON_STATE_VALUE_END;
SetString();
StringClear();
} else {
if (c < 32) return Status::GRPC_JSON_PARSE_ERROR;
StringAddChar(c);
@ -495,20 +503,18 @@ JsonReader::Status JsonReader::Run() {
break;
case '{':
container_just_begun_ = 1;
ContainerBegins(GRPC_JSON_OBJECT);
depth_++;
container_just_begun_ = true;
if (!StartContainer(Json::Type::OBJECT)) {
return Status::GRPC_JSON_PARSE_ERROR;
}
state_ = State::GRPC_JSON_STATE_OBJECT_KEY_BEGIN;
in_object_ = 1;
in_array_ = 0;
break;
case '[':
container_just_begun_ = 1;
ContainerBegins(GRPC_JSON_ARRAY);
depth_++;
in_object_ = 0;
in_array_ = 1;
container_just_begun_ = true;
if (!StartContainer(Json::Type::ARRAY)) {
return Status::GRPC_JSON_PARSE_ERROR;
}
break;
default:
return Status::GRPC_JSON_PARSE_ERROR;
@ -809,29 +815,41 @@ JsonReader::Status JsonReader::Run() {
GPR_UNREACHABLE_CODE(return Status::GRPC_JSON_INTERNAL_ERROR);
}
grpc_json* JsonReader::Parse(char* input, size_t size) {
JsonReader reader(input, size);
grpc_error* JsonReader::Parse(StringView input, Json* output) {
JsonReader reader(input);
Status status = reader.Run();
grpc_json* json = reader.top_;
if ((status != Status::GRPC_JSON_DONE) && json != nullptr) {
grpc_json_destroy(json);
json = nullptr;
if (reader.truncated_errors_) {
reader.errors_.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING(
"too many errors encountered during JSON parsing -- fix reported "
"errors and try again to see additional errors"));
}
if (status == Status::GRPC_JSON_INTERNAL_ERROR) {
char* msg;
gpr_asprintf(&msg, "internal error in JSON parser at index %" PRIuPTR,
reader.CurrentIndex());
reader.errors_.push_back(GRPC_ERROR_CREATE_FROM_COPIED_STRING(msg));
gpr_free(msg);
} else if (status == Status::GRPC_JSON_PARSE_ERROR) {
char* msg;
gpr_asprintf(&msg, "JSON parse error at index %" PRIuPTR,
reader.CurrentIndex());
reader.errors_.push_back(GRPC_ERROR_CREATE_FROM_COPIED_STRING(msg));
gpr_free(msg);
}
if (!reader.errors_.empty()) {
return GRPC_ERROR_CREATE_FROM_VECTOR("JSON parsing failed",
&reader.errors_);
}
return json;
*output = std::move(reader.root_value_);
return GRPC_ERROR_NONE;
}
} // namespace
} // namespace grpc_core
/* And finally, let's define our public API. */
grpc_json* grpc_json_parse_string_with_len(char* input, size_t size) {
if (input == nullptr) return nullptr;
return grpc_core::JsonReader::Parse(input, size);
Json Json::Parse(StringView json_str, grpc_error** error) {
Json value;
*error = JsonReader::Parse(json_str, &value);
return value;
}
#define UNBOUND_JSON_STRING_LENGTH 0x7fffffff
grpc_json* grpc_json_parse_string(char* input) {
return grpc_json_parse_string_with_len(input, UNBOUND_JSON_STRING_LENGTH);
}
} // namespace grpc_core

@ -1,825 +0,0 @@
/*
*
* Copyright 2015-2016 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
#include <grpc/support/port_platform.h>
#include <string.h>
#include <grpc/support/log.h>
#include <grpc/support/string_util.h>
#include "src/core/lib/json/json.h"
namespace grpc_core {
namespace {
class JsonReader {
public:
static grpc_error* Parse(StringView input, Json* output);
private:
enum class Status {
GRPC_JSON_DONE, /* The parser finished successfully. */
GRPC_JSON_PARSE_ERROR, /* The parser found an error in the json stream. */
GRPC_JSON_INTERNAL_ERROR /* The parser got an internal error. */
};
enum class State {
GRPC_JSON_STATE_OBJECT_KEY_BEGIN,
GRPC_JSON_STATE_OBJECT_KEY_STRING,
GRPC_JSON_STATE_OBJECT_KEY_END,
GRPC_JSON_STATE_VALUE_BEGIN,
GRPC_JSON_STATE_VALUE_STRING,
GRPC_JSON_STATE_STRING_ESCAPE,
GRPC_JSON_STATE_STRING_ESCAPE_U1,
GRPC_JSON_STATE_STRING_ESCAPE_U2,
GRPC_JSON_STATE_STRING_ESCAPE_U3,
GRPC_JSON_STATE_STRING_ESCAPE_U4,
GRPC_JSON_STATE_VALUE_NUMBER,
GRPC_JSON_STATE_VALUE_NUMBER_WITH_DECIMAL,
GRPC_JSON_STATE_VALUE_NUMBER_ZERO,
GRPC_JSON_STATE_VALUE_NUMBER_DOT,
GRPC_JSON_STATE_VALUE_NUMBER_E,
GRPC_JSON_STATE_VALUE_NUMBER_EPM,
GRPC_JSON_STATE_VALUE_TRUE_R,
GRPC_JSON_STATE_VALUE_TRUE_U,
GRPC_JSON_STATE_VALUE_TRUE_E,
GRPC_JSON_STATE_VALUE_FALSE_A,
GRPC_JSON_STATE_VALUE_FALSE_L,
GRPC_JSON_STATE_VALUE_FALSE_S,
GRPC_JSON_STATE_VALUE_FALSE_E,
GRPC_JSON_STATE_VALUE_NULL_U,
GRPC_JSON_STATE_VALUE_NULL_L1,
GRPC_JSON_STATE_VALUE_NULL_L2,
GRPC_JSON_STATE_VALUE_END,
GRPC_JSON_STATE_END
};
/* The first non-unicode value is 0x110000. But let's pick
* a value high enough to start our error codes from. These
* values are safe to return from the read_char function.
*/
static constexpr uint32_t GRPC_JSON_READ_CHAR_EOF = 0x7ffffff0;
explicit JsonReader(StringView input)
: original_input_(reinterpret_cast<const uint8_t*>(input.data())),
input_(original_input_),
remaining_input_(input.size()) {}
Status Run();
uint32_t ReadChar();
bool IsComplete();
size_t CurrentIndex() const { return input_ - original_input_ - 1; }
void StringAddChar(uint32_t c);
void StringAddUtf32(uint32_t c);
Json* CreateAndLinkValue();
void StartContainer(Json::Type type);
void EndContainer();
void SetKey();
void SetString();
bool SetNumber();
void SetTrue();
void SetFalse();
void SetNull();
const uint8_t* original_input_;
const uint8_t* input_;
size_t remaining_input_;
State state_ = State::GRPC_JSON_STATE_VALUE_BEGIN;
bool escaped_string_was_key_ = false;
bool container_just_begun_ = false;
uint16_t unicode_char_ = 0;
uint16_t unicode_high_surrogate_ = 0;
std::vector<grpc_error*> errors_;
Json root_value_;
std::vector<Json*> stack_;
std::string key_;
std::string string_;
};
void JsonReader::StringAddChar(uint32_t c) {
string_.push_back(static_cast<uint8_t>(c));
}
void JsonReader::StringAddUtf32(uint32_t c) {
if (c <= 0x7f) {
StringAddChar(c);
} else if (c <= 0x7ff) {
uint32_t b1 = 0xc0 | ((c >> 6) & 0x1f);
uint32_t b2 = 0x80 | (c & 0x3f);
StringAddChar(b1);
StringAddChar(b2);
} else if (c <= 0xffff) {
uint32_t b1 = 0xe0 | ((c >> 12) & 0x0f);
uint32_t b2 = 0x80 | ((c >> 6) & 0x3f);
uint32_t b3 = 0x80 | (c & 0x3f);
StringAddChar(b1);
StringAddChar(b2);
StringAddChar(b3);
} else if (c <= 0x1fffff) {
uint32_t b1 = 0xf0 | ((c >> 18) & 0x07);
uint32_t b2 = 0x80 | ((c >> 12) & 0x3f);
uint32_t b3 = 0x80 | ((c >> 6) & 0x3f);
uint32_t b4 = 0x80 | (c & 0x3f);
StringAddChar(b1);
StringAddChar(b2);
StringAddChar(b3);
StringAddChar(b4);
}
}
uint32_t JsonReader::ReadChar() {
if (remaining_input_ == 0) return GRPC_JSON_READ_CHAR_EOF;
const uint32_t r = *input_++;
--remaining_input_;
if (r == 0) {
remaining_input_ = 0;
return GRPC_JSON_READ_CHAR_EOF;
}
return r;
}
Json* JsonReader::CreateAndLinkValue() {
Json* value;
if (stack_.empty()) {
value = &root_value_;
} else {
Json* parent = stack_.back();
if (parent->type() == Json::Type::OBJECT) {
if (parent->object_value().find(key_) != parent->object_value().end()) {
char* msg;
gpr_asprintf(&msg, "duplicate key \"%s\" at index %" PRIuPTR,
key_.c_str(), CurrentIndex());
errors_.push_back(GRPC_ERROR_CREATE_FROM_COPIED_STRING(msg));
gpr_free(msg);
}
value = &(*parent->mutable_object())[std::move(key_)];
} else {
GPR_ASSERT(parent->type() == Json::Type::ARRAY);
parent->mutable_array()->emplace_back();
value = &parent->mutable_array()->back();
}
}
return value;
}
void JsonReader::StartContainer(Json::Type type) {
Json* value = CreateAndLinkValue();
if (type == Json::Type::OBJECT) {
*value = Json::Object();
} else {
GPR_ASSERT(type == Json::Type::ARRAY);
*value = Json::Array();
}
stack_.push_back(value);
}
void JsonReader::EndContainer() {
GPR_ASSERT(!stack_.empty());
stack_.pop_back();
}
void JsonReader::SetKey() {
key_ = std::move(string_);
string_.clear();
}
void JsonReader::SetString() {
Json* value = CreateAndLinkValue();
*value = std::move(string_);
string_.clear();
}
bool JsonReader::SetNumber() {
Json* value = CreateAndLinkValue();
*value = Json(std::move(string_), /*is_number=*/true);
string_.clear();
return true;
}
void JsonReader::SetTrue() {
Json* value = CreateAndLinkValue();
*value = true;
string_.clear();
}
void JsonReader::SetFalse() {
Json* value = CreateAndLinkValue();
*value = false;
string_.clear();
}
void JsonReader::SetNull() { CreateAndLinkValue(); }
bool JsonReader::IsComplete() {
return (stack_.empty() && (state_ == State::GRPC_JSON_STATE_END ||
state_ == State::GRPC_JSON_STATE_VALUE_END));
}
/* Call this function to start parsing the input. It will return the following:
* . GRPC_JSON_DONE if the input got eof, and the parsing finished
* successfully.
* . GRPC_JSON_PARSE_ERROR if the input was somehow invalid.
* . GRPC_JSON_INTERNAL_ERROR if the parser somehow ended into an invalid
* internal state.
*/
JsonReader::Status JsonReader::Run() {
uint32_t c;
/* This state-machine is a strict implementation of ECMA-404 */
while (true) {
c = ReadChar();
switch (c) {
/* Let's process the error case first. */
case GRPC_JSON_READ_CHAR_EOF:
if (IsComplete()) {
return Status::GRPC_JSON_DONE;
} else {
return Status::GRPC_JSON_PARSE_ERROR;
}
break;
/* Processing whitespaces. */
case ' ':
case '\t':
case '\n':
case '\r':
switch (state_) {
case State::GRPC_JSON_STATE_OBJECT_KEY_BEGIN:
case State::GRPC_JSON_STATE_OBJECT_KEY_END:
case State::GRPC_JSON_STATE_VALUE_BEGIN:
case State::GRPC_JSON_STATE_VALUE_END:
case State::GRPC_JSON_STATE_END:
break;
case State::GRPC_JSON_STATE_OBJECT_KEY_STRING:
case State::GRPC_JSON_STATE_VALUE_STRING:
if (c != ' ') return Status::GRPC_JSON_PARSE_ERROR;
if (unicode_high_surrogate_ != 0) {
return Status::GRPC_JSON_PARSE_ERROR;
}
StringAddChar(c);
break;
case State::GRPC_JSON_STATE_VALUE_NUMBER:
case State::GRPC_JSON_STATE_VALUE_NUMBER_WITH_DECIMAL:
case State::GRPC_JSON_STATE_VALUE_NUMBER_ZERO:
case State::GRPC_JSON_STATE_VALUE_NUMBER_EPM:
if (!SetNumber()) return Status::GRPC_JSON_PARSE_ERROR;
state_ = State::GRPC_JSON_STATE_VALUE_END;
break;
default:
return Status::GRPC_JSON_PARSE_ERROR;
}
break;
/* Value, object or array terminations. */
case ',':
case '}':
case ']':
switch (state_) {
case State::GRPC_JSON_STATE_OBJECT_KEY_STRING:
case State::GRPC_JSON_STATE_VALUE_STRING:
if (unicode_high_surrogate_ != 0) {
return Status::GRPC_JSON_PARSE_ERROR;
}
StringAddChar(c);
break;
case State::GRPC_JSON_STATE_VALUE_NUMBER:
case State::GRPC_JSON_STATE_VALUE_NUMBER_WITH_DECIMAL:
case State::GRPC_JSON_STATE_VALUE_NUMBER_ZERO:
case State::GRPC_JSON_STATE_VALUE_NUMBER_EPM:
if (stack_.empty()) {
return Status::GRPC_JSON_PARSE_ERROR;
} else if (c == '}' &&
stack_.back()->type() != Json::Type::OBJECT) {
return Status::GRPC_JSON_PARSE_ERROR;
return Status::GRPC_JSON_PARSE_ERROR;
} else if (c == ']' && stack_.back()->type() != Json::Type::ARRAY) {
return Status::GRPC_JSON_PARSE_ERROR;
}
if (!SetNumber()) return Status::GRPC_JSON_PARSE_ERROR;
state_ = State::GRPC_JSON_STATE_VALUE_END;
/* The missing break here is intentional. */
/* fallthrough */
case State::GRPC_JSON_STATE_VALUE_END:
case State::GRPC_JSON_STATE_OBJECT_KEY_BEGIN:
case State::GRPC_JSON_STATE_VALUE_BEGIN:
if (c == ',') {
if (state_ != State::GRPC_JSON_STATE_VALUE_END) {
return Status::GRPC_JSON_PARSE_ERROR;
}
if (!stack_.empty() &&
stack_.back()->type() == Json::Type::OBJECT) {
state_ = State::GRPC_JSON_STATE_OBJECT_KEY_BEGIN;
} else if (!stack_.empty() &&
stack_.back()->type() == Json::Type::ARRAY) {
state_ = State::GRPC_JSON_STATE_VALUE_BEGIN;
} else {
return Status::GRPC_JSON_PARSE_ERROR;
}
} else {
if (stack_.empty()) {
return Status::GRPC_JSON_PARSE_ERROR;
}
if (c == '}' && stack_.back()->type() != Json::Type::OBJECT) {
return Status::GRPC_JSON_PARSE_ERROR;
}
if (c == '}' &&
state_ == State::GRPC_JSON_STATE_OBJECT_KEY_BEGIN &&
!container_just_begun_) {
return Status::GRPC_JSON_PARSE_ERROR;
}
if (c == ']' && stack_.back()->type() != Json::Type::ARRAY) {
return Status::GRPC_JSON_PARSE_ERROR;
}
if (c == ']' && state_ == State::GRPC_JSON_STATE_VALUE_BEGIN &&
!container_just_begun_) {
return Status::GRPC_JSON_PARSE_ERROR;
}
state_ = State::GRPC_JSON_STATE_VALUE_END;
EndContainer();
if (stack_.empty()) {
state_ = State::GRPC_JSON_STATE_END;
}
}
break;
default:
return Status::GRPC_JSON_PARSE_ERROR;
}
break;
/* In-string escaping. */
case '\\':
switch (state_) {
case State::GRPC_JSON_STATE_OBJECT_KEY_STRING:
escaped_string_was_key_ = true;
state_ = State::GRPC_JSON_STATE_STRING_ESCAPE;
break;
case State::GRPC_JSON_STATE_VALUE_STRING:
escaped_string_was_key_ = false;
state_ = State::GRPC_JSON_STATE_STRING_ESCAPE;
break;
/* This is the \\ case. */
case State::GRPC_JSON_STATE_STRING_ESCAPE:
if (unicode_high_surrogate_ != 0)
return Status::GRPC_JSON_PARSE_ERROR;
StringAddChar('\\');
if (escaped_string_was_key_) {
state_ = State::GRPC_JSON_STATE_OBJECT_KEY_STRING;
} else {
state_ = State::GRPC_JSON_STATE_VALUE_STRING;
}
break;
default:
return Status::GRPC_JSON_PARSE_ERROR;
}
break;
default:
container_just_begun_ = false;
switch (state_) {
case State::GRPC_JSON_STATE_OBJECT_KEY_BEGIN:
if (c != '"') return Status::GRPC_JSON_PARSE_ERROR;
state_ = State::GRPC_JSON_STATE_OBJECT_KEY_STRING;
break;
case State::GRPC_JSON_STATE_OBJECT_KEY_STRING:
if (unicode_high_surrogate_ != 0) {
return Status::GRPC_JSON_PARSE_ERROR;
}
if (c == '"') {
state_ = State::GRPC_JSON_STATE_OBJECT_KEY_END;
SetKey();
} else {
if (c < 32) return Status::GRPC_JSON_PARSE_ERROR;
StringAddChar(c);
}
break;
case State::GRPC_JSON_STATE_VALUE_STRING:
if (unicode_high_surrogate_ != 0) {
return Status::GRPC_JSON_PARSE_ERROR;
}
if (c == '"') {
state_ = State::GRPC_JSON_STATE_VALUE_END;
SetString();
} else {
if (c < 32) return Status::GRPC_JSON_PARSE_ERROR;
StringAddChar(c);
}
break;
case State::GRPC_JSON_STATE_OBJECT_KEY_END:
if (c != ':') return Status::GRPC_JSON_PARSE_ERROR;
state_ = State::GRPC_JSON_STATE_VALUE_BEGIN;
break;
case State::GRPC_JSON_STATE_VALUE_BEGIN:
switch (c) {
case 't':
state_ = State::GRPC_JSON_STATE_VALUE_TRUE_R;
break;
case 'f':
state_ = State::GRPC_JSON_STATE_VALUE_FALSE_A;
break;
case 'n':
state_ = State::GRPC_JSON_STATE_VALUE_NULL_U;
break;
case '"':
state_ = State::GRPC_JSON_STATE_VALUE_STRING;
break;
case '0':
StringAddChar(c);
state_ = State::GRPC_JSON_STATE_VALUE_NUMBER_ZERO;
break;
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
case '-':
StringAddChar(c);
state_ = State::GRPC_JSON_STATE_VALUE_NUMBER;
break;
case '{':
container_just_begun_ = true;
StartContainer(Json::Type::OBJECT);
state_ = State::GRPC_JSON_STATE_OBJECT_KEY_BEGIN;
break;
case '[':
container_just_begun_ = true;
StartContainer(Json::Type::ARRAY);
break;
default:
return Status::GRPC_JSON_PARSE_ERROR;
}
break;
case State::GRPC_JSON_STATE_STRING_ESCAPE:
if (escaped_string_was_key_) {
state_ = State::GRPC_JSON_STATE_OBJECT_KEY_STRING;
} else {
state_ = State::GRPC_JSON_STATE_VALUE_STRING;
}
if (unicode_high_surrogate_ && c != 'u') {
return Status::GRPC_JSON_PARSE_ERROR;
}
switch (c) {
case '"':
case '/':
StringAddChar(c);
break;
case 'b':
StringAddChar('\b');
break;
case 'f':
StringAddChar('\f');
break;
case 'n':
StringAddChar('\n');
break;
case 'r':
StringAddChar('\r');
break;
case 't':
StringAddChar('\t');
break;
case 'u':
state_ = State::GRPC_JSON_STATE_STRING_ESCAPE_U1;
unicode_char_ = 0;
break;
default:
return Status::GRPC_JSON_PARSE_ERROR;
}
break;
case State::GRPC_JSON_STATE_STRING_ESCAPE_U1:
case State::GRPC_JSON_STATE_STRING_ESCAPE_U2:
case State::GRPC_JSON_STATE_STRING_ESCAPE_U3:
case State::GRPC_JSON_STATE_STRING_ESCAPE_U4:
if ((c >= '0') && (c <= '9')) {
c -= '0';
} else if ((c >= 'A') && (c <= 'F')) {
c -= 'A' - 10;
} else if ((c >= 'a') && (c <= 'f')) {
c -= 'a' - 10;
} else {
return Status::GRPC_JSON_PARSE_ERROR;
}
unicode_char_ = static_cast<uint16_t>(unicode_char_ << 4);
unicode_char_ = static_cast<uint16_t>(unicode_char_ | c);
switch (state_) {
case State::GRPC_JSON_STATE_STRING_ESCAPE_U1:
state_ = State::GRPC_JSON_STATE_STRING_ESCAPE_U2;
break;
case State::GRPC_JSON_STATE_STRING_ESCAPE_U2:
state_ = State::GRPC_JSON_STATE_STRING_ESCAPE_U3;
break;
case State::GRPC_JSON_STATE_STRING_ESCAPE_U3:
state_ = State::GRPC_JSON_STATE_STRING_ESCAPE_U4;
break;
case State::GRPC_JSON_STATE_STRING_ESCAPE_U4:
/* See grpc_json_writer_escape_string to have a description
* of what's going on here.
*/
if ((unicode_char_ & 0xfc00) == 0xd800) {
/* high surrogate utf-16 */
if (unicode_high_surrogate_ != 0)
return Status::GRPC_JSON_PARSE_ERROR;
unicode_high_surrogate_ = unicode_char_;
} else if ((unicode_char_ & 0xfc00) == 0xdc00) {
/* low surrogate utf-16 */
uint32_t utf32;
if (unicode_high_surrogate_ == 0)
return Status::GRPC_JSON_PARSE_ERROR;
utf32 = 0x10000;
utf32 += static_cast<uint32_t>(
(unicode_high_surrogate_ - 0xd800) * 0x400);
utf32 += static_cast<uint32_t>(unicode_char_ - 0xdc00);
StringAddUtf32(utf32);
unicode_high_surrogate_ = 0;
} else {
/* anything else */
if (unicode_high_surrogate_ != 0)
return Status::GRPC_JSON_PARSE_ERROR;
StringAddUtf32(unicode_char_);
}
if (escaped_string_was_key_) {
state_ = State::GRPC_JSON_STATE_OBJECT_KEY_STRING;
} else {
state_ = State::GRPC_JSON_STATE_VALUE_STRING;
}
break;
default:
GPR_UNREACHABLE_CODE(return Status::GRPC_JSON_INTERNAL_ERROR);
}
break;
case State::GRPC_JSON_STATE_VALUE_NUMBER:
StringAddChar(c);
switch (c) {
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
break;
case 'e':
case 'E':
state_ = State::GRPC_JSON_STATE_VALUE_NUMBER_E;
break;
case '.':
state_ = State::GRPC_JSON_STATE_VALUE_NUMBER_DOT;
break;
default:
return Status::GRPC_JSON_PARSE_ERROR;
}
break;
case State::GRPC_JSON_STATE_VALUE_NUMBER_WITH_DECIMAL:
StringAddChar(c);
switch (c) {
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
break;
case 'e':
case 'E':
state_ = State::GRPC_JSON_STATE_VALUE_NUMBER_E;
break;
default:
return Status::GRPC_JSON_PARSE_ERROR;
}
break;
case State::GRPC_JSON_STATE_VALUE_NUMBER_ZERO:
if (c != '.') return Status::GRPC_JSON_PARSE_ERROR;
StringAddChar(c);
state_ = State::GRPC_JSON_STATE_VALUE_NUMBER_DOT;
break;
case State::GRPC_JSON_STATE_VALUE_NUMBER_DOT:
StringAddChar(c);
switch (c) {
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
state_ = State::GRPC_JSON_STATE_VALUE_NUMBER_WITH_DECIMAL;
break;
default:
return Status::GRPC_JSON_PARSE_ERROR;
}
break;
case State::GRPC_JSON_STATE_VALUE_NUMBER_E:
StringAddChar(c);
switch (c) {
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
case '+':
case '-':
state_ = State::GRPC_JSON_STATE_VALUE_NUMBER_EPM;
break;
default:
return Status::GRPC_JSON_PARSE_ERROR;
}
break;
case State::GRPC_JSON_STATE_VALUE_NUMBER_EPM:
StringAddChar(c);
switch (c) {
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
break;
default:
return Status::GRPC_JSON_PARSE_ERROR;
}
break;
case State::GRPC_JSON_STATE_VALUE_TRUE_R:
if (c != 'r') return Status::GRPC_JSON_PARSE_ERROR;
state_ = State::GRPC_JSON_STATE_VALUE_TRUE_U;
break;
case State::GRPC_JSON_STATE_VALUE_TRUE_U:
if (c != 'u') return Status::GRPC_JSON_PARSE_ERROR;
state_ = State::GRPC_JSON_STATE_VALUE_TRUE_E;
break;
case State::GRPC_JSON_STATE_VALUE_TRUE_E:
if (c != 'e') return Status::GRPC_JSON_PARSE_ERROR;
SetTrue();
state_ = State::GRPC_JSON_STATE_VALUE_END;
break;
case State::GRPC_JSON_STATE_VALUE_FALSE_A:
if (c != 'a') return Status::GRPC_JSON_PARSE_ERROR;
state_ = State::GRPC_JSON_STATE_VALUE_FALSE_L;
break;
case State::GRPC_JSON_STATE_VALUE_FALSE_L:
if (c != 'l') return Status::GRPC_JSON_PARSE_ERROR;
state_ = State::GRPC_JSON_STATE_VALUE_FALSE_S;
break;
case State::GRPC_JSON_STATE_VALUE_FALSE_S:
if (c != 's') return Status::GRPC_JSON_PARSE_ERROR;
state_ = State::GRPC_JSON_STATE_VALUE_FALSE_E;
break;
case State::GRPC_JSON_STATE_VALUE_FALSE_E:
if (c != 'e') return Status::GRPC_JSON_PARSE_ERROR;
SetFalse();
state_ = State::GRPC_JSON_STATE_VALUE_END;
break;
case State::GRPC_JSON_STATE_VALUE_NULL_U:
if (c != 'u') return Status::GRPC_JSON_PARSE_ERROR;
state_ = State::GRPC_JSON_STATE_VALUE_NULL_L1;
break;
case State::GRPC_JSON_STATE_VALUE_NULL_L1:
if (c != 'l') return Status::GRPC_JSON_PARSE_ERROR;
state_ = State::GRPC_JSON_STATE_VALUE_NULL_L2;
break;
case State::GRPC_JSON_STATE_VALUE_NULL_L2:
if (c != 'l') return Status::GRPC_JSON_PARSE_ERROR;
SetNull();
state_ = State::GRPC_JSON_STATE_VALUE_END;
break;
/* All of the VALUE_END cases are handled in the specialized case
* above. */
case State::GRPC_JSON_STATE_VALUE_END:
switch (c) {
case ',':
case '}':
case ']':
GPR_UNREACHABLE_CODE(return Status::GRPC_JSON_INTERNAL_ERROR);
break;
default:
return Status::GRPC_JSON_PARSE_ERROR;
}
break;
case State::GRPC_JSON_STATE_END:
return Status::GRPC_JSON_PARSE_ERROR;
}
}
}
GPR_UNREACHABLE_CODE(return Status::GRPC_JSON_INTERNAL_ERROR);
}
grpc_error* JsonReader::Parse(StringView input, Json* output) {
JsonReader reader(input);
Status status = reader.Run();
if (status == Status::GRPC_JSON_INTERNAL_ERROR) {
char* msg;
gpr_asprintf(&msg, "internal error in JSON parser at index %" PRIuPTR,
reader.CurrentIndex());
reader.errors_.push_back(GRPC_ERROR_CREATE_FROM_COPIED_STRING(msg));
gpr_free(msg);
} else if (status == Status::GRPC_JSON_PARSE_ERROR) {
char* msg;
gpr_asprintf(&msg, "JSON parse error at index %" PRIuPTR,
reader.CurrentIndex());
reader.errors_.push_back(GRPC_ERROR_CREATE_FROM_COPIED_STRING(msg));
gpr_free(msg);
}
if (!reader.errors_.empty()) {
return GRPC_ERROR_CREATE_FROM_VECTOR("JSON parsing failed",
&reader.errors_);
}
*output = std::move(reader.root_value_);
return GRPC_ERROR_NONE;
}
} // namespace
Json Json::Parse(StringView json_str, grpc_error** error) {
Json value;
*error = JsonReader::Parse(json_str, &value);
return value;
}
} // namespace grpc_core

@ -26,6 +26,8 @@
#include "src/core/lib/json/json.h"
#include "src/core/lib/gprpp/string_view.h"
namespace grpc_core {
namespace {
@ -43,35 +45,33 @@ namespace {
*/
class JsonWriter {
public:
static char* Dump(const grpc_json* json, int indent);
static std::string Dump(const Json& value, int indent);
private:
explicit JsonWriter(int indent) : indent_(indent) {}
void OutputCheck(size_t needed);
void OutputChar(char c);
void OutputStringWithLen(const char* str, size_t len);
void OutputString(const char* str);
void OutputString(const StringView str);
void OutputIndent();
void ValueEnd();
void EscapeUtf16(uint16_t utf16);
void EscapeString(const char* string);
void ContainerBegins(grpc_json_type type);
void ContainerEnds(grpc_json_type type);
void ObjectKey(const char* string);
void ValueRaw(const char* string);
void ValueRawWithLen(const char* string, size_t len);
void ValueString(const char* string);
void DumpRecursive(const grpc_json* json, int in_object);
void EscapeString(const std::string& string);
void ContainerBegins(Json::Type type);
void ContainerEnds(Json::Type type);
void ObjectKey(const std::string& string);
void ValueRaw(const std::string& string);
void ValueString(const std::string& string);
void DumpObject(const Json::Object& object);
void DumpArray(const Json::Array& array);
void DumpValue(const Json& value);
int indent_;
int depth_ = 0;
int container_empty_ = 1;
int got_key_ = 0;
char* output_ = nullptr;
size_t free_space_ = 0;
size_t string_len_ = 0;
size_t allocated_ = 0;
bool container_empty_ = true;
bool got_key_ = false;
std::string output_;
};
/* This function checks if there's enough space left in the output buffer,
@ -79,31 +79,22 @@ class JsonWriter {
* bytes at a time (or multiples thereof).
*/
void JsonWriter::OutputCheck(size_t needed) {
if (free_space_ >= needed) return;
needed -= free_space_;
size_t free_space = output_.capacity() - output_.size();
if (free_space >= needed) return;
needed -= free_space;
/* Round up by 256 bytes. */
needed = (needed + 0xff) & ~0xffU;
output_ = static_cast<char*>(gpr_realloc(output_, allocated_ + needed));
free_space_ += needed;
allocated_ += needed;
output_.reserve(output_.capacity() + needed);
}
void JsonWriter::OutputChar(char c) {
OutputCheck(1);
output_[string_len_++] = c;
free_space_--;
output_.push_back(c);
}
void JsonWriter::OutputStringWithLen(const char* str, size_t len) {
OutputCheck(len);
memcpy(output_ + string_len_, str, len);
string_len_ += len;
free_space_ -= len;
}
void JsonWriter::OutputString(const char* str) {
size_t len = strlen(str);
OutputStringWithLen(str, len);
void JsonWriter::OutputString(const StringView str) {
OutputCheck(str.size());
output_.append(str.data(), str.size());
}
void JsonWriter::OutputIndent() {
@ -119,16 +110,16 @@ void JsonWriter::OutputIndent() {
return;
}
while (spaces >= (sizeof(spacesstr) - 1)) {
OutputStringWithLen(spacesstr, sizeof(spacesstr) - 1);
OutputString(StringView(spacesstr, sizeof(spacesstr) - 1));
spaces -= static_cast<unsigned>(sizeof(spacesstr) - 1);
}
if (spaces == 0) return;
OutputStringWithLen(spacesstr + sizeof(spacesstr) - 1 - spaces, spaces);
OutputString(StringView(spacesstr + sizeof(spacesstr) - 1 - spaces, spaces));
}
void JsonWriter::ValueEnd() {
if (container_empty_) {
container_empty_ = 0;
container_empty_ = false;
if (indent_ == 0 || depth_ == 0) return;
OutputChar('\n');
} else {
@ -140,17 +131,17 @@ void JsonWriter::ValueEnd() {
void JsonWriter::EscapeUtf16(uint16_t utf16) {
static const char hex[] = "0123456789abcdef";
OutputStringWithLen("\\u", 2);
OutputString(StringView("\\u", 2));
OutputChar(hex[(utf16 >> 12) & 0x0f]);
OutputChar(hex[(utf16 >> 8) & 0x0f]);
OutputChar(hex[(utf16 >> 4) & 0x0f]);
OutputChar(hex[(utf16)&0x0f]);
}
void JsonWriter::EscapeString(const char* string) {
void JsonWriter::EscapeString(const std::string& string) {
OutputChar('"');
while (true) {
uint8_t c = static_cast<uint8_t>(*string++);
for (size_t idx = 0; idx < string.size(); ++idx) {
uint8_t c = static_cast<uint8_t>(string[idx]);
if (c == 0) {
break;
} else if (c >= 32 && c <= 126) {
@ -159,19 +150,19 @@ void JsonWriter::EscapeString(const char* string) {
} else if (c < 32 || c == 127) {
switch (c) {
case '\b':
OutputStringWithLen("\\b", 2);
OutputString(StringView("\\b", 2));
break;
case '\f':
OutputStringWithLen("\\f", 2);
OutputString(StringView("\\f", 2));
break;
case '\n':
OutputStringWithLen("\\n", 2);
OutputString(StringView("\\n", 2));
break;
case '\r':
OutputStringWithLen("\\r", 2);
OutputString(StringView("\\r", 2));
break;
case '\t':
OutputStringWithLen("\\t", 2);
OutputString(StringView("\\t", 2));
break;
default:
EscapeUtf16(c);
@ -196,7 +187,13 @@ void JsonWriter::EscapeString(const char* string) {
}
for (i = 0; i < extra; i++) {
utf32 <<= 6;
c = static_cast<uint8_t>(*string++);
++idx;
/* Breaks out and bail if we hit the end of the string. */
if (idx == string.size()) {
valid = 0;
break;
}
c = static_cast<uint8_t>(string[idx]);
/* Breaks out and bail on any invalid UTF-8 sequence, including \0. */
if ((c & 0xc0) != 0x80) {
valid = 0;
@ -239,98 +236,101 @@ void JsonWriter::EscapeString(const char* string) {
OutputChar('"');
}
void JsonWriter::ContainerBegins(grpc_json_type type) {
void JsonWriter::ContainerBegins(Json::Type type) {
if (!got_key_) ValueEnd();
OutputIndent();
OutputChar(type == GRPC_JSON_OBJECT ? '{' : '[');
container_empty_ = 1;
got_key_ = 0;
OutputChar(type == Json::Type::OBJECT ? '{' : '[');
container_empty_ = true;
got_key_ = false;
depth_++;
}
void JsonWriter::ContainerEnds(grpc_json_type type) {
void JsonWriter::ContainerEnds(Json::Type type) {
if (indent_ && !container_empty_) OutputChar('\n');
depth_--;
if (!container_empty_) OutputIndent();
OutputChar(type == GRPC_JSON_OBJECT ? '}' : ']');
container_empty_ = 0;
got_key_ = 0;
OutputChar(type == Json::Type::OBJECT ? '}' : ']');
container_empty_ = false;
got_key_ = false;
}
void JsonWriter::ObjectKey(const char* string) {
void JsonWriter::ObjectKey(const std::string& string) {
ValueEnd();
OutputIndent();
EscapeString(string);
OutputChar(':');
got_key_ = 1;
got_key_ = true;
}
void JsonWriter::ValueRaw(const char* string) {
void JsonWriter::ValueRaw(const std::string& string) {
if (!got_key_) ValueEnd();
OutputIndent();
OutputString(string);
got_key_ = 0;
got_key_ = false;
}
void JsonWriter::ValueRawWithLen(const char* string, size_t len) {
void JsonWriter::ValueString(const std::string& string) {
if (!got_key_) ValueEnd();
OutputIndent();
OutputStringWithLen(string, len);
got_key_ = 0;
EscapeString(string);
got_key_ = false;
}
void JsonWriter::ValueString(const char* string) {
if (!got_key_) ValueEnd();
OutputIndent();
EscapeString(string);
got_key_ = 0;
void JsonWriter::DumpObject(const Json::Object& object) {
ContainerBegins(Json::Type::OBJECT);
for (const auto& p : object) {
ObjectKey(p.first.data());
DumpValue(p.second);
}
ContainerEnds(Json::Type::OBJECT);
}
void JsonWriter::DumpRecursive(const grpc_json* json, int in_object) {
while (json != nullptr) {
if (in_object) ObjectKey(json->key);
switch (json->type) {
case GRPC_JSON_OBJECT:
case GRPC_JSON_ARRAY:
ContainerBegins(json->type);
if (json->child != nullptr) {
DumpRecursive(json->child, json->type == GRPC_JSON_OBJECT);
}
ContainerEnds(json->type);
break;
case GRPC_JSON_STRING:
ValueString(json->value);
break;
case GRPC_JSON_NUMBER:
ValueRaw(json->value);
break;
case GRPC_JSON_TRUE:
ValueRawWithLen("true", 4);
break;
case GRPC_JSON_FALSE:
ValueRawWithLen("false", 5);
break;
case GRPC_JSON_NULL:
ValueRawWithLen("null", 4);
break;
default:
GPR_UNREACHABLE_CODE(abort());
}
json = json->next;
void JsonWriter::DumpArray(const Json::Array& array) {
ContainerBegins(Json::Type::ARRAY);
for (const auto& v : array) {
DumpValue(v);
}
ContainerEnds(Json::Type::ARRAY);
}
char* JsonWriter::Dump(const grpc_json* json, int indent) {
void JsonWriter::DumpValue(const Json& value) {
switch (value.type()) {
case Json::Type::OBJECT:
DumpObject(value.object_value());
break;
case Json::Type::ARRAY:
DumpArray(value.array_value());
break;
case Json::Type::STRING:
ValueString(value.string_value());
break;
case Json::Type::NUMBER:
ValueRaw(value.string_value());
break;
case Json::Type::JSON_TRUE:
ValueRaw(std::string("true", 4));
break;
case Json::Type::JSON_FALSE:
ValueRaw(std::string("false", 5));
break;
case Json::Type::JSON_NULL:
ValueRaw(std::string("null", 4));
break;
default:
GPR_UNREACHABLE_CODE(abort());
}
}
std::string JsonWriter::Dump(const Json& value, int indent) {
JsonWriter writer(indent);
writer.DumpRecursive(json, 0);
writer.OutputChar(0);
return writer.output_;
writer.DumpValue(value);
return std::move(writer.output_);
}
} // namespace
} // namespace grpc_core
char* grpc_json_dump_to_string(const grpc_json* json, int indent) {
return grpc_core::JsonWriter::Dump(json, indent);
std::string Json::Dump(int indent) const {
return JsonWriter::Dump(*this, indent);
}
} // namespace grpc_core

@ -1,336 +0,0 @@
/*
*
* Copyright 2015 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
#include <grpc/support/port_platform.h>
#include <stdlib.h>
#include <string.h>
#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
#include "src/core/lib/json/json.h"
#include "src/core/lib/gprpp/string_view.h"
namespace grpc_core {
namespace {
/* The idea of the writer is basically symmetrical of the reader. While the
* reader emits various calls to your code, the writer takes basically the
* same calls and emit json out of it. It doesn't try to make any check on
* the order of the calls you do on it. Meaning you can theorically force
* it to generate invalid json.
*
* Also, unlike the reader, the writer expects UTF-8 encoded input strings.
* These strings will be UTF-8 validated, and any invalid character will
* cut the conversion short, before any invalid UTF-8 sequence, thus forming
* a valid UTF-8 string overall.
*/
class JsonWriter {
public:
static std::string Dump(const Json& value, int indent);
private:
explicit JsonWriter(int indent) : indent_(indent) {}
void OutputCheck(size_t needed);
void OutputChar(char c);
void OutputString(const StringView str);
void OutputIndent();
void ValueEnd();
void EscapeUtf16(uint16_t utf16);
void EscapeString(const std::string& string);
void ContainerBegins(Json::Type type);
void ContainerEnds(Json::Type type);
void ObjectKey(const std::string& string);
void ValueRaw(const std::string& string);
void ValueString(const std::string& string);
void DumpObject(const Json::Object& object);
void DumpArray(const Json::Array& array);
void DumpValue(const Json& value);
int indent_;
int depth_ = 0;
bool container_empty_ = true;
bool got_key_ = false;
std::string output_;
};
/* This function checks if there's enough space left in the output buffer,
* and will enlarge it if necessary. We're only allocating chunks of 256
* bytes at a time (or multiples thereof).
*/
void JsonWriter::OutputCheck(size_t needed) {
size_t free_space = output_.capacity() - output_.size();
if (free_space >= needed) return;
needed -= free_space;
/* Round up by 256 bytes. */
needed = (needed + 0xff) & ~0xffU;
output_.reserve(output_.capacity() + needed);
}
void JsonWriter::OutputChar(char c) {
OutputCheck(1);
output_.push_back(c);
}
void JsonWriter::OutputString(const StringView str) {
OutputCheck(str.size());
output_.append(str.data(), str.size());
}
void JsonWriter::OutputIndent() {
static const char spacesstr[] =
" "
" "
" "
" ";
unsigned spaces = static_cast<unsigned>(depth_ * indent_);
if (indent_ == 0) return;
if (got_key_) {
OutputChar(' ');
return;
}
while (spaces >= (sizeof(spacesstr) - 1)) {
OutputString(StringView(spacesstr, sizeof(spacesstr) - 1));
spaces -= static_cast<unsigned>(sizeof(spacesstr) - 1);
}
if (spaces == 0) return;
OutputString(StringView(spacesstr + sizeof(spacesstr) - 1 - spaces, spaces));
}
void JsonWriter::ValueEnd() {
if (container_empty_) {
container_empty_ = false;
if (indent_ == 0 || depth_ == 0) return;
OutputChar('\n');
} else {
OutputChar(',');
if (indent_ == 0) return;
OutputChar('\n');
}
}
void JsonWriter::EscapeUtf16(uint16_t utf16) {
static const char hex[] = "0123456789abcdef";
OutputString(StringView("\\u", 2));
OutputChar(hex[(utf16 >> 12) & 0x0f]);
OutputChar(hex[(utf16 >> 8) & 0x0f]);
OutputChar(hex[(utf16 >> 4) & 0x0f]);
OutputChar(hex[(utf16)&0x0f]);
}
void JsonWriter::EscapeString(const std::string& string) {
OutputChar('"');
for (size_t idx = 0; idx < string.size(); ++idx) {
uint8_t c = static_cast<uint8_t>(string[idx]);
if (c == 0) {
break;
} else if (c >= 32 && c <= 126) {
if (c == '\\' || c == '"') OutputChar('\\');
OutputChar(static_cast<char>(c));
} else if (c < 32 || c == 127) {
switch (c) {
case '\b':
OutputString(StringView("\\b", 2));
break;
case '\f':
OutputString(StringView("\\f", 2));
break;
case '\n':
OutputString(StringView("\\n", 2));
break;
case '\r':
OutputString(StringView("\\r", 2));
break;
case '\t':
OutputString(StringView("\\t", 2));
break;
default:
EscapeUtf16(c);
break;
}
} else {
uint32_t utf32 = 0;
int extra = 0;
int i;
int valid = 1;
if ((c & 0xe0) == 0xc0) {
utf32 = c & 0x1f;
extra = 1;
} else if ((c & 0xf0) == 0xe0) {
utf32 = c & 0x0f;
extra = 2;
} else if ((c & 0xf8) == 0xf0) {
utf32 = c & 0x07;
extra = 3;
} else {
break;
}
for (i = 0; i < extra; i++) {
utf32 <<= 6;
++idx;
/* Breaks out and bail if we hit the end of the string. */
if (idx == string.size()) {
valid = 0;
break;
}
c = static_cast<uint8_t>(string[idx]);
/* Breaks out and bail on any invalid UTF-8 sequence, including \0. */
if ((c & 0xc0) != 0x80) {
valid = 0;
break;
}
utf32 |= c & 0x3f;
}
if (!valid) break;
/* The range 0xd800 - 0xdfff is reserved by the surrogates ad vitam.
* Any other range is technically reserved for future usage, so if we
* don't want the software to break in the future, we have to allow
* anything else. The first non-unicode character is 0x110000. */
if (((utf32 >= 0xd800) && (utf32 <= 0xdfff)) || (utf32 >= 0x110000))
break;
if (utf32 >= 0x10000) {
/* If utf32 contains a character that is above 0xffff, it needs to be
* broken down into a utf-16 surrogate pair. A surrogate pair is first
* a high surrogate, followed by a low surrogate. Each surrogate holds
* 10 bits of usable data, thus allowing a total of 20 bits of data.
* The high surrogate marker is 0xd800, while the low surrogate marker
* is 0xdc00. The low 10 bits of each will be the usable data.
*
* After re-combining the 20 bits of data, one has to add 0x10000 to
* the resulting value, in order to obtain the original character.
* This is obviously because the range 0x0000 - 0xffff can be written
* without any special trick.
*
* Since 0x10ffff is the highest allowed character, we're working in
* the range 0x00000 - 0xfffff after we decrement it by 0x10000.
* That range is exactly 20 bits.
*/
utf32 -= 0x10000;
EscapeUtf16(static_cast<uint16_t>(0xd800 | (utf32 >> 10)));
EscapeUtf16(static_cast<uint16_t>(0xdc00 | (utf32 & 0x3ff)));
} else {
EscapeUtf16(static_cast<uint16_t>(utf32));
}
}
}
OutputChar('"');
}
void JsonWriter::ContainerBegins(Json::Type type) {
if (!got_key_) ValueEnd();
OutputIndent();
OutputChar(type == Json::Type::OBJECT ? '{' : '[');
container_empty_ = true;
got_key_ = false;
depth_++;
}
void JsonWriter::ContainerEnds(Json::Type type) {
if (indent_ && !container_empty_) OutputChar('\n');
depth_--;
if (!container_empty_) OutputIndent();
OutputChar(type == Json::Type::OBJECT ? '}' : ']');
container_empty_ = false;
got_key_ = false;
}
void JsonWriter::ObjectKey(const std::string& string) {
ValueEnd();
OutputIndent();
EscapeString(string);
OutputChar(':');
got_key_ = true;
}
void JsonWriter::ValueRaw(const std::string& string) {
if (!got_key_) ValueEnd();
OutputIndent();
OutputString(string);
got_key_ = false;
}
void JsonWriter::ValueString(const std::string& string) {
if (!got_key_) ValueEnd();
OutputIndent();
EscapeString(string);
got_key_ = false;
}
void JsonWriter::DumpObject(const Json::Object& object) {
ContainerBegins(Json::Type::OBJECT);
for (const auto& p : object) {
ObjectKey(p.first.data());
DumpValue(p.second);
}
ContainerEnds(Json::Type::OBJECT);
}
void JsonWriter::DumpArray(const Json::Array& array) {
ContainerBegins(Json::Type::ARRAY);
for (const auto& v : array) {
DumpValue(v);
}
ContainerEnds(Json::Type::ARRAY);
}
void JsonWriter::DumpValue(const Json& value) {
switch (value.type()) {
case Json::Type::OBJECT:
DumpObject(value.object_value());
break;
case Json::Type::ARRAY:
DumpArray(value.array_value());
break;
case Json::Type::STRING:
ValueString(value.string_value());
break;
case Json::Type::NUMBER:
ValueRaw(value.string_value());
break;
case Json::Type::JSON_TRUE:
ValueRaw(std::string("true", 4));
break;
case Json::Type::JSON_FALSE:
ValueRaw(std::string("false", 5));
break;
case Json::Type::JSON_NULL:
ValueRaw(std::string("null", 4));
break;
default:
GPR_UNREACHABLE_CODE(abort());
}
}
std::string JsonWriter::Dump(const Json& value, int indent) {
JsonWriter writer(indent);
writer.DumpValue(value);
return std::move(writer.output_);
}
} // namespace
std::string Json::Dump(int indent) const {
return JsonWriter::Dump(*this, indent);
}
} // namespace grpc_core

@ -30,7 +30,7 @@
const size_t kBiosDataBufferSize = 256;
static char* trim(const char* src) {
if (src == nullptr) {
if (src == nullptr || *src == '\0') {
return nullptr;
}
char* des = nullptr;

@ -1,106 +0,0 @@
/*
*
* Copyright 2015 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
#include <functional>
#include <grpcpp/generic/generic_stub.h>
#include <grpcpp/impl/rpc_method.h>
#include <grpcpp/support/client_callback.h>
namespace grpc_impl {
namespace {
std::unique_ptr<grpc::GenericClientAsyncReaderWriter> CallInternal(
grpc::ChannelInterface* channel, grpc::ClientContext* context,
const grpc::string& method, CompletionQueue* cq, bool start, void* tag) {
return std::unique_ptr<grpc::GenericClientAsyncReaderWriter>(
internal::ClientAsyncReaderWriterFactory<grpc::ByteBuffer,
grpc::ByteBuffer>::
Create(channel, cq,
grpc::internal::RpcMethod(
method.c_str(), grpc::internal::RpcMethod::BIDI_STREAMING),
context, start, tag));
}
} // namespace
// begin a call to a named method
std::unique_ptr<grpc::GenericClientAsyncReaderWriter> GenericStub::Call(
grpc::ClientContext* context, const grpc::string& method,
CompletionQueue* cq, void* tag) {
return CallInternal(channel_.get(), context, method, cq, true, tag);
}
// setup a call to a named method
std::unique_ptr<grpc::GenericClientAsyncReaderWriter> GenericStub::PrepareCall(
grpc::ClientContext* context, const grpc::string& method,
CompletionQueue* cq) {
return CallInternal(channel_.get(), context, method, cq, false, nullptr);
}
// setup a unary call to a named method
std::unique_ptr<grpc::GenericClientAsyncResponseReader>
GenericStub::PrepareUnaryCall(grpc::ClientContext* context,
const grpc::string& method,
const grpc::ByteBuffer& request,
CompletionQueue* cq) {
return std::unique_ptr<grpc::GenericClientAsyncResponseReader>(
internal::ClientAsyncResponseReaderFactory<grpc::ByteBuffer>::Create(
channel_.get(), cq,
grpc::internal::RpcMethod(method.c_str(),
grpc::internal::RpcMethod::NORMAL_RPC),
context, request, false));
}
void GenericStub::UnaryCallInternal(
grpc::ClientContext* context, const grpc::string& method,
const grpc::ByteBuffer* request, grpc::ByteBuffer* response,
std::function<void(grpc::Status)> on_completion) {
internal::CallbackUnaryCall(
channel_.get(),
grpc::internal::RpcMethod(method.c_str(),
grpc::internal::RpcMethod::NORMAL_RPC),
context, request, response, std::move(on_completion));
}
void GenericStub::PrepareBidiStreamingCallInternal(
grpc::ClientContext* context, const grpc::string& method,
ClientBidiReactor<grpc::ByteBuffer, grpc::ByteBuffer>* reactor) {
internal::ClientCallbackReaderWriterFactory<
grpc::ByteBuffer,
grpc::ByteBuffer>::Create(channel_.get(),
grpc::internal::RpcMethod(
method.c_str(),
grpc::internal::RpcMethod::BIDI_STREAMING),
context, reactor);
}
void GenericStub::PrepareUnaryCallInternal(grpc::ClientContext* context,
const grpc::string& method,
const grpc::ByteBuffer* request,
grpc::ByteBuffer* response,
ClientUnaryReactor* reactor) {
internal::ClientCallbackUnaryFactory::Create<grpc::ByteBuffer,
grpc::ByteBuffer>(
channel_.get(),
grpc::internal::RpcMethod(method.c_str(),
grpc::internal::RpcMethod::NORMAL_RPC),
context, request, response, reactor);
}
} // namespace grpc_impl

@ -39,6 +39,12 @@ CompletionQueue::CompletionQueue(grpc_completion_queue* take)
void CompletionQueue::Shutdown() {
g_gli_initializer.summon();
#ifndef NDEBUG
if (!ServerListEmpty()) {
gpr_log(GPR_ERROR,
"CompletionQueue shutdown being shutdown before its server.");
}
#endif
CompleteAvalanching();
}

@ -354,9 +354,8 @@ std::unique_ptr<grpc::Server> ServerBuilder::BuildAndStart() {
// server
// 2. cqs_: Completion queues added via AddCompletionQueue() call
for (const auto& value : *sync_server_cqs) {
grpc_server_register_completion_queue(server->server_, value->cq(),
nullptr);
for (const auto& cq : *sync_server_cqs) {
grpc_server_register_completion_queue(server->server_, cq->cq(), nullptr);
has_frequently_polled_cqs = true;
}
@ -369,10 +368,12 @@ std::unique_ptr<grpc::Server> ServerBuilder::BuildAndStart() {
// AddCompletionQueue() API. Some of them may not be frequently polled (i.e by
// calling Next() or AsyncNext()) and hence are not safe to be used for
// listening to incoming channels. Such completion queues must be registered
// as non-listening queues
for (const auto& value : cqs_) {
grpc_server_register_completion_queue(server->server_, value->cq(),
nullptr);
// as non-listening queues. In debug mode, these should have their server list
// tracked since these are provided the user and must be Shutdown by the user
// after the server is shutdown.
for (const auto& cq : cqs_) {
grpc_server_register_completion_queue(server->server_, cq->cq(), nullptr);
cq->RegisterServer(server.get());
}
if (!has_frequently_polled_cqs) {

@ -1249,6 +1249,9 @@ void Server::Start(grpc::ServerCompletionQueue** cqs, size_t num_cqs) {
}
for (size_t i = 0; i < num_cqs; i++) {
#ifndef NDEBUG
cq_list_.push_back(cqs[i]);
#endif
if (cqs[i]->IsFrequentlyPolled()) {
new UnimplementedAsyncRequest(this, cqs[i]);
}
@ -1360,6 +1363,15 @@ void Server::ShutdownInternal(gpr_timespec deadline) {
shutdown_notified_ = true;
shutdown_cv_.Broadcast();
#ifndef NDEBUG
// Unregister this server with the CQs passed into it by the user so that
// those can be checked for properly-ordered shutdown.
for (auto* cq : cq_list_) {
cq->UnregisterServer(this);
}
cq_list_.clear();
#endif
}
void Server::Wait() {

@ -208,6 +208,7 @@ CORE_SOURCE_FILES = [
'src/core/lib/gpr/string_util_windows.cc',
'src/core/lib/gpr/string_windows.cc',
'src/core/lib/gpr/sync.cc',
'src/core/lib/gpr/sync_abseil.cc',
'src/core/lib/gpr/sync_posix.cc',
'src/core/lib/gpr/sync_windows.cc',
'src/core/lib/gpr/time.cc',
@ -323,11 +324,8 @@ CORE_SOURCE_FILES = [
'src/core/lib/iomgr/wakeup_fd_pipe.cc',
'src/core/lib/iomgr/wakeup_fd_posix.cc',
'src/core/lib/iomgr/work_serializer.cc',
'src/core/lib/json/json.cc',
'src/core/lib/json/json_reader.cc',
'src/core/lib/json/json_reader_new.cc',
'src/core/lib/json/json_writer.cc',
'src/core/lib/json/json_writer_new.cc',
'src/core/lib/profiling/basic_timers.cc',
'src/core/lib/profiling/stap_timers.cc',
'src/core/lib/security/context/security_context.cc',

@ -210,6 +210,8 @@ class TestMetadata(AioTestBase):
self.assertEqual(_RESPONSE, await call)
self.assertEqual(grpc.StatusCode.OK, await call.code())
@unittest.skipIf(platform.system() == 'Windows',
'https://github.com/grpc/grpc/issues/21943')
async def test_invalid_metadata(self):
multicallable = self._client.unary_unary(_TEST_CLIENT_TO_SERVER)
for exception_type, metadata in _INVALID_METADATA_TEST_CASES:

@ -10,5 +10,5 @@ RUN apt-get update && apt-get install -y ${'\\'}
# Install Python packages from PyPI
RUN pip install --upgrade pip==19.3.1
RUN pip install virtualenv
RUN pip install virtualenv==16.7.9
RUN pip install futures==2.2.0 enum34==1.0.4 protobuf==3.5.2.post1 six==1.10.0 twisted==17.5.0

@ -28,8 +28,8 @@
libtool ${"\\"}
curl ${"\\"}
shellcheck
RUN python2 -m pip install simplejson mako virtualenv lxml
RUN python3 -m pip install simplejson mako virtualenv lxml
RUN python2 -m pip install simplejson mako virtualenv==16.7.9 lxml
RUN python3 -m pip install simplejson mako virtualenv==16.7.9 lxml
<%include file="../../clang5.include"/>
<%include file="../../bazel.include"/>

@ -20,21 +20,6 @@ licenses(["notice"]) # Apache v2
load("//test/core/util:grpc_fuzzer.bzl", "grpc_fuzzer")
grpc_fuzzer(
name = "api_fuzzer",
size = "enormous",
srcs = ["api_fuzzer.cc"],
corpus = "api_fuzzer_corpus",
language = "C++",
tags = ["no_windows"],
deps = [
"//:gpr",
"//:grpc",
"//test/core/end2end:ssl_test_data",
"//test/core/util:grpc_test_util",
],
)
grpc_fuzzer(
name = "client_fuzzer",
srcs = ["client_fuzzer.cc"],

File diff suppressed because it is too large Load Diff

@ -1,27 +0,0 @@
# tracers
"api\x00"
"channel\x00"
"channel_stack_builder\x00"
"connectivity_state\x00"
"flowctl\x00"
"http\x00"
"http1\x00"
"round_robin\x00"
"secure_endpoint\x00"
"tcp\x00"
"transport_security\x00"
# channel args
"\x00grpc.census\x00"
"\x00grpc.max_concurrent_streams\x00"
"\x00grpc.max_message_length\x00"
"\x00grpc.http2.initial_sequence_number\x00"
"\x00grpc.http2.lookahead_bytes\x00"
"\x00grpc.http2.hpack_table_size.decoder\x00"
"\x00grpc.http2.hpack_table_size.encoder\x00"
"\x01grpc.default_authority\x00"
"\x01grpc.primary_user_agent\x00"
"\x01grpc.secondary_user_agent\x00"
"\x00grpc.max_reconnect_backoff_ms\x00"
"\x01grpc.ssl_target_name_override\x00"

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save