Imported Upstream version 1.35.0 upstream/1.35.0
authorDongHun Kwak <dh0128.kwak@samsung.com>
Mon, 1 Feb 2021 06:18:35 +0000 (15:18 +0900)
committerDongHun Kwak <dh0128.kwak@samsung.com>
Mon, 1 Feb 2021 06:18:35 +0000 (15:18 +0900)
1167 files changed:
.bazelignore
.clang-tidy
.github/ISSUE_TEMPLATE/bug_report.md
.github/ISSUE_TEMPLATE/cleanup_request.md
.github/ISSUE_TEMPLATE/feature_request.md
.github/ISSUE_TEMPLATE/question.md
.github/pull_request_template.md
BUILD
BUILD.gn
CMakeLists.txt
Makefile
Rakefile
bazel/grpc_deps.bzl
bazel/grpc_extra_deps.bzl
bazel/update_mirror.sh
build_autogenerated.yaml
build_handwritten.yaml
config.m4
config.w32
doc/environment_variables.md
doc/g_stands_for.md
doc/grpc_release_schedule.md
doc/grpc_xds_features.md
doc/python/sphinx/grpc_asyncio.rst
etc/roots.pem
examples/BUILD [deleted file]
examples/README.md
examples/cpp/compression/BUILD [new file with mode: 0644]
examples/cpp/helloworld/BUILD [new file with mode: 0644]
examples/cpp/keyvaluestore/BUILD [new file with mode: 0644]
examples/cpp/load_balancing/BUILD [new file with mode: 0644]
examples/cpp/metadata/BUILD [new file with mode: 0644]
examples/cpp/route_guide/BUILD [new file with mode: 0644]
examples/objective-c/BUILD
examples/objective-c/helloworld/README.md
examples/protos/BUILD [new file with mode: 0644]
examples/python/async_streaming/README.md [new file with mode: 0644]
examples/python/async_streaming/client.py [new file with mode: 0644]
examples/python/async_streaming/phone.proto [new file with mode: 0644]
examples/python/async_streaming/phone_pb2.py [new file with mode: 0644]
examples/python/async_streaming/phone_pb2_grpc.py [new file with mode: 0644]
examples/python/async_streaming/server.py [new file with mode: 0644]
examples/python/auth/BUILD.bazel
examples/python/auth/_credentials.py
examples/python/auth/async_customized_auth_client.py [new file with mode: 0644]
examples/python/auth/async_customized_auth_server.py [new file with mode: 0644]
examples/python/auth/customized_auth_client.py
examples/python/auth/customized_auth_server.py
examples/python/auth/helloworld.proto [new symlink]
examples/python/auth/test/_auth_example_test.py
examples/python/compression/BUILD.bazel
examples/python/compression/client.py
examples/python/compression/server.py
examples/python/debug/BUILD.bazel
examples/python/debug/asyncio_debug_server.py [new file with mode: 0644]
examples/python/debug/asyncio_get_stats.py [new file with mode: 0644]
examples/python/debug/asyncio_send_message.py [new file with mode: 0644]
examples/python/debug/debug_server.py
examples/python/debug/get_stats.py
examples/python/debug/helloworld.proto [new symlink]
examples/python/debug/send_message.py
examples/python/debug/test/_debug_example_test.py
examples/python/errors/BUILD.bazel
examples/python/errors/client.py
examples/python/errors/server.py
examples/python/errors/test/_error_handling_example_test.py
examples/python/helloworld/async_greeter_client.py
examples/python/helloworld/async_greeter_client_with_options.py [new file with mode: 0644]
examples/python/helloworld/async_greeter_server.py
examples/python/helloworld/async_greeter_server_with_reflection.py [new file with mode: 0644]
examples/python/route_guide/asyncio_route_guide_client.py [new file with mode: 0644]
examples/python/route_guide/asyncio_route_guide_server.py [new file with mode: 0644]
examples/python/wait_for_ready/BUILD.bazel
examples/python/wait_for_ready/asyncio_wait_for_ready_example.py [new file with mode: 0644]
examples/python/wait_for_ready/helloworld.proto [new symlink]
examples/python/wait_for_ready/test/_wait_for_ready_example_test.py
examples/python/wait_for_ready/wait_for_ready_example.py
gRPC-C++.podspec
gRPC-Core.podspec
gRPC-ProtoRPC.podspec
gRPC-RxLibrary.podspec
gRPC.podspec
grpc.def
grpc.gemspec
grpc.gyp
include/grpc/compression.h
include/grpc/grpc.h
include/grpc/grpc_security.h
include/grpc/impl/codegen/atm_windows.h
include/grpc/impl/codegen/byte_buffer.h
include/grpc/impl/codegen/grpc_types.h
include/grpc/impl/codegen/log.h
include/grpc/impl/codegen/sync_windows.h
include/grpc/slice_buffer.h
include/grpc/support/sync.h
include/grpc/support/time.h
include/grpcpp/alarm.h
include/grpcpp/channel.h
include/grpcpp/impl/codegen/byte_buffer.h
include/grpcpp/impl/codegen/call_op_set.h
include/grpcpp/impl/codegen/callback_common.h
include/grpcpp/impl/codegen/client_callback.h
include/grpcpp/impl/codegen/client_context.h
include/grpcpp/impl/codegen/client_unary_call.h
include/grpcpp/impl/codegen/completion_queue.h
include/grpcpp/impl/codegen/config.h
include/grpcpp/impl/codegen/config_protobuf.h
include/grpcpp/impl/codegen/core_codegen.h
include/grpcpp/impl/codegen/delegating_channel.h
include/grpcpp/impl/codegen/grpc_library.h
include/grpcpp/impl/codegen/intercepted_channel.h
include/grpcpp/impl/codegen/interceptor_common.h
include/grpcpp/impl/codegen/method_handler.h
include/grpcpp/impl/codegen/method_handler_impl.h [moved from test/core/util/debugger_macros.h with 62% similarity]
include/grpcpp/impl/codegen/proto_buffer_reader.h
include/grpcpp/impl/codegen/proto_buffer_writer.h
include/grpcpp/impl/codegen/proto_utils.h
include/grpcpp/impl/codegen/rpc_method.h
include/grpcpp/impl/codegen/server_callback.h
include/grpcpp/impl/codegen/server_callback_handlers.h
include/grpcpp/impl/codegen/server_context.h
include/grpcpp/impl/codegen/server_interface.h
include/grpcpp/impl/codegen/service_type.h
include/grpcpp/impl/codegen/slice.h
include/grpcpp/impl/codegen/string_ref.h
include/grpcpp/impl/codegen/time.h
include/grpcpp/impl/server_initializer.h
include/grpcpp/resource_quota.h
include/grpcpp/security/credentials.h
include/grpcpp/security/server_credentials.h
include/grpcpp/security/tls_certificate_provider.h
include/grpcpp/security/tls_credentials_options.h
include/grpcpp/server.h
include/grpcpp/server_builder.h
include/grpcpp/support/channel_arguments.h
include/grpcpp/xds_server_builder.h [new file with mode: 0644]
package.xml
setup.cfg
src/abseil-cpp/gen_build_yaml.py
src/core/README.md
src/core/ext/filters/client_channel/backend_metric.cc
src/core/ext/filters/client_channel/client_channel.cc
src/core/ext/filters/client_channel/client_channel.h
src/core/ext/filters/client_channel/client_channel_plugin.cc
src/core/ext/filters/client_channel/config_selector.h
src/core/ext/filters/client_channel/dynamic_filters.cc [new file with mode: 0644]
src/core/ext/filters/client_channel/dynamic_filters.h [new file with mode: 0644]
src/core/ext/filters/client_channel/health/health_check_client.cc
src/core/ext/filters/client_channel/health/health_check_client.h
src/core/ext/filters/client_channel/http_connect_handshaker.cc
src/core/ext/filters/client_channel/http_proxy.cc
src/core/ext/filters/client_channel/lb_policy.cc
src/core/ext/filters/client_channel/lb_policy.h
src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc
src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.cc
src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.h
src/core/ext/filters/client_channel/lb_policy/xds/cds.cc
src/core/ext/filters/client_channel/lb_policy/xds/eds.cc [deleted file]
src/core/ext/filters/client_channel/lb_policy/xds/xds.h
src/core/ext/filters/client_channel/lb_policy/xds/xds_channel_args.h [new file with mode: 0644]
src/core/ext/filters/client_channel/lb_policy/xds/xds_cluster_impl.cc
src/core/ext/filters/client_channel/lb_policy/xds/xds_cluster_manager.cc
src/core/ext/filters/client_channel/lb_policy/xds/xds_cluster_resolver.cc [new file with mode: 0644]
src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc
src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.cc [deleted file]
src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.h
src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_posix.cc
src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc
src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h
src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_fallback.cc [deleted file]
src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc
src/core/ext/filters/client_channel/resolver/fake/fake_resolver.cc
src/core/ext/filters/client_channel/resolver/sockaddr/sockaddr_resolver.cc
src/core/ext/filters/client_channel/resolver/xds/xds_resolver.cc
src/core/ext/filters/client_channel/resolver_factory.h
src/core/ext/filters/client_channel/resolver_registry.cc
src/core/ext/filters/client_channel/resolver_registry.h
src/core/ext/filters/client_channel/resolver_result_parsing.cc
src/core/ext/filters/client_channel/resolver_result_parsing.h
src/core/ext/filters/client_channel/resolving_lb_policy.cc [deleted file]
src/core/ext/filters/client_channel/resolving_lb_policy.h [deleted file]
src/core/ext/filters/client_channel/retry_throttle.cc
src/core/ext/filters/client_channel/retry_throttle.h
src/core/ext/filters/client_channel/service_config_call_data.h
src/core/ext/filters/client_channel/subchannel.cc
src/core/ext/filters/client_channel/subchannel.h
src/core/ext/filters/deadline/deadline_filter.cc
src/core/ext/filters/http/client_authority_filter.cc
src/core/ext/filters/http/http_filters_plugin.cc
src/core/ext/filters/load_reporting/server_load_reporting_filter.cc
src/core/ext/filters/message_size/message_size_filter.cc
src/core/ext/filters/workarounds/workaround_utils.cc
src/core/ext/transport/chttp2/client/authority.cc
src/core/ext/transport/chttp2/client/insecure/channel_create.cc
src/core/ext/transport/chttp2/client/insecure/channel_create_posix.cc
src/core/ext/transport/chttp2/client/secure/secure_channel_create.cc
src/core/ext/transport/chttp2/server/chttp2_server.cc
src/core/ext/transport/chttp2/server/insecure/server_chttp2_posix.cc
src/core/ext/transport/chttp2/transport/chttp2_transport.cc
src/core/ext/transport/chttp2/transport/flow_control.h
src/core/ext/transport/chttp2/transport/frame_settings.h
src/core/ext/transport/chttp2/transport/frame_window_update.cc
src/core/ext/transport/chttp2/transport/writing.cc
src/core/ext/transport/cronet/transport/cronet_status.h
src/core/ext/transport/cronet/transport/cronet_transport.cc
src/core/ext/transport/inproc/inproc_transport.cc
src/core/ext/upb-generated/envoy/annotations/deprecation.upb.h
src/core/ext/upb-generated/envoy/annotations/resource.upb.c
src/core/ext/upb-generated/envoy/annotations/resource.upb.h
src/core/ext/upb-generated/envoy/config/accesslog/v3/accesslog.upb.c
src/core/ext/upb-generated/envoy/config/accesslog/v3/accesslog.upb.h
src/core/ext/upb-generated/envoy/config/cluster/v3/circuit_breaker.upb.c
src/core/ext/upb-generated/envoy/config/cluster/v3/circuit_breaker.upb.h
src/core/ext/upb-generated/envoy/config/cluster/v3/cluster.upb.c
src/core/ext/upb-generated/envoy/config/cluster/v3/cluster.upb.h
src/core/ext/upb-generated/envoy/config/cluster/v3/filter.upb.c
src/core/ext/upb-generated/envoy/config/cluster/v3/filter.upb.h
src/core/ext/upb-generated/envoy/config/cluster/v3/outlier_detection.upb.c
src/core/ext/upb-generated/envoy/config/cluster/v3/outlier_detection.upb.h
src/core/ext/upb-generated/envoy/config/core/v3/address.upb.c
src/core/ext/upb-generated/envoy/config/core/v3/address.upb.h
src/core/ext/upb-generated/envoy/config/core/v3/backoff.upb.c
src/core/ext/upb-generated/envoy/config/core/v3/backoff.upb.h
src/core/ext/upb-generated/envoy/config/core/v3/base.upb.c
src/core/ext/upb-generated/envoy/config/core/v3/base.upb.h
src/core/ext/upb-generated/envoy/config/core/v3/config_source.upb.c
src/core/ext/upb-generated/envoy/config/core/v3/config_source.upb.h
src/core/ext/upb-generated/envoy/config/core/v3/event_service_config.upb.c
src/core/ext/upb-generated/envoy/config/core/v3/event_service_config.upb.h
src/core/ext/upb-generated/envoy/config/core/v3/extension.upb.c
src/core/ext/upb-generated/envoy/config/core/v3/extension.upb.h
src/core/ext/upb-generated/envoy/config/core/v3/grpc_service.upb.c
src/core/ext/upb-generated/envoy/config/core/v3/grpc_service.upb.h
src/core/ext/upb-generated/envoy/config/core/v3/health_check.upb.c
src/core/ext/upb-generated/envoy/config/core/v3/health_check.upb.h
src/core/ext/upb-generated/envoy/config/core/v3/http_uri.upb.c
src/core/ext/upb-generated/envoy/config/core/v3/http_uri.upb.h
src/core/ext/upb-generated/envoy/config/core/v3/protocol.upb.c
src/core/ext/upb-generated/envoy/config/core/v3/protocol.upb.h
src/core/ext/upb-generated/envoy/config/core/v3/proxy_protocol.upb.c
src/core/ext/upb-generated/envoy/config/core/v3/proxy_protocol.upb.h
src/core/ext/upb-generated/envoy/config/core/v3/socket_option.upb.c
src/core/ext/upb-generated/envoy/config/core/v3/socket_option.upb.h
src/core/ext/upb-generated/envoy/config/core/v3/substitution_format_string.upb.c
src/core/ext/upb-generated/envoy/config/core/v3/substitution_format_string.upb.h
src/core/ext/upb-generated/envoy/config/endpoint/v3/endpoint.upb.c
src/core/ext/upb-generated/envoy/config/endpoint/v3/endpoint.upb.h
src/core/ext/upb-generated/envoy/config/endpoint/v3/endpoint_components.upb.c
src/core/ext/upb-generated/envoy/config/endpoint/v3/endpoint_components.upb.h
src/core/ext/upb-generated/envoy/config/endpoint/v3/load_report.upb.c
src/core/ext/upb-generated/envoy/config/endpoint/v3/load_report.upb.h
src/core/ext/upb-generated/envoy/config/listener/v3/api_listener.upb.c
src/core/ext/upb-generated/envoy/config/listener/v3/api_listener.upb.h
src/core/ext/upb-generated/envoy/config/listener/v3/listener.upb.c
src/core/ext/upb-generated/envoy/config/listener/v3/listener.upb.h
src/core/ext/upb-generated/envoy/config/listener/v3/listener_components.upb.c
src/core/ext/upb-generated/envoy/config/listener/v3/listener_components.upb.h
src/core/ext/upb-generated/envoy/config/listener/v3/udp_listener_config.upb.c
src/core/ext/upb-generated/envoy/config/listener/v3/udp_listener_config.upb.h
src/core/ext/upb-generated/envoy/config/rbac/v3/rbac.upb.c
src/core/ext/upb-generated/envoy/config/rbac/v3/rbac.upb.h
src/core/ext/upb-generated/envoy/config/route/v3/route.upb.c
src/core/ext/upb-generated/envoy/config/route/v3/route.upb.h
src/core/ext/upb-generated/envoy/config/route/v3/route_components.upb.c
src/core/ext/upb-generated/envoy/config/route/v3/route_components.upb.h
src/core/ext/upb-generated/envoy/config/route/v3/scoped_route.upb.c
src/core/ext/upb-generated/envoy/config/route/v3/scoped_route.upb.h
src/core/ext/upb-generated/envoy/config/trace/v3/http_tracer.upb.c
src/core/ext/upb-generated/envoy/config/trace/v3/http_tracer.upb.h
src/core/ext/upb-generated/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.upb.c
src/core/ext/upb-generated/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.upb.h
src/core/ext/upb-generated/envoy/extensions/transport_sockets/tls/v3/cert.upb.h
src/core/ext/upb-generated/envoy/extensions/transport_sockets/tls/v3/common.upb.c
src/core/ext/upb-generated/envoy/extensions/transport_sockets/tls/v3/common.upb.h
src/core/ext/upb-generated/envoy/extensions/transport_sockets/tls/v3/secret.upb.c
src/core/ext/upb-generated/envoy/extensions/transport_sockets/tls/v3/secret.upb.h
src/core/ext/upb-generated/envoy/extensions/transport_sockets/tls/v3/tls.upb.c
src/core/ext/upb-generated/envoy/extensions/transport_sockets/tls/v3/tls.upb.h
src/core/ext/upb-generated/envoy/service/cluster/v3/cds.upb.c
src/core/ext/upb-generated/envoy/service/cluster/v3/cds.upb.h
src/core/ext/upb-generated/envoy/service/discovery/v3/ads.upb.c
src/core/ext/upb-generated/envoy/service/discovery/v3/ads.upb.h
src/core/ext/upb-generated/envoy/service/discovery/v3/discovery.upb.c
src/core/ext/upb-generated/envoy/service/discovery/v3/discovery.upb.h
src/core/ext/upb-generated/envoy/service/endpoint/v3/eds.upb.c
src/core/ext/upb-generated/envoy/service/endpoint/v3/eds.upb.h
src/core/ext/upb-generated/envoy/service/listener/v3/lds.upb.c
src/core/ext/upb-generated/envoy/service/listener/v3/lds.upb.h
src/core/ext/upb-generated/envoy/service/load_stats/v3/lrs.upb.c
src/core/ext/upb-generated/envoy/service/load_stats/v3/lrs.upb.h
src/core/ext/upb-generated/envoy/service/route/v3/rds.upb.c
src/core/ext/upb-generated/envoy/service/route/v3/rds.upb.h
src/core/ext/upb-generated/envoy/service/route/v3/srds.upb.c
src/core/ext/upb-generated/envoy/service/route/v3/srds.upb.h
src/core/ext/upb-generated/envoy/type/matcher/v3/metadata.upb.c
src/core/ext/upb-generated/envoy/type/matcher/v3/metadata.upb.h
src/core/ext/upb-generated/envoy/type/matcher/v3/number.upb.c
src/core/ext/upb-generated/envoy/type/matcher/v3/number.upb.h
src/core/ext/upb-generated/envoy/type/matcher/v3/path.upb.c
src/core/ext/upb-generated/envoy/type/matcher/v3/path.upb.h
src/core/ext/upb-generated/envoy/type/matcher/v3/regex.upb.c
src/core/ext/upb-generated/envoy/type/matcher/v3/regex.upb.h
src/core/ext/upb-generated/envoy/type/matcher/v3/string.upb.c
src/core/ext/upb-generated/envoy/type/matcher/v3/string.upb.h
src/core/ext/upb-generated/envoy/type/matcher/v3/value.upb.c
src/core/ext/upb-generated/envoy/type/matcher/v3/value.upb.h
src/core/ext/upb-generated/envoy/type/metadata/v3/metadata.upb.c
src/core/ext/upb-generated/envoy/type/metadata/v3/metadata.upb.h
src/core/ext/upb-generated/envoy/type/tracing/v3/custom_tag.upb.c
src/core/ext/upb-generated/envoy/type/tracing/v3/custom_tag.upb.h
src/core/ext/upb-generated/envoy/type/v3/http.upb.h
src/core/ext/upb-generated/envoy/type/v3/percent.upb.c
src/core/ext/upb-generated/envoy/type/v3/percent.upb.h
src/core/ext/upb-generated/envoy/type/v3/range.upb.c
src/core/ext/upb-generated/envoy/type/v3/range.upb.h
src/core/ext/upb-generated/envoy/type/v3/semantic_version.upb.c
src/core/ext/upb-generated/envoy/type/v3/semantic_version.upb.h
src/core/ext/upb-generated/google/api/annotations.upb.h
src/core/ext/upb-generated/google/api/expr/v1alpha1/checked.upb.c
src/core/ext/upb-generated/google/api/expr/v1alpha1/checked.upb.h
src/core/ext/upb-generated/google/api/expr/v1alpha1/syntax.upb.c
src/core/ext/upb-generated/google/api/expr/v1alpha1/syntax.upb.h
src/core/ext/upb-generated/google/api/http.upb.c
src/core/ext/upb-generated/google/api/http.upb.h
src/core/ext/upb-generated/google/protobuf/any.upb.c
src/core/ext/upb-generated/google/protobuf/any.upb.h
src/core/ext/upb-generated/google/protobuf/descriptor.upb.c
src/core/ext/upb-generated/google/protobuf/descriptor.upb.h
src/core/ext/upb-generated/google/protobuf/duration.upb.c
src/core/ext/upb-generated/google/protobuf/duration.upb.h
src/core/ext/upb-generated/google/protobuf/empty.upb.c
src/core/ext/upb-generated/google/protobuf/empty.upb.h
src/core/ext/upb-generated/google/protobuf/struct.upb.c
src/core/ext/upb-generated/google/protobuf/struct.upb.h
src/core/ext/upb-generated/google/protobuf/timestamp.upb.c
src/core/ext/upb-generated/google/protobuf/timestamp.upb.h
src/core/ext/upb-generated/google/protobuf/wrappers.upb.c
src/core/ext/upb-generated/google/protobuf/wrappers.upb.h
src/core/ext/upb-generated/google/rpc/status.upb.c
src/core/ext/upb-generated/google/rpc/status.upb.h
src/core/ext/upb-generated/src/proto/grpc/gcp/altscontext.upb.c
src/core/ext/upb-generated/src/proto/grpc/gcp/altscontext.upb.h
src/core/ext/upb-generated/src/proto/grpc/gcp/handshaker.upb.c
src/core/ext/upb-generated/src/proto/grpc/gcp/handshaker.upb.h
src/core/ext/upb-generated/src/proto/grpc/gcp/transport_security_common.upb.c
src/core/ext/upb-generated/src/proto/grpc/gcp/transport_security_common.upb.h
src/core/ext/upb-generated/src/proto/grpc/health/v1/health.upb.c
src/core/ext/upb-generated/src/proto/grpc/health/v1/health.upb.h
src/core/ext/upb-generated/src/proto/grpc/lb/v1/load_balancer.upb.c
src/core/ext/upb-generated/src/proto/grpc/lb/v1/load_balancer.upb.h
src/core/ext/upb-generated/third_party/istio/security/proto/providers/google/meshca.upb.c
src/core/ext/upb-generated/third_party/istio/security/proto/providers/google/meshca.upb.h
src/core/ext/upb-generated/udpa/annotations/migrate.upb.c
src/core/ext/upb-generated/udpa/annotations/migrate.upb.h
src/core/ext/upb-generated/udpa/annotations/security.upb.c
src/core/ext/upb-generated/udpa/annotations/security.upb.h
src/core/ext/upb-generated/udpa/annotations/sensitive.upb.h
src/core/ext/upb-generated/udpa/annotations/status.upb.c
src/core/ext/upb-generated/udpa/annotations/status.upb.h
src/core/ext/upb-generated/udpa/annotations/versioning.upb.c
src/core/ext/upb-generated/udpa/annotations/versioning.upb.h
src/core/ext/upb-generated/udpa/core/v1/authority.upb.c
src/core/ext/upb-generated/udpa/core/v1/authority.upb.h
src/core/ext/upb-generated/udpa/core/v1/collection_entry.upb.c
src/core/ext/upb-generated/udpa/core/v1/collection_entry.upb.h
src/core/ext/upb-generated/udpa/core/v1/context_params.upb.c
src/core/ext/upb-generated/udpa/core/v1/context_params.upb.h
src/core/ext/upb-generated/udpa/core/v1/resource.upb.c
src/core/ext/upb-generated/udpa/core/v1/resource.upb.h
src/core/ext/upb-generated/udpa/core/v1/resource_locator.upb.c
src/core/ext/upb-generated/udpa/core/v1/resource_locator.upb.h
src/core/ext/upb-generated/udpa/core/v1/resource_name.upb.c
src/core/ext/upb-generated/udpa/core/v1/resource_name.upb.h
src/core/ext/upb-generated/udpa/data/orca/v1/orca_load_report.upb.c
src/core/ext/upb-generated/udpa/data/orca/v1/orca_load_report.upb.h
src/core/ext/upb-generated/validate/validate.upb.c
src/core/ext/upb-generated/validate/validate.upb.h
src/core/ext/upbdefs-generated/google/protobuf/any.upbdefs.c
src/core/ext/upbdefs-generated/google/protobuf/descriptor.upbdefs.c
src/core/ext/upbdefs-generated/google/protobuf/duration.upbdefs.c
src/core/ext/upbdefs-generated/google/protobuf/empty.upbdefs.c
src/core/ext/upbdefs-generated/google/protobuf/struct.upbdefs.c
src/core/ext/upbdefs-generated/google/protobuf/timestamp.upbdefs.c
src/core/ext/upbdefs-generated/google/protobuf/wrappers.upbdefs.c
src/core/ext/xds/certificate_provider_store.cc
src/core/ext/xds/certificate_provider_store.h
src/core/ext/xds/file_watcher_certificate_provider_factory.cc
src/core/ext/xds/file_watcher_certificate_provider_factory.h
src/core/ext/xds/xds_api.cc
src/core/ext/xds/xds_api.h
src/core/ext/xds/xds_bootstrap.h
src/core/ext/xds/xds_certificate_provider.cc
src/core/ext/xds/xds_certificate_provider.h
src/core/ext/xds/xds_client.cc
src/core/ext/xds/xds_client.h
src/core/ext/xds/xds_client_stats.cc
src/core/ext/xds/xds_server_config_fetcher.cc [new file with mode: 0644]
src/core/lib/channel/channel_args.cc
src/core/lib/channel/channel_trace.h
src/core/lib/channel/channelz.cc
src/core/lib/channel/channelz.h
src/core/lib/channel/channelz_registry.h
src/core/lib/channel/handshaker.cc
src/core/lib/compression/compression_args.cc
src/core/lib/debug/stats.h
src/core/lib/debug/stats_data.h
src/core/lib/gpr/alloc.cc
src/core/lib/gpr/log.cc
src/core/lib/gpr/log_linux.cc
src/core/lib/gpr/log_posix.cc
src/core/lib/gpr/log_windows.cc
src/core/lib/gpr/spinlock.h
src/core/lib/gpr/string.cc
src/core/lib/gpr/string.h
src/core/lib/gpr/sync.cc
src/core/lib/gpr/time.cc
src/core/lib/gprpp/arena.h
src/core/lib/gprpp/map.h [deleted file]
src/core/lib/gprpp/ref_counted.h
src/core/lib/gprpp/ref_counted_ptr.h
src/core/lib/gprpp/thd_posix.cc
src/core/lib/gprpp/thd_windows.cc
src/core/lib/http/httpcli.cc
src/core/lib/http/httpcli.h
src/core/lib/http/httpcli_security_connector.cc
src/core/lib/http/parser.cc
src/core/lib/iomgr/call_combiner.cc
src/core/lib/iomgr/combiner.cc
src/core/lib/iomgr/endpoint.h
src/core/lib/iomgr/error.cc
src/core/lib/iomgr/error_internal.h
src/core/lib/iomgr/ev_epoll1_linux.cc
src/core/lib/iomgr/ev_epollex_linux.cc
src/core/lib/iomgr/ev_poll_posix.cc
src/core/lib/iomgr/exec_ctx.h
src/core/lib/iomgr/executor.cc
src/core/lib/iomgr/executor.h
src/core/lib/iomgr/executor/threadpool.h
src/core/lib/iomgr/iomgr.cc
src/core/lib/iomgr/load_file.h
src/core/lib/iomgr/lockfree_event.cc
src/core/lib/iomgr/lockfree_event.h
src/core/lib/iomgr/parse_address.cc
src/core/lib/iomgr/parse_address.h
src/core/lib/iomgr/poller/eventmanager_libuv.h
src/core/lib/iomgr/pollset_set_custom.cc
src/core/lib/iomgr/python_util.h
src/core/lib/iomgr/resolve_address.cc
src/core/lib/iomgr/resource_quota.cc
src/core/lib/iomgr/sockaddr_utils.cc
src/core/lib/iomgr/sockaddr_utils.h
src/core/lib/iomgr/socket_factory_posix.cc
src/core/lib/iomgr/socket_mutator.cc
src/core/lib/iomgr/tcp_client.cc
src/core/lib/iomgr/tcp_client_custom.cc
src/core/lib/iomgr/tcp_custom.cc
src/core/lib/iomgr/tcp_posix.cc
src/core/lib/iomgr/tcp_server_custom.cc
src/core/lib/iomgr/timer_custom.cc
src/core/lib/iomgr/timer_generic.cc
src/core/lib/iomgr/timer_manager.cc
src/core/lib/iomgr/udp_server.cc
src/core/lib/iomgr/udp_server.h
src/core/lib/iomgr/unix_sockets_posix.cc
src/core/lib/json/json.h
src/core/lib/security/authorization/evaluate_args.cc
src/core/lib/security/authorization/evaluate_args.h
src/core/lib/security/context/security_context.cc
src/core/lib/security/credentials/alts/check_gcp_environment.cc
src/core/lib/security/credentials/credentials.cc
src/core/lib/security/credentials/external/aws_external_account_credentials.cc [new file with mode: 0644]
src/core/lib/security/credentials/external/aws_external_account_credentials.h [new file with mode: 0644]
src/core/lib/security/credentials/external/aws_request_signer.cc
src/core/lib/security/credentials/external/aws_request_signer.h
src/core/lib/security/credentials/external/external_account_credentials.cc
src/core/lib/security/credentials/external/external_account_credentials.h
src/core/lib/security/credentials/external/file_external_account_credentials.cc
src/core/lib/security/credentials/external/file_external_account_credentials.h
src/core/lib/security/credentials/external/url_external_account_credentials.cc
src/core/lib/security/credentials/external/url_external_account_credentials.h
src/core/lib/security/credentials/fake/fake_credentials.cc
src/core/lib/security/credentials/google_default/google_default_credentials.cc
src/core/lib/security/credentials/insecure/insecure_credentials.cc
src/core/lib/security/credentials/jwt/json_token.cc
src/core/lib/security/credentials/jwt/jwt_verifier.cc
src/core/lib/security/credentials/oauth2/oauth2_credentials.cc
src/core/lib/security/credentials/oauth2/oauth2_credentials.h
src/core/lib/security/credentials/plugin/plugin_credentials.cc
src/core/lib/security/credentials/ssl/ssl_credentials.cc
src/core/lib/security/credentials/ssl/ssl_credentials.h
src/core/lib/security/credentials/tls/grpc_tls_certificate_distributor.cc
src/core/lib/security/credentials/tls/grpc_tls_certificate_distributor.h
src/core/lib/security/credentials/tls/grpc_tls_certificate_provider.cc
src/core/lib/security/credentials/tls/grpc_tls_certificate_provider.h
src/core/lib/security/credentials/tls/grpc_tls_credentials_options.cc
src/core/lib/security/credentials/tls/grpc_tls_credentials_options.h
src/core/lib/security/credentials/tls/tls_credentials.cc
src/core/lib/security/credentials/tls/tls_utils.cc [new file with mode: 0644]
src/core/lib/security/credentials/tls/tls_utils.h [new file with mode: 0644]
src/core/lib/security/credentials/xds/xds_credentials.cc
src/core/lib/security/credentials/xds/xds_credentials.h
src/core/lib/security/security_connector/alts/alts_security_connector.cc
src/core/lib/security/security_connector/fake/fake_security_connector.cc
src/core/lib/security/security_connector/insecure/insecure_security_connector.cc
src/core/lib/security/security_connector/insecure/insecure_security_connector.h
src/core/lib/security/security_connector/local/local_security_connector.cc
src/core/lib/security/security_connector/security_connector.cc
src/core/lib/security/security_connector/ssl/ssl_security_connector.cc
src/core/lib/security/security_connector/ssl_utils.cc
src/core/lib/security/security_connector/ssl_utils.h
src/core/lib/security/security_connector/tls/tls_security_connector.cc
src/core/lib/security/security_connector/tls/tls_security_connector.h
src/core/lib/security/transport/secure_endpoint.cc
src/core/lib/security/transport/security_handshaker.cc
src/core/lib/slice/slice_intern.cc
src/core/lib/slice/slice_internal.h
src/core/lib/surface/call.cc
src/core/lib/surface/call_details.cc
src/core/lib/surface/channel.cc
src/core/lib/surface/channel.h
src/core/lib/surface/channel_init.cc
src/core/lib/surface/completion_queue.cc
src/core/lib/surface/completion_queue.h
src/core/lib/surface/init.cc
src/core/lib/surface/init_unsecure.cc
src/core/lib/surface/lame_client.cc
src/core/lib/surface/lame_client.h
src/core/lib/surface/server.cc
src/core/lib/surface/server.h
src/core/lib/surface/version.cc
src/core/lib/transport/authority_override.cc
src/core/lib/transport/authority_override.h
src/core/lib/transport/connectivity_state.h
src/core/lib/transport/error_utils.h
src/core/lib/transport/metadata_batch.h
src/core/lib/transport/static_metadata.cc
src/core/lib/transport/status_metadata.cc
src/core/lib/transport/transport.h
src/core/lib/uri/uri_parser.cc
src/core/lib/uri/uri_parser.h
src/core/plugin_registry/grpc_plugin_registry.cc
src/core/tsi/alts/crypt/gsec.cc
src/core/tsi/alts/frame_protector/frame_handler.cc
src/core/tsi/alts/handshaker/alts_handshaker_client.cc
src/core/tsi/alts/handshaker/alts_tsi_handshaker.cc
src/core/tsi/alts/zero_copy_frame_protector/alts_iovec_record_protocol.cc
src/core/tsi/alts/zero_copy_frame_protector/alts_zero_copy_grpc_protector.cc
src/core/tsi/fake_transport_security.cc
src/core/tsi/ssl/session_cache/ssl_session_boringssl.cc
src/core/tsi/ssl_transport_security.cc
src/core/tsi/ssl_transport_security.h
src/core/tsi/test_creds/README
src/core/tsi/test_creds/client1.key [new file with mode: 0644]
src/core/tsi/test_creds/client1.pem [new file with mode: 0644]
src/core/tsi/test_creds/client2.key [new file with mode: 0644]
src/core/tsi/test_creds/client2.pem [new file with mode: 0644]
src/core/tsi/transport_security.cc
src/core/tsi/transport_security_interface.h
src/cpp/Protobuf-C++.podspec
src/cpp/README.md
src/cpp/client/secure_credentials.cc
src/cpp/client/xds_credentials.cc
src/cpp/common/channel_filter.cc
src/cpp/common/tls_certificate_provider.cc
src/cpp/common/version_cc.cc
src/cpp/ext/filters/census/client_filter.cc
src/cpp/ext/filters/census/context.cc
src/cpp/ext/filters/census/rpc_encoding.h
src/cpp/ext/proto_server_reflection.cc
src/cpp/server/dynamic_thread_pool.h
src/cpp/server/insecure_server_credentials.cc
src/cpp/server/secure_server_credentials.cc
src/cpp/server/secure_server_credentials.h
src/cpp/server/server_builder.cc
src/cpp/server/server_cc.cc
src/cpp/server/server_context.cc
src/cpp/server/xds_server_credentials.cc [new file with mode: 0644]
src/cpp/thread_manager/thread_manager.h
src/csharp/Grpc.Core.Api/VersionInfo.cs
src/csharp/Grpc.IntegrationTesting/Messages.cs
src/csharp/Grpc.IntegrationTesting/Test.cs
src/csharp/Grpc.IntegrationTesting/TestGrpc.cs
src/csharp/build/dependencies.props
src/objective-c/!ProtoCompiler-gRPCCppPlugin.podspec
src/objective-c/!ProtoCompiler-gRPCPlugin.podspec
src/objective-c/!ProtoCompiler.podspec
src/objective-c/GRPCClient/version.h
src/objective-c/tests/version.h
src/php/composer.json
src/php/docker/alpine/Dockerfile
src/php/docker/centos7/Dockerfile
src/php/docker/grpc-ext/Dockerfile
src/php/docker/grpc-src/Dockerfile
src/php/docker/i386/Dockerfile
src/php/docker/php-future/Dockerfile
src/php/docker/php-src/Dockerfile
src/php/docker/php-zts/Dockerfile
src/php/docker/php8/Dockerfile
src/php/ext/grpc/php_grpc.c
src/php/ext/grpc/version.h
src/php/tests/generated_code/GPBMetadata/Math.php
src/php/tests/interop/GPBMetadata/Src/Proto/Grpc/Testing/Messages.php
src/php/tests/interop/GPBMetadata/Src/Proto/Grpc/Testing/PBEmpty.php
src/php/tests/interop/GPBMetadata/Src/Proto/Grpc/Testing/Test.php
src/php/tests/interop/Grpc/Testing/ClientConfigureRequest.php [new file with mode: 0644]
src/php/tests/interop/Grpc/Testing/ClientConfigureRequest/Metadata.php [new file with mode: 0644]
src/php/tests/interop/Grpc/Testing/ClientConfigureRequest/RpcType.php [new file with mode: 0644]
src/php/tests/interop/Grpc/Testing/ClientConfigureRequest_Metadata.php [new file with mode: 0644]
src/php/tests/interop/Grpc/Testing/ClientConfigureRequest_RpcType.php [new file with mode: 0644]
src/php/tests/interop/Grpc/Testing/ClientConfigureResponse.php [new file with mode: 0644]
src/php/tests/interop/Grpc/Testing/LoadBalancerAccumulatedStatsRequest.php [new file with mode: 0644]
src/php/tests/interop/Grpc/Testing/LoadBalancerAccumulatedStatsResponse.php [new file with mode: 0644]
src/php/tests/interop/Grpc/Testing/LoadBalancerStatsServiceClient.php
src/php/tests/interop/Grpc/Testing/XdsUpdateClientConfigureServiceClient.php [new file with mode: 0644]
src/php/tests/unit_tests/CallCredentialsTest.php
src/php/tests/unit_tests/CallInvokerTest.php
src/php/tests/unit_tests/CallTest.php
src/php/tests/unit_tests/ChannelCredentialsTest.php
src/php/tests/unit_tests/ChannelTest.php
src/php/tests/unit_tests/EndToEndTest.php
src/php/tests/unit_tests/PersistentChannelTests/PersistentChannelTest.php
src/php/tests/unit_tests/ServerTest.php
src/php/tests/unit_tests/TimevalTest.php
src/proto/grpc/testing/xds/v3/BUILD
src/proto/grpc/testing/xds/v3/base.proto
src/proto/grpc/testing/xds/v3/cluster.proto
src/proto/grpc/testing/xds/v3/string.proto [new file with mode: 0644]
src/proto/grpc/testing/xds/v3/tls.proto [new file with mode: 0644]
src/python/grpcio/grpc/_cython/_cygrpc/aio/call.pyx.pxi
src/python/grpcio/grpc/_cython/_cygrpc/aio/callback_common.pyx.pxi
src/python/grpcio/grpc/_cython/_cygrpc/aio/server.pxd.pxi
src/python/grpcio/grpc/_cython/_cygrpc/aio/server.pyx.pxi
src/python/grpcio/grpc/_grpcio_metadata.py
src/python/grpcio/grpc/aio/_base_server.py
src/python/grpcio/grpc_core_dependencies.py
src/python/grpcio/grpc_version.py
src/python/grpcio_channelz/grpc_version.py
src/python/grpcio_health_checking/grpc_version.py
src/python/grpcio_reflection/grpc_version.py
src/python/grpcio_status/grpc_version.py
src/python/grpcio_testing/grpc_version.py
src/python/grpcio_tests/grpc_version.py
src/python/grpcio_tests/tests_aio/unit/_test_server.py
src/python/grpcio_tests/tests_aio/unit/call_test.py
src/python/grpcio_tests/tests_aio/unit/server_test.py
src/python/grpcio_tests/tests_py3_only/interop/xds_interop_client.py
src/ruby/end2end/package_with_underscore_test.rb
src/ruby/ext/grpc/rb_event_thread.c
src/ruby/ext/grpc/rb_grpc_imports.generated.c
src/ruby/ext/grpc/rb_grpc_imports.generated.h
src/ruby/lib/grpc/version.rb
src/ruby/pb/src/proto/grpc/testing/messages_pb.rb
src/ruby/pb/src/proto/grpc/testing/test_services_pb.rb
src/ruby/pb/test/xds_client.rb
src/ruby/qps/src/proto/grpc/testing/messages_pb.rb
src/ruby/spec/pb/codegen/package_option_spec.rb
src/ruby/tools/version.rb
src/upb/gen_build_yaml.py
templates/Makefile.template
templates/gRPC-C++.podspec.template
templates/gRPC-Core.podspec.template
templates/grpc.gemspec.template
templates/src/csharp/build/dependencies.props.template
templates/src/objective-c/!ProtoCompiler-gRPCCppPlugin.podspec.template
templates/src/objective-c/!ProtoCompiler-gRPCPlugin.podspec.template
templates/src/objective-c/!ProtoCompiler.podspec.template [new file with mode: 0644]
templates/src/php/docker/download_phpunit.include
templates/src/php/docker/php8/Dockerfile.template
templates/test/cpp/naming/resolver_component_tests_defs.include
templates/tools/distrib/python/grpc_version.py.template
templates/tools/distrib/python/grpcio_tools/grpc_version.py.template
templates/tools/dockerfile/bazel.include
templates/tools/dockerfile/interoptest/grpc_interop_ruby/Dockerfile.template
templates/tools/dockerfile/ruby_deps.include
templates/tools/dockerfile/test/ruby_buster_x64/Dockerfile.template [moved from templates/tools/dockerfile/test/ruby_jessie_x64/Dockerfile.template with 93% similarity]
templates/tools/dockerfile/test/sanity/Dockerfile.template
templates/tools/run_tests/generated/lb_interop_test_scenarios.json.template [deleted file]
test/core/bad_client/bad_client.cc
test/core/bad_client/tests/duplicate_header.cc
test/core/bad_client/tests/head_of_line_blocking.cc
test/core/bad_client/tests/server_registered_method.cc
test/core/bad_client/tests/simple_request.cc
test/core/bad_connection/close_fd_test.cc
test/core/bad_ssl/bad_ssl_test.cc
test/core/bad_ssl/server_common.cc
test/core/channel/channel_stack_builder_test.cc
test/core/channel/channel_trace_test.cc
test/core/channel/channelz_test.cc
test/core/client_channel/resolvers/dns_resolver_connectivity_test.cc
test/core/client_channel/resolvers/dns_resolver_cooldown_test.cc
test/core/client_channel/resolvers/dns_resolver_test.cc
test/core/client_channel/resolvers/fake_resolver_test.cc
test/core/client_channel/resolvers/sockaddr_resolver_test.cc
test/core/client_channel/retry_throttle_test.cc
test/core/client_channel/service_config_test.cc
test/core/end2end/bad_server_response_test.cc
test/core/end2end/connection_refused_test.cc
test/core/end2end/cq_verifier.cc
test/core/end2end/cq_verifier.h
test/core/end2end/dualstack_socket_test.cc
test/core/end2end/end2end_nosec_tests.cc
test/core/end2end/end2end_tests.cc
test/core/end2end/end2end_tests.h
test/core/end2end/fixtures/h2_fakesec.cc
test/core/end2end/fixtures/h2_insecure.cc [new file with mode: 0644]
test/core/end2end/fixtures/h2_sockpair+trace.cc
test/core/end2end/fixtures/h2_sockpair.cc
test/core/end2end/fixtures/h2_sockpair_1byte.cc
test/core/end2end/fixtures/h2_tls.cc
test/core/end2end/fuzzers/client_fuzzer.cc
test/core/end2end/fuzzers/server_fuzzer.cc
test/core/end2end/generate_tests.bzl
test/core/end2end/goaway_server_test.cc
test/core/end2end/h2_ssl_session_reuse_test.cc
test/core/end2end/invalid_call_argument_test.cc
test/core/end2end/no_server_test.cc
test/core/end2end/tests/authority_not_supported.cc
test/core/end2end/tests/bad_hostname.cc
test/core/end2end/tests/bad_ping.cc
test/core/end2end/tests/binary_metadata.cc
test/core/end2end/tests/call_creds.cc
test/core/end2end/tests/call_host_override.cc
test/core/end2end/tests/cancel_after_accept.cc
test/core/end2end/tests/cancel_after_client_done.cc
test/core/end2end/tests/cancel_after_invoke.cc
test/core/end2end/tests/cancel_after_round_trip.cc
test/core/end2end/tests/cancel_before_invoke.cc
test/core/end2end/tests/cancel_in_a_vacuum.cc
test/core/end2end/tests/cancel_with_status.cc
test/core/end2end/tests/channelz.cc
test/core/end2end/tests/client_streaming.cc
test/core/end2end/tests/compressed_payload.cc
test/core/end2end/tests/connectivity.cc
test/core/end2end/tests/default_host.cc
test/core/end2end/tests/disappearing_server.cc
test/core/end2end/tests/empty_batch.cc
test/core/end2end/tests/filter_causes_close.cc
test/core/end2end/tests/filter_context.cc
test/core/end2end/tests/filter_init_fails.cc [moved from test/core/end2end/tests/filter_call_init_fails.cc with 89% similarity]
test/core/end2end/tests/filter_latency.cc
test/core/end2end/tests/filter_status_code.cc
test/core/end2end/tests/graceful_server_shutdown.cc
test/core/end2end/tests/high_initial_seqno.cc
test/core/end2end/tests/hpack_size.cc
test/core/end2end/tests/idempotent_request.cc
test/core/end2end/tests/invoke_large_request.cc
test/core/end2end/tests/keepalive_timeout.cc
test/core/end2end/tests/large_metadata.cc
test/core/end2end/tests/max_concurrent_streams.cc
test/core/end2end/tests/max_connection_age.cc
test/core/end2end/tests/max_connection_idle.cc
test/core/end2end/tests/max_message_length.cc
test/core/end2end/tests/negative_deadline.cc
test/core/end2end/tests/no_error_on_hotpath.cc
test/core/end2end/tests/no_logging.cc
test/core/end2end/tests/no_op.cc
test/core/end2end/tests/payload.cc
test/core/end2end/tests/ping.cc
test/core/end2end/tests/ping_pong_streaming.cc
test/core/end2end/tests/proxy_auth.cc
test/core/end2end/tests/registered_call.cc
test/core/end2end/tests/request_with_flags.cc
test/core/end2end/tests/request_with_payload.cc
test/core/end2end/tests/resource_quota_server.cc
test/core/end2end/tests/retry.cc
test/core/end2end/tests/retry_cancellation.cc
test/core/end2end/tests/retry_disabled.cc
test/core/end2end/tests/retry_exceeds_buffer_size_in_initial_batch.cc
test/core/end2end/tests/retry_exceeds_buffer_size_in_subsequent_batch.cc
test/core/end2end/tests/retry_non_retriable_status.cc
test/core/end2end/tests/retry_non_retriable_status_before_recv_trailing_metadata_started.cc
test/core/end2end/tests/retry_recv_initial_metadata.cc
test/core/end2end/tests/retry_recv_message.cc
test/core/end2end/tests/retry_server_pushback_delay.cc
test/core/end2end/tests/retry_server_pushback_disabled.cc
test/core/end2end/tests/retry_streaming.cc
test/core/end2end/tests/retry_streaming_after_commit.cc
test/core/end2end/tests/retry_streaming_succeeds_before_replay_finished.cc
test/core/end2end/tests/retry_throttled.cc
test/core/end2end/tests/retry_too_many_attempts.cc
test/core/end2end/tests/server_finishes_request.cc
test/core/end2end/tests/server_streaming.cc
test/core/end2end/tests/shutdown_finishes_calls.cc
test/core/end2end/tests/shutdown_finishes_tags.cc
test/core/end2end/tests/simple_cacheable_request.cc
test/core/end2end/tests/simple_delayed_request.cc
test/core/end2end/tests/simple_metadata.cc
test/core/end2end/tests/simple_request.cc
test/core/end2end/tests/stream_compression_compressed_payload.cc
test/core/end2end/tests/stream_compression_payload.cc
test/core/end2end/tests/stream_compression_ping_pong_streaming.cc
test/core/end2end/tests/streaming_error_response.cc
test/core/end2end/tests/trailing_metadata.cc
test/core/end2end/tests/workaround_cronet_compression.cc
test/core/end2end/tests/write_buffering.cc
test/core/end2end/tests/write_buffering_at_end.cc
test/core/fling/client.cc
test/core/fling/fling_stream_test.cc
test/core/fling/fling_test.cc
test/core/fling/server.cc
test/core/gpr/BUILD
test/core/gpr/arena_test.cc
test/core/gpr/log_test.cc
test/core/gpr/sync_test.cc
test/core/gprpp/fork_test.cc
test/core/gprpp/mpscq_test.cc
test/core/handshake/client_ssl.cc
test/core/handshake/readahead_handshaker_server_ssl.cc
test/core/http/httpcli_test.cc
test/core/http/httpscli_test.cc
test/core/iomgr/BUILD
test/core/iomgr/combiner_test.cc
test/core/iomgr/mpmcqueue_test.cc
test/core/iomgr/parse_address_test.cc
test/core/iomgr/parse_address_with_named_scope_id_test.cc
test/core/iomgr/poller/eventmanager_libuv_test.cc
test/core/iomgr/resolve_address_posix_test.cc
test/core/iomgr/resolve_address_test.cc
test/core/iomgr/resource_quota_test.cc
test/core/iomgr/stranded_event_test.cc
test/core/iomgr/tcp_posix_test.cc
test/core/iomgr/timer_list_test.cc
test/core/iomgr/work_serializer_test.cc
test/core/security/BUILD
test/core/security/credentials_test.cc
test/core/security/grpc_tls_certificate_distributor_test.cc
test/core/security/grpc_tls_certificate_provider_test.cc [new file with mode: 0644]
test/core/security/grpc_tls_credentials_options_test.cc
test/core/security/insecure_security_connector_test.cc
test/core/security/jwt_verifier_test.cc
test/core/security/security_connector_test.cc
test/core/security/tls_security_connector_test.cc
test/core/security/xds_credentials_test.cc [new file with mode: 0644]
test/core/surface/BUILD
test/core/surface/completion_queue_test.cc
test/core/surface/completion_queue_threading_test.cc
test/core/surface/concurrent_connectivity_test.cc
test/core/surface/lame_client_test.cc
test/core/surface/num_external_connectivity_watchers_test.cc
test/core/surface/public_headers_must_be_c89.c
test/core/transport/chttp2/stream_map_test.cc
test/core/transport/chttp2/too_many_pings_test.cc
test/core/tsi/alts/crypt/gsec_test_util.cc
test/core/tsi/alts/crypt/gsec_test_util.h
test/core/tsi/alts/frame_protector/frame_handler_test.cc
test/core/tsi/alts/handshaker/alts_concurrent_connectivity_test.cc
test/core/tsi/ssl_transport_security_test.cc
test/core/tsi/transport_security_test_lib.cc
test/core/uri/BUILD
test/core/uri/uri_fuzzer_test.cc
test/core/uri/uri_parser_test.cc
test/core/util/BUILD
test/core/util/cmdline.cc
test/core/util/cmdline_test.cc
test/core/util/debugger_macros.cc [deleted file]
test/core/util/histogram.cc
test/core/util/mock_endpoint.cc
test/core/util/mock_endpoint.h
test/core/util/passthru_endpoint.cc
test/core/util/stack_tracer.cc
test/core/util/test_config.cc
test/core/util/test_tcp_server.h
test/core/util/tls_utils.cc [new file with mode: 0644]
test/core/util/tls_utils.h [new file with mode: 0644]
test/core/xds/BUILD
test/core/xds/certificate_provider_store_test.cc
test/core/xds/xds_bootstrap_test.cc
test/core/xds/xds_certificate_provider_test.cc
test/cpp/client/BUILD
test/cpp/client/client_channel_stress_test.cc
test/cpp/client/credentials_test.cc
test/cpp/client/destroy_grpclb_channel_with_active_connect_stress_test.cc
test/cpp/common/channel_arguments_test.cc
test/cpp/end2end/BUILD
test/cpp/end2end/async_end2end_test.cc
test/cpp/end2end/cfstream_test.cc
test/cpp/end2end/channelz_service_test.cc
test/cpp/end2end/client_callback_end2end_test.cc
test/cpp/end2end/client_interceptors_end2end_test.cc
test/cpp/end2end/client_lb_end2end_test.cc
test/cpp/end2end/delegating_channel_test.cc
test/cpp/end2end/end2end_test.cc
test/cpp/end2end/filter_end2end_test.cc
test/cpp/end2end/flaky_network_test.cc
test/cpp/end2end/generic_end2end_test.cc
test/cpp/end2end/grpclb_end2end_test.cc
test/cpp/end2end/hybrid_end2end_test.cc
test/cpp/end2end/interceptors_util.h
test/cpp/end2end/raw_end2end_test.cc
test/cpp/end2end/server_interceptors_end2end_test.cc
test/cpp/end2end/service_config_end2end_test.cc
test/cpp/end2end/shutdown_test.cc
test/cpp/end2end/thread_stress_test.cc
test/cpp/end2end/time_change_test.cc
test/cpp/end2end/xds_credentials_end2end_test.cc
test/cpp/end2end/xds_end2end_test.cc
test/cpp/ext/filters/census/stats_plugin_end2end_test.cc
test/cpp/interop/client_helper.h
test/cpp/interop/http2_client.h
test/cpp/interop/interop_server.cc
test/cpp/interop/server_helper.h
test/cpp/interop/stress_interop_client.h
test/cpp/interop/xds_interop_client.cc
test/cpp/interop/xds_interop_server.cc
test/cpp/microbenchmarks/bm_call_create.cc
test/cpp/microbenchmarks/bm_chttp2_transport.cc
test/cpp/microbenchmarks/bm_cq.cc
test/cpp/microbenchmarks/bm_cq_multiple_threads.cc
test/cpp/microbenchmarks/bm_fullstack_trickle.cc
test/cpp/microbenchmarks/bm_threadpool.cc
test/cpp/microbenchmarks/fullstack_context_mutators.h
test/cpp/microbenchmarks/fullstack_fixtures.h
test/cpp/microbenchmarks/fullstack_streaming_ping_pong.h
test/cpp/microbenchmarks/fullstack_streaming_pump.h
test/cpp/naming/BUILD
test/cpp/naming/address_sorting_test.cc
test/cpp/naming/cancel_ares_query_test.cc
test/cpp/naming/dns_test_util.cc
test/cpp/naming/gen_build_yaml.py
test/cpp/naming/resolver_component_test.cc
test/cpp/naming/resolver_component_tests_runner.py
test/cpp/naming/resolver_component_tests_runner_invoker.cc
test/cpp/naming/utils/dns_server.py
test/cpp/qps/client.h
test/cpp/qps/client_async.cc
test/cpp/qps/client_callback.cc
test/cpp/qps/client_sync.cc
test/cpp/qps/histogram.h
test/cpp/qps/parse_json.cc
test/cpp/qps/qps_benchmark_script.bzl
test/cpp/qps/qps_worker.cc
test/cpp/qps/report.h
test/cpp/server/BUILD
test/cpp/server/credentials_test.cc
test/cpp/server/server_builder_with_socket_mutator_test.cc
test/cpp/server/server_request_call_test.cc
test/cpp/util/channelz_sampler_test.cc
test/cpp/util/cli_call.cc
test/cpp/util/grpc_cli.cc
test/cpp/util/grpc_tool.cc
test/cpp/util/grpc_tool_test.cc
test/cpp/util/subprocess.h
third_party/BUILD
third_party/cares/cares.BUILD
third_party/protobuf.patch [new file with mode: 0644]
third_party/rake-compiler-dock/README.md [deleted file]
third_party/rake-compiler-dock/build/patchelf_gem.sh [deleted file]
third_party/rake-compiler-dock/build/patches/ruby-2.5.7/no_sendfile.patch [deleted file]
third_party/rake-compiler-dock/build/patches/ruby-2.7.0/no_sendfile.patch [deleted file]
third_party/rake-compiler-dock/build/patches2/hoe-3.20.0/0001-Load-encrypted-private-key-using-ENV-GEM_PRIVATE_KEY.patch [deleted file]
third_party/rake-compiler-dock/build/patches2/rake-compiler-1.1.0/0001-Fix-determining-of-ruby-versions-in-rake-native-gem.patch [deleted file]
third_party/rake-compiler-dock/build/patches2/rake-compiler-1.1.0/0001-cross-ruby-remove-needless-Makefile.in-preparation.patch [deleted file]
third_party/rake-compiler-dock/build/patches2/rake-compiler-1.1.0/0002-Extend-mingw-search-pattern-to-find-x86_64-gcc.patch [deleted file]
third_party/rake-compiler-dock/build/patches2/rake-compiler-1.1.0/0002-Strip-cross-built-shared-library-files-while-linking.patch [deleted file]
third_party/rake-compiler-dock/build/patches2/rake-compiler-1.1.0/0003-Allow-building-of-cross-rubies-in-parallel.patch [deleted file]
third_party/rake-compiler-dock/build/patches2/rake-compiler-1.1.0/0004-Enable-build-of-static-libruby.patch [deleted file]
third_party/rake-compiler-dock/build/patches2/ruby-2.7.0/ruby2_keywords.patch [deleted file]
third_party/rake-compiler-dock/build/sigfw.c [deleted file]
third_party/rake-compiler-dock/push_testing_images.sh [deleted file]
third_party/rake-compiler-dock/rake_x64-mingw32/Dockerfile
third_party/rake-compiler-dock/rake_x86-linux/Dockerfile
third_party/rake-compiler-dock/rake_x86-mingw32/Dockerfile
third_party/rake-compiler-dock/rake_x86_64-linux/Dockerfile
third_party/upb/.bazelrc [new file with mode: 0644]
third_party/upb/BUILD [new file with mode: 0644]
third_party/upb/WORKSPACE
third_party/upb/bazel/build_defs.bzl
third_party/upb/bazel/lua.BUILD
third_party/upb/bazel/ragel.BUILD
third_party/upb/bazel/upb_proto_library.bzl
third_party/upb/bazel/workspace_deps.bzl
third_party/upb/benchmark.py [deleted file]
third_party/upb/benchmarks/BUILD [new file with mode: 0644]
third_party/upb/benchmarks/BUILD.googleapis [new file with mode: 0644]
third_party/upb/benchmarks/benchmark.cc [new file with mode: 0644]
third_party/upb/benchmarks/build_defs.bzl [new file with mode: 0644]
third_party/upb/benchmarks/compare.py [new file with mode: 0755]
third_party/upb/benchmarks/descriptor.proto [new file with mode: 0644]
third_party/upb/benchmarks/descriptor_sv.proto [new file with mode: 0644]
third_party/upb/benchmarks/empty.proto [new file with mode: 0644]
third_party/upb/benchmarks/gen_protobuf_binary_cc.py [new file with mode: 0644]
third_party/upb/benchmarks/gen_synthetic_protos.py [new file with mode: 0644]
third_party/upb/benchmarks/gen_upb_binary_c.py [new file with mode: 0644]
third_party/upb/cmake/BUILD [new file with mode: 0644]
third_party/upb/cmake/CMakeLists.txt [moved from third_party/upb/CMakeLists.txt with 69% similarity]
third_party/upb/cmake/README.md [new file with mode: 0644]
third_party/upb/cmake/build_defs.bzl [new file with mode: 0644]
third_party/upb/cmake/google/protobuf/descriptor.upb.c [moved from third_party/upb/generated_for_cmake/google/protobuf/descriptor.upb.c with 80% similarity]
third_party/upb/cmake/google/protobuf/descriptor.upb.h [moved from third_party/upb/generated_for_cmake/google/protobuf/descriptor.upb.h with 84% similarity]
third_party/upb/cmake/make_cmakelists.py [moved from third_party/upb/tools/make_cmakelists.py with 91% similarity]
third_party/upb/cmake/staleness_test.py [moved from third_party/upb/tools/staleness_test.py with 94% similarity]
third_party/upb/cmake/staleness_test_lib.py [moved from third_party/upb/tools/staleness_test_lib.py with 93% similarity]
third_party/upb/cmake/upb/json/parser.c [moved from third_party/upb/generated_for_cmake/upb/json/parser.c with 99% similarity]
third_party/upb/examples/bazel/BUILD
third_party/upb/examples/bazel/test_binary.c
third_party/upb/kokoro/ubuntu/build.sh
third_party/upb/kokoro/ubuntu/presubmit.cfg
third_party/upb/tests/BUILD [new file with mode: 0644]
third_party/upb/tests/benchmark.cc [deleted file]
third_party/upb/tests/bindings/lua/BUILD [new file with mode: 0644]
third_party/upb/tests/bindings/lua/main.c
third_party/upb/tests/bindings/lua/test.proto [new file with mode: 0644]
third_party/upb/tests/bindings/lua/test_upb.lua
third_party/upb/tests/conformance_upb.c
third_party/upb/tests/pb/test_decoder.cc
third_party/upb/tests/pb/test_encoder.cc
third_party/upb/tests/pb/test_varint.c [deleted file]
third_party/upb/tests/test_cpp.cc
third_party/upb/tests/test_generated_code.c
third_party/upb/tests/test_table.cc
third_party/upb/third_party/wyhash/BUILD [new file with mode: 0644]
third_party/upb/third_party/wyhash/LICENSE [new file with mode: 0644]
third_party/upb/third_party/wyhash/wyhash.h [new file with mode: 0644]
third_party/upb/upb/bindings/lua/BUILD [new file with mode: 0644]
third_party/upb/upb/bindings/lua/def.c
third_party/upb/upb/bindings/lua/lua_proto_library.bzl
third_party/upb/upb/bindings/lua/msg.c
third_party/upb/upb/bindings/lua/upb.c
third_party/upb/upb/bindings/lua/upb.h
third_party/upb/upb/bindings/stdc++/string.h [deleted file]
third_party/upb/upb/decode.c
third_party/upb/upb/decode.h
third_party/upb/upb/decode.int.h [new file with mode: 0644]
third_party/upb/upb/decode_fast.c [new file with mode: 0644]
third_party/upb/upb/decode_fast.h [new file with mode: 0644]
third_party/upb/upb/def.c
third_party/upb/upb/def.h
third_party/upb/upb/def.hpp
third_party/upb/upb/encode.c
third_party/upb/upb/encode.h
third_party/upb/upb/handlers.c
third_party/upb/upb/json/parser.rl
third_party/upb/upb/json/printer.c
third_party/upb/upb/json_decode.c
third_party/upb/upb/json_encode.c
third_party/upb/upb/json_encode.h
third_party/upb/upb/msg.c
third_party/upb/upb/msg.h
third_party/upb/upb/pb/compile_decoder.c
third_party/upb/upb/pb/encoder.c
third_party/upb/upb/pb/textprinter.c
third_party/upb/upb/pb/varint.int.h
third_party/upb/upb/port.c [deleted file]
third_party/upb/upb/port_def.inc
third_party/upb/upb/port_undef.inc
third_party/upb/upb/reflection.c
third_party/upb/upb/table.c
third_party/upb/upb/table.int.h
third_party/upb/upb/text_encode.c
third_party/upb/upb/text_encode.h
third_party/upb/upb/upb.c
third_party/upb/upb/upb.h
third_party/upb/upb/upb.hpp
third_party/upb/upb/upb.int.h [new file with mode: 0644]
third_party/upb/upbc/BUILD [new file with mode: 0644]
third_party/upb/upbc/common.cc [new file with mode: 0644]
third_party/upb/upbc/common.h [new file with mode: 0644]
third_party/upb/upbc/generator.h [deleted file]
third_party/upb/upbc/main.cc [deleted file]
third_party/upb/upbc/message_layout.cc
third_party/upb/upbc/message_layout.h
third_party/upb/upbc/protoc-gen-upb.cc [moved from third_party/upb/upbc/generator.cc with 69% similarity]
third_party/upb/upbc/protoc-gen-upbdefs.cc [new file with mode: 0644]
tools/bazel
tools/buildgen/build_cleaner.py
tools/buildgen/generate_build_additions.sh
tools/buildgen/generate_projects.sh
tools/buildgen/mako_renderer.py
tools/buildgen/plugins/expand_version.py
tools/codegen/core/gen_static_metadata.py
tools/codegen/core/gen_upb_api.sh
tools/distrib/check_copyright.py
tools/distrib/check_include_guards.py
tools/distrib/python/grpc_version.py
tools/distrib/python/grpcio_tools/grpc_version.py
tools/distrib/python/grpcio_tools/protoc_lib_deps.py
tools/distrib/rake_compiler_docker_image.rb
tools/distrib/run_clang_tidy.py
tools/dockerfile/distribtest/ruby_jessie_x64_ruby_3_0/Dockerfile [moved from tools/dockerfile/distribtest/ruby_centos6_x64/Dockerfile with 57% similarity]
tools/dockerfile/grpc_clang_tidy/clang_tidy_all_the_things.sh
tools/dockerfile/interoptest/grpc_interop_ruby/Dockerfile
tools/dockerfile/interoptest/lb_interop_fake_servers/build_interop.sh [deleted file]
tools/dockerfile/push_testing_images.sh
tools/dockerfile/test/bazel/Dockerfile
tools/dockerfile/test/ruby_buster_x64/Dockerfile [moved from tools/dockerfile/test/ruby_jessie_x64/Dockerfile with 86% similarity]
tools/dockerfile/test/sanity/Dockerfile
tools/doxygen/Doxyfile.c++
tools/doxygen/Doxyfile.c++.internal
tools/doxygen/Doxyfile.core.internal
tools/doxygen/Doxyfile.objc
tools/doxygen/Doxyfile.objc.internal
tools/doxygen/Doxyfile.php
tools/failures/detect_new_failures.py [deleted file]
tools/failures/sql/new_failures_24h.sql [deleted file]
tools/internal_ci/helper_scripts/prepare_build_grpclb_interop_rc [deleted file]
tools/internal_ci/helper_scripts/prepare_build_macos_rc
tools/internal_ci/linux/grpc_android.sh
tools/internal_ci/linux/grpc_xds_bazel_python_test_in_docker.sh
tools/internal_ci/linux/grpc_xds_bazel_test_in_docker.sh
tools/internal_ci/linux/grpc_xds_csharp_test_in_docker.sh
tools/internal_ci/linux/grpc_xds_php_test_in_docker.sh
tools/internal_ci/linux/grpc_xds_ruby.sh
tools/internal_ci/linux/grpc_xds_ruby_test_in_docker.sh
tools/internal_ci/windows/bazel_rbe.bat
tools/interop_matrix/client_matrix.py
tools/interop_matrix/testcases/go__master
tools/interop_matrix/testcases/go__v1.20.0 [new file with mode: 0755]
tools/profiling/bloat/bloat_diff.py
tools/run_tests/artifacts/artifact_targets.py
tools/run_tests/artifacts/build_artifact_protoc.sh
tools/run_tests/artifacts/distribtest_targets.py
tools/run_tests/generated/tests.json
tools/run_tests/helper_scripts/build_ruby.sh
tools/run_tests/performance/scenario_config_exporter.py [new file with mode: 0755]
tools/run_tests/run_tests.py
tools/run_tests/run_xds_tests.py
tools/run_tests/sanity/check_bazel_workspace.py
tools/run_tests/sanity/check_deprecated_grpc++.py
tools/run_tests/sanity/check_port_platform.py
tools/run_tests/sanity/check_submodules.sh
tools/run_tests/sanity/check_test_filtering.py
tools/run_tests/sanity/check_tracer_sanity.py
tools/run_tests/sanity/check_version.py
tools/run_tests/sanity/core_banned_functions.py
tools/run_tests/xds_k8s_test_driver/.gitignore [new file with mode: 0644]
tools/run_tests/xds_k8s_test_driver/README.md [new file with mode: 0644]
tools/run_tests/xds_k8s_test_driver/bin/__init__.py [moved from tools/internal_ci/linux/grpclb_in_dns_interop.cfg with 61% similarity]
tools/run_tests/xds_k8s_test_driver/bin/run_channelz.py [new file with mode: 0755]
tools/run_tests/xds_k8s_test_driver/bin/run_td_setup.py [new file with mode: 0755]
tools/run_tests/xds_k8s_test_driver/bin/run_test_client.py [new file with mode: 0755]
tools/run_tests/xds_k8s_test_driver/bin/run_test_server.py [new file with mode: 0755]
tools/run_tests/xds_k8s_test_driver/config/common.cfg [new file with mode: 0644]
tools/run_tests/xds_k8s_test_driver/config/grpc-testing.cfg [new file with mode: 0644]
tools/run_tests/xds_k8s_test_driver/config/local-dev.cfg.example [new file with mode: 0644]
tools/run_tests/xds_k8s_test_driver/framework/__init__.py [moved from tools/internal_ci/linux/grpc_run_grpclb_interop_tests.sh with 58% similarity, mode: 0644]
tools/run_tests/xds_k8s_test_driver/framework/helpers/__init__.py [new file with mode: 0644]
tools/run_tests/xds_k8s_test_driver/framework/helpers/retryers.py [new file with mode: 0644]
tools/run_tests/xds_k8s_test_driver/framework/infrastructure/__init__.py [new file with mode: 0644]
tools/run_tests/xds_k8s_test_driver/framework/infrastructure/gcp/__init__.py [new file with mode: 0644]
tools/run_tests/xds_k8s_test_driver/framework/infrastructure/gcp/api.py [new file with mode: 0644]
tools/run_tests/xds_k8s_test_driver/framework/infrastructure/gcp/compute.py [new file with mode: 0644]
tools/run_tests/xds_k8s_test_driver/framework/infrastructure/gcp/network_security.py [new file with mode: 0644]
tools/run_tests/xds_k8s_test_driver/framework/infrastructure/gcp/network_services.py [new file with mode: 0644]
tools/run_tests/xds_k8s_test_driver/framework/infrastructure/k8s.py [new file with mode: 0644]
tools/run_tests/xds_k8s_test_driver/framework/infrastructure/traffic_director.py [new file with mode: 0644]
tools/run_tests/xds_k8s_test_driver/framework/rpc/__init__.py [new file with mode: 0644]
tools/run_tests/xds_k8s_test_driver/framework/rpc/grpc.py [new file with mode: 0644]
tools/run_tests/xds_k8s_test_driver/framework/rpc/grpc_channelz.py [new file with mode: 0644]
tools/run_tests/xds_k8s_test_driver/framework/rpc/grpc_testing.py [new file with mode: 0644]
tools/run_tests/xds_k8s_test_driver/framework/test_app/__init__.py [new file with mode: 0644]
tools/run_tests/xds_k8s_test_driver/framework/test_app/base_runner.py [new file with mode: 0644]
tools/run_tests/xds_k8s_test_driver/framework/test_app/client_app.py [new file with mode: 0644]
tools/run_tests/xds_k8s_test_driver/framework/test_app/server_app.py [new file with mode: 0644]
tools/run_tests/xds_k8s_test_driver/framework/xds_flags.py [new file with mode: 0644]
tools/run_tests/xds_k8s_test_driver/framework/xds_k8s_flags.py [new file with mode: 0644]
tools/run_tests/xds_k8s_test_driver/framework/xds_k8s_testcase.py [new file with mode: 0644]
tools/run_tests/xds_k8s_test_driver/kubernetes-manifests/client-secure.deployment.yaml [new file with mode: 0644]
tools/run_tests/xds_k8s_test_driver/kubernetes-manifests/client.deployment.yaml [new file with mode: 0644]
tools/run_tests/xds_k8s_test_driver/kubernetes-manifests/namespace.yaml [new file with mode: 0644]
tools/run_tests/xds_k8s_test_driver/kubernetes-manifests/server-secure.deployment.yaml [new file with mode: 0644]
tools/run_tests/xds_k8s_test_driver/kubernetes-manifests/server.deployment.yaml [new file with mode: 0644]
tools/run_tests/xds_k8s_test_driver/kubernetes-manifests/server.service.yaml [new file with mode: 0644]
tools/run_tests/xds_k8s_test_driver/kubernetes-manifests/service-account.yaml [new file with mode: 0644]
tools/run_tests/xds_k8s_test_driver/requirements.txt [new file with mode: 0644]
tools/run_tests/xds_k8s_test_driver/tests/__init__.py [new file with mode: 0644]
tools/run_tests/xds_k8s_test_driver/tests/baseline_test.py [new file with mode: 0644]
tools/run_tests/xds_k8s_test_driver/tests/security_test.py [new file with mode: 0644]

index 797afef..b85dcc0 100644 (file)
@@ -6,6 +6,11 @@ bins
 libs
 objs
 third_party/abseil-cpp
+third_party/bloaty
+third_party/boringssl-with-bazel
 third_party/googleapis
+third_party/googletest
+third_party/protobuf
 third_party/protoc-gen-validate
 third_party/udpa
+third_party/upb
index 8a377f3..752b25e 100644 (file)
@@ -4,17 +4,12 @@ Checks: '-*,
   abseil-*,
   -abseil-no-namespace,
   bugprone-*,
-  -bugprone-integer-division,
   -bugprone-narrowing-conversions,
   -bugprone-too-small-loop-variable,
   performance-*,
   -performance-unnecessary-copy-initialization,
   -performance-unnecessary-value-param,
   google-*,
-  -google-build-using-namespace,
-  -google-explicit-constructor,
-  -google-readability-casting,
-  -google-readability-todo,
   -google-runtime-int,
   -google-runtime-references,
   misc-definitions-in-headers,
@@ -33,7 +28,7 @@ Checks: '-*,
   readability-container-size-empty,
   readability-deleted-default,
   readability-function-size,
-  -readability-inconsistent-declaration-parameter-name,
+  readability-inconsistent-declaration-parameter-name,
   readability-redundant-control-flow,
   readability-redundant-smartptr-get,
   readability-string-compare'
index 2692dc7..1a096d5 100644 (file)
@@ -2,7 +2,7 @@
 name: Report a bug
 about: Create a report to help us improve
 labels: kind/bug, priority/P2
-assignees: karthikravis
+assignees: donnadionne
 
 ---
 
index bea10f3..ef88ef4 100644 (file)
@@ -2,7 +2,7 @@
 name: Request a cleanup
 about: Suggest a cleanup in our repository
 labels: kind/internal cleanup, priority/P2
-assignees: karthikravis
+assignees: donnadionne
 
 ---
 
index e113497..f230fe2 100644 (file)
@@ -2,7 +2,7 @@
 name: Request a feature
 about: Suggest an idea for this project
 labels: kind/enhancement, priority/P2
-assignees: karthikravis
+assignees: donnadionne
 
 ---
 
index db52e41..77ecf5e 100644 (file)
@@ -2,7 +2,7 @@
 name: Ask a question
 about: Ask a question
 labels: kind/question, priority/P3
-assignees: karthikravis
+assignees: donnadionne
 
 ---
 
index 681d2f8..eddba66 100644 (file)
@@ -8,4 +8,4 @@ If you know who should review your pull request, please remove the mentioning be
 
 -->
 
-@karthikravis
+@donnadionne
diff --git a/BUILD b/BUILD
index 6601b27..909b811 100644 (file)
--- a/BUILD
+++ b/BUILD
@@ -80,11 +80,11 @@ config_setting(
 python_config_settings()
 
 # This should be updated along with build_handwritten.yaml
-g_stands_for = "gauntlet"
+g_stands_for = "gecko"
 
 core_version = "14.0.0"
 
-version = "1.34.1"
+version = "1.35.0"
 
 GPR_PUBLIC_HDRS = [
     "include/grpc/support/alloc.h",
@@ -323,11 +323,11 @@ grpc_cc_library(
         "grpc_no_xds": [],
         "//conditions:default": [
             "grpc_lb_policy_cds",
-            "grpc_lb_policy_eds",
             "grpc_lb_policy_xds_cluster_impl",
             "grpc_lb_policy_xds_cluster_manager",
+            "grpc_lb_policy_xds_cluster_resolver",
             "grpc_resolver_xds",
-            "grpc_xds_credentials",
+            "grpc_xds_server_config_fetcher",
         ],
     },
     standalone = True,
@@ -344,6 +344,9 @@ grpc_cc_library(
 grpc_cc_library(
     name = "grpc++_public_hdrs",
     hdrs = GRPCXX_PUBLIC_HDRS,
+    external_deps = [
+        "protobuf_headers",
+    ],
 )
 
 grpc_cc_library(
@@ -367,12 +370,16 @@ grpc_cc_library(
         "src/cpp/common/tls_credentials_options_util.h",
         "src/cpp/server/secure_server_credentials.h",
     ],
+    external_deps = [
+        "protobuf_headers",
+    ],
     language = "c++",
     public_hdrs = GRPCXX_PUBLIC_HDRS,
     select_deps = {
         "grpc_no_xds": [],
         "//conditions:default": [
-            "grpc++_xds_credentials",
+            "grpc++_xds_client",
+            "grpc++_xds_server",
         ],
     },
     standalone = True,
@@ -388,7 +395,7 @@ grpc_cc_library(
 )
 
 grpc_cc_library(
-    name = "grpc++_xds_credentials",
+    name = "grpc++_xds_client",
     srcs = [
         "src/cpp/client/xds_credentials.cc",
     ],
@@ -402,6 +409,23 @@ grpc_cc_library(
 )
 
 grpc_cc_library(
+    name = "grpc++_xds_server",
+    srcs = [
+        "src/cpp/server/xds_server_credentials.cc",
+    ],
+    hdrs = [
+        "src/cpp/server/secure_server_credentials.h",
+    ],
+    language = "c++",
+    public_hdrs = [
+        "include/grpcpp/xds_server_builder.h",
+    ],
+    deps = [
+        "grpc++_base",
+    ],
+)
+
+grpc_cc_library(
     name = "grpc++_unsecure",
     srcs = [
         "src/cpp/client/insecure_credentials.cc",
@@ -567,7 +591,6 @@ grpc_cc_library(
         "src/core/lib/gprpp/global_config_generic.h",
         "src/core/lib/gprpp/host_port.h",
         "src/core/lib/gprpp/manual_constructor.h",
-        "src/core/lib/gprpp/map.h",
         "src/core/lib/gprpp/memory.h",
         "src/core/lib/gprpp/mpscq.h",
         "src/core/lib/gprpp/stat.h",
@@ -1002,8 +1025,10 @@ grpc_cc_library(
         "madler_zlib",
         "absl/container:inlined_vector",
         "absl/status",
+        "absl/status:statusor",
         "absl/strings",
         "absl/types:optional",
+        "absl/container:flat_hash_map",
     ],
     language = "c++",
     public_hdrs = GRPC_PUBLIC_HDRS,
@@ -1070,6 +1095,7 @@ grpc_cc_library(
         "src/core/ext/filters/client_channel/client_channel_factory.cc",
         "src/core/ext/filters/client_channel/client_channel_plugin.cc",
         "src/core/ext/filters/client_channel/config_selector.cc",
+        "src/core/ext/filters/client_channel/dynamic_filters.cc",
         "src/core/ext/filters/client_channel/global_subchannel_pool.cc",
         "src/core/ext/filters/client_channel/health/health_check_client.cc",
         "src/core/ext/filters/client_channel/http_connect_handshaker.cc",
@@ -1082,7 +1108,6 @@ grpc_cc_library(
         "src/core/ext/filters/client_channel/resolver.cc",
         "src/core/ext/filters/client_channel/resolver_registry.cc",
         "src/core/ext/filters/client_channel/resolver_result_parsing.cc",
-        "src/core/ext/filters/client_channel/resolving_lb_policy.cc",
         "src/core/ext/filters/client_channel/retry_throttle.cc",
         "src/core/ext/filters/client_channel/server_address.cc",
         "src/core/ext/filters/client_channel/service_config.cc",
@@ -1099,6 +1124,7 @@ grpc_cc_library(
         "src/core/ext/filters/client_channel/client_channel_factory.h",
         "src/core/ext/filters/client_channel/config_selector.h",
         "src/core/ext/filters/client_channel/connector.h",
+        "src/core/ext/filters/client_channel/dynamic_filters.h",
         "src/core/ext/filters/client_channel/global_subchannel_pool.h",
         "src/core/ext/filters/client_channel/health/health_check_client.h",
         "src/core/ext/filters/client_channel/http_connect_handshaker.h",
@@ -1114,7 +1140,6 @@ grpc_cc_library(
         "src/core/ext/filters/client_channel/resolver_factory.h",
         "src/core/ext/filters/client_channel/resolver_registry.h",
         "src/core/ext/filters/client_channel/resolver_result_parsing.h",
-        "src/core/ext/filters/client_channel/resolving_lb_policy.h",
         "src/core/ext/filters/client_channel/retry_throttle.h",
         "src/core/ext/filters/client_channel/server_address.h",
         "src/core/ext/filters/client_channel/service_config.h",
@@ -1335,45 +1360,33 @@ grpc_cc_library(
 )
 
 grpc_cc_library(
-    name = "grpc_xds_credentials",
+    name = "grpc_xds_client",
     srcs = [
         "src/core/ext/xds/certificate_provider_registry.cc",
         "src/core/ext/xds/certificate_provider_store.cc",
+        "src/core/ext/xds/file_watcher_certificate_provider_factory.cc",
+        "src/core/ext/xds/xds_api.cc",
+        "src/core/ext/xds/xds_bootstrap.cc",
         "src/core/ext/xds/xds_certificate_provider.cc",
+        "src/core/ext/xds/xds_client.cc",
+        "src/core/ext/xds/xds_client_stats.cc",
         "src/core/lib/security/credentials/xds/xds_credentials.cc",
     ],
     hdrs = [
         "src/core/ext/xds/certificate_provider_factory.h",
         "src/core/ext/xds/certificate_provider_registry.h",
         "src/core/ext/xds/certificate_provider_store.h",
-        "src/core/ext/xds/xds_certificate_provider.h",
-        "src/core/lib/security/credentials/xds/xds_credentials.h",
-    ],
-    external_deps = [
-        "absl/functional:bind_front",
-    ],
-    language = "c++",
-    deps = [
-        "grpc_secure",
-    ],
-)
-
-grpc_cc_library(
-    name = "grpc_xds_client",
-    srcs = [
-        "src/core/ext/xds/xds_api.cc",
-        "src/core/ext/xds/xds_bootstrap.cc",
-        "src/core/ext/xds/xds_client.cc",
-        "src/core/ext/xds/xds_client_stats.cc",
-    ],
-    hdrs = [
+        "src/core/ext/xds/file_watcher_certificate_provider_factory.h",
         "src/core/ext/xds/xds_api.h",
         "src/core/ext/xds/xds_bootstrap.h",
+        "src/core/ext/xds/xds_certificate_provider.h",
         "src/core/ext/xds/xds_channel_args.h",
         "src/core/ext/xds/xds_client.h",
         "src/core/ext/xds/xds_client_stats.h",
+        "src/core/lib/security/credentials/xds/xds_credentials.h",
     ],
     external_deps = [
+        "absl/functional:bind_front",
         "upb_lib",
         "upb_textformat_lib",
         "re2",
@@ -1384,25 +1397,19 @@ grpc_cc_library(
         "envoy_ads_upbdefs",
         "grpc_base",
         "grpc_client_channel",
-        "grpc_file_watcher_certificate_provider_factory",
-        "grpc_google_mesh_ca_certificate_provider_factory",
+        "grpc_secure",
         "grpc_transport_chttp2_client_secure",
-        "grpc_xds_credentials",
     ],
 )
 
 grpc_cc_library(
-    name = "grpc_file_watcher_certificate_provider_factory",
+    name = "grpc_xds_server_config_fetcher",
     srcs = [
-        "src/core/ext/xds/file_watcher_certificate_provider_factory.cc",
-    ],
-    hdrs = [
-        "src/core/ext/xds/file_watcher_certificate_provider_factory.h",
+        "src/core/ext/xds/xds_server_config_fetcher.cc",
     ],
     language = "c++",
     deps = [
-        "grpc_base",
-        "grpc_xds_credentials",
+        "grpc_xds_client",
     ],
 )
 
@@ -1417,7 +1424,7 @@ grpc_cc_library(
     language = "c++",
     deps = [
         "grpc_base",
-        "grpc_xds_credentials",
+        "grpc_xds_client",
     ],
 )
 
@@ -1435,6 +1442,14 @@ grpc_cc_library(
 )
 
 grpc_cc_library(
+    name = "grpc_lb_xds_channel_args",
+    hdrs = [
+        "src/core/ext/filters/client_channel/lb_policy/xds/xds_channel_args.h",
+    ],
+    language = "c++",
+)
+
+grpc_cc_library(
     name = "grpc_lb_xds_common",
     hdrs = [
         "src/core/ext/filters/client_channel/lb_policy/xds/xds.h",
@@ -1448,9 +1463,9 @@ grpc_cc_library(
 )
 
 grpc_cc_library(
-    name = "grpc_lb_policy_eds",
+    name = "grpc_lb_policy_xds_cluster_resolver",
     srcs = [
-        "src/core/ext/filters/client_channel/lb_policy/xds/eds.cc",
+        "src/core/ext/filters/client_channel/lb_policy/xds/xds_cluster_resolver.cc",
     ],
     external_deps = [
         "absl/strings",
@@ -1477,6 +1492,7 @@ grpc_cc_library(
     deps = [
         "grpc_base",
         "grpc_client_channel",
+        "grpc_lb_xds_channel_args",
         "grpc_lb_xds_common",
         "grpc_xds_client",
     ],
@@ -1731,12 +1747,10 @@ grpc_cc_library(
     name = "grpc_resolver_dns_ares",
     srcs = [
         "src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc",
-        "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.cc",
         "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_libuv.cc",
         "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_posix.cc",
         "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_windows.cc",
         "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc",
-        "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_fallback.cc",
         "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv.cc",
         "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_posix.cc",
         "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc",
@@ -1812,6 +1826,7 @@ grpc_cc_library(
         "src/core/lib/security/credentials/composite/composite_credentials.cc",
         "src/core/lib/security/credentials/credentials.cc",
         "src/core/lib/security/credentials/credentials_metadata.cc",
+        "src/core/lib/security/credentials/external/aws_external_account_credentials.cc",
         "src/core/lib/security/credentials/external/aws_request_signer.cc",
         "src/core/lib/security/credentials/external/external_account_credentials.cc",
         "src/core/lib/security/credentials/external/file_external_account_credentials.cc",
@@ -1832,6 +1847,7 @@ grpc_cc_library(
         "src/core/lib/security/credentials/tls/grpc_tls_certificate_provider.cc",
         "src/core/lib/security/credentials/tls/grpc_tls_credentials_options.cc",
         "src/core/lib/security/credentials/tls/tls_credentials.cc",
+        "src/core/lib/security/credentials/tls/tls_utils.cc",
         "src/core/lib/security/security_connector/alts/alts_security_connector.cc",
         "src/core/lib/security/security_connector/fake/fake_security_connector.cc",
         "src/core/lib/security/security_connector/insecure/insecure_security_connector.cc",
@@ -1858,6 +1874,7 @@ grpc_cc_library(
         "src/core/lib/security/credentials/alts/alts_credentials.h",
         "src/core/lib/security/credentials/composite/composite_credentials.h",
         "src/core/lib/security/credentials/credentials.h",
+        "src/core/lib/security/credentials/external/aws_external_account_credentials.h",
         "src/core/lib/security/credentials/external/aws_request_signer.h",
         "src/core/lib/security/credentials/external/external_account_credentials.h",
         "src/core/lib/security/credentials/external/file_external_account_credentials.h",
@@ -1876,6 +1893,7 @@ grpc_cc_library(
         "src/core/lib/security/credentials/tls/grpc_tls_certificate_provider.h",
         "src/core/lib/security/credentials/tls/grpc_tls_credentials_options.h",
         "src/core/lib/security/credentials/tls/tls_credentials.h",
+        "src/core/lib/security/credentials/tls/tls_utils.h",
         "src/core/lib/security/security_connector/alts/alts_security_connector.h",
         "src/core/lib/security/security_connector/fake/fake_security_connector.h",
         "src/core/lib/security/security_connector/insecure/insecure_security_connector.h",
@@ -1898,6 +1916,7 @@ grpc_cc_library(
     deps = [
         "alts_util",
         "grpc_base",
+        "grpc_lb_xds_channel_args",
         "grpc_transport_chttp2_alpn",
         "tsi",
     ],
@@ -2255,6 +2274,9 @@ grpc_cc_library(
     name = "grpc++_base",
     srcs = GRPCXX_SRCS,
     hdrs = GRPCXX_HDRS,
+    external_deps = [
+        "protobuf_headers",
+    ],
     language = "c++",
     public_hdrs = GRPCXX_PUBLIC_HDRS,
     deps = [
@@ -2269,6 +2291,9 @@ grpc_cc_library(
     name = "grpc++_base_unsecure",
     srcs = GRPCXX_SRCS,
     hdrs = GRPCXX_HDRS,
+    external_deps = [
+        "protobuf_headers",
+    ],
     language = "c++",
     public_hdrs = GRPCXX_PUBLIC_HDRS,
     deps = [
@@ -2377,6 +2402,9 @@ grpc_cc_library(
 
 grpc_cc_library(
     name = "grpc++_codegen_proto",
+    external_deps = [
+        "protobuf_headers",
+    ],
     language = "c++",
     public_hdrs = [
         "include/grpc++/impl/codegen/proto_utils.h",
@@ -2448,6 +2476,9 @@ grpc_cc_library(
     srcs = [
         "src/cpp/client/channel_test_peer.cc",
     ],
+    external_deps = [
+        "gtest",
+    ],
     public_hdrs = [
         "include/grpc++/test/mock_stream.h",
         "include/grpc++/test/server_context_test_spouse.h",
index 6c93c6c..e3f6df5 100644 (file)
--- a/BUILD.gn
+++ b/BUILD.gn
@@ -159,7 +159,6 @@ config("grpc_config") {
         "src/core/lib/gprpp/host_port.cc",
         "src/core/lib/gprpp/host_port.h",
         "src/core/lib/gprpp/manual_constructor.h",
-        "src/core/lib/gprpp/map.h",
         "src/core/lib/gprpp/memory.h",
         "src/core/lib/gprpp/mpscq.cc",
         "src/core/lib/gprpp/mpscq.h",
@@ -224,6 +223,8 @@ config("grpc_config") {
         "src/core/ext/filters/client_channel/config_selector.cc",
         "src/core/ext/filters/client_channel/config_selector.h",
         "src/core/ext/filters/client_channel/connector.h",
+        "src/core/ext/filters/client_channel/dynamic_filters.cc",
+        "src/core/ext/filters/client_channel/dynamic_filters.h",
         "src/core/ext/filters/client_channel/global_subchannel_pool.cc",
         "src/core/ext/filters/client_channel/global_subchannel_pool.h",
         "src/core/ext/filters/client_channel/health/health_check_client.cc",
@@ -256,10 +257,11 @@ config("grpc_config") {
         "src/core/ext/filters/client_channel/lb_policy/subchannel_list.h",
         "src/core/ext/filters/client_channel/lb_policy/weighted_target/weighted_target.cc",
         "src/core/ext/filters/client_channel/lb_policy/xds/cds.cc",
-        "src/core/ext/filters/client_channel/lb_policy/xds/eds.cc",
         "src/core/ext/filters/client_channel/lb_policy/xds/xds.h",
+        "src/core/ext/filters/client_channel/lb_policy/xds/xds_channel_args.h",
         "src/core/ext/filters/client_channel/lb_policy/xds/xds_cluster_impl.cc",
         "src/core/ext/filters/client_channel/lb_policy/xds/xds_cluster_manager.cc",
+        "src/core/ext/filters/client_channel/lb_policy/xds/xds_cluster_resolver.cc",
         "src/core/ext/filters/client_channel/lb_policy_factory.h",
         "src/core/ext/filters/client_channel/lb_policy_registry.cc",
         "src/core/ext/filters/client_channel/lb_policy_registry.h",
@@ -271,14 +273,12 @@ config("grpc_config") {
         "src/core/ext/filters/client_channel/resolver.cc",
         "src/core/ext/filters/client_channel/resolver.h",
         "src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc",
-        "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.cc",
         "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.h",
         "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_libuv.cc",
         "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_posix.cc",
         "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_windows.cc",
         "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc",
         "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h",
-        "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_fallback.cc",
         "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv.cc",
         "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_posix.cc",
         "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc",
@@ -295,8 +295,6 @@ config("grpc_config") {
         "src/core/ext/filters/client_channel/resolver_registry.h",
         "src/core/ext/filters/client_channel/resolver_result_parsing.cc",
         "src/core/ext/filters/client_channel/resolver_result_parsing.h",
-        "src/core/ext/filters/client_channel/resolving_lb_policy.cc",
-        "src/core/ext/filters/client_channel/resolving_lb_policy.h",
         "src/core/ext/filters/client_channel/retry_throttle.cc",
         "src/core/ext/filters/client_channel/retry_throttle.h",
         "src/core/ext/filters/client_channel/server_address.cc",
@@ -730,8 +728,6 @@ config("grpc_config") {
         "src/core/ext/xds/certificate_provider_store.h",
         "src/core/ext/xds/file_watcher_certificate_provider_factory.cc",
         "src/core/ext/xds/file_watcher_certificate_provider_factory.h",
-        "src/core/ext/xds/google_mesh_ca_certificate_provider_factory.cc",
-        "src/core/ext/xds/google_mesh_ca_certificate_provider_factory.h",
         "src/core/ext/xds/xds_api.cc",
         "src/core/ext/xds/xds_api.h",
         "src/core/ext/xds/xds_bootstrap.cc",
@@ -743,6 +739,7 @@ config("grpc_config") {
         "src/core/ext/xds/xds_client.h",
         "src/core/ext/xds/xds_client_stats.cc",
         "src/core/ext/xds/xds_client_stats.h",
+        "src/core/ext/xds/xds_server_config_fetcher.cc",
         "src/core/lib/avl/avl.cc",
         "src/core/lib/avl/avl.h",
         "src/core/lib/backoff/backoff.cc",
@@ -1009,6 +1006,8 @@ config("grpc_config") {
         "src/core/lib/security/credentials/credentials.cc",
         "src/core/lib/security/credentials/credentials.h",
         "src/core/lib/security/credentials/credentials_metadata.cc",
+        "src/core/lib/security/credentials/external/aws_external_account_credentials.cc",
+        "src/core/lib/security/credentials/external/aws_external_account_credentials.h",
         "src/core/lib/security/credentials/external/aws_request_signer.cc",
         "src/core/lib/security/credentials/external/aws_request_signer.h",
         "src/core/lib/security/credentials/external/external_account_credentials.cc",
@@ -1047,6 +1046,8 @@ config("grpc_config") {
         "src/core/lib/security/credentials/tls/grpc_tls_credentials_options.h",
         "src/core/lib/security/credentials/tls/tls_credentials.cc",
         "src/core/lib/security/credentials/tls/tls_credentials.h",
+        "src/core/lib/security/credentials/tls/tls_utils.cc",
+        "src/core/lib/security/credentials/tls/tls_utils.h",
         "src/core/lib/security/credentials/xds/xds_credentials.cc",
         "src/core/lib/security/credentials/xds/xds_credentials.h",
         "src/core/lib/security/security_connector/alts/alts_security_connector.cc",
@@ -1221,10 +1222,12 @@ config("grpc_config") {
         ":upb",
         ":absl/types:optional",
         ":absl/strings:strings",
+        ":absl/status:statusor",
         ":absl/status:status",
         ":absl/functional:bind_front",
         ":absl/container:inlined_vector",
         ":absl/container:flat_hash_set",
+        ":absl/container:flat_hash_map",
         "//third_party/cares",
         ":address_sorting",
     ]
@@ -1425,6 +1428,7 @@ config("grpc_config") {
         "include/grpcpp/support/sync_stream.h",
         "include/grpcpp/support/time.h",
         "include/grpcpp/support/validate_service_config.h",
+        "include/grpcpp/xds_server_builder.h",
         "src/cpp/client/channel_cc.cc",
         "src/cpp/client/client_callback.cc",
         "src/cpp/client/client_context.cc",
@@ -1479,6 +1483,7 @@ config("grpc_config") {
         "src/cpp/server/server_credentials.cc",
         "src/cpp/server/server_posix.cc",
         "src/cpp/server/thread_pool_interface.h",
+        "src/cpp/server/xds_server_credentials.cc",
         "src/cpp/thread_manager/thread_manager.cc",
         "src/cpp/thread_manager/thread_manager.h",
         "src/cpp/util/byte_buffer_cc.cc",
index d610331..6bdae22 100644 (file)
 cmake_minimum_required(VERSION 3.5.1)
 
 set(PACKAGE_NAME          "grpc")
-set(PACKAGE_VERSION       "1.34.1")
+set(PACKAGE_VERSION       "1.35.0")
 set(gRPC_CORE_VERSION     "14.0.0")
 set(gRPC_CORE_SOVERSION   "14")
-set(gRPC_CPP_VERSION      "1.34.1")
+set(gRPC_CPP_VERSION      "1.35.0")
 set(gRPC_CPP_SOVERSION    "1")
-set(gRPC_CSHARP_VERSION   "2.34.1")
+set(gRPC_CSHARP_VERSION   "2.35.0")
 set(gRPC_CSHARP_SOVERSION "2")
 set(PACKAGE_STRING        "${PACKAGE_NAME} ${PACKAGE_VERSION}")
 set(PACKAGE_TARNAME       "${PACKAGE_NAME}-${PACKAGE_VERSION}")
@@ -122,6 +122,7 @@ set(gRPC_ABSL_USED_TARGETS
   absl_errno_saver
   absl_exponential_biased
   absl_fixed_array
+  absl_flat_hash_map
   absl_flat_hash_set
   absl_function_ref
   absl_graphcycles_internal
@@ -140,12 +141,14 @@ set(gRPC_ABSL_USED_TARGETS
   absl_malloc_internal
   absl_memory
   absl_optional
+  absl_raw_hash_map
   absl_raw_hash_set
   absl_raw_logging_internal
   absl_span
   absl_spinlock_wait
   absl_stacktrace
   absl_status
+  absl_statusor
   absl_str_format
   absl_str_format_internal
   absl_strings
@@ -497,6 +500,12 @@ protobuf_generate_grpc_cpp(
   src/proto/grpc/testing/xds/v3/route.proto
 )
 protobuf_generate_grpc_cpp(
+  src/proto/grpc/testing/xds/v3/string.proto
+)
+protobuf_generate_grpc_cpp(
+  src/proto/grpc/testing/xds/v3/tls.proto
+)
+protobuf_generate_grpc_cpp(
   test/core/tsi/alts/fake_handshaker/handshaker.proto
 )
 protobuf_generate_grpc_cpp(
@@ -611,7 +620,6 @@ if(gRPC_BUILD_TESTS)
   add_dependencies(buildtests_c jwt_verifier_test)
   add_dependencies(buildtests_c lame_client_test)
   add_dependencies(buildtests_c load_file_test)
-  add_dependencies(buildtests_c log_test)
   add_dependencies(buildtests_c manual_constructor_test)
   add_dependencies(buildtests_c message_compress_test)
   add_dependencies(buildtests_c metadata_test)
@@ -690,7 +698,6 @@ if(gRPC_BUILD_TESTS)
   if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX)
     add_dependencies(buildtests_c udp_server_test)
   endif()
-  add_dependencies(buildtests_c uri_parser_test)
   add_dependencies(buildtests_c useful_test)
   add_dependencies(buildtests_c varint_test)
 
@@ -830,6 +837,7 @@ if(gRPC_BUILD_TESTS)
   add_dependencies(buildtests_cxx google_mesh_ca_certificate_provider_factory_test)
   add_dependencies(buildtests_cxx grpc_cli)
   add_dependencies(buildtests_cxx grpc_tls_certificate_distributor_test)
+  add_dependencies(buildtests_cxx grpc_tls_certificate_provider_test)
   add_dependencies(buildtests_cxx grpc_tls_credentials_options_test)
   if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX)
     add_dependencies(buildtests_cxx grpc_tool_test)
@@ -857,6 +865,7 @@ if(gRPC_BUILD_TESTS)
   add_dependencies(buildtests_cxx lb_get_cpu_stats_test)
   add_dependencies(buildtests_cxx lb_load_data_store_test)
   add_dependencies(buildtests_cxx linux_system_roots_test)
+  add_dependencies(buildtests_cxx log_test)
   add_dependencies(buildtests_cxx message_allocator_end2end_test)
   add_dependencies(buildtests_cxx mock_test)
   add_dependencies(buildtests_cxx nonblocking_test)
@@ -927,6 +936,7 @@ if(gRPC_BUILD_TESTS)
   add_dependencies(buildtests_cxx tls_security_connector_test)
   add_dependencies(buildtests_cxx too_many_pings_test)
   add_dependencies(buildtests_cxx unknown_frame_bad_client_test)
+  add_dependencies(buildtests_cxx uri_parser_test)
   add_dependencies(buildtests_cxx window_overflow_bad_client_test)
   if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX)
     add_dependencies(buildtests_cxx work_serializer_test)
@@ -937,6 +947,7 @@ if(gRPC_BUILD_TESTS)
   add_dependencies(buildtests_cxx xds_bootstrap_test)
   add_dependencies(buildtests_cxx xds_certificate_provider_test)
   add_dependencies(buildtests_cxx xds_credentials_end2end_test)
+  add_dependencies(buildtests_cxx xds_credentials_test)
   if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX)
     add_dependencies(buildtests_cxx xds_end2end_test)
   endif()
@@ -1042,9 +1053,9 @@ add_library(end2end_nosec_tests
   test/core/end2end/tests/default_host.cc
   test/core/end2end/tests/disappearing_server.cc
   test/core/end2end/tests/empty_batch.cc
-  test/core/end2end/tests/filter_call_init_fails.cc
   test/core/end2end/tests/filter_causes_close.cc
   test/core/end2end/tests/filter_context.cc
+  test/core/end2end/tests/filter_init_fails.cc
   test/core/end2end/tests/filter_latency.cc
   test/core/end2end/tests/filter_status_code.cc
   test/core/end2end/tests/graceful_server_shutdown.cc
@@ -1176,9 +1187,9 @@ add_library(end2end_tests
   test/core/end2end/tests/default_host.cc
   test/core/end2end/tests/disappearing_server.cc
   test/core/end2end/tests/empty_batch.cc
-  test/core/end2end/tests/filter_call_init_fails.cc
   test/core/end2end/tests/filter_causes_close.cc
   test/core/end2end/tests/filter_context.cc
+  test/core/end2end/tests/filter_init_fails.cc
   test/core/end2end/tests/filter_latency.cc
   test/core/end2end/tests/filter_status_code.cc
   test/core/end2end/tests/graceful_server_shutdown.cc
@@ -1442,6 +1453,7 @@ add_library(grpc
   src/core/ext/filters/client_channel/client_channel_factory.cc
   src/core/ext/filters/client_channel/client_channel_plugin.cc
   src/core/ext/filters/client_channel/config_selector.cc
+  src/core/ext/filters/client_channel/dynamic_filters.cc
   src/core/ext/filters/client_channel/global_subchannel_pool.cc
   src/core/ext/filters/client_channel/health/health_check_client.cc
   src/core/ext/filters/client_channel/http_connect_handshaker.cc
@@ -1460,20 +1472,18 @@ add_library(grpc
   src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc
   src/core/ext/filters/client_channel/lb_policy/weighted_target/weighted_target.cc
   src/core/ext/filters/client_channel/lb_policy/xds/cds.cc
-  src/core/ext/filters/client_channel/lb_policy/xds/eds.cc
   src/core/ext/filters/client_channel/lb_policy/xds/xds_cluster_impl.cc
   src/core/ext/filters/client_channel/lb_policy/xds/xds_cluster_manager.cc
+  src/core/ext/filters/client_channel/lb_policy/xds/xds_cluster_resolver.cc
   src/core/ext/filters/client_channel/lb_policy_registry.cc
   src/core/ext/filters/client_channel/local_subchannel_pool.cc
   src/core/ext/filters/client_channel/proxy_mapper_registry.cc
   src/core/ext/filters/client_channel/resolver.cc
   src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc
-  src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.cc
   src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_libuv.cc
   src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_posix.cc
   src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_windows.cc
   src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc
-  src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_fallback.cc
   src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv.cc
   src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_posix.cc
   src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc
@@ -1484,7 +1494,6 @@ add_library(grpc
   src/core/ext/filters/client_channel/resolver/xds/xds_resolver.cc
   src/core/ext/filters/client_channel/resolver_registry.cc
   src/core/ext/filters/client_channel/resolver_result_parsing.cc
-  src/core/ext/filters/client_channel/resolving_lb_policy.cc
   src/core/ext/filters/client_channel/retry_throttle.cc
   src/core/ext/filters/client_channel/server_address.cc
   src/core/ext/filters/client_channel/service_config.cc
@@ -1706,12 +1715,12 @@ add_library(grpc
   src/core/ext/xds/certificate_provider_registry.cc
   src/core/ext/xds/certificate_provider_store.cc
   src/core/ext/xds/file_watcher_certificate_provider_factory.cc
-  src/core/ext/xds/google_mesh_ca_certificate_provider_factory.cc
   src/core/ext/xds/xds_api.cc
   src/core/ext/xds/xds_bootstrap.cc
   src/core/ext/xds/xds_certificate_provider.cc
   src/core/ext/xds/xds_client.cc
   src/core/ext/xds/xds_client_stats.cc
+  src/core/ext/xds/xds_server_config_fetcher.cc
   src/core/lib/avl/avl.cc
   src/core/lib/backoff/backoff.cc
   src/core/lib/channel/channel_args.cc
@@ -1851,6 +1860,7 @@ add_library(grpc
   src/core/lib/security/credentials/composite/composite_credentials.cc
   src/core/lib/security/credentials/credentials.cc
   src/core/lib/security/credentials/credentials_metadata.cc
+  src/core/lib/security/credentials/external/aws_external_account_credentials.cc
   src/core/lib/security/credentials/external/aws_request_signer.cc
   src/core/lib/security/credentials/external/external_account_credentials.cc
   src/core/lib/security/credentials/external/file_external_account_credentials.cc
@@ -1871,6 +1881,7 @@ add_library(grpc
   src/core/lib/security/credentials/tls/grpc_tls_certificate_provider.cc
   src/core/lib/security/credentials/tls/grpc_tls_credentials_options.cc
   src/core/lib/security/credentials/tls/tls_credentials.cc
+  src/core/lib/security/credentials/tls/tls_utils.cc
   src/core/lib/security/credentials/xds/xds_credentials.cc
   src/core/lib/security/security_connector/alts/alts_security_connector.cc
   src/core/lib/security/security_connector/fake/fake_security_connector.cc
@@ -2002,10 +2013,12 @@ target_link_libraries(grpc
   upb
   absl::optional
   absl::strings
+  absl::statusor
   absl::status
   absl::bind_front
   absl::inlined_vector
   absl::flat_hash_set
+  absl::flat_hash_map
 )
 if(_gRPC_PLATFORM_IOS OR _gRPC_PLATFORM_MAC)
   target_link_libraries(grpc "-framework CoreFoundation")
@@ -2091,7 +2104,6 @@ if(gRPC_BUILD_TESTS)
 
 add_library(grpc_test_util
   test/core/util/cmdline.cc
-  test/core/util/debugger_macros.cc
   test/core/util/eval_args_mock_endpoint.cc
   test/core/util/fuzzer_util.cc
   test/core/util/grpc_profiler.cc
@@ -2111,6 +2123,7 @@ add_library(grpc_test_util
   test/core/util/subprocess_windows.cc
   test/core/util/test_config.cc
   test/core/util/test_tcp_server.cc
+  test/core/util/tls_utils.cc
   test/core/util/tracer_util.cc
   test/core/util/trickle_endpoint.cc
 )
@@ -2163,7 +2176,6 @@ if(gRPC_BUILD_TESTS)
 
 add_library(grpc_test_util_unsecure
   test/core/util/cmdline.cc
-  test/core/util/debugger_macros.cc
   test/core/util/eval_args_mock_endpoint.cc
   test/core/util/fuzzer_util.cc
   test/core/util/grpc_profiler.cc
@@ -2242,6 +2254,7 @@ add_library(grpc_unsecure
   src/core/ext/filters/client_channel/client_channel_factory.cc
   src/core/ext/filters/client_channel/client_channel_plugin.cc
   src/core/ext/filters/client_channel/config_selector.cc
+  src/core/ext/filters/client_channel/dynamic_filters.cc
   src/core/ext/filters/client_channel/global_subchannel_pool.cc
   src/core/ext/filters/client_channel/health/health_check_client.cc
   src/core/ext/filters/client_channel/http_connect_handshaker.cc
@@ -2264,12 +2277,10 @@ add_library(grpc_unsecure
   src/core/ext/filters/client_channel/proxy_mapper_registry.cc
   src/core/ext/filters/client_channel/resolver.cc
   src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc
-  src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.cc
   src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_libuv.cc
   src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_posix.cc
   src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_windows.cc
   src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc
-  src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_fallback.cc
   src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv.cc
   src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_posix.cc
   src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc
@@ -2279,7 +2290,6 @@ add_library(grpc_unsecure
   src/core/ext/filters/client_channel/resolver/sockaddr/sockaddr_resolver.cc
   src/core/ext/filters/client_channel/resolver_registry.cc
   src/core/ext/filters/client_channel/resolver_result_parsing.cc
-  src/core/ext/filters/client_channel/resolving_lb_policy.cc
   src/core/ext/filters/client_channel/retry_throttle.cc
   src/core/ext/filters/client_channel/server_address.cc
   src/core/ext/filters/client_channel/service_config.cc
@@ -2556,8 +2566,10 @@ target_link_libraries(grpc_unsecure
   upb
   absl::optional
   absl::strings
+  absl::statusor
   absl::status
   absl::inlined_vector
+  absl::flat_hash_map
 )
 if(_gRPC_PLATFORM_IOS OR _gRPC_PLATFORM_MAC)
   target_link_libraries(grpc_unsecure "-framework CoreFoundation")
@@ -2709,6 +2721,7 @@ add_library(grpc++
   src/cpp/server/server_context.cc
   src/cpp/server/server_credentials.cc
   src/cpp/server/server_posix.cc
+  src/cpp/server/xds_server_credentials.cc
   src/cpp/thread_manager/thread_manager.cc
   src/cpp/util/byte_buffer_cc.cc
   src/cpp/util/status.cc
@@ -2939,6 +2952,7 @@ foreach(_hdr
   include/grpcpp/support/sync_stream.h
   include/grpcpp/support/time.h
   include/grpcpp/support/validate_service_config.h
+  include/grpcpp/xds_server_builder.h
 )
   string(REPLACE "include/" "" _path ${_hdr})
   get_filename_component(_path ${_path} PATH)
@@ -3767,15 +3781,17 @@ endif()
 endif()
 
 add_library(upb
+  third_party/upb/upb/decode_fast.c
   third_party/upb/upb/decode.c
+  third_party/upb/upb/def.c
   third_party/upb/upb/encode.c
+  third_party/upb/upb/json_decode.c
+  third_party/upb/upb/json_encode.c
   third_party/upb/upb/msg.c
-  third_party/upb/upb/port.c
-  third_party/upb/upb/table.c
-  third_party/upb/upb/upb.c
-  third_party/upb/upb/def.c
   third_party/upb/upb/reflection.c
+  third_party/upb/upb/table.c
   third_party/upb/upb/text_encode.c
+  third_party/upb/upb/upb.c
   src/core/ext/upb-generated/google/protobuf/any.upb.c
   src/core/ext/upb-generated/google/protobuf/descriptor.upb.c
   src/core/ext/upb-generated/google/protobuf/duration.upb.c
@@ -6294,36 +6310,6 @@ target_link_libraries(load_file_test
 endif()
 if(gRPC_BUILD_TESTS)
 
-add_executable(log_test
-  test/core/gpr/log_test.cc
-)
-
-target_include_directories(log_test
-  PRIVATE
-    ${CMAKE_CURRENT_SOURCE_DIR}
-    ${CMAKE_CURRENT_SOURCE_DIR}/include
-    ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR}
-    ${_gRPC_RE2_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(log_test
-  ${_gRPC_ALLTARGETS_LIBRARIES}
-  grpc_test_util
-  grpc
-  gpr
-  address_sorting
-  upb
-)
-
-
-endif()
-if(gRPC_BUILD_TESTS)
-
 add_executable(manual_constructor_test
   test/core/gprpp/manual_constructor_test.cc
 )
@@ -8036,36 +8022,6 @@ endif()
 endif()
 if(gRPC_BUILD_TESTS)
 
-add_executable(uri_parser_test
-  test/core/uri/uri_parser_test.cc
-)
-
-target_include_directories(uri_parser_test
-  PRIVATE
-    ${CMAKE_CURRENT_SOURCE_DIR}
-    ${CMAKE_CURRENT_SOURCE_DIR}/include
-    ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR}
-    ${_gRPC_RE2_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(uri_parser_test
-  ${_gRPC_ALLTARGETS_LIBRARIES}
-  grpc_test_util
-  grpc
-  gpr
-  address_sorting
-  upb
-)
-
-
-endif()
-if(gRPC_BUILD_TESTS)
-
 add_executable(useful_test
   test/core/gpr/useful_test.cc
 )
@@ -11341,6 +11297,7 @@ endif()
 if(gRPC_BUILD_TESTS)
 
 add_executable(google_mesh_ca_certificate_provider_factory_test
+  src/core/ext/xds/google_mesh_ca_certificate_provider_factory.cc
   test/core/xds/google_mesh_ca_certificate_provider_factory_test.cc
   third_party/googletest/googletest/src/gtest-all.cc
   third_party/googletest/googlemock/src/gmock-all.cc
@@ -11732,6 +11689,44 @@ target_link_libraries(grpc_tls_certificate_distributor_test
 endif()
 if(gRPC_BUILD_TESTS)
 
+add_executable(grpc_tls_certificate_provider_test
+  test/core/security/grpc_tls_certificate_provider_test.cc
+  third_party/googletest/googletest/src/gtest-all.cc
+  third_party/googletest/googlemock/src/gmock-all.cc
+)
+
+target_include_directories(grpc_tls_certificate_provider_test
+  PRIVATE
+    ${CMAKE_CURRENT_SOURCE_DIR}
+    ${CMAKE_CURRENT_SOURCE_DIR}/include
+    ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR}
+    ${_gRPC_RE2_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(grpc_tls_certificate_provider_test
+  ${_gRPC_PROTOBUF_LIBRARIES}
+  ${_gRPC_ALLTARGETS_LIBRARIES}
+  grpc_test_util
+  grpc
+  gpr
+  address_sorting
+  upb
+)
+
+
+endif()
+if(gRPC_BUILD_TESTS)
+
 add_executable(grpc_tls_credentials_options_test
   test/core/security/grpc_tls_credentials_options_test.cc
   third_party/googletest/googletest/src/gtest-all.cc
@@ -12703,6 +12698,44 @@ target_link_libraries(linux_system_roots_test
 endif()
 if(gRPC_BUILD_TESTS)
 
+add_executable(log_test
+  test/core/gpr/log_test.cc
+  third_party/googletest/googletest/src/gtest-all.cc
+  third_party/googletest/googlemock/src/gmock-all.cc
+)
+
+target_include_directories(log_test
+  PRIVATE
+    ${CMAKE_CURRENT_SOURCE_DIR}
+    ${CMAKE_CURRENT_SOURCE_DIR}/include
+    ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR}
+    ${_gRPC_RE2_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(log_test
+  ${_gRPC_PROTOBUF_LIBRARIES}
+  ${_gRPC_ALLTARGETS_LIBRARIES}
+  grpc_test_util
+  grpc
+  gpr
+  address_sorting
+  upb
+)
+
+
+endif()
+if(gRPC_BUILD_TESTS)
+
 add_executable(message_allocator_end2end_test
   ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo.pb.cc
   ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo.grpc.pb.cc
@@ -15086,6 +15119,44 @@ target_link_libraries(unknown_frame_bad_client_test
 endif()
 if(gRPC_BUILD_TESTS)
 
+add_executable(uri_parser_test
+  test/core/uri/uri_parser_test.cc
+  third_party/googletest/googletest/src/gtest-all.cc
+  third_party/googletest/googlemock/src/gmock-all.cc
+)
+
+target_include_directories(uri_parser_test
+  PRIVATE
+    ${CMAKE_CURRENT_SOURCE_DIR}
+    ${CMAKE_CURRENT_SOURCE_DIR}/include
+    ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR}
+    ${_gRPC_RE2_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(uri_parser_test
+  ${_gRPC_PROTOBUF_LIBRARIES}
+  ${_gRPC_ALLTARGETS_LIBRARIES}
+  grpc_test_util
+  grpc
+  gpr
+  address_sorting
+  upb
+)
+
+
+endif()
+if(gRPC_BUILD_TESTS)
+
 add_executable(window_overflow_bad_client_test
   test/core/bad_client/bad_client.cc
   test/core/bad_client/tests/window_overflow.cc
@@ -15181,7 +15252,6 @@ if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX)
     ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/simple_messages.pb.h
     ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/simple_messages.grpc.pb.h
     test/core/util/cmdline.cc
-    test/core/util/debugger_macros.cc
     test/core/util/eval_args_mock_endpoint.cc
     test/core/util/fuzzer_util.cc
     test/core/util/grpc_profiler.cc
@@ -15372,6 +15442,44 @@ target_link_libraries(xds_credentials_end2end_test
 
 endif()
 if(gRPC_BUILD_TESTS)
+
+add_executable(xds_credentials_test
+  test/core/security/xds_credentials_test.cc
+  third_party/googletest/googletest/src/gtest-all.cc
+  third_party/googletest/googlemock/src/gmock-all.cc
+)
+
+target_include_directories(xds_credentials_test
+  PRIVATE
+    ${CMAKE_CURRENT_SOURCE_DIR}
+    ${CMAKE_CURRENT_SOURCE_DIR}/include
+    ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR}
+    ${_gRPC_RE2_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_credentials_test
+  ${_gRPC_PROTOBUF_LIBRARIES}
+  ${_gRPC_ALLTARGETS_LIBRARIES}
+  grpc_test_util
+  grpc
+  gpr
+  address_sorting
+  upb
+)
+
+
+endif()
+if(gRPC_BUILD_TESTS)
 if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX)
 
   add_executable(xds_end2end_test
@@ -15475,6 +15583,14 @@ if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX)
     ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/route.grpc.pb.cc
     ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/route.pb.h
     ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/route.grpc.pb.h
+    ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/string.pb.cc
+    ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/string.grpc.pb.cc
+    ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/string.pb.h
+    ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/string.grpc.pb.h
+    ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/tls.pb.cc
+    ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/tls.grpc.pb.cc
+    ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/tls.pb.h
+    ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/tls.grpc.pb.h
     test/cpp/end2end/test_service_impl.cc
     test/cpp/end2end/xds_end2end_test.cc
     third_party/googletest/googletest/src/gtest-all.cc
@@ -16222,7 +16338,7 @@ generate_pkgconfig(
   "high performance general RPC framework"
   "${gRPC_CORE_VERSION}"
   "gpr openssl"
-  "-lgrpc -laddress_sorting -lre2 -lupb -lcares -lz -labsl_raw_hash_set -labsl_hashtablez_sampler -labsl_exponential_biased -labsl_hash -labsl_bad_variant_access -labsl_city -labsl_status -labsl_cord -labsl_str_format_internal -labsl_synchronization -labsl_graphcycles_internal -labsl_symbolize -labsl_demangle_internal -labsl_stacktrace -labsl_debugging_internal -labsl_malloc_internal -labsl_time -labsl_time_zone -labsl_civil_time -labsl_strings -labsl_strings_internal -labsl_throw_delegate -labsl_int128 -labsl_base -labsl_spinlock_wait -labsl_bad_optional_access -labsl_raw_logging_internal -labsl_log_severity"
+  "-lgrpc -laddress_sorting -lre2 -lupb -lcares -lz -labsl_raw_hash_set -labsl_hashtablez_sampler -labsl_exponential_biased -labsl_hash -labsl_city -labsl_statusor -labsl_bad_variant_access -labsl_status -labsl_cord -labsl_str_format_internal -labsl_synchronization -labsl_graphcycles_internal -labsl_symbolize -labsl_demangle_internal -labsl_stacktrace -labsl_debugging_internal -labsl_malloc_internal -labsl_time -labsl_time_zone -labsl_civil_time -labsl_strings -labsl_strings_internal -labsl_throw_delegate -labsl_int128 -labsl_base -labsl_spinlock_wait -labsl_bad_optional_access -labsl_raw_logging_internal -labsl_log_severity"
   ""
   "grpc.pc")
 
@@ -16232,7 +16348,7 @@ generate_pkgconfig(
   "high performance general RPC framework without SSL"
   "${gRPC_CORE_VERSION}"
   "gpr"
-  "-lgrpc_unsecure -labsl_status -labsl_cord -labsl_str_format_internal -labsl_synchronization -labsl_graphcycles_internal -labsl_symbolize -labsl_demangle_internal -labsl_stacktrace -labsl_debugging_internal -labsl_malloc_internal -labsl_time -labsl_time_zone -labsl_civil_time -labsl_strings -labsl_strings_internal -labsl_throw_delegate -labsl_int128 -labsl_base -labsl_spinlock_wait -labsl_bad_optional_access -labsl_raw_logging_internal -labsl_log_severity"
+  "-lgrpc_unsecure -labsl_raw_hash_set -labsl_hashtablez_sampler -labsl_exponential_biased -labsl_hash -labsl_city -labsl_statusor -labsl_bad_variant_access -labsl_status -labsl_cord -labsl_str_format_internal -labsl_synchronization -labsl_graphcycles_internal -labsl_symbolize -labsl_demangle_internal -labsl_stacktrace -labsl_debugging_internal -labsl_malloc_internal -labsl_time -labsl_time_zone -labsl_civil_time -labsl_strings -labsl_strings_internal -labsl_throw_delegate -labsl_int128 -labsl_base -labsl_spinlock_wait -labsl_bad_optional_access -labsl_raw_logging_internal -labsl_log_severity"
   ""
   "grpc_unsecure.pc")
 
@@ -16242,7 +16358,7 @@ generate_pkgconfig(
   "C++ wrapper for gRPC"
   "${gRPC_CPP_VERSION}"
   "grpc"
-  "-lgrpc++ -labsl_raw_hash_set -labsl_hashtablez_sampler -labsl_exponential_biased -labsl_hash -labsl_bad_variant_access -labsl_city -labsl_status -labsl_cord -labsl_str_format_internal -labsl_synchronization -labsl_graphcycles_internal -labsl_symbolize -labsl_demangle_internal -labsl_stacktrace -labsl_debugging_internal -labsl_malloc_internal -labsl_time -labsl_time_zone -labsl_civil_time -labsl_strings -labsl_strings_internal -labsl_throw_delegate -labsl_int128 -labsl_base -labsl_spinlock_wait -labsl_bad_optional_access -labsl_raw_logging_internal -labsl_log_severity"
+  "-lgrpc++ -labsl_raw_hash_set -labsl_hashtablez_sampler -labsl_exponential_biased -labsl_hash -labsl_city -labsl_statusor -labsl_bad_variant_access -labsl_status -labsl_cord -labsl_str_format_internal -labsl_synchronization -labsl_graphcycles_internal -labsl_symbolize -labsl_demangle_internal -labsl_stacktrace -labsl_debugging_internal -labsl_malloc_internal -labsl_time -labsl_time_zone -labsl_civil_time -labsl_strings -labsl_strings_internal -labsl_throw_delegate -labsl_int128 -labsl_base -labsl_spinlock_wait -labsl_bad_optional_access -labsl_raw_logging_internal -labsl_log_severity"
   ""
   "grpc++.pc")
 
@@ -16252,6 +16368,6 @@ generate_pkgconfig(
   "C++ wrapper for gRPC without SSL"
   "${gRPC_CPP_VERSION}"
   "grpc_unsecure"
-  "-lgrpc++_unsecure -labsl_status -labsl_cord -labsl_str_format_internal -labsl_synchronization -labsl_graphcycles_internal -labsl_symbolize -labsl_demangle_internal -labsl_stacktrace -labsl_debugging_internal -labsl_malloc_internal -labsl_time -labsl_time_zone -labsl_civil_time -labsl_strings -labsl_strings_internal -labsl_throw_delegate -labsl_int128 -labsl_base -labsl_spinlock_wait -labsl_bad_optional_access -labsl_raw_logging_internal -labsl_log_severity"
+  "-lgrpc++_unsecure -labsl_raw_hash_set -labsl_hashtablez_sampler -labsl_exponential_biased -labsl_hash -labsl_city -labsl_statusor -labsl_bad_variant_access -labsl_status -labsl_cord -labsl_str_format_internal -labsl_synchronization -labsl_graphcycles_internal -labsl_symbolize -labsl_demangle_internal -labsl_stacktrace -labsl_debugging_internal -labsl_malloc_internal -labsl_time -labsl_time_zone -labsl_civil_time -labsl_strings -labsl_strings_internal -labsl_throw_delegate -labsl_int128 -labsl_base -labsl_spinlock_wait -labsl_bad_optional_access -labsl_raw_logging_internal -labsl_log_severity"
   ""
   "grpc++_unsecure.pc")
index e5e1338..1599ca4 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -254,7 +254,6 @@ DEFINES_ubsan = NDEBUG GRPC_UBSAN
 
 prefix ?= /usr/local
 
-PROTOC ?= protoc
 DTRACE ?= dtrace
 CONFIG ?= opt
 # Doing X ?= Y is the same as:
@@ -456,8 +455,8 @@ Q = @
 endif
 
 CORE_VERSION = 14.0.0
-CPP_VERSION = 1.34.1
-CSHARP_VERSION = 2.34.1
+CPP_VERSION = 1.35.0
+CSHARP_VERSION = 2.35.0
 
 CPPFLAGS_NO_ARCH += $(addprefix -I, $(INCLUDES)) $(addprefix -D, $(DEFINES))
 CPPFLAGS += $(CPPFLAGS_NO_ARCH) $(ARCH_FLAGS)
@@ -627,39 +626,6 @@ endif # EMBED_OPENSSL
 
 LDLIBS_SECURE += $(addprefix -l, $(LIBS_SECURE))
 
-# Setup protobuf dependency
-
-# we only support building protobuf from submodule
-HAS_SYSTEM_PROTOBUF = false
-HAS_PROTOC = false
-HAS_VALID_PROTOC = false
-ifeq ($(wildcard third_party/protobuf/src/google/protobuf/descriptor.pb.h),)
-HAS_EMBEDDED_PROTOBUF = false
-ifneq ($(HAS_VALID_PROTOC),true)
-NO_PROTOC = true
-endif
-else
-HAS_EMBEDDED_PROTOBUF = true
-endif
-
-PROTOC_PLUGINS_DIR = $(BINDIR)/$(CONFIG)
-
-PROTOC_PLUGINS_ALL = $(BINDIR)/$(CONFIG)/grpc_cpp_plugin $(BINDIR)/$(CONFIG)/grpc_csharp_plugin $(BINDIR)/$(CONFIG)/grpc_node_plugin $(BINDIR)/$(CONFIG)/grpc_objective_c_plugin $(BINDIR)/$(CONFIG)/grpc_php_plugin $(BINDIR)/$(CONFIG)/grpc_python_plugin $(BINDIR)/$(CONFIG)/grpc_ruby_plugin
-ifeq ($(HAS_EMBEDDED_PROTOBUF),true)
-PROTOBUF_DEP = $(LIBDIR)/$(CONFIG)/protobuf/libprotobuf.a
-CPPFLAGS := -Ithird_party/protobuf/src $(CPPFLAGS)
-LDFLAGS := -L$(LIBDIR)/$(CONFIG)/protobuf $(LDFLAGS)
-PROTOC = $(BINDIR)/$(CONFIG)/protobuf/protoc
-PROTOC_PLUGINS = $(PROTOC_PLUGINS_ALL)
-else
-NO_PROTOBUF = true
-endif
-
-LIBS_PROTOBUF = protobuf
-LIBS_PROTOC = protoc protobuf
-HOST_LDLIBS_PROTOC += $(addprefix -l, $(LIBS_PROTOC))
-LDLIBS_PROTOBUF += $(addprefix -l, $(LIBS_PROTOBUF))
-
 ifeq ($(MAKECMDGOALS),clean)
 NO_DEPS = true
 endif
@@ -667,7 +633,7 @@ endif
 .SECONDARY = %.pb.h %.pb.cc
 
 ifeq ($(DEP_MISSING),)
-all: static shared plugins
+all: static shared
 dep_error:
        @echo "You shouldn't see this message - all of your dependencies are correct."
 else
@@ -702,10 +668,6 @@ endif
 
 openssl_dep_error: openssl_dep_message git_update stop
 
-protobuf_dep_error: protobuf_dep_message git_update stop
-
-protoc_dep_error: protoc_dep_message git_update stop
-
 openssl_dep_message:
        @echo
        @echo "DEPENDENCY ERROR"
@@ -721,34 +683,6 @@ openssl_dep_message:
        @echo "  make run_dep_checks"
        @echo
 
-protobuf_dep_message:
-       @echo
-       @echo "DEPENDENCY ERROR"
-       @echo
-       @echo "The target you are trying to run requires protobuf 3.12.0+"
-       @echo "Your system doesn't have it, and neither does the third_party directory."
-       @echo
-       @echo "Please consult BUILDING.md to get more information."
-       @echo
-       @echo "If you need information about why these tests failed, run:"
-       @echo
-       @echo "  make run_dep_checks"
-       @echo
-
-protoc_dep_message:
-       @echo
-       @echo "DEPENDENCY ERROR"
-       @echo
-       @echo "The target you are trying to run requires protobuf-compiler 3.12.0+"
-       @echo "Your system doesn't have it, and neither does the third_party directory."
-       @echo
-       @echo "Please consult BUILDING.md to get more information."
-       @echo
-       @echo "If you need information about why these tests failed, run:"
-       @echo
-       @echo "  make run_dep_checks"
-       @echo
-
 systemtap_dep_error:
        @echo
        @echo "DEPENDENCY ERROR"
@@ -772,50 +706,26 @@ install_not_supported_error: install_not_supported_message stop
 stop:
        @false
 
-grpc_cpp_plugin: $(BINDIR)/$(CONFIG)/grpc_cpp_plugin
-grpc_csharp_plugin: $(BINDIR)/$(CONFIG)/grpc_csharp_plugin
-grpc_node_plugin: $(BINDIR)/$(CONFIG)/grpc_node_plugin
-grpc_objective_c_plugin: $(BINDIR)/$(CONFIG)/grpc_objective_c_plugin
-grpc_php_plugin: $(BINDIR)/$(CONFIG)/grpc_php_plugin
-grpc_python_plugin: $(BINDIR)/$(CONFIG)/grpc_python_plugin
-grpc_ruby_plugin: $(BINDIR)/$(CONFIG)/grpc_ruby_plugin
 
 run_dep_checks:
        @echo "run_dep_checks target has been deprecated."
 
-third_party/protobuf/configure:
-       $(E) "[AUTOGEN] Preparing protobuf"
-       $(Q)(cd third_party/protobuf ; autoreconf -f -i -Wall,no-obsolete)
-
-$(LIBDIR)/$(CONFIG)/protobuf/libprotobuf.a: third_party/protobuf/configure
-       $(E) "[MAKE]    Building protobuf"
-       $(Q)mkdir -p $(LIBDIR)/$(CONFIG)/protobuf
-       $(Q)(cd third_party/protobuf ; CC="$(CC)" CXX="$(CXX)" LDFLAGS="$(LDFLAGS_$(CONFIG)) -g $(PROTOBUF_LDFLAGS_EXTRA)" CPPFLAGS="$(PIC_CPPFLAGS) $(CPPFLAGS_$(CONFIG)) -g $(PROTOBUF_CPPFLAGS_EXTRA)" ./configure --disable-shared --enable-static $(PROTOBUF_CONFIG_OPTS))
-       $(Q)$(MAKE) -C third_party/protobuf clean
-       $(Q)$(MAKE) -C third_party/protobuf
-       $(Q)mkdir -p $(BINDIR)/$(CONFIG)/protobuf
-       $(Q)cp third_party/protobuf/src/.libs/libprotoc.a $(LIBDIR)/$(CONFIG)/protobuf
-       $(Q)cp third_party/protobuf/src/.libs/libprotobuf.a $(LIBDIR)/$(CONFIG)/protobuf
-       $(Q)cp third_party/protobuf/src/protoc $(BINDIR)/$(CONFIG)/protobuf
-
 static: static_c static_cxx
 
 static_c: cache.mk  $(LIBDIR)/$(CONFIG)/libaddress_sorting.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgrpc_csharp_ext.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libupb.a
 
-static_cxx: cache.mk  $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc++_alts.a $(LIBDIR)/$(CONFIG)/libgrpc++_error_details.a $(LIBDIR)/$(CONFIG)/libgrpc++_reflection.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpcpp_channelz.a
+static_cxx: cache.mk 
 
 static_csharp: static_c 
 
 shared: shared_c shared_cxx
 
 shared_c: cache.mk $(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)address_sorting$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)gpr$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)grpc$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)grpc_csharp_ext$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)grpc_unsecure$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)upb$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE)
-shared_cxx: cache.mk $(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)grpc++$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)grpc++_alts$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)grpc++_error_details$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)grpc++_reflection$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)grpc++_unsecure$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)grpcpp_channelz$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP)
+shared_cxx: cache.mk
 
 shared_csharp: shared_c 
 grpc_csharp_ext: shared_csharp
 
-plugins: $(PROTOC_PLUGINS)
-
 privatelibs: privatelibs_c privatelibs_cxx
 
 privatelibs_c:  $(LIBDIR)/$(CONFIG)/libre2.a $(LIBDIR)/$(CONFIG)/libz.a $(LIBDIR)/$(CONFIG)/libares.a
@@ -850,18 +760,6 @@ endif
 
 strip-static_cxx: static_cxx
 ifeq ($(CONFIG),opt)
-       $(E) "[STRIP]   Stripping libgrpc++.a"
-       $(Q) $(STRIP) $(LIBDIR)/$(CONFIG)/libgrpc++.a
-       $(E) "[STRIP]   Stripping libgrpc++_alts.a"
-       $(Q) $(STRIP) $(LIBDIR)/$(CONFIG)/libgrpc++_alts.a
-       $(E) "[STRIP]   Stripping libgrpc++_error_details.a"
-       $(Q) $(STRIP) $(LIBDIR)/$(CONFIG)/libgrpc++_error_details.a
-       $(E) "[STRIP]   Stripping libgrpc++_reflection.a"
-       $(Q) $(STRIP) $(LIBDIR)/$(CONFIG)/libgrpc++_reflection.a
-       $(E) "[STRIP]   Stripping libgrpc++_unsecure.a"
-       $(Q) $(STRIP) $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a
-       $(E) "[STRIP]   Stripping libgrpcpp_channelz.a"
-       $(Q) $(STRIP) $(LIBDIR)/$(CONFIG)/libgrpcpp_channelz.a
 endif
 
 strip-shared_c: shared_c
@@ -882,18 +780,6 @@ endif
 
 strip-shared_cxx: shared_cxx
 ifeq ($(CONFIG),opt)
-       $(E) "[STRIP]   Stripping $(SHARED_PREFIX)grpc++$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP)"
-       $(Q) $(STRIP) $(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)grpc++$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP)
-       $(E) "[STRIP]   Stripping $(SHARED_PREFIX)grpc++_alts$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP)"
-       $(Q) $(STRIP) $(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)grpc++_alts$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP)
-       $(E) "[STRIP]   Stripping $(SHARED_PREFIX)grpc++_error_details$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP)"
-       $(Q) $(STRIP) $(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)grpc++_error_details$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP)
-       $(E) "[STRIP]   Stripping $(SHARED_PREFIX)grpc++_reflection$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP)"
-       $(Q) $(STRIP) $(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)grpc++_reflection$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP)
-       $(E) "[STRIP]   Stripping $(SHARED_PREFIX)grpc++_unsecure$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP)"
-       $(Q) $(STRIP) $(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)grpc++_unsecure$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP)
-       $(E) "[STRIP]   Stripping $(SHARED_PREFIX)grpcpp_channelz$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP)"
-       $(Q) $(STRIP) $(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)grpcpp_channelz$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP)
 endif
 
 strip-shared_csharp: shared_csharp
@@ -904,1595 +790,249 @@ cache.mk::
        $(E) "[MAKE]    Generating $@"
        $(Q) echo "$(CACHE_MK)" | tr , '\n' >$@
 
-ifeq ($(NO_PROTOC),true)
-$(GENDIR)/src/proto/grpc/channelz/channelz.pb.cc: protoc_dep_error
-$(GENDIR)/src/proto/grpc/channelz/channelz.grpc.pb.cc: protoc_dep_error
-else
-
-$(GENDIR)/src/proto/grpc/channelz/channelz.pb.cc: src/proto/grpc/channelz/channelz.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS) 
-       $(E) "[PROTOC]  Generating protobuf CC file from $<"
-       $(Q) mkdir -p `dirname $@`
-       $(Q) $(PROTOC) -Ithird_party/protobuf/src -I. --cpp_out=$(GENDIR) $<
-
-$(GENDIR)/src/proto/grpc/channelz/channelz.grpc.pb.cc: src/proto/grpc/channelz/channelz.proto $(GENDIR)/src/proto/grpc/channelz/channelz.pb.cc $(PROTOBUF_DEP) $(PROTOC_PLUGINS) 
-       $(E) "[GRPC]    Generating gRPC's protobuf service CC file from $<"
+ifeq ($(CONFIG),stapprof)
+src/core/profiling/stap_timers.c: $(GENDIR)/src/core/profiling/stap_probes.h
+ifeq ($(HAS_SYSTEMTAP),true)
+$(GENDIR)/src/core/profiling/stap_probes.h: src/core/profiling/stap_probes.d
+       $(E) "[DTRACE]  Compiling $<"
        $(Q) mkdir -p `dirname $@`
-       $(Q) $(PROTOC) -Ithird_party/protobuf/src -I. --grpc_out=$(GENDIR) --plugin=protoc-gen-grpc=$(PROTOC_PLUGINS_DIR)/grpc_cpp_plugin$(EXECUTABLE_SUFFIX) $<
-endif
-
-ifeq ($(NO_PROTOC),true)
-$(GENDIR)/src/proto/grpc/core/stats.pb.cc: protoc_dep_error
-$(GENDIR)/src/proto/grpc/core/stats.grpc.pb.cc: protoc_dep_error
+       $(Q) $(DTRACE) -C -h -s $< -o $@
 else
+$(GENDIR)/src/core/profiling/stap_probes.h: systemtap_dep_error stop
+endif
+endif
 
-$(GENDIR)/src/proto/grpc/core/stats.pb.cc: src/proto/grpc/core/stats.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS) 
-       $(E) "[PROTOC]  Generating protobuf CC file from $<"
+$(OBJDIR)/$(CONFIG)/%.o : %.c
+       $(E) "[C]       Compiling $<"
        $(Q) mkdir -p `dirname $@`
-       $(Q) $(PROTOC) -Ithird_party/protobuf/src -I. --cpp_out=$(GENDIR) $<
+       $(Q) $(CC) $(CPPFLAGS) $(CFLAGS) -MMD -MF $(addsuffix .dep, $(basename $@)) -c -o $@ $<
 
-$(GENDIR)/src/proto/grpc/core/stats.grpc.pb.cc: src/proto/grpc/core/stats.proto $(GENDIR)/src/proto/grpc/core/stats.pb.cc $(PROTOBUF_DEP) $(PROTOC_PLUGINS) 
-       $(E) "[GRPC]    Generating gRPC's protobuf service CC file from $<"
+$(OBJDIR)/$(CONFIG)/%.o : $(GENDIR)/%.pb.cc
+       $(E) "[CXX]     Compiling $<"
        $(Q) mkdir -p `dirname $@`
-       $(Q) $(PROTOC) -Ithird_party/protobuf/src -I. --grpc_out=$(GENDIR) --plugin=protoc-gen-grpc=$(PROTOC_PLUGINS_DIR)/grpc_cpp_plugin$(EXECUTABLE_SUFFIX) $<
-endif
-
-ifeq ($(NO_PROTOC),true)
-$(GENDIR)/src/proto/grpc/health/v1/health.pb.cc: protoc_dep_error
-$(GENDIR)/src/proto/grpc/health/v1/health.grpc.pb.cc: protoc_dep_error
-else
+       $(Q) $(CXX) $(CPPFLAGS) $(CXXFLAGS) -MMD -MF $(addsuffix .dep, $(basename $@)) -c -o $@ $<
 
-$(GENDIR)/src/proto/grpc/health/v1/health.pb.cc: src/proto/grpc/health/v1/health.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS) 
-       $(E) "[PROTOC]  Generating protobuf CC file from $<"
+$(OBJDIR)/$(CONFIG)/src/compiler/%.o : src/compiler/%.cc
+       $(E) "[HOSTCXX] Compiling $<"
        $(Q) mkdir -p `dirname $@`
-       $(Q) $(PROTOC) -Ithird_party/protobuf/src -I. --cpp_out=$(GENDIR) $<
+       $(Q) $(HOST_CXX) $(HOST_CXXFLAGS) $(HOST_CPPFLAGS) -MMD -MF $(addsuffix .dep, $(basename $@)) -c -o $@ $<
 
-$(GENDIR)/src/proto/grpc/health/v1/health.grpc.pb.cc: src/proto/grpc/health/v1/health.proto $(GENDIR)/src/proto/grpc/health/v1/health.pb.cc $(PROTOBUF_DEP) $(PROTOC_PLUGINS) 
-       $(E) "[GRPC]    Generating gRPC's protobuf service CC file from $<"
+$(OBJDIR)/$(CONFIG)/src/core/%.o : src/core/%.cc
+       $(E) "[CXX]     Compiling $<"
        $(Q) mkdir -p `dirname $@`
-       $(Q) $(PROTOC) -Ithird_party/protobuf/src -I. --grpc_out=$(GENDIR) --plugin=protoc-gen-grpc=$(PROTOC_PLUGINS_DIR)/grpc_cpp_plugin$(EXECUTABLE_SUFFIX) $<
-endif
+       $(Q) $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(COREFLAGS) -MMD -MF $(addsuffix .dep, $(basename $@)) -c -o $@ $<
 
-ifeq ($(NO_PROTOC),true)
-$(GENDIR)/src/proto/grpc/lb/v1/load_balancer.pb.cc: protoc_dep_error
-$(GENDIR)/src/proto/grpc/lb/v1/load_balancer.grpc.pb.cc: protoc_dep_error
-else
+$(OBJDIR)/$(CONFIG)/test/core/%.o : test/core/%.cc
+       $(E) "[CXX]     Compiling $<"
+       $(Q) mkdir -p `dirname $@`
+       $(Q) $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(COREFLAGS) -MMD -MF $(addsuffix .dep, $(basename $@)) -c -o $@ $<
 
-$(GENDIR)/src/proto/grpc/lb/v1/load_balancer.pb.cc: src/proto/grpc/lb/v1/load_balancer.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS) 
-       $(E) "[PROTOC]  Generating protobuf CC file from $<"
+$(OBJDIR)/$(CONFIG)/%.o : %.cc
+       $(E) "[CXX]     Compiling $<"
        $(Q) mkdir -p `dirname $@`
-       $(Q) $(PROTOC) -Ithird_party/protobuf/src -I. --cpp_out=$(GENDIR) $<
+       $(Q) $(CXX) $(CPPFLAGS) $(CXXFLAGS) -MMD -MF $(addsuffix .dep, $(basename $@)) -c -o $@ $<
 
-$(GENDIR)/src/proto/grpc/lb/v1/load_balancer.grpc.pb.cc: src/proto/grpc/lb/v1/load_balancer.proto $(GENDIR)/src/proto/grpc/lb/v1/load_balancer.pb.cc $(PROTOBUF_DEP) $(PROTOC_PLUGINS) 
-       $(E) "[GRPC]    Generating gRPC's protobuf service CC file from $<"
+$(OBJDIR)/$(CONFIG)/%.o : %.cpp
+       $(E) "[CXX]     Compiling $<"
        $(Q) mkdir -p `dirname $@`
-       $(Q) $(PROTOC) -Ithird_party/protobuf/src -I. --grpc_out=$(GENDIR) --plugin=protoc-gen-grpc=$(PROTOC_PLUGINS_DIR)/grpc_cpp_plugin$(EXECUTABLE_SUFFIX) $<
-endif
+       $(Q) $(CXX) $(CPPFLAGS) $(CXXFLAGS) -MMD -MF $(addsuffix .dep, $(basename $@)) -c -o $@ $<
 
-ifeq ($(NO_PROTOC),true)
-$(GENDIR)/src/proto/grpc/reflection/v1alpha/reflection.pb.cc: protoc_dep_error
-$(GENDIR)/src/proto/grpc/reflection/v1alpha/reflection.grpc.pb.cc: protoc_dep_error
-else
+install: install_not_supported_error
 
-$(GENDIR)/src/proto/grpc/reflection/v1alpha/reflection.pb.cc: src/proto/grpc/reflection/v1alpha/reflection.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS) 
-       $(E) "[PROTOC]  Generating protobuf CC file from $<"
-       $(Q) mkdir -p `dirname $@`
-       $(Q) $(PROTOC) -Ithird_party/protobuf/src -I. --cpp_out=$(GENDIR) $<
+install_c: install_not_supported_error
 
-$(GENDIR)/src/proto/grpc/reflection/v1alpha/reflection.grpc.pb.cc: src/proto/grpc/reflection/v1alpha/reflection.proto $(GENDIR)/src/proto/grpc/reflection/v1alpha/reflection.pb.cc $(PROTOBUF_DEP) $(PROTOC_PLUGINS) 
-       $(E) "[GRPC]    Generating gRPC's protobuf service CC file from $<"
-       $(Q) mkdir -p `dirname $@`
-       $(Q) $(PROTOC) -Ithird_party/protobuf/src -I. --grpc_out=$(GENDIR) --plugin=protoc-gen-grpc=$(PROTOC_PLUGINS_DIR)/grpc_cpp_plugin$(EXECUTABLE_SUFFIX) $<
-endif
+install_cxx: install_not_supported_error
 
-ifeq ($(NO_PROTOC),true)
-$(GENDIR)/src/proto/grpc/status/status.pb.cc: protoc_dep_error
-$(GENDIR)/src/proto/grpc/status/status.grpc.pb.cc: protoc_dep_error
-else
+install_csharp: install_not_supported_error
 
-$(GENDIR)/src/proto/grpc/status/status.pb.cc: src/proto/grpc/status/status.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS) 
-       $(E) "[PROTOC]  Generating protobuf CC file from $<"
-       $(Q) mkdir -p `dirname $@`
-       $(Q) $(PROTOC) -Ithird_party/protobuf/src -I. --cpp_out=$(GENDIR) $<
+install-static: install_not_supported_error
 
-$(GENDIR)/src/proto/grpc/status/status.grpc.pb.cc: src/proto/grpc/status/status.proto $(GENDIR)/src/proto/grpc/status/status.pb.cc $(PROTOBUF_DEP) $(PROTOC_PLUGINS) 
-       $(E) "[GRPC]    Generating gRPC's protobuf service CC file from $<"
-       $(Q) mkdir -p `dirname $@`
-       $(Q) $(PROTOC) -Ithird_party/protobuf/src -I. --grpc_out=$(GENDIR) --plugin=protoc-gen-grpc=$(PROTOC_PLUGINS_DIR)/grpc_cpp_plugin$(EXECUTABLE_SUFFIX) $<
-endif
+install-certs: install_not_supported_error
 
-ifeq ($(NO_PROTOC),true)
-$(GENDIR)/src/proto/grpc/testing/benchmark_service.pb.cc: protoc_dep_error
-$(GENDIR)/src/proto/grpc/testing/benchmark_service.grpc.pb.cc: protoc_dep_error
-else
+clean:
+       $(E) "[CLEAN]   Cleaning build directories."
+       $(Q) $(RM) -rf $(OBJDIR) $(LIBDIR) $(BINDIR) $(GENDIR) cache.mk
 
-$(GENDIR)/src/proto/grpc/testing/benchmark_service.pb.cc: src/proto/grpc/testing/benchmark_service.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS) $(GENDIR)/src/proto/grpc/testing/messages.pb.cc
-       $(E) "[PROTOC]  Generating protobuf CC file from $<"
-       $(Q) mkdir -p `dirname $@`
-       $(Q) $(PROTOC) -Ithird_party/protobuf/src -I. --cpp_out=$(GENDIR) $<
 
-$(GENDIR)/src/proto/grpc/testing/benchmark_service.grpc.pb.cc: src/proto/grpc/testing/benchmark_service.proto $(GENDIR)/src/proto/grpc/testing/benchmark_service.pb.cc $(PROTOBUF_DEP) $(PROTOC_PLUGINS) $(GENDIR)/src/proto/grpc/testing/messages.pb.cc $(GENDIR)/src/proto/grpc/testing/messages.grpc.pb.cc
-       $(E) "[GRPC]    Generating gRPC's protobuf service CC file from $<"
-       $(Q) mkdir -p `dirname $@`
-       $(Q) $(PROTOC) -Ithird_party/protobuf/src -I. --grpc_out=$(GENDIR) --plugin=protoc-gen-grpc=$(PROTOC_PLUGINS_DIR)/grpc_cpp_plugin$(EXECUTABLE_SUFFIX) $<
-endif
+# The various libraries
 
-ifeq ($(NO_PROTOC),true)
-$(GENDIR)/src/proto/grpc/testing/control.pb.cc: protoc_dep_error
-$(GENDIR)/src/proto/grpc/testing/control.grpc.pb.cc: protoc_dep_error
-else
 
-$(GENDIR)/src/proto/grpc/testing/control.pb.cc: src/proto/grpc/testing/control.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS) $(GENDIR)/src/proto/grpc/testing/payloads.pb.cc $(GENDIR)/src/proto/grpc/testing/stats.pb.cc
-       $(E) "[PROTOC]  Generating protobuf CC file from $<"
-       $(Q) mkdir -p `dirname $@`
-       $(Q) $(PROTOC) -Ithird_party/protobuf/src -I. --cpp_out=$(GENDIR) $<
+# start of build recipe for library "address_sorting" (generated by makelib(lib) template function)
+LIBADDRESS_SORTING_SRC = \
+    third_party/address_sorting/address_sorting.c \
+    third_party/address_sorting/address_sorting_posix.c \
+    third_party/address_sorting/address_sorting_windows.c \
 
-$(GENDIR)/src/proto/grpc/testing/control.grpc.pb.cc: src/proto/grpc/testing/control.proto $(GENDIR)/src/proto/grpc/testing/control.pb.cc $(PROTOBUF_DEP) $(PROTOC_PLUGINS) $(GENDIR)/src/proto/grpc/testing/payloads.pb.cc $(GENDIR)/src/proto/grpc/testing/payloads.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/stats.pb.cc $(GENDIR)/src/proto/grpc/testing/stats.grpc.pb.cc
-       $(E) "[GRPC]    Generating gRPC's protobuf service CC file from $<"
-       $(Q) mkdir -p `dirname $@`
-       $(Q) $(PROTOC) -Ithird_party/protobuf/src -I. --grpc_out=$(GENDIR) --plugin=protoc-gen-grpc=$(PROTOC_PLUGINS_DIR)/grpc_cpp_plugin$(EXECUTABLE_SUFFIX) $<
-endif
+PUBLIC_HEADERS_C += \
 
-ifeq ($(NO_PROTOC),true)
-$(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.pb.cc: protoc_dep_error
-$(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.grpc.pb.cc: protoc_dep_error
-else
+LIBADDRESS_SORTING_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBADDRESS_SORTING_SRC))))
 
-$(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.pb.cc: src/proto/grpc/testing/duplicate/echo_duplicate.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS) $(GENDIR)/src/proto/grpc/testing/echo_messages.pb.cc
-       $(E) "[PROTOC]  Generating protobuf CC file from $<"
-       $(Q) mkdir -p `dirname $@`
-       $(Q) $(PROTOC) -Ithird_party/protobuf/src -I. --cpp_out=$(GENDIR) $<
 
-$(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.grpc.pb.cc: src/proto/grpc/testing/duplicate/echo_duplicate.proto $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.pb.cc $(PROTOBUF_DEP) $(PROTOC_PLUGINS) $(GENDIR)/src/proto/grpc/testing/echo_messages.pb.cc $(GENDIR)/src/proto/grpc/testing/echo_messages.grpc.pb.cc
-       $(E) "[GRPC]    Generating gRPC's protobuf service CC file from $<"
+$(LIBDIR)/$(CONFIG)/libaddress_sorting.a:  $(LIBADDRESS_SORTING_OBJS) 
+       $(E) "[AR]      Creating $@"
        $(Q) mkdir -p `dirname $@`
-       $(Q) $(PROTOC) -Ithird_party/protobuf/src -I. --grpc_out=$(GENDIR) --plugin=protoc-gen-grpc=$(PROTOC_PLUGINS_DIR)/grpc_cpp_plugin$(EXECUTABLE_SUFFIX) $<
+       $(Q) rm -f $(LIBDIR)/$(CONFIG)/libaddress_sorting.a
+       $(Q) $(AR) $(ARFLAGS) $(LIBDIR)/$(CONFIG)/libaddress_sorting.a $(LIBADDRESS_SORTING_OBJS) 
+ifeq ($(SYSTEM),Darwin)
+       $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libaddress_sorting.a
 endif
 
-ifeq ($(NO_PROTOC),true)
-$(GENDIR)/src/proto/grpc/testing/echo.pb.cc: protoc_dep_error
-$(GENDIR)/src/proto/grpc/testing/echo.grpc.pb.cc: protoc_dep_error
-else
-
 
-$(GENDIR)/src/proto/grpc/testing/echo.pb.cc: src/proto/grpc/testing/echo.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS) $(GENDIR)/src/proto/grpc/testing/echo_messages.pb.cc $(GENDIR)/src/proto/grpc/testing/simple_messages.pb.cc
-       $(E) "[PROTOC]  Generating protobuf CC file from $<"
-       $(Q) mkdir -p `dirname $@`
-       $(Q) $(PROTOC) -Ithird_party/protobuf/src -I. --cpp_out=$(GENDIR) $<
 
-$(GENDIR)/src/proto/grpc/testing/echo.grpc.pb.cc: src/proto/grpc/testing/echo.proto $(GENDIR)/src/proto/grpc/testing/echo.pb.cc $(PROTOBUF_DEP) $(PROTOC_PLUGINS) $(GENDIR)/src/proto/grpc/testing/echo_messages.pb.cc $(GENDIR)/src/proto/grpc/testing/echo_messages.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/simple_messages.pb.cc $(GENDIR)/src/proto/grpc/testing/simple_messages.grpc.pb.cc
-       $(E) "[GRPC]    Generating gRPC's protobuf service CC file from $<"
+ifeq ($(SYSTEM),MINGW32)
+$(LIBDIR)/$(CONFIG)/address_sorting$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE): $(LIBADDRESS_SORTING_OBJS)  $(ZLIB_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(RE2_DEP) $(UPB_DEP) $(GRPC_ABSEIL_DEP)
+       $(E) "[LD]      Linking $@"
        $(Q) mkdir -p `dirname $@`
-       $(Q) $(PROTOC) -Ithird_party/protobuf/src -I. --grpc_out=generate_mock_code=true:$(GENDIR) --plugin=protoc-gen-grpc=$(PROTOC_PLUGINS_DIR)/grpc_cpp_plugin$(EXECUTABLE_SUFFIX) $<
-endif
-
-ifeq ($(NO_PROTOC),true)
-$(GENDIR)/src/proto/grpc/testing/echo_messages.pb.cc: protoc_dep_error
-$(GENDIR)/src/proto/grpc/testing/echo_messages.grpc.pb.cc: protoc_dep_error
+       $(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,--output-def=$(LIBDIR)/$(CONFIG)/address_sorting$(SHARED_VERSION_CORE).def -Wl,--out-implib=$(LIBDIR)/$(CONFIG)/libaddress_sorting$(SHARED_VERSION_CORE)-dll.a -o $(LIBDIR)/$(CONFIG)/address_sorting$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBADDRESS_SORTING_OBJS) $(ZLIB_MERGE_LIBS) $(CARES_MERGE_LIBS) $(ADDRESS_SORTING_MERGE_LIBS) $(RE2_MERGE_LIBS) $(UPB_MERGE_LIBS) $(GRPC_ABSEIL_MERGE_LIBS) $(LDLIBS)
 else
-
-$(GENDIR)/src/proto/grpc/testing/echo_messages.pb.cc: src/proto/grpc/testing/echo_messages.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS) 
-       $(E) "[PROTOC]  Generating protobuf CC file from $<"
+$(LIBDIR)/$(CONFIG)/libaddress_sorting$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE): $(LIBADDRESS_SORTING_OBJS)  $(ZLIB_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(RE2_DEP) $(UPB_DEP) $(GRPC_ABSEIL_DEP)
+       $(E) "[LD]      Linking $@"
        $(Q) mkdir -p `dirname $@`
-       $(Q) $(PROTOC) -Ithird_party/protobuf/src -I. --cpp_out=$(GENDIR) $<
+ifeq ($(SYSTEM),Darwin)
+       $(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -install_name $(SHARED_PREFIX)address_sorting$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) -dynamiclib -o $(LIBDIR)/$(CONFIG)/libaddress_sorting$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBADDRESS_SORTING_OBJS) $(ZLIB_MERGE_LIBS) $(CARES_MERGE_LIBS) $(ADDRESS_SORTING_MERGE_LIBS) $(RE2_MERGE_LIBS) $(UPB_MERGE_LIBS) $(GRPC_ABSEIL_MERGE_LIBS) $(LDLIBS)
+else
+       $(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,-soname,libaddress_sorting.so.14 -o $(LIBDIR)/$(CONFIG)/libaddress_sorting$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBADDRESS_SORTING_OBJS) $(ZLIB_MERGE_LIBS) $(CARES_MERGE_LIBS) $(ADDRESS_SORTING_MERGE_LIBS) $(RE2_MERGE_LIBS) $(UPB_MERGE_LIBS) $(GRPC_ABSEIL_MERGE_LIBS) $(LDLIBS)
+       $(Q) ln -sf $(SHARED_PREFIX)address_sorting$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBDIR)/$(CONFIG)/libaddress_sorting$(SHARED_VERSION_CORE).so.14
+       $(Q) ln -sf $(SHARED_PREFIX)address_sorting$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBDIR)/$(CONFIG)/libaddress_sorting$(SHARED_VERSION_CORE).so
+endif
+endif
 
-$(GENDIR)/src/proto/grpc/testing/echo_messages.grpc.pb.cc: src/proto/grpc/testing/echo_messages.proto $(GENDIR)/src/proto/grpc/testing/echo_messages.pb.cc $(PROTOBUF_DEP) $(PROTOC_PLUGINS) 
-       $(E) "[GRPC]    Generating gRPC's protobuf service CC file from $<"
-       $(Q) mkdir -p `dirname $@`
-       $(Q) $(PROTOC) -Ithird_party/protobuf/src -I. --grpc_out=$(GENDIR) --plugin=protoc-gen-grpc=$(PROTOC_PLUGINS_DIR)/grpc_cpp_plugin$(EXECUTABLE_SUFFIX) $<
+ifneq ($(NO_DEPS),true)
+-include $(LIBADDRESS_SORTING_OBJS:.o=.dep)
 endif
+# end of build recipe for library "address_sorting"
 
-ifeq ($(NO_PROTOC),true)
-$(GENDIR)/src/proto/grpc/testing/empty.pb.cc: protoc_dep_error
-$(GENDIR)/src/proto/grpc/testing/empty.grpc.pb.cc: protoc_dep_error
-else
 
-$(GENDIR)/src/proto/grpc/testing/empty.pb.cc: src/proto/grpc/testing/empty.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS) 
-       $(E) "[PROTOC]  Generating protobuf CC file from $<"
-       $(Q) mkdir -p `dirname $@`
-       $(Q) $(PROTOC) -Ithird_party/protobuf/src -I. --cpp_out=$(GENDIR) $<
+# start of build recipe for library "gpr" (generated by makelib(lib) template function)
+LIBGPR_SRC = \
+    src/core/lib/gpr/alloc.cc \
+    src/core/lib/gpr/atm.cc \
+    src/core/lib/gpr/cpu_iphone.cc \
+    src/core/lib/gpr/cpu_linux.cc \
+    src/core/lib/gpr/cpu_posix.cc \
+    src/core/lib/gpr/cpu_windows.cc \
+    src/core/lib/gpr/env_linux.cc \
+    src/core/lib/gpr/env_posix.cc \
+    src/core/lib/gpr/env_windows.cc \
+    src/core/lib/gpr/log.cc \
+    src/core/lib/gpr/log_android.cc \
+    src/core/lib/gpr/log_linux.cc \
+    src/core/lib/gpr/log_posix.cc \
+    src/core/lib/gpr/log_windows.cc \
+    src/core/lib/gpr/murmur_hash.cc \
+    src/core/lib/gpr/string.cc \
+    src/core/lib/gpr/string_posix.cc \
+    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 \
+    src/core/lib/gpr/time_posix.cc \
+    src/core/lib/gpr/time_precise.cc \
+    src/core/lib/gpr/time_windows.cc \
+    src/core/lib/gpr/tls_pthread.cc \
+    src/core/lib/gpr/tmpfile_msys.cc \
+    src/core/lib/gpr/tmpfile_posix.cc \
+    src/core/lib/gpr/tmpfile_windows.cc \
+    src/core/lib/gpr/wrap_memcpy.cc \
+    src/core/lib/gprpp/arena.cc \
+    src/core/lib/gprpp/examine_stack.cc \
+    src/core/lib/gprpp/fork.cc \
+    src/core/lib/gprpp/global_config_env.cc \
+    src/core/lib/gprpp/host_port.cc \
+    src/core/lib/gprpp/mpscq.cc \
+    src/core/lib/gprpp/stat_posix.cc \
+    src/core/lib/gprpp/stat_windows.cc \
+    src/core/lib/gprpp/thd_posix.cc \
+    src/core/lib/gprpp/thd_windows.cc \
+    src/core/lib/profiling/basic_timers.cc \
+    src/core/lib/profiling/stap_timers.cc \
 
-$(GENDIR)/src/proto/grpc/testing/empty.grpc.pb.cc: src/proto/grpc/testing/empty.proto $(GENDIR)/src/proto/grpc/testing/empty.pb.cc $(PROTOBUF_DEP) $(PROTOC_PLUGINS) 
-       $(E) "[GRPC]    Generating gRPC's protobuf service CC file from $<"
-       $(Q) mkdir -p `dirname $@`
-       $(Q) $(PROTOC) -Ithird_party/protobuf/src -I. --grpc_out=$(GENDIR) --plugin=protoc-gen-grpc=$(PROTOC_PLUGINS_DIR)/grpc_cpp_plugin$(EXECUTABLE_SUFFIX) $<
-endif
+PUBLIC_HEADERS_C += \
+    include/grpc/impl/codegen/atm.h \
+    include/grpc/impl/codegen/atm_gcc_atomic.h \
+    include/grpc/impl/codegen/atm_gcc_sync.h \
+    include/grpc/impl/codegen/atm_windows.h \
+    include/grpc/impl/codegen/byte_buffer.h \
+    include/grpc/impl/codegen/byte_buffer_reader.h \
+    include/grpc/impl/codegen/compression_types.h \
+    include/grpc/impl/codegen/connectivity_state.h \
+    include/grpc/impl/codegen/fork.h \
+    include/grpc/impl/codegen/gpr_slice.h \
+    include/grpc/impl/codegen/gpr_types.h \
+    include/grpc/impl/codegen/grpc_types.h \
+    include/grpc/impl/codegen/log.h \
+    include/grpc/impl/codegen/port_platform.h \
+    include/grpc/impl/codegen/propagation_bits.h \
+    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 \
+    include/grpc/impl/codegen/sync_windows.h \
+    include/grpc/support/alloc.h \
+    include/grpc/support/atm.h \
+    include/grpc/support/atm_gcc_atomic.h \
+    include/grpc/support/atm_gcc_sync.h \
+    include/grpc/support/atm_windows.h \
+    include/grpc/support/cpu.h \
+    include/grpc/support/log.h \
+    include/grpc/support/log_windows.h \
+    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 \
+    include/grpc/support/sync_windows.h \
+    include/grpc/support/thd_id.h \
+    include/grpc/support/time.h \
 
-ifeq ($(NO_PROTOC),true)
-$(GENDIR)/src/proto/grpc/testing/messages.pb.cc: protoc_dep_error
-$(GENDIR)/src/proto/grpc/testing/messages.grpc.pb.cc: protoc_dep_error
-else
+LIBGPR_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBGPR_SRC))))
 
-$(GENDIR)/src/proto/grpc/testing/messages.pb.cc: src/proto/grpc/testing/messages.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS) 
-       $(E) "[PROTOC]  Generating protobuf CC file from $<"
-       $(Q) mkdir -p `dirname $@`
-       $(Q) $(PROTOC) -Ithird_party/protobuf/src -I. --cpp_out=$(GENDIR) $<
 
-$(GENDIR)/src/proto/grpc/testing/messages.grpc.pb.cc: src/proto/grpc/testing/messages.proto $(GENDIR)/src/proto/grpc/testing/messages.pb.cc $(PROTOBUF_DEP) $(PROTOC_PLUGINS) 
-       $(E) "[GRPC]    Generating gRPC's protobuf service CC file from $<"
+$(LIBDIR)/$(CONFIG)/libgpr.a: $(ZLIB_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(RE2_DEP) $(UPB_DEP) $(GRPC_ABSEIL_DEP)  $(LIBGPR_OBJS) 
+       $(E) "[AR]      Creating $@"
        $(Q) mkdir -p `dirname $@`
-       $(Q) $(PROTOC) -Ithird_party/protobuf/src -I. --grpc_out=$(GENDIR) --plugin=protoc-gen-grpc=$(PROTOC_PLUGINS_DIR)/grpc_cpp_plugin$(EXECUTABLE_SUFFIX) $<
+       $(Q) rm -f $(LIBDIR)/$(CONFIG)/libgpr.a
+       $(Q) $(AR) $(ARFLAGS) $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBGPR_OBJS) 
+ifeq ($(SYSTEM),Darwin)
+       $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libgpr.a
 endif
 
-ifeq ($(NO_PROTOC),true)
-$(GENDIR)/src/proto/grpc/testing/payloads.pb.cc: protoc_dep_error
-$(GENDIR)/src/proto/grpc/testing/payloads.grpc.pb.cc: protoc_dep_error
-else
 
-$(GENDIR)/src/proto/grpc/testing/payloads.pb.cc: src/proto/grpc/testing/payloads.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS) 
-       $(E) "[PROTOC]  Generating protobuf CC file from $<"
-       $(Q) mkdir -p `dirname $@`
-       $(Q) $(PROTOC) -Ithird_party/protobuf/src -I. --cpp_out=$(GENDIR) $<
 
-$(GENDIR)/src/proto/grpc/testing/payloads.grpc.pb.cc: src/proto/grpc/testing/payloads.proto $(GENDIR)/src/proto/grpc/testing/payloads.pb.cc $(PROTOBUF_DEP) $(PROTOC_PLUGINS) 
-       $(E) "[GRPC]    Generating gRPC's protobuf service CC file from $<"
+ifeq ($(SYSTEM),MINGW32)
+$(LIBDIR)/$(CONFIG)/gpr$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE): $(LIBGPR_OBJS)  $(ZLIB_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(RE2_DEP) $(UPB_DEP) $(GRPC_ABSEIL_DEP)
+       $(E) "[LD]      Linking $@"
        $(Q) mkdir -p `dirname $@`
-       $(Q) $(PROTOC) -Ithird_party/protobuf/src -I. --grpc_out=$(GENDIR) --plugin=protoc-gen-grpc=$(PROTOC_PLUGINS_DIR)/grpc_cpp_plugin$(EXECUTABLE_SUFFIX) $<
-endif
-
-ifeq ($(NO_PROTOC),true)
-$(GENDIR)/src/proto/grpc/testing/report_qps_scenario_service.pb.cc: protoc_dep_error
-$(GENDIR)/src/proto/grpc/testing/report_qps_scenario_service.grpc.pb.cc: protoc_dep_error
+       $(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,--output-def=$(LIBDIR)/$(CONFIG)/gpr$(SHARED_VERSION_CORE).def -Wl,--out-implib=$(LIBDIR)/$(CONFIG)/libgpr$(SHARED_VERSION_CORE)-dll.a -o $(LIBDIR)/$(CONFIG)/gpr$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBGPR_OBJS) $(ZLIB_MERGE_LIBS) $(CARES_MERGE_LIBS) $(ADDRESS_SORTING_MERGE_LIBS) $(RE2_MERGE_LIBS) $(UPB_MERGE_LIBS) $(GRPC_ABSEIL_MERGE_LIBS) $(LDLIBS)
 else
-
-$(GENDIR)/src/proto/grpc/testing/report_qps_scenario_service.pb.cc: src/proto/grpc/testing/report_qps_scenario_service.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS) $(GENDIR)/src/proto/grpc/testing/control.pb.cc
-       $(E) "[PROTOC]  Generating protobuf CC file from $<"
-       $(Q) mkdir -p `dirname $@`
-       $(Q) $(PROTOC) -Ithird_party/protobuf/src -I. --cpp_out=$(GENDIR) $<
-
-$(GENDIR)/src/proto/grpc/testing/report_qps_scenario_service.grpc.pb.cc: src/proto/grpc/testing/report_qps_scenario_service.proto $(GENDIR)/src/proto/grpc/testing/report_qps_scenario_service.pb.cc $(PROTOBUF_DEP) $(PROTOC_PLUGINS) $(GENDIR)/src/proto/grpc/testing/control.pb.cc $(GENDIR)/src/proto/grpc/testing/control.grpc.pb.cc
-       $(E) "[GRPC]    Generating gRPC's protobuf service CC file from $<"
-       $(Q) mkdir -p `dirname $@`
-       $(Q) $(PROTOC) -Ithird_party/protobuf/src -I. --grpc_out=$(GENDIR) --plugin=protoc-gen-grpc=$(PROTOC_PLUGINS_DIR)/grpc_cpp_plugin$(EXECUTABLE_SUFFIX) $<
-endif
-
-ifeq ($(NO_PROTOC),true)
-$(GENDIR)/src/proto/grpc/testing/simple_messages.pb.cc: protoc_dep_error
-$(GENDIR)/src/proto/grpc/testing/simple_messages.grpc.pb.cc: protoc_dep_error
-else
-
-$(GENDIR)/src/proto/grpc/testing/simple_messages.pb.cc: src/proto/grpc/testing/simple_messages.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS) 
-       $(E) "[PROTOC]  Generating protobuf CC file from $<"
-       $(Q) mkdir -p `dirname $@`
-       $(Q) $(PROTOC) -Ithird_party/protobuf/src -I. --cpp_out=$(GENDIR) $<
-
-$(GENDIR)/src/proto/grpc/testing/simple_messages.grpc.pb.cc: src/proto/grpc/testing/simple_messages.proto $(GENDIR)/src/proto/grpc/testing/simple_messages.pb.cc $(PROTOBUF_DEP) $(PROTOC_PLUGINS) 
-       $(E) "[GRPC]    Generating gRPC's protobuf service CC file from $<"
-       $(Q) mkdir -p `dirname $@`
-       $(Q) $(PROTOC) -Ithird_party/protobuf/src -I. --grpc_out=$(GENDIR) --plugin=protoc-gen-grpc=$(PROTOC_PLUGINS_DIR)/grpc_cpp_plugin$(EXECUTABLE_SUFFIX) $<
-endif
-
-ifeq ($(NO_PROTOC),true)
-$(GENDIR)/src/proto/grpc/testing/stats.pb.cc: protoc_dep_error
-$(GENDIR)/src/proto/grpc/testing/stats.grpc.pb.cc: protoc_dep_error
-else
-
-$(GENDIR)/src/proto/grpc/testing/stats.pb.cc: src/proto/grpc/testing/stats.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS) $(GENDIR)/src/proto/grpc/core/stats.pb.cc
-       $(E) "[PROTOC]  Generating protobuf CC file from $<"
-       $(Q) mkdir -p `dirname $@`
-       $(Q) $(PROTOC) -Ithird_party/protobuf/src -I. --cpp_out=$(GENDIR) $<
-
-$(GENDIR)/src/proto/grpc/testing/stats.grpc.pb.cc: src/proto/grpc/testing/stats.proto $(GENDIR)/src/proto/grpc/testing/stats.pb.cc $(PROTOBUF_DEP) $(PROTOC_PLUGINS) $(GENDIR)/src/proto/grpc/core/stats.pb.cc $(GENDIR)/src/proto/grpc/core/stats.grpc.pb.cc
-       $(E) "[GRPC]    Generating gRPC's protobuf service CC file from $<"
-       $(Q) mkdir -p `dirname $@`
-       $(Q) $(PROTOC) -Ithird_party/protobuf/src -I. --grpc_out=$(GENDIR) --plugin=protoc-gen-grpc=$(PROTOC_PLUGINS_DIR)/grpc_cpp_plugin$(EXECUTABLE_SUFFIX) $<
-endif
-
-ifeq ($(NO_PROTOC),true)
-$(GENDIR)/src/proto/grpc/testing/test.pb.cc: protoc_dep_error
-$(GENDIR)/src/proto/grpc/testing/test.grpc.pb.cc: protoc_dep_error
-else
-
-$(GENDIR)/src/proto/grpc/testing/test.pb.cc: src/proto/grpc/testing/test.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS) $(GENDIR)/src/proto/grpc/testing/empty.pb.cc $(GENDIR)/src/proto/grpc/testing/messages.pb.cc
-       $(E) "[PROTOC]  Generating protobuf CC file from $<"
-       $(Q) mkdir -p `dirname $@`
-       $(Q) $(PROTOC) -Ithird_party/protobuf/src -I. --cpp_out=$(GENDIR) $<
-
-$(GENDIR)/src/proto/grpc/testing/test.grpc.pb.cc: src/proto/grpc/testing/test.proto $(GENDIR)/src/proto/grpc/testing/test.pb.cc $(PROTOBUF_DEP) $(PROTOC_PLUGINS) $(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
-       $(E) "[GRPC]    Generating gRPC's protobuf service CC file from $<"
-       $(Q) mkdir -p `dirname $@`
-       $(Q) $(PROTOC) -Ithird_party/protobuf/src -I. --grpc_out=$(GENDIR) --plugin=protoc-gen-grpc=$(PROTOC_PLUGINS_DIR)/grpc_cpp_plugin$(EXECUTABLE_SUFFIX) $<
-endif
-
-ifeq ($(NO_PROTOC),true)
-$(GENDIR)/src/proto/grpc/testing/worker_service.pb.cc: protoc_dep_error
-$(GENDIR)/src/proto/grpc/testing/worker_service.grpc.pb.cc: protoc_dep_error
-else
-
-$(GENDIR)/src/proto/grpc/testing/worker_service.pb.cc: src/proto/grpc/testing/worker_service.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS) $(GENDIR)/src/proto/grpc/testing/control.pb.cc
-       $(E) "[PROTOC]  Generating protobuf CC file from $<"
-       $(Q) mkdir -p `dirname $@`
-       $(Q) $(PROTOC) -Ithird_party/protobuf/src -I. --cpp_out=$(GENDIR) $<
-
-$(GENDIR)/src/proto/grpc/testing/worker_service.grpc.pb.cc: src/proto/grpc/testing/worker_service.proto $(GENDIR)/src/proto/grpc/testing/worker_service.pb.cc $(PROTOBUF_DEP) $(PROTOC_PLUGINS) $(GENDIR)/src/proto/grpc/testing/control.pb.cc $(GENDIR)/src/proto/grpc/testing/control.grpc.pb.cc
-       $(E) "[GRPC]    Generating gRPC's protobuf service CC file from $<"
-       $(Q) mkdir -p `dirname $@`
-       $(Q) $(PROTOC) -Ithird_party/protobuf/src -I. --grpc_out=$(GENDIR) --plugin=protoc-gen-grpc=$(PROTOC_PLUGINS_DIR)/grpc_cpp_plugin$(EXECUTABLE_SUFFIX) $<
-endif
-
-ifeq ($(NO_PROTOC),true)
-$(GENDIR)/src/proto/grpc/testing/xds/ads_for_test.pb.cc: protoc_dep_error
-$(GENDIR)/src/proto/grpc/testing/xds/ads_for_test.grpc.pb.cc: protoc_dep_error
-else
-
-$(GENDIR)/src/proto/grpc/testing/xds/ads_for_test.pb.cc: src/proto/grpc/testing/xds/ads_for_test.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS) $(GENDIR)/src/proto/grpc/testing/xds/eds_for_test.pb.cc
-       $(E) "[PROTOC]  Generating protobuf CC file from $<"
-       $(Q) mkdir -p `dirname $@`
-       $(Q) $(PROTOC) -Ithird_party/protobuf/src -I. --cpp_out=$(GENDIR) $<
-
-$(GENDIR)/src/proto/grpc/testing/xds/ads_for_test.grpc.pb.cc: src/proto/grpc/testing/xds/ads_for_test.proto $(GENDIR)/src/proto/grpc/testing/xds/ads_for_test.pb.cc $(PROTOBUF_DEP) $(PROTOC_PLUGINS) $(GENDIR)/src/proto/grpc/testing/xds/eds_for_test.pb.cc $(GENDIR)/src/proto/grpc/testing/xds/eds_for_test.grpc.pb.cc
-       $(E) "[GRPC]    Generating gRPC's protobuf service CC file from $<"
-       $(Q) mkdir -p `dirname $@`
-       $(Q) $(PROTOC) -Ithird_party/protobuf/src -I. --grpc_out=$(GENDIR) --plugin=protoc-gen-grpc=$(PROTOC_PLUGINS_DIR)/grpc_cpp_plugin$(EXECUTABLE_SUFFIX) $<
-endif
-
-ifeq ($(NO_PROTOC),true)
-$(GENDIR)/src/proto/grpc/testing/xds/cds_for_test.pb.cc: protoc_dep_error
-$(GENDIR)/src/proto/grpc/testing/xds/cds_for_test.grpc.pb.cc: protoc_dep_error
-else
-
-$(GENDIR)/src/proto/grpc/testing/xds/cds_for_test.pb.cc: src/proto/grpc/testing/xds/cds_for_test.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS) 
-       $(E) "[PROTOC]  Generating protobuf CC file from $<"
-       $(Q) mkdir -p `dirname $@`
-       $(Q) $(PROTOC) -Ithird_party/protobuf/src -I. --cpp_out=$(GENDIR) $<
-
-$(GENDIR)/src/proto/grpc/testing/xds/cds_for_test.grpc.pb.cc: src/proto/grpc/testing/xds/cds_for_test.proto $(GENDIR)/src/proto/grpc/testing/xds/cds_for_test.pb.cc $(PROTOBUF_DEP) $(PROTOC_PLUGINS) 
-       $(E) "[GRPC]    Generating gRPC's protobuf service CC file from $<"
-       $(Q) mkdir -p `dirname $@`
-       $(Q) $(PROTOC) -Ithird_party/protobuf/src -I. --grpc_out=$(GENDIR) --plugin=protoc-gen-grpc=$(PROTOC_PLUGINS_DIR)/grpc_cpp_plugin$(EXECUTABLE_SUFFIX) $<
-endif
-
-ifeq ($(NO_PROTOC),true)
-$(GENDIR)/src/proto/grpc/testing/xds/eds_for_test.pb.cc: protoc_dep_error
-$(GENDIR)/src/proto/grpc/testing/xds/eds_for_test.grpc.pb.cc: protoc_dep_error
-else
-
-$(GENDIR)/src/proto/grpc/testing/xds/eds_for_test.pb.cc: src/proto/grpc/testing/xds/eds_for_test.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS) 
-       $(E) "[PROTOC]  Generating protobuf CC file from $<"
-       $(Q) mkdir -p `dirname $@`
-       $(Q) $(PROTOC) -Ithird_party/protobuf/src -I. --cpp_out=$(GENDIR) $<
-
-$(GENDIR)/src/proto/grpc/testing/xds/eds_for_test.grpc.pb.cc: src/proto/grpc/testing/xds/eds_for_test.proto $(GENDIR)/src/proto/grpc/testing/xds/eds_for_test.pb.cc $(PROTOBUF_DEP) $(PROTOC_PLUGINS) 
-       $(E) "[GRPC]    Generating gRPC's protobuf service CC file from $<"
-       $(Q) mkdir -p `dirname $@`
-       $(Q) $(PROTOC) -Ithird_party/protobuf/src -I. --grpc_out=$(GENDIR) --plugin=protoc-gen-grpc=$(PROTOC_PLUGINS_DIR)/grpc_cpp_plugin$(EXECUTABLE_SUFFIX) $<
-endif
-
-ifeq ($(NO_PROTOC),true)
-$(GENDIR)/src/proto/grpc/testing/xds/lds_rds_for_test.pb.cc: protoc_dep_error
-$(GENDIR)/src/proto/grpc/testing/xds/lds_rds_for_test.grpc.pb.cc: protoc_dep_error
-else
-
-$(GENDIR)/src/proto/grpc/testing/xds/lds_rds_for_test.pb.cc: src/proto/grpc/testing/xds/lds_rds_for_test.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS) $(GENDIR)/src/proto/grpc/testing/xds/cds_for_test.pb.cc $(GENDIR)/src/proto/grpc/testing/xds/eds_for_test.pb.cc
-       $(E) "[PROTOC]  Generating protobuf CC file from $<"
-       $(Q) mkdir -p `dirname $@`
-       $(Q) $(PROTOC) -Ithird_party/protobuf/src -I. --cpp_out=$(GENDIR) $<
-
-$(GENDIR)/src/proto/grpc/testing/xds/lds_rds_for_test.grpc.pb.cc: src/proto/grpc/testing/xds/lds_rds_for_test.proto $(GENDIR)/src/proto/grpc/testing/xds/lds_rds_for_test.pb.cc $(PROTOBUF_DEP) $(PROTOC_PLUGINS) $(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
-       $(E) "[GRPC]    Generating gRPC's protobuf service CC file from $<"
-       $(Q) mkdir -p `dirname $@`
-       $(Q) $(PROTOC) -Ithird_party/protobuf/src -I. --grpc_out=$(GENDIR) --plugin=protoc-gen-grpc=$(PROTOC_PLUGINS_DIR)/grpc_cpp_plugin$(EXECUTABLE_SUFFIX) $<
-endif
-
-ifeq ($(NO_PROTOC),true)
-$(GENDIR)/src/proto/grpc/testing/xds/lrs_for_test.pb.cc: protoc_dep_error
-$(GENDIR)/src/proto/grpc/testing/xds/lrs_for_test.grpc.pb.cc: protoc_dep_error
-else
-
-$(GENDIR)/src/proto/grpc/testing/xds/lrs_for_test.pb.cc: src/proto/grpc/testing/xds/lrs_for_test.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS) $(GENDIR)/src/proto/grpc/testing/xds/eds_for_test.pb.cc
-       $(E) "[PROTOC]  Generating protobuf CC file from $<"
-       $(Q) mkdir -p `dirname $@`
-       $(Q) $(PROTOC) -Ithird_party/protobuf/src -I. --cpp_out=$(GENDIR) $<
-
-$(GENDIR)/src/proto/grpc/testing/xds/lrs_for_test.grpc.pb.cc: src/proto/grpc/testing/xds/lrs_for_test.proto $(GENDIR)/src/proto/grpc/testing/xds/lrs_for_test.pb.cc $(PROTOBUF_DEP) $(PROTOC_PLUGINS) $(GENDIR)/src/proto/grpc/testing/xds/eds_for_test.pb.cc $(GENDIR)/src/proto/grpc/testing/xds/eds_for_test.grpc.pb.cc
-       $(E) "[GRPC]    Generating gRPC's protobuf service CC file from $<"
-       $(Q) mkdir -p `dirname $@`
-       $(Q) $(PROTOC) -Ithird_party/protobuf/src -I. --grpc_out=$(GENDIR) --plugin=protoc-gen-grpc=$(PROTOC_PLUGINS_DIR)/grpc_cpp_plugin$(EXECUTABLE_SUFFIX) $<
-endif
-
-ifeq ($(NO_PROTOC),true)
-$(GENDIR)/src/proto/grpc/testing/xds/orca_load_report_for_test.pb.cc: protoc_dep_error
-$(GENDIR)/src/proto/grpc/testing/xds/orca_load_report_for_test.grpc.pb.cc: protoc_dep_error
-else
-
-$(GENDIR)/src/proto/grpc/testing/xds/orca_load_report_for_test.pb.cc: src/proto/grpc/testing/xds/orca_load_report_for_test.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS) 
-       $(E) "[PROTOC]  Generating protobuf CC file from $<"
-       $(Q) mkdir -p `dirname $@`
-       $(Q) $(PROTOC) -Ithird_party/protobuf/src -I. --cpp_out=$(GENDIR) $<
-
-$(GENDIR)/src/proto/grpc/testing/xds/orca_load_report_for_test.grpc.pb.cc: src/proto/grpc/testing/xds/orca_load_report_for_test.proto $(GENDIR)/src/proto/grpc/testing/xds/orca_load_report_for_test.pb.cc $(PROTOBUF_DEP) $(PROTOC_PLUGINS) 
-       $(E) "[GRPC]    Generating gRPC's protobuf service CC file from $<"
-       $(Q) mkdir -p `dirname $@`
-       $(Q) $(PROTOC) -Ithird_party/protobuf/src -I. --grpc_out=$(GENDIR) --plugin=protoc-gen-grpc=$(PROTOC_PLUGINS_DIR)/grpc_cpp_plugin$(EXECUTABLE_SUFFIX) $<
-endif
-
-ifeq ($(NO_PROTOC),true)
-$(GENDIR)/src/proto/grpc/testing/xds/v3/address.pb.cc: protoc_dep_error
-$(GENDIR)/src/proto/grpc/testing/xds/v3/address.grpc.pb.cc: protoc_dep_error
-else
-
-$(GENDIR)/src/proto/grpc/testing/xds/v3/address.pb.cc: src/proto/grpc/testing/xds/v3/address.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS) 
-       $(E) "[PROTOC]  Generating protobuf CC file from $<"
-       $(Q) mkdir -p `dirname $@`
-       $(Q) $(PROTOC) -Ithird_party/protobuf/src -I. --cpp_out=$(GENDIR) $<
-
-$(GENDIR)/src/proto/grpc/testing/xds/v3/address.grpc.pb.cc: src/proto/grpc/testing/xds/v3/address.proto $(GENDIR)/src/proto/grpc/testing/xds/v3/address.pb.cc $(PROTOBUF_DEP) $(PROTOC_PLUGINS) 
-       $(E) "[GRPC]    Generating gRPC's protobuf service CC file from $<"
-       $(Q) mkdir -p `dirname $@`
-       $(Q) $(PROTOC) -Ithird_party/protobuf/src -I. --grpc_out=$(GENDIR) --plugin=protoc-gen-grpc=$(PROTOC_PLUGINS_DIR)/grpc_cpp_plugin$(EXECUTABLE_SUFFIX) $<
-endif
-
-ifeq ($(NO_PROTOC),true)
-$(GENDIR)/src/proto/grpc/testing/xds/v3/ads.pb.cc: protoc_dep_error
-$(GENDIR)/src/proto/grpc/testing/xds/v3/ads.grpc.pb.cc: protoc_dep_error
-else
-
-$(GENDIR)/src/proto/grpc/testing/xds/v3/ads.pb.cc: src/proto/grpc/testing/xds/v3/ads.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS) $(GENDIR)/src/proto/grpc/testing/xds/v3/discovery.pb.cc
-       $(E) "[PROTOC]  Generating protobuf CC file from $<"
-       $(Q) mkdir -p `dirname $@`
-       $(Q) $(PROTOC) -Ithird_party/protobuf/src -I. --cpp_out=$(GENDIR) $<
-
-$(GENDIR)/src/proto/grpc/testing/xds/v3/ads.grpc.pb.cc: src/proto/grpc/testing/xds/v3/ads.proto $(GENDIR)/src/proto/grpc/testing/xds/v3/ads.pb.cc $(PROTOBUF_DEP) $(PROTOC_PLUGINS) $(GENDIR)/src/proto/grpc/testing/xds/v3/discovery.pb.cc $(GENDIR)/src/proto/grpc/testing/xds/v3/discovery.grpc.pb.cc
-       $(E) "[GRPC]    Generating gRPC's protobuf service CC file from $<"
-       $(Q) mkdir -p `dirname $@`
-       $(Q) $(PROTOC) -Ithird_party/protobuf/src -I. --grpc_out=$(GENDIR) --plugin=protoc-gen-grpc=$(PROTOC_PLUGINS_DIR)/grpc_cpp_plugin$(EXECUTABLE_SUFFIX) $<
-endif
-
-ifeq ($(NO_PROTOC),true)
-$(GENDIR)/src/proto/grpc/testing/xds/v3/base.pb.cc: protoc_dep_error
-$(GENDIR)/src/proto/grpc/testing/xds/v3/base.grpc.pb.cc: protoc_dep_error
-else
-
-$(GENDIR)/src/proto/grpc/testing/xds/v3/base.pb.cc: src/proto/grpc/testing/xds/v3/base.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS) $(GENDIR)/src/proto/grpc/testing/xds/v3/percent.pb.cc
-       $(E) "[PROTOC]  Generating protobuf CC file from $<"
-       $(Q) mkdir -p `dirname $@`
-       $(Q) $(PROTOC) -Ithird_party/protobuf/src -I. --cpp_out=$(GENDIR) $<
-
-$(GENDIR)/src/proto/grpc/testing/xds/v3/base.grpc.pb.cc: src/proto/grpc/testing/xds/v3/base.proto $(GENDIR)/src/proto/grpc/testing/xds/v3/base.pb.cc $(PROTOBUF_DEP) $(PROTOC_PLUGINS) $(GENDIR)/src/proto/grpc/testing/xds/v3/percent.pb.cc $(GENDIR)/src/proto/grpc/testing/xds/v3/percent.grpc.pb.cc
-       $(E) "[GRPC]    Generating gRPC's protobuf service CC file from $<"
-       $(Q) mkdir -p `dirname $@`
-       $(Q) $(PROTOC) -Ithird_party/protobuf/src -I. --grpc_out=$(GENDIR) --plugin=protoc-gen-grpc=$(PROTOC_PLUGINS_DIR)/grpc_cpp_plugin$(EXECUTABLE_SUFFIX) $<
-endif
-
-ifeq ($(NO_PROTOC),true)
-$(GENDIR)/src/proto/grpc/testing/xds/v3/cluster.pb.cc: protoc_dep_error
-$(GENDIR)/src/proto/grpc/testing/xds/v3/cluster.grpc.pb.cc: protoc_dep_error
-else
-
-$(GENDIR)/src/proto/grpc/testing/xds/v3/cluster.pb.cc: src/proto/grpc/testing/xds/v3/cluster.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS) $(GENDIR)/src/proto/grpc/testing/xds/v3/config_source.pb.cc
-       $(E) "[PROTOC]  Generating protobuf CC file from $<"
-       $(Q) mkdir -p `dirname $@`
-       $(Q) $(PROTOC) -Ithird_party/protobuf/src -I. --cpp_out=$(GENDIR) $<
-
-$(GENDIR)/src/proto/grpc/testing/xds/v3/cluster.grpc.pb.cc: src/proto/grpc/testing/xds/v3/cluster.proto $(GENDIR)/src/proto/grpc/testing/xds/v3/cluster.pb.cc $(PROTOBUF_DEP) $(PROTOC_PLUGINS) $(GENDIR)/src/proto/grpc/testing/xds/v3/config_source.pb.cc $(GENDIR)/src/proto/grpc/testing/xds/v3/config_source.grpc.pb.cc
-       $(E) "[GRPC]    Generating gRPC's protobuf service CC file from $<"
-       $(Q) mkdir -p `dirname $@`
-       $(Q) $(PROTOC) -Ithird_party/protobuf/src -I. --grpc_out=$(GENDIR) --plugin=protoc-gen-grpc=$(PROTOC_PLUGINS_DIR)/grpc_cpp_plugin$(EXECUTABLE_SUFFIX) $<
-endif
-
-ifeq ($(NO_PROTOC),true)
-$(GENDIR)/src/proto/grpc/testing/xds/v3/config_source.pb.cc: protoc_dep_error
-$(GENDIR)/src/proto/grpc/testing/xds/v3/config_source.grpc.pb.cc: protoc_dep_error
-else
-
-$(GENDIR)/src/proto/grpc/testing/xds/v3/config_source.pb.cc: src/proto/grpc/testing/xds/v3/config_source.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS) 
-       $(E) "[PROTOC]  Generating protobuf CC file from $<"
-       $(Q) mkdir -p `dirname $@`
-       $(Q) $(PROTOC) -Ithird_party/protobuf/src -I. --cpp_out=$(GENDIR) $<
-
-$(GENDIR)/src/proto/grpc/testing/xds/v3/config_source.grpc.pb.cc: src/proto/grpc/testing/xds/v3/config_source.proto $(GENDIR)/src/proto/grpc/testing/xds/v3/config_source.pb.cc $(PROTOBUF_DEP) $(PROTOC_PLUGINS) 
-       $(E) "[GRPC]    Generating gRPC's protobuf service CC file from $<"
-       $(Q) mkdir -p `dirname $@`
-       $(Q) $(PROTOC) -Ithird_party/protobuf/src -I. --grpc_out=$(GENDIR) --plugin=protoc-gen-grpc=$(PROTOC_PLUGINS_DIR)/grpc_cpp_plugin$(EXECUTABLE_SUFFIX) $<
-endif
-
-ifeq ($(NO_PROTOC),true)
-$(GENDIR)/src/proto/grpc/testing/xds/v3/discovery.pb.cc: protoc_dep_error
-$(GENDIR)/src/proto/grpc/testing/xds/v3/discovery.grpc.pb.cc: protoc_dep_error
-else
-
-$(GENDIR)/src/proto/grpc/testing/xds/v3/discovery.pb.cc: src/proto/grpc/testing/xds/v3/discovery.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS) $(GENDIR)/src/proto/grpc/testing/xds/v3/base.pb.cc
-       $(E) "[PROTOC]  Generating protobuf CC file from $<"
-       $(Q) mkdir -p `dirname $@`
-       $(Q) $(PROTOC) -Ithird_party/protobuf/src -I. --cpp_out=$(GENDIR) $<
-
-$(GENDIR)/src/proto/grpc/testing/xds/v3/discovery.grpc.pb.cc: src/proto/grpc/testing/xds/v3/discovery.proto $(GENDIR)/src/proto/grpc/testing/xds/v3/discovery.pb.cc $(PROTOBUF_DEP) $(PROTOC_PLUGINS) $(GENDIR)/src/proto/grpc/testing/xds/v3/base.pb.cc $(GENDIR)/src/proto/grpc/testing/xds/v3/base.grpc.pb.cc
-       $(E) "[GRPC]    Generating gRPC's protobuf service CC file from $<"
-       $(Q) mkdir -p `dirname $@`
-       $(Q) $(PROTOC) -Ithird_party/protobuf/src -I. --grpc_out=$(GENDIR) --plugin=protoc-gen-grpc=$(PROTOC_PLUGINS_DIR)/grpc_cpp_plugin$(EXECUTABLE_SUFFIX) $<
-endif
-
-ifeq ($(NO_PROTOC),true)
-$(GENDIR)/src/proto/grpc/testing/xds/v3/endpoint.pb.cc: protoc_dep_error
-$(GENDIR)/src/proto/grpc/testing/xds/v3/endpoint.grpc.pb.cc: protoc_dep_error
-else
-
-$(GENDIR)/src/proto/grpc/testing/xds/v3/endpoint.pb.cc: src/proto/grpc/testing/xds/v3/endpoint.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS) $(GENDIR)/src/proto/grpc/testing/xds/v3/address.pb.cc $(GENDIR)/src/proto/grpc/testing/xds/v3/base.pb.cc $(GENDIR)/src/proto/grpc/testing/xds/v3/percent.pb.cc
-       $(E) "[PROTOC]  Generating protobuf CC file from $<"
-       $(Q) mkdir -p `dirname $@`
-       $(Q) $(PROTOC) -Ithird_party/protobuf/src -I. --cpp_out=$(GENDIR) $<
-
-$(GENDIR)/src/proto/grpc/testing/xds/v3/endpoint.grpc.pb.cc: src/proto/grpc/testing/xds/v3/endpoint.proto $(GENDIR)/src/proto/grpc/testing/xds/v3/endpoint.pb.cc $(PROTOBUF_DEP) $(PROTOC_PLUGINS) $(GENDIR)/src/proto/grpc/testing/xds/v3/address.pb.cc $(GENDIR)/src/proto/grpc/testing/xds/v3/address.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/xds/v3/base.pb.cc $(GENDIR)/src/proto/grpc/testing/xds/v3/base.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/xds/v3/percent.pb.cc $(GENDIR)/src/proto/grpc/testing/xds/v3/percent.grpc.pb.cc
-       $(E) "[GRPC]    Generating gRPC's protobuf service CC file from $<"
-       $(Q) mkdir -p `dirname $@`
-       $(Q) $(PROTOC) -Ithird_party/protobuf/src -I. --grpc_out=$(GENDIR) --plugin=protoc-gen-grpc=$(PROTOC_PLUGINS_DIR)/grpc_cpp_plugin$(EXECUTABLE_SUFFIX) $<
-endif
-
-ifeq ($(NO_PROTOC),true)
-$(GENDIR)/src/proto/grpc/testing/xds/v3/http_connection_manager.pb.cc: protoc_dep_error
-$(GENDIR)/src/proto/grpc/testing/xds/v3/http_connection_manager.grpc.pb.cc: protoc_dep_error
-else
-
-$(GENDIR)/src/proto/grpc/testing/xds/v3/http_connection_manager.pb.cc: src/proto/grpc/testing/xds/v3/http_connection_manager.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS) $(GENDIR)/src/proto/grpc/testing/xds/v3/config_source.pb.cc $(GENDIR)/src/proto/grpc/testing/xds/v3/protocol.pb.cc $(GENDIR)/src/proto/grpc/testing/xds/v3/route.pb.cc
-       $(E) "[PROTOC]  Generating protobuf CC file from $<"
-       $(Q) mkdir -p `dirname $@`
-       $(Q) $(PROTOC) -Ithird_party/protobuf/src -I. --cpp_out=$(GENDIR) $<
-
-$(GENDIR)/src/proto/grpc/testing/xds/v3/http_connection_manager.grpc.pb.cc: src/proto/grpc/testing/xds/v3/http_connection_manager.proto $(GENDIR)/src/proto/grpc/testing/xds/v3/http_connection_manager.pb.cc $(PROTOBUF_DEP) $(PROTOC_PLUGINS) $(GENDIR)/src/proto/grpc/testing/xds/v3/config_source.pb.cc $(GENDIR)/src/proto/grpc/testing/xds/v3/config_source.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/xds/v3/protocol.pb.cc $(GENDIR)/src/proto/grpc/testing/xds/v3/protocol.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/xds/v3/route.pb.cc $(GENDIR)/src/proto/grpc/testing/xds/v3/route.grpc.pb.cc
-       $(E) "[GRPC]    Generating gRPC's protobuf service CC file from $<"
-       $(Q) mkdir -p `dirname $@`
-       $(Q) $(PROTOC) -Ithird_party/protobuf/src -I. --grpc_out=$(GENDIR) --plugin=protoc-gen-grpc=$(PROTOC_PLUGINS_DIR)/grpc_cpp_plugin$(EXECUTABLE_SUFFIX) $<
-endif
-
-ifeq ($(NO_PROTOC),true)
-$(GENDIR)/src/proto/grpc/testing/xds/v3/listener.pb.cc: protoc_dep_error
-$(GENDIR)/src/proto/grpc/testing/xds/v3/listener.grpc.pb.cc: protoc_dep_error
-else
-
-$(GENDIR)/src/proto/grpc/testing/xds/v3/listener.pb.cc: src/proto/grpc/testing/xds/v3/listener.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS) 
-       $(E) "[PROTOC]  Generating protobuf CC file from $<"
-       $(Q) mkdir -p `dirname $@`
-       $(Q) $(PROTOC) -Ithird_party/protobuf/src -I. --cpp_out=$(GENDIR) $<
-
-$(GENDIR)/src/proto/grpc/testing/xds/v3/listener.grpc.pb.cc: src/proto/grpc/testing/xds/v3/listener.proto $(GENDIR)/src/proto/grpc/testing/xds/v3/listener.pb.cc $(PROTOBUF_DEP) $(PROTOC_PLUGINS) 
-       $(E) "[GRPC]    Generating gRPC's protobuf service CC file from $<"
-       $(Q) mkdir -p `dirname $@`
-       $(Q) $(PROTOC) -Ithird_party/protobuf/src -I. --grpc_out=$(GENDIR) --plugin=protoc-gen-grpc=$(PROTOC_PLUGINS_DIR)/grpc_cpp_plugin$(EXECUTABLE_SUFFIX) $<
-endif
-
-ifeq ($(NO_PROTOC),true)
-$(GENDIR)/src/proto/grpc/testing/xds/v3/load_report.pb.cc: protoc_dep_error
-$(GENDIR)/src/proto/grpc/testing/xds/v3/load_report.grpc.pb.cc: protoc_dep_error
-else
-
-$(GENDIR)/src/proto/grpc/testing/xds/v3/load_report.pb.cc: src/proto/grpc/testing/xds/v3/load_report.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS) $(GENDIR)/src/proto/grpc/testing/xds/v3/address.pb.cc $(GENDIR)/src/proto/grpc/testing/xds/v3/base.pb.cc
-       $(E) "[PROTOC]  Generating protobuf CC file from $<"
-       $(Q) mkdir -p `dirname $@`
-       $(Q) $(PROTOC) -Ithird_party/protobuf/src -I. --cpp_out=$(GENDIR) $<
-
-$(GENDIR)/src/proto/grpc/testing/xds/v3/load_report.grpc.pb.cc: src/proto/grpc/testing/xds/v3/load_report.proto $(GENDIR)/src/proto/grpc/testing/xds/v3/load_report.pb.cc $(PROTOBUF_DEP) $(PROTOC_PLUGINS) $(GENDIR)/src/proto/grpc/testing/xds/v3/address.pb.cc $(GENDIR)/src/proto/grpc/testing/xds/v3/address.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/xds/v3/base.pb.cc $(GENDIR)/src/proto/grpc/testing/xds/v3/base.grpc.pb.cc
-       $(E) "[GRPC]    Generating gRPC's protobuf service CC file from $<"
-       $(Q) mkdir -p `dirname $@`
-       $(Q) $(PROTOC) -Ithird_party/protobuf/src -I. --grpc_out=$(GENDIR) --plugin=protoc-gen-grpc=$(PROTOC_PLUGINS_DIR)/grpc_cpp_plugin$(EXECUTABLE_SUFFIX) $<
-endif
-
-ifeq ($(NO_PROTOC),true)
-$(GENDIR)/src/proto/grpc/testing/xds/v3/lrs.pb.cc: protoc_dep_error
-$(GENDIR)/src/proto/grpc/testing/xds/v3/lrs.grpc.pb.cc: protoc_dep_error
-else
-
-$(GENDIR)/src/proto/grpc/testing/xds/v3/lrs.pb.cc: src/proto/grpc/testing/xds/v3/lrs.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS) $(GENDIR)/src/proto/grpc/testing/xds/v3/base.pb.cc $(GENDIR)/src/proto/grpc/testing/xds/v3/load_report.pb.cc
-       $(E) "[PROTOC]  Generating protobuf CC file from $<"
-       $(Q) mkdir -p `dirname $@`
-       $(Q) $(PROTOC) -Ithird_party/protobuf/src -I. --cpp_out=$(GENDIR) $<
-
-$(GENDIR)/src/proto/grpc/testing/xds/v3/lrs.grpc.pb.cc: src/proto/grpc/testing/xds/v3/lrs.proto $(GENDIR)/src/proto/grpc/testing/xds/v3/lrs.pb.cc $(PROTOBUF_DEP) $(PROTOC_PLUGINS) $(GENDIR)/src/proto/grpc/testing/xds/v3/base.pb.cc $(GENDIR)/src/proto/grpc/testing/xds/v3/base.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/xds/v3/load_report.pb.cc $(GENDIR)/src/proto/grpc/testing/xds/v3/load_report.grpc.pb.cc
-       $(E) "[GRPC]    Generating gRPC's protobuf service CC file from $<"
-       $(Q) mkdir -p `dirname $@`
-       $(Q) $(PROTOC) -Ithird_party/protobuf/src -I. --grpc_out=$(GENDIR) --plugin=protoc-gen-grpc=$(PROTOC_PLUGINS_DIR)/grpc_cpp_plugin$(EXECUTABLE_SUFFIX) $<
-endif
-
-ifeq ($(NO_PROTOC),true)
-$(GENDIR)/src/proto/grpc/testing/xds/v3/percent.pb.cc: protoc_dep_error
-$(GENDIR)/src/proto/grpc/testing/xds/v3/percent.grpc.pb.cc: protoc_dep_error
-else
-
-$(GENDIR)/src/proto/grpc/testing/xds/v3/percent.pb.cc: src/proto/grpc/testing/xds/v3/percent.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS) 
-       $(E) "[PROTOC]  Generating protobuf CC file from $<"
-       $(Q) mkdir -p `dirname $@`
-       $(Q) $(PROTOC) -Ithird_party/protobuf/src -I. --cpp_out=$(GENDIR) $<
-
-$(GENDIR)/src/proto/grpc/testing/xds/v3/percent.grpc.pb.cc: src/proto/grpc/testing/xds/v3/percent.proto $(GENDIR)/src/proto/grpc/testing/xds/v3/percent.pb.cc $(PROTOBUF_DEP) $(PROTOC_PLUGINS) 
-       $(E) "[GRPC]    Generating gRPC's protobuf service CC file from $<"
-       $(Q) mkdir -p `dirname $@`
-       $(Q) $(PROTOC) -Ithird_party/protobuf/src -I. --grpc_out=$(GENDIR) --plugin=protoc-gen-grpc=$(PROTOC_PLUGINS_DIR)/grpc_cpp_plugin$(EXECUTABLE_SUFFIX) $<
-endif
-
-ifeq ($(NO_PROTOC),true)
-$(GENDIR)/src/proto/grpc/testing/xds/v3/protocol.pb.cc: protoc_dep_error
-$(GENDIR)/src/proto/grpc/testing/xds/v3/protocol.grpc.pb.cc: protoc_dep_error
-else
-
-$(GENDIR)/src/proto/grpc/testing/xds/v3/protocol.pb.cc: src/proto/grpc/testing/xds/v3/protocol.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS) 
-       $(E) "[PROTOC]  Generating protobuf CC file from $<"
-       $(Q) mkdir -p `dirname $@`
-       $(Q) $(PROTOC) -Ithird_party/protobuf/src -I. --cpp_out=$(GENDIR) $<
-
-$(GENDIR)/src/proto/grpc/testing/xds/v3/protocol.grpc.pb.cc: src/proto/grpc/testing/xds/v3/protocol.proto $(GENDIR)/src/proto/grpc/testing/xds/v3/protocol.pb.cc $(PROTOBUF_DEP) $(PROTOC_PLUGINS) 
-       $(E) "[GRPC]    Generating gRPC's protobuf service CC file from $<"
-       $(Q) mkdir -p `dirname $@`
-       $(Q) $(PROTOC) -Ithird_party/protobuf/src -I. --grpc_out=$(GENDIR) --plugin=protoc-gen-grpc=$(PROTOC_PLUGINS_DIR)/grpc_cpp_plugin$(EXECUTABLE_SUFFIX) $<
-endif
-
-ifeq ($(NO_PROTOC),true)
-$(GENDIR)/src/proto/grpc/testing/xds/v3/range.pb.cc: protoc_dep_error
-$(GENDIR)/src/proto/grpc/testing/xds/v3/range.grpc.pb.cc: protoc_dep_error
-else
-
-$(GENDIR)/src/proto/grpc/testing/xds/v3/range.pb.cc: src/proto/grpc/testing/xds/v3/range.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS) 
-       $(E) "[PROTOC]  Generating protobuf CC file from $<"
-       $(Q) mkdir -p `dirname $@`
-       $(Q) $(PROTOC) -Ithird_party/protobuf/src -I. --cpp_out=$(GENDIR) $<
-
-$(GENDIR)/src/proto/grpc/testing/xds/v3/range.grpc.pb.cc: src/proto/grpc/testing/xds/v3/range.proto $(GENDIR)/src/proto/grpc/testing/xds/v3/range.pb.cc $(PROTOBUF_DEP) $(PROTOC_PLUGINS) 
-       $(E) "[GRPC]    Generating gRPC's protobuf service CC file from $<"
-       $(Q) mkdir -p `dirname $@`
-       $(Q) $(PROTOC) -Ithird_party/protobuf/src -I. --grpc_out=$(GENDIR) --plugin=protoc-gen-grpc=$(PROTOC_PLUGINS_DIR)/grpc_cpp_plugin$(EXECUTABLE_SUFFIX) $<
-endif
-
-ifeq ($(NO_PROTOC),true)
-$(GENDIR)/src/proto/grpc/testing/xds/v3/regex.pb.cc: protoc_dep_error
-$(GENDIR)/src/proto/grpc/testing/xds/v3/regex.grpc.pb.cc: protoc_dep_error
-else
-
-$(GENDIR)/src/proto/grpc/testing/xds/v3/regex.pb.cc: src/proto/grpc/testing/xds/v3/regex.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS) 
-       $(E) "[PROTOC]  Generating protobuf CC file from $<"
-       $(Q) mkdir -p `dirname $@`
-       $(Q) $(PROTOC) -Ithird_party/protobuf/src -I. --cpp_out=$(GENDIR) $<
-
-$(GENDIR)/src/proto/grpc/testing/xds/v3/regex.grpc.pb.cc: src/proto/grpc/testing/xds/v3/regex.proto $(GENDIR)/src/proto/grpc/testing/xds/v3/regex.pb.cc $(PROTOBUF_DEP) $(PROTOC_PLUGINS) 
-       $(E) "[GRPC]    Generating gRPC's protobuf service CC file from $<"
-       $(Q) mkdir -p `dirname $@`
-       $(Q) $(PROTOC) -Ithird_party/protobuf/src -I. --grpc_out=$(GENDIR) --plugin=protoc-gen-grpc=$(PROTOC_PLUGINS_DIR)/grpc_cpp_plugin$(EXECUTABLE_SUFFIX) $<
-endif
-
-ifeq ($(NO_PROTOC),true)
-$(GENDIR)/src/proto/grpc/testing/xds/v3/route.pb.cc: protoc_dep_error
-$(GENDIR)/src/proto/grpc/testing/xds/v3/route.grpc.pb.cc: protoc_dep_error
-else
-
-$(GENDIR)/src/proto/grpc/testing/xds/v3/route.pb.cc: src/proto/grpc/testing/xds/v3/route.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS) $(GENDIR)/src/proto/grpc/testing/xds/v3/base.pb.cc $(GENDIR)/src/proto/grpc/testing/xds/v3/regex.pb.cc $(GENDIR)/src/proto/grpc/testing/xds/v3/percent.pb.cc $(GENDIR)/src/proto/grpc/testing/xds/v3/range.pb.cc
-       $(E) "[PROTOC]  Generating protobuf CC file from $<"
-       $(Q) mkdir -p `dirname $@`
-       $(Q) $(PROTOC) -Ithird_party/protobuf/src -I. --cpp_out=$(GENDIR) $<
-
-$(GENDIR)/src/proto/grpc/testing/xds/v3/route.grpc.pb.cc: src/proto/grpc/testing/xds/v3/route.proto $(GENDIR)/src/proto/grpc/testing/xds/v3/route.pb.cc $(PROTOBUF_DEP) $(PROTOC_PLUGINS) $(GENDIR)/src/proto/grpc/testing/xds/v3/base.pb.cc $(GENDIR)/src/proto/grpc/testing/xds/v3/base.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/xds/v3/regex.pb.cc $(GENDIR)/src/proto/grpc/testing/xds/v3/regex.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/xds/v3/percent.pb.cc $(GENDIR)/src/proto/grpc/testing/xds/v3/percent.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/xds/v3/range.pb.cc $(GENDIR)/src/proto/grpc/testing/xds/v3/range.grpc.pb.cc
-       $(E) "[GRPC]    Generating gRPC's protobuf service CC file from $<"
-       $(Q) mkdir -p `dirname $@`
-       $(Q) $(PROTOC) -Ithird_party/protobuf/src -I. --grpc_out=$(GENDIR) --plugin=protoc-gen-grpc=$(PROTOC_PLUGINS_DIR)/grpc_cpp_plugin$(EXECUTABLE_SUFFIX) $<
-endif
-
-ifeq ($(NO_PROTOC),true)
-$(GENDIR)/test/core/tsi/alts/fake_handshaker/handshaker.pb.cc: protoc_dep_error
-$(GENDIR)/test/core/tsi/alts/fake_handshaker/handshaker.grpc.pb.cc: protoc_dep_error
-else
-
-$(GENDIR)/test/core/tsi/alts/fake_handshaker/handshaker.pb.cc: test/core/tsi/alts/fake_handshaker/handshaker.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS) 
-       $(E) "[PROTOC]  Generating protobuf CC file from $<"
-       $(Q) mkdir -p `dirname $@`
-       $(Q) $(PROTOC) -Ithird_party/protobuf/src -I. --cpp_out=$(GENDIR) $<
-
-$(GENDIR)/test/core/tsi/alts/fake_handshaker/handshaker.grpc.pb.cc: test/core/tsi/alts/fake_handshaker/handshaker.proto $(GENDIR)/test/core/tsi/alts/fake_handshaker/handshaker.pb.cc $(PROTOBUF_DEP) $(PROTOC_PLUGINS) 
-       $(E) "[GRPC]    Generating gRPC's protobuf service CC file from $<"
-       $(Q) mkdir -p `dirname $@`
-       $(Q) $(PROTOC) -Ithird_party/protobuf/src -I. --grpc_out=$(GENDIR) --plugin=protoc-gen-grpc=$(PROTOC_PLUGINS_DIR)/grpc_cpp_plugin$(EXECUTABLE_SUFFIX) $<
-endif
-
-ifeq ($(NO_PROTOC),true)
-$(GENDIR)/test/core/tsi/alts/fake_handshaker/transport_security_common.pb.cc: protoc_dep_error
-$(GENDIR)/test/core/tsi/alts/fake_handshaker/transport_security_common.grpc.pb.cc: protoc_dep_error
-else
-
-$(GENDIR)/test/core/tsi/alts/fake_handshaker/transport_security_common.pb.cc: test/core/tsi/alts/fake_handshaker/transport_security_common.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS) 
-       $(E) "[PROTOC]  Generating protobuf CC file from $<"
-       $(Q) mkdir -p `dirname $@`
-       $(Q) $(PROTOC) -Ithird_party/protobuf/src -I. --cpp_out=$(GENDIR) $<
-
-$(GENDIR)/test/core/tsi/alts/fake_handshaker/transport_security_common.grpc.pb.cc: test/core/tsi/alts/fake_handshaker/transport_security_common.proto $(GENDIR)/test/core/tsi/alts/fake_handshaker/transport_security_common.pb.cc $(PROTOBUF_DEP) $(PROTOC_PLUGINS) 
-       $(E) "[GRPC]    Generating gRPC's protobuf service CC file from $<"
-       $(Q) mkdir -p `dirname $@`
-       $(Q) $(PROTOC) -Ithird_party/protobuf/src -I. --grpc_out=$(GENDIR) --plugin=protoc-gen-grpc=$(PROTOC_PLUGINS_DIR)/grpc_cpp_plugin$(EXECUTABLE_SUFFIX) $<
-endif
-
-
-ifeq ($(CONFIG),stapprof)
-src/core/profiling/stap_timers.c: $(GENDIR)/src/core/profiling/stap_probes.h
-ifeq ($(HAS_SYSTEMTAP),true)
-$(GENDIR)/src/core/profiling/stap_probes.h: src/core/profiling/stap_probes.d
-       $(E) "[DTRACE]  Compiling $<"
-       $(Q) mkdir -p `dirname $@`
-       $(Q) $(DTRACE) -C -h -s $< -o $@
-else
-$(GENDIR)/src/core/profiling/stap_probes.h: systemtap_dep_error stop
-endif
-endif
-
-$(OBJDIR)/$(CONFIG)/%.o : %.c
-       $(E) "[C]       Compiling $<"
-       $(Q) mkdir -p `dirname $@`
-       $(Q) $(CC) $(CPPFLAGS) $(CFLAGS) -MMD -MF $(addsuffix .dep, $(basename $@)) -c -o $@ $<
-
-$(OBJDIR)/$(CONFIG)/%.o : $(GENDIR)/%.pb.cc
-       $(E) "[CXX]     Compiling $<"
-       $(Q) mkdir -p `dirname $@`
-       $(Q) $(CXX) $(CPPFLAGS) $(CXXFLAGS) -MMD -MF $(addsuffix .dep, $(basename $@)) -c -o $@ $<
-
-$(OBJDIR)/$(CONFIG)/src/compiler/%.o : src/compiler/%.cc
-       $(E) "[HOSTCXX] Compiling $<"
-       $(Q) mkdir -p `dirname $@`
-       $(Q) $(HOST_CXX) $(HOST_CXXFLAGS) $(HOST_CPPFLAGS) -MMD -MF $(addsuffix .dep, $(basename $@)) -c -o $@ $<
-
-$(OBJDIR)/$(CONFIG)/src/core/%.o : src/core/%.cc
-       $(E) "[CXX]     Compiling $<"
-       $(Q) mkdir -p `dirname $@`
-       $(Q) $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(COREFLAGS) -MMD -MF $(addsuffix .dep, $(basename $@)) -c -o $@ $<
-
-$(OBJDIR)/$(CONFIG)/test/core/%.o : test/core/%.cc
-       $(E) "[CXX]     Compiling $<"
-       $(Q) mkdir -p `dirname $@`
-       $(Q) $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(COREFLAGS) -MMD -MF $(addsuffix .dep, $(basename $@)) -c -o $@ $<
-
-$(OBJDIR)/$(CONFIG)/%.o : %.cc
-       $(E) "[CXX]     Compiling $<"
-       $(Q) mkdir -p `dirname $@`
-       $(Q) $(CXX) $(CPPFLAGS) $(CXXFLAGS) -MMD -MF $(addsuffix .dep, $(basename $@)) -c -o $@ $<
-
-$(OBJDIR)/$(CONFIG)/%.o : %.cpp
-       $(E) "[CXX]     Compiling $<"
-       $(Q) mkdir -p `dirname $@`
-       $(Q) $(CXX) $(CPPFLAGS) $(CXXFLAGS) -MMD -MF $(addsuffix .dep, $(basename $@)) -c -o $@ $<
-
-install: install_not_supported_error
-
-install_c: install_not_supported_error
-
-install_cxx: install_not_supported_error
-
-install_csharp: install_not_supported_error
-
-install-static: install_not_supported_error
-
-install-certs: install_not_supported_error
-
-clean:
-       $(E) "[CLEAN]   Cleaning build directories."
-       $(Q) $(RM) -rf $(OBJDIR) $(LIBDIR) $(BINDIR) $(GENDIR) cache.mk
-
-
-# The various libraries
-
-
-# start of build recipe for library "address_sorting" (generated by makelib(lib) template function)
-LIBADDRESS_SORTING_SRC = \
-    third_party/address_sorting/address_sorting.c \
-    third_party/address_sorting/address_sorting_posix.c \
-    third_party/address_sorting/address_sorting_windows.c \
-
-PUBLIC_HEADERS_C += \
-
-LIBADDRESS_SORTING_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBADDRESS_SORTING_SRC))))
-
-
-$(LIBDIR)/$(CONFIG)/libaddress_sorting.a:  $(LIBADDRESS_SORTING_OBJS) 
-       $(E) "[AR]      Creating $@"
-       $(Q) mkdir -p `dirname $@`
-       $(Q) rm -f $(LIBDIR)/$(CONFIG)/libaddress_sorting.a
-       $(Q) $(AR) $(ARFLAGS) $(LIBDIR)/$(CONFIG)/libaddress_sorting.a $(LIBADDRESS_SORTING_OBJS) 
-ifeq ($(SYSTEM),Darwin)
-       $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libaddress_sorting.a
-endif
-
-
-
-ifeq ($(SYSTEM),MINGW32)
-$(LIBDIR)/$(CONFIG)/address_sorting$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE): $(LIBADDRESS_SORTING_OBJS)  $(ZLIB_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(RE2_DEP) $(UPB_DEP) $(GRPC_ABSEIL_DEP)
-       $(E) "[LD]      Linking $@"
-       $(Q) mkdir -p `dirname $@`
-       $(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,--output-def=$(LIBDIR)/$(CONFIG)/address_sorting$(SHARED_VERSION_CORE).def -Wl,--out-implib=$(LIBDIR)/$(CONFIG)/libaddress_sorting$(SHARED_VERSION_CORE)-dll.a -o $(LIBDIR)/$(CONFIG)/address_sorting$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBADDRESS_SORTING_OBJS) $(ZLIB_MERGE_LIBS) $(CARES_MERGE_LIBS) $(ADDRESS_SORTING_MERGE_LIBS) $(RE2_MERGE_LIBS) $(UPB_MERGE_LIBS) $(GRPC_ABSEIL_MERGE_LIBS) $(LDLIBS)
-else
-$(LIBDIR)/$(CONFIG)/libaddress_sorting$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE): $(LIBADDRESS_SORTING_OBJS)  $(ZLIB_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(RE2_DEP) $(UPB_DEP) $(GRPC_ABSEIL_DEP)
-       $(E) "[LD]      Linking $@"
-       $(Q) mkdir -p `dirname $@`
-ifeq ($(SYSTEM),Darwin)
-       $(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -install_name $(SHARED_PREFIX)address_sorting$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) -dynamiclib -o $(LIBDIR)/$(CONFIG)/libaddress_sorting$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBADDRESS_SORTING_OBJS) $(ZLIB_MERGE_LIBS) $(CARES_MERGE_LIBS) $(ADDRESS_SORTING_MERGE_LIBS) $(RE2_MERGE_LIBS) $(UPB_MERGE_LIBS) $(GRPC_ABSEIL_MERGE_LIBS) $(LDLIBS)
-else
-       $(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,-soname,libaddress_sorting.so.14 -o $(LIBDIR)/$(CONFIG)/libaddress_sorting$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBADDRESS_SORTING_OBJS) $(ZLIB_MERGE_LIBS) $(CARES_MERGE_LIBS) $(ADDRESS_SORTING_MERGE_LIBS) $(RE2_MERGE_LIBS) $(UPB_MERGE_LIBS) $(GRPC_ABSEIL_MERGE_LIBS) $(LDLIBS)
-       $(Q) ln -sf $(SHARED_PREFIX)address_sorting$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBDIR)/$(CONFIG)/libaddress_sorting$(SHARED_VERSION_CORE).so.14
-       $(Q) ln -sf $(SHARED_PREFIX)address_sorting$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBDIR)/$(CONFIG)/libaddress_sorting$(SHARED_VERSION_CORE).so
-endif
-endif
-
-ifneq ($(NO_DEPS),true)
--include $(LIBADDRESS_SORTING_OBJS:.o=.dep)
-endif
-# end of build recipe for library "address_sorting"
-
-
-# start of build recipe for library "gpr" (generated by makelib(lib) template function)
-LIBGPR_SRC = \
-    src/core/lib/gpr/alloc.cc \
-    src/core/lib/gpr/atm.cc \
-    src/core/lib/gpr/cpu_iphone.cc \
-    src/core/lib/gpr/cpu_linux.cc \
-    src/core/lib/gpr/cpu_posix.cc \
-    src/core/lib/gpr/cpu_windows.cc \
-    src/core/lib/gpr/env_linux.cc \
-    src/core/lib/gpr/env_posix.cc \
-    src/core/lib/gpr/env_windows.cc \
-    src/core/lib/gpr/log.cc \
-    src/core/lib/gpr/log_android.cc \
-    src/core/lib/gpr/log_linux.cc \
-    src/core/lib/gpr/log_posix.cc \
-    src/core/lib/gpr/log_windows.cc \
-    src/core/lib/gpr/murmur_hash.cc \
-    src/core/lib/gpr/string.cc \
-    src/core/lib/gpr/string_posix.cc \
-    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 \
-    src/core/lib/gpr/time_posix.cc \
-    src/core/lib/gpr/time_precise.cc \
-    src/core/lib/gpr/time_windows.cc \
-    src/core/lib/gpr/tls_pthread.cc \
-    src/core/lib/gpr/tmpfile_msys.cc \
-    src/core/lib/gpr/tmpfile_posix.cc \
-    src/core/lib/gpr/tmpfile_windows.cc \
-    src/core/lib/gpr/wrap_memcpy.cc \
-    src/core/lib/gprpp/arena.cc \
-    src/core/lib/gprpp/examine_stack.cc \
-    src/core/lib/gprpp/fork.cc \
-    src/core/lib/gprpp/global_config_env.cc \
-    src/core/lib/gprpp/host_port.cc \
-    src/core/lib/gprpp/mpscq.cc \
-    src/core/lib/gprpp/stat_posix.cc \
-    src/core/lib/gprpp/stat_windows.cc \
-    src/core/lib/gprpp/thd_posix.cc \
-    src/core/lib/gprpp/thd_windows.cc \
-    src/core/lib/profiling/basic_timers.cc \
-    src/core/lib/profiling/stap_timers.cc \
-
-PUBLIC_HEADERS_C += \
-    include/grpc/impl/codegen/atm.h \
-    include/grpc/impl/codegen/atm_gcc_atomic.h \
-    include/grpc/impl/codegen/atm_gcc_sync.h \
-    include/grpc/impl/codegen/atm_windows.h \
-    include/grpc/impl/codegen/byte_buffer.h \
-    include/grpc/impl/codegen/byte_buffer_reader.h \
-    include/grpc/impl/codegen/compression_types.h \
-    include/grpc/impl/codegen/connectivity_state.h \
-    include/grpc/impl/codegen/fork.h \
-    include/grpc/impl/codegen/gpr_slice.h \
-    include/grpc/impl/codegen/gpr_types.h \
-    include/grpc/impl/codegen/grpc_types.h \
-    include/grpc/impl/codegen/log.h \
-    include/grpc/impl/codegen/port_platform.h \
-    include/grpc/impl/codegen/propagation_bits.h \
-    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 \
-    include/grpc/impl/codegen/sync_windows.h \
-    include/grpc/support/alloc.h \
-    include/grpc/support/atm.h \
-    include/grpc/support/atm_gcc_atomic.h \
-    include/grpc/support/atm_gcc_sync.h \
-    include/grpc/support/atm_windows.h \
-    include/grpc/support/cpu.h \
-    include/grpc/support/log.h \
-    include/grpc/support/log_windows.h \
-    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 \
-    include/grpc/support/sync_windows.h \
-    include/grpc/support/thd_id.h \
-    include/grpc/support/time.h \
-
-LIBGPR_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBGPR_SRC))))
-
-
-$(LIBDIR)/$(CONFIG)/libgpr.a: $(ZLIB_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(RE2_DEP) $(UPB_DEP) $(GRPC_ABSEIL_DEP)  $(LIBGPR_OBJS) 
-       $(E) "[AR]      Creating $@"
-       $(Q) mkdir -p `dirname $@`
-       $(Q) rm -f $(LIBDIR)/$(CONFIG)/libgpr.a
-       $(Q) $(AR) $(ARFLAGS) $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBGPR_OBJS) 
-ifeq ($(SYSTEM),Darwin)
-       $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libgpr.a
-endif
-
-
-
-ifeq ($(SYSTEM),MINGW32)
-$(LIBDIR)/$(CONFIG)/gpr$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE): $(LIBGPR_OBJS)  $(ZLIB_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(RE2_DEP) $(UPB_DEP) $(GRPC_ABSEIL_DEP)
-       $(E) "[LD]      Linking $@"
-       $(Q) mkdir -p `dirname $@`
-       $(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,--output-def=$(LIBDIR)/$(CONFIG)/gpr$(SHARED_VERSION_CORE).def -Wl,--out-implib=$(LIBDIR)/$(CONFIG)/libgpr$(SHARED_VERSION_CORE)-dll.a -o $(LIBDIR)/$(CONFIG)/gpr$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBGPR_OBJS) $(ZLIB_MERGE_LIBS) $(CARES_MERGE_LIBS) $(ADDRESS_SORTING_MERGE_LIBS) $(RE2_MERGE_LIBS) $(UPB_MERGE_LIBS) $(GRPC_ABSEIL_MERGE_LIBS) $(LDLIBS)
-else
-$(LIBDIR)/$(CONFIG)/libgpr$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE): $(LIBGPR_OBJS)  $(ZLIB_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(RE2_DEP) $(UPB_DEP) $(GRPC_ABSEIL_DEP)
-       $(E) "[LD]      Linking $@"
-       $(Q) mkdir -p `dirname $@`
-ifeq ($(SYSTEM),Darwin)
-       $(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -install_name $(SHARED_PREFIX)gpr$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) -dynamiclib -o $(LIBDIR)/$(CONFIG)/libgpr$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBGPR_OBJS) $(ZLIB_MERGE_LIBS) $(CARES_MERGE_LIBS) $(ADDRESS_SORTING_MERGE_LIBS) $(RE2_MERGE_LIBS) $(UPB_MERGE_LIBS) $(GRPC_ABSEIL_MERGE_LIBS) $(LDLIBS)
-else
-       $(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,-soname,libgpr.so.14 -o $(LIBDIR)/$(CONFIG)/libgpr$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBGPR_OBJS) $(ZLIB_MERGE_LIBS) $(CARES_MERGE_LIBS) $(ADDRESS_SORTING_MERGE_LIBS) $(RE2_MERGE_LIBS) $(UPB_MERGE_LIBS) $(GRPC_ABSEIL_MERGE_LIBS) $(LDLIBS)
-       $(Q) ln -sf $(SHARED_PREFIX)gpr$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBDIR)/$(CONFIG)/libgpr$(SHARED_VERSION_CORE).so.14
-       $(Q) ln -sf $(SHARED_PREFIX)gpr$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBDIR)/$(CONFIG)/libgpr$(SHARED_VERSION_CORE).so
-endif
-endif
-
-ifneq ($(NO_DEPS),true)
--include $(LIBGPR_OBJS:.o=.dep)
-endif
-# end of build recipe for library "gpr"
-
-
-# start of build recipe for library "grpc" (generated by makelib(lib) template function)
-LIBGRPC_SRC = \
-    src/core/ext/filters/census/grpc_context.cc \
-    src/core/ext/filters/client_channel/backend_metric.cc \
-    src/core/ext/filters/client_channel/backup_poller.cc \
-    src/core/ext/filters/client_channel/channel_connectivity.cc \
-    src/core/ext/filters/client_channel/client_channel.cc \
-    src/core/ext/filters/client_channel/client_channel_channelz.cc \
-    src/core/ext/filters/client_channel/client_channel_factory.cc \
-    src/core/ext/filters/client_channel/client_channel_plugin.cc \
-    src/core/ext/filters/client_channel/config_selector.cc \
-    src/core/ext/filters/client_channel/global_subchannel_pool.cc \
-    src/core/ext/filters/client_channel/health/health_check_client.cc \
-    src/core/ext/filters/client_channel/http_connect_handshaker.cc \
-    src/core/ext/filters/client_channel/http_proxy.cc \
-    src/core/ext/filters/client_channel/lb_policy.cc \
-    src/core/ext/filters/client_channel/lb_policy/address_filtering.cc \
-    src/core/ext/filters/client_channel/lb_policy/child_policy_handler.cc \
-    src/core/ext/filters/client_channel/lb_policy/grpclb/client_load_reporting_filter.cc \
-    src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc \
-    src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_balancer_addresses.cc \
-    src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel_secure.cc \
-    src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.cc \
-    src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.cc \
-    src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc \
-    src/core/ext/filters/client_channel/lb_policy/priority/priority.cc \
-    src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc \
-    src/core/ext/filters/client_channel/lb_policy/weighted_target/weighted_target.cc \
-    src/core/ext/filters/client_channel/lb_policy/xds/cds.cc \
-    src/core/ext/filters/client_channel/lb_policy/xds/eds.cc \
-    src/core/ext/filters/client_channel/lb_policy/xds/xds_cluster_impl.cc \
-    src/core/ext/filters/client_channel/lb_policy/xds/xds_cluster_manager.cc \
-    src/core/ext/filters/client_channel/lb_policy_registry.cc \
-    src/core/ext/filters/client_channel/local_subchannel_pool.cc \
-    src/core/ext/filters/client_channel/proxy_mapper_registry.cc \
-    src/core/ext/filters/client_channel/resolver.cc \
-    src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc \
-    src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.cc \
-    src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_libuv.cc \
-    src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_posix.cc \
-    src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_windows.cc \
-    src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc \
-    src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_fallback.cc \
-    src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv.cc \
-    src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_posix.cc \
-    src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc \
-    src/core/ext/filters/client_channel/resolver/dns/dns_resolver_selection.cc \
-    src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc \
-    src/core/ext/filters/client_channel/resolver/fake/fake_resolver.cc \
-    src/core/ext/filters/client_channel/resolver/sockaddr/sockaddr_resolver.cc \
-    src/core/ext/filters/client_channel/resolver/xds/xds_resolver.cc \
-    src/core/ext/filters/client_channel/resolver_registry.cc \
-    src/core/ext/filters/client_channel/resolver_result_parsing.cc \
-    src/core/ext/filters/client_channel/resolving_lb_policy.cc \
-    src/core/ext/filters/client_channel/retry_throttle.cc \
-    src/core/ext/filters/client_channel/server_address.cc \
-    src/core/ext/filters/client_channel/service_config.cc \
-    src/core/ext/filters/client_channel/service_config_channel_arg_filter.cc \
-    src/core/ext/filters/client_channel/service_config_parser.cc \
-    src/core/ext/filters/client_channel/subchannel.cc \
-    src/core/ext/filters/client_channel/subchannel_pool_interface.cc \
-    src/core/ext/filters/client_idle/client_idle_filter.cc \
-    src/core/ext/filters/deadline/deadline_filter.cc \
-    src/core/ext/filters/http/client/http_client_filter.cc \
-    src/core/ext/filters/http/client_authority_filter.cc \
-    src/core/ext/filters/http/http_filters_plugin.cc \
-    src/core/ext/filters/http/message_compress/message_compress_filter.cc \
-    src/core/ext/filters/http/message_compress/message_decompress_filter.cc \
-    src/core/ext/filters/http/server/http_server_filter.cc \
-    src/core/ext/filters/max_age/max_age_filter.cc \
-    src/core/ext/filters/message_size/message_size_filter.cc \
-    src/core/ext/filters/workarounds/workaround_cronet_compression_filter.cc \
-    src/core/ext/filters/workarounds/workaround_utils.cc \
-    src/core/ext/transport/chttp2/alpn/alpn.cc \
-    src/core/ext/transport/chttp2/client/authority.cc \
-    src/core/ext/transport/chttp2/client/chttp2_connector.cc \
-    src/core/ext/transport/chttp2/client/insecure/channel_create.cc \
-    src/core/ext/transport/chttp2/client/insecure/channel_create_posix.cc \
-    src/core/ext/transport/chttp2/client/secure/secure_channel_create.cc \
-    src/core/ext/transport/chttp2/server/chttp2_server.cc \
-    src/core/ext/transport/chttp2/server/insecure/server_chttp2.cc \
-    src/core/ext/transport/chttp2/server/insecure/server_chttp2_posix.cc \
-    src/core/ext/transport/chttp2/server/secure/server_secure_chttp2.cc \
-    src/core/ext/transport/chttp2/transport/bin_decoder.cc \
-    src/core/ext/transport/chttp2/transport/bin_encoder.cc \
-    src/core/ext/transport/chttp2/transport/chttp2_plugin.cc \
-    src/core/ext/transport/chttp2/transport/chttp2_transport.cc \
-    src/core/ext/transport/chttp2/transport/context_list.cc \
-    src/core/ext/transport/chttp2/transport/flow_control.cc \
-    src/core/ext/transport/chttp2/transport/frame_data.cc \
-    src/core/ext/transport/chttp2/transport/frame_goaway.cc \
-    src/core/ext/transport/chttp2/transport/frame_ping.cc \
-    src/core/ext/transport/chttp2/transport/frame_rst_stream.cc \
-    src/core/ext/transport/chttp2/transport/frame_settings.cc \
-    src/core/ext/transport/chttp2/transport/frame_window_update.cc \
-    src/core/ext/transport/chttp2/transport/hpack_encoder.cc \
-    src/core/ext/transport/chttp2/transport/hpack_parser.cc \
-    src/core/ext/transport/chttp2/transport/hpack_table.cc \
-    src/core/ext/transport/chttp2/transport/http2_settings.cc \
-    src/core/ext/transport/chttp2/transport/huffsyms.cc \
-    src/core/ext/transport/chttp2/transport/incoming_metadata.cc \
-    src/core/ext/transport/chttp2/transport/parsing.cc \
-    src/core/ext/transport/chttp2/transport/stream_lists.cc \
-    src/core/ext/transport/chttp2/transport/stream_map.cc \
-    src/core/ext/transport/chttp2/transport/varint.cc \
-    src/core/ext/transport/chttp2/transport/writing.cc \
-    src/core/ext/transport/inproc/inproc_plugin.cc \
-    src/core/ext/transport/inproc/inproc_transport.cc \
-    src/core/ext/upb-generated/envoy/annotations/deprecation.upb.c \
-    src/core/ext/upb-generated/envoy/annotations/resource.upb.c \
-    src/core/ext/upb-generated/envoy/config/accesslog/v3/accesslog.upb.c \
-    src/core/ext/upb-generated/envoy/config/cluster/v3/circuit_breaker.upb.c \
-    src/core/ext/upb-generated/envoy/config/cluster/v3/cluster.upb.c \
-    src/core/ext/upb-generated/envoy/config/cluster/v3/filter.upb.c \
-    src/core/ext/upb-generated/envoy/config/cluster/v3/outlier_detection.upb.c \
-    src/core/ext/upb-generated/envoy/config/core/v3/address.upb.c \
-    src/core/ext/upb-generated/envoy/config/core/v3/backoff.upb.c \
-    src/core/ext/upb-generated/envoy/config/core/v3/base.upb.c \
-    src/core/ext/upb-generated/envoy/config/core/v3/config_source.upb.c \
-    src/core/ext/upb-generated/envoy/config/core/v3/event_service_config.upb.c \
-    src/core/ext/upb-generated/envoy/config/core/v3/extension.upb.c \
-    src/core/ext/upb-generated/envoy/config/core/v3/grpc_service.upb.c \
-    src/core/ext/upb-generated/envoy/config/core/v3/health_check.upb.c \
-    src/core/ext/upb-generated/envoy/config/core/v3/http_uri.upb.c \
-    src/core/ext/upb-generated/envoy/config/core/v3/protocol.upb.c \
-    src/core/ext/upb-generated/envoy/config/core/v3/proxy_protocol.upb.c \
-    src/core/ext/upb-generated/envoy/config/core/v3/socket_option.upb.c \
-    src/core/ext/upb-generated/envoy/config/core/v3/substitution_format_string.upb.c \
-    src/core/ext/upb-generated/envoy/config/endpoint/v3/endpoint.upb.c \
-    src/core/ext/upb-generated/envoy/config/endpoint/v3/endpoint_components.upb.c \
-    src/core/ext/upb-generated/envoy/config/endpoint/v3/load_report.upb.c \
-    src/core/ext/upb-generated/envoy/config/listener/v3/api_listener.upb.c \
-    src/core/ext/upb-generated/envoy/config/listener/v3/listener.upb.c \
-    src/core/ext/upb-generated/envoy/config/listener/v3/listener_components.upb.c \
-    src/core/ext/upb-generated/envoy/config/listener/v3/udp_listener_config.upb.c \
-    src/core/ext/upb-generated/envoy/config/rbac/v3/rbac.upb.c \
-    src/core/ext/upb-generated/envoy/config/route/v3/route.upb.c \
-    src/core/ext/upb-generated/envoy/config/route/v3/route_components.upb.c \
-    src/core/ext/upb-generated/envoy/config/route/v3/scoped_route.upb.c \
-    src/core/ext/upb-generated/envoy/config/trace/v3/http_tracer.upb.c \
-    src/core/ext/upb-generated/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.upb.c \
-    src/core/ext/upb-generated/envoy/extensions/transport_sockets/tls/v3/cert.upb.c \
-    src/core/ext/upb-generated/envoy/extensions/transport_sockets/tls/v3/common.upb.c \
-    src/core/ext/upb-generated/envoy/extensions/transport_sockets/tls/v3/secret.upb.c \
-    src/core/ext/upb-generated/envoy/extensions/transport_sockets/tls/v3/tls.upb.c \
-    src/core/ext/upb-generated/envoy/service/cluster/v3/cds.upb.c \
-    src/core/ext/upb-generated/envoy/service/discovery/v3/ads.upb.c \
-    src/core/ext/upb-generated/envoy/service/discovery/v3/discovery.upb.c \
-    src/core/ext/upb-generated/envoy/service/endpoint/v3/eds.upb.c \
-    src/core/ext/upb-generated/envoy/service/listener/v3/lds.upb.c \
-    src/core/ext/upb-generated/envoy/service/load_stats/v3/lrs.upb.c \
-    src/core/ext/upb-generated/envoy/service/route/v3/rds.upb.c \
-    src/core/ext/upb-generated/envoy/service/route/v3/srds.upb.c \
-    src/core/ext/upb-generated/envoy/type/matcher/v3/metadata.upb.c \
-    src/core/ext/upb-generated/envoy/type/matcher/v3/number.upb.c \
-    src/core/ext/upb-generated/envoy/type/matcher/v3/path.upb.c \
-    src/core/ext/upb-generated/envoy/type/matcher/v3/regex.upb.c \
-    src/core/ext/upb-generated/envoy/type/matcher/v3/string.upb.c \
-    src/core/ext/upb-generated/envoy/type/matcher/v3/value.upb.c \
-    src/core/ext/upb-generated/envoy/type/metadata/v3/metadata.upb.c \
-    src/core/ext/upb-generated/envoy/type/tracing/v3/custom_tag.upb.c \
-    src/core/ext/upb-generated/envoy/type/v3/http.upb.c \
-    src/core/ext/upb-generated/envoy/type/v3/percent.upb.c \
-    src/core/ext/upb-generated/envoy/type/v3/range.upb.c \
-    src/core/ext/upb-generated/envoy/type/v3/semantic_version.upb.c \
-    src/core/ext/upb-generated/google/api/annotations.upb.c \
-    src/core/ext/upb-generated/google/api/expr/v1alpha1/checked.upb.c \
-    src/core/ext/upb-generated/google/api/expr/v1alpha1/syntax.upb.c \
-    src/core/ext/upb-generated/google/api/http.upb.c \
-    src/core/ext/upb-generated/google/protobuf/any.upb.c \
-    src/core/ext/upb-generated/google/protobuf/duration.upb.c \
-    src/core/ext/upb-generated/google/protobuf/empty.upb.c \
-    src/core/ext/upb-generated/google/protobuf/struct.upb.c \
-    src/core/ext/upb-generated/google/protobuf/timestamp.upb.c \
-    src/core/ext/upb-generated/google/protobuf/wrappers.upb.c \
-    src/core/ext/upb-generated/google/rpc/status.upb.c \
-    src/core/ext/upb-generated/src/proto/grpc/gcp/altscontext.upb.c \
-    src/core/ext/upb-generated/src/proto/grpc/gcp/handshaker.upb.c \
-    src/core/ext/upb-generated/src/proto/grpc/gcp/transport_security_common.upb.c \
-    src/core/ext/upb-generated/src/proto/grpc/health/v1/health.upb.c \
-    src/core/ext/upb-generated/src/proto/grpc/lb/v1/load_balancer.upb.c \
-    src/core/ext/upb-generated/udpa/annotations/migrate.upb.c \
-    src/core/ext/upb-generated/udpa/annotations/security.upb.c \
-    src/core/ext/upb-generated/udpa/annotations/sensitive.upb.c \
-    src/core/ext/upb-generated/udpa/annotations/status.upb.c \
-    src/core/ext/upb-generated/udpa/annotations/versioning.upb.c \
-    src/core/ext/upb-generated/udpa/core/v1/authority.upb.c \
-    src/core/ext/upb-generated/udpa/core/v1/collection_entry.upb.c \
-    src/core/ext/upb-generated/udpa/core/v1/context_params.upb.c \
-    src/core/ext/upb-generated/udpa/core/v1/resource.upb.c \
-    src/core/ext/upb-generated/udpa/core/v1/resource_locator.upb.c \
-    src/core/ext/upb-generated/udpa/core/v1/resource_name.upb.c \
-    src/core/ext/upb-generated/udpa/data/orca/v1/orca_load_report.upb.c \
-    src/core/ext/upb-generated/validate/validate.upb.c \
-    src/core/ext/upbdefs-generated/envoy/annotations/deprecation.upbdefs.c \
-    src/core/ext/upbdefs-generated/envoy/annotations/resource.upbdefs.c \
-    src/core/ext/upbdefs-generated/envoy/config/accesslog/v3/accesslog.upbdefs.c \
-    src/core/ext/upbdefs-generated/envoy/config/cluster/v3/circuit_breaker.upbdefs.c \
-    src/core/ext/upbdefs-generated/envoy/config/cluster/v3/cluster.upbdefs.c \
-    src/core/ext/upbdefs-generated/envoy/config/cluster/v3/filter.upbdefs.c \
-    src/core/ext/upbdefs-generated/envoy/config/cluster/v3/outlier_detection.upbdefs.c \
-    src/core/ext/upbdefs-generated/envoy/config/core/v3/address.upbdefs.c \
-    src/core/ext/upbdefs-generated/envoy/config/core/v3/backoff.upbdefs.c \
-    src/core/ext/upbdefs-generated/envoy/config/core/v3/base.upbdefs.c \
-    src/core/ext/upbdefs-generated/envoy/config/core/v3/config_source.upbdefs.c \
-    src/core/ext/upbdefs-generated/envoy/config/core/v3/event_service_config.upbdefs.c \
-    src/core/ext/upbdefs-generated/envoy/config/core/v3/extension.upbdefs.c \
-    src/core/ext/upbdefs-generated/envoy/config/core/v3/grpc_service.upbdefs.c \
-    src/core/ext/upbdefs-generated/envoy/config/core/v3/health_check.upbdefs.c \
-    src/core/ext/upbdefs-generated/envoy/config/core/v3/http_uri.upbdefs.c \
-    src/core/ext/upbdefs-generated/envoy/config/core/v3/protocol.upbdefs.c \
-    src/core/ext/upbdefs-generated/envoy/config/core/v3/proxy_protocol.upbdefs.c \
-    src/core/ext/upbdefs-generated/envoy/config/core/v3/socket_option.upbdefs.c \
-    src/core/ext/upbdefs-generated/envoy/config/core/v3/substitution_format_string.upbdefs.c \
-    src/core/ext/upbdefs-generated/envoy/config/endpoint/v3/endpoint.upbdefs.c \
-    src/core/ext/upbdefs-generated/envoy/config/endpoint/v3/endpoint_components.upbdefs.c \
-    src/core/ext/upbdefs-generated/envoy/config/endpoint/v3/load_report.upbdefs.c \
-    src/core/ext/upbdefs-generated/envoy/config/listener/v3/api_listener.upbdefs.c \
-    src/core/ext/upbdefs-generated/envoy/config/listener/v3/listener.upbdefs.c \
-    src/core/ext/upbdefs-generated/envoy/config/listener/v3/listener_components.upbdefs.c \
-    src/core/ext/upbdefs-generated/envoy/config/listener/v3/udp_listener_config.upbdefs.c \
-    src/core/ext/upbdefs-generated/envoy/config/route/v3/route.upbdefs.c \
-    src/core/ext/upbdefs-generated/envoy/config/route/v3/route_components.upbdefs.c \
-    src/core/ext/upbdefs-generated/envoy/config/route/v3/scoped_route.upbdefs.c \
-    src/core/ext/upbdefs-generated/envoy/config/trace/v3/http_tracer.upbdefs.c \
-    src/core/ext/upbdefs-generated/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.upbdefs.c \
-    src/core/ext/upbdefs-generated/envoy/extensions/transport_sockets/tls/v3/cert.upbdefs.c \
-    src/core/ext/upbdefs-generated/envoy/extensions/transport_sockets/tls/v3/common.upbdefs.c \
-    src/core/ext/upbdefs-generated/envoy/extensions/transport_sockets/tls/v3/secret.upbdefs.c \
-    src/core/ext/upbdefs-generated/envoy/extensions/transport_sockets/tls/v3/tls.upbdefs.c \
-    src/core/ext/upbdefs-generated/envoy/service/cluster/v3/cds.upbdefs.c \
-    src/core/ext/upbdefs-generated/envoy/service/discovery/v3/ads.upbdefs.c \
-    src/core/ext/upbdefs-generated/envoy/service/discovery/v3/discovery.upbdefs.c \
-    src/core/ext/upbdefs-generated/envoy/service/endpoint/v3/eds.upbdefs.c \
-    src/core/ext/upbdefs-generated/envoy/service/listener/v3/lds.upbdefs.c \
-    src/core/ext/upbdefs-generated/envoy/service/load_stats/v3/lrs.upbdefs.c \
-    src/core/ext/upbdefs-generated/envoy/service/route/v3/rds.upbdefs.c \
-    src/core/ext/upbdefs-generated/envoy/service/route/v3/srds.upbdefs.c \
-    src/core/ext/upbdefs-generated/envoy/type/matcher/v3/metadata.upbdefs.c \
-    src/core/ext/upbdefs-generated/envoy/type/matcher/v3/number.upbdefs.c \
-    src/core/ext/upbdefs-generated/envoy/type/matcher/v3/path.upbdefs.c \
-    src/core/ext/upbdefs-generated/envoy/type/matcher/v3/regex.upbdefs.c \
-    src/core/ext/upbdefs-generated/envoy/type/matcher/v3/string.upbdefs.c \
-    src/core/ext/upbdefs-generated/envoy/type/matcher/v3/value.upbdefs.c \
-    src/core/ext/upbdefs-generated/envoy/type/metadata/v3/metadata.upbdefs.c \
-    src/core/ext/upbdefs-generated/envoy/type/tracing/v3/custom_tag.upbdefs.c \
-    src/core/ext/upbdefs-generated/envoy/type/v3/http.upbdefs.c \
-    src/core/ext/upbdefs-generated/envoy/type/v3/percent.upbdefs.c \
-    src/core/ext/upbdefs-generated/envoy/type/v3/range.upbdefs.c \
-    src/core/ext/upbdefs-generated/envoy/type/v3/semantic_version.upbdefs.c \
-    src/core/ext/upbdefs-generated/google/api/annotations.upbdefs.c \
-    src/core/ext/upbdefs-generated/google/api/http.upbdefs.c \
-    src/core/ext/upbdefs-generated/google/protobuf/any.upbdefs.c \
-    src/core/ext/upbdefs-generated/google/protobuf/descriptor.upbdefs.c \
-    src/core/ext/upbdefs-generated/google/protobuf/duration.upbdefs.c \
-    src/core/ext/upbdefs-generated/google/protobuf/empty.upbdefs.c \
-    src/core/ext/upbdefs-generated/google/protobuf/struct.upbdefs.c \
-    src/core/ext/upbdefs-generated/google/protobuf/timestamp.upbdefs.c \
-    src/core/ext/upbdefs-generated/google/protobuf/wrappers.upbdefs.c \
-    src/core/ext/upbdefs-generated/google/rpc/status.upbdefs.c \
-    src/core/ext/upbdefs-generated/udpa/annotations/migrate.upbdefs.c \
-    src/core/ext/upbdefs-generated/udpa/annotations/security.upbdefs.c \
-    src/core/ext/upbdefs-generated/udpa/annotations/sensitive.upbdefs.c \
-    src/core/ext/upbdefs-generated/udpa/annotations/status.upbdefs.c \
-    src/core/ext/upbdefs-generated/udpa/annotations/versioning.upbdefs.c \
-    src/core/ext/upbdefs-generated/udpa/core/v1/authority.upbdefs.c \
-    src/core/ext/upbdefs-generated/udpa/core/v1/collection_entry.upbdefs.c \
-    src/core/ext/upbdefs-generated/udpa/core/v1/context_params.upbdefs.c \
-    src/core/ext/upbdefs-generated/udpa/core/v1/resource.upbdefs.c \
-    src/core/ext/upbdefs-generated/udpa/core/v1/resource_locator.upbdefs.c \
-    src/core/ext/upbdefs-generated/udpa/core/v1/resource_name.upbdefs.c \
-    src/core/ext/upbdefs-generated/validate/validate.upbdefs.c \
-    src/core/ext/xds/certificate_provider_registry.cc \
-    src/core/ext/xds/certificate_provider_store.cc \
-    src/core/ext/xds/file_watcher_certificate_provider_factory.cc \
-    src/core/ext/xds/google_mesh_ca_certificate_provider_factory.cc \
-    src/core/ext/xds/xds_api.cc \
-    src/core/ext/xds/xds_bootstrap.cc \
-    src/core/ext/xds/xds_certificate_provider.cc \
-    src/core/ext/xds/xds_client.cc \
-    src/core/ext/xds/xds_client_stats.cc \
-    src/core/lib/avl/avl.cc \
-    src/core/lib/backoff/backoff.cc \
-    src/core/lib/channel/channel_args.cc \
-    src/core/lib/channel/channel_stack.cc \
-    src/core/lib/channel/channel_stack_builder.cc \
-    src/core/lib/channel/channel_trace.cc \
-    src/core/lib/channel/channelz.cc \
-    src/core/lib/channel/channelz_registry.cc \
-    src/core/lib/channel/connected_channel.cc \
-    src/core/lib/channel/handshaker.cc \
-    src/core/lib/channel/handshaker_registry.cc \
-    src/core/lib/channel/status_util.cc \
-    src/core/lib/compression/compression.cc \
-    src/core/lib/compression/compression_args.cc \
-    src/core/lib/compression/compression_internal.cc \
-    src/core/lib/compression/message_compress.cc \
-    src/core/lib/compression/stream_compression.cc \
-    src/core/lib/compression/stream_compression_gzip.cc \
-    src/core/lib/compression/stream_compression_identity.cc \
-    src/core/lib/debug/stats.cc \
-    src/core/lib/debug/stats_data.cc \
-    src/core/lib/debug/trace.cc \
-    src/core/lib/http/format_request.cc \
-    src/core/lib/http/httpcli.cc \
-    src/core/lib/http/httpcli_security_connector.cc \
-    src/core/lib/http/parser.cc \
-    src/core/lib/iomgr/buffer_list.cc \
-    src/core/lib/iomgr/call_combiner.cc \
-    src/core/lib/iomgr/cfstream_handle.cc \
-    src/core/lib/iomgr/combiner.cc \
-    src/core/lib/iomgr/dualstack_socket_posix.cc \
-    src/core/lib/iomgr/endpoint.cc \
-    src/core/lib/iomgr/endpoint_cfstream.cc \
-    src/core/lib/iomgr/endpoint_pair_posix.cc \
-    src/core/lib/iomgr/endpoint_pair_uv.cc \
-    src/core/lib/iomgr/endpoint_pair_windows.cc \
-    src/core/lib/iomgr/error.cc \
-    src/core/lib/iomgr/error_cfstream.cc \
-    src/core/lib/iomgr/ev_apple.cc \
-    src/core/lib/iomgr/ev_epoll1_linux.cc \
-    src/core/lib/iomgr/ev_epollex_linux.cc \
-    src/core/lib/iomgr/ev_poll_posix.cc \
-    src/core/lib/iomgr/ev_posix.cc \
-    src/core/lib/iomgr/ev_windows.cc \
-    src/core/lib/iomgr/exec_ctx.cc \
-    src/core/lib/iomgr/executor.cc \
-    src/core/lib/iomgr/executor/mpmcqueue.cc \
-    src/core/lib/iomgr/executor/threadpool.cc \
-    src/core/lib/iomgr/fork_posix.cc \
-    src/core/lib/iomgr/fork_windows.cc \
-    src/core/lib/iomgr/gethostname_fallback.cc \
-    src/core/lib/iomgr/gethostname_host_name_max.cc \
-    src/core/lib/iomgr/gethostname_sysconf.cc \
-    src/core/lib/iomgr/grpc_if_nametoindex_posix.cc \
-    src/core/lib/iomgr/grpc_if_nametoindex_unsupported.cc \
-    src/core/lib/iomgr/internal_errqueue.cc \
-    src/core/lib/iomgr/iocp_windows.cc \
-    src/core/lib/iomgr/iomgr.cc \
-    src/core/lib/iomgr/iomgr_custom.cc \
-    src/core/lib/iomgr/iomgr_internal.cc \
-    src/core/lib/iomgr/iomgr_posix.cc \
-    src/core/lib/iomgr/iomgr_posix_cfstream.cc \
-    src/core/lib/iomgr/iomgr_uv.cc \
-    src/core/lib/iomgr/iomgr_windows.cc \
-    src/core/lib/iomgr/is_epollexclusive_available.cc \
-    src/core/lib/iomgr/load_file.cc \
-    src/core/lib/iomgr/lockfree_event.cc \
-    src/core/lib/iomgr/parse_address.cc \
-    src/core/lib/iomgr/poller/eventmanager_libuv.cc \
-    src/core/lib/iomgr/polling_entity.cc \
-    src/core/lib/iomgr/pollset.cc \
-    src/core/lib/iomgr/pollset_custom.cc \
-    src/core/lib/iomgr/pollset_set.cc \
-    src/core/lib/iomgr/pollset_set_custom.cc \
-    src/core/lib/iomgr/pollset_set_windows.cc \
-    src/core/lib/iomgr/pollset_uv.cc \
-    src/core/lib/iomgr/pollset_windows.cc \
-    src/core/lib/iomgr/resolve_address.cc \
-    src/core/lib/iomgr/resolve_address_custom.cc \
-    src/core/lib/iomgr/resolve_address_posix.cc \
-    src/core/lib/iomgr/resolve_address_windows.cc \
-    src/core/lib/iomgr/resource_quota.cc \
-    src/core/lib/iomgr/sockaddr_utils.cc \
-    src/core/lib/iomgr/socket_factory_posix.cc \
-    src/core/lib/iomgr/socket_mutator.cc \
-    src/core/lib/iomgr/socket_utils_common_posix.cc \
-    src/core/lib/iomgr/socket_utils_linux.cc \
-    src/core/lib/iomgr/socket_utils_posix.cc \
-    src/core/lib/iomgr/socket_utils_uv.cc \
-    src/core/lib/iomgr/socket_utils_windows.cc \
-    src/core/lib/iomgr/socket_windows.cc \
-    src/core/lib/iomgr/tcp_client.cc \
-    src/core/lib/iomgr/tcp_client_cfstream.cc \
-    src/core/lib/iomgr/tcp_client_custom.cc \
-    src/core/lib/iomgr/tcp_client_posix.cc \
-    src/core/lib/iomgr/tcp_client_windows.cc \
-    src/core/lib/iomgr/tcp_custom.cc \
-    src/core/lib/iomgr/tcp_posix.cc \
-    src/core/lib/iomgr/tcp_server.cc \
-    src/core/lib/iomgr/tcp_server_custom.cc \
-    src/core/lib/iomgr/tcp_server_posix.cc \
-    src/core/lib/iomgr/tcp_server_utils_posix_common.cc \
-    src/core/lib/iomgr/tcp_server_utils_posix_ifaddrs.cc \
-    src/core/lib/iomgr/tcp_server_utils_posix_noifaddrs.cc \
-    src/core/lib/iomgr/tcp_server_windows.cc \
-    src/core/lib/iomgr/tcp_uv.cc \
-    src/core/lib/iomgr/tcp_windows.cc \
-    src/core/lib/iomgr/time_averaged_stats.cc \
-    src/core/lib/iomgr/timer.cc \
-    src/core/lib/iomgr/timer_custom.cc \
-    src/core/lib/iomgr/timer_generic.cc \
-    src/core/lib/iomgr/timer_heap.cc \
-    src/core/lib/iomgr/timer_manager.cc \
-    src/core/lib/iomgr/timer_uv.cc \
-    src/core/lib/iomgr/udp_server.cc \
-    src/core/lib/iomgr/unix_sockets_posix.cc \
-    src/core/lib/iomgr/unix_sockets_posix_noop.cc \
-    src/core/lib/iomgr/wakeup_fd_eventfd.cc \
-    src/core/lib/iomgr/wakeup_fd_nospecial.cc \
-    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_reader.cc \
-    src/core/lib/json/json_util.cc \
-    src/core/lib/json/json_writer.cc \
-    src/core/lib/security/authorization/authorization_engine.cc \
-    src/core/lib/security/authorization/evaluate_args.cc \
-    src/core/lib/security/context/security_context.cc \
-    src/core/lib/security/credentials/alts/alts_credentials.cc \
-    src/core/lib/security/credentials/alts/check_gcp_environment.cc \
-    src/core/lib/security/credentials/alts/check_gcp_environment_linux.cc \
-    src/core/lib/security/credentials/alts/check_gcp_environment_no_op.cc \
-    src/core/lib/security/credentials/alts/check_gcp_environment_windows.cc \
-    src/core/lib/security/credentials/alts/grpc_alts_credentials_client_options.cc \
-    src/core/lib/security/credentials/alts/grpc_alts_credentials_options.cc \
-    src/core/lib/security/credentials/alts/grpc_alts_credentials_server_options.cc \
-    src/core/lib/security/credentials/composite/composite_credentials.cc \
-    src/core/lib/security/credentials/credentials.cc \
-    src/core/lib/security/credentials/credentials_metadata.cc \
-    src/core/lib/security/credentials/external/aws_request_signer.cc \
-    src/core/lib/security/credentials/external/external_account_credentials.cc \
-    src/core/lib/security/credentials/external/file_external_account_credentials.cc \
-    src/core/lib/security/credentials/external/url_external_account_credentials.cc \
-    src/core/lib/security/credentials/fake/fake_credentials.cc \
-    src/core/lib/security/credentials/google_default/credentials_generic.cc \
-    src/core/lib/security/credentials/google_default/google_default_credentials.cc \
-    src/core/lib/security/credentials/iam/iam_credentials.cc \
-    src/core/lib/security/credentials/insecure/insecure_credentials.cc \
-    src/core/lib/security/credentials/jwt/json_token.cc \
-    src/core/lib/security/credentials/jwt/jwt_credentials.cc \
-    src/core/lib/security/credentials/jwt/jwt_verifier.cc \
-    src/core/lib/security/credentials/local/local_credentials.cc \
-    src/core/lib/security/credentials/oauth2/oauth2_credentials.cc \
-    src/core/lib/security/credentials/plugin/plugin_credentials.cc \
-    src/core/lib/security/credentials/ssl/ssl_credentials.cc \
-    src/core/lib/security/credentials/tls/grpc_tls_certificate_distributor.cc \
-    src/core/lib/security/credentials/tls/grpc_tls_certificate_provider.cc \
-    src/core/lib/security/credentials/tls/grpc_tls_credentials_options.cc \
-    src/core/lib/security/credentials/tls/tls_credentials.cc \
-    src/core/lib/security/credentials/xds/xds_credentials.cc \
-    src/core/lib/security/security_connector/alts/alts_security_connector.cc \
-    src/core/lib/security/security_connector/fake/fake_security_connector.cc \
-    src/core/lib/security/security_connector/insecure/insecure_security_connector.cc \
-    src/core/lib/security/security_connector/load_system_roots_fallback.cc \
-    src/core/lib/security/security_connector/load_system_roots_linux.cc \
-    src/core/lib/security/security_connector/local/local_security_connector.cc \
-    src/core/lib/security/security_connector/security_connector.cc \
-    src/core/lib/security/security_connector/ssl/ssl_security_connector.cc \
-    src/core/lib/security/security_connector/ssl_utils.cc \
-    src/core/lib/security/security_connector/ssl_utils_config.cc \
-    src/core/lib/security/security_connector/tls/tls_security_connector.cc \
-    src/core/lib/security/transport/client_auth_filter.cc \
-    src/core/lib/security/transport/secure_endpoint.cc \
-    src/core/lib/security/transport/security_handshaker.cc \
-    src/core/lib/security/transport/server_auth_filter.cc \
-    src/core/lib/security/transport/tsi_error.cc \
-    src/core/lib/security/util/json_util.cc \
-    src/core/lib/slice/b64.cc \
-    src/core/lib/slice/percent_encoding.cc \
-    src/core/lib/slice/slice.cc \
-    src/core/lib/slice/slice_buffer.cc \
-    src/core/lib/slice/slice_intern.cc \
-    src/core/lib/slice/slice_string_helpers.cc \
-    src/core/lib/surface/api_trace.cc \
-    src/core/lib/surface/byte_buffer.cc \
-    src/core/lib/surface/byte_buffer_reader.cc \
-    src/core/lib/surface/call.cc \
-    src/core/lib/surface/call_details.cc \
-    src/core/lib/surface/call_log_batch.cc \
-    src/core/lib/surface/channel.cc \
-    src/core/lib/surface/channel_init.cc \
-    src/core/lib/surface/channel_ping.cc \
-    src/core/lib/surface/channel_stack_type.cc \
-    src/core/lib/surface/completion_queue.cc \
-    src/core/lib/surface/completion_queue_factory.cc \
-    src/core/lib/surface/event_string.cc \
-    src/core/lib/surface/init.cc \
-    src/core/lib/surface/init_secure.cc \
-    src/core/lib/surface/lame_client.cc \
-    src/core/lib/surface/metadata_array.cc \
-    src/core/lib/surface/server.cc \
-    src/core/lib/surface/validate_metadata.cc \
-    src/core/lib/surface/version.cc \
-    src/core/lib/transport/authority_override.cc \
-    src/core/lib/transport/bdp_estimator.cc \
-    src/core/lib/transport/byte_stream.cc \
-    src/core/lib/transport/connectivity_state.cc \
-    src/core/lib/transport/error_utils.cc \
-    src/core/lib/transport/metadata.cc \
-    src/core/lib/transport/metadata_batch.cc \
-    src/core/lib/transport/pid_controller.cc \
-    src/core/lib/transport/static_metadata.cc \
-    src/core/lib/transport/status_conversion.cc \
-    src/core/lib/transport/status_metadata.cc \
-    src/core/lib/transport/timeout_encoding.cc \
-    src/core/lib/transport/transport.cc \
-    src/core/lib/transport/transport_op_string.cc \
-    src/core/lib/uri/uri_parser.cc \
-    src/core/plugin_registry/grpc_plugin_registry.cc \
-    src/core/tsi/alts/crypt/aes_gcm.cc \
-    src/core/tsi/alts/crypt/gsec.cc \
-    src/core/tsi/alts/frame_protector/alts_counter.cc \
-    src/core/tsi/alts/frame_protector/alts_crypter.cc \
-    src/core/tsi/alts/frame_protector/alts_frame_protector.cc \
-    src/core/tsi/alts/frame_protector/alts_record_protocol_crypter_common.cc \
-    src/core/tsi/alts/frame_protector/alts_seal_privacy_integrity_crypter.cc \
-    src/core/tsi/alts/frame_protector/alts_unseal_privacy_integrity_crypter.cc \
-    src/core/tsi/alts/frame_protector/frame_handler.cc \
-    src/core/tsi/alts/handshaker/alts_handshaker_client.cc \
-    src/core/tsi/alts/handshaker/alts_shared_resource.cc \
-    src/core/tsi/alts/handshaker/alts_tsi_handshaker.cc \
-    src/core/tsi/alts/handshaker/alts_tsi_utils.cc \
-    src/core/tsi/alts/handshaker/transport_security_common_api.cc \
-    src/core/tsi/alts/zero_copy_frame_protector/alts_grpc_integrity_only_record_protocol.cc \
-    src/core/tsi/alts/zero_copy_frame_protector/alts_grpc_privacy_integrity_record_protocol.cc \
-    src/core/tsi/alts/zero_copy_frame_protector/alts_grpc_record_protocol_common.cc \
-    src/core/tsi/alts/zero_copy_frame_protector/alts_iovec_record_protocol.cc \
-    src/core/tsi/alts/zero_copy_frame_protector/alts_zero_copy_grpc_protector.cc \
-    src/core/tsi/fake_transport_security.cc \
-    src/core/tsi/local_transport_security.cc \
-    src/core/tsi/ssl/session_cache/ssl_session_boringssl.cc \
-    src/core/tsi/ssl/session_cache/ssl_session_cache.cc \
-    src/core/tsi/ssl/session_cache/ssl_session_openssl.cc \
-    src/core/tsi/ssl_transport_security.cc \
-    src/core/tsi/transport_security.cc \
-    src/core/tsi/transport_security_grpc.cc \
-
-PUBLIC_HEADERS_C += \
-    include/grpc/byte_buffer.h \
-    include/grpc/byte_buffer_reader.h \
-    include/grpc/census.h \
-    include/grpc/compression.h \
-    include/grpc/fork.h \
-    include/grpc/grpc.h \
-    include/grpc/grpc_posix.h \
-    include/grpc/grpc_security.h \
-    include/grpc/grpc_security_constants.h \
-    include/grpc/load_reporting.h \
-    include/grpc/slice.h \
-    include/grpc/slice_buffer.h \
-    include/grpc/status.h \
-    include/grpc/support/workaround_list.h \
-
-LIBGRPC_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBGRPC_SRC))))
-
-
-ifeq ($(NO_SECURE),true)
-
-# You can't build secure libraries if you don't have OpenSSL.
-
-$(LIBDIR)/$(CONFIG)/libgrpc.a: openssl_dep_error
-
-$(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)grpc$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE): openssl_dep_error
-
-else
-
-
-$(LIBDIR)/$(CONFIG)/libgrpc.a: $(ZLIB_DEP) $(OPENSSL_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(RE2_DEP) $(UPB_DEP) $(GRPC_ABSEIL_DEP)  $(LIBGRPC_OBJS)  $(LIBGPR_OBJS)  $(LIBGRPC_ABSEIL_OBJS)  $(ZLIB_MERGE_OBJS)  $(CARES_MERGE_OBJS)  $(ADDRESS_SORTING_MERGE_OBJS)  $(RE2_MERGE_OBJS)  $(UPB_MERGE_OBJS)  $(OPENSSL_MERGE_OBJS) 
-       $(E) "[AR]      Creating $@"
-       $(Q) mkdir -p `dirname $@`
-       $(Q) rm -f $(LIBDIR)/$(CONFIG)/libgrpc.a
-       $(Q) $(AR) $(ARFLAGS) $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBGRPC_OBJS)  $(LIBGPR_OBJS)  $(LIBGRPC_ABSEIL_OBJS)  $(ZLIB_MERGE_OBJS)  $(CARES_MERGE_OBJS)  $(ADDRESS_SORTING_MERGE_OBJS)  $(RE2_MERGE_OBJS)  $(UPB_MERGE_OBJS)  $(OPENSSL_MERGE_OBJS) 
-ifeq ($(SYSTEM),Darwin)
-       $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libgrpc.a
-endif
-
-
-
-ifeq ($(SYSTEM),MINGW32)
-$(LIBDIR)/$(CONFIG)/grpc$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE): $(LIBGRPC_OBJS)  $(ZLIB_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(RE2_DEP) $(UPB_DEP) $(GRPC_ABSEIL_DEP) $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libaddress_sorting.a $(LIBDIR)/$(CONFIG)/libupb.a $(OPENSSL_DEP)
-       $(E) "[LD]      Linking $@"
-       $(Q) mkdir -p `dirname $@`
-       $(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,--output-def=$(LIBDIR)/$(CONFIG)/grpc$(SHARED_VERSION_CORE).def -Wl,--out-implib=$(LIBDIR)/$(CONFIG)/libgrpc$(SHARED_VERSION_CORE)-dll.a -o $(LIBDIR)/$(CONFIG)/grpc$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBGRPC_OBJS) $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libaddress_sorting.a $(LIBDIR)/$(CONFIG)/libupb.a $(OPENSSL_MERGE_LIBS) $(LDLIBS_SECURE) $(ZLIB_MERGE_LIBS) $(CARES_MERGE_LIBS) $(ADDRESS_SORTING_MERGE_LIBS) $(RE2_MERGE_LIBS) $(UPB_MERGE_LIBS) $(GRPC_ABSEIL_MERGE_LIBS) $(LDLIBS)
-else
-$(LIBDIR)/$(CONFIG)/libgrpc$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE): $(LIBGRPC_OBJS)  $(ZLIB_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(RE2_DEP) $(UPB_DEP) $(GRPC_ABSEIL_DEP) $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libaddress_sorting.a $(LIBDIR)/$(CONFIG)/libupb.a $(OPENSSL_DEP)
-       $(E) "[LD]      Linking $@"
-       $(Q) mkdir -p `dirname $@`
-ifeq ($(SYSTEM),Darwin)
-       $(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -install_name $(SHARED_PREFIX)grpc$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) -dynamiclib -o $(LIBDIR)/$(CONFIG)/libgrpc$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBGRPC_OBJS) $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libaddress_sorting.a $(LIBDIR)/$(CONFIG)/libupb.a $(OPENSSL_MERGE_LIBS) $(LDLIBS_SECURE) $(ZLIB_MERGE_LIBS) $(CARES_MERGE_LIBS) $(ADDRESS_SORTING_MERGE_LIBS) $(RE2_MERGE_LIBS) $(UPB_MERGE_LIBS) $(GRPC_ABSEIL_MERGE_LIBS) $(LDLIBS)
-else
-       $(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,-soname,libgrpc.so.14 -o $(LIBDIR)/$(CONFIG)/libgrpc$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBGRPC_OBJS) $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libaddress_sorting.a $(LIBDIR)/$(CONFIG)/libupb.a $(OPENSSL_MERGE_LIBS) $(LDLIBS_SECURE) $(ZLIB_MERGE_LIBS) $(CARES_MERGE_LIBS) $(ADDRESS_SORTING_MERGE_LIBS) $(RE2_MERGE_LIBS) $(UPB_MERGE_LIBS) $(GRPC_ABSEIL_MERGE_LIBS) $(LDLIBS)
-       $(Q) ln -sf $(SHARED_PREFIX)grpc$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBDIR)/$(CONFIG)/libgrpc$(SHARED_VERSION_CORE).so.14
-       $(Q) ln -sf $(SHARED_PREFIX)grpc$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBDIR)/$(CONFIG)/libgrpc$(SHARED_VERSION_CORE).so
-endif
-endif
-
-endif
-
-ifneq ($(NO_SECURE),true)
-ifneq ($(NO_DEPS),true)
--include $(LIBGRPC_OBJS:.o=.dep)
-endif
-endif
-# end of build recipe for library "grpc"
-
-
-# start of build recipe for library "grpc_csharp_ext" (generated by makelib(lib) template function)
-LIBGRPC_CSHARP_EXT_SRC = \
-    src/csharp/ext/grpc_csharp_ext.c \
-
-PUBLIC_HEADERS_C += \
-
-LIBGRPC_CSHARP_EXT_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBGRPC_CSHARP_EXT_SRC))))
-
-
-ifeq ($(NO_SECURE),true)
-
-# You can't build secure libraries if you don't have OpenSSL.
-
-$(LIBDIR)/$(CONFIG)/libgrpc_csharp_ext.a: openssl_dep_error
-
-$(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)grpc_csharp_ext$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE): openssl_dep_error
-
-else
-
-
-$(LIBDIR)/$(CONFIG)/libgrpc_csharp_ext.a: $(ZLIB_DEP) $(OPENSSL_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(RE2_DEP) $(UPB_DEP) $(GRPC_ABSEIL_DEP)  $(LIBGRPC_CSHARP_EXT_OBJS) 
-       $(E) "[AR]      Creating $@"
-       $(Q) mkdir -p `dirname $@`
-       $(Q) rm -f $(LIBDIR)/$(CONFIG)/libgrpc_csharp_ext.a
-       $(Q) $(AR) $(ARFLAGS) $(LIBDIR)/$(CONFIG)/libgrpc_csharp_ext.a $(LIBGRPC_CSHARP_EXT_OBJS) 
-ifeq ($(SYSTEM),Darwin)
-       $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libgrpc_csharp_ext.a
-endif
-
-
-
-ifeq ($(SYSTEM),MINGW32)
-$(LIBDIR)/$(CONFIG)/grpc_csharp_ext$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE): $(LIBGRPC_CSHARP_EXT_OBJS)  $(ZLIB_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(RE2_DEP) $(UPB_DEP) $(GRPC_ABSEIL_DEP) $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libaddress_sorting.a $(LIBDIR)/$(CONFIG)/libupb.a $(OPENSSL_DEP)
-       $(E) "[LD]      Linking $@"
-       $(Q) mkdir -p `dirname $@`
-       $(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,--output-def=$(LIBDIR)/$(CONFIG)/grpc_csharp_ext$(SHARED_VERSION_CORE).def -Wl,--out-implib=$(LIBDIR)/$(CONFIG)/libgrpc_csharp_ext$(SHARED_VERSION_CORE)-dll.a -o $(LIBDIR)/$(CONFIG)/grpc_csharp_ext$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBGRPC_CSHARP_EXT_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libaddress_sorting.a $(LIBDIR)/$(CONFIG)/libupb.a $(ZLIB_MERGE_LIBS) $(CARES_MERGE_LIBS) $(ADDRESS_SORTING_MERGE_LIBS) $(RE2_MERGE_LIBS) $(UPB_MERGE_LIBS) $(GRPC_ABSEIL_MERGE_LIBS) $(LDLIBS)
-else
-$(LIBDIR)/$(CONFIG)/libgrpc_csharp_ext$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE): $(LIBGRPC_CSHARP_EXT_OBJS)  $(ZLIB_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(RE2_DEP) $(UPB_DEP) $(GRPC_ABSEIL_DEP) $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libaddress_sorting.a $(LIBDIR)/$(CONFIG)/libupb.a $(OPENSSL_DEP)
-       $(E) "[LD]      Linking $@"
+$(LIBDIR)/$(CONFIG)/libgpr$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE): $(LIBGPR_OBJS)  $(ZLIB_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(RE2_DEP) $(UPB_DEP) $(GRPC_ABSEIL_DEP)
+       $(E) "[LD]      Linking $@"
        $(Q) mkdir -p `dirname $@`
 ifeq ($(SYSTEM),Darwin)
-       $(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -install_name $(SHARED_PREFIX)grpc_csharp_ext$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) -dynamiclib -o $(LIBDIR)/$(CONFIG)/libgrpc_csharp_ext$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBGRPC_CSHARP_EXT_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libaddress_sorting.a $(LIBDIR)/$(CONFIG)/libupb.a $(ZLIB_MERGE_LIBS) $(CARES_MERGE_LIBS) $(ADDRESS_SORTING_MERGE_LIBS) $(RE2_MERGE_LIBS) $(UPB_MERGE_LIBS) $(GRPC_ABSEIL_MERGE_LIBS) $(LDLIBS)
+       $(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -install_name $(SHARED_PREFIX)gpr$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) -dynamiclib -o $(LIBDIR)/$(CONFIG)/libgpr$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBGPR_OBJS) $(ZLIB_MERGE_LIBS) $(CARES_MERGE_LIBS) $(ADDRESS_SORTING_MERGE_LIBS) $(RE2_MERGE_LIBS) $(UPB_MERGE_LIBS) $(GRPC_ABSEIL_MERGE_LIBS) $(LDLIBS)
 else
-       $(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,-soname,libgrpc_csharp_ext.so.14 -o $(LIBDIR)/$(CONFIG)/libgrpc_csharp_ext$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBGRPC_CSHARP_EXT_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libaddress_sorting.a $(LIBDIR)/$(CONFIG)/libupb.a $(ZLIB_MERGE_LIBS) $(CARES_MERGE_LIBS) $(ADDRESS_SORTING_MERGE_LIBS) $(RE2_MERGE_LIBS) $(UPB_MERGE_LIBS) $(GRPC_ABSEIL_MERGE_LIBS) $(LDLIBS)
-       $(Q) ln -sf $(SHARED_PREFIX)grpc_csharp_ext$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBDIR)/$(CONFIG)/libgrpc_csharp_ext$(SHARED_VERSION_CORE).so.14
-       $(Q) ln -sf $(SHARED_PREFIX)grpc_csharp_ext$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBDIR)/$(CONFIG)/libgrpc_csharp_ext$(SHARED_VERSION_CORE).so
-endif
+       $(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,-soname,libgpr.so.14 -o $(LIBDIR)/$(CONFIG)/libgpr$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBGPR_OBJS) $(ZLIB_MERGE_LIBS) $(CARES_MERGE_LIBS) $(ADDRESS_SORTING_MERGE_LIBS) $(RE2_MERGE_LIBS) $(UPB_MERGE_LIBS) $(GRPC_ABSEIL_MERGE_LIBS) $(LDLIBS)
+       $(Q) ln -sf $(SHARED_PREFIX)gpr$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBDIR)/$(CONFIG)/libgpr$(SHARED_VERSION_CORE).so.14
+       $(Q) ln -sf $(SHARED_PREFIX)gpr$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBDIR)/$(CONFIG)/libgpr$(SHARED_VERSION_CORE).so
 endif
-
 endif
 
-ifneq ($(NO_SECURE),true)
 ifneq ($(NO_DEPS),true)
--include $(LIBGRPC_CSHARP_EXT_OBJS:.o=.dep)
-endif
+-include $(LIBGPR_OBJS:.o=.dep)
 endif
-# end of build recipe for library "grpc_csharp_ext"
+# end of build recipe for library "gpr"
 
 
-# start of build recipe for library "grpc_unsecure" (generated by makelib(lib) template function)
-LIBGRPC_UNSECURE_SRC = \
+# start of build recipe for library "grpc" (generated by makelib(lib) template function)
+LIBGRPC_SRC = \
     src/core/ext/filters/census/grpc_context.cc \
     src/core/ext/filters/client_channel/backend_metric.cc \
     src/core/ext/filters/client_channel/backup_poller.cc \
@@ -2502,6 +1042,7 @@ LIBGRPC_UNSECURE_SRC = \
     src/core/ext/filters/client_channel/client_channel_factory.cc \
     src/core/ext/filters/client_channel/client_channel_plugin.cc \
     src/core/ext/filters/client_channel/config_selector.cc \
+    src/core/ext/filters/client_channel/dynamic_filters.cc \
     src/core/ext/filters/client_channel/global_subchannel_pool.cc \
     src/core/ext/filters/client_channel/health/health_check_client.cc \
     src/core/ext/filters/client_channel/http_connect_handshaker.cc \
@@ -2512,24 +1053,26 @@ LIBGRPC_UNSECURE_SRC = \
     src/core/ext/filters/client_channel/lb_policy/grpclb/client_load_reporting_filter.cc \
     src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc \
     src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_balancer_addresses.cc \
-    src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel.cc \
+    src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel_secure.cc \
     src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.cc \
     src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.cc \
     src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc \
     src/core/ext/filters/client_channel/lb_policy/priority/priority.cc \
     src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc \
     src/core/ext/filters/client_channel/lb_policy/weighted_target/weighted_target.cc \
+    src/core/ext/filters/client_channel/lb_policy/xds/cds.cc \
+    src/core/ext/filters/client_channel/lb_policy/xds/xds_cluster_impl.cc \
+    src/core/ext/filters/client_channel/lb_policy/xds/xds_cluster_manager.cc \
+    src/core/ext/filters/client_channel/lb_policy/xds/xds_cluster_resolver.cc \
     src/core/ext/filters/client_channel/lb_policy_registry.cc \
     src/core/ext/filters/client_channel/local_subchannel_pool.cc \
     src/core/ext/filters/client_channel/proxy_mapper_registry.cc \
     src/core/ext/filters/client_channel/resolver.cc \
     src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc \
-    src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.cc \
     src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_libuv.cc \
     src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_posix.cc \
     src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_windows.cc \
     src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc \
-    src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_fallback.cc \
     src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv.cc \
     src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_posix.cc \
     src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc \
@@ -2537,9 +1080,9 @@ LIBGRPC_UNSECURE_SRC = \
     src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc \
     src/core/ext/filters/client_channel/resolver/fake/fake_resolver.cc \
     src/core/ext/filters/client_channel/resolver/sockaddr/sockaddr_resolver.cc \
+    src/core/ext/filters/client_channel/resolver/xds/xds_resolver.cc \
     src/core/ext/filters/client_channel/resolver_registry.cc \
     src/core/ext/filters/client_channel/resolver_result_parsing.cc \
-    src/core/ext/filters/client_channel/resolving_lb_policy.cc \
     src/core/ext/filters/client_channel/retry_throttle.cc \
     src/core/ext/filters/client_channel/server_address.cc \
     src/core/ext/filters/client_channel/service_config.cc \
@@ -2564,9 +1107,11 @@ LIBGRPC_UNSECURE_SRC = \
     src/core/ext/transport/chttp2/client/chttp2_connector.cc \
     src/core/ext/transport/chttp2/client/insecure/channel_create.cc \
     src/core/ext/transport/chttp2/client/insecure/channel_create_posix.cc \
+    src/core/ext/transport/chttp2/client/secure/secure_channel_create.cc \
     src/core/ext/transport/chttp2/server/chttp2_server.cc \
     src/core/ext/transport/chttp2/server/insecure/server_chttp2.cc \
     src/core/ext/transport/chttp2/server/insecure/server_chttp2_posix.cc \
+    src/core/ext/transport/chttp2/server/secure/server_secure_chttp2.cc \
     src/core/ext/transport/chttp2/transport/bin_decoder.cc \
     src/core/ext/transport/chttp2/transport/bin_encoder.cc \
     src/core/ext/transport/chttp2/transport/chttp2_plugin.cc \
@@ -2592,6 +1137,63 @@ LIBGRPC_UNSECURE_SRC = \
     src/core/ext/transport/chttp2/transport/writing.cc \
     src/core/ext/transport/inproc/inproc_plugin.cc \
     src/core/ext/transport/inproc/inproc_transport.cc \
+    src/core/ext/upb-generated/envoy/annotations/deprecation.upb.c \
+    src/core/ext/upb-generated/envoy/annotations/resource.upb.c \
+    src/core/ext/upb-generated/envoy/config/accesslog/v3/accesslog.upb.c \
+    src/core/ext/upb-generated/envoy/config/cluster/v3/circuit_breaker.upb.c \
+    src/core/ext/upb-generated/envoy/config/cluster/v3/cluster.upb.c \
+    src/core/ext/upb-generated/envoy/config/cluster/v3/filter.upb.c \
+    src/core/ext/upb-generated/envoy/config/cluster/v3/outlier_detection.upb.c \
+    src/core/ext/upb-generated/envoy/config/core/v3/address.upb.c \
+    src/core/ext/upb-generated/envoy/config/core/v3/backoff.upb.c \
+    src/core/ext/upb-generated/envoy/config/core/v3/base.upb.c \
+    src/core/ext/upb-generated/envoy/config/core/v3/config_source.upb.c \
+    src/core/ext/upb-generated/envoy/config/core/v3/event_service_config.upb.c \
+    src/core/ext/upb-generated/envoy/config/core/v3/extension.upb.c \
+    src/core/ext/upb-generated/envoy/config/core/v3/grpc_service.upb.c \
+    src/core/ext/upb-generated/envoy/config/core/v3/health_check.upb.c \
+    src/core/ext/upb-generated/envoy/config/core/v3/http_uri.upb.c \
+    src/core/ext/upb-generated/envoy/config/core/v3/protocol.upb.c \
+    src/core/ext/upb-generated/envoy/config/core/v3/proxy_protocol.upb.c \
+    src/core/ext/upb-generated/envoy/config/core/v3/socket_option.upb.c \
+    src/core/ext/upb-generated/envoy/config/core/v3/substitution_format_string.upb.c \
+    src/core/ext/upb-generated/envoy/config/endpoint/v3/endpoint.upb.c \
+    src/core/ext/upb-generated/envoy/config/endpoint/v3/endpoint_components.upb.c \
+    src/core/ext/upb-generated/envoy/config/endpoint/v3/load_report.upb.c \
+    src/core/ext/upb-generated/envoy/config/listener/v3/api_listener.upb.c \
+    src/core/ext/upb-generated/envoy/config/listener/v3/listener.upb.c \
+    src/core/ext/upb-generated/envoy/config/listener/v3/listener_components.upb.c \
+    src/core/ext/upb-generated/envoy/config/listener/v3/udp_listener_config.upb.c \
+    src/core/ext/upb-generated/envoy/config/rbac/v3/rbac.upb.c \
+    src/core/ext/upb-generated/envoy/config/route/v3/route.upb.c \
+    src/core/ext/upb-generated/envoy/config/route/v3/route_components.upb.c \
+    src/core/ext/upb-generated/envoy/config/route/v3/scoped_route.upb.c \
+    src/core/ext/upb-generated/envoy/config/trace/v3/http_tracer.upb.c \
+    src/core/ext/upb-generated/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.upb.c \
+    src/core/ext/upb-generated/envoy/extensions/transport_sockets/tls/v3/cert.upb.c \
+    src/core/ext/upb-generated/envoy/extensions/transport_sockets/tls/v3/common.upb.c \
+    src/core/ext/upb-generated/envoy/extensions/transport_sockets/tls/v3/secret.upb.c \
+    src/core/ext/upb-generated/envoy/extensions/transport_sockets/tls/v3/tls.upb.c \
+    src/core/ext/upb-generated/envoy/service/cluster/v3/cds.upb.c \
+    src/core/ext/upb-generated/envoy/service/discovery/v3/ads.upb.c \
+    src/core/ext/upb-generated/envoy/service/discovery/v3/discovery.upb.c \
+    src/core/ext/upb-generated/envoy/service/endpoint/v3/eds.upb.c \
+    src/core/ext/upb-generated/envoy/service/listener/v3/lds.upb.c \
+    src/core/ext/upb-generated/envoy/service/load_stats/v3/lrs.upb.c \
+    src/core/ext/upb-generated/envoy/service/route/v3/rds.upb.c \
+    src/core/ext/upb-generated/envoy/service/route/v3/srds.upb.c \
+    src/core/ext/upb-generated/envoy/type/matcher/v3/metadata.upb.c \
+    src/core/ext/upb-generated/envoy/type/matcher/v3/number.upb.c \
+    src/core/ext/upb-generated/envoy/type/matcher/v3/path.upb.c \
+    src/core/ext/upb-generated/envoy/type/matcher/v3/regex.upb.c \
+    src/core/ext/upb-generated/envoy/type/matcher/v3/string.upb.c \
+    src/core/ext/upb-generated/envoy/type/matcher/v3/value.upb.c \
+    src/core/ext/upb-generated/envoy/type/metadata/v3/metadata.upb.c \
+    src/core/ext/upb-generated/envoy/type/tracing/v3/custom_tag.upb.c \
+    src/core/ext/upb-generated/envoy/type/v3/http.upb.c \
+    src/core/ext/upb-generated/envoy/type/v3/percent.upb.c \
+    src/core/ext/upb-generated/envoy/type/v3/range.upb.c \
+    src/core/ext/upb-generated/envoy/type/v3/semantic_version.upb.c \
     src/core/ext/upb-generated/google/api/annotations.upb.c \
     src/core/ext/upb-generated/google/api/expr/v1alpha1/checked.upb.c \
     src/core/ext/upb-generated/google/api/expr/v1alpha1/syntax.upb.c \
@@ -2603,10 +1205,111 @@ LIBGRPC_UNSECURE_SRC = \
     src/core/ext/upb-generated/google/protobuf/timestamp.upb.c \
     src/core/ext/upb-generated/google/protobuf/wrappers.upb.c \
     src/core/ext/upb-generated/google/rpc/status.upb.c \
+    src/core/ext/upb-generated/src/proto/grpc/gcp/altscontext.upb.c \
+    src/core/ext/upb-generated/src/proto/grpc/gcp/handshaker.upb.c \
+    src/core/ext/upb-generated/src/proto/grpc/gcp/transport_security_common.upb.c \
     src/core/ext/upb-generated/src/proto/grpc/health/v1/health.upb.c \
     src/core/ext/upb-generated/src/proto/grpc/lb/v1/load_balancer.upb.c \
+    src/core/ext/upb-generated/udpa/annotations/migrate.upb.c \
+    src/core/ext/upb-generated/udpa/annotations/security.upb.c \
+    src/core/ext/upb-generated/udpa/annotations/sensitive.upb.c \
+    src/core/ext/upb-generated/udpa/annotations/status.upb.c \
+    src/core/ext/upb-generated/udpa/annotations/versioning.upb.c \
+    src/core/ext/upb-generated/udpa/core/v1/authority.upb.c \
+    src/core/ext/upb-generated/udpa/core/v1/collection_entry.upb.c \
+    src/core/ext/upb-generated/udpa/core/v1/context_params.upb.c \
+    src/core/ext/upb-generated/udpa/core/v1/resource.upb.c \
+    src/core/ext/upb-generated/udpa/core/v1/resource_locator.upb.c \
+    src/core/ext/upb-generated/udpa/core/v1/resource_name.upb.c \
     src/core/ext/upb-generated/udpa/data/orca/v1/orca_load_report.upb.c \
     src/core/ext/upb-generated/validate/validate.upb.c \
+    src/core/ext/upbdefs-generated/envoy/annotations/deprecation.upbdefs.c \
+    src/core/ext/upbdefs-generated/envoy/annotations/resource.upbdefs.c \
+    src/core/ext/upbdefs-generated/envoy/config/accesslog/v3/accesslog.upbdefs.c \
+    src/core/ext/upbdefs-generated/envoy/config/cluster/v3/circuit_breaker.upbdefs.c \
+    src/core/ext/upbdefs-generated/envoy/config/cluster/v3/cluster.upbdefs.c \
+    src/core/ext/upbdefs-generated/envoy/config/cluster/v3/filter.upbdefs.c \
+    src/core/ext/upbdefs-generated/envoy/config/cluster/v3/outlier_detection.upbdefs.c \
+    src/core/ext/upbdefs-generated/envoy/config/core/v3/address.upbdefs.c \
+    src/core/ext/upbdefs-generated/envoy/config/core/v3/backoff.upbdefs.c \
+    src/core/ext/upbdefs-generated/envoy/config/core/v3/base.upbdefs.c \
+    src/core/ext/upbdefs-generated/envoy/config/core/v3/config_source.upbdefs.c \
+    src/core/ext/upbdefs-generated/envoy/config/core/v3/event_service_config.upbdefs.c \
+    src/core/ext/upbdefs-generated/envoy/config/core/v3/extension.upbdefs.c \
+    src/core/ext/upbdefs-generated/envoy/config/core/v3/grpc_service.upbdefs.c \
+    src/core/ext/upbdefs-generated/envoy/config/core/v3/health_check.upbdefs.c \
+    src/core/ext/upbdefs-generated/envoy/config/core/v3/http_uri.upbdefs.c \
+    src/core/ext/upbdefs-generated/envoy/config/core/v3/protocol.upbdefs.c \
+    src/core/ext/upbdefs-generated/envoy/config/core/v3/proxy_protocol.upbdefs.c \
+    src/core/ext/upbdefs-generated/envoy/config/core/v3/socket_option.upbdefs.c \
+    src/core/ext/upbdefs-generated/envoy/config/core/v3/substitution_format_string.upbdefs.c \
+    src/core/ext/upbdefs-generated/envoy/config/endpoint/v3/endpoint.upbdefs.c \
+    src/core/ext/upbdefs-generated/envoy/config/endpoint/v3/endpoint_components.upbdefs.c \
+    src/core/ext/upbdefs-generated/envoy/config/endpoint/v3/load_report.upbdefs.c \
+    src/core/ext/upbdefs-generated/envoy/config/listener/v3/api_listener.upbdefs.c \
+    src/core/ext/upbdefs-generated/envoy/config/listener/v3/listener.upbdefs.c \
+    src/core/ext/upbdefs-generated/envoy/config/listener/v3/listener_components.upbdefs.c \
+    src/core/ext/upbdefs-generated/envoy/config/listener/v3/udp_listener_config.upbdefs.c \
+    src/core/ext/upbdefs-generated/envoy/config/route/v3/route.upbdefs.c \
+    src/core/ext/upbdefs-generated/envoy/config/route/v3/route_components.upbdefs.c \
+    src/core/ext/upbdefs-generated/envoy/config/route/v3/scoped_route.upbdefs.c \
+    src/core/ext/upbdefs-generated/envoy/config/trace/v3/http_tracer.upbdefs.c \
+    src/core/ext/upbdefs-generated/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.upbdefs.c \
+    src/core/ext/upbdefs-generated/envoy/extensions/transport_sockets/tls/v3/cert.upbdefs.c \
+    src/core/ext/upbdefs-generated/envoy/extensions/transport_sockets/tls/v3/common.upbdefs.c \
+    src/core/ext/upbdefs-generated/envoy/extensions/transport_sockets/tls/v3/secret.upbdefs.c \
+    src/core/ext/upbdefs-generated/envoy/extensions/transport_sockets/tls/v3/tls.upbdefs.c \
+    src/core/ext/upbdefs-generated/envoy/service/cluster/v3/cds.upbdefs.c \
+    src/core/ext/upbdefs-generated/envoy/service/discovery/v3/ads.upbdefs.c \
+    src/core/ext/upbdefs-generated/envoy/service/discovery/v3/discovery.upbdefs.c \
+    src/core/ext/upbdefs-generated/envoy/service/endpoint/v3/eds.upbdefs.c \
+    src/core/ext/upbdefs-generated/envoy/service/listener/v3/lds.upbdefs.c \
+    src/core/ext/upbdefs-generated/envoy/service/load_stats/v3/lrs.upbdefs.c \
+    src/core/ext/upbdefs-generated/envoy/service/route/v3/rds.upbdefs.c \
+    src/core/ext/upbdefs-generated/envoy/service/route/v3/srds.upbdefs.c \
+    src/core/ext/upbdefs-generated/envoy/type/matcher/v3/metadata.upbdefs.c \
+    src/core/ext/upbdefs-generated/envoy/type/matcher/v3/number.upbdefs.c \
+    src/core/ext/upbdefs-generated/envoy/type/matcher/v3/path.upbdefs.c \
+    src/core/ext/upbdefs-generated/envoy/type/matcher/v3/regex.upbdefs.c \
+    src/core/ext/upbdefs-generated/envoy/type/matcher/v3/string.upbdefs.c \
+    src/core/ext/upbdefs-generated/envoy/type/matcher/v3/value.upbdefs.c \
+    src/core/ext/upbdefs-generated/envoy/type/metadata/v3/metadata.upbdefs.c \
+    src/core/ext/upbdefs-generated/envoy/type/tracing/v3/custom_tag.upbdefs.c \
+    src/core/ext/upbdefs-generated/envoy/type/v3/http.upbdefs.c \
+    src/core/ext/upbdefs-generated/envoy/type/v3/percent.upbdefs.c \
+    src/core/ext/upbdefs-generated/envoy/type/v3/range.upbdefs.c \
+    src/core/ext/upbdefs-generated/envoy/type/v3/semantic_version.upbdefs.c \
+    src/core/ext/upbdefs-generated/google/api/annotations.upbdefs.c \
+    src/core/ext/upbdefs-generated/google/api/http.upbdefs.c \
+    src/core/ext/upbdefs-generated/google/protobuf/any.upbdefs.c \
+    src/core/ext/upbdefs-generated/google/protobuf/descriptor.upbdefs.c \
+    src/core/ext/upbdefs-generated/google/protobuf/duration.upbdefs.c \
+    src/core/ext/upbdefs-generated/google/protobuf/empty.upbdefs.c \
+    src/core/ext/upbdefs-generated/google/protobuf/struct.upbdefs.c \
+    src/core/ext/upbdefs-generated/google/protobuf/timestamp.upbdefs.c \
+    src/core/ext/upbdefs-generated/google/protobuf/wrappers.upbdefs.c \
+    src/core/ext/upbdefs-generated/google/rpc/status.upbdefs.c \
+    src/core/ext/upbdefs-generated/udpa/annotations/migrate.upbdefs.c \
+    src/core/ext/upbdefs-generated/udpa/annotations/security.upbdefs.c \
+    src/core/ext/upbdefs-generated/udpa/annotations/sensitive.upbdefs.c \
+    src/core/ext/upbdefs-generated/udpa/annotations/status.upbdefs.c \
+    src/core/ext/upbdefs-generated/udpa/annotations/versioning.upbdefs.c \
+    src/core/ext/upbdefs-generated/udpa/core/v1/authority.upbdefs.c \
+    src/core/ext/upbdefs-generated/udpa/core/v1/collection_entry.upbdefs.c \
+    src/core/ext/upbdefs-generated/udpa/core/v1/context_params.upbdefs.c \
+    src/core/ext/upbdefs-generated/udpa/core/v1/resource.upbdefs.c \
+    src/core/ext/upbdefs-generated/udpa/core/v1/resource_locator.upbdefs.c \
+    src/core/ext/upbdefs-generated/udpa/core/v1/resource_name.upbdefs.c \
+    src/core/ext/upbdefs-generated/validate/validate.upbdefs.c \
+    src/core/ext/xds/certificate_provider_registry.cc \
+    src/core/ext/xds/certificate_provider_store.cc \
+    src/core/ext/xds/file_watcher_certificate_provider_factory.cc \
+    src/core/ext/xds/xds_api.cc \
+    src/core/ext/xds/xds_bootstrap.cc \
+    src/core/ext/xds/xds_certificate_provider.cc \
+    src/core/ext/xds/xds_client.cc \
+    src/core/ext/xds/xds_client_stats.cc \
+    src/core/ext/xds/xds_server_config_fetcher.cc \
     src/core/lib/avl/avl.cc \
     src/core/lib/backoff/backoff.cc \
     src/core/lib/channel/channel_args.cc \
@@ -2631,6 +1334,7 @@ LIBGRPC_UNSECURE_SRC = \
     src/core/lib/debug/trace.cc \
     src/core/lib/http/format_request.cc \
     src/core/lib/http/httpcli.cc \
+    src/core/lib/http/httpcli_security_connector.cc \
     src/core/lib/http/parser.cc \
     src/core/lib/iomgr/buffer_list.cc \
     src/core/lib/iomgr/call_combiner.cc \
@@ -2731,6 +1435,60 @@ LIBGRPC_UNSECURE_SRC = \
     src/core/lib/json/json_reader.cc \
     src/core/lib/json/json_util.cc \
     src/core/lib/json/json_writer.cc \
+    src/core/lib/security/authorization/authorization_engine.cc \
+    src/core/lib/security/authorization/evaluate_args.cc \
+    src/core/lib/security/context/security_context.cc \
+    src/core/lib/security/credentials/alts/alts_credentials.cc \
+    src/core/lib/security/credentials/alts/check_gcp_environment.cc \
+    src/core/lib/security/credentials/alts/check_gcp_environment_linux.cc \
+    src/core/lib/security/credentials/alts/check_gcp_environment_no_op.cc \
+    src/core/lib/security/credentials/alts/check_gcp_environment_windows.cc \
+    src/core/lib/security/credentials/alts/grpc_alts_credentials_client_options.cc \
+    src/core/lib/security/credentials/alts/grpc_alts_credentials_options.cc \
+    src/core/lib/security/credentials/alts/grpc_alts_credentials_server_options.cc \
+    src/core/lib/security/credentials/composite/composite_credentials.cc \
+    src/core/lib/security/credentials/credentials.cc \
+    src/core/lib/security/credentials/credentials_metadata.cc \
+    src/core/lib/security/credentials/external/aws_external_account_credentials.cc \
+    src/core/lib/security/credentials/external/aws_request_signer.cc \
+    src/core/lib/security/credentials/external/external_account_credentials.cc \
+    src/core/lib/security/credentials/external/file_external_account_credentials.cc \
+    src/core/lib/security/credentials/external/url_external_account_credentials.cc \
+    src/core/lib/security/credentials/fake/fake_credentials.cc \
+    src/core/lib/security/credentials/google_default/credentials_generic.cc \
+    src/core/lib/security/credentials/google_default/google_default_credentials.cc \
+    src/core/lib/security/credentials/iam/iam_credentials.cc \
+    src/core/lib/security/credentials/insecure/insecure_credentials.cc \
+    src/core/lib/security/credentials/jwt/json_token.cc \
+    src/core/lib/security/credentials/jwt/jwt_credentials.cc \
+    src/core/lib/security/credentials/jwt/jwt_verifier.cc \
+    src/core/lib/security/credentials/local/local_credentials.cc \
+    src/core/lib/security/credentials/oauth2/oauth2_credentials.cc \
+    src/core/lib/security/credentials/plugin/plugin_credentials.cc \
+    src/core/lib/security/credentials/ssl/ssl_credentials.cc \
+    src/core/lib/security/credentials/tls/grpc_tls_certificate_distributor.cc \
+    src/core/lib/security/credentials/tls/grpc_tls_certificate_provider.cc \
+    src/core/lib/security/credentials/tls/grpc_tls_credentials_options.cc \
+    src/core/lib/security/credentials/tls/tls_credentials.cc \
+    src/core/lib/security/credentials/tls/tls_utils.cc \
+    src/core/lib/security/credentials/xds/xds_credentials.cc \
+    src/core/lib/security/security_connector/alts/alts_security_connector.cc \
+    src/core/lib/security/security_connector/fake/fake_security_connector.cc \
+    src/core/lib/security/security_connector/insecure/insecure_security_connector.cc \
+    src/core/lib/security/security_connector/load_system_roots_fallback.cc \
+    src/core/lib/security/security_connector/load_system_roots_linux.cc \
+    src/core/lib/security/security_connector/local/local_security_connector.cc \
+    src/core/lib/security/security_connector/security_connector.cc \
+    src/core/lib/security/security_connector/ssl/ssl_security_connector.cc \
+    src/core/lib/security/security_connector/ssl_utils.cc \
+    src/core/lib/security/security_connector/ssl_utils_config.cc \
+    src/core/lib/security/security_connector/tls/tls_security_connector.cc \
+    src/core/lib/security/transport/client_auth_filter.cc \
+    src/core/lib/security/transport/secure_endpoint.cc \
+    src/core/lib/security/transport/security_handshaker.cc \
+    src/core/lib/security/transport/server_auth_filter.cc \
+    src/core/lib/security/transport/tsi_error.cc \
+    src/core/lib/security/util/json_util.cc \
     src/core/lib/slice/b64.cc \
     src/core/lib/slice/percent_encoding.cc \
     src/core/lib/slice/slice.cc \
@@ -2751,7 +1509,7 @@ LIBGRPC_UNSECURE_SRC = \
     src/core/lib/surface/completion_queue_factory.cc \
     src/core/lib/surface/event_string.cc \
     src/core/lib/surface/init.cc \
-    src/core/lib/surface/init_unsecure.cc \
+    src/core/lib/surface/init_secure.cc \
     src/core/lib/surface/lame_client.cc \
     src/core/lib/surface/metadata_array.cc \
     src/core/lib/surface/server.cc \
@@ -2772,7 +1530,34 @@ LIBGRPC_UNSECURE_SRC = \
     src/core/lib/transport/transport.cc \
     src/core/lib/transport/transport_op_string.cc \
     src/core/lib/uri/uri_parser.cc \
-    src/core/plugin_registry/grpc_unsecure_plugin_registry.cc \
+    src/core/plugin_registry/grpc_plugin_registry.cc \
+    src/core/tsi/alts/crypt/aes_gcm.cc \
+    src/core/tsi/alts/crypt/gsec.cc \
+    src/core/tsi/alts/frame_protector/alts_counter.cc \
+    src/core/tsi/alts/frame_protector/alts_crypter.cc \
+    src/core/tsi/alts/frame_protector/alts_frame_protector.cc \
+    src/core/tsi/alts/frame_protector/alts_record_protocol_crypter_common.cc \
+    src/core/tsi/alts/frame_protector/alts_seal_privacy_integrity_crypter.cc \
+    src/core/tsi/alts/frame_protector/alts_unseal_privacy_integrity_crypter.cc \
+    src/core/tsi/alts/frame_protector/frame_handler.cc \
+    src/core/tsi/alts/handshaker/alts_handshaker_client.cc \
+    src/core/tsi/alts/handshaker/alts_shared_resource.cc \
+    src/core/tsi/alts/handshaker/alts_tsi_handshaker.cc \
+    src/core/tsi/alts/handshaker/alts_tsi_utils.cc \
+    src/core/tsi/alts/handshaker/transport_security_common_api.cc \
+    src/core/tsi/alts/zero_copy_frame_protector/alts_grpc_integrity_only_record_protocol.cc \
+    src/core/tsi/alts/zero_copy_frame_protector/alts_grpc_privacy_integrity_record_protocol.cc \
+    src/core/tsi/alts/zero_copy_frame_protector/alts_grpc_record_protocol_common.cc \
+    src/core/tsi/alts/zero_copy_frame_protector/alts_iovec_record_protocol.cc \
+    src/core/tsi/alts/zero_copy_frame_protector/alts_zero_copy_grpc_protector.cc \
+    src/core/tsi/fake_transport_security.cc \
+    src/core/tsi/local_transport_security.cc \
+    src/core/tsi/ssl/session_cache/ssl_session_boringssl.cc \
+    src/core/tsi/ssl/session_cache/ssl_session_cache.cc \
+    src/core/tsi/ssl/session_cache/ssl_session_openssl.cc \
+    src/core/tsi/ssl_transport_security.cc \
+    src/core/tsi/transport_security.cc \
+    src/core/tsi/transport_security_grpc.cc \
 
 PUBLIC_HEADERS_C += \
     include/grpc/byte_buffer.h \
@@ -2782,6 +1567,7 @@ PUBLIC_HEADERS_C += \
     include/grpc/fork.h \
     include/grpc/grpc.h \
     include/grpc/grpc_posix.h \
+    include/grpc/grpc_security.h \
     include/grpc/grpc_security_constants.h \
     include/grpc/load_reporting.h \
     include/grpc/slice.h \
@@ -2789,965 +1575,448 @@ PUBLIC_HEADERS_C += \
     include/grpc/status.h \
     include/grpc/support/workaround_list.h \
 
-LIBGRPC_UNSECURE_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBGRPC_UNSECURE_SRC))))
-
-
-$(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a: $(ZLIB_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(RE2_DEP) $(UPB_DEP) $(GRPC_ABSEIL_DEP)  $(LIBGRPC_UNSECURE_OBJS)  $(LIBGPR_OBJS)  $(LIBGRPC_ABSEIL_OBJS)  $(ZLIB_MERGE_OBJS)  $(CARES_MERGE_OBJS)  $(ADDRESS_SORTING_MERGE_OBJS)  $(RE2_MERGE_OBJS)  $(UPB_MERGE_OBJS) 
-       $(E) "[AR]      Creating $@"
-       $(Q) mkdir -p `dirname $@`
-       $(Q) rm -f $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a
-       $(Q) $(AR) $(ARFLAGS) $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBGRPC_UNSECURE_OBJS)  $(LIBGPR_OBJS)  $(LIBGRPC_ABSEIL_OBJS)  $(ZLIB_MERGE_OBJS)  $(CARES_MERGE_OBJS)  $(ADDRESS_SORTING_MERGE_OBJS)  $(RE2_MERGE_OBJS)  $(UPB_MERGE_OBJS) 
-ifeq ($(SYSTEM),Darwin)
-       $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a
-endif
-
-
-
-ifeq ($(SYSTEM),MINGW32)
-$(LIBDIR)/$(CONFIG)/grpc_unsecure$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE): $(LIBGRPC_UNSECURE_OBJS)  $(ZLIB_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(RE2_DEP) $(UPB_DEP) $(GRPC_ABSEIL_DEP) $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libaddress_sorting.a $(LIBDIR)/$(CONFIG)/libupb.a
-       $(E) "[LD]      Linking $@"
-       $(Q) mkdir -p `dirname $@`
-       $(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,--output-def=$(LIBDIR)/$(CONFIG)/grpc_unsecure$(SHARED_VERSION_CORE).def -Wl,--out-implib=$(LIBDIR)/$(CONFIG)/libgrpc_unsecure$(SHARED_VERSION_CORE)-dll.a -o $(LIBDIR)/$(CONFIG)/grpc_unsecure$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBGRPC_UNSECURE_OBJS) $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libaddress_sorting.a $(LIBDIR)/$(CONFIG)/libupb.a $(ZLIB_MERGE_LIBS) $(CARES_MERGE_LIBS) $(ADDRESS_SORTING_MERGE_LIBS) $(RE2_MERGE_LIBS) $(UPB_MERGE_LIBS) $(GRPC_ABSEIL_MERGE_LIBS) $(LDLIBS)
-else
-$(LIBDIR)/$(CONFIG)/libgrpc_unsecure$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE): $(LIBGRPC_UNSECURE_OBJS)  $(ZLIB_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(RE2_DEP) $(UPB_DEP) $(GRPC_ABSEIL_DEP) $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libaddress_sorting.a $(LIBDIR)/$(CONFIG)/libupb.a
-       $(E) "[LD]      Linking $@"
-       $(Q) mkdir -p `dirname $@`
-ifeq ($(SYSTEM),Darwin)
-       $(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -install_name $(SHARED_PREFIX)grpc_unsecure$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) -dynamiclib -o $(LIBDIR)/$(CONFIG)/libgrpc_unsecure$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBGRPC_UNSECURE_OBJS) $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libaddress_sorting.a $(LIBDIR)/$(CONFIG)/libupb.a $(ZLIB_MERGE_LIBS) $(CARES_MERGE_LIBS) $(ADDRESS_SORTING_MERGE_LIBS) $(RE2_MERGE_LIBS) $(UPB_MERGE_LIBS) $(GRPC_ABSEIL_MERGE_LIBS) $(LDLIBS)
-else
-       $(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,-soname,libgrpc_unsecure.so.14 -o $(LIBDIR)/$(CONFIG)/libgrpc_unsecure$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBGRPC_UNSECURE_OBJS) $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libaddress_sorting.a $(LIBDIR)/$(CONFIG)/libupb.a $(ZLIB_MERGE_LIBS) $(CARES_MERGE_LIBS) $(ADDRESS_SORTING_MERGE_LIBS) $(RE2_MERGE_LIBS) $(UPB_MERGE_LIBS) $(GRPC_ABSEIL_MERGE_LIBS) $(LDLIBS)
-       $(Q) ln -sf $(SHARED_PREFIX)grpc_unsecure$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBDIR)/$(CONFIG)/libgrpc_unsecure$(SHARED_VERSION_CORE).so.14
-       $(Q) ln -sf $(SHARED_PREFIX)grpc_unsecure$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBDIR)/$(CONFIG)/libgrpc_unsecure$(SHARED_VERSION_CORE).so
-endif
-endif
-
-ifneq ($(NO_DEPS),true)
--include $(LIBGRPC_UNSECURE_OBJS:.o=.dep)
-endif
-# end of build recipe for library "grpc_unsecure"
-
-
-# start of build recipe for library "grpc++" (generated by makelib(lib) template function)
-LIBGRPC++_SRC = \
-    src/cpp/client/channel_cc.cc \
-    src/cpp/client/client_callback.cc \
-    src/cpp/client/client_context.cc \
-    src/cpp/client/client_interceptor.cc \
-    src/cpp/client/create_channel.cc \
-    src/cpp/client/create_channel_internal.cc \
-    src/cpp/client/create_channel_posix.cc \
-    src/cpp/client/credentials_cc.cc \
-    src/cpp/client/insecure_credentials.cc \
-    src/cpp/client/secure_credentials.cc \
-    src/cpp/client/xds_credentials.cc \
-    src/cpp/codegen/codegen_init.cc \
-    src/cpp/common/alarm.cc \
-    src/cpp/common/auth_property_iterator.cc \
-    src/cpp/common/channel_arguments.cc \
-    src/cpp/common/channel_filter.cc \
-    src/cpp/common/completion_queue_cc.cc \
-    src/cpp/common/core_codegen.cc \
-    src/cpp/common/resource_quota_cc.cc \
-    src/cpp/common/rpc_method.cc \
-    src/cpp/common/secure_auth_context.cc \
-    src/cpp/common/secure_channel_arguments.cc \
-    src/cpp/common/secure_create_auth_context.cc \
-    src/cpp/common/tls_certificate_provider.cc \
-    src/cpp/common/tls_credentials_options.cc \
-    src/cpp/common/tls_credentials_options_util.cc \
-    src/cpp/common/validate_service_config.cc \
-    src/cpp/common/version_cc.cc \
-    src/cpp/server/async_generic_service.cc \
-    src/cpp/server/channel_argument_option.cc \
-    src/cpp/server/create_default_thread_pool.cc \
-    src/cpp/server/dynamic_thread_pool.cc \
-    src/cpp/server/external_connection_acceptor_impl.cc \
-    src/cpp/server/health/default_health_check_service.cc \
-    src/cpp/server/health/health_check_service.cc \
-    src/cpp/server/health/health_check_service_server_builder_option.cc \
-    src/cpp/server/insecure_server_credentials.cc \
-    src/cpp/server/secure_server_credentials.cc \
-    src/cpp/server/server_builder.cc \
-    src/cpp/server/server_callback.cc \
-    src/cpp/server/server_cc.cc \
-    src/cpp/server/server_context.cc \
-    src/cpp/server/server_credentials.cc \
-    src/cpp/server/server_posix.cc \
-    src/cpp/thread_manager/thread_manager.cc \
-    src/cpp/util/byte_buffer_cc.cc \
-    src/cpp/util/status.cc \
-    src/cpp/util/string_ref.cc \
-    src/cpp/util/time_cc.cc \
-
-PUBLIC_HEADERS_CXX += \
-    include/grpc++/alarm.h \
-    include/grpc++/channel.h \
-    include/grpc++/client_context.h \
-    include/grpc++/completion_queue.h \
-    include/grpc++/create_channel.h \
-    include/grpc++/create_channel_posix.h \
-    include/grpc++/ext/health_check_service_server_builder_option.h \
-    include/grpc++/generic/async_generic_service.h \
-    include/grpc++/generic/generic_stub.h \
-    include/grpc++/grpc++.h \
-    include/grpc++/health_check_service_interface.h \
-    include/grpc++/impl/call.h \
-    include/grpc++/impl/channel_argument_option.h \
-    include/grpc++/impl/client_unary_call.h \
-    include/grpc++/impl/codegen/async_stream.h \
-    include/grpc++/impl/codegen/async_unary_call.h \
-    include/grpc++/impl/codegen/byte_buffer.h \
-    include/grpc++/impl/codegen/call.h \
-    include/grpc++/impl/codegen/call_hook.h \
-    include/grpc++/impl/codegen/channel_interface.h \
-    include/grpc++/impl/codegen/client_context.h \
-    include/grpc++/impl/codegen/client_unary_call.h \
-    include/grpc++/impl/codegen/completion_queue.h \
-    include/grpc++/impl/codegen/completion_queue_tag.h \
-    include/grpc++/impl/codegen/config.h \
-    include/grpc++/impl/codegen/config_protobuf.h \
-    include/grpc++/impl/codegen/core_codegen.h \
-    include/grpc++/impl/codegen/core_codegen_interface.h \
-    include/grpc++/impl/codegen/create_auth_context.h \
-    include/grpc++/impl/codegen/grpc_library.h \
-    include/grpc++/impl/codegen/metadata_map.h \
-    include/grpc++/impl/codegen/method_handler_impl.h \
-    include/grpc++/impl/codegen/proto_utils.h \
-    include/grpc++/impl/codegen/rpc_method.h \
-    include/grpc++/impl/codegen/rpc_service_method.h \
-    include/grpc++/impl/codegen/security/auth_context.h \
-    include/grpc++/impl/codegen/serialization_traits.h \
-    include/grpc++/impl/codegen/server_context.h \
-    include/grpc++/impl/codegen/server_interface.h \
-    include/grpc++/impl/codegen/service_type.h \
-    include/grpc++/impl/codegen/slice.h \
-    include/grpc++/impl/codegen/status.h \
-    include/grpc++/impl/codegen/status_code_enum.h \
-    include/grpc++/impl/codegen/string_ref.h \
-    include/grpc++/impl/codegen/stub_options.h \
-    include/grpc++/impl/codegen/sync_stream.h \
-    include/grpc++/impl/codegen/time.h \
-    include/grpc++/impl/grpc_library.h \
-    include/grpc++/impl/method_handler_impl.h \
-    include/grpc++/impl/rpc_method.h \
-    include/grpc++/impl/rpc_service_method.h \
-    include/grpc++/impl/serialization_traits.h \
-    include/grpc++/impl/server_builder_option.h \
-    include/grpc++/impl/server_builder_plugin.h \
-    include/grpc++/impl/server_initializer.h \
-    include/grpc++/impl/service_type.h \
-    include/grpc++/resource_quota.h \
-    include/grpc++/security/auth_context.h \
-    include/grpc++/security/auth_metadata_processor.h \
-    include/grpc++/security/credentials.h \
-    include/grpc++/security/server_credentials.h \
-    include/grpc++/server.h \
-    include/grpc++/server_builder.h \
-    include/grpc++/server_context.h \
-    include/grpc++/server_posix.h \
-    include/grpc++/support/async_stream.h \
-    include/grpc++/support/async_unary_call.h \
-    include/grpc++/support/byte_buffer.h \
-    include/grpc++/support/channel_arguments.h \
-    include/grpc++/support/config.h \
-    include/grpc++/support/slice.h \
-    include/grpc++/support/status.h \
-    include/grpc++/support/status_code_enum.h \
-    include/grpc++/support/string_ref.h \
-    include/grpc++/support/stub_options.h \
-    include/grpc++/support/sync_stream.h \
-    include/grpc++/support/time.h \
-    include/grpcpp/alarm.h \
-    include/grpcpp/channel.h \
-    include/grpcpp/client_context.h \
-    include/grpcpp/completion_queue.h \
-    include/grpcpp/create_channel.h \
-    include/grpcpp/create_channel_posix.h \
-    include/grpcpp/ext/health_check_service_server_builder_option.h \
-    include/grpcpp/generic/async_generic_service.h \
-    include/grpcpp/generic/generic_stub.h \
-    include/grpcpp/grpcpp.h \
-    include/grpcpp/health_check_service_interface.h \
-    include/grpcpp/impl/call.h \
-    include/grpcpp/impl/channel_argument_option.h \
-    include/grpcpp/impl/client_unary_call.h \
-    include/grpcpp/impl/codegen/async_generic_service.h \
-    include/grpcpp/impl/codegen/async_stream.h \
-    include/grpcpp/impl/codegen/async_unary_call.h \
-    include/grpcpp/impl/codegen/byte_buffer.h \
-    include/grpcpp/impl/codegen/call.h \
-    include/grpcpp/impl/codegen/call_hook.h \
-    include/grpcpp/impl/codegen/call_op_set.h \
-    include/grpcpp/impl/codegen/call_op_set_interface.h \
-    include/grpcpp/impl/codegen/callback_common.h \
-    include/grpcpp/impl/codegen/channel_interface.h \
-    include/grpcpp/impl/codegen/client_callback.h \
-    include/grpcpp/impl/codegen/client_context.h \
-    include/grpcpp/impl/codegen/client_interceptor.h \
-    include/grpcpp/impl/codegen/client_unary_call.h \
-    include/grpcpp/impl/codegen/completion_queue.h \
-    include/grpcpp/impl/codegen/completion_queue_tag.h \
-    include/grpcpp/impl/codegen/config.h \
-    include/grpcpp/impl/codegen/config_protobuf.h \
-    include/grpcpp/impl/codegen/core_codegen.h \
-    include/grpcpp/impl/codegen/core_codegen_interface.h \
-    include/grpcpp/impl/codegen/create_auth_context.h \
-    include/grpcpp/impl/codegen/delegating_channel.h \
-    include/grpcpp/impl/codegen/grpc_library.h \
-    include/grpcpp/impl/codegen/intercepted_channel.h \
-    include/grpcpp/impl/codegen/interceptor.h \
-    include/grpcpp/impl/codegen/interceptor_common.h \
-    include/grpcpp/impl/codegen/message_allocator.h \
-    include/grpcpp/impl/codegen/metadata_map.h \
-    include/grpcpp/impl/codegen/method_handler.h \
-    include/grpcpp/impl/codegen/proto_buffer_reader.h \
-    include/grpcpp/impl/codegen/proto_buffer_writer.h \
-    include/grpcpp/impl/codegen/proto_utils.h \
-    include/grpcpp/impl/codegen/rpc_method.h \
-    include/grpcpp/impl/codegen/rpc_service_method.h \
-    include/grpcpp/impl/codegen/security/auth_context.h \
-    include/grpcpp/impl/codegen/serialization_traits.h \
-    include/grpcpp/impl/codegen/server_callback.h \
-    include/grpcpp/impl/codegen/server_callback_handlers.h \
-    include/grpcpp/impl/codegen/server_context.h \
-    include/grpcpp/impl/codegen/server_interceptor.h \
-    include/grpcpp/impl/codegen/server_interface.h \
-    include/grpcpp/impl/codegen/service_type.h \
-    include/grpcpp/impl/codegen/slice.h \
-    include/grpcpp/impl/codegen/status.h \
-    include/grpcpp/impl/codegen/status_code_enum.h \
-    include/grpcpp/impl/codegen/string_ref.h \
-    include/grpcpp/impl/codegen/stub_options.h \
-    include/grpcpp/impl/codegen/sync.h \
-    include/grpcpp/impl/codegen/sync_stream.h \
-    include/grpcpp/impl/codegen/time.h \
-    include/grpcpp/impl/grpc_library.h \
-    include/grpcpp/impl/method_handler_impl.h \
-    include/grpcpp/impl/rpc_method.h \
-    include/grpcpp/impl/rpc_service_method.h \
-    include/grpcpp/impl/serialization_traits.h \
-    include/grpcpp/impl/server_builder_option.h \
-    include/grpcpp/impl/server_builder_plugin.h \
-    include/grpcpp/impl/server_initializer.h \
-    include/grpcpp/impl/service_type.h \
-    include/grpcpp/resource_quota.h \
-    include/grpcpp/security/auth_context.h \
-    include/grpcpp/security/auth_metadata_processor.h \
-    include/grpcpp/security/credentials.h \
-    include/grpcpp/security/server_credentials.h \
-    include/grpcpp/security/tls_certificate_provider.h \
-    include/grpcpp/security/tls_credentials_options.h \
-    include/grpcpp/server.h \
-    include/grpcpp/server_builder.h \
-    include/grpcpp/server_context.h \
-    include/grpcpp/server_posix.h \
-    include/grpcpp/support/async_stream.h \
-    include/grpcpp/support/async_unary_call.h \
-    include/grpcpp/support/byte_buffer.h \
-    include/grpcpp/support/channel_arguments.h \
-    include/grpcpp/support/client_callback.h \
-    include/grpcpp/support/client_interceptor.h \
-    include/grpcpp/support/config.h \
-    include/grpcpp/support/interceptor.h \
-    include/grpcpp/support/message_allocator.h \
-    include/grpcpp/support/method_handler.h \
-    include/grpcpp/support/proto_buffer_reader.h \
-    include/grpcpp/support/proto_buffer_writer.h \
-    include/grpcpp/support/server_callback.h \
-    include/grpcpp/support/server_interceptor.h \
-    include/grpcpp/support/slice.h \
-    include/grpcpp/support/status.h \
-    include/grpcpp/support/status_code_enum.h \
-    include/grpcpp/support/string_ref.h \
-    include/grpcpp/support/stub_options.h \
-    include/grpcpp/support/sync_stream.h \
-    include/grpcpp/support/time.h \
-    include/grpcpp/support/validate_service_config.h \
-
-LIBGRPC++_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBGRPC++_SRC))))
-
-
-ifeq ($(NO_SECURE),true)
-
-# You can't build secure libraries if you don't have OpenSSL.
-
-$(LIBDIR)/$(CONFIG)/libgrpc++.a: openssl_dep_error
-
-$(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)grpc++$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP): openssl_dep_error
-
-else
-
-ifeq ($(NO_PROTOBUF),true)
-
-# You can't build a C++ library if you don't have protobuf - a bit overreached, but still okay.
-
-$(LIBDIR)/$(CONFIG)/libgrpc++.a: protobuf_dep_error
-
-$(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)grpc++$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP): protobuf_dep_error
-
-else
-
-$(LIBDIR)/$(CONFIG)/libgrpc++.a: $(ZLIB_DEP) $(OPENSSL_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(RE2_DEP) $(UPB_DEP) $(GRPC_ABSEIL_DEP)  $(PROTOBUF_DEP) $(LIBGRPC++_OBJS)  $(LIBGPR_OBJS)  $(LIBGRPC_ABSEIL_OBJS)  $(ZLIB_MERGE_OBJS)  $(CARES_MERGE_OBJS)  $(ADDRESS_SORTING_MERGE_OBJS)  $(RE2_MERGE_OBJS)  $(UPB_MERGE_OBJS) 
-       $(E) "[AR]      Creating $@"
-       $(Q) mkdir -p `dirname $@`
-       $(Q) rm -f $(LIBDIR)/$(CONFIG)/libgrpc++.a
-       $(Q) $(AR) $(ARFLAGS) $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBGRPC++_OBJS)  $(LIBGPR_OBJS)  $(LIBGRPC_ABSEIL_OBJS)  $(ZLIB_MERGE_OBJS)  $(CARES_MERGE_OBJS)  $(ADDRESS_SORTING_MERGE_OBJS)  $(RE2_MERGE_OBJS)  $(UPB_MERGE_OBJS) 
-ifeq ($(SYSTEM),Darwin)
-       $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libgrpc++.a
-endif
-
-
-
-ifeq ($(SYSTEM),MINGW32)
-$(LIBDIR)/$(CONFIG)/grpc++$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP): $(LIBGRPC++_OBJS)  $(ZLIB_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(RE2_DEP) $(UPB_DEP) $(GRPC_ABSEIL_DEP) $(PROTOBUF_DEP) $(LIBDIR)/$(CONFIG)/grpc$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBDIR)/$(CONFIG)/gpr$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBDIR)/$(CONFIG)/address_sorting$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBDIR)/$(CONFIG)/upb$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(OPENSSL_DEP)
-       $(E) "[LD]      Linking $@"
-       $(Q) mkdir -p `dirname $@`
-       $(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,--output-def=$(LIBDIR)/$(CONFIG)/grpc++$(SHARED_VERSION_CPP).def -Wl,--out-implib=$(LIBDIR)/$(CONFIG)/libgrpc++$(SHARED_VERSION_CPP)-dll.a -o $(LIBDIR)/$(CONFIG)/grpc++$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBGRPC++_OBJS) $(ZLIB_MERGE_LIBS) $(CARES_MERGE_LIBS) $(ADDRESS_SORTING_MERGE_LIBS) $(RE2_MERGE_LIBS) $(UPB_MERGE_LIBS) $(GRPC_ABSEIL_MERGE_LIBS) $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) -lgrpc$(SHARED_VERSION_CORE)-dll -lgpr$(SHARED_VERSION_CORE)-dll -laddress_sorting$(SHARED_VERSION_CORE)-dll -lupb$(SHARED_VERSION_CORE)-dll
-else
-$(LIBDIR)/$(CONFIG)/libgrpc++$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP): $(LIBGRPC++_OBJS)  $(ZLIB_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(RE2_DEP) $(UPB_DEP) $(GRPC_ABSEIL_DEP) $(PROTOBUF_DEP) $(LIBDIR)/$(CONFIG)/libgrpc.$(SHARED_EXT_CORE) $(LIBDIR)/$(CONFIG)/libgpr.$(SHARED_EXT_CORE) $(LIBDIR)/$(CONFIG)/libaddress_sorting.$(SHARED_EXT_CORE) $(LIBDIR)/$(CONFIG)/libupb.$(SHARED_EXT_CORE) $(OPENSSL_DEP)
-       $(E) "[LD]      Linking $@"
-       $(Q) mkdir -p `dirname $@`
-ifeq ($(SYSTEM),Darwin)
-       $(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -install_name $(SHARED_PREFIX)grpc++$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) -dynamiclib -o $(LIBDIR)/$(CONFIG)/libgrpc++$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBGRPC++_OBJS) $(ZLIB_MERGE_LIBS) $(CARES_MERGE_LIBS) $(ADDRESS_SORTING_MERGE_LIBS) $(RE2_MERGE_LIBS) $(UPB_MERGE_LIBS) $(GRPC_ABSEIL_MERGE_LIBS) $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) -lgrpc -lgpr -laddress_sorting -lupb
-else
-       $(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,-soname,libgrpc++.so.1 -o $(LIBDIR)/$(CONFIG)/libgrpc++$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBGRPC++_OBJS) $(ZLIB_MERGE_LIBS) $(CARES_MERGE_LIBS) $(ADDRESS_SORTING_MERGE_LIBS) $(RE2_MERGE_LIBS) $(UPB_MERGE_LIBS) $(GRPC_ABSEIL_MERGE_LIBS) $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) -lgrpc -lgpr -laddress_sorting -lupb
-       $(Q) ln -sf $(SHARED_PREFIX)grpc++$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBDIR)/$(CONFIG)/libgrpc++$(SHARED_VERSION_CPP).so.1
-       $(Q) ln -sf $(SHARED_PREFIX)grpc++$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBDIR)/$(CONFIG)/libgrpc++$(SHARED_VERSION_CPP).so
-endif
-endif
-
-endif
-
-endif
-
-ifneq ($(NO_SECURE),true)
-ifneq ($(NO_DEPS),true)
--include $(LIBGRPC++_OBJS:.o=.dep)
-endif
-endif
-# end of build recipe for library "grpc++"
-
-
-# start of build recipe for library "grpc++_alts" (generated by makelib(lib) template function)
-LIBGRPC++_ALTS_SRC = \
-    src/cpp/common/alts_context.cc \
-    src/cpp/common/alts_util.cc \
-
-PUBLIC_HEADERS_CXX += \
-    include/grpcpp/security/alts_context.h \
-    include/grpcpp/security/alts_util.h \
-
-LIBGRPC++_ALTS_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBGRPC++_ALTS_SRC))))
-
-
-ifeq ($(NO_SECURE),true)
-
-# You can't build secure libraries if you don't have OpenSSL.
-
-$(LIBDIR)/$(CONFIG)/libgrpc++_alts.a: openssl_dep_error
-
-$(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)grpc++_alts$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP): openssl_dep_error
-
-else
-
-ifeq ($(NO_PROTOBUF),true)
-
-# You can't build a C++ library if you don't have protobuf - a bit overreached, but still okay.
-
-$(LIBDIR)/$(CONFIG)/libgrpc++_alts.a: protobuf_dep_error
-
-$(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)grpc++_alts$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP): protobuf_dep_error
-
-else
-
-$(LIBDIR)/$(CONFIG)/libgrpc++_alts.a: $(ZLIB_DEP) $(OPENSSL_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(RE2_DEP) $(UPB_DEP) $(GRPC_ABSEIL_DEP)  $(PROTOBUF_DEP) $(LIBGRPC++_ALTS_OBJS)  $(LIBGPR_OBJS)  $(LIBGRPC_ABSEIL_OBJS)  $(ZLIB_MERGE_OBJS)  $(CARES_MERGE_OBJS)  $(ADDRESS_SORTING_MERGE_OBJS)  $(RE2_MERGE_OBJS)  $(UPB_MERGE_OBJS) 
-       $(E) "[AR]      Creating $@"
-       $(Q) mkdir -p `dirname $@`
-       $(Q) rm -f $(LIBDIR)/$(CONFIG)/libgrpc++_alts.a
-       $(Q) $(AR) $(ARFLAGS) $(LIBDIR)/$(CONFIG)/libgrpc++_alts.a $(LIBGRPC++_ALTS_OBJS)  $(LIBGPR_OBJS)  $(LIBGRPC_ABSEIL_OBJS)  $(ZLIB_MERGE_OBJS)  $(CARES_MERGE_OBJS)  $(ADDRESS_SORTING_MERGE_OBJS)  $(RE2_MERGE_OBJS)  $(UPB_MERGE_OBJS) 
-ifeq ($(SYSTEM),Darwin)
-       $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libgrpc++_alts.a
-endif
-
-
-
-ifeq ($(SYSTEM),MINGW32)
-$(LIBDIR)/$(CONFIG)/grpc++_alts$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP): $(LIBGRPC++_ALTS_OBJS)  $(ZLIB_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(RE2_DEP) $(UPB_DEP) $(GRPC_ABSEIL_DEP) $(PROTOBUF_DEP) $(LIBDIR)/$(CONFIG)/grpc++$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBDIR)/$(CONFIG)/grpc$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBDIR)/$(CONFIG)/gpr$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBDIR)/$(CONFIG)/address_sorting$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBDIR)/$(CONFIG)/upb$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(OPENSSL_DEP)
-       $(E) "[LD]      Linking $@"
-       $(Q) mkdir -p `dirname $@`
-       $(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,--output-def=$(LIBDIR)/$(CONFIG)/grpc++_alts$(SHARED_VERSION_CPP).def -Wl,--out-implib=$(LIBDIR)/$(CONFIG)/libgrpc++_alts$(SHARED_VERSION_CPP)-dll.a -o $(LIBDIR)/$(CONFIG)/grpc++_alts$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBGRPC++_ALTS_OBJS) $(ZLIB_MERGE_LIBS) $(CARES_MERGE_LIBS) $(ADDRESS_SORTING_MERGE_LIBS) $(RE2_MERGE_LIBS) $(UPB_MERGE_LIBS) $(GRPC_ABSEIL_MERGE_LIBS) $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) -lgrpc++$(SHARED_VERSION_CPP)-dll -lgrpc$(SHARED_VERSION_CORE)-dll -lgpr$(SHARED_VERSION_CORE)-dll -laddress_sorting$(SHARED_VERSION_CORE)-dll -lupb$(SHARED_VERSION_CORE)-dll
-else
-$(LIBDIR)/$(CONFIG)/libgrpc++_alts$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP): $(LIBGRPC++_ALTS_OBJS)  $(ZLIB_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(RE2_DEP) $(UPB_DEP) $(GRPC_ABSEIL_DEP) $(PROTOBUF_DEP) $(LIBDIR)/$(CONFIG)/libgrpc++.$(SHARED_EXT_CPP) $(LIBDIR)/$(CONFIG)/libgrpc.$(SHARED_EXT_CORE) $(LIBDIR)/$(CONFIG)/libgpr.$(SHARED_EXT_CORE) $(LIBDIR)/$(CONFIG)/libaddress_sorting.$(SHARED_EXT_CORE) $(LIBDIR)/$(CONFIG)/libupb.$(SHARED_EXT_CORE) $(OPENSSL_DEP)
-       $(E) "[LD]      Linking $@"
-       $(Q) mkdir -p `dirname $@`
-ifeq ($(SYSTEM),Darwin)
-       $(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -install_name $(SHARED_PREFIX)grpc++_alts$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) -dynamiclib -o $(LIBDIR)/$(CONFIG)/libgrpc++_alts$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBGRPC++_ALTS_OBJS) $(ZLIB_MERGE_LIBS) $(CARES_MERGE_LIBS) $(ADDRESS_SORTING_MERGE_LIBS) $(RE2_MERGE_LIBS) $(UPB_MERGE_LIBS) $(GRPC_ABSEIL_MERGE_LIBS) $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) -lgrpc++ -lgrpc -lgpr -laddress_sorting -lupb
-else
-       $(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,-soname,libgrpc++_alts.so.1 -o $(LIBDIR)/$(CONFIG)/libgrpc++_alts$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBGRPC++_ALTS_OBJS) $(ZLIB_MERGE_LIBS) $(CARES_MERGE_LIBS) $(ADDRESS_SORTING_MERGE_LIBS) $(RE2_MERGE_LIBS) $(UPB_MERGE_LIBS) $(GRPC_ABSEIL_MERGE_LIBS) $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) -lgrpc++ -lgrpc -lgpr -laddress_sorting -lupb
-       $(Q) ln -sf $(SHARED_PREFIX)grpc++_alts$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBDIR)/$(CONFIG)/libgrpc++_alts$(SHARED_VERSION_CPP).so.1
-       $(Q) ln -sf $(SHARED_PREFIX)grpc++_alts$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBDIR)/$(CONFIG)/libgrpc++_alts$(SHARED_VERSION_CPP).so
-endif
-endif
-
-endif
-
-endif
-
-ifneq ($(NO_SECURE),true)
-ifneq ($(NO_DEPS),true)
--include $(LIBGRPC++_ALTS_OBJS:.o=.dep)
-endif
-endif
-# end of build recipe for library "grpc++_alts"
-
-
-# start of build recipe for library "grpc++_error_details" (generated by makelib(lib) template function)
-LIBGRPC++_ERROR_DETAILS_SRC = \
-    $(GENDIR)/src/proto/grpc/status/status.pb.cc $(GENDIR)/src/proto/grpc/status/status.grpc.pb.cc \
-    src/cpp/util/error_details.cc \
-
-PUBLIC_HEADERS_CXX += \
-    include/grpc++/support/error_details.h \
-    include/grpcpp/support/error_details.h \
-
-LIBGRPC++_ERROR_DETAILS_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBGRPC++_ERROR_DETAILS_SRC))))
-
-
-ifeq ($(NO_SECURE),true)
-
-# You can't build secure libraries if you don't have OpenSSL.
-
-$(LIBDIR)/$(CONFIG)/libgrpc++_error_details.a: openssl_dep_error
-
-$(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)grpc++_error_details$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP): openssl_dep_error
-
-else
-
-ifeq ($(NO_PROTOBUF),true)
-
-# You can't build a C++ library if you don't have protobuf - a bit overreached, but still okay.
-
-$(LIBDIR)/$(CONFIG)/libgrpc++_error_details.a: protobuf_dep_error
-
-$(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)grpc++_error_details$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP): protobuf_dep_error
-
-else
-
-$(LIBDIR)/$(CONFIG)/libgrpc++_error_details.a: $(ZLIB_DEP) $(OPENSSL_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(RE2_DEP) $(UPB_DEP) $(GRPC_ABSEIL_DEP)  $(PROTOBUF_DEP) $(LIBGRPC++_ERROR_DETAILS_OBJS) 
-       $(E) "[AR]      Creating $@"
-       $(Q) mkdir -p `dirname $@`
-       $(Q) rm -f $(LIBDIR)/$(CONFIG)/libgrpc++_error_details.a
-       $(Q) $(AR) $(ARFLAGS) $(LIBDIR)/$(CONFIG)/libgrpc++_error_details.a $(LIBGRPC++_ERROR_DETAILS_OBJS) 
-ifeq ($(SYSTEM),Darwin)
-       $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libgrpc++_error_details.a
-endif
-
-
-
-ifeq ($(SYSTEM),MINGW32)
-$(LIBDIR)/$(CONFIG)/grpc++_error_details$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP): $(LIBGRPC++_ERROR_DETAILS_OBJS)  $(ZLIB_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(RE2_DEP) $(UPB_DEP) $(GRPC_ABSEIL_DEP) $(PROTOBUF_DEP) $(LIBDIR)/$(CONFIG)/grpc++$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBDIR)/$(CONFIG)/grpc$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBDIR)/$(CONFIG)/gpr$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBDIR)/$(CONFIG)/address_sorting$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBDIR)/$(CONFIG)/upb$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(OPENSSL_DEP)
-       $(E) "[LD]      Linking $@"
-       $(Q) mkdir -p `dirname $@`
-       $(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,--output-def=$(LIBDIR)/$(CONFIG)/grpc++_error_details$(SHARED_VERSION_CPP).def -Wl,--out-implib=$(LIBDIR)/$(CONFIG)/libgrpc++_error_details$(SHARED_VERSION_CPP)-dll.a -o $(LIBDIR)/$(CONFIG)/grpc++_error_details$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBGRPC++_ERROR_DETAILS_OBJS) $(ZLIB_MERGE_LIBS) $(CARES_MERGE_LIBS) $(ADDRESS_SORTING_MERGE_LIBS) $(RE2_MERGE_LIBS) $(UPB_MERGE_LIBS) $(GRPC_ABSEIL_MERGE_LIBS) $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) -lgrpc++$(SHARED_VERSION_CPP)-dll -lgrpc$(SHARED_VERSION_CORE)-dll -lgpr$(SHARED_VERSION_CORE)-dll -laddress_sorting$(SHARED_VERSION_CORE)-dll -lupb$(SHARED_VERSION_CORE)-dll
-else
-$(LIBDIR)/$(CONFIG)/libgrpc++_error_details$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP): $(LIBGRPC++_ERROR_DETAILS_OBJS)  $(ZLIB_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(RE2_DEP) $(UPB_DEP) $(GRPC_ABSEIL_DEP) $(PROTOBUF_DEP) $(LIBDIR)/$(CONFIG)/libgrpc++.$(SHARED_EXT_CPP) $(LIBDIR)/$(CONFIG)/libgrpc.$(SHARED_EXT_CORE) $(LIBDIR)/$(CONFIG)/libgpr.$(SHARED_EXT_CORE) $(LIBDIR)/$(CONFIG)/libaddress_sorting.$(SHARED_EXT_CORE) $(LIBDIR)/$(CONFIG)/libupb.$(SHARED_EXT_CORE) $(OPENSSL_DEP)
-       $(E) "[LD]      Linking $@"
-       $(Q) mkdir -p `dirname $@`
-ifeq ($(SYSTEM),Darwin)
-       $(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -install_name $(SHARED_PREFIX)grpc++_error_details$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) -dynamiclib -o $(LIBDIR)/$(CONFIG)/libgrpc++_error_details$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBGRPC++_ERROR_DETAILS_OBJS) $(ZLIB_MERGE_LIBS) $(CARES_MERGE_LIBS) $(ADDRESS_SORTING_MERGE_LIBS) $(RE2_MERGE_LIBS) $(UPB_MERGE_LIBS) $(GRPC_ABSEIL_MERGE_LIBS) $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) -lgrpc++ -lgrpc -lgpr -laddress_sorting -lupb
-else
-       $(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,-soname,libgrpc++_error_details.so.1 -o $(LIBDIR)/$(CONFIG)/libgrpc++_error_details$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBGRPC++_ERROR_DETAILS_OBJS) $(ZLIB_MERGE_LIBS) $(CARES_MERGE_LIBS) $(ADDRESS_SORTING_MERGE_LIBS) $(RE2_MERGE_LIBS) $(UPB_MERGE_LIBS) $(GRPC_ABSEIL_MERGE_LIBS) $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) -lgrpc++ -lgrpc -lgpr -laddress_sorting -lupb
-       $(Q) ln -sf $(SHARED_PREFIX)grpc++_error_details$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBDIR)/$(CONFIG)/libgrpc++_error_details$(SHARED_VERSION_CPP).so.1
-       $(Q) ln -sf $(SHARED_PREFIX)grpc++_error_details$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBDIR)/$(CONFIG)/libgrpc++_error_details$(SHARED_VERSION_CPP).so
-endif
-endif
-
-endif
-
-endif
-
-ifneq ($(NO_SECURE),true)
-ifneq ($(NO_DEPS),true)
--include $(LIBGRPC++_ERROR_DETAILS_OBJS:.o=.dep)
-endif
-endif
-$(OBJDIR)/$(CONFIG)/src/cpp/util/error_details.o: $(GENDIR)/src/proto/grpc/status/status.pb.cc $(GENDIR)/src/proto/grpc/status/status.grpc.pb.cc
-# end of build recipe for library "grpc++_error_details"
-
-
-# start of build recipe for library "grpc++_reflection" (generated by makelib(lib) template function)
-LIBGRPC++_REFLECTION_SRC = \
-    $(GENDIR)/src/proto/grpc/reflection/v1alpha/reflection.pb.cc $(GENDIR)/src/proto/grpc/reflection/v1alpha/reflection.grpc.pb.cc \
-    src/cpp/ext/proto_server_reflection.cc \
-    src/cpp/ext/proto_server_reflection_plugin.cc \
-
-PUBLIC_HEADERS_CXX += \
-    include/grpc++/ext/proto_server_reflection_plugin.h \
-    include/grpcpp/ext/proto_server_reflection_plugin.h \
-
-LIBGRPC++_REFLECTION_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBGRPC++_REFLECTION_SRC))))
+LIBGRPC_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBGRPC_SRC))))
 
 
 ifeq ($(NO_SECURE),true)
 
 # You can't build secure libraries if you don't have OpenSSL.
 
-$(LIBDIR)/$(CONFIG)/libgrpc++_reflection.a: openssl_dep_error
-
-$(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)grpc++_reflection$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP): openssl_dep_error
-
-else
-
-ifeq ($(NO_PROTOBUF),true)
-
-# You can't build a C++ library if you don't have protobuf - a bit overreached, but still okay.
-
-$(LIBDIR)/$(CONFIG)/libgrpc++_reflection.a: protobuf_dep_error
-
-$(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)grpc++_reflection$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP): protobuf_dep_error
-
-else
-
-$(LIBDIR)/$(CONFIG)/libgrpc++_reflection.a: $(ZLIB_DEP) $(OPENSSL_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(RE2_DEP) $(UPB_DEP) $(GRPC_ABSEIL_DEP)  $(PROTOBUF_DEP) $(LIBGRPC++_REFLECTION_OBJS) 
-       $(E) "[AR]      Creating $@"
-       $(Q) mkdir -p `dirname $@`
-       $(Q) rm -f $(LIBDIR)/$(CONFIG)/libgrpc++_reflection.a
-       $(Q) $(AR) $(ARFLAGS) $(LIBDIR)/$(CONFIG)/libgrpc++_reflection.a $(LIBGRPC++_REFLECTION_OBJS) 
-ifeq ($(SYSTEM),Darwin)
-       $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libgrpc++_reflection.a
-endif
-
-
-
-ifeq ($(SYSTEM),MINGW32)
-$(LIBDIR)/$(CONFIG)/grpc++_reflection$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP): $(LIBGRPC++_REFLECTION_OBJS)  $(ZLIB_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(RE2_DEP) $(UPB_DEP) $(GRPC_ABSEIL_DEP) $(PROTOBUF_DEP) $(LIBDIR)/$(CONFIG)/grpc++$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBDIR)/$(CONFIG)/grpc$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBDIR)/$(CONFIG)/gpr$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBDIR)/$(CONFIG)/address_sorting$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBDIR)/$(CONFIG)/upb$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(OPENSSL_DEP)
-       $(E) "[LD]      Linking $@"
-       $(Q) mkdir -p `dirname $@`
-       $(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,--output-def=$(LIBDIR)/$(CONFIG)/grpc++_reflection$(SHARED_VERSION_CPP).def -Wl,--out-implib=$(LIBDIR)/$(CONFIG)/libgrpc++_reflection$(SHARED_VERSION_CPP)-dll.a -o $(LIBDIR)/$(CONFIG)/grpc++_reflection$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBGRPC++_REFLECTION_OBJS) $(ZLIB_MERGE_LIBS) $(CARES_MERGE_LIBS) $(ADDRESS_SORTING_MERGE_LIBS) $(RE2_MERGE_LIBS) $(UPB_MERGE_LIBS) $(GRPC_ABSEIL_MERGE_LIBS) $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) -lgrpc++$(SHARED_VERSION_CPP)-dll -lgrpc$(SHARED_VERSION_CORE)-dll -lgpr$(SHARED_VERSION_CORE)-dll -laddress_sorting$(SHARED_VERSION_CORE)-dll -lupb$(SHARED_VERSION_CORE)-dll
-else
-$(LIBDIR)/$(CONFIG)/libgrpc++_reflection$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP): $(LIBGRPC++_REFLECTION_OBJS)  $(ZLIB_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(RE2_DEP) $(UPB_DEP) $(GRPC_ABSEIL_DEP) $(PROTOBUF_DEP) $(LIBDIR)/$(CONFIG)/libgrpc++.$(SHARED_EXT_CPP) $(LIBDIR)/$(CONFIG)/libgrpc.$(SHARED_EXT_CORE) $(LIBDIR)/$(CONFIG)/libgpr.$(SHARED_EXT_CORE) $(LIBDIR)/$(CONFIG)/libaddress_sorting.$(SHARED_EXT_CORE) $(LIBDIR)/$(CONFIG)/libupb.$(SHARED_EXT_CORE) $(OPENSSL_DEP)
-       $(E) "[LD]      Linking $@"
-       $(Q) mkdir -p `dirname $@`
-ifeq ($(SYSTEM),Darwin)
-       $(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -install_name $(SHARED_PREFIX)grpc++_reflection$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) -dynamiclib -o $(LIBDIR)/$(CONFIG)/libgrpc++_reflection$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBGRPC++_REFLECTION_OBJS) $(ZLIB_MERGE_LIBS) $(CARES_MERGE_LIBS) $(ADDRESS_SORTING_MERGE_LIBS) $(RE2_MERGE_LIBS) $(UPB_MERGE_LIBS) $(GRPC_ABSEIL_MERGE_LIBS) $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) -lgrpc++ -lgrpc -lgpr -laddress_sorting -lupb
-else
-       $(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,-soname,libgrpc++_reflection.so.1 -o $(LIBDIR)/$(CONFIG)/libgrpc++_reflection$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBGRPC++_REFLECTION_OBJS) $(ZLIB_MERGE_LIBS) $(CARES_MERGE_LIBS) $(ADDRESS_SORTING_MERGE_LIBS) $(RE2_MERGE_LIBS) $(UPB_MERGE_LIBS) $(GRPC_ABSEIL_MERGE_LIBS) $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) -lgrpc++ -lgrpc -lgpr -laddress_sorting -lupb
-       $(Q) ln -sf $(SHARED_PREFIX)grpc++_reflection$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBDIR)/$(CONFIG)/libgrpc++_reflection$(SHARED_VERSION_CPP).so.1
-       $(Q) ln -sf $(SHARED_PREFIX)grpc++_reflection$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBDIR)/$(CONFIG)/libgrpc++_reflection$(SHARED_VERSION_CPP).so
-endif
-endif
-
-endif
-
-endif
+$(LIBDIR)/$(CONFIG)/libgrpc.a: openssl_dep_error
 
-ifneq ($(NO_SECURE),true)
-ifneq ($(NO_DEPS),true)
--include $(LIBGRPC++_REFLECTION_OBJS:.o=.dep)
-endif
-endif
-$(OBJDIR)/$(CONFIG)/src/cpp/ext/proto_server_reflection.o: $(GENDIR)/src/proto/grpc/reflection/v1alpha/reflection.pb.cc $(GENDIR)/src/proto/grpc/reflection/v1alpha/reflection.grpc.pb.cc
-$(OBJDIR)/$(CONFIG)/src/cpp/ext/proto_server_reflection_plugin.o: $(GENDIR)/src/proto/grpc/reflection/v1alpha/reflection.pb.cc $(GENDIR)/src/proto/grpc/reflection/v1alpha/reflection.grpc.pb.cc
-# end of build recipe for library "grpc++_reflection"
-
-
-# start of build recipe for library "grpc++_unsecure" (generated by makelib(lib) template function)
-LIBGRPC++_UNSECURE_SRC = \
-    src/cpp/client/channel_cc.cc \
-    src/cpp/client/client_callback.cc \
-    src/cpp/client/client_context.cc \
-    src/cpp/client/client_interceptor.cc \
-    src/cpp/client/create_channel.cc \
-    src/cpp/client/create_channel_internal.cc \
-    src/cpp/client/create_channel_posix.cc \
-    src/cpp/client/credentials_cc.cc \
-    src/cpp/client/insecure_credentials.cc \
-    src/cpp/codegen/codegen_init.cc \
-    src/cpp/common/alarm.cc \
-    src/cpp/common/channel_arguments.cc \
-    src/cpp/common/channel_filter.cc \
-    src/cpp/common/completion_queue_cc.cc \
-    src/cpp/common/core_codegen.cc \
-    src/cpp/common/insecure_create_auth_context.cc \
-    src/cpp/common/resource_quota_cc.cc \
-    src/cpp/common/rpc_method.cc \
-    src/cpp/common/validate_service_config.cc \
-    src/cpp/common/version_cc.cc \
-    src/cpp/server/async_generic_service.cc \
-    src/cpp/server/channel_argument_option.cc \
-    src/cpp/server/create_default_thread_pool.cc \
-    src/cpp/server/dynamic_thread_pool.cc \
-    src/cpp/server/external_connection_acceptor_impl.cc \
-    src/cpp/server/health/default_health_check_service.cc \
-    src/cpp/server/health/health_check_service.cc \
-    src/cpp/server/health/health_check_service_server_builder_option.cc \
-    src/cpp/server/insecure_server_credentials.cc \
-    src/cpp/server/server_builder.cc \
-    src/cpp/server/server_callback.cc \
-    src/cpp/server/server_cc.cc \
-    src/cpp/server/server_context.cc \
-    src/cpp/server/server_credentials.cc \
-    src/cpp/server/server_posix.cc \
-    src/cpp/thread_manager/thread_manager.cc \
-    src/cpp/util/byte_buffer_cc.cc \
-    src/cpp/util/status.cc \
-    src/cpp/util/string_ref.cc \
-    src/cpp/util/time_cc.cc \
-
-PUBLIC_HEADERS_CXX += \
-    include/grpc++/alarm.h \
-    include/grpc++/channel.h \
-    include/grpc++/client_context.h \
-    include/grpc++/completion_queue.h \
-    include/grpc++/create_channel.h \
-    include/grpc++/create_channel_posix.h \
-    include/grpc++/ext/health_check_service_server_builder_option.h \
-    include/grpc++/generic/async_generic_service.h \
-    include/grpc++/generic/generic_stub.h \
-    include/grpc++/grpc++.h \
-    include/grpc++/health_check_service_interface.h \
-    include/grpc++/impl/call.h \
-    include/grpc++/impl/channel_argument_option.h \
-    include/grpc++/impl/client_unary_call.h \
-    include/grpc++/impl/codegen/async_stream.h \
-    include/grpc++/impl/codegen/async_unary_call.h \
-    include/grpc++/impl/codegen/byte_buffer.h \
-    include/grpc++/impl/codegen/call.h \
-    include/grpc++/impl/codegen/call_hook.h \
-    include/grpc++/impl/codegen/channel_interface.h \
-    include/grpc++/impl/codegen/client_context.h \
-    include/grpc++/impl/codegen/client_unary_call.h \
-    include/grpc++/impl/codegen/completion_queue.h \
-    include/grpc++/impl/codegen/completion_queue_tag.h \
-    include/grpc++/impl/codegen/config.h \
-    include/grpc++/impl/codegen/config_protobuf.h \
-    include/grpc++/impl/codegen/core_codegen.h \
-    include/grpc++/impl/codegen/core_codegen_interface.h \
-    include/grpc++/impl/codegen/create_auth_context.h \
-    include/grpc++/impl/codegen/grpc_library.h \
-    include/grpc++/impl/codegen/metadata_map.h \
-    include/grpc++/impl/codegen/method_handler_impl.h \
-    include/grpc++/impl/codegen/proto_utils.h \
-    include/grpc++/impl/codegen/rpc_method.h \
-    include/grpc++/impl/codegen/rpc_service_method.h \
-    include/grpc++/impl/codegen/security/auth_context.h \
-    include/grpc++/impl/codegen/serialization_traits.h \
-    include/grpc++/impl/codegen/server_context.h \
-    include/grpc++/impl/codegen/server_interface.h \
-    include/grpc++/impl/codegen/service_type.h \
-    include/grpc++/impl/codegen/slice.h \
-    include/grpc++/impl/codegen/status.h \
-    include/grpc++/impl/codegen/status_code_enum.h \
-    include/grpc++/impl/codegen/string_ref.h \
-    include/grpc++/impl/codegen/stub_options.h \
-    include/grpc++/impl/codegen/sync_stream.h \
-    include/grpc++/impl/codegen/time.h \
-    include/grpc++/impl/grpc_library.h \
-    include/grpc++/impl/method_handler_impl.h \
-    include/grpc++/impl/rpc_method.h \
-    include/grpc++/impl/rpc_service_method.h \
-    include/grpc++/impl/serialization_traits.h \
-    include/grpc++/impl/server_builder_option.h \
-    include/grpc++/impl/server_builder_plugin.h \
-    include/grpc++/impl/server_initializer.h \
-    include/grpc++/impl/service_type.h \
-    include/grpc++/resource_quota.h \
-    include/grpc++/security/auth_context.h \
-    include/grpc++/security/auth_metadata_processor.h \
-    include/grpc++/security/credentials.h \
-    include/grpc++/security/server_credentials.h \
-    include/grpc++/server.h \
-    include/grpc++/server_builder.h \
-    include/grpc++/server_context.h \
-    include/grpc++/server_posix.h \
-    include/grpc++/support/async_stream.h \
-    include/grpc++/support/async_unary_call.h \
-    include/grpc++/support/byte_buffer.h \
-    include/grpc++/support/channel_arguments.h \
-    include/grpc++/support/config.h \
-    include/grpc++/support/slice.h \
-    include/grpc++/support/status.h \
-    include/grpc++/support/status_code_enum.h \
-    include/grpc++/support/string_ref.h \
-    include/grpc++/support/stub_options.h \
-    include/grpc++/support/sync_stream.h \
-    include/grpc++/support/time.h \
-    include/grpcpp/alarm.h \
-    include/grpcpp/channel.h \
-    include/grpcpp/client_context.h \
-    include/grpcpp/completion_queue.h \
-    include/grpcpp/create_channel.h \
-    include/grpcpp/create_channel_posix.h \
-    include/grpcpp/ext/health_check_service_server_builder_option.h \
-    include/grpcpp/generic/async_generic_service.h \
-    include/grpcpp/generic/generic_stub.h \
-    include/grpcpp/grpcpp.h \
-    include/grpcpp/health_check_service_interface.h \
-    include/grpcpp/impl/call.h \
-    include/grpcpp/impl/channel_argument_option.h \
-    include/grpcpp/impl/client_unary_call.h \
-    include/grpcpp/impl/codegen/async_generic_service.h \
-    include/grpcpp/impl/codegen/async_stream.h \
-    include/grpcpp/impl/codegen/async_unary_call.h \
-    include/grpcpp/impl/codegen/byte_buffer.h \
-    include/grpcpp/impl/codegen/call.h \
-    include/grpcpp/impl/codegen/call_hook.h \
-    include/grpcpp/impl/codegen/call_op_set.h \
-    include/grpcpp/impl/codegen/call_op_set_interface.h \
-    include/grpcpp/impl/codegen/callback_common.h \
-    include/grpcpp/impl/codegen/channel_interface.h \
-    include/grpcpp/impl/codegen/client_callback.h \
-    include/grpcpp/impl/codegen/client_context.h \
-    include/grpcpp/impl/codegen/client_interceptor.h \
-    include/grpcpp/impl/codegen/client_unary_call.h \
-    include/grpcpp/impl/codegen/completion_queue.h \
-    include/grpcpp/impl/codegen/completion_queue_tag.h \
-    include/grpcpp/impl/codegen/config.h \
-    include/grpcpp/impl/codegen/config_protobuf.h \
-    include/grpcpp/impl/codegen/core_codegen.h \
-    include/grpcpp/impl/codegen/core_codegen_interface.h \
-    include/grpcpp/impl/codegen/create_auth_context.h \
-    include/grpcpp/impl/codegen/delegating_channel.h \
-    include/grpcpp/impl/codegen/grpc_library.h \
-    include/grpcpp/impl/codegen/intercepted_channel.h \
-    include/grpcpp/impl/codegen/interceptor.h \
-    include/grpcpp/impl/codegen/interceptor_common.h \
-    include/grpcpp/impl/codegen/message_allocator.h \
-    include/grpcpp/impl/codegen/metadata_map.h \
-    include/grpcpp/impl/codegen/method_handler.h \
-    include/grpcpp/impl/codegen/proto_buffer_reader.h \
-    include/grpcpp/impl/codegen/proto_buffer_writer.h \
-    include/grpcpp/impl/codegen/proto_utils.h \
-    include/grpcpp/impl/codegen/rpc_method.h \
-    include/grpcpp/impl/codegen/rpc_service_method.h \
-    include/grpcpp/impl/codegen/security/auth_context.h \
-    include/grpcpp/impl/codegen/serialization_traits.h \
-    include/grpcpp/impl/codegen/server_callback.h \
-    include/grpcpp/impl/codegen/server_callback_handlers.h \
-    include/grpcpp/impl/codegen/server_context.h \
-    include/grpcpp/impl/codegen/server_interceptor.h \
-    include/grpcpp/impl/codegen/server_interface.h \
-    include/grpcpp/impl/codegen/service_type.h \
-    include/grpcpp/impl/codegen/slice.h \
-    include/grpcpp/impl/codegen/status.h \
-    include/grpcpp/impl/codegen/status_code_enum.h \
-    include/grpcpp/impl/codegen/string_ref.h \
-    include/grpcpp/impl/codegen/stub_options.h \
-    include/grpcpp/impl/codegen/sync.h \
-    include/grpcpp/impl/codegen/sync_stream.h \
-    include/grpcpp/impl/codegen/time.h \
-    include/grpcpp/impl/grpc_library.h \
-    include/grpcpp/impl/method_handler_impl.h \
-    include/grpcpp/impl/rpc_method.h \
-    include/grpcpp/impl/rpc_service_method.h \
-    include/grpcpp/impl/serialization_traits.h \
-    include/grpcpp/impl/server_builder_option.h \
-    include/grpcpp/impl/server_builder_plugin.h \
-    include/grpcpp/impl/server_initializer.h \
-    include/grpcpp/impl/service_type.h \
-    include/grpcpp/resource_quota.h \
-    include/grpcpp/security/auth_context.h \
-    include/grpcpp/security/auth_metadata_processor.h \
-    include/grpcpp/security/credentials.h \
-    include/grpcpp/security/server_credentials.h \
-    include/grpcpp/security/tls_certificate_provider.h \
-    include/grpcpp/security/tls_credentials_options.h \
-    include/grpcpp/server.h \
-    include/grpcpp/server_builder.h \
-    include/grpcpp/server_context.h \
-    include/grpcpp/server_posix.h \
-    include/grpcpp/support/async_stream.h \
-    include/grpcpp/support/async_unary_call.h \
-    include/grpcpp/support/byte_buffer.h \
-    include/grpcpp/support/channel_arguments.h \
-    include/grpcpp/support/client_callback.h \
-    include/grpcpp/support/client_interceptor.h \
-    include/grpcpp/support/config.h \
-    include/grpcpp/support/interceptor.h \
-    include/grpcpp/support/message_allocator.h \
-    include/grpcpp/support/method_handler.h \
-    include/grpcpp/support/proto_buffer_reader.h \
-    include/grpcpp/support/proto_buffer_writer.h \
-    include/grpcpp/support/server_callback.h \
-    include/grpcpp/support/server_interceptor.h \
-    include/grpcpp/support/slice.h \
-    include/grpcpp/support/status.h \
-    include/grpcpp/support/status_code_enum.h \
-    include/grpcpp/support/string_ref.h \
-    include/grpcpp/support/stub_options.h \
-    include/grpcpp/support/sync_stream.h \
-    include/grpcpp/support/time.h \
-    include/grpcpp/support/validate_service_config.h \
-
-LIBGRPC++_UNSECURE_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBGRPC++_UNSECURE_SRC))))
-
-
-ifeq ($(NO_PROTOBUF),true)
-
-# You can't build a C++ library if you don't have protobuf - a bit overreached, but still okay.
-
-$(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a: protobuf_dep_error
-
-$(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)grpc++_unsecure$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP): protobuf_dep_error
+$(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)grpc$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE): openssl_dep_error
 
 else
 
-$(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a: $(ZLIB_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(RE2_DEP) $(UPB_DEP) $(GRPC_ABSEIL_DEP)  $(PROTOBUF_DEP) $(LIBGRPC++_UNSECURE_OBJS)  $(LIBGPR_OBJS)  $(LIBGRPC_ABSEIL_OBJS)  $(ZLIB_MERGE_OBJS)  $(CARES_MERGE_OBJS)  $(ADDRESS_SORTING_MERGE_OBJS)  $(RE2_MERGE_OBJS)  $(UPB_MERGE_OBJS) 
+$(LIBDIR)/$(CONFIG)/libgrpc.a: $(ZLIB_DEP) $(OPENSSL_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(RE2_DEP) $(UPB_DEP) $(GRPC_ABSEIL_DEP)  $(LIBGRPC_OBJS)  $(LIBGPR_OBJS)  $(LIBGRPC_ABSEIL_OBJS)  $(ZLIB_MERGE_OBJS)  $(CARES_MERGE_OBJS)  $(ADDRESS_SORTING_MERGE_OBJS)  $(RE2_MERGE_OBJS)  $(UPB_MERGE_OBJS)  $(OPENSSL_MERGE_OBJS) 
        $(E) "[AR]      Creating $@"
        $(Q) mkdir -p `dirname $@`
-       $(Q) rm -f $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a
-       $(Q) $(AR) $(ARFLAGS) $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBGRPC++_UNSECURE_OBJS)  $(LIBGPR_OBJS)  $(LIBGRPC_ABSEIL_OBJS)  $(ZLIB_MERGE_OBJS)  $(CARES_MERGE_OBJS)  $(ADDRESS_SORTING_MERGE_OBJS)  $(RE2_MERGE_OBJS)  $(UPB_MERGE_OBJS) 
+       $(Q) rm -f $(LIBDIR)/$(CONFIG)/libgrpc.a
+       $(Q) $(AR) $(ARFLAGS) $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBGRPC_OBJS)  $(LIBGPR_OBJS)  $(LIBGRPC_ABSEIL_OBJS)  $(ZLIB_MERGE_OBJS)  $(CARES_MERGE_OBJS)  $(ADDRESS_SORTING_MERGE_OBJS)  $(RE2_MERGE_OBJS)  $(UPB_MERGE_OBJS)  $(OPENSSL_MERGE_OBJS) 
 ifeq ($(SYSTEM),Darwin)
-       $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a
+       $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libgrpc.a
 endif
 
 
 
 ifeq ($(SYSTEM),MINGW32)
-$(LIBDIR)/$(CONFIG)/grpc++_unsecure$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP): $(LIBGRPC++_UNSECURE_OBJS)  $(ZLIB_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(RE2_DEP) $(UPB_DEP) $(GRPC_ABSEIL_DEP) $(PROTOBUF_DEP) $(LIBDIR)/$(CONFIG)/grpc_unsecure$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBDIR)/$(CONFIG)/gpr$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBDIR)/$(CONFIG)/address_sorting$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBDIR)/$(CONFIG)/upb$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE)
+$(LIBDIR)/$(CONFIG)/grpc$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE): $(LIBGRPC_OBJS)  $(ZLIB_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(RE2_DEP) $(UPB_DEP) $(GRPC_ABSEIL_DEP) $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libaddress_sorting.a $(LIBDIR)/$(CONFIG)/libupb.a $(OPENSSL_DEP)
        $(E) "[LD]      Linking $@"
        $(Q) mkdir -p `dirname $@`
-       $(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,--output-def=$(LIBDIR)/$(CONFIG)/grpc++_unsecure$(SHARED_VERSION_CPP).def -Wl,--out-implib=$(LIBDIR)/$(CONFIG)/libgrpc++_unsecure$(SHARED_VERSION_CPP)-dll.a -o $(LIBDIR)/$(CONFIG)/grpc++_unsecure$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBGRPC++_UNSECURE_OBJS) $(ZLIB_MERGE_LIBS) $(CARES_MERGE_LIBS) $(ADDRESS_SORTING_MERGE_LIBS) $(RE2_MERGE_LIBS) $(UPB_MERGE_LIBS) $(GRPC_ABSEIL_MERGE_LIBS) $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) -lgrpc_unsecure$(SHARED_VERSION_CORE)-dll -lgpr$(SHARED_VERSION_CORE)-dll -laddress_sorting$(SHARED_VERSION_CORE)-dll -lupb$(SHARED_VERSION_CORE)-dll
+       $(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,--output-def=$(LIBDIR)/$(CONFIG)/grpc$(SHARED_VERSION_CORE).def -Wl,--out-implib=$(LIBDIR)/$(CONFIG)/libgrpc$(SHARED_VERSION_CORE)-dll.a -o $(LIBDIR)/$(CONFIG)/grpc$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBGRPC_OBJS) $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libaddress_sorting.a $(LIBDIR)/$(CONFIG)/libupb.a $(OPENSSL_MERGE_LIBS) $(LDLIBS_SECURE) $(ZLIB_MERGE_LIBS) $(CARES_MERGE_LIBS) $(ADDRESS_SORTING_MERGE_LIBS) $(RE2_MERGE_LIBS) $(UPB_MERGE_LIBS) $(GRPC_ABSEIL_MERGE_LIBS) $(LDLIBS)
 else
-$(LIBDIR)/$(CONFIG)/libgrpc++_unsecure$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP): $(LIBGRPC++_UNSECURE_OBJS)  $(ZLIB_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(RE2_DEP) $(UPB_DEP) $(GRPC_ABSEIL_DEP) $(PROTOBUF_DEP) $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.$(SHARED_EXT_CORE) $(LIBDIR)/$(CONFIG)/libgpr.$(SHARED_EXT_CORE) $(LIBDIR)/$(CONFIG)/libaddress_sorting.$(SHARED_EXT_CORE) $(LIBDIR)/$(CONFIG)/libupb.$(SHARED_EXT_CORE)
+$(LIBDIR)/$(CONFIG)/libgrpc$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE): $(LIBGRPC_OBJS)  $(ZLIB_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(RE2_DEP) $(UPB_DEP) $(GRPC_ABSEIL_DEP) $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libaddress_sorting.a $(LIBDIR)/$(CONFIG)/libupb.a $(OPENSSL_DEP)
        $(E) "[LD]      Linking $@"
        $(Q) mkdir -p `dirname $@`
 ifeq ($(SYSTEM),Darwin)
-       $(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -install_name $(SHARED_PREFIX)grpc++_unsecure$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) -dynamiclib -o $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBGRPC++_UNSECURE_OBJS) $(ZLIB_MERGE_LIBS) $(CARES_MERGE_LIBS) $(ADDRESS_SORTING_MERGE_LIBS) $(RE2_MERGE_LIBS) $(UPB_MERGE_LIBS) $(GRPC_ABSEIL_MERGE_LIBS) $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) -lgrpc_unsecure -lgpr -laddress_sorting -lupb
+       $(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -install_name $(SHARED_PREFIX)grpc$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) -dynamiclib -o $(LIBDIR)/$(CONFIG)/libgrpc$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBGRPC_OBJS) $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libaddress_sorting.a $(LIBDIR)/$(CONFIG)/libupb.a $(OPENSSL_MERGE_LIBS) $(LDLIBS_SECURE) $(ZLIB_MERGE_LIBS) $(CARES_MERGE_LIBS) $(ADDRESS_SORTING_MERGE_LIBS) $(RE2_MERGE_LIBS) $(UPB_MERGE_LIBS) $(GRPC_ABSEIL_MERGE_LIBS) $(LDLIBS)
 else
-       $(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,-soname,libgrpc++_unsecure.so.1 -o $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBGRPC++_UNSECURE_OBJS) $(ZLIB_MERGE_LIBS) $(CARES_MERGE_LIBS) $(ADDRESS_SORTING_MERGE_LIBS) $(RE2_MERGE_LIBS) $(UPB_MERGE_LIBS) $(GRPC_ABSEIL_MERGE_LIBS) $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) -lgrpc_unsecure -lgpr -laddress_sorting -lupb
-       $(Q) ln -sf $(SHARED_PREFIX)grpc++_unsecure$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure$(SHARED_VERSION_CPP).so.1
-       $(Q) ln -sf $(SHARED_PREFIX)grpc++_unsecure$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure$(SHARED_VERSION_CPP).so
+       $(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,-soname,libgrpc.so.14 -o $(LIBDIR)/$(CONFIG)/libgrpc$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBGRPC_OBJS) $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libaddress_sorting.a $(LIBDIR)/$(CONFIG)/libupb.a $(OPENSSL_MERGE_LIBS) $(LDLIBS_SECURE) $(ZLIB_MERGE_LIBS) $(CARES_MERGE_LIBS) $(ADDRESS_SORTING_MERGE_LIBS) $(RE2_MERGE_LIBS) $(UPB_MERGE_LIBS) $(GRPC_ABSEIL_MERGE_LIBS) $(LDLIBS)
+       $(Q) ln -sf $(SHARED_PREFIX)grpc$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBDIR)/$(CONFIG)/libgrpc$(SHARED_VERSION_CORE).so.14
+       $(Q) ln -sf $(SHARED_PREFIX)grpc$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBDIR)/$(CONFIG)/libgrpc$(SHARED_VERSION_CORE).so
 endif
 endif
 
 endif
 
+ifneq ($(NO_SECURE),true)
 ifneq ($(NO_DEPS),true)
--include $(LIBGRPC++_UNSECURE_OBJS:.o=.dep)
+-include $(LIBGRPC_OBJS:.o=.dep)
 endif
-# end of build recipe for library "grpc++_unsecure"
+endif
+# end of build recipe for library "grpc"
 
 
-# start of build recipe for library "grpc_plugin_support" (generated by makelib(lib) template function)
-LIBGRPC_PLUGIN_SUPPORT_SRC = \
-    src/compiler/cpp_generator.cc \
-    src/compiler/csharp_generator.cc \
-    src/compiler/node_generator.cc \
-    src/compiler/objective_c_generator.cc \
-    src/compiler/php_generator.cc \
-    src/compiler/python_generator.cc \
-    src/compiler/ruby_generator.cc \
+# start of build recipe for library "grpc_csharp_ext" (generated by makelib(lib) template function)
+LIBGRPC_CSHARP_EXT_SRC = \
+    src/csharp/ext/grpc_csharp_ext.c \
 
-PUBLIC_HEADERS_CXX += \
-    include/grpc++/impl/codegen/config_protobuf.h \
-    include/grpcpp/impl/codegen/config_protobuf.h \
+PUBLIC_HEADERS_C += \
 
-LIBGRPC_PLUGIN_SUPPORT_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBGRPC_PLUGIN_SUPPORT_SRC))))
+LIBGRPC_CSHARP_EXT_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBGRPC_CSHARP_EXT_SRC))))
 
 
-ifeq ($(NO_PROTOBUF),true)
+ifeq ($(NO_SECURE),true)
 
-# You can't build a C++ library if you don't have protobuf - a bit overreached, but still okay.
+# You can't build secure libraries if you don't have OpenSSL.
 
-$(LIBDIR)/$(CONFIG)/libgrpc_plugin_support.a: protobuf_dep_error
+$(LIBDIR)/$(CONFIG)/libgrpc_csharp_ext.a: openssl_dep_error
 
+$(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)grpc_csharp_ext$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE): openssl_dep_error
 
 else
 
-$(LIBDIR)/$(CONFIG)/libgrpc_plugin_support.a: $(ZLIB_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(RE2_DEP) $(UPB_DEP) $(GRPC_ABSEIL_DEP)  $(PROTOBUF_DEP) $(LIBGRPC_PLUGIN_SUPPORT_OBJS) 
+$(LIBDIR)/$(CONFIG)/libgrpc_csharp_ext.a: $(ZLIB_DEP) $(OPENSSL_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(RE2_DEP) $(UPB_DEP) $(GRPC_ABSEIL_DEP)  $(LIBGRPC_CSHARP_EXT_OBJS) 
        $(E) "[AR]      Creating $@"
        $(Q) mkdir -p `dirname $@`
-       $(Q) rm -f $(LIBDIR)/$(CONFIG)/libgrpc_plugin_support.a
-       $(Q) $(AR) $(ARFLAGS) $(LIBDIR)/$(CONFIG)/libgrpc_plugin_support.a $(LIBGRPC_PLUGIN_SUPPORT_OBJS) 
+       $(Q) rm -f $(LIBDIR)/$(CONFIG)/libgrpc_csharp_ext.a
+       $(Q) $(AR) $(ARFLAGS) $(LIBDIR)/$(CONFIG)/libgrpc_csharp_ext.a $(LIBGRPC_CSHARP_EXT_OBJS) 
 ifeq ($(SYSTEM),Darwin)
-       $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libgrpc_plugin_support.a
+       $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libgrpc_csharp_ext.a
 endif
 
 
 
+ifeq ($(SYSTEM),MINGW32)
+$(LIBDIR)/$(CONFIG)/grpc_csharp_ext$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE): $(LIBGRPC_CSHARP_EXT_OBJS)  $(ZLIB_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(RE2_DEP) $(UPB_DEP) $(GRPC_ABSEIL_DEP) $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libaddress_sorting.a $(LIBDIR)/$(CONFIG)/libupb.a $(OPENSSL_DEP)
+       $(E) "[LD]      Linking $@"
+       $(Q) mkdir -p `dirname $@`
+       $(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,--output-def=$(LIBDIR)/$(CONFIG)/grpc_csharp_ext$(SHARED_VERSION_CORE).def -Wl,--out-implib=$(LIBDIR)/$(CONFIG)/libgrpc_csharp_ext$(SHARED_VERSION_CORE)-dll.a -o $(LIBDIR)/$(CONFIG)/grpc_csharp_ext$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBGRPC_CSHARP_EXT_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libaddress_sorting.a $(LIBDIR)/$(CONFIG)/libupb.a $(ZLIB_MERGE_LIBS) $(CARES_MERGE_LIBS) $(ADDRESS_SORTING_MERGE_LIBS) $(RE2_MERGE_LIBS) $(UPB_MERGE_LIBS) $(GRPC_ABSEIL_MERGE_LIBS) $(LDLIBS)
+else
+$(LIBDIR)/$(CONFIG)/libgrpc_csharp_ext$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE): $(LIBGRPC_CSHARP_EXT_OBJS)  $(ZLIB_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(RE2_DEP) $(UPB_DEP) $(GRPC_ABSEIL_DEP) $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libaddress_sorting.a $(LIBDIR)/$(CONFIG)/libupb.a $(OPENSSL_DEP)
+       $(E) "[LD]      Linking $@"
+       $(Q) mkdir -p `dirname $@`
+ifeq ($(SYSTEM),Darwin)
+       $(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -install_name $(SHARED_PREFIX)grpc_csharp_ext$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) -dynamiclib -o $(LIBDIR)/$(CONFIG)/libgrpc_csharp_ext$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBGRPC_CSHARP_EXT_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libaddress_sorting.a $(LIBDIR)/$(CONFIG)/libupb.a $(ZLIB_MERGE_LIBS) $(CARES_MERGE_LIBS) $(ADDRESS_SORTING_MERGE_LIBS) $(RE2_MERGE_LIBS) $(UPB_MERGE_LIBS) $(GRPC_ABSEIL_MERGE_LIBS) $(LDLIBS)
+else
+       $(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,-soname,libgrpc_csharp_ext.so.14 -o $(LIBDIR)/$(CONFIG)/libgrpc_csharp_ext$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBGRPC_CSHARP_EXT_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libaddress_sorting.a $(LIBDIR)/$(CONFIG)/libupb.a $(ZLIB_MERGE_LIBS) $(CARES_MERGE_LIBS) $(ADDRESS_SORTING_MERGE_LIBS) $(RE2_MERGE_LIBS) $(UPB_MERGE_LIBS) $(GRPC_ABSEIL_MERGE_LIBS) $(LDLIBS)
+       $(Q) ln -sf $(SHARED_PREFIX)grpc_csharp_ext$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBDIR)/$(CONFIG)/libgrpc_csharp_ext$(SHARED_VERSION_CORE).so.14
+       $(Q) ln -sf $(SHARED_PREFIX)grpc_csharp_ext$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBDIR)/$(CONFIG)/libgrpc_csharp_ext$(SHARED_VERSION_CORE).so
+endif
+endif
 
 endif
 
+ifneq ($(NO_SECURE),true)
 ifneq ($(NO_DEPS),true)
--include $(LIBGRPC_PLUGIN_SUPPORT_OBJS:.o=.dep)
+-include $(LIBGRPC_CSHARP_EXT_OBJS:.o=.dep)
 endif
-# end of build recipe for library "grpc_plugin_support"
-
-
-# start of build recipe for library "grpcpp_channelz" (generated by makelib(lib) template function)
-LIBGRPCPP_CHANNELZ_SRC = \
-    $(GENDIR)/src/proto/grpc/channelz/channelz.pb.cc $(GENDIR)/src/proto/grpc/channelz/channelz.grpc.pb.cc \
-    src/cpp/server/channelz/channelz_service.cc \
-    src/cpp/server/channelz/channelz_service_plugin.cc \
-
-PUBLIC_HEADERS_CXX += \
-    include/grpcpp/ext/channelz_service_plugin.h \
-
-LIBGRPCPP_CHANNELZ_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBGRPCPP_CHANNELZ_SRC))))
-
-
-ifeq ($(NO_SECURE),true)
-
-# You can't build secure libraries if you don't have OpenSSL.
-
-$(LIBDIR)/$(CONFIG)/libgrpcpp_channelz.a: openssl_dep_error
-
-$(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)grpcpp_channelz$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP): openssl_dep_error
-
-else
+endif
+# end of build recipe for library "grpc_csharp_ext"
 
-ifeq ($(NO_PROTOBUF),true)
 
-# You can't build a C++ library if you don't have protobuf - a bit overreached, but still okay.
+# start of build recipe for library "grpc_unsecure" (generated by makelib(lib) template function)
+LIBGRPC_UNSECURE_SRC = \
+    src/core/ext/filters/census/grpc_context.cc \
+    src/core/ext/filters/client_channel/backend_metric.cc \
+    src/core/ext/filters/client_channel/backup_poller.cc \
+    src/core/ext/filters/client_channel/channel_connectivity.cc \
+    src/core/ext/filters/client_channel/client_channel.cc \
+    src/core/ext/filters/client_channel/client_channel_channelz.cc \
+    src/core/ext/filters/client_channel/client_channel_factory.cc \
+    src/core/ext/filters/client_channel/client_channel_plugin.cc \
+    src/core/ext/filters/client_channel/config_selector.cc \
+    src/core/ext/filters/client_channel/dynamic_filters.cc \
+    src/core/ext/filters/client_channel/global_subchannel_pool.cc \
+    src/core/ext/filters/client_channel/health/health_check_client.cc \
+    src/core/ext/filters/client_channel/http_connect_handshaker.cc \
+    src/core/ext/filters/client_channel/http_proxy.cc \
+    src/core/ext/filters/client_channel/lb_policy.cc \
+    src/core/ext/filters/client_channel/lb_policy/address_filtering.cc \
+    src/core/ext/filters/client_channel/lb_policy/child_policy_handler.cc \
+    src/core/ext/filters/client_channel/lb_policy/grpclb/client_load_reporting_filter.cc \
+    src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc \
+    src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_balancer_addresses.cc \
+    src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel.cc \
+    src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.cc \
+    src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.cc \
+    src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc \
+    src/core/ext/filters/client_channel/lb_policy/priority/priority.cc \
+    src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc \
+    src/core/ext/filters/client_channel/lb_policy/weighted_target/weighted_target.cc \
+    src/core/ext/filters/client_channel/lb_policy_registry.cc \
+    src/core/ext/filters/client_channel/local_subchannel_pool.cc \
+    src/core/ext/filters/client_channel/proxy_mapper_registry.cc \
+    src/core/ext/filters/client_channel/resolver.cc \
+    src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc \
+    src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_libuv.cc \
+    src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_posix.cc \
+    src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_windows.cc \
+    src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc \
+    src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv.cc \
+    src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_posix.cc \
+    src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc \
+    src/core/ext/filters/client_channel/resolver/dns/dns_resolver_selection.cc \
+    src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc \
+    src/core/ext/filters/client_channel/resolver/fake/fake_resolver.cc \
+    src/core/ext/filters/client_channel/resolver/sockaddr/sockaddr_resolver.cc \
+    src/core/ext/filters/client_channel/resolver_registry.cc \
+    src/core/ext/filters/client_channel/resolver_result_parsing.cc \
+    src/core/ext/filters/client_channel/retry_throttle.cc \
+    src/core/ext/filters/client_channel/server_address.cc \
+    src/core/ext/filters/client_channel/service_config.cc \
+    src/core/ext/filters/client_channel/service_config_channel_arg_filter.cc \
+    src/core/ext/filters/client_channel/service_config_parser.cc \
+    src/core/ext/filters/client_channel/subchannel.cc \
+    src/core/ext/filters/client_channel/subchannel_pool_interface.cc \
+    src/core/ext/filters/client_idle/client_idle_filter.cc \
+    src/core/ext/filters/deadline/deadline_filter.cc \
+    src/core/ext/filters/http/client/http_client_filter.cc \
+    src/core/ext/filters/http/client_authority_filter.cc \
+    src/core/ext/filters/http/http_filters_plugin.cc \
+    src/core/ext/filters/http/message_compress/message_compress_filter.cc \
+    src/core/ext/filters/http/message_compress/message_decompress_filter.cc \
+    src/core/ext/filters/http/server/http_server_filter.cc \
+    src/core/ext/filters/max_age/max_age_filter.cc \
+    src/core/ext/filters/message_size/message_size_filter.cc \
+    src/core/ext/filters/workarounds/workaround_cronet_compression_filter.cc \
+    src/core/ext/filters/workarounds/workaround_utils.cc \
+    src/core/ext/transport/chttp2/alpn/alpn.cc \
+    src/core/ext/transport/chttp2/client/authority.cc \
+    src/core/ext/transport/chttp2/client/chttp2_connector.cc \
+    src/core/ext/transport/chttp2/client/insecure/channel_create.cc \
+    src/core/ext/transport/chttp2/client/insecure/channel_create_posix.cc \
+    src/core/ext/transport/chttp2/server/chttp2_server.cc \
+    src/core/ext/transport/chttp2/server/insecure/server_chttp2.cc \
+    src/core/ext/transport/chttp2/server/insecure/server_chttp2_posix.cc \
+    src/core/ext/transport/chttp2/transport/bin_decoder.cc \
+    src/core/ext/transport/chttp2/transport/bin_encoder.cc \
+    src/core/ext/transport/chttp2/transport/chttp2_plugin.cc \
+    src/core/ext/transport/chttp2/transport/chttp2_transport.cc \
+    src/core/ext/transport/chttp2/transport/context_list.cc \
+    src/core/ext/transport/chttp2/transport/flow_control.cc \
+    src/core/ext/transport/chttp2/transport/frame_data.cc \
+    src/core/ext/transport/chttp2/transport/frame_goaway.cc \
+    src/core/ext/transport/chttp2/transport/frame_ping.cc \
+    src/core/ext/transport/chttp2/transport/frame_rst_stream.cc \
+    src/core/ext/transport/chttp2/transport/frame_settings.cc \
+    src/core/ext/transport/chttp2/transport/frame_window_update.cc \
+    src/core/ext/transport/chttp2/transport/hpack_encoder.cc \
+    src/core/ext/transport/chttp2/transport/hpack_parser.cc \
+    src/core/ext/transport/chttp2/transport/hpack_table.cc \
+    src/core/ext/transport/chttp2/transport/http2_settings.cc \
+    src/core/ext/transport/chttp2/transport/huffsyms.cc \
+    src/core/ext/transport/chttp2/transport/incoming_metadata.cc \
+    src/core/ext/transport/chttp2/transport/parsing.cc \
+    src/core/ext/transport/chttp2/transport/stream_lists.cc \
+    src/core/ext/transport/chttp2/transport/stream_map.cc \
+    src/core/ext/transport/chttp2/transport/varint.cc \
+    src/core/ext/transport/chttp2/transport/writing.cc \
+    src/core/ext/transport/inproc/inproc_plugin.cc \
+    src/core/ext/transport/inproc/inproc_transport.cc \
+    src/core/ext/upb-generated/google/api/annotations.upb.c \
+    src/core/ext/upb-generated/google/api/expr/v1alpha1/checked.upb.c \
+    src/core/ext/upb-generated/google/api/expr/v1alpha1/syntax.upb.c \
+    src/core/ext/upb-generated/google/api/http.upb.c \
+    src/core/ext/upb-generated/google/protobuf/any.upb.c \
+    src/core/ext/upb-generated/google/protobuf/duration.upb.c \
+    src/core/ext/upb-generated/google/protobuf/empty.upb.c \
+    src/core/ext/upb-generated/google/protobuf/struct.upb.c \
+    src/core/ext/upb-generated/google/protobuf/timestamp.upb.c \
+    src/core/ext/upb-generated/google/protobuf/wrappers.upb.c \
+    src/core/ext/upb-generated/google/rpc/status.upb.c \
+    src/core/ext/upb-generated/src/proto/grpc/health/v1/health.upb.c \
+    src/core/ext/upb-generated/src/proto/grpc/lb/v1/load_balancer.upb.c \
+    src/core/ext/upb-generated/udpa/data/orca/v1/orca_load_report.upb.c \
+    src/core/ext/upb-generated/validate/validate.upb.c \
+    src/core/lib/avl/avl.cc \
+    src/core/lib/backoff/backoff.cc \
+    src/core/lib/channel/channel_args.cc \
+    src/core/lib/channel/channel_stack.cc \
+    src/core/lib/channel/channel_stack_builder.cc \
+    src/core/lib/channel/channel_trace.cc \
+    src/core/lib/channel/channelz.cc \
+    src/core/lib/channel/channelz_registry.cc \
+    src/core/lib/channel/connected_channel.cc \
+    src/core/lib/channel/handshaker.cc \
+    src/core/lib/channel/handshaker_registry.cc \
+    src/core/lib/channel/status_util.cc \
+    src/core/lib/compression/compression.cc \
+    src/core/lib/compression/compression_args.cc \
+    src/core/lib/compression/compression_internal.cc \
+    src/core/lib/compression/message_compress.cc \
+    src/core/lib/compression/stream_compression.cc \
+    src/core/lib/compression/stream_compression_gzip.cc \
+    src/core/lib/compression/stream_compression_identity.cc \
+    src/core/lib/debug/stats.cc \
+    src/core/lib/debug/stats_data.cc \
+    src/core/lib/debug/trace.cc \
+    src/core/lib/http/format_request.cc \
+    src/core/lib/http/httpcli.cc \
+    src/core/lib/http/parser.cc \
+    src/core/lib/iomgr/buffer_list.cc \
+    src/core/lib/iomgr/call_combiner.cc \
+    src/core/lib/iomgr/cfstream_handle.cc \
+    src/core/lib/iomgr/combiner.cc \
+    src/core/lib/iomgr/dualstack_socket_posix.cc \
+    src/core/lib/iomgr/endpoint.cc \
+    src/core/lib/iomgr/endpoint_cfstream.cc \
+    src/core/lib/iomgr/endpoint_pair_posix.cc \
+    src/core/lib/iomgr/endpoint_pair_uv.cc \
+    src/core/lib/iomgr/endpoint_pair_windows.cc \
+    src/core/lib/iomgr/error.cc \
+    src/core/lib/iomgr/error_cfstream.cc \
+    src/core/lib/iomgr/ev_apple.cc \
+    src/core/lib/iomgr/ev_epoll1_linux.cc \
+    src/core/lib/iomgr/ev_epollex_linux.cc \
+    src/core/lib/iomgr/ev_poll_posix.cc \
+    src/core/lib/iomgr/ev_posix.cc \
+    src/core/lib/iomgr/ev_windows.cc \
+    src/core/lib/iomgr/exec_ctx.cc \
+    src/core/lib/iomgr/executor.cc \
+    src/core/lib/iomgr/executor/mpmcqueue.cc \
+    src/core/lib/iomgr/executor/threadpool.cc \
+    src/core/lib/iomgr/fork_posix.cc \
+    src/core/lib/iomgr/fork_windows.cc \
+    src/core/lib/iomgr/gethostname_fallback.cc \
+    src/core/lib/iomgr/gethostname_host_name_max.cc \
+    src/core/lib/iomgr/gethostname_sysconf.cc \
+    src/core/lib/iomgr/grpc_if_nametoindex_posix.cc \
+    src/core/lib/iomgr/grpc_if_nametoindex_unsupported.cc \
+    src/core/lib/iomgr/internal_errqueue.cc \
+    src/core/lib/iomgr/iocp_windows.cc \
+    src/core/lib/iomgr/iomgr.cc \
+    src/core/lib/iomgr/iomgr_custom.cc \
+    src/core/lib/iomgr/iomgr_internal.cc \
+    src/core/lib/iomgr/iomgr_posix.cc \
+    src/core/lib/iomgr/iomgr_posix_cfstream.cc \
+    src/core/lib/iomgr/iomgr_uv.cc \
+    src/core/lib/iomgr/iomgr_windows.cc \
+    src/core/lib/iomgr/is_epollexclusive_available.cc \
+    src/core/lib/iomgr/load_file.cc \
+    src/core/lib/iomgr/lockfree_event.cc \
+    src/core/lib/iomgr/parse_address.cc \
+    src/core/lib/iomgr/poller/eventmanager_libuv.cc \
+    src/core/lib/iomgr/polling_entity.cc \
+    src/core/lib/iomgr/pollset.cc \
+    src/core/lib/iomgr/pollset_custom.cc \
+    src/core/lib/iomgr/pollset_set.cc \
+    src/core/lib/iomgr/pollset_set_custom.cc \
+    src/core/lib/iomgr/pollset_set_windows.cc \
+    src/core/lib/iomgr/pollset_uv.cc \
+    src/core/lib/iomgr/pollset_windows.cc \
+    src/core/lib/iomgr/resolve_address.cc \
+    src/core/lib/iomgr/resolve_address_custom.cc \
+    src/core/lib/iomgr/resolve_address_posix.cc \
+    src/core/lib/iomgr/resolve_address_windows.cc \
+    src/core/lib/iomgr/resource_quota.cc \
+    src/core/lib/iomgr/sockaddr_utils.cc \
+    src/core/lib/iomgr/socket_factory_posix.cc \
+    src/core/lib/iomgr/socket_mutator.cc \
+    src/core/lib/iomgr/socket_utils_common_posix.cc \
+    src/core/lib/iomgr/socket_utils_linux.cc \
+    src/core/lib/iomgr/socket_utils_posix.cc \
+    src/core/lib/iomgr/socket_utils_uv.cc \
+    src/core/lib/iomgr/socket_utils_windows.cc \
+    src/core/lib/iomgr/socket_windows.cc \
+    src/core/lib/iomgr/tcp_client.cc \
+    src/core/lib/iomgr/tcp_client_cfstream.cc \
+    src/core/lib/iomgr/tcp_client_custom.cc \
+    src/core/lib/iomgr/tcp_client_posix.cc \
+    src/core/lib/iomgr/tcp_client_windows.cc \
+    src/core/lib/iomgr/tcp_custom.cc \
+    src/core/lib/iomgr/tcp_posix.cc \
+    src/core/lib/iomgr/tcp_server.cc \
+    src/core/lib/iomgr/tcp_server_custom.cc \
+    src/core/lib/iomgr/tcp_server_posix.cc \
+    src/core/lib/iomgr/tcp_server_utils_posix_common.cc \
+    src/core/lib/iomgr/tcp_server_utils_posix_ifaddrs.cc \
+    src/core/lib/iomgr/tcp_server_utils_posix_noifaddrs.cc \
+    src/core/lib/iomgr/tcp_server_windows.cc \
+    src/core/lib/iomgr/tcp_uv.cc \
+    src/core/lib/iomgr/tcp_windows.cc \
+    src/core/lib/iomgr/time_averaged_stats.cc \
+    src/core/lib/iomgr/timer.cc \
+    src/core/lib/iomgr/timer_custom.cc \
+    src/core/lib/iomgr/timer_generic.cc \
+    src/core/lib/iomgr/timer_heap.cc \
+    src/core/lib/iomgr/timer_manager.cc \
+    src/core/lib/iomgr/timer_uv.cc \
+    src/core/lib/iomgr/udp_server.cc \
+    src/core/lib/iomgr/unix_sockets_posix.cc \
+    src/core/lib/iomgr/unix_sockets_posix_noop.cc \
+    src/core/lib/iomgr/wakeup_fd_eventfd.cc \
+    src/core/lib/iomgr/wakeup_fd_nospecial.cc \
+    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_reader.cc \
+    src/core/lib/json/json_util.cc \
+    src/core/lib/json/json_writer.cc \
+    src/core/lib/slice/b64.cc \
+    src/core/lib/slice/percent_encoding.cc \
+    src/core/lib/slice/slice.cc \
+    src/core/lib/slice/slice_buffer.cc \
+    src/core/lib/slice/slice_intern.cc \
+    src/core/lib/slice/slice_string_helpers.cc \
+    src/core/lib/surface/api_trace.cc \
+    src/core/lib/surface/byte_buffer.cc \
+    src/core/lib/surface/byte_buffer_reader.cc \
+    src/core/lib/surface/call.cc \
+    src/core/lib/surface/call_details.cc \
+    src/core/lib/surface/call_log_batch.cc \
+    src/core/lib/surface/channel.cc \
+    src/core/lib/surface/channel_init.cc \
+    src/core/lib/surface/channel_ping.cc \
+    src/core/lib/surface/channel_stack_type.cc \
+    src/core/lib/surface/completion_queue.cc \
+    src/core/lib/surface/completion_queue_factory.cc \
+    src/core/lib/surface/event_string.cc \
+    src/core/lib/surface/init.cc \
+    src/core/lib/surface/init_unsecure.cc \
+    src/core/lib/surface/lame_client.cc \
+    src/core/lib/surface/metadata_array.cc \
+    src/core/lib/surface/server.cc \
+    src/core/lib/surface/validate_metadata.cc \
+    src/core/lib/surface/version.cc \
+    src/core/lib/transport/authority_override.cc \
+    src/core/lib/transport/bdp_estimator.cc \
+    src/core/lib/transport/byte_stream.cc \
+    src/core/lib/transport/connectivity_state.cc \
+    src/core/lib/transport/error_utils.cc \
+    src/core/lib/transport/metadata.cc \
+    src/core/lib/transport/metadata_batch.cc \
+    src/core/lib/transport/pid_controller.cc \
+    src/core/lib/transport/static_metadata.cc \
+    src/core/lib/transport/status_conversion.cc \
+    src/core/lib/transport/status_metadata.cc \
+    src/core/lib/transport/timeout_encoding.cc \
+    src/core/lib/transport/transport.cc \
+    src/core/lib/transport/transport_op_string.cc \
+    src/core/lib/uri/uri_parser.cc \
+    src/core/plugin_registry/grpc_unsecure_plugin_registry.cc \
 
-$(LIBDIR)/$(CONFIG)/libgrpcpp_channelz.a: protobuf_dep_error
+PUBLIC_HEADERS_C += \
+    include/grpc/byte_buffer.h \
+    include/grpc/byte_buffer_reader.h \
+    include/grpc/census.h \
+    include/grpc/compression.h \
+    include/grpc/fork.h \
+    include/grpc/grpc.h \
+    include/grpc/grpc_posix.h \
+    include/grpc/grpc_security_constants.h \
+    include/grpc/load_reporting.h \
+    include/grpc/slice.h \
+    include/grpc/slice_buffer.h \
+    include/grpc/status.h \
+    include/grpc/support/workaround_list.h \
 
-$(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)grpcpp_channelz$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP): protobuf_dep_error
+LIBGRPC_UNSECURE_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBGRPC_UNSECURE_SRC))))
 
-else
 
-$(LIBDIR)/$(CONFIG)/libgrpcpp_channelz.a: $(ZLIB_DEP) $(OPENSSL_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(RE2_DEP) $(UPB_DEP) $(GRPC_ABSEIL_DEP)  $(PROTOBUF_DEP) $(LIBGRPCPP_CHANNELZ_OBJS) 
+$(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a: $(ZLIB_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(RE2_DEP) $(UPB_DEP) $(GRPC_ABSEIL_DEP)  $(LIBGRPC_UNSECURE_OBJS)  $(LIBGPR_OBJS)  $(LIBGRPC_ABSEIL_OBJS)  $(ZLIB_MERGE_OBJS)  $(CARES_MERGE_OBJS)  $(ADDRESS_SORTING_MERGE_OBJS)  $(RE2_MERGE_OBJS)  $(UPB_MERGE_OBJS) 
        $(E) "[AR]      Creating $@"
        $(Q) mkdir -p `dirname $@`
-       $(Q) rm -f $(LIBDIR)/$(CONFIG)/libgrpcpp_channelz.a
-       $(Q) $(AR) $(ARFLAGS) $(LIBDIR)/$(CONFIG)/libgrpcpp_channelz.a $(LIBGRPCPP_CHANNELZ_OBJS) 
+       $(Q) rm -f $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a
+       $(Q) $(AR) $(ARFLAGS) $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBGRPC_UNSECURE_OBJS)  $(LIBGPR_OBJS)  $(LIBGRPC_ABSEIL_OBJS)  $(ZLIB_MERGE_OBJS)  $(CARES_MERGE_OBJS)  $(ADDRESS_SORTING_MERGE_OBJS)  $(RE2_MERGE_OBJS)  $(UPB_MERGE_OBJS) 
 ifeq ($(SYSTEM),Darwin)
-       $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libgrpcpp_channelz.a
+       $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a
 endif
 
 
 
 ifeq ($(SYSTEM),MINGW32)
-$(LIBDIR)/$(CONFIG)/grpcpp_channelz$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP): $(LIBGRPCPP_CHANNELZ_OBJS)  $(ZLIB_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(RE2_DEP) $(UPB_DEP) $(GRPC_ABSEIL_DEP) $(PROTOBUF_DEP) $(LIBDIR)/$(CONFIG)/grpc++$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBDIR)/$(CONFIG)/grpc$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBDIR)/$(CONFIG)/gpr$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBDIR)/$(CONFIG)/address_sorting$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBDIR)/$(CONFIG)/upb$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(OPENSSL_DEP)
+$(LIBDIR)/$(CONFIG)/grpc_unsecure$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE): $(LIBGRPC_UNSECURE_OBJS)  $(ZLIB_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(RE2_DEP) $(UPB_DEP) $(GRPC_ABSEIL_DEP) $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libaddress_sorting.a $(LIBDIR)/$(CONFIG)/libupb.a
        $(E) "[LD]      Linking $@"
        $(Q) mkdir -p `dirname $@`
-       $(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,--output-def=$(LIBDIR)/$(CONFIG)/grpcpp_channelz$(SHARED_VERSION_CPP).def -Wl,--out-implib=$(LIBDIR)/$(CONFIG)/libgrpcpp_channelz$(SHARED_VERSION_CPP)-dll.a -o $(LIBDIR)/$(CONFIG)/grpcpp_channelz$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBGRPCPP_CHANNELZ_OBJS) $(ZLIB_MERGE_LIBS) $(CARES_MERGE_LIBS) $(ADDRESS_SORTING_MERGE_LIBS) $(RE2_MERGE_LIBS) $(UPB_MERGE_LIBS) $(GRPC_ABSEIL_MERGE_LIBS) $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) -lgrpc++$(SHARED_VERSION_CPP)-dll -lgrpc$(SHARED_VERSION_CORE)-dll -lgpr$(SHARED_VERSION_CORE)-dll -laddress_sorting$(SHARED_VERSION_CORE)-dll -lupb$(SHARED_VERSION_CORE)-dll
+       $(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,--output-def=$(LIBDIR)/$(CONFIG)/grpc_unsecure$(SHARED_VERSION_CORE).def -Wl,--out-implib=$(LIBDIR)/$(CONFIG)/libgrpc_unsecure$(SHARED_VERSION_CORE)-dll.a -o $(LIBDIR)/$(CONFIG)/grpc_unsecure$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBGRPC_UNSECURE_OBJS) $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libaddress_sorting.a $(LIBDIR)/$(CONFIG)/libupb.a $(ZLIB_MERGE_LIBS) $(CARES_MERGE_LIBS) $(ADDRESS_SORTING_MERGE_LIBS) $(RE2_MERGE_LIBS) $(UPB_MERGE_LIBS) $(GRPC_ABSEIL_MERGE_LIBS) $(LDLIBS)
 else
-$(LIBDIR)/$(CONFIG)/libgrpcpp_channelz$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP): $(LIBGRPCPP_CHANNELZ_OBJS)  $(ZLIB_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(RE2_DEP) $(UPB_DEP) $(GRPC_ABSEIL_DEP) $(PROTOBUF_DEP) $(LIBDIR)/$(CONFIG)/libgrpc++.$(SHARED_EXT_CPP) $(LIBDIR)/$(CONFIG)/libgrpc.$(SHARED_EXT_CORE) $(LIBDIR)/$(CONFIG)/libgpr.$(SHARED_EXT_CORE) $(LIBDIR)/$(CONFIG)/libaddress_sorting.$(SHARED_EXT_CORE) $(LIBDIR)/$(CONFIG)/libupb.$(SHARED_EXT_CORE) $(OPENSSL_DEP)
+$(LIBDIR)/$(CONFIG)/libgrpc_unsecure$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE): $(LIBGRPC_UNSECURE_OBJS)  $(ZLIB_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(RE2_DEP) $(UPB_DEP) $(GRPC_ABSEIL_DEP) $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libaddress_sorting.a $(LIBDIR)/$(CONFIG)/libupb.a
        $(E) "[LD]      Linking $@"
        $(Q) mkdir -p `dirname $@`
 ifeq ($(SYSTEM),Darwin)
-       $(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -install_name $(SHARED_PREFIX)grpcpp_channelz$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) -dynamiclib -o $(LIBDIR)/$(CONFIG)/libgrpcpp_channelz$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBGRPCPP_CHANNELZ_OBJS) $(ZLIB_MERGE_LIBS) $(CARES_MERGE_LIBS) $(ADDRESS_SORTING_MERGE_LIBS) $(RE2_MERGE_LIBS) $(UPB_MERGE_LIBS) $(GRPC_ABSEIL_MERGE_LIBS) $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) -lgrpc++ -lgrpc -lgpr -laddress_sorting -lupb
+       $(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -install_name $(SHARED_PREFIX)grpc_unsecure$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) -dynamiclib -o $(LIBDIR)/$(CONFIG)/libgrpc_unsecure$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBGRPC_UNSECURE_OBJS) $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libaddress_sorting.a $(LIBDIR)/$(CONFIG)/libupb.a $(ZLIB_MERGE_LIBS) $(CARES_MERGE_LIBS) $(ADDRESS_SORTING_MERGE_LIBS) $(RE2_MERGE_LIBS) $(UPB_MERGE_LIBS) $(GRPC_ABSEIL_MERGE_LIBS) $(LDLIBS)
 else
-       $(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,-soname,libgrpcpp_channelz.so.1 -o $(LIBDIR)/$(CONFIG)/libgrpcpp_channelz$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBGRPCPP_CHANNELZ_OBJS) $(ZLIB_MERGE_LIBS) $(CARES_MERGE_LIBS) $(ADDRESS_SORTING_MERGE_LIBS) $(RE2_MERGE_LIBS) $(UPB_MERGE_LIBS) $(GRPC_ABSEIL_MERGE_LIBS) $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) -lgrpc++ -lgrpc -lgpr -laddress_sorting -lupb
-       $(Q) ln -sf $(SHARED_PREFIX)grpcpp_channelz$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBDIR)/$(CONFIG)/libgrpcpp_channelz$(SHARED_VERSION_CPP).so.1
-       $(Q) ln -sf $(SHARED_PREFIX)grpcpp_channelz$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBDIR)/$(CONFIG)/libgrpcpp_channelz$(SHARED_VERSION_CPP).so
-endif
-endif
-
+       $(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,-soname,libgrpc_unsecure.so.14 -o $(LIBDIR)/$(CONFIG)/libgrpc_unsecure$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBGRPC_UNSECURE_OBJS) $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libaddress_sorting.a $(LIBDIR)/$(CONFIG)/libupb.a $(ZLIB_MERGE_LIBS) $(CARES_MERGE_LIBS) $(ADDRESS_SORTING_MERGE_LIBS) $(RE2_MERGE_LIBS) $(UPB_MERGE_LIBS) $(GRPC_ABSEIL_MERGE_LIBS) $(LDLIBS)
+       $(Q) ln -sf $(SHARED_PREFIX)grpc_unsecure$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBDIR)/$(CONFIG)/libgrpc_unsecure$(SHARED_VERSION_CORE).so.14
+       $(Q) ln -sf $(SHARED_PREFIX)grpc_unsecure$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBDIR)/$(CONFIG)/libgrpc_unsecure$(SHARED_VERSION_CORE).so
 endif
-
 endif
 
-ifneq ($(NO_SECURE),true)
 ifneq ($(NO_DEPS),true)
--include $(LIBGRPCPP_CHANNELZ_OBJS:.o=.dep)
-endif
+-include $(LIBGRPC_UNSECURE_OBJS:.o=.dep)
 endif
-$(OBJDIR)/$(CONFIG)/src/cpp/server/channelz/channelz_service.o: $(GENDIR)/src/proto/grpc/channelz/channelz.pb.cc $(GENDIR)/src/proto/grpc/channelz/channelz.grpc.pb.cc
-$(OBJDIR)/$(CONFIG)/src/cpp/server/channelz/channelz_service_plugin.o: $(GENDIR)/src/proto/grpc/channelz/channelz.pb.cc $(GENDIR)/src/proto/grpc/channelz/channelz.grpc.pb.cc
-# end of build recipe for library "grpcpp_channelz"
+# end of build recipe for library "grpc_unsecure"
 
 
 # start of build recipe for library "boringssl" (generated by makelib(lib) template function)
@@ -4097,15 +2366,17 @@ endif
 
 # start of build recipe for library "upb" (generated by makelib(lib) template function)
 LIBUPB_SRC = \
+    third_party/upb/upb/decode_fast.c \
     third_party/upb/upb/decode.c \
+    third_party/upb/upb/def.c \
     third_party/upb/upb/encode.c \
+    third_party/upb/upb/json_decode.c \
+    third_party/upb/upb/json_encode.c \
     third_party/upb/upb/msg.c \
-    third_party/upb/upb/port.c \
-    third_party/upb/upb/table.c \
-    third_party/upb/upb/upb.c \
-    third_party/upb/upb/def.c \
     third_party/upb/upb/reflection.c \
+    third_party/upb/upb/table.c \
     third_party/upb/upb/text_encode.c \
+    third_party/upb/upb/upb.c \
     src/core/ext/upb-generated/google/protobuf/any.upb.c \
     src/core/ext/upb-generated/google/protobuf/descriptor.upb.c \
     src/core/ext/upb-generated/google/protobuf/duration.upb.c \
@@ -4184,6 +2455,7 @@ PUBLIC_HEADERS_C += \
 LIBZ_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBZ_SRC))))
 
 $(LIBZ_OBJS): CFLAGS += -fvisibility=hidden
+$(LIBZ_OBJS): CPPFLAGS += -DHAVE_UNISTD_H
 
 $(LIBDIR)/$(CONFIG)/libz.a:  $(LIBZ_OBJS) 
        $(E) "[AR]      Creating $@"
@@ -4311,6 +2583,7 @@ LIBGRPC_ABSEIL_SRC = \
     third_party/abseil-cpp/absl/numeric/int128.cc \
     third_party/abseil-cpp/absl/status/status.cc \
     third_party/abseil-cpp/absl/status/status_payload_printer.cc \
+    third_party/abseil-cpp/absl/status/statusor.cc \
     third_party/abseil-cpp/absl/strings/ascii.cc \
     third_party/abseil-cpp/absl/strings/charconv.cc \
     third_party/abseil-cpp/absl/strings/cord.cc \
@@ -4383,242 +2656,6 @@ endif
 # end of build recipe for library "grpc_abseil"
 
 
-# All of the test targets, and protoc plugins
-
-
-# start of build recipe for target "grpc_cpp_plugin" (generated by maketarget(tgt) template function)
-GRPC_CPP_PLUGIN_SRC = \
-    src/compiler/cpp_plugin.cc \
-
-GRPC_CPP_PLUGIN_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(GRPC_CPP_PLUGIN_SRC))))
-
-
-
-ifeq ($(NO_PROTOBUF),true)
-
-# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.12.0+.
-
-$(BINDIR)/$(CONFIG)/grpc_cpp_plugin: protobuf_dep_error
-
-else
-
-$(BINDIR)/$(CONFIG)/grpc_cpp_plugin: $(PROTOBUF_DEP) $(GRPC_CPP_PLUGIN_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_plugin_support.a
-       $(E) "[HOSTLD]  Linking $@"
-       $(Q) mkdir -p `dirname $@`
-       $(Q) $(HOST_LDXX) $(HOST_LDFLAGS) $(GRPC_CPP_PLUGIN_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_plugin_support.a $(HOST_LDLIBSXX) $(HOST_LDLIBS_PROTOC) $(HOST_LDLIBS) $(HOST_LDLIBS_PROTOC) -o $(BINDIR)/$(CONFIG)/grpc_cpp_plugin
-
-endif
-
-$(OBJDIR)/$(CONFIG)/src/compiler/cpp_plugin.o:  $(LIBDIR)/$(CONFIG)/libgrpc_plugin_support.a
-
-deps_grpc_cpp_plugin: $(GRPC_CPP_PLUGIN_OBJS:.o=.dep)
-
-ifneq ($(NO_DEPS),true)
--include $(GRPC_CPP_PLUGIN_OBJS:.o=.dep)
-endif
-# end of build recipe for target "grpc_cpp_plugin"
-
-
-# start of build recipe for target "grpc_csharp_plugin" (generated by maketarget(tgt) template function)
-GRPC_CSHARP_PLUGIN_SRC = \
-    src/compiler/csharp_plugin.cc \
-
-GRPC_CSHARP_PLUGIN_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(GRPC_CSHARP_PLUGIN_SRC))))
-
-
-
-ifeq ($(NO_PROTOBUF),true)
-
-# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.12.0+.
-
-$(BINDIR)/$(CONFIG)/grpc_csharp_plugin: protobuf_dep_error
-
-else
-
-$(BINDIR)/$(CONFIG)/grpc_csharp_plugin: $(PROTOBUF_DEP) $(GRPC_CSHARP_PLUGIN_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_plugin_support.a
-       $(E) "[HOSTLD]  Linking $@"
-       $(Q) mkdir -p `dirname $@`
-       $(Q) $(HOST_LDXX) $(HOST_LDFLAGS) $(GRPC_CSHARP_PLUGIN_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_plugin_support.a $(HOST_LDLIBSXX) $(HOST_LDLIBS_PROTOC) $(HOST_LDLIBS) $(HOST_LDLIBS_PROTOC) -o $(BINDIR)/$(CONFIG)/grpc_csharp_plugin
-
-endif
-
-$(OBJDIR)/$(CONFIG)/src/compiler/csharp_plugin.o:  $(LIBDIR)/$(CONFIG)/libgrpc_plugin_support.a
-
-deps_grpc_csharp_plugin: $(GRPC_CSHARP_PLUGIN_OBJS:.o=.dep)
-
-ifneq ($(NO_DEPS),true)
--include $(GRPC_CSHARP_PLUGIN_OBJS:.o=.dep)
-endif
-# end of build recipe for target "grpc_csharp_plugin"
-
-
-# start of build recipe for target "grpc_node_plugin" (generated by maketarget(tgt) template function)
-GRPC_NODE_PLUGIN_SRC = \
-    src/compiler/node_plugin.cc \
-
-GRPC_NODE_PLUGIN_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(GRPC_NODE_PLUGIN_SRC))))
-
-
-
-ifeq ($(NO_PROTOBUF),true)
-
-# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.12.0+.
-
-$(BINDIR)/$(CONFIG)/grpc_node_plugin: protobuf_dep_error
-
-else
-
-$(BINDIR)/$(CONFIG)/grpc_node_plugin: $(PROTOBUF_DEP) $(GRPC_NODE_PLUGIN_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_plugin_support.a
-       $(E) "[HOSTLD]  Linking $@"
-       $(Q) mkdir -p `dirname $@`
-       $(Q) $(HOST_LDXX) $(HOST_LDFLAGS) $(GRPC_NODE_PLUGIN_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_plugin_support.a $(HOST_LDLIBSXX) $(HOST_LDLIBS_PROTOC) $(HOST_LDLIBS) $(HOST_LDLIBS_PROTOC) -o $(BINDIR)/$(CONFIG)/grpc_node_plugin
-
-endif
-
-$(OBJDIR)/$(CONFIG)/src/compiler/node_plugin.o:  $(LIBDIR)/$(CONFIG)/libgrpc_plugin_support.a
-
-deps_grpc_node_plugin: $(GRPC_NODE_PLUGIN_OBJS:.o=.dep)
-
-ifneq ($(NO_DEPS),true)
--include $(GRPC_NODE_PLUGIN_OBJS:.o=.dep)
-endif
-# end of build recipe for target "grpc_node_plugin"
-
-
-# start of build recipe for target "grpc_objective_c_plugin" (generated by maketarget(tgt) template function)
-GRPC_OBJECTIVE_C_PLUGIN_SRC = \
-    src/compiler/objective_c_plugin.cc \
-
-GRPC_OBJECTIVE_C_PLUGIN_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(GRPC_OBJECTIVE_C_PLUGIN_SRC))))
-
-
-
-ifeq ($(NO_PROTOBUF),true)
-
-# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.12.0+.
-
-$(BINDIR)/$(CONFIG)/grpc_objective_c_plugin: protobuf_dep_error
-
-else
-
-$(BINDIR)/$(CONFIG)/grpc_objective_c_plugin: $(PROTOBUF_DEP) $(GRPC_OBJECTIVE_C_PLUGIN_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_plugin_support.a
-       $(E) "[HOSTLD]  Linking $@"
-       $(Q) mkdir -p `dirname $@`
-       $(Q) $(HOST_LDXX) $(HOST_LDFLAGS) $(GRPC_OBJECTIVE_C_PLUGIN_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_plugin_support.a $(HOST_LDLIBSXX) $(HOST_LDLIBS_PROTOC) $(HOST_LDLIBS) $(HOST_LDLIBS_PROTOC) -o $(BINDIR)/$(CONFIG)/grpc_objective_c_plugin
-
-endif
-
-$(OBJDIR)/$(CONFIG)/src/compiler/objective_c_plugin.o:  $(LIBDIR)/$(CONFIG)/libgrpc_plugin_support.a
-
-deps_grpc_objective_c_plugin: $(GRPC_OBJECTIVE_C_PLUGIN_OBJS:.o=.dep)
-
-ifneq ($(NO_DEPS),true)
--include $(GRPC_OBJECTIVE_C_PLUGIN_OBJS:.o=.dep)
-endif
-# end of build recipe for target "grpc_objective_c_plugin"
-
-
-# start of build recipe for target "grpc_php_plugin" (generated by maketarget(tgt) template function)
-GRPC_PHP_PLUGIN_SRC = \
-    src/compiler/php_plugin.cc \
-
-GRPC_PHP_PLUGIN_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(GRPC_PHP_PLUGIN_SRC))))
-
-
-
-ifeq ($(NO_PROTOBUF),true)
-
-# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.12.0+.
-
-$(BINDIR)/$(CONFIG)/grpc_php_plugin: protobuf_dep_error
-
-else
-
-$(BINDIR)/$(CONFIG)/grpc_php_plugin: $(PROTOBUF_DEP) $(GRPC_PHP_PLUGIN_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_plugin_support.a
-       $(E) "[HOSTLD]  Linking $@"
-       $(Q) mkdir -p `dirname $@`
-       $(Q) $(HOST_LDXX) $(HOST_LDFLAGS) $(GRPC_PHP_PLUGIN_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_plugin_support.a $(HOST_LDLIBSXX) $(HOST_LDLIBS_PROTOC) $(HOST_LDLIBS) $(HOST_LDLIBS_PROTOC) -o $(BINDIR)/$(CONFIG)/grpc_php_plugin
-
-endif
-
-$(OBJDIR)/$(CONFIG)/src/compiler/php_plugin.o:  $(LIBDIR)/$(CONFIG)/libgrpc_plugin_support.a
-
-deps_grpc_php_plugin: $(GRPC_PHP_PLUGIN_OBJS:.o=.dep)
-
-ifneq ($(NO_DEPS),true)
--include $(GRPC_PHP_PLUGIN_OBJS:.o=.dep)
-endif
-# end of build recipe for target "grpc_php_plugin"
-
-
-# start of build recipe for target "grpc_python_plugin" (generated by maketarget(tgt) template function)
-GRPC_PYTHON_PLUGIN_SRC = \
-    src/compiler/python_plugin.cc \
-
-GRPC_PYTHON_PLUGIN_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(GRPC_PYTHON_PLUGIN_SRC))))
-
-
-
-ifeq ($(NO_PROTOBUF),true)
-
-# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.12.0+.
-
-$(BINDIR)/$(CONFIG)/grpc_python_plugin: protobuf_dep_error
-
-else
-
-$(BINDIR)/$(CONFIG)/grpc_python_plugin: $(PROTOBUF_DEP) $(GRPC_PYTHON_PLUGIN_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_plugin_support.a
-       $(E) "[HOSTLD]  Linking $@"
-       $(Q) mkdir -p `dirname $@`
-       $(Q) $(HOST_LDXX) $(HOST_LDFLAGS) $(GRPC_PYTHON_PLUGIN_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_plugin_support.a $(HOST_LDLIBSXX) $(HOST_LDLIBS_PROTOC) $(HOST_LDLIBS) $(HOST_LDLIBS_PROTOC) -o $(BINDIR)/$(CONFIG)/grpc_python_plugin
-
-endif
-
-$(OBJDIR)/$(CONFIG)/src/compiler/python_plugin.o:  $(LIBDIR)/$(CONFIG)/libgrpc_plugin_support.a
-
-deps_grpc_python_plugin: $(GRPC_PYTHON_PLUGIN_OBJS:.o=.dep)
-
-ifneq ($(NO_DEPS),true)
--include $(GRPC_PYTHON_PLUGIN_OBJS:.o=.dep)
-endif
-# end of build recipe for target "grpc_python_plugin"
-
-
-# start of build recipe for target "grpc_ruby_plugin" (generated by maketarget(tgt) template function)
-GRPC_RUBY_PLUGIN_SRC = \
-    src/compiler/ruby_plugin.cc \
-
-GRPC_RUBY_PLUGIN_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(GRPC_RUBY_PLUGIN_SRC))))
-
-
-
-ifeq ($(NO_PROTOBUF),true)
-
-# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.12.0+.
-
-$(BINDIR)/$(CONFIG)/grpc_ruby_plugin: protobuf_dep_error
-
-else
-
-$(BINDIR)/$(CONFIG)/grpc_ruby_plugin: $(PROTOBUF_DEP) $(GRPC_RUBY_PLUGIN_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_plugin_support.a
-       $(E) "[HOSTLD]  Linking $@"
-       $(Q) mkdir -p `dirname $@`
-       $(Q) $(HOST_LDXX) $(HOST_LDFLAGS) $(GRPC_RUBY_PLUGIN_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_plugin_support.a $(HOST_LDLIBSXX) $(HOST_LDLIBS_PROTOC) $(HOST_LDLIBS) $(HOST_LDLIBS_PROTOC) -o $(BINDIR)/$(CONFIG)/grpc_ruby_plugin
-
-endif
-
-$(OBJDIR)/$(CONFIG)/src/compiler/ruby_plugin.o:  $(LIBDIR)/$(CONFIG)/libgrpc_plugin_support.a
-
-deps_grpc_ruby_plugin: $(GRPC_RUBY_PLUGIN_OBJS:.o=.dep)
-
-ifneq ($(NO_DEPS),true)
--include $(GRPC_RUBY_PLUGIN_OBJS:.o=.dep)
-endif
-# end of build recipe for target "grpc_ruby_plugin"
-
-
-
-
 
 
 # TODO(jtattermusch): is there a way to get around this hack?
@@ -4628,9 +2665,9 @@ ifneq ($(OPENSSL_DEP),)
 # otherwise parallel compilation will fail if a source is compiled first.
 src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel_secure.cc: $(OPENSSL_DEP)
 src/core/ext/filters/client_channel/lb_policy/xds/cds.cc: $(OPENSSL_DEP)
-src/core/ext/filters/client_channel/lb_policy/xds/eds.cc: $(OPENSSL_DEP)
 src/core/ext/filters/client_channel/lb_policy/xds/xds_cluster_impl.cc: $(OPENSSL_DEP)
 src/core/ext/filters/client_channel/lb_policy/xds/xds_cluster_manager.cc: $(OPENSSL_DEP)
+src/core/ext/filters/client_channel/lb_policy/xds/xds_cluster_resolver.cc: $(OPENSSL_DEP)
 src/core/ext/filters/client_channel/resolver/xds/xds_resolver.cc: $(OPENSSL_DEP)
 src/core/ext/transport/chttp2/client/secure/secure_channel_create.cc: $(OPENSSL_DEP)
 src/core/ext/transport/chttp2/server/secure/server_secure_chttp2.cc: $(OPENSSL_DEP)
@@ -4779,12 +2816,12 @@ src/core/ext/upbdefs-generated/validate/validate.upbdefs.c: $(OPENSSL_DEP)
 src/core/ext/xds/certificate_provider_registry.cc: $(OPENSSL_DEP)
 src/core/ext/xds/certificate_provider_store.cc: $(OPENSSL_DEP)
 src/core/ext/xds/file_watcher_certificate_provider_factory.cc: $(OPENSSL_DEP)
-src/core/ext/xds/google_mesh_ca_certificate_provider_factory.cc: $(OPENSSL_DEP)
 src/core/ext/xds/xds_api.cc: $(OPENSSL_DEP)
 src/core/ext/xds/xds_bootstrap.cc: $(OPENSSL_DEP)
 src/core/ext/xds/xds_certificate_provider.cc: $(OPENSSL_DEP)
 src/core/ext/xds/xds_client.cc: $(OPENSSL_DEP)
 src/core/ext/xds/xds_client_stats.cc: $(OPENSSL_DEP)
+src/core/ext/xds/xds_server_config_fetcher.cc: $(OPENSSL_DEP)
 src/core/lib/http/httpcli_security_connector.cc: $(OPENSSL_DEP)
 src/core/lib/security/authorization/authorization_engine.cc: $(OPENSSL_DEP)
 src/core/lib/security/authorization/evaluate_args.cc: $(OPENSSL_DEP)
@@ -4800,6 +2837,7 @@ src/core/lib/security/credentials/alts/grpc_alts_credentials_server_options.cc:
 src/core/lib/security/credentials/composite/composite_credentials.cc: $(OPENSSL_DEP)
 src/core/lib/security/credentials/credentials.cc: $(OPENSSL_DEP)
 src/core/lib/security/credentials/credentials_metadata.cc: $(OPENSSL_DEP)
+src/core/lib/security/credentials/external/aws_external_account_credentials.cc: $(OPENSSL_DEP)
 src/core/lib/security/credentials/external/aws_request_signer.cc: $(OPENSSL_DEP)
 src/core/lib/security/credentials/external/external_account_credentials.cc: $(OPENSSL_DEP)
 src/core/lib/security/credentials/external/file_external_account_credentials.cc: $(OPENSSL_DEP)
@@ -4820,6 +2858,7 @@ src/core/lib/security/credentials/tls/grpc_tls_certificate_distributor.cc: $(OPE
 src/core/lib/security/credentials/tls/grpc_tls_certificate_provider.cc: $(OPENSSL_DEP)
 src/core/lib/security/credentials/tls/grpc_tls_credentials_options.cc: $(OPENSSL_DEP)
 src/core/lib/security/credentials/tls/tls_credentials.cc: $(OPENSSL_DEP)
+src/core/lib/security/credentials/tls/tls_utils.cc: $(OPENSSL_DEP)
 src/core/lib/security/credentials/xds/xds_credentials.cc: $(OPENSSL_DEP)
 src/core/lib/security/security_connector/alts/alts_security_connector.cc: $(OPENSSL_DEP)
 src/core/lib/security/security_connector/fake/fake_security_connector.cc: $(OPENSSL_DEP)
@@ -4867,23 +2906,6 @@ src/core/tsi/ssl/session_cache/ssl_session_openssl.cc: $(OPENSSL_DEP)
 src/core/tsi/ssl_transport_security.cc: $(OPENSSL_DEP)
 src/core/tsi/transport_security.cc: $(OPENSSL_DEP)
 src/core/tsi/transport_security_grpc.cc: $(OPENSSL_DEP)
-src/cpp/client/secure_credentials.cc: $(OPENSSL_DEP)
-src/cpp/client/xds_credentials.cc: $(OPENSSL_DEP)
-src/cpp/common/alts_context.cc: $(OPENSSL_DEP)
-src/cpp/common/alts_util.cc: $(OPENSSL_DEP)
-src/cpp/common/auth_property_iterator.cc: $(OPENSSL_DEP)
-src/cpp/common/secure_auth_context.cc: $(OPENSSL_DEP)
-src/cpp/common/secure_channel_arguments.cc: $(OPENSSL_DEP)
-src/cpp/common/secure_create_auth_context.cc: $(OPENSSL_DEP)
-src/cpp/common/tls_certificate_provider.cc: $(OPENSSL_DEP)
-src/cpp/common/tls_credentials_options.cc: $(OPENSSL_DEP)
-src/cpp/common/tls_credentials_options_util.cc: $(OPENSSL_DEP)
-src/cpp/ext/proto_server_reflection.cc: $(OPENSSL_DEP)
-src/cpp/ext/proto_server_reflection_plugin.cc: $(OPENSSL_DEP)
-src/cpp/server/channelz/channelz_service.cc: $(OPENSSL_DEP)
-src/cpp/server/channelz/channelz_service_plugin.cc: $(OPENSSL_DEP)
-src/cpp/server/secure_server_credentials.cc: $(OPENSSL_DEP)
-src/cpp/util/error_details.cc: $(OPENSSL_DEP)
 src/csharp/ext/grpc_csharp_ext.c: $(OPENSSL_DEP)
 endif
 
index bad56df..c4cb314 100755 (executable)
--- a/Rakefile
+++ b/Rakefile
@@ -121,7 +121,7 @@ task 'gem:native' do
   verbose = ENV['V'] || '0'
 
   grpc_config = ENV['GRPC_CONFIG'] || 'opt'
-  ruby_cc_versions = '2.7.0:2.6.0:2.5.0:2.4.0:2.3.0'
+  ruby_cc_versions = ['3.0.0', '2.7.0', '2.6.0', '2.5.0', '2.4.0', '2.3.0'].join(':')
 
   if RUBY_PLATFORM =~ /darwin/
     FileUtils.touch 'grpc_c.32.ruby'
@@ -139,20 +139,22 @@ task 'gem:native' do
         gem update --system --no-document && \
         bundle && \
         rake native:#{plat} pkg/#{spec.full_name}-#{plat}.gem pkg/#{spec.full_name}.gem \
-          RUBY_CC_VERSION=#{ruby_cc_versions} V=#{verbose} GRPC_CONFIG=#{grpc_config}
+          RUBY_CC_VERSION=#{ruby_cc_versions} \
+          V=#{verbose} \
+          GRPC_CONFIG=#{grpc_config}
       EOT
     end
     # Truncate grpc_c.*.ruby files because they're for Windows only.
     File.truncate('grpc_c.32.ruby', 0)
     File.truncate('grpc_c.64.ruby', 0)
     ['x86_64-linux', 'x86-linux'].each do |plat|
-      run_rake_compiler plat,  <<-EOT
+      run_rake_compiler plat, <<-EOT
         gem update --system --no-document && \
         bundle && \
         rake native:#{plat} pkg/#{spec.full_name}-#{plat}.gem pkg/#{spec.full_name}.gem \
-          RUBY_CC_VERSION=#{ruby_cc_versions} V=#{verbose} GRPC_CONFIG=#{grpc_config} &&
-        sudo chmod -R a+rw pkg &&
-        patchelf_gem.sh pkg/#{spec.full_name}-#{plat}.gem
+          RUBY_CC_VERSION=#{ruby_cc_versions} \
+          V=#{verbose} \
+          GRPC_CONFIG=#{grpc_config}
       EOT
     end
   end
index 0ef4102..0d13c28 100644 (file)
@@ -22,6 +22,11 @@ def grpc_deps():
     )
 
     native.bind(
+        name = "upb_json_lib",
+        actual = "@upb//:json",
+    )
+
+    native.bind(
         name = "absl",
         actual = "@com_google_absl//absl",
     )
@@ -164,12 +169,14 @@ def grpc_deps():
     if "com_google_protobuf" not in native.existing_rules():
         http_archive(
             name = "com_google_protobuf",
-            sha256 = "e589e39ef46fb2b3b476b3ca355bd324e5984cbdfac19f0e1625f0042e99c276",
-            strip_prefix = "protobuf-fde7cf7358ec7cd69e8db9be4f1fa6a5c431386a",
+            sha256 = "88f7b3d062759e9428394cd2b854722c7142de6d9ea1cc0514a251dcec91bc0b",
+            strip_prefix = "protobuf-19fb89416f3fdc2d6668f3738f444885575285bc",
             urls = [
-                "https://storage.googleapis.com/grpc-bazel-mirror/github.com/google/protobuf/archive/fde7cf7358ec7cd69e8db9be4f1fa6a5c431386a.tar.gz",
-                "https://github.com/google/protobuf/archive/fde7cf7358ec7cd69e8db9be4f1fa6a5c431386a.tar.gz",
+                "https://storage.googleapis.com/grpc-bazel-mirror/github.com/google/protobuf/archive/19fb89416f3fdc2d6668f3738f444885575285bc.tar.gz",
+                "https://github.com/google/protobuf/archive/19fb89416f3fdc2d6668f3738f444885575285bc.tar.gz",
             ],
+            patches = ["@com_github_grpc_grpc//third_party:protobuf.patch"],
+            patch_args = ["-p1"],
         )
 
     if "com_google_googletest" not in native.existing_rules():
@@ -288,11 +295,11 @@ def grpc_deps():
     if "upb" not in native.existing_rules():
         http_archive(
             name = "upb",
-            sha256 = "7992217989f3156f8109931c1fc6db3434b7414957cb82371552377beaeb9d6c",
-            strip_prefix = "upb-382d5afc60e05470c23e8de19b19fc5ad231e732",
+            sha256 = "c0b97bf91dfea7e8d7579c24e2ecdd02d10b00f3c5defc3dce23d95100d0e664",
+            strip_prefix = "upb-60607da72e89ba0c84c84054d2e562d8b6b61177",
             urls = [
-                "https://storage.googleapis.com/grpc-bazel-mirror/github.com/protocolbuffers/upb/archive/382d5afc60e05470c23e8de19b19fc5ad231e732.tar.gz",
-                "https://github.com/protocolbuffers/upb/archive/382d5afc60e05470c23e8de19b19fc5ad231e732.tar.gz",
+                "https://storage.googleapis.com/grpc-bazel-mirror/github.com/protocolbuffers/upb/archive/60607da72e89ba0c84c84054d2e562d8b6b61177.tar.gz",
+                "https://github.com/protocolbuffers/upb/archive/60607da72e89ba0c84c84054d2e562d8b6b61177.tar.gz",
             ],
         )
 
index 4c1dfad..9c3038f 100644 (file)
@@ -7,7 +7,7 @@ load("@io_bazel_rules_go//go:deps.bzl", "go_register_toolchains", "go_rules_depe
 load("@build_bazel_rules_apple//apple:repositories.bzl", "apple_rules_dependencies")
 load("@build_bazel_apple_support//lib:repositories.bzl", "apple_support_dependencies")
 
-def grpc_extra_deps():
+def grpc_extra_deps(ignore_version_differences = False):
     """Loads the extra dependencies.
 
     These are necessary for using the external repositories defined in
@@ -35,6 +35,6 @@ def grpc_extra_deps():
     go_rules_dependencies()
     go_register_toolchains()
 
-    apple_rules_dependencies()
+    apple_rules_dependencies(ignore_version_differences = ignore_version_differences)
 
     apple_support_dependencies()
index b9c17b4..4b754cf 100755 (executable)
@@ -60,6 +60,10 @@ upload github.com/bazelbuild/bazel/releases/download/2.2.0/bazel-2.2.0-linux-x86
 upload github.com/bazelbuild/bazel/releases/download/2.2.0/bazel-2.2.0-darwin-x86_64
 upload github.com/bazelbuild/bazel/releases/download/2.2.0/bazel-2.2.0-windows-x86_64.exe
 
+upload github.com/bazelbuild/bazel/releases/download/3.7.1/bazel-3.7.1-linux-x86_64
+upload github.com/bazelbuild/bazel/releases/download/3.7.1/bazel-3.7.1-darwin-x86_64
+upload github.com/bazelbuild/bazel/releases/download/3.7.1/bazel-3.7.1-windows-x86_64.exe
+
 # Collect the github archives to mirror from grpc_deps.bzl
 grep -o '"https://github.com/[^"]*"' bazel/grpc_deps.bzl | sed 's/^"https:\/\///' | sed 's/"$//' | while read -r line ; do
     echo "Updating mirror for ${line}"
index e8c0240..e9245b7 100644 (file)
@@ -55,9 +55,9 @@ libs:
   - test/core/end2end/tests/default_host.cc
   - test/core/end2end/tests/disappearing_server.cc
   - test/core/end2end/tests/empty_batch.cc
-  - test/core/end2end/tests/filter_call_init_fails.cc
   - test/core/end2end/tests/filter_causes_close.cc
   - test/core/end2end/tests/filter_context.cc
+  - test/core/end2end/tests/filter_init_fails.cc
   - test/core/end2end/tests/filter_latency.cc
   - test/core/end2end/tests/filter_status_code.cc
   - test/core/end2end/tests/graceful_server_shutdown.cc
@@ -165,9 +165,9 @@ libs:
   - test/core/end2end/tests/default_host.cc
   - test/core/end2end/tests/disappearing_server.cc
   - test/core/end2end/tests/empty_batch.cc
-  - test/core/end2end/tests/filter_call_init_fails.cc
   - test/core/end2end/tests/filter_causes_close.cc
   - test/core/end2end/tests/filter_context.cc
+  - test/core/end2end/tests/filter_init_fails.cc
   - test/core/end2end/tests/filter_latency.cc
   - test/core/end2end/tests/filter_status_code.cc
   - test/core/end2end/tests/graceful_server_shutdown.cc
@@ -303,7 +303,6 @@ libs:
   - src/core/lib/gprpp/global_config_generic.h
   - src/core/lib/gprpp/host_port.h
   - src/core/lib/gprpp/manual_constructor.h
-  - src/core/lib/gprpp/map.h
   - src/core/lib/gprpp/memory.h
   - src/core/lib/gprpp/mpscq.h
   - src/core/lib/gprpp/stat.h
@@ -391,6 +390,7 @@ libs:
   - src/core/ext/filters/client_channel/client_channel_factory.h
   - src/core/ext/filters/client_channel/config_selector.h
   - src/core/ext/filters/client_channel/connector.h
+  - src/core/ext/filters/client_channel/dynamic_filters.h
   - src/core/ext/filters/client_channel/global_subchannel_pool.h
   - src/core/ext/filters/client_channel/health/health_check_client.h
   - src/core/ext/filters/client_channel/http_connect_handshaker.h
@@ -406,6 +406,7 @@ libs:
   - src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.h
   - src/core/ext/filters/client_channel/lb_policy/subchannel_list.h
   - src/core/ext/filters/client_channel/lb_policy/xds/xds.h
+  - src/core/ext/filters/client_channel/lb_policy/xds/xds_channel_args.h
   - src/core/ext/filters/client_channel/lb_policy_factory.h
   - src/core/ext/filters/client_channel/lb_policy_registry.h
   - src/core/ext/filters/client_channel/local_subchannel_pool.h
@@ -420,7 +421,6 @@ libs:
   - src/core/ext/filters/client_channel/resolver_factory.h
   - src/core/ext/filters/client_channel/resolver_registry.h
   - src/core/ext/filters/client_channel/resolver_result_parsing.h
-  - src/core/ext/filters/client_channel/resolving_lb_policy.h
   - src/core/ext/filters/client_channel/retry_throttle.h
   - src/core/ext/filters/client_channel/server_address.h
   - src/core/ext/filters/client_channel/service_config.h
@@ -633,7 +633,6 @@ libs:
   - src/core/ext/xds/certificate_provider_registry.h
   - src/core/ext/xds/certificate_provider_store.h
   - src/core/ext/xds/file_watcher_certificate_provider_factory.h
-  - src/core/ext/xds/google_mesh_ca_certificate_provider_factory.h
   - src/core/ext/xds/xds_api.h
   - src/core/ext/xds/xds_bootstrap.h
   - src/core/ext/xds/xds_certificate_provider.h
@@ -767,6 +766,7 @@ libs:
   - src/core/lib/security/credentials/alts/grpc_alts_credentials_options.h
   - src/core/lib/security/credentials/composite/composite_credentials.h
   - src/core/lib/security/credentials/credentials.h
+  - src/core/lib/security/credentials/external/aws_external_account_credentials.h
   - src/core/lib/security/credentials/external/aws_request_signer.h
   - src/core/lib/security/credentials/external/external_account_credentials.h
   - src/core/lib/security/credentials/external/file_external_account_credentials.h
@@ -785,6 +785,7 @@ libs:
   - src/core/lib/security/credentials/tls/grpc_tls_certificate_provider.h
   - src/core/lib/security/credentials/tls/grpc_tls_credentials_options.h
   - src/core/lib/security/credentials/tls/tls_credentials.h
+  - src/core/lib/security/credentials/tls/tls_utils.h
   - src/core/lib/security/credentials/xds/xds_credentials.h
   - src/core/lib/security/security_connector/alts/alts_security_connector.h
   - src/core/lib/security/security_connector/fake/fake_security_connector.h
@@ -873,6 +874,7 @@ libs:
   - src/core/ext/filters/client_channel/client_channel_factory.cc
   - src/core/ext/filters/client_channel/client_channel_plugin.cc
   - src/core/ext/filters/client_channel/config_selector.cc
+  - src/core/ext/filters/client_channel/dynamic_filters.cc
   - src/core/ext/filters/client_channel/global_subchannel_pool.cc
   - src/core/ext/filters/client_channel/health/health_check_client.cc
   - src/core/ext/filters/client_channel/http_connect_handshaker.cc
@@ -891,20 +893,18 @@ libs:
   - src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc
   - src/core/ext/filters/client_channel/lb_policy/weighted_target/weighted_target.cc
   - src/core/ext/filters/client_channel/lb_policy/xds/cds.cc
-  - src/core/ext/filters/client_channel/lb_policy/xds/eds.cc
   - src/core/ext/filters/client_channel/lb_policy/xds/xds_cluster_impl.cc
   - src/core/ext/filters/client_channel/lb_policy/xds/xds_cluster_manager.cc
+  - src/core/ext/filters/client_channel/lb_policy/xds/xds_cluster_resolver.cc
   - src/core/ext/filters/client_channel/lb_policy_registry.cc
   - src/core/ext/filters/client_channel/local_subchannel_pool.cc
   - src/core/ext/filters/client_channel/proxy_mapper_registry.cc
   - src/core/ext/filters/client_channel/resolver.cc
   - src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc
-  - src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.cc
   - src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_libuv.cc
   - src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_posix.cc
   - src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_windows.cc
   - src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc
-  - src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_fallback.cc
   - src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv.cc
   - src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_posix.cc
   - src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc
@@ -915,7 +915,6 @@ libs:
   - src/core/ext/filters/client_channel/resolver/xds/xds_resolver.cc
   - src/core/ext/filters/client_channel/resolver_registry.cc
   - src/core/ext/filters/client_channel/resolver_result_parsing.cc
-  - src/core/ext/filters/client_channel/resolving_lb_policy.cc
   - src/core/ext/filters/client_channel/retry_throttle.cc
   - src/core/ext/filters/client_channel/server_address.cc
   - src/core/ext/filters/client_channel/service_config.cc
@@ -1137,12 +1136,12 @@ libs:
   - src/core/ext/xds/certificate_provider_registry.cc
   - src/core/ext/xds/certificate_provider_store.cc
   - src/core/ext/xds/file_watcher_certificate_provider_factory.cc
-  - src/core/ext/xds/google_mesh_ca_certificate_provider_factory.cc
   - src/core/ext/xds/xds_api.cc
   - src/core/ext/xds/xds_bootstrap.cc
   - src/core/ext/xds/xds_certificate_provider.cc
   - src/core/ext/xds/xds_client.cc
   - src/core/ext/xds/xds_client_stats.cc
+  - src/core/ext/xds/xds_server_config_fetcher.cc
   - src/core/lib/avl/avl.cc
   - src/core/lib/backoff/backoff.cc
   - src/core/lib/channel/channel_args.cc
@@ -1282,6 +1281,7 @@ libs:
   - src/core/lib/security/credentials/composite/composite_credentials.cc
   - src/core/lib/security/credentials/credentials.cc
   - src/core/lib/security/credentials/credentials_metadata.cc
+  - src/core/lib/security/credentials/external/aws_external_account_credentials.cc
   - src/core/lib/security/credentials/external/aws_request_signer.cc
   - src/core/lib/security/credentials/external/external_account_credentials.cc
   - src/core/lib/security/credentials/external/file_external_account_credentials.cc
@@ -1302,6 +1302,7 @@ libs:
   - src/core/lib/security/credentials/tls/grpc_tls_certificate_provider.cc
   - src/core/lib/security/credentials/tls/grpc_tls_credentials_options.cc
   - src/core/lib/security/credentials/tls/tls_credentials.cc
+  - src/core/lib/security/credentials/tls/tls_utils.cc
   - src/core/lib/security/credentials/xds/xds_credentials.cc
   - src/core/lib/security/security_connector/alts/alts_security_connector.cc
   - src/core/lib/security/security_connector/fake/fake_security_connector.cc
@@ -1395,10 +1396,12 @@ libs:
   - upb
   - absl/types:optional
   - absl/strings:strings
+  - absl/status:statusor
   - absl/status:status
   - absl/functional:bind_front
   - absl/container:inlined_vector
   - absl/container:flat_hash_set
+  - absl/container:flat_hash_map
   baselib: true
   deps_linkage: static
   dll: true
@@ -1424,7 +1427,6 @@ libs:
   public_headers: []
   headers:
   - test/core/util/cmdline.h
-  - test/core/util/debugger_macros.h
   - test/core/util/eval_args_mock_endpoint.h
   - test/core/util/fuzzer_util.h
   - test/core/util/grpc_profiler.h
@@ -1442,11 +1444,11 @@ libs:
   - test/core/util/subprocess.h
   - test/core/util/test_config.h
   - test/core/util/test_tcp_server.h
+  - test/core/util/tls_utils.h
   - test/core/util/tracer_util.h
   - test/core/util/trickle_endpoint.h
   src:
   - test/core/util/cmdline.cc
-  - test/core/util/debugger_macros.cc
   - test/core/util/eval_args_mock_endpoint.cc
   - test/core/util/fuzzer_util.cc
   - test/core/util/grpc_profiler.cc
@@ -1466,6 +1468,7 @@ libs:
   - test/core/util/subprocess_windows.cc
   - test/core/util/test_config.cc
   - test/core/util/test_tcp_server.cc
+  - test/core/util/tls_utils.cc
   - test/core/util/tracer_util.cc
   - test/core/util/trickle_endpoint.cc
   deps:
@@ -1482,7 +1485,6 @@ libs:
   public_headers: []
   headers:
   - test/core/util/cmdline.h
-  - test/core/util/debugger_macros.h
   - test/core/util/eval_args_mock_endpoint.h
   - test/core/util/fuzzer_util.h
   - test/core/util/grpc_profiler.h
@@ -1504,7 +1506,6 @@ libs:
   - test/core/util/trickle_endpoint.h
   src:
   - test/core/util/cmdline.cc
-  - test/core/util/debugger_macros.cc
   - test/core/util/eval_args_mock_endpoint.cc
   - test/core/util/fuzzer_util.cc
   - test/core/util/grpc_profiler.cc
@@ -1560,6 +1561,7 @@ libs:
   - src/core/ext/filters/client_channel/client_channel_factory.h
   - src/core/ext/filters/client_channel/config_selector.h
   - src/core/ext/filters/client_channel/connector.h
+  - src/core/ext/filters/client_channel/dynamic_filters.h
   - src/core/ext/filters/client_channel/global_subchannel_pool.h
   - src/core/ext/filters/client_channel/health/health_check_client.h
   - src/core/ext/filters/client_channel/http_connect_handshaker.h
@@ -1587,7 +1589,6 @@ libs:
   - src/core/ext/filters/client_channel/resolver_factory.h
   - src/core/ext/filters/client_channel/resolver_registry.h
   - src/core/ext/filters/client_channel/resolver_result_parsing.h
-  - src/core/ext/filters/client_channel/resolving_lb_policy.h
   - src/core/ext/filters/client_channel/retry_throttle.h
   - src/core/ext/filters/client_channel/server_address.h
   - src/core/ext/filters/client_channel/service_config.h
@@ -1804,6 +1805,7 @@ libs:
   - src/core/ext/filters/client_channel/client_channel_factory.cc
   - src/core/ext/filters/client_channel/client_channel_plugin.cc
   - src/core/ext/filters/client_channel/config_selector.cc
+  - src/core/ext/filters/client_channel/dynamic_filters.cc
   - src/core/ext/filters/client_channel/global_subchannel_pool.cc
   - src/core/ext/filters/client_channel/health/health_check_client.cc
   - src/core/ext/filters/client_channel/http_connect_handshaker.cc
@@ -1826,12 +1828,10 @@ libs:
   - src/core/ext/filters/client_channel/proxy_mapper_registry.cc
   - src/core/ext/filters/client_channel/resolver.cc
   - src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc
-  - src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.cc
   - src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_libuv.cc
   - src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_posix.cc
   - src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_windows.cc
   - src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc
-  - src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_fallback.cc
   - src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv.cc
   - src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_posix.cc
   - src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc
@@ -1841,7 +1841,6 @@ libs:
   - src/core/ext/filters/client_channel/resolver/sockaddr/sockaddr_resolver.cc
   - src/core/ext/filters/client_channel/resolver_registry.cc
   - src/core/ext/filters/client_channel/resolver_result_parsing.cc
-  - src/core/ext/filters/client_channel/resolving_lb_policy.cc
   - src/core/ext/filters/client_channel/retry_throttle.cc
   - src/core/ext/filters/client_channel/server_address.cc
   - src/core/ext/filters/client_channel/service_config.cc
@@ -2081,8 +2080,10 @@ libs:
   - upb
   - absl/types:optional
   - absl/strings:strings
+  - absl/status:statusor
   - absl/status:status
   - absl/container:inlined_vector
+  - absl/container:flat_hash_map
   baselib: true
   deps_linkage: static
   dll: true
@@ -2298,6 +2299,7 @@ libs:
   - include/grpcpp/support/sync_stream.h
   - include/grpcpp/support/time.h
   - include/grpcpp/support/validate_service_config.h
+  - include/grpcpp/xds_server_builder.h
   headers:
   - src/cpp/client/create_channel_internal.h
   - src/cpp/client/secure_credentials.h
@@ -2355,6 +2357,7 @@ libs:
   - src/cpp/server/server_context.cc
   - src/cpp/server/server_credentials.cc
   - src/cpp/server/server_posix.cc
+  - src/cpp/server/xds_server_credentials.cc
   - src/cpp/thread_manager/thread_manager.cc
   - src/cpp/util/byte_buffer_cc.cc
   - src/cpp/util/status.cc
@@ -3258,7 +3261,6 @@ targets:
   uses_polling: false
 - name: concurrent_connectivity_test
   build: test
-  run: false
   language: c
   headers: []
   src:
@@ -3857,19 +3859,6 @@ targets:
   - address_sorting
   - upb
   uses_polling: false
-- name: log_test
-  build: test
-  language: c
-  headers: []
-  src:
-  - test/core/gpr/log_test.cc
-  deps:
-  - grpc_test_util
-  - grpc
-  - gpr
-  - address_sorting
-  - upb
-  uses_polling: false
 - name: manual_constructor_test
   build: test
   language: c
@@ -4637,18 +4626,6 @@ targets:
   - linux
   - posix
   - mac
-- name: uri_parser_test
-  build: test
-  language: c
-  headers: []
-  src:
-  - test/core/uri/uri_parser_test.cc
-  deps:
-  - grpc_test_util
-  - grpc
-  - gpr
-  - address_sorting
-  - upb
 - name: useful_test
   build: test
   language: c
@@ -5433,7 +5410,6 @@ targets:
 - name: cancel_ares_query_test
   gtest: true
   build: test
-  run: false
   language: c++
   headers:
   - test/core/end2end/cq_verifier.h
@@ -6103,8 +6079,10 @@ targets:
   gtest: true
   build: test
   language: c++
-  headers: []
+  headers:
+  - src/core/ext/xds/google_mesh_ca_certificate_provider_factory.h
   src:
+  - src/core/ext/xds/google_mesh_ca_certificate_provider_factory.cc
   - test/core/xds/google_mesh_ca_certificate_provider_factory_test.cc
   deps:
   - grpc_test_util
@@ -6217,6 +6195,19 @@ targets:
   - gpr
   - address_sorting
   - upb
+- name: grpc_tls_certificate_provider_test
+  gtest: true
+  build: test
+  language: c++
+  headers: []
+  src:
+  - test/core/security/grpc_tls_certificate_provider_test.cc
+  deps:
+  - grpc_test_util
+  - grpc
+  - gpr
+  - address_sorting
+  - upb
 - name: grpc_tls_credentials_options_test
   gtest: true
   build: test
@@ -6689,6 +6680,20 @@ targets:
   - gpr
   - address_sorting
   - upb
+- name: log_test
+  gtest: true
+  build: test
+  language: c++
+  headers: []
+  src:
+  - test/core/gpr/log_test.cc
+  deps:
+  - grpc_test_util
+  - grpc
+  - gpr
+  - address_sorting
+  - upb
+  uses_polling: false
 - name: message_allocator_end2end_test
   gtest: true
   build: test
@@ -7506,7 +7511,6 @@ targets:
 - name: stranded_event_test
   gtest: true
   build: test
-  run: false
   language: c++
   headers:
   - test/core/end2end/cq_verifier.h
@@ -7759,6 +7763,19 @@ targets:
   corpus_dirs:
   - test/core/uri/uri_corpus
   maxlen: 128
+- name: uri_parser_test
+  gtest: true
+  build: test
+  language: c++
+  headers: []
+  src:
+  - test/core/uri/uri_parser_test.cc
+  deps:
+  - grpc_test_util
+  - grpc
+  - gpr
+  - address_sorting
+  - upb
 - name: window_overflow_bad_client_test
   gtest: true
   build: test
@@ -7799,7 +7816,6 @@ targets:
   language: c++
   headers:
   - test/core/util/cmdline.h
-  - test/core/util/debugger_macros.h
   - test/core/util/eval_args_mock_endpoint.h
   - test/core/util/fuzzer_util.h
   - test/core/util/grpc_profiler.h
@@ -7824,7 +7840,6 @@ targets:
   - src/proto/grpc/testing/echo_messages.proto
   - src/proto/grpc/testing/simple_messages.proto
   - test/core/util/cmdline.cc
-  - test/core/util/debugger_macros.cc
   - test/core/util/eval_args_mock_endpoint.cc
   - test/core/util/fuzzer_util.cc
   - test/core/util/grpc_profiler.cc
@@ -7906,6 +7921,19 @@ targets:
   - gpr
   - address_sorting
   - upb
+- name: xds_credentials_test
+  gtest: true
+  build: test
+  language: c++
+  headers: []
+  src:
+  - test/core/security/xds_credentials_test.cc
+  deps:
+  - grpc_test_util
+  - grpc
+  - gpr
+  - address_sorting
+  - upb
 - name: xds_end2end_test
   gtest: true
   build: test
@@ -7939,6 +7967,8 @@ targets:
   - src/proto/grpc/testing/xds/v3/range.proto
   - src/proto/grpc/testing/xds/v3/regex.proto
   - src/proto/grpc/testing/xds/v3/route.proto
+  - src/proto/grpc/testing/xds/v3/string.proto
+  - src/proto/grpc/testing/xds/v3/tls.proto
   - test/cpp/end2end/test_service_impl.cc
   - test/cpp/end2end/xds_end2end_test.cc
   deps:
index e3ee527..c4c9c6a 100644 (file)
@@ -14,8 +14,9 @@ settings:
   '#10': See the expand_version.py for all the quirks here
   core_version: 14.0.0
   csharp_major_version: 2
-  g_stands_for: gauntlet
-  version: 1.34.1
+  g_stands_for: gecko
+  protobuf_version: 3.14.0
+  version: 1.35.0
 targets:
 - name: check_epollexclusive
   build: tool
@@ -215,6 +216,7 @@ defaults:
     LDFLAGS: -g
   zlib:
     CFLAGS: -fvisibility=hidden
+    CPPFLAGS: -DHAVE_UNISTD_H
 php_config_m4:
   deps:
   - grpc
index 358acfc..3c620e5 100644 (file)
--- a/config.m4
+++ b/config.m4
@@ -48,6 +48,7 @@ if test "$PHP_GRPC" != "no"; then
     src/core/ext/filters/client_channel/client_channel_factory.cc \
     src/core/ext/filters/client_channel/client_channel_plugin.cc \
     src/core/ext/filters/client_channel/config_selector.cc \
+    src/core/ext/filters/client_channel/dynamic_filters.cc \
     src/core/ext/filters/client_channel/global_subchannel_pool.cc \
     src/core/ext/filters/client_channel/health/health_check_client.cc \
     src/core/ext/filters/client_channel/http_connect_handshaker.cc \
@@ -66,20 +67,18 @@ if test "$PHP_GRPC" != "no"; then
     src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc \
     src/core/ext/filters/client_channel/lb_policy/weighted_target/weighted_target.cc \
     src/core/ext/filters/client_channel/lb_policy/xds/cds.cc \
-    src/core/ext/filters/client_channel/lb_policy/xds/eds.cc \
     src/core/ext/filters/client_channel/lb_policy/xds/xds_cluster_impl.cc \
     src/core/ext/filters/client_channel/lb_policy/xds/xds_cluster_manager.cc \
+    src/core/ext/filters/client_channel/lb_policy/xds/xds_cluster_resolver.cc \
     src/core/ext/filters/client_channel/lb_policy_registry.cc \
     src/core/ext/filters/client_channel/local_subchannel_pool.cc \
     src/core/ext/filters/client_channel/proxy_mapper_registry.cc \
     src/core/ext/filters/client_channel/resolver.cc \
     src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc \
-    src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.cc \
     src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_libuv.cc \
     src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_posix.cc \
     src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_windows.cc \
     src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc \
-    src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_fallback.cc \
     src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv.cc \
     src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_posix.cc \
     src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc \
@@ -90,7 +89,6 @@ if test "$PHP_GRPC" != "no"; then
     src/core/ext/filters/client_channel/resolver/xds/xds_resolver.cc \
     src/core/ext/filters/client_channel/resolver_registry.cc \
     src/core/ext/filters/client_channel/resolver_result_parsing.cc \
-    src/core/ext/filters/client_channel/resolving_lb_policy.cc \
     src/core/ext/filters/client_channel/retry_throttle.cc \
     src/core/ext/filters/client_channel/server_address.cc \
     src/core/ext/filters/client_channel/service_config.cc \
@@ -313,12 +311,12 @@ if test "$PHP_GRPC" != "no"; then
     src/core/ext/xds/certificate_provider_registry.cc \
     src/core/ext/xds/certificate_provider_store.cc \
     src/core/ext/xds/file_watcher_certificate_provider_factory.cc \
-    src/core/ext/xds/google_mesh_ca_certificate_provider_factory.cc \
     src/core/ext/xds/xds_api.cc \
     src/core/ext/xds/xds_bootstrap.cc \
     src/core/ext/xds/xds_certificate_provider.cc \
     src/core/ext/xds/xds_client.cc \
     src/core/ext/xds/xds_client_stats.cc \
+    src/core/ext/xds/xds_server_config_fetcher.cc \
     src/core/lib/avl/avl.cc \
     src/core/lib/backoff/backoff.cc \
     src/core/lib/channel/channel_args.cc \
@@ -502,6 +500,7 @@ if test "$PHP_GRPC" != "no"; then
     src/core/lib/security/credentials/composite/composite_credentials.cc \
     src/core/lib/security/credentials/credentials.cc \
     src/core/lib/security/credentials/credentials_metadata.cc \
+    src/core/lib/security/credentials/external/aws_external_account_credentials.cc \
     src/core/lib/security/credentials/external/aws_request_signer.cc \
     src/core/lib/security/credentials/external/external_account_credentials.cc \
     src/core/lib/security/credentials/external/file_external_account_credentials.cc \
@@ -522,6 +521,7 @@ if test "$PHP_GRPC" != "no"; then
     src/core/lib/security/credentials/tls/grpc_tls_certificate_provider.cc \
     src/core/lib/security/credentials/tls/grpc_tls_credentials_options.cc \
     src/core/lib/security/credentials/tls/tls_credentials.cc \
+    src/core/lib/security/credentials/tls/tls_utils.cc \
     src/core/lib/security/credentials/xds/xds_credentials.cc \
     src/core/lib/security/security_connector/alts/alts_security_connector.cc \
     src/core/lib/security/security_connector/fake/fake_security_connector.cc \
@@ -644,6 +644,7 @@ if test "$PHP_GRPC" != "no"; then
     third_party/abseil-cpp/absl/numeric/int128.cc \
     third_party/abseil-cpp/absl/status/status.cc \
     third_party/abseil-cpp/absl/status/status_payload_printer.cc \
+    third_party/abseil-cpp/absl/status/statusor.cc \
     third_party/abseil-cpp/absl/strings/ascii.cc \
     third_party/abseil-cpp/absl/strings/charconv.cc \
     third_party/abseil-cpp/absl/strings/cord.cc \
@@ -986,10 +987,12 @@ if test "$PHP_GRPC" != "no"; then
     third_party/re2/util/rune.cc \
     third_party/re2/util/strutil.cc \
     third_party/upb/upb/decode.c \
+    third_party/upb/upb/decode_fast.c \
     third_party/upb/upb/def.c \
     third_party/upb/upb/encode.c \
+    third_party/upb/upb/json_decode.c \
+    third_party/upb/upb/json_encode.c \
     third_party/upb/upb/msg.c \
-    third_party/upb/upb/port.c \
     third_party/upb/upb/reflection.c \
     third_party/upb/upb/table.c \
     third_party/upb/upb/text_encode.c \
index 4c4d59a..b7bf079 100644 (file)
@@ -15,6 +15,7 @@ if (PHP_GRPC != "no") {
     "src\\core\\ext\\filters\\client_channel\\client_channel_factory.cc " +
     "src\\core\\ext\\filters\\client_channel\\client_channel_plugin.cc " +
     "src\\core\\ext\\filters\\client_channel\\config_selector.cc " +
+    "src\\core\\ext\\filters\\client_channel\\dynamic_filters.cc " +
     "src\\core\\ext\\filters\\client_channel\\global_subchannel_pool.cc " +
     "src\\core\\ext\\filters\\client_channel\\health\\health_check_client.cc " +
     "src\\core\\ext\\filters\\client_channel\\http_connect_handshaker.cc " +
@@ -33,20 +34,18 @@ if (PHP_GRPC != "no") {
     "src\\core\\ext\\filters\\client_channel\\lb_policy\\round_robin\\round_robin.cc " +
     "src\\core\\ext\\filters\\client_channel\\lb_policy\\weighted_target\\weighted_target.cc " +
     "src\\core\\ext\\filters\\client_channel\\lb_policy\\xds\\cds.cc " +
-    "src\\core\\ext\\filters\\client_channel\\lb_policy\\xds\\eds.cc " +
     "src\\core\\ext\\filters\\client_channel\\lb_policy\\xds\\xds_cluster_impl.cc " +
     "src\\core\\ext\\filters\\client_channel\\lb_policy\\xds\\xds_cluster_manager.cc " +
+    "src\\core\\ext\\filters\\client_channel\\lb_policy\\xds\\xds_cluster_resolver.cc " +
     "src\\core\\ext\\filters\\client_channel\\lb_policy_registry.cc " +
     "src\\core\\ext\\filters\\client_channel\\local_subchannel_pool.cc " +
     "src\\core\\ext\\filters\\client_channel\\proxy_mapper_registry.cc " +
     "src\\core\\ext\\filters\\client_channel\\resolver.cc " +
     "src\\core\\ext\\filters\\client_channel\\resolver\\dns\\c_ares\\dns_resolver_ares.cc " +
-    "src\\core\\ext\\filters\\client_channel\\resolver\\dns\\c_ares\\grpc_ares_ev_driver.cc " +
     "src\\core\\ext\\filters\\client_channel\\resolver\\dns\\c_ares\\grpc_ares_ev_driver_libuv.cc " +
     "src\\core\\ext\\filters\\client_channel\\resolver\\dns\\c_ares\\grpc_ares_ev_driver_posix.cc " +
     "src\\core\\ext\\filters\\client_channel\\resolver\\dns\\c_ares\\grpc_ares_ev_driver_windows.cc " +
     "src\\core\\ext\\filters\\client_channel\\resolver\\dns\\c_ares\\grpc_ares_wrapper.cc " +
-    "src\\core\\ext\\filters\\client_channel\\resolver\\dns\\c_ares\\grpc_ares_wrapper_fallback.cc " +
     "src\\core\\ext\\filters\\client_channel\\resolver\\dns\\c_ares\\grpc_ares_wrapper_libuv.cc " +
     "src\\core\\ext\\filters\\client_channel\\resolver\\dns\\c_ares\\grpc_ares_wrapper_posix.cc " +
     "src\\core\\ext\\filters\\client_channel\\resolver\\dns\\c_ares\\grpc_ares_wrapper_windows.cc " +
@@ -57,7 +56,6 @@ if (PHP_GRPC != "no") {
     "src\\core\\ext\\filters\\client_channel\\resolver\\xds\\xds_resolver.cc " +
     "src\\core\\ext\\filters\\client_channel\\resolver_registry.cc " +
     "src\\core\\ext\\filters\\client_channel\\resolver_result_parsing.cc " +
-    "src\\core\\ext\\filters\\client_channel\\resolving_lb_policy.cc " +
     "src\\core\\ext\\filters\\client_channel\\retry_throttle.cc " +
     "src\\core\\ext\\filters\\client_channel\\server_address.cc " +
     "src\\core\\ext\\filters\\client_channel\\service_config.cc " +
@@ -280,12 +278,12 @@ if (PHP_GRPC != "no") {
     "src\\core\\ext\\xds\\certificate_provider_registry.cc " +
     "src\\core\\ext\\xds\\certificate_provider_store.cc " +
     "src\\core\\ext\\xds\\file_watcher_certificate_provider_factory.cc " +
-    "src\\core\\ext\\xds\\google_mesh_ca_certificate_provider_factory.cc " +
     "src\\core\\ext\\xds\\xds_api.cc " +
     "src\\core\\ext\\xds\\xds_bootstrap.cc " +
     "src\\core\\ext\\xds\\xds_certificate_provider.cc " +
     "src\\core\\ext\\xds\\xds_client.cc " +
     "src\\core\\ext\\xds\\xds_client_stats.cc " +
+    "src\\core\\ext\\xds\\xds_server_config_fetcher.cc " +
     "src\\core\\lib\\avl\\avl.cc " +
     "src\\core\\lib\\backoff\\backoff.cc " +
     "src\\core\\lib\\channel\\channel_args.cc " +
@@ -469,6 +467,7 @@ if (PHP_GRPC != "no") {
     "src\\core\\lib\\security\\credentials\\composite\\composite_credentials.cc " +
     "src\\core\\lib\\security\\credentials\\credentials.cc " +
     "src\\core\\lib\\security\\credentials\\credentials_metadata.cc " +
+    "src\\core\\lib\\security\\credentials\\external\\aws_external_account_credentials.cc " +
     "src\\core\\lib\\security\\credentials\\external\\aws_request_signer.cc " +
     "src\\core\\lib\\security\\credentials\\external\\external_account_credentials.cc " +
     "src\\core\\lib\\security\\credentials\\external\\file_external_account_credentials.cc " +
@@ -489,6 +488,7 @@ if (PHP_GRPC != "no") {
     "src\\core\\lib\\security\\credentials\\tls\\grpc_tls_certificate_provider.cc " +
     "src\\core\\lib\\security\\credentials\\tls\\grpc_tls_credentials_options.cc " +
     "src\\core\\lib\\security\\credentials\\tls\\tls_credentials.cc " +
+    "src\\core\\lib\\security\\credentials\\tls\\tls_utils.cc " +
     "src\\core\\lib\\security\\credentials\\xds\\xds_credentials.cc " +
     "src\\core\\lib\\security\\security_connector\\alts\\alts_security_connector.cc " +
     "src\\core\\lib\\security\\security_connector\\fake\\fake_security_connector.cc " +
@@ -611,6 +611,7 @@ if (PHP_GRPC != "no") {
     "third_party\\abseil-cpp\\absl\\numeric\\int128.cc " +
     "third_party\\abseil-cpp\\absl\\status\\status.cc " +
     "third_party\\abseil-cpp\\absl\\status\\status_payload_printer.cc " +
+    "third_party\\abseil-cpp\\absl\\status\\statusor.cc " +
     "third_party\\abseil-cpp\\absl\\strings\\ascii.cc " +
     "third_party\\abseil-cpp\\absl\\strings\\charconv.cc " +
     "third_party\\abseil-cpp\\absl\\strings\\cord.cc " +
@@ -953,10 +954,12 @@ if (PHP_GRPC != "no") {
     "third_party\\re2\\util\\rune.cc " +
     "third_party\\re2\\util\\strutil.cc " +
     "third_party\\upb\\upb\\decode.c " +
+    "third_party\\upb\\upb\\decode_fast.c " +
     "third_party\\upb\\upb\\def.c " +
     "third_party\\upb\\upb\\encode.c " +
+    "third_party\\upb\\upb\\json_decode.c " +
+    "third_party\\upb\\upb\\json_encode.c " +
     "third_party\\upb\\upb\\msg.c " +
-    "third_party\\upb\\upb\\port.c " +
     "third_party\\upb\\upb\\reflection.c " +
     "third_party\\upb\\upb\\table.c " +
     "third_party\\upb\\upb\\text_encode.c " +
index 7333782..bdb54a0 100644 (file)
@@ -57,7 +57,6 @@ some configuration as environment variables that can be set.
   - compression - traces compression operations
   - connectivity_state - traces connectivity state changes to channels
   - cronet - traces state in the cronet transport engine
-  - eds_lb - traces eds LB policy
   - executor - traces grpc's internal thread pool ('the executor')
   - glb - traces the grpclb load balancer
   - handshaker - traces handshaking state
@@ -91,6 +90,7 @@ some configuration as environment variables that can be set.
   - xds_client - traces xds client
   - xds_cluster_manager_lb - traces cluster manager LB policy
   - xds_cluster_impl_lb - traces cluster impl LB policy
+  - xds_cluster_resolver_lb - traces xds cluster resolver LB policy
   - xds_resolver - traces xds resolver
 
   The following tracers will only run in binaries built in DEBUG mode. This is
@@ -134,7 +134,12 @@ some configuration as environment variables that can be set.
   Default gRPC logging verbosity - one of:
   - DEBUG - log all gRPC messages
   - INFO - log INFO and ERROR message
-  - ERROR - log only errors
+  - ERROR - log only errors (default)
+  - NONE - won't log any
+
+* GRPC_STACKTRACE_MINLOGLEVEL
+  Minimum loglevel to print the stack-trace - one of DEBUG, INFO, ERROR, and NONE.
+  NONE is a default value.
 
 * GRPC_TRACE_FUZZER
   if set, the fuzzers will output trace (it is usually suppressed).
index b004f52..92edee5 100644 (file)
@@ -34,4 +34,4 @@
 - 1.32 'g' stands for ['giggle'](https://github.com/grpc/grpc/tree/v1.32.x)
 - 1.33 'g' stands for ['geeky'](https://github.com/grpc/grpc/tree/v1.33.x)
 - 1.34 'g' stands for ['gauntlet'](https://github.com/grpc/grpc/tree/v1.34.x)
-- 1.35 'g' stands for ['gecko'](https://github.com/grpc/grpc/tree/master)
+- 1.35 'g' stands for ['gecko'](https://github.com/grpc/grpc/tree/v1.35.x)
index 84863cc..5494828 100644 (file)
@@ -29,4 +29,13 @@ v1.32.0 |Aug 25, 2020        |Sep 8, 2020
 v1.33.0 |Oct 6, 2020 |Oct 20, 2020
 v1.34.0 |Nov 17, 2020 |Dec 1, 2020
 v1.35.0 |Dec 29, 2020 |Jan 12, 2021
-v1.36.0 |Feb 9 26, 2021        |Feb 23, 2021
+v1.36.0 |Feb 9, 2021 |Feb 23, 2021
+v1.37.0 |Mar 23, 2021 |Apr 6, 2021
+v1.38.0 |May 4, 2021 |May 18, 2021
+v1.39.0 |Jun 15, 2021 |Jun 29, 2021
+v1.40.0 |Jul 27, 2021 |Aug 10, 2021
+v1.41.0 |Sep 7, 2021 |Sep 21, 2021
+v1.42.0 |Oct 19, 2021 |Nov 2, 2021
+v1.43.0 |Nov 30, 2021 |Dec 14, 2021
+v1.44.0 |Jan 11, 2022 |Jan 25, 2022
+v1.45.0 |Feb 22, 2022 |Mar 8, 2022
index 798a072..49711c0 100644 (file)
@@ -34,8 +34,12 @@ The optional `load_balancing_weight` is always ignored.
 Initially, only `google_default` channel creds will be supported
 to authenticate with the xDS server.
 
-Features | gRFCs  | [C++, Python,<br> Ruby, PHP, C#](https://github.com/grpc/grpc/releases) | [Java](https://github.com/grpc/grpc-java/releases) | [Go](https://github.com/grpc/grpc-go/releases)
----------|--------|--------------|------|------
-**xDS Infrastructure in gRPC client channel:**<ul><li>LDS->RDS->CDS->EDS flow</li><li>ADS stream</li></ul> | [A27](https://github.com/grpc/proposal/blob/master/A27-xds-global-load-balancing.md) | v1.30.0  | v1.30.0 | v1.30.0 |
-**Load Balancing:**<ul><li>[Virtual host](https://www.envoyproxy.io/docs/envoy/latest/api-v2/api/v2/route/route_components.proto#route-virtualhost) domains matching</li><li>Only default path ("" or "/") matching</li><li>Priority-based weighted round-robin locality picking</li><li>Round-robin endpoint picking within locality</li><li>[Cluster](https://www.envoyproxy.io/docs/envoy/latest/api-v2/api/v2/route/route_components.proto#envoy-api-msg-route-routeaction) route action</li><li>Client-side Load reporting via [LRS](https://github.com/envoyproxy/data-plane-api/blob/master/envoy/service/load_stats/v2/lrs.proto)</li></ul> | [A27](https://github.com/grpc/proposal/blob/master/A27-xds-global-load-balancing.md) | v1.30.0  | v1.30.0 | v1.30.0 |
-Request matching based on:<ul><li>[Path](https://www.envoyproxy.io/docs/envoy/latest/api-v2/api/v2/route/route_components.proto#route-routematch) (prefix, full path and safe regex)</li><li>[Headers](https://www.envoyproxy.io/docs/envoy/latest/api-v2/api/v2/route/route_components.proto#route-headermatcher)</li></ul>Request routing to multiple clusters based on [weights](https://www.envoyproxy.io/docs/envoy/latest/api-v2/api/v2/route/route_components.proto#route-weightedcluster) | [A28](https://github.com/grpc/proposal/blob/master/A28-xds-traffic-splitting-and-routing.md) | v1.31.0 | v1.31.0 | v1.31.0 |
+The gRPC language implementations not listed in the table below do not support
+xDS features.
+
+Features | gRFCs  | [C++, Python,<br> Ruby, PHP](https://github.com/grpc/grpc/releases) | [Java](https://github.com/grpc/grpc-java/releases) | [Go](https://github.com/grpc/grpc-go/releases) | [Node](https://github.com/grpc/grpc-node/releases)
+---------|--------|--------------|------|------|------
+**xDS Infrastructure in gRPC client channel:**<ul><li>LDS->RDS->CDS->EDS flow</li><li>ADS stream</li></ul> | [A27](https://github.com/grpc/proposal/blob/master/A27-xds-global-load-balancing.md) | v1.30.0  | v1.30.0 | v1.30.0 | v1.2.0 |
+**Load Balancing:**<ul><li>[Virtual host](https://www.envoyproxy.io/docs/envoy/latest/api-v2/api/v2/route/route_components.proto#route-virtualhost) domains matching</li><li>Only default path ("" or "/") matching</li><li>Priority-based weighted round-robin locality picking</li><li>Round-robin endpoint picking within locality</li><li>[Cluster](https://www.envoyproxy.io/docs/envoy/latest/api-v2/api/v2/route/route_components.proto#envoy-api-msg-route-routeaction) route action</li><li>Client-side Load reporting via [LRS](https://github.com/envoyproxy/data-plane-api/blob/master/envoy/service/load_stats/v2/lrs.proto)</li></ul> | [A27](https://github.com/grpc/proposal/blob/master/A27-xds-global-load-balancing.md) | v1.30.0  | v1.30.0 | v1.30.0 | v1.2.0 |
+Request matching based on:<ul><li>[Path](https://www.envoyproxy.io/docs/envoy/latest/api-v2/api/v2/route/route_components.proto#route-routematch) (prefix, full path and safe regex)</li><ul><li>[case_sensitive](https://www.envoyproxy.io/docs/envoy/latest/api-v2/api/v2/route/route_components.proto#route-routematch) must be true else config is NACKed</li></ul><li>[Headers](https://www.envoyproxy.io/docs/envoy/latest/api-v2/api/v2/route/route_components.proto#route-headermatcher)</li></ul>Request routing to multiple clusters based on [weights](https://www.envoyproxy.io/docs/envoy/latest/api-v2/api/v2/route/route_components.proto#route-weightedcluster) | [A28](https://github.com/grpc/proposal/blob/master/A28-xds-traffic-splitting-and-routing.md) | v1.31.0 | v1.31.0 | v1.31.0 | |
+Case insensitive prefix/full path matching:<ul><li>[case_sensitive](https://www.envoyproxy.io/docs/envoy/latest/api-v2/api/v2/route/route_components.proto#route-routematch) can be true or false</li></ul> | | v1.34.0 | v1.34.0 | v1.34.0 | |
index cc52f12..b0ba347 100644 (file)
@@ -100,11 +100,20 @@ Server-Side Context
 
 
 Client-Side Interceptor
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+^^^^^^^^^^^^^^^^^^^^^^^
 
 .. autoclass:: ClientCallDetails
 .. autoclass:: InterceptedUnaryUnaryCall
+.. autoclass:: ClientInterceptor
 .. autoclass:: UnaryUnaryClientInterceptor
+.. autoclass:: UnaryStreamClientInterceptor
+.. autoclass:: StreamUnaryClientInterceptor
+.. autoclass:: StreamStreamClientInterceptor
+
+Server-Side Interceptor
+^^^^^^^^^^^^^^^^^^^^^^^
+
+.. autoclass:: ServerInterceptor
 
 
 Multi-Callable Interfaces
index 0b38474..1616abe 100644 (file)
@@ -61,38 +61,6 @@ AfvDbbnvRG15RjF+Cv6pgsH/76tuIMRQyV+dTZsXjAzlAcmgQWpzU/qlULRuJQ/7
 TBj0/VLZjmmx6BEP3ojY+x1J96relc8geMJgEtslQIxq/H5COEBkEveegeGTLg==
 -----END CERTIFICATE-----
 
-# Issuer: CN=VeriSign Class 3 Public Primary Certification Authority - G3 O=VeriSign, Inc. OU=VeriSign Trust Network/(c) 1999 VeriSign, Inc. - For authorized use only
-# Subject: CN=VeriSign Class 3 Public Primary Certification Authority - G3 O=VeriSign, Inc. OU=VeriSign Trust Network/(c) 1999 VeriSign, Inc. - For authorized use only
-# Label: "Verisign Class 3 Public Primary Certification Authority - G3"
-# Serial: 206684696279472310254277870180966723415
-# MD5 Fingerprint: cd:68:b6:a7:c7:c4:ce:75:e0:1d:4f:57:44:61:92:09
-# SHA1 Fingerprint: 13:2d:0d:45:53:4b:69:97:cd:b2:d5:c3:39:e2:55:76:60:9b:5c:c6
-# SHA256 Fingerprint: eb:04:cf:5e:b1:f3:9a:fa:76:2f:2b:b1:20:f2:96:cb:a5:20:c1:b9:7d:b1:58:95:65:b8:1c:b9:a1:7b:72:44
------BEGIN CERTIFICATE-----
-MIIEGjCCAwICEQCbfgZJoz5iudXukEhxKe9XMA0GCSqGSIb3DQEBBQUAMIHKMQsw
-CQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZl
-cmlTaWduIFRydXN0IE5ldHdvcmsxOjA4BgNVBAsTMShjKSAxOTk5IFZlcmlTaWdu
-LCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxRTBDBgNVBAMTPFZlcmlT
-aWduIENsYXNzIDMgUHVibGljIFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3Jp
-dHkgLSBHMzAeFw05OTEwMDEwMDAwMDBaFw0zNjA3MTYyMzU5NTlaMIHKMQswCQYD
-VQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlT
-aWduIFRydXN0IE5ldHdvcmsxOjA4BgNVBAsTMShjKSAxOTk5IFZlcmlTaWduLCBJ
-bmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxRTBDBgNVBAMTPFZlcmlTaWdu
-IENsYXNzIDMgUHVibGljIFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkg
-LSBHMzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMu6nFL8eB8aHm8b
-N3O9+MlrlBIwT/A2R/XQkQr1F8ilYcEWQE37imGQ5XYgwREGfassbqb1EUGO+i2t
-KmFZpGcmTNDovFJbcCAEWNF6yaRpvIMXZK0Fi7zQWM6NjPXr8EJJC52XJ2cybuGu
-kxUccLwgTS8Y3pKI6GyFVxEa6X7jJhFUokWWVYPKMIno3Nij7SqAP395ZVc+FSBm
-CC+Vk7+qRy+oRpfwEuL+wgorUeZ25rdGt+INpsyow0xZVYnm6FNcHOqd8GIWC6fJ
-Xwzw3sJ2zq/3avL6QaaiMxTJ5Xpj055iN9WFZZ4O5lMkdBteHRJTW8cs54NJOxWu
-imi5V5cCAwEAATANBgkqhkiG9w0BAQUFAAOCAQEAERSWwauSCPc/L8my/uRan2Te
-2yFPhpk0djZX3dAVL8WtfxUfN2JzPtTnX84XA9s1+ivbrmAJXx5fj267Cz3qWhMe
-DGBvtcC1IyIuBwvLqXTLR7sdwdela8wv0kL9Sd2nic9TutoAWii/gt/4uhMdUIaC
-/Y4wjylGsB49Ndo4YhYYSq3mtlFs3q9i6wHQHiT+eo8SGhJouPtmmRQURVyu565p
-F4ErWjfJXir0xuKhXFSbplQAz/DxwceYMBo7Nhbbo27q/a2ywtrvAkcTisDxszGt
-TxzhT5yvDwyd93gN2PQ1VoDat20Xj50egWTh/sVFuq1ruQp6Tk9LhO5L8X3dEQ==
------END CERTIFICATE-----
-
 # Issuer: CN=Entrust.net Certification Authority (2048) O=Entrust.net OU=www.entrust.net/CPS_2048 incorp. by ref. (limits liab.)/(c) 1999 Entrust.net Limited
 # Subject: CN=Entrust.net Certification Authority (2048) O=Entrust.net OU=www.entrust.net/CPS_2048 incorp. by ref. (limits liab.)/(c) 1999 Entrust.net Limited
 # Label: "Entrust.net Premium 2048 Secure Server CA"
@@ -155,39 +123,6 @@ ksLi4xaNmjICq44Y3ekQEe5+NauQrz4wlHrQMz2nZQ/1/I6eYs9HRCwBXbsdtTLS
 R9I4LtD+gdwyah617jzV/OeBHRnDJELqYzmp
 -----END CERTIFICATE-----
 
-# Issuer: CN=AddTrust External CA Root O=AddTrust AB OU=AddTrust External TTP Network
-# Subject: CN=AddTrust External CA Root O=AddTrust AB OU=AddTrust External TTP Network
-# Label: "AddTrust External Root"
-# Serial: 1
-# MD5 Fingerprint: 1d:35:54:04:85:78:b0:3f:42:42:4d:bf:20:73:0a:3f
-# SHA1 Fingerprint: 02:fa:f3:e2:91:43:54:68:60:78:57:69:4d:f5:e4:5b:68:85:18:68
-# SHA256 Fingerprint: 68:7f:a4:51:38:22:78:ff:f0:c8:b1:1f:8d:43:d5:76:67:1c:6e:b2:bc:ea:b4:13:fb:83:d9:65:d0:6d:2f:f2
------BEGIN CERTIFICATE-----
-MIIENjCCAx6gAwIBAgIBATANBgkqhkiG9w0BAQUFADBvMQswCQYDVQQGEwJTRTEU
-MBIGA1UEChMLQWRkVHJ1c3QgQUIxJjAkBgNVBAsTHUFkZFRydXN0IEV4dGVybmFs
-IFRUUCBOZXR3b3JrMSIwIAYDVQQDExlBZGRUcnVzdCBFeHRlcm5hbCBDQSBSb290
-MB4XDTAwMDUzMDEwNDgzOFoXDTIwMDUzMDEwNDgzOFowbzELMAkGA1UEBhMCU0Ux
-FDASBgNVBAoTC0FkZFRydXN0IEFCMSYwJAYDVQQLEx1BZGRUcnVzdCBFeHRlcm5h
-bCBUVFAgTmV0d29yazEiMCAGA1UEAxMZQWRkVHJ1c3QgRXh0ZXJuYWwgQ0EgUm9v
-dDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALf3GjPm8gAELTngTlvt
-H7xsD821+iO2zt6bETOXpClMfZOfvUq8k+0DGuOPz+VtUFrWlymUWoCwSXrbLpX9
-uMq/NzgtHj6RQa1wVsfwTz/oMp50ysiQVOnGXw94nZpAPA6sYapeFI+eh6FqUNzX
-mk6vBbOmcZSccbNQYArHE504B4YCqOmoaSYYkKtMsE8jqzpPhNjfzp/haW+710LX
-a0Tkx63ubUFfclpxCDezeWWkWaCUN/cALw3CknLa0Dhy2xSoRcRdKn23tNbE7qzN
-E0S3ySvdQwAl+mG5aWpYIxG3pzOPVnVZ9c0p10a3CitlttNCbxWyuHv77+ldU9U0
-WicCAwEAAaOB3DCB2TAdBgNVHQ4EFgQUrb2YejS0Jvf6xCZU7wO94CTLVBowCwYD
-VR0PBAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wgZkGA1UdIwSBkTCBjoAUrb2YejS0
-Jvf6xCZU7wO94CTLVBqhc6RxMG8xCzAJBgNVBAYTAlNFMRQwEgYDVQQKEwtBZGRU
-cnVzdCBBQjEmMCQGA1UECxMdQWRkVHJ1c3QgRXh0ZXJuYWwgVFRQIE5ldHdvcmsx
-IjAgBgNVBAMTGUFkZFRydXN0IEV4dGVybmFsIENBIFJvb3SCAQEwDQYJKoZIhvcN
-AQEFBQADggEBALCb4IUlwtYj4g+WBpKdQZic2YR5gdkeWxQHIzZlj7DYd7usQWxH
-YINRsPkyPef89iYTx4AWpb9a/IfPeHmJIZriTAcKhjW88t5RxNKWt9x+Tu5w/Rw5
-6wwCURQtjr0W4MHfRnXnJK3s9EK0hZNwEGe6nQY1ShjTK3rMUUKhemPR5ruhxSvC
-Nr4TDea9Y355e6cJDUCrat2PisP29owaQgVR1EX1n6diIWgVIEM8med8vSTYqZEX
-c4g/VhsxOBi0cQ+azcgOno4uG+GMmIPLHzHxREzGBHNJdmAPx/i9F4BrLunMTA5a
-mnkPIAou1Z5jJh5VkpTYghdae9C8x49OhgQ=
------END CERTIFICATE-----
-
 # Issuer: CN=Entrust Root Certification Authority O=Entrust, Inc. OU=www.entrust.net/CPS is incorporated by reference/(c) 2006 Entrust, Inc.
 # Subject: CN=Entrust Root Certification Authority O=Entrust, Inc. OU=www.entrust.net/CPS is incorporated by reference/(c) 2006 Entrust, Inc.
 # Label: "Entrust Root Certification Authority"
@@ -223,112 +158,6 @@ eu6FSqdQgPCnXEqULl8FmTxSQeDNtGPPAUO6nIPcj2A781q0tHuu2guQOHXvgR1m
 0vdXcDazv/wor3ElhVsT/h5/WrQ8
 -----END CERTIFICATE-----
 
-# Issuer: CN=GeoTrust Global CA O=GeoTrust Inc.
-# Subject: CN=GeoTrust Global CA O=GeoTrust Inc.
-# Label: "GeoTrust Global CA"
-# Serial: 144470
-# MD5 Fingerprint: f7:75:ab:29:fb:51:4e:b7:77:5e:ff:05:3c:99:8e:f5
-# SHA1 Fingerprint: de:28:f4:a4:ff:e5:b9:2f:a3:c5:03:d1:a3:49:a7:f9:96:2a:82:12
-# SHA256 Fingerprint: ff:85:6a:2d:25:1d:cd:88:d3:66:56:f4:50:12:67:98:cf:ab:aa:de:40:79:9c:72:2d:e4:d2:b5:db:36:a7:3a
------BEGIN CERTIFICATE-----
-MIIDVDCCAjygAwIBAgIDAjRWMA0GCSqGSIb3DQEBBQUAMEIxCzAJBgNVBAYTAlVT
-MRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMRswGQYDVQQDExJHZW9UcnVzdCBHbG9i
-YWwgQ0EwHhcNMDIwNTIxMDQwMDAwWhcNMjIwNTIxMDQwMDAwWjBCMQswCQYDVQQG
-EwJVUzEWMBQGA1UEChMNR2VvVHJ1c3QgSW5jLjEbMBkGA1UEAxMSR2VvVHJ1c3Qg
-R2xvYmFsIENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2swYYzD9
-9BcjGlZ+W988bDjkcbd4kdS8odhM+KhDtgPpTSEHCIjaWC9mOSm9BXiLnTjoBbdq
-fnGk5sRgprDvgOSJKA+eJdbtg/OtppHHmMlCGDUUna2YRpIuT8rxh0PBFpVXLVDv
-iS2Aelet8u5fa9IAjbkU+BQVNdnARqN7csiRv8lVK83Qlz6cJmTM386DGXHKTubU
-1XupGc1V3sjs0l44U+VcT4wt/lAjNvxm5suOpDkZALeVAjmRCw7+OC7RHQWa9k0+
-bw8HHa8sHo9gOeL6NlMTOdReJivbPagUvTLrGAMoUgRx5aszPeE4uwc2hGKceeoW
-MPRfwCvocWvk+QIDAQABo1MwUTAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBTA
-ephojYn7qwVkDBF9qn1luMrMTjAfBgNVHSMEGDAWgBTAephojYn7qwVkDBF9qn1l
-uMrMTjANBgkqhkiG9w0BAQUFAAOCAQEANeMpauUvXVSOKVCUn5kaFOSPeCpilKIn
-Z57QzxpeR+nBsqTP3UEaBU6bS+5Kb1VSsyShNwrrZHYqLizz/Tt1kL/6cdjHPTfS
-tQWVYrmm3ok9Nns4d0iXrKYgjy6myQzCsplFAMfOEVEiIuCl6rYVSAlk6l5PdPcF
-PseKUgzbFbS9bZvlxrFUaKnjaZC2mqUPuLk/IH2uSrW4nOQdtqvmlKXBx4Ot2/Un
-hw4EbNX/3aBd7YdStysVAq45pmp06drE57xNNB6pXE0zX5IJL4hmXXeXxx12E6nV
-5fEWCRE11azbJHFwLJhWC9kXtNHjUStedejV0NxPNO3CBWaAocvmMw==
------END CERTIFICATE-----
-
-# Issuer: CN=GeoTrust Universal CA O=GeoTrust Inc.
-# Subject: CN=GeoTrust Universal CA O=GeoTrust Inc.
-# Label: "GeoTrust Universal CA"
-# Serial: 1
-# MD5 Fingerprint: 92:65:58:8b:a2:1a:31:72:73:68:5c:b4:a5:7a:07:48
-# SHA1 Fingerprint: e6:21:f3:35:43:79:05:9a:4b:68:30:9d:8a:2f:74:22:15:87:ec:79
-# SHA256 Fingerprint: a0:45:9b:9f:63:b2:25:59:f5:fa:5d:4c:6d:b3:f9:f7:2f:f1:93:42:03:35:78:f0:73:bf:1d:1b:46:cb:b9:12
------BEGIN CERTIFICATE-----
-MIIFaDCCA1CgAwIBAgIBATANBgkqhkiG9w0BAQUFADBFMQswCQYDVQQGEwJVUzEW
-MBQGA1UEChMNR2VvVHJ1c3QgSW5jLjEeMBwGA1UEAxMVR2VvVHJ1c3QgVW5pdmVy
-c2FsIENBMB4XDTA0MDMwNDA1MDAwMFoXDTI5MDMwNDA1MDAwMFowRTELMAkGA1UE
-BhMCVVMxFjAUBgNVBAoTDUdlb1RydXN0IEluYy4xHjAcBgNVBAMTFUdlb1RydXN0
-IFVuaXZlcnNhbCBDQTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAKYV
-VaCjxuAfjJ0hUNfBvitbtaSeodlyWL0AG0y/YckUHUWCq8YdgNY96xCcOq9tJPi8
-cQGeBvV8Xx7BDlXKg5pZMK4ZyzBIle0iN430SppyZj6tlcDgFgDgEB8rMQ7XlFTT
-QjOgNB0eRXbdT8oYN+yFFXoZCPzVx5zw8qkuEKmS5j1YPakWaDwvdSEYfyh3peFh
-F7em6fgemdtzbvQKoiFs7tqqhZJmr/Z6a4LauiIINQ/PQvE1+mrufislzDoR5G2v
-c7J2Ha3QsnhnGqQ5HFELZ1aD/ThdDc7d8Lsrlh/eezJS/R27tQahsiFepdaVaH/w
-mZ7cRQg+59IJDTWU3YBOU5fXtQlEIGQWFwMCTFMNaN7VqnJNk22CDtucvc+081xd
-VHppCZbW2xHBjXWotM85yM48vCR85mLK4b19p71XZQvk/iXttmkQ3CgaRr0BHdCX
-teGYO8A3ZNY9lO4L4fUorgtWv3GLIylBjobFS1J72HGrH4oVpjuDWtdYAVHGTEHZ
-f9hBZ3KiKN9gg6meyHv8U3NyWfWTehd2Ds735VzZC1U0oqpbtWpU5xPKV+yXbfRe
-Bi9Fi1jUIxaS5BZuKGNZMN9QAZxjiRqf2xeUgnA3wySemkfWWspOqGmJch+RbNt+
-nhutxx9z3SxPGWX9f5NAEC7S8O08ni4oPmkmM8V7AgMBAAGjYzBhMA8GA1UdEwEB
-/wQFMAMBAf8wHQYDVR0OBBYEFNq7LqqwDLiIJlF0XG0D08DYj3rWMB8GA1UdIwQY
-MBaAFNq7LqqwDLiIJlF0XG0D08DYj3rWMA4GA1UdDwEB/wQEAwIBhjANBgkqhkiG
-9w0BAQUFAAOCAgEAMXjmx7XfuJRAyXHEqDXsRh3ChfMoWIawC/yOsjmPRFWrZIRc
-aanQmjg8+uUfNeVE44B5lGiku8SfPeE0zTBGi1QrlaXv9z+ZhP015s8xxtxqv6fX
-IwjhmF7DWgh2qaavdy+3YL1ERmrvl/9zlcGO6JP7/TG37FcREUWbMPEaiDnBTzyn
-ANXH/KttgCJwpQzgXQQpAvvLoJHRfNbDflDVnVi+QTjruXU8FdmbyUqDWcDaU/0z
-uzYYm4UPFd3uLax2k7nZAY1IEKj79TiG8dsKxr2EoyNB3tZ3b4XUhRxQ4K5RirqN
-Pnbiucon8l+f725ZDQbYKxek0nxru18UGkiPGkzns0ccjkxFKyDuSN/n3QmOGKja
-QI2SJhFTYXNd673nxE0pN2HrrDktZy4W1vUAg4WhzH92xH3kt0tm7wNFYGm2DFKW
-koRepqO1pD4r2czYG0eq8kTaT/kD6PAUyz/zg97QwVTjt+gKN02LIFkDMBmhLMi9
-ER/frslKxfMnZmaGrGiR/9nmUxwPi1xpZQomyB40w11Re9epnAahNt3ViZS82eQt
-DF4JbAiXfKM9fJP/P6EUp8+1Xevb2xzEdt+Iub1FBZUbrvxGakyvSOPOrg/Sfuvm
-bJxPgWp6ZKy7PtXny3YuxadIwVyQD8vIP/rmMuGNG2+k5o7Y+SlIis5z/iw=
------END CERTIFICATE-----
-
-# Issuer: CN=GeoTrust Universal CA 2 O=GeoTrust Inc.
-# Subject: CN=GeoTrust Universal CA 2 O=GeoTrust Inc.
-# Label: "GeoTrust Universal CA 2"
-# Serial: 1
-# MD5 Fingerprint: 34:fc:b8:d0:36:db:9e:14:b3:c2:f2:db:8f:e4:94:c7
-# SHA1 Fingerprint: 37:9a:19:7b:41:85:45:35:0c:a6:03:69:f3:3c:2e:af:47:4f:20:79
-# SHA256 Fingerprint: a0:23:4f:3b:c8:52:7c:a5:62:8e:ec:81:ad:5d:69:89:5d:a5:68:0d:c9:1d:1c:b8:47:7f:33:f8:78:b9:5b:0b
------BEGIN CERTIFICATE-----
-MIIFbDCCA1SgAwIBAgIBATANBgkqhkiG9w0BAQUFADBHMQswCQYDVQQGEwJVUzEW
-MBQGA1UEChMNR2VvVHJ1c3QgSW5jLjEgMB4GA1UEAxMXR2VvVHJ1c3QgVW5pdmVy
-c2FsIENBIDIwHhcNMDQwMzA0MDUwMDAwWhcNMjkwMzA0MDUwMDAwWjBHMQswCQYD
-VQQGEwJVUzEWMBQGA1UEChMNR2VvVHJ1c3QgSW5jLjEgMB4GA1UEAxMXR2VvVHJ1
-c3QgVW5pdmVyc2FsIENBIDIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoIC
-AQCzVFLByT7y2dyxUxpZKeexw0Uo5dfR7cXFS6GqdHtXr0om/Nj1XqduGdt0DE81
-WzILAePb63p3NeqqWuDW6KFXlPCQo3RWlEQwAx5cTiuFJnSCegx2oG9NzkEtoBUG
-FF+3Qs17j1hhNNwqCPkuwwGmIkQcTAeC5lvO0Ep8BNMZcyfwqph/Lq9O64ceJHdq
-XbboW0W63MOhBW9Wjo8QJqVJwy7XQYci4E+GymC16qFjwAGXEHm9ADwSbSsVsaxL
-se4YuU6W3Nx2/zu+z18DwPw76L5GG//aQMJS9/7jOvdqdzXQ2o3rXhhqMcceujwb
-KNZrVMaqW9eiLBsZzKIC9ptZvTdrhrVtgrrY6slWvKk2WP0+GfPtDCapkzj4T8Fd
-IgbQl+rhrcZV4IErKIM6+vR7IVEAvlI4zs1meaj0gVbi0IMJR1FbUGrP20gaXT73
-y/Zl92zxlfgCOzJWgjl6W70viRu/obTo/3+NjN8D8WBOWBFM66M/ECuDmgFz2ZRt
-hAAnZqzwcEAJQpKtT5MNYQlRJNiS1QuUYbKHsu3/mjX/hVTK7URDrBs8FmtISgoc
-QIgfksILAAX/8sgCSqSqqcyZlpwvWOB94b67B9xfBHJcMTTD7F8t4D1kkCLm0ey4
-Lt1ZrtmhN79UNdxzMk+MBB4zsslG8dhcyFVQyWi9qLo2CQIDAQABo2MwYTAPBgNV
-HRMBAf8EBTADAQH/MB0GA1UdDgQWBBR281Xh+qQ2+/CfXGJx7Tz0RzgQKzAfBgNV
-HSMEGDAWgBR281Xh+qQ2+/CfXGJx7Tz0RzgQKzAOBgNVHQ8BAf8EBAMCAYYwDQYJ
-KoZIhvcNAQEFBQADggIBAGbBxiPz2eAubl/oz66wsCVNK/g7WJtAJDday6sWSf+z
-dXkzoS9tcBc0kf5nfo/sm+VegqlVHy/c1FEHEv6sFj4sNcZj/NwQ6w2jqtB8zNHQ
-L1EuxBRa3ugZ4T7GzKQp5y6EqgYweHZUcyiYWTjgAA1i00J9IZ+uPTqM1fp3DRgr
-Fg5fNuH8KrUwJM/gYwx7WBr+mbpCErGR9Hxo4sjoryzqyX6uuyo9DRXcNJW2GHSo
-ag/HtPQTxORb7QrSpJdMKu0vbBKJPfEncKpqA1Ihn0CoZ1Dy81of398j9tx4TuaY
-T1U6U+Pv8vSfx3zYWK8pIpe44L2RLrB27FcRz+8pRPPphXpgY+RdM4kX2TGq2tbz
-GDVyz4crL2MjhF2EjD9XoIj8mZEoJmmZ1I+XRL6O1UixpCgp8RW04eWe3fiPpm8m
-1wk8OhwRDqZsN/etRIcsKMfYdIKz0G9KV7s1KSegi+ghp4dkNl3M2Basx7InQJJV
-OCiNUW7dFGdTbHFcJoRNdVq2fmBWqU2t+5sel/MN2dKXVHfaPRK34B7vCAas+YWH
-6aLcr34YEoP9VhdBLtUpgn2Z9DH2canPLAEnpQW5qrJITirvn5NSUZU8UnOOVkwX
-QMAJKOSLakhT2+zNVVXxxvjpoixMptEmX36vWkzaH6byHCx+rgIW0lbQL1dTR+iS
------END CERTIFICATE-----
-
 # Issuer: CN=AAA Certificate Services O=Comodo CA Limited
 # Subject: CN=AAA Certificate Services O=Comodo CA Limited
 # Label: "Comodo AAA Services root"
@@ -643,46 +472,6 @@ VSJYACPq4xJDKVtHCN2MQWplBqjlIapBtJUhlbl90TSrE9atvNziPTnNvT51cKEY
 WQPJIrSPnNVeKtelttQKbfi3QBFGmh95DmK/D5fs4C8fF5Q=
 -----END CERTIFICATE-----
 
-# Issuer: O=Government Root Certification Authority
-# Subject: O=Government Root Certification Authority
-# Label: "Taiwan GRCA"
-# Serial: 42023070807708724159991140556527066870
-# MD5 Fingerprint: 37:85:44:53:32:45:1f:20:f0:f3:95:e1:25:c4:43:4e
-# SHA1 Fingerprint: f4:8b:11:bf:de:ab:be:94:54:20:71:e6:41:de:6b:be:88:2b:40:b9
-# SHA256 Fingerprint: 76:00:29:5e:ef:e8:5b:9e:1f:d6:24:db:76:06:2a:aa:ae:59:81:8a:54:d2:77:4c:d4:c0:b2:c0:11:31:e1:b3
------BEGIN CERTIFICATE-----
-MIIFcjCCA1qgAwIBAgIQH51ZWtcvwgZEpYAIaeNe9jANBgkqhkiG9w0BAQUFADA/
-MQswCQYDVQQGEwJUVzEwMC4GA1UECgwnR292ZXJubWVudCBSb290IENlcnRpZmlj
-YXRpb24gQXV0aG9yaXR5MB4XDTAyMTIwNTEzMjMzM1oXDTMyMTIwNTEzMjMzM1ow
-PzELMAkGA1UEBhMCVFcxMDAuBgNVBAoMJ0dvdmVybm1lbnQgUm9vdCBDZXJ0aWZp
-Y2F0aW9uIEF1dGhvcml0eTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIB
-AJoluOzMonWoe/fOW1mKydGGEghU7Jzy50b2iPN86aXfTEc2pBsBHH8eV4qNw8XR
-IePaJD9IK/ufLqGU5ywck9G/GwGHU5nOp/UKIXZ3/6m3xnOUT0b3EEk3+qhZSV1q
-gQdW8or5BtD3cCJNtLdBuTK4sfCxw5w/cP1T3YGq2GN49thTbqGsaoQkclSGxtKy
-yhwOeYHWtXBiCAEuTk8O1RGvqa/lmr/czIdtJuTJV6L7lvnM4T9TjGxMfptTCAts
-F/tnyMKtsc2AtJfcdgEWFelq16TheEfOhtX7MfP6Mb40qij7cEwdScevLJ1tZqa2
-jWR+tSBqnTuBto9AAGdLiYa4zGX+FVPpBMHWXx1E1wovJ5pGfaENda1UhhXcSTvx
-ls4Pm6Dso3pdvtUqdULle96ltqqvKKyskKw4t9VoNSZ63Pc78/1Fm9G7Q3hub/FC
-VGqY8A2tl+lSXunVanLeavcbYBT0peS2cWeqH+riTcFCQP5nRhc4L0c/cZyu5SHK
-YS1tB6iEfC3uUSXxY5Ce/eFXiGvviiNtsea9P63RPZYLhY3Naye7twWb7LuRqQoH
-EgKXTiCQ8P8NHuJBO9NAOueNXdpm5AKwB1KYXA6OM5zCppX7VRluTI6uSw+9wThN
-Xo+EHWbNxWCWtFJaBYmOlXqYwZE8lSOyDvR5tMl8wUohAgMBAAGjajBoMB0GA1Ud
-DgQWBBTMzO/MKWCkO7GStjz6MmKPrCUVOzAMBgNVHRMEBTADAQH/MDkGBGcqBwAE
-MTAvMC0CAQAwCQYFKw4DAhoFADAHBgVnKgMAAAQUA5vwIhP/lSg209yewDL7MTqK
-UWUwDQYJKoZIhvcNAQEFBQADggIBAECASvomyc5eMN1PhnR2WPWus4MzeKR6dBcZ
-TulStbngCnRiqmjKeKBMmo4sIy7VahIkv9Ro04rQ2JyftB8M3jh+Vzj8jeJPXgyf
-qzvS/3WXy6TjZwj/5cAWtUgBfen5Cv8b5Wppv3ghqMKnI6mGq3ZW6A4M9hPdKmaK
-ZEk9GhiHkASfQlK3T8v+R0F2Ne//AHY2RTKbxkaFXeIksB7jSJaYV0eUVXoPQbFE
-JPPB/hprv4j9wabak2BegUqZIJxIZhm1AHlUD7gsL0u8qV1bYH+Mh6XgUmMqvtg7
-hUAV/h62ZT/FS9p+tXo1KaMuephgIqP0fSdOLeq0dDzpD6QzDxARvBMB1uUO07+1
-EqLhRSPAzAhuYbeJq4PjJB7mXQfnHyA+z2fI56wwbSdLaG5LKlwCCDTb+HbkZ6Mm
-nD+iMsJKxYEYMRBWqoTvLQr/uB930r+lWKBi5NdLkXWNiYCYfm3LU05er/ayl4WX
-udpVBrkk7tfGOB5jGxI7leFYrPLfhNVfmS8NVVvmONsuP3LpSIXLuykTjx44Vbnz
-ssQwmSNOXfJIoRIM3BKQCZBUkQM8R+XVyWXgt0t97EfTsws+rZ7QdAAO671RrcDe
-LMDDav7v3Aun+kbfYNucpllQdSNpc5Oy+fwC00fmcc4QAu4njIT/rEUNE1yDMuAl
-pYYsfPQS
------END CERTIFICATE-----
-
 # Issuer: CN=DigiCert Assured ID Root CA O=DigiCert Inc OU=www.digicert.com
 # Subject: CN=DigiCert Assured ID Root CA O=DigiCert Inc OU=www.digicert.com
 # Label: "DigiCert Assured ID Root CA"
@@ -884,104 +673,6 @@ hAhm0sQ2fac+EPyI4NSA5QC9qvNOBqN6avlicuMJT+ubDgEj8Z+7fNzcbBGXJbLy
 tGMU0gYqZ4yD9c7qB9iaah7s5Aq7KkzrCWA5zspi2C5u
 -----END CERTIFICATE-----
 
-# Issuer: CN=GeoTrust Primary Certification Authority O=GeoTrust Inc.
-# Subject: CN=GeoTrust Primary Certification Authority O=GeoTrust Inc.
-# Label: "GeoTrust Primary Certification Authority"
-# Serial: 32798226551256963324313806436981982369
-# MD5 Fingerprint: 02:26:c3:01:5e:08:30:37:43:a9:d0:7d:cf:37:e6:bf
-# SHA1 Fingerprint: 32:3c:11:8e:1b:f7:b8:b6:52:54:e2:e2:10:0d:d6:02:90:37:f0:96
-# SHA256 Fingerprint: 37:d5:10:06:c5:12:ea:ab:62:64:21:f1:ec:8c:92:01:3f:c5:f8:2a:e9:8e:e5:33:eb:46:19:b8:de:b4:d0:6c
------BEGIN CERTIFICATE-----
-MIIDfDCCAmSgAwIBAgIQGKy1av1pthU6Y2yv2vrEoTANBgkqhkiG9w0BAQUFADBY
-MQswCQYDVQQGEwJVUzEWMBQGA1UEChMNR2VvVHJ1c3QgSW5jLjExMC8GA1UEAxMo
-R2VvVHJ1c3QgUHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0wNjEx
-MjcwMDAwMDBaFw0zNjA3MTYyMzU5NTlaMFgxCzAJBgNVBAYTAlVTMRYwFAYDVQQK
-Ew1HZW9UcnVzdCBJbmMuMTEwLwYDVQQDEyhHZW9UcnVzdCBQcmltYXJ5IENlcnRp
-ZmljYXRpb24gQXV0aG9yaXR5MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC
-AQEAvrgVe//UfH1nrYNke8hCUy3f9oQIIGHWAVlqnEQRr+92/ZV+zmEwu3qDXwK9
-AWbK7hWNb6EwnL2hhZ6UOvNWiAAxz9juapYC2e0DjPt1befquFUWBRaa9OBesYjA
-ZIVcFU2Ix7e64HXprQU9nceJSOC7KMgD4TCTZF5SwFlwIjVXiIrxlQqD17wxcwE0
-7e9GceBrAqg1cmuXm2bgyxx5X9gaBGgeRwLmnWDiNpcB3841kt++Z8dtd1k7j53W
-kBWUvEI0EME5+bEnPn7WinXFsq+W06Lem+SYvn3h6YGttm/81w7a4DSwDRp35+MI
-mO9Y+pyEtzavwt+s0vQQBnBxNQIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4G
-A1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQULNVQQZcVi/CPNmFbSvtr2ZnJM5IwDQYJ
-KoZIhvcNAQEFBQADggEBAFpwfyzdtzRP9YZRqSa+S7iq8XEN3GHHoOo0Hnp3DwQ1
-6CePbJC/kRYkRj5KTs4rFtULUh38H2eiAkUxT87z+gOneZ1TatnaYzr4gNfTmeGl
-4b7UVXGYNTq+k+qurUKykG/g/CFNNWMziUnWm07Kx+dOCQD32sfvmWKZd7aVIl6K
-oKv0uHiYyjgZmclynnjNS6yvGaBzEi38wkG6gZHaFloxt/m0cYASSJlyc1pZU8Fj
-UjPtp8nSOQJw+uCxQmYpqptR7TBUIhRf2asdweSU8Pj1K/fqynhG1riR/aYNKxoU
-AT6A8EKglQdebc3MS6RFjasS6LPeWuWgfOgPIh1a6Vk=
------END CERTIFICATE-----
-
-# Issuer: CN=thawte Primary Root CA O=thawte, Inc. OU=Certification Services Division/(c) 2006 thawte, Inc. - For authorized use only
-# Subject: CN=thawte Primary Root CA O=thawte, Inc. OU=Certification Services Division/(c) 2006 thawte, Inc. - For authorized use only
-# Label: "thawte Primary Root CA"
-# Serial: 69529181992039203566298953787712940909
-# MD5 Fingerprint: 8c:ca:dc:0b:22:ce:f5:be:72:ac:41:1a:11:a8:d8:12
-# SHA1 Fingerprint: 91:c6:d6:ee:3e:8a:c8:63:84:e5:48:c2:99:29:5c:75:6c:81:7b:81
-# SHA256 Fingerprint: 8d:72:2f:81:a9:c1:13:c0:79:1d:f1:36:a2:96:6d:b2:6c:95:0a:97:1d:b4:6b:41:99:f4:ea:54:b7:8b:fb:9f
------BEGIN CERTIFICATE-----
-MIIEIDCCAwigAwIBAgIQNE7VVyDV7exJ9C/ON9srbTANBgkqhkiG9w0BAQUFADCB
-qTELMAkGA1UEBhMCVVMxFTATBgNVBAoTDHRoYXd0ZSwgSW5jLjEoMCYGA1UECxMf
-Q2VydGlmaWNhdGlvbiBTZXJ2aWNlcyBEaXZpc2lvbjE4MDYGA1UECxMvKGMpIDIw
-MDYgdGhhd3RlLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxHzAdBgNV
-BAMTFnRoYXd0ZSBQcmltYXJ5IFJvb3QgQ0EwHhcNMDYxMTE3MDAwMDAwWhcNMzYw
-NzE2MjM1OTU5WjCBqTELMAkGA1UEBhMCVVMxFTATBgNVBAoTDHRoYXd0ZSwgSW5j
-LjEoMCYGA1UECxMfQ2VydGlmaWNhdGlvbiBTZXJ2aWNlcyBEaXZpc2lvbjE4MDYG
-A1UECxMvKGMpIDIwMDYgdGhhd3RlLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNl
-IG9ubHkxHzAdBgNVBAMTFnRoYXd0ZSBQcmltYXJ5IFJvb3QgQ0EwggEiMA0GCSqG
-SIb3DQEBAQUAA4IBDwAwggEKAoIBAQCsoPD7gFnUnMekz52hWXMJEEUMDSxuaPFs
-W0hoSVk3/AszGcJ3f8wQLZU0HObrTQmnHNK4yZc2AreJ1CRfBsDMRJSUjQJib+ta
-3RGNKJpchJAQeg29dGYvajig4tVUROsdB58Hum/u6f1OCyn1PoSgAfGcq/gcfomk
-6KHYcWUNo1F77rzSImANuVud37r8UVsLr5iy6S7pBOhih94ryNdOwUxkHt3Ph1i6
-Sk/KaAcdHJ1KxtUvkcx8cXIcxcBn6zL9yZJclNqFwJu/U30rCfSMnZEfl2pSy94J
-NqR32HuHUETVPm4pafs5SSYeCaWAe0At6+gnhcn+Yf1+5nyXHdWdAgMBAAGjQjBA
-MA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBR7W0XP
-r87Lev0xkhpqtvNG61dIUDANBgkqhkiG9w0BAQUFAAOCAQEAeRHAS7ORtvzw6WfU
-DW5FvlXok9LOAz/t2iWwHVfLHjp2oEzsUHboZHIMpKnxuIvW1oeEuzLlQRHAd9mz
-YJ3rG9XRbkREqaYB7FViHXe4XI5ISXycO1cRrK1zN44veFyQaEfZYGDm/Ac9IiAX
-xPcW6cTYcvnIc3zfFi8VqT79aie2oetaupgf1eNNZAqdE8hhuvU5HIe6uL17In/2
-/qxAeeWsEG89jxt5dovEN7MhGITlNgDrYyCZuen+MwS7QcjBAvlEYyCegc5C09Y/
-LHbTY5xZ3Y+m4Q6gLkH3LpVHz7z9M/P2C2F+fpErgUfCJzDupxBdN49cOSvkBPB7
-jVaMaA==
------END CERTIFICATE-----
-
-# Issuer: CN=VeriSign Class 3 Public Primary Certification Authority - G5 O=VeriSign, Inc. OU=VeriSign Trust Network/(c) 2006 VeriSign, Inc. - For authorized use only
-# Subject: CN=VeriSign Class 3 Public Primary Certification Authority - G5 O=VeriSign, Inc. OU=VeriSign Trust Network/(c) 2006 VeriSign, Inc. - For authorized use only
-# Label: "VeriSign Class 3 Public Primary Certification Authority - G5"
-# Serial: 33037644167568058970164719475676101450
-# MD5 Fingerprint: cb:17:e4:31:67:3e:e2:09:fe:45:57:93:f3:0a:fa:1c
-# SHA1 Fingerprint: 4e:b6:d5:78:49:9b:1c:cf:5f:58:1e:ad:56:be:3d:9b:67:44:a5:e5
-# SHA256 Fingerprint: 9a:cf:ab:7e:43:c8:d8:80:d0:6b:26:2a:94:de:ee:e4:b4:65:99:89:c3:d0:ca:f1:9b:af:64:05:e4:1a:b7:df
------BEGIN CERTIFICATE-----
-MIIE0zCCA7ugAwIBAgIQGNrRniZ96LtKIVjNzGs7SjANBgkqhkiG9w0BAQUFADCB
-yjELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQL
-ExZWZXJpU2lnbiBUcnVzdCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNiBWZXJp
-U2lnbiwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MUUwQwYDVQQDEzxW
-ZXJpU2lnbiBDbGFzcyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0
-aG9yaXR5IC0gRzUwHhcNMDYxMTA4MDAwMDAwWhcNMzYwNzE2MjM1OTU5WjCByjEL
-MAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZW
-ZXJpU2lnbiBUcnVzdCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNiBWZXJpU2ln
-biwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MUUwQwYDVQQDEzxWZXJp
-U2lnbiBDbGFzcyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9y
-aXR5IC0gRzUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCvJAgIKXo1
-nmAMqudLO07cfLw8RRy7K+D+KQL5VwijZIUVJ/XxrcgxiV0i6CqqpkKzj/i5Vbex
-t0uz/o9+B1fs70PbZmIVYc9gDaTY3vjgw2IIPVQT60nKWVSFJuUrjxuf6/WhkcIz
-SdhDY2pSS9KP6HBRTdGJaXvHcPaz3BJ023tdS1bTlr8Vd6Gw9KIl8q8ckmcY5fQG
-BO+QueQA5N06tRn/Arr0PO7gi+s3i+z016zy9vA9r911kTMZHRxAy3QkGSGT2RT+
-rCpSx4/VBEnkjWNHiDxpg8v+R70rfk/Fla4OndTRQ8Bnc+MUCH7lP59zuDMKz10/
-NIeWiu5T6CUVAgMBAAGjgbIwga8wDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8E
-BAMCAQYwbQYIKwYBBQUHAQwEYTBfoV2gWzBZMFcwVRYJaW1hZ2UvZ2lmMCEwHzAH
-BgUrDgMCGgQUj+XTGoasjY5rw8+AatRIGCx7GS4wJRYjaHR0cDovL2xvZ28udmVy
-aXNpZ24uY29tL3ZzbG9nby5naWYwHQYDVR0OBBYEFH/TZafC3ey78DAJ80M5+gKv
-MzEzMA0GCSqGSIb3DQEBBQUAA4IBAQCTJEowX2LP2BqYLz3q3JktvXf2pXkiOOzE
-p6B4Eq1iDkVwZMXnl2YtmAl+X6/WzChl8gGqCBpH3vn5fJJaCGkgDdk+bW48DW7Y
-5gaRQBi5+MHt39tBquCWIMnNZBU4gcmU7qKEKQsTb47bDN0lAtukixlE0kF6BWlK
-WE9gyn6CagsCqiUXObXbf+eEZSqVir2G3l6BFoMtEMze/aiCKm0oHw0LxOXnGiYZ
-4fQRbxC1lfznQgUy286dUV4otp6F01vvpX1FQHKOtw5rDgb7MzVIcbidJ4vEZV8N
-hnacRHr2lVz2XTIIM6RUthg/aFzyQkqFOFSDX9HoLPKsEdao7WNq
------END CERTIFICATE-----
-
 # Issuer: CN=SecureTrust CA O=SecureTrust Corporation
 # Subject: CN=SecureTrust CA O=SecureTrust Corporation
 # Label: "SecureTrust CA"
@@ -1130,38 +821,6 @@ fQjGGoe9GKhzvSbKYAydzpmfz1wPMOG+FDHqAjAU9JM8SaczepBGR7NjfRObTrdv
 GDeAU/7dIOA1mjbRxwG55tzd8/8dLDoWV9mSOdY=
 -----END CERTIFICATE-----
 
-# Issuer: CN=OISTE WISeKey Global Root GA CA O=WISeKey OU=Copyright (c) 2005/OISTE Foundation Endorsed
-# Subject: CN=OISTE WISeKey Global Root GA CA O=WISeKey OU=Copyright (c) 2005/OISTE Foundation Endorsed
-# Label: "OISTE WISeKey Global Root GA CA"
-# Serial: 86718877871133159090080555911823548314
-# MD5 Fingerprint: bc:6c:51:33:a7:e9:d3:66:63:54:15:72:1b:21:92:93
-# SHA1 Fingerprint: 59:22:a1:e1:5a:ea:16:35:21:f8:98:39:6a:46:46:b0:44:1b:0f:a9
-# SHA256 Fingerprint: 41:c9:23:86:6a:b4:ca:d6:b7:ad:57:80:81:58:2e:02:07:97:a6:cb:df:4f:ff:78:ce:83:96:b3:89:37:d7:f5
------BEGIN CERTIFICATE-----
-MIID8TCCAtmgAwIBAgIQQT1yx/RrH4FDffHSKFTfmjANBgkqhkiG9w0BAQUFADCB
-ijELMAkGA1UEBhMCQ0gxEDAOBgNVBAoTB1dJU2VLZXkxGzAZBgNVBAsTEkNvcHly
-aWdodCAoYykgMjAwNTEiMCAGA1UECxMZT0lTVEUgRm91bmRhdGlvbiBFbmRvcnNl
-ZDEoMCYGA1UEAxMfT0lTVEUgV0lTZUtleSBHbG9iYWwgUm9vdCBHQSBDQTAeFw0w
-NTEyMTExNjAzNDRaFw0zNzEyMTExNjA5NTFaMIGKMQswCQYDVQQGEwJDSDEQMA4G
-A1UEChMHV0lTZUtleTEbMBkGA1UECxMSQ29weXJpZ2h0IChjKSAyMDA1MSIwIAYD
-VQQLExlPSVNURSBGb3VuZGF0aW9uIEVuZG9yc2VkMSgwJgYDVQQDEx9PSVNURSBX
-SVNlS2V5IEdsb2JhbCBSb290IEdBIENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A
-MIIBCgKCAQEAy0+zAJs9Nt350UlqaxBJH+zYK7LG+DKBKUOVTJoZIyEVRd7jyBxR
-VVuuk+g3/ytr6dTqvirdqFEr12bDYVxgAsj1znJ7O7jyTmUIms2kahnBAbtzptf2
-w93NvKSLtZlhuAGio9RN1AU9ka34tAhxZK9w8RxrfvbDd50kc3vkDIzh2TbhmYsF
-mQvtRTEJysIA2/dyoJaqlYfQjse2YXMNdmaM3Bu0Y6Kff5MTMPGhJ9vZ/yxViJGg
-4E8HsChWjBgbl0SOid3gF27nKu+POQoxhILYQBRJLnpB5Kf+42TMwVlxSywhp1t9
-4B3RLoGbw9ho972WG6xwsRYUC9tguSYBBQIDAQABo1EwTzALBgNVHQ8EBAMCAYYw
-DwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUswN+rja8sHnR3JQmthG+IbJphpQw
-EAYJKwYBBAGCNxUBBAMCAQAwDQYJKoZIhvcNAQEFBQADggEBAEuh/wuHbrP5wUOx
-SPMowB0uyQlB+pQAHKSkq0lPjz0e701vvbyk9vImMMkQyh2I+3QZH4VFvbBsUfk2
-ftv1TDI6QU9bR8/oCy22xBmddMVHxjtqD6wU2zz0c5ypBd8A3HR4+vg1YFkCExh8
-vPtNsCBtQ7tgMHpnM1zFmdH4LTlSc/uMqpclXHLZCB6rTjzjgTGfA6b7wP4piFXa
-hNVQA7bihKOmNqoROgHhGEvWRGizPflTdISzRpFGlgC3gCy24eMQ4tui5yiPAZZi
-Fj4A4xylNoEYokxSdsARo27mHbrjWr42U8U+dY+GaSlYU7Wcu2+fXMUY7N0v4ZjJ
-/L7fCg0=
------END CERTIFICATE-----
-
 # Issuer: CN=Certigna O=Dhimyotis
 # Subject: CN=Certigna O=Dhimyotis
 # Label: "Certigna"
@@ -1291,95 +950,6 @@ i/nDhDwTqn6Sm1dTk/pwwpEOMfmbZ13pljheX7NzTogVZ96edhBiIL5VaZVDADlN
 9u6wWk5JRFRYX0KD
 -----END CERTIFICATE-----
 
-# Issuer: CN=GeoTrust Primary Certification Authority - G3 O=GeoTrust Inc. OU=(c) 2008 GeoTrust Inc. - For authorized use only
-# Subject: CN=GeoTrust Primary Certification Authority - G3 O=GeoTrust Inc. OU=(c) 2008 GeoTrust Inc. - For authorized use only
-# Label: "GeoTrust Primary Certification Authority - G3"
-# Serial: 28809105769928564313984085209975885599
-# MD5 Fingerprint: b5:e8:34:36:c9:10:44:58:48:70:6d:2e:83:d4:b8:05
-# SHA1 Fingerprint: 03:9e:ed:b8:0b:e7:a0:3c:69:53:89:3b:20:d2:d9:32:3a:4c:2a:fd
-# SHA256 Fingerprint: b4:78:b8:12:25:0d:f8:78:63:5c:2a:a7:ec:7d:15:5e:aa:62:5e:e8:29:16:e2:cd:29:43:61:88:6c:d1:fb:d4
------BEGIN CERTIFICATE-----
-MIID/jCCAuagAwIBAgIQFaxulBmyeUtB9iepwxgPHzANBgkqhkiG9w0BAQsFADCB
-mDELMAkGA1UEBhMCVVMxFjAUBgNVBAoTDUdlb1RydXN0IEluYy4xOTA3BgNVBAsT
-MChjKSAyMDA4IEdlb1RydXN0IEluYy4gLSBGb3IgYXV0aG9yaXplZCB1c2Ugb25s
-eTE2MDQGA1UEAxMtR2VvVHJ1c3QgUHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhv
-cml0eSAtIEczMB4XDTA4MDQwMjAwMDAwMFoXDTM3MTIwMTIzNTk1OVowgZgxCzAJ
-BgNVBAYTAlVTMRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMTkwNwYDVQQLEzAoYykg
-MjAwOCBHZW9UcnVzdCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxNjA0
-BgNVBAMTLUdlb1RydXN0IFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkg
-LSBHMzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANziXmJYHTNXOTIz
-+uvLh4yn1ErdBojqZI4xmKU4kB6Yzy5jK/BGvESyiaHAKAxJcCGVn2TAppMSAmUm
-hsalifD614SgcK9PGpc/BkTVyetyEH3kMSj7HGHmKAdEc5IiaacDiGydY8hS2pgn
-5whMcD60yRLBxWeDXTPzAxHsatBT4tG6NmCUgLthY2xbF37fQJQeqw3CIShwiP/W
-JmxsYAQlTlV+fe+/lEjetx3dcI0FX4ilm/LC7urRQEFtYjgdVgbFA0dRIBn8exAL
-DmKudlW/X3e+PkkBUz2YJQN2JFodtNuJ6nnltrM7P7pMKEF/BqxqjsHQ9gUdfeZC
-huOl1UcCAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYw
-HQYDVR0OBBYEFMR5yo6hTgMdHNxr2zFblD4/MH8tMA0GCSqGSIb3DQEBCwUAA4IB
-AQAtxRPPVoB7eni9n64smefv2t+UXglpp+duaIy9cr5HqQ6XErhK8WTTOd8lNNTB
-zU6B8A8ExCSzNJbGpqow32hhc9f5joWJ7w5elShKKiePEI4ufIbEAp7aDHdlDkQN
-kv39sxY2+hENHYwOB4lqKVb3cvTdFZx3NWZXqxNT2I7BQMXXExZacse3aQHEerGD
-AWh9jUGhlBjBJVz88P6DAod8DQ3PLghcSkANPuyBYeYk28rgDi0Hsj5W3I31QYUH
-SJsMC8tJP33st/3LjWeJGqvtux6jAAgIFyqCXDFdRootD4abdNlF+9RAsXqqaC2G
-spki4cErx5z481+oghLrGREt
------END CERTIFICATE-----
-
-# Issuer: CN=thawte Primary Root CA - G2 O=thawte, Inc. OU=(c) 2007 thawte, Inc. - For authorized use only
-# Subject: CN=thawte Primary Root CA - G2 O=thawte, Inc. OU=(c) 2007 thawte, Inc. - For authorized use only
-# Label: "thawte Primary Root CA - G2"
-# Serial: 71758320672825410020661621085256472406
-# MD5 Fingerprint: 74:9d:ea:60:24:c4:fd:22:53:3e:cc:3a:72:d9:29:4f
-# SHA1 Fingerprint: aa:db:bc:22:23:8f:c4:01:a1:27:bb:38:dd:f4:1d:db:08:9e:f0:12
-# SHA256 Fingerprint: a4:31:0d:50:af:18:a6:44:71:90:37:2a:86:af:af:8b:95:1f:fb:43:1d:83:7f:1e:56:88:b4:59:71:ed:15:57
------BEGIN CERTIFICATE-----
-MIICiDCCAg2gAwIBAgIQNfwmXNmET8k9Jj1Xm67XVjAKBggqhkjOPQQDAzCBhDEL
-MAkGA1UEBhMCVVMxFTATBgNVBAoTDHRoYXd0ZSwgSW5jLjE4MDYGA1UECxMvKGMp
-IDIwMDcgdGhhd3RlLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxJDAi
-BgNVBAMTG3RoYXd0ZSBQcmltYXJ5IFJvb3QgQ0EgLSBHMjAeFw0wNzExMDUwMDAw
-MDBaFw0zODAxMTgyMzU5NTlaMIGEMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMdGhh
-d3RlLCBJbmMuMTgwNgYDVQQLEy8oYykgMjAwNyB0aGF3dGUsIEluYy4gLSBGb3Ig
-YXV0aG9yaXplZCB1c2Ugb25seTEkMCIGA1UEAxMbdGhhd3RlIFByaW1hcnkgUm9v
-dCBDQSAtIEcyMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAEotWcgnuVnfFSeIf+iha/
-BebfowJPDQfGAFG6DAJSLSKkQjnE/o/qycG+1E3/n3qe4rF8mq2nhglzh9HnmuN6
-papu+7qzcMBniKI11KOasf2twu8x+qi58/sIxpHR+ymVo0IwQDAPBgNVHRMBAf8E
-BTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUmtgAMADna3+FGO6Lts6K
-DPgR4bswCgYIKoZIzj0EAwMDaQAwZgIxAN344FdHW6fmCsO99YCKlzUNG4k8VIZ3
-KMqh9HneteY4sPBlcIx/AlTCv//YoT7ZzwIxAMSNlPzcU9LcnXgWHxUzI1NS41ox
-XZ3Krr0TKUQNJ1uo52icEvdYPy5yAlejj6EULg==
------END CERTIFICATE-----
-
-# Issuer: CN=thawte Primary Root CA - G3 O=thawte, Inc. OU=Certification Services Division/(c) 2008 thawte, Inc. - For authorized use only
-# Subject: CN=thawte Primary Root CA - G3 O=thawte, Inc. OU=Certification Services Division/(c) 2008 thawte, Inc. - For authorized use only
-# Label: "thawte Primary Root CA - G3"
-# Serial: 127614157056681299805556476275995414779
-# MD5 Fingerprint: fb:1b:5d:43:8a:94:cd:44:c6:76:f2:43:4b:47:e7:31
-# SHA1 Fingerprint: f1:8b:53:8d:1b:e9:03:b6:a6:f0:56:43:5b:17:15:89:ca:f3:6b:f2
-# SHA256 Fingerprint: 4b:03:f4:58:07:ad:70:f2:1b:fc:2c:ae:71:c9:fd:e4:60:4c:06:4c:f5:ff:b6:86:ba:e5:db:aa:d7:fd:d3:4c
------BEGIN CERTIFICATE-----
-MIIEKjCCAxKgAwIBAgIQYAGXt0an6rS0mtZLL/eQ+zANBgkqhkiG9w0BAQsFADCB
-rjELMAkGA1UEBhMCVVMxFTATBgNVBAoTDHRoYXd0ZSwgSW5jLjEoMCYGA1UECxMf
-Q2VydGlmaWNhdGlvbiBTZXJ2aWNlcyBEaXZpc2lvbjE4MDYGA1UECxMvKGMpIDIw
-MDggdGhhd3RlLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxJDAiBgNV
-BAMTG3RoYXd0ZSBQcmltYXJ5IFJvb3QgQ0EgLSBHMzAeFw0wODA0MDIwMDAwMDBa
-Fw0zNzEyMDEyMzU5NTlaMIGuMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMdGhhd3Rl
-LCBJbmMuMSgwJgYDVQQLEx9DZXJ0aWZpY2F0aW9uIFNlcnZpY2VzIERpdmlzaW9u
-MTgwNgYDVQQLEy8oYykgMjAwOCB0aGF3dGUsIEluYy4gLSBGb3IgYXV0aG9yaXpl
-ZCB1c2Ugb25seTEkMCIGA1UEAxMbdGhhd3RlIFByaW1hcnkgUm9vdCBDQSAtIEcz
-MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAsr8nLPvb2FvdeHsbnndm
-gcs+vHyu86YnmjSjaDFxODNi5PNxZnmxqWWjpYvVj2AtP0LMqmsywCPLLEHd5N/8
-YZzic7IilRFDGF/Eth9XbAoFWCLINkw6fKXRz4aviKdEAhN0cXMKQlkC+BsUa0Lf
-b1+6a4KinVvnSr0eAXLbS3ToO39/fR8EtCab4LRarEc9VbjXsCZSKAExQGbY2SS9
-9irY7CFJXJv2eul/VTV+lmuNk5Mny5K76qxAwJ/C+IDPXfRa3M50hqY+bAtTyr2S
-zhkGcuYMXDhpxwTWvGzOW/b3aJzcJRVIiKHpqfiYnODz1TEoYRFsZ5aNOZnLwkUk
-OQIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNV
-HQ4EFgQUrWyqlGCc7eT/+j4KdCtjA/e2Wb8wDQYJKoZIhvcNAQELBQADggEBABpA
-2JVlrAmSicY59BDlqQ5mU1143vokkbvnRFHfxhY0Cu9qRFHqKweKA3rD6z8KLFIW
-oCtDuSWQP3CpMyVtRRooOyfPqsMpQhvfO0zAMzRbQYi/aytlryjvsvXDqmbOe1bu
-t8jLZ8HJnBoYuMTDSQPxYA5QzUbF83d597YV4Djbxy8ooAw/dyZ02SUS2jHaGh7c
-KUGRIjxpp7sC8rZcJwOJ9Abqm+RyguOhCcHpABnTPtRwa7pxpqpYrvS76Wy274fM
-m7v/OeZWYdMKp8RcTGB7BXcmer/YB1IsYvdwY9k5vG8cwnncdimvzsUsZAReiDZu
-MdRAGmI0Nj81Aa6sY6A=
------END CERTIFICATE-----
-
 # Issuer: CN=GeoTrust Primary Certification Authority - G2 O=GeoTrust Inc. OU=(c) 2007 GeoTrust Inc. - For authorized use only
 # Subject: CN=GeoTrust Primary Certification Authority - G2 O=GeoTrust Inc. OU=(c) 2007 GeoTrust Inc. - For authorized use only
 # Label: "GeoTrust Primary Certification Authority - G2"
@@ -1441,35 +1011,6 @@ lRQOfc2VNNnSj3BzgXucfr2YYdhFh5iQxeuGMMY1v/D/w1WIg0vvBZIGcfK4mJO3
 7M2CYfE45k+XmCpajQ==
 -----END CERTIFICATE-----
 
-# Issuer: CN=VeriSign Class 3 Public Primary Certification Authority - G4 O=VeriSign, Inc. OU=VeriSign Trust Network/(c) 2007 VeriSign, Inc. - For authorized use only
-# Subject: CN=VeriSign Class 3 Public Primary Certification Authority - G4 O=VeriSign, Inc. OU=VeriSign Trust Network/(c) 2007 VeriSign, Inc. - For authorized use only
-# Label: "VeriSign Class 3 Public Primary Certification Authority - G4"
-# Serial: 63143484348153506665311985501458640051
-# MD5 Fingerprint: 3a:52:e1:e7:fd:6f:3a:e3:6f:f3:6f:99:1b:f9:22:41
-# SHA1 Fingerprint: 22:d5:d8:df:8f:02:31:d1:8d:f7:9d:b7:cf:8a:2d:64:c9:3f:6c:3a
-# SHA256 Fingerprint: 69:dd:d7:ea:90:bb:57:c9:3e:13:5d:c8:5e:a6:fc:d5:48:0b:60:32:39:bd:c4:54:fc:75:8b:2a:26:cf:7f:79
------BEGIN CERTIFICATE-----
-MIIDhDCCAwqgAwIBAgIQL4D+I4wOIg9IZxIokYesszAKBggqhkjOPQQDAzCByjEL
-MAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZW
-ZXJpU2lnbiBUcnVzdCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNyBWZXJpU2ln
-biwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MUUwQwYDVQQDEzxWZXJp
-U2lnbiBDbGFzcyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9y
-aXR5IC0gRzQwHhcNMDcxMTA1MDAwMDAwWhcNMzgwMTE4MjM1OTU5WjCByjELMAkG
-A1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZWZXJp
-U2lnbiBUcnVzdCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNyBWZXJpU2lnbiwg
-SW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MUUwQwYDVQQDEzxWZXJpU2ln
-biBDbGFzcyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5
-IC0gRzQwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAASnVnp8Utpkmw4tXNherJI9/gHm
-GUo9FANL+mAnINmDiWn6VMaaGF5VKmTeBvaNSjutEDxlPZCIBIngMGGzrl0Bp3ve
-fLK+ymVhAIau2o970ImtTR1ZmkGxvEeA3J5iw/mjgbIwga8wDwYDVR0TAQH/BAUw
-AwEB/zAOBgNVHQ8BAf8EBAMCAQYwbQYIKwYBBQUHAQwEYTBfoV2gWzBZMFcwVRYJ
-aW1hZ2UvZ2lmMCEwHzAHBgUrDgMCGgQUj+XTGoasjY5rw8+AatRIGCx7GS4wJRYj
-aHR0cDovL2xvZ28udmVyaXNpZ24uY29tL3ZzbG9nby5naWYwHQYDVR0OBBYEFLMW
-kf3upm7ktS5Jj4d4gYDs5bG1MAoGCCqGSM49BAMDA2gAMGUCMGYhDBgmYFo4e1ZC
-4Kf8NoRRkSAsdk1DPcQdhCPQrNZ8NQbOzWm9kA3bbEhCHQ6qQgIxAJw9SDkjOVga
-FRJZap7v1VmyHVIsmXHNxynfGyphe3HR3vPA5Q06Sqotp9iGKt0uEA==
------END CERTIFICATE-----
-
 # Issuer: CN=NetLock Arany (Class Gold) FÅ‘tanúsítvány O=NetLock Kft. OU=Tanúsítványkiadók (Certification Services)
 # Subject: CN=NetLock Arany (Class Gold) FÅ‘tanúsítvány O=NetLock Kft. OU=Tanúsítványkiadók (Certification Services)
 # Label: "NetLock Arany (Class Gold) FÅ‘tanúsítvány"
@@ -1502,47 +1043,6 @@ uLjbvrW5KfnaNwUASZQDhETnv0Mxz3WLJdH0pmT1kvarBes96aULNmLazAZfNou2
 XjG4Kvte9nHfRCaexOYNkbQudZWAUWpLMKawYqGT8ZvYzsRjdT9ZR7E=
 -----END CERTIFICATE-----
 
-# Issuer: CN=Staat der Nederlanden Root CA - G2 O=Staat der Nederlanden
-# Subject: CN=Staat der Nederlanden Root CA - G2 O=Staat der Nederlanden
-# Label: "Staat der Nederlanden Root CA - G2"
-# Serial: 10000012
-# MD5 Fingerprint: 7c:a5:0f:f8:5b:9a:7d:6d:30:ae:54:5a:e3:42:a2:8a
-# SHA1 Fingerprint: 59:af:82:79:91:86:c7:b4:75:07:cb:cf:03:57:46:eb:04:dd:b7:16
-# SHA256 Fingerprint: 66:8c:83:94:7d:a6:3b:72:4b:ec:e1:74:3c:31:a0:e6:ae:d0:db:8e:c5:b3:1b:e3:77:bb:78:4f:91:b6:71:6f
------BEGIN CERTIFICATE-----
-MIIFyjCCA7KgAwIBAgIEAJiWjDANBgkqhkiG9w0BAQsFADBaMQswCQYDVQQGEwJO
-TDEeMBwGA1UECgwVU3RhYXQgZGVyIE5lZGVybGFuZGVuMSswKQYDVQQDDCJTdGFh
-dCBkZXIgTmVkZXJsYW5kZW4gUm9vdCBDQSAtIEcyMB4XDTA4MDMyNjExMTgxN1oX
-DTIwMDMyNTExMDMxMFowWjELMAkGA1UEBhMCTkwxHjAcBgNVBAoMFVN0YWF0IGRl
-ciBOZWRlcmxhbmRlbjErMCkGA1UEAwwiU3RhYXQgZGVyIE5lZGVybGFuZGVuIFJv
-b3QgQ0EgLSBHMjCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAMVZ5291
-qj5LnLW4rJ4L5PnZyqtdj7U5EILXr1HgO+EASGrP2uEGQxGZqhQlEq0i6ABtQ8Sp
-uOUfiUtnvWFI7/3S4GCI5bkYYCjDdyutsDeqN95kWSpGV+RLufg3fNU254DBtvPU
-Z5uW6M7XxgpT0GtJlvOjCwV3SPcl5XCsMBQgJeN/dVrlSPhOewMHBPqCYYdu8DvE
-pMfQ9XQ+pV0aCPKbJdL2rAQmPlU6Yiile7Iwr/g3wtG61jj99O9JMDeZJiFIhQGp
-5Rbn3JBV3w/oOM2ZNyFPXfUib2rFEhZgF1XyZWampzCROME4HYYEhLoaJXhena/M
-UGDWE4dS7WMfbWV9whUYdMrhfmQpjHLYFhN9C0lK8SgbIHRrxT3dsKpICT0ugpTN
-GmXZK4iambwYfp/ufWZ8Pr2UuIHOzZgweMFvZ9C+X+Bo7d7iscksWXiSqt8rYGPy
-5V6548r6f1CGPqI0GAwJaCgRHOThuVw+R7oyPxjMW4T182t0xHJ04eOLoEq9jWYv
-6q012iDTiIJh8BIitrzQ1aTsr1SIJSQ8p22xcik/Plemf1WvbibG/ufMQFxRRIEK
-eN5KzlW/HdXZt1bv8Hb/C3m1r737qWmRRpdogBQ2HbN/uymYNqUg+oJgYjOk7Na6
-B6duxc8UpufWkjTYgfX8HV2qXB72o007uPc5AgMBAAGjgZcwgZQwDwYDVR0TAQH/
-BAUwAwEB/zBSBgNVHSAESzBJMEcGBFUdIAAwPzA9BggrBgEFBQcCARYxaHR0cDov
-L3d3dy5wa2lvdmVyaGVpZC5ubC9wb2xpY2llcy9yb290LXBvbGljeS1HMjAOBgNV
-HQ8BAf8EBAMCAQYwHQYDVR0OBBYEFJFoMocVHYnitfGsNig0jQt8YojrMA0GCSqG
-SIb3DQEBCwUAA4ICAQCoQUpnKpKBglBu4dfYszk78wIVCVBR7y29JHuIhjv5tLyS
-CZa59sCrI2AGeYwRTlHSeYAz+51IvuxBQ4EffkdAHOV6CMqqi3WtFMTC6GY8ggen
-5ieCWxjmD27ZUD6KQhgpxrRW/FYQoAUXvQwjf/ST7ZwaUb7dRUG/kSS0H4zpX897
-IZmflZ85OkYcbPnNe5yQzSipx6lVu6xiNGI1E0sUOlWDuYaNkqbG9AclVMwWVxJK
-gnjIFNkXgiYtXSAfea7+1HAWFpWD2DU5/1JddRwWxRNVz0fMdWVSSt7wsKfkCpYL
-+63C4iWEst3kvX5ZbJvw8NjnyvLplzh+ib7M+zkXYT9y2zqR2GUBGR2tUKRXCnxL
-vJxxcypFURmFzI79R6d0lR2o0a9OF7FpJsKqeFdbxU2n5Z4FF5TKsl+gSRiNNOkm
-bEgeqmiSBeGCc1qb3AdbCG19ndeNIdn8FCCqwkXfP+cAslHkwvgFuXkajDTznlvk
-N1trSt8sV4pAWja63XVECDdCcAz+3F4hoKOKwJCcaNpQ5kUQR3i2TtJlycM33+FC
-Y7BXN0Ute4qcvwXqZVUz9zkQxSgqIXobisQk+T8VyJoVIPVVYpbtbZNQvOSqeK3Z
-ywplh6ZmwcSBo3c6WB4L7oOLnR7SUqTMHW+wmG2UMbX4cQrcufx9MmDm66+KAQ==
------END CERTIFICATE-----
-
 # Issuer: CN=Hongkong Post Root CA 1 O=Hongkong Post
 # Subject: CN=Hongkong Post Root CA 1 O=Hongkong Post
 # Label: "Hongkong Post Root CA 1"
@@ -2394,38 +1894,6 @@ e9eiPZaGzPImNC1qkp2aGtAw4l1OBLBfiyB+d8E9lYLRRpo7PHi4b6HQDWSieB4p
 TpPDpFQUWw==
 -----END CERTIFICATE-----
 
-# Issuer: CN=EE Certification Centre Root CA O=AS Sertifitseerimiskeskus
-# Subject: CN=EE Certification Centre Root CA O=AS Sertifitseerimiskeskus
-# Label: "EE Certification Centre Root CA"
-# Serial: 112324828676200291871926431888494945866
-# MD5 Fingerprint: 43:5e:88:d4:7d:1a:4a:7e:fd:84:2e:52:eb:01:d4:6f
-# SHA1 Fingerprint: c9:a8:b9:e7:55:80:5e:58:e3:53:77:a7:25:eb:af:c3:7b:27:cc:d7
-# SHA256 Fingerprint: 3e:84:ba:43:42:90:85:16:e7:75:73:c0:99:2f:09:79:ca:08:4e:46:85:68:1f:f1:95:cc:ba:8a:22:9b:8a:76
------BEGIN CERTIFICATE-----
-MIIEAzCCAuugAwIBAgIQVID5oHPtPwBMyonY43HmSjANBgkqhkiG9w0BAQUFADB1
-MQswCQYDVQQGEwJFRTEiMCAGA1UECgwZQVMgU2VydGlmaXRzZWVyaW1pc2tlc2t1
-czEoMCYGA1UEAwwfRUUgQ2VydGlmaWNhdGlvbiBDZW50cmUgUm9vdCBDQTEYMBYG
-CSqGSIb3DQEJARYJcGtpQHNrLmVlMCIYDzIwMTAxMDMwMTAxMDMwWhgPMjAzMDEy
-MTcyMzU5NTlaMHUxCzAJBgNVBAYTAkVFMSIwIAYDVQQKDBlBUyBTZXJ0aWZpdHNl
-ZXJpbWlza2Vza3VzMSgwJgYDVQQDDB9FRSBDZXJ0aWZpY2F0aW9uIENlbnRyZSBS
-b290IENBMRgwFgYJKoZIhvcNAQkBFglwa2lAc2suZWUwggEiMA0GCSqGSIb3DQEB
-AQUAA4IBDwAwggEKAoIBAQDIIMDs4MVLqwd4lfNE7vsLDP90jmG7sWLqI9iroWUy
-euuOF0+W2Ap7kaJjbMeMTC55v6kF/GlclY1i+blw7cNRfdCT5mzrMEvhvH2/UpvO
-bntl8jixwKIy72KyaOBhU8E2lf/slLo2rpwcpzIP5Xy0xm90/XsY6KxX7QYgSzIw
-WFv9zajmofxwvI6Sc9uXp3whrj3B9UiHbCe9nyV0gVWw93X2PaRka9ZP585ArQ/d
-MtO8ihJTmMmJ+xAdTX7Nfh9WDSFwhfYggx/2uh8Ej+p3iDXE/+pOoYtNP2MbRMNE
-1CV2yreN1x5KZmTNXMWcg+HCCIia7E6j8T4cLNlsHaFLAgMBAAGjgYowgYcwDwYD
-VR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFBLyWj7qVhy/
-zQas8fElyalL1BSZMEUGA1UdJQQ+MDwGCCsGAQUFBwMCBggrBgEFBQcDAQYIKwYB
-BQUHAwMGCCsGAQUFBwMEBggrBgEFBQcDCAYIKwYBBQUHAwkwDQYJKoZIhvcNAQEF
-BQADggEBAHv25MANqhlHt01Xo/6tu7Fq1Q+e2+RjxY6hUFaTlrg4wCQiZrxTFGGV
-v9DHKpY5P30osxBAIWrEr7BSdxjhlthWXePdNl4dp1BUoMUq5KqMlIpPnTX/dqQG
-E5Gion0ARD9V04I8GtVbvFZMIi5GQ4okQC3zErg7cBqklrkar4dBGmoYDQZPxz5u
-uSlNDUmJEYcyW+ZLBMjkXOZ0c5RdFpgTlf7727FE5TpwrDdr5rMzcijJs1eg9gIW
-iAYLtqZLICjU3j2LrTcFU3T+bsy8QxdxXvnFzBqpYe73dgzzcvRyrc9yAjYHR8/v
-GVCJYMzpJJUPwssd8m92kMfMdcGWxZ0=
------END CERTIFICATE-----
-
 # Issuer: CN=D-TRUST Root Class 3 CA 2 2009 O=D-Trust GmbH
 # Subject: CN=D-TRUST Root Class 3 CA 2 2009 O=D-Trust GmbH
 # Label: "D-TRUST Root Class 3 CA 2 2009"
@@ -3791,47 +3259,6 @@ CkcO8DdZEv8tmZQoTipPNU0zWgIxAOp1AE47xDqUEpHJWEadIRNyp4iciuRMStuW
 1KyLa2tJElMzrdfkviT8tQp21KW8EA==
 -----END CERTIFICATE-----
 
-# Issuer: CN=LuxTrust Global Root 2 O=LuxTrust S.A.
-# Subject: CN=LuxTrust Global Root 2 O=LuxTrust S.A.
-# Label: "LuxTrust Global Root 2"
-# Serial: 59914338225734147123941058376788110305822489521
-# MD5 Fingerprint: b2:e1:09:00:61:af:f7:f1:91:6f:c4:ad:8d:5e:3b:7c
-# SHA1 Fingerprint: 1e:0e:56:19:0a:d1:8b:25:98:b2:04:44:ff:66:8a:04:17:99:5f:3f
-# SHA256 Fingerprint: 54:45:5f:71:29:c2:0b:14:47:c4:18:f9:97:16:8f:24:c5:8f:c5:02:3b:f5:da:5b:e2:eb:6e:1d:d8:90:2e:d5
------BEGIN CERTIFICATE-----
-MIIFwzCCA6ugAwIBAgIUCn6m30tEntpqJIWe5rgV0xZ/u7EwDQYJKoZIhvcNAQEL
-BQAwRjELMAkGA1UEBhMCTFUxFjAUBgNVBAoMDUx1eFRydXN0IFMuQS4xHzAdBgNV
-BAMMFkx1eFRydXN0IEdsb2JhbCBSb290IDIwHhcNMTUwMzA1MTMyMTU3WhcNMzUw
-MzA1MTMyMTU3WjBGMQswCQYDVQQGEwJMVTEWMBQGA1UECgwNTHV4VHJ1c3QgUy5B
-LjEfMB0GA1UEAwwWTHV4VHJ1c3QgR2xvYmFsIFJvb3QgMjCCAiIwDQYJKoZIhvcN
-AQEBBQADggIPADCCAgoCggIBANeFl78RmOnwYoNMPIf5U2o3C/IPPIfOb9wmKb3F
-ibrJgz337spbxm1Jc7TJRqMbNBM/wYlFV/TZsfs2ZUv7COJIcRHIbjuend+JZTem
-hfY7RBi2xjcwYkSSl2l9QjAk5A0MiWtj3sXh306pFGxT4GHO9hcvHTy95iJMHZP1
-EMShduxq3sVs35a0VkBCwGKSMKEtFZSg0iAGCW5qbeXrt77U8PEVfIvmTroTzEsn
-Xpk8F12PgX8zPU/TPxvsXD/wPEx1bvKm1Z3aLQdjAsZy6ZS8TEmVT4hSyNvoaYL4
-zDRbIvCGp4m9SAptZoFtyMhk+wHh9OHe2Z7d21vUKpkmFRseTJIpgp7VkoGSQXAZ
-96Tlk0u8d2cx3Rz9MXANF5kM+Qw5GSoXtTBxVdUPrljhPS80m8+f9niFwpN6cj5m
-j5wWEWCPnolvZ77gR1o7DJpni89Gxq44o/KnvObWhWszJHAiS8sIm7vI+AIpHb4g
-DEa/a4ebsypmQjVGbKq6rfmYe+lQVRQxv7HaLe2ArWgk+2mr2HETMOZns4dA/Yl+
-8kPREd8vZS9kzl8UubG/Mb2HeFpZZYiq/FkySIbWTLkpS5XTdvN3JW1CHDiDTf2j
-X5t/Lax5Gw5CMZdjpPuKadUiDTSQMC6otOBttpSsvItO13D8xTiOZCXhTTmQzsmH
-hFhxAgMBAAGjgagwgaUwDwYDVR0TAQH/BAUwAwEB/zBCBgNVHSAEOzA5MDcGByuB
-KwEBAQowLDAqBggrBgEFBQcCARYeaHR0cHM6Ly9yZXBvc2l0b3J5Lmx1eHRydXN0
-Lmx1MA4GA1UdDwEB/wQEAwIBBjAfBgNVHSMEGDAWgBT/GCh2+UgFLKGu8SsbK7JT
-+Et8szAdBgNVHQ4EFgQU/xgodvlIBSyhrvErGyuyU/hLfLMwDQYJKoZIhvcNAQEL
-BQADggIBAGoZFO1uecEsh9QNcH7X9njJCwROxLHOk3D+sFTAMs2ZMGQXvw/l4jP9
-BzZAcg4atmpZ1gDlaCDdLnINH2pkMSCEfUmmWjfrRcmF9dTHF5kH5ptV5AzoqbTO
-jFu1EVzPig4N1qx3gf4ynCSecs5U89BvolbW7MM3LGVYvlcAGvI1+ut7MV3CwRI9
-loGIlonBWVx65n9wNOeD4rHh4bhY79SV5GCc8JaXcozrhAIuZY+kt9J/Z93I055c
-qqmkoCUUBpvsT34tC38ddfEz2O3OuHVtPlu5mB0xDVbYQw8wkbIEa91WvpWAVWe+
-2M2D2RjuLg+GLZKecBPs3lHJQ3gCpU3I+V/EkVhGFndadKpAvAefMLmx9xIX3eP/
-JEAdemrRTxgKqpAd60Ae36EeRJIQmvKN4dFLRp7oRUKX6kWZ8+xm1QL68qZKJKre
-zrnK+T+Tb/mjuuqlPpmt/f97mfVl7vBZKGfXkJWkE4SphMHozs51k2MavDzq1WQf
-LSoSOcbDWjLtR5EWDrw4wVDej8oqkDQc7kGUnF4ZLvhFSZl0kbAEb+MEWrGrKqv+
-x9CWttrhSmQGbmBNvUJO/3jaJMobtNeWOWyu8Q6qp31IiyBMz2TWuJdGsE7RKlY6
-oJO9r4Ak4Ap+58rVyuiFVdw2KuGUaJPHZnJED4AhMmwlxyOAgwrr
------END CERTIFICATE-----
-
 # Issuer: CN=TUBITAK Kamu SM SSL Kok Sertifikasi - Surum 1 O=Turkiye Bilimsel ve Teknolojik Arastirma Kurumu - TUBITAK OU=Kamu Sertifikasyon Merkezi - Kamu SM
 # Subject: CN=TUBITAK Kamu SM SSL Kok Sertifikasi - Surum 1 O=Turkiye Bilimsel ve Teknolojik Arastirma Kurumu - TUBITAK OU=Kamu Sertifikasyon Merkezi - Kamu SM
 # Label: "TUBITAK Kamu SM SSL Kok Sertifikasi - Surum 1"
@@ -4642,3 +4069,260 @@ IQ6SwJAfzyBfyjs4x7dtOvPmRLgOMWuIjnDrnBdSqEGULoe256YSxXXfW8AKbnuk
 5F6G+TaU33fD6Q3AOfF5u0aOq0NZJ7cguyPpVkAh7DE9ZapD8j3fcEThuk0mEDuY
 n/PIjhs4ViFqUZPTkcpG2om3PVODLAgfi49T3f+sHw==
 -----END CERTIFICATE-----
+
+# Issuer: CN=Microsoft ECC Root Certificate Authority 2017 O=Microsoft Corporation
+# Subject: CN=Microsoft ECC Root Certificate Authority 2017 O=Microsoft Corporation
+# Label: "Microsoft ECC Root Certificate Authority 2017"
+# Serial: 136839042543790627607696632466672567020
+# MD5 Fingerprint: dd:a1:03:e6:4a:93:10:d1:bf:f0:19:42:cb:fe:ed:67
+# SHA1 Fingerprint: 99:9a:64:c3:7f:f4:7d:9f:ab:95:f1:47:69:89:14:60:ee:c4:c3:c5
+# SHA256 Fingerprint: 35:8d:f3:9d:76:4a:f9:e1:b7:66:e9:c9:72:df:35:2e:e1:5c:fa:c2:27:af:6a:d1:d7:0e:8e:4a:6e:dc:ba:02
+-----BEGIN CERTIFICATE-----
+MIICWTCCAd+gAwIBAgIQZvI9r4fei7FK6gxXMQHC7DAKBggqhkjOPQQDAzBlMQsw
+CQYDVQQGEwJVUzEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMTYwNAYD
+VQQDEy1NaWNyb3NvZnQgRUNDIFJvb3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5IDIw
+MTcwHhcNMTkxMjE4MjMwNjQ1WhcNNDIwNzE4MjMxNjA0WjBlMQswCQYDVQQGEwJV
+UzEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMTYwNAYDVQQDEy1NaWNy
+b3NvZnQgRUNDIFJvb3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5IDIwMTcwdjAQBgcq
+hkjOPQIBBgUrgQQAIgNiAATUvD0CQnVBEyPNgASGAlEvaqiBYgtlzPbKnR5vSmZR
+ogPZnZH6thaxjG7efM3beaYvzrvOcS/lpaso7GMEZpn4+vKTEAXhgShC48Zo9OYb
+hGBKia/teQ87zvH2RPUBeMCjVDBSMA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8E
+BTADAQH/MB0GA1UdDgQWBBTIy5lycFIM+Oa+sgRXKSrPQhDtNTAQBgkrBgEEAYI3
+FQEEAwIBADAKBggqhkjOPQQDAwNoADBlAjBY8k3qDPlfXu5gKcs68tvWMoQZP3zV
+L8KxzJOuULsJMsbG7X7JNpQS5GiFBqIb0C8CMQCZ6Ra0DvpWSNSkMBaReNtUjGUB
+iudQZsIxtzm6uBoiB078a1QWIP8rtedMDE2mT3M=
+-----END CERTIFICATE-----
+
+# Issuer: CN=Microsoft RSA Root Certificate Authority 2017 O=Microsoft Corporation
+# Subject: CN=Microsoft RSA Root Certificate Authority 2017 O=Microsoft Corporation
+# Label: "Microsoft RSA Root Certificate Authority 2017"
+# Serial: 40975477897264996090493496164228220339
+# MD5 Fingerprint: 10:ff:00:ff:cf:c9:f8:c7:7a:c0:ee:35:8e:c9:0f:47
+# SHA1 Fingerprint: 73:a5:e6:4a:3b:ff:83:16:ff:0e:dc:cc:61:8a:90:6e:4e:ae:4d:74
+# SHA256 Fingerprint: c7:41:f7:0f:4b:2a:8d:88:bf:2e:71:c1:41:22:ef:53:ef:10:eb:a0:cf:a5:e6:4c:fa:20:f4:18:85:30:73:e0
+-----BEGIN CERTIFICATE-----
+MIIFqDCCA5CgAwIBAgIQHtOXCV/YtLNHcB6qvn9FszANBgkqhkiG9w0BAQwFADBl
+MQswCQYDVQQGEwJVUzEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMTYw
+NAYDVQQDEy1NaWNyb3NvZnQgUlNBIFJvb3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5
+IDIwMTcwHhcNMTkxMjE4MjI1MTIyWhcNNDIwNzE4MjMwMDIzWjBlMQswCQYDVQQG
+EwJVUzEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMTYwNAYDVQQDEy1N
+aWNyb3NvZnQgUlNBIFJvb3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5IDIwMTcwggIi
+MA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDKW76UM4wplZEWCpW9R2LBifOZ
+Nt9GkMml7Xhqb0eRaPgnZ1AzHaGm++DlQ6OEAlcBXZxIQIJTELy/xztokLaCLeX0
+ZdDMbRnMlfl7rEqUrQ7eS0MdhweSE5CAg2Q1OQT85elss7YfUJQ4ZVBcF0a5toW1
+HLUX6NZFndiyJrDKxHBKrmCk3bPZ7Pw71VdyvD/IybLeS2v4I2wDwAW9lcfNcztm
+gGTjGqwu+UcF8ga2m3P1eDNbx6H7JyqhtJqRjJHTOoI+dkC0zVJhUXAoP8XFWvLJ
+jEm7FFtNyP9nTUwSlq31/niol4fX/V4ggNyhSyL71Imtus5Hl0dVe49FyGcohJUc
+aDDv70ngNXtk55iwlNpNhTs+VcQor1fznhPbRiefHqJeRIOkpcrVE7NLP8TjwuaG
+YaRSMLl6IE9vDzhTyzMMEyuP1pq9KsgtsRx9S1HKR9FIJ3Jdh+vVReZIZZ2vUpC6
+W6IYZVcSn2i51BVrlMRpIpj0M+Dt+VGOQVDJNE92kKz8OMHY4Xu54+OU4UZpyw4K
+UGsTuqwPN1q3ErWQgR5WrlcihtnJ0tHXUeOrO8ZV/R4O03QK0dqq6mm4lyiPSMQH
++FJDOvTKVTUssKZqwJz58oHhEmrARdlns87/I6KJClTUFLkqqNfs+avNJVgyeY+Q
+W5g5xAgGwax/Dj0ApQIDAQABo1QwUjAOBgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/
+BAUwAwEB/zAdBgNVHQ4EFgQUCctZf4aycI8awznjwNnpv7tNsiMwEAYJKwYBBAGC
+NxUBBAMCAQAwDQYJKoZIhvcNAQEMBQADggIBAKyvPl3CEZaJjqPnktaXFbgToqZC
+LgLNFgVZJ8og6Lq46BrsTaiXVq5lQ7GPAJtSzVXNUzltYkyLDVt8LkS/gxCP81OC
+gMNPOsduET/m4xaRhPtthH80dK2Jp86519efhGSSvpWhrQlTM93uCupKUY5vVau6
+tZRGrox/2KJQJWVggEbbMwSubLWYdFQl3JPk+ONVFT24bcMKpBLBaYVu32TxU5nh
+SnUgnZUP5NbcA/FZGOhHibJXWpS2qdgXKxdJ5XbLwVaZOjex/2kskZGT4d9Mozd2
+TaGf+G0eHdP67Pv0RR0Tbc/3WeUiJ3IrhvNXuzDtJE3cfVa7o7P4NHmJweDyAmH3
+pvwPuxwXC65B2Xy9J6P9LjrRk5Sxcx0ki69bIImtt2dmefU6xqaWM/5TkshGsRGR
+xpl/j8nWZjEgQRCHLQzWwa80mMpkg/sTV9HB8Dx6jKXB/ZUhoHHBk2dxEuqPiApp
+GWSZI1b7rCoucL5mxAyE7+WL85MB+GqQk2dLsmijtWKP6T+MejteD+eMuMZ87zf9
+dOLITzNy4ZQ5bb0Sr74MTnB8G2+NszKTc0QWbej09+CVgI+WXTik9KveCjCHk9hN
+AHFiRSdLOkKEW39lt2c0Ui2cFmuqqNh7o0JMcccMyj6D5KbvtwEwXlGjefVwaaZB
+RA+GsCyRxj3qrg+E
+-----END CERTIFICATE-----
+
+# Issuer: CN=e-Szigno Root CA 2017 O=Microsec Ltd.
+# Subject: CN=e-Szigno Root CA 2017 O=Microsec Ltd.
+# Label: "e-Szigno Root CA 2017"
+# Serial: 411379200276854331539784714
+# MD5 Fingerprint: de:1f:f6:9e:84:ae:a7:b4:21:ce:1e:58:7d:d1:84:98
+# SHA1 Fingerprint: 89:d4:83:03:4f:9e:9a:48:80:5f:72:37:d4:a9:a6:ef:cb:7c:1f:d1
+# SHA256 Fingerprint: be:b0:0b:30:83:9b:9b:c3:2c:32:e4:44:79:05:95:06:41:f2:64:21:b1:5e:d0:89:19:8b:51:8a:e2:ea:1b:99
+-----BEGIN CERTIFICATE-----
+MIICQDCCAeWgAwIBAgIMAVRI7yH9l1kN9QQKMAoGCCqGSM49BAMCMHExCzAJBgNV
+BAYTAkhVMREwDwYDVQQHDAhCdWRhcGVzdDEWMBQGA1UECgwNTWljcm9zZWMgTHRk
+LjEXMBUGA1UEYQwOVkFUSFUtMjM1ODQ0OTcxHjAcBgNVBAMMFWUtU3ppZ25vIFJv
+b3QgQ0EgMjAxNzAeFw0xNzA4MjIxMjA3MDZaFw00MjA4MjIxMjA3MDZaMHExCzAJ
+BgNVBAYTAkhVMREwDwYDVQQHDAhCdWRhcGVzdDEWMBQGA1UECgwNTWljcm9zZWMg
+THRkLjEXMBUGA1UEYQwOVkFUSFUtMjM1ODQ0OTcxHjAcBgNVBAMMFWUtU3ppZ25v
+IFJvb3QgQ0EgMjAxNzBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABJbcPYrYsHtv
+xie+RJCxs1YVe45DJH0ahFnuY2iyxl6H0BVIHqiQrb1TotreOpCmYF9oMrWGQd+H
+Wyx7xf58etqjYzBhMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0G
+A1UdDgQWBBSHERUI0arBeAyxr87GyZDvvzAEwDAfBgNVHSMEGDAWgBSHERUI0arB
+eAyxr87GyZDvvzAEwDAKBggqhkjOPQQDAgNJADBGAiEAtVfd14pVCzbhhkT61Nlo
+jbjcI4qKDdQvfepz7L9NbKgCIQDLpbQS+ue16M9+k/zzNY9vTlp8tLxOsvxyqltZ
++efcMQ==
+-----END CERTIFICATE-----
+
+# Issuer: O=CERTSIGN SA OU=certSIGN ROOT CA G2
+# Subject: O=CERTSIGN SA OU=certSIGN ROOT CA G2
+# Label: "certSIGN Root CA G2"
+# Serial: 313609486401300475190
+# MD5 Fingerprint: 8c:f1:75:8a:c6:19:cf:94:b7:f7:65:20:87:c3:97:c7
+# SHA1 Fingerprint: 26:f9:93:b4:ed:3d:28:27:b0:b9:4b:a7:e9:15:1d:a3:8d:92:e5:32
+# SHA256 Fingerprint: 65:7c:fe:2f:a7:3f:aa:38:46:25:71:f3:32:a2:36:3a:46:fc:e7:02:09:51:71:07:02:cd:fb:b6:ee:da:33:05
+-----BEGIN CERTIFICATE-----
+MIIFRzCCAy+gAwIBAgIJEQA0tk7GNi02MA0GCSqGSIb3DQEBCwUAMEExCzAJBgNV
+BAYTAlJPMRQwEgYDVQQKEwtDRVJUU0lHTiBTQTEcMBoGA1UECxMTY2VydFNJR04g
+Uk9PVCBDQSBHMjAeFw0xNzAyMDYwOTI3MzVaFw00MjAyMDYwOTI3MzVaMEExCzAJ
+BgNVBAYTAlJPMRQwEgYDVQQKEwtDRVJUU0lHTiBTQTEcMBoGA1UECxMTY2VydFNJ
+R04gUk9PVCBDQSBHMjCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAMDF
+dRmRfUR0dIf+DjuW3NgBFszuY5HnC2/OOwppGnzC46+CjobXXo9X69MhWf05N0Iw
+vlDqtg+piNguLWkh59E3GE59kdUWX2tbAMI5Qw02hVK5U2UPHULlj88F0+7cDBrZ
+uIt4ImfkabBoxTzkbFpG583H+u/E7Eu9aqSs/cwoUe+StCmrqzWaTOTECMYmzPhp
+n+Sc8CnTXPnGFiWeI8MgwT0PPzhAsP6CRDiqWhqKa2NYOLQV07YRaXseVO6MGiKs
+cpc/I1mbySKEwQdPzH/iV8oScLumZfNpdWO9lfsbl83kqK/20U6o2YpxJM02PbyW
+xPFsqa7lzw1uKA2wDrXKUXt4FMMgL3/7FFXhEZn91QqhngLjYl/rNUssuHLoPj1P
+rCy7Lobio3aP5ZMqz6WryFyNSwb/EkaseMsUBzXgqd+L6a8VTxaJW732jcZZroiF
+DsGJ6x9nxUWO/203Nit4ZoORUSs9/1F3dmKh7Gc+PoGD4FapUB8fepmrY7+EF3fx
+DTvf95xhszWYijqy7DwaNz9+j5LP2RIUZNoQAhVB/0/E6xyjyfqZ90bp4RjZsbgy
+LcsUDFDYg2WD7rlcz8sFWkz6GZdr1l0T08JcVLwyc6B49fFtHsufpaafItzRUZ6C
+eWRgKRM+o/1Pcmqr4tTluCRVLERLiohEnMqE0yo7AgMBAAGjQjBAMA8GA1UdEwEB
+/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBSCIS1mxteg4BXrzkwJ
+d8RgnlRuAzANBgkqhkiG9w0BAQsFAAOCAgEAYN4auOfyYILVAzOBywaK8SJJ6ejq
+kX/GM15oGQOGO0MBzwdw5AgeZYWR5hEit/UCI46uuR59H35s5r0l1ZUa8gWmr4UC
+b6741jH/JclKyMeKqdmfS0mbEVeZkkMR3rYzpMzXjWR91M08KCy0mpbqTfXERMQl
+qiCA2ClV9+BB/AYm/7k29UMUA2Z44RGx2iBfRgB4ACGlHgAoYXhvqAEBj500mv/0
+OJD7uNGzcgbJceaBxXntC6Z58hMLnPddDnskk7RI24Zf3lCGeOdA5jGokHZwYa+c
+NywRtYK3qq4kNFtyDGkNzVmf9nGvnAvRCjj5BiKDUyUM/FHE5r7iOZULJK2v0ZXk
+ltd0ZGtxTgI8qoXzIKNDOXZbbFD+mpwUHmUUihW9o4JFWklWatKcsWMy5WHgUyIO
+pwpJ6st+H6jiYoD2EEVSmAYY3qXNL3+q1Ok+CHLsIwMCPKaq2LxndD0UF/tUSxfj
+03k9bWtJySgOLnRQvwzZRjoQhsmnP+mg7H/rpXdYaXHmgwo38oZJar55CJD2AhZk
+PuXaTH4MNMn5X7azKFGnpyuqSfqNZSlO42sTp5SjLVFteAxEy9/eCG/Oo2Sr05WE
+1LlSVHJ7liXMvGnjSG4N0MedJ5qq+BOS3R7fY581qRY27Iy4g/Q9iY/NtBde17MX
+QRBdJ3NghVdJIgc=
+-----END CERTIFICATE-----
+
+# Issuer: CN=Trustwave Global Certification Authority O=Trustwave Holdings, Inc.
+# Subject: CN=Trustwave Global Certification Authority O=Trustwave Holdings, Inc.
+# Label: "Trustwave Global Certification Authority"
+# Serial: 1846098327275375458322922162
+# MD5 Fingerprint: f8:1c:18:2d:2f:ba:5f:6d:a1:6c:bc:c7:ab:91:c7:0e
+# SHA1 Fingerprint: 2f:8f:36:4f:e1:58:97:44:21:59:87:a5:2a:9a:d0:69:95:26:7f:b5
+# SHA256 Fingerprint: 97:55:20:15:f5:dd:fc:3c:87:88:c0:06:94:45:55:40:88:94:45:00:84:f1:00:86:70:86:bc:1a:2b:b5:8d:c8
+-----BEGIN CERTIFICATE-----
+MIIF2jCCA8KgAwIBAgIMBfcOhtpJ80Y1LrqyMA0GCSqGSIb3DQEBCwUAMIGIMQsw
+CQYDVQQGEwJVUzERMA8GA1UECAwISWxsaW5vaXMxEDAOBgNVBAcMB0NoaWNhZ28x
+ITAfBgNVBAoMGFRydXN0d2F2ZSBIb2xkaW5ncywgSW5jLjExMC8GA1UEAwwoVHJ1
+c3R3YXZlIEdsb2JhbCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0xNzA4MjMx
+OTM0MTJaFw00MjA4MjMxOTM0MTJaMIGIMQswCQYDVQQGEwJVUzERMA8GA1UECAwI
+SWxsaW5vaXMxEDAOBgNVBAcMB0NoaWNhZ28xITAfBgNVBAoMGFRydXN0d2F2ZSBI
+b2xkaW5ncywgSW5jLjExMC8GA1UEAwwoVHJ1c3R3YXZlIEdsb2JhbCBDZXJ0aWZp
+Y2F0aW9uIEF1dGhvcml0eTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIB
+ALldUShLPDeS0YLOvR29zd24q88KPuFd5dyqCblXAj7mY2Hf8g+CY66j96xz0Xzn
+swuvCAAJWX/NKSqIk4cXGIDtiLK0thAfLdZfVaITXdHG6wZWiYj+rDKd/VzDBcdu
+7oaJuogDnXIhhpCujwOl3J+IKMujkkkP7NAP4m1ET4BqstTnoApTAbqOl5F2brz8
+1Ws25kCI1nsvXwXoLG0R8+eyvpJETNKXpP7ScoFDB5zpET71ixpZfR9oWN0EACyW
+80OzfpgZdNmcc9kYvkHHNHnZ9GLCQ7mzJ7Aiy/k9UscwR7PJPrhq4ufogXBeQotP
+JqX+OsIgbrv4Fo7NDKm0G2x2EOFYeUY+VM6AqFcJNykbmROPDMjWLBz7BegIlT1l
+RtzuzWniTY+HKE40Cz7PFNm73bZQmq131BnW2hqIyE4bJ3XYsgjxroMwuREOzYfw
+hI0Vcnyh78zyiGG69Gm7DIwLdVcEuE4qFC49DxweMqZiNu5m4iK4BUBjECLzMx10
+coos9TkpoNPnG4CELcU9402x/RpvumUHO1jsQkUm+9jaJXLE9gCxInm943xZYkqc
+BW89zubWR2OZxiRvchLIrH+QtAuRcOi35hYQcRfO3gZPSEF9NUqjifLJS3tBEW1n
+twiYTOURGa5CgNz7kAXU+FDKvuStx8KU1xad5hePrzb7AgMBAAGjQjBAMA8GA1Ud
+EwEB/wQFMAMBAf8wHQYDVR0OBBYEFJngGWcNYtt2s9o9uFvo/ULSMQ6HMA4GA1Ud
+DwEB/wQEAwIBBjANBgkqhkiG9w0BAQsFAAOCAgEAmHNw4rDT7TnsTGDZqRKGFx6W
+0OhUKDtkLSGm+J1WE2pIPU/HPinbbViDVD2HfSMF1OQc3Og4ZYbFdada2zUFvXfe
+uyk3QAUHw5RSn8pk3fEbK9xGChACMf1KaA0HZJDmHvUqoai7PF35owgLEQzxPy0Q
+lG/+4jSHg9bP5Rs1bdID4bANqKCqRieCNqcVtgimQlRXtpla4gt5kNdXElE1GYhB
+aCXUNxeEFfsBctyV3lImIJgm4nb1J2/6ADtKYdkNy1GTKv0WBpanI5ojSP5RvbbE
+sLFUzt5sQa0WZ37b/TjNuThOssFgy50X31ieemKyJo90lZvkWx3SD92YHJtZuSPT
+MaCm/zjdzyBP6VhWOmfD0faZmZ26NraAL4hHT4a/RDqA5Dccprrql5gR0IRiR2Qe
+qu5AvzSxnI9O4fKSTx+O856X3vOmeWqJcU9LJxdI/uz0UA9PSX3MReO9ekDFQdxh
+VicGaeVyQYHTtgGJoC86cnn+OjC/QezHYj6RS8fZMXZC+fc8Y+wmjHMMfRod6qh8
+h6jCJ3zhM0EPz8/8AKAigJ5Kp28AsEFFtyLKaEjFQqKu3R3y4G5OBVixwJAWKqQ9
+EEC+j2Jjg6mcgn0tAumDMHzLJ8n9HmYAsC7TIS+OMxZsmO0QqAfWzJPP29FpHOTK
+yeC2nOnOcXHebD8WpHk=
+-----END CERTIFICATE-----
+
+# Issuer: CN=Trustwave Global ECC P256 Certification Authority O=Trustwave Holdings, Inc.
+# Subject: CN=Trustwave Global ECC P256 Certification Authority O=Trustwave Holdings, Inc.
+# Label: "Trustwave Global ECC P256 Certification Authority"
+# Serial: 4151900041497450638097112925
+# MD5 Fingerprint: 5b:44:e3:8d:5d:36:86:26:e8:0d:05:d2:59:a7:83:54
+# SHA1 Fingerprint: b4:90:82:dd:45:0c:be:8b:5b:b1:66:d3:e2:a4:08:26:cd:ed:42:cf
+# SHA256 Fingerprint: 94:5b:bc:82:5e:a5:54:f4:89:d1:fd:51:a7:3d:df:2e:a6:24:ac:70:19:a0:52:05:22:5c:22:a7:8c:cf:a8:b4
+-----BEGIN CERTIFICATE-----
+MIICYDCCAgegAwIBAgIMDWpfCD8oXD5Rld9dMAoGCCqGSM49BAMCMIGRMQswCQYD
+VQQGEwJVUzERMA8GA1UECBMISWxsaW5vaXMxEDAOBgNVBAcTB0NoaWNhZ28xITAf
+BgNVBAoTGFRydXN0d2F2ZSBIb2xkaW5ncywgSW5jLjE6MDgGA1UEAxMxVHJ1c3R3
+YXZlIEdsb2JhbCBFQ0MgUDI1NiBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0x
+NzA4MjMxOTM1MTBaFw00MjA4MjMxOTM1MTBaMIGRMQswCQYDVQQGEwJVUzERMA8G
+A1UECBMISWxsaW5vaXMxEDAOBgNVBAcTB0NoaWNhZ28xITAfBgNVBAoTGFRydXN0
+d2F2ZSBIb2xkaW5ncywgSW5jLjE6MDgGA1UEAxMxVHJ1c3R3YXZlIEdsb2JhbCBF
+Q0MgUDI1NiBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTBZMBMGByqGSM49AgEGCCqG
+SM49AwEHA0IABH77bOYj43MyCMpg5lOcunSNGLB4kFKA3TjASh3RqMyTpJcGOMoN
+FWLGjgEqZZ2q3zSRLoHB5DOSMcT9CTqmP62jQzBBMA8GA1UdEwEB/wQFMAMBAf8w
+DwYDVR0PAQH/BAUDAwcGADAdBgNVHQ4EFgQUo0EGrJBt0UrrdaVKEJmzsaGLSvcw
+CgYIKoZIzj0EAwIDRwAwRAIgB+ZU2g6gWrKuEZ+Hxbb/ad4lvvigtwjzRM4q3wgh
+DDcCIC0mA6AFvWvR9lz4ZcyGbbOcNEhjhAnFjXca4syc4XR7
+-----END CERTIFICATE-----
+
+# Issuer: CN=Trustwave Global ECC P384 Certification Authority O=Trustwave Holdings, Inc.
+# Subject: CN=Trustwave Global ECC P384 Certification Authority O=Trustwave Holdings, Inc.
+# Label: "Trustwave Global ECC P384 Certification Authority"
+# Serial: 2704997926503831671788816187
+# MD5 Fingerprint: ea:cf:60:c4:3b:b9:15:29:40:a1:97:ed:78:27:93:d6
+# SHA1 Fingerprint: e7:f3:a3:c8:cf:6f:c3:04:2e:6d:0e:67:32:c5:9e:68:95:0d:5e:d2
+# SHA256 Fingerprint: 55:90:38:59:c8:c0:c3:eb:b8:75:9e:ce:4e:25:57:22:5f:f5:75:8b:bd:38:eb:d4:82:76:60:1e:1b:d5:80:97
+-----BEGIN CERTIFICATE-----
+MIICnTCCAiSgAwIBAgIMCL2Fl2yZJ6SAaEc7MAoGCCqGSM49BAMDMIGRMQswCQYD
+VQQGEwJVUzERMA8GA1UECBMISWxsaW5vaXMxEDAOBgNVBAcTB0NoaWNhZ28xITAf
+BgNVBAoTGFRydXN0d2F2ZSBIb2xkaW5ncywgSW5jLjE6MDgGA1UEAxMxVHJ1c3R3
+YXZlIEdsb2JhbCBFQ0MgUDM4NCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0x
+NzA4MjMxOTM2NDNaFw00MjA4MjMxOTM2NDNaMIGRMQswCQYDVQQGEwJVUzERMA8G
+A1UECBMISWxsaW5vaXMxEDAOBgNVBAcTB0NoaWNhZ28xITAfBgNVBAoTGFRydXN0
+d2F2ZSBIb2xkaW5ncywgSW5jLjE6MDgGA1UEAxMxVHJ1c3R3YXZlIEdsb2JhbCBF
+Q0MgUDM4NCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTB2MBAGByqGSM49AgEGBSuB
+BAAiA2IABGvaDXU1CDFHBa5FmVXxERMuSvgQMSOjfoPTfygIOiYaOs+Xgh+AtycJ
+j9GOMMQKmw6sWASr9zZ9lCOkmwqKi6vr/TklZvFe/oyujUF5nQlgziip04pt89ZF
+1PKYhDhloKNDMEEwDwYDVR0TAQH/BAUwAwEB/zAPBgNVHQ8BAf8EBQMDBwYAMB0G
+A1UdDgQWBBRVqYSJ0sEyvRjLbKYHTsjnnb6CkDAKBggqhkjOPQQDAwNnADBkAjA3
+AZKXRRJ+oPM+rRk6ct30UJMDEr5E0k9BpIycnR+j9sKS50gU/k6bpZFXrsY3crsC
+MGclCrEMXu6pY5Jv5ZAL/mYiykf9ijH3g/56vxC+GCsej/YpHpRZ744hN8tRmKVu
+Sw==
+-----END CERTIFICATE-----
+
+# Issuer: CN=NAVER Global Root Certification Authority O=NAVER BUSINESS PLATFORM Corp.
+# Subject: CN=NAVER Global Root Certification Authority O=NAVER BUSINESS PLATFORM Corp.
+# Label: "NAVER Global Root Certification Authority"
+# Serial: 9013692873798656336226253319739695165984492813
+# MD5 Fingerprint: c8:7e:41:f6:25:3b:f5:09:b3:17:e8:46:3d:bf:d0:9b
+# SHA1 Fingerprint: 8f:6b:f2:a9:27:4a:da:14:a0:c4:f4:8e:61:27:f9:c0:1e:78:5d:d1
+# SHA256 Fingerprint: 88:f4:38:dc:f8:ff:d1:fa:8f:42:91:15:ff:e5:f8:2a:e1:e0:6e:0c:70:c3:75:fa:ad:71:7b:34:a4:9e:72:65
+-----BEGIN CERTIFICATE-----
+MIIFojCCA4qgAwIBAgIUAZQwHqIL3fXFMyqxQ0Rx+NZQTQ0wDQYJKoZIhvcNAQEM
+BQAwaTELMAkGA1UEBhMCS1IxJjAkBgNVBAoMHU5BVkVSIEJVU0lORVNTIFBMQVRG
+T1JNIENvcnAuMTIwMAYDVQQDDClOQVZFUiBHbG9iYWwgUm9vdCBDZXJ0aWZpY2F0
+aW9uIEF1dGhvcml0eTAeFw0xNzA4MTgwODU4NDJaFw0zNzA4MTgyMzU5NTlaMGkx
+CzAJBgNVBAYTAktSMSYwJAYDVQQKDB1OQVZFUiBCVVNJTkVTUyBQTEFURk9STSBD
+b3JwLjEyMDAGA1UEAwwpTkFWRVIgR2xvYmFsIFJvb3QgQ2VydGlmaWNhdGlvbiBB
+dXRob3JpdHkwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC21PGTXLVA
+iQqrDZBbUGOukJR0F0Vy1ntlWilLp1agS7gvQnXp2XskWjFlqxcX0TM62RHcQDaH
+38dq6SZeWYp34+hInDEW+j6RscrJo+KfziFTowI2MMtSAuXaMl3Dxeb57hHHi8lE
+HoSTGEq0n+USZGnQJoViAbbJAh2+g1G7XNr4rRVqmfeSVPc0W+m/6imBEtRTkZaz
+kVrd/pBzKPswRrXKCAfHcXLJZtM0l/aM9BhK4dA9WkW2aacp+yPOiNgSnABIqKYP
+szuSjXEOdMWLyEz59JuOuDxp7W87UC9Y7cSw0BwbagzivESq2M0UXZR4Yb8Obtoq
+vC8MC3GmsxY/nOb5zJ9TNeIDoKAYv7vxvvTWjIcNQvcGufFt7QSUqP620wbGQGHf
+nZ3zVHbOUzoBppJB7ASjjw2i1QnK1sua8e9DXcCrpUHPXFNwcMmIpi3Ua2FzUCaG
+YQ5fG8Ir4ozVu53BA0K6lNpfqbDKzE0K70dpAy8i+/Eozr9dUGWokG2zdLAIx6yo
+0es+nPxdGoMuK8u180SdOqcXYZaicdNwlhVNt0xz7hlcxVs+Qf6sdWA7G2POAN3a
+CJBitOUt7kinaxeZVL6HSuOpXgRM6xBtVNbv8ejyYhbLgGvtPe31HzClrkvJE+2K
+AQHJuFFYwGY6sWZLxNUxAmLpdIQM201GLQIDAQABo0IwQDAdBgNVHQ4EFgQU0p+I
+36HNLL3s9TsBAZMzJ7LrYEswDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMB
+Af8wDQYJKoZIhvcNAQEMBQADggIBADLKgLOdPVQG3dLSLvCkASELZ0jKbY7gyKoN
+qo0hV4/GPnrK21HUUrPUloSlWGB/5QuOH/XcChWB5Tu2tyIvCZwTFrFsDDUIbatj
+cu3cvuzHV+YwIHHW1xDBE1UBjCpD5EHxzzp6U5LOogMFDTjfArsQLtk70pt6wKGm
++LUx5vR1yblTmXVHIloUFcd4G7ad6Qz4G3bxhYTeodoS76TiEJd6eN4MUZeoIUCL
+hr0N8F5OSza7OyAfikJW4Qsav3vQIkMsRIz75Sq0bBwcupTgE34h5prCy8VCZLQe
+lHsIJchxzIdFV4XTnyliIoNRlwAYl3dqmJLJfGBs32x9SuRwTMKeuB330DTHD8z7
+p/8Dvq1wkNoL3chtl1+afwkyQf3NosxabUzyqkn+Zvjp2DXrDige7kgvOtB5CTh8
+piKCk5XQA76+AqAF3SAi428diDRgxuYKuQl1C/AH6GmWNcf7I4GOODm4RStDeKLR
+LBT/DShycpWbXgnbiUSYqqFJu3FS8r/2/yehNq+4tneI3TqkbZs0kNwUXTC/t+sX
+5Ie3cdCh13cV1ELX8vMxmV2b3RZtP+oGI/hGoiLtk/bdmuYqh7GYVPEi92tF4+KO
+dh2ajcQGjTa3FPOdVGm3jjzVpG2Tgbet9r1ke8LJaDmgkpzNNIaRkPpkUZ3+/uul
+9XXeifdy
+-----END CERTIFICATE-----
diff --git a/examples/BUILD b/examples/BUILD
deleted file mode 100644 (file)
index 1644840..0000000
+++ /dev/null
@@ -1,252 +0,0 @@
-# Copyright 2017 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.
-
-licenses(["notice"])  # 3-clause BSD
-
-package(default_visibility = ["//visibility:public"])
-
-load("@grpc_python_dependencies//:requirements.bzl", "requirement")
-load("@rules_proto//proto:defs.bzl", "proto_library")
-load("//bazel:cc_grpc_library.bzl", "cc_grpc_library")
-load("//bazel:grpc_build_system.bzl", "grpc_proto_library")
-load("//bazel:python_rules.bzl", "py_grpc_library", "py_proto_library")
-
-grpc_proto_library(
-    name = "auth_sample",
-    srcs = ["protos/auth_sample.proto"],
-)
-
-grpc_proto_library(
-    name = "hellostreamingworld",
-    srcs = ["protos/hellostreamingworld.proto"],
-)
-
-# The following three rules demonstrate the usage of the cc_grpc_library rule in
-# in a mode compatible with the native proto_library and cc_proto_library rules.
-proto_library(
-    name = "helloworld_proto",
-    srcs = ["protos/helloworld.proto"],
-)
-
-cc_proto_library(
-    name = "helloworld_cc_proto",
-    deps = [":helloworld_proto"],
-)
-
-cc_grpc_library(
-    name = "helloworld_cc_grpc",
-    srcs = [":helloworld_proto"],
-    grpc_only = True,
-    deps = [":helloworld_cc_proto"],
-)
-
-grpc_proto_library(
-    name = "route_guide",
-    srcs = ["protos/route_guide.proto"],
-)
-
-proto_library(
-    name = "keyvaluestore_proto",
-    srcs = ["protos/keyvaluestore.proto"],
-)
-
-grpc_proto_library(
-    name = "keyvaluestore",
-    srcs = ["protos/keyvaluestore.proto"],
-)
-
-proto_library(
-    name = "protos/helloworld_proto",
-    srcs = ["protos/helloworld.proto"],
-)
-
-py_proto_library(
-    name = "helloworld_py_pb2",
-    deps = [":protos/helloworld_proto"],
-)
-
-py_grpc_library(
-    name = "helloworld_py_pb2_grpc",
-    srcs = [":protos/helloworld_proto"],
-    deps = [":helloworld_py_pb2"],
-)
-
-cc_binary(
-    name = "greeter_client",
-    srcs = ["cpp/helloworld/greeter_client.cc"],
-    defines = ["BAZEL_BUILD"],
-    deps = [
-        ":helloworld_cc_grpc",
-        "//:grpc++",
-    ],
-)
-
-cc_binary(
-    name = "greeter_async_client",
-    srcs = ["cpp/helloworld/greeter_async_client.cc"],
-    defines = ["BAZEL_BUILD"],
-    deps = [
-        ":helloworld_cc_grpc",
-        "//:grpc++",
-    ],
-)
-
-cc_binary(
-    name = "greeter_async_client2",
-    srcs = ["cpp/helloworld/greeter_async_client2.cc"],
-    defines = ["BAZEL_BUILD"],
-    deps = [
-        ":helloworld_cc_grpc",
-        "//:grpc++",
-    ],
-)
-
-cc_binary(
-    name = "greeter_server",
-    srcs = ["cpp/helloworld/greeter_server.cc"],
-    defines = ["BAZEL_BUILD"],
-    deps = [
-        ":helloworld_cc_grpc",
-        "//:grpc++",
-        "//:grpc++_reflection",
-    ],
-)
-
-cc_binary(
-    name = "greeter_async_server",
-    srcs = ["cpp/helloworld/greeter_async_server.cc"],
-    defines = ["BAZEL_BUILD"],
-    deps = [
-        ":helloworld_cc_grpc",
-        "//:grpc++",
-    ],
-)
-
-cc_binary(
-    name = "metadata_client",
-    srcs = ["cpp/metadata/greeter_client.cc"],
-    defines = ["BAZEL_BUILD"],
-    deps = [
-        ":helloworld_cc_grpc",
-        "//:grpc++",
-    ],
-)
-
-cc_binary(
-    name = "metadata_server",
-    srcs = ["cpp/metadata/greeter_server.cc"],
-    defines = ["BAZEL_BUILD"],
-    deps = [
-        ":helloworld_cc_grpc",
-        "//:grpc++",
-    ],
-)
-
-cc_binary(
-    name = "lb_client",
-    srcs = ["cpp/load_balancing/greeter_client.cc"],
-    defines = ["BAZEL_BUILD"],
-    deps = [
-        ":helloworld_cc_grpc",
-        "//:grpc++",
-    ],
-)
-
-cc_binary(
-    name = "lb_server",
-    srcs = ["cpp/load_balancing/greeter_server.cc"],
-    defines = ["BAZEL_BUILD"],
-    deps = [
-        ":helloworld_cc_grpc",
-        "//:grpc++",
-    ],
-)
-
-cc_binary(
-    name = "compression_client",
-    srcs = ["cpp/compression/greeter_client.cc"],
-    defines = ["BAZEL_BUILD"],
-    deps = [
-        ":helloworld_cc_grpc",
-        "//:grpc++",
-    ],
-)
-
-cc_binary(
-    name = "compression_server",
-    srcs = ["cpp/compression/greeter_server.cc"],
-    defines = ["BAZEL_BUILD"],
-    deps = [
-        ":helloworld_cc_grpc",
-        "//:grpc++",
-    ],
-)
-
-cc_binary(
-    name = "keyvaluestore_client",
-    srcs = [
-        "cpp/keyvaluestore/caching_interceptor.h",
-        "cpp/keyvaluestore/client.cc",
-    ],
-    defines = ["BAZEL_BUILD"],
-    deps = [
-        ":keyvaluestore",
-        "//:grpc++",
-    ],
-)
-
-cc_binary(
-    name = "keyvaluestore_server",
-    srcs = ["cpp/keyvaluestore/server.cc"],
-    defines = ["BAZEL_BUILD"],
-    deps = [
-        ":keyvaluestore",
-        "//:grpc++",
-    ],
-)
-
-cc_binary(
-    name = "route_guide_client",
-    srcs = [
-        "cpp/route_guide/helper.cc",
-        "cpp/route_guide/helper.h",
-        "cpp/route_guide/route_guide_client.cc",
-    ],
-    data = ["cpp/route_guide/route_guide_db.json"],
-    defines = ["BAZEL_BUILD"],
-    deps = [
-        ":route_guide",
-        "//:grpc++",
-    ],
-)
-
-cc_binary(
-    name = "route_guide_server",
-    srcs = [
-        "cpp/route_guide/helper.cc",
-        "cpp/route_guide/helper.h",
-        "cpp/route_guide/route_guide_server.cc",
-    ],
-    data = ["cpp/route_guide/route_guide_db.json"],
-    defines = ["BAZEL_BUILD"],
-    deps = [
-        ":route_guide",
-        "//:grpc++",
-    ],
-)
-
-proto_library(
-    name = "route_guide_proto",
-    srcs = ["protos/route_guide.proto"],
-)
index 9b7fbab..49751c5 100644 (file)
@@ -3,6 +3,7 @@
 This directory contains examples for all the C-based gRPC implementations. Each
 language subdirectory contains a Hello World example and more:
 
+* [Android](android)
 * [C#](csharp)
 * [C++](cpp)
 * [Node.js](node)
@@ -11,8 +12,7 @@ language subdirectory contains a Hello World example and more:
 * [Python](python/helloworld)
 * [Ruby](ruby)
 
-For a complete list of supported languages, see [Supported languages and
-platforms][lang].
+For a complete list of supported languages, see [Supported languages][lang].
 
 For comprehensive documentation, including an [Introduction to gRPC][intro] and
 tutorials that use this example code, visit [grpc.io](https://grpc.io).
diff --git a/examples/cpp/compression/BUILD b/examples/cpp/compression/BUILD
new file mode 100644 (file)
index 0000000..8df2ecb
--- /dev/null
@@ -0,0 +1,35 @@
+# Copyright 2020 the 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.
+
+licenses(["notice"])  # 3-clause BSD
+
+cc_binary(
+    name = "compression_client",
+    srcs = ["greeter_client.cc"],
+    defines = ["BAZEL_BUILD"],
+    deps = [
+        "//:grpc++",
+        "//examples/protos:helloworld_cc_grpc",
+    ],
+)
+
+cc_binary(
+    name = "compression_server",
+    srcs = ["greeter_server.cc"],
+    defines = ["BAZEL_BUILD"],
+    deps = [
+        "//:grpc++",
+        "//examples/protos:helloworld_cc_grpc",
+    ],
+)
diff --git a/examples/cpp/helloworld/BUILD b/examples/cpp/helloworld/BUILD
new file mode 100644 (file)
index 0000000..ac13e52
--- /dev/null
@@ -0,0 +1,66 @@
+# Copyright 2020 the 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.
+
+licenses(["notice"])  # 3-clause BSD
+
+cc_binary(
+    name = "greeter_client",
+    srcs = ["greeter_client.cc"],
+    defines = ["BAZEL_BUILD"],
+    deps = [
+        "//:grpc++",
+        "//examples/protos:helloworld_cc_grpc",
+    ],
+)
+
+cc_binary(
+    name = "greeter_async_client",
+    srcs = ["greeter_async_client.cc"],
+    defines = ["BAZEL_BUILD"],
+    deps = [
+        "//:grpc++",
+        "//examples/protos:helloworld_cc_grpc",
+    ],
+)
+
+cc_binary(
+    name = "greeter_async_client2",
+    srcs = ["greeter_async_client2.cc"],
+    defines = ["BAZEL_BUILD"],
+    deps = [
+        "//:grpc++",
+        "//examples/protos:helloworld_cc_grpc",
+    ],
+)
+
+cc_binary(
+    name = "greeter_server",
+    srcs = ["greeter_server.cc"],
+    defines = ["BAZEL_BUILD"],
+    deps = [
+        "//:grpc++",
+        "//:grpc++_reflection",
+        "//examples/protos:helloworld_cc_grpc",
+    ],
+)
+
+cc_binary(
+    name = "greeter_async_server",
+    srcs = ["greeter_async_server.cc"],
+    defines = ["BAZEL_BUILD"],
+    deps = [
+        "//:grpc++",
+        "//examples/protos:helloworld_cc_grpc",
+    ],
+)
diff --git a/examples/cpp/keyvaluestore/BUILD b/examples/cpp/keyvaluestore/BUILD
new file mode 100644 (file)
index 0000000..ac1fec2
--- /dev/null
@@ -0,0 +1,38 @@
+# Copyright 2020 the 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.
+
+licenses(["notice"])  # 3-clause BSD
+
+cc_binary(
+    name = "keyvaluestore_client",
+    srcs = [
+        "caching_interceptor.h",
+        "client.cc",
+    ],
+    defines = ["BAZEL_BUILD"],
+    deps = [
+        "//:grpc++",
+        "//examples/protos:keyvaluestore",
+    ],
+)
+
+cc_binary(
+    name = "keyvaluestore_server",
+    srcs = ["server.cc"],
+    defines = ["BAZEL_BUILD"],
+    deps = [
+        "//:grpc++",
+        "//examples/protos:keyvaluestore",
+    ],
+)
diff --git a/examples/cpp/load_balancing/BUILD b/examples/cpp/load_balancing/BUILD
new file mode 100644 (file)
index 0000000..52c07fd
--- /dev/null
@@ -0,0 +1,35 @@
+# Copyright 2020 the 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.
+
+licenses(["notice"])  # 3-clause BSD
+
+cc_binary(
+    name = "lb_server",
+    srcs = ["greeter_server.cc"],
+    defines = ["BAZEL_BUILD"],
+    deps = [
+        "//:grpc++",
+        "//examples/protos:helloworld_cc_grpc",
+    ],
+)
+
+cc_binary(
+    name = "lb_client",
+    srcs = ["greeter_client.cc"],
+    defines = ["BAZEL_BUILD"],
+    deps = [
+        "//:grpc++",
+        "//examples/protos:helloworld_cc_grpc",
+    ],
+)
diff --git a/examples/cpp/metadata/BUILD b/examples/cpp/metadata/BUILD
new file mode 100644 (file)
index 0000000..90cb90c
--- /dev/null
@@ -0,0 +1,35 @@
+# Copyright 2020 the 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.
+
+licenses(["notice"])  # 3-clause BSD
+
+cc_binary(
+    name = "metadata_client",
+    srcs = ["greeter_client.cc"],
+    defines = ["BAZEL_BUILD"],
+    deps = [
+        "//:grpc++",
+        "//examples/protos:helloworld_cc_grpc",
+    ],
+)
+
+cc_binary(
+    name = "metadata_server",
+    srcs = ["greeter_server.cc"],
+    defines = ["BAZEL_BUILD"],
+    deps = [
+        "//:grpc++",
+        "//examples/protos:helloworld_cc_grpc",
+    ],
+)
diff --git a/examples/cpp/route_guide/BUILD b/examples/cpp/route_guide/BUILD
new file mode 100644 (file)
index 0000000..8aac557
--- /dev/null
@@ -0,0 +1,56 @@
+# Copyright 2020 the 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.
+
+licenses(["notice"])  # 3-clause BSD
+
+cc_library(
+    name = "route_guide_helper",
+    srcs = [
+        "helper.cc",
+        "helper.h",
+    ],
+    defines = ["BAZEL_BUILD"],
+    deps = [
+        "//:grpc++",
+        "//examples/protos:route_guide",
+    ],
+)
+
+cc_binary(
+    name = "route_guide_client",
+    srcs = [
+        "route_guide_client.cc",
+    ],
+    data = ["route_guide_db.json"],
+    defines = ["BAZEL_BUILD"],
+    deps = [
+        ":route_guide_helper",
+        "//:grpc++",
+        "//examples/protos:route_guide",
+    ],
+)
+
+cc_binary(
+    name = "route_guide_server",
+    srcs = [
+        "route_guide_server.cc",
+    ],
+    data = ["route_guide_db.json"],
+    defines = ["BAZEL_BUILD"],
+    deps = [
+        ":route_guide_helper",
+        "//:grpc++",
+        "//examples/protos:route_guide",
+    ],
+)
index 988a317..965da49 100644 (file)
@@ -22,17 +22,17 @@ load("@build_bazel_rules_apple//apple:macos.bzl", "macos_application")
 
 objc_grpc_library(
     name = "HelloWorld_grpc_proto",
-    srcs = ["//examples:protos/helloworld.proto"],
+    srcs = ["//examples/protos:helloworld.proto"],
     tags = ["manual"],
-    deps = ["//examples:helloworld_proto"],
+    deps = ["//examples/protos:helloworld_proto"],
 )
 
 # This one works with import "external/com_github_grpc_grpc/examples/protos/Keyvaluestore.pbrpc.h"
 objc_grpc_library(
     name = "Keyvaluestore_grpc_proto_external",
-    srcs = ["//external/com_github_grpc_grpc/examples:protos/keyvaluestore.proto"],
+    srcs = ["//external/com_github_grpc_grpc/examples/protos:keyvaluestore.proto"],
     tags = ["manual"],
-    deps = ["@com_github_grpc_grpc//examples:keyvaluestore_proto"],
+    deps = ["@com_github_grpc_grpc//examples/protos:keyvaluestore_proto"],
 )
 
 objc_library(
@@ -86,9 +86,9 @@ macos_application(
 
 objc_grpc_library(
     name = "RouteGuide",
-    srcs = ["//examples:protos/route_guide.proto"],
+    srcs = ["//examples/protos:route_guide.proto"],
     tags = ["manual"],
-    deps = ["//examples:route_guide_proto"],
+    deps = ["//examples/protos:route_guide_proto"],
 )
 
 objc_library(
index 2fa390d..9142de9 100644 (file)
@@ -84,7 +84,7 @@ $ bazel build :HelloWorld
 #### Try it!
 To run the Hello World sample properly, we need a local server. Let's compile and run the corresponding C++ server:
 ```shell
-$ bazel run //examples:greeter_server
+$ bazel run //examples/cpp/helloworld:greeter_server
 ```
 
 To run the sample, you need to know the available simulator runtimes in your machine. You could either list the available runtimes yourself by running:
diff --git a/examples/protos/BUILD b/examples/protos/BUILD
new file mode 100644 (file)
index 0000000..5418b88
--- /dev/null
@@ -0,0 +1,83 @@
+# Copyright 2020 the 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.
+
+licenses(["notice"])  # 3-clause BSD
+
+package(default_visibility = ["//visibility:public"])
+
+load("@grpc_python_dependencies//:requirements.bzl", "requirement")
+load("@rules_proto//proto:defs.bzl", "proto_library")
+load("//bazel:cc_grpc_library.bzl", "cc_grpc_library")
+load("//bazel:grpc_build_system.bzl", "grpc_proto_library")
+load("//bazel:python_rules.bzl", "py_grpc_library", "py_proto_library")
+
+grpc_proto_library(
+    name = "auth_sample",
+    srcs = ["auth_sample.proto"],
+)
+
+grpc_proto_library(
+    name = "hellostreamingworld",
+    srcs = ["hellostreamingworld.proto"],
+)
+
+# The following three rules demonstrate the usage of the cc_grpc_library rule in
+# in a mode compatible with the native proto_library and cc_proto_library rules.
+proto_library(
+    name = "helloworld_proto",
+    srcs = ["helloworld.proto"],
+)
+
+cc_proto_library(
+    name = "helloworld_cc_proto",
+    deps = [":helloworld_proto"],
+)
+
+cc_grpc_library(
+    name = "helloworld_cc_grpc",
+    srcs = [":helloworld_proto"],
+    grpc_only = True,
+    deps = [":helloworld_cc_proto"],
+)
+
+grpc_proto_library(
+    name = "route_guide",
+    srcs = ["route_guide.proto"],
+)
+
+proto_library(
+    name = "keyvaluestore_proto",
+    srcs = ["keyvaluestore.proto"],
+)
+
+grpc_proto_library(
+    name = "keyvaluestore",
+    srcs = ["keyvaluestore.proto"],
+)
+
+py_proto_library(
+    name = "helloworld_py_pb2",
+    deps = [":helloworld_proto"],
+)
+
+py_grpc_library(
+    name = "helloworld_py_pb2_grpc",
+    srcs = [":helloworld_proto"],
+    deps = [":helloworld_py_pb2"],
+)
+
+proto_library(
+    name = "route_guide_proto",
+    srcs = [":route_guide.proto"],
+)
diff --git a/examples/python/async_streaming/README.md b/examples/python/async_streaming/README.md
new file mode 100644 (file)
index 0000000..4dac53b
--- /dev/null
@@ -0,0 +1,50 @@
+# gRPC Python Non-Blocking Streaming RPC Client Example
+
+The goal of this example is to demonstrate how to handle streaming responses
+without blocking the current thread. Effectively, this can be achieved by
+converting the gRPC Python streaming API into callback-based.
+
+In this example, the RPC service `Phone` simulates the life cycle of virtual
+phone calls. It requires one thread to handle the phone-call session state
+changes, and another thread to process the audio stream. In this case, the
+normal blocking style API could not fulfill the need easily. Hence, we should
+asynchronously execute the streaming RPC.
+
+## Steps to run this example
+
+Start the server in one session
+```
+python3 server.py
+```
+
+Start the client in another session
+```
+python3 client.py
+```
+
+## Example Output
+```
+$ python3 server.py
+INFO:root:Server serving at [::]:50051
+INFO:root:Received a phone call request for number [1415926535]
+INFO:root:Created a call session [{
+  "sessionId": "0",
+  "media": "https://link.to.audio.resources"
+}]
+INFO:root:Call finished [1415926535]
+INFO:root:Call session cleaned [{
+  "sessionId": "0",
+  "media": "https://link.to.audio.resources"
+}]
+```
+
+```
+$ python3 client.py
+INFO:root:Waiting for peer to connect [1415926535]...
+INFO:root:Call toward [1415926535] enters [NEW] state
+INFO:root:Call toward [1415926535] enters [ACTIVE] state
+INFO:root:Consuming audio resource [https://link.to.audio.resources]
+INFO:root:Call toward [1415926535] enters [ENDED] state
+INFO:root:Audio session finished [https://link.to.audio.resources]
+INFO:root:Call finished!
+```
diff --git a/examples/python/async_streaming/client.py b/examples/python/async_streaming/client.py
new file mode 100644 (file)
index 0000000..25db693
--- /dev/null
@@ -0,0 +1,119 @@
+# Copyright 2020 The 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.
+
+import logging
+import threading
+from typing import Iterator
+from concurrent.futures import ThreadPoolExecutor
+
+import grpc
+
+import phone_pb2
+import phone_pb2_grpc
+
+
+class CallMaker:
+
+    def __init__(self, executor: ThreadPoolExecutor, channel: grpc.Channel,
+                 phone_number: str) -> None:
+        self._executor = executor
+        self._channel = channel
+        self._stub = phone_pb2_grpc.PhoneStub(self._channel)
+        self._phone_number = phone_number
+        self._session_id = None
+        self._audio_session_link = None
+        self._call_state = None
+        self._peer_responded = threading.Event()
+        self._call_finished = threading.Event()
+        self._consumer_future = None
+
+    def _response_watcher(
+            self,
+            response_iterator: Iterator[phone_pb2.StreamCallResponse]) -> None:
+        try:
+            for response in response_iterator:
+                # NOTE: All fields in Proto3 are optional. This is the recommended way
+                # to check if a field is present or not, or to exam which one-of field is
+                # fulfilled by this message.
+                if response.HasField("call_info"):
+                    self._on_call_info(response.call_info)
+                elif response.HasField("call_state"):
+                    self._on_call_state(response.call_state.state)
+                else:
+                    raise RuntimeError(
+                        "Received StreamCallResponse without call_info and call_state"
+                    )
+        except Exception as e:
+            self._peer_responded.set()
+            raise
+
+    def _on_call_info(self, call_info: phone_pb2.CallInfo) -> None:
+        self._session_id = call_info.session_id
+        self._audio_session_link = call_info.media
+
+    def _on_call_state(self, call_state: phone_pb2.CallState.State) -> None:
+        logging.info("Call toward [%s] enters [%s] state", self._phone_number,
+                     phone_pb2.CallState.State.Name(call_state))
+        self._call_state = call_state
+        if call_state is phone_pb2.CallState.State.ACTIVE:
+            self._peer_responded.set()
+        if call_state is phone_pb2.CallState.State.ENDED:
+            self._peer_responded.set()
+            self._call_finished.set()
+
+    def call(self) -> None:
+        request = phone_pb2.StreamCallRequest()
+        request.phone_number = self._phone_number
+        response_iterator = self._stub.StreamCall(iter((request,)))
+        # Instead of consuming the response on current thread, spawn a consumption thread.
+        self._consumer_future = self._executor.submit(self._response_watcher,
+                                                      response_iterator)
+
+    def wait_peer(self) -> None:
+        logging.info("Waiting for peer to connect [%s]...", self._phone_number)
+        self._peer_responded.wait(timeout=None)
+        if self._consumer_future.done():
+            # If the future raises, forwards the exception here
+            self._consumer_future.result()
+        return self._call_state is phone_pb2.CallState.State.ACTIVE
+
+    def audio_session(self) -> None:
+        assert self._audio_session_link is not None
+        logging.info("Consuming audio resource [%s]", self._audio_session_link)
+        self._call_finished.wait(timeout=None)
+        logging.info("Audio session finished [%s]", self._audio_session_link)
+
+
+def process_call(executor: ThreadPoolExecutor, channel: grpc.Channel,
+                 phone_number: str) -> None:
+    call_maker = CallMaker(executor, channel, phone_number)
+    call_maker.call()
+    if call_maker.wait_peer():
+        call_maker.audio_session()
+        logging.info("Call finished!")
+    else:
+        logging.info("Call failed: peer didn't answer")
+
+
+def run():
+    executor = ThreadPoolExecutor()
+    with grpc.insecure_channel("localhost:50051") as channel:
+        future = executor.submit(process_call, executor, channel,
+                                 "555-0100-XXXX")
+        future.result()
+
+
+if __name__ == '__main__':
+    logging.basicConfig(level=logging.INFO)
+    run()
diff --git a/examples/python/async_streaming/phone.proto b/examples/python/async_streaming/phone.proto
new file mode 100644 (file)
index 0000000..64c5999
--- /dev/null
@@ -0,0 +1,52 @@
+// Copyright 2020 The 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.
+
+syntax = "proto3";
+
+package grpc.testing;
+
+message CallInfo {
+  string session_id = 1;
+  string media = 2;
+}
+
+message CallState {
+  enum State {
+    // The default state.
+    UNDEFINED = 0;
+    // The call is newly created.
+    NEW = 1;
+    // The call is connected.
+    ACTIVE = 6;
+    // The call is finished.
+    ENDED = 7;
+  }
+  State state = 2;
+}
+
+message StreamCallRequest {
+  string phone_number = 1;
+}
+
+message StreamCallResponse {
+  oneof stream_call_response {
+    CallInfo call_info = 1;
+    CallState call_state = 2;
+  } 
+}
+
+service Phone {
+  // Makes a phone call and communicate states via a stream.
+  rpc StreamCall(stream StreamCallRequest) returns (stream StreamCallResponse);
+}
diff --git a/examples/python/async_streaming/phone_pb2.py b/examples/python/async_streaming/phone_pb2.py
new file mode 100644 (file)
index 0000000..9afdfec
--- /dev/null
@@ -0,0 +1,267 @@
+# -*- coding: utf-8 -*-
+# Generated by the protocol buffer compiler.  DO NOT EDIT!
+# source: phone.proto
+
+from google.protobuf import descriptor as _descriptor
+from google.protobuf import message as _message
+from google.protobuf import reflection as _reflection
+from google.protobuf import symbol_database as _symbol_database
+# @@protoc_insertion_point(imports)
+
+_sym_db = _symbol_database.Default()
+
+
+
+
+DESCRIPTOR = _descriptor.FileDescriptor(
+  name='phone.proto',
+  package='grpc.testing',
+  syntax='proto3',
+  serialized_options=None,
+  serialized_pb=b'\n\x0bphone.proto\x12\x0cgrpc.testing\"-\n\x08\x43\x61llInfo\x12\x12\n\nsession_id\x18\x01 \x01(\t\x12\r\n\x05media\x18\x02 \x01(\t\"q\n\tCallState\x12,\n\x05state\x18\x02 \x01(\x0e\x32\x1d.grpc.testing.CallState.State\"6\n\x05State\x12\r\n\tUNDEFINED\x10\x00\x12\x07\n\x03NEW\x10\x01\x12\n\n\x06\x41\x43TIVE\x10\x06\x12\t\n\x05\x45NDED\x10\x07\")\n\x11StreamCallRequest\x12\x14\n\x0cphone_number\x18\x01 \x01(\t\"\x88\x01\n\x12StreamCallResponse\x12+\n\tcall_info\x18\x01 \x01(\x0b\x32\x16.grpc.testing.CallInfoH\x00\x12-\n\ncall_state\x18\x02 \x01(\x0b\x32\x17.grpc.testing.CallStateH\x00\x42\x16\n\x14stream_call_response2\\\n\x05Phone\x12S\n\nStreamCall\x12\x1f.grpc.testing.StreamCallRequest\x1a .grpc.testing.StreamCallResponse(\x01\x30\x01\x62\x06proto3'
+)
+
+
+
+_CALLSTATE_STATE = _descriptor.EnumDescriptor(
+  name='State',
+  full_name='grpc.testing.CallState.State',
+  filename=None,
+  file=DESCRIPTOR,
+  values=[
+    _descriptor.EnumValueDescriptor(
+      name='UNDEFINED', index=0, number=0,
+      serialized_options=None,
+      type=None),
+    _descriptor.EnumValueDescriptor(
+      name='NEW', index=1, number=1,
+      serialized_options=None,
+      type=None),
+    _descriptor.EnumValueDescriptor(
+      name='ACTIVE', index=2, number=6,
+      serialized_options=None,
+      type=None),
+    _descriptor.EnumValueDescriptor(
+      name='ENDED', index=3, number=7,
+      serialized_options=None,
+      type=None),
+  ],
+  containing_type=None,
+  serialized_options=None,
+  serialized_start=135,
+  serialized_end=189,
+)
+_sym_db.RegisterEnumDescriptor(_CALLSTATE_STATE)
+
+
+_CALLINFO = _descriptor.Descriptor(
+  name='CallInfo',
+  full_name='grpc.testing.CallInfo',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='session_id', full_name='grpc.testing.CallInfo.session_id', index=0,
+      number=1, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='media', full_name='grpc.testing.CallInfo.media', index=1,
+      number=2, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=29,
+  serialized_end=74,
+)
+
+
+_CALLSTATE = _descriptor.Descriptor(
+  name='CallState',
+  full_name='grpc.testing.CallState',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='state', full_name='grpc.testing.CallState.state', index=0,
+      number=2, type=14, cpp_type=8, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+    _CALLSTATE_STATE,
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=76,
+  serialized_end=189,
+)
+
+
+_STREAMCALLREQUEST = _descriptor.Descriptor(
+  name='StreamCallRequest',
+  full_name='grpc.testing.StreamCallRequest',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='phone_number', full_name='grpc.testing.StreamCallRequest.phone_number', index=0,
+      number=1, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=191,
+  serialized_end=232,
+)
+
+
+_STREAMCALLRESPONSE = _descriptor.Descriptor(
+  name='StreamCallResponse',
+  full_name='grpc.testing.StreamCallResponse',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='call_info', full_name='grpc.testing.StreamCallResponse.call_info', index=0,
+      number=1, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='call_state', full_name='grpc.testing.StreamCallResponse.call_state', index=1,
+      number=2, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+    _descriptor.OneofDescriptor(
+      name='stream_call_response', full_name='grpc.testing.StreamCallResponse.stream_call_response',
+      index=0, containing_type=None, fields=[]),
+  ],
+  serialized_start=235,
+  serialized_end=371,
+)
+
+_CALLSTATE.fields_by_name['state'].enum_type = _CALLSTATE_STATE
+_CALLSTATE_STATE.containing_type = _CALLSTATE
+_STREAMCALLRESPONSE.fields_by_name['call_info'].message_type = _CALLINFO
+_STREAMCALLRESPONSE.fields_by_name['call_state'].message_type = _CALLSTATE
+_STREAMCALLRESPONSE.oneofs_by_name['stream_call_response'].fields.append(
+  _STREAMCALLRESPONSE.fields_by_name['call_info'])
+_STREAMCALLRESPONSE.fields_by_name['call_info'].containing_oneof = _STREAMCALLRESPONSE.oneofs_by_name['stream_call_response']
+_STREAMCALLRESPONSE.oneofs_by_name['stream_call_response'].fields.append(
+  _STREAMCALLRESPONSE.fields_by_name['call_state'])
+_STREAMCALLRESPONSE.fields_by_name['call_state'].containing_oneof = _STREAMCALLRESPONSE.oneofs_by_name['stream_call_response']
+DESCRIPTOR.message_types_by_name['CallInfo'] = _CALLINFO
+DESCRIPTOR.message_types_by_name['CallState'] = _CALLSTATE
+DESCRIPTOR.message_types_by_name['StreamCallRequest'] = _STREAMCALLREQUEST
+DESCRIPTOR.message_types_by_name['StreamCallResponse'] = _STREAMCALLRESPONSE
+_sym_db.RegisterFileDescriptor(DESCRIPTOR)
+
+CallInfo = _reflection.GeneratedProtocolMessageType('CallInfo', (_message.Message,), {
+  'DESCRIPTOR' : _CALLINFO,
+  '__module__' : 'phone_pb2'
+  # @@protoc_insertion_point(class_scope:grpc.testing.CallInfo)
+  })
+_sym_db.RegisterMessage(CallInfo)
+
+CallState = _reflection.GeneratedProtocolMessageType('CallState', (_message.Message,), {
+  'DESCRIPTOR' : _CALLSTATE,
+  '__module__' : 'phone_pb2'
+  # @@protoc_insertion_point(class_scope:grpc.testing.CallState)
+  })
+_sym_db.RegisterMessage(CallState)
+
+StreamCallRequest = _reflection.GeneratedProtocolMessageType('StreamCallRequest', (_message.Message,), {
+  'DESCRIPTOR' : _STREAMCALLREQUEST,
+  '__module__' : 'phone_pb2'
+  # @@protoc_insertion_point(class_scope:grpc.testing.StreamCallRequest)
+  })
+_sym_db.RegisterMessage(StreamCallRequest)
+
+StreamCallResponse = _reflection.GeneratedProtocolMessageType('StreamCallResponse', (_message.Message,), {
+  'DESCRIPTOR' : _STREAMCALLRESPONSE,
+  '__module__' : 'phone_pb2'
+  # @@protoc_insertion_point(class_scope:grpc.testing.StreamCallResponse)
+  })
+_sym_db.RegisterMessage(StreamCallResponse)
+
+
+
+_PHONE = _descriptor.ServiceDescriptor(
+  name='Phone',
+  full_name='grpc.testing.Phone',
+  file=DESCRIPTOR,
+  index=0,
+  serialized_options=None,
+  serialized_start=373,
+  serialized_end=465,
+  methods=[
+  _descriptor.MethodDescriptor(
+    name='StreamCall',
+    full_name='grpc.testing.Phone.StreamCall',
+    index=0,
+    containing_service=None,
+    input_type=_STREAMCALLREQUEST,
+    output_type=_STREAMCALLRESPONSE,
+    serialized_options=None,
+  ),
+])
+_sym_db.RegisterServiceDescriptor(_PHONE)
+
+DESCRIPTOR.services_by_name['Phone'] = _PHONE
+
+# @@protoc_insertion_point(module_scope)
diff --git a/examples/python/async_streaming/phone_pb2_grpc.py b/examples/python/async_streaming/phone_pb2_grpc.py
new file mode 100644 (file)
index 0000000..39bc58d
--- /dev/null
@@ -0,0 +1,65 @@
+# Generated by the gRPC Python protocol compiler plugin. DO NOT EDIT!
+import grpc
+
+import phone_pb2 as phone__pb2
+
+
+class PhoneStub(object):
+    """Missing associated documentation comment in .proto file"""
+
+    def __init__(self, channel):
+        """Constructor.
+
+        Args:
+            channel: A grpc.Channel.
+        """
+        self.StreamCall = channel.stream_stream(
+                '/grpc.testing.Phone/StreamCall',
+                request_serializer=phone__pb2.StreamCallRequest.SerializeToString,
+                response_deserializer=phone__pb2.StreamCallResponse.FromString,
+                )
+
+
+class PhoneServicer(object):
+    """Missing associated documentation comment in .proto file"""
+
+    def StreamCall(self, request_iterator, context):
+        """Makes a phone call and communicate states via a stream.
+        """
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+
+def add_PhoneServicer_to_server(servicer, server):
+    rpc_method_handlers = {
+            'StreamCall': grpc.stream_stream_rpc_method_handler(
+                    servicer.StreamCall,
+                    request_deserializer=phone__pb2.StreamCallRequest.FromString,
+                    response_serializer=phone__pb2.StreamCallResponse.SerializeToString,
+            ),
+    }
+    generic_handler = grpc.method_handlers_generic_handler(
+            'grpc.testing.Phone', rpc_method_handlers)
+    server.add_generic_rpc_handlers((generic_handler,))
+
+
+ # This class is part of an EXPERIMENTAL API.
+class Phone(object):
+    """Missing associated documentation comment in .proto file"""
+
+    @staticmethod
+    def StreamCall(request_iterator,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.stream_stream(request_iterator, target, '/grpc.testing.Phone/StreamCall',
+            phone__pb2.StreamCallRequest.SerializeToString,
+            phone__pb2.StreamCallResponse.FromString,
+            options, channel_credentials,
+            call_credentials, compression, wait_for_ready, timeout, metadata)
diff --git a/examples/python/async_streaming/server.py b/examples/python/async_streaming/server.py
new file mode 100644 (file)
index 0000000..96ff822
--- /dev/null
@@ -0,0 +1,92 @@
+# Copyright 2020 The 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.
+
+import logging
+import time
+from concurrent.futures import ThreadPoolExecutor
+from typing import Iterable
+import threading
+
+import grpc
+from google.protobuf.json_format import MessageToJson
+
+import phone_pb2
+import phone_pb2_grpc
+
+
+def create_state_response(call_state: phone_pb2.CallState.State
+                         ) -> phone_pb2.StreamCallResponse:
+    response = phone_pb2.StreamCallResponse()
+    response.call_state.state = call_state
+    return response
+
+
+class Phone(phone_pb2_grpc.PhoneServicer):
+
+    def __init__(self):
+        self._id_counter = 0
+        self._lock = threading.RLock()
+
+    def _create_call_session(self) -> phone_pb2.CallInfo:
+        call_info = phone_pb2.CallInfo()
+        with self._lock:
+            call_info.session_id = str(self._id_counter)
+            self._id_counter += 1
+        call_info.media = "https://link.to.audio.resources"
+        logging.info("Created a call session [%s]", MessageToJson(call_info))
+        return call_info
+
+    def _clean_call_session(self, call_info: phone_pb2.CallInfo) -> None:
+        logging.info("Call session cleaned [%s]", MessageToJson(call_info))
+
+    def StreamCall(self,
+                   request_iterator: Iterable[phone_pb2.StreamCallRequest],
+                   context: grpc.ServicerContext
+                  ) -> Iterable[phone_pb2.StreamCallResponse]:
+        try:
+            request = next(request_iterator)
+            logging.info("Received a phone call request for number [%s]",
+                         request.phone_number)
+        except StopIteration:
+            raise RuntimeError("Failed to receive call request")
+        # Simulate the acceptance of call request
+        time.sleep(1)
+        yield create_state_response(phone_pb2.CallState.NEW)
+        # Simulate the start of the call session
+        time.sleep(1)
+        call_info = self._create_call_session()
+        context.add_callback(lambda: self._clean_call_session(call_info))
+        response = phone_pb2.StreamCallResponse()
+        response.call_info.session_id = call_info.session_id
+        response.call_info.media = call_info.media
+        yield response
+        yield create_state_response(phone_pb2.CallState.ACTIVE)
+        # Simulate the end of the call
+        time.sleep(2)
+        yield create_state_response(phone_pb2.CallState.ENDED)
+        logging.info("Call finished [%s]", request.phone_number)
+
+
+def serve(address: str) -> None:
+    server = grpc.server(ThreadPoolExecutor())
+    phone_pb2_grpc.add_PhoneServicer_to_server(Phone(), server)
+    server.add_insecure_port(address)
+    server.start()
+    logging.info("Server serving at %s", address)
+    server.wait_for_termination()
+
+
+if __name__ == "__main__":
+    logging.basicConfig(level=logging.INFO)
+    serve("[::]:50051")
index 3838b39..0ed770b 100644 (file)
@@ -33,12 +33,12 @@ py_binary(
     name = "customized_auth_client",
     testonly = 1,
     srcs = ["customized_auth_client.py"],
+    data = ["helloworld.proto"],
     python_version = "PY3",
     deps = [
         ":_credentials",
-        "//examples:helloworld_py_pb2",
-        "//examples:helloworld_py_pb2_grpc",
         "//src/python/grpcio/grpc:grpcio",
+        "//tools/distrib/python/grpcio_tools:grpc_tools",
     ],
 )
 
@@ -46,12 +46,40 @@ py_binary(
     name = "customized_auth_server",
     testonly = 1,
     srcs = ["customized_auth_server.py"],
+    data = ["helloworld.proto"],
     python_version = "PY3",
     deps = [
         ":_credentials",
-        "//examples:helloworld_py_pb2",
-        "//examples:helloworld_py_pb2_grpc",
         "//src/python/grpcio/grpc:grpcio",
+        "//tools/distrib/python/grpcio_tools:grpc_tools",
+    ],
+)
+
+py_binary(
+    name = "async_customized_auth_client",
+    testonly = 1,
+    srcs = ["async_customized_auth_client.py"],
+    data = ["helloworld.proto"],
+    imports = ["."],
+    python_version = "PY3",
+    deps = [
+        ":_credentials",
+        "//src/python/grpcio/grpc:grpcio",
+        "//tools/distrib/python/grpcio_tools:grpc_tools",
+    ],
+)
+
+py_binary(
+    name = "async_customized_auth_server",
+    testonly = 1,
+    srcs = ["async_customized_auth_server.py"],
+    data = ["helloworld.proto"],
+    imports = ["."],
+    python_version = "PY3",
+    deps = [
+        ":_credentials",
+        "//src/python/grpcio/grpc:grpcio",
+        "//tools/distrib/python/grpcio_tools:grpc_tools",
     ],
 )
 
@@ -61,9 +89,11 @@ py_test(
     python_version = "PY3",
     deps = [
         ":_credentials",
+        ":async_customized_auth_client",
+        ":async_customized_auth_server",
         ":customized_auth_client",
         ":customized_auth_server",
-        "//examples:helloworld_py_pb2",
         "//src/python/grpcio/grpc:grpcio",
+        "//tools/distrib/python/grpcio_tools:grpc_tools",
     ],
 )
index 732587b..ebd0ef6 100644 (file)
 # limitations under the License.
 """Loading SSL credentials for gRPC Python authentication example."""
 
-from __future__ import absolute_import
-from __future__ import division
-from __future__ import print_function
-
 import os
 
 
diff --git a/examples/python/auth/async_customized_auth_client.py b/examples/python/auth/async_customized_auth_client.py
new file mode 100644 (file)
index 0000000..343a262
--- /dev/null
@@ -0,0 +1,101 @@
+# Copyright 2020 The 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.
+"""Client of the Python AsyncIO example of customizing authentication mechanism."""
+
+import argparse
+import asyncio
+import logging
+
+import grpc
+
+import _credentials
+
+helloworld_pb2, helloworld_pb2_grpc = grpc.protos_and_services(
+    "helloworld.proto")
+
+_LOGGER = logging.getLogger(__name__)
+_LOGGER.setLevel(logging.INFO)
+
+_SERVER_ADDR_TEMPLATE = 'localhost:%d'
+_SIGNATURE_HEADER_KEY = 'x-signature'
+
+
+class AuthGateway(grpc.AuthMetadataPlugin):
+
+    def __call__(self, context: grpc.AuthMetadataContext,
+                 callback: grpc.AuthMetadataPluginCallback) -> None:
+        """Implements authentication by passing metadata to a callback.
+
+        Implementations of this method must not block.
+
+        Args:
+          context: An AuthMetadataContext providing information on the RPC that
+            the plugin is being called to authenticate.
+          callback: An AuthMetadataPluginCallback to be invoked either
+            synchronously or asynchronously.
+        """
+        # Example AuthMetadataContext object:
+        # AuthMetadataContext(
+        #     service_url=u'https://localhost:50051/helloworld.Greeter',
+        #     method_name=u'SayHello')
+        signature = context.method_name[::-1]
+        callback(((_SIGNATURE_HEADER_KEY, signature),), None)
+
+
+def create_client_channel(addr: str) -> grpc.aio.Channel:
+    # Call credential object will be invoked for every single RPC
+    call_credentials = grpc.metadata_call_credentials(AuthGateway(),
+                                                      name='auth gateway')
+    # Channel credential will be valid for the entire channel
+    channel_credential = grpc.ssl_channel_credentials(
+        _credentials.ROOT_CERTIFICATE)
+    # Combining channel credentials and call credentials together
+    composite_credentials = grpc.composite_channel_credentials(
+        channel_credential,
+        call_credentials,
+    )
+    channel = grpc.aio.secure_channel(addr, composite_credentials)
+    return channel
+
+
+async def send_rpc(channel: grpc.aio.Channel) -> helloworld_pb2.HelloReply:
+    stub = helloworld_pb2_grpc.GreeterStub(channel)
+    request = helloworld_pb2.HelloRequest(name='you')
+    try:
+        response = await stub.SayHello(request)
+    except grpc.RpcError as rpc_error:
+        _LOGGER.error('Received error: %s', rpc_error)
+        return rpc_error
+    else:
+        _LOGGER.info('Received message: %s', response)
+        return response
+
+
+async def main() -> None:
+    parser = argparse.ArgumentParser()
+    parser.add_argument('--port',
+                        nargs='?',
+                        type=int,
+                        default=50051,
+                        help='the address of server')
+    args = parser.parse_args()
+
+    channel = create_client_channel(_SERVER_ADDR_TEMPLATE % args.port)
+    await send_rpc(channel)
+    await channel.close()
+
+
+if __name__ == '__main__':
+    logging.basicConfig(level=logging.INFO)
+    asyncio.run(main())
diff --git a/examples/python/auth/async_customized_auth_server.py b/examples/python/auth/async_customized_auth_server.py
new file mode 100644 (file)
index 0000000..2521601
--- /dev/null
@@ -0,0 +1,103 @@
+# Copyright 2020 The 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.
+"""Server of the Python AsyncIO example of customizing authentication mechanism."""
+
+import argparse
+import asyncio
+import logging
+from typing import Awaitable, Callable, Tuple
+
+import grpc
+
+import _credentials
+
+helloworld_pb2, helloworld_pb2_grpc = grpc.protos_and_services(
+    "helloworld.proto")
+
+_LOGGER = logging.getLogger(__name__)
+_LOGGER.setLevel(logging.INFO)
+
+_LISTEN_ADDRESS_TEMPLATE = 'localhost:%d'
+_SIGNATURE_HEADER_KEY = 'x-signature'
+
+
+class SignatureValidationInterceptor(grpc.aio.ServerInterceptor):
+
+    def __init__(self):
+
+        def abort(ignored_request, context: grpc.aio.ServicerContext) -> None:
+            context.abort(grpc.StatusCode.UNAUTHENTICATED, 'Invalid signature')
+
+        self._abort_handler = grpc.unary_unary_rpc_method_handler(abort)
+
+    async def intercept_service(
+            self, continuation: Callable[[grpc.HandlerCallDetails], Awaitable[
+                grpc.RpcMethodHandler]],
+            handler_call_details: grpc.HandlerCallDetails
+    ) -> grpc.RpcMethodHandler:
+        # Example HandlerCallDetails object:
+        #     _HandlerCallDetails(
+        #       method=u'/helloworld.Greeter/SayHello',
+        #       invocation_metadata=...)
+        method_name = handler_call_details.method.split('/')[-1]
+        expected_metadata = (_SIGNATURE_HEADER_KEY, method_name[::-1])
+        if expected_metadata in handler_call_details.invocation_metadata:
+            return await continuation(handler_call_details)
+        else:
+            return self._abort_handler
+
+
+class SimpleGreeter(helloworld_pb2_grpc.GreeterServicer):
+
+    async def SayHello(self, request: helloworld_pb2.HelloRequest,
+                       unused_context) -> helloworld_pb2.HelloReply:
+        return helloworld_pb2.HelloReply(message='Hello, %s!' % request.name)
+
+
+async def run_server(port: int) -> Tuple[grpc.aio.Server, int]:
+    # Bind interceptor to server
+    server = grpc.aio.server(interceptors=(SignatureValidationInterceptor(),))
+    helloworld_pb2_grpc.add_GreeterServicer_to_server(SimpleGreeter(), server)
+
+    # Loading credentials
+    server_credentials = grpc.ssl_server_credentials(((
+        _credentials.SERVER_CERTIFICATE_KEY,
+        _credentials.SERVER_CERTIFICATE,
+    ),))
+
+    # Pass down credentials
+    port = server.add_secure_port(_LISTEN_ADDRESS_TEMPLATE % port,
+                                  server_credentials)
+
+    await server.start()
+    return server, port
+
+
+async def main() -> None:
+    parser = argparse.ArgumentParser()
+    parser.add_argument('--port',
+                        nargs='?',
+                        type=int,
+                        default=50051,
+                        help='the listening port')
+    args = parser.parse_args()
+
+    server, port = await run_server(args.port)
+    logging.info('Server is listening at port :%d', port)
+    await server.wait_for_termination()
+
+
+if __name__ == '__main__':
+    logging.basicConfig(level=logging.INFO)
+    asyncio.run(main())
index 49eb25b..59227a4 100644 (file)
 # limitations under the License.
 """Client of the Python example of customizing authentication mechanism."""
 
-from __future__ import absolute_import
-from __future__ import division
-from __future__ import print_function
-
 import argparse
 import contextlib
 import logging
 
 import grpc
-from examples import helloworld_pb2
-from examples import helloworld_pb2_grpc
-from examples.python.auth import _credentials
+import _credentials
+
+helloworld_pb2, helloworld_pb2_grpc = grpc.protos_and_services(
+    "helloworld.proto")
 
 _LOGGER = logging.getLogger(__name__)
 _LOGGER.setLevel(logging.INFO)
index ecc73e3..492c842 100644 (file)
 # limitations under the License.
 """Server of the Python example of customizing authentication mechanism."""
 
-from __future__ import absolute_import
-from __future__ import division
-from __future__ import print_function
-
 import argparse
 import contextlib
 import logging
 from concurrent import futures
 
 import grpc
-from examples import helloworld_pb2
-from examples import helloworld_pb2_grpc
-from examples.python.auth import _credentials
+import _credentials
+
+helloworld_pb2, helloworld_pb2_grpc = grpc.protos_and_services(
+    "helloworld.proto")
 
 _LOGGER = logging.getLogger(__name__)
 _LOGGER.setLevel(logging.INFO)
diff --git a/examples/python/auth/helloworld.proto b/examples/python/auth/helloworld.proto
new file mode 120000 (symlink)
index 0000000..a052c1c
--- /dev/null
@@ -0,0 +1 @@
+../../protos/helloworld.proto
\ No newline at end of file
index 8e1a3b2..25e8393 100644 (file)
 # limitations under the License.
 """Test for gRPC Python authentication example."""
 
-from __future__ import absolute_import
-from __future__ import division
-from __future__ import print_function
-
+import asyncio
 import unittest
 
 import grpc
 from examples.python.auth import _credentials
 from examples.python.auth import customized_auth_client
 from examples.python.auth import customized_auth_server
+from examples.python.auth import async_customized_auth_client
+from examples.python.auth import async_customized_auth_server
 
 _SERVER_ADDR_TEMPLATE = 'localhost:%d'
 
@@ -51,6 +50,19 @@ class AuthExampleTest(unittest.TestCase):
                 resp = customized_auth_client.send_rpc(channel)
                 self.assertEqual(resp.code(), grpc.StatusCode.UNAUTHENTICATED)
 
+    def test_successful_call_asyncio(self):
+
+        async def test_body():
+            server, port = await async_customized_auth_server.run_server(0)
+            channel = async_customized_auth_client.create_client_channel(
+                _SERVER_ADDR_TEMPLATE % port)
+            await async_customized_auth_client.send_rpc(channel)
+            await channel.close()
+            await server.stop(0)
+            # No unhandled exception raised, test passed!
+
+        asyncio.get_event_loop().run_until_complete(test_body())
+
 
 if __name__ == '__main__':
     unittest.main(verbosity=2)
index 1ab1d5a..beba230 100644 (file)
@@ -18,8 +18,8 @@ py_binary(
     python_version = "PY3",
     srcs_version = "PY2AND3",
     deps = [
-        "//examples:helloworld_py_pb2",
-        "//examples:helloworld_py_pb2_grpc",
+        "//examples/protos:helloworld_py_pb2",
+        "//examples/protos:helloworld_py_pb2_grpc",
         "//src/python/grpcio/grpc:grpcio",
     ],
 )
@@ -30,8 +30,8 @@ py_binary(
     python_version = "PY3",
     srcs_version = "PY2AND3",
     deps = [
-        "//examples:helloworld_py_pb2",
-        "//examples:helloworld_py_pb2_grpc",
+        "//examples/protos:helloworld_py_pb2",
+        "//examples/protos:helloworld_py_pb2_grpc",
         "//src/python/grpcio/grpc:grpcio",
     ],
 )
index 5d7a2ae..3de9d9e 100644 (file)
@@ -21,8 +21,8 @@ import argparse
 import logging
 import grpc
 
-from examples import helloworld_pb2
-from examples import helloworld_pb2_grpc
+from examples.protos import helloworld_pb2
+from examples.protos import helloworld_pb2_grpc
 
 _DESCRIPTION = 'A client capable of compression.'
 _COMPRESSION_OPTIONS = {
index 15fb0d0..935b044 100644 (file)
@@ -23,8 +23,8 @@ import logging
 import threading
 import grpc
 
-from examples import helloworld_pb2
-from examples import helloworld_pb2_grpc
+from examples.protos import helloworld_pb2
+from examples.protos import helloworld_pb2_grpc
 
 _DESCRIPTION = 'A server capable of compression.'
 _COMPRESSION_OPTIONS = {
index 029f78d..9cc8e16 100644 (file)
 
 load("@grpc_python_dependencies//:requirements.bzl", "requirement")
 
+package(default_testonly = 1)
+
 py_binary(
     name = "debug_server",
-    testonly = 1,
     srcs = ["debug_server.py"],
+    data = ["helloworld.proto"],
+    imports = ["."],
+    python_version = "PY3",
     deps = [
-        "//examples:helloworld_py_pb2",
-        "//examples:helloworld_py_pb2_grpc",
         "//src/python/grpcio/grpc:grpcio",
         "//src/python/grpcio_channelz/grpc_channelz/v1:grpc_channelz",
+        "//tools/distrib/python/grpcio_tools:grpc_tools",
     ],
 )
 
 py_binary(
     name = "send_message",
-    testonly = 1,
     srcs = ["send_message.py"],
+    data = ["helloworld.proto"],
+    imports = ["."],
     python_version = "PY3",
     deps = [
-        "//examples:helloworld_py_pb2",
-        "//examples:helloworld_py_pb2_grpc",
         "//src/python/grpcio/grpc:grpcio",
+        "//tools/distrib/python/grpcio_tools:grpc_tools",
     ],
 )
 
 py_binary(
     name = "get_stats",
-    testonly = 1,
     srcs = ["get_stats.py"],
     python_version = "PY3",
     deps = [
@@ -49,17 +51,52 @@ py_binary(
     ],
 )
 
+py_binary(
+    name = "asyncio_debug_server",
+    srcs = ["asyncio_debug_server.py"],
+    data = ["helloworld.proto"],
+    imports = ["."],
+    python_version = "PY3",
+    deps = [
+        "//src/python/grpcio/grpc:grpcio",
+        "//src/python/grpcio_channelz/grpc_channelz/v1:grpc_channelz",
+        "//tools/distrib/python/grpcio_tools:grpc_tools",
+    ],
+)
+
+py_binary(
+    name = "asyncio_send_message",
+    srcs = ["asyncio_send_message.py"],
+    data = ["helloworld.proto"],
+    imports = ["."],
+    python_version = "PY3",
+    deps = [
+        "//src/python/grpcio/grpc:grpcio",
+        "//tools/distrib/python/grpcio_tools:grpc_tools",
+    ],
+)
+
+py_binary(
+    name = "asyncio_get_stats",
+    srcs = ["asyncio_get_stats.py"],
+    python_version = "PY3",
+    deps = [
+        "//src/python/grpcio/grpc:grpcio",
+        "//src/python/grpcio_channelz/grpc_channelz/v1:grpc_channelz",
+    ],
+)
+
 py_test(
     name = "_debug_example_test",
     srcs = ["test/_debug_example_test.py"],
+    imports = ["."],
     python_version = "PY3",
     deps = [
+        ":asyncio_debug_server",
+        ":asyncio_get_stats",
+        ":asyncio_send_message",
         ":debug_server",
         ":get_stats",
         ":send_message",
-        "//examples:helloworld_py_pb2",
-        "//examples:helloworld_py_pb2_grpc",
-        "//src/python/grpcio/grpc:grpcio",
-        "//src/python/grpcio_channelz/grpc_channelz/v1:grpc_channelz",
     ],
 )
diff --git a/examples/python/debug/asyncio_debug_server.py b/examples/python/debug/asyncio_debug_server.py
new file mode 100644 (file)
index 0000000..09b6e2d
--- /dev/null
@@ -0,0 +1,83 @@
+# Copyright 2020 The 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.
+"""The Python AsyncIO example of utilizing Channelz feature."""
+
+import asyncio
+import argparse
+import logging
+import random
+
+import grpc
+
+helloworld_pb2, helloworld_pb2_grpc = grpc.protos_and_services(
+    "helloworld.proto")
+
+# TODO: Suppress until the macOS segfault fix rolled out
+from grpc_channelz.v1 import channelz  # pylint: disable=wrong-import-position
+
+_LOGGER = logging.getLogger(__name__)
+_LOGGER.setLevel(logging.INFO)
+
+_RANDOM_FAILURE_RATE = 0.3
+
+
+class FaultInjectGreeter(helloworld_pb2_grpc.GreeterServicer):
+
+    def __init__(self, failure_rate):
+        self._failure_rate = failure_rate
+
+    async def SayHello(self, request: helloworld_pb2.HelloRequest,
+                       context: grpc.aio.ServicerContext
+                      ) -> helloworld_pb2.HelloReply:
+        if random.random() < self._failure_rate:
+            context.abort(grpc.StatusCode.UNAVAILABLE,
+                          'Randomly injected failure.')
+        return helloworld_pb2.HelloReply(message=f'Hello, {request.name}!')
+
+
+def create_server(addr: str, failure_rate: float) -> grpc.aio.Server:
+    server = grpc.aio.server()
+    helloworld_pb2_grpc.add_GreeterServicer_to_server(
+        FaultInjectGreeter(failure_rate), server)
+
+    # Add Channelz Servicer to the gRPC server
+    channelz.add_channelz_servicer(server)
+
+    server.add_insecure_port(addr)
+    return server
+
+
+async def main() -> None:
+    parser = argparse.ArgumentParser()
+    parser.add_argument('--addr',
+                        nargs=1,
+                        type=str,
+                        default='[::]:50051',
+                        help='the address to listen on')
+    parser.add_argument(
+        '--failure_rate',
+        nargs=1,
+        type=float,
+        default=0.3,
+        help='a float indicates the percentage of failed message injections')
+    args = parser.parse_args()
+
+    server = create_server(addr=args.addr, failure_rate=args.failure_rate)
+    await server.start()
+    await server.wait_for_termination()
+
+
+if __name__ == '__main__':
+    logging.basicConfig(level=logging.INFO)
+    asyncio.get_event_loop().run_until_complete(main())
diff --git a/examples/python/debug/asyncio_get_stats.py b/examples/python/debug/asyncio_get_stats.py
new file mode 100644 (file)
index 0000000..a421f8a
--- /dev/null
@@ -0,0 +1,46 @@
+# Copyright 2020 The 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.
+"""Poll statistics from the server."""
+
+import asyncio
+import logging
+import argparse
+import grpc
+
+from grpc_channelz.v1 import channelz_pb2
+from grpc_channelz.v1 import channelz_pb2_grpc
+
+
+async def run(addr: str) -> None:
+    async with grpc.aio.insecure_channel(addr) as channel:
+        channelz_stub = channelz_pb2_grpc.ChannelzStub(channel)
+        response = await channelz_stub.GetServers(
+            channelz_pb2.GetServersRequest(start_server_id=0))
+        print('Info for all servers: %s' % response)
+
+
+async def main() -> None:
+    parser = argparse.ArgumentParser()
+    parser.add_argument('--addr',
+                        nargs=1,
+                        type=str,
+                        default='[::]:50051',
+                        help='the address to request')
+    args = parser.parse_args()
+    run(addr=args.addr)
+
+
+if __name__ == '__main__':
+    logging.basicConfig()
+    asyncio.get_event_loop().run_until_complete(main())
diff --git a/examples/python/debug/asyncio_send_message.py b/examples/python/debug/asyncio_send_message.py
new file mode 100644 (file)
index 0000000..c392399
--- /dev/null
@@ -0,0 +1,61 @@
+# Copyright 2020 The 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.
+"""Send multiple greeting messages to the backend."""
+
+import asyncio
+import logging
+import argparse
+import grpc
+
+helloworld_pb2, helloworld_pb2_grpc = grpc.protos_and_services(
+    "helloworld.proto")
+
+
+async def process(stub: helloworld_pb2_grpc.GreeterStub,
+                  request: helloworld_pb2.HelloRequest) -> None:
+    try:
+        response = await stub.SayHello(request)
+    except grpc.aio.AioRpcError as rpc_error:
+        print(f'Received error: {rpc_error}')
+    else:
+        print(f'Received message: {response}')
+
+
+async def run(addr: str, n: int) -> None:
+    async with grpc.aio.insecure_channel(addr) as channel:
+        stub = helloworld_pb2_grpc.GreeterStub(channel)
+        request = helloworld_pb2.HelloRequest(name='you')
+        for _ in range(n):
+            await process(stub, request)
+
+
+async def main() -> None:
+    parser = argparse.ArgumentParser()
+    parser.add_argument('--addr',
+                        nargs=1,
+                        type=str,
+                        default='[::]:50051',
+                        help='the address to request')
+    parser.add_argument('-n',
+                        nargs=1,
+                        type=int,
+                        default=10,
+                        help='an integer for number of messages to sent')
+    args = parser.parse_args()
+    await run(addr=args.addr, n=args.n)
+
+
+if __name__ == '__main__':
+    logging.basicConfig(level=logging.INFO)
+    asyncio.get_event_loop().run_until_complete(main())
index ce78fe3..f627d3b 100644 (file)
@@ -23,10 +23,12 @@ from concurrent import futures
 import random
 
 import grpc
-from grpc_channelz.v1 import channelz
 
-from examples import helloworld_pb2
-from examples import helloworld_pb2_grpc
+helloworld_pb2, helloworld_pb2_grpc = grpc.protos_and_services(
+    "helloworld.proto")
+
+# TODO: Suppress until the macOS segfault fix rolled out
+from grpc_channelz.v1 import channelz  # pylint: disable=wrong-import-position
 
 _LOGGER = logging.getLogger(__name__)
 _LOGGER.setLevel(logging.INFO)
index 2888182..398e1c0 100644 (file)
@@ -28,9 +28,11 @@ from grpc_channelz.v1 import channelz_pb2_grpc
 def run(addr):
     with grpc.insecure_channel(addr) as channel:
         channelz_stub = channelz_pb2_grpc.ChannelzStub(channel)
-        response = channelz_stub.GetServers(
-            channelz_pb2.GetServersRequest(start_server_id=0))
-        print('Info for all servers: %s' % response)
+        # This RPC pulls server-level metrics, like sent/received messages,
+        # succeeded/failed RPCs. For more info see:
+        # https://github.com/grpc/grpc/blob/master/src/proto/grpc/channelz/channelz.proto
+        response = channelz_stub.GetServers(channelz_pb2.GetServersRequest())
+        print(f'Info for all servers: {response}')
 
 
 def main():
diff --git a/examples/python/debug/helloworld.proto b/examples/python/debug/helloworld.proto
new file mode 120000 (symlink)
index 0000000..a052c1c
--- /dev/null
@@ -0,0 +1 @@
+../../protos/helloworld.proto
\ No newline at end of file
index 63cc60a..3f02199 100644 (file)
@@ -20,8 +20,9 @@ from __future__ import print_function
 import logging
 import argparse
 import grpc
-from examples import helloworld_pb2
-from examples import helloworld_pb2_grpc
+
+helloworld_pb2, helloworld_pb2_grpc = grpc.protos_and_services(
+    "helloworld.proto")
 
 
 def process(stub, request):
index 26a40ae..efd7dbe 100644 (file)
 # limitations under the License.
 """Test for gRPC Python debug example."""
 
-from __future__ import absolute_import
-from __future__ import division
-from __future__ import print_function
-
+import asyncio
 import logging
 import unittest
 
 from examples.python.debug import debug_server
+from examples.python.debug import asyncio_debug_server
 from examples.python.debug import send_message
+from examples.python.debug import asyncio_send_message
 from examples.python.debug import get_stats
+from examples.python.debug import asyncio_get_stats
 
 _LOGGER = logging.getLogger(__name__)
 _LOGGER.setLevel(logging.INFO)
@@ -47,7 +47,23 @@ class DebugExampleTest(unittest.TestCase):
         server.stop(None)
         # No unhandled exception raised, test passed!
 
+    def test_asyncio_channelz_example(self):
+
+        async def body():
+            server = asyncio_debug_server.create_server(
+                addr='[::]:0', failure_rate=_FAILURE_RATE)
+            port = server.add_insecure_port('[::]:0')
+            await server.start()
+            address = _ADDR_TEMPLATE % port
+
+            await asyncio_send_message.run(addr=address, n=_NUMBER_OF_MESSAGES)
+            await asyncio_get_stats.run(addr=address)
+            await server.stop(None)
+            # No unhandled exception raised, test passed!
+
+        asyncio.get_event_loop().run_until_complete(body())
+
 
 if __name__ == '__main__':
-    logging.basicConfig()
+    logging.basicConfig(level=logging.DEBUG)
     unittest.main(verbosity=2)
index a6aacd7..cdd056e 100644 (file)
@@ -19,8 +19,8 @@ py_library(
     testonly = 1,
     srcs = ["client.py"],
     deps = [
-        "//examples:helloworld_py_pb2",
-        "//examples:helloworld_py_pb2_grpc",
+        "//examples/protos:helloworld_py_pb2",
+        "//examples/protos:helloworld_py_pb2_grpc",
         "//src/python/grpcio/grpc:grpcio",
         "//src/python/grpcio_status/grpc_status",
         requirement("googleapis-common-protos"),
@@ -34,8 +34,8 @@ py_library(
     deps = [
         "//src/python/grpcio/grpc:grpcio",
         "//src/python/grpcio_status/grpc_status:grpc_status",
-        "//examples:helloworld_py_pb2",
-        "//examples:helloworld_py_pb2_grpc",
+        "//examples/protos:helloworld_py_pb2",
+        "//examples/protos:helloworld_py_pb2_grpc",
     ] + select({
         "//conditions:default": [requirement("futures")],
         "//:python3": [],
index c762d79..a79b8fc 100644 (file)
@@ -20,8 +20,8 @@ import grpc
 from grpc_status import rpc_status
 from google.rpc import error_details_pb2
 
-from examples import helloworld_pb2
-from examples import helloworld_pb2_grpc
+from examples.protos import helloworld_pb2
+from examples.protos import helloworld_pb2_grpc
 
 _LOGGER = logging.getLogger(__name__)
 
index 096d217..c410367 100644 (file)
@@ -23,8 +23,8 @@ from grpc_status import rpc_status
 from google.protobuf import any_pb2
 from google.rpc import code_pb2, status_pb2, error_details_pb2
 
-from examples import helloworld_pb2
-from examples import helloworld_pb2_grpc
+from examples.protos import helloworld_pb2
+from examples.protos import helloworld_pb2_grpc
 
 
 def create_greet_limit_exceed_error_status(name):
index 9eb81ba..a79ca45 100644 (file)
@@ -26,7 +26,7 @@ import logging
 
 import grpc
 
-from examples import helloworld_pb2_grpc
+from examples.protos import helloworld_pb2_grpc
 from examples.python.errors import client as error_handling_client
 from examples.python.errors import server as error_handling_server
 
index 29633f9..08a5423 100644 (file)
@@ -21,10 +21,7 @@ import helloworld_pb2
 import helloworld_pb2_grpc
 
 
-async def run():
-    # NOTE(gRPC Python Team): .close() is possible on a channel and should be
-    # used in circumstances in which the with statement does not fit the needs
-    # of the code.
+async def run() -> None:
     async with grpc.aio.insecure_channel('localhost:50051') as channel:
         stub = helloworld_pb2_grpc.GreeterStub(channel)
         response = await stub.SayHello(helloworld_pb2.HelloRequest(name='you'))
diff --git a/examples/python/helloworld/async_greeter_client_with_options.py b/examples/python/helloworld/async_greeter_client_with_options.py
new file mode 100644 (file)
index 0000000..0edd255
--- /dev/null
@@ -0,0 +1,43 @@
+# Copyright 2020 The 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.
+"""gRPC Python AsyncIO helloworld.Greeter client with channel options and timeout parameters."""
+
+import asyncio
+import logging
+
+import grpc
+
+import helloworld_pb2
+import helloworld_pb2_grpc
+
+# For more channel options, please see https://grpc.io/grpc/core/group__grpc__arg__keys.html
+CHANNEL_OPTIONS = [('grpc.lb_policy_name', 'pick_first'),
+                   ('grpc.enable_retries', 0),
+                   ('grpc.keepalive_timeout_ms', 10000)]
+
+
+async def run() -> None:
+    async with grpc.aio.insecure_channel(target='localhost:50051',
+                                         options=CHANNEL_OPTIONS) as channel:
+        stub = helloworld_pb2_grpc.GreeterStub(channel)
+        # Timeout in seconds.
+        # Please refer gRPC Python documents for more detail. https://grpc.io/grpc/python/grpc.html
+        response = await stub.SayHello(helloworld_pb2.HelloRequest(name='you'),
+                                       timeout=10)
+    print("Greeter client received: " + response.message)
+
+
+if __name__ == '__main__':
+    logging.basicConfig()
+    asyncio.run(run())
index 48c5dac..5cfa630 100644 (file)
@@ -23,18 +23,26 @@ import helloworld_pb2_grpc
 
 class Greeter(helloworld_pb2_grpc.GreeterServicer):
 
-    async def SayHello(self, request, context):
+    async def SayHello(self, request: helloworld_pb2.HelloRequest,
+                       context: grpc.aio.ServicerContext
+                      ) -> helloworld_pb2.HelloReply:
         return helloworld_pb2.HelloReply(message='Hello, %s!' % request.name)
 
 
-async def serve():
+async def serve() -> None:
     server = grpc.aio.server()
     helloworld_pb2_grpc.add_GreeterServicer_to_server(Greeter(), server)
     listen_addr = '[::]:50051'
     server.add_insecure_port(listen_addr)
     logging.info("Starting server on %s", listen_addr)
     await server.start()
-    await server.wait_for_termination()
+    try:
+        await server.wait_for_termination()
+    except KeyboardInterrupt:
+        # Shuts down the server with 0 seconds of grace period. During the
+        # grace period, the server won't accept new connections and allow
+        # existing RPCs to continue within the grace period.
+        await server.stop(0)
 
 
 if __name__ == '__main__':
diff --git a/examples/python/helloworld/async_greeter_server_with_reflection.py b/examples/python/helloworld/async_greeter_server_with_reflection.py
new file mode 100644 (file)
index 0000000..dada3d3
--- /dev/null
@@ -0,0 +1,49 @@
+# Copyright 2020 The 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.
+"""The reflection-enabled version of gRPC AsyncIO helloworld.Greeter server."""
+
+import asyncio
+import logging
+
+import grpc
+from grpc_reflection.v1alpha import reflection
+
+import helloworld_pb2
+import helloworld_pb2_grpc
+
+
+class Greeter(helloworld_pb2_grpc.GreeterServicer):
+
+    async def SayHello(self, request: helloworld_pb2.HelloRequest,
+                       context: grpc.aio.ServicerContext
+                      ) -> helloworld_pb2.HelloReply:
+        return helloworld_pb2.HelloReply(message='Hello, %s!' % request.name)
+
+
+async def serve() -> None:
+    server = grpc.aio.server()
+    helloworld_pb2_grpc.add_GreeterServicer_to_server(Greeter(), server)
+    SERVICE_NAMES = (
+        helloworld_pb2.DESCRIPTOR.services_by_name['Greeter'].full_name,
+        reflection.SERVICE_NAME,
+    )
+    reflection.enable_server_reflection(SERVICE_NAMES, server)
+    server.add_insecure_port('[::]:50051')
+    await server.start()
+    await server.wait_for_termination()
+
+
+if __name__ == '__main__':
+    logging.basicConfig()
+    asyncio.run(serve())
diff --git a/examples/python/route_guide/asyncio_route_guide_client.py b/examples/python/route_guide/asyncio_route_guide_client.py
new file mode 100644 (file)
index 0000000..3606f48
--- /dev/null
@@ -0,0 +1,129 @@
+# Copyright 2020 The 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.
+"""The Python AsyncIO implementation of the gRPC route guide client."""
+
+import asyncio
+import random
+import logging
+from typing import List, Iterable
+
+import grpc
+
+import route_guide_pb2
+import route_guide_pb2_grpc
+import route_guide_resources
+
+
+def make_route_note(message: str, latitude: int,
+                    longitude: int) -> route_guide_pb2.RouteNote:
+    return route_guide_pb2.RouteNote(
+        message=message,
+        location=route_guide_pb2.Point(latitude=latitude, longitude=longitude))
+
+
+# Performs an unary call
+async def guide_get_one_feature(stub: route_guide_pb2_grpc.RouteGuideStub,
+                                point: route_guide_pb2.Point) -> None:
+    feature = await stub.GetFeature(point)
+    if not feature.location:
+        print("Server returned incomplete feature")
+        return
+
+    if feature.name:
+        print(f"Feature called {feature.name} at {feature.location}")
+    else:
+        print(f"Found no feature at {feature.location}")
+
+
+async def guide_get_feature(stub: route_guide_pb2_grpc.RouteGuideStub) -> None:
+    await guide_get_one_feature(
+        stub, route_guide_pb2.Point(latitude=409146138, longitude=-746188906))
+    await guide_get_one_feature(stub,
+                                route_guide_pb2.Point(latitude=0, longitude=0))
+
+
+# Performs a server-streaming call
+async def guide_list_features(stub: route_guide_pb2_grpc.RouteGuideStub
+                             ) -> None:
+    rectangle = route_guide_pb2.Rectangle(
+        lo=route_guide_pb2.Point(latitude=400000000, longitude=-750000000),
+        hi=route_guide_pb2.Point(latitude=420000000, longitude=-730000000))
+    print("Looking for features between 40, -75 and 42, -73")
+
+    features = stub.ListFeatures(rectangle)
+
+    async for feature in features:
+        print(f"Feature called {feature.name} at {feature.location}")
+
+
+def generate_route(feature_list: List[route_guide_pb2.Feature]
+                  ) -> Iterable[route_guide_pb2.Point]:
+    for _ in range(0, 10):
+        random_feature = random.choice(feature_list)
+        print(f"Visiting point {random_feature.location}")
+        yield random_feature.location
+
+
+# Performs a client-streaming call
+async def guide_record_route(stub: route_guide_pb2_grpc.RouteGuideStub) -> None:
+    feature_list = route_guide_resources.read_route_guide_database()
+    route_iterator = generate_route(feature_list)
+
+    # gRPC AsyncIO client-streaming RPC API accepts both synchronous iterables
+    # and async iterables.
+    route_summary = await stub.RecordRoute(route_iterator)
+    print(f"Finished trip with {route_summary.point_count} points")
+    print(f"Passed {route_summary.feature_count} features")
+    print(f"Travelled {route_summary.distance} meters")
+    print(f"It took {route_summary.elapsed_time} seconds")
+
+
+def generate_messages() -> Iterable[route_guide_pb2.RouteNote]:
+    messages = [
+        make_route_note("First message", 0, 0),
+        make_route_note("Second message", 0, 1),
+        make_route_note("Third message", 1, 0),
+        make_route_note("Fourth message", 0, 0),
+        make_route_note("Fifth message", 1, 0),
+    ]
+    for msg in messages:
+        print(f"Sending {msg.message} at {msg.location}")
+        yield msg
+
+
+# Performs a bidi-streaming call
+async def guide_route_chat(stub: route_guide_pb2_grpc.RouteGuideStub) -> None:
+    # gRPC AsyncIO bidi-streaming RPC API accepts both synchronous iterables
+    # and async iterables.
+    call = stub.RouteChat(generate_messages())
+    async for response in call:
+        print(f"Received message {response.message} at {response.location}")
+
+
+async def main() -> None:
+    async with grpc.aio.insecure_channel('localhost:50051') as channel:
+        stub = route_guide_pb2_grpc.RouteGuideStub(channel)
+        print("-------------- GetFeature --------------")
+        await guide_get_feature(stub)
+        print("-------------- ListFeatures --------------")
+        await guide_list_features(stub)
+        print("-------------- RecordRoute --------------")
+        await guide_record_route(stub)
+        print("-------------- RouteChat --------------")
+        await guide_route_chat(stub)
+
+
+if __name__ == '__main__':
+    logging.basicConfig(level=logging.INFO)
+    asyncio.get_event_loop().run_until_complete(main())
diff --git a/examples/python/route_guide/asyncio_route_guide_server.py b/examples/python/route_guide/asyncio_route_guide_server.py
new file mode 100644 (file)
index 0000000..22c1908
--- /dev/null
@@ -0,0 +1,134 @@
+# Copyright 2020 The 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.
+"""The Python AsyncIO implementation of the gRPC route guide server."""
+
+import asyncio
+import time
+import math
+import logging
+from typing import AsyncIterable, Iterable
+
+import grpc
+
+import route_guide_pb2
+import route_guide_pb2_grpc
+import route_guide_resources
+
+
+def get_feature(feature_db: Iterable[route_guide_pb2.Feature],
+                point: route_guide_pb2.Point) -> route_guide_pb2.Feature:
+    """Returns Feature at given location or None."""
+    for feature in feature_db:
+        if feature.location == point:
+            return feature
+    return None
+
+
+def get_distance(start: route_guide_pb2.Point,
+                 end: route_guide_pb2.Point) -> float:
+    """Distance between two points."""
+    coord_factor = 10000000.0
+    lat_1 = start.latitude / coord_factor
+    lat_2 = end.latitude / coord_factor
+    lon_1 = start.longitude / coord_factor
+    lon_2 = end.longitude / coord_factor
+    lat_rad_1 = math.radians(lat_1)
+    lat_rad_2 = math.radians(lat_2)
+    delta_lat_rad = math.radians(lat_2 - lat_1)
+    delta_lon_rad = math.radians(lon_2 - lon_1)
+
+    # Formula is based on http://mathforum.org/library/drmath/view/51879.html
+    a = (pow(math.sin(delta_lat_rad / 2), 2) +
+         (math.cos(lat_rad_1) * math.cos(lat_rad_2) *
+          pow(math.sin(delta_lon_rad / 2), 2)))
+    c = 2 * math.atan2(math.sqrt(a), math.sqrt(1 - a))
+    R = 6371000
+    # metres
+    return R * c
+
+
+class RouteGuideServicer(route_guide_pb2_grpc.RouteGuideServicer):
+    """Provides methods that implement functionality of route guide server."""
+
+    def __init__(self) -> None:
+        self.db = route_guide_resources.read_route_guide_database()
+
+    def GetFeature(self, request: route_guide_pb2.Point,
+                   unused_context) -> route_guide_pb2.Feature:
+        feature = get_feature(self.db, request)
+        if feature is None:
+            return route_guide_pb2.Feature(name="", location=request)
+        else:
+            return feature
+
+    async def ListFeatures(self, request: route_guide_pb2.Rectangle,
+                           unused_context
+                          ) -> AsyncIterable[route_guide_pb2.Feature]:
+        left = min(request.lo.longitude, request.hi.longitude)
+        right = max(request.lo.longitude, request.hi.longitude)
+        top = max(request.lo.latitude, request.hi.latitude)
+        bottom = min(request.lo.latitude, request.hi.latitude)
+        for feature in self.db:
+            if (feature.location.longitude >= left and
+                    feature.location.longitude <= right and
+                    feature.location.latitude >= bottom and
+                    feature.location.latitude <= top):
+                yield feature
+
+    async def RecordRoute(
+            self, request_iterator: AsyncIterable[route_guide_pb2.Point],
+            unused_context) -> route_guide_pb2.RouteSummary:
+        point_count = 0
+        feature_count = 0
+        distance = 0.0
+        prev_point = None
+
+        start_time = time.time()
+        async for point in request_iterator:
+            point_count += 1
+            if get_feature(self.db, point):
+                feature_count += 1
+            if prev_point:
+                distance += get_distance(prev_point, point)
+            prev_point = point
+
+        elapsed_time = time.time() - start_time
+        return route_guide_pb2.RouteSummary(point_count=point_count,
+                                            feature_count=feature_count,
+                                            distance=int(distance),
+                                            elapsed_time=int(elapsed_time))
+
+    async def RouteChat(
+            self, request_iterator: AsyncIterable[route_guide_pb2.RouteNote],
+            unused_context) -> AsyncIterable[route_guide_pb2.RouteNote]:
+        prev_notes = []
+        async for new_note in request_iterator:
+            for prev_note in prev_notes:
+                if prev_note.location == new_note.location:
+                    yield prev_note
+            prev_notes.append(new_note)
+
+
+async def serve() -> None:
+    server = grpc.aio.server()
+    route_guide_pb2_grpc.add_RouteGuideServicer_to_server(
+        RouteGuideServicer(), server)
+    server.add_insecure_port('[::]:50051')
+    await server.start()
+    await server.wait_for_termination()
+
+
+if __name__ == '__main__':
+    logging.basicConfig(level=logging.INFO)
+    asyncio.get_event_loop().run_until_complete(serve())
index 0892b36..e783af8 100644 (file)
 
 load("@grpc_python_dependencies//:requirements.bzl", "requirement")
 
-py_library(
+package(default_testonly = 1)
+
+py_binary(
     name = "wait_for_ready_example",
-    testonly = 1,
     srcs = ["wait_for_ready_example.py"],
+    data = ["helloworld.proto"],
+    imports = ["."],
+    python_version = "PY3",
+    deps = [
+        "//src/python/grpcio/grpc:grpcio",
+        "//tools/distrib/python/grpcio_tools:grpc_tools",
+    ],
+)
+
+py_binary(
+    name = "asyncio_wait_for_ready_example",
+    srcs = ["asyncio_wait_for_ready_example.py"],
+    data = ["helloworld.proto"],
+    imports = ["."],
+    python_version = "PY3",
     deps = [
-        "//examples:helloworld_py_pb2",
-        "//examples:helloworld_py_pb2_grpc",
         "//src/python/grpcio/grpc:grpcio",
+        "//tools/distrib/python/grpcio_tools:grpc_tools",
     ],
 )
 
@@ -30,5 +45,8 @@ py_test(
     size = "small",
     srcs = ["test/_wait_for_ready_example_test.py"],
     python_version = "PY3",
-    deps = [":wait_for_ready_example"],
+    deps = [
+        ":asyncio_wait_for_ready_example",
+        ":wait_for_ready_example",
+    ],
 )
diff --git a/examples/python/wait_for_ready/asyncio_wait_for_ready_example.py b/examples/python/wait_for_ready/asyncio_wait_for_ready_example.py
new file mode 100644 (file)
index 0000000..f449909
--- /dev/null
@@ -0,0 +1,109 @@
+# Copyright 2020 The 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.
+"""The Python example of utilizing wait-for-ready flag."""
+
+import asyncio
+import logging
+from contextlib import contextmanager
+import socket
+from typing import Iterable
+
+import grpc
+
+helloworld_pb2, helloworld_pb2_grpc = grpc.protos_and_services(
+    "helloworld.proto")
+
+_LOGGER = logging.getLogger(__name__)
+_LOGGER.setLevel(logging.INFO)
+
+
+@contextmanager
+def get_free_loopback_tcp_port() -> Iterable[str]:
+    if socket.has_ipv6:
+        tcp_socket = socket.socket(socket.AF_INET6)
+    else:
+        tcp_socket = socket.socket(socket.AF_INET)
+    tcp_socket.bind(('', 0))
+    address_tuple = tcp_socket.getsockname()
+    yield f"localhost:{address_tuple[1]}"
+    tcp_socket.close()
+
+
+class Greeter(helloworld_pb2_grpc.GreeterServicer):
+
+    async def SayHello(self, request: helloworld_pb2.HelloRequest,
+                       unused_context) -> helloworld_pb2.HelloReply:
+        return helloworld_pb2.HelloReply(message=f'Hello, {request.name}!')
+
+
+def create_server(server_address: str):
+    server = grpc.aio.server()
+    helloworld_pb2_grpc.add_GreeterServicer_to_server(Greeter(), server)
+    bound_port = server.add_insecure_port(server_address)
+    assert bound_port == int(server_address.split(':')[-1])
+    return server
+
+
+async def process(stub: helloworld_pb2_grpc.GreeterStub,
+                  wait_for_ready: bool = None) -> None:
+    try:
+        response = await stub.SayHello(helloworld_pb2.HelloRequest(name='you'),
+                                       wait_for_ready=wait_for_ready)
+        message = response.message
+    except grpc.aio.AioRpcError as rpc_error:
+        assert rpc_error.code() == grpc.StatusCode.UNAVAILABLE
+        assert not wait_for_ready
+        message = rpc_error
+    else:
+        assert wait_for_ready
+    _LOGGER.info("Wait-for-ready %s, client received: %s",
+                 "enabled" if wait_for_ready else "disabled", message)
+
+
+async def main() -> None:
+    # Pick a random free port
+    with get_free_loopback_tcp_port() as server_address:
+        # Create gRPC channel
+        channel = grpc.aio.insecure_channel(server_address)
+        stub = helloworld_pb2_grpc.GreeterStub(channel)
+
+        # Fire an RPC without wait_for_ready
+        fail_fast_task = asyncio.get_event_loop().create_task(
+            process(stub, wait_for_ready=False))
+        # Fire an RPC with wait_for_ready
+        wait_for_ready_task = asyncio.get_event_loop().create_task(
+            process(stub, wait_for_ready=True))
+
+    # Wait for the channel entering TRANSIENT FAILURE state.
+    state = channel.get_state()
+    while state != grpc.ChannelConnectivity.TRANSIENT_FAILURE:
+        await channel.wait_for_state_change(state)
+        state = channel.get_state()
+
+    # Start the server to handle the RPC
+    server = create_server(server_address)
+    await server.start()
+
+    # Expected to fail with StatusCode.UNAVAILABLE.
+    await fail_fast_task
+    # Expected to success.
+    await wait_for_ready_task
+
+    await server.stop(None)
+    await channel.close()
+
+
+if __name__ == '__main__':
+    logging.basicConfig(level=logging.INFO)
+    asyncio.get_event_loop().run_until_complete(main())
diff --git a/examples/python/wait_for_ready/helloworld.proto b/examples/python/wait_for_ready/helloworld.proto
new file mode 120000 (symlink)
index 0000000..a052c1c
--- /dev/null
@@ -0,0 +1 @@
+../../protos/helloworld.proto
\ No newline at end of file
index 03e83a1..24d9865 100644 (file)
 # limitations under the License.
 """Tests of the wait-for-ready example."""
 
+import asyncio
 import unittest
 import logging
 
 from examples.python.wait_for_ready import wait_for_ready_example
+from examples.python.wait_for_ready import asyncio_wait_for_ready_example
 
 
 class WaitForReadyExampleTest(unittest.TestCase):
@@ -25,7 +27,12 @@ class WaitForReadyExampleTest(unittest.TestCase):
         wait_for_ready_example.main()
         # No unhandled exception raised, no deadlock, test passed!
 
+    def test_asyncio_wait_for_ready_example(self):
+        asyncio.get_event_loop().run_until_complete(
+            asyncio_wait_for_ready_example.main())
+        # No unhandled exception raised, no deadlock, test passed!
+
 
 if __name__ == '__main__':
-    logging.basicConfig()
+    logging.basicConfig(level=logging.DEBUG)
     unittest.main(verbosity=2)
index db2aeaf..6b6da86 100644 (file)
@@ -13,7 +13,6 @@
 # limitations under the License.
 """The Python example of utilizing wait-for-ready flag."""
 
-from __future__ import print_function
 import logging
 from concurrent import futures
 from contextlib import contextmanager
@@ -22,8 +21,8 @@ import threading
 
 import grpc
 
-from examples import helloworld_pb2
-from examples import helloworld_pb2_grpc
+helloworld_pb2, helloworld_pb2_grpc = grpc.protos_and_services(
+    "helloworld.proto")
 
 _LOGGER = logging.getLogger(__name__)
 _LOGGER.setLevel(logging.INFO)
index 002be7c..27702df 100644 (file)
@@ -22,7 +22,7 @@
 Pod::Spec.new do |s|
   s.name     = 'gRPC-C++'
   # TODO (mxyan): use version that match gRPC version when pod is stabilized
-  version = '1.34.1'
+  version = '1.35.0'
   s.version  = version
   s.summary  = 'gRPC C++ library'
   s.homepage = 'https://grpc.io'
@@ -177,7 +177,8 @@ Pod::Spec.new do |s|
                       'include/grpcpp/support/stub_options.h',
                       'include/grpcpp/support/sync_stream.h',
                       'include/grpcpp/support/time.h',
-                      'include/grpcpp/support/validate_service_config.h'
+                      'include/grpcpp/support/validate_service_config.h',
+                      'include/grpcpp/xds_server_builder.h'
   end
 
   s.subspec 'Implementation' do |ss|
@@ -186,11 +187,13 @@ Pod::Spec.new do |s|
     ss.dependency 'gRPC-Core', version
     abseil_version = '1.20200923.2'
     ss.dependency 'abseil/base/base', abseil_version
+    ss.dependency 'abseil/container/flat_hash_map', abseil_version
     ss.dependency 'abseil/container/flat_hash_set', abseil_version
     ss.dependency 'abseil/container/inlined_vector', abseil_version
     ss.dependency 'abseil/functional/bind_front', abseil_version
     ss.dependency 'abseil/memory/memory', abseil_version
     ss.dependency 'abseil/status/status', abseil_version
+    ss.dependency 'abseil/status/statusor', abseil_version
     ss.dependency 'abseil/strings/str_format', abseil_version
     ss.dependency 'abseil/strings/strings', abseil_version
     ss.dependency 'abseil/synchronization/synchronization', abseil_version
@@ -204,6 +207,7 @@ Pod::Spec.new do |s|
                       'src/core/ext/filters/client_channel/client_channel_factory.h',
                       'src/core/ext/filters/client_channel/config_selector.h',
                       'src/core/ext/filters/client_channel/connector.h',
+                      'src/core/ext/filters/client_channel/dynamic_filters.h',
                       'src/core/ext/filters/client_channel/global_subchannel_pool.h',
                       'src/core/ext/filters/client_channel/health/health_check_client.h',
                       'src/core/ext/filters/client_channel/http_connect_handshaker.h',
@@ -219,6 +223,7 @@ Pod::Spec.new do |s|
                       'src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.h',
                       'src/core/ext/filters/client_channel/lb_policy/subchannel_list.h',
                       'src/core/ext/filters/client_channel/lb_policy/xds/xds.h',
+                      'src/core/ext/filters/client_channel/lb_policy/xds/xds_channel_args.h',
                       'src/core/ext/filters/client_channel/lb_policy_factory.h',
                       'src/core/ext/filters/client_channel/lb_policy_registry.h',
                       'src/core/ext/filters/client_channel/local_subchannel_pool.h',
@@ -233,7 +238,6 @@ Pod::Spec.new do |s|
                       'src/core/ext/filters/client_channel/resolver_factory.h',
                       'src/core/ext/filters/client_channel/resolver_registry.h',
                       'src/core/ext/filters/client_channel/resolver_result_parsing.h',
-                      'src/core/ext/filters/client_channel/resolving_lb_policy.h',
                       'src/core/ext/filters/client_channel/retry_throttle.h',
                       'src/core/ext/filters/client_channel/server_address.h',
                       'src/core/ext/filters/client_channel/service_config.h',
@@ -447,7 +451,6 @@ Pod::Spec.new do |s|
                       'src/core/ext/xds/certificate_provider_registry.h',
                       'src/core/ext/xds/certificate_provider_store.h',
                       'src/core/ext/xds/file_watcher_certificate_provider_factory.h',
-                      'src/core/ext/xds/google_mesh_ca_certificate_provider_factory.h',
                       'src/core/ext/xds/xds_api.h',
                       'src/core/ext/xds/xds_bootstrap.h',
                       'src/core/ext/xds/xds_certificate_provider.h',
@@ -505,7 +508,6 @@ Pod::Spec.new do |s|
                       'src/core/lib/gprpp/global_config_generic.h',
                       'src/core/lib/gprpp/host_port.h',
                       'src/core/lib/gprpp/manual_constructor.h',
-                      'src/core/lib/gprpp/map.h',
                       'src/core/lib/gprpp/memory.h',
                       'src/core/lib/gprpp/mpscq.h',
                       'src/core/lib/gprpp/orphanable.h',
@@ -612,6 +614,7 @@ Pod::Spec.new do |s|
                       'src/core/lib/security/credentials/alts/grpc_alts_credentials_options.h',
                       'src/core/lib/security/credentials/composite/composite_credentials.h',
                       'src/core/lib/security/credentials/credentials.h',
+                      'src/core/lib/security/credentials/external/aws_external_account_credentials.h',
                       'src/core/lib/security/credentials/external/aws_request_signer.h',
                       'src/core/lib/security/credentials/external/external_account_credentials.h',
                       'src/core/lib/security/credentials/external/file_external_account_credentials.h',
@@ -630,6 +633,7 @@ Pod::Spec.new do |s|
                       'src/core/lib/security/credentials/tls/grpc_tls_certificate_provider.h',
                       'src/core/lib/security/credentials/tls/grpc_tls_credentials_options.h',
                       'src/core/lib/security/credentials/tls/tls_credentials.h',
+                      'src/core/lib/security/credentials/tls/tls_utils.h',
                       'src/core/lib/security/credentials/xds/xds_credentials.h',
                       'src/core/lib/security/security_connector/alts/alts_security_connector.h',
                       'src/core/lib/security/security_connector/fake/fake_security_connector.h',
@@ -762,6 +766,7 @@ Pod::Spec.new do |s|
                       'src/cpp/server/server_credentials.cc',
                       'src/cpp/server/server_posix.cc',
                       'src/cpp/server/thread_pool_interface.h',
+                      'src/cpp/server/xds_server_credentials.cc',
                       'src/cpp/thread_manager/thread_manager.cc',
                       'src/cpp/thread_manager/thread_manager.h',
                       'src/cpp/util/byte_buffer_cc.cc',
@@ -794,10 +799,15 @@ Pod::Spec.new do |s|
                       'third_party/re2/util/test.h',
                       'third_party/re2/util/utf.h',
                       'third_party/re2/util/util.h',
+                      'third_party/upb/third_party/wyhash/wyhash.h',
                       'third_party/upb/upb/decode.h',
+                      'third_party/upb/upb/decode.int.h',
+                      'third_party/upb/upb/decode_fast.h',
                       'third_party/upb/upb/def.h',
                       'third_party/upb/upb/def.hpp',
                       'third_party/upb/upb/encode.h',
+                      'third_party/upb/upb/json_decode.h',
+                      'third_party/upb/upb/json_encode.h',
                       'third_party/upb/upb/msg.h',
                       'third_party/upb/upb/port_def.inc',
                       'third_party/upb/upb/port_undef.inc',
@@ -805,7 +815,8 @@ Pod::Spec.new do |s|
                       'third_party/upb/upb/table.int.h',
                       'third_party/upb/upb/text_encode.h',
                       'third_party/upb/upb/upb.h',
-                      'third_party/upb/upb/upb.hpp'
+                      'third_party/upb/upb/upb.hpp',
+                      'third_party/upb/upb/upb.int.h'
 
     ss.private_header_files = 'src/core/ext/filters/client_channel/backend_metric.h',
                               'src/core/ext/filters/client_channel/backup_poller.h',
@@ -814,6 +825,7 @@ Pod::Spec.new do |s|
                               'src/core/ext/filters/client_channel/client_channel_factory.h',
                               'src/core/ext/filters/client_channel/config_selector.h',
                               'src/core/ext/filters/client_channel/connector.h',
+                              'src/core/ext/filters/client_channel/dynamic_filters.h',
                               'src/core/ext/filters/client_channel/global_subchannel_pool.h',
                               'src/core/ext/filters/client_channel/health/health_check_client.h',
                               'src/core/ext/filters/client_channel/http_connect_handshaker.h',
@@ -829,6 +841,7 @@ Pod::Spec.new do |s|
                               'src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.h',
                               'src/core/ext/filters/client_channel/lb_policy/subchannel_list.h',
                               'src/core/ext/filters/client_channel/lb_policy/xds/xds.h',
+                              'src/core/ext/filters/client_channel/lb_policy/xds/xds_channel_args.h',
                               'src/core/ext/filters/client_channel/lb_policy_factory.h',
                               'src/core/ext/filters/client_channel/lb_policy_registry.h',
                               'src/core/ext/filters/client_channel/local_subchannel_pool.h',
@@ -843,7 +856,6 @@ Pod::Spec.new do |s|
                               'src/core/ext/filters/client_channel/resolver_factory.h',
                               'src/core/ext/filters/client_channel/resolver_registry.h',
                               'src/core/ext/filters/client_channel/resolver_result_parsing.h',
-                              'src/core/ext/filters/client_channel/resolving_lb_policy.h',
                               'src/core/ext/filters/client_channel/retry_throttle.h',
                               'src/core/ext/filters/client_channel/server_address.h',
                               'src/core/ext/filters/client_channel/service_config.h',
@@ -1057,7 +1069,6 @@ Pod::Spec.new do |s|
                               'src/core/ext/xds/certificate_provider_registry.h',
                               'src/core/ext/xds/certificate_provider_store.h',
                               'src/core/ext/xds/file_watcher_certificate_provider_factory.h',
-                              'src/core/ext/xds/google_mesh_ca_certificate_provider_factory.h',
                               'src/core/ext/xds/xds_api.h',
                               'src/core/ext/xds/xds_bootstrap.h',
                               'src/core/ext/xds/xds_certificate_provider.h',
@@ -1115,7 +1126,6 @@ Pod::Spec.new do |s|
                               'src/core/lib/gprpp/global_config_generic.h',
                               'src/core/lib/gprpp/host_port.h',
                               'src/core/lib/gprpp/manual_constructor.h',
-                              'src/core/lib/gprpp/map.h',
                               'src/core/lib/gprpp/memory.h',
                               'src/core/lib/gprpp/mpscq.h',
                               'src/core/lib/gprpp/orphanable.h',
@@ -1222,6 +1232,7 @@ Pod::Spec.new do |s|
                               'src/core/lib/security/credentials/alts/grpc_alts_credentials_options.h',
                               'src/core/lib/security/credentials/composite/composite_credentials.h',
                               'src/core/lib/security/credentials/credentials.h',
+                              'src/core/lib/security/credentials/external/aws_external_account_credentials.h',
                               'src/core/lib/security/credentials/external/aws_request_signer.h',
                               'src/core/lib/security/credentials/external/external_account_credentials.h',
                               'src/core/lib/security/credentials/external/file_external_account_credentials.h',
@@ -1240,6 +1251,7 @@ Pod::Spec.new do |s|
                               'src/core/lib/security/credentials/tls/grpc_tls_certificate_provider.h',
                               'src/core/lib/security/credentials/tls/grpc_tls_credentials_options.h',
                               'src/core/lib/security/credentials/tls/tls_credentials.h',
+                              'src/core/lib/security/credentials/tls/tls_utils.h',
                               'src/core/lib/security/credentials/xds/xds_credentials.h',
                               'src/core/lib/security/security_connector/alts/alts_security_connector.h',
                               'src/core/lib/security/security_connector/fake/fake_security_connector.h',
@@ -1355,10 +1367,15 @@ Pod::Spec.new do |s|
                               'third_party/re2/util/test.h',
                               'third_party/re2/util/utf.h',
                               'third_party/re2/util/util.h',
+                              'third_party/upb/third_party/wyhash/wyhash.h',
                               'third_party/upb/upb/decode.h',
+                              'third_party/upb/upb/decode.int.h',
+                              'third_party/upb/upb/decode_fast.h',
                               'third_party/upb/upb/def.h',
                               'third_party/upb/upb/def.hpp',
                               'third_party/upb/upb/encode.h',
+                              'third_party/upb/upb/json_decode.h',
+                              'third_party/upb/upb/json_encode.h',
                               'third_party/upb/upb/msg.h',
                               'third_party/upb/upb/port_def.inc',
                               'third_party/upb/upb/port_undef.inc',
@@ -1366,7 +1383,8 @@ Pod::Spec.new do |s|
                               'third_party/upb/upb/table.int.h',
                               'third_party/upb/upb/text_encode.h',
                               'third_party/upb/upb/upb.h',
-                              'third_party/upb/upb/upb.hpp'
+                              'third_party/upb/upb/upb.hpp',
+                              'third_party/upb/upb/upb.int.h'
   end
 
   s.subspec 'Protobuf' do |ss|
@@ -1399,6 +1417,7 @@ Pod::Spec.new do |s|
 
   s.prepare_command = <<-END_OF_COMMAND
     sed -E -i '' 's;#include <openssl/(.*)>;#if COCOAPODS==1\\\n  #include <openssl_grpc/\\1>\\\n#else\\\n  #include <openssl/\\1>\\\n#endif;g' $(find src/core -type f \\( -path '*.h' -or -path '*.cc' \\) -print | xargs grep -H -c '#include <openssl_grpc/' | grep 0$ | cut -d':' -f1)
+    find third_party/upb/ -type f \\( -name '*.h' -or -name '*.hpp' -or -name '*.c' -or -name '*.cc' \\) -print0 | xargs -0 -L1 sed -E -i'.grpc_back' 's;#include "third_party/(.*)";#if COCOAPODS==1\\\n  #include  "third_party/upb/third_party/\\1"\\\n#else\\\n  #include  "third_party/\\1"\\\n#endif;g'
     find src/core/ src/cpp/ third_party/upb/ -type f \\( -name '*.h' -or -name '*.hpp' -or -name '*.c' -or -name '*.cc' \\) -print0 | xargs -0 -L1 sed -E -i'.grpc_back' 's;#include "upb/(.*)";#if COCOAPODS==1\\\n  #include  "third_party/upb/upb/\\1"\\\n#else\\\n  #include  "upb/\\1"\\\n#endif;g'
     find src/core/ src/cpp/ third_party/upb/ -type f -name '*.grpc_back' -print0 | xargs -0 rm
     find src/core/ src/cpp/ third_party/upb/ -type f \\( -name '*.h' -or -name '*.c' -or -name '*.cc' \\) -print0 | xargs -0 -L1 sed -E -i'.grpc_back' 's;#include "(.*).upb.h";#if COCOAPODS==1\\\n  #include  "src/core/ext/upb-generated/\\1.upb.h"\\\n#else\\\n  #include  "\\1.upb.h"\\\n#endif;g'
index f264e35..5c48280 100644 (file)
@@ -21,7 +21,7 @@
 
 Pod::Spec.new do |s|
   s.name     = 'gRPC-Core'
-  version = '1.34.1'
+  version = '1.35.0'
   s.version  = version
   s.summary  = 'Core cross-platform gRPC library, written in C'
   s.homepage = 'https://grpc.io'
@@ -175,11 +175,13 @@ Pod::Spec.new do |s|
     ss.dependency "#{s.name}/Interface", version
     ss.dependency 'BoringSSL-GRPC', '0.0.14'
     ss.dependency 'abseil/base/base', abseil_version
+    ss.dependency 'abseil/container/flat_hash_map', abseil_version
     ss.dependency 'abseil/container/flat_hash_set', abseil_version
     ss.dependency 'abseil/container/inlined_vector', abseil_version
     ss.dependency 'abseil/functional/bind_front', abseil_version
     ss.dependency 'abseil/memory/memory', abseil_version
     ss.dependency 'abseil/status/status', abseil_version
+    ss.dependency 'abseil/status/statusor', abseil_version
     ss.dependency 'abseil/strings/str_format', abseil_version
     ss.dependency 'abseil/strings/strings', abseil_version
     ss.dependency 'abseil/synchronization/synchronization', abseil_version
@@ -203,6 +205,8 @@ Pod::Spec.new do |s|
                       'src/core/ext/filters/client_channel/config_selector.cc',
                       'src/core/ext/filters/client_channel/config_selector.h',
                       'src/core/ext/filters/client_channel/connector.h',
+                      'src/core/ext/filters/client_channel/dynamic_filters.cc',
+                      'src/core/ext/filters/client_channel/dynamic_filters.h',
                       'src/core/ext/filters/client_channel/global_subchannel_pool.cc',
                       'src/core/ext/filters/client_channel/global_subchannel_pool.h',
                       'src/core/ext/filters/client_channel/health/health_check_client.cc',
@@ -235,10 +239,11 @@ Pod::Spec.new do |s|
                       'src/core/ext/filters/client_channel/lb_policy/subchannel_list.h',
                       'src/core/ext/filters/client_channel/lb_policy/weighted_target/weighted_target.cc',
                       'src/core/ext/filters/client_channel/lb_policy/xds/cds.cc',
-                      'src/core/ext/filters/client_channel/lb_policy/xds/eds.cc',
                       'src/core/ext/filters/client_channel/lb_policy/xds/xds.h',
+                      'src/core/ext/filters/client_channel/lb_policy/xds/xds_channel_args.h',
                       'src/core/ext/filters/client_channel/lb_policy/xds/xds_cluster_impl.cc',
                       'src/core/ext/filters/client_channel/lb_policy/xds/xds_cluster_manager.cc',
+                      'src/core/ext/filters/client_channel/lb_policy/xds/xds_cluster_resolver.cc',
                       'src/core/ext/filters/client_channel/lb_policy_factory.h',
                       'src/core/ext/filters/client_channel/lb_policy_registry.cc',
                       'src/core/ext/filters/client_channel/lb_policy_registry.h',
@@ -250,14 +255,12 @@ Pod::Spec.new do |s|
                       'src/core/ext/filters/client_channel/resolver.cc',
                       'src/core/ext/filters/client_channel/resolver.h',
                       'src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc',
-                      'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.cc',
                       'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.h',
                       'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_libuv.cc',
                       'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_posix.cc',
                       'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_windows.cc',
                       'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc',
                       'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h',
-                      'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_fallback.cc',
                       'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv.cc',
                       'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_posix.cc',
                       'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc',
@@ -274,8 +277,6 @@ Pod::Spec.new do |s|
                       'src/core/ext/filters/client_channel/resolver_registry.h',
                       'src/core/ext/filters/client_channel/resolver_result_parsing.cc',
                       'src/core/ext/filters/client_channel/resolver_result_parsing.h',
-                      'src/core/ext/filters/client_channel/resolving_lb_policy.cc',
-                      'src/core/ext/filters/client_channel/resolving_lb_policy.h',
                       'src/core/ext/filters/client_channel/retry_throttle.cc',
                       'src/core/ext/filters/client_channel/retry_throttle.h',
                       'src/core/ext/filters/client_channel/server_address.cc',
@@ -711,8 +712,6 @@ Pod::Spec.new do |s|
                       'src/core/ext/xds/certificate_provider_store.h',
                       'src/core/ext/xds/file_watcher_certificate_provider_factory.cc',
                       'src/core/ext/xds/file_watcher_certificate_provider_factory.h',
-                      'src/core/ext/xds/google_mesh_ca_certificate_provider_factory.cc',
-                      'src/core/ext/xds/google_mesh_ca_certificate_provider_factory.h',
                       'src/core/ext/xds/xds_api.cc',
                       'src/core/ext/xds/xds_api.h',
                       'src/core/ext/xds/xds_bootstrap.cc',
@@ -724,6 +723,7 @@ Pod::Spec.new do |s|
                       'src/core/ext/xds/xds_client.h',
                       'src/core/ext/xds/xds_client_stats.cc',
                       'src/core/ext/xds/xds_client_stats.h',
+                      'src/core/ext/xds/xds_server_config_fetcher.cc',
                       'src/core/lib/avl/avl.cc',
                       'src/core/lib/avl/avl.h',
                       'src/core/lib/backoff/backoff.cc',
@@ -834,7 +834,6 @@ Pod::Spec.new do |s|
                       'src/core/lib/gprpp/host_port.cc',
                       'src/core/lib/gprpp/host_port.h',
                       'src/core/lib/gprpp/manual_constructor.h',
-                      'src/core/lib/gprpp/map.h',
                       'src/core/lib/gprpp/memory.h',
                       'src/core/lib/gprpp/mpscq.cc',
                       'src/core/lib/gprpp/mpscq.h',
@@ -1065,6 +1064,8 @@ Pod::Spec.new do |s|
                       'src/core/lib/security/credentials/credentials.cc',
                       'src/core/lib/security/credentials/credentials.h',
                       'src/core/lib/security/credentials/credentials_metadata.cc',
+                      'src/core/lib/security/credentials/external/aws_external_account_credentials.cc',
+                      'src/core/lib/security/credentials/external/aws_external_account_credentials.h',
                       'src/core/lib/security/credentials/external/aws_request_signer.cc',
                       'src/core/lib/security/credentials/external/aws_request_signer.h',
                       'src/core/lib/security/credentials/external/external_account_credentials.cc',
@@ -1103,6 +1104,8 @@ Pod::Spec.new do |s|
                       'src/core/lib/security/credentials/tls/grpc_tls_credentials_options.h',
                       'src/core/lib/security/credentials/tls/tls_credentials.cc',
                       'src/core/lib/security/credentials/tls/tls_credentials.h',
+                      'src/core/lib/security/credentials/tls/tls_utils.cc',
+                      'src/core/lib/security/credentials/tls/tls_utils.h',
                       'src/core/lib/security/credentials/xds/xds_credentials.cc',
                       'src/core/lib/security/credentials/xds/xds_credentials.h',
                       'src/core/lib/security/security_connector/alts/alts_security_connector.cc',
@@ -1317,16 +1320,23 @@ Pod::Spec.new do |s|
                       'third_party/re2/util/test.h',
                       'third_party/re2/util/utf.h',
                       'third_party/re2/util/util.h',
+                      'third_party/upb/third_party/wyhash/wyhash.h',
                       'third_party/upb/upb/decode.c',
                       'third_party/upb/upb/decode.h',
+                      'third_party/upb/upb/decode.int.h',
+                      'third_party/upb/upb/decode_fast.c',
+                      'third_party/upb/upb/decode_fast.h',
                       'third_party/upb/upb/def.c',
                       'third_party/upb/upb/def.h',
                       'third_party/upb/upb/def.hpp',
                       'third_party/upb/upb/encode.c',
                       'third_party/upb/upb/encode.h',
+                      'third_party/upb/upb/json_decode.c',
+                      'third_party/upb/upb/json_decode.h',
+                      'third_party/upb/upb/json_encode.c',
+                      'third_party/upb/upb/json_encode.h',
                       'third_party/upb/upb/msg.c',
                       'third_party/upb/upb/msg.h',
-                      'third_party/upb/upb/port.c',
                       'third_party/upb/upb/port_def.inc',
                       'third_party/upb/upb/port_undef.inc',
                       'third_party/upb/upb/reflection.c',
@@ -1337,7 +1347,8 @@ Pod::Spec.new do |s|
                       'third_party/upb/upb/text_encode.h',
                       'third_party/upb/upb/upb.c',
                       'third_party/upb/upb/upb.h',
-                      'third_party/upb/upb/upb.hpp'
+                      'third_party/upb/upb/upb.hpp',
+                      'third_party/upb/upb/upb.int.h'
     ss.private_header_files = 'src/core/ext/filters/client_channel/backend_metric.h',
                               'src/core/ext/filters/client_channel/backup_poller.h',
                               'src/core/ext/filters/client_channel/client_channel.h',
@@ -1345,6 +1356,7 @@ Pod::Spec.new do |s|
                               'src/core/ext/filters/client_channel/client_channel_factory.h',
                               'src/core/ext/filters/client_channel/config_selector.h',
                               'src/core/ext/filters/client_channel/connector.h',
+                              'src/core/ext/filters/client_channel/dynamic_filters.h',
                               'src/core/ext/filters/client_channel/global_subchannel_pool.h',
                               'src/core/ext/filters/client_channel/health/health_check_client.h',
                               'src/core/ext/filters/client_channel/http_connect_handshaker.h',
@@ -1360,6 +1372,7 @@ Pod::Spec.new do |s|
                               'src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.h',
                               'src/core/ext/filters/client_channel/lb_policy/subchannel_list.h',
                               'src/core/ext/filters/client_channel/lb_policy/xds/xds.h',
+                              'src/core/ext/filters/client_channel/lb_policy/xds/xds_channel_args.h',
                               'src/core/ext/filters/client_channel/lb_policy_factory.h',
                               'src/core/ext/filters/client_channel/lb_policy_registry.h',
                               'src/core/ext/filters/client_channel/local_subchannel_pool.h',
@@ -1374,7 +1387,6 @@ Pod::Spec.new do |s|
                               'src/core/ext/filters/client_channel/resolver_factory.h',
                               'src/core/ext/filters/client_channel/resolver_registry.h',
                               'src/core/ext/filters/client_channel/resolver_result_parsing.h',
-                              'src/core/ext/filters/client_channel/resolving_lb_policy.h',
                               'src/core/ext/filters/client_channel/retry_throttle.h',
                               'src/core/ext/filters/client_channel/server_address.h',
                               'src/core/ext/filters/client_channel/service_config.h',
@@ -1588,7 +1600,6 @@ Pod::Spec.new do |s|
                               'src/core/ext/xds/certificate_provider_registry.h',
                               'src/core/ext/xds/certificate_provider_store.h',
                               'src/core/ext/xds/file_watcher_certificate_provider_factory.h',
-                              'src/core/ext/xds/google_mesh_ca_certificate_provider_factory.h',
                               'src/core/ext/xds/xds_api.h',
                               'src/core/ext/xds/xds_bootstrap.h',
                               'src/core/ext/xds/xds_certificate_provider.h',
@@ -1646,7 +1657,6 @@ Pod::Spec.new do |s|
                               'src/core/lib/gprpp/global_config_generic.h',
                               'src/core/lib/gprpp/host_port.h',
                               'src/core/lib/gprpp/manual_constructor.h',
-                              'src/core/lib/gprpp/map.h',
                               'src/core/lib/gprpp/memory.h',
                               'src/core/lib/gprpp/mpscq.h',
                               'src/core/lib/gprpp/orphanable.h',
@@ -1753,6 +1763,7 @@ Pod::Spec.new do |s|
                               'src/core/lib/security/credentials/alts/grpc_alts_credentials_options.h',
                               'src/core/lib/security/credentials/composite/composite_credentials.h',
                               'src/core/lib/security/credentials/credentials.h',
+                              'src/core/lib/security/credentials/external/aws_external_account_credentials.h',
                               'src/core/lib/security/credentials/external/aws_request_signer.h',
                               'src/core/lib/security/credentials/external/external_account_credentials.h',
                               'src/core/lib/security/credentials/external/file_external_account_credentials.h',
@@ -1771,6 +1782,7 @@ Pod::Spec.new do |s|
                               'src/core/lib/security/credentials/tls/grpc_tls_certificate_provider.h',
                               'src/core/lib/security/credentials/tls/grpc_tls_credentials_options.h',
                               'src/core/lib/security/credentials/tls/tls_credentials.h',
+                              'src/core/lib/security/credentials/tls/tls_utils.h',
                               'src/core/lib/security/credentials/xds/xds_credentials.h',
                               'src/core/lib/security/security_connector/alts/alts_security_connector.h',
                               'src/core/lib/security/security_connector/fake/fake_security_connector.h',
@@ -1875,10 +1887,15 @@ Pod::Spec.new do |s|
                               'third_party/re2/util/test.h',
                               'third_party/re2/util/utf.h',
                               'third_party/re2/util/util.h',
+                              'third_party/upb/third_party/wyhash/wyhash.h',
                               'third_party/upb/upb/decode.h',
+                              'third_party/upb/upb/decode.int.h',
+                              'third_party/upb/upb/decode_fast.h',
                               'third_party/upb/upb/def.h',
                               'third_party/upb/upb/def.hpp',
                               'third_party/upb/upb/encode.h',
+                              'third_party/upb/upb/json_decode.h',
+                              'third_party/upb/upb/json_encode.h',
                               'third_party/upb/upb/msg.h',
                               'third_party/upb/upb/port_def.inc',
                               'third_party/upb/upb/port_undef.inc',
@@ -1886,7 +1903,8 @@ Pod::Spec.new do |s|
                               'third_party/upb/upb/table.int.h',
                               'third_party/upb/upb/text_encode.h',
                               'third_party/upb/upb/upb.h',
-                              'third_party/upb/upb/upb.hpp'
+                              'third_party/upb/upb/upb.hpp',
+                              'third_party/upb/upb/upb.int.h'
   end
 
   # CFStream is now default. Leaving this subspec only for compatibility purpose.
@@ -1961,9 +1979,9 @@ Pod::Spec.new do |s|
                       'test/core/end2end/tests/default_host.cc',
                       'test/core/end2end/tests/disappearing_server.cc',
                       'test/core/end2end/tests/empty_batch.cc',
-                      'test/core/end2end/tests/filter_call_init_fails.cc',
                       'test/core/end2end/tests/filter_causes_close.cc',
                       'test/core/end2end/tests/filter_context.cc',
+                      'test/core/end2end/tests/filter_init_fails.cc',
                       'test/core/end2end/tests/filter_latency.cc',
                       'test/core/end2end/tests/filter_status_code.cc',
                       'test/core/end2end/tests/graceful_server_shutdown.cc',
@@ -2023,8 +2041,6 @@ Pod::Spec.new do |s|
                       'test/core/end2end/tests/write_buffering_at_end.cc',
                       'test/core/util/cmdline.cc',
                       'test/core/util/cmdline.h',
-                      'test/core/util/debugger_macros.cc',
-                      'test/core/util/debugger_macros.h',
                       'test/core/util/eval_args_mock_endpoint.cc',
                       'test/core/util/eval_args_mock_endpoint.h',
                       'test/core/util/fuzzer_util.cc',
@@ -2060,6 +2076,8 @@ Pod::Spec.new do |s|
                       'test/core/util/test_config.h',
                       'test/core/util/test_tcp_server.cc',
                       'test/core/util/test_tcp_server.h',
+                      'test/core/util/tls_utils.cc',
+                      'test/core/util/tls_utils.h',
                       'test/core/util/tracer_util.cc',
                       'test/core/util/tracer_util.h',
                       'test/core/util/trickle_endpoint.cc',
@@ -2069,6 +2087,7 @@ Pod::Spec.new do |s|
   # TODO (mxyan): Instead of this hack, add include path "third_party" to C core's include path?
   s.prepare_command = <<-END_OF_COMMAND
     sed -E -i '' 's;#include <openssl/(.*)>;#if COCOAPODS==1\\\n  #include <openssl_grpc/\\1>\\\n#else\\\n  #include <openssl/\\1>\\\n#endif;g' $(find src/core -type f \\( -path '*.h' -or -path '*.cc' \\) -print | xargs grep -H -c '#include <openssl_grpc/' | grep 0$ | cut -d':' -f1)
+    find third_party/upb/ -type f \\( -name '*.h' -or -name '*.hpp' -or -name '*.c' -or -name '*.cc' \\) -print0 | xargs -0 -L1 sed -E -i'.grpc_back' 's;#include "third_party/(.*)";#if COCOAPODS==1\\\n  #include  "third_party/upb/third_party/\\1"\\\n#else\\\n  #include  "third_party/\\1"\\\n#endif;g'
     find src/core/ src/cpp/ third_party/upb/ -type f \\( -name '*.h' -or -name '*.hpp' -or -name '*.c' -or -name '*.cc' \\) -print0 | xargs -0 -L1 sed -E -i'.grpc_back' 's;#include "upb/(.*)";#if COCOAPODS==1\\\n  #include  "third_party/upb/upb/\\1"\\\n#else\\\n  #include  "upb/\\1"\\\n#endif;g'
     find src/core/ src/cpp/ third_party/upb/ -type f -name '*.grpc_back' -print0 | xargs -0 rm
     find src/core/ src/cpp/ third_party/upb/ -type f \\( -name '*.h' -or -name '*.c' -or -name '*.cc' \\) -print0 | xargs -0 -L1 sed -E -i'.grpc_back' 's;#include "(.*).upb.h";#if COCOAPODS==1\\\n  #include  "src/core/ext/upb-generated/\\1.upb.h"\\\n#else\\\n  #include  "\\1.upb.h"\\\n#endif;g'
index dae9811..dfca5dc 100644 (file)
@@ -21,7 +21,7 @@
 
 Pod::Spec.new do |s|
   s.name     = 'gRPC-ProtoRPC'
-  version = '1.34.1'
+  version = '1.35.0'
   s.version  = version
   s.summary  = 'RPC library for Protocol Buffers, based on gRPC'
   s.homepage = 'https://grpc.io'
index 157c84d..bdd39fa 100644 (file)
@@ -21,7 +21,7 @@
 
 Pod::Spec.new do |s|
   s.name     = 'gRPC-RxLibrary'
-  version = '1.34.1'
+  version = '1.35.0'
   s.version  = version
   s.summary  = 'Reactive Extensions library for iOS/OSX.'
   s.homepage = 'https://grpc.io'
index 73fd9dc..330679a 100644 (file)
@@ -20,7 +20,7 @@
 
 Pod::Spec.new do |s|
   s.name     = 'gRPC'
-  version = '1.34.1'
+  version = '1.35.0'
   s.version  = version
   s.summary  = 'gRPC client library for iOS/OSX'
   s.homepage = 'https://grpc.io'
index aecf99a..4dcb9ed 100644 (file)
--- a/grpc.def
+++ b/grpc.def
@@ -57,6 +57,9 @@ EXPORTS
     grpc_server_request_registered_call
     grpc_server_create
     grpc_server_register_completion_queue
+    grpc_server_config_fetcher_xds_create
+    grpc_server_config_fetcher_destroy
+    grpc_server_set_config_fetcher
     grpc_server_add_insecure_http2_port
     grpc_server_start
     grpc_server_shutdown_and_notify
@@ -107,6 +110,7 @@ EXPORTS
     grpc_google_compute_engine_credentials_create
     grpc_max_auth_token_lifetime
     grpc_service_account_jwt_access_credentials_create
+    grpc_external_account_credentials_create
     grpc_google_refresh_token_credentials_create
     grpc_access_token_credentials_create
     grpc_google_iam_credentials_create
@@ -139,6 +143,7 @@ EXPORTS
     grpc_tls_identity_pairs_add_pair
     grpc_tls_identity_pairs_destroy
     grpc_tls_certificate_provider_static_data_create
+    grpc_tls_certificate_provider_file_watcher_create
     grpc_tls_certificate_provider_release
     grpc_tls_credentials_options_create
     grpc_tls_credentials_options_set_cert_request_type
@@ -152,6 +157,7 @@ EXPORTS
     grpc_tls_server_authorization_check_config_create
     grpc_tls_server_authorization_check_config_release
     grpc_xds_credentials_create
+    grpc_xds_server_credentials_create
     grpc_raw_byte_buffer_create
     grpc_raw_compressed_byte_buffer_create
     grpc_byte_buffer_copy
index 9338ae2..4359a21 100644 (file)
@@ -32,7 +32,7 @@ Gem::Specification.new do |s|
   s.require_paths = %w( src/ruby/lib src/ruby/bin src/ruby/pb )
   s.platform      = Gem::Platform::RUBY
 
-  s.add_dependency 'google-protobuf', '~> 3.13'
+  s.add_dependency 'google-protobuf', '~> 3.14'
   s.add_dependency 'googleapis-common-protos-types', '~> 1.0'
 
   s.add_development_dependency 'bundler',            '>= 1.9'
@@ -120,6 +120,8 @@ Gem::Specification.new do |s|
   s.files += %w( src/core/ext/filters/client_channel/config_selector.cc )
   s.files += %w( src/core/ext/filters/client_channel/config_selector.h )
   s.files += %w( src/core/ext/filters/client_channel/connector.h )
+  s.files += %w( src/core/ext/filters/client_channel/dynamic_filters.cc )
+  s.files += %w( src/core/ext/filters/client_channel/dynamic_filters.h )
   s.files += %w( src/core/ext/filters/client_channel/global_subchannel_pool.cc )
   s.files += %w( src/core/ext/filters/client_channel/global_subchannel_pool.h )
   s.files += %w( src/core/ext/filters/client_channel/health/health_check_client.cc )
@@ -152,10 +154,11 @@ Gem::Specification.new do |s|
   s.files += %w( src/core/ext/filters/client_channel/lb_policy/subchannel_list.h )
   s.files += %w( src/core/ext/filters/client_channel/lb_policy/weighted_target/weighted_target.cc )
   s.files += %w( src/core/ext/filters/client_channel/lb_policy/xds/cds.cc )
-  s.files += %w( src/core/ext/filters/client_channel/lb_policy/xds/eds.cc )
   s.files += %w( src/core/ext/filters/client_channel/lb_policy/xds/xds.h )
+  s.files += %w( src/core/ext/filters/client_channel/lb_policy/xds/xds_channel_args.h )
   s.files += %w( src/core/ext/filters/client_channel/lb_policy/xds/xds_cluster_impl.cc )
   s.files += %w( src/core/ext/filters/client_channel/lb_policy/xds/xds_cluster_manager.cc )
+  s.files += %w( src/core/ext/filters/client_channel/lb_policy/xds/xds_cluster_resolver.cc )
   s.files += %w( src/core/ext/filters/client_channel/lb_policy_factory.h )
   s.files += %w( src/core/ext/filters/client_channel/lb_policy_registry.cc )
   s.files += %w( src/core/ext/filters/client_channel/lb_policy_registry.h )
@@ -167,14 +170,12 @@ Gem::Specification.new do |s|
   s.files += %w( src/core/ext/filters/client_channel/resolver.cc )
   s.files += %w( src/core/ext/filters/client_channel/resolver.h )
   s.files += %w( src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc )
-  s.files += %w( src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.cc )
   s.files += %w( src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.h )
   s.files += %w( src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_libuv.cc )
   s.files += %w( src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_posix.cc )
   s.files += %w( src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_windows.cc )
   s.files += %w( src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc )
   s.files += %w( src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h )
-  s.files += %w( src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_fallback.cc )
   s.files += %w( src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv.cc )
   s.files += %w( src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_posix.cc )
   s.files += %w( src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc )
@@ -191,8 +192,6 @@ Gem::Specification.new do |s|
   s.files += %w( src/core/ext/filters/client_channel/resolver_registry.h )
   s.files += %w( src/core/ext/filters/client_channel/resolver_result_parsing.cc )
   s.files += %w( src/core/ext/filters/client_channel/resolver_result_parsing.h )
-  s.files += %w( src/core/ext/filters/client_channel/resolving_lb_policy.cc )
-  s.files += %w( src/core/ext/filters/client_channel/resolving_lb_policy.h )
   s.files += %w( src/core/ext/filters/client_channel/retry_throttle.cc )
   s.files += %w( src/core/ext/filters/client_channel/retry_throttle.h )
   s.files += %w( src/core/ext/filters/client_channel/server_address.cc )
@@ -628,8 +627,6 @@ Gem::Specification.new do |s|
   s.files += %w( src/core/ext/xds/certificate_provider_store.h )
   s.files += %w( src/core/ext/xds/file_watcher_certificate_provider_factory.cc )
   s.files += %w( src/core/ext/xds/file_watcher_certificate_provider_factory.h )
-  s.files += %w( src/core/ext/xds/google_mesh_ca_certificate_provider_factory.cc )
-  s.files += %w( src/core/ext/xds/google_mesh_ca_certificate_provider_factory.h )
   s.files += %w( src/core/ext/xds/xds_api.cc )
   s.files += %w( src/core/ext/xds/xds_api.h )
   s.files += %w( src/core/ext/xds/xds_bootstrap.cc )
@@ -641,6 +638,7 @@ Gem::Specification.new do |s|
   s.files += %w( src/core/ext/xds/xds_client.h )
   s.files += %w( src/core/ext/xds/xds_client_stats.cc )
   s.files += %w( src/core/ext/xds/xds_client_stats.h )
+  s.files += %w( src/core/ext/xds/xds_server_config_fetcher.cc )
   s.files += %w( src/core/lib/avl/avl.cc )
   s.files += %w( src/core/lib/avl/avl.h )
   s.files += %w( src/core/lib/backoff/backoff.cc )
@@ -751,7 +749,6 @@ Gem::Specification.new do |s|
   s.files += %w( src/core/lib/gprpp/host_port.cc )
   s.files += %w( src/core/lib/gprpp/host_port.h )
   s.files += %w( src/core/lib/gprpp/manual_constructor.h )
-  s.files += %w( src/core/lib/gprpp/map.h )
   s.files += %w( src/core/lib/gprpp/memory.h )
   s.files += %w( src/core/lib/gprpp/mpscq.cc )
   s.files += %w( src/core/lib/gprpp/mpscq.h )
@@ -982,6 +979,8 @@ Gem::Specification.new do |s|
   s.files += %w( src/core/lib/security/credentials/credentials.cc )
   s.files += %w( src/core/lib/security/credentials/credentials.h )
   s.files += %w( src/core/lib/security/credentials/credentials_metadata.cc )
+  s.files += %w( src/core/lib/security/credentials/external/aws_external_account_credentials.cc )
+  s.files += %w( src/core/lib/security/credentials/external/aws_external_account_credentials.h )
   s.files += %w( src/core/lib/security/credentials/external/aws_request_signer.cc )
   s.files += %w( src/core/lib/security/credentials/external/aws_request_signer.h )
   s.files += %w( src/core/lib/security/credentials/external/external_account_credentials.cc )
@@ -1020,6 +1019,8 @@ Gem::Specification.new do |s|
   s.files += %w( src/core/lib/security/credentials/tls/grpc_tls_credentials_options.h )
   s.files += %w( src/core/lib/security/credentials/tls/tls_credentials.cc )
   s.files += %w( src/core/lib/security/credentials/tls/tls_credentials.h )
+  s.files += %w( src/core/lib/security/credentials/tls/tls_utils.cc )
+  s.files += %w( src/core/lib/security/credentials/tls/tls_utils.h )
   s.files += %w( src/core/lib/security/credentials/xds/xds_credentials.cc )
   s.files += %w( src/core/lib/security/credentials/xds/xds_credentials.h )
   s.files += %w( src/core/lib/security/security_connector/alts/alts_security_connector.cc )
@@ -1242,6 +1243,7 @@ Gem::Specification.new do |s|
   s.files += %w( third_party/abseil-cpp/absl/base/port.h )
   s.files += %w( third_party/abseil-cpp/absl/base/thread_annotations.h )
   s.files += %w( third_party/abseil-cpp/absl/container/fixed_array.h )
+  s.files += %w( third_party/abseil-cpp/absl/container/flat_hash_map.h )
   s.files += %w( third_party/abseil-cpp/absl/container/flat_hash_set.h )
   s.files += %w( third_party/abseil-cpp/absl/container/inlined_vector.h )
   s.files += %w( third_party/abseil-cpp/absl/container/internal/common.h )
@@ -1256,6 +1258,7 @@ Gem::Specification.new do |s|
   s.files += %w( third_party/abseil-cpp/absl/container/internal/have_sse.h )
   s.files += %w( third_party/abseil-cpp/absl/container/internal/inlined_vector.h )
   s.files += %w( third_party/abseil-cpp/absl/container/internal/layout.h )
+  s.files += %w( third_party/abseil-cpp/absl/container/internal/raw_hash_map.h )
   s.files += %w( third_party/abseil-cpp/absl/container/internal/raw_hash_set.cc )
   s.files += %w( third_party/abseil-cpp/absl/container/internal/raw_hash_set.h )
   s.files += %w( third_party/abseil-cpp/absl/debugging/internal/address_is_readable.cc )
@@ -1299,10 +1302,13 @@ Gem::Specification.new do |s|
   s.files += %w( third_party/abseil-cpp/absl/numeric/int128_have_intrinsic.inc )
   s.files += %w( third_party/abseil-cpp/absl/numeric/int128_no_intrinsic.inc )
   s.files += %w( third_party/abseil-cpp/absl/status/internal/status_internal.h )
+  s.files += %w( third_party/abseil-cpp/absl/status/internal/statusor_internal.h )
   s.files += %w( third_party/abseil-cpp/absl/status/status.cc )
   s.files += %w( third_party/abseil-cpp/absl/status/status.h )
   s.files += %w( third_party/abseil-cpp/absl/status/status_payload_printer.cc )
   s.files += %w( third_party/abseil-cpp/absl/status/status_payload_printer.h )
+  s.files += %w( third_party/abseil-cpp/absl/status/statusor.cc )
+  s.files += %w( third_party/abseil-cpp/absl/status/statusor.h )
   s.files += %w( third_party/abseil-cpp/absl/strings/ascii.cc )
   s.files += %w( third_party/abseil-cpp/absl/strings/ascii.h )
   s.files += %w( third_party/abseil-cpp/absl/strings/charconv.cc )
@@ -2018,16 +2024,23 @@ Gem::Specification.new do |s|
   s.files += %w( third_party/re2/util/test.h )
   s.files += %w( third_party/re2/util/utf.h )
   s.files += %w( third_party/re2/util/util.h )
+  s.files += %w( third_party/upb/third_party/wyhash/wyhash.h )
   s.files += %w( third_party/upb/upb/decode.c )
   s.files += %w( third_party/upb/upb/decode.h )
+  s.files += %w( third_party/upb/upb/decode.int.h )
+  s.files += %w( third_party/upb/upb/decode_fast.c )
+  s.files += %w( third_party/upb/upb/decode_fast.h )
   s.files += %w( third_party/upb/upb/def.c )
   s.files += %w( third_party/upb/upb/def.h )
   s.files += %w( third_party/upb/upb/def.hpp )
   s.files += %w( third_party/upb/upb/encode.c )
   s.files += %w( third_party/upb/upb/encode.h )
+  s.files += %w( third_party/upb/upb/json_decode.c )
+  s.files += %w( third_party/upb/upb/json_decode.h )
+  s.files += %w( third_party/upb/upb/json_encode.c )
+  s.files += %w( third_party/upb/upb/json_encode.h )
   s.files += %w( third_party/upb/upb/msg.c )
   s.files += %w( third_party/upb/upb/msg.h )
-  s.files += %w( third_party/upb/upb/port.c )
   s.files += %w( third_party/upb/upb/port_def.inc )
   s.files += %w( third_party/upb/upb/port_undef.inc )
   s.files += %w( third_party/upb/upb/reflection.c )
@@ -2039,6 +2052,7 @@ Gem::Specification.new do |s|
   s.files += %w( third_party/upb/upb/upb.c )
   s.files += %w( third_party/upb/upb/upb.h )
   s.files += %w( third_party/upb/upb/upb.hpp )
+  s.files += %w( third_party/upb/upb/upb.int.h )
   s.files += %w( third_party/zlib/adler32.c )
   s.files += %w( third_party/zlib/compress.c )
   s.files += %w( third_party/zlib/crc32.c )
index 7a8ad7c..0432bb5 100644 (file)
--- a/grpc.gyp
+++ b/grpc.gyp
         'test/core/end2end/tests/default_host.cc',
         'test/core/end2end/tests/disappearing_server.cc',
         'test/core/end2end/tests/empty_batch.cc',
-        'test/core/end2end/tests/filter_call_init_fails.cc',
         'test/core/end2end/tests/filter_causes_close.cc',
         'test/core/end2end/tests/filter_context.cc',
+        'test/core/end2end/tests/filter_init_fails.cc',
         'test/core/end2end/tests/filter_latency.cc',
         'test/core/end2end/tests/filter_status_code.cc',
         'test/core/end2end/tests/graceful_server_shutdown.cc',
         'test/core/end2end/tests/default_host.cc',
         'test/core/end2end/tests/disappearing_server.cc',
         'test/core/end2end/tests/empty_batch.cc',
-        'test/core/end2end/tests/filter_call_init_fails.cc',
         'test/core/end2end/tests/filter_causes_close.cc',
         'test/core/end2end/tests/filter_context.cc',
+        'test/core/end2end/tests/filter_init_fails.cc',
         'test/core/end2end/tests/filter_latency.cc',
         'test/core/end2end/tests/filter_status_code.cc',
         'test/core/end2end/tests/graceful_server_shutdown.cc',
         'upb',
         'absl/types:optional',
         'absl/strings:strings',
+        'absl/status:statusor',
         'absl/status:status',
         'absl/functional:bind_front',
         'absl/container:inlined_vector',
         'absl/container:flat_hash_set',
+        'absl/container:flat_hash_map',
       ],
       'sources': [
         'src/core/ext/filters/census/grpc_context.cc',
         'src/core/ext/filters/client_channel/client_channel_factory.cc',
         'src/core/ext/filters/client_channel/client_channel_plugin.cc',
         'src/core/ext/filters/client_channel/config_selector.cc',
+        'src/core/ext/filters/client_channel/dynamic_filters.cc',
         'src/core/ext/filters/client_channel/global_subchannel_pool.cc',
         'src/core/ext/filters/client_channel/health/health_check_client.cc',
         'src/core/ext/filters/client_channel/http_connect_handshaker.cc',
         'src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc',
         'src/core/ext/filters/client_channel/lb_policy/weighted_target/weighted_target.cc',
         'src/core/ext/filters/client_channel/lb_policy/xds/cds.cc',
-        'src/core/ext/filters/client_channel/lb_policy/xds/eds.cc',
         'src/core/ext/filters/client_channel/lb_policy/xds/xds_cluster_impl.cc',
         'src/core/ext/filters/client_channel/lb_policy/xds/xds_cluster_manager.cc',
+        'src/core/ext/filters/client_channel/lb_policy/xds/xds_cluster_resolver.cc',
         'src/core/ext/filters/client_channel/lb_policy_registry.cc',
         'src/core/ext/filters/client_channel/local_subchannel_pool.cc',
         'src/core/ext/filters/client_channel/proxy_mapper_registry.cc',
         'src/core/ext/filters/client_channel/resolver.cc',
         'src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc',
-        'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.cc',
         'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_libuv.cc',
         'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_posix.cc',
         'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_windows.cc',
         'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc',
-        'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_fallback.cc',
         'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv.cc',
         'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_posix.cc',
         'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc',
         'src/core/ext/filters/client_channel/resolver/xds/xds_resolver.cc',
         'src/core/ext/filters/client_channel/resolver_registry.cc',
         'src/core/ext/filters/client_channel/resolver_result_parsing.cc',
-        'src/core/ext/filters/client_channel/resolving_lb_policy.cc',
         'src/core/ext/filters/client_channel/retry_throttle.cc',
         'src/core/ext/filters/client_channel/server_address.cc',
         'src/core/ext/filters/client_channel/service_config.cc',
         'src/core/ext/xds/certificate_provider_registry.cc',
         'src/core/ext/xds/certificate_provider_store.cc',
         'src/core/ext/xds/file_watcher_certificate_provider_factory.cc',
-        'src/core/ext/xds/google_mesh_ca_certificate_provider_factory.cc',
         'src/core/ext/xds/xds_api.cc',
         'src/core/ext/xds/xds_bootstrap.cc',
         'src/core/ext/xds/xds_certificate_provider.cc',
         'src/core/ext/xds/xds_client.cc',
         'src/core/ext/xds/xds_client_stats.cc',
+        'src/core/ext/xds/xds_server_config_fetcher.cc',
         'src/core/lib/avl/avl.cc',
         'src/core/lib/backoff/backoff.cc',
         'src/core/lib/channel/channel_args.cc',
         'src/core/lib/security/credentials/composite/composite_credentials.cc',
         'src/core/lib/security/credentials/credentials.cc',
         'src/core/lib/security/credentials/credentials_metadata.cc',
+        'src/core/lib/security/credentials/external/aws_external_account_credentials.cc',
         'src/core/lib/security/credentials/external/aws_request_signer.cc',
         'src/core/lib/security/credentials/external/external_account_credentials.cc',
         'src/core/lib/security/credentials/external/file_external_account_credentials.cc',
         'src/core/lib/security/credentials/tls/grpc_tls_certificate_provider.cc',
         'src/core/lib/security/credentials/tls/grpc_tls_credentials_options.cc',
         'src/core/lib/security/credentials/tls/tls_credentials.cc',
+        'src/core/lib/security/credentials/tls/tls_utils.cc',
         'src/core/lib/security/credentials/xds/xds_credentials.cc',
         'src/core/lib/security/security_connector/alts/alts_security_connector.cc',
         'src/core/lib/security/security_connector/fake/fake_security_connector.cc',
       ],
       'sources': [
         'test/core/util/cmdline.cc',
-        'test/core/util/debugger_macros.cc',
         'test/core/util/eval_args_mock_endpoint.cc',
         'test/core/util/fuzzer_util.cc',
         'test/core/util/grpc_profiler.cc',
         'test/core/util/subprocess_windows.cc',
         'test/core/util/test_config.cc',
         'test/core/util/test_tcp_server.cc',
+        'test/core/util/tls_utils.cc',
         'test/core/util/tracer_util.cc',
         'test/core/util/trickle_endpoint.cc',
       ],
       ],
       'sources': [
         'test/core/util/cmdline.cc',
-        'test/core/util/debugger_macros.cc',
         'test/core/util/eval_args_mock_endpoint.cc',
         'test/core/util/fuzzer_util.cc',
         'test/core/util/grpc_profiler.cc',
         'upb',
         'absl/types:optional',
         'absl/strings:strings',
+        'absl/status:statusor',
         'absl/status:status',
         'absl/container:inlined_vector',
+        'absl/container:flat_hash_map',
       ],
       'sources': [
         'src/core/ext/filters/census/grpc_context.cc',
         'src/core/ext/filters/client_channel/client_channel_factory.cc',
         'src/core/ext/filters/client_channel/client_channel_plugin.cc',
         'src/core/ext/filters/client_channel/config_selector.cc',
+        'src/core/ext/filters/client_channel/dynamic_filters.cc',
         'src/core/ext/filters/client_channel/global_subchannel_pool.cc',
         'src/core/ext/filters/client_channel/health/health_check_client.cc',
         'src/core/ext/filters/client_channel/http_connect_handshaker.cc',
         'src/core/ext/filters/client_channel/proxy_mapper_registry.cc',
         'src/core/ext/filters/client_channel/resolver.cc',
         'src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc',
-        'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.cc',
         'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_libuv.cc',
         'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_posix.cc',
         'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_windows.cc',
         'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc',
-        'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_fallback.cc',
         'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv.cc',
         'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_posix.cc',
         'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc',
         'src/core/ext/filters/client_channel/resolver/sockaddr/sockaddr_resolver.cc',
         'src/core/ext/filters/client_channel/resolver_registry.cc',
         'src/core/ext/filters/client_channel/resolver_result_parsing.cc',
-        'src/core/ext/filters/client_channel/resolving_lb_policy.cc',
         'src/core/ext/filters/client_channel/retry_throttle.cc',
         'src/core/ext/filters/client_channel/server_address.cc',
         'src/core/ext/filters/client_channel/service_config.cc',
         'src/cpp/server/server_context.cc',
         'src/cpp/server/server_credentials.cc',
         'src/cpp/server/server_posix.cc',
+        'src/cpp/server/xds_server_credentials.cc',
         'src/cpp/thread_manager/thread_manager.cc',
         'src/cpp/util/byte_buffer_cc.cc',
         'src/cpp/util/status.cc',
       'dependencies': [
       ],
       'sources': [
+        'third_party/upb/upb/decode_fast.c',
         'third_party/upb/upb/decode.c',
+        'third_party/upb/upb/def.c',
         'third_party/upb/upb/encode.c',
+        'third_party/upb/upb/json_decode.c',
+        'third_party/upb/upb/json_encode.c',
         'third_party/upb/upb/msg.c',
-        'third_party/upb/upb/port.c',
-        'third_party/upb/upb/table.c',
-        'third_party/upb/upb/upb.c',
-        'third_party/upb/upb/def.c',
         'third_party/upb/upb/reflection.c',
+        'third_party/upb/upb/table.c',
         'third_party/upb/upb/text_encode.c',
+        'third_party/upb/upb/upb.c',
         'src/core/ext/upb-generated/google/protobuf/any.upb.c',
         'src/core/ext/upb-generated/google/protobuf/descriptor.upb.c',
         'src/core/ext/upb-generated/google/protobuf/duration.upb.c',
index a4f6a8f..1769566 100644 (file)
@@ -41,7 +41,7 @@ GRPCAPI int grpc_compression_algorithm_is_stream(
 /** Parses the \a slice as a grpc_compression_algorithm instance and updating \a
  * algorithm. Returns 1 upon success, 0 otherwise. */
 GRPCAPI int grpc_compression_algorithm_parse(
-    grpc_slice value, grpc_compression_algorithm* algorithm);
+    grpc_slice name, grpc_compression_algorithm* algorithm);
 
 /** Updates \a name with the encoding name corresponding to a valid \a
  * algorithm. Note that \a name is statically allocated and must *not* be freed.
index 020acdb..09bb106 100644 (file)
@@ -411,6 +411,20 @@ GRPCAPI void grpc_server_register_completion_queue(grpc_server* server,
                                                    grpc_completion_queue* cq,
                                                    void* reserved);
 
+typedef struct grpc_server_config_fetcher grpc_server_config_fetcher;
+
+/** EXPERIMENTAL.  Creates an xDS config fetcher. */
+GRPCAPI grpc_server_config_fetcher* grpc_server_config_fetcher_xds_create();
+
+/** EXPERIMENTAL.  Destroys a config fetcher. */
+GRPCAPI void grpc_server_config_fetcher_destroy(
+    grpc_server_config_fetcher* config_fetcher);
+
+/** EXPERIMENTAL.  Sets the server's config fetcher.  Takes ownership.
+    Must be called before adding ports */
+GRPCAPI void grpc_server_set_config_fetcher(
+    grpc_server* server, grpc_server_config_fetcher* config_fetcher);
+
 /** Add a HTTP2 over plaintext over tcp listener.
     Returns bound port number on success, 0 on failure.
     REQUIRES: server not started */
index 12f39ec..c1d7295 100644 (file)
@@ -330,6 +330,14 @@ grpc_service_account_jwt_access_credentials_create(const char* json_key,
                                                    gpr_timespec token_lifetime,
                                                    void* reserved);
 
+/** Builds External Account credentials.
+ - json_string is the JSON string containing the credentials options.
+ - scopes_string contains the scopes to be binded with the credentials.
+   This API is used for experimental purposes for now and may change in the
+ future. */
+GRPCAPI grpc_call_credentials* grpc_external_account_credentials_create(
+    const char* json_string, const char* scopes_string);
+
 /** Creates an Oauth2 Refresh Token credentials object for connecting to Google.
    May return NULL if the input is invalid.
    WARNING: Do NOT use this credentials to connect to a non-google service as
@@ -808,6 +816,31 @@ grpc_tls_certificate_provider_static_data_create(
     const char* root_certificate, grpc_tls_identity_pairs* pem_key_cert_pairs);
 
 /**
+ * Creates a grpc_tls_certificate_provider that will watch the credential
+ * changes on the file system. This provider will always return the up-to-date
+ * cert data for all the cert names callers set through
+ * |grpc_tls_credentials_options|. Note that this API only supports one key-cert
+ * file and hence one set of identity key-cert pair, so SNI(Server Name
+ * Indication) is not supported.
+ * - private_key_path is the file path of the private key. This must be set if
+ *   |identity_certificate_path| is set. Otherwise, it could be null if no
+ *   identity credentials are needed.
+ * - identity_certificate_path is the file path of the identity certificate
+ *   chain. This must be set if |private_key_path| is set. Otherwise, it could
+ *   be null if no identity credentials are needed.
+ * - root_cert_path is the file path to the root certificate bundle. This
+ *   may be null if no root certs are needed.
+ * - refresh_interval_sec is the refreshing interval that we will check the
+ *   files for updates.
+ * It does not take ownership of parameters.
+ * It is used for experimental purpose for now and subject to change.
+ */
+GRPCAPI grpc_tls_certificate_provider*
+grpc_tls_certificate_provider_file_watcher_create(
+    const char* private_key_path, const char* identity_certificate_path,
+    const char* root_cert_path, unsigned int refresh_interval_sec);
+
+/**
  * Releases a grpc_tls_certificate_provider object. The creator of the
  * grpc_tls_certificate_provider object is responsible for its release. It is
  * used for experimental purpose for now and subject to change.
@@ -917,6 +950,8 @@ typedef void (*grpc_tls_on_server_authorization_check_done_cb)(
    - target_name is the name of an endpoint the channel is connecting to.
    - peer_cert represents a complete certificate chain including both
      signing and leaf certificates.
+   - \a subject_alternative_names is an array of size
+     \a subject_alternative_names_size consisting of pointers to strings.
    - status and error_details contain information
      about errors occurred when a server authorization check request is
      scheduled/cancelled.
@@ -936,6 +971,8 @@ struct grpc_tls_server_authorization_check_arg {
   const char* target_name;
   const char* peer_cert;
   const char* peer_cert_full_chain;
+  char** subject_alternative_names;
+  size_t subject_alternative_names_size;
   grpc_status_code status;
   grpc_tls_error_details* error_details;
   grpc_tls_server_authorization_check_config* config;
@@ -1009,10 +1046,17 @@ grpc_channel_credentials* grpc_insecure_credentials_create();
 /**
  * EXPERIMENTAL API - Subject to change
  *
- * This method creates an XDS channel credentials object.
+ * This method creates an insecure server credentials object.
+ */
+grpc_server_credentials* grpc_insecure_server_credentials_create();
+
+/**
+ * EXPERIMENTAL API - Subject to change
+ *
+ * This method creates an xDS channel credentials object.
  *
- * Creating a channel with credentials of this type indicates that an xDS
- * channel should get credentials configuration from the xDS control plane.
+ * Creating a channel with credentials of this type indicates that the channel
+ * should get credentials configuration from the xDS control plane.
  *
  * \a fallback_credentials are used if the channel target does not have the
  * 'xds:///' scheme or if the xDS control plane does not provide information on
@@ -1022,6 +1066,20 @@ grpc_channel_credentials* grpc_insecure_credentials_create();
 GRPCAPI grpc_channel_credentials* grpc_xds_credentials_create(
     grpc_channel_credentials* fallback_credentials);
 
+/**
+ * EXPERIMENTAL API - Subject to change
+ *
+ * This method creates an xDS server credentials object.
+ *
+ * \a fallback_credentials are used if the xDS control plane does not provide
+ * information on how to fetch credentials dynamically.
+ *
+ * Does NOT take ownership of the \a fallback_credentials. (Internally takes
+ * a ref to the object.)
+ */
+GRPCAPI grpc_server_credentials* grpc_xds_server_credentials_create(
+    grpc_server_credentials* fallback_credentials);
+
 #ifdef __cplusplus
 }
 #endif
index c016b90..36c76ab 100644 (file)
@@ -22,6 +22,8 @@
 /** Win32 variant of atm_platform.h */
 #include <grpc/impl/codegen/port_platform.h>
 
+#ifdef GPR_WINDOWS
+
 typedef intptr_t gpr_atm;
 #define GPR_ATM_MAX INTPTR_MAX
 #define GPR_ATM_MIN INTPTR_MIN
@@ -125,4 +127,6 @@ static __inline gpr_atm gpr_atm_full_xchg(gpr_atm* p, gpr_atm n) {
   return (gpr_atm)InterlockedExchangePointer((PVOID*)p, (PVOID)n);
 }
 
+#endif /* GPR_WINDOWS */
+
 #endif /* GRPC_IMPL_CODEGEN_ATM_WINDOWS_H */
index 1247906..0413729 100644 (file)
@@ -53,7 +53,7 @@ GRPCAPI grpc_byte_buffer* grpc_byte_buffer_copy(grpc_byte_buffer* bb);
 GRPCAPI size_t grpc_byte_buffer_length(grpc_byte_buffer* bb);
 
 /** Destroys \a byte_buffer deallocating all its memory. */
-GRPCAPI void grpc_byte_buffer_destroy(grpc_byte_buffer* byte_buffer);
+GRPCAPI void grpc_byte_buffer_destroy(grpc_byte_buffer* bb);
 
 /** Reader for byte buffers. Iterates over slices in the byte buffer */
 struct grpc_byte_buffer_reader;
index 379a50f..d67a9e9 100644 (file)
@@ -462,7 +462,7 @@ typedef enum grpc_call_error {
 
 /** Default send/receive message size limits in bytes. -1 for unlimited. */
 /** TODO(roth) Make this match the default receive limit after next release */
-#define GRPC_DEFAULT_MAX_SEND_MESSAGE_LENGTH -1
+#define GRPC_DEFAULT_MAX_SEND_MESSAGE_LENGTH (-1)
 #define GRPC_DEFAULT_MAX_RECV_MESSAGE_LENGTH (4 * 1024 * 1024)
 
 /** Write Flags: */
index ad7f024..9dd3a51 100644 (file)
@@ -46,8 +46,6 @@ typedef enum gpr_log_severity {
   GPR_LOG_SEVERITY_ERROR
 } gpr_log_severity;
 
-#define GPR_LOG_VERBOSITY_UNSET -1
-
 /** Returns a string representation of the log severity */
 GPRAPI const char* gpr_log_severity_string(gpr_log_severity severity);
 
index ba5d5ae..f2ff83b 100644 (file)
@@ -21,6 +21,8 @@
 
 #include <grpc/impl/codegen/port_platform.h>
 
+#ifdef GPR_WINDOWS
+
 #include <grpc/impl/codegen/sync_generic.h>
 
 typedef struct {
@@ -33,4 +35,6 @@ typedef CONDITION_VARIABLE gpr_cv;
 typedef INIT_ONCE gpr_once;
 #define GPR_ONCE_INIT INIT_ONCE_STATIC_INIT
 
+#endif /* GPR_WINDOWS */
+
 #endif /* GRPC_IMPL_CODEGEN_SYNC_WINDOWS_H */
index 3260019..d8c6b91 100644 (file)
@@ -59,7 +59,7 @@ GPRAPI void grpc_slice_buffer_swap(grpc_slice_buffer* a, grpc_slice_buffer* b);
 GPRAPI void grpc_slice_buffer_move_into(grpc_slice_buffer* src,
                                         grpc_slice_buffer* dst);
 /** remove n bytes from the end of a slice buffer */
-GPRAPI void grpc_slice_buffer_trim_end(grpc_slice_buffer* src, size_t n,
+GPRAPI void grpc_slice_buffer_trim_end(grpc_slice_buffer* sb, size_t n,
                                        grpc_slice_buffer* garbage);
 /** move the first n bytes of src into dst */
 GPRAPI void grpc_slice_buffer_move_first(grpc_slice_buffer* src, size_t n,
@@ -72,9 +72,9 @@ GPRAPI void grpc_slice_buffer_move_first_no_ref(grpc_slice_buffer* src,
 GPRAPI void grpc_slice_buffer_move_first_into_buffer(grpc_slice_buffer* src,
                                                      size_t n, void* dst);
 /** take the first slice in the slice buffer */
-GPRAPI grpc_slice grpc_slice_buffer_take_first(grpc_slice_buffer* src);
+GPRAPI grpc_slice grpc_slice_buffer_take_first(grpc_slice_buffer* sb);
 /** undo the above with (a possibly different) \a slice */
-GPRAPI void grpc_slice_buffer_undo_take_first(grpc_slice_buffer* src,
+GPRAPI void grpc_slice_buffer_undo_take_first(grpc_slice_buffer* sb,
                                               grpc_slice slice);
 
 #ifdef __cplusplus
index da820de..f617322 100644 (file)
@@ -94,12 +94,12 @@ GPRAPI void gpr_cv_broadcast(gpr_cv* cv);
    GPR_ONCE_INIT.  e.g.,
      static gpr_once once_var = GPR_ONCE_INIT;     */
 
-/** Ensure that (*init_routine)() has been called exactly once (for the
+/** Ensure that (*init_function)() has been called exactly once (for the
    specified gpr_once instance) and then return.
    If multiple threads call gpr_once() on the same gpr_once instance, one of
-   them will call (*init_routine)(), and the others will block until that call
+   them will call (*init_function)(), and the others will block until that call
    finishes.*/
-GPRAPI void gpr_once_init(gpr_once* once, void (*init_routine)(void));
+GPRAPI void gpr_once_init(gpr_once* once, void (*init_function)(void));
 
 /** --- One-time event notification ---
 
index 550ffc2..44aead5 100644 (file)
@@ -51,7 +51,7 @@ GPRAPI gpr_timespec gpr_now(gpr_clock_type clock);
 
 /** Convert a timespec from one clock to another */
 GPRAPI gpr_timespec gpr_convert_clock_type(gpr_timespec t,
-                                           gpr_clock_type target_clock);
+                                           gpr_clock_type clock_type);
 
 /** Return -ve, 0, or +ve according to whether a < b, a == b, or a > b
    respectively.  */
@@ -66,12 +66,12 @@ GPRAPI gpr_timespec gpr_time_sub(gpr_timespec a, gpr_timespec b);
 
 /** Return a timespec representing a given number of time units. INT64_MIN is
    interpreted as gpr_inf_past, and INT64_MAX as gpr_inf_future.  */
-GPRAPI gpr_timespec gpr_time_from_micros(int64_t x, gpr_clock_type clock_type);
-GPRAPI gpr_timespec gpr_time_from_nanos(int64_t x, gpr_clock_type clock_type);
-GPRAPI gpr_timespec gpr_time_from_millis(int64_t x, gpr_clock_type clock_type);
-GPRAPI gpr_timespec gpr_time_from_seconds(int64_t x, gpr_clock_type clock_type);
-GPRAPI gpr_timespec gpr_time_from_minutes(int64_t x, gpr_clock_type clock_type);
-GPRAPI gpr_timespec gpr_time_from_hours(int64_t x, gpr_clock_type clock_type);
+GPRAPI gpr_timespec gpr_time_from_micros(int64_t us, gpr_clock_type clock_type);
+GPRAPI gpr_timespec gpr_time_from_nanos(int64_t ns, gpr_clock_type clock_type);
+GPRAPI gpr_timespec gpr_time_from_millis(int64_t ms, gpr_clock_type clock_type);
+GPRAPI gpr_timespec gpr_time_from_seconds(int64_t s, gpr_clock_type clock_type);
+GPRAPI gpr_timespec gpr_time_from_minutes(int64_t m, gpr_clock_type clock_type);
+GPRAPI gpr_timespec gpr_time_from_hours(int64_t h, gpr_clock_type clock_type);
 
 GPRAPI int32_t gpr_time_to_millis(gpr_timespec timespec);
 
index 96add23..1405590 100644 (file)
@@ -38,7 +38,7 @@ class Alarm : private ::grpc::GrpcLibraryCodegen {
   Alarm();
 
   /// Destroy the given completion queue alarm, cancelling it in the process.
-  ~Alarm();
+  ~Alarm() override;
 
   /// DEPRECATED: Create and set a completion queue alarm instance associated to
   /// \a cq.
@@ -66,8 +66,8 @@ class Alarm : private ::grpc::GrpcLibraryCodegen {
   Alarm& operator=(const Alarm&) = delete;
 
   /// Alarms are movable.
-  Alarm(Alarm&& rhs) : alarm_(rhs.alarm_) { rhs.alarm_ = nullptr; }
-  Alarm& operator=(Alarm&& rhs) {
+  Alarm(Alarm&& rhs) noexcept : alarm_(rhs.alarm_) { rhs.alarm_ = nullptr; }
+  Alarm& operator=(Alarm&& rhs) noexcept {
     alarm_ = rhs.alarm_;
     rhs.alarm_ = nullptr;
     return *this;
index 88f016c..5e67c64 100644 (file)
@@ -56,7 +56,7 @@ class Channel final : public ::grpc::ChannelInterface,
                       public std::enable_shared_from_this<Channel>,
                       private ::grpc::GrpcLibraryCodegen {
  public:
-  ~Channel();
+  ~Channel() override;
 
   /// Get the current channel state. If the channel is in IDLE and
   /// \a try_to_connect is set to true, try to connect.
index a8836fd..4347745 100644 (file)
@@ -196,10 +196,14 @@ class ByteBuffer final {
 
   class ByteBufferPointer {
    public:
+    /* NOLINTNEXTLINE(google-explicit-constructor) */
     ByteBufferPointer(const ByteBuffer* b)
         : bbuf_(const_cast<ByteBuffer*>(b)) {}
+    /* NOLINTNEXTLINE(google-explicit-constructor) */
     operator ByteBuffer*() { return bbuf_; }
+    /* NOLINTNEXTLINE(google-explicit-constructor) */
     operator grpc_byte_buffer*() { return bbuf_->buffer_; }
+    /* NOLINTNEXTLINE(google-explicit-constructor) */
     operator grpc_byte_buffer**() { return &bbuf_->buffer_; }
 
    private:
index 88cfde6..370d519 100644 (file)
@@ -58,7 +58,7 @@ inline grpc_metadata* FillMetadataArray(
     return nullptr;
   }
   grpc_metadata* metadata_array =
-      (grpc_metadata*)(g_core_codegen_interface->gpr_malloc(
+      static_cast<grpc_metadata*>(g_core_codegen_interface->gpr_malloc(
           (*metadata_count) * sizeof(grpc_metadata)));
   size_t i = 0;
   for (auto iter = metadata.cbegin(); iter != metadata.cend(); ++iter, ++i) {
@@ -234,7 +234,7 @@ class CallOpSendInitialMetadata {
     grpc_op* op = &ops[(*nops)++];
     op->op = GRPC_OP_SEND_INITIAL_METADATA;
     op->flags = flags_;
-    op->reserved = NULL;
+    op->reserved = nullptr;
     initial_metadata_ =
         FillMetadataArray(*metadata_map_, &initial_metadata_count_, "");
     op->data.send_initial_metadata.count = initial_metadata_count_;
@@ -318,7 +318,7 @@ class CallOpSendMessage {
     grpc_op* op = &ops[(*nops)++];
     op->op = GRPC_OP_SEND_MESSAGE;
     op->flags = write_options_.flags();
-    op->reserved = NULL;
+    op->reserved = nullptr;
     op->data.send_message.send_message = send_buf_.c_buffer();
     // Flags are per-message: clear them after use.
     write_options_.Clear();
@@ -436,7 +436,7 @@ class CallOpRecvMessage {
     grpc_op* op = &ops[(*nops)++];
     op->op = GRPC_OP_RECV_MESSAGE;
     op->flags = 0;
-    op->reserved = NULL;
+    op->reserved = nullptr;
     op->data.recv_message.recv_message = recv_buf_.c_buffer_ptr();
   }
 
@@ -512,7 +512,7 @@ class DeserializeFunc {
 template <class R>
 class DeserializeFuncType final : public DeserializeFunc {
  public:
-  DeserializeFuncType(R* message) : message_(message) {}
+  explicit DeserializeFuncType(R* message) : message_(message) {}
   Status Deserialize(ByteBuffer* buf) override {
     return SerializationTraits<R>::Deserialize(buf->bbuf_ptr(), message_);
   }
@@ -545,7 +545,7 @@ class CallOpGenericRecvMessage {
     grpc_op* op = &ops[(*nops)++];
     op->op = GRPC_OP_RECV_MESSAGE;
     op->flags = 0;
-    op->reserved = NULL;
+    op->reserved = nullptr;
     op->data.recv_message.recv_message = recv_buf_.c_buffer_ptr();
   }
 
@@ -628,7 +628,7 @@ class CallOpClientSendClose {
     grpc_op* op = &ops[(*nops)++];
     op->op = GRPC_OP_SEND_CLOSE_FROM_CLIENT;
     op->flags = 0;
-    op->reserved = NULL;
+    op->reserved = nullptr;
   }
   void FinishOp(bool* /*status*/) { send_ = false; }
 
@@ -680,7 +680,7 @@ class CallOpServerSendStatus {
     op->data.send_status_from_server.status_details =
         send_error_message_.empty() ? nullptr : &error_message_slice_;
     op->flags = 0;
-    op->reserved = NULL;
+    op->reserved = nullptr;
   }
 
   void FinishOp(bool* /*status*/) {
@@ -734,7 +734,7 @@ class CallOpRecvInitialMetadata {
     op->op = GRPC_OP_RECV_INITIAL_METADATA;
     op->data.recv_initial_metadata.recv_initial_metadata = metadata_map_->arr();
     op->flags = 0;
-    op->reserved = NULL;
+    op->reserved = nullptr;
   }
 
   void FinishOp(bool* /*status*/) {
@@ -788,7 +788,7 @@ class CallOpClientRecvStatus {
     op->data.recv_status_on_client.status_details = &error_message_;
     op->data.recv_status_on_client.error_string = &debug_error_string_;
     op->flags = 0;
-    op->reserved = NULL;
+    op->reserved = nullptr;
   }
 
   void FinishOp(bool* /*status*/) {
@@ -806,7 +806,8 @@ class CallOpClientRecvStatus {
                  metadata_map_->GetBinaryErrorDetails());
       if (debug_error_string_ != nullptr) {
         client_context_->set_debug_error_string(debug_error_string_);
-        g_core_codegen_interface->gpr_free((void*)debug_error_string_);
+        g_core_codegen_interface->gpr_free(
+            const_cast<char*>(debug_error_string_));
       }
     }
     // TODO(soheil): Find callers that set debug string even for status OK,
index aa3bd26..086a179 100644 (file)
@@ -24,6 +24,7 @@
 #include <grpc/impl/codegen/grpc_types.h>
 #include <grpcpp/impl/codegen/call.h>
 #include <grpcpp/impl/codegen/channel_interface.h>
+#include <grpcpp/impl/codegen/completion_queue_tag.h>
 #include <grpcpp/impl/codegen/config.h>
 #include <grpcpp/impl/codegen/core_codegen_interface.h>
 #include <grpcpp/impl/codegen/status.h>
@@ -189,6 +190,7 @@ class CallbackWithSuccessTag
   void force_run(bool ok) { Run(ok); }
 
   /// check if this tag is currently set
+  /* NOLINTNEXTLINE(google-explicit-constructor) */
   operator bool() const { return call_ != nullptr; }
 
  private:
index f2ddaba..77bc885 100644 (file)
@@ -251,7 +251,7 @@ class ClientBidiReactor : public internal::ClientReactor {
   ///                not deleted or modified until OnWriteDone is called.
   /// \param[in] options The WriteOptions to use for writing this message
   void StartWrite(const Request* req, ::grpc::WriteOptions options) {
-    stream_->Write(req, std::move(options));
+    stream_->Write(req, options);
   }
 
   /// Initiate/post a write operation with specified options and an indication
@@ -264,7 +264,7 @@ class ClientBidiReactor : public internal::ClientReactor {
   ///                not deleted or modified until OnWriteDone is called.
   /// \param[in] options The WriteOptions to use for writing this message
   void StartWriteLast(const Request* req, ::grpc::WriteOptions options) {
-    StartWrite(req, std::move(options.set_last_message()));
+    StartWrite(req, options.set_last_message());
   }
 
   /// Indicate that the RPC will have no more write operations. This can only be
@@ -391,10 +391,10 @@ class ClientWriteReactor : public internal::ClientReactor {
     StartWrite(req, ::grpc::WriteOptions());
   }
   void StartWrite(const Request* req, ::grpc::WriteOptions options) {
-    writer_->Write(req, std::move(options));
+    writer_->Write(req, options);
   }
   void StartWriteLast(const Request* req, ::grpc::WriteOptions options) {
-    StartWrite(req, std::move(options.set_last_message()));
+    StartWrite(req, options.set_last_message());
   }
   void StartWritesDone() { writer_->WritesDone(); }
 
index 8a0bd62..acf1d85 100644 (file)
@@ -311,7 +311,7 @@ class ClientContext {
   ///
   /// \see grpc::AuthContext.
   std::shared_ptr<const grpc::AuthContext> auth_context() const {
-    if (auth_context_.get() == nullptr) {
+    if (auth_context_ == nullptr) {
       auth_context_ = grpc::CreateAuthContext(call_);
     }
     return auth_context_;
index b2430ad..d41ea1a 100644 (file)
@@ -20,6 +20,7 @@
 #define GRPCPP_IMPL_CODEGEN_CLIENT_UNARY_CALL_H
 
 #include <grpcpp/impl/codegen/call.h>
+#include <grpcpp/impl/codegen/call_op_set.h>
 #include <grpcpp/impl/codegen/channel_interface.h>
 #include <grpcpp/impl/codegen/config.h>
 #include <grpcpp/impl/codegen/core_codegen_interface.h>
index 0234951..f6589f0 100644 (file)
@@ -114,7 +114,7 @@ class CompletionQueue : private ::grpc::GrpcLibraryCodegen {
   explicit CompletionQueue(grpc_completion_queue* take);
 
   /// Destructor. Destroys the owned wrapped completion queue / instance.
-  ~CompletionQueue() {
+  ~CompletionQueue() override {
     ::grpc::g_core_codegen_interface->grpc_completion_queue_destroy(cq_);
   }
 
@@ -243,11 +243,11 @@ class CompletionQueue : private ::grpc::GrpcLibraryCodegen {
 
  protected:
   /// Private constructor of CompletionQueue only visible to friend classes
-  CompletionQueue(const grpc_completion_queue_attributes& attributes) {
+  explicit CompletionQueue(const grpc_completion_queue_attributes& attributes) {
     cq_ = ::grpc::g_core_codegen_interface->grpc_completion_queue_create(
         ::grpc::g_core_codegen_interface->grpc_completion_queue_factory_lookup(
             &attributes),
-        &attributes, NULL);
+        &attributes, nullptr);
     InitialAvalanching();  // reserve this for the future shutdown
   }
 
@@ -301,7 +301,7 @@ class CompletionQueue : private ::grpc::GrpcLibraryCodegen {
   /// initialized, it must be flushed on the same thread.
   class CompletionQueueTLSCache {
    public:
-    CompletionQueueTLSCache(CompletionQueue* cq);
+    explicit CompletionQueueTLSCache(CompletionQueue* cq);
     ~CompletionQueueTLSCache();
     bool Flush(void** tag, bool* ok);
 
index 7c398d1..0a8a9c1 100644 (file)
@@ -36,8 +36,8 @@ namespace grpc {
 // Using grpc::string and grpc::to_string is discouraged in favor of
 // std::string and std::to_string. This is only for legacy code using
 // them explictly.
-using std::string;     // deprecated
-using std::to_string;  // deprecated
+using std::string;     // deprecated // NOLINT(misc-unused-using-decls)
+using std::to_string;  // deprecated // NOLINT(misc-unused-using-decls)
 
 }  // namespace grpc
 
index c4012fb..49db4c5 100644 (file)
@@ -65,6 +65,7 @@
 
 #ifndef GRPC_CUSTOM_JSONUTIL
 #include <google/protobuf/util/json_util.h>
+#include <google/protobuf/util/type_resolver_util.h>
 #define GRPC_CUSTOM_JSONUTIL ::google::protobuf::util
 #define GRPC_CUSTOM_UTIL_STATUS ::google::protobuf::util::Status
 #endif
@@ -90,6 +91,7 @@ namespace util {
 typedef GRPC_CUSTOM_UTIL_STATUS Status;
 }  // namespace util
 
+// NOLINTNEXTLINE(misc-unused-alias-decls)
 namespace json = GRPC_CUSTOM_JSONUTIL;
 
 namespace io {
index 50c8da4..df2a03c 100644 (file)
@@ -31,10 +31,9 @@ namespace grpc {
 /// Implementation of the core codegen interface.
 class CoreCodegen final : public CoreCodegenInterface {
  private:
-  virtual const grpc_completion_queue_factory*
-  grpc_completion_queue_factory_lookup(
+  const grpc_completion_queue_factory* grpc_completion_queue_factory_lookup(
       const grpc_completion_queue_attributes* attributes) override;
-  virtual grpc_completion_queue* grpc_completion_queue_create(
+  grpc_completion_queue* grpc_completion_queue_create(
       const grpc_completion_queue_factory* factory,
       const grpc_completion_queue_attributes* attributes,
       void* reserved) override;
@@ -115,8 +114,8 @@ class CoreCodegen final : public CoreCodegenInterface {
   gpr_timespec gpr_inf_future(gpr_clock_type type) override;
   gpr_timespec gpr_time_0(gpr_clock_type type) override;
 
-  virtual const Status& ok() override;
-  virtual const Status& cancelled() override;
+  const Status& ok() override;
+  const Status& cancelled() override;
 
   void assert_fail(const char* failed_assertion, const char* file,
                    int line) override;
index 1a3bbd3..0479567 100644 (file)
 #ifndef GRPCPP_IMPL_CODEGEN_DELEGATING_CHANNEL_H
 #define GRPCPP_IMPL_CODEGEN_DELEGATING_CHANNEL_H
 
+#include <memory>
+
+#include <grpcpp/impl/codegen/channel_interface.h>
+
 namespace grpc {
 namespace experimental {
 
 class DelegatingChannel : public ::grpc::ChannelInterface {
  public:
-  virtual ~DelegatingChannel() {}
+  ~DelegatingChannel() override {}
 
-  DelegatingChannel(std::shared_ptr<::grpc::ChannelInterface> delegate_channel)
+  explicit DelegatingChannel(
+      std::shared_ptr<::grpc::ChannelInterface> delegate_channel)
       : delegate_channel_(delegate_channel) {}
 
   grpc_connectivity_state GetState(bool try_to_connect) override {
index 17c904d..660d6d0 100644 (file)
@@ -37,7 +37,8 @@ extern GrpcLibraryInterface* g_glip;
 /// Classes that require gRPC to be initialized should inherit from this class.
 class GrpcLibraryCodegen {
  public:
-  GrpcLibraryCodegen(bool call_grpc_init = true) : grpc_init_called_(false) {
+  explicit GrpcLibraryCodegen(bool call_grpc_init = true)
+      : grpc_init_called_(false) {
     if (call_grpc_init) {
       GPR_CODEGEN_ASSERT(g_glip &&
                          "gRPC library not initialized. See "
index c729970..e3a4c8e 100644 (file)
@@ -34,7 +34,7 @@ class InterceptorBatchMethodsImpl;
 /// see the RPC.
 class InterceptedChannel : public ChannelInterface {
  public:
-  virtual ~InterceptedChannel() { channel_ = nullptr; }
+  ~InterceptedChannel() override { channel_ = nullptr; }
 
   /// Get the current channel state. If the channel is in IDLE and
   /// \a try_to_connect is set to true, try to connect.
index b6a9fc3..520d981 100644 (file)
@@ -45,7 +45,7 @@ class InterceptorBatchMethodsImpl
     }
   }
 
-  ~InterceptorBatchMethodsImpl() {}
+  ~InterceptorBatchMethodsImpl() override {}
 
   bool QueryInterceptionHookPoint(
       experimental::InterceptionHookPoints type) override {
@@ -223,7 +223,7 @@ class InterceptorBatchMethodsImpl
   bool InterceptorsListEmpty() {
     auto* client_rpc_info = call_->client_rpc_info();
     if (client_rpc_info != nullptr) {
-      if (client_rpc_info->interceptors_.size() == 0) {
+      if (client_rpc_info->interceptors_.empty()) {
         return true;
       } else {
         return false;
@@ -231,8 +231,7 @@ class InterceptorBatchMethodsImpl
     }
 
     auto* server_rpc_info = call_->server_rpc_info();
-    if (server_rpc_info == nullptr ||
-        server_rpc_info->interceptors_.size() == 0) {
+    if (server_rpc_info == nullptr || server_rpc_info->interceptors_.empty()) {
       return true;
     }
     return false;
@@ -247,7 +246,7 @@ class InterceptorBatchMethodsImpl
     GPR_CODEGEN_ASSERT(ops_);
     auto* client_rpc_info = call_->client_rpc_info();
     if (client_rpc_info != nullptr) {
-      if (client_rpc_info->interceptors_.size() == 0) {
+      if (client_rpc_info->interceptors_.empty()) {
         return true;
       } else {
         RunClientInterceptors();
@@ -256,8 +255,7 @@ class InterceptorBatchMethodsImpl
     }
 
     auto* server_rpc_info = call_->server_rpc_info();
-    if (server_rpc_info == nullptr ||
-        server_rpc_info->interceptors_.size() == 0) {
+    if (server_rpc_info == nullptr || server_rpc_info->interceptors_.empty()) {
       return true;
     }
     RunServerInterceptors();
@@ -273,8 +271,7 @@ class InterceptorBatchMethodsImpl
     GPR_CODEGEN_ASSERT(reverse_ == true);
     GPR_CODEGEN_ASSERT(call_->client_rpc_info() == nullptr);
     auto* server_rpc_info = call_->server_rpc_info();
-    if (server_rpc_info == nullptr ||
-        server_rpc_info->interceptors_.size() == 0) {
+    if (server_rpc_info == nullptr || server_rpc_info->interceptors_.empty()) {
       return true;
     }
     callback_ = std::move(f);
@@ -489,7 +486,6 @@ class CancelInterceptorBatchMethods
     GPR_CODEGEN_ASSERT(false &&
                        "It is illegal to call ModifySendStatus on a method "
                        "which has a Cancel notification");
-    return;
   }
 
   std::multimap<std::string, std::string>* GetSendTrailingMetadata() override {
index 604de89..963423d 100644 (file)
@@ -261,7 +261,7 @@ class ServerStreamingHandler : public ::grpc::internal::MethodHandler {
 template <class Streamer, bool WriteNeeded>
 class TemplatedBidiStreamingHandler : public ::grpc::internal::MethodHandler {
  public:
-  TemplatedBidiStreamingHandler(
+  explicit TemplatedBidiStreamingHandler(
       std::function<::grpc::Status(::grpc::ServerContext*, Streamer*)> func)
       : func_(func), write_needed_(WriteNeeded) {}
 
similarity index 62%
rename from test/core/util/debugger_macros.h
rename to include/grpcpp/impl/codegen/method_handler_impl.h
index 71228c6..cc88a13 100644 (file)
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2016 gRPC authors.
+ * Copyright 2018 gRPC authors.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
  *
  */
 
-#ifndef GRPC_TEST_CORE_UTIL_DEBUGGER_MACROS_H
-#define GRPC_TEST_CORE_UTIL_DEBUGGER_MACROS_H
+#ifndef GRPCPP_IMPL_CODEGEN_METHOD_HANDLER_IMPL_H
+#define GRPCPP_IMPL_CODEGEN_METHOD_HANDLER_IMPL_H
 
-#include "src/core/ext/transport/chttp2/transport/internal.h"
-#include "src/core/lib/surface/call.h"
-
-grpc_chttp2_stream* grpc_chttp2_stream_from_call(grpc_call* call);
-
-#endif /* GRPC_TEST_CORE_UTIL_DEBUGGER_MACROS_H */
+#endif  // GRPCPP_IMPL_CODEGEN_METHOD_HANDLER_IMPL_H
index 4874712..d25b79a 100644 (file)
@@ -59,7 +59,7 @@ class ProtoBufferReader : public ::grpc::protobuf::io::ZeroCopyInputStream {
     }
   }
 
-  ~ProtoBufferReader() {
+  ~ProtoBufferReader() override {
     if (status_.ok()) {
       g_core_codegen_interface->grpc_byte_buffer_reader_destroy(&reader_);
     }
@@ -76,7 +76,7 @@ class ProtoBufferReader : public ::grpc::protobuf::io::ZeroCopyInputStream {
       *data = GRPC_SLICE_START_PTR(*slice_) + GRPC_SLICE_LENGTH(*slice_) -
               backup_count_;
       GPR_CODEGEN_ASSERT(backup_count_ <= INT_MAX);
-      *size = (int)backup_count_;
+      *size = static_cast<int>(backup_count_);
       backup_count_ = 0;
       return true;
     }
@@ -88,7 +88,7 @@ class ProtoBufferReader : public ::grpc::protobuf::io::ZeroCopyInputStream {
     *data = GRPC_SLICE_START_PTR(*slice_);
     // On win x64, int is only 32bit
     GPR_CODEGEN_ASSERT(GRPC_SLICE_LENGTH(*slice_) <= INT_MAX);
-    byte_count_ += * size = (int)GRPC_SLICE_LENGTH(*slice_);
+    byte_count_ += * size = static_cast<int>(GRPC_SLICE_LENGTH(*slice_));
     return true;
   }
 
index 0af4616..cd9d70c 100644 (file)
@@ -65,12 +65,12 @@ class ProtoBufferWriter : public ::grpc::protobuf::io::ZeroCopyOutputStream {
     GPR_CODEGEN_ASSERT(!byte_buffer->Valid());
     /// Create an empty raw byte buffer and look at its underlying slice buffer
     grpc_byte_buffer* bp =
-        g_core_codegen_interface->grpc_raw_byte_buffer_create(NULL, 0);
+        g_core_codegen_interface->grpc_raw_byte_buffer_create(nullptr, 0);
     byte_buffer->set_buffer(bp);
     slice_buffer_ = &bp->data.raw.slice_buffer;
   }
 
-  ~ProtoBufferWriter() {
+  ~ProtoBufferWriter() override {
     if (have_backup_) {
       g_core_codegen_interface->grpc_slice_unref(backup_slice_);
     }
@@ -107,7 +107,7 @@ class ProtoBufferWriter : public ::grpc::protobuf::io::ZeroCopyOutputStream {
     *data = GRPC_SLICE_START_PTR(slice_);
     // On win x64, int is only 32bit
     GPR_CODEGEN_ASSERT(GRPC_SLICE_LENGTH(slice_) <= INT_MAX);
-    byte_count_ += * size = (int)GRPC_SLICE_LENGTH(slice_);
+    byte_count_ += * size = static_cast<int>(GRPC_SLICE_LENGTH(slice_));
     g_core_codegen_interface->grpc_slice_buffer_add(slice_buffer_, slice_);
     return true;
   }
@@ -122,7 +122,7 @@ class ProtoBufferWriter : public ::grpc::protobuf::io::ZeroCopyOutputStream {
     /// 4. Mark that we still have the remaining part (for later use/unref)
     GPR_CODEGEN_ASSERT(count <= static_cast<int>(GRPC_SLICE_LENGTH(slice_)));
     g_core_codegen_interface->grpc_slice_buffer_pop(slice_buffer_);
-    if ((size_t)count == GRPC_SLICE_LENGTH(slice_)) {
+    if (static_cast<size_t>(count) == GRPC_SLICE_LENGTH(slice_)) {
       backup_slice_ = slice_;
     } else {
       backup_slice_ = g_core_codegen_interface->grpc_slice_split_tail(
@@ -133,7 +133,7 @@ class ProtoBufferWriter : public ::grpc::protobuf::io::ZeroCopyOutputStream {
     // on a following Next() call, a reference will be returned to this slice
     // via GRPC_SLICE_START_PTR, which will not be an address held by
     // slice_buffer_.
-    have_backup_ = backup_slice_.refcount != NULL;
+    have_backup_ = backup_slice_.refcount != nullptr;
     byte_count_ -= count;
   }
 
index 2df4904..7f5c6e9 100644 (file)
@@ -50,7 +50,7 @@ Status GenericSerialize(const grpc::protobuf::MessageLite& msg, ByteBuffer* bb,
                 "::protobuf::io::ZeroCopyOutputStream");
   *own_buffer = true;
   int byte_size = static_cast<int>(msg.ByteSizeLong());
-  if ((size_t)byte_size <= GRPC_SLICE_INLINED_SIZE) {
+  if (static_cast<size_t>(byte_size) <= GRPC_SLICE_INLINED_SIZE) {
     Slice slice(byte_size);
     // We serialize directly into the allocated slices memory
     GPR_CODEGEN_ASSERT(slice.end() == msg.SerializeWithCachedSizesToArray(
index 9dcde95..394a29b 100644 (file)
@@ -36,7 +36,7 @@ class RpcMethod {
   };
 
   RpcMethod(const char* name, RpcType type)
-      : name_(name), method_type_(type), channel_tag_(NULL) {}
+      : name_(name), method_type_(type), channel_tag_(nullptr) {}
 
   RpcMethod(const char* name, RpcType type,
             const std::shared_ptr<ChannelInterface>& channel)
index 08d1666..9dda984 100644 (file)
@@ -190,7 +190,7 @@ class ServerBidiReactor;
 // the API.
 class ServerCallbackUnary : public internal::ServerCallbackCall {
  public:
-  virtual ~ServerCallbackUnary() {}
+  ~ServerCallbackUnary() override {}
   virtual void Finish(::grpc::Status s) = 0;
   virtual void SendInitialMetadata() = 0;
 
@@ -206,7 +206,7 @@ class ServerCallbackUnary : public internal::ServerCallbackCall {
 template <class Request>
 class ServerCallbackReader : public internal::ServerCallbackCall {
  public:
-  virtual ~ServerCallbackReader() {}
+  ~ServerCallbackReader() override {}
   virtual void Finish(::grpc::Status s) = 0;
   virtual void SendInitialMetadata() = 0;
   virtual void Read(Request* msg) = 0;
@@ -220,7 +220,7 @@ class ServerCallbackReader : public internal::ServerCallbackCall {
 template <class Response>
 class ServerCallbackWriter : public internal::ServerCallbackCall {
  public:
-  virtual ~ServerCallbackWriter() {}
+  ~ServerCallbackWriter() override {}
 
   virtual void Finish(::grpc::Status s) = 0;
   virtual void SendInitialMetadata() = 0;
@@ -237,7 +237,7 @@ class ServerCallbackWriter : public internal::ServerCallbackCall {
 template <class Request, class Response>
 class ServerCallbackReaderWriter : public internal::ServerCallbackCall {
  public:
-  virtual ~ServerCallbackReaderWriter() {}
+  ~ServerCallbackReaderWriter() override {}
 
   virtual void Finish(::grpc::Status s) = 0;
   virtual void SendInitialMetadata() = 0;
@@ -268,7 +268,7 @@ class ServerBidiReactor : public internal::ServerReactor {
   // TODO(vjpai): Switch to default constructor and default initializer when
   //              gcc-4.x is no longer supported
   ServerBidiReactor() : stream_(nullptr) {}
-  ~ServerBidiReactor() = default;
+  ~ServerBidiReactor() override = default;
 
   /// Send any initial metadata stored in the RPC context. If not invoked,
   /// any initial metadata will be passed along with the first Write or the
@@ -328,11 +328,11 @@ class ServerBidiReactor : public internal::ServerReactor {
       stream = stream_.load(std::memory_order_relaxed);
       if (stream == nullptr) {
         backlog_.write_wanted = resp;
-        backlog_.write_options_wanted = std::move(options);
+        backlog_.write_options_wanted = options;
         return;
       }
     }
-    stream->Write(resp, std::move(options));
+    stream->Write(resp, options);
   }
 
   /// Initiate a write operation with specified options and final RPC Status,
@@ -358,12 +358,12 @@ class ServerBidiReactor : public internal::ServerReactor {
       if (stream == nullptr) {
         backlog_.write_and_finish_wanted = true;
         backlog_.write_wanted = resp;
-        backlog_.write_options_wanted = std::move(options);
+        backlog_.write_options_wanted = options;
         backlog_.status_wanted = std::move(s);
         return;
       }
     }
-    stream->WriteAndFinish(resp, std::move(options), std::move(s));
+    stream->WriteAndFinish(resp, options, std::move(s));
   }
 
   /// Inform system of a planned write operation with specified options, but
@@ -375,7 +375,7 @@ class ServerBidiReactor : public internal::ServerReactor {
   ///                 not deleted or modified until OnWriteDone is called.
   /// \param[in] options The WriteOptions to use for writing this message
   void StartWriteLast(const Response* resp, ::grpc::WriteOptions options) {
-    StartWrite(resp, std::move(options.set_last_message()));
+    StartWrite(resp, options.set_last_message());
   }
 
   /// Indicate that the stream is to be finished and the trailing metadata and
@@ -484,7 +484,7 @@ template <class Request>
 class ServerReadReactor : public internal::ServerReactor {
  public:
   ServerReadReactor() : reader_(nullptr) {}
-  ~ServerReadReactor() = default;
+  ~ServerReadReactor() override = default;
 
   /// The following operation initiations are exactly like ServerBidiReactor.
   void StartSendInitialMetadata() {
@@ -571,7 +571,7 @@ template <class Response>
 class ServerWriteReactor : public internal::ServerReactor {
  public:
   ServerWriteReactor() : writer_(nullptr) {}
-  ~ServerWriteReactor() = default;
+  ~ServerWriteReactor() override = default;
 
   /// The following operation initiations are exactly like ServerBidiReactor.
   void StartSendInitialMetadata() {
@@ -598,11 +598,11 @@ class ServerWriteReactor : public internal::ServerReactor {
       writer = writer_.load(std::memory_order_relaxed);
       if (writer == nullptr) {
         backlog_.write_wanted = resp;
-        backlog_.write_options_wanted = std::move(options);
+        backlog_.write_options_wanted = options;
         return;
       }
     }
-    writer->Write(resp, std::move(options));
+    writer->Write(resp, options);
   }
   void StartWriteAndFinish(const Response* resp, ::grpc::WriteOptions options,
                            ::grpc::Status s) {
@@ -614,15 +614,15 @@ class ServerWriteReactor : public internal::ServerReactor {
       if (writer == nullptr) {
         backlog_.write_and_finish_wanted = true;
         backlog_.write_wanted = resp;
-        backlog_.write_options_wanted = std::move(options);
+        backlog_.write_options_wanted = options;
         backlog_.status_wanted = std::move(s);
         return;
       }
     }
-    writer->WriteAndFinish(resp, std::move(options), std::move(s));
+    writer->WriteAndFinish(resp, options, std::move(s));
   }
   void StartWriteLast(const Response* resp, ::grpc::WriteOptions options) {
-    StartWrite(resp, std::move(options.set_last_message()));
+    StartWrite(resp, options.set_last_message());
   }
   void Finish(::grpc::Status s) {
     ServerCallbackWriter<Response>* writer =
@@ -688,7 +688,7 @@ class ServerWriteReactor : public internal::ServerReactor {
 class ServerUnaryReactor : public internal::ServerReactor {
  public:
   ServerUnaryReactor() : call_(nullptr) {}
-  ~ServerUnaryReactor() = default;
+  ~ServerUnaryReactor() override = default;
 
   /// StartSendInitialMetadata is exactly like ServerBidiReactor.
   void StartSendInitialMetadata() {
index 9cee8e9..4815cb4 100644 (file)
@@ -53,7 +53,7 @@ class CallbackUnaryHandler : public ::grpc::internal::MethodHandler {
         param.call->call(), sizeof(ServerCallbackUnaryImpl)))
         ServerCallbackUnaryImpl(
             static_cast<::grpc::CallbackServerContext*>(param.server_context),
-            param.call, allocator_state, std::move(param.call_requester));
+            param.call, allocator_state, param.call_requester);
     param.server_context->BeginCompletionOp(
         param.call, [call](bool) { call->MaybeDone(); }, call);
 
@@ -266,7 +266,7 @@ class CallbackClientStreamingHandler : public ::grpc::internal::MethodHandler {
         param.call->call(), sizeof(ServerCallbackReaderImpl)))
         ServerCallbackReaderImpl(
             static_cast<::grpc::CallbackServerContext*>(param.server_context),
-            param.call, std::move(param.call_requester));
+            param.call, param.call_requester);
     // Inlineable OnDone can be false in the CompletionOp callback because there
     // is no read reactor that has an inlineable OnDone; this only applies to
     // the DefaultReactor (which is unary).
@@ -453,7 +453,7 @@ class CallbackServerStreamingHandler : public ::grpc::internal::MethodHandler {
         ServerCallbackWriterImpl(
             static_cast<::grpc::CallbackServerContext*>(param.server_context),
             param.call, static_cast<RequestType*>(param.request),
-            std::move(param.call_requester));
+            param.call_requester);
     // Inlineable OnDone can be false in the CompletionOp callback because there
     // is no write reactor that has an inlineable OnDone; this only applies to
     // the DefaultReactor (which is unary).
@@ -673,7 +673,7 @@ class CallbackBidiHandler : public ::grpc::internal::MethodHandler {
         param.call->call(), sizeof(ServerCallbackReaderWriterImpl)))
         ServerCallbackReaderWriterImpl(
             static_cast<::grpc::CallbackServerContext*>(param.server_context),
-            param.call, std::move(param.call_requester));
+            param.call, param.call_requester);
     // Inlineable OnDone can be false in the CompletionOp callback because there
     // is no bidi reactor that has an inlineable OnDone; this only applies to
     // the DefaultReactor (which is unary).
index 56dcb61..5a62873 100644 (file)
@@ -265,7 +265,7 @@ class ServerContextBase {
   ///
   /// \see grpc::AuthContext.
   std::shared_ptr<const ::grpc::AuthContext> auth_context() const {
-    if (auth_context_.get() == nullptr) {
+    if (auth_context_ == nullptr) {
       auth_context_ = ::grpc::CreateAuthContext(call_.call);
     }
     return auth_context_;
@@ -415,7 +415,7 @@ class ServerContextBase {
       const char* method, ::grpc::internal::RpcMethod::RpcType type,
       const std::vector<std::unique_ptr<
           ::grpc::experimental::ServerInterceptorFactoryInterface>>& creators) {
-    if (creators.size() != 0) {
+    if (!creators.empty()) {
       rpc_info_ = new ::grpc::experimental::ServerRpcInfo(this, method, type);
       rpc_info_->RegisterInterceptors(creators);
     }
@@ -476,6 +476,7 @@ class ServerContextBase {
   };
 
   void SetupTestDefaultReactor(std::function<void(::grpc::Status)> func) {
+    // NOLINTNEXTLINE(modernize-make-unique)
     test_unary_.reset(new TestServerCallbackUnary(this, std::move(func)));
   }
   bool test_status_set() const {
index fef2dc7..c4398f4 100644 (file)
@@ -64,7 +64,7 @@ class ServerInterceptorFactoryInterface;
 
 class ServerInterface : public internal::CallHook {
  public:
-  virtual ~ServerInterface() {}
+  ~ServerInterface() override {}
 
   /// \a Shutdown does the following things:
   ///
@@ -186,8 +186,8 @@ class ServerInterface : public internal::CallHook {
 
   virtual grpc_server* server() = 0;
 
-  virtual void PerformOpsOnCall(internal::CallOpSetInterface* ops,
-                                internal::Call* call) = 0;
+  void PerformOpsOnCall(internal::CallOpSetInterface* ops,
+                        internal::Call* call) override = 0;
 
   class BaseAsyncRequest : public internal::CompletionQueueTag {
    public:
@@ -196,7 +196,7 @@ class ServerInterface : public internal::CallHook {
                      ::grpc::CompletionQueue* call_cq,
                      ::grpc::ServerCompletionQueue* notification_cq, void* tag,
                      bool delete_on_finalize);
-    virtual ~BaseAsyncRequest();
+    ~BaseAsyncRequest() override;
 
     bool FinalizeResult(void** tag, bool* status) override;
 
@@ -228,7 +228,7 @@ class ServerInterface : public internal::CallHook {
                            void* tag, const char* name,
                            internal::RpcMethod::RpcType type);
 
-    virtual bool FinalizeResult(void** tag, bool* status) override {
+    bool FinalizeResult(void** tag, bool* status) override {
       /* If we are done intercepting, then there is nothing more for us to do */
       if (done_intercepting_) {
         return BaseAsyncRequest::FinalizeResult(tag, status);
@@ -283,7 +283,7 @@ class ServerInterface : public internal::CallHook {
                    notification_cq);
     }
 
-    ~PayloadAsyncRequest() {
+    ~PayloadAsyncRequest() override {
       payload_.Release();  // We do not own the payload_
     }
 
index 30be904..57ca9f0 100644 (file)
@@ -91,7 +91,7 @@ class Service {
 
   bool has_generic_methods() const {
     for (const auto& method : methods_) {
-      if (method.get() == nullptr) {
+      if (method == nullptr) {
         return true;
       }
     }
index 1ef093e..ea55025 100644 (file)
@@ -49,7 +49,7 @@ class Slice final {
   Slice(grpc_slice slice, StealRef) : slice_(slice) {}
 
   /// Allocate a slice of specified size
-  Slice(size_t len)
+  explicit Slice(size_t len)
       : slice_(g_core_codegen_interface->grpc_slice_malloc(len)) {}
 
   /// Construct a slice from a copied buffer
@@ -58,6 +58,7 @@ class Slice final {
             reinterpret_cast<const char*>(buf), len)) {}
 
   /// Construct a slice from a copied string
+  /* NOLINTNEXTLINE(google-explicit-constructor) */
   Slice(const std::string& str)
       : slice_(g_core_codegen_interface->grpc_slice_from_copied_buffer(
             str.c_str(), str.length())) {}
index 6bdcfc1..153f371 100644 (file)
@@ -57,8 +57,10 @@ class string_ref {
     return *this;
   }
 
+  /* NOLINTNEXTLINE(google-explicit-constructor) */
   string_ref(const char* s) : data_(s), length_(strlen(s)) {}
   string_ref(const char* s, size_t l) : data_(s), length_(l) {}
+  /* NOLINTNEXTLINE(google-explicit-constructor) */
   string_ref(const std::string& s) : data_(s.data()), length_(s.length()) {}
 
   /// iterators
index a08e9cb..340a06f 100644 (file)
@@ -50,6 +50,7 @@ class TimePoint {
 template <>
 class TimePoint<gpr_timespec> {
  public:
+  /* NOLINTNEXTLINE(google-explicit-constructor) */
   TimePoint(const gpr_timespec& time) : time_(time) {}
   gpr_timespec raw_time() { return time_; }
 
@@ -73,6 +74,7 @@ std::chrono::system_clock::time_point Timespec2Timepoint(gpr_timespec t);
 template <>
 class TimePoint<std::chrono::system_clock::time_point> {
  public:
+  /* NOLINTNEXTLINE(google-explicit-constructor) */
   TimePoint(const std::chrono::system_clock::time_point& time) {
     Timepoint2Timespec(time, &time_);
   }
index b4e6b45..610df80 100644 (file)
@@ -30,7 +30,7 @@ class Service;
 
 class ServerInitializer {
  public:
-  ServerInitializer(grpc::Server* server) : server_(server) {}
+  explicit ServerInitializer(grpc::Server* server) : server_(server) {}
 
   bool RegisterService(std::shared_ptr<grpc::Service> service) {
     if (!server_->RegisterService(nullptr, service.get())) {
index e511213..374feae 100644 (file)
@@ -36,7 +36,7 @@ class ResourceQuota final : private ::grpc::GrpcLibraryCodegen {
   /// \param name - a unique name for this ResourceQuota.
   explicit ResourceQuota(const std::string& name);
   ResourceQuota();
-  ~ResourceQuota();
+  ~ResourceQuota() override;
 
   /// Resize this \a ResourceQuota to a new size. If \a new_size is smaller
   /// than the current size of the pool, memory usage will be monotonically
index 2c915c8..98b5d9a 100644 (file)
@@ -69,7 +69,7 @@ std::shared_ptr<ChannelCredentials> XdsCredentials(
 class ChannelCredentials : private grpc::GrpcLibraryCodegen {
  public:
   ChannelCredentials();
-  ~ChannelCredentials();
+  ~ChannelCredentials() override;
 
  protected:
   friend std::shared_ptr<ChannelCredentials> CompositeChannelCredentials(
@@ -126,7 +126,7 @@ class ChannelCredentials : private grpc::GrpcLibraryCodegen {
 class CallCredentials : private grpc::GrpcLibraryCodegen {
  public:
   CallCredentials();
-  ~CallCredentials();
+  ~CallCredentials() override;
 
   /// Apply this instance's credentials to \a call.
   virtual bool ApplyToCall(grpc_call* call) = 0;
@@ -307,6 +307,12 @@ grpc::Status StsCredentialsOptionsFromEnv(StsCredentialsOptions* options);
 std::shared_ptr<CallCredentials> StsCredentials(
     const StsCredentialsOptions& options);
 
+/// Builds External Account credentials.
+/// json_string is the JSON string containing the credentials options.
+/// scopes contains the scopes to be binded with the credentials.
+std::shared_ptr<CallCredentials> ExternalAccountCredentials(
+    const grpc::string& json_string, const std::vector<grpc::string>& scopes);
+
 std::shared_ptr<CallCredentials> MetadataCredentialsFromPlugin(
     std::unique_ptr<MetadataCredentialsPlugin> plugin,
     grpc_security_level min_security_level);
index b5f0b26..ad7c0e7 100644 (file)
@@ -32,13 +32,15 @@ struct grpc_server;
 namespace grpc {
 
 class Server;
+class ServerCredentials;
+class SecureServerCredentials;
 /// Options to create ServerCredentials with SSL
 struct SslServerCredentialsOptions {
   /// \warning Deprecated
   SslServerCredentialsOptions()
       : force_client_auth(false),
         client_certificate_request(GRPC_SSL_DONT_REQUEST_CLIENT_CERTIFICATE) {}
-  SslServerCredentialsOptions(
+  explicit SslServerCredentialsOptions(
       grpc_ssl_client_certificate_request_type request_type)
       : force_client_auth(false), client_certificate_request(request_type) {}
 
@@ -58,6 +60,12 @@ struct SslServerCredentialsOptions {
   grpc_ssl_client_certificate_request_type client_certificate_request;
 };
 
+namespace experimental {
+/// Builds Xds ServerCredentials given fallback credentials
+std::shared_ptr<ServerCredentials> XdsServerCredentials(
+    const std::shared_ptr<ServerCredentials>& fallback_credentials);
+}  // namespace experimental
+
 /// Wrapper around \a grpc_server_credentials, a way to authenticate a server.
 class ServerCredentials {
  public:
@@ -71,12 +79,30 @@ class ServerCredentials {
  private:
   friend class Server;
 
+  // We need this friend declaration for access to Insecure() and
+  // AsSecureServerCredentials(). When these two functions are no longer
+  // necessary, this friend declaration can be removed too.
+  friend std::shared_ptr<ServerCredentials>
+  grpc::experimental::XdsServerCredentials(
+      const std::shared_ptr<ServerCredentials>& fallback_credentials);
+
   /// Tries to bind \a server to the given \a addr (eg, localhost:1234,
   /// 192.168.1.1:31416, [::1]:27182, etc.)
   ///
   /// \return bound port number on success, 0 on failure.
   // TODO(dgq): the "port" part seems to be a misnomer.
   virtual int AddPortToServer(const std::string& addr, grpc_server* server) = 0;
+
+  // TODO(yashykt): This is a hack since InsecureServerCredentials() cannot use
+  // grpc_insecure_server_credentials_create() and should be removed after
+  // insecure builds are removed from gRPC.
+  virtual bool IsInsecure() const { return false; }
+
+  // TODO(yashkt): This is a hack that should be removed once we remove insecure
+  // builds and the indirect method of adding ports to a server.
+  virtual SecureServerCredentials* AsSecureServerCredentials() {
+    return nullptr;
+  }
 };
 
 /// Builds SSL ServerCredentials given SSL specific options
index 797687c..a7480cc 100644 (file)
@@ -59,14 +59,64 @@ class StaticDataCertificateProvider : public CertificateProviderInterface {
       const std::string& root_certificate,
       const std::vector<IdentityKeyCertPair>& identity_key_cert_pairs);
 
-  StaticDataCertificateProvider(const std::string& root_certificate)
+  explicit StaticDataCertificateProvider(const std::string& root_certificate)
       : StaticDataCertificateProvider(root_certificate, {}) {}
 
-  StaticDataCertificateProvider(
+  explicit StaticDataCertificateProvider(
       const std::vector<IdentityKeyCertPair>& identity_key_cert_pairs)
       : StaticDataCertificateProvider("", identity_key_cert_pairs) {}
 
-  ~StaticDataCertificateProvider();
+  ~StaticDataCertificateProvider() override;
+
+  grpc_tls_certificate_provider* c_provider() override { return c_provider_; }
+
+ private:
+  grpc_tls_certificate_provider* c_provider_ = nullptr;
+};
+
+// A CertificateProviderInterface implementation that will watch the credential
+// changes on the file system. This provider will always return the up-to-date
+// cert data for all the cert names callers set through |TlsCredentialsOptions|.
+// Several things to note:
+// 1. This API only supports one key-cert file and hence one set of identity
+// key-cert pair, so SNI(Server Name Indication) is not supported.
+// 2. The private key and identity certificate should always match. This API
+// guarantees atomic read, and it is the callers' responsibility to do atomic
+// updates. There are many ways to atomically update the key and certs in the
+// file system. To name a few:
+//   1)  creating a new directory, renaming the old directory to a new name, and
+//   then renaming the new directory to the original name of the old directory.
+//   2)  using a symlink for the directory. When need to change, put new
+//   credential data in a new directory, and change symlink.
+class FileWatcherCertificateProvider final
+    : public CertificateProviderInterface {
+ public:
+  // Constructor to get credential updates from root and identity file paths.
+  //
+  // @param private_key_path is the file path of the private key.
+  // @param identity_certificate_path is the file path of the identity
+  // certificate chain.
+  // @param root_cert_path is the file path to the root certificate bundle.
+  // @param refresh_interval_sec is the refreshing interval that we will check
+  // the files for updates.
+  FileWatcherCertificateProvider(const std::string& private_key_path,
+                                 const std::string& identity_certificate_path,
+                                 const std::string& root_cert_path,
+                                 unsigned int refresh_interval_sec);
+  // Constructor to get credential updates from identity file paths only.
+  FileWatcherCertificateProvider(const std::string& private_key_path,
+                                 const std::string& identity_certificate_path,
+                                 unsigned int refresh_interval_sec)
+      : FileWatcherCertificateProvider(private_key_path,
+                                       identity_certificate_path, "",
+                                       refresh_interval_sec) {}
+  // Constructor to get credential updates from root file path only.
+  FileWatcherCertificateProvider(const std::string& root_cert_path,
+                                 unsigned int refresh_interval_sec)
+      : FileWatcherCertificateProvider("", "", root_cert_path,
+                                       refresh_interval_sec) {}
+
+  ~FileWatcherCertificateProvider() override;
 
   grpc_tls_certificate_provider* c_provider() override { return c_provider_; }
 
index aaa1a90..6abdcaa 100644 (file)
@@ -54,7 +54,8 @@ class TlsServerAuthorizationCheckArg {
   /** TlsServerAuthorizationCheckArg does not take ownership of the C arg passed
    * to the constructor. One must remember to free any memory allocated to the
    * C arg after using the setter functions below. **/
-  TlsServerAuthorizationCheckArg(grpc_tls_server_authorization_check_arg* arg);
+  explicit TlsServerAuthorizationCheckArg(
+      grpc_tls_server_authorization_check_arg* arg);
   ~TlsServerAuthorizationCheckArg();
 
   /** Getters for member fields. **/
@@ -101,7 +102,7 @@ struct TlsServerAuthorizationCheckInterface {
  *  purposes for now and it is subject to change. **/
 class TlsServerAuthorizationCheckConfig {
  public:
-  TlsServerAuthorizationCheckConfig(
+  explicit TlsServerAuthorizationCheckConfig(
       std::shared_ptr<TlsServerAuthorizationCheckInterface>
           server_authorization_check_interface);
   ~TlsServerAuthorizationCheckConfig();
index 718ae1a..5dc73a1 100644 (file)
@@ -58,7 +58,7 @@ class ExternalConnectionAcceptorImpl;
 /// \a Server instances.
 class Server : public ServerInterface, private GrpcLibraryCodegen {
  public:
-  ~Server();
+  ~Server() override;
 
   /// Block until the server shuts down.
   ///
@@ -133,7 +133,7 @@ class Server : public ServerInterface, private GrpcLibraryCodegen {
  protected:
   /// Register a service. This call does not take ownership of the service.
   /// The service must exist for the lifetime of the Server instance.
-  bool RegisterService(const std::string* host, Service* service) override;
+  bool RegisterService(const std::string* addr, Service* service) override;
 
   /// Try binding the server to the given \a addr endpoint
   /// (port, and optionally including IP address to bind to).
@@ -179,6 +179,7 @@ class Server : public ServerInterface, private GrpcLibraryCodegen {
          int min_pollers, int max_pollers, int sync_cq_timeout_msec,
          std::vector<std::shared_ptr<internal::ExternalConnectionAcceptorImpl>>
              acceptors,
+         grpc_server_config_fetcher* server_config_fetcher = nullptr,
          grpc_resource_quota* server_rq = nullptr,
          std::vector<
              std::unique_ptr<experimental::ServerInterceptorFactoryInterface>>
index 06a0c83..cb75d87 100644 (file)
@@ -347,6 +347,11 @@ class ServerBuilder {
     return option_refs;
   }
 
+  /// Experimental API, subject to change.
+  void set_fetcher(grpc_server_config_fetcher* server_config_fetcher) {
+    server_config_fetcher_ = server_config_fetcher;
+  }
+
  private:
   friend class ::grpc::testing::ServerBuilderPluginTest;
 
@@ -405,6 +410,7 @@ class ServerBuilder {
       interceptor_creators_;
   std::vector<std::shared_ptr<grpc::internal::ExternalConnectionAcceptorImpl>>
       acceptors_;
+  grpc_server_config_fetcher* server_config_fetcher_ = nullptr;
 };
 
 }  // namespace grpc
index 13146ca..41a8ad3 100644 (file)
@@ -117,7 +117,7 @@ class ChannelArguments {
   grpc_channel_args c_channel_args() const {
     grpc_channel_args out;
     out.num_args = args_.size();
-    out.args = args_.empty() ? NULL : const_cast<grpc_arg*>(&args_[0]);
+    out.args = args_.empty() ? nullptr : const_cast<grpc_arg*>(&args_[0]);
     return out;
   }
 
diff --git a/include/grpcpp/xds_server_builder.h b/include/grpcpp/xds_server_builder.h
new file mode 100644 (file)
index 0000000..1ed9e83
--- /dev/null
@@ -0,0 +1,43 @@
+//
+//
+// 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 GRPCPP_XDS_SERVER_BUILDER_H
+#define GRPCPP_XDS_SERVER_BUILDER_H
+
+#include <grpc/impl/codegen/port_platform.h>
+
+#include <grpcpp/server_builder.h>
+
+namespace grpc {
+namespace experimental {
+
+class XdsServerBuilder : public ::grpc::ServerBuilder {
+ public:
+  std::unique_ptr<Server> BuildAndStart() override {
+    grpc_server_config_fetcher* fetcher =
+        grpc_server_config_fetcher_xds_create();
+    if (fetcher == nullptr) return nullptr;
+    set_fetcher(fetcher);
+    return ServerBuilder::BuildAndStart();
+  }
+};
+
+}  // namespace experimental
+}  // namespace grpc
+
+#endif /* GRPCPP_XDS_SERVER_BUILDER_H */
index 0513028..ab68aa0 100644 (file)
@@ -13,8 +13,8 @@
  <date>2019-09-24</date>
  <time>16:06:07</time>
  <version>
-  <release>1.34.1</release>
-  <api>1.34.1</api>
+  <release>1.35.0</release>
+  <api>1.35.0</api>
  </version>
  <stability>
   <release>stable</release>
@@ -22,7 +22,7 @@
  </stability>
  <license>Apache 2.0</license>
  <notes>
-- gRPC Core 1.34.1 update
+- gRPC Core 1.35.0 update
  </notes>
  <contents>
   <dir baseinstalldir="/" name="/">
     <file baseinstalldir="/" name="src/core/ext/filters/client_channel/config_selector.cc" role="src" />
     <file baseinstalldir="/" name="src/core/ext/filters/client_channel/config_selector.h" role="src" />
     <file baseinstalldir="/" name="src/core/ext/filters/client_channel/connector.h" role="src" />
+    <file baseinstalldir="/" name="src/core/ext/filters/client_channel/dynamic_filters.cc" role="src" />
+    <file baseinstalldir="/" name="src/core/ext/filters/client_channel/dynamic_filters.h" role="src" />
     <file baseinstalldir="/" name="src/core/ext/filters/client_channel/global_subchannel_pool.cc" role="src" />
     <file baseinstalldir="/" name="src/core/ext/filters/client_channel/global_subchannel_pool.h" role="src" />
     <file baseinstalldir="/" name="src/core/ext/filters/client_channel/health/health_check_client.cc" role="src" />
     <file baseinstalldir="/" name="src/core/ext/filters/client_channel/lb_policy/subchannel_list.h" role="src" />
     <file baseinstalldir="/" name="src/core/ext/filters/client_channel/lb_policy/weighted_target/weighted_target.cc" role="src" />
     <file baseinstalldir="/" name="src/core/ext/filters/client_channel/lb_policy/xds/cds.cc" role="src" />
-    <file baseinstalldir="/" name="src/core/ext/filters/client_channel/lb_policy/xds/eds.cc" role="src" />
     <file baseinstalldir="/" name="src/core/ext/filters/client_channel/lb_policy/xds/xds.h" role="src" />
+    <file baseinstalldir="/" name="src/core/ext/filters/client_channel/lb_policy/xds/xds_channel_args.h" role="src" />
     <file baseinstalldir="/" name="src/core/ext/filters/client_channel/lb_policy/xds/xds_cluster_impl.cc" role="src" />
     <file baseinstalldir="/" name="src/core/ext/filters/client_channel/lb_policy/xds/xds_cluster_manager.cc" role="src" />
+    <file baseinstalldir="/" name="src/core/ext/filters/client_channel/lb_policy/xds/xds_cluster_resolver.cc" role="src" />
     <file baseinstalldir="/" name="src/core/ext/filters/client_channel/lb_policy_factory.h" role="src" />
     <file baseinstalldir="/" name="src/core/ext/filters/client_channel/lb_policy_registry.cc" role="src" />
     <file baseinstalldir="/" name="src/core/ext/filters/client_channel/lb_policy_registry.h" role="src" />
     <file baseinstalldir="/" name="src/core/ext/filters/client_channel/resolver.cc" role="src" />
     <file baseinstalldir="/" name="src/core/ext/filters/client_channel/resolver.h" role="src" />
     <file baseinstalldir="/" name="src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc" role="src" />
-    <file baseinstalldir="/" name="src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.cc" role="src" />
     <file baseinstalldir="/" name="src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.h" role="src" />
     <file baseinstalldir="/" name="src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_libuv.cc" role="src" />
     <file baseinstalldir="/" name="src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_posix.cc" role="src" />
     <file baseinstalldir="/" name="src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_windows.cc" role="src" />
     <file baseinstalldir="/" name="src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc" role="src" />
     <file baseinstalldir="/" name="src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h" role="src" />
-    <file baseinstalldir="/" name="src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_fallback.cc" role="src" />
     <file baseinstalldir="/" name="src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv.cc" role="src" />
     <file baseinstalldir="/" name="src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_posix.cc" role="src" />
     <file baseinstalldir="/" name="src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc" role="src" />
     <file baseinstalldir="/" name="src/core/ext/filters/client_channel/resolver_registry.h" role="src" />
     <file baseinstalldir="/" name="src/core/ext/filters/client_channel/resolver_result_parsing.cc" role="src" />
     <file baseinstalldir="/" name="src/core/ext/filters/client_channel/resolver_result_parsing.h" role="src" />
-    <file baseinstalldir="/" name="src/core/ext/filters/client_channel/resolving_lb_policy.cc" role="src" />
-    <file baseinstalldir="/" name="src/core/ext/filters/client_channel/resolving_lb_policy.h" role="src" />
     <file baseinstalldir="/" name="src/core/ext/filters/client_channel/retry_throttle.cc" role="src" />
     <file baseinstalldir="/" name="src/core/ext/filters/client_channel/retry_throttle.h" role="src" />
     <file baseinstalldir="/" name="src/core/ext/filters/client_channel/server_address.cc" role="src" />
     <file baseinstalldir="/" name="src/core/ext/xds/certificate_provider_store.h" role="src" />
     <file baseinstalldir="/" name="src/core/ext/xds/file_watcher_certificate_provider_factory.cc" role="src" />
     <file baseinstalldir="/" name="src/core/ext/xds/file_watcher_certificate_provider_factory.h" role="src" />
-    <file baseinstalldir="/" name="src/core/ext/xds/google_mesh_ca_certificate_provider_factory.cc" role="src" />
-    <file baseinstalldir="/" name="src/core/ext/xds/google_mesh_ca_certificate_provider_factory.h" role="src" />
     <file baseinstalldir="/" name="src/core/ext/xds/xds_api.cc" role="src" />
     <file baseinstalldir="/" name="src/core/ext/xds/xds_api.h" role="src" />
     <file baseinstalldir="/" name="src/core/ext/xds/xds_bootstrap.cc" role="src" />
     <file baseinstalldir="/" name="src/core/ext/xds/xds_client.h" role="src" />
     <file baseinstalldir="/" name="src/core/ext/xds/xds_client_stats.cc" role="src" />
     <file baseinstalldir="/" name="src/core/ext/xds/xds_client_stats.h" role="src" />
+    <file baseinstalldir="/" name="src/core/ext/xds/xds_server_config_fetcher.cc" role="src" />
     <file baseinstalldir="/" name="src/core/lib/avl/avl.cc" role="src" />
     <file baseinstalldir="/" name="src/core/lib/avl/avl.h" role="src" />
     <file baseinstalldir="/" name="src/core/lib/backoff/backoff.cc" role="src" />
     <file baseinstalldir="/" name="src/core/lib/gprpp/host_port.cc" role="src" />
     <file baseinstalldir="/" name="src/core/lib/gprpp/host_port.h" role="src" />
     <file baseinstalldir="/" name="src/core/lib/gprpp/manual_constructor.h" role="src" />
-    <file baseinstalldir="/" name="src/core/lib/gprpp/map.h" role="src" />
     <file baseinstalldir="/" name="src/core/lib/gprpp/memory.h" role="src" />
     <file baseinstalldir="/" name="src/core/lib/gprpp/mpscq.cc" role="src" />
     <file baseinstalldir="/" name="src/core/lib/gprpp/mpscq.h" role="src" />
     <file baseinstalldir="/" name="src/core/lib/security/credentials/credentials.cc" role="src" />
     <file baseinstalldir="/" name="src/core/lib/security/credentials/credentials.h" role="src" />
     <file baseinstalldir="/" name="src/core/lib/security/credentials/credentials_metadata.cc" role="src" />
+    <file baseinstalldir="/" name="src/core/lib/security/credentials/external/aws_external_account_credentials.cc" role="src" />
+    <file baseinstalldir="/" name="src/core/lib/security/credentials/external/aws_external_account_credentials.h" role="src" />
     <file baseinstalldir="/" name="src/core/lib/security/credentials/external/aws_request_signer.cc" role="src" />
     <file baseinstalldir="/" name="src/core/lib/security/credentials/external/aws_request_signer.h" role="src" />
     <file baseinstalldir="/" name="src/core/lib/security/credentials/external/external_account_credentials.cc" role="src" />
     <file baseinstalldir="/" name="src/core/lib/security/credentials/tls/grpc_tls_credentials_options.h" role="src" />
     <file baseinstalldir="/" name="src/core/lib/security/credentials/tls/tls_credentials.cc" role="src" />
     <file baseinstalldir="/" name="src/core/lib/security/credentials/tls/tls_credentials.h" role="src" />
+    <file baseinstalldir="/" name="src/core/lib/security/credentials/tls/tls_utils.cc" role="src" />
+    <file baseinstalldir="/" name="src/core/lib/security/credentials/tls/tls_utils.h" role="src" />
     <file baseinstalldir="/" name="src/core/lib/security/credentials/xds/xds_credentials.cc" role="src" />
     <file baseinstalldir="/" name="src/core/lib/security/credentials/xds/xds_credentials.h" role="src" />
     <file baseinstalldir="/" name="src/core/lib/security/security_connector/alts/alts_security_connector.cc" role="src" />
     <file baseinstalldir="/" name="third_party/abseil-cpp/absl/base/port.h" role="src" />
     <file baseinstalldir="/" name="third_party/abseil-cpp/absl/base/thread_annotations.h" role="src" />
     <file baseinstalldir="/" name="third_party/abseil-cpp/absl/container/fixed_array.h" role="src" />
+    <file baseinstalldir="/" name="third_party/abseil-cpp/absl/container/flat_hash_map.h" role="src" />
     <file baseinstalldir="/" name="third_party/abseil-cpp/absl/container/flat_hash_set.h" role="src" />
     <file baseinstalldir="/" name="third_party/abseil-cpp/absl/container/inlined_vector.h" role="src" />
     <file baseinstalldir="/" name="third_party/abseil-cpp/absl/container/internal/common.h" role="src" />
     <file baseinstalldir="/" name="third_party/abseil-cpp/absl/container/internal/have_sse.h" role="src" />
     <file baseinstalldir="/" name="third_party/abseil-cpp/absl/container/internal/inlined_vector.h" role="src" />
     <file baseinstalldir="/" name="third_party/abseil-cpp/absl/container/internal/layout.h" role="src" />
+    <file baseinstalldir="/" name="third_party/abseil-cpp/absl/container/internal/raw_hash_map.h" role="src" />
     <file baseinstalldir="/" name="third_party/abseil-cpp/absl/container/internal/raw_hash_set.cc" role="src" />
     <file baseinstalldir="/" name="third_party/abseil-cpp/absl/container/internal/raw_hash_set.h" role="src" />
     <file baseinstalldir="/" name="third_party/abseil-cpp/absl/debugging/internal/address_is_readable.cc" role="src" />
     <file baseinstalldir="/" name="third_party/abseil-cpp/absl/numeric/int128_have_intrinsic.inc" role="src" />
     <file baseinstalldir="/" name="third_party/abseil-cpp/absl/numeric/int128_no_intrinsic.inc" role="src" />
     <file baseinstalldir="/" name="third_party/abseil-cpp/absl/status/internal/status_internal.h" role="src" />
+    <file baseinstalldir="/" name="third_party/abseil-cpp/absl/status/internal/statusor_internal.h" role="src" />
     <file baseinstalldir="/" name="third_party/abseil-cpp/absl/status/status.cc" role="src" />
     <file baseinstalldir="/" name="third_party/abseil-cpp/absl/status/status.h" role="src" />
     <file baseinstalldir="/" name="third_party/abseil-cpp/absl/status/status_payload_printer.cc" role="src" />
     <file baseinstalldir="/" name="third_party/abseil-cpp/absl/status/status_payload_printer.h" role="src" />
+    <file baseinstalldir="/" name="third_party/abseil-cpp/absl/status/statusor.cc" role="src" />
+    <file baseinstalldir="/" name="third_party/abseil-cpp/absl/status/statusor.h" role="src" />
     <file baseinstalldir="/" name="third_party/abseil-cpp/absl/strings/ascii.cc" role="src" />
     <file baseinstalldir="/" name="third_party/abseil-cpp/absl/strings/ascii.h" role="src" />
     <file baseinstalldir="/" name="third_party/abseil-cpp/absl/strings/charconv.cc" role="src" />
     <file baseinstalldir="/" name="third_party/re2/util/test.h" role="src" />
     <file baseinstalldir="/" name="third_party/re2/util/utf.h" role="src" />
     <file baseinstalldir="/" name="third_party/re2/util/util.h" role="src" />
+    <file baseinstalldir="/" name="third_party/upb/third_party/wyhash/wyhash.h" role="src" />
     <file baseinstalldir="/" name="third_party/upb/upb/decode.c" role="src" />
     <file baseinstalldir="/" name="third_party/upb/upb/decode.h" role="src" />
+    <file baseinstalldir="/" name="third_party/upb/upb/decode.int.h" role="src" />
+    <file baseinstalldir="/" name="third_party/upb/upb/decode_fast.c" role="src" />
+    <file baseinstalldir="/" name="third_party/upb/upb/decode_fast.h" role="src" />
     <file baseinstalldir="/" name="third_party/upb/upb/def.c" role="src" />
     <file baseinstalldir="/" name="third_party/upb/upb/def.h" role="src" />
     <file baseinstalldir="/" name="third_party/upb/upb/def.hpp" role="src" />
     <file baseinstalldir="/" name="third_party/upb/upb/encode.c" role="src" />
     <file baseinstalldir="/" name="third_party/upb/upb/encode.h" role="src" />
+    <file baseinstalldir="/" name="third_party/upb/upb/json_decode.c" role="src" />
+    <file baseinstalldir="/" name="third_party/upb/upb/json_decode.h" role="src" />
+    <file baseinstalldir="/" name="third_party/upb/upb/json_encode.c" role="src" />
+    <file baseinstalldir="/" name="third_party/upb/upb/json_encode.h" role="src" />
     <file baseinstalldir="/" name="third_party/upb/upb/msg.c" role="src" />
     <file baseinstalldir="/" name="third_party/upb/upb/msg.h" role="src" />
-    <file baseinstalldir="/" name="third_party/upb/upb/port.c" role="src" />
     <file baseinstalldir="/" name="third_party/upb/upb/port_def.inc" role="src" />
     <file baseinstalldir="/" name="third_party/upb/upb/port_undef.inc" role="src" />
     <file baseinstalldir="/" name="third_party/upb/upb/reflection.c" role="src" />
     <file baseinstalldir="/" name="third_party/upb/upb/upb.c" role="src" />
     <file baseinstalldir="/" name="third_party/upb/upb/upb.h" role="src" />
     <file baseinstalldir="/" name="third_party/upb/upb/upb.hpp" role="src" />
+    <file baseinstalldir="/" name="third_party/upb/upb/upb.int.h" role="src" />
     <file baseinstalldir="/" name="third_party/zlib/adler32.c" role="src" />
     <file baseinstalldir="/" name="third_party/zlib/compress.c" role="src" />
     <file baseinstalldir="/" name="third_party/zlib/crc32.c" role="src" />
index d54017a..51ddf19 100644 (file)
--- a/setup.cfg
+++ b/setup.cfg
@@ -19,12 +19,17 @@ based_on_style = google
 [metadata]
 license_files = LICENSE
 
+# NOTE(lidiz) Adding examples one by one due to pytype aggressive errer:
+# ninja: error: build.ninja:178: multiple rules generate helloworld_pb2.pyi [-w dupbuild=err]
 [pytype]
 inputs =
     src/python/grpcio/grpc/experimental
     src/python/grpcio_tests/tests_aio
+    examples/python/auth
+    examples/python/helloworld
 
 # NOTE(lidiz)
 # import-error: C extension triggers import-error.
 # module-attr: pytype cannot understand the namespace packages by Google.
-disable = "import-error,module-attr"
+# attribute-error: Data classes in grpc module doesn't specify attributes.
+disable = "import-error,module-attr,attribute-error"
index 2f32a3e..889c44b 100755 (executable)
@@ -20,7 +20,7 @@ import yaml
 BUILDS_YAML_PATH = os.path.join(os.path.dirname(os.path.abspath(__file__)),
                                 'preprocessed_builds.yaml')
 with open(BUILDS_YAML_PATH) as f:
-    builds = yaml.load(f)
+    builds = yaml.load(f, Loader=yaml.FullLoader)
 
 for build in builds:
     build['build'] = 'private'
index 5dea45a..d0f77c5 100644 (file)
@@ -1,4 +1,6 @@
-# Overview
+# gRPC core library
+
+This shared library provides all of gRPC's core functionality through a low
+level API. gRPC libraries for the other languages supported in this repo, are
+built on top of this shared core library.
 
-This directory contains source code for C library (a.k.a the *gRPC C core*) that provides all gRPC's core functionality through a low level API. Libraries in other languages in this repository (C++, C#, Ruby,
-Python, PHP, NodeJS, Objective-C) are layered on top of this library.
index 4d108aa..441657e 100644 (file)
 #include "udpa/data/orca/v1/orca_load_report.upb.h"
 #include "upb/upb.hpp"
 
-#include "src/core/lib/gprpp/map.h"
-
 namespace grpc_core {
 
 namespace {
 
 template <typename EntryType>
-std::map<absl::string_view, double, StringLess> ParseMap(
+std::map<absl::string_view, double> ParseMap(
     udpa_data_orca_v1_OrcaLoadReport* msg,
     const EntryType* (*entry_func)(const udpa_data_orca_v1_OrcaLoadReport*,
                                    size_t*),
     upb_strview (*key_func)(const EntryType*),
     double (*value_func)(const EntryType*), Arena* arena) {
-  std::map<absl::string_view, double, StringLess> result;
+  std::map<absl::string_view, double> result;
   size_t i = UPB_MAP_BEGIN;
   while (true) {
     const auto* entry = entry_func(msg, &i);
index b6ebeb3..048cd20 100644 (file)
@@ -1,20 +1,18 @@
-/*
- *
- * 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.
- *
- */
+//
+// 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>
 
@@ -30,6 +28,7 @@
 
 #include "absl/strings/numbers.h"
 #include "absl/strings/str_cat.h"
+#include "absl/strings/str_join.h"
 #include "absl/strings/string_view.h"
 
 #include <grpc/support/alloc.h>
 #include "src/core/ext/filters/client_channel/backend_metric.h"
 #include "src/core/ext/filters/client_channel/backup_poller.h"
 #include "src/core/ext/filters/client_channel/config_selector.h"
+#include "src/core/ext/filters/client_channel/dynamic_filters.h"
 #include "src/core/ext/filters/client_channel/global_subchannel_pool.h"
 #include "src/core/ext/filters/client_channel/http_connect_handshaker.h"
+#include "src/core/ext/filters/client_channel/lb_policy/child_policy_handler.h"
 #include "src/core/ext/filters/client_channel/lb_policy_registry.h"
 #include "src/core/ext/filters/client_channel/local_subchannel_pool.h"
 #include "src/core/ext/filters/client_channel/proxy_mapper_registry.h"
 #include "src/core/ext/filters/client_channel/resolver_registry.h"
 #include "src/core/ext/filters/client_channel/resolver_result_parsing.h"
-#include "src/core/ext/filters/client_channel/resolving_lb_policy.h"
 #include "src/core/ext/filters/client_channel/retry_throttle.h"
 #include "src/core/ext/filters/client_channel/service_config.h"
 #include "src/core/ext/filters/client_channel/service_config_call_data.h"
@@ -62,7 +62,6 @@
 #include "src/core/lib/channel/status_util.h"
 #include "src/core/lib/gpr/string.h"
 #include "src/core/lib/gprpp/manual_constructor.h"
-#include "src/core/lib/gprpp/map.h"
 #include "src/core/lib/gprpp/sync.h"
 #include "src/core/lib/iomgr/iomgr.h"
 #include "src/core/lib/iomgr/polling_entity.h"
@@ -78,9 +77,6 @@
 #include "src/core/lib/transport/static_metadata.h"
 #include "src/core/lib/transport/status_metadata.h"
 
-using grpc_core::internal::ClientChannelMethodParsedConfig;
-using grpc_core::internal::ServerRetryThrottleData;
-
 //
 // Client channel filter
 //
@@ -103,8 +99,19 @@ using grpc_core::internal::ServerRetryThrottleData;
 //   send_trailing_metadata
 #define MAX_PENDING_BATCHES 6
 
+// Channel arg containing a pointer to the ChannelData object.
+#define GRPC_ARG_CLIENT_CHANNEL_DATA "grpc.internal.client_channel_data"
+
+// Channel arg containing a pointer to the RetryThrottleData object.
+#define GRPC_ARG_RETRY_THROTTLE_DATA "grpc.internal.retry_throttle_data"
+
 namespace grpc_core {
 
+using internal::ClientChannelGlobalParsedConfig;
+using internal::ClientChannelMethodParsedConfig;
+using internal::ClientChannelServiceConfigParser;
+using internal::ServerRetryThrottleData;
+
 TraceFlag grpc_client_channel_call_trace(false, "client_channel_call");
 TraceFlag grpc_client_channel_routing_trace(false, "client_channel_routing");
 
@@ -114,11 +121,17 @@ namespace {
 // ChannelData definition
 //
 
+class LoadBalancedCall;
+
 class ChannelData {
  public:
-  struct QueuedPick {
+  struct ResolverQueuedCall {
     grpc_call_element* elem;
-    QueuedPick* next = nullptr;
+    ResolverQueuedCall* next = nullptr;
+  };
+  struct LbQueuedCall {
+    LoadBalancedCall* lb_call;
+    LbQueuedCall* next = nullptr;
   };
 
   static grpc_error* Init(grpc_channel_element* elem,
@@ -141,32 +154,39 @@ class ChannelData {
     return disconnect_error_.Load(MemoryOrder::ACQUIRE);
   }
 
-  Mutex* data_plane_mu() const { return &data_plane_mu_; }
-
-  LoadBalancingPolicy::SubchannelPicker* picker() const {
-    return picker_.get();
-  }
-  void AddQueuedPick(QueuedPick* pick, grpc_polling_entity* pollent);
-  void RemoveQueuedPick(QueuedPick* to_remove, grpc_polling_entity* pollent);
-
+  Mutex* resolution_mu() const { return &resolution_mu_; }
+  // These methods all require holding resolution_mu_.
+  void AddResolverQueuedCall(ResolverQueuedCall* call,
+                             grpc_polling_entity* pollent);
+  void RemoveResolverQueuedCall(ResolverQueuedCall* to_remove,
+                                grpc_polling_entity* pollent);
   bool received_service_config_data() const {
     return received_service_config_data_;
   }
   grpc_error* resolver_transient_failure_error() const {
     return resolver_transient_failure_error_;
   }
-  RefCountedPtr<ServerRetryThrottleData> retry_throttle_data() const {
-    return retry_throttle_data_;
-  }
   RefCountedPtr<ServiceConfig> service_config() const {
     return service_config_;
   }
   ConfigSelector* config_selector() const { return config_selector_.get(); }
-  WorkSerializer* work_serializer() const { return work_serializer_.get(); }
+  RefCountedPtr<DynamicFilters> dynamic_filters() const {
+    return dynamic_filters_;
+  }
 
+  Mutex* data_plane_mu() const { return &data_plane_mu_; }
+  // These methods all require holding data_plane_mu_.
+  LoadBalancingPolicy::SubchannelPicker* picker() const {
+    return picker_.get();
+  }
+  void AddLbQueuedCall(LbQueuedCall* call, grpc_polling_entity* pollent);
+  void RemoveLbQueuedCall(LbQueuedCall* to_remove,
+                          grpc_polling_entity* pollent);
   RefCountedPtr<ConnectedSubchannel> GetConnectedSubchannelInDataPlane(
       SubchannelInterface* subchannel) const;
 
+  WorkSerializer* work_serializer() const { return work_serializer_.get(); }
+
   grpc_connectivity_state CheckConnectivityState(bool try_to_connect);
 
   void AddExternalConnectivityWatcher(grpc_polling_entity pollent,
@@ -236,30 +256,46 @@ class ChannelData {
     Atomic<bool> done_{false};
   };
 
-  class ChannelConfigHelper
-      : public ResolvingLoadBalancingPolicy::ChannelConfigHelper {
+  class ResolverResultHandler : public Resolver::ResultHandler {
    public:
-    explicit ChannelConfigHelper(ChannelData* chand) : chand_(chand) {}
+    explicit ResolverResultHandler(ChannelData* chand) : chand_(chand) {
+      GRPC_CHANNEL_STACK_REF(chand_->owning_stack_, "ResolverResultHandler");
+    }
 
-    ChooseServiceConfigResult ChooseServiceConfig(
-        const Resolver::Result& result) override;
+    ~ResolverResultHandler() override {
+      if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_routing_trace)) {
+        gpr_log(GPR_INFO, "chand=%p: resolver shutdown complete", chand_);
+      }
+      GRPC_CHANNEL_STACK_UNREF(chand_->owning_stack_, "ResolverResultHandler");
+    }
 
-    void StartUsingServiceConfigForCalls() override;
+    void ReturnResult(Resolver::Result result) override {
+      chand_->OnResolverResultChangedLocked(std::move(result));
+    }
 
-    void ResolverTransientFailure(grpc_error* error) override;
+    void ReturnError(grpc_error* error) override {
+      chand_->OnResolverErrorLocked(error);
+    }
 
    private:
-    static void ChooseLbPolicy(
-        const Resolver::Result& resolver_result,
-        const internal::ClientChannelGlobalParsedConfig* parsed_service_config,
-        RefCountedPtr<LoadBalancingPolicy::Config>* lb_policy_config);
-
     ChannelData* chand_;
   };
 
   ChannelData(grpc_channel_element_args* args, grpc_error** error);
   ~ChannelData();
 
+  // Note: All methods with "Locked" suffix must be invoked from within
+  // work_serializer_.
+
+  void OnResolverResultChangedLocked(Resolver::Result result);
+  void OnResolverErrorLocked(grpc_error* error);
+
+  void CreateOrUpdateLbPolicyLocked(
+      RefCountedPtr<LoadBalancingPolicy::Config> lb_policy_config,
+      Resolver::Result result);
+  OrphanablePtr<LoadBalancingPolicy> CreateLbPolicyLocked(
+      const grpc_channel_args& args);
+
   void UpdateStateAndPickerLocked(
       grpc_connectivity_state state, const absl::Status& status,
       const char* reason,
@@ -273,9 +309,8 @@ class ChannelData {
 
   void UpdateServiceConfigInDataPlaneLocked();
 
-  void CreateResolvingLoadBalancingPolicyLocked();
-
-  void DestroyResolvingLoadBalancingPolicyLocked();
+  void CreateResolverLocked();
+  void DestroyResolverAndLbPolicyLocked();
 
   grpc_error* DoPingLocked(grpc_transport_op* op);
 
@@ -293,35 +328,44 @@ class ChannelData {
   ClientChannelFactory* client_channel_factory_;
   const grpc_channel_args* channel_args_;
   RefCountedPtr<ServiceConfig> default_service_config_;
-  grpc_core::UniquePtr<char> server_name_;
-  grpc_core::UniquePtr<char> target_uri_;
+  std::string server_name_;
+  UniquePtr<char> target_uri_;
   channelz::ChannelNode* channelz_node_;
-  ChannelConfigHelper channel_config_helper_;
 
   //
-  // Fields used in the data plane.  Guarded by data_plane_mu.
+  // Fields related to name resolution.  Guarded by resolution_mu_.
   //
-  mutable Mutex data_plane_mu_;
-  std::unique_ptr<LoadBalancingPolicy::SubchannelPicker> picker_;
-  QueuedPick* queued_picks_ = nullptr;  // Linked list of queued picks.
+  mutable Mutex resolution_mu_;
+  // Linked list of calls queued waiting for resolver result.
+  ResolverQueuedCall* resolver_queued_calls_ = nullptr;
   // Data from service config.
   grpc_error* resolver_transient_failure_error_ = GRPC_ERROR_NONE;
   bool received_service_config_data_ = false;
-  RefCountedPtr<ServerRetryThrottleData> retry_throttle_data_;
   RefCountedPtr<ServiceConfig> service_config_;
   RefCountedPtr<ConfigSelector> config_selector_;
+  RefCountedPtr<DynamicFilters> dynamic_filters_;
+
+  //
+  // Fields used in the data plane.  Guarded by data_plane_mu_.
+  //
+  mutable Mutex data_plane_mu_;
+  std::unique_ptr<LoadBalancingPolicy::SubchannelPicker> picker_;
+  // Linked list of calls queued waiting for LB pick.
+  LbQueuedCall* lb_queued_calls_ = nullptr;
 
   //
   // Fields used in the control plane.  Guarded by work_serializer.
   //
   std::shared_ptr<WorkSerializer> work_serializer_;
   grpc_pollset_set* interested_parties_;
-  RefCountedPtr<SubchannelPoolInterface> subchannel_pool_;
-  OrphanablePtr<ResolvingLoadBalancingPolicy> resolving_lb_policy_;
   ConnectivityStateTracker state_tracker_;
-  grpc_core::UniquePtr<char> health_check_service_name_;
+  OrphanablePtr<Resolver> resolver_;
+  bool previous_resolution_contained_addresses_ = false;
   RefCountedPtr<ServiceConfig> saved_service_config_;
   RefCountedPtr<ConfigSelector> saved_config_selector_;
+  absl::optional<std::string> health_check_service_name_;
+  OrphanablePtr<LoadBalancingPolicy> lb_policy_;
+  RefCountedPtr<SubchannelPoolInterface> subchannel_pool_;
   // The number of SubchannelWrapper instances referencing a given Subchannel.
   std::map<Subchannel*, int> subchannel_refcount_map_;
   // The set of SubchannelWrappers that currently exist.
@@ -346,8 +390,8 @@ class ChannelData {
   // synchronously via get_channel_info().
   //
   gpr_mu info_mu_;
-  grpc_core::UniquePtr<char> info_lb_policy_name_;
-  grpc_core::UniquePtr<char> info_service_config_json_;
+  UniquePtr<char> info_lb_policy_name_;
+  UniquePtr<char> info_service_config_json_;
 
   //
   // Fields guarded by a mutex, since they need to be accessed
@@ -373,114 +417,140 @@ class CallData {
       grpc_call_element* elem, grpc_transport_stream_op_batch* batch);
   static void SetPollent(grpc_call_element* elem, grpc_polling_entity* pollent);
 
-  RefCountedPtr<SubchannelCall> subchannel_call() { return subchannel_call_; }
+  // Invoked by channel for queued calls when name resolution is completed.
+  static void CheckResolution(void* arg, grpc_error* error);
+  // Helper function for applying the service config to a call while
+  // holding ChannelData::resolution_mu_.
+  // Returns true if the service config has been applied to the call, in which
+  // case the caller must invoke ResolutionDone() or AsyncResolutionDone()
+  // with the returned error.
+  bool CheckResolutionLocked(grpc_call_element* elem, grpc_error** error);
+  // Schedules a callback to continue processing the call once
+  // resolution is complete.  The callback will not run until after this
+  // method returns.
+  void AsyncResolutionDone(grpc_call_element* elem, grpc_error* error);
 
-  // Invoked by channel for queued picks when the picker is updated.
-  static void PickSubchannel(void* arg, grpc_error* error);
+ private:
+  class ResolverQueuedCallCanceller;
 
-  // Helper function for performing a pick while holding the data plane
-  // mutex.  Returns true if the pick is complete, in which case the caller
-  // must invoke PickDone() or AsyncPickDone() with the returned error.
-  bool PickSubchannelLocked(grpc_call_element* elem, grpc_error** error);
+  CallData(grpc_call_element* elem, const ChannelData& chand,
+           const grpc_call_element_args& args);
+  ~CallData();
 
-  // Schedules a callback to process the completed pick.  The callback
-  // will not run until after this method returns.
-  void AsyncPickDone(grpc_call_element* elem, grpc_error* error);
+  // Returns the index into pending_batches_ to be used for batch.
+  static size_t GetBatchIndex(grpc_transport_stream_op_batch* batch);
+  void PendingBatchesAdd(grpc_call_element* elem,
+                         grpc_transport_stream_op_batch* batch);
+  static void FailPendingBatchInCallCombiner(void* arg, grpc_error* error);
+  // A predicate type and some useful implementations for PendingBatchesFail().
+  typedef bool (*YieldCallCombinerPredicate)(
+      const CallCombinerClosureList& closures);
+  static bool YieldCallCombiner(const CallCombinerClosureList& /*closures*/) {
+    return true;
+  }
+  static bool NoYieldCallCombiner(const CallCombinerClosureList& /*closures*/) {
+    return false;
+  }
+  static bool YieldCallCombinerIfPendingBatchesFound(
+      const CallCombinerClosureList& closures) {
+    return closures.size() > 0;
+  }
+  // Fails all pending batches.
+  // If yield_call_combiner_predicate returns true, assumes responsibility for
+  // yielding the call combiner.
+  void PendingBatchesFail(
+      grpc_call_element* elem, grpc_error* error,
+      YieldCallCombinerPredicate yield_call_combiner_predicate);
+  static void ResumePendingBatchInCallCombiner(void* arg, grpc_error* ignored);
+  // Resumes all pending batches on lb_call_.
+  void PendingBatchesResume(grpc_call_element* elem);
 
- private:
-  class QueuedPickCanceller;
+  // Applies service config to the call.  Must be invoked once we know
+  // that the resolver has returned results to the channel.
+  // If an error is returned, the error indicates the status with which
+  // the call should be failed.
+  grpc_error* ApplyServiceConfigToCallLocked(
+      grpc_call_element* elem, grpc_metadata_batch* initial_metadata);
+  // Invoked when the resolver result is applied to the caller, on both
+  // success or failure.
+  static void ResolutionDone(void* arg, grpc_error* error);
+  // Removes the call (if present) from the channel's list of calls queued
+  // for name resolution.
+  void MaybeRemoveCallFromResolverQueuedCallsLocked(grpc_call_element* elem);
+  // Adds the call (if not already present) to the channel's list of
+  // calls queued for name resolution.
+  void MaybeAddCallToResolverQueuedCallsLocked(grpc_call_element* elem);
+
+  static void RecvInitialMetadataReadyForConfigSelectorCommitCallback(
+      void* arg, grpc_error* error);
+  void InjectRecvInitialMetadataReadyForConfigSelectorCommitCallback(
+      grpc_transport_stream_op_batch* batch);
 
-  class Metadata : public LoadBalancingPolicy::MetadataInterface {
-   public:
-    Metadata(CallData* calld, grpc_metadata_batch* batch)
-        : calld_(calld), batch_(batch) {}
-
-    void Add(absl::string_view key, absl::string_view value) override {
-      grpc_linked_mdelem* linked_mdelem = static_cast<grpc_linked_mdelem*>(
-          calld_->arena_->Alloc(sizeof(grpc_linked_mdelem)));
-      linked_mdelem->md = grpc_mdelem_from_slices(
-          grpc_core::ExternallyManagedSlice(key.data(), key.size()),
-          grpc_core::ExternallyManagedSlice(value.data(), value.size()));
-      GPR_ASSERT(grpc_metadata_batch_link_tail(batch_, linked_mdelem) ==
-                 GRPC_ERROR_NONE);
-    }
+  void CreateDynamicCall(grpc_call_element* elem);
 
-    iterator begin() const override {
-      static_assert(sizeof(grpc_linked_mdelem*) <= sizeof(intptr_t),
-                    "iterator size too large");
-      return iterator(
-          this, reinterpret_cast<intptr_t>(MaybeSkipEntry(batch_->list.head)));
-    }
-    iterator end() const override {
-      static_assert(sizeof(grpc_linked_mdelem*) <= sizeof(intptr_t),
-                    "iterator size too large");
-      return iterator(this, 0);
-    }
+  // State for handling deadlines.
+  // The code in deadline_filter.c requires this to be the first field.
+  // TODO(roth): This is slightly sub-optimal in that grpc_deadline_state
+  // and this struct both independently store pointers to the call stack
+  // and call combiner.  If/when we have time, find a way to avoid this
+  // without breaking the grpc_deadline_state abstraction.
+  grpc_deadline_state deadline_state_;
 
-    iterator erase(iterator it) override {
-      grpc_linked_mdelem* linked_mdelem =
-          reinterpret_cast<grpc_linked_mdelem*>(GetIteratorHandle(it));
-      intptr_t handle = reinterpret_cast<intptr_t>(linked_mdelem->next);
-      grpc_metadata_batch_remove(batch_, linked_mdelem);
-      return iterator(this, handle);
-    }
+  grpc_slice path_;  // Request path.
+  gpr_cycle_counter call_start_time_;
+  grpc_millis deadline_;
+  Arena* arena_;
+  grpc_call_stack* owning_call_;
+  CallCombiner* call_combiner_;
+  grpc_call_context_element* call_context_;
 
-   private:
-    grpc_linked_mdelem* MaybeSkipEntry(grpc_linked_mdelem* entry) const {
-      if (entry != nullptr && batch_->idx.named.path == entry) {
-        return entry->next;
-      }
-      return entry;
-    }
+  grpc_polling_entity* pollent_ = nullptr;
 
-    intptr_t IteratorHandleNext(intptr_t handle) const override {
-      grpc_linked_mdelem* linked_mdelem =
-          reinterpret_cast<grpc_linked_mdelem*>(handle);
-      return reinterpret_cast<intptr_t>(MaybeSkipEntry(linked_mdelem->next));
-    }
+  grpc_closure pick_closure_;
 
-    std::pair<absl::string_view, absl::string_view> IteratorHandleGet(
-        intptr_t handle) const override {
-      grpc_linked_mdelem* linked_mdelem =
-          reinterpret_cast<grpc_linked_mdelem*>(handle);
-      return std::make_pair(
-          StringViewFromSlice(GRPC_MDKEY(linked_mdelem->md)),
-          StringViewFromSlice(GRPC_MDVALUE(linked_mdelem->md)));
-    }
+  // Accessed while holding ChannelData::resolution_mu_.
+  bool service_config_applied_ = false;
+  bool queued_pending_resolver_result_ = false;
+  ChannelData::ResolverQueuedCall resolver_queued_call_;
+  ResolverQueuedCallCanceller* resolver_call_canceller_ = nullptr;
 
-    CallData* calld_;
-    grpc_metadata_batch* batch_;
-  };
+  std::function<void()> on_call_committed_;
 
-  class LbCallState : public LoadBalancingPolicy::CallState {
-   public:
-    explicit LbCallState(CallData* calld) : calld_(calld) {}
-
-    void* Alloc(size_t size) override { return calld_->arena_->Alloc(size); }
-
-    const LoadBalancingPolicy::BackendMetricData* GetBackendMetricData()
-        override {
-      if (calld_->backend_metric_data_ == nullptr) {
-        grpc_linked_mdelem* md = calld_->recv_trailing_metadata_->idx.named
-                                     .x_endpoint_load_metrics_bin;
-        if (md != nullptr) {
-          calld_->backend_metric_data_ =
-              ParseBackendMetricData(GRPC_MDVALUE(md->md), calld_->arena_);
-        }
-      }
-      return calld_->backend_metric_data_;
-    }
+  grpc_closure* original_recv_initial_metadata_ready_ = nullptr;
+  grpc_closure recv_initial_metadata_ready_;
 
-    absl::string_view ExperimentalGetCallAttribute(const char* key) override {
-      auto it = calld_->call_attributes_.find(key);
-      if (it == calld_->call_attributes_.end()) return absl::string_view();
-      return it->second;
-    }
+  RefCountedPtr<DynamicFilters> dynamic_filters_;
+  RefCountedPtr<DynamicFilters::Call> dynamic_call_;
 
-   private:
-    CallData* calld_;
-  };
+  // Batches are added to this list when received from above.
+  // They are removed when we are done handling the batch (i.e., when
+  // either we have invoked all of the batch's callbacks or we have
+  // passed the batch down to the LB call and are not intercepting any of
+  // its callbacks).
+  grpc_transport_stream_op_batch* pending_batches_[MAX_PENDING_BATCHES] = {};
+
+  // Set when we get a cancel_stream op.
+  grpc_error* cancel_error_ = GRPC_ERROR_NONE;
+};
+
+//
+// RetryingCall definition
+//
+
+class RetryingCall {
+ public:
+  RetryingCall(
+      ChannelData* chand, const grpc_call_element_args& args,
+      grpc_polling_entity* pollent,
+      RefCountedPtr<ServerRetryThrottleData> retry_throttle_data,
+      const ClientChannelMethodParsedConfig::RetryPolicy* retry_policy);
+  ~RetryingCall();
+
+  void StartTransportStreamOpBatch(grpc_transport_stream_op_batch* batch);
 
+  RefCountedPtr<SubchannelCall> subchannel_call() const;
+
+ private:
   // State used for starting a retryable batch on a subchannel call.
   // This provides its own grpc_transport_stream_op_batch and other data
   // structures needed to populate the ops in the batch.
@@ -491,15 +561,15 @@ class CallData {
     // specified refcount.  If set_on_complete is true, the batch's
     // on_complete callback will be set to point to on_complete();
     // otherwise, the batch's on_complete callback will be null.
-    static SubchannelCallBatchData* Create(grpc_call_element* elem,
-                                           int refcount, bool set_on_complete);
+    static SubchannelCallBatchData* Create(RetryingCall* call, int refcount,
+                                           bool set_on_complete);
 
     void Unref() {
       if (gpr_unref(&refs)) Destroy();
     }
 
-    SubchannelCallBatchData(grpc_call_element* elem, CallData* calld,
-                            int refcount, bool set_on_complete);
+    SubchannelCallBatchData(RetryingCall* call, int refcount,
+                            bool set_on_complete);
     // All dtor code must be added in `Destroy()`. This is because we may
     // call closures in `SubchannelCallBatchData` after they are unrefed by
     // `Unref()`, and msan would complain about accessing this class
@@ -510,7 +580,8 @@ class CallData {
 
     gpr_refcount refs;
     grpc_call_element* elem;
-    RefCountedPtr<SubchannelCall> subchannel_call;
+    RetryingCall* call;
+    RefCountedPtr<LoadBalancedCall> lb_call;
     // The batch to use in the subchannel call.
     // Its payload field points to SubchannelCallRetryState::batch_payload.
     grpc_transport_stream_op_batch batch;
@@ -590,43 +661,32 @@ class CallData {
   // Pending batches stored in call data.
   struct PendingBatch {
     // The pending batch.  If nullptr, this slot is empty.
-    grpc_transport_stream_op_batch* batch;
+    grpc_transport_stream_op_batch* batch = nullptr;
     // Indicates whether payload for send ops has been cached in CallData.
-    bool send_ops_cached;
+    bool send_ops_cached = false;
   };
 
-  CallData(grpc_call_element* elem, const ChannelData& chand,
-           const grpc_call_element_args& args);
-  ~CallData();
-
   // Caches data for send ops so that it can be retried later, if not
   // already cached.
   void MaybeCacheSendOpsForBatch(PendingBatch* pending);
-  void FreeCachedSendInitialMetadata(ChannelData* chand);
+  void FreeCachedSendInitialMetadata();
   // Frees cached send_message at index idx.
-  void FreeCachedSendMessage(ChannelData* chand, size_t idx);
-  void FreeCachedSendTrailingMetadata(ChannelData* chand);
+  void FreeCachedSendMessage(size_t idx);
+  void FreeCachedSendTrailingMetadata();
   // Frees cached send ops that have already been completed after
   // committing the call.
-  void FreeCachedSendOpDataAfterCommit(grpc_call_element* elem,
-                                       SubchannelCallRetryState* retry_state);
+  void FreeCachedSendOpDataAfterCommit(SubchannelCallRetryState* retry_state);
   // Frees cached send ops that were completed by the completed batch in
   // batch_data.  Used when batches are completed after the call is committed.
   void FreeCachedSendOpDataForCompletedBatch(
-      grpc_call_element* elem, SubchannelCallBatchData* batch_data,
+      SubchannelCallBatchData* batch_data,
       SubchannelCallRetryState* retry_state);
 
-  static void RecvTrailingMetadataReadyForLoadBalancingPolicy(
-      void* arg, grpc_error* error);
-  void MaybeInjectRecvTrailingMetadataReadyForLoadBalancingPolicy(
-      grpc_transport_stream_op_batch* batch);
-
   // Returns the index into pending_batches_ to be used for batch.
   static size_t GetBatchIndex(grpc_transport_stream_op_batch* batch);
-  void PendingBatchesAdd(grpc_call_element* elem,
-                         grpc_transport_stream_op_batch* batch);
+  void PendingBatchesAdd(grpc_transport_stream_op_batch* batch);
   void PendingBatchClear(PendingBatch* pending);
-  void MaybeClearPendingBatch(grpc_call_element* elem, PendingBatch* pending);
+  void MaybeClearPendingBatch(PendingBatch* pending);
   static void FailPendingBatchInCallCombiner(void* arg, grpc_error* error);
   // A predicate type and some useful implementations for PendingBatchesFail().
   typedef bool (*YieldCallCombinerPredicate)(
@@ -645,26 +705,24 @@ class CallData {
   // If yield_call_combiner_predicate returns true, assumes responsibility for
   // yielding the call combiner.
   void PendingBatchesFail(
-      grpc_call_element* elem, grpc_error* error,
+      grpc_error* error,
       YieldCallCombinerPredicate yield_call_combiner_predicate);
   static void ResumePendingBatchInCallCombiner(void* arg, grpc_error* ignored);
-  // Resumes all pending batches on subchannel_call_.
-  void PendingBatchesResume(grpc_call_element* elem);
+  // Resumes all pending batches on lb_call_.
+  void PendingBatchesResume();
   // Returns a pointer to the first pending batch for which predicate(batch)
   // returns true, or null if not found.
   template <typename Predicate>
-  PendingBatch* PendingBatchFind(grpc_call_element* elem,
-                                 const char* log_message, Predicate predicate);
+  PendingBatch* PendingBatchFind(const char* log_message, Predicate predicate);
 
   // Commits the call so that no further retry attempts will be performed.
-  void RetryCommit(grpc_call_element* elem,
-                   SubchannelCallRetryState* retry_state);
+  void RetryCommit(SubchannelCallRetryState* retry_state);
   // Starts a retry after appropriate back-off.
-  void DoRetry(grpc_call_element* elem, SubchannelCallRetryState* retry_state,
+  void DoRetry(SubchannelCallRetryState* retry_state,
                grpc_millis server_pushback_ms);
   // Returns true if the call is being retried.
-  bool MaybeRetry(grpc_call_element* elem, SubchannelCallBatchData* batch_data,
-                  grpc_status_code status, grpc_mdelem* server_pushback_md);
+  bool MaybeRetry(SubchannelCallBatchData* batch_data, grpc_status_code status,
+                  grpc_mdelem* server_pushback_md);
 
   // Invokes recv_initial_metadata_ready for a subchannel batch.
   static void InvokeRecvInitialMetadataCallback(void* arg, grpc_error* error);
@@ -685,8 +743,8 @@ class CallData {
                      grpc_mdelem** server_pushback_md);
   // Adds recv_trailing_metadata_ready closure to closures.
   void AddClosureForRecvTrailingMetadataReady(
-      grpc_call_element* elem, SubchannelCallBatchData* batch_data,
-      grpc_error* error, CallCombinerClosureList* closures);
+      SubchannelCallBatchData* batch_data, grpc_error* error,
+      CallCombinerClosureList* closures);
   // Adds any necessary closures for deferred recv_initial_metadata and
   // recv_message callbacks to closures.
   static void AddClosuresForDeferredRecvCallbacks(
@@ -699,8 +757,8 @@ class CallData {
   // For any pending batch containing an op that has not yet been started,
   // adds the pending batch's completion closures to closures.
   void AddClosuresToFailUnstartedPendingBatches(
-      grpc_call_element* elem, SubchannelCallRetryState* retry_state,
-      grpc_error* error, CallCombinerClosureList* closures);
+      SubchannelCallRetryState* retry_state, grpc_error* error,
+      CallCombinerClosureList* closures);
   // Runs necessary closures upon completion of a call attempt.
   void RunClosuresForCompletedCall(SubchannelCallBatchData* batch_data,
                                    grpc_error* error);
@@ -710,8 +768,7 @@ class CallData {
 
   // Adds the on_complete closure for the pending batch completed in
   // batch_data to closures.
-  void AddClosuresForCompletedPendingBatch(grpc_call_element* elem,
-                                           SubchannelCallBatchData* batch_data,
+  void AddClosuresForCompletedPendingBatch(SubchannelCallBatchData* batch_data,
                                            grpc_error* error,
                                            CallCombinerClosureList* closures);
 
@@ -719,7 +776,7 @@ class CallData {
   // subchannel call, adds a closure to closures to invoke
   // StartRetriableSubchannelBatches().
   void AddClosuresForReplayOrPendingSendOps(
-      grpc_call_element* elem, SubchannelCallBatchData* batch_data,
+      SubchannelCallBatchData* batch_data,
       SubchannelCallRetryState* retry_state, CallCombinerClosureList* closures);
 
   // Callback used to intercept on_complete from subchannel calls.
@@ -728,15 +785,13 @@ class CallData {
 
   static void StartBatchInCallCombiner(void* arg, grpc_error* ignored);
   // Adds a closure to closures that will execute batch in the call combiner.
-  void AddClosureForSubchannelBatch(grpc_call_element* elem,
-                                    grpc_transport_stream_op_batch* batch,
+  void AddClosureForSubchannelBatch(grpc_transport_stream_op_batch* batch,
                                     CallCombinerClosureList* closures);
   // Adds retriable send_initial_metadata op to batch_data.
   void AddRetriableSendInitialMetadataOp(SubchannelCallRetryState* retry_state,
                                          SubchannelCallBatchData* batch_data);
   // Adds retriable send_message op to batch_data.
-  void AddRetriableSendMessageOp(grpc_call_element* elem,
-                                 SubchannelCallRetryState* retry_state,
+  void AddRetriableSendMessageOp(SubchannelCallRetryState* retry_state,
                                  SubchannelCallBatchData* batch_data);
   // Adds retriable send_trailing_metadata op to batch_data.
   void AddRetriableSendTrailingMetadataOp(SubchannelCallRetryState* retry_state,
@@ -754,42 +809,26 @@ class CallData {
   // is used in the case where a recv_initial_metadata or recv_message
   // op fails in a way that we know the call is over but when the application
   // has not yet started its own recv_trailing_metadata op.
-  void StartInternalRecvTrailingMetadata(grpc_call_element* elem);
+  void StartInternalRecvTrailingMetadata();
   // If there are any cached send ops that need to be replayed on the
   // current subchannel call, creates and returns a new subchannel batch
   // to replay those ops.  Otherwise, returns nullptr.
   SubchannelCallBatchData* MaybeCreateSubchannelBatchForReplay(
-      grpc_call_element* elem, SubchannelCallRetryState* retry_state);
+      SubchannelCallRetryState* retry_state);
   // Adds subchannel batches for pending batches to closures.
   void AddSubchannelBatchesForPendingBatches(
-      grpc_call_element* elem, SubchannelCallRetryState* retry_state,
-      CallCombinerClosureList* closures);
+      SubchannelCallRetryState* retry_state, CallCombinerClosureList* closures);
   // Constructs and starts whatever subchannel batches are needed on the
   // subchannel call.
   static void StartRetriableSubchannelBatches(void* arg, grpc_error* ignored);
 
-  void CreateSubchannelCall(grpc_call_element* elem);
-  // Invoked when a pick is completed, on both success or failure.
-  static void PickDone(void* arg, grpc_error* error);
-  // Removes the call from the channel's list of queued picks if present.
-  void MaybeRemoveCallFromQueuedPicksLocked(grpc_call_element* elem);
-  // Adds the call to the channel's list of queued picks if not already present.
-  void MaybeAddCallToQueuedPicksLocked(grpc_call_element* elem);
-  // Applies service config to the call.  Must be invoked once we know
-  // that the resolver has returned results to the channel.
-  // If an error is returned, the error indicates the status with which
-  // the call should be failed.
-  grpc_error* ApplyServiceConfigToCallLocked(
-      grpc_call_element* elem, grpc_metadata_batch* initial_metadata);
-  void MaybeInvokeConfigSelectorCommitCallback();
+  static void CreateLbCall(void* arg, grpc_error* error);
 
-  // State for handling deadlines.
-  // The code in deadline_filter.c requires this to be the first field.
-  // TODO(roth): This is slightly sub-optimal in that grpc_deadline_state
-  // and this struct both independently store pointers to the call stack
-  // and call combiner.  If/when we have time, find a way to avoid this
-  // without breaking the grpc_deadline_state abstraction.
-  grpc_deadline_state deadline_state_;
+  ChannelData* chand_;
+  grpc_polling_entity* pollent_;
+  RefCountedPtr<ServerRetryThrottleData> retry_throttle_data_;
+  const ClientChannelMethodParsedConfig::RetryPolicy* retry_policy_ = nullptr;
+  BackOff retry_backoff_;
 
   grpc_slice path_;  // Request path.
   gpr_cycle_counter call_start_time_;
@@ -799,53 +838,32 @@ class CallData {
   CallCombiner* call_combiner_;
   grpc_call_context_element* call_context_;
 
-  RefCountedPtr<ServerRetryThrottleData> retry_throttle_data_;
-  const ClientChannelMethodParsedConfig* method_params_ = nullptr;
-  std::map<const char*, absl::string_view> call_attributes_;
-  std::function<void()> on_call_committed_;
-
-  RefCountedPtr<SubchannelCall> subchannel_call_;
-
-  // Set when we get a cancel_stream op.
-  grpc_error* cancel_error_ = GRPC_ERROR_NONE;
-
-  ChannelData::QueuedPick pick_;
-  bool pick_queued_ = false;
-  bool service_config_applied_ = false;
-  QueuedPickCanceller* pick_canceller_ = nullptr;
-  LbCallState lb_call_state_;
-  const LoadBalancingPolicy::BackendMetricData* backend_metric_data_ = nullptr;
-  RefCountedPtr<ConnectedSubchannel> connected_subchannel_;
-  std::function<void(grpc_error*, LoadBalancingPolicy::MetadataInterface*,
-                     LoadBalancingPolicy::CallState*)>
-      lb_recv_trailing_metadata_ready_;
-  grpc_closure pick_closure_;
-
-  // For intercepting recv_trailing_metadata_ready for the LB policy.
-  grpc_metadata_batch* recv_trailing_metadata_ = nullptr;
-  grpc_closure recv_trailing_metadata_ready_;
-  grpc_closure* original_recv_trailing_metadata_ready_ = nullptr;
+  grpc_closure retry_closure_;
 
-  grpc_polling_entity* pollent_ = nullptr;
+  RefCountedPtr<LoadBalancedCall> lb_call_;
 
   // Batches are added to this list when received from above.
   // They are removed when we are done handling the batch (i.e., when
   // either we have invoked all of the batch's callbacks or we have
-  // passed the batch down to the subchannel call and are not
-  // intercepting any of its callbacks).
-  PendingBatch pending_batches_[MAX_PENDING_BATCHES] = {};
+  // passed the batch down to the LB call and are not intercepting any of
+  // its callbacks).
+  // TODO(roth): Now that the retry code is split out into its own call
+  // object, revamp this to work in a cleaner way, since we no longer need
+  // for batches to ever wait for name resolution or LB picks.
+  PendingBatch pending_batches_[MAX_PENDING_BATCHES];
   bool pending_send_initial_metadata_ : 1;
   bool pending_send_message_ : 1;
   bool pending_send_trailing_metadata_ : 1;
 
+  // Set when we get a cancel_stream op.
+  grpc_error* cancel_error_ = GRPC_ERROR_NONE;
+
   // Retry state.
   bool enable_retries_ : 1;
   bool retry_committed_ : 1;
   bool last_attempt_got_server_pushback_ : 1;
   int num_attempts_completed_ = 0;
   size_t bytes_buffered_for_retry_ = 0;
-  // TODO(roth): Restructure this to eliminate use of ManualConstructor.
-  ManualConstructor<BackOff> retry_backoff_;
   grpc_timer retry_timer_;
 
   // The number of pending retriable subchannel batches containing send ops.
@@ -879,55 +897,403 @@ class CallData {
 };
 
 //
-// ChannelData::SubchannelWrapper
+// LoadBalancedCall definition
 //
 
-// This class is a wrapper for Subchannel that hides details of the
-// channel's implementation (such as the health check service name and
-// connected subchannel) from the LB policy API.
-//
-// Note that no synchronization is needed here, because even if the
-// underlying subchannel is shared between channels, this wrapper will only
-// be used within one channel, so it will always be synchronized by the
-// control plane work_serializer.
-class ChannelData::SubchannelWrapper : public SubchannelInterface {
+// This object is ref-counted, but it cannot inherit from RefCounted<>,
+// because it is allocated on the arena and can't free its memory when
+// its refcount goes to zero.  So instead, it manually implements the
+// same API as RefCounted<>, so that it can be used with RefCountedPtr<>.
+class LoadBalancedCall {
  public:
-  SubchannelWrapper(ChannelData* chand, Subchannel* subchannel,
-                    grpc_core::UniquePtr<char> health_check_service_name)
-      : SubchannelInterface(
-            GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_routing_trace)
-                ? "SubchannelWrapper"
-                : nullptr),
-        chand_(chand),
-        subchannel_(subchannel),
-        health_check_service_name_(std::move(health_check_service_name)) {
-    if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_routing_trace)) {
-      gpr_log(GPR_INFO,
-              "chand=%p: creating subchannel wrapper %p for subchannel %p",
-              chand, this, subchannel_);
-    }
-    GRPC_CHANNEL_STACK_REF(chand_->owning_stack_, "SubchannelWrapper");
-    auto* subchannel_node = subchannel_->channelz_node();
-    if (subchannel_node != nullptr) {
-      auto it = chand_->subchannel_refcount_map_.find(subchannel_);
-      if (it == chand_->subchannel_refcount_map_.end()) {
-        chand_->channelz_node_->AddChildSubchannel(subchannel_node->uuid());
-        it = chand_->subchannel_refcount_map_.emplace(subchannel_, 0).first;
-      }
-      ++it->second;
-    }
-    chand_->subchannel_wrappers_.insert(this);
-  }
+  static RefCountedPtr<LoadBalancedCall> Create(
+      ChannelData* chand, const grpc_call_element_args& args,
+      grpc_polling_entity* pollent, size_t parent_data_size);
 
-  ~SubchannelWrapper() override {
-    if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_routing_trace)) {
-      gpr_log(GPR_INFO,
-              "chand=%p: destroying subchannel wrapper %p for subchannel %p",
-              chand_, this, subchannel_);
-    }
-    chand_->subchannel_wrappers_.erase(this);
-    auto* subchannel_node = subchannel_->channelz_node();
-    if (subchannel_node != nullptr) {
+  LoadBalancedCall(ChannelData* chand, const grpc_call_element_args& args,
+                   grpc_polling_entity* pollent);
+  ~LoadBalancedCall();
+
+  // Interface of RefCounted<>.
+  RefCountedPtr<LoadBalancedCall> Ref() GRPC_MUST_USE_RESULT;
+  RefCountedPtr<LoadBalancedCall> Ref(const DebugLocation& location,
+                                      const char* reason) GRPC_MUST_USE_RESULT;
+  // When refcount drops to 0, destroys itself and the associated call stack,
+  // but does NOT free the memory because it's in the call arena.
+  void Unref();
+  void Unref(const DebugLocation& location, const char* reason);
+
+  void* GetParentData();
+
+  void StartTransportStreamOpBatch(grpc_transport_stream_op_batch* batch);
+
+  // Invoked by channel for queued LB picks when the picker is updated.
+  static void PickSubchannel(void* arg, grpc_error* error);
+  // Helper function for performing an LB pick while holding the data plane
+  // mutex.  Returns true if the pick is complete, in which case the caller
+  // must invoke PickDone() or AsyncPickDone() with the returned error.
+  bool PickSubchannelLocked(grpc_error** error);
+  // Schedules a callback to process the completed pick.  The callback
+  // will not run until after this method returns.
+  void AsyncPickDone(grpc_error* error);
+
+  RefCountedPtr<SubchannelCall> subchannel_call() const {
+    return subchannel_call_;
+  }
+
+ private:
+  // Allow RefCountedPtr<> to access IncrementRefCount().
+  template <typename T>
+  friend class ::grpc_core::RefCountedPtr;
+
+  class LbQueuedCallCanceller;
+  class Metadata;
+  class LbCallState;
+
+  // Interface of RefCounted<>.
+  void IncrementRefCount();
+  void IncrementRefCount(const DebugLocation& location, const char* reason);
+
+  // Returns the index into pending_batches_ to be used for batch.
+  static size_t GetBatchIndex(grpc_transport_stream_op_batch* batch);
+  void PendingBatchesAdd(grpc_transport_stream_op_batch* batch);
+  static void FailPendingBatchInCallCombiner(void* arg, grpc_error* error);
+  // A predicate type and some useful implementations for PendingBatchesFail().
+  typedef bool (*YieldCallCombinerPredicate)(
+      const CallCombinerClosureList& closures);
+  static bool YieldCallCombiner(const CallCombinerClosureList& /*closures*/) {
+    return true;
+  }
+  static bool NoYieldCallCombiner(const CallCombinerClosureList& /*closures*/) {
+    return false;
+  }
+  static bool YieldCallCombinerIfPendingBatchesFound(
+      const CallCombinerClosureList& closures) {
+    return closures.size() > 0;
+  }
+  // Fails all pending batches.
+  // If yield_call_combiner_predicate returns true, assumes responsibility for
+  // yielding the call combiner.
+  void PendingBatchesFail(
+      grpc_error* error,
+      YieldCallCombinerPredicate yield_call_combiner_predicate);
+  static void ResumePendingBatchInCallCombiner(void* arg, grpc_error* ignored);
+  // Resumes all pending batches on subchannel_call_.
+  void PendingBatchesResume();
+
+  static void RecvTrailingMetadataReadyForLoadBalancingPolicy(
+      void* arg, grpc_error* error);
+  void InjectRecvTrailingMetadataReadyForLoadBalancingPolicy(
+      grpc_transport_stream_op_batch* batch);
+
+  void CreateSubchannelCall();
+  // Invoked when a pick is completed, on both success or failure.
+  static void PickDone(void* arg, grpc_error* error);
+  // Removes the call from the channel's list of queued picks if present.
+  void MaybeRemoveCallFromLbQueuedCallsLocked();
+  // Adds the call to the channel's list of queued picks if not already present.
+  void MaybeAddCallToLbQueuedCallsLocked();
+
+  RefCount refs_;
+
+  ChannelData* chand_;
+
+  // TODO(roth): Instead of duplicating these fields in every filter
+  // that uses any one of them, we should store them in the call
+  // context.  This will save per-call memory overhead.
+  grpc_slice path_;  // Request path.
+  gpr_cycle_counter call_start_time_;
+  grpc_millis deadline_;
+  Arena* arena_;
+  grpc_call_stack* owning_call_;
+  CallCombiner* call_combiner_;
+  grpc_call_context_element* call_context_;
+
+  // Set when we get a cancel_stream op.
+  grpc_error* cancel_error_ = GRPC_ERROR_NONE;
+
+  grpc_polling_entity* pollent_ = nullptr;
+
+  grpc_closure pick_closure_;
+
+  // Accessed while holding ChannelData::data_plane_mu_.
+  ChannelData::LbQueuedCall queued_call_;
+  bool queued_pending_lb_pick_ = false;
+  const LoadBalancingPolicy::BackendMetricData* backend_metric_data_ = nullptr;
+  RefCountedPtr<ConnectedSubchannel> connected_subchannel_;
+  std::function<void(grpc_error*, LoadBalancingPolicy::MetadataInterface*,
+                     LoadBalancingPolicy::CallState*)>
+      lb_recv_trailing_metadata_ready_;
+  LbQueuedCallCanceller* lb_call_canceller_ = nullptr;
+
+  RefCountedPtr<SubchannelCall> subchannel_call_;
+
+  // For intercepting recv_trailing_metadata_ready for the LB policy.
+  grpc_metadata_batch* recv_trailing_metadata_ = nullptr;
+  grpc_closure recv_trailing_metadata_ready_;
+  grpc_closure* original_recv_trailing_metadata_ready_ = nullptr;
+
+  // Batches are added to this list when received from above.
+  // They are removed when we are done handling the batch (i.e., when
+  // either we have invoked all of the batch's callbacks or we have
+  // passed the batch down to the subchannel call and are not
+  // intercepting any of its callbacks).
+  grpc_transport_stream_op_batch* pending_batches_[MAX_PENDING_BATCHES] = {};
+};
+
+//
+// dynamic termination filter
+//
+
+// Channel arg pointer vtable for GRPC_ARG_CLIENT_CHANNEL_DATA.
+void* ChannelDataArgCopy(void* p) { return p; }
+void ChannelDataArgDestroy(void* p) {}
+int ChannelDataArgCmp(void* p, void* q) { return GPR_ICMP(p, q); }
+const grpc_arg_pointer_vtable kChannelDataArgPointerVtable = {
+    ChannelDataArgCopy, ChannelDataArgDestroy, ChannelDataArgCmp};
+
+// Channel arg pointer vtable for GRPC_ARG_RETRY_THROTTLE_DATA.
+void* RetryThrottleDataArgCopy(void* p) {
+  auto* retry_throttle_data = static_cast<ServerRetryThrottleData*>(p);
+  retry_throttle_data->Ref().release();
+  return p;
+}
+void RetryThrottleDataArgDestroy(void* p) {
+  auto* retry_throttle_data = static_cast<ServerRetryThrottleData*>(p);
+  retry_throttle_data->Unref();
+}
+int RetryThrottleDataArgCmp(void* p, void* q) { return GPR_ICMP(p, q); }
+const grpc_arg_pointer_vtable kRetryThrottleDataArgPointerVtable = {
+    RetryThrottleDataArgCopy, RetryThrottleDataArgDestroy,
+    RetryThrottleDataArgCmp};
+
+class DynamicTerminationFilterChannelData {
+ public:
+  static grpc_error* Init(grpc_channel_element* elem,
+                          grpc_channel_element_args* args);
+
+  static void Destroy(grpc_channel_element* elem) {
+    auto* chand =
+        static_cast<DynamicTerminationFilterChannelData*>(elem->channel_data);
+    chand->~DynamicTerminationFilterChannelData();
+  }
+
+  // Will never be called.
+  static void StartTransportOp(grpc_channel_element* elem,
+                               grpc_transport_op* op) {}
+  static void GetChannelInfo(grpc_channel_element* elem,
+                             const grpc_channel_info* info) {}
+
+  ChannelData* chand() const { return chand_; }
+  RefCountedPtr<ServerRetryThrottleData> retry_throttle_data() const {
+    return retry_throttle_data_;
+  }
+
+ private:
+  static RefCountedPtr<ServerRetryThrottleData> GetRetryThrottleDataFromArgs(
+      const grpc_channel_args* args) {
+    auto* retry_throttle_data =
+        grpc_channel_args_find_pointer<ServerRetryThrottleData>(
+            args, GRPC_ARG_RETRY_THROTTLE_DATA);
+    if (retry_throttle_data == nullptr) return nullptr;
+    return retry_throttle_data->Ref();
+  }
+
+  explicit DynamicTerminationFilterChannelData(const grpc_channel_args* args)
+      : chand_(grpc_channel_args_find_pointer<ChannelData>(
+            args, GRPC_ARG_CLIENT_CHANNEL_DATA)),
+        retry_throttle_data_(GetRetryThrottleDataFromArgs(args)) {}
+
+  ChannelData* chand_;
+  RefCountedPtr<ServerRetryThrottleData> retry_throttle_data_;
+};
+
+class DynamicTerminationFilterCallData {
+ public:
+  static grpc_error* Init(grpc_call_element* elem,
+                          const grpc_call_element_args* args) {
+    new (elem->call_data) DynamicTerminationFilterCallData(*args);
+    return GRPC_ERROR_NONE;
+  }
+
+  static void Destroy(grpc_call_element* elem,
+                      const grpc_call_final_info* final_info,
+                      grpc_closure* then_schedule_closure) {
+    auto* calld =
+        static_cast<DynamicTerminationFilterCallData*>(elem->call_data);
+    auto* chand =
+        static_cast<DynamicTerminationFilterChannelData*>(elem->channel_data);
+    RefCountedPtr<SubchannelCall> subchannel_call;
+    if (chand->chand()->enable_retries()) {
+      if (GPR_LIKELY(calld->retrying_call_ != nullptr)) {
+        subchannel_call = calld->retrying_call_->subchannel_call();
+        calld->retrying_call_->~RetryingCall();
+      }
+    } else {
+      if (GPR_LIKELY(calld->lb_call_ != nullptr)) {
+        subchannel_call = calld->lb_call_->subchannel_call();
+      }
+    }
+    calld->~DynamicTerminationFilterCallData();
+    if (GPR_LIKELY(subchannel_call != nullptr)) {
+      subchannel_call->SetAfterCallStackDestroy(then_schedule_closure);
+    } else {
+      // TODO(yashkt) : This can potentially be a Closure::Run
+      ExecCtx::Run(DEBUG_LOCATION, then_schedule_closure, GRPC_ERROR_NONE);
+    }
+  }
+
+  static void StartTransportStreamOpBatch(
+      grpc_call_element* elem, grpc_transport_stream_op_batch* batch) {
+    auto* calld =
+        static_cast<DynamicTerminationFilterCallData*>(elem->call_data);
+    auto* chand =
+        static_cast<DynamicTerminationFilterChannelData*>(elem->channel_data);
+    if (chand->chand()->enable_retries()) {
+      calld->retrying_call_->StartTransportStreamOpBatch(batch);
+    } else {
+      calld->lb_call_->StartTransportStreamOpBatch(batch);
+    }
+  }
+
+  static void SetPollent(grpc_call_element* elem,
+                         grpc_polling_entity* pollent) {
+    auto* calld =
+        static_cast<DynamicTerminationFilterCallData*>(elem->call_data);
+    auto* chand =
+        static_cast<DynamicTerminationFilterChannelData*>(elem->channel_data);
+    ChannelData* client_channel = chand->chand();
+    grpc_call_element_args args = {
+        calld->owning_call_,     nullptr,
+        calld->call_context_,    calld->path_,
+        calld->call_start_time_, calld->deadline_,
+        calld->arena_,           calld->call_combiner_};
+    if (client_channel->enable_retries()) {
+      // Get retry settings from service config.
+      auto* svc_cfg_call_data = static_cast<ServiceConfigCallData*>(
+          calld->call_context_[GRPC_CONTEXT_SERVICE_CONFIG_CALL_DATA].value);
+      GPR_ASSERT(svc_cfg_call_data != nullptr);
+      auto* method_config = static_cast<const ClientChannelMethodParsedConfig*>(
+          svc_cfg_call_data->GetMethodParsedConfig(
+              ClientChannelServiceConfigParser::ParserIndex()));
+      // Create retrying call.
+      calld->retrying_call_ = calld->arena_->New<RetryingCall>(
+          client_channel, args, pollent, chand->retry_throttle_data(),
+          method_config == nullptr ? nullptr : method_config->retry_policy());
+      if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_routing_trace)) {
+        gpr_log(
+            GPR_INFO,
+            "chand=%p dymamic_termination_calld=%p: create retrying_call=%p",
+            client_channel, calld, calld->retrying_call_);
+      }
+    } else {
+      calld->lb_call_ =
+          LoadBalancedCall::Create(client_channel, args, pollent, 0);
+      if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_routing_trace)) {
+        gpr_log(GPR_INFO,
+                "chand=%p dynamic_termination_calld=%p: create lb_call=%p",
+                chand, client_channel, calld->lb_call_.get());
+      }
+    }
+  }
+
+ private:
+  explicit DynamicTerminationFilterCallData(const grpc_call_element_args& args)
+      : path_(grpc_slice_ref_internal(args.path)),
+        call_start_time_(args.start_time),
+        deadline_(args.deadline),
+        arena_(args.arena),
+        owning_call_(args.call_stack),
+        call_combiner_(args.call_combiner),
+        call_context_(args.context) {}
+
+  ~DynamicTerminationFilterCallData() { grpc_slice_unref_internal(path_); }
+
+  grpc_slice path_;  // Request path.
+  gpr_cycle_counter call_start_time_;
+  grpc_millis deadline_;
+  Arena* arena_;
+  grpc_call_stack* owning_call_;
+  CallCombiner* call_combiner_;
+  grpc_call_context_element* call_context_;
+
+  RetryingCall* retrying_call_ = nullptr;
+  RefCountedPtr<LoadBalancedCall> lb_call_;
+};
+
+const grpc_channel_filter kDynamicTerminationFilterVtable = {
+    DynamicTerminationFilterCallData::StartTransportStreamOpBatch,
+    DynamicTerminationFilterChannelData::StartTransportOp,
+    sizeof(DynamicTerminationFilterCallData),
+    DynamicTerminationFilterCallData::Init,
+    DynamicTerminationFilterCallData::SetPollent,
+    DynamicTerminationFilterCallData::Destroy,
+    sizeof(DynamicTerminationFilterChannelData),
+    DynamicTerminationFilterChannelData::Init,
+    DynamicTerminationFilterChannelData::Destroy,
+    DynamicTerminationFilterChannelData::GetChannelInfo,
+    "dynamic_filter_termination",
+};
+
+grpc_error* DynamicTerminationFilterChannelData::Init(
+    grpc_channel_element* elem, grpc_channel_element_args* args) {
+  GPR_ASSERT(args->is_last);
+  GPR_ASSERT(elem->filter == &kDynamicTerminationFilterVtable);
+  new (elem->channel_data)
+      DynamicTerminationFilterChannelData(args->channel_args);
+  return GRPC_ERROR_NONE;
+}
+
+//
+// ChannelData::SubchannelWrapper
+//
+
+// This class is a wrapper for Subchannel that hides details of the
+// channel's implementation (such as the health check service name and
+// connected subchannel) from the LB policy API.
+//
+// Note that no synchronization is needed here, because even if the
+// underlying subchannel is shared between channels, this wrapper will only
+// be used within one channel, so it will always be synchronized by the
+// control plane work_serializer.
+class ChannelData::SubchannelWrapper : public SubchannelInterface {
+ public:
+  SubchannelWrapper(ChannelData* chand, Subchannel* subchannel,
+                    absl::optional<std::string> health_check_service_name)
+      : SubchannelInterface(
+            GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_routing_trace)
+                ? "SubchannelWrapper"
+                : nullptr),
+        chand_(chand),
+        subchannel_(subchannel),
+        health_check_service_name_(std::move(health_check_service_name)) {
+    if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_routing_trace)) {
+      gpr_log(GPR_INFO,
+              "chand=%p: creating subchannel wrapper %p for subchannel %p",
+              chand, this, subchannel_);
+    }
+    GRPC_CHANNEL_STACK_REF(chand_->owning_stack_, "SubchannelWrapper");
+    auto* subchannel_node = subchannel_->channelz_node();
+    if (subchannel_node != nullptr) {
+      auto it = chand_->subchannel_refcount_map_.find(subchannel_);
+      if (it == chand_->subchannel_refcount_map_.end()) {
+        chand_->channelz_node_->AddChildSubchannel(subchannel_node->uuid());
+        it = chand_->subchannel_refcount_map_.emplace(subchannel_, 0).first;
+      }
+      ++it->second;
+    }
+    chand_->subchannel_wrappers_.insert(this);
+  }
+
+  ~SubchannelWrapper() override {
+    if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_routing_trace)) {
+      gpr_log(GPR_INFO,
+              "chand=%p: destroying subchannel wrapper %p for subchannel %p",
+              chand_, this, subchannel_);
+    }
+    chand_->subchannel_wrappers_.erase(this);
+    auto* subchannel_node = subchannel_->channelz_node();
+    if (subchannel_node != nullptr) {
       auto it = chand_->subchannel_refcount_map_.find(subchannel_);
       GPR_ASSERT(it != chand_->subchannel_refcount_map_.end());
       --it->second;
@@ -943,7 +1309,7 @@ class ChannelData::SubchannelWrapper : public SubchannelInterface {
   grpc_connectivity_state CheckConnectivityState() override {
     RefCountedPtr<ConnectedSubchannel> connected_subchannel;
     grpc_connectivity_state connectivity_state =
-        subchannel_->CheckConnectivityState(health_check_service_name_.get(),
+        subchannel_->CheckConnectivityState(health_check_service_name_,
                                             &connected_subchannel);
     MaybeUpdateConnectedSubchannel(std::move(connected_subchannel));
     return connectivity_state;
@@ -958,9 +1324,7 @@ class ChannelData::SubchannelWrapper : public SubchannelInterface {
                                          Ref(DEBUG_LOCATION, "WatcherWrapper"),
                                          initial_state);
     subchannel_->WatchConnectivityState(
-        initial_state,
-        grpc_core::UniquePtr<char>(
-            gpr_strdup(health_check_service_name_.get())),
+        initial_state, health_check_service_name_,
         RefCountedPtr<Subchannel::ConnectivityStateWatcherInterface>(
             watcher_wrapper));
   }
@@ -969,7 +1333,7 @@ class ChannelData::SubchannelWrapper : public SubchannelInterface {
       ConnectivityStateWatcherInterface* watcher) override {
     auto it = watcher_map_.find(watcher);
     GPR_ASSERT(it != watcher_map_.end());
-    subchannel_->CancelConnectivityStateWatch(health_check_service_name_.get(),
+    subchannel_->CancelConnectivityStateWatch(health_check_service_name_,
                                               it->second);
     watcher_map_.erase(it);
   }
@@ -987,13 +1351,13 @@ class ChannelData::SubchannelWrapper : public SubchannelInterface {
   }
 
   void UpdateHealthCheckServiceName(
-      grpc_core::UniquePtr<char> health_check_service_name) {
+      absl::optional<std::string> health_check_service_name) {
     if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_routing_trace)) {
       gpr_log(GPR_INFO,
               "chand=%p: subchannel wrapper %p: updating health check service "
               "name from \"%s\" to \"%s\"",
-              chand_, this, health_check_service_name_.get(),
-              health_check_service_name.get());
+              chand_, this, health_check_service_name_->c_str(),
+              health_check_service_name->c_str());
     }
     for (auto& p : watcher_map_) {
       WatcherWrapper*& watcher_wrapper = p.second;
@@ -1008,13 +1372,11 @@ class ChannelData::SubchannelWrapper : public SubchannelInterface {
       // problem, we may be able to handle it by waiting for the new
       // watcher to report READY before we use it to replace the old one.
       WatcherWrapper* replacement = watcher_wrapper->MakeReplacement();
-      subchannel_->CancelConnectivityStateWatch(
-          health_check_service_name_.get(), watcher_wrapper);
+      subchannel_->CancelConnectivityStateWatch(health_check_service_name_,
+                                                watcher_wrapper);
       watcher_wrapper = replacement;
       subchannel_->WatchConnectivityState(
-          replacement->last_seen_state(),
-          grpc_core::UniquePtr<char>(
-              gpr_strdup(health_check_service_name.get())),
+          replacement->last_seen_state(), health_check_service_name,
           RefCountedPtr<Subchannel::ConnectivityStateWatcherInterface>(
               replacement));
     }
@@ -1113,7 +1475,7 @@ class ChannelData::SubchannelWrapper : public SubchannelInterface {
       }
       ConnectivityStateChange state_change = PopConnectivityStateChange();
       absl::optional<absl::Cord> keepalive_throttling =
-          state_change.status.GetPayload(grpc_core::kKeepaliveThrottlingKey);
+          state_change.status.GetPayload(kKeepaliveThrottlingKey);
       if (keepalive_throttling.has_value()) {
         int new_keepalive_time = -1;
         if (absl::SimpleAtoi(std::string(keepalive_throttling.value()),
@@ -1178,7 +1540,7 @@ class ChannelData::SubchannelWrapper : public SubchannelInterface {
 
   ChannelData* chand_;
   Subchannel* subchannel_;
-  grpc_core::UniquePtr<char> health_check_service_name_;
+  absl::optional<std::string> health_check_service_name_;
   // Maps from the address of the watcher passed to us by the LB policy
   // to the address of the WrapperWatcher that we passed to the underlying
   // subchannel.  This is needed so that when the LB policy calls
@@ -1367,13 +1729,13 @@ class ChannelData::ClientChannelControlHelper
 
   RefCountedPtr<SubchannelInterface> CreateSubchannel(
       ServerAddress address, const grpc_channel_args& args) override {
+    if (chand_->resolver_ == nullptr) return nullptr;  // Shutting down.
     // Determine health check service name.
     bool inhibit_health_checking = grpc_channel_arg_get_bool(
         grpc_channel_args_find(&args, GRPC_ARG_INHIBIT_HEALTH_CHECKING), false);
-    grpc_core::UniquePtr<char> health_check_service_name;
+    absl::optional<std::string> health_check_service_name;
     if (!inhibit_health_checking) {
-      health_check_service_name.reset(
-          gpr_strdup(chand_->health_check_service_name_.get()));
+      health_check_service_name = chand_->health_check_service_name_;
     }
     // Remove channel args that should not affect subchannel uniqueness.
     static const char* args_to_remove[] = {
@@ -1410,6 +1772,7 @@ class ChannelData::ClientChannelControlHelper
   void UpdateState(
       grpc_connectivity_state state, const absl::Status& status,
       std::unique_ptr<LoadBalancingPolicy::SubchannelPicker> picker) override {
+    if (chand_->resolver_ == nullptr) return;  // Shutting down.
     grpc_error* disconnect_error = chand_->disconnect_error();
     if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_routing_trace)) {
       const char* extra = disconnect_error == GRPC_ERROR_NONE
@@ -1426,11 +1789,17 @@ class ChannelData::ClientChannelControlHelper
     }
   }
 
-  // No-op -- we should never get this from ResolvingLoadBalancingPolicy.
-  void RequestReresolution() override {}
+  void RequestReresolution() override {
+    if (chand_->resolver_ == nullptr) return;  // Shutting down.
+    if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_routing_trace)) {
+      gpr_log(GPR_INFO, "chand=%p: started name re-resolving", chand_);
+    }
+    chand_->resolver_->RequestReresolutionLocked();
+  }
 
   void AddTraceEvent(TraceSeverity severity,
                      absl::string_view message) override {
+    if (chand_->resolver_ == nullptr) return;  // Shutting down.
     if (chand_->channelz_node_ != nullptr) {
       chand_->channelz_node_->AddTraceEvent(
           ConvertSeverityEnum(severity),
@@ -1450,140 +1819,7 @@ class ChannelData::ClientChannelControlHelper
 };
 
 //
-// ChannelData::ChannelConfigHelper
-//
-
-ChannelData::ChannelConfigHelper::ChooseServiceConfigResult
-ChannelData::ChannelConfigHelper::ChooseServiceConfig(
-    const Resolver::Result& result) {
-  ChooseServiceConfigResult service_config_result;
-  RefCountedPtr<ServiceConfig> service_config;
-  RefCountedPtr<ConfigSelector> config_selector;
-  if (result.service_config_error != GRPC_ERROR_NONE) {
-    if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_routing_trace)) {
-      gpr_log(GPR_INFO, "chand=%p: resolver returned service config error: %s",
-              chand_, grpc_error_string(result.service_config_error));
-    }
-    // If the service config was invalid, then fallback to the
-    // previously returned service config.
-    if (chand_->saved_service_config_ != nullptr) {
-      if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_routing_trace)) {
-        gpr_log(GPR_INFO,
-                "chand=%p: resolver returned invalid service config. "
-                "Continuing to use previous service config.",
-                chand_);
-      }
-      service_config = chand_->saved_service_config_;
-      config_selector = chand_->saved_config_selector_;
-    } else {
-      // No previously returned config, so put the channel into
-      // TRANSIENT_FAILURE.
-      service_config_result.no_valid_service_config = true;
-      return service_config_result;
-    }
-  } else if (result.service_config == nullptr) {
-    // Resolver did not return any service config.
-    if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_routing_trace)) {
-      gpr_log(GPR_INFO,
-              "chand=%p: resolver returned no service config. Using default "
-              "service config for channel.",
-              chand_);
-    }
-    service_config = chand_->default_service_config_;
-  } else {
-    // Use ServiceConfig and ConfigSelector returned by resolver.
-    service_config = result.service_config;
-    config_selector = ConfigSelector::GetFromChannelArgs(*result.args);
-  }
-  GPR_ASSERT(service_config != nullptr);
-  // Extract global config for client channel.
-  const internal::ClientChannelGlobalParsedConfig* parsed_service_config =
-      static_cast<const internal::ClientChannelGlobalParsedConfig*>(
-          service_config->GetGlobalParsedConfig(
-              internal::ClientChannelServiceConfigParser::ParserIndex()));
-  // Find LB policy config.
-  ChooseLbPolicy(result, parsed_service_config,
-                 &service_config_result.lb_policy_config);
-  // Check if the ServiceConfig has changed.
-  const bool service_config_changed =
-      chand_->saved_service_config_ == nullptr ||
-      service_config->json_string() !=
-          chand_->saved_service_config_->json_string();
-  // Check if the ConfigSelector has changed.
-  const bool config_selector_changed = !ConfigSelector::Equals(
-      chand_->saved_config_selector_.get(), config_selector.get());
-  // Indicate a change if either the ServiceConfig or ConfigSelector have
-  // changed.
-  service_config_result.service_config_changed =
-      service_config_changed || config_selector_changed;
-  // If it has, apply the global parameters now.
-  if (service_config_result.service_config_changed) {
-    chand_->UpdateServiceConfigInControlPlaneLocked(
-        std::move(service_config), std::move(config_selector),
-        parsed_service_config, service_config_result.lb_policy_config->name());
-  }
-  // Return results.
-  return service_config_result;
-}
-
-void ChannelData::ChannelConfigHelper::StartUsingServiceConfigForCalls() {
-  chand_->UpdateServiceConfigInDataPlaneLocked();
-}
-
-void ChannelData::ChannelConfigHelper::ResolverTransientFailure(
-    grpc_error* error) {
-  MutexLock lock(&chand_->data_plane_mu_);
-  GRPC_ERROR_UNREF(chand_->resolver_transient_failure_error_);
-  chand_->resolver_transient_failure_error_ = error;
-}
-
-void ChannelData::ChannelConfigHelper::ChooseLbPolicy(
-    const Resolver::Result& resolver_result,
-    const internal::ClientChannelGlobalParsedConfig* parsed_service_config,
-    RefCountedPtr<LoadBalancingPolicy::Config>* lb_policy_config) {
-  // Prefer the LB policy config found in the service config.
-  if (parsed_service_config->parsed_lb_config() != nullptr) {
-    *lb_policy_config = parsed_service_config->parsed_lb_config();
-    return;
-  }
-  // Try the deprecated LB policy name from the service config.
-  // If not, try the setting from channel args.
-  const char* policy_name = nullptr;
-  if (!parsed_service_config->parsed_deprecated_lb_policy().empty()) {
-    policy_name = parsed_service_config->parsed_deprecated_lb_policy().c_str();
-  } else {
-    const grpc_arg* channel_arg =
-        grpc_channel_args_find(resolver_result.args, GRPC_ARG_LB_POLICY_NAME);
-    policy_name = grpc_channel_arg_get_string(channel_arg);
-  }
-  // Use pick_first if nothing was specified and we didn't select grpclb
-  // above.
-  if (policy_name == nullptr) policy_name = "pick_first";
-  // Now that we have the policy name, construct an empty config for it.
-  Json config_json = Json::Array{Json::Object{
-      {policy_name, Json::Object{}},
-  }};
-  grpc_error* parse_error = GRPC_ERROR_NONE;
-  *lb_policy_config = LoadBalancingPolicyRegistry::ParseLoadBalancingConfig(
-      config_json, &parse_error);
-  // The policy name came from one of three places:
-  // - The deprecated loadBalancingPolicy field in the service config,
-  //   in which case the code in ClientChannelServiceConfigParser
-  //   already verified that the policy does not require a config.
-  // - One of the hard-coded values here, all of which are known to not
-  //   require a config.
-  // - A channel arg, in which case the application did something that
-  //   is a misuse of our API.
-  // In the first two cases, these assertions will always be true.  In
-  // the last case, this is probably fine for now.
-  // TODO(roth): If the last case becomes a problem, add better error
-  // handling here.
-  GPR_ASSERT(*lb_policy_config != nullptr);
-  GPR_ASSERT(parse_error == GRPC_ERROR_NONE);
-}
-
-//
-// ChannelData implementation
+// ChannelData implementation
 //
 
 grpc_error* ChannelData::Init(grpc_channel_element* elem,
@@ -1640,11 +1876,10 @@ ChannelData::ChannelData(grpc_channel_element_args* args, grpc_error** error)
       client_channel_factory_(
           ClientChannelFactory::GetFromChannelArgs(args->channel_args)),
       channelz_node_(GetChannelzNode(args->channel_args)),
-      channel_config_helper_(this),
       work_serializer_(std::make_shared<WorkSerializer>()),
       interested_parties_(grpc_pollset_set_create()),
-      subchannel_pool_(GetSubchannelPool(args->channel_args)),
       state_tracker_("client_channel", GRPC_CHANNEL_IDLE),
+      subchannel_pool_(GetSubchannelPool(args->channel_args)),
       disconnect_error_(GRPC_ERROR_NONE) {
   if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_routing_trace)) {
     gpr_log(GPR_INFO, "chand=%p: creating client_channel for channel stack %p",
@@ -1681,12 +1916,10 @@ ChannelData::ChannelData(grpc_channel_element_args* args, grpc_error** error)
     default_service_config_.reset();
     return;
   }
-  grpc_uri* uri = grpc_uri_parse(server_uri, true);
-  if (uri != nullptr && uri->path[0] != '\0') {
-    server_name_.reset(
-        gpr_strdup(uri->path[0] == '/' ? uri->path + 1 : uri->path));
+  absl::StatusOr<URI> uri = URI::Parse(server_uri);
+  if (uri.ok() && !uri->path().empty()) {
+    server_name_ = std::string(absl::StripPrefix(uri->path(), "/"));
   }
-  grpc_uri_destroy(uri);
   char* proxy_name = nullptr;
   grpc_channel_args* new_args = nullptr;
   ProxyMapperRegistry::MapName(server_uri, args->channel_args, &proxy_name,
@@ -1715,7 +1948,7 @@ ChannelData::~ChannelData() {
   if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_routing_trace)) {
     gpr_log(GPR_INFO, "chand=%p: destroying channel", this);
   }
-  DestroyResolvingLoadBalancingPolicyLocked();
+  DestroyResolverAndLbPolicyLocked();
   grpc_channel_args_destroy(channel_args_);
   GRPC_ERROR_UNREF(resolver_transient_failure_error_);
   // Stop backup polling.
@@ -1725,80 +1958,280 @@ ChannelData::~ChannelData() {
   gpr_mu_destroy(&info_mu_);
 }
 
-void ChannelData::UpdateStateAndPickerLocked(
-    grpc_connectivity_state state, const absl::Status& status,
-    const char* reason,
-    std::unique_ptr<LoadBalancingPolicy::SubchannelPicker> picker) {
-  // Clean the control plane when entering IDLE.
-  if (picker == nullptr || state == GRPC_CHANNEL_SHUTDOWN) {
-    health_check_service_name_.reset();
-    saved_service_config_.reset();
-    saved_config_selector_.reset();
+RefCountedPtr<LoadBalancingPolicy::Config> ChooseLbPolicy(
+    const Resolver::Result& resolver_result,
+    const internal::ClientChannelGlobalParsedConfig* parsed_service_config) {
+  // Prefer the LB policy config found in the service config.
+  if (parsed_service_config->parsed_lb_config() != nullptr) {
+    return parsed_service_config->parsed_lb_config();
   }
-  // Update connectivity state.
-  state_tracker_.SetState(state, status, reason);
-  if (channelz_node_ != nullptr) {
-    channelz_node_->SetConnectivityState(state);
-    channelz_node_->AddTraceEvent(
-        channelz::ChannelTrace::Severity::Info,
-        grpc_slice_from_static_string(
-            channelz::ChannelNode::GetChannelConnectivityStateChangeString(
-                state)));
+  // Try the deprecated LB policy name from the service config.
+  // If not, try the setting from channel args.
+  const char* policy_name = nullptr;
+  if (!parsed_service_config->parsed_deprecated_lb_policy().empty()) {
+    policy_name = parsed_service_config->parsed_deprecated_lb_policy().c_str();
+  } else {
+    const grpc_arg* channel_arg =
+        grpc_channel_args_find(resolver_result.args, GRPC_ARG_LB_POLICY_NAME);
+    policy_name = grpc_channel_arg_get_string(channel_arg);
   }
-  // Grab data plane lock to do subchannel updates and update the picker.
+  // Use pick_first if nothing was specified and we didn't select grpclb
+  // above.
+  if (policy_name == nullptr) policy_name = "pick_first";
+  // Now that we have the policy name, construct an empty config for it.
+  Json config_json = Json::Array{Json::Object{
+      {policy_name, Json::Object{}},
+  }};
+  grpc_error* parse_error = GRPC_ERROR_NONE;
+  auto lb_policy_config = LoadBalancingPolicyRegistry::ParseLoadBalancingConfig(
+      config_json, &parse_error);
+  // The policy name came from one of three places:
+  // - The deprecated loadBalancingPolicy field in the service config,
+  //   in which case the code in ClientChannelServiceConfigParser
+  //   already verified that the policy does not require a config.
+  // - One of the hard-coded values here, all of which are known to not
+  //   require a config.
+  // - A channel arg, in which case the application did something that
+  //   is a misuse of our API.
+  // In the first two cases, these assertions will always be true.  In
+  // the last case, this is probably fine for now.
+  // TODO(roth): If the last case becomes a problem, add better error
+  // handling here.
+  GPR_ASSERT(lb_policy_config != nullptr);
+  GPR_ASSERT(parse_error == GRPC_ERROR_NONE);
+  return lb_policy_config;
+}
+
+void ChannelData::OnResolverResultChangedLocked(Resolver::Result result) {
+  // Handle race conditions.
+  if (resolver_ == nullptr) return;
+  if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_routing_trace)) {
+    gpr_log(GPR_INFO, "chand=%p: got resolver result", this);
+  }
+  // We only want to trace the address resolution in the follow cases:
+  // (a) Address resolution resulted in service config change.
+  // (b) Address resolution that causes number of backends to go from
+  //     zero to non-zero.
+  // (c) Address resolution that causes number of backends to go from
+  //     non-zero to zero.
+  // (d) Address resolution that causes a new LB policy to be created.
   //
-  // Note that we want to minimize the work done while holding the data
-  // plane lock, to keep the critical section small.  So, for all of the
-  // objects that we might wind up unreffing here, we actually hold onto
-  // the refs until after we release the lock, and then unref them at
-  // that point.  This includes the following:
-  // - refs to subchannel wrappers in the keys of pending_subchannel_updates_
-  // - ref stored in retry_throttle_data_
-  // - ref stored in service_config_
-  // - ref stored in config_selector_
-  // - ownership of the existing picker in picker_
-  RefCountedPtr<ServerRetryThrottleData> retry_throttle_data_to_unref;
-  RefCountedPtr<ServiceConfig> service_config_to_unref;
-  RefCountedPtr<ConfigSelector> config_selector_to_unref;
-  {
-    MutexLock lock(&data_plane_mu_);
-    // Handle subchannel updates.
-    for (auto& p : pending_subchannel_updates_) {
+  // We track a list of strings to eventually be concatenated and traced.
+  absl::InlinedVector<const char*, 3> trace_strings;
+  if (result.addresses.empty() && previous_resolution_contained_addresses_) {
+    trace_strings.push_back("Address list became empty");
+  } else if (!result.addresses.empty() &&
+             !previous_resolution_contained_addresses_) {
+    trace_strings.push_back("Address list became non-empty");
+  }
+  previous_resolution_contained_addresses_ = !result.addresses.empty();
+  // The result of grpc_error_string() is owned by the error itself.
+  // We're storing that string in trace_strings, so we need to make sure
+  // that the error lives until we're done with the string.
+  grpc_error* service_config_error =
+      GRPC_ERROR_REF(result.service_config_error);
+  if (service_config_error != GRPC_ERROR_NONE) {
+    trace_strings.push_back(grpc_error_string(service_config_error));
+  }
+  // Choose the service config.
+  RefCountedPtr<ServiceConfig> service_config;
+  RefCountedPtr<ConfigSelector> config_selector;
+  if (service_config_error != GRPC_ERROR_NONE) {
+    if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_routing_trace)) {
+      gpr_log(GPR_INFO, "chand=%p: resolver returned service config error: %s",
+              this, grpc_error_string(service_config_error));
+    }
+    // If the service config was invalid, then fallback to the
+    // previously returned service config.
+    if (saved_service_config_ != nullptr) {
       if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_routing_trace)) {
         gpr_log(GPR_INFO,
-                "chand=%p: updating subchannel wrapper %p data plane "
-                "connected_subchannel to %p",
-                this, p.first.get(), p.second.get());
+                "chand=%p: resolver returned invalid service config. "
+                "Continuing to use previous service config.",
+                this);
       }
-      // Note: We do not remove the entry from pending_subchannel_updates_
-      // here, since this would unref the subchannel wrapper; instead,
-      // we wait until we've released the lock to clear the map.
-      p.first->set_connected_subchannel_in_data_plane(std::move(p.second));
+      service_config = saved_service_config_;
+      config_selector = saved_config_selector_;
+    } else {
+      // We received an invalid service config and we don't have a
+      // previous service config to fall back to.  Put the channel into
+      // TRANSIENT_FAILURE.
+      OnResolverErrorLocked(GRPC_ERROR_REF(service_config_error));
+      trace_strings.push_back("no valid service config");
     }
-    // Swap out the picker.
-    // Note: Original value will be destroyed after the lock is released.
-    picker_.swap(picker);
-    // Clean the data plane if the updated picker is nullptr.
-    if (picker_ == nullptr || state == GRPC_CHANNEL_SHUTDOWN) {
-      received_service_config_data_ = false;
-      // Note: We save the objects to unref until after the lock is released.
-      retry_throttle_data_to_unref = std::move(retry_throttle_data_);
-      service_config_to_unref = std::move(service_config_);
-      config_selector_to_unref = std::move(config_selector_);
+  } else if (result.service_config == nullptr) {
+    // Resolver did not return any service config.
+    if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_routing_trace)) {
+      gpr_log(GPR_INFO,
+              "chand=%p: resolver returned no service config. Using default "
+              "service config for channel.",
+              this);
     }
-    // Re-process queued picks.
-    for (QueuedPick* pick = queued_picks_; pick != nullptr; pick = pick->next) {
-      grpc_call_element* elem = pick->elem;
-      CallData* calld = static_cast<CallData*>(elem->call_data);
-      grpc_error* error = GRPC_ERROR_NONE;
-      if (calld->PickSubchannelLocked(elem, &error)) {
-        calld->AsyncPickDone(elem, error);
+    service_config = default_service_config_;
+  } else {
+    // Use ServiceConfig and ConfigSelector returned by resolver.
+    service_config = result.service_config;
+    config_selector = ConfigSelector::GetFromChannelArgs(*result.args);
+  }
+  if (service_config != nullptr) {
+    // Extract global config for client channel.
+    const internal::ClientChannelGlobalParsedConfig* parsed_service_config =
+        static_cast<const internal::ClientChannelGlobalParsedConfig*>(
+            service_config->GetGlobalParsedConfig(
+                internal::ClientChannelServiceConfigParser::ParserIndex()));
+    // Choose LB policy config.
+    RefCountedPtr<LoadBalancingPolicy::Config> lb_policy_config =
+        ChooseLbPolicy(result, parsed_service_config);
+    // Check if the ServiceConfig has changed.
+    const bool service_config_changed =
+        saved_service_config_ == nullptr ||
+        service_config->json_string() != saved_service_config_->json_string();
+    // Check if the ConfigSelector has changed.
+    const bool config_selector_changed = !ConfigSelector::Equals(
+        saved_config_selector_.get(), config_selector.get());
+    // If either has changed, apply the global parameters now.
+    if (service_config_changed || config_selector_changed) {
+      // Update service config in control plane.
+      UpdateServiceConfigInControlPlaneLocked(
+          std::move(service_config), std::move(config_selector),
+          parsed_service_config, lb_policy_config->name());
+    } else if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_routing_trace)) {
+      gpr_log(GPR_INFO, "chand=%p: service config not changed", this);
+    }
+    // Create or update LB policy, as needed.
+    CreateOrUpdateLbPolicyLocked(std::move(lb_policy_config),
+                                 std::move(result));
+    if (service_config_changed || config_selector_changed) {
+      // Start using new service config for calls.
+      // This needs to happen after the LB policy has been updated, since
+      // the ConfigSelector may need the LB policy to know about new
+      // destinations before it can send RPCs to those destinations.
+      UpdateServiceConfigInDataPlaneLocked();
+      // TODO(ncteisen): might be worth somehow including a snippet of the
+      // config in the trace, at the risk of bloating the trace logs.
+      trace_strings.push_back("Service config changed");
+    }
+  }
+  // Add channel trace event.
+  if (!trace_strings.empty()) {
+    std::string message =
+        absl::StrCat("Resolution event: ", absl::StrJoin(trace_strings, ", "));
+    if (channelz_node_ != nullptr) {
+      channelz_node_->AddTraceEvent(channelz::ChannelTrace::Severity::Info,
+                                    grpc_slice_from_cpp_string(message));
+    }
+  }
+  GRPC_ERROR_UNREF(service_config_error);
+}
+
+void ChannelData::OnResolverErrorLocked(grpc_error* error) {
+  if (resolver_ == nullptr) {
+    GRPC_ERROR_UNREF(error);
+    return;
+  }
+  if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_routing_trace)) {
+    gpr_log(GPR_INFO, "chand=%p: resolver transient failure: %s", this,
+            grpc_error_string(error));
+  }
+  // If we already have an LB policy from a previous resolution
+  // result, then we continue to let it set the connectivity state.
+  // Otherwise, we go into TRANSIENT_FAILURE.
+  if (lb_policy_ == nullptr) {
+    grpc_error* state_error = GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING(
+        "Resolver transient failure", &error, 1);
+    {
+      MutexLock lock(&resolution_mu_);
+      // Update resolver transient failure.
+      GRPC_ERROR_UNREF(resolver_transient_failure_error_);
+      resolver_transient_failure_error_ = GRPC_ERROR_REF(state_error);
+      // Process calls that were queued waiting for the resolver result.
+      for (ResolverQueuedCall* call = resolver_queued_calls_; call != nullptr;
+           call = call->next) {
+        grpc_call_element* elem = call->elem;
+        CallData* calld = static_cast<CallData*>(elem->call_data);
+        grpc_error* error = GRPC_ERROR_NONE;
+        if (calld->CheckResolutionLocked(elem, &error)) {
+          calld->AsyncResolutionDone(elem, error);
+        }
       }
     }
+    // Update connectivity state.
+    UpdateStateAndPickerLocked(
+        GRPC_CHANNEL_TRANSIENT_FAILURE, grpc_error_to_absl_status(state_error),
+        "resolver failure",
+        absl::make_unique<LoadBalancingPolicy::TransientFailurePicker>(
+            state_error));
+  }
+  GRPC_ERROR_UNREF(error);
+}
+
+void ChannelData::CreateOrUpdateLbPolicyLocked(
+    RefCountedPtr<LoadBalancingPolicy::Config> lb_policy_config,
+    Resolver::Result result) {
+  // Construct update.
+  LoadBalancingPolicy::UpdateArgs update_args;
+  update_args.addresses = std::move(result.addresses);
+  update_args.config = std::move(lb_policy_config);
+  // Remove the config selector from channel args so that we're not holding
+  // unnecessary refs that cause it to be destroyed somewhere other than in the
+  // WorkSerializer.
+  const char* arg_name = GRPC_ARG_CONFIG_SELECTOR;
+  update_args.args =
+      grpc_channel_args_copy_and_remove(result.args, &arg_name, 1);
+  // Create policy if needed.
+  if (lb_policy_ == nullptr) {
+    lb_policy_ = CreateLbPolicyLocked(*update_args.args);
+  }
+  // Update the policy.
+  if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_routing_trace)) {
+    gpr_log(GPR_INFO, "chand=%p: Updating child policy %p", this,
+            lb_policy_.get());
+  }
+  lb_policy_->UpdateLocked(std::move(update_args));
+}
+
+// Creates a new LB policy.
+OrphanablePtr<LoadBalancingPolicy> ChannelData::CreateLbPolicyLocked(
+    const grpc_channel_args& args) {
+  LoadBalancingPolicy::Args lb_policy_args;
+  lb_policy_args.work_serializer = work_serializer_;
+  lb_policy_args.channel_control_helper =
+      absl::make_unique<ClientChannelControlHelper>(this);
+  lb_policy_args.args = &args;
+  OrphanablePtr<LoadBalancingPolicy> lb_policy =
+      MakeOrphanable<ChildPolicyHandler>(std::move(lb_policy_args),
+                                         &grpc_client_channel_routing_trace);
+  if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_routing_trace)) {
+    gpr_log(GPR_INFO, "chand=%p: created new LB policy %p", this,
+            lb_policy.get());
+  }
+  grpc_pollset_set_add_pollset_set(lb_policy->interested_parties(),
+                                   interested_parties_);
+  return lb_policy;
+}
+
+void ChannelData::AddResolverQueuedCall(ResolverQueuedCall* call,
+                                        grpc_polling_entity* pollent) {
+  // Add call to queued calls list.
+  call->next = resolver_queued_calls_;
+  resolver_queued_calls_ = call;
+  // Add call's pollent to channel's interested_parties, so that I/O
+  // can be done under the call's CQ.
+  grpc_polling_entity_add_to_pollset_set(pollent, interested_parties_);
+}
+
+void ChannelData::RemoveResolverQueuedCall(ResolverQueuedCall* to_remove,
+                                           grpc_polling_entity* pollent) {
+  // Remove call's pollent from channel's interested_parties.
+  grpc_polling_entity_del_from_pollset_set(pollent, interested_parties_);
+  // Remove from queued calls list.
+  for (ResolverQueuedCall** call = &resolver_queued_calls_; *call != nullptr;
+       call = &(*call)->next) {
+    if (*call == to_remove) {
+      *call = to_remove->next;
+      return;
+    }
   }
-  // Clear the pending update map after releasing the lock, to keep the
-  // critical section small.
-  pending_subchannel_updates_.clear();
 }
 
 void ChannelData::UpdateServiceConfigInControlPlaneLocked(
@@ -1806,7 +2239,7 @@ void ChannelData::UpdateServiceConfigInControlPlaneLocked(
     RefCountedPtr<ConfigSelector> config_selector,
     const internal::ClientChannelGlobalParsedConfig* parsed_service_config,
     const char* lb_policy_name) {
-  grpc_core::UniquePtr<char> service_config_json(
+  UniquePtr<char> service_config_json(
       gpr_strdup(service_config->json_string().c_str()));
   if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_routing_trace)) {
     gpr_log(GPR_INFO,
@@ -1816,22 +2249,18 @@ void ChannelData::UpdateServiceConfigInControlPlaneLocked(
   // Save service config.
   saved_service_config_ = std::move(service_config);
   // Update health check service name if needed.
-  if (((health_check_service_name_ == nullptr) !=
-       (parsed_service_config->health_check_service_name() == nullptr)) ||
-      (health_check_service_name_ != nullptr &&
-       strcmp(health_check_service_name_.get(),
-              parsed_service_config->health_check_service_name()) != 0)) {
-    health_check_service_name_.reset(
-        gpr_strdup(parsed_service_config->health_check_service_name()));
+  if (health_check_service_name_ !=
+      parsed_service_config->health_check_service_name()) {
+    health_check_service_name_ =
+        parsed_service_config->health_check_service_name();
     // Update health check service name used by existing subchannel wrappers.
     for (auto* subchannel_wrapper : subchannel_wrappers_) {
       subchannel_wrapper->UpdateHealthCheckServiceName(
-          grpc_core::UniquePtr<char>(
-              gpr_strdup(health_check_service_name_.get())));
+          health_check_service_name_);
     }
   }
   // Swap out the data used by GetChannelInfo().
-  grpc_core::UniquePtr<char> lb_policy_name_owned(gpr_strdup(lb_policy_name));
+  UniquePtr<char> lb_policy_name_owned(gpr_strdup(lb_policy_name));
   {
     MutexLock lock(&info_mu_);
     info_lb_policy_name_ = std::move(lb_policy_name_owned);
@@ -1846,19 +2275,6 @@ void ChannelData::UpdateServiceConfigInControlPlaneLocked(
 }
 
 void ChannelData::UpdateServiceConfigInDataPlaneLocked() {
-  // Get retry throttle data from service config.
-  const internal::ClientChannelGlobalParsedConfig* parsed_service_config =
-      static_cast<const internal::ClientChannelGlobalParsedConfig*>(
-          saved_service_config_->GetGlobalParsedConfig(
-              internal::ClientChannelServiceConfigParser::ParserIndex()));
-  absl::optional<internal::ClientChannelGlobalParsedConfig::RetryThrottling>
-      retry_throttle_config = parsed_service_config->retry_throttling();
-  RefCountedPtr<ServerRetryThrottleData> retry_throttle_data;
-  if (retry_throttle_config.has_value()) {
-    retry_throttle_data = internal::ServerRetryThrottleMap::GetDataForServer(
-        server_name_.get(), retry_throttle_config.value().max_milli_tokens,
-        retry_throttle_config.value().milli_token_ratio);
-  }
   // Grab ref to service config.
   RefCountedPtr<ServiceConfig> service_config = saved_service_config_;
   // Grab ref to config selector.  Use default if resolver didn't supply one.
@@ -1871,27 +2287,61 @@ void ChannelData::UpdateServiceConfigInDataPlaneLocked() {
     config_selector =
         MakeRefCounted<DefaultConfigSelector>(saved_service_config_);
   }
+  // Get retry throttle data from service config.
+  const internal::ClientChannelGlobalParsedConfig* parsed_service_config =
+      static_cast<const internal::ClientChannelGlobalParsedConfig*>(
+          saved_service_config_->GetGlobalParsedConfig(
+              internal::ClientChannelServiceConfigParser::ParserIndex()));
+  absl::optional<internal::ClientChannelGlobalParsedConfig::RetryThrottling>
+      retry_throttle_config = parsed_service_config->retry_throttling();
+  RefCountedPtr<ServerRetryThrottleData> retry_throttle_data;
+  if (retry_throttle_config.has_value()) {
+    retry_throttle_data = internal::ServerRetryThrottleMap::GetDataForServer(
+        server_name_, retry_throttle_config.value().max_milli_tokens,
+        retry_throttle_config.value().milli_token_ratio);
+  }
+  // Construct per-LB filter stack.
+  std::vector<const grpc_channel_filter*> filters =
+      config_selector->GetFilters();
+  filters.push_back(&kDynamicTerminationFilterVtable);
+  absl::InlinedVector<grpc_arg, 2> args_to_add;
+  args_to_add.push_back(grpc_channel_arg_pointer_create(
+      const_cast<char*>(GRPC_ARG_CLIENT_CHANNEL_DATA), this,
+      &kChannelDataArgPointerVtable));
+  if (retry_throttle_data != nullptr) {
+    args_to_add.push_back(grpc_channel_arg_pointer_create(
+        const_cast<char*>(GRPC_ARG_RETRY_THROTTLE_DATA),
+        retry_throttle_data.get(), &kRetryThrottleDataArgPointerVtable));
+  }
+  grpc_channel_args* new_args = grpc_channel_args_copy_and_add(
+      channel_args_, args_to_add.data(), args_to_add.size());
+  RefCountedPtr<DynamicFilters> dynamic_filters =
+      DynamicFilters::Create(new_args, std::move(filters));
+  GPR_ASSERT(dynamic_filters != nullptr);
+  grpc_channel_args_destroy(new_args);
   // Grab data plane lock to update service config.
   //
   // We defer unreffing the old values (and deallocating memory) until
   // after releasing the lock to keep the critical section small.
+  std::set<grpc_call_element*> calls_pending_resolver_result;
   {
-    MutexLock lock(&data_plane_mu_);
+    MutexLock lock(&resolution_mu_);
     GRPC_ERROR_UNREF(resolver_transient_failure_error_);
     resolver_transient_failure_error_ = GRPC_ERROR_NONE;
     // Update service config.
     received_service_config_data_ = true;
     // Old values will be unreffed after lock is released.
-    retry_throttle_data_.swap(retry_throttle_data);
     service_config_.swap(service_config);
     config_selector_.swap(config_selector);
-    // Re-process queued picks.
-    for (QueuedPick* pick = queued_picks_; pick != nullptr; pick = pick->next) {
-      grpc_call_element* elem = pick->elem;
+    dynamic_filters_.swap(dynamic_filters);
+    // Process calls that were queued waiting for the resolver result.
+    for (ResolverQueuedCall* call = resolver_queued_calls_; call != nullptr;
+         call = call->next) {
+      grpc_call_element* elem = call->elem;
       CallData* calld = static_cast<CallData*>(elem->call_data);
       grpc_error* error = GRPC_ERROR_NONE;
-      if (calld->PickSubchannelLocked(elem, &error)) {
-        calld->AsyncPickDone(elem, error);
+      if (calld->CheckResolutionLocked(elem, &error)) {
+        calld->AsyncResolutionDone(elem, error);
       }
     }
   }
@@ -1899,63 +2349,148 @@ void ChannelData::UpdateServiceConfigInDataPlaneLocked() {
   // of scope.
 }
 
-void ChannelData::CreateResolvingLoadBalancingPolicyLocked() {
-  // Instantiate resolving LB policy.
-  LoadBalancingPolicy::Args lb_args;
-  lb_args.work_serializer = work_serializer_;
-  lb_args.channel_control_helper =
-      absl::make_unique<ClientChannelControlHelper>(this);
-  lb_args.args = channel_args_;
-  grpc_core::UniquePtr<char> target_uri(gpr_strdup(target_uri_.get()));
-  resolving_lb_policy_.reset(new ResolvingLoadBalancingPolicy(
-      std::move(lb_args), &grpc_client_channel_routing_trace,
-      std::move(target_uri), &channel_config_helper_));
-  grpc_pollset_set_add_pollset_set(resolving_lb_policy_->interested_parties(),
-                                   interested_parties_);
+void ChannelData::CreateResolverLocked() {
   if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_routing_trace)) {
-    gpr_log(GPR_INFO, "chand=%p: created resolving_lb_policy=%p", this,
-            resolving_lb_policy_.get());
-  }
-}
-
-void ChannelData::DestroyResolvingLoadBalancingPolicyLocked() {
-  if (resolving_lb_policy_ != nullptr) {
-    grpc_pollset_set_del_pollset_set(resolving_lb_policy_->interested_parties(),
-                                     interested_parties_);
-    resolving_lb_policy_.reset();
+    gpr_log(GPR_INFO, "chand=%p: starting name resolution", this);
+  }
+  resolver_ = ResolverRegistry::CreateResolver(
+      target_uri_.get(), channel_args_, interested_parties_, work_serializer_,
+      absl::make_unique<ResolverResultHandler>(this));
+  // Since the validity of the args was checked when the channel was created,
+  // CreateResolver() must return a non-null result.
+  GPR_ASSERT(resolver_ != nullptr);
+  UpdateStateAndPickerLocked(
+      GRPC_CHANNEL_CONNECTING, absl::Status(), "started resolving",
+      absl::make_unique<LoadBalancingPolicy::QueuePicker>(nullptr));
+  resolver_->StartLocked();
+  if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_routing_trace)) {
+    gpr_log(GPR_INFO, "chand=%p: created resolver=%p", this, resolver_.get());
   }
 }
 
-grpc_error* ChannelData::DoPingLocked(grpc_transport_op* op) {
-  if (state_tracker_.state() != GRPC_CHANNEL_READY) {
-    return GRPC_ERROR_CREATE_FROM_STATIC_STRING("channel not connected");
-  }
-  LoadBalancingPolicy::PickResult result =
-      picker_->Pick(LoadBalancingPolicy::PickArgs());
-  ConnectedSubchannel* connected_subchannel = nullptr;
-  if (result.subchannel != nullptr) {
-    SubchannelWrapper* subchannel =
-        static_cast<SubchannelWrapper*>(result.subchannel.get());
-    connected_subchannel = subchannel->connected_subchannel();
-  }
-  if (connected_subchannel != nullptr) {
-    connected_subchannel->Ping(op->send_ping.on_initiate, op->send_ping.on_ack);
-  } else {
-    if (result.error == GRPC_ERROR_NONE) {
-      result.error = GRPC_ERROR_CREATE_FROM_STATIC_STRING(
-          "LB policy dropped call on ping");
+void ChannelData::DestroyResolverAndLbPolicyLocked() {
+  if (resolver_ != nullptr) {
+    if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_routing_trace)) {
+      gpr_log(GPR_INFO, "chand=%p: shutting down resolver=%p", this,
+              resolver_.get());
+    }
+    resolver_.reset();
+    if (lb_policy_ != nullptr) {
+      if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_routing_trace)) {
+        gpr_log(GPR_INFO, "chand=%p: shutting down lb_policy=%p", this,
+                lb_policy_.get());
+      }
+      grpc_pollset_set_del_pollset_set(lb_policy_->interested_parties(),
+                                       interested_parties_);
+      lb_policy_.reset();
     }
   }
-  return result.error;
 }
 
-void ChannelData::StartTransportOpLocked(grpc_transport_op* op) {
-  // Connectivity watch.
-  if (op->start_connectivity_watch != nullptr) {
-    state_tracker_.AddWatcher(op->start_connectivity_watch_state,
-                              std::move(op->start_connectivity_watch));
+void ChannelData::UpdateStateAndPickerLocked(
+    grpc_connectivity_state state, const absl::Status& status,
+    const char* reason,
+    std::unique_ptr<LoadBalancingPolicy::SubchannelPicker> picker) {
+  // Clean the control plane when entering IDLE.
+  if (picker == nullptr || state == GRPC_CHANNEL_SHUTDOWN) {
+    saved_service_config_.reset();
+    saved_config_selector_.reset();
   }
-  if (op->stop_connectivity_watch != nullptr) {
+  // Update connectivity state.
+  state_tracker_.SetState(state, status, reason);
+  if (channelz_node_ != nullptr) {
+    channelz_node_->SetConnectivityState(state);
+    channelz_node_->AddTraceEvent(
+        channelz::ChannelTrace::Severity::Info,
+        grpc_slice_from_static_string(
+            channelz::ChannelNode::GetChannelConnectivityStateChangeString(
+                state)));
+  }
+  // Grab data plane lock to do subchannel updates and update the picker.
+  //
+  // Note that we want to minimize the work done while holding the data
+  // plane lock, to keep the critical section small.  So, for all of the
+  // objects that we might wind up unreffing here, we actually hold onto
+  // the refs until after we release the lock, and then unref them at
+  // that point.  This includes the following:
+  // - refs to subchannel wrappers in the keys of pending_subchannel_updates_
+  // - ref stored in service_config_
+  // - ref stored in config_selector_
+  // - ref stored in dynamic_filters_
+  // - ownership of the existing picker in picker_
+  RefCountedPtr<ServiceConfig> service_config_to_unref;
+  RefCountedPtr<ConfigSelector> config_selector_to_unref;
+  RefCountedPtr<DynamicFilters> dynamic_filters_to_unref;
+  {
+    MutexLock lock(&data_plane_mu_);
+    // Handle subchannel updates.
+    for (auto& p : pending_subchannel_updates_) {
+      if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_routing_trace)) {
+        gpr_log(GPR_INFO,
+                "chand=%p: updating subchannel wrapper %p data plane "
+                "connected_subchannel to %p",
+                this, p.first.get(), p.second.get());
+      }
+      // Note: We do not remove the entry from pending_subchannel_updates_
+      // here, since this would unref the subchannel wrapper; instead,
+      // we wait until we've released the lock to clear the map.
+      p.first->set_connected_subchannel_in_data_plane(std::move(p.second));
+    }
+    // Swap out the picker.
+    // Note: Original value will be destroyed after the lock is released.
+    picker_.swap(picker);
+    // Clean the data plane if the updated picker is nullptr.
+    if (picker_ == nullptr || state == GRPC_CHANNEL_SHUTDOWN) {
+      received_service_config_data_ = false;
+      // Note: We save the objects to unref until after the lock is released.
+      service_config_to_unref = std::move(service_config_);
+      config_selector_to_unref = std::move(config_selector_);
+      dynamic_filters_to_unref = std::move(dynamic_filters_);
+    }
+    // Re-process queued picks.
+    for (LbQueuedCall* call = lb_queued_calls_; call != nullptr;
+         call = call->next) {
+      grpc_error* error = GRPC_ERROR_NONE;
+      if (call->lb_call->PickSubchannelLocked(&error)) {
+        call->lb_call->AsyncPickDone(error);
+      }
+    }
+  }
+  // Clear the pending update map after releasing the lock, to keep the
+  // critical section small.
+  pending_subchannel_updates_.clear();
+}
+
+grpc_error* ChannelData::DoPingLocked(grpc_transport_op* op) {
+  if (state_tracker_.state() != GRPC_CHANNEL_READY) {
+    return GRPC_ERROR_CREATE_FROM_STATIC_STRING("channel not connected");
+  }
+  LoadBalancingPolicy::PickResult result =
+      picker_->Pick(LoadBalancingPolicy::PickArgs());
+  ConnectedSubchannel* connected_subchannel = nullptr;
+  if (result.subchannel != nullptr) {
+    SubchannelWrapper* subchannel =
+        static_cast<SubchannelWrapper*>(result.subchannel.get());
+    connected_subchannel = subchannel->connected_subchannel();
+  }
+  if (connected_subchannel != nullptr) {
+    connected_subchannel->Ping(op->send_ping.on_initiate, op->send_ping.on_ack);
+  } else {
+    if (result.error == GRPC_ERROR_NONE) {
+      result.error = GRPC_ERROR_CREATE_FROM_STATIC_STRING(
+          "LB policy dropped call on ping");
+    }
+  }
+  return result.error;
+}
+
+void ChannelData::StartTransportOpLocked(grpc_transport_op* op) {
+  // Connectivity watch.
+  if (op->start_connectivity_watch != nullptr) {
+    state_tracker_.AddWatcher(op->start_connectivity_watch_state,
+                              std::move(op->start_connectivity_watch));
+  }
+  if (op->stop_connectivity_watch != nullptr) {
     state_tracker_.RemoveWatcher(op->stop_connectivity_watch);
   }
   // Ping.
@@ -1972,8 +2507,8 @@ void ChannelData::StartTransportOpLocked(grpc_transport_op* op) {
   }
   // Reset backoff.
   if (op->reset_connect_backoff) {
-    if (resolving_lb_policy_ != nullptr) {
-      resolving_lb_policy_->ResetBackoffLocked();
+    if (lb_policy_ != nullptr) {
+      lb_policy_->ResetBackoffLocked();
     }
   }
   // Disconnect or enter IDLE.
@@ -1982,7 +2517,7 @@ void ChannelData::StartTransportOpLocked(grpc_transport_op* op) {
       gpr_log(GPR_INFO, "chand=%p: disconnect_with_error: %s", this,
               grpc_error_string(op->disconnect_with_error));
     }
-    DestroyResolvingLoadBalancingPolicyLocked();
+    DestroyResolverAndLbPolicyLocked();
     intptr_t value;
     if (grpc_error_get_int(op->disconnect_with_error,
                            GRPC_ERROR_INT_CHANNEL_CONNECTIVITY_STATE, &value) &&
@@ -2035,25 +2570,25 @@ void ChannelData::GetChannelInfo(grpc_channel_element* elem,
   }
 }
 
-void ChannelData::AddQueuedPick(QueuedPick* pick,
-                                grpc_polling_entity* pollent) {
+void ChannelData::AddLbQueuedCall(LbQueuedCall* call,
+                                  grpc_polling_entity* pollent) {
   // Add call to queued picks list.
-  pick->next = queued_picks_;
-  queued_picks_ = pick;
+  call->next = lb_queued_calls_;
+  lb_queued_calls_ = call;
   // Add call's pollent to channel's interested_parties, so that I/O
   // can be done under the call's CQ.
   grpc_polling_entity_add_to_pollset_set(pollent, interested_parties_);
 }
 
-void ChannelData::RemoveQueuedPick(QueuedPick* to_remove,
-                                   grpc_polling_entity* pollent) {
+void ChannelData::RemoveLbQueuedCall(LbQueuedCall* to_remove,
+                                     grpc_polling_entity* pollent) {
   // Remove call's pollent from channel's interested_parties.
   grpc_polling_entity_del_from_pollset_set(pollent, interested_parties_);
   // Remove from queued picks list.
-  for (QueuedPick** pick = &queued_picks_; *pick != nullptr;
-       pick = &(*pick)->next) {
-    if (*pick == to_remove) {
-      *pick = to_remove->next;
+  for (LbQueuedCall** call = &lb_queued_calls_; *call != nullptr;
+       call = &(*call)->next) {
+    if (*call == to_remove) {
+      *call = to_remove->next;
       return;
     }
   }
@@ -2071,10 +2606,10 @@ ChannelData::GetConnectedSubchannelInDataPlane(
 }
 
 void ChannelData::TryToConnectLocked() {
-  if (resolving_lb_policy_ != nullptr) {
-    resolving_lb_policy_->ExitIdleLocked();
-  } else {
-    CreateResolvingLoadBalancingPolicyLocked();
+  if (lb_policy_ != nullptr) {
+    lb_policy_->ExitIdleLocked();
+  } else if (resolver_ == nullptr) {
+    CreateResolverLocked();
   }
   GRPC_CHANNEL_STACK_UNREF(owning_stack_, "TryToConnect");
 }
@@ -2104,41 +2639,6 @@ void ChannelData::RemoveConnectivityWatcher(
 // CallData implementation
 //
 
-// Retry support:
-//
-// In order to support retries, we act as a proxy for stream op batches.
-// When we get a batch from the surface, we add it to our list of pending
-// batches, and we then use those batches to construct separate "child"
-// batches to be started on the subchannel call.  When the child batches
-// return, we then decide which pending batches have been completed and
-// schedule their callbacks accordingly.  If a subchannel call fails and
-// we want to retry it, we do a new pick and start again, constructing
-// new "child" batches for the new subchannel call.
-//
-// Note that retries are committed when receiving data from the server
-// (except for Trailers-Only responses).  However, there may be many
-// send ops started before receiving any data, so we may have already
-// completed some number of send ops (and returned the completions up to
-// the surface) by the time we realize that we need to retry.  To deal
-// with this, we cache data for send ops, so that we can replay them on a
-// different subchannel call even after we have completed the original
-// batches.
-//
-// There are two sets of data to maintain:
-// - In call_data (in the parent channel), we maintain a list of pending
-//   ops and cached data for send ops.
-// - In the subchannel call, we maintain state to indicate what ops have
-//   already been sent down to that call.
-//
-// When constructing the "child" batches, we compare those two sets of
-// data to see which batches need to be sent to the subchannel call.
-
-// TODO(roth): In subsequent PRs:
-// - add support for transparent retries (including initial metadata)
-// - figure out how to record stats in census for retries
-//   (census filter is on top of this one)
-// - add census stats for retries
-
 CallData::CallData(grpc_call_element* elem, const ChannelData& chand,
                    const grpc_call_element_args& args)
     : deadline_state_(elem, args,
@@ -2151,25 +2651,14 @@ CallData::CallData(grpc_call_element* elem, const ChannelData& chand,
       arena_(args.arena),
       owning_call_(args.call_stack),
       call_combiner_(args.call_combiner),
-      call_context_(args.context),
-      lb_call_state_(this),
-      pending_send_initial_metadata_(false),
-      pending_send_message_(false),
-      pending_send_trailing_metadata_(false),
-      enable_retries_(chand.enable_retries()),
-      retry_committed_(false),
-      last_attempt_got_server_pushback_(false) {}
+      call_context_(args.context) {}
 
 CallData::~CallData() {
   grpc_slice_unref_internal(path_);
   GRPC_ERROR_UNREF(cancel_error_);
-  if (backend_metric_data_ != nullptr) {
-    backend_metric_data_
-        ->LoadBalancingPolicy::BackendMetricData::~BackendMetricData();
-  }
   // Make sure there are no remaining pending batches.
   for (size_t i = 0; i < GPR_ARRAY_SIZE(pending_batches_); ++i) {
-    GPR_ASSERT(pending_batches_[i].batch == nullptr);
+    GPR_ASSERT(pending_batches_[i] == nullptr);
   }
 }
 
@@ -2184,10 +2673,11 @@ void CallData::Destroy(grpc_call_element* elem,
                        const grpc_call_final_info* /*final_info*/,
                        grpc_closure* then_schedule_closure) {
   CallData* calld = static_cast<CallData*>(elem->call_data);
-  RefCountedPtr<SubchannelCall> subchannel_call = calld->subchannel_call_;
+  RefCountedPtr<DynamicFilters::Call> dynamic_call =
+      std::move(calld->dynamic_call_);
   calld->~CallData();
-  if (GPR_LIKELY(subchannel_call != nullptr)) {
-    subchannel_call->SetAfterCallStackDestroy(then_schedule_closure);
+  if (GPR_LIKELY(dynamic_call != nullptr)) {
+    dynamic_call->SetAfterCallStackDestroy(then_schedule_closure);
   } else {
     // TODO(yashkt) : This can potentially be a Closure::Run
     ExecCtx::Run(DEBUG_LOCATION, then_schedule_closure, GRPC_ERROR_NONE);
@@ -2202,6 +2692,10 @@ void CallData::StartTransportStreamOpBatch(
   if (GPR_LIKELY(chand->deadline_checking_enabled())) {
     grpc_deadline_state_client_start_transport_stream_op_batch(elem, batch);
   }
+  // Intercept recv_initial_metadata for config selector on-committed callback.
+  if (batch->recv_initial_metadata) {
+    calld->InjectRecvInitialMetadataReadyForConfigSelectorCommitCallback(batch);
+  }
   // If we've previously been cancelled, immediately fail any new batches.
   if (GPR_UNLIKELY(calld->cancel_error_ != GRPC_ERROR_NONE)) {
     if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_call_trace)) {
@@ -2227,12 +2721,10 @@ void CallData::StartTransportStreamOpBatch(
       gpr_log(GPR_INFO, "chand=%p calld=%p: recording cancel_error=%s", chand,
               calld, grpc_error_string(calld->cancel_error_));
     }
-    // If we do not have a subchannel call (i.e., a pick has not yet
-    // been started), fail all pending batches.  Otherwise, send the
-    // cancellation down to the subchannel call.
-    if (calld->subchannel_call_ == nullptr) {
-      // TODO(roth): If there is a pending retry callback, do we need to
-      // cancel it here?
+    // If we do not have a dynamic call (i.e., name resolution has not
+    // yet completed), fail all pending batches.  Otherwise, send the
+    // cancellation down to the dynamic call.
+    if (calld->dynamic_call_ == nullptr) {
       calld->PendingBatchesFail(elem, GRPC_ERROR_REF(calld->cancel_error_),
                                 NoYieldCallCombiner);
       // Note: This will release the call combiner.
@@ -2240,35 +2732,35 @@ void CallData::StartTransportStreamOpBatch(
           batch, GRPC_ERROR_REF(calld->cancel_error_), calld->call_combiner_);
     } else {
       // Note: This will release the call combiner.
-      calld->subchannel_call_->StartTransportStreamOpBatch(batch);
+      calld->dynamic_call_->StartTransportStreamOpBatch(batch);
     }
     return;
   }
   // Add the batch to the pending list.
   calld->PendingBatchesAdd(elem, batch);
-  // Check if we've already gotten a subchannel call.
-  // Note that once we have picked a subchannel, we do not need to acquire
-  // the channel's data plane mutex, which is more efficient (especially for
-  // streaming calls).
-  if (calld->subchannel_call_ != nullptr) {
+  // Check if we've already created a dynamic call.
+  // Note that once we have done so, we do not need to acquire the channel's
+  // resolution mutex, which is more efficient (especially for streaming calls).
+  if (calld->dynamic_call_ != nullptr) {
     if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_call_trace)) {
-      gpr_log(GPR_INFO,
-              "chand=%p calld=%p: starting batch on subchannel_call=%p", chand,
-              calld, calld->subchannel_call_.get());
+      gpr_log(GPR_INFO, "chand=%p calld=%p: starting batch on dynamic_call=%p",
+              chand, calld, calld->dynamic_call_.get());
     }
     calld->PendingBatchesResume(elem);
     return;
   }
-  // We do not yet have a subchannel call.
+  // We do not yet have a dynamic call.
   // For batches containing a send_initial_metadata op, acquire the
-  // channel's data plane mutex to pick a subchannel.
+  // channel's resolution mutex to apply the service config to the call,
+  // after which we will create a dynamic call.
   if (GPR_LIKELY(batch->send_initial_metadata)) {
     if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_call_trace)) {
       gpr_log(GPR_INFO,
-              "chand=%p calld=%p: grabbing data plane mutex to perform pick",
+              "chand=%p calld=%p: grabbing resolution mutex to apply service "
+              "config",
               chand, calld);
     }
-    PickSubchannel(elem, GRPC_ERROR_NONE);
+    CheckResolution(elem, GRPC_ERROR_NONE);
   } else {
     // For all other batches, release the call combiner.
     if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_call_trace)) {
@@ -2288,156 +2780,6 @@ void CallData::SetPollent(grpc_call_element* elem,
 }
 
 //
-// send op data caching
-//
-
-void CallData::MaybeCacheSendOpsForBatch(PendingBatch* pending) {
-  if (pending->send_ops_cached) return;
-  pending->send_ops_cached = true;
-  grpc_transport_stream_op_batch* batch = pending->batch;
-  // Save a copy of metadata for send_initial_metadata ops.
-  if (batch->send_initial_metadata) {
-    seen_send_initial_metadata_ = true;
-    GPR_ASSERT(send_initial_metadata_storage_ == nullptr);
-    grpc_metadata_batch* send_initial_metadata =
-        batch->payload->send_initial_metadata.send_initial_metadata;
-    send_initial_metadata_storage_ = (grpc_linked_mdelem*)arena_->Alloc(
-        sizeof(grpc_linked_mdelem) * send_initial_metadata->list.count);
-    grpc_metadata_batch_copy(send_initial_metadata, &send_initial_metadata_,
-                             send_initial_metadata_storage_);
-    send_initial_metadata_flags_ =
-        batch->payload->send_initial_metadata.send_initial_metadata_flags;
-    peer_string_ = batch->payload->send_initial_metadata.peer_string;
-  }
-  // Set up cache for send_message ops.
-  if (batch->send_message) {
-    ByteStreamCache* cache = arena_->New<ByteStreamCache>(
-        std::move(batch->payload->send_message.send_message));
-    send_messages_.push_back(cache);
-  }
-  // Save metadata batch for send_trailing_metadata ops.
-  if (batch->send_trailing_metadata) {
-    seen_send_trailing_metadata_ = true;
-    GPR_ASSERT(send_trailing_metadata_storage_ == nullptr);
-    grpc_metadata_batch* send_trailing_metadata =
-        batch->payload->send_trailing_metadata.send_trailing_metadata;
-    send_trailing_metadata_storage_ = (grpc_linked_mdelem*)arena_->Alloc(
-        sizeof(grpc_linked_mdelem) * send_trailing_metadata->list.count);
-    grpc_metadata_batch_copy(send_trailing_metadata, &send_trailing_metadata_,
-                             send_trailing_metadata_storage_);
-  }
-}
-
-void CallData::FreeCachedSendInitialMetadata(ChannelData* chand) {
-  if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_call_trace)) {
-    gpr_log(GPR_INFO,
-            "chand=%p calld=%p: destroying calld->send_initial_metadata", chand,
-            this);
-  }
-  grpc_metadata_batch_destroy(&send_initial_metadata_);
-}
-
-void CallData::FreeCachedSendMessage(ChannelData* chand, size_t idx) {
-  if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_call_trace)) {
-    gpr_log(GPR_INFO,
-            "chand=%p calld=%p: destroying calld->send_messages[%" PRIuPTR "]",
-            chand, this, idx);
-  }
-  send_messages_[idx]->Destroy();
-}
-
-void CallData::FreeCachedSendTrailingMetadata(ChannelData* chand) {
-  if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_call_trace)) {
-    gpr_log(GPR_INFO,
-            "chand=%p calld=%p: destroying calld->send_trailing_metadata",
-            chand, this);
-  }
-  grpc_metadata_batch_destroy(&send_trailing_metadata_);
-}
-
-void CallData::FreeCachedSendOpDataAfterCommit(
-    grpc_call_element* elem, SubchannelCallRetryState* retry_state) {
-  ChannelData* chand = static_cast<ChannelData*>(elem->channel_data);
-  if (retry_state->completed_send_initial_metadata) {
-    FreeCachedSendInitialMetadata(chand);
-  }
-  for (size_t i = 0; i < retry_state->completed_send_message_count; ++i) {
-    FreeCachedSendMessage(chand, i);
-  }
-  if (retry_state->completed_send_trailing_metadata) {
-    FreeCachedSendTrailingMetadata(chand);
-  }
-}
-
-void CallData::FreeCachedSendOpDataForCompletedBatch(
-    grpc_call_element* elem, SubchannelCallBatchData* batch_data,
-    SubchannelCallRetryState* retry_state) {
-  ChannelData* chand = static_cast<ChannelData*>(elem->channel_data);
-  if (batch_data->batch.send_initial_metadata) {
-    FreeCachedSendInitialMetadata(chand);
-  }
-  if (batch_data->batch.send_message) {
-    FreeCachedSendMessage(chand, retry_state->completed_send_message_count - 1);
-  }
-  if (batch_data->batch.send_trailing_metadata) {
-    FreeCachedSendTrailingMetadata(chand);
-  }
-}
-
-//
-// LB recv_trailing_metadata_ready handling
-//
-
-void CallData::RecvTrailingMetadataReadyForLoadBalancingPolicy(
-    void* arg, grpc_error* error) {
-  CallData* calld = static_cast<CallData*>(arg);
-  // Set error if call did not succeed.
-  grpc_error* error_for_lb = GRPC_ERROR_NONE;
-  if (error != GRPC_ERROR_NONE) {
-    error_for_lb = error;
-  } else {
-    const auto& fields = calld->recv_trailing_metadata_->idx.named;
-    GPR_ASSERT(fields.grpc_status != nullptr);
-    grpc_status_code status =
-        grpc_get_status_code_from_metadata(fields.grpc_status->md);
-    std::string msg;
-    if (status != GRPC_STATUS_OK) {
-      error_for_lb = grpc_error_set_int(
-          GRPC_ERROR_CREATE_FROM_STATIC_STRING("call failed"),
-          GRPC_ERROR_INT_GRPC_STATUS, status);
-      if (fields.grpc_message != nullptr) {
-        error_for_lb = grpc_error_set_str(
-            error_for_lb, GRPC_ERROR_STR_GRPC_MESSAGE,
-            grpc_slice_ref_internal(GRPC_MDVALUE(fields.grpc_message->md)));
-      }
-    }
-  }
-  // Invoke callback to LB policy.
-  Metadata trailing_metadata(calld, calld->recv_trailing_metadata_);
-  calld->lb_recv_trailing_metadata_ready_(error_for_lb, &trailing_metadata,
-                                          &calld->lb_call_state_);
-  if (error == GRPC_ERROR_NONE) GRPC_ERROR_UNREF(error_for_lb);
-  // Chain to original callback.
-  Closure::Run(DEBUG_LOCATION, calld->original_recv_trailing_metadata_ready_,
-               GRPC_ERROR_REF(error));
-}
-
-void CallData::MaybeInjectRecvTrailingMetadataReadyForLoadBalancingPolicy(
-    grpc_transport_stream_op_batch* batch) {
-  if (lb_recv_trailing_metadata_ready_ != nullptr) {
-    recv_trailing_metadata_ =
-        batch->payload->recv_trailing_metadata.recv_trailing_metadata;
-    original_recv_trailing_metadata_ready_ =
-        batch->payload->recv_trailing_metadata.recv_trailing_metadata_ready;
-    GRPC_CLOSURE_INIT(&recv_trailing_metadata_ready_,
-                      RecvTrailingMetadataReadyForLoadBalancingPolicy, this,
-                      grpc_schedule_on_exec_ctx);
-    batch->payload->recv_trailing_metadata.recv_trailing_metadata_ready =
-        &recv_trailing_metadata_ready_;
-  }
-}
-
-//
 // pending_batches management
 //
 
@@ -2463,21 +2805,669 @@ void CallData::PendingBatchesAdd(grpc_call_element* elem,
             "chand=%p calld=%p: adding pending batch at index %" PRIuPTR, chand,
             this, idx);
   }
-  PendingBatch* pending = &pending_batches_[idx];
-  GPR_ASSERT(pending->batch == nullptr);
-  pending->batch = batch;
-  pending->send_ops_cached = false;
-  if (enable_retries_) {
-    // Update state in calld about pending batches.
-    // Also check if the batch takes us over the retry buffer limit.
-    // Note: We don't check the size of trailing metadata here, because
-    // gRPC clients do not send trailing metadata.
-    if (batch->send_initial_metadata) {
-      pending_send_initial_metadata_ = true;
-      bytes_buffered_for_retry_ += grpc_metadata_batch_size(
-          batch->payload->send_initial_metadata.send_initial_metadata);
-    }
-    if (batch->send_message) {
+  grpc_transport_stream_op_batch*& pending = pending_batches_[idx];
+  GPR_ASSERT(pending == nullptr);
+  pending = batch;
+}
+
+// This is called via the call combiner, so access to calld is synchronized.
+void CallData::FailPendingBatchInCallCombiner(void* arg, grpc_error* error) {
+  grpc_transport_stream_op_batch* batch =
+      static_cast<grpc_transport_stream_op_batch*>(arg);
+  CallData* calld = static_cast<CallData*>(batch->handler_private.extra_arg);
+  // Note: This will release the call combiner.
+  grpc_transport_stream_op_batch_finish_with_failure(
+      batch, GRPC_ERROR_REF(error), calld->call_combiner_);
+}
+
+// This is called via the call combiner, so access to calld is synchronized.
+void CallData::PendingBatchesFail(
+    grpc_call_element* elem, grpc_error* error,
+    YieldCallCombinerPredicate yield_call_combiner_predicate) {
+  GPR_ASSERT(error != GRPC_ERROR_NONE);
+  if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_call_trace)) {
+    size_t num_batches = 0;
+    for (size_t i = 0; i < GPR_ARRAY_SIZE(pending_batches_); ++i) {
+      if (pending_batches_[i] != nullptr) ++num_batches;
+    }
+    gpr_log(GPR_INFO,
+            "chand=%p calld=%p: failing %" PRIuPTR " pending batches: %s",
+            elem->channel_data, this, num_batches, grpc_error_string(error));
+  }
+  CallCombinerClosureList closures;
+  for (size_t i = 0; i < GPR_ARRAY_SIZE(pending_batches_); ++i) {
+    grpc_transport_stream_op_batch*& batch = pending_batches_[i];
+    if (batch != nullptr) {
+      batch->handler_private.extra_arg = this;
+      GRPC_CLOSURE_INIT(&batch->handler_private.closure,
+                        FailPendingBatchInCallCombiner, batch,
+                        grpc_schedule_on_exec_ctx);
+      closures.Add(&batch->handler_private.closure, GRPC_ERROR_REF(error),
+                   "PendingBatchesFail");
+      batch = nullptr;
+    }
+  }
+  if (yield_call_combiner_predicate(closures)) {
+    closures.RunClosures(call_combiner_);
+  } else {
+    closures.RunClosuresWithoutYielding(call_combiner_);
+  }
+  GRPC_ERROR_UNREF(error);
+}
+
+// This is called via the call combiner, so access to calld is synchronized.
+void CallData::ResumePendingBatchInCallCombiner(void* arg,
+                                                grpc_error* /*ignored*/) {
+  grpc_transport_stream_op_batch* batch =
+      static_cast<grpc_transport_stream_op_batch*>(arg);
+  auto* elem =
+      static_cast<grpc_call_element*>(batch->handler_private.extra_arg);
+  auto* calld = static_cast<CallData*>(elem->call_data);
+  // Note: This will release the call combiner.
+  calld->dynamic_call_->StartTransportStreamOpBatch(batch);
+}
+
+// This is called via the call combiner, so access to calld is synchronized.
+void CallData::PendingBatchesResume(grpc_call_element* elem) {
+  ChannelData* chand = static_cast<ChannelData*>(elem->channel_data);
+  // Retries not enabled; send down batches as-is.
+  if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_call_trace)) {
+    size_t num_batches = 0;
+    for (size_t i = 0; i < GPR_ARRAY_SIZE(pending_batches_); ++i) {
+      if (pending_batches_[i] != nullptr) ++num_batches;
+    }
+    gpr_log(GPR_INFO,
+            "chand=%p calld=%p: starting %" PRIuPTR
+            " pending batches on dynamic_call=%p",
+            chand, this, num_batches, dynamic_call_.get());
+  }
+  CallCombinerClosureList closures;
+  for (size_t i = 0; i < GPR_ARRAY_SIZE(pending_batches_); ++i) {
+    grpc_transport_stream_op_batch*& batch = pending_batches_[i];
+    if (batch != nullptr) {
+      batch->handler_private.extra_arg = elem;
+      GRPC_CLOSURE_INIT(&batch->handler_private.closure,
+                        ResumePendingBatchInCallCombiner, batch, nullptr);
+      closures.Add(&batch->handler_private.closure, GRPC_ERROR_NONE,
+                   "PendingBatchesResume");
+      batch = nullptr;
+    }
+  }
+  // Note: This will release the call combiner.
+  closures.RunClosures(call_combiner_);
+}
+
+//
+// name resolution
+//
+
+// A class to handle the call combiner cancellation callback for a
+// queued pick.
+class CallData::ResolverQueuedCallCanceller {
+ public:
+  explicit ResolverQueuedCallCanceller(grpc_call_element* elem) : elem_(elem) {
+    auto* calld = static_cast<CallData*>(elem->call_data);
+    GRPC_CALL_STACK_REF(calld->owning_call_, "ResolverQueuedCallCanceller");
+    GRPC_CLOSURE_INIT(&closure_, &CancelLocked, this,
+                      grpc_schedule_on_exec_ctx);
+    calld->call_combiner_->SetNotifyOnCancel(&closure_);
+  }
+
+ private:
+  static void CancelLocked(void* arg, grpc_error* error) {
+    auto* self = static_cast<ResolverQueuedCallCanceller*>(arg);
+    auto* chand = static_cast<ChannelData*>(self->elem_->channel_data);
+    auto* calld = static_cast<CallData*>(self->elem_->call_data);
+    {
+      MutexLock lock(chand->resolution_mu());
+      if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_routing_trace)) {
+        gpr_log(GPR_INFO,
+                "chand=%p calld=%p: cancelling resolver queued pick: "
+                "error=%s self=%p calld->resolver_pick_canceller=%p",
+                chand, calld, grpc_error_string(error), self,
+                calld->resolver_call_canceller_);
+      }
+      if (calld->resolver_call_canceller_ == self && error != GRPC_ERROR_NONE) {
+        // Remove pick from list of queued picks.
+        calld->MaybeRemoveCallFromResolverQueuedCallsLocked(self->elem_);
+        // Fail pending batches on the call.
+        calld->PendingBatchesFail(self->elem_, GRPC_ERROR_REF(error),
+                                  YieldCallCombinerIfPendingBatchesFound);
+      }
+    }
+    GRPC_CALL_STACK_UNREF(calld->owning_call_, "ResolvingQueuedCallCanceller");
+    delete self;
+  }
+
+  grpc_call_element* elem_;
+  grpc_closure closure_;
+};
+
+void CallData::MaybeRemoveCallFromResolverQueuedCallsLocked(
+    grpc_call_element* elem) {
+  if (!queued_pending_resolver_result_) return;
+  auto* chand = static_cast<ChannelData*>(elem->channel_data);
+  if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_routing_trace)) {
+    gpr_log(GPR_INFO,
+            "chand=%p calld=%p: removing from resolver queued picks list",
+            chand, this);
+  }
+  chand->RemoveResolverQueuedCall(&resolver_queued_call_, pollent_);
+  queued_pending_resolver_result_ = false;
+  // Lame the call combiner canceller.
+  resolver_call_canceller_ = nullptr;
+}
+
+void CallData::MaybeAddCallToResolverQueuedCallsLocked(
+    grpc_call_element* elem) {
+  if (queued_pending_resolver_result_) return;
+  auto* chand = static_cast<ChannelData*>(elem->channel_data);
+  if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_routing_trace)) {
+    gpr_log(GPR_INFO, "chand=%p calld=%p: adding to resolver queued picks list",
+            chand, this);
+  }
+  queued_pending_resolver_result_ = true;
+  resolver_queued_call_.elem = elem;
+  chand->AddResolverQueuedCall(&resolver_queued_call_, pollent_);
+  // Register call combiner cancellation callback.
+  resolver_call_canceller_ = new ResolverQueuedCallCanceller(elem);
+}
+
+grpc_error* CallData::ApplyServiceConfigToCallLocked(
+    grpc_call_element* elem, grpc_metadata_batch* initial_metadata) {
+  ChannelData* chand = static_cast<ChannelData*>(elem->channel_data);
+  if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_routing_trace)) {
+    gpr_log(GPR_INFO, "chand=%p calld=%p: applying service config to call",
+            chand, this);
+  }
+  ConfigSelector* config_selector = chand->config_selector();
+  if (config_selector != nullptr) {
+    // Use the ConfigSelector to determine the config for the call.
+    ConfigSelector::CallConfig call_config =
+        config_selector->GetCallConfig({&path_, initial_metadata, arena_});
+    if (call_config.error != GRPC_ERROR_NONE) return call_config.error;
+    on_call_committed_ = std::move(call_config.on_call_committed);
+    // Create a ServiceConfigCallData for the call.  This stores a ref to the
+    // ServiceConfig and caches the right set of parsed configs to use for
+    // the call.  The MethodConfig will store itself in the call context,
+    // so that it can be accessed by filters in the subchannel, and it
+    // will be cleaned up when the call ends.
+    auto* service_config_call_data = arena_->New<ServiceConfigCallData>(
+        std::move(call_config.service_config), call_config.method_configs,
+        std::move(call_config.call_attributes), call_context_);
+    // Apply our own method params to the call.
+    auto* method_params = static_cast<ClientChannelMethodParsedConfig*>(
+        service_config_call_data->GetMethodParsedConfig(
+            internal::ClientChannelServiceConfigParser::ParserIndex()));
+    if (method_params != nullptr) {
+      // If the deadline from the service config is shorter than the one
+      // from the client API, reset the deadline timer.
+      if (chand->deadline_checking_enabled() && method_params->timeout() != 0) {
+        const grpc_millis per_method_deadline =
+            grpc_cycle_counter_to_millis_round_up(call_start_time_) +
+            method_params->timeout();
+        if (per_method_deadline < deadline_) {
+          deadline_ = per_method_deadline;
+          grpc_deadline_state_reset(elem, deadline_);
+        }
+      }
+      // If the service config set wait_for_ready and the application
+      // did not explicitly set it, use the value from the service config.
+      uint32_t* send_initial_metadata_flags =
+          &pending_batches_[0]
+               ->payload->send_initial_metadata.send_initial_metadata_flags;
+      if (method_params->wait_for_ready().has_value() &&
+          !(*send_initial_metadata_flags &
+            GRPC_INITIAL_METADATA_WAIT_FOR_READY_EXPLICITLY_SET)) {
+        if (method_params->wait_for_ready().value()) {
+          *send_initial_metadata_flags |= GRPC_INITIAL_METADATA_WAIT_FOR_READY;
+        } else {
+          *send_initial_metadata_flags &= ~GRPC_INITIAL_METADATA_WAIT_FOR_READY;
+        }
+      }
+    }
+    // Set the dynamic filter stack.
+    dynamic_filters_ = chand->dynamic_filters();
+  }
+  return GRPC_ERROR_NONE;
+}
+
+void CallData::RecvInitialMetadataReadyForConfigSelectorCommitCallback(
+    void* arg, grpc_error* error) {
+  auto* self = static_cast<CallData*>(arg);
+  if (self->on_call_committed_ != nullptr) {
+    self->on_call_committed_();
+    self->on_call_committed_ = nullptr;
+  }
+  // Chain to original callback.
+  Closure::Run(DEBUG_LOCATION, self->original_recv_initial_metadata_ready_,
+               GRPC_ERROR_REF(error));
+}
+
+// TODO(roth): Consider not intercepting this callback unless we
+// actually need to, if this causes a performance problem.
+void CallData::InjectRecvInitialMetadataReadyForConfigSelectorCommitCallback(
+    grpc_transport_stream_op_batch* batch) {
+  original_recv_initial_metadata_ready_ =
+      batch->payload->recv_initial_metadata.recv_initial_metadata_ready;
+  GRPC_CLOSURE_INIT(&recv_initial_metadata_ready_,
+                    RecvInitialMetadataReadyForConfigSelectorCommitCallback,
+                    this, nullptr);
+  batch->payload->recv_initial_metadata.recv_initial_metadata_ready =
+      &recv_initial_metadata_ready_;
+}
+
+void CallData::AsyncResolutionDone(grpc_call_element* elem, grpc_error* error) {
+  GRPC_CLOSURE_INIT(&pick_closure_, ResolutionDone, elem, nullptr);
+  ExecCtx::Run(DEBUG_LOCATION, &pick_closure_, error);
+}
+
+void CallData::ResolutionDone(void* arg, grpc_error* error) {
+  grpc_call_element* elem = static_cast<grpc_call_element*>(arg);
+  ChannelData* chand = static_cast<ChannelData*>(elem->channel_data);
+  CallData* calld = static_cast<CallData*>(elem->call_data);
+  if (error != GRPC_ERROR_NONE) {
+    if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_routing_trace)) {
+      gpr_log(GPR_INFO,
+              "chand=%p calld=%p: error applying config to call: error=%s",
+              chand, calld, grpc_error_string(error));
+    }
+    calld->PendingBatchesFail(elem, GRPC_ERROR_REF(error), YieldCallCombiner);
+    return;
+  }
+  calld->CreateDynamicCall(elem);
+}
+
+void CallData::CheckResolution(void* arg, grpc_error* error) {
+  grpc_call_element* elem = static_cast<grpc_call_element*>(arg);
+  CallData* calld = static_cast<CallData*>(elem->call_data);
+  ChannelData* chand = static_cast<ChannelData*>(elem->channel_data);
+  bool resolution_complete;
+  {
+    MutexLock lock(chand->resolution_mu());
+    resolution_complete = calld->CheckResolutionLocked(elem, &error);
+  }
+  if (resolution_complete) {
+    ResolutionDone(elem, error);
+    GRPC_ERROR_UNREF(error);
+  }
+}
+
+bool CallData::CheckResolutionLocked(grpc_call_element* elem,
+                                     grpc_error** error) {
+  ChannelData* chand = static_cast<ChannelData*>(elem->channel_data);
+  // If we're still in IDLE, we need to start resolving.
+  if (GPR_UNLIKELY(chand->CheckConnectivityState(false) == GRPC_CHANNEL_IDLE)) {
+    // Bounce into the control plane work serializer to start resolving,
+    // in case we are still in IDLE state.  Since we are holding on to the
+    // resolution mutex here, we offload it on the ExecCtx so that we don't
+    // deadlock with ourselves.
+    GRPC_CHANNEL_STACK_REF(chand->owning_stack(), "CheckResolutionLocked");
+    ExecCtx::Run(
+        DEBUG_LOCATION,
+        GRPC_CLOSURE_CREATE(
+            [](void* arg, grpc_error* /*error*/) {
+              auto* chand = static_cast<ChannelData*>(arg);
+              chand->work_serializer()->Run(
+                  [chand]() {
+                    chand->CheckConnectivityState(/*try_to_connect=*/true);
+                    GRPC_CHANNEL_STACK_UNREF(chand->owning_stack(),
+                                             "CheckResolutionLocked");
+                  },
+                  DEBUG_LOCATION);
+            },
+            chand, nullptr),
+        GRPC_ERROR_NONE);
+  }
+  // Get send_initial_metadata batch and flags.
+  auto& send_initial_metadata =
+      pending_batches_[0]->payload->send_initial_metadata;
+  grpc_metadata_batch* initial_metadata_batch =
+      send_initial_metadata.send_initial_metadata;
+  const uint32_t send_initial_metadata_flags =
+      send_initial_metadata.send_initial_metadata_flags;
+  // If we don't yet have a resolver result, we need to queue the call
+  // until we get one.
+  if (GPR_UNLIKELY(!chand->received_service_config_data())) {
+    // If the resolver returned transient failure before returning the
+    // first service config, fail any non-wait_for_ready calls.
+    grpc_error* resolver_error = chand->resolver_transient_failure_error();
+    if (resolver_error != GRPC_ERROR_NONE &&
+        (send_initial_metadata_flags & GRPC_INITIAL_METADATA_WAIT_FOR_READY) ==
+            0) {
+      MaybeRemoveCallFromResolverQueuedCallsLocked(elem);
+      *error = GRPC_ERROR_REF(resolver_error);
+      return true;
+    }
+    // Either the resolver has not yet returned a result, or it has
+    // returned transient failure but the call is wait_for_ready.  In
+    // either case, queue the call.
+    MaybeAddCallToResolverQueuedCallsLocked(elem);
+    return false;
+  }
+  // Apply service config to call if not yet applied.
+  if (GPR_LIKELY(!service_config_applied_)) {
+    service_config_applied_ = true;
+    *error = ApplyServiceConfigToCallLocked(elem, initial_metadata_batch);
+  }
+  MaybeRemoveCallFromResolverQueuedCallsLocked(elem);
+  return true;
+}
+
+void CallData::CreateDynamicCall(grpc_call_element* elem) {
+  auto* chand = static_cast<ChannelData*>(elem->channel_data);
+  DynamicFilters::Call::Args args = {std::move(dynamic_filters_),
+                                     pollent_,
+                                     path_,
+                                     call_start_time_,
+                                     deadline_,
+                                     arena_,
+                                     call_context_,
+                                     call_combiner_};
+  grpc_error* error = GRPC_ERROR_NONE;
+  DynamicFilters* channel_stack = args.channel_stack.get();
+  dynamic_call_ = channel_stack->CreateCall(std::move(args), &error);
+  if (error != GRPC_ERROR_NONE) {
+    if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_routing_trace)) {
+      gpr_log(GPR_INFO,
+              "chand=%p calld=%p: failed to create dynamic call: error=%s",
+              chand, this, grpc_error_string(error));
+    }
+    PendingBatchesFail(elem, error, YieldCallCombiner);
+    return;
+  }
+  PendingBatchesResume(elem);
+}
+
+//
+// RetryingCall implementation
+//
+
+// Retry support:
+//
+// In order to support retries, we act as a proxy for stream op batches.
+// When we get a batch from the surface, we add it to our list of pending
+// batches, and we then use those batches to construct separate "child"
+// batches to be started on the subchannel call.  When the child batches
+// return, we then decide which pending batches have been completed and
+// schedule their callbacks accordingly.  If a subchannel call fails and
+// we want to retry it, we do a new pick and start again, constructing
+// new "child" batches for the new subchannel call.
+//
+// Note that retries are committed when receiving data from the server
+// (except for Trailers-Only responses).  However, there may be many
+// send ops started before receiving any data, so we may have already
+// completed some number of send ops (and returned the completions up to
+// the surface) by the time we realize that we need to retry.  To deal
+// with this, we cache data for send ops, so that we can replay them on a
+// different subchannel call even after we have completed the original
+// batches.
+//
+// There are two sets of data to maintain:
+// - In call_data (in the parent channel), we maintain a list of pending
+//   ops and cached data for send ops.
+// - In the subchannel call, we maintain state to indicate what ops have
+//   already been sent down to that call.
+//
+// When constructing the "child" batches, we compare those two sets of
+// data to see which batches need to be sent to the subchannel call.
+
+// TODO(roth): In subsequent PRs:
+// - add support for transparent retries (including initial metadata)
+// - figure out how to record stats in census for retries
+//   (census filter is on top of this one)
+// - add census stats for retries
+
+RetryingCall::RetryingCall(
+    ChannelData* chand, const grpc_call_element_args& args,
+    grpc_polling_entity* pollent,
+    RefCountedPtr<ServerRetryThrottleData> retry_throttle_data,
+    const ClientChannelMethodParsedConfig::RetryPolicy* retry_policy)
+    : chand_(chand),
+      pollent_(pollent),
+      retry_throttle_data_(std::move(retry_throttle_data)),
+      retry_policy_(retry_policy),
+      retry_backoff_(
+          BackOff::Options()
+              .set_initial_backoff(
+                  retry_policy_ == nullptr ? 0 : retry_policy_->initial_backoff)
+              .set_multiplier(retry_policy_ == nullptr
+                                  ? 0
+                                  : retry_policy_->backoff_multiplier)
+              .set_jitter(RETRY_BACKOFF_JITTER)
+              .set_max_backoff(
+                  retry_policy_ == nullptr ? 0 : retry_policy_->max_backoff)),
+      path_(grpc_slice_ref_internal(args.path)),
+      call_start_time_(args.start_time),
+      deadline_(args.deadline),
+      arena_(args.arena),
+      owning_call_(args.call_stack),
+      call_combiner_(args.call_combiner),
+      call_context_(args.context),
+      pending_send_initial_metadata_(false),
+      pending_send_message_(false),
+      pending_send_trailing_metadata_(false),
+      enable_retries_(true),
+      retry_committed_(false),
+      last_attempt_got_server_pushback_(false) {}
+
+RetryingCall::~RetryingCall() {
+  grpc_slice_unref_internal(path_);
+  GRPC_ERROR_UNREF(cancel_error_);
+  // Make sure there are no remaining pending batches.
+  for (size_t i = 0; i < GPR_ARRAY_SIZE(pending_batches_); ++i) {
+    GPR_ASSERT(pending_batches_[i].batch == nullptr);
+  }
+}
+
+void RetryingCall::StartTransportStreamOpBatch(
+    grpc_transport_stream_op_batch* batch) {
+  // If we've previously been cancelled, immediately fail any new batches.
+  if (GPR_UNLIKELY(cancel_error_ != GRPC_ERROR_NONE)) {
+    if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_call_trace)) {
+      gpr_log(GPR_INFO,
+              "chand=%p retrying_call=%p: failing batch with error: %s", chand_,
+              this, grpc_error_string(cancel_error_));
+    }
+    // Note: This will release the call combiner.
+    grpc_transport_stream_op_batch_finish_with_failure(
+        batch, GRPC_ERROR_REF(cancel_error_), call_combiner_);
+    return;
+  }
+  // Handle cancellation.
+  if (GPR_UNLIKELY(batch->cancel_stream)) {
+    // Stash a copy of cancel_error in our call data, so that we can use
+    // it for subsequent operations.  This ensures that if the call is
+    // cancelled before any batches are passed down (e.g., if the deadline
+    // is in the past when the call starts), we can return the right
+    // error to the caller when the first batch does get passed down.
+    GRPC_ERROR_UNREF(cancel_error_);
+    cancel_error_ = GRPC_ERROR_REF(batch->payload->cancel_stream.cancel_error);
+    if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_call_trace)) {
+      gpr_log(GPR_INFO, "chand=%p retrying_call=%p: recording cancel_error=%s",
+              chand_, this, grpc_error_string(cancel_error_));
+    }
+    // If we do not have an LB call (i.e., a pick has not yet been started),
+    // fail all pending batches.  Otherwise, send the cancellation down to the
+    // LB call.
+    if (lb_call_ == nullptr) {
+      // TODO(roth): If there is a pending retry callback, do we need to
+      // cancel it here?
+      PendingBatchesFail(GRPC_ERROR_REF(cancel_error_), NoYieldCallCombiner);
+      // Note: This will release the call combiner.
+      grpc_transport_stream_op_batch_finish_with_failure(
+          batch, GRPC_ERROR_REF(cancel_error_), call_combiner_);
+    } else {
+      // Note: This will release the call combiner.
+      lb_call_->StartTransportStreamOpBatch(batch);
+    }
+    return;
+  }
+  // Add the batch to the pending list.
+  PendingBatchesAdd(batch);
+  // Create LB call if needed.
+  // TODO(roth): If we get a new batch from the surface after the
+  // initial retry attempt has failed, while the retry timer is pending,
+  // we should queue the batch and not try to send it immediately.
+  if (lb_call_ == nullptr) {
+    // We do not yet have an LB call, so create one.
+    if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_call_trace)) {
+      gpr_log(GPR_INFO, "chand=%p retrying_call=%p: creating LB call", chand_,
+              this);
+    }
+    CreateLbCall(this, GRPC_ERROR_NONE);
+    return;
+  }
+  // Send batches to LB call.
+  if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_call_trace)) {
+    gpr_log(GPR_INFO, "chand=%p retrying_call=%p: starting batch on lb_call=%p",
+            chand_, this, lb_call_.get());
+  }
+  PendingBatchesResume();
+}
+
+RefCountedPtr<SubchannelCall> RetryingCall::subchannel_call() const {
+  if (lb_call_ == nullptr) return nullptr;
+  return lb_call_->subchannel_call();
+}
+
+//
+// send op data caching
+//
+
+void RetryingCall::MaybeCacheSendOpsForBatch(PendingBatch* pending) {
+  if (pending->send_ops_cached) return;
+  pending->send_ops_cached = true;
+  grpc_transport_stream_op_batch* batch = pending->batch;
+  // Save a copy of metadata for send_initial_metadata ops.
+  if (batch->send_initial_metadata) {
+    seen_send_initial_metadata_ = true;
+    GPR_ASSERT(send_initial_metadata_storage_ == nullptr);
+    grpc_metadata_batch* send_initial_metadata =
+        batch->payload->send_initial_metadata.send_initial_metadata;
+    send_initial_metadata_storage_ =
+        static_cast<grpc_linked_mdelem*>(arena_->Alloc(
+            sizeof(grpc_linked_mdelem) * send_initial_metadata->list.count));
+    grpc_metadata_batch_copy(send_initial_metadata, &send_initial_metadata_,
+                             send_initial_metadata_storage_);
+    send_initial_metadata_flags_ =
+        batch->payload->send_initial_metadata.send_initial_metadata_flags;
+    peer_string_ = batch->payload->send_initial_metadata.peer_string;
+  }
+  // Set up cache for send_message ops.
+  if (batch->send_message) {
+    ByteStreamCache* cache = arena_->New<ByteStreamCache>(
+        std::move(batch->payload->send_message.send_message));
+    send_messages_.push_back(cache);
+  }
+  // Save metadata batch for send_trailing_metadata ops.
+  if (batch->send_trailing_metadata) {
+    seen_send_trailing_metadata_ = true;
+    GPR_ASSERT(send_trailing_metadata_storage_ == nullptr);
+    grpc_metadata_batch* send_trailing_metadata =
+        batch->payload->send_trailing_metadata.send_trailing_metadata;
+    send_trailing_metadata_storage_ =
+        static_cast<grpc_linked_mdelem*>(arena_->Alloc(
+            sizeof(grpc_linked_mdelem) * send_trailing_metadata->list.count));
+    grpc_metadata_batch_copy(send_trailing_metadata, &send_trailing_metadata_,
+                             send_trailing_metadata_storage_);
+  }
+}
+
+void RetryingCall::FreeCachedSendInitialMetadata() {
+  if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_call_trace)) {
+    gpr_log(GPR_INFO,
+            "chand=%p retrying_call=%p: destroying send_initial_metadata",
+            chand_, this);
+  }
+  grpc_metadata_batch_destroy(&send_initial_metadata_);
+}
+
+void RetryingCall::FreeCachedSendMessage(size_t idx) {
+  if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_call_trace)) {
+    gpr_log(GPR_INFO,
+            "chand=%p retrying_call=%p: destroying send_messages[%" PRIuPTR "]",
+            chand_, this, idx);
+  }
+  send_messages_[idx]->Destroy();
+}
+
+void RetryingCall::FreeCachedSendTrailingMetadata() {
+  if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_call_trace)) {
+    gpr_log(GPR_INFO,
+            "chand_=%p retrying_call=%p: destroying send_trailing_metadata",
+            chand_, this);
+  }
+  grpc_metadata_batch_destroy(&send_trailing_metadata_);
+}
+
+void RetryingCall::FreeCachedSendOpDataAfterCommit(
+    SubchannelCallRetryState* retry_state) {
+  if (retry_state->completed_send_initial_metadata) {
+    FreeCachedSendInitialMetadata();
+  }
+  for (size_t i = 0; i < retry_state->completed_send_message_count; ++i) {
+    FreeCachedSendMessage(i);
+  }
+  if (retry_state->completed_send_trailing_metadata) {
+    FreeCachedSendTrailingMetadata();
+  }
+}
+
+void RetryingCall::FreeCachedSendOpDataForCompletedBatch(
+    SubchannelCallBatchData* batch_data,
+    SubchannelCallRetryState* retry_state) {
+  if (batch_data->batch.send_initial_metadata) {
+    FreeCachedSendInitialMetadata();
+  }
+  if (batch_data->batch.send_message) {
+    FreeCachedSendMessage(retry_state->completed_send_message_count - 1);
+  }
+  if (batch_data->batch.send_trailing_metadata) {
+    FreeCachedSendTrailingMetadata();
+  }
+}
+
+//
+// pending_batches management
+//
+
+size_t RetryingCall::GetBatchIndex(grpc_transport_stream_op_batch* batch) {
+  // Note: It is important the send_initial_metadata be the first entry
+  // here, since the code in pick_subchannel_locked() assumes it will be.
+  if (batch->send_initial_metadata) return 0;
+  if (batch->send_message) return 1;
+  if (batch->send_trailing_metadata) return 2;
+  if (batch->recv_initial_metadata) return 3;
+  if (batch->recv_message) return 4;
+  if (batch->recv_trailing_metadata) return 5;
+  GPR_UNREACHABLE_CODE(return (size_t)-1);
+}
+
+// This is called via the call combiner, so access to calld is synchronized.
+void RetryingCall::PendingBatchesAdd(grpc_transport_stream_op_batch* batch) {
+  const size_t idx = GetBatchIndex(batch);
+  if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_call_trace)) {
+    gpr_log(
+        GPR_INFO,
+        "chand_=%p retrying_call=%p: adding pending batch at index %" PRIuPTR,
+        chand_, this, idx);
+  }
+  PendingBatch* pending = &pending_batches_[idx];
+  GPR_ASSERT(pending->batch == nullptr);
+  pending->batch = batch;
+  pending->send_ops_cached = false;
+  if (enable_retries_) {
+    // Update state in calld about pending batches.
+    // Also check if the batch takes us over the retry buffer limit.
+    // Note: We don't check the size of trailing metadata here, because
+    // gRPC clients do not send trailing metadata.
+    if (batch->send_initial_metadata) {
+      pending_send_initial_metadata_ = true;
+      bytes_buffered_for_retry_ += grpc_metadata_batch_size(
+          batch->payload->send_initial_metadata.send_initial_metadata);
+    }
+    if (batch->send_message) {
       pending_send_message_ = true;
       bytes_buffered_for_retry_ +=
           batch->payload->send_message.send_message->length();
@@ -2486,32 +3476,35 @@ void CallData::PendingBatchesAdd(grpc_call_element* elem,
       pending_send_trailing_metadata_ = true;
     }
     if (GPR_UNLIKELY(bytes_buffered_for_retry_ >
-                     chand->per_rpc_retry_buffer_size())) {
+                     chand_->per_rpc_retry_buffer_size())) {
       if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_call_trace)) {
         gpr_log(GPR_INFO,
-                "chand=%p calld=%p: exceeded retry buffer size, committing",
-                chand, this);
+                "chand=%p retrying_call=%p: exceeded retry buffer size, "
+                "committing",
+                chand_, this);
       }
       SubchannelCallRetryState* retry_state =
-          subchannel_call_ == nullptr ? nullptr
-                                      : static_cast<SubchannelCallRetryState*>(
-                                            subchannel_call_->GetParentData());
-      RetryCommit(elem, retry_state);
+          lb_call_ == nullptr ? nullptr
+                              : static_cast<SubchannelCallRetryState*>(
+                                    lb_call_->GetParentData());
+      RetryCommit(retry_state);
       // If we are not going to retry and have not yet started, pretend
       // retries are disabled so that we don't bother with retry overhead.
       if (num_attempts_completed_ == 0) {
         if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_call_trace)) {
           gpr_log(GPR_INFO,
-                  "chand=%p calld=%p: disabling retries before first attempt",
-                  chand, this);
+                  "chand=%p retrying_call=%p: disabling retries before first "
+                  "attempt",
+                  chand_, this);
         }
+        // TODO(roth): Treat this as a commit?
         enable_retries_ = false;
       }
     }
   }
 }
 
-void CallData::PendingBatchClear(PendingBatch* pending) {
+void RetryingCall::PendingBatchClear(PendingBatch* pending) {
   if (enable_retries_) {
     if (pending->batch->send_initial_metadata) {
       pending_send_initial_metadata_ = false;
@@ -2526,9 +3519,7 @@ void CallData::PendingBatchClear(PendingBatch* pending) {
   pending->batch = nullptr;
 }
 
-void CallData::MaybeClearPendingBatch(grpc_call_element* elem,
-                                      PendingBatch* pending) {
-  ChannelData* chand = static_cast<ChannelData*>(elem->channel_data);
+void RetryingCall::MaybeClearPendingBatch(PendingBatch* pending) {
   grpc_transport_stream_op_batch* batch = pending->batch;
   // We clear the pending batch if all of its callbacks have been
   // scheduled and reset to nullptr.
@@ -2542,26 +3533,28 @@ void CallData::MaybeClearPendingBatch(grpc_call_element* elem,
        batch->payload->recv_trailing_metadata.recv_trailing_metadata_ready ==
            nullptr)) {
     if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_call_trace)) {
-      gpr_log(GPR_INFO, "chand=%p calld=%p: clearing pending batch", chand,
-              this);
+      gpr_log(GPR_INFO, "chand=%p retrying_call=%p: clearing pending batch",
+              chand_, this);
     }
     PendingBatchClear(pending);
   }
 }
 
 // This is called via the call combiner, so access to calld is synchronized.
-void CallData::FailPendingBatchInCallCombiner(void* arg, grpc_error* error) {
+void RetryingCall::FailPendingBatchInCallCombiner(void* arg,
+                                                  grpc_error* error) {
   grpc_transport_stream_op_batch* batch =
       static_cast<grpc_transport_stream_op_batch*>(arg);
-  CallData* calld = static_cast<CallData*>(batch->handler_private.extra_arg);
+  RetryingCall* call =
+      static_cast<RetryingCall*>(batch->handler_private.extra_arg);
   // Note: This will release the call combiner.
   grpc_transport_stream_op_batch_finish_with_failure(
-      batch, GRPC_ERROR_REF(error), calld->call_combiner_);
+      batch, GRPC_ERROR_REF(error), call->call_combiner_);
 }
 
 // This is called via the call combiner, so access to calld is synchronized.
-void CallData::PendingBatchesFail(
-    grpc_call_element* elem, grpc_error* error,
+void RetryingCall::PendingBatchesFail(
+    grpc_error* error,
     YieldCallCombinerPredicate yield_call_combiner_predicate) {
   GPR_ASSERT(error != GRPC_ERROR_NONE);
   if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_call_trace)) {
@@ -2570,17 +3563,15 @@ void CallData::PendingBatchesFail(
       if (pending_batches_[i].batch != nullptr) ++num_batches;
     }
     gpr_log(GPR_INFO,
-            "chand=%p calld=%p: failing %" PRIuPTR " pending batches: %s",
-            elem->channel_data, this, num_batches, grpc_error_string(error));
+            "chand=%p retrying_call=%p: failing %" PRIuPTR
+            " pending batches: %s",
+            chand_, this, num_batches, grpc_error_string(error));
   }
   CallCombinerClosureList closures;
   for (size_t i = 0; i < GPR_ARRAY_SIZE(pending_batches_); ++i) {
     PendingBatch* pending = &pending_batches_[i];
     grpc_transport_stream_op_batch* batch = pending->batch;
     if (batch != nullptr) {
-      if (batch->recv_trailing_metadata) {
-        MaybeInjectRecvTrailingMetadataReadyForLoadBalancingPolicy(batch);
-      }
       batch->handler_private.extra_arg = this;
       GRPC_CLOSURE_INIT(&batch->handler_private.closure,
                         FailPendingBatchInCallCombiner, batch,
@@ -2599,21 +3590,20 @@ void CallData::PendingBatchesFail(
 }
 
 // This is called via the call combiner, so access to calld is synchronized.
-void CallData::ResumePendingBatchInCallCombiner(void* arg,
-                                                grpc_error* /*ignored*/) {
+void RetryingCall::ResumePendingBatchInCallCombiner(void* arg,
+                                                    grpc_error* /*ignored*/) {
   grpc_transport_stream_op_batch* batch =
       static_cast<grpc_transport_stream_op_batch*>(arg);
-  SubchannelCall* subchannel_call =
-      static_cast<SubchannelCall*>(batch->handler_private.extra_arg);
+  auto* lb_call =
+      static_cast<LoadBalancedCall*>(batch->handler_private.extra_arg);
   // Note: This will release the call combiner.
-  subchannel_call->StartTransportStreamOpBatch(batch);
+  lb_call->StartTransportStreamOpBatch(batch);
 }
 
 // This is called via the call combiner, so access to calld is synchronized.
-void CallData::PendingBatchesResume(grpc_call_element* elem) {
-  ChannelData* chand = static_cast<ChannelData*>(elem->channel_data);
+void RetryingCall::PendingBatchesResume() {
   if (enable_retries_) {
-    StartRetriableSubchannelBatches(elem, GRPC_ERROR_NONE);
+    StartRetriableSubchannelBatches(this, GRPC_ERROR_NONE);
     return;
   }
   // Retries not enabled; send down batches as-is.
@@ -2623,22 +3613,18 @@ void CallData::PendingBatchesResume(grpc_call_element* elem) {
       if (pending_batches_[i].batch != nullptr) ++num_batches;
     }
     gpr_log(GPR_INFO,
-            "chand=%p calld=%p: starting %" PRIuPTR
-            " pending batches on subchannel_call=%p",
-            chand, this, num_batches, subchannel_call_.get());
+            "chand=%p retrying_call=%p: starting %" PRIuPTR
+            " pending batches on lb_call=%p",
+            chand_, this, num_batches, lb_call_.get());
   }
   CallCombinerClosureList closures;
   for (size_t i = 0; i < GPR_ARRAY_SIZE(pending_batches_); ++i) {
     PendingBatch* pending = &pending_batches_[i];
     grpc_transport_stream_op_batch* batch = pending->batch;
     if (batch != nullptr) {
-      if (batch->recv_trailing_metadata) {
-        MaybeInjectRecvTrailingMetadataReadyForLoadBalancingPolicy(batch);
-      }
-      batch->handler_private.extra_arg = subchannel_call_.get();
+      batch->handler_private.extra_arg = lb_call_.get();
       GRPC_CLOSURE_INIT(&batch->handler_private.closure,
-                        ResumePendingBatchInCallCombiner, batch,
-                        grpc_schedule_on_exec_ctx);
+                        ResumePendingBatchInCallCombiner, batch, nullptr);
       closures.Add(&batch->handler_private.closure, GRPC_ERROR_NONE,
                    "PendingBatchesResume");
       PendingBatchClear(pending);
@@ -2649,18 +3635,17 @@ void CallData::PendingBatchesResume(grpc_call_element* elem) {
 }
 
 template <typename Predicate>
-CallData::PendingBatch* CallData::PendingBatchFind(grpc_call_element* elem,
-                                                   const char* log_message,
-                                                   Predicate predicate) {
-  ChannelData* chand = static_cast<ChannelData*>(elem->channel_data);
+RetryingCall::PendingBatch* RetryingCall::PendingBatchFind(
+    const char* log_message, Predicate predicate) {
   for (size_t i = 0; i < GPR_ARRAY_SIZE(pending_batches_); ++i) {
     PendingBatch* pending = &pending_batches_[i];
     grpc_transport_stream_op_batch* batch = pending->batch;
     if (batch != nullptr && predicate(batch)) {
       if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_call_trace)) {
-        gpr_log(GPR_INFO,
-                "chand=%p calld=%p: %s pending batch at index %" PRIuPTR, chand,
-                this, log_message, i);
+        gpr_log(
+            GPR_INFO,
+            "chand=%p retrying_call=%p: %s pending batch at index %" PRIuPTR,
+            chand_, this, log_message, i);
       }
       return pending;
     }
@@ -2672,28 +3657,23 @@ CallData::PendingBatch* CallData::PendingBatchFind(grpc_call_element* elem,
 // retry code
 //
 
-void CallData::RetryCommit(grpc_call_element* elem,
-                           SubchannelCallRetryState* retry_state) {
-  ChannelData* chand = static_cast<ChannelData*>(elem->channel_data);
+void RetryingCall::RetryCommit(SubchannelCallRetryState* retry_state) {
   if (retry_committed_) return;
   retry_committed_ = true;
   if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_call_trace)) {
-    gpr_log(GPR_INFO, "chand=%p calld=%p: committing retries", chand, this);
+    gpr_log(GPR_INFO, "chand=%p retrying_call=%p: committing retries", chand_,
+            this);
   }
   if (retry_state != nullptr) {
-    FreeCachedSendOpDataAfterCommit(elem, retry_state);
+    FreeCachedSendOpDataAfterCommit(retry_state);
   }
 }
 
-void CallData::DoRetry(grpc_call_element* elem,
-                       SubchannelCallRetryState* retry_state,
-                       grpc_millis server_pushback_ms) {
-  ChannelData* chand = static_cast<ChannelData*>(elem->channel_data);
-  GPR_ASSERT(method_params_ != nullptr);
-  const auto* retry_policy = method_params_->retry_policy();
-  GPR_ASSERT(retry_policy != nullptr);
-  // Reset subchannel call.
-  subchannel_call_.reset();
+void RetryingCall::DoRetry(SubchannelCallRetryState* retry_state,
+                           grpc_millis server_pushback_ms) {
+  GPR_ASSERT(retry_policy_ != nullptr);
+  // Reset LB call.
+  lb_call_.reset();
   // Compute backoff delay.
   grpc_millis next_attempt_time;
   if (server_pushback_ms >= 0) {
@@ -2701,49 +3681,38 @@ void CallData::DoRetry(grpc_call_element* elem,
     last_attempt_got_server_pushback_ = true;
   } else {
     if (num_attempts_completed_ == 1 || last_attempt_got_server_pushback_) {
-      retry_backoff_.Init(
-          BackOff::Options()
-              .set_initial_backoff(retry_policy->initial_backoff)
-              .set_multiplier(retry_policy->backoff_multiplier)
-              .set_jitter(RETRY_BACKOFF_JITTER)
-              .set_max_backoff(retry_policy->max_backoff));
       last_attempt_got_server_pushback_ = false;
     }
-    next_attempt_time = retry_backoff_->NextAttemptTime();
+    next_attempt_time = retry_backoff_.NextAttemptTime();
   }
   if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_call_trace)) {
     gpr_log(GPR_INFO,
-            "chand=%p calld=%p: retrying failed call in %" PRId64 " ms", chand,
-            this, next_attempt_time - ExecCtx::Get()->Now());
+            "chand=%p retrying_call=%p: retrying failed call in %" PRId64 " ms",
+            chand_, this, next_attempt_time - ExecCtx::Get()->Now());
   }
   // Schedule retry after computed delay.
-  GRPC_CLOSURE_INIT(&pick_closure_, PickSubchannel, elem,
-                    grpc_schedule_on_exec_ctx);
-  grpc_timer_init(&retry_timer_, next_attempt_time, &pick_closure_);
+  GRPC_CLOSURE_INIT(&retry_closure_, CreateLbCall, this, nullptr);
+  grpc_timer_init(&retry_timer_, next_attempt_time, &retry_closure_);
   // Update bookkeeping.
   if (retry_state != nullptr) retry_state->retry_dispatched = true;
 }
 
-bool CallData::MaybeRetry(grpc_call_element* elem,
-                          SubchannelCallBatchData* batch_data,
-                          grpc_status_code status,
-                          grpc_mdelem* server_pushback_md) {
-  ChannelData* chand = static_cast<ChannelData*>(elem->channel_data);
+bool RetryingCall::MaybeRetry(SubchannelCallBatchData* batch_data,
+                              grpc_status_code status,
+                              grpc_mdelem* server_pushback_md) {
   // Get retry policy.
-  if (method_params_ == nullptr) return false;
-  const auto* retry_policy = method_params_->retry_policy();
-  if (retry_policy == nullptr) return false;
+  if (retry_policy_ == nullptr) return false;
   // If we've already dispatched a retry from this call, return true.
   // This catches the case where the batch has multiple callbacks
   // (i.e., it includes either recv_message or recv_initial_metadata).
   SubchannelCallRetryState* retry_state = nullptr;
   if (batch_data != nullptr) {
     retry_state = static_cast<SubchannelCallRetryState*>(
-        batch_data->subchannel_call->GetParentData());
+        batch_data->lb_call->GetParentData());
     if (retry_state->retry_dispatched) {
       if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_call_trace)) {
-        gpr_log(GPR_INFO, "chand=%p calld=%p: retry already dispatched", chand,
-                this);
+        gpr_log(GPR_INFO, "chand=%p retrying_call=%p: retry already dispatched",
+                chand_, this);
       }
       return true;
     }
@@ -2754,16 +3723,18 @@ bool CallData::MaybeRetry(grpc_call_element* elem,
       retry_throttle_data_->RecordSuccess();
     }
     if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_call_trace)) {
-      gpr_log(GPR_INFO, "chand=%p calld=%p: call succeeded", chand, this);
+      gpr_log(GPR_INFO, "chand=%p retrying_call=%p: call succeeded", chand_,
+              this);
     }
     return false;
   }
   // Status is not OK.  Check whether the status is retryable.
-  if (!retry_policy->retryable_status_codes.Contains(status)) {
+  if (!retry_policy_->retryable_status_codes.Contains(status)) {
     if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_call_trace)) {
-      gpr_log(GPR_INFO,
-              "chand=%p calld=%p: status %s not configured as retryable", chand,
-              this, grpc_status_code_to_string(status));
+      gpr_log(
+          GPR_INFO,
+          "chand=%p retrying_call=%p: status %s not configured as retryable",
+          chand_, this, grpc_status_code_to_string(status));
     }
     return false;
   }
@@ -2777,24 +3748,25 @@ bool CallData::MaybeRetry(grpc_call_element* elem,
   if (retry_throttle_data_ != nullptr &&
       !retry_throttle_data_->RecordFailure()) {
     if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_call_trace)) {
-      gpr_log(GPR_INFO, "chand=%p calld=%p: retries throttled", chand, this);
+      gpr_log(GPR_INFO, "chand=%p retrying_call=%p: retries throttled", chand_,
+              this);
     }
     return false;
   }
   // Check whether the call is committed.
   if (retry_committed_) {
     if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_call_trace)) {
-      gpr_log(GPR_INFO, "chand=%p calld=%p: retries already committed", chand,
-              this);
+      gpr_log(GPR_INFO, "chand=%p retrying_call=%p: retries already committed",
+              chand_, this);
     }
     return false;
   }
   // Check whether we have retries remaining.
   ++num_attempts_completed_;
-  if (num_attempts_completed_ >= retry_policy->max_attempts) {
+  if (num_attempts_completed_ >= retry_policy_->max_attempts) {
     if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_call_trace)) {
-      gpr_log(GPR_INFO, "chand=%p calld=%p: exceeded %d retry attempts", chand,
-              this, retry_policy->max_attempts);
+      gpr_log(GPR_INFO, "chand=%p retrying_call=%p: exceeded %d retry attempts",
+              chand_, this, retry_policy_->max_attempts);
     }
     return false;
   }
@@ -2802,8 +3774,9 @@ bool CallData::MaybeRetry(grpc_call_element* elem,
   if (cancel_error_ != GRPC_ERROR_NONE) {
     if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_call_trace)) {
       gpr_log(GPR_INFO,
-              "chand=%p calld=%p: call cancelled from surface, not retrying",
-              chand, this);
+              "chand=%p retrying_call=%p: call cancelled from surface, not "
+              "retrying",
+              chand_, this);
     }
     return false;
   }
@@ -2814,54 +3787,54 @@ bool CallData::MaybeRetry(grpc_call_element* elem,
     uint32_t ms;
     if (!grpc_parse_slice_to_uint32(GRPC_MDVALUE(*server_pushback_md), &ms)) {
       if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_call_trace)) {
-        gpr_log(GPR_INFO,
-                "chand=%p calld=%p: not retrying due to server push-back",
-                chand, this);
+        gpr_log(
+            GPR_INFO,
+            "chand=%p retrying_call=%p: not retrying due to server push-back",
+            chand_, this);
       }
       return false;
     } else {
       if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_call_trace)) {
-        gpr_log(GPR_INFO, "chand=%p calld=%p: server push-back: retry in %u ms",
-                chand, this, ms);
+        gpr_log(GPR_INFO,
+                "chand=%p retrying_call=%p: server push-back: retry in %u ms",
+                chand_, this, ms);
       }
-      server_pushback_ms = (grpc_millis)ms;
+      server_pushback_ms = static_cast<grpc_millis>(ms);
     }
   }
-  DoRetry(elem, retry_state, server_pushback_ms);
+  DoRetry(retry_state, server_pushback_ms);
   return true;
 }
 
 //
-// CallData::SubchannelCallBatchData
+// RetryingCall::SubchannelCallBatchData
 //
 
-CallData::SubchannelCallBatchData* CallData::SubchannelCallBatchData::Create(
-    grpc_call_element* elem, int refcount, bool set_on_complete) {
-  CallData* calld = static_cast<CallData*>(elem->call_data);
-  return calld->arena_->New<SubchannelCallBatchData>(elem, calld, refcount,
-                                                     set_on_complete);
+RetryingCall::SubchannelCallBatchData*
+RetryingCall::SubchannelCallBatchData::Create(RetryingCall* call, int refcount,
+                                              bool set_on_complete) {
+  return call->arena_->New<SubchannelCallBatchData>(call, refcount,
+                                                    set_on_complete);
 }
 
-CallData::SubchannelCallBatchData::SubchannelCallBatchData(
-    grpc_call_element* elem, CallData* calld, int refcount,
-    bool set_on_complete)
-    : elem(elem), subchannel_call(calld->subchannel_call_) {
+RetryingCall::SubchannelCallBatchData::SubchannelCallBatchData(
+    RetryingCall* call, int refcount, bool set_on_complete)
+    : call(call), lb_call(call->lb_call_) {
   SubchannelCallRetryState* retry_state =
-      static_cast<SubchannelCallRetryState*>(
-          calld->subchannel_call_->GetParentData());
+      static_cast<SubchannelCallRetryState*>(lb_call->GetParentData());
   batch.payload = &retry_state->batch_payload;
   gpr_ref_init(&refs, refcount);
   if (set_on_complete) {
-    GRPC_CLOSURE_INIT(&on_complete, CallData::OnComplete, this,
+    GRPC_CLOSURE_INIT(&on_complete, RetryingCall::OnComplete, this,
                       grpc_schedule_on_exec_ctx);
     batch.on_complete = &on_complete;
   }
-  GRPC_CALL_STACK_REF(calld->owning_call_, "batch_data");
+  GRPC_CALL_STACK_REF(call->owning_call_, "batch_data");
 }
 
-void CallData::SubchannelCallBatchData::Destroy() {
+void RetryingCall::SubchannelCallBatchData::Destroy() {
   SubchannelCallRetryState* retry_state =
-      static_cast<SubchannelCallRetryState*>(subchannel_call->GetParentData());
+      static_cast<SubchannelCallRetryState*>(lb_call->GetParentData());
   if (batch.send_initial_metadata) {
     grpc_metadata_batch_destroy(&retry_state->send_initial_metadata);
   }
@@ -2874,22 +3847,21 @@ void CallData::SubchannelCallBatchData::Destroy() {
   if (batch.recv_trailing_metadata) {
     grpc_metadata_batch_destroy(&retry_state->recv_trailing_metadata);
   }
-  subchannel_call.reset();
-  CallData* calld = static_cast<CallData*>(elem->call_data);
-  GRPC_CALL_STACK_UNREF(calld->owning_call_, "batch_data");
+  lb_call.reset();
+  GRPC_CALL_STACK_UNREF(call->owning_call_, "batch_data");
 }
 
 //
 // recv_initial_metadata callback handling
 //
 
-void CallData::InvokeRecvInitialMetadataCallback(void* arg, grpc_error* error) {
+void RetryingCall::InvokeRecvInitialMetadataCallback(void* arg,
+                                                     grpc_error* error) {
   SubchannelCallBatchData* batch_data =
       static_cast<SubchannelCallBatchData*>(arg);
-  CallData* calld = static_cast<CallData*>(batch_data->elem->call_data);
   // Find pending batch.
-  PendingBatch* pending = calld->PendingBatchFind(
-      batch_data->elem, "invoking recv_initial_metadata_ready for",
+  PendingBatch* pending = batch_data->call->PendingBatchFind(
+      "invoking recv_initial_metadata_ready for",
       [](grpc_transport_stream_op_batch* batch) {
         return batch->recv_initial_metadata &&
                batch->payload->recv_initial_metadata
@@ -2899,7 +3871,7 @@ void CallData::InvokeRecvInitialMetadataCallback(void* arg, grpc_error* error) {
   // Return metadata.
   SubchannelCallRetryState* retry_state =
       static_cast<SubchannelCallRetryState*>(
-          batch_data->subchannel_call->GetParentData());
+          batch_data->lb_call->GetParentData());
   grpc_metadata_batch_move(
       &retry_state->recv_initial_metadata,
       pending->batch->payload->recv_initial_metadata.recv_initial_metadata);
@@ -2911,33 +3883,32 @@ void CallData::InvokeRecvInitialMetadataCallback(void* arg, grpc_error* error) {
           .recv_initial_metadata_ready;
   pending->batch->payload->recv_initial_metadata.recv_initial_metadata_ready =
       nullptr;
-  calld->MaybeClearPendingBatch(batch_data->elem, pending);
+  batch_data->call->MaybeClearPendingBatch(pending);
   batch_data->Unref();
   // Invoke callback.
   Closure::Run(DEBUG_LOCATION, recv_initial_metadata_ready,
                GRPC_ERROR_REF(error));
 }
 
-void CallData::RecvInitialMetadataReady(void* arg, grpc_error* error) {
+void RetryingCall::RecvInitialMetadataReady(void* arg, grpc_error* error) {
   SubchannelCallBatchData* batch_data =
       static_cast<SubchannelCallBatchData*>(arg);
-  grpc_call_element* elem = batch_data->elem;
-  ChannelData* chand = static_cast<ChannelData*>(elem->channel_data);
-  CallData* calld = static_cast<CallData*>(elem->call_data);
+  RetryingCall* call = batch_data->call;
   if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_call_trace)) {
-    gpr_log(GPR_INFO,
-            "chand=%p calld=%p: got recv_initial_metadata_ready, error=%s",
-            chand, calld, grpc_error_string(error));
+    gpr_log(
+        GPR_INFO,
+        "chand=%p retrying_call=%p: got recv_initial_metadata_ready, error=%s",
+        call->chand_, call, grpc_error_string(error));
   }
   SubchannelCallRetryState* retry_state =
       static_cast<SubchannelCallRetryState*>(
-          batch_data->subchannel_call->GetParentData());
+          batch_data->lb_call->GetParentData());
   retry_state->completed_recv_initial_metadata = true;
   // If a retry was already dispatched, then we're not going to use the
   // result of this recv_initial_metadata op, so do nothing.
   if (retry_state->retry_dispatched) {
     GRPC_CALL_COMBINER_STOP(
-        calld->call_combiner_,
+        call->call_combiner_,
         "recv_initial_metadata_ready after retry dispatched");
     return;
   }
@@ -2949,43 +3920,43 @@ void CallData::RecvInitialMetadataReady(void* arg, grpc_error* error) {
                     error != GRPC_ERROR_NONE) &&
                    !retry_state->completed_recv_trailing_metadata)) {
     if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_call_trace)) {
-      gpr_log(GPR_INFO,
-              "chand=%p calld=%p: deferring recv_initial_metadata_ready "
-              "(Trailers-Only)",
-              chand, calld);
+      gpr_log(
+          GPR_INFO,
+          "chand=%p retrying_call=%p: deferring recv_initial_metadata_ready "
+          "(Trailers-Only)",
+          call->chand_, call);
     }
     retry_state->recv_initial_metadata_ready_deferred_batch = batch_data;
     retry_state->recv_initial_metadata_error = GRPC_ERROR_REF(error);
     if (!retry_state->started_recv_trailing_metadata) {
       // recv_trailing_metadata not yet started by application; start it
       // ourselves to get status.
-      calld->StartInternalRecvTrailingMetadata(elem);
+      call->StartInternalRecvTrailingMetadata();
     } else {
       GRPC_CALL_COMBINER_STOP(
-          calld->call_combiner_,
+          call->call_combiner_,
           "recv_initial_metadata_ready trailers-only or error");
     }
     return;
   }
   // Received valid initial metadata, so commit the call.
-  calld->RetryCommit(elem, retry_state);
-  calld->MaybeInvokeConfigSelectorCommitCallback();
+  call->RetryCommit(retry_state);
   // Invoke the callback to return the result to the surface.
   // Manually invoking a callback function; it does not take ownership of error.
-  calld->InvokeRecvInitialMetadataCallback(batch_data, error);
+  call->InvokeRecvInitialMetadataCallback(batch_data, error);
 }
 
 //
 // recv_message callback handling
 //
 
-void CallData::InvokeRecvMessageCallback(void* arg, grpc_error* error) {
+void RetryingCall::InvokeRecvMessageCallback(void* arg, grpc_error* error) {
   SubchannelCallBatchData* batch_data =
       static_cast<SubchannelCallBatchData*>(arg);
-  CallData* calld = static_cast<CallData*>(batch_data->elem->call_data);
+  RetryingCall* call = batch_data->call;
   // Find pending op.
-  PendingBatch* pending = calld->PendingBatchFind(
-      batch_data->elem, "invoking recv_message_ready for",
+  PendingBatch* pending = call->PendingBatchFind(
+      "invoking recv_message_ready for",
       [](grpc_transport_stream_op_batch* batch) {
         return batch->recv_message &&
                batch->payload->recv_message.recv_message_ready != nullptr;
@@ -2994,7 +3965,7 @@ void CallData::InvokeRecvMessageCallback(void* arg, grpc_error* error) {
   // Return payload.
   SubchannelCallRetryState* retry_state =
       static_cast<SubchannelCallRetryState*>(
-          batch_data->subchannel_call->GetParentData());
+          batch_data->lb_call->GetParentData());
   *pending->batch->payload->recv_message.recv_message =
       std::move(retry_state->recv_message);
   // Update bookkeeping.
@@ -3003,30 +3974,29 @@ void CallData::InvokeRecvMessageCallback(void* arg, grpc_error* error) {
   grpc_closure* recv_message_ready =
       pending->batch->payload->recv_message.recv_message_ready;
   pending->batch->payload->recv_message.recv_message_ready = nullptr;
-  calld->MaybeClearPendingBatch(batch_data->elem, pending);
+  call->MaybeClearPendingBatch(pending);
   batch_data->Unref();
   // Invoke callback.
   Closure::Run(DEBUG_LOCATION, recv_message_ready, GRPC_ERROR_REF(error));
 }
 
-void CallData::RecvMessageReady(void* arg, grpc_error* error) {
+void RetryingCall::RecvMessageReady(void* arg, grpc_error* error) {
   SubchannelCallBatchData* batch_data =
       static_cast<SubchannelCallBatchData*>(arg);
-  grpc_call_element* elem = batch_data->elem;
-  ChannelData* chand = static_cast<ChannelData*>(elem->channel_data);
-  CallData* calld = static_cast<CallData*>(elem->call_data);
+  RetryingCall* call = batch_data->call;
   if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_call_trace)) {
-    gpr_log(GPR_INFO, "chand=%p calld=%p: got recv_message_ready, error=%s",
-            chand, calld, grpc_error_string(error));
+    gpr_log(GPR_INFO,
+            "chand=%p retrying_call=%p: got recv_message_ready, error=%s",
+            call->chand_, call, grpc_error_string(error));
   }
   SubchannelCallRetryState* retry_state =
       static_cast<SubchannelCallRetryState*>(
-          batch_data->subchannel_call->GetParentData());
+          batch_data->lb_call->GetParentData());
   ++retry_state->completed_recv_message_count;
   // If a retry was already dispatched, then we're not going to use the
   // result of this recv_message op, so do nothing.
   if (retry_state->retry_dispatched) {
-    GRPC_CALL_COMBINER_STOP(calld->call_combiner_,
+    GRPC_CALL_COMBINER_STOP(call->call_combiner_,
                             "recv_message_ready after retry dispatched");
     return;
   }
@@ -3038,37 +4008,37 @@ void CallData::RecvMessageReady(void* arg, grpc_error* error) {
           (retry_state->recv_message == nullptr || error != GRPC_ERROR_NONE) &&
           !retry_state->completed_recv_trailing_metadata)) {
     if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_call_trace)) {
-      gpr_log(GPR_INFO,
-              "chand=%p calld=%p: deferring recv_message_ready (nullptr "
-              "message and recv_trailing_metadata pending)",
-              chand, calld);
+      gpr_log(
+          GPR_INFO,
+          "chand=%p retrying_call=%p: deferring recv_message_ready (nullptr "
+          "message and recv_trailing_metadata pending)",
+          call->chand_, call);
     }
     retry_state->recv_message_ready_deferred_batch = batch_data;
     retry_state->recv_message_error = GRPC_ERROR_REF(error);
     if (!retry_state->started_recv_trailing_metadata) {
       // recv_trailing_metadata not yet started by application; start it
       // ourselves to get status.
-      calld->StartInternalRecvTrailingMetadata(elem);
+      call->StartInternalRecvTrailingMetadata();
     } else {
-      GRPC_CALL_COMBINER_STOP(calld->call_combiner_, "recv_message_ready null");
+      GRPC_CALL_COMBINER_STOP(call->call_combiner_, "recv_message_ready null");
     }
     return;
   }
   // Received a valid message, so commit the call.
-  calld->RetryCommit(elem, retry_state);
-  calld->MaybeInvokeConfigSelectorCommitCallback();
+  call->RetryCommit(retry_state);
   // Invoke the callback to return the result to the surface.
   // Manually invoking a callback function; it does not take ownership of error.
-  calld->InvokeRecvMessageCallback(batch_data, error);
+  call->InvokeRecvMessageCallback(batch_data, error);
 }
 
 //
 // recv_trailing_metadata handling
 //
 
-void CallData::GetCallStatus(grpc_metadata_batch* md_batch, grpc_error* error,
-                             grpc_status_code* status,
-                             grpc_mdelem** server_pushback_md) {
+void RetryingCall::GetCallStatus(grpc_metadata_batch* md_batch,
+                                 grpc_error* error, grpc_status_code* status,
+                                 grpc_mdelem** server_pushback_md) {
   if (error != GRPC_ERROR_NONE) {
     grpc_error_get_status(error, deadline_, status, nullptr, nullptr, nullptr);
   } else {
@@ -3083,12 +4053,12 @@ void CallData::GetCallStatus(grpc_metadata_batch* md_batch, grpc_error* error,
   GRPC_ERROR_UNREF(error);
 }
 
-void CallData::AddClosureForRecvTrailingMetadataReady(
-    grpc_call_element* elem, SubchannelCallBatchData* batch_data,
-    grpc_error* error, CallCombinerClosureList* closures) {
+void RetryingCall::AddClosureForRecvTrailingMetadataReady(
+    SubchannelCallBatchData* batch_data, grpc_error* error,
+    CallCombinerClosureList* closures) {
   // Find pending batch.
   PendingBatch* pending = PendingBatchFind(
-      elem, "invoking recv_trailing_metadata for",
+      "invoking recv_trailing_metadata for",
       [](grpc_transport_stream_op_batch* batch) {
         return batch->recv_trailing_metadata &&
                batch->payload->recv_trailing_metadata
@@ -3103,7 +4073,7 @@ void CallData::AddClosureForRecvTrailingMetadataReady(
   // Return metadata.
   SubchannelCallRetryState* retry_state =
       static_cast<SubchannelCallRetryState*>(
-          batch_data->subchannel_call->GetParentData());
+          batch_data->lb_call->GetParentData());
   grpc_metadata_batch_move(
       &retry_state->recv_trailing_metadata,
       pending->batch->payload->recv_trailing_metadata.recv_trailing_metadata);
@@ -3114,10 +4084,10 @@ void CallData::AddClosureForRecvTrailingMetadataReady(
   // Update bookkeeping.
   pending->batch->payload->recv_trailing_metadata.recv_trailing_metadata_ready =
       nullptr;
-  MaybeClearPendingBatch(elem, pending);
+  MaybeClearPendingBatch(pending);
 }
 
-void CallData::AddClosuresForDeferredRecvCallbacks(
+void RetryingCall::AddClosuresForDeferredRecvCallbacks(
     SubchannelCallBatchData* batch_data, SubchannelCallRetryState* retry_state,
     CallCombinerClosureList* closures) {
   if (batch_data->batch.recv_trailing_metadata) {
@@ -3148,8 +4118,8 @@ void CallData::AddClosuresForDeferredRecvCallbacks(
   }
 }
 
-bool CallData::PendingBatchIsUnstarted(PendingBatch* pending,
-                                       SubchannelCallRetryState* retry_state) {
+bool RetryingCall::PendingBatchIsUnstarted(
+    PendingBatch* pending, SubchannelCallRetryState* retry_state) {
   if (pending->batch == nullptr || pending->batch->on_complete == nullptr) {
     return false;
   }
@@ -3168,45 +4138,44 @@ bool CallData::PendingBatchIsUnstarted(PendingBatch* pending,
   return false;
 }
 
-void CallData::AddClosuresToFailUnstartedPendingBatches(
-    grpc_call_element* elem, SubchannelCallRetryState* retry_state,
-    grpc_error* error, CallCombinerClosureList* closures) {
-  ChannelData* chand = static_cast<ChannelData*>(elem->channel_data);
+void RetryingCall::AddClosuresToFailUnstartedPendingBatches(
+    SubchannelCallRetryState* retry_state, grpc_error* error,
+    CallCombinerClosureList* closures) {
   for (size_t i = 0; i < GPR_ARRAY_SIZE(pending_batches_); ++i) {
     PendingBatch* pending = &pending_batches_[i];
     if (PendingBatchIsUnstarted(pending, retry_state)) {
       if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_call_trace)) {
         gpr_log(GPR_INFO,
-                "chand=%p calld=%p: failing unstarted pending batch at index "
+                "chand=%p retrying_call=%p: failing unstarted pending batch at "
+                "index "
                 "%" PRIuPTR,
-                chand, this, i);
+                chand_, this, i);
       }
       closures->Add(pending->batch->on_complete, GRPC_ERROR_REF(error),
                     "failing on_complete for pending batch");
       pending->batch->on_complete = nullptr;
-      MaybeClearPendingBatch(elem, pending);
+      MaybeClearPendingBatch(pending);
     }
   }
   GRPC_ERROR_UNREF(error);
 }
 
-void CallData::RunClosuresForCompletedCall(SubchannelCallBatchData* batch_data,
-                                           grpc_error* error) {
-  grpc_call_element* elem = batch_data->elem;
+void RetryingCall::RunClosuresForCompletedCall(
+    SubchannelCallBatchData* batch_data, grpc_error* error) {
   SubchannelCallRetryState* retry_state =
       static_cast<SubchannelCallRetryState*>(
-          batch_data->subchannel_call->GetParentData());
+          batch_data->lb_call->GetParentData());
   // Construct list of closures to execute.
   CallCombinerClosureList closures;
   // First, add closure for recv_trailing_metadata_ready.
-  AddClosureForRecvTrailingMetadataReady(elem, batch_data,
-                                         GRPC_ERROR_REF(error), &closures);
+  AddClosureForRecvTrailingMetadataReady(batch_data, GRPC_ERROR_REF(error),
+                                         &closures);
   // If there are deferred recv_initial_metadata_ready or recv_message_ready
   // callbacks, add them to closures.
   AddClosuresForDeferredRecvCallbacks(batch_data, retry_state, &closures);
   // Add closures to fail any pending batches that have not yet been started.
-  AddClosuresToFailUnstartedPendingBatches(elem, retry_state,
-                                           GRPC_ERROR_REF(error), &closures);
+  AddClosuresToFailUnstartedPendingBatches(retry_state, GRPC_ERROR_REF(error),
+                                           &closures);
   // Don't need batch_data anymore.
   batch_data->Unref();
   // Schedule all of the closures identified above.
@@ -3215,34 +4184,33 @@ void CallData::RunClosuresForCompletedCall(SubchannelCallBatchData* batch_data,
   GRPC_ERROR_UNREF(error);
 }
 
-void CallData::RecvTrailingMetadataReady(void* arg, grpc_error* error) {
+void RetryingCall::RecvTrailingMetadataReady(void* arg, grpc_error* error) {
   SubchannelCallBatchData* batch_data =
       static_cast<SubchannelCallBatchData*>(arg);
-  grpc_call_element* elem = batch_data->elem;
-  ChannelData* chand = static_cast<ChannelData*>(elem->channel_data);
-  CallData* calld = static_cast<CallData*>(elem->call_data);
+  RetryingCall* call = batch_data->call;
   if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_call_trace)) {
-    gpr_log(GPR_INFO,
-            "chand=%p calld=%p: got recv_trailing_metadata_ready, error=%s",
-            chand, calld, grpc_error_string(error));
+    gpr_log(
+        GPR_INFO,
+        "chand=%p retrying_call=%p: got recv_trailing_metadata_ready, error=%s",
+        call->chand_, call, grpc_error_string(error));
   }
   SubchannelCallRetryState* retry_state =
       static_cast<SubchannelCallRetryState*>(
-          batch_data->subchannel_call->GetParentData());
+          batch_data->lb_call->GetParentData());
   retry_state->completed_recv_trailing_metadata = true;
   // Get the call's status and check for server pushback metadata.
   grpc_status_code status = GRPC_STATUS_OK;
   grpc_mdelem* server_pushback_md = nullptr;
   grpc_metadata_batch* md_batch =
       batch_data->batch.payload->recv_trailing_metadata.recv_trailing_metadata;
-  calld->GetCallStatus(md_batch, GRPC_ERROR_REF(error), &status,
-                       &server_pushback_md);
+  call->GetCallStatus(md_batch, GRPC_ERROR_REF(error), &status,
+                      &server_pushback_md);
   if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_call_trace)) {
-    gpr_log(GPR_INFO, "chand=%p calld=%p: call finished, status=%s", chand,
-            calld, grpc_status_code_to_string(status));
+    gpr_log(GPR_INFO, "chand=%p retrying_call=%p: call finished, status=%s",
+            call->chand_, call, grpc_status_code_to_string(status));
   }
   // Check if we should retry.
-  if (calld->MaybeRetry(elem, batch_data, status, server_pushback_md)) {
+  if (call->MaybeRetry(batch_data, status, server_pushback_md)) {
     // Unref batch_data for deferred recv_initial_metadata_ready or
     // recv_message_ready callbacks, if any.
     if (retry_state->recv_initial_metadata_ready_deferred_batch != nullptr) {
@@ -3257,21 +4225,20 @@ void CallData::RecvTrailingMetadataReady(void* arg, grpc_error* error) {
     return;
   }
   // Not retrying, so commit the call.
-  calld->RetryCommit(elem, retry_state);
-  calld->MaybeInvokeConfigSelectorCommitCallback();
+  call->RetryCommit(retry_state);
   // Run any necessary closures.
-  calld->RunClosuresForCompletedCall(batch_data, GRPC_ERROR_REF(error));
+  call->RunClosuresForCompletedCall(batch_data, GRPC_ERROR_REF(error));
 }
 
 //
 // on_complete callback handling
 //
 
-void CallData::AddClosuresForCompletedPendingBatch(
-    grpc_call_element* elem, SubchannelCallBatchData* batch_data,
-    grpc_error* error, CallCombinerClosureList* closures) {
+void RetryingCall::AddClosuresForCompletedPendingBatch(
+    SubchannelCallBatchData* batch_data, grpc_error* error,
+    CallCombinerClosureList* closures) {
   PendingBatch* pending = PendingBatchFind(
-      elem, "completed", [batch_data](grpc_transport_stream_op_batch* batch) {
+      "completed", [batch_data](grpc_transport_stream_op_batch* batch) {
         // Match the pending batch with the same set of send ops as the
         // subchannel batch we've just completed.
         return batch->on_complete != nullptr &&
@@ -3291,13 +4258,12 @@ void CallData::AddClosuresForCompletedPendingBatch(
   closures->Add(pending->batch->on_complete, error,
                 "on_complete for pending batch");
   pending->batch->on_complete = nullptr;
-  MaybeClearPendingBatch(elem, pending);
+  MaybeClearPendingBatch(pending);
 }
 
-void CallData::AddClosuresForReplayOrPendingSendOps(
-    grpc_call_element* elem, SubchannelCallBatchData* batch_data,
-    SubchannelCallRetryState* retry_state, CallCombinerClosureList* closures) {
-  ChannelData* chand = static_cast<ChannelData*>(elem->channel_data);
+void RetryingCall::AddClosuresForReplayOrPendingSendOps(
+    SubchannelCallBatchData* batch_data, SubchannelCallRetryState* retry_state,
+    CallCombinerClosureList* closures) {
   bool have_pending_send_message_ops =
       retry_state->started_send_message_count < send_messages_.size();
   bool have_pending_send_trailing_metadata_op =
@@ -3318,31 +4284,31 @@ void CallData::AddClosuresForReplayOrPendingSendOps(
   if (have_pending_send_message_ops || have_pending_send_trailing_metadata_op) {
     if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_call_trace)) {
       gpr_log(GPR_INFO,
-              "chand=%p calld=%p: starting next batch for pending send op(s)",
-              chand, this);
+              "chand=%p retrying_call=%p: starting next batch for pending send "
+              "op(s)",
+              chand_, this);
     }
     GRPC_CLOSURE_INIT(&batch_data->batch.handler_private.closure,
-                      StartRetriableSubchannelBatches, elem,
+                      StartRetriableSubchannelBatches, this,
                       grpc_schedule_on_exec_ctx);
     closures->Add(&batch_data->batch.handler_private.closure, GRPC_ERROR_NONE,
                   "starting next batch for send_* op(s)");
   }
 }
 
-void CallData::OnComplete(void* arg, grpc_error* error) {
+void RetryingCall::OnComplete(void* arg, grpc_error* error) {
   SubchannelCallBatchData* batch_data =
       static_cast<SubchannelCallBatchData*>(arg);
-  grpc_call_element* elem = batch_data->elem;
-  ChannelData* chand = static_cast<ChannelData*>(elem->channel_data);
-  CallData* calld = static_cast<CallData*>(elem->call_data);
+  RetryingCall* call = batch_data->call;
   if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_call_trace)) {
-    gpr_log(GPR_INFO, "chand=%p calld=%p: got on_complete, error=%s, batch=%s",
-            chand, calld, grpc_error_string(error),
+    gpr_log(GPR_INFO,
+            "chand=%p retrying_call=%p: got on_complete, error=%s, batch=%s",
+            call->chand_, call, grpc_error_string(error),
             grpc_transport_stream_op_batch_string(&batch_data->batch).c_str());
   }
   SubchannelCallRetryState* retry_state =
       static_cast<SubchannelCallRetryState*>(
-          batch_data->subchannel_call->GetParentData());
+          batch_data->lb_call->GetParentData());
   // Update bookkeeping in retry_state.
   if (batch_data->batch.send_initial_metadata) {
     retry_state->completed_send_initial_metadata = true;
@@ -3355,8 +4321,8 @@ void CallData::OnComplete(void* arg, grpc_error* error) {
   }
   // If the call is committed, free cached data for send ops that we've just
   // completed.
-  if (calld->retry_committed_) {
-    calld->FreeCachedSendOpDataForCompletedBatch(elem, batch_data, retry_state);
+  if (call->retry_committed_) {
+    call->FreeCachedSendOpDataForCompletedBatch(batch_data, retry_state);
   }
   // Construct list of closures to execute.
   CallCombinerClosureList closures;
@@ -3365,28 +4331,28 @@ void CallData::OnComplete(void* arg, grpc_error* error) {
   // Otherwise, invoke the callback to return the result to the surface.
   if (!retry_state->retry_dispatched) {
     // Add closure for the completed pending batch, if any.
-    calld->AddClosuresForCompletedPendingBatch(
-        elem, batch_data, GRPC_ERROR_REF(error), &closures);
+    call->AddClosuresForCompletedPendingBatch(batch_data, GRPC_ERROR_REF(error),
+                                              &closures);
     // If needed, add a callback to start any replay or pending send ops on
     // the subchannel call.
     if (!retry_state->completed_recv_trailing_metadata) {
-      calld->AddClosuresForReplayOrPendingSendOps(elem, batch_data, retry_state,
-                                                  &closures);
+      call->AddClosuresForReplayOrPendingSendOps(batch_data, retry_state,
+                                                 &closures);
     }
   }
   // Track number of pending subchannel send batches and determine if this
   // was the last one.
-  --calld->num_pending_retriable_subchannel_send_batches_;
+  --call->num_pending_retriable_subchannel_send_batches_;
   const bool last_send_batch_complete =
-      calld->num_pending_retriable_subchannel_send_batches_ == 0;
+      call->num_pending_retriable_subchannel_send_batches_ == 0;
   // Don't need batch_data anymore.
   batch_data->Unref();
   // Schedule all of the closures identified above.
   // Note: This yeilds the call combiner.
-  closures.RunClosures(calld->call_combiner_);
+  closures.RunClosures(call->call_combiner_);
   // If this was the last subchannel send batch, unref the call stack.
   if (last_send_batch_complete) {
-    GRPC_CALL_STACK_UNREF(calld->owning_call_, "subchannel_send_batches");
+    GRPC_CALL_STACK_UNREF(call->owning_call_, "subchannel_send_batches");
   }
 }
 
@@ -3394,31 +4360,31 @@ void CallData::OnComplete(void* arg, grpc_error* error) {
 // subchannel batch construction
 //
 
-void CallData::StartBatchInCallCombiner(void* arg, grpc_error* /*ignored*/) {
+void RetryingCall::StartBatchInCallCombiner(void* arg,
+                                            grpc_error* /*ignored*/) {
   grpc_transport_stream_op_batch* batch =
       static_cast<grpc_transport_stream_op_batch*>(arg);
-  SubchannelCall* subchannel_call =
-      static_cast<SubchannelCall*>(batch->handler_private.extra_arg);
+  auto* lb_call =
+      static_cast<LoadBalancedCall*>(batch->handler_private.extra_arg);
   // Note: This will release the call combiner.
-  subchannel_call->StartTransportStreamOpBatch(batch);
+  lb_call->StartTransportStreamOpBatch(batch);
 }
 
-void CallData::AddClosureForSubchannelBatch(
-    grpc_call_element* elem, grpc_transport_stream_op_batch* batch,
-    CallCombinerClosureList* closures) {
-  ChannelData* chand = static_cast<ChannelData*>(elem->channel_data);
-  batch->handler_private.extra_arg = subchannel_call_.get();
+void RetryingCall::AddClosureForSubchannelBatch(
+    grpc_transport_stream_op_batch* batch, CallCombinerClosureList* closures) {
+  batch->handler_private.extra_arg = lb_call_.get();
   GRPC_CLOSURE_INIT(&batch->handler_private.closure, StartBatchInCallCombiner,
                     batch, grpc_schedule_on_exec_ctx);
   if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_call_trace)) {
-    gpr_log(GPR_INFO, "chand=%p calld=%p: starting subchannel batch: %s", chand,
+    gpr_log(GPR_INFO,
+            "chand=%p retrying_call=%p: starting subchannel batch: %s", chand_,
             this, grpc_transport_stream_op_batch_string(batch).c_str());
   }
   closures->Add(&batch->handler_private.closure, GRPC_ERROR_NONE,
                 "start_subchannel_batch");
 }
 
-void CallData::AddRetriableSendInitialMetadataOp(
+void RetryingCall::AddRetriableSendInitialMetadataOp(
     SubchannelCallRetryState* retry_state,
     SubchannelCallBatchData* batch_data) {
   // Maps the number of retries to the corresponding metadata value slice.
@@ -3466,14 +4432,14 @@ void CallData::AddRetriableSendInitialMetadataOp(
   batch_data->batch.payload->send_initial_metadata.peer_string = peer_string_;
 }
 
-void CallData::AddRetriableSendMessageOp(grpc_call_element* elem,
-                                         SubchannelCallRetryState* retry_state,
-                                         SubchannelCallBatchData* batch_data) {
-  ChannelData* chand = static_cast<ChannelData*>(elem->channel_data);
+void RetryingCall::AddRetriableSendMessageOp(
+    SubchannelCallRetryState* retry_state,
+    SubchannelCallBatchData* batch_data) {
   if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_call_trace)) {
     gpr_log(GPR_INFO,
-            "chand=%p calld=%p: starting calld->send_messages[%" PRIuPTR "]",
-            chand, this, retry_state->started_send_message_count);
+            "chand=%p retrying_call=%p: starting calld->send_messages[%" PRIuPTR
+            "]",
+            chand_, this, retry_state->started_send_message_count);
   }
   ByteStreamCache* cache =
       send_messages_[retry_state->started_send_message_count];
@@ -3484,7 +4450,7 @@ void CallData::AddRetriableSendMessageOp(grpc_call_element* elem,
       retry_state->send_message.get());
 }
 
-void CallData::AddRetriableSendTrailingMetadataOp(
+void RetryingCall::AddRetriableSendTrailingMetadataOp(
     SubchannelCallRetryState* retry_state,
     SubchannelCallBatchData* batch_data) {
   // We need to make a copy of the metadata batch for each attempt, since
@@ -3502,7 +4468,7 @@ void CallData::AddRetriableSendTrailingMetadataOp(
       &retry_state->send_trailing_metadata;
 }
 
-void CallData::AddRetriableRecvInitialMetadataOp(
+void RetryingCall::AddRetriableRecvInitialMetadataOp(
     SubchannelCallRetryState* retry_state,
     SubchannelCallBatchData* batch_data) {
   retry_state->started_recv_initial_metadata = true;
@@ -3519,8 +4485,9 @@ void CallData::AddRetriableRecvInitialMetadataOp(
       &retry_state->recv_initial_metadata_ready;
 }
 
-void CallData::AddRetriableRecvMessageOp(SubchannelCallRetryState* retry_state,
-                                         SubchannelCallBatchData* batch_data) {
+void RetryingCall::AddRetriableRecvMessageOp(
+    SubchannelCallRetryState* retry_state,
+    SubchannelCallBatchData* batch_data) {
   ++retry_state->started_recv_message_count;
   batch_data->batch.recv_message = true;
   batch_data->batch.payload->recv_message.recv_message =
@@ -3531,7 +4498,7 @@ void CallData::AddRetriableRecvMessageOp(SubchannelCallRetryState* retry_state,
       &retry_state->recv_message_ready;
 }
 
-void CallData::AddRetriableRecvTrailingMetadataOp(
+void RetryingCall::AddRetriableRecvTrailingMetadataOp(
     SubchannelCallRetryState* retry_state,
     SubchannelCallBatchData* batch_data) {
   retry_state->started_recv_trailing_metadata = true;
@@ -3547,39 +4514,36 @@ void CallData::AddRetriableRecvTrailingMetadataOp(
   batch_data->batch.payload->recv_trailing_metadata
       .recv_trailing_metadata_ready =
       &retry_state->recv_trailing_metadata_ready;
-  MaybeInjectRecvTrailingMetadataReadyForLoadBalancingPolicy(
-      &batch_data->batch);
 }
 
-void CallData::StartInternalRecvTrailingMetadata(grpc_call_element* elem) {
-  ChannelData* chand = static_cast<ChannelData*>(elem->channel_data);
+void RetryingCall::StartInternalRecvTrailingMetadata() {
   if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_call_trace)) {
-    gpr_log(GPR_INFO,
-            "chand=%p calld=%p: call failed but recv_trailing_metadata not "
-            "started; starting it internally",
-            chand, this);
+    gpr_log(
+        GPR_INFO,
+        "chand=%p retrying_call=%p: call failed but recv_trailing_metadata not "
+        "started; starting it internally",
+        chand_, this);
   }
   SubchannelCallRetryState* retry_state =
-      static_cast<SubchannelCallRetryState*>(subchannel_call_->GetParentData());
+      static_cast<SubchannelCallRetryState*>(lb_call_->GetParentData());
   // Create batch_data with 2 refs, since this batch will be unreffed twice:
   // once for the recv_trailing_metadata_ready callback when the subchannel
   // batch returns, and again when we actually get a recv_trailing_metadata
   // op from the surface.
   SubchannelCallBatchData* batch_data =
-      SubchannelCallBatchData::Create(elem, 2, false /* set_on_complete */);
+      SubchannelCallBatchData::Create(this, 2, false /* set_on_complete */);
   AddRetriableRecvTrailingMetadataOp(retry_state, batch_data);
   retry_state->recv_trailing_metadata_internal_batch = batch_data;
   // Note: This will release the call combiner.
-  subchannel_call_->StartTransportStreamOpBatch(&batch_data->batch);
+  lb_call_->StartTransportStreamOpBatch(&batch_data->batch);
 }
 
 // If there are any cached send ops that need to be replayed on the
 // current subchannel call, creates and returns a new subchannel batch
 // to replay those ops.  Otherwise, returns nullptr.
-CallData::SubchannelCallBatchData*
-CallData::MaybeCreateSubchannelBatchForReplay(
-    grpc_call_element* elem, SubchannelCallRetryState* retry_state) {
-  ChannelData* chand = static_cast<ChannelData*>(elem->channel_data);
+RetryingCall::SubchannelCallBatchData*
+RetryingCall::MaybeCreateSubchannelBatchForReplay(
+    SubchannelCallRetryState* retry_state) {
   SubchannelCallBatchData* replay_batch_data = nullptr;
   // send_initial_metadata.
   if (seen_send_initial_metadata_ &&
@@ -3587,12 +4551,12 @@ CallData::MaybeCreateSubchannelBatchForReplay(
       !pending_send_initial_metadata_) {
     if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_call_trace)) {
       gpr_log(GPR_INFO,
-              "chand=%p calld=%p: replaying previously completed "
+              "chand=%p retrying_call=%p: replaying previously completed "
               "send_initial_metadata op",
-              chand, this);
+              chand_, this);
     }
     replay_batch_data =
-        SubchannelCallBatchData::Create(elem, 1, true /* set_on_complete */);
+        SubchannelCallBatchData::Create(this, 1, true /* set_on_complete */);
     AddRetriableSendInitialMetadataOp(retry_state, replay_batch_data);
   }
   // send_message.
@@ -3603,15 +4567,15 @@ CallData::MaybeCreateSubchannelBatchForReplay(
       !pending_send_message_) {
     if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_call_trace)) {
       gpr_log(GPR_INFO,
-              "chand=%p calld=%p: replaying previously completed "
+              "chand=%p retrying_call=%p: replaying previously completed "
               "send_message op",
-              chand, this);
+              chand_, this);
     }
     if (replay_batch_data == nullptr) {
       replay_batch_data =
-          SubchannelCallBatchData::Create(elem, 1, true /* set_on_complete */);
+          SubchannelCallBatchData::Create(this, 1, true /* set_on_complete */);
     }
-    AddRetriableSendMessageOp(elem, retry_state, replay_batch_data);
+    AddRetriableSendMessageOp(retry_state, replay_batch_data);
   }
   // send_trailing_metadata.
   // Note that we only add this op if we have no more send_message ops
@@ -3623,22 +4587,21 @@ CallData::MaybeCreateSubchannelBatchForReplay(
       !pending_send_trailing_metadata_) {
     if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_call_trace)) {
       gpr_log(GPR_INFO,
-              "chand=%p calld=%p: replaying previously completed "
+              "chand=%p retrying_call=%p: replaying previously completed "
               "send_trailing_metadata op",
-              chand, this);
+              chand_, this);
     }
     if (replay_batch_data == nullptr) {
       replay_batch_data =
-          SubchannelCallBatchData::Create(elem, 1, true /* set_on_complete */);
+          SubchannelCallBatchData::Create(this, 1, true /* set_on_complete */);
     }
     AddRetriableSendTrailingMetadataOp(retry_state, replay_batch_data);
   }
   return replay_batch_data;
 }
 
-void CallData::AddSubchannelBatchesForPendingBatches(
-    grpc_call_element* elem, SubchannelCallRetryState* retry_state,
-    CallCombinerClosureList* closures) {
+void RetryingCall::AddSubchannelBatchesForPendingBatches(
+    SubchannelCallRetryState* retry_state, CallCombinerClosureList* closures) {
   for (size_t i = 0; i < GPR_ARRAY_SIZE(pending_batches_); ++i) {
     PendingBatch* pending = &pending_batches_[i];
     grpc_transport_stream_op_batch* batch = pending->batch;
@@ -3704,11 +4667,10 @@ void CallData::AddSubchannelBatchesForPendingBatches(
       continue;
     }
     // If we're not retrying, just send the batch as-is.
-    if (method_params_ == nullptr ||
-        method_params_->retry_policy() == nullptr || retry_committed_) {
-      // TODO(roth) : We should probably call
-      // MaybeInjectRecvTrailingMetadataReadyForLoadBalancingPolicy here.
-      AddClosureForSubchannelBatch(elem, batch, closures);
+    // TODO(roth): This condition doesn't seem exactly right -- maybe need a
+    // notion of "draining" once we've committed and are done replaying?
+    if (retry_policy_ == nullptr || retry_committed_) {
+      AddClosureForSubchannelBatch(batch, closures);
       PendingBatchClear(pending);
       continue;
     }
@@ -3720,280 +4682,643 @@ void CallData::AddSubchannelBatchesForPendingBatches(
                               batch->recv_message +
                               batch->recv_trailing_metadata;
     SubchannelCallBatchData* batch_data = SubchannelCallBatchData::Create(
-        elem, num_callbacks, has_send_ops /* set_on_complete */);
+        this, num_callbacks, has_send_ops /* set_on_complete */);
     // Cache send ops if needed.
     MaybeCacheSendOpsForBatch(pending);
     // send_initial_metadata.
     if (batch->send_initial_metadata) {
       AddRetriableSendInitialMetadataOp(retry_state, batch_data);
     }
-    // send_message.
-    if (batch->send_message) {
-      AddRetriableSendMessageOp(elem, retry_state, batch_data);
+    // send_message.
+    if (batch->send_message) {
+      AddRetriableSendMessageOp(retry_state, batch_data);
+    }
+    // send_trailing_metadata.
+    if (batch->send_trailing_metadata) {
+      AddRetriableSendTrailingMetadataOp(retry_state, batch_data);
+    }
+    // recv_initial_metadata.
+    if (batch->recv_initial_metadata) {
+      // recv_flags is only used on the server side.
+      GPR_ASSERT(batch->payload->recv_initial_metadata.recv_flags == nullptr);
+      AddRetriableRecvInitialMetadataOp(retry_state, batch_data);
+    }
+    // recv_message.
+    if (batch->recv_message) {
+      AddRetriableRecvMessageOp(retry_state, batch_data);
+    }
+    // recv_trailing_metadata.
+    if (batch->recv_trailing_metadata) {
+      AddRetriableRecvTrailingMetadataOp(retry_state, batch_data);
+    }
+    AddClosureForSubchannelBatch(&batch_data->batch, closures);
+    // Track number of pending subchannel send batches.
+    // If this is the first one, take a ref to the call stack.
+    if (batch->send_initial_metadata || batch->send_message ||
+        batch->send_trailing_metadata) {
+      if (num_pending_retriable_subchannel_send_batches_ == 0) {
+        GRPC_CALL_STACK_REF(owning_call_, "subchannel_send_batches");
+      }
+      ++num_pending_retriable_subchannel_send_batches_;
+    }
+  }
+}
+
+void RetryingCall::StartRetriableSubchannelBatches(void* arg,
+                                                   grpc_error* /*ignored*/) {
+  RetryingCall* call = static_cast<RetryingCall*>(arg);
+  if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_call_trace)) {
+    gpr_log(GPR_INFO,
+            "chand=%p retrying_call=%p: constructing retriable batches",
+            call->chand_, call);
+  }
+  SubchannelCallRetryState* retry_state =
+      static_cast<SubchannelCallRetryState*>(call->lb_call_->GetParentData());
+  // Construct list of closures to execute, one for each pending batch.
+  CallCombinerClosureList closures;
+  // Replay previously-returned send_* ops if needed.
+  SubchannelCallBatchData* replay_batch_data =
+      call->MaybeCreateSubchannelBatchForReplay(retry_state);
+  if (replay_batch_data != nullptr) {
+    call->AddClosureForSubchannelBatch(&replay_batch_data->batch, &closures);
+    // Track number of pending subchannel send batches.
+    // If this is the first one, take a ref to the call stack.
+    if (call->num_pending_retriable_subchannel_send_batches_ == 0) {
+      GRPC_CALL_STACK_REF(call->owning_call_, "subchannel_send_batches");
+    }
+    ++call->num_pending_retriable_subchannel_send_batches_;
+  }
+  // Now add pending batches.
+  call->AddSubchannelBatchesForPendingBatches(retry_state, &closures);
+  // Start batches on subchannel call.
+  if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_call_trace)) {
+    gpr_log(GPR_INFO,
+            "chand=%p retrying_call=%p: starting %" PRIuPTR
+            " retriable batches on lb_call=%p",
+            call->chand_, call, closures.size(), call->lb_call_.get());
+  }
+  // Note: This will yield the call combiner.
+  closures.RunClosures(call->call_combiner_);
+}
+
+void RetryingCall::CreateLbCall(void* arg, grpc_error* /*error*/) {
+  auto* call = static_cast<RetryingCall*>(arg);
+  const size_t parent_data_size =
+      call->enable_retries_ ? sizeof(SubchannelCallRetryState) : 0;
+  grpc_call_element_args args = {call->owning_call_,     nullptr,
+                                 call->call_context_,    call->path_,
+                                 call->call_start_time_, call->deadline_,
+                                 call->arena_,           call->call_combiner_};
+  call->lb_call_ = LoadBalancedCall::Create(call->chand_, args, call->pollent_,
+                                            parent_data_size);
+  if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_routing_trace)) {
+    gpr_log(GPR_INFO, "chand=%p retrying_call=%p: create lb_call=%p",
+            call->chand_, call, call->lb_call_.get());
+  }
+  if (parent_data_size > 0) {
+    new (call->lb_call_->GetParentData())
+        SubchannelCallRetryState(call->call_context_);
+  }
+  call->PendingBatchesResume();
+}
+
+//
+// LoadBalancedCall::Metadata
+//
+
+class LoadBalancedCall::Metadata
+    : public LoadBalancingPolicy::MetadataInterface {
+ public:
+  Metadata(LoadBalancedCall* lb_call, grpc_metadata_batch* batch)
+      : lb_call_(lb_call), batch_(batch) {}
+
+  void Add(absl::string_view key, absl::string_view value) override {
+    grpc_linked_mdelem* linked_mdelem = static_cast<grpc_linked_mdelem*>(
+        lb_call_->arena_->Alloc(sizeof(grpc_linked_mdelem)));
+    linked_mdelem->md = grpc_mdelem_from_slices(
+        ExternallyManagedSlice(key.data(), key.size()),
+        ExternallyManagedSlice(value.data(), value.size()));
+    GPR_ASSERT(grpc_metadata_batch_link_tail(batch_, linked_mdelem) ==
+               GRPC_ERROR_NONE);
+  }
+
+  iterator begin() const override {
+    static_assert(sizeof(grpc_linked_mdelem*) <= sizeof(intptr_t),
+                  "iterator size too large");
+    return iterator(
+        this, reinterpret_cast<intptr_t>(MaybeSkipEntry(batch_->list.head)));
+  }
+  iterator end() const override {
+    static_assert(sizeof(grpc_linked_mdelem*) <= sizeof(intptr_t),
+                  "iterator size too large");
+    return iterator(this, 0);
+  }
+
+  iterator erase(iterator it) override {
+    grpc_linked_mdelem* linked_mdelem =
+        reinterpret_cast<grpc_linked_mdelem*>(GetIteratorHandle(it));
+    intptr_t handle = reinterpret_cast<intptr_t>(linked_mdelem->next);
+    grpc_metadata_batch_remove(batch_, linked_mdelem);
+    return iterator(this, handle);
+  }
+
+ private:
+  grpc_linked_mdelem* MaybeSkipEntry(grpc_linked_mdelem* entry) const {
+    if (entry != nullptr && batch_->idx.named.path == entry) {
+      return entry->next;
+    }
+    return entry;
+  }
+
+  intptr_t IteratorHandleNext(intptr_t handle) const override {
+    grpc_linked_mdelem* linked_mdelem =
+        reinterpret_cast<grpc_linked_mdelem*>(handle);
+    return reinterpret_cast<intptr_t>(MaybeSkipEntry(linked_mdelem->next));
+  }
+
+  std::pair<absl::string_view, absl::string_view> IteratorHandleGet(
+      intptr_t handle) const override {
+    grpc_linked_mdelem* linked_mdelem =
+        reinterpret_cast<grpc_linked_mdelem*>(handle);
+    return std::make_pair(StringViewFromSlice(GRPC_MDKEY(linked_mdelem->md)),
+                          StringViewFromSlice(GRPC_MDVALUE(linked_mdelem->md)));
+  }
+
+  LoadBalancedCall* lb_call_;
+  grpc_metadata_batch* batch_;
+};
+
+//
+// LoadBalancedCall::LbCallState
+//
+
+class LoadBalancedCall::LbCallState : public LoadBalancingPolicy::CallState {
+ public:
+  explicit LbCallState(LoadBalancedCall* lb_call) : lb_call_(lb_call) {}
+
+  void* Alloc(size_t size) override { return lb_call_->arena_->Alloc(size); }
+
+  const LoadBalancingPolicy::BackendMetricData* GetBackendMetricData()
+      override {
+    if (lb_call_->backend_metric_data_ == nullptr) {
+      grpc_linked_mdelem* md = lb_call_->recv_trailing_metadata_->idx.named
+                                   .x_endpoint_load_metrics_bin;
+      if (md != nullptr) {
+        lb_call_->backend_metric_data_ =
+            ParseBackendMetricData(GRPC_MDVALUE(md->md), lb_call_->arena_);
+      }
+    }
+    return lb_call_->backend_metric_data_;
+  }
+
+  absl::string_view ExperimentalGetCallAttribute(const char* key) override {
+    auto* service_config_call_data = static_cast<ServiceConfigCallData*>(
+        lb_call_->call_context_[GRPC_CONTEXT_SERVICE_CONFIG_CALL_DATA].value);
+    auto& call_attributes = service_config_call_data->call_attributes();
+    auto it = call_attributes.find(key);
+    if (it == call_attributes.end()) return absl::string_view();
+    return it->second;
+  }
+
+ private:
+  LoadBalancedCall* lb_call_;
+};
+
+//
+// LoadBalancedCall
+//
+
+RefCountedPtr<LoadBalancedCall> LoadBalancedCall::Create(
+    ChannelData* chand, const grpc_call_element_args& args,
+    grpc_polling_entity* pollent, size_t parent_data_size) {
+  const size_t alloc_size =
+      parent_data_size > 0
+          ? (GPR_ROUND_UP_TO_ALIGNMENT_SIZE(sizeof(LoadBalancedCall)) +
+             parent_data_size)
+          : sizeof(LoadBalancedCall);
+  auto* lb_call = static_cast<LoadBalancedCall*>(args.arena->Alloc(alloc_size));
+  new (lb_call) LoadBalancedCall(chand, args, pollent);
+  return lb_call;
+}
+
+LoadBalancedCall::LoadBalancedCall(ChannelData* chand,
+                                   const grpc_call_element_args& args,
+                                   grpc_polling_entity* pollent)
+    : refs_(1, GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_routing_trace)
+                   ? "LoadBalancedCall"
+                   : nullptr),
+      chand_(chand),
+      path_(grpc_slice_ref_internal(args.path)),
+      call_start_time_(args.start_time),
+      deadline_(args.deadline),
+      arena_(args.arena),
+      owning_call_(args.call_stack),
+      call_combiner_(args.call_combiner),
+      call_context_(args.context),
+      pollent_(pollent) {}
+
+LoadBalancedCall::~LoadBalancedCall() {
+  grpc_slice_unref_internal(path_);
+  GRPC_ERROR_UNREF(cancel_error_);
+  if (backend_metric_data_ != nullptr) {
+    backend_metric_data_
+        ->LoadBalancingPolicy::BackendMetricData::~BackendMetricData();
+  }
+  // Make sure there are no remaining pending batches.
+  for (size_t i = 0; i < GPR_ARRAY_SIZE(pending_batches_); ++i) {
+    GPR_ASSERT(pending_batches_[i] == nullptr);
+  }
+}
+
+RefCountedPtr<LoadBalancedCall> LoadBalancedCall::Ref() {
+  IncrementRefCount();
+  return RefCountedPtr<LoadBalancedCall>(this);
+}
+
+RefCountedPtr<LoadBalancedCall> LoadBalancedCall::Ref(
+    const DebugLocation& location, const char* reason) {
+  IncrementRefCount(location, reason);
+  return RefCountedPtr<LoadBalancedCall>(this);
+}
+
+void LoadBalancedCall::Unref() {
+  if (GPR_UNLIKELY(refs_.Unref())) {
+    this->~LoadBalancedCall();
+  }
+}
+
+void LoadBalancedCall::Unref(const DebugLocation& location,
+                             const char* reason) {
+  if (GPR_UNLIKELY(refs_.Unref(location, reason))) {
+    this->~LoadBalancedCall();
+  }
+}
+
+void LoadBalancedCall::IncrementRefCount() { refs_.Ref(); }
+
+void LoadBalancedCall::IncrementRefCount(const DebugLocation& location,
+                                         const char* reason) {
+  refs_.Ref(location, reason);
+}
+
+void* LoadBalancedCall::GetParentData() {
+  return reinterpret_cast<char*>(this) +
+         GPR_ROUND_UP_TO_ALIGNMENT_SIZE(sizeof(LoadBalancedCall));
+}
+
+size_t LoadBalancedCall::GetBatchIndex(grpc_transport_stream_op_batch* batch) {
+  // Note: It is important the send_initial_metadata be the first entry
+  // here, since the code in pick_subchannel_locked() assumes it will be.
+  if (batch->send_initial_metadata) return 0;
+  if (batch->send_message) return 1;
+  if (batch->send_trailing_metadata) return 2;
+  if (batch->recv_initial_metadata) return 3;
+  if (batch->recv_message) return 4;
+  if (batch->recv_trailing_metadata) return 5;
+  GPR_UNREACHABLE_CODE(return (size_t)-1);
+}
+
+// This is called via the call combiner, so access to calld is synchronized.
+void LoadBalancedCall::PendingBatchesAdd(
+    grpc_transport_stream_op_batch* batch) {
+  const size_t idx = GetBatchIndex(batch);
+  if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_call_trace)) {
+    gpr_log(GPR_INFO,
+            "chand=%p lb_call=%p: adding pending batch at index %" PRIuPTR,
+            chand_, this, idx);
+  }
+  GPR_ASSERT(pending_batches_[idx] == nullptr);
+  pending_batches_[idx] = batch;
+}
+
+// This is called via the call combiner, so access to calld is synchronized.
+void LoadBalancedCall::FailPendingBatchInCallCombiner(void* arg,
+                                                      grpc_error* error) {
+  grpc_transport_stream_op_batch* batch =
+      static_cast<grpc_transport_stream_op_batch*>(arg);
+  auto* self = static_cast<LoadBalancedCall*>(batch->handler_private.extra_arg);
+  // Note: This will release the call combiner.
+  grpc_transport_stream_op_batch_finish_with_failure(
+      batch, GRPC_ERROR_REF(error), self->call_combiner_);
+}
+
+// This is called via the call combiner, so access to calld is synchronized.
+void LoadBalancedCall::PendingBatchesFail(
+    grpc_error* error,
+    YieldCallCombinerPredicate yield_call_combiner_predicate) {
+  GPR_ASSERT(error != GRPC_ERROR_NONE);
+  if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_call_trace)) {
+    size_t num_batches = 0;
+    for (size_t i = 0; i < GPR_ARRAY_SIZE(pending_batches_); ++i) {
+      if (pending_batches_[i] != nullptr) ++num_batches;
+    }
+    gpr_log(GPR_INFO,
+            "chand=%p lb_call=%p: failing %" PRIuPTR " pending batches: %s",
+            chand_, this, num_batches, grpc_error_string(error));
+  }
+  CallCombinerClosureList closures;
+  for (size_t i = 0; i < GPR_ARRAY_SIZE(pending_batches_); ++i) {
+    grpc_transport_stream_op_batch*& batch = pending_batches_[i];
+    if (batch != nullptr) {
+      batch->handler_private.extra_arg = this;
+      GRPC_CLOSURE_INIT(&batch->handler_private.closure,
+                        FailPendingBatchInCallCombiner, batch,
+                        grpc_schedule_on_exec_ctx);
+      closures.Add(&batch->handler_private.closure, GRPC_ERROR_REF(error),
+                   "PendingBatchesFail");
+      batch = nullptr;
+    }
+  }
+  if (yield_call_combiner_predicate(closures)) {
+    closures.RunClosures(call_combiner_);
+  } else {
+    closures.RunClosuresWithoutYielding(call_combiner_);
+  }
+  GRPC_ERROR_UNREF(error);
+}
+
+// This is called via the call combiner, so access to calld is synchronized.
+void LoadBalancedCall::ResumePendingBatchInCallCombiner(
+    void* arg, grpc_error* /*ignored*/) {
+  grpc_transport_stream_op_batch* batch =
+      static_cast<grpc_transport_stream_op_batch*>(arg);
+  SubchannelCall* subchannel_call =
+      static_cast<SubchannelCall*>(batch->handler_private.extra_arg);
+  // Note: This will release the call combiner.
+  subchannel_call->StartTransportStreamOpBatch(batch);
+}
+
+// This is called via the call combiner, so access to calld is synchronized.
+void LoadBalancedCall::PendingBatchesResume() {
+  if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_call_trace)) {
+    size_t num_batches = 0;
+    for (size_t i = 0; i < GPR_ARRAY_SIZE(pending_batches_); ++i) {
+      if (pending_batches_[i] != nullptr) ++num_batches;
+    }
+    gpr_log(GPR_INFO,
+            "chand=%p lb_call=%p: starting %" PRIuPTR
+            " pending batches on subchannel_call=%p",
+            chand_, this, num_batches, subchannel_call_.get());
+  }
+  CallCombinerClosureList closures;
+  for (size_t i = 0; i < GPR_ARRAY_SIZE(pending_batches_); ++i) {
+    grpc_transport_stream_op_batch*& batch = pending_batches_[i];
+    if (batch != nullptr) {
+      batch->handler_private.extra_arg = subchannel_call_.get();
+      GRPC_CLOSURE_INIT(&batch->handler_private.closure,
+                        ResumePendingBatchInCallCombiner, batch,
+                        grpc_schedule_on_exec_ctx);
+      closures.Add(&batch->handler_private.closure, GRPC_ERROR_NONE,
+                   "PendingBatchesResume");
+      batch = nullptr;
+    }
+  }
+  // Note: This will release the call combiner.
+  closures.RunClosures(call_combiner_);
+}
+
+void LoadBalancedCall::StartTransportStreamOpBatch(
+    grpc_transport_stream_op_batch* batch) {
+  // Intercept recv_trailing_metadata_ready for LB callback.
+  if (batch->recv_trailing_metadata) {
+    InjectRecvTrailingMetadataReadyForLoadBalancingPolicy(batch);
+  }
+  // If we've previously been cancelled, immediately fail any new batches.
+  if (GPR_UNLIKELY(cancel_error_ != GRPC_ERROR_NONE)) {
+    if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_call_trace)) {
+      gpr_log(GPR_INFO, "chand=%p lb_call=%p: failing batch with error: %s",
+              chand_, this, grpc_error_string(cancel_error_));
     }
-    // send_trailing_metadata.
-    if (batch->send_trailing_metadata) {
-      AddRetriableSendTrailingMetadataOp(retry_state, batch_data);
+    // Note: This will release the call combiner.
+    grpc_transport_stream_op_batch_finish_with_failure(
+        batch, GRPC_ERROR_REF(cancel_error_), call_combiner_);
+    return;
+  }
+  // Handle cancellation.
+  if (GPR_UNLIKELY(batch->cancel_stream)) {
+    // Stash a copy of cancel_error in our call data, so that we can use
+    // it for subsequent operations.  This ensures that if the call is
+    // cancelled before any batches are passed down (e.g., if the deadline
+    // is in the past when the call starts), we can return the right
+    // error to the caller when the first batch does get passed down.
+    GRPC_ERROR_UNREF(cancel_error_);
+    cancel_error_ = GRPC_ERROR_REF(batch->payload->cancel_stream.cancel_error);
+    if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_call_trace)) {
+      gpr_log(GPR_INFO, "chand=%p lb_call=%p: recording cancel_error=%s",
+              chand_, this, grpc_error_string(cancel_error_));
     }
-    // recv_initial_metadata.
-    if (batch->recv_initial_metadata) {
-      // recv_flags is only used on the server side.
-      GPR_ASSERT(batch->payload->recv_initial_metadata.recv_flags == nullptr);
-      AddRetriableRecvInitialMetadataOp(retry_state, batch_data);
+    // If we do not have a subchannel call (i.e., a pick has not yet
+    // been started), fail all pending batches.  Otherwise, send the
+    // cancellation down to the subchannel call.
+    if (subchannel_call_ == nullptr) {
+      PendingBatchesFail(GRPC_ERROR_REF(cancel_error_), NoYieldCallCombiner);
+      // Note: This will release the call combiner.
+      grpc_transport_stream_op_batch_finish_with_failure(
+          batch, GRPC_ERROR_REF(cancel_error_), call_combiner_);
+    } else {
+      // Note: This will release the call combiner.
+      subchannel_call_->StartTransportStreamOpBatch(batch);
     }
-    // recv_message.
-    if (batch->recv_message) {
-      AddRetriableRecvMessageOp(retry_state, batch_data);
+    return;
+  }
+  // Add the batch to the pending list.
+  PendingBatchesAdd(batch);
+  // Check if we've already gotten a subchannel call.
+  // Note that once we have picked a subchannel, we do not need to acquire
+  // the channel's data plane mutex, which is more efficient (especially for
+  // streaming calls).
+  if (subchannel_call_ != nullptr) {
+    if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_call_trace)) {
+      gpr_log(GPR_INFO,
+              "chand=%p lb_call=%p: starting batch on subchannel_call=%p",
+              chand_, this, subchannel_call_.get());
     }
-    // recv_trailing_metadata.
-    if (batch->recv_trailing_metadata) {
-      AddRetriableRecvTrailingMetadataOp(retry_state, batch_data);
+    PendingBatchesResume();
+    return;
+  }
+  // We do not yet have a subchannel call.
+  // For batches containing a send_initial_metadata op, acquire the
+  // channel's data plane mutex to pick a subchannel.
+  if (GPR_LIKELY(batch->send_initial_metadata)) {
+    if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_call_trace)) {
+      gpr_log(GPR_INFO,
+              "chand=%p lb_call=%p: grabbing data plane mutex to perform pick",
+              chand_, this);
     }
-    AddClosureForSubchannelBatch(elem, &batch_data->batch, closures);
-    // Track number of pending subchannel send batches.
-    // If this is the first one, take a ref to the call stack.
-    if (batch->send_initial_metadata || batch->send_message ||
-        batch->send_trailing_metadata) {
-      if (num_pending_retriable_subchannel_send_batches_ == 0) {
-        GRPC_CALL_STACK_REF(owning_call_, "subchannel_send_batches");
-      }
-      ++num_pending_retriable_subchannel_send_batches_;
+    PickSubchannel(this, GRPC_ERROR_NONE);
+  } else {
+    // For all other batches, release the call combiner.
+    if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_call_trace)) {
+      gpr_log(GPR_INFO,
+              "chand=%p lb_call=%p: saved batch, yielding call combiner",
+              chand_, this);
     }
+    GRPC_CALL_COMBINER_STOP(call_combiner_,
+                            "batch does not include send_initial_metadata");
   }
 }
 
-void CallData::StartRetriableSubchannelBatches(void* arg,
-                                               grpc_error* /*ignored*/) {
-  grpc_call_element* elem = static_cast<grpc_call_element*>(arg);
-  ChannelData* chand = static_cast<ChannelData*>(elem->channel_data);
-  CallData* calld = static_cast<CallData*>(elem->call_data);
-  if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_call_trace)) {
-    gpr_log(GPR_INFO, "chand=%p calld=%p: constructing retriable batches",
-            chand, calld);
-  }
-  SubchannelCallRetryState* retry_state =
-      static_cast<SubchannelCallRetryState*>(
-          calld->subchannel_call_->GetParentData());
-  // Construct list of closures to execute, one for each pending batch.
-  CallCombinerClosureList closures;
-  // Replay previously-returned send_* ops if needed.
-  SubchannelCallBatchData* replay_batch_data =
-      calld->MaybeCreateSubchannelBatchForReplay(elem, retry_state);
-  if (replay_batch_data != nullptr) {
-    calld->AddClosureForSubchannelBatch(elem, &replay_batch_data->batch,
-                                        &closures);
-    // Track number of pending subchannel send batches.
-    // If this is the first one, take a ref to the call stack.
-    if (calld->num_pending_retriable_subchannel_send_batches_ == 0) {
-      GRPC_CALL_STACK_REF(calld->owning_call_, "subchannel_send_batches");
+void LoadBalancedCall::RecvTrailingMetadataReadyForLoadBalancingPolicy(
+    void* arg, grpc_error* error) {
+  auto* self = static_cast<LoadBalancedCall*>(arg);
+  if (self->lb_recv_trailing_metadata_ready_ != nullptr) {
+    // Set error if call did not succeed.
+    grpc_error* error_for_lb = GRPC_ERROR_NONE;
+    if (error != GRPC_ERROR_NONE) {
+      error_for_lb = error;
+    } else {
+      const auto& fields = self->recv_trailing_metadata_->idx.named;
+      GPR_ASSERT(fields.grpc_status != nullptr);
+      grpc_status_code status =
+          grpc_get_status_code_from_metadata(fields.grpc_status->md);
+      std::string msg;
+      if (status != GRPC_STATUS_OK) {
+        error_for_lb = grpc_error_set_int(
+            GRPC_ERROR_CREATE_FROM_STATIC_STRING("call failed"),
+            GRPC_ERROR_INT_GRPC_STATUS, status);
+        if (fields.grpc_message != nullptr) {
+          error_for_lb = grpc_error_set_str(
+              error_for_lb, GRPC_ERROR_STR_GRPC_MESSAGE,
+              grpc_slice_ref_internal(GRPC_MDVALUE(fields.grpc_message->md)));
+        }
+      }
     }
-    ++calld->num_pending_retriable_subchannel_send_batches_;
-  }
-  // Now add pending batches.
-  calld->AddSubchannelBatchesForPendingBatches(elem, retry_state, &closures);
-  // Start batches on subchannel call.
-  if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_call_trace)) {
-    gpr_log(GPR_INFO,
-            "chand=%p calld=%p: starting %" PRIuPTR
-            " retriable batches on subchannel_call=%p",
-            chand, calld, closures.size(), calld->subchannel_call_.get());
+    // Invoke callback to LB policy.
+    Metadata trailing_metadata(self, self->recv_trailing_metadata_);
+    LbCallState lb_call_state(self);
+    self->lb_recv_trailing_metadata_ready_(error_for_lb, &trailing_metadata,
+                                           &lb_call_state);
+    if (error == GRPC_ERROR_NONE) GRPC_ERROR_UNREF(error_for_lb);
   }
-  // Note: This will yield the call combiner.
-  closures.RunClosures(calld->call_combiner_);
+  // Chain to original callback.
+  Closure::Run(DEBUG_LOCATION, self->original_recv_trailing_metadata_ready_,
+               GRPC_ERROR_REF(error));
 }
 
-//
-// LB pick
-//
+// TODO(roth): Consider not intercepting this callback unless we
+// actually need to, if this causes a performance problem.
+void LoadBalancedCall::InjectRecvTrailingMetadataReadyForLoadBalancingPolicy(
+    grpc_transport_stream_op_batch* batch) {
+  recv_trailing_metadata_ =
+      batch->payload->recv_trailing_metadata.recv_trailing_metadata;
+  original_recv_trailing_metadata_ready_ =
+      batch->payload->recv_trailing_metadata.recv_trailing_metadata_ready;
+  GRPC_CLOSURE_INIT(&recv_trailing_metadata_ready_,
+                    RecvTrailingMetadataReadyForLoadBalancingPolicy, this,
+                    grpc_schedule_on_exec_ctx);
+  batch->payload->recv_trailing_metadata.recv_trailing_metadata_ready =
+      &recv_trailing_metadata_ready_;
+}
 
-void CallData::CreateSubchannelCall(grpc_call_element* elem) {
-  ChannelData* chand = static_cast<ChannelData*>(elem->channel_data);
-  const size_t parent_data_size =
-      enable_retries_ ? sizeof(SubchannelCallRetryState) : 0;
+void LoadBalancedCall::CreateSubchannelCall() {
   SubchannelCall::Args call_args = {
       std::move(connected_subchannel_), pollent_, path_, call_start_time_,
       deadline_, arena_,
       // TODO(roth): When we implement hedging support, we will probably
       // need to use a separate call context for each subchannel call.
-      call_context_, call_combiner_, parent_data_size};
+      call_context_, call_combiner_};
   grpc_error* error = GRPC_ERROR_NONE;
   subchannel_call_ = SubchannelCall::Create(std::move(call_args), &error);
   if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_routing_trace)) {
-    gpr_log(GPR_INFO, "chand=%p calld=%p: create subchannel_call=%p: error=%s",
-            chand, this, subchannel_call_.get(), grpc_error_string(error));
+    gpr_log(GPR_INFO,
+            "chand=%p lb_call=%p: create subchannel_call=%p: error=%s", chand_,
+            this, subchannel_call_.get(), grpc_error_string(error));
   }
   if (GPR_UNLIKELY(error != GRPC_ERROR_NONE)) {
-    PendingBatchesFail(elem, error, YieldCallCombiner);
+    PendingBatchesFail(error, YieldCallCombiner);
   } else {
-    if (parent_data_size > 0) {
-      new (subchannel_call_->GetParentData())
-          SubchannelCallRetryState(call_context_);
-    }
-    PendingBatchesResume(elem);
-  }
-}
-
-void CallData::AsyncPickDone(grpc_call_element* elem, grpc_error* error) {
-  GRPC_CLOSURE_INIT(&pick_closure_, PickDone, elem, grpc_schedule_on_exec_ctx);
-  ExecCtx::Run(DEBUG_LOCATION, &pick_closure_, error);
-}
-
-void CallData::PickDone(void* arg, grpc_error* error) {
-  grpc_call_element* elem = static_cast<grpc_call_element*>(arg);
-  ChannelData* chand = static_cast<ChannelData*>(elem->channel_data);
-  CallData* calld = static_cast<CallData*>(elem->call_data);
-  if (error != GRPC_ERROR_NONE) {
-    if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_routing_trace)) {
-      gpr_log(GPR_INFO,
-              "chand=%p calld=%p: failed to pick subchannel: error=%s", chand,
-              calld, grpc_error_string(error));
-    }
-    calld->PendingBatchesFail(elem, GRPC_ERROR_REF(error), YieldCallCombiner);
-    return;
+    PendingBatchesResume();
   }
-  calld->CreateSubchannelCall(elem);
 }
 
 // A class to handle the call combiner cancellation callback for a
 // queued pick.
-class CallData::QueuedPickCanceller {
+// TODO(roth): When we implement hedging support, we won't be able to
+// register a call combiner cancellation closure for each LB pick,
+// because there may be multiple LB picks happening in parallel.
+// Instead, we will probably need to maintain a list in the CallData
+// object of pending LB picks to be cancelled when the closure runs.
+class LoadBalancedCall::LbQueuedCallCanceller {
  public:
-  explicit QueuedPickCanceller(grpc_call_element* elem) : elem_(elem) {
-    auto* calld = static_cast<CallData*>(elem->call_data);
-    GRPC_CALL_STACK_REF(calld->owning_call_, "QueuedPickCanceller");
-    GRPC_CLOSURE_INIT(&closure_, &CancelLocked, this,
-                      grpc_schedule_on_exec_ctx);
-    calld->call_combiner_->SetNotifyOnCancel(&closure_);
+  explicit LbQueuedCallCanceller(RefCountedPtr<LoadBalancedCall> lb_call)
+      : lb_call_(std::move(lb_call)) {
+    GRPC_CALL_STACK_REF(lb_call_->owning_call_, "LbQueuedCallCanceller");
+    GRPC_CLOSURE_INIT(&closure_, &CancelLocked, this, nullptr);
+    lb_call_->call_combiner_->SetNotifyOnCancel(&closure_);
   }
 
  private:
   static void CancelLocked(void* arg, grpc_error* error) {
-    auto* self = static_cast<QueuedPickCanceller*>(arg);
-    auto* chand = static_cast<ChannelData*>(self->elem_->channel_data);
-    auto* calld = static_cast<CallData*>(self->elem_->call_data);
-    MutexLock lock(chand->data_plane_mu());
-    if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_routing_trace)) {
-      gpr_log(GPR_INFO,
-              "chand=%p calld=%p: cancelling queued pick: "
-              "error=%s self=%p calld->pick_canceller=%p",
-              chand, calld, grpc_error_string(error), self,
-              calld->pick_canceller_);
-    }
-    if (calld->pick_canceller_ == self && error != GRPC_ERROR_NONE) {
-      // Remove pick from list of queued picks.
-      calld->MaybeInvokeConfigSelectorCommitCallback();
-      calld->MaybeRemoveCallFromQueuedPicksLocked(self->elem_);
-      // Fail pending batches on the call.
-      calld->PendingBatchesFail(self->elem_, GRPC_ERROR_REF(error),
-                                YieldCallCombinerIfPendingBatchesFound);
-    }
-    GRPC_CALL_STACK_UNREF(calld->owning_call_, "QueuedPickCanceller");
+    auto* self = static_cast<LbQueuedCallCanceller*>(arg);
+    auto* lb_call = self->lb_call_.get();
+    auto* chand = lb_call->chand_;
+    {
+      MutexLock lock(chand->data_plane_mu());
+      if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_routing_trace)) {
+        gpr_log(GPR_INFO,
+                "chand=%p lb_call=%p: cancelling queued pick: "
+                "error=%s self=%p calld->pick_canceller=%p",
+                chand, lb_call, grpc_error_string(error), self,
+                lb_call->lb_call_canceller_);
+      }
+      if (lb_call->lb_call_canceller_ == self && error != GRPC_ERROR_NONE) {
+        // Remove pick from list of queued picks.
+        lb_call->MaybeRemoveCallFromLbQueuedCallsLocked();
+        // Fail pending batches on the call.
+        lb_call->PendingBatchesFail(GRPC_ERROR_REF(error),
+                                    YieldCallCombinerIfPendingBatchesFound);
+      }
+    }
+    GRPC_CALL_STACK_UNREF(lb_call->owning_call_, "LbQueuedCallCanceller");
     delete self;
   }
 
-  grpc_call_element* elem_;
+  RefCountedPtr<LoadBalancedCall> lb_call_;
   grpc_closure closure_;
 };
 
-void CallData::MaybeRemoveCallFromQueuedPicksLocked(grpc_call_element* elem) {
-  if (!pick_queued_) return;
-  auto* chand = static_cast<ChannelData*>(elem->channel_data);
+void LoadBalancedCall::MaybeRemoveCallFromLbQueuedCallsLocked() {
+  if (!queued_pending_lb_pick_) return;
   if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_routing_trace)) {
-    gpr_log(GPR_INFO, "chand=%p calld=%p: removing from queued picks list",
-            chand, this);
+    gpr_log(GPR_INFO, "chand=%p lb_call=%p: removing from queued picks list",
+            chand_, this);
   }
-  chand->RemoveQueuedPick(&pick_, pollent_);
-  pick_queued_ = false;
+  chand_->RemoveLbQueuedCall(&queued_call_, pollent_);
+  queued_pending_lb_pick_ = false;
   // Lame the call combiner canceller.
-  pick_canceller_ = nullptr;
+  lb_call_canceller_ = nullptr;
 }
 
-void CallData::MaybeAddCallToQueuedPicksLocked(grpc_call_element* elem) {
-  if (pick_queued_) return;
-  auto* chand = static_cast<ChannelData*>(elem->channel_data);
+void LoadBalancedCall::MaybeAddCallToLbQueuedCallsLocked() {
+  if (queued_pending_lb_pick_) return;
   if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_routing_trace)) {
-    gpr_log(GPR_INFO, "chand=%p calld=%p: adding to queued picks list", chand,
-            this);
+    gpr_log(GPR_INFO, "chand=%p lb_call=%p: adding to queued picks list",
+            chand_, this);
   }
-  pick_queued_ = true;
-  pick_.elem = elem;
-  chand->AddQueuedPick(&pick_, pollent_);
+  queued_pending_lb_pick_ = true;
+  queued_call_.lb_call = this;
+  chand_->AddLbQueuedCall(&queued_call_, pollent_);
   // Register call combiner cancellation callback.
-  pick_canceller_ = new QueuedPickCanceller(elem);
+  lb_call_canceller_ = new LbQueuedCallCanceller(Ref());
 }
 
-grpc_error* CallData::ApplyServiceConfigToCallLocked(
-    grpc_call_element* elem, grpc_metadata_batch* initial_metadata) {
-  ChannelData* chand = static_cast<ChannelData*>(elem->channel_data);
-  if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_routing_trace)) {
-    gpr_log(GPR_INFO, "chand=%p calld=%p: applying service config to call",
-            chand, this);
-  }
-  ConfigSelector* config_selector = chand->config_selector();
-  if (config_selector != nullptr) {
-    // Use the ConfigSelector to determine the config for the call.
-    ConfigSelector::CallConfig call_config =
-        config_selector->GetCallConfig({&path_, initial_metadata, arena_});
-    if (call_config.error != GRPC_ERROR_NONE) return call_config.error;
-    call_attributes_ = std::move(call_config.call_attributes);
-    on_call_committed_ = std::move(call_config.on_call_committed);
-    // Create a ServiceConfigCallData for the call.  This stores a ref to the
-    // ServiceConfig and caches the right set of parsed configs to use for
-    // the call.  The MethodConfig will store itself in the call context,
-    // so that it can be accessed by filters in the subchannel, and it
-    // will be cleaned up when the call ends.
-    auto* service_config_call_data = arena_->New<ServiceConfigCallData>(
-        std::move(call_config.service_config), call_config.method_configs,
-        call_context_);
-    // Apply our own method params to the call.
-    method_params_ = static_cast<ClientChannelMethodParsedConfig*>(
-        service_config_call_data->GetMethodParsedConfig(
-            internal::ClientChannelServiceConfigParser::ParserIndex()));
-    if (method_params_ != nullptr) {
-      // If the deadline from the service config is shorter than the one
-      // from the client API, reset the deadline timer.
-      if (chand->deadline_checking_enabled() &&
-          method_params_->timeout() != 0) {
-        const grpc_millis per_method_deadline =
-            grpc_cycle_counter_to_millis_round_up(call_start_time_) +
-            method_params_->timeout();
-        if (per_method_deadline < deadline_) {
-          deadline_ = per_method_deadline;
-          grpc_deadline_state_reset(elem, deadline_);
-        }
-      }
-      // If the service config set wait_for_ready and the application
-      // did not explicitly set it, use the value from the service config.
-      uint32_t* send_initial_metadata_flags =
-          &pending_batches_[0]
-               .batch->payload->send_initial_metadata
-               .send_initial_metadata_flags;
-      if (method_params_->wait_for_ready().has_value() &&
-          !(*send_initial_metadata_flags &
-            GRPC_INITIAL_METADATA_WAIT_FOR_READY_EXPLICITLY_SET)) {
-        if (method_params_->wait_for_ready().value()) {
-          *send_initial_metadata_flags |= GRPC_INITIAL_METADATA_WAIT_FOR_READY;
-        } else {
-          *send_initial_metadata_flags &= ~GRPC_INITIAL_METADATA_WAIT_FOR_READY;
-        }
-      }
-    }
-    // Set retry throttle data for call.
-    retry_throttle_data_ = chand->retry_throttle_data();
-  }
-  // If no retry policy, disable retries.
-  // TODO(roth): Remove this when adding support for transparent retries.
-  if (method_params_ == nullptr || method_params_->retry_policy() == nullptr) {
-    enable_retries_ = false;
-  }
-  return GRPC_ERROR_NONE;
+void LoadBalancedCall::AsyncPickDone(grpc_error* error) {
+  GRPC_CLOSURE_INIT(&pick_closure_, PickDone, this, grpc_schedule_on_exec_ctx);
+  ExecCtx::Run(DEBUG_LOCATION, &pick_closure_, error);
 }
 
-void CallData::MaybeInvokeConfigSelectorCommitCallback() {
-  if (on_call_committed_ != nullptr) {
-    on_call_committed_();
-    on_call_committed_ = nullptr;
+void LoadBalancedCall::PickDone(void* arg, grpc_error* error) {
+  auto* self = static_cast<LoadBalancedCall*>(arg);
+  if (error != GRPC_ERROR_NONE) {
+    if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_routing_trace)) {
+      gpr_log(GPR_INFO,
+              "chand=%p lb_call=%p: failed to pick subchannel: error=%s",
+              self->chand_, self, grpc_error_string(error));
+    }
+    self->PendingBatchesFail(GRPC_ERROR_REF(error), YieldCallCombiner);
+    return;
   }
+  self->CreateSubchannelCall();
 }
 
 const char* PickResultTypeName(
@@ -4009,120 +5334,51 @@ const char* PickResultTypeName(
   GPR_UNREACHABLE_CODE(return "UNKNOWN");
 }
 
-void CallData::PickSubchannel(void* arg, grpc_error* error) {
-  grpc_call_element* elem = static_cast<grpc_call_element*>(arg);
-  CallData* calld = static_cast<CallData*>(elem->call_data);
-  ChannelData* chand = static_cast<ChannelData*>(elem->channel_data);
+void LoadBalancedCall::PickSubchannel(void* arg, grpc_error* error) {
+  auto* self = static_cast<LoadBalancedCall*>(arg);
   bool pick_complete;
   {
-    MutexLock lock(chand->data_plane_mu());
-    pick_complete = calld->PickSubchannelLocked(elem, &error);
+    MutexLock lock(self->chand_->data_plane_mu());
+    pick_complete = self->PickSubchannelLocked(&error);
   }
   if (pick_complete) {
-    PickDone(elem, error);
+    PickDone(self, error);
     GRPC_ERROR_UNREF(error);
   }
 }
 
-bool CallData::PickSubchannelLocked(grpc_call_element* elem,
-                                    grpc_error** error) {
-  ChannelData* chand = static_cast<ChannelData*>(elem->channel_data);
+bool LoadBalancedCall::PickSubchannelLocked(grpc_error** error) {
   GPR_ASSERT(connected_subchannel_ == nullptr);
   GPR_ASSERT(subchannel_call_ == nullptr);
-  // The picker being null means that the channel is currently in IDLE state.
-  // The incoming call will make the channel exit IDLE.
-  if (chand->picker() == nullptr) {
-    GRPC_CHANNEL_STACK_REF(chand->owning_stack(), "PickSubchannelLocked");
-    // Bounce into the control plane work serializer to exit IDLE. Since we are
-    // holding on to the data plane mutex here, we offload it on the ExecCtx so
-    // that we don't deadlock with ourselves.
-    ExecCtx::Run(
-        DEBUG_LOCATION,
-        GRPC_CLOSURE_CREATE(
-            [](void* arg, grpc_error* /*error*/) {
-              auto* chand = static_cast<ChannelData*>(arg);
-              chand->work_serializer()->Run(
-                  [chand]() {
-                    chand->CheckConnectivityState(/*try_to_connect=*/true);
-                    GRPC_CHANNEL_STACK_UNREF(chand->owning_stack(),
-                                             "PickSubchannelLocked");
-                  },
-                  DEBUG_LOCATION);
-            },
-            chand, nullptr),
-        GRPC_ERROR_NONE);
-    // Queue the pick, so that it will be attempted once the channel
-    // becomes connected.
-    MaybeAddCallToQueuedPicksLocked(elem);
-    return false;
-  }
+  // Grab initial metadata.
+  auto& send_initial_metadata =
+      pending_batches_[0]->payload->send_initial_metadata;
   grpc_metadata_batch* initial_metadata_batch =
-      seen_send_initial_metadata_
-          ? &send_initial_metadata_
-          : pending_batches_[0]
-                .batch->payload->send_initial_metadata.send_initial_metadata;
-  // Grab initial metadata flags so that we can check later if the call has
-  // wait_for_ready enabled.
+      send_initial_metadata.send_initial_metadata;
   const uint32_t send_initial_metadata_flags =
-      seen_send_initial_metadata_ ? send_initial_metadata_flags_
-                                  : pending_batches_[0]
-                                        .batch->payload->send_initial_metadata
-                                        .send_initial_metadata_flags;
-  // Avoid picking if we haven't yet received service config data.
-  if (GPR_UNLIKELY(!chand->received_service_config_data())) {
-    // If the resolver returned transient failure before returning the
-    // first service config, fail any non-wait_for_ready calls.
-    grpc_error* resolver_error = chand->resolver_transient_failure_error();
-    if (resolver_error != GRPC_ERROR_NONE &&
-        (send_initial_metadata_flags & GRPC_INITIAL_METADATA_WAIT_FOR_READY) ==
-            0) {
-      MaybeRemoveCallFromQueuedPicksLocked(elem);
-      *error = GRPC_ERROR_REF(resolver_error);
-      return true;
-    }
-    // Either the resolver has not yet returned a result, or it has
-    // returned transient failure but the call is wait_for_ready.  In
-    // either case, queue the call.
-    MaybeAddCallToQueuedPicksLocked(elem);
-    return false;
-  }
-  // Apply service config to call if not yet applied.
-  if (GPR_LIKELY(!service_config_applied_)) {
-    service_config_applied_ = true;
-    *error = ApplyServiceConfigToCallLocked(elem, initial_metadata_batch);
-    if (*error != GRPC_ERROR_NONE) return true;
-  }
-  // If this is a retry, use the send_initial_metadata payload that
-  // we've cached; otherwise, use the pending batch.  The
-  // send_initial_metadata batch will be the first pending batch in the
-  // list, as set by GetBatchIndex() above.
-  // TODO(roth): What if the LB policy needs to add something to the
-  // call's initial metadata, and then there's a retry?  We don't want
-  // the new metadata to be added twice.  We might need to somehow
-  // allocate the subchannel batch earlier so that we can give the
-  // subchannel's copy of the metadata batch (which is copied for each
-  // attempt) to the LB policy instead the one from the parent channel.
+      send_initial_metadata.send_initial_metadata_flags;
+  // Perform LB pick.
   LoadBalancingPolicy::PickArgs pick_args;
   pick_args.path = StringViewFromSlice(path_);
-  pick_args.call_state = &lb_call_state_;
+  LbCallState lb_call_state(this);
+  pick_args.call_state = &lb_call_state;
   Metadata initial_metadata(this, initial_metadata_batch);
   pick_args.initial_metadata = &initial_metadata;
-  // Attempt pick.
-  auto result = chand->picker()->Pick(pick_args);
+  auto result = chand_->picker()->Pick(pick_args);
   if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_routing_trace)) {
-    gpr_log(GPR_INFO,
-            "chand=%p calld=%p: LB pick returned %s (subchannel=%p, error=%s)",
-            chand, this, PickResultTypeName(result.type),
-            result.subchannel.get(), grpc_error_string(result.error));
+    gpr_log(
+        GPR_INFO,
+        "chand=%p lb_call=%p: LB pick returned %s (subchannel=%p, error=%s)",
+        chand_, this, PickResultTypeName(result.type), result.subchannel.get(),
+        grpc_error_string(result.error));
   }
   switch (result.type) {
     case LoadBalancingPolicy::PickResult::PICK_FAILED: {
       // If we're shutting down, fail all RPCs.
-      grpc_error* disconnect_error = chand->disconnect_error();
+      grpc_error* disconnect_error = chand_->disconnect_error();
       if (disconnect_error != GRPC_ERROR_NONE) {
         GRPC_ERROR_UNREF(result.error);
-        MaybeRemoveCallFromQueuedPicksLocked(elem);
-        MaybeInvokeConfigSelectorCommitCallback();
+        MaybeRemoveCallFromLbQueuedCallsLocked();
         *error = GRPC_ERROR_REF(disconnect_error);
         return true;
       }
@@ -4130,23 +5386,13 @@ bool CallData::PickSubchannelLocked(grpc_call_element* elem,
       // attempt's final status.
       if ((send_initial_metadata_flags &
            GRPC_INITIAL_METADATA_WAIT_FOR_READY) == 0) {
-        // Retry if appropriate; otherwise, fail.
-        grpc_status_code status = GRPC_STATUS_OK;
-        grpc_error_get_status(result.error, deadline_, &status, nullptr,
-                              nullptr, nullptr);
-        const bool retried = enable_retries_ &&
-                             MaybeRetry(elem, nullptr /* batch_data */, status,
-                                        nullptr /* server_pushback_md */);
-        if (!retried) {
-          grpc_error* new_error =
-              GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING(
-                  "Failed to pick subchannel", &result.error, 1);
-          GRPC_ERROR_UNREF(result.error);
-          *error = new_error;
-          MaybeInvokeConfigSelectorCommitCallback();
-        }
-        MaybeRemoveCallFromQueuedPicksLocked(elem);
-        return !retried;
+        grpc_error* new_error =
+            GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING(
+                "Failed to pick subchannel", &result.error, 1);
+        GRPC_ERROR_UNREF(result.error);
+        *error = new_error;
+        MaybeRemoveCallFromLbQueuedCallsLocked();
+        return true;
       }
       // If wait_for_ready is true, then queue to retry when we get a new
       // picker.
@@ -4154,26 +5400,22 @@ bool CallData::PickSubchannelLocked(grpc_call_element* elem,
     }
     // Fallthrough
     case LoadBalancingPolicy::PickResult::PICK_QUEUE:
-      MaybeAddCallToQueuedPicksLocked(elem);
+      MaybeAddCallToLbQueuedCallsLocked();
       return false;
     default:  // PICK_COMPLETE
-      MaybeRemoveCallFromQueuedPicksLocked(elem);
+      MaybeRemoveCallFromLbQueuedCallsLocked();
       // Handle drops.
       if (GPR_UNLIKELY(result.subchannel == nullptr)) {
         result.error = grpc_error_set_int(
             GRPC_ERROR_CREATE_FROM_STATIC_STRING(
                 "Call dropped by load balancing policy"),
             GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_UNAVAILABLE);
-        MaybeInvokeConfigSelectorCommitCallback();
       } else {
         // Grab a ref to the connected subchannel while we're still
         // holding the data plane mutex.
         connected_subchannel_ =
-            chand->GetConnectedSubchannelInDataPlane(result.subchannel.get());
+            chand_->GetConnectedSubchannelInDataPlane(result.subchannel.get());
         GPR_ASSERT(connected_subchannel_ != nullptr);
-        if (!enable_retries_ || retry_committed_) {
-          MaybeInvokeConfigSelectorCommitCallback();
-        }
       }
       lb_recv_trailing_metadata_ready_ = result.recv_trailing_metadata_ready;
       *error = result.error;
@@ -4219,17 +5461,17 @@ int grpc_client_channel_num_external_connectivity_watchers(
 
 void grpc_client_channel_watch_connectivity_state(
     grpc_channel_element* elem, grpc_polling_entity pollent,
-    grpc_connectivity_state* state, grpc_closure* closure,
+    grpc_connectivity_state* state, grpc_closure* on_complete,
     grpc_closure* watcher_timer_init) {
   auto* chand = static_cast<ChannelData*>(elem->channel_data);
   if (state == nullptr) {
     // Handle cancellation.
     GPR_ASSERT(watcher_timer_init == nullptr);
-    chand->RemoveExternalConnectivityWatcher(closure, /*cancel=*/true);
+    chand->RemoveExternalConnectivityWatcher(on_complete, /*cancel=*/true);
     return;
   }
   // Handle addition.
-  return chand->AddExternalConnectivityWatcher(pollent, state, closure,
+  return chand->AddExternalConnectivityWatcher(pollent, state, on_complete,
                                                watcher_timer_init);
 }
 
@@ -4247,9 +5489,3 @@ void grpc_client_channel_stop_connectivity_watch(
   auto* chand = static_cast<ChannelData*>(elem->channel_data);
   chand->RemoveConnectivityWatcher(watcher);
 }
-
-grpc_core::RefCountedPtr<grpc_core::SubchannelCall>
-grpc_client_channel_get_subchannel_call(grpc_call_element* elem) {
-  auto* calld = static_cast<CallData*>(elem->call_data);
-  return calld->subchannel_call();
-}
index 35c2a2a..202de8a 100644 (file)
@@ -75,8 +75,4 @@ void grpc_client_channel_stop_connectivity_watch(
     grpc_channel_element* elem,
     grpc_core::AsyncConnectivityStateWatcherInterface* watcher);
 
-/* Debug helper: pull the subchannel call from a call stack element */
-grpc_core::RefCountedPtr<grpc_core::SubchannelCall>
-grpc_client_channel_get_subchannel_call(grpc_call_element* elem);
-
 #endif  // GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_CLIENT_CHANNEL_H
index 2358415..5690545 100644 (file)
@@ -54,7 +54,7 @@ void grpc_client_channel_init(void) {
   grpc_core::GlobalSubchannelPool::Init();
   grpc_channel_init_register_stage(
       GRPC_CLIENT_CHANNEL, GRPC_CHANNEL_INIT_BUILTIN_PRIORITY, append_filter,
-      (void*)&grpc_client_channel_filter);
+      const_cast<grpc_channel_filter*>(&grpc_client_channel_filter));
   grpc_http_connect_register_handshaker_factory();
   grpc_client_channel_global_init_backup_polling();
 }
index 54e6bd5..62e4ce5 100644 (file)
@@ -21,6 +21,7 @@
 
 #include <functional>
 #include <map>
+#include <vector>
 
 #include "absl/strings/string_view.h"
 
@@ -28,6 +29,7 @@
 
 #include "src/core/ext/filters/client_channel/service_config.h"
 #include "src/core/ext/filters/client_channel/service_config_parser.h"
+#include "src/core/lib/channel/channel_stack.h"
 #include "src/core/lib/gprpp/arena.h"
 #include "src/core/lib/gprpp/ref_counted.h"
 #include "src/core/lib/gprpp/ref_counted_ptr.h"
@@ -80,6 +82,8 @@ class ConfigSelector : public RefCounted<ConfigSelector> {
     return cs1->Equals(cs2);
   }
 
+  virtual std::vector<const grpc_channel_filter*> GetFilters() { return {}; }
+
   virtual CallConfig GetCallConfig(GetCallConfigArgs args) = 0;
 
   grpc_arg MakeChannelArg() const;
diff --git a/src/core/ext/filters/client_channel/dynamic_filters.cc b/src/core/ext/filters/client_channel/dynamic_filters.cc
new file mode 100644 (file)
index 0000000..afde3c7
--- /dev/null
@@ -0,0 +1,186 @@
+//
+// 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>
+
+#include "src/core/ext/filters/client_channel/dynamic_filters.h"
+
+#include "src/core/lib/channel/channel_stack.h"
+#include "src/core/lib/surface/lame_client.h"
+
+// Conversion between call and call stack.
+#define CALL_TO_CALL_STACK(call)                                     \
+  (grpc_call_stack*)((char*)(call) + GPR_ROUND_UP_TO_ALIGNMENT_SIZE( \
+                                         sizeof(DynamicFilters::Call)))
+#define CALL_STACK_TO_CALL(callstack)                     \
+  (DynamicFilters::Call*)(((char*)(call_stack)) -         \
+                          GPR_ROUND_UP_TO_ALIGNMENT_SIZE( \
+                              sizeof(DynamicFilters::Call)))
+
+namespace grpc_core {
+
+//
+// DynamicFilters::Call
+//
+
+DynamicFilters::Call::Call(Args args, grpc_error** error)
+    : channel_stack_(std::move(args.channel_stack)) {
+  grpc_call_stack* call_stack = CALL_TO_CALL_STACK(this);
+  const grpc_call_element_args call_args = {
+      call_stack,        /* call_stack */
+      nullptr,           /* server_transport_data */
+      args.context,      /* context */
+      args.path,         /* path */
+      args.start_time,   /* start_time */
+      args.deadline,     /* deadline */
+      args.arena,        /* arena */
+      args.call_combiner /* call_combiner */
+  };
+  *error = grpc_call_stack_init(channel_stack_->channel_stack_, 1, Destroy,
+                                this, &call_args);
+  if (GPR_UNLIKELY(*error != GRPC_ERROR_NONE)) {
+    const char* error_string = grpc_error_string(*error);
+    gpr_log(GPR_ERROR, "error: %s", error_string);
+    return;
+  }
+  grpc_call_stack_set_pollset_or_pollset_set(call_stack, args.pollent);
+}
+
+void DynamicFilters::Call::StartTransportStreamOpBatch(
+    grpc_transport_stream_op_batch* batch) {
+  grpc_call_stack* call_stack = CALL_TO_CALL_STACK(this);
+  grpc_call_element* top_elem = grpc_call_stack_element(call_stack, 0);
+  GRPC_CALL_LOG_OP(GPR_INFO, top_elem, batch);
+  top_elem->filter->start_transport_stream_op_batch(top_elem, batch);
+}
+
+void DynamicFilters::Call::SetAfterCallStackDestroy(grpc_closure* closure) {
+  GPR_ASSERT(after_call_stack_destroy_ == nullptr);
+  GPR_ASSERT(closure != nullptr);
+  after_call_stack_destroy_ = closure;
+}
+
+RefCountedPtr<DynamicFilters::Call> DynamicFilters::Call::Ref() {
+  IncrementRefCount();
+  return RefCountedPtr<DynamicFilters::Call>(this);
+}
+
+RefCountedPtr<DynamicFilters::Call> DynamicFilters::Call::Ref(
+    const grpc_core::DebugLocation& location, const char* reason) {
+  IncrementRefCount(location, reason);
+  return RefCountedPtr<DynamicFilters::Call>(this);
+}
+
+void DynamicFilters::Call::Unref() {
+  GRPC_CALL_STACK_UNREF(CALL_TO_CALL_STACK(this), "");
+}
+
+void DynamicFilters::Call::Unref(const DebugLocation& /*location*/,
+                                 const char* reason) {
+  GRPC_CALL_STACK_UNREF(CALL_TO_CALL_STACK(this), reason);
+}
+
+void DynamicFilters::Call::Destroy(void* arg, grpc_error* /*error*/) {
+  DynamicFilters::Call* self = static_cast<DynamicFilters::Call*>(arg);
+  // Keep some members before destroying the subchannel call.
+  grpc_closure* after_call_stack_destroy = self->after_call_stack_destroy_;
+  RefCountedPtr<DynamicFilters> channel_stack = std::move(self->channel_stack_);
+  // Destroy the subchannel call.
+  self->~Call();
+  // Destroy the call stack. This should be after destroying the call, because
+  // call->after_call_stack_destroy(), if not null, will free the call arena.
+  grpc_call_stack_destroy(CALL_TO_CALL_STACK(self), nullptr,
+                          after_call_stack_destroy);
+  // Automatically reset channel_stack. This should be after destroying the call
+  // stack, because destroying call stack needs access to the channel stack.
+}
+
+void DynamicFilters::Call::IncrementRefCount() {
+  GRPC_CALL_STACK_REF(CALL_TO_CALL_STACK(this), "");
+}
+
+void DynamicFilters::Call::IncrementRefCount(
+    const grpc_core::DebugLocation& /*location*/, const char* reason) {
+  GRPC_CALL_STACK_REF(CALL_TO_CALL_STACK(this), reason);
+}
+
+//
+// DynamicFilters
+//
+
+namespace {
+
+void DestroyChannelStack(void* arg, grpc_error* /*error*/) {
+  grpc_channel_stack* channel_stack = static_cast<grpc_channel_stack*>(arg);
+  grpc_channel_stack_destroy(channel_stack);
+  gpr_free(channel_stack);
+}
+
+std::pair<grpc_channel_stack*, grpc_error*> CreateChannelStack(
+    const grpc_channel_args* args,
+    std::vector<const grpc_channel_filter*> filters) {
+  // Allocate memory for channel stack.
+  const size_t channel_stack_size =
+      grpc_channel_stack_size(filters.data(), filters.size());
+  grpc_channel_stack* channel_stack =
+      reinterpret_cast<grpc_channel_stack*>(gpr_zalloc(channel_stack_size));
+  // Initialize stack.
+  grpc_error* error = grpc_channel_stack_init(
+      /*initial_refs=*/1, DestroyChannelStack, channel_stack, filters.data(),
+      filters.size(), args, /*optional_transport=*/nullptr, "DynamicFilters",
+      channel_stack);
+  if (error != GRPC_ERROR_NONE) {
+    gpr_log(GPR_ERROR, "error initializing client internal stack: %s",
+            grpc_error_string(error));
+    grpc_channel_stack_destroy(channel_stack);
+    gpr_free(channel_stack);
+    return {nullptr, error};
+  }
+  return {channel_stack, GRPC_ERROR_NONE};
+}
+
+}  // namespace
+
+RefCountedPtr<DynamicFilters> DynamicFilters::Create(
+    const grpc_channel_args* args,
+    std::vector<const grpc_channel_filter*> filters) {
+  // Attempt to create channel stack from requested filters.
+  auto p = CreateChannelStack(args, std::move(filters));
+  if (p.second != GRPC_ERROR_NONE) {
+    // Initial pass failed.  Create with lame filter.
+    grpc_error* error = p.second;
+    p = CreateChannelStack(args, {&grpc_lame_filter});
+    GPR_ASSERT(p.second == GRPC_ERROR_NONE);
+    grpc_channel_element* elem = grpc_channel_stack_element(p.first, 0);
+    SetLameFilterError(elem, error);
+  }
+  return MakeRefCounted<DynamicFilters>(p.first);
+}
+
+DynamicFilters::~DynamicFilters() {
+  GRPC_CHANNEL_STACK_UNREF(channel_stack_, "~DynamicFilters");
+}
+
+RefCountedPtr<DynamicFilters::Call> DynamicFilters::CreateCall(
+    DynamicFilters::Call::Args args, grpc_error** error) {
+  size_t allocation_size = GPR_ROUND_UP_TO_ALIGNMENT_SIZE(sizeof(Call)) +
+                           channel_stack_->call_stack_size;
+  Call* call = static_cast<Call*>(args.arena->Alloc(allocation_size));
+  new (call) Call(std::move(args), error);
+  return call;
+}
+
+}  // namespace grpc_core
diff --git a/src/core/ext/filters/client_channel/dynamic_filters.h b/src/core/ext/filters/client_channel/dynamic_filters.h
new file mode 100644 (file)
index 0000000..bcdc6d3
--- /dev/null
@@ -0,0 +1,99 @@
+//
+// 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_CORE_EXT_FILTERS_CLIENT_CHANNEL_DYNAMIC_FILTERS_H
+#define GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_DYNAMIC_FILTERS_H
+
+#include <grpc/support/port_platform.h>
+
+#include <vector>
+
+#include "src/core/lib/channel/channel_stack.h"
+#include "src/core/lib/gpr/time_precise.h"
+#include "src/core/lib/gprpp/arena.h"
+#include "src/core/lib/gprpp/ref_counted.h"
+#include "src/core/lib/iomgr/exec_ctx.h"
+#include "src/core/lib/iomgr/polling_entity.h"
+
+namespace grpc_core {
+
+class DynamicFilters : public RefCounted<DynamicFilters> {
+ public:
+  // Implements the interface of RefCounted<>.
+  class Call {
+   public:
+    struct Args {
+      RefCountedPtr<DynamicFilters> channel_stack;
+      grpc_polling_entity* pollent;
+      grpc_slice path;
+      gpr_cycle_counter start_time;
+      grpc_millis deadline;
+      Arena* arena;
+      grpc_call_context_element* context;
+      CallCombiner* call_combiner;
+    };
+
+    Call(Args args, grpc_error** error);
+
+    // Continues processing a transport stream op batch.
+    void StartTransportStreamOpBatch(grpc_transport_stream_op_batch* batch);
+
+    // Sets the 'then_schedule_closure' argument for call stack destruction.
+    // Must be called once per call.
+    void SetAfterCallStackDestroy(grpc_closure* closure);
+
+    // Interface of RefCounted<>.
+    RefCountedPtr<Call> Ref() GRPC_MUST_USE_RESULT;
+    RefCountedPtr<Call> Ref(const DebugLocation& location,
+                            const char* reason) GRPC_MUST_USE_RESULT;
+    // When refcount drops to 0, destroys itself and the associated call stack,
+    // but does NOT free the memory because it's in the call arena.
+    void Unref();
+    void Unref(const DebugLocation& location, const char* reason);
+
+   private:
+    // Allow RefCountedPtr<> to access IncrementRefCount().
+    template <typename T>
+    friend class RefCountedPtr;
+
+    // Interface of RefCounted<>.
+    void IncrementRefCount();
+    void IncrementRefCount(const DebugLocation& location, const char* reason);
+
+    static void Destroy(void* arg, grpc_error* error);
+
+    RefCountedPtr<DynamicFilters> channel_stack_;
+    grpc_closure* after_call_stack_destroy_ = nullptr;
+  };
+
+  static RefCountedPtr<DynamicFilters> Create(
+      const grpc_channel_args* args,
+      std::vector<const grpc_channel_filter*> filters);
+
+  explicit DynamicFilters(grpc_channel_stack* channel_stack)
+      : channel_stack_(channel_stack) {}
+
+  ~DynamicFilters() override;
+
+  RefCountedPtr<Call> CreateCall(Call::Args args, grpc_error** error);
+
+ private:
+  grpc_channel_stack* channel_stack_;
+};
+
+}  // namespace grpc_core
+
+#endif  // GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_DYNAMIC_FILTERS_H
index 4e49ed6..7885fad 100644 (file)
@@ -46,7 +46,7 @@ TraceFlag grpc_health_check_client_trace(false, "health_check_client");
 //
 
 HealthCheckClient::HealthCheckClient(
-    const char* service_name,
+    std::string service_name,
     RefCountedPtr<ConnectedSubchannel> connected_subchannel,
     grpc_pollset_set* interested_parties,
     RefCountedPtr<channelz::SubchannelNode> channelz_node,
@@ -55,7 +55,7 @@ HealthCheckClient::HealthCheckClient(
           GRPC_TRACE_FLAG_ENABLED(grpc_health_check_client_trace)
               ? "HealthCheckClient"
               : nullptr),
-      service_name_(service_name),
+      service_name_(std::move(service_name)),
       connected_subchannel_(std::move(connected_subchannel)),
       interested_parties_(interested_parties),
       channelz_node_(std::move(channelz_node)),
@@ -180,13 +180,14 @@ void HealthCheckClient::OnRetryTimer(void* arg, grpc_error* error) {
 
 namespace {
 
-void EncodeRequest(const char* service_name,
+void EncodeRequest(const std::string& service_name,
                    ManualConstructor<SliceBufferByteStream>* send_message) {
   upb::Arena arena;
   grpc_health_v1_HealthCheckRequest* request_struct =
       grpc_health_v1_HealthCheckRequest_new(arena.ptr());
   grpc_health_v1_HealthCheckRequest_set_service(
-      request_struct, upb_strview_makez(service_name));
+      request_struct,
+      upb_strview_make(service_name.data(), service_name.size()));
   size_t buf_length;
   char* buf = grpc_health_v1_HealthCheckRequest_serialize(
       request_struct, arena.ptr(), &buf_length);
@@ -252,7 +253,7 @@ HealthCheckClient::CallState::CallState(
     : health_check_client_(std::move(health_check_client)),
       pollent_(grpc_polling_entity_create_from_pollset_set(interested_parties)),
       arena_(Arena::Create(health_check_client_->connected_subchannel_
-                               ->GetInitialCallSizeEstimate(0))),
+                               ->GetInitialCallSizeEstimate())),
       payload_(context_) {}
 
 HealthCheckClient::CallState::~CallState() {
@@ -291,7 +292,6 @@ void HealthCheckClient::CallState::StartCall() {
       arena_,
       context_,
       &call_combiner_,
-      0,  // parent_data_size
   };
   grpc_error* error = GRPC_ERROR_NONE;
   call_ = SubchannelCall::Create(std::move(args), &error).release();
index 24b59c7..0fc39b0 100644 (file)
@@ -44,7 +44,7 @@ namespace grpc_core {
 
 class HealthCheckClient : public InternallyRefCounted<HealthCheckClient> {
  public:
-  HealthCheckClient(const char* service_name,
+  HealthCheckClient(std::string service_name,
                     RefCountedPtr<ConnectedSubchannel> connected_subchannel,
                     grpc_pollset_set* interested_parties,
                     RefCountedPtr<channelz::SubchannelNode> channelz_node,
@@ -150,7 +150,7 @@ class HealthCheckClient : public InternallyRefCounted<HealthCheckClient> {
   void SetHealthStatusLocked(grpc_connectivity_state state,
                              const char* reason);  // Requires holding mu_.
 
-  const char* service_name_;  // Do not own.
+  std::string service_name_;
   RefCountedPtr<ConnectedSubchannel> connected_subchannel_;
   grpc_pollset_set* interested_parties_;  // Do not own.
   RefCountedPtr<channelz::SubchannelNode> channelz_node_;
index 1b9817c..f469a5a 100644 (file)
@@ -332,7 +332,7 @@ void HttpConnectHandshaker::DoHandshake(grpc_tcp_server_acceptor* /*acceptor*/,
   grpc_httpcli_request request;
   request.host = server_name;
   request.ssl_host_override = nullptr;
-  request.http.method = (char*)"CONNECT";
+  request.http.method = const_cast<char*>("CONNECT");
   request.http.path = server_name;
   request.http.version = GRPC_HTTP_HTTP10;  // Set by OnReadDone
   request.http.hdrs = headers;
@@ -382,8 +382,7 @@ class HttpConnectHandshakerFactory : public HandshakerFactory {
 }  // namespace grpc_core
 
 void grpc_http_connect_register_handshaker_factory() {
-  using namespace grpc_core;
-  HandshakerRegistry::RegisterHandshakerFactory(
-      true /* at_start */, HANDSHAKER_CLIENT,
-      absl::make_unique<HttpConnectHandshakerFactory>());
+  grpc_core::HandshakerRegistry::RegisterHandshakerFactory(
+      true /* at_start */, grpc_core::HANDSHAKER_CLIENT,
+      absl::make_unique<grpc_core::HttpConnectHandshakerFactory>());
 }
index 9bd3fe3..f061c42 100644 (file)
@@ -24,6 +24,7 @@
 #include <string.h>
 
 #include "absl/strings/str_cat.h"
+#include "absl/strings/strip.h"
 
 #include <grpc/support/alloc.h>
 #include <grpc/support/log.h>
@@ -47,9 +48,10 @@ namespace {
  * credentials if present in the 'http_proxy' env var, otherwise leaves it
  * unchanged. It is caller's responsibility to gpr_free user_cred.
  */
+// TODO(hork): change this to return std::string
 char* GetHttpProxyServer(const grpc_channel_args* args, char** user_cred) {
   GPR_ASSERT(user_cred != nullptr);
-  grpc_uri* uri = nullptr;
+  absl::StatusOr<URI> uri;
   char* proxy_name = nullptr;
   char** authority_strs = nullptr;
   size_t authority_nstrs;
@@ -69,17 +71,20 @@ char* GetHttpProxyServer(const grpc_channel_args* args, char** user_cred) {
   if (uri_str == nullptr) return nullptr;
   // an emtpy value means "don't use proxy"
   if (uri_str[0] == '\0') goto done;
-  uri = grpc_uri_parse(uri_str, false /* suppress_errors */);
-  if (uri == nullptr || uri->authority == nullptr) {
-    gpr_log(GPR_ERROR, "cannot parse value of 'http_proxy' env var");
+  uri = URI::Parse(uri_str);
+  if (!uri.ok() || uri->authority().empty()) {
+    gpr_log(GPR_ERROR, "cannot parse value of 'http_proxy' env var. Error: %s",
+            uri.status().ToString().c_str());
     goto done;
   }
-  if (strcmp(uri->scheme, "http") != 0) {
-    gpr_log(GPR_ERROR, "'%s' scheme not supported in proxy URI", uri->scheme);
+  if (uri->scheme() != "http") {
+    gpr_log(GPR_ERROR, "'%s' scheme not supported in proxy URI",
+            uri->scheme().c_str());
     goto done;
   }
   /* Split on '@' to separate user credentials from host */
-  gpr_string_split(uri->authority, "@", &authority_strs, &authority_nstrs);
+  gpr_string_split(uri->authority().c_str(), "@", &authority_strs,
+                   &authority_nstrs);
   GPR_ASSERT(authority_nstrs != 0); /* should have at least 1 string */
   if (authority_nstrs == 1) {
     /* User cred not present in authority */
@@ -99,7 +104,6 @@ char* GetHttpProxyServer(const grpc_channel_args* args, char** user_cred) {
   gpr_free(authority_strs);
 done:
   gpr_free(uri_str);
-  grpc_uri_destroy(uri);
   return proxy_name;
 }
 
@@ -114,15 +118,15 @@ class HttpProxyMapper : public ProxyMapperInterface {
     *name_to_resolve = GetHttpProxyServer(args, &user_cred);
     if (*name_to_resolve == nullptr) return false;
     char* no_proxy_str = nullptr;
-    grpc_uri* uri = grpc_uri_parse(server_uri, false /* suppress_errors */);
-    if (uri == nullptr || uri->path[0] == '\0') {
+    absl::StatusOr<URI> uri = URI::Parse(server_uri);
+    if (!uri.ok() || uri->path().empty()) {
       gpr_log(GPR_ERROR,
               "'http_proxy' environment variable set, but cannot "
-              "parse server URI '%s' -- not using proxy",
-              server_uri);
+              "parse server URI '%s' -- not using proxy. Error: %s",
+              server_uri, uri.status().ToString().c_str());
       goto no_use_proxy;
     }
-    if (strcmp(uri->scheme, "unix") == 0) {
+    if (uri->scheme() == "unix") {
       gpr_log(GPR_INFO, "not using proxy for Unix domain socket '%s'",
               server_uri);
       goto no_use_proxy;
@@ -135,9 +139,8 @@ class HttpProxyMapper : public ProxyMapperInterface {
       bool use_proxy = true;
       std::string server_host;
       std::string server_port;
-      if (!grpc_core::SplitHostPort(
-              uri->path[0] == '/' ? uri->path + 1 : uri->path, &server_host,
-              &server_port)) {
+      if (!SplitHostPort(absl::StripPrefix(uri->path(), "/"), &server_host,
+                         &server_port)) {
         gpr_log(GPR_INFO,
                 "unable to split host and port, not checking no_proxy list for "
                 "host '%s'",
@@ -172,8 +175,8 @@ class HttpProxyMapper : public ProxyMapperInterface {
     }
     grpc_arg args_to_add[2];
     args_to_add[0] = grpc_channel_arg_string_create(
-        (char*)GRPC_ARG_HTTP_CONNECT_SERVER,
-        uri->path[0] == '/' ? uri->path + 1 : uri->path);
+        const_cast<char*>(GRPC_ARG_HTTP_CONNECT_SERVER),
+        const_cast<char*>(absl::StripPrefix(uri->path(), "/").data()));
     if (user_cred != nullptr) {
       /* Use base64 encoding for user credentials as stated in RFC 7617 */
       char* encoded_user_cred =
@@ -188,11 +191,9 @@ class HttpProxyMapper : public ProxyMapperInterface {
     } else {
       *new_args = grpc_channel_args_copy_and_add(args, args_to_add, 1);
     }
-    grpc_uri_destroy(uri);
     gpr_free(user_cred);
     return true;
   no_use_proxy:
-    if (uri != nullptr) grpc_uri_destroy(uri);
     gpr_free(*name_to_resolve);
     *name_to_resolve = nullptr;
     gpr_free(user_cred);
index 53c61ee..4ef8cbb 100644 (file)
@@ -105,7 +105,7 @@ LoadBalancingPolicy::PickResult LoadBalancingPolicy::QueuePicker::Pick(
   // 2. We are currently running in the data plane mutex, but we
   //    need to bounce into the control plane work_serializer to call
   //    ExitIdleLocked().
-  if (!exit_idle_called_) {
+  if (!exit_idle_called_ && parent_ != nullptr) {
     exit_idle_called_ = true;
     auto* parent = parent_->Ref().release();  // ref held by lambda.
     ExecCtx::Run(DEBUG_LOCATION,
index 13c315e..c9fc142 100644 (file)
@@ -30,7 +30,6 @@
 #include "src/core/ext/filters/client_channel/server_address.h"
 #include "src/core/ext/filters/client_channel/service_config.h"
 #include "src/core/ext/filters/client_channel/subchannel_interface.h"
-#include "src/core/lib/gprpp/map.h"
 #include "src/core/lib/gprpp/orphanable.h"
 #include "src/core/lib/gprpp/ref_counted_ptr.h"
 #include "src/core/lib/iomgr/polling_entity.h"
@@ -95,11 +94,11 @@ class LoadBalancingPolicy : public InternallyRefCounted<LoadBalancingPolicy> {
     /// Application-specific requests cost metrics.  Metric names are
     /// determined by the application.  Each value is an absolute cost
     /// (e.g. 3487 bytes of storage) associated with the request.
-    std::map<absl::string_view, double, StringLess> request_cost;
+    std::map<absl::string_view, double> request_cost;
     /// Application-specific resource utilization metrics.  Metric names
     /// are determined by the application.  Each value is expressed as a
     /// fraction of total resources available.
-    std::map<absl::string_view, double, StringLess> utilization;
+    std::map<absl::string_view, double> utilization;
   };
 
   /// Interface for accessing per-call state.
index 3ef8620..6a46a0b 100644 (file)
@@ -68,6 +68,7 @@
 #include "absl/strings/str_cat.h"
 #include "absl/strings/str_format.h"
 #include "absl/strings/str_join.h"
+#include "absl/strings/strip.h"
 
 #include "upb/upb.hpp"
 
@@ -426,7 +427,7 @@ class GrpcLb : public LoadBalancingPolicy {
   void CreateOrUpdateChildPolicyLocked();
 
   // Who the client is trying to communicate with.
-  const char* server_name_ = nullptr;
+  std::string server_name_;
   // Configurations for the policy.
   RefCountedPtr<GrpcLbConfig> config_;
 
@@ -491,7 +492,7 @@ bool GrpcLb::Serverlist::operator==(const Serverlist& other) const {
 void ParseServer(const GrpcLbServer& server, grpc_resolved_address* addr) {
   memset(addr, 0, sizeof(*addr));
   if (server.drop) return;
-  const uint16_t netorder_port = grpc_htons((uint16_t)server.port);
+  const uint16_t netorder_port = grpc_htons(static_cast<uint16_t>(server.port));
   /* the addresses are given in binary format (a in(6)_addr struct) in
    * server->ip_address.bytes. */
   if (server.ip_size == 4) {
@@ -502,7 +503,8 @@ void ParseServer(const GrpcLbServer& server, grpc_resolved_address* addr) {
     addr4->sin_port = netorder_port;
   } else if (server.ip_size == 16) {
     addr->len = static_cast<socklen_t>(sizeof(grpc_sockaddr_in6));
-    grpc_sockaddr_in6* addr6 = (grpc_sockaddr_in6*)&addr->addr;
+    grpc_sockaddr_in6* addr6 =
+        reinterpret_cast<grpc_sockaddr_in6*>(&addr->addr);
     addr6->sin6_family = GRPC_AF_INET6;
     memcpy(&addr6->sin6_addr, server.ip_addr, server.ip_size);
     addr6->sin6_port = netorder_port;
@@ -532,17 +534,18 @@ bool IsServerValid(const GrpcLbServer& server, size_t idx, bool log) {
   if (GPR_UNLIKELY(server.port >> 16 != 0)) {
     if (log) {
       gpr_log(GPR_ERROR,
-              "Invalid port '%d' at index %lu of serverlist. Ignoring.",
-              server.port, (unsigned long)idx);
+              "Invalid port '%d' at index %" PRIuPTR
+              " of serverlist. Ignoring.",
+              server.port, idx);
     }
     return false;
   }
   if (GPR_UNLIKELY(server.ip_size != 4 && server.ip_size != 16)) {
     if (log) {
       gpr_log(GPR_ERROR,
-              "Expected IP to be 4 or 16 bytes, got %d at index %lu of "
-              "serverlist. Ignoring",
-              server.ip_size, (unsigned long)idx);
+              "Expected IP to be 4 or 16 bytes, got %d at index %" PRIuPTR
+              " of serverlist. Ignoring",
+              server.ip_size, idx);
     }
     return false;
   }
@@ -754,8 +757,7 @@ GrpcLb::BalancerCallState::BalancerCallState(
   // Init the LB call. Note that the LB call will progress every time there's
   // activity in grpclb_policy_->interested_parties(), which is comprised of
   // the polling entities from client_channel.
-  GPR_ASSERT(grpclb_policy()->server_name_ != nullptr);
-  GPR_ASSERT(grpclb_policy()->server_name_[0] != '\0');
+  GPR_ASSERT(!grpclb_policy()->server_name_.empty());
   // Closure Initialization
   GRPC_CLOSURE_INIT(&lb_on_initial_request_sent_, OnInitialRequestSent, this,
                     grpc_schedule_on_exec_ctx);
@@ -778,7 +780,7 @@ GrpcLb::BalancerCallState::BalancerCallState(
   upb::Arena arena;
   grpc_slice request_payload_slice = GrpcLbRequestCreate(
       grpclb_policy()->config_->service_name().empty()
-          ? grpclb_policy()->server_name_
+          ? grpclb_policy()->server_name_.c_str()
           : grpclb_policy()->config_->service_name().c_str(),
       arena.ptr());
   send_message_payload_ =
@@ -844,8 +846,9 @@ void GrpcLb::BalancerCallState::StartQuery() {
   // with the callback.
   auto self = Ref(DEBUG_LOCATION, "on_initial_request_sent");
   self.release();
-  call_error = grpc_call_start_batch_and_execute(
-      lb_call_, ops, (size_t)(op - ops), &lb_on_initial_request_sent_);
+  call_error = grpc_call_start_batch_and_execute(lb_call_, ops,
+                                                 static_cast<size_t>(op - ops),
+                                                 &lb_on_initial_request_sent_);
   GPR_ASSERT(GRPC_CALL_OK == call_error);
   // Op: recv initial metadata.
   op = ops;
@@ -867,7 +870,8 @@ void GrpcLb::BalancerCallState::StartQuery() {
   self = Ref(DEBUG_LOCATION, "on_message_received");
   self.release();
   call_error = grpc_call_start_batch_and_execute(
-      lb_call_, ops, (size_t)(op - ops), &lb_on_balancer_message_received_);
+      lb_call_, ops, static_cast<size_t>(op - ops),
+      &lb_on_balancer_message_received_);
   GPR_ASSERT(GRPC_CALL_OK == call_error);
   // Op: recv server status.
   op = ops;
@@ -883,7 +887,8 @@ void GrpcLb::BalancerCallState::StartQuery() {
   // ref instead of a new ref. When it's invoked, it's the initial ref that is
   // unreffed.
   call_error = grpc_call_start_batch_and_execute(
-      lb_call_, ops, (size_t)(op - ops), &lb_on_balancer_status_received_);
+      lb_call_, ops, static_cast<size_t>(op - ops),
+      &lb_on_balancer_status_received_);
   GPR_ASSERT(GRPC_CALL_OK == call_error);
 }
 
@@ -1335,15 +1340,14 @@ GrpcLb::GrpcLb(Args args)
   const grpc_arg* arg = grpc_channel_args_find(args.args, GRPC_ARG_SERVER_URI);
   const char* server_uri = grpc_channel_arg_get_string(arg);
   GPR_ASSERT(server_uri != nullptr);
-  grpc_uri* uri = grpc_uri_parse(server_uri, true);
-  GPR_ASSERT(uri->path[0] != '\0');
-  server_name_ = gpr_strdup(uri->path[0] == '/' ? uri->path + 1 : uri->path);
+  absl::StatusOr<URI> uri = URI::Parse(server_uri);
+  GPR_ASSERT(uri.ok() && !uri->path().empty());
+  server_name_ = std::string(absl::StripPrefix(uri->path(), "/"));
   if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_glb_trace)) {
     gpr_log(GPR_INFO,
             "[grpclb %p] Will use '%s' as the server name for LB request.",
-            this, server_name_);
+            this, server_name_.c_str());
   }
-  grpc_uri_destroy(uri);
   // Record LB call timeout.
   arg = grpc_channel_args_find(args.args, GRPC_ARG_GRPCLB_CALL_TIMEOUT_MS);
   lb_call_timeout_ms_ = grpc_channel_arg_get_integer(arg, {0, 0, INT_MAX});
@@ -1353,10 +1357,7 @@ GrpcLb::GrpcLb(Args args)
       arg, {GRPC_GRPCLB_DEFAULT_FALLBACK_TIMEOUT_MS, 0, INT_MAX});
 }
 
-GrpcLb::~GrpcLb() {
-  gpr_free((void*)server_name_);
-  grpc_channel_args_destroy(args_);
-}
+GrpcLb::~GrpcLb() { grpc_channel_args_destroy(args_); }
 
 void GrpcLb::ShutdownLocked() {
   shutting_down_ = true;
@@ -1457,7 +1458,7 @@ void GrpcLb::ProcessAddressesAndChannelArgsLocked(
   // since we use this to trigger the client_load_reporting filter.
   static const char* args_to_remove[] = {GRPC_ARG_LB_POLICY_NAME};
   grpc_arg new_arg = grpc_channel_arg_string_create(
-      (char*)GRPC_ARG_LB_POLICY_NAME, (char*)"grpclb");
+      const_cast<char*>(GRPC_ARG_LB_POLICY_NAME), const_cast<char*>("grpclb"));
   grpc_channel_args_destroy(args_);
   args_ = grpc_channel_args_copy_and_add_and_remove(
       &args, args_to_remove, GPR_ARRAY_SIZE(args_to_remove), &new_arg, 1);
@@ -1766,7 +1767,8 @@ bool maybe_add_client_load_reporting_filter(grpc_channel_stack_builder* builder,
     // will minimize the number of metadata elements that the filter
     // needs to iterate through to find the ClientStats object.
     return grpc_channel_stack_builder_prepend_filter(
-        builder, (const grpc_channel_filter*)arg, nullptr, nullptr);
+        builder, static_cast<const grpc_channel_filter*>(arg), nullptr,
+        nullptr);
   }
   return true;
 }
@@ -1777,10 +1779,10 @@ void grpc_lb_policy_grpclb_init() {
   grpc_core::LoadBalancingPolicyRegistry::Builder::
       RegisterLoadBalancingPolicyFactory(
           absl::make_unique<grpc_core::GrpcLbFactory>());
-  grpc_channel_init_register_stage(GRPC_CLIENT_SUBCHANNEL,
-                                   GRPC_CHANNEL_INIT_BUILTIN_PRIORITY,
-                                   maybe_add_client_load_reporting_filter,
-                                   (void*)&grpc_client_load_reporting_filter);
+  grpc_channel_init_register_stage(
+      GRPC_CLIENT_SUBCHANNEL, GRPC_CHANNEL_INIT_BUILTIN_PRIORITY,
+      maybe_add_client_load_reporting_filter,
+      const_cast<grpc_channel_filter*>(&grpc_client_load_reporting_filter));
 }
 
 void grpc_lb_policy_grpclb_shutdown() {}
index 3185b99..2ba01c1 100644 (file)
@@ -155,13 +155,13 @@ grpc_millis grpc_grpclb_duration_to_millis(
 
 }  // namespace
 
-bool GrpcLbResponseParse(const grpc_slice& encoded_grpc_grpclb_response,
+bool GrpcLbResponseParse(const grpc_slice& serialized_response,
                          upb_arena* arena, GrpcLbResponse* result) {
   grpc_lb_v1_LoadBalanceResponse* response =
       grpc_lb_v1_LoadBalanceResponse_parse(
           reinterpret_cast<const char*>(
-              GRPC_SLICE_START_PTR(encoded_grpc_grpclb_response)),
-          GRPC_SLICE_LENGTH(encoded_grpc_grpclb_response), arena);
+              GRPC_SLICE_START_PTR(serialized_response)),
+          GRPC_SLICE_LENGTH(serialized_response), arena);
   // Handle serverlist responses.
   if (ParseServerList(*response, &result->serverlist)) {
     result->type = result->SERVERLIST;
index 6caa120..1a55251 100644 (file)
@@ -66,7 +66,7 @@ grpc_slice GrpcLbLoadReportRequestCreate(
 
 // Deserialize a grpclb response.
 bool GrpcLbResponseParse(const grpc_slice& serialized_response,
-                         upb_arena* arena, GrpcLbResponse* response);
+                         upb_arena* arena, GrpcLbResponse* result);
 
 }  // namespace grpc_core
 
index bb336d7..8a10db5 100644 (file)
@@ -24,6 +24,7 @@
 #include "src/core/ext/filters/client_channel/lb_policy_factory.h"
 #include "src/core/ext/filters/client_channel/lb_policy_registry.h"
 #include "src/core/ext/filters/client_channel/service_config.h"
+#include "src/core/ext/xds/xds_certificate_provider.h"
 #include "src/core/ext/xds/xds_client.h"
 #include "src/core/lib/channel/channel_args.h"
 #include "src/core/lib/gprpp/memory.h"
@@ -31,6 +32,7 @@
 #include "src/core/lib/gprpp/ref_counted_ptr.h"
 #include "src/core/lib/iomgr/closure.h"
 #include "src/core/lib/iomgr/exec_ctx.h"
+#include "src/core/lib/security/credentials/xds/xds_credentials.h"
 #include "src/core/lib/transport/error_utils.h"
 
 namespace grpc_core {
@@ -121,6 +123,9 @@ class CdsLb : public LoadBalancingPolicy {
   void OnError(grpc_error* error);
   void OnResourceDoesNotExist();
 
+  grpc_error* UpdateXdsCertificateProvider(
+      const XdsApi::CdsUpdate& cluster_data);
+
   void MaybeDestroyChildPolicyLocked();
 
   RefCountedPtr<CdsLbConfig> config_;
@@ -134,6 +139,10 @@ class CdsLb : public LoadBalancingPolicy {
   // Note that this is not owned, so this pointer must never be derefernced.
   ClusterWatcher* cluster_watcher_ = nullptr;
 
+  RefCountedPtr<grpc_tls_certificate_provider> root_certificate_provider_;
+  RefCountedPtr<grpc_tls_certificate_provider> identity_certificate_provider_;
+  RefCountedPtr<XdsCertificateProvider> xds_certificate_provider_;
+
   // Child LB policy.
   OrphanablePtr<LoadBalancingPolicy> child_policy_;
 
@@ -312,20 +321,32 @@ void CdsLb::UpdateLocked(UpdateArgs args) {
 
 void CdsLb::OnClusterChanged(XdsApi::CdsUpdate cluster_data) {
   if (GRPC_TRACE_FLAG_ENABLED(grpc_cds_lb_trace)) {
-    gpr_log(GPR_INFO,
-            "[cdslb %p] received CDS update from xds client %p: "
-            "eds_service_name=%s lrs_load_reporting_server_name=%s "
-            "max_concurrent_requests=%d",
-            this, xds_client_.get(), cluster_data.eds_service_name.c_str(),
-            cluster_data.lrs_load_reporting_server_name.has_value()
-                ? cluster_data.lrs_load_reporting_server_name.value().c_str()
-                : "(unset)",
-            cluster_data.max_concurrent_requests);
+    gpr_log(GPR_INFO, "[cdslb %p] received CDS update from xds client %p: %s",
+            this, xds_client_.get(), cluster_data.ToString().c_str());
+  }
+  grpc_error* error = GRPC_ERROR_NONE;
+  error = UpdateXdsCertificateProvider(cluster_data);
+  if (error != GRPC_ERROR_NONE) {
+    return OnError(error);
   }
   // Construct config for child policy.
-  Json::Object child_config = {
+  Json::Object discovery_mechanism = {
       {"clusterName", config_->cluster()},
       {"max_concurrent_requests", cluster_data.max_concurrent_requests},
+      {"type", "EDS"},
+  };
+  if (!cluster_data.eds_service_name.empty()) {
+    discovery_mechanism["edsServiceName"] = cluster_data.eds_service_name;
+  }
+  if (cluster_data.lrs_load_reporting_server_name.has_value()) {
+    discovery_mechanism["lrsLoadReportingServerName"] =
+        cluster_data.lrs_load_reporting_server_name.value();
+  }
+  Json::Object child_config = {
+      {"discoveryMechanisms",
+       Json::Array{
+           discovery_mechanism,
+       }},
       {"localityPickingPolicy",
        Json::Array{
            Json::Object{
@@ -342,16 +363,9 @@ void CdsLb::OnClusterChanged(XdsApi::CdsUpdate cluster_data) {
            },
        }},
   };
-  if (!cluster_data.eds_service_name.empty()) {
-    child_config["edsServiceName"] = cluster_data.eds_service_name;
-  }
-  if (cluster_data.lrs_load_reporting_server_name.has_value()) {
-    child_config["lrsLoadReportingServerName"] =
-        cluster_data.lrs_load_reporting_server_name.value();
-  }
   Json json = Json::Array{
       Json::Object{
-          {"eds_experimental", std::move(child_config)},
+          {"xds_cluster_resolver_experimental", std::move(child_config)},
       },
   };
   if (GRPC_TRACE_FLAG_ENABLED(grpc_cds_lb_trace)) {
@@ -359,7 +373,6 @@ void CdsLb::OnClusterChanged(XdsApi::CdsUpdate cluster_data) {
     gpr_log(GPR_INFO, "[cdslb %p] generated config for child policy: %s", this,
             json_str.c_str());
   }
-  grpc_error* error = GRPC_ERROR_NONE;
   RefCountedPtr<LoadBalancingPolicy::Config> config =
       LoadBalancingPolicyRegistry::ParseLoadBalancingConfig(json, &error);
   if (error != GRPC_ERROR_NONE) {
@@ -389,7 +402,12 @@ void CdsLb::OnClusterChanged(XdsApi::CdsUpdate cluster_data) {
   // Update child policy.
   UpdateArgs args;
   args.config = std::move(config);
-  args.args = grpc_channel_args_copy(args_);
+  if (xds_certificate_provider_ != nullptr) {
+    grpc_arg arg_to_add = xds_certificate_provider_->MakeChannelArg();
+    args.args = grpc_channel_args_copy_and_add(args_, &arg_to_add, 1);
+  } else {
+    args.args = grpc_channel_args_copy(args_);
+  }
   child_policy_->UpdateLocked(std::move(args));
 }
 
@@ -425,6 +443,130 @@ void CdsLb::OnResourceDoesNotExist() {
   MaybeDestroyChildPolicyLocked();
 }
 
+grpc_error* CdsLb::UpdateXdsCertificateProvider(
+    const XdsApi::CdsUpdate& cluster_data) {
+  // Early out if channel is not configured to use xds security.
+  grpc_channel_credentials* channel_credentials =
+      grpc_channel_credentials_find_in_args(args_);
+  if (channel_credentials == nullptr ||
+      channel_credentials->type() != kCredentialsTypeXds) {
+    xds_certificate_provider_ = nullptr;
+    return GRPC_ERROR_NONE;
+  }
+  absl::string_view root_provider_instance_name =
+      cluster_data.common_tls_context.combined_validation_context
+          .validation_context_certificate_provider_instance.instance_name;
+  absl::string_view root_provider_cert_name =
+      cluster_data.common_tls_context.combined_validation_context
+          .validation_context_certificate_provider_instance.certificate_name;
+  absl::string_view identity_provider_instance_name =
+      cluster_data.common_tls_context
+          .tls_certificate_certificate_provider_instance.instance_name;
+  absl::string_view identity_provider_cert_name =
+      cluster_data.common_tls_context
+          .tls_certificate_certificate_provider_instance.certificate_name;
+  RefCountedPtr<XdsCertificateProvider> new_root_provider;
+  if (!root_provider_instance_name.empty()) {
+    new_root_provider =
+        xds_client_->certificate_provider_store()
+            .CreateOrGetCertificateProvider(root_provider_instance_name);
+    if (new_root_provider == nullptr) {
+      return GRPC_ERROR_CREATE_FROM_COPIED_STRING(
+          absl::StrCat("Certificate provider instance name: \"",
+                       root_provider_instance_name, "\" not recognized.")
+              .c_str());
+    }
+  }
+  if (root_certificate_provider_ != new_root_provider) {
+    if (root_certificate_provider_ != nullptr &&
+        root_certificate_provider_->interested_parties() != nullptr) {
+      grpc_pollset_set_del_pollset_set(
+          interested_parties(),
+          root_certificate_provider_->interested_parties());
+    }
+    if (new_root_provider != nullptr &&
+        new_root_provider->interested_parties() != nullptr) {
+      grpc_pollset_set_add_pollset_set(interested_parties(),
+                                       new_root_provider->interested_parties());
+    }
+    root_certificate_provider_ = std::move(new_root_provider);
+  }
+  RefCountedPtr<XdsCertificateProvider> new_identity_provider;
+  if (!identity_provider_instance_name.empty()) {
+    new_identity_provider =
+        xds_client_->certificate_provider_store()
+            .CreateOrGetCertificateProvider(identity_provider_instance_name);
+    if (new_identity_provider == nullptr) {
+      return GRPC_ERROR_CREATE_FROM_COPIED_STRING(
+          absl::StrCat("Certificate provider instance name: \"",
+                       identity_provider_instance_name, "\" not recognized.")
+              .c_str());
+    }
+  }
+  if (identity_certificate_provider_ != new_identity_provider) {
+    if (identity_certificate_provider_ != nullptr &&
+        identity_certificate_provider_->interested_parties() != nullptr) {
+      grpc_pollset_set_del_pollset_set(
+          interested_parties(),
+          identity_certificate_provider_->interested_parties());
+    }
+    if (new_identity_provider != nullptr &&
+        new_identity_provider->interested_parties() != nullptr) {
+      grpc_pollset_set_add_pollset_set(
+          interested_parties(), new_identity_provider->interested_parties());
+    }
+    identity_certificate_provider_ = std::move(new_identity_provider);
+  }
+  const std::vector<XdsApi::StringMatcher>& match_subject_alt_names =
+      cluster_data.common_tls_context.combined_validation_context
+          .default_validation_context.match_subject_alt_names;
+  if (!root_provider_instance_name.empty() &&
+      !identity_provider_instance_name.empty()) {
+    // Using mTLS configuration
+    if (xds_certificate_provider_ != nullptr &&
+        xds_certificate_provider_->ProvidesRootCerts() &&
+        xds_certificate_provider_->ProvidesIdentityCerts()) {
+      xds_certificate_provider_->UpdateRootCertNameAndDistributor(
+          root_provider_cert_name, root_certificate_provider_->distributor());
+      xds_certificate_provider_->UpdateIdentityCertNameAndDistributor(
+          identity_provider_cert_name,
+          identity_certificate_provider_->distributor());
+      xds_certificate_provider_->UpdateSubjectAlternativeNameMatchers(
+          match_subject_alt_names);
+    } else {
+      // Existing xDS certificate provider does not have mTLS configuration.
+      // Create new certificate provider so that new subchannel connectors are
+      // created.
+      xds_certificate_provider_ = MakeRefCounted<XdsCertificateProvider>(
+          root_provider_cert_name, root_certificate_provider_->distributor(),
+          identity_provider_cert_name,
+          identity_certificate_provider_->distributor(),
+          match_subject_alt_names);
+    }
+  } else if (!root_provider_instance_name.empty()) {
+    // Using TLS configuration
+    if (xds_certificate_provider_ != nullptr &&
+        xds_certificate_provider_->ProvidesRootCerts() &&
+        !xds_certificate_provider_->ProvidesIdentityCerts()) {
+      xds_certificate_provider_->UpdateRootCertNameAndDistributor(
+          root_provider_cert_name, root_certificate_provider_->distributor());
+      xds_certificate_provider_->UpdateSubjectAlternativeNameMatchers(
+          match_subject_alt_names);
+    } else {
+      // Existing xDS certificate provider does not have TLS configuration.
+      // Create new certificate provider so that new subchannel connectors are
+      // created.
+      xds_certificate_provider_ = MakeRefCounted<XdsCertificateProvider>(
+          root_provider_cert_name, root_certificate_provider_->distributor(),
+          "", nullptr, match_subject_alt_names);
+    }
+  } else {
+    // No configuration provided.
+    xds_certificate_provider_ = nullptr;
+  }
+  return GRPC_ERROR_NONE;
+}
+
 //
 // factory
 //
diff --git a/src/core/ext/filters/client_channel/lb_policy/xds/eds.cc b/src/core/ext/filters/client_channel/lb_policy/xds/eds.cc
deleted file mode 100644 (file)
index 22d7531..0000000
+++ /dev/null
@@ -1,909 +0,0 @@
-//
-// Copyright 2018 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 <limits.h>
-
-#include "absl/strings/str_cat.h"
-#include "absl/types/optional.h"
-
-#include <grpc/grpc.h>
-
-#include "src/core/ext/filters/client_channel/client_channel.h"
-#include "src/core/ext/filters/client_channel/lb_policy.h"
-#include "src/core/ext/filters/client_channel/lb_policy/address_filtering.h"
-#include "src/core/ext/filters/client_channel/lb_policy/child_policy_handler.h"
-#include "src/core/ext/filters/client_channel/lb_policy/xds/xds.h"
-#include "src/core/ext/filters/client_channel/lb_policy_factory.h"
-#include "src/core/ext/filters/client_channel/lb_policy_registry.h"
-#include "src/core/ext/filters/client_channel/server_address.h"
-#include "src/core/ext/xds/xds_channel_args.h"
-#include "src/core/ext/xds/xds_client.h"
-#include "src/core/ext/xds/xds_client_stats.h"
-#include "src/core/lib/channel/channel_args.h"
-#include "src/core/lib/gpr/string.h"
-#include "src/core/lib/gprpp/orphanable.h"
-#include "src/core/lib/gprpp/ref_counted_ptr.h"
-#include "src/core/lib/iomgr/work_serializer.h"
-#include "src/core/lib/transport/error_utils.h"
-#include "src/core/lib/uri/uri_parser.h"
-
-#define GRPC_EDS_DEFAULT_FALLBACK_TIMEOUT 10000
-
-namespace grpc_core {
-
-TraceFlag grpc_lb_eds_trace(false, "eds_lb");
-
-const char* kXdsLocalityNameAttributeKey = "xds_locality_name";
-
-namespace {
-
-constexpr char kEds[] = "eds_experimental";
-
-// Config for EDS LB policy.
-class EdsLbConfig : public LoadBalancingPolicy::Config {
- public:
-  EdsLbConfig(std::string cluster_name, std::string eds_service_name,
-              absl::optional<std::string> lrs_load_reporting_server_name,
-              Json locality_picking_policy, Json endpoint_picking_policy,
-              uint32_t max_concurrent_requests)
-      : cluster_name_(std::move(cluster_name)),
-        eds_service_name_(std::move(eds_service_name)),
-        lrs_load_reporting_server_name_(
-            std::move(lrs_load_reporting_server_name)),
-        locality_picking_policy_(std::move(locality_picking_policy)),
-        endpoint_picking_policy_(std::move(endpoint_picking_policy)),
-        max_concurrent_requests_(max_concurrent_requests) {}
-
-  const char* name() const override { return kEds; }
-
-  const std::string& cluster_name() const { return cluster_name_; }
-  const std::string& eds_service_name() const { return eds_service_name_; }
-  const absl::optional<std::string>& lrs_load_reporting_server_name() const {
-    return lrs_load_reporting_server_name_;
-  };
-  const Json& locality_picking_policy() const {
-    return locality_picking_policy_;
-  }
-  const Json& endpoint_picking_policy() const {
-    return endpoint_picking_policy_;
-  }
-  const uint32_t max_concurrent_requests() const {
-    return max_concurrent_requests_;
-  }
-
- private:
-  std::string cluster_name_;
-  std::string eds_service_name_;
-  absl::optional<std::string> lrs_load_reporting_server_name_;
-  Json locality_picking_policy_;
-  Json endpoint_picking_policy_;
-  uint32_t max_concurrent_requests_;
-};
-
-// EDS LB policy.
-class EdsLb : public LoadBalancingPolicy {
- public:
-  EdsLb(RefCountedPtr<XdsClient> xds_client, Args args);
-
-  const char* name() const override { return kEds; }
-
-  void UpdateLocked(UpdateArgs args) override;
-  void ResetBackoffLocked() override;
-
- private:
-  class EndpointWatcher : public XdsClient::EndpointWatcherInterface {
-   public:
-    explicit EndpointWatcher(RefCountedPtr<EdsLb> parent)
-        : parent_(std::move(parent)) {}
-    void OnEndpointChanged(XdsApi::EdsUpdate update) override {
-      new Notifier(parent_, std::move(update));
-    }
-    void OnError(grpc_error* error) override { new Notifier(parent_, error); }
-    void OnResourceDoesNotExist() override { new Notifier(parent_); }
-
-   private:
-    class Notifier {
-     public:
-      Notifier(RefCountedPtr<EdsLb> parent, XdsApi::EdsUpdate update);
-      Notifier(RefCountedPtr<EdsLb> parent, grpc_error* error);
-      explicit Notifier(RefCountedPtr<EdsLb> parent);
-
-     private:
-      enum Type { kUpdate, kError, kDoesNotExist };
-
-      static void RunInExecCtx(void* arg, grpc_error* error);
-      void RunInWorkSerializer(grpc_error* error);
-
-      RefCountedPtr<EdsLb> parent_;
-      grpc_closure closure_;
-      XdsApi::EdsUpdate update_;
-      Type type_;
-    };
-
-    RefCountedPtr<EdsLb> parent_;
-  };
-
-  class Helper : public ChannelControlHelper {
-   public:
-    explicit Helper(RefCountedPtr<EdsLb> eds_policy)
-        : eds_policy_(std::move(eds_policy)) {}
-
-    ~Helper() override { eds_policy_.reset(DEBUG_LOCATION, "Helper"); }
-
-    RefCountedPtr<SubchannelInterface> CreateSubchannel(
-        ServerAddress address, const grpc_channel_args& args) override;
-    void UpdateState(grpc_connectivity_state state, const absl::Status& status,
-                     std::unique_ptr<SubchannelPicker> picker) override;
-    // This is a no-op, because we get the addresses from the xds
-    // client, which is a watch-based API.
-    void RequestReresolution() override {}
-    void AddTraceEvent(TraceSeverity severity,
-                       absl::string_view message) override;
-
-   private:
-    RefCountedPtr<EdsLb> eds_policy_;
-  };
-
-  ~EdsLb() override;
-
-  void ShutdownLocked() override;
-
-  void OnEndpointChanged(XdsApi::EdsUpdate update);
-  void OnError(grpc_error* error);
-  void OnResourceDoesNotExist();
-
-  void MaybeDestroyChildPolicyLocked();
-
-  void UpdatePriorityList(XdsApi::EdsUpdate::PriorityList priority_list);
-  void UpdateChildPolicyLocked();
-  OrphanablePtr<LoadBalancingPolicy> CreateChildPolicyLocked(
-      const grpc_channel_args* args);
-  ServerAddressList CreateChildPolicyAddressesLocked();
-  RefCountedPtr<Config> CreateChildPolicyConfigLocked();
-  grpc_channel_args* CreateChildPolicyArgsLocked(
-      const grpc_channel_args* args_in);
-
-  // Caller must ensure that config_ is set before calling.
-  const absl::string_view GetEdsResourceName() const {
-    if (!is_xds_uri_) return server_name_;
-    if (!config_->eds_service_name().empty()) {
-      return config_->eds_service_name();
-    }
-    return config_->cluster_name();
-  }
-
-  // Returns a pair containing the cluster and eds_service_name to use
-  // for LRS load reporting.
-  // Caller must ensure that config_ is set before calling.
-  std::pair<absl::string_view, absl::string_view> GetLrsClusterKey() const {
-    if (!is_xds_uri_) return {server_name_, nullptr};
-    return {config_->cluster_name(), config_->eds_service_name()};
-  }
-
-  // Server name from target URI.
-  std::string server_name_;
-  bool is_xds_uri_;
-
-  // Current channel args and config from the resolver.
-  const grpc_channel_args* args_ = nullptr;
-  RefCountedPtr<EdsLbConfig> config_;
-
-  // Internal state.
-  bool shutting_down_ = false;
-
-  // The xds client and endpoint watcher.
-  RefCountedPtr<XdsClient> xds_client_;
-  // A pointer to the endpoint watcher, to be used when cancelling the watch.
-  // Note that this is not owned, so this pointer must never be derefernced.
-  EndpointWatcher* endpoint_watcher_ = nullptr;
-  // The latest data from the endpoint watcher.
-  XdsApi::EdsUpdate::PriorityList priority_list_;
-  // State used to retain child policy names for priority policy.
-  std::vector<size_t /*child_number*/> priority_child_numbers_;
-
-  RefCountedPtr<XdsApi::EdsUpdate::DropConfig> drop_config_;
-
-  OrphanablePtr<LoadBalancingPolicy> child_policy_;
-};
-
-//
-// EdsLb::Helper
-//
-
-RefCountedPtr<SubchannelInterface> EdsLb::Helper::CreateSubchannel(
-    ServerAddress address, const grpc_channel_args& args) {
-  if (eds_policy_->shutting_down_) return nullptr;
-  return eds_policy_->channel_control_helper()->CreateSubchannel(
-      std::move(address), args);
-}
-
-void EdsLb::Helper::UpdateState(grpc_connectivity_state state,
-                                const absl::Status& status,
-                                std::unique_ptr<SubchannelPicker> picker) {
-  if (eds_policy_->shutting_down_ || eds_policy_->child_policy_ == nullptr) {
-    return;
-  }
-  if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_eds_trace)) {
-    gpr_log(GPR_INFO, "[edslb %p] child policy updated state=%s (%s) picker=%p",
-            eds_policy_.get(), ConnectivityStateName(state),
-            status.ToString().c_str(), picker.get());
-  }
-  eds_policy_->channel_control_helper()->UpdateState(state, status,
-                                                     std::move(picker));
-}
-
-void EdsLb::Helper::AddTraceEvent(TraceSeverity severity,
-                                  absl::string_view message) {
-  if (eds_policy_->shutting_down_) return;
-  eds_policy_->channel_control_helper()->AddTraceEvent(severity, message);
-}
-
-//
-// EdsLb::EndpointWatcher::Notifier
-//
-
-EdsLb::EndpointWatcher::Notifier::Notifier(RefCountedPtr<EdsLb> parent,
-                                           XdsApi::EdsUpdate update)
-    : parent_(std::move(parent)), update_(std::move(update)), type_(kUpdate) {
-  GRPC_CLOSURE_INIT(&closure_, &RunInExecCtx, this, nullptr);
-  ExecCtx::Run(DEBUG_LOCATION, &closure_, GRPC_ERROR_NONE);
-}
-
-EdsLb::EndpointWatcher::Notifier::Notifier(RefCountedPtr<EdsLb> parent,
-                                           grpc_error* error)
-    : parent_(std::move(parent)), type_(kError) {
-  GRPC_CLOSURE_INIT(&closure_, &RunInExecCtx, this, nullptr);
-  ExecCtx::Run(DEBUG_LOCATION, &closure_, error);
-}
-
-EdsLb::EndpointWatcher::Notifier::Notifier(RefCountedPtr<EdsLb> parent)
-    : parent_(std::move(parent)), type_(kDoesNotExist) {
-  GRPC_CLOSURE_INIT(&closure_, &RunInExecCtx, this, nullptr);
-  ExecCtx::Run(DEBUG_LOCATION, &closure_, GRPC_ERROR_NONE);
-}
-
-void EdsLb::EndpointWatcher::Notifier::RunInExecCtx(void* arg,
-                                                    grpc_error* error) {
-  Notifier* self = static_cast<Notifier*>(arg);
-  GRPC_ERROR_REF(error);
-  self->parent_->work_serializer()->Run(
-      [self, error]() { self->RunInWorkSerializer(error); }, DEBUG_LOCATION);
-}
-
-void EdsLb::EndpointWatcher::Notifier::RunInWorkSerializer(grpc_error* error) {
-  switch (type_) {
-    case kUpdate:
-      parent_->OnEndpointChanged(std::move(update_));
-      break;
-    case kError:
-      parent_->OnError(error);
-      break;
-    case kDoesNotExist:
-      parent_->OnResourceDoesNotExist();
-      break;
-  };
-  delete this;
-}
-
-//
-// EdsLb public methods
-//
-
-EdsLb::EdsLb(RefCountedPtr<XdsClient> xds_client, Args args)
-    : LoadBalancingPolicy(std::move(args)), xds_client_(std::move(xds_client)) {
-  if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_eds_trace)) {
-    gpr_log(GPR_INFO, "[edslb %p] created -- using xds client %p", this,
-            xds_client_.get());
-  }
-  // Record server name.
-  const char* server_uri =
-      grpc_channel_args_find_string(args.args, GRPC_ARG_SERVER_URI);
-  GPR_ASSERT(server_uri != nullptr);
-  grpc_uri* uri = grpc_uri_parse(server_uri, true);
-  GPR_ASSERT(uri->path[0] != '\0');
-  server_name_ = uri->path[0] == '/' ? uri->path + 1 : uri->path;
-  is_xds_uri_ = strcmp(uri->scheme, "xds") == 0;
-  if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_eds_trace)) {
-    gpr_log(GPR_INFO, "[edslb %p] server name from channel (is_xds_uri=%d): %s",
-            this, is_xds_uri_, server_name_.c_str());
-  }
-  grpc_uri_destroy(uri);
-  // EDS-only flow.
-  if (!is_xds_uri_) {
-    // Setup channelz linkage.
-    channelz::ChannelNode* parent_channelz_node =
-        grpc_channel_args_find_pointer<channelz::ChannelNode>(
-            args.args, GRPC_ARG_CHANNELZ_CHANNEL_NODE);
-    if (parent_channelz_node != nullptr) {
-      xds_client_->AddChannelzLinkage(parent_channelz_node);
-    }
-    // Couple polling.
-    grpc_pollset_set_add_pollset_set(xds_client_->interested_parties(),
-                                     interested_parties());
-  }
-}
-
-EdsLb::~EdsLb() {
-  if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_eds_trace)) {
-    gpr_log(GPR_INFO, "[edslb %p] destroying eds LB policy", this);
-  }
-}
-
-void EdsLb::ShutdownLocked() {
-  if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_eds_trace)) {
-    gpr_log(GPR_INFO, "[edslb %p] shutting down", this);
-  }
-  shutting_down_ = true;
-  MaybeDestroyChildPolicyLocked();
-  // Cancel watcher.
-  if (endpoint_watcher_ != nullptr) {
-    if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_eds_trace)) {
-      gpr_log(GPR_INFO, "[edslb %p] cancelling xds watch for %s", this,
-              std::string(GetEdsResourceName()).c_str());
-    }
-    xds_client_->CancelEndpointDataWatch(GetEdsResourceName(),
-                                         endpoint_watcher_);
-  }
-  if (!is_xds_uri_) {
-    // Remove channelz linkage.
-    channelz::ChannelNode* parent_channelz_node =
-        grpc_channel_args_find_pointer<channelz::ChannelNode>(
-            args_, GRPC_ARG_CHANNELZ_CHANNEL_NODE);
-    if (parent_channelz_node != nullptr) {
-      xds_client_->RemoveChannelzLinkage(parent_channelz_node);
-    }
-    // Decouple polling.
-    grpc_pollset_set_del_pollset_set(xds_client_->interested_parties(),
-                                     interested_parties());
-  }
-  xds_client_.reset(DEBUG_LOCATION, "EdsLb");
-  // Destroy channel args.
-  grpc_channel_args_destroy(args_);
-  args_ = nullptr;
-}
-
-void EdsLb::MaybeDestroyChildPolicyLocked() {
-  if (child_policy_ != nullptr) {
-    grpc_pollset_set_del_pollset_set(child_policy_->interested_parties(),
-                                     interested_parties());
-    child_policy_.reset();
-  }
-}
-
-void EdsLb::UpdateLocked(UpdateArgs args) {
-  if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_eds_trace)) {
-    gpr_log(GPR_INFO, "[edslb %p] Received update", this);
-  }
-  const bool is_initial_update = args_ == nullptr;
-  // Update config.
-  auto old_config = std::move(config_);
-  config_ = std::move(args.config);
-  // Update args.
-  grpc_channel_args_destroy(args_);
-  args_ = args.args;
-  args.args = nullptr;
-  // Update child policy if needed.
-  if (child_policy_ != nullptr) UpdateChildPolicyLocked();
-  // Create endpoint watcher if needed.
-  if (is_initial_update) {
-    if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_eds_trace)) {
-      gpr_log(GPR_INFO, "[edslb %p] starting xds watch for %s", this,
-              std::string(GetEdsResourceName()).c_str());
-    }
-    auto watcher = absl::make_unique<EndpointWatcher>(
-        Ref(DEBUG_LOCATION, "EndpointWatcher"));
-    endpoint_watcher_ = watcher.get();
-    xds_client_->WatchEndpointData(GetEdsResourceName(), std::move(watcher));
-  }
-}
-
-void EdsLb::ResetBackoffLocked() {
-  // When the XdsClient is instantiated in the resolver instead of in this
-  // LB policy, this is done via the resolver, so we don't need to do it here.
-  if (!is_xds_uri_ && xds_client_ != nullptr) xds_client_->ResetBackoff();
-  if (child_policy_ != nullptr) {
-    child_policy_->ResetBackoffLocked();
-  }
-}
-
-void EdsLb::OnEndpointChanged(XdsApi::EdsUpdate update) {
-  if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_eds_trace)) {
-    gpr_log(GPR_INFO, "[edslb %p] Received EDS update from xds client", this);
-  }
-  // Update the drop config.
-  drop_config_ = std::move(update.drop_config);
-  // If priority list is empty, add a single priority, just so that we
-  // have a child in which to create the xds_cluster_impl policy.
-  if (update.priorities.empty()) update.priorities.emplace_back();
-  // Update child policy.
-  UpdatePriorityList(std::move(update.priorities));
-}
-
-void EdsLb::OnError(grpc_error* error) {
-  gpr_log(GPR_ERROR, "[edslb %p] xds watcher reported error: %s", this,
-          grpc_error_string(error));
-  // Go into TRANSIENT_FAILURE if we have not yet created the child
-  // policy (i.e., we have not yet received data from xds).  Otherwise,
-  // we keep running with the data we had previously.
-  if (child_policy_ == nullptr) {
-    channel_control_helper()->UpdateState(
-        GRPC_CHANNEL_TRANSIENT_FAILURE, grpc_error_to_absl_status(error),
-        absl::make_unique<TransientFailurePicker>(error));
-  } else {
-    GRPC_ERROR_UNREF(error);
-  }
-}
-
-void EdsLb::OnResourceDoesNotExist() {
-  gpr_log(
-      GPR_ERROR,
-      "[edslb %p] EDS resource does not exist -- reporting TRANSIENT_FAILURE",
-      this);
-  grpc_error* error = grpc_error_set_int(
-      GRPC_ERROR_CREATE_FROM_STATIC_STRING("EDS resource does not exist"),
-      GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_UNAVAILABLE);
-  channel_control_helper()->UpdateState(
-      GRPC_CHANNEL_TRANSIENT_FAILURE, grpc_error_to_absl_status(error),
-      absl::make_unique<TransientFailurePicker>(error));
-  MaybeDestroyChildPolicyLocked();
-}
-
-//
-// child policy-related methods
-//
-
-void EdsLb::UpdatePriorityList(XdsApi::EdsUpdate::PriorityList priority_list) {
-  // Build some maps from locality to child number and the reverse from
-  // the old data in priority_list_ and priority_child_numbers_.
-  std::map<XdsLocalityName*, size_t /*child_number*/, XdsLocalityName::Less>
-      locality_child_map;
-  std::map<size_t, std::set<XdsLocalityName*>> child_locality_map;
-  for (size_t priority = 0; priority < priority_list_.size(); ++priority) {
-    size_t child_number = priority_child_numbers_[priority];
-    const auto& localities = priority_list_[priority].localities;
-    for (const auto& p : localities) {
-      XdsLocalityName* locality_name = p.first;
-      locality_child_map[locality_name] = child_number;
-      child_locality_map[child_number].insert(locality_name);
-    }
-  }
-  // Construct new list of children.
-  std::vector<size_t> priority_child_numbers;
-  for (size_t priority = 0; priority < priority_list.size(); ++priority) {
-    const auto& localities = priority_list[priority].localities;
-    absl::optional<size_t> child_number;
-    // If one of the localities in this priority already existed, reuse its
-    // child number.
-    for (const auto& p : localities) {
-      XdsLocalityName* locality_name = p.first;
-      if (!child_number.has_value()) {
-        auto it = locality_child_map.find(locality_name);
-        if (it != locality_child_map.end()) {
-          child_number = it->second;
-          locality_child_map.erase(it);
-          // Remove localities that *used* to be in this child number, so
-          // that we don't incorrectly reuse this child number for a
-          // subsequent priority.
-          for (XdsLocalityName* old_locality :
-               child_locality_map[*child_number]) {
-            locality_child_map.erase(old_locality);
-          }
-        }
-      } else {
-        // Remove all localities that are now in this child number, so
-        // that we don't accidentally reuse this child number for a
-        // subsequent priority.
-        locality_child_map.erase(locality_name);
-      }
-    }
-    // If we didn't find an existing child number, assign a new one.
-    if (!child_number.has_value()) {
-      for (child_number = 0;
-           child_locality_map.find(*child_number) != child_locality_map.end();
-           ++(*child_number)) {
-      }
-      // Add entry so we know that the child number is in use.
-      // (Don't need to add the list of localities, since we won't use them.)
-      child_locality_map[*child_number];
-    }
-    priority_child_numbers.push_back(*child_number);
-  }
-  // Save update.
-  priority_list_ = std::move(priority_list);
-  priority_child_numbers_ = std::move(priority_child_numbers);
-  // Update child policy.
-  UpdateChildPolicyLocked();
-}
-
-ServerAddressList EdsLb::CreateChildPolicyAddressesLocked() {
-  ServerAddressList addresses;
-  for (size_t priority = 0; priority < priority_list_.size(); ++priority) {
-    const auto& localities = priority_list_[priority].localities;
-    std::string priority_child_name =
-        absl::StrCat("child", priority_child_numbers_[priority]);
-    for (const auto& p : localities) {
-      const auto& locality_name = p.first;
-      const auto& locality = p.second;
-      std::vector<std::string> hierarchical_path = {
-          priority_child_name, locality_name->AsHumanReadableString()};
-      for (const auto& endpoint : locality.endpoints) {
-        addresses.emplace_back(
-            endpoint
-                .WithAttribute(kHierarchicalPathAttributeKey,
-                               MakeHierarchicalPathAttribute(hierarchical_path))
-                .WithAttribute(kXdsLocalityNameAttributeKey,
-                               absl::make_unique<XdsLocalityAttribute>(
-                                   locality_name->Ref())));
-      }
-    }
-  }
-  return addresses;
-}
-
-RefCountedPtr<LoadBalancingPolicy::Config>
-EdsLb::CreateChildPolicyConfigLocked() {
-  const auto lrs_key = GetLrsClusterKey();
-  Json::Object priority_children;
-  Json::Array priority_priorities;
-  for (size_t priority = 0; priority < priority_list_.size(); ++priority) {
-    const auto& localities = priority_list_[priority].localities;
-    Json::Object weighted_targets;
-    for (const auto& p : localities) {
-      XdsLocalityName* locality_name = p.first;
-      const auto& locality = p.second;
-      // Construct JSON object containing locality name.
-      Json::Object locality_name_json;
-      if (!locality_name->region().empty()) {
-        locality_name_json["region"] = locality_name->region();
-      }
-      if (!locality_name->zone().empty()) {
-        locality_name_json["zone"] = locality_name->zone();
-      }
-      if (!locality_name->sub_zone().empty()) {
-        locality_name_json["subzone"] = locality_name->sub_zone();
-      }
-      // Add weighted target entry.
-      weighted_targets[locality_name->AsHumanReadableString()] = Json::Object{
-          {"weight", locality.lb_weight},
-          {"childPolicy", config_->endpoint_picking_policy()},
-      };
-    }
-    // Construct locality-picking policy.
-    // Start with field from our config and add the "targets" field.
-    Json locality_picking_config = config_->locality_picking_policy();
-    Json::Object& config =
-        *(*locality_picking_config.mutable_array())[0].mutable_object();
-    auto it = config.begin();
-    GPR_ASSERT(it != config.end());
-    (*it->second.mutable_object())["targets"] = std::move(weighted_targets);
-    // Wrap it in the drop policy.
-    Json::Array drop_categories;
-    for (const auto& category : drop_config_->drop_category_list()) {
-      drop_categories.push_back(Json::Object{
-          {"category", category.name},
-          {"requests_per_million", category.parts_per_million},
-      });
-    }
-    Json::Object xds_cluster_impl_config = {
-        {"clusterName", std::string(lrs_key.first)},
-        {"childPolicy", std::move(locality_picking_config)},
-        {"dropCategories", std::move(drop_categories)},
-        {"maxConcurrentRequests", config_->max_concurrent_requests()},
-    };
-    if (!lrs_key.second.empty()) {
-      xds_cluster_impl_config["edsServiceName"] = std::string(lrs_key.second);
-    }
-    if (config_->lrs_load_reporting_server_name().has_value()) {
-      xds_cluster_impl_config["lrsLoadReportingServerName"] =
-          config_->lrs_load_reporting_server_name().value();
-    }
-    Json locality_picking_policy = Json::Array{Json::Object{
-        {"xds_cluster_impl_experimental", std::move(xds_cluster_impl_config)},
-    }};
-    // Add priority entry.
-    const size_t child_number = priority_child_numbers_[priority];
-    std::string child_name = absl::StrCat("child", child_number);
-    priority_priorities.emplace_back(child_name);
-    priority_children[child_name] = Json::Object{
-        {"config", std::move(locality_picking_policy)},
-        {"ignore_reresolution_requests", true},
-    };
-  }
-  Json json = Json::Array{Json::Object{
-      {"priority_experimental",
-       Json::Object{
-           {"children", std::move(priority_children)},
-           {"priorities", std::move(priority_priorities)},
-       }},
-  }};
-  if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_eds_trace)) {
-    std::string json_str = json.Dump(/*indent=*/1);
-    gpr_log(GPR_INFO, "[edslb %p] generated config for child policy: %s", this,
-            json_str.c_str());
-  }
-  grpc_error* error = GRPC_ERROR_NONE;
-  RefCountedPtr<LoadBalancingPolicy::Config> config =
-      LoadBalancingPolicyRegistry::ParseLoadBalancingConfig(json, &error);
-  if (error != GRPC_ERROR_NONE) {
-    // This should never happen, but if it does, we basically have no
-    // way to fix it, so we put the channel in TRANSIENT_FAILURE.
-    gpr_log(GPR_ERROR,
-            "[edslb %p] error parsing generated child policy config -- "
-            "will put channel in TRANSIENT_FAILURE: %s",
-            this, grpc_error_string(error));
-    error = grpc_error_set_int(
-        grpc_error_add_child(
-            GRPC_ERROR_CREATE_FROM_STATIC_STRING(
-                "eds LB policy: error parsing generated child policy config"),
-            error),
-        GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_INTERNAL);
-    channel_control_helper()->UpdateState(
-        GRPC_CHANNEL_TRANSIENT_FAILURE, grpc_error_to_absl_status(error),
-        absl::make_unique<TransientFailurePicker>(error));
-    return nullptr;
-  }
-  return config;
-}
-
-void EdsLb::UpdateChildPolicyLocked() {
-  if (shutting_down_) return;
-  UpdateArgs update_args;
-  update_args.config = CreateChildPolicyConfigLocked();
-  if (update_args.config == nullptr) return;
-  update_args.addresses = CreateChildPolicyAddressesLocked();
-  update_args.args = CreateChildPolicyArgsLocked(args_);
-  if (child_policy_ == nullptr) {
-    child_policy_ = CreateChildPolicyLocked(update_args.args);
-  }
-  if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_eds_trace)) {
-    gpr_log(GPR_INFO, "[edslb %p] Updating child policy %p", this,
-            child_policy_.get());
-  }
-  child_policy_->UpdateLocked(std::move(update_args));
-}
-
-grpc_channel_args* EdsLb::CreateChildPolicyArgsLocked(
-    const grpc_channel_args* args) {
-  grpc_arg args_to_add[] = {
-      // A channel arg indicating if the target is a backend inferred from an
-      // xds load balancer.
-      // TODO(roth): This isn't needed with the new fallback design.
-      // Remove as part of implementing the new fallback functionality.
-      grpc_channel_arg_integer_create(
-          const_cast<char*>(GRPC_ARG_ADDRESS_IS_BACKEND_FROM_XDS_LOAD_BALANCER),
-          1),
-      // Inhibit client-side health checking, since the balancer does
-      // this for us.
-      grpc_channel_arg_integer_create(
-          const_cast<char*>(GRPC_ARG_INHIBIT_HEALTH_CHECKING), 1),
-  };
-  return grpc_channel_args_copy_and_add(args, args_to_add,
-                                        GPR_ARRAY_SIZE(args_to_add));
-}
-
-OrphanablePtr<LoadBalancingPolicy> EdsLb::CreateChildPolicyLocked(
-    const grpc_channel_args* args) {
-  LoadBalancingPolicy::Args lb_policy_args;
-  lb_policy_args.work_serializer = work_serializer();
-  lb_policy_args.args = args;
-  lb_policy_args.channel_control_helper =
-      absl::make_unique<Helper>(Ref(DEBUG_LOCATION, "Helper"));
-  OrphanablePtr<LoadBalancingPolicy> lb_policy =
-      LoadBalancingPolicyRegistry::CreateLoadBalancingPolicy(
-          "priority_experimental", std::move(lb_policy_args));
-  if (GPR_UNLIKELY(lb_policy == nullptr)) {
-    gpr_log(GPR_ERROR, "[edslb %p] failure creating child policy", this);
-    return nullptr;
-  }
-  if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_eds_trace)) {
-    gpr_log(GPR_INFO, "[edslb %p]: Created new child policy %p", this,
-            lb_policy.get());
-  }
-  // Add our interested_parties pollset_set to that of the newly created
-  // child policy. This will make the child policy progress upon activity on
-  // this policy, which in turn is tied to the application's call.
-  grpc_pollset_set_add_pollset_set(lb_policy->interested_parties(),
-                                   interested_parties());
-  return lb_policy;
-}
-
-//
-// factory
-//
-
-class EdsLbFactory : public LoadBalancingPolicyFactory {
- public:
-  OrphanablePtr<LoadBalancingPolicy> CreateLoadBalancingPolicy(
-      LoadBalancingPolicy::Args args) const override {
-    grpc_error* error = GRPC_ERROR_NONE;
-    RefCountedPtr<XdsClient> xds_client = XdsClient::GetOrCreate(&error);
-    if (error != GRPC_ERROR_NONE) {
-      gpr_log(GPR_ERROR,
-              "cannot get XdsClient to instantiate eds LB policy: %s",
-              grpc_error_string(error));
-      GRPC_ERROR_UNREF(error);
-      return nullptr;
-    }
-    return MakeOrphanable<EdsChildHandler>(std::move(xds_client),
-                                           std::move(args));
-  }
-
-  const char* name() const override { return kEds; }
-
-  RefCountedPtr<LoadBalancingPolicy::Config> ParseLoadBalancingConfig(
-      const Json& json, grpc_error** error) const override {
-    GPR_DEBUG_ASSERT(error != nullptr && *error == GRPC_ERROR_NONE);
-    if (json.type() == Json::Type::JSON_NULL) {
-      // eds was mentioned as a policy in the deprecated loadBalancingPolicy
-      // field or in the client API.
-      *error = GRPC_ERROR_CREATE_FROM_STATIC_STRING(
-          "field:loadBalancingPolicy error:eds policy requires configuration. "
-          "Please use loadBalancingConfig field of service config instead.");
-      return nullptr;
-    }
-    std::vector<grpc_error*> error_list;
-    // EDS service name.
-    std::string eds_service_name;
-    auto it = json.object_value().find("edsServiceName");
-    if (it != json.object_value().end()) {
-      if (it->second.type() != Json::Type::STRING) {
-        error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING(
-            "field:edsServiceName error:type should be string"));
-      } else {
-        eds_service_name = it->second.string_value();
-      }
-    }
-    // Cluster name.
-    std::string cluster_name;
-    it = json.object_value().find("clusterName");
-    if (it == json.object_value().end()) {
-      error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING(
-          "field:clusterName error:required field missing"));
-    } else if (it->second.type() != Json::Type::STRING) {
-      error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING(
-          "field:clusterName error:type should be string"));
-    } else {
-      cluster_name = it->second.string_value();
-    }
-    // LRS load reporting server name.
-    absl::optional<std::string> lrs_load_reporting_server_name;
-    it = json.object_value().find("lrsLoadReportingServerName");
-    if (it != json.object_value().end()) {
-      if (it->second.type() != Json::Type::STRING) {
-        error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING(
-            "field:lrsLoadReportingServerName error:type should be string"));
-      } else {
-        lrs_load_reporting_server_name.emplace(it->second.string_value());
-      }
-    }
-    // Locality-picking policy.
-    Json locality_picking_policy;
-    it = json.object_value().find("localityPickingPolicy");
-    if (it == json.object_value().end()) {
-      locality_picking_policy = Json::Array{
-          Json::Object{
-              {"weighted_target_experimental",
-               Json::Object{
-                   {"targets", Json::Object()},
-               }},
-          },
-      };
-    } else {
-      locality_picking_policy = it->second;
-    }
-    grpc_error* parse_error = GRPC_ERROR_NONE;
-    if (LoadBalancingPolicyRegistry::ParseLoadBalancingConfig(
-            locality_picking_policy, &parse_error) == nullptr) {
-      GPR_DEBUG_ASSERT(parse_error != GRPC_ERROR_NONE);
-      error_list.push_back(GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING(
-          "localityPickingPolicy", &parse_error, 1));
-      GRPC_ERROR_UNREF(parse_error);
-    }
-    // Endpoint-picking policy.  Called "childPolicy" for xds policy.
-    Json endpoint_picking_policy;
-    it = json.object_value().find("endpointPickingPolicy");
-    if (it == json.object_value().end()) {
-      endpoint_picking_policy = Json::Array{
-          Json::Object{
-              {"round_robin", Json::Object()},
-          },
-      };
-    } else {
-      endpoint_picking_policy = it->second;
-    }
-    parse_error = GRPC_ERROR_NONE;
-    if (LoadBalancingPolicyRegistry::ParseLoadBalancingConfig(
-            endpoint_picking_policy, &parse_error) == nullptr) {
-      GPR_DEBUG_ASSERT(parse_error != GRPC_ERROR_NONE);
-      error_list.push_back(GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING(
-          "endpointPickingPolicy", &parse_error, 1));
-      GRPC_ERROR_UNREF(parse_error);
-    }
-    // Max concurrent requests.
-    uint32_t max_concurrent_requests = 1024;
-    it = json.object_value().find("max_concurrent_requests");
-    if (it != json.object_value().end()) {
-      if (it->second.type() != Json::Type::NUMBER) {
-        error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING(
-            "field:max_concurrent_requests error:must be of type number"));
-      } else {
-        max_concurrent_requests =
-            gpr_parse_nonnegative_int(it->second.string_value().c_str());
-      }
-    }
-    // Construct config.
-    if (error_list.empty()) {
-      return MakeRefCounted<EdsLbConfig>(
-          std::move(cluster_name), std::move(eds_service_name),
-          std::move(lrs_load_reporting_server_name),
-          std::move(locality_picking_policy),
-          std::move(endpoint_picking_policy), max_concurrent_requests);
-    } else {
-      *error = GRPC_ERROR_CREATE_FROM_VECTOR(
-          "eds_experimental LB policy config", &error_list);
-      return nullptr;
-    }
-  }
-
- private:
-  class EdsChildHandler : public ChildPolicyHandler {
-   public:
-    EdsChildHandler(RefCountedPtr<XdsClient> xds_client, Args args)
-        : ChildPolicyHandler(std::move(args), &grpc_lb_eds_trace),
-          xds_client_(std::move(xds_client)) {}
-
-    bool ConfigChangeRequiresNewPolicyInstance(
-        LoadBalancingPolicy::Config* old_config,
-        LoadBalancingPolicy::Config* new_config) const override {
-      GPR_ASSERT(old_config->name() == kEds);
-      GPR_ASSERT(new_config->name() == kEds);
-      EdsLbConfig* old_eds_config = static_cast<EdsLbConfig*>(old_config);
-      EdsLbConfig* new_eds_config = static_cast<EdsLbConfig*>(new_config);
-      return old_eds_config->cluster_name() != new_eds_config->cluster_name() ||
-             old_eds_config->eds_service_name() !=
-                 new_eds_config->eds_service_name() ||
-             old_eds_config->lrs_load_reporting_server_name() !=
-                 new_eds_config->lrs_load_reporting_server_name();
-    }
-
-    OrphanablePtr<LoadBalancingPolicy> CreateLoadBalancingPolicy(
-        const char* name, LoadBalancingPolicy::Args args) const override {
-      return MakeOrphanable<EdsLb>(xds_client_, std::move(args));
-    }
-
-   private:
-    RefCountedPtr<XdsClient> xds_client_;
-  };
-};
-
-}  // namespace
-
-}  // namespace grpc_core
-
-//
-// Plugin registration
-//
-
-void grpc_lb_policy_eds_init() {
-  grpc_core::LoadBalancingPolicyRegistry::Builder::
-      RegisterLoadBalancingPolicyFactory(
-          absl::make_unique<grpc_core::EdsLbFactory>());
-}
-
-void grpc_lb_policy_eds_shutdown() {}
index 18d138b..7546f5b 100644 (file)
 #include "src/core/ext/xds/xds_client_stats.h"
 #include "src/core/lib/gprpp/ref_counted_ptr.h"
 
-/** Channel arg indicating if a target corresponding to the address is a backend
- * received from a balancer. The type of this arg is an integer and the value is
- * treated as a bool. */
-// TODO(roth): Depending on how we ultimately decide to handle fallback,
-// this may no longer be needed.
-#define GRPC_ARG_ADDRESS_IS_BACKEND_FROM_XDS_LOAD_BALANCER \
-  "grpc.address_is_backend_from_xds_load_balancer"
-
 namespace grpc_core {
 
 // Defined in the EDS policy.
diff --git a/src/core/ext/filters/client_channel/lb_policy/xds/xds_channel_args.h b/src/core/ext/filters/client_channel/lb_policy/xds/xds_channel_args.h
new file mode 100644 (file)
index 0000000..dd64ea7
--- /dev/null
@@ -0,0 +1,24 @@
+//
+// 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_CORE_EXT_FILTERS_CLIENT_CHANNEL_LB_POLICY_XDS_XDS_CHANNEL_ARGS_H
+#define GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_LB_POLICY_XDS_XDS_CHANNEL_ARGS_H
+
+// Channel arg indicating the xDS cluster name.
+// Set by xds_cluster_impl LB policy and used by GoogleDefaultCredentials.
+#define GRPC_ARG_XDS_CLUSTER_NAME "grpc.internal.xds_cluster_name"
+
+#endif  // GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_LB_POLICY_XDS_XDS_CHANNEL_ARGS_H
index b347677..c2d9ec0 100644 (file)
@@ -23,6 +23,7 @@
 #include "src/core/ext/filters/client_channel/lb_policy.h"
 #include "src/core/ext/filters/client_channel/lb_policy/child_policy_handler.h"
 #include "src/core/ext/filters/client_channel/lb_policy/xds/xds.h"
+#include "src/core/ext/filters/client_channel/lb_policy/xds/xds_channel_args.h"
 #include "src/core/ext/filters/client_channel/lb_policy_factory.h"
 #include "src/core/ext/filters/client_channel/lb_policy_registry.h"
 #include "src/core/ext/xds/xds_client.h"
@@ -454,7 +455,6 @@ void XdsClusterImplLb::UpdateLocked(UpdateArgs args) {
   }
   // Update child policy.
   UpdateChildPolicyLocked(std::move(args.addresses), args.args);
-  args.args = nullptr;
 }
 
 void XdsClusterImplLb::MaybeUpdatePickerLocked() {
@@ -522,7 +522,10 @@ void XdsClusterImplLb::UpdateChildPolicyLocked(ServerAddressList addresses,
   UpdateArgs update_args;
   update_args.addresses = std::move(addresses);
   update_args.config = config_->child_policy();
-  update_args.args = args;
+  grpc_arg cluster_arg = grpc_channel_arg_string_create(
+      const_cast<char*>(GRPC_ARG_XDS_CLUSTER_NAME),
+      const_cast<char*>(config_->cluster_name().c_str()));
+  update_args.args = grpc_channel_args_copy_and_add(args, &cluster_arg, 1);
   // Update the policy.
   if (GRPC_TRACE_FLAG_ENABLED(grpc_xds_cluster_impl_lb_trace)) {
     gpr_log(GPR_INFO,
index 1ff42e5..4d76b39 100644 (file)
@@ -55,7 +55,7 @@ class XdsClusterManagerLbConfig : public LoadBalancingPolicy::Config {
   using ClusterMap =
       std::map<std::string, RefCountedPtr<LoadBalancingPolicy::Config>>;
 
-  XdsClusterManagerLbConfig(ClusterMap cluster_map)
+  explicit XdsClusterManagerLbConfig(ClusterMap cluster_map)
       : cluster_map_(std::move(cluster_map)) {}
 
   const char* name() const override { return kXdsClusterManager; }
diff --git a/src/core/ext/filters/client_channel/lb_policy/xds/xds_cluster_resolver.cc b/src/core/ext/filters/client_channel/lb_policy/xds/xds_cluster_resolver.cc
new file mode 100644 (file)
index 0000000..0133a71
--- /dev/null
@@ -0,0 +1,1262 @@
+//
+// Copyright 2018 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 <limits.h>
+
+#include "absl/strings/str_cat.h"
+#include "absl/types/optional.h"
+
+#include <grpc/grpc.h>
+
+#include "src/core/ext/filters/client_channel/client_channel.h"
+#include "src/core/ext/filters/client_channel/lb_policy.h"
+#include "src/core/ext/filters/client_channel/lb_policy/address_filtering.h"
+#include "src/core/ext/filters/client_channel/lb_policy/child_policy_handler.h"
+#include "src/core/ext/filters/client_channel/lb_policy/xds/xds.h"
+#include "src/core/ext/filters/client_channel/lb_policy_factory.h"
+#include "src/core/ext/filters/client_channel/lb_policy_registry.h"
+#include "src/core/ext/filters/client_channel/resolver_registry.h"
+#include "src/core/ext/filters/client_channel/server_address.h"
+#include "src/core/ext/xds/xds_channel_args.h"
+#include "src/core/ext/xds/xds_client.h"
+#include "src/core/ext/xds/xds_client_stats.h"
+#include "src/core/lib/channel/channel_args.h"
+#include "src/core/lib/gpr/string.h"
+#include "src/core/lib/gprpp/orphanable.h"
+#include "src/core/lib/gprpp/ref_counted_ptr.h"
+#include "src/core/lib/iomgr/work_serializer.h"
+#include "src/core/lib/transport/error_utils.h"
+#include "src/core/lib/uri/uri_parser.h"
+
+#define GRPC_EDS_DEFAULT_FALLBACK_TIMEOUT 10000
+
+namespace grpc_core {
+
+TraceFlag grpc_lb_xds_cluster_resolver_trace(false, "xds_cluster_resolver_lb");
+
+const char* kXdsLocalityNameAttributeKey = "xds_locality_name";
+
+namespace {
+
+constexpr char kXdsClusterResolver[] = "xds_cluster_resolver_experimental";
+
+// Config for EDS LB policy.
+class XdsClusterResolverLbConfig : public LoadBalancingPolicy::Config {
+ public:
+  struct DiscoveryMechanism {
+    std::string cluster_name;
+    absl::optional<std::string> lrs_load_reporting_server_name;
+    uint32_t max_concurrent_requests;
+    enum DiscoveryMechanismType {
+      EDS,
+      LOGICAL_DNS,
+    };
+    DiscoveryMechanismType type;
+    std::string eds_service_name;
+
+    bool operator==(const DiscoveryMechanism& other) const {
+      return (cluster_name == other.cluster_name &&
+              lrs_load_reporting_server_name ==
+                  other.lrs_load_reporting_server_name &&
+              max_concurrent_requests == other.max_concurrent_requests &&
+              type == other.type && eds_service_name == other.eds_service_name);
+    }
+  };
+
+  XdsClusterResolverLbConfig(
+      std::vector<DiscoveryMechanism> discovery_mechanisms,
+      Json locality_picking_policy, Json endpoint_picking_policy)
+      : discovery_mechanisms_(std::move(discovery_mechanisms)),
+        locality_picking_policy_(std::move(locality_picking_policy)),
+        endpoint_picking_policy_(std::move(endpoint_picking_policy)) {}
+
+  const char* name() const override { return kXdsClusterResolver; }
+
+  const std::vector<DiscoveryMechanism>& discovery_mechanisms() const {
+    return discovery_mechanisms_;
+  }
+  const Json& locality_picking_policy() const {
+    return locality_picking_policy_;
+  }
+  const Json& endpoint_picking_policy() const {
+    return endpoint_picking_policy_;
+  }
+
+ private:
+  std::vector<DiscoveryMechanism> discovery_mechanisms_;
+  Json locality_picking_policy_;
+  Json endpoint_picking_policy_;
+};
+
+// Xds Cluster Resolver LB policy.
+class XdsClusterResolverLb : public LoadBalancingPolicy {
+ public:
+  XdsClusterResolverLb(RefCountedPtr<XdsClient> xds_client, Args args);
+
+  const char* name() const override { return kXdsClusterResolver; }
+
+  void UpdateLocked(UpdateArgs args) override;
+  void ResetBackoffLocked() override;
+
+ private:
+  // Discovery Mechanism Base class
+  //
+  // Implemented by EDS and LOGICAL_DNS.
+  //
+  // Implementations are responsible for calling the LB policy's
+  // OnEndpointChanged(), OnError(), and OnResourceDoesNotExist()
+  // methods when the corresponding events occur.
+  //
+  // Must implement Orphan() method to cancel the watchers.
+  class DiscoveryMechanism : public InternallyRefCounted<DiscoveryMechanism> {
+   public:
+    DiscoveryMechanism(
+        RefCountedPtr<XdsClusterResolverLb> xds_cluster_resolver_lb,
+        size_t index)
+        : parent_(std::move(xds_cluster_resolver_lb)), index_(index) {}
+    virtual void Start() = 0;
+    void Orphan() override = 0;
+
+    // Caller must ensure that config_ is set before calling.
+    const absl::string_view GetXdsClusterResolverResourceName() const {
+      if (!parent_->is_xds_uri_) return parent_->server_name_;
+      if (!parent_->config_->discovery_mechanisms()[index_]
+               .eds_service_name.empty()) {
+        return parent_->config_->discovery_mechanisms()[index_]
+            .eds_service_name;
+      }
+      return parent_->config_->discovery_mechanisms()[index_].cluster_name;
+    }
+
+    // Returns a pair containing the cluster and eds_service_name
+    // to use for LRS load reporting. Caller must ensure that config_ is set
+    // before calling.
+    std::pair<absl::string_view, absl::string_view> GetLrsClusterKey() const {
+      if (!parent_->is_xds_uri_) return {parent_->server_name_, nullptr};
+      return {
+          parent_->config_->discovery_mechanisms()[index_].cluster_name,
+          parent_->config_->discovery_mechanisms()[index_].eds_service_name};
+    }
+
+   protected:
+    XdsClusterResolverLb* parent() const { return parent_.get(); }
+    size_t index() const { return index_; }
+
+   private:
+    RefCountedPtr<XdsClusterResolverLb> parent_;
+    // Stores its own index in the vector of DiscoveryMechanism.
+    size_t index_;
+  };
+
+  class EdsDiscoveryMechanism : public DiscoveryMechanism {
+   public:
+    EdsDiscoveryMechanism(
+        RefCountedPtr<XdsClusterResolverLb> xds_cluster_resolver_lb,
+        size_t index)
+        : DiscoveryMechanism(std::move(xds_cluster_resolver_lb), index) {}
+    void Start() override;
+    void Orphan() override;
+
+   private:
+    class EndpointWatcher : public XdsClient::EndpointWatcherInterface {
+     public:
+      explicit EndpointWatcher(
+          RefCountedPtr<EdsDiscoveryMechanism> discovery_mechanism)
+          : discovery_mechanism_(std::move(discovery_mechanism)) {}
+      ~EndpointWatcher() override {
+        discovery_mechanism_.reset(DEBUG_LOCATION, "EndpointWatcher");
+      }
+      void OnEndpointChanged(XdsApi::EdsUpdate update) override {
+        new Notifier(discovery_mechanism_, std::move(update));
+      }
+      void OnError(grpc_error* error) override {
+        new Notifier(discovery_mechanism_, error);
+      }
+      void OnResourceDoesNotExist() override {
+        new Notifier(discovery_mechanism_);
+      }
+
+     private:
+      class Notifier {
+       public:
+        Notifier(RefCountedPtr<EdsDiscoveryMechanism> discovery_mechanism,
+                 XdsApi::EdsUpdate update);
+        Notifier(RefCountedPtr<EdsDiscoveryMechanism> discovery_mechanism,
+                 grpc_error* error);
+        explicit Notifier(
+            RefCountedPtr<EdsDiscoveryMechanism> discovery_mechanism);
+        ~Notifier() { discovery_mechanism_.reset(DEBUG_LOCATION, "Notifier"); }
+
+       private:
+        enum Type { kUpdate, kError, kDoesNotExist };
+
+        static void RunInExecCtx(void* arg, grpc_error* error);
+        void RunInWorkSerializer(grpc_error* error);
+
+        RefCountedPtr<EdsDiscoveryMechanism> discovery_mechanism_;
+        grpc_closure closure_;
+        XdsApi::EdsUpdate update_;
+        Type type_;
+      };
+
+      RefCountedPtr<EdsDiscoveryMechanism> discovery_mechanism_;
+    };
+
+    // Note that this is not owned, so this pointer must never be dereferenced.
+    EndpointWatcher* watcher_ = nullptr;
+  };
+
+  class LogicalDNSDiscoveryMechanism : public DiscoveryMechanism {
+   public:
+    LogicalDNSDiscoveryMechanism(
+        RefCountedPtr<XdsClusterResolverLb> xds_cluster_resolver_lb,
+        size_t index)
+        : DiscoveryMechanism(std::move(xds_cluster_resolver_lb), index) {}
+    void Start() override;
+    void Orphan() override;
+
+   private:
+    class ResolverResultHandler : public Resolver::ResultHandler {
+     public:
+      explicit ResolverResultHandler(
+          RefCountedPtr<LogicalDNSDiscoveryMechanism> discovery_mechanism)
+          : discovery_mechanism_(std::move(discovery_mechanism)) {}
+
+      ~ResolverResultHandler() override {}
+
+      void ReturnResult(Resolver::Result result) override;
+
+      void ReturnError(grpc_error* error) override;
+
+     private:
+      RefCountedPtr<LogicalDNSDiscoveryMechanism> discovery_mechanism_;
+    };
+    // This is only necessary because of a bug in msvc where nested class cannot
+    // access protected member in base class.
+    friend class ResolverResultHandler;
+    OrphanablePtr<Resolver> resolver_;
+  };
+
+  struct DiscoveryMechanismEntry {
+    OrphanablePtr<DiscoveryMechanism> discovery_mechanism;
+    bool first_update_received = false;
+    // Number of priorities this mechanism has contributed to priority_list_.
+    // (The sum of this across all discovery mechanisms should always equal
+    // the number of priorities in priority_list_.)
+    uint32_t num_priorities = 0;
+    RefCountedPtr<XdsApi::EdsUpdate::DropConfig> drop_config;
+    // Populated only when an update has been delivered by the mechanism
+    // but has not yet been applied to the LB policy's combined priority_list_.
+    absl::optional<XdsApi::EdsUpdate::PriorityList> pending_priority_list;
+  };
+
+  class Helper : public ChannelControlHelper {
+   public:
+    explicit Helper(
+        RefCountedPtr<XdsClusterResolverLb> xds_cluster_resolver_policy)
+        : xds_cluster_resolver_policy_(std::move(xds_cluster_resolver_policy)) {
+    }
+
+    ~Helper() override {
+      xds_cluster_resolver_policy_.reset(DEBUG_LOCATION, "Helper");
+    }
+
+    RefCountedPtr<SubchannelInterface> CreateSubchannel(
+        ServerAddress address, const grpc_channel_args& args) override;
+    void UpdateState(grpc_connectivity_state state, const absl::Status& status,
+                     std::unique_ptr<SubchannelPicker> picker) override;
+    // This is a no-op, because we get the addresses from the xds
+    // client, which is a watch-based API.
+    void RequestReresolution() override {}
+    void AddTraceEvent(TraceSeverity severity,
+                       absl::string_view message) override;
+
+   private:
+    RefCountedPtr<XdsClusterResolverLb> xds_cluster_resolver_policy_;
+  };
+
+  ~XdsClusterResolverLb() override;
+
+  void ShutdownLocked() override;
+
+  void OnEndpointChanged(size_t index, XdsApi::EdsUpdate update);
+  void OnError(size_t index, grpc_error* error);
+  void OnResourceDoesNotExist(size_t index);
+
+  void MaybeDestroyChildPolicyLocked();
+
+  void UpdatePriorityList(XdsApi::EdsUpdate::PriorityList priority_list);
+  void UpdateChildPolicyLocked();
+  OrphanablePtr<LoadBalancingPolicy> CreateChildPolicyLocked(
+      const grpc_channel_args* args);
+  ServerAddressList CreateChildPolicyAddressesLocked();
+  RefCountedPtr<Config> CreateChildPolicyConfigLocked();
+  grpc_channel_args* CreateChildPolicyArgsLocked(
+      const grpc_channel_args* args_in);
+
+  // Server name from target URI.
+  std::string server_name_;
+  bool is_xds_uri_;
+
+  // Current channel args and config from the resolver.
+  const grpc_channel_args* args_ = nullptr;
+  RefCountedPtr<XdsClusterResolverLbConfig> config_;
+
+  // Internal state.
+  bool shutting_down_ = false;
+
+  // The xds client and endpoint watcher.
+  RefCountedPtr<XdsClient> xds_client_;
+
+  // Vector of discovery mechansism entries in priority order.
+  std::vector<DiscoveryMechanismEntry> discovery_mechanisms_;
+
+  // The latest data from the endpoint watcher.
+  XdsApi::EdsUpdate::PriorityList priority_list_;
+  // State used to retain child policy names for priority policy.
+  std::vector<size_t /*child_number*/> priority_child_numbers_;
+
+  OrphanablePtr<LoadBalancingPolicy> child_policy_;
+};
+
+//
+// XdsClusterResolverLb::Helper
+//
+
+RefCountedPtr<SubchannelInterface>
+XdsClusterResolverLb::Helper::CreateSubchannel(ServerAddress address,
+                                               const grpc_channel_args& args) {
+  if (xds_cluster_resolver_policy_->shutting_down_) return nullptr;
+  return xds_cluster_resolver_policy_->channel_control_helper()
+      ->CreateSubchannel(std::move(address), args);
+}
+
+void XdsClusterResolverLb::Helper::UpdateState(
+    grpc_connectivity_state state, const absl::Status& status,
+    std::unique_ptr<SubchannelPicker> picker) {
+  if (xds_cluster_resolver_policy_->shutting_down_ ||
+      xds_cluster_resolver_policy_->child_policy_ == nullptr) {
+    return;
+  }
+  if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_xds_cluster_resolver_trace)) {
+    gpr_log(GPR_INFO,
+            "[xds_cluster_resolver_lb %p] child policy updated state=%s (%s) "
+            "picker=%p",
+            xds_cluster_resolver_policy_.get(), ConnectivityStateName(state),
+            status.ToString().c_str(), picker.get());
+  }
+  xds_cluster_resolver_policy_->channel_control_helper()->UpdateState(
+      state, status, std::move(picker));
+}
+
+void XdsClusterResolverLb::Helper::AddTraceEvent(TraceSeverity severity,
+                                                 absl::string_view message) {
+  if (xds_cluster_resolver_policy_->shutting_down_) return;
+  xds_cluster_resolver_policy_->channel_control_helper()->AddTraceEvent(
+      severity, message);
+}
+
+//
+// XdsClusterResolverLb::EdsDiscoveryMechanism
+//
+
+void XdsClusterResolverLb::EdsDiscoveryMechanism::Start() {
+  if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_xds_cluster_resolver_trace)) {
+    gpr_log(GPR_INFO,
+            "[xds_cluster_resolver_lb %p] eds discovery mechanism %" PRIuPTR
+            ":%p starting xds watch for %s",
+            parent(), index(), this,
+            std::string(GetXdsClusterResolverResourceName()).c_str());
+  }
+  auto watcher = absl::make_unique<EndpointWatcher>(
+      Ref(DEBUG_LOCATION, "EdsDiscoveryMechanism"));
+  watcher_ = watcher.get();
+  parent()->xds_client_->WatchEndpointData(GetXdsClusterResolverResourceName(),
+                                           std::move(watcher));
+}
+
+void XdsClusterResolverLb::EdsDiscoveryMechanism::Orphan() {
+  if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_xds_cluster_resolver_trace)) {
+    gpr_log(GPR_INFO,
+            "[xds_cluster_resolver_lb %p] eds discovery mechanism %" PRIuPTR
+            ":%p cancelling xds watch for %s",
+            parent(), index(), this,
+            std::string(GetXdsClusterResolverResourceName()).c_str());
+  }
+  parent()->xds_client_->CancelEndpointDataWatch(
+      GetXdsClusterResolverResourceName(), watcher_);
+  Unref();
+}
+
+//
+// XdsClusterResolverLb::EndpointWatcher::Notifier
+//
+
+XdsClusterResolverLb::EdsDiscoveryMechanism::EndpointWatcher::Notifier::
+    Notifier(RefCountedPtr<XdsClusterResolverLb::EdsDiscoveryMechanism>
+                 discovery_mechanism,
+             XdsApi::EdsUpdate update)
+    : discovery_mechanism_(std::move(discovery_mechanism)),
+      update_(std::move(update)),
+      type_(kUpdate) {
+  GRPC_CLOSURE_INIT(&closure_, &RunInExecCtx, this, nullptr);
+  ExecCtx::Run(DEBUG_LOCATION, &closure_, GRPC_ERROR_NONE);
+}
+
+XdsClusterResolverLb::EdsDiscoveryMechanism::EndpointWatcher::Notifier::
+    Notifier(RefCountedPtr<XdsClusterResolverLb::EdsDiscoveryMechanism>
+                 discovery_mechanism,
+             grpc_error* error)
+    : discovery_mechanism_(std::move(discovery_mechanism)), type_(kError) {
+  GRPC_CLOSURE_INIT(&closure_, &RunInExecCtx, this, nullptr);
+  ExecCtx::Run(DEBUG_LOCATION, &closure_, error);
+}
+
+XdsClusterResolverLb::EdsDiscoveryMechanism::EndpointWatcher::Notifier::
+    Notifier(RefCountedPtr<XdsClusterResolverLb::EdsDiscoveryMechanism>
+                 discovery_mechanism)
+    : discovery_mechanism_(std::move(discovery_mechanism)),
+      type_(kDoesNotExist) {
+  GRPC_CLOSURE_INIT(&closure_, &RunInExecCtx, this, nullptr);
+  ExecCtx::Run(DEBUG_LOCATION, &closure_, GRPC_ERROR_NONE);
+}
+
+void XdsClusterResolverLb::EdsDiscoveryMechanism::EndpointWatcher::Notifier::
+    RunInExecCtx(void* arg, grpc_error* error) {
+  Notifier* self = static_cast<Notifier*>(arg);
+  GRPC_ERROR_REF(error);
+  self->discovery_mechanism_->parent()->work_serializer()->Run(
+      [self, error]() { self->RunInWorkSerializer(error); }, DEBUG_LOCATION);
+}
+
+void XdsClusterResolverLb::EdsDiscoveryMechanism::EndpointWatcher::Notifier::
+    RunInWorkSerializer(grpc_error* error) {
+  switch (type_) {
+    case kUpdate:
+      discovery_mechanism_->parent()->OnEndpointChanged(
+          discovery_mechanism_->index(), std::move(update_));
+      break;
+    case kError:
+      discovery_mechanism_->parent()->OnError(discovery_mechanism_->index(),
+                                              error);
+      break;
+    case kDoesNotExist:
+      discovery_mechanism_->parent()->OnResourceDoesNotExist(
+          discovery_mechanism_->index());
+      break;
+  };
+  delete this;
+}
+
+//
+// XdsClusterResolverLb::LogicalDNSDiscoveryMechanism
+//
+
+void XdsClusterResolverLb::LogicalDNSDiscoveryMechanism::Start() {
+  resolver_ = ResolverRegistry::CreateResolver(
+      parent()->server_name_.c_str(), parent()->args_,
+      grpc_pollset_set_create(), parent()->work_serializer(),
+      absl::make_unique<ResolverResultHandler>(
+          Ref(DEBUG_LOCATION, "LogicalDNSDiscoveryMechanism")));
+  if (resolver_ == nullptr) {
+    parent()->OnResourceDoesNotExist(index());
+    return;
+  }
+  resolver_->StartLocked();
+  if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_xds_cluster_resolver_trace)) {
+    gpr_log(GPR_INFO,
+            "[xds_cluster_resolver_lb %p] logical DNS discovery mechanism "
+            "%" PRIuPTR ":%p starting dns resolver %p",
+            parent(), index(), this, resolver_.get());
+  }
+}
+
+void XdsClusterResolverLb::LogicalDNSDiscoveryMechanism::Orphan() {
+  if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_xds_cluster_resolver_trace)) {
+    gpr_log(
+        GPR_INFO,
+        "[xds_cluster_resolver_lb %p] logical DNS discovery mechanism %" PRIuPTR
+        ":%p shutting down dns resolver %p",
+        parent(), index(), this, resolver_.get());
+  }
+  resolver_.reset();
+  Unref();
+}
+
+//
+// XdsClusterResolverLb::LogicalDNSDiscoveryMechanism::ResolverResultHandler
+//
+
+void XdsClusterResolverLb::LogicalDNSDiscoveryMechanism::ResolverResultHandler::
+    ReturnResult(Resolver::Result result) {
+  // convert result to eds update
+  XdsApi::EdsUpdate update;
+  XdsApi::EdsUpdate::Priority::Locality locality;
+  locality.name = MakeRefCounted<XdsLocalityName>("", "", "");
+  locality.endpoints = std::move(result.addresses);
+  update.priorities[0].localities.emplace(locality.name.get(),
+                                          std::move(locality));
+  discovery_mechanism_->parent()->OnEndpointChanged(
+      discovery_mechanism_->index(), std::move(update));
+}
+
+void XdsClusterResolverLb::LogicalDNSDiscoveryMechanism::ResolverResultHandler::
+    ReturnError(grpc_error* error) {
+  discovery_mechanism_->parent()->OnError(discovery_mechanism_->index(), error);
+}
+
+//
+// XdsClusterResolverLb public methods
+//
+
+XdsClusterResolverLb::XdsClusterResolverLb(RefCountedPtr<XdsClient> xds_client,
+                                           Args args)
+    : LoadBalancingPolicy(std::move(args)), xds_client_(std::move(xds_client)) {
+  if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_xds_cluster_resolver_trace)) {
+    gpr_log(GPR_INFO,
+            "[xds_cluster_resolver_lb %p] created -- using xds client %p", this,
+            xds_client_.get());
+  }
+  // Record server name.
+  const char* server_uri =
+      grpc_channel_args_find_string(args.args, GRPC_ARG_SERVER_URI);
+  GPR_ASSERT(server_uri != nullptr);
+  absl::StatusOr<URI> uri = URI::Parse(server_uri);
+  GPR_ASSERT(uri.ok() && !uri->path().empty());
+  server_name_ = std::string(absl::StripPrefix(uri->path(), "/"));
+  is_xds_uri_ = uri->scheme() == "xds";
+  if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_xds_cluster_resolver_trace)) {
+    gpr_log(GPR_INFO,
+            "[xds_cluster_resolver_lb %p] server name from channel "
+            "(is_xds_uri=%d): %s",
+            this, is_xds_uri_, server_name_.c_str());
+  }
+  // EDS-only flow.
+  if (!is_xds_uri_) {
+    // Setup channelz linkage.
+    channelz::ChannelNode* parent_channelz_node =
+        grpc_channel_args_find_pointer<channelz::ChannelNode>(
+            args.args, GRPC_ARG_CHANNELZ_CHANNEL_NODE);
+    if (parent_channelz_node != nullptr) {
+      xds_client_->AddChannelzLinkage(parent_channelz_node);
+    }
+    // Couple polling.
+    grpc_pollset_set_add_pollset_set(xds_client_->interested_parties(),
+                                     interested_parties());
+  }
+}
+
+XdsClusterResolverLb::~XdsClusterResolverLb() {
+  if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_xds_cluster_resolver_trace)) {
+    gpr_log(GPR_INFO,
+            "[xds_cluster_resolver_lb %p] destroying xds_cluster_resolver LB "
+            "policy",
+            this);
+  }
+}
+
+void XdsClusterResolverLb::ShutdownLocked() {
+  if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_xds_cluster_resolver_trace)) {
+    gpr_log(GPR_INFO, "[xds_cluster_resolver_lb %p] shutting down", this);
+  }
+  shutting_down_ = true;
+  MaybeDestroyChildPolicyLocked();
+  discovery_mechanisms_.clear();
+  if (!is_xds_uri_) {
+    // Remove channelz linkage.
+    channelz::ChannelNode* parent_channelz_node =
+        grpc_channel_args_find_pointer<channelz::ChannelNode>(
+            args_, GRPC_ARG_CHANNELZ_CHANNEL_NODE);
+    if (parent_channelz_node != nullptr) {
+      xds_client_->RemoveChannelzLinkage(parent_channelz_node);
+    }
+    // Decouple polling.
+    grpc_pollset_set_del_pollset_set(xds_client_->interested_parties(),
+                                     interested_parties());
+  }
+  xds_client_.reset(DEBUG_LOCATION, "XdsClusterResolverLb");
+  // Destroy channel args.
+  grpc_channel_args_destroy(args_);
+  args_ = nullptr;
+}
+
+void XdsClusterResolverLb::MaybeDestroyChildPolicyLocked() {
+  if (child_policy_ != nullptr) {
+    grpc_pollset_set_del_pollset_set(child_policy_->interested_parties(),
+                                     interested_parties());
+    child_policy_.reset();
+  }
+}
+
+void XdsClusterResolverLb::UpdateLocked(UpdateArgs args) {
+  if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_xds_cluster_resolver_trace)) {
+    gpr_log(GPR_INFO, "[xds_cluster_resolver_lb %p] Received update", this);
+  }
+  const bool is_initial_update = args_ == nullptr;
+  // Update config.
+  auto old_config = std::move(config_);
+  config_ = std::move(args.config);
+  // Update args.
+  grpc_channel_args_destroy(args_);
+  args_ = args.args;
+  args.args = nullptr;
+  // Update child policy if needed.
+  if (child_policy_ != nullptr) UpdateChildPolicyLocked();
+  // Create endpoint watcher if needed.
+  if (is_initial_update) {
+    for (const auto& config : config_->discovery_mechanisms()) {
+      DiscoveryMechanismEntry entry;
+      if (config.type == XdsClusterResolverLbConfig::DiscoveryMechanism::
+                             DiscoveryMechanismType::EDS) {
+        entry.discovery_mechanism =
+            grpc_core::MakeOrphanable<EdsDiscoveryMechanism>(
+                Ref(DEBUG_LOCATION, "EdsDiscoveryMechanism"),
+                discovery_mechanisms_.size());
+      } else if (config.type == XdsClusterResolverLbConfig::DiscoveryMechanism::
+                                    DiscoveryMechanismType::LOGICAL_DNS) {
+        entry.discovery_mechanism =
+            grpc_core::MakeOrphanable<LogicalDNSDiscoveryMechanism>(
+                Ref(DEBUG_LOCATION, "LogicalDNSDiscoveryMechanism"),
+                discovery_mechanisms_.size());
+      } else {
+        GPR_ASSERT(0);
+      }
+      discovery_mechanisms_.push_back(std::move(entry));
+    }
+    // Call start() on all discovery mechanisms after creation.
+    for (const auto& discovery_mechanism : discovery_mechanisms_) {
+      discovery_mechanism.discovery_mechanism->Start();
+    }
+  }
+}
+
+void XdsClusterResolverLb::ResetBackoffLocked() {
+  // When the XdsClient is instantiated in the resolver instead of in this
+  // LB policy, this is done via the resolver, so we don't need to do it here.
+  if (!is_xds_uri_ && xds_client_ != nullptr) xds_client_->ResetBackoff();
+  if (child_policy_ != nullptr) {
+    child_policy_->ResetBackoffLocked();
+  }
+}
+
+void XdsClusterResolverLb::OnEndpointChanged(size_t index,
+                                             XdsApi::EdsUpdate update) {
+  if (shutting_down_) return;
+  if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_xds_cluster_resolver_trace)) {
+    gpr_log(GPR_INFO,
+            "[xds_cluster_resolver_lb %p] Received update from xds client"
+            " for discovery mechanism %" PRIuPTR "",
+            this, index);
+  }
+  // We need at least one priority for each discovery mechanism, just so that we
+  // have a child in which to create the xds_cluster_impl policy.  This ensures
+  // that we properly handle the case of a discovery mechanism dropping 100% of
+  // calls, the OnError() case, and the OnResourceDoesNotExist() case.
+  if (update.priorities.empty()) update.priorities.emplace_back();
+  discovery_mechanisms_[index].drop_config = std::move(update.drop_config);
+  discovery_mechanisms_[index].pending_priority_list =
+      std::move(update.priorities);
+  discovery_mechanisms_[index].first_update_received = true;
+  if (!discovery_mechanisms_[0].first_update_received) {
+    // We have not yet received an update for index 0, so wait until that
+    // happens to create the child policy.
+    return;
+  }
+  // Construct new priority list.
+  XdsApi::EdsUpdate::PriorityList priority_list;
+  size_t priority_index = 0;
+  for (DiscoveryMechanismEntry& mechanism : discovery_mechanisms_) {
+    // If the mechanism has a pending update, use that.
+    // Otherwise, use the priorities that it previously contributed to the
+    // combined list.
+    if (mechanism.pending_priority_list.has_value()) {
+      priority_list.insert(priority_list.end(),
+                           mechanism.pending_priority_list->begin(),
+                           mechanism.pending_priority_list->end());
+      priority_index += mechanism.num_priorities;
+      mechanism.num_priorities = mechanism.pending_priority_list->size();
+      mechanism.pending_priority_list.reset();
+    } else {
+      priority_list.insert(
+          priority_list.end(), priority_list_.begin() + priority_index,
+          priority_list_.begin() + priority_index + mechanism.num_priorities);
+      priority_index += mechanism.num_priorities;
+    }
+  }
+  // Update child policy.
+  UpdatePriorityList(std::move(priority_list));
+}
+
+void XdsClusterResolverLb::OnError(size_t index, grpc_error* error) {
+  gpr_log(GPR_ERROR,
+          "[xds_cluster_resolver_lb %p] discovery mechanism %" PRIuPTR
+          " xds watcher reported error: %s",
+          this, index, grpc_error_string(error));
+  GRPC_ERROR_UNREF(error);
+  if (shutting_down_) return;
+  if (!discovery_mechanisms_[index].first_update_received) {
+    // Call OnEndpointChanged with an empty update just like
+    // OnResourceDoesNotExist.
+    OnEndpointChanged(index, XdsApi::EdsUpdate());
+  }
+}
+
+void XdsClusterResolverLb::OnResourceDoesNotExist(size_t index) {
+  gpr_log(GPR_ERROR,
+          "[xds_cluster_resolver_lb %p] discovery mechanism %" PRIuPTR
+          " resource does not exist",
+          this, index);
+  if (shutting_down_) return;
+  // Call OnEndpointChanged with an empty update.
+  OnEndpointChanged(index, XdsApi::EdsUpdate());
+}
+
+//
+// child policy-related methods
+//
+
+void XdsClusterResolverLb::UpdatePriorityList(
+    XdsApi::EdsUpdate::PriorityList priority_list) {
+  // Build some maps from locality to child number and the reverse from
+  // the old data in priority_list_ and priority_child_numbers_.
+  std::map<XdsLocalityName*, size_t /*child_number*/, XdsLocalityName::Less>
+      locality_child_map;
+  std::map<size_t, std::set<XdsLocalityName*>> child_locality_map;
+  for (size_t priority = 0; priority < priority_list_.size(); ++priority) {
+    size_t child_number = priority_child_numbers_[priority];
+    const auto& localities = priority_list_[priority].localities;
+    for (const auto& p : localities) {
+      XdsLocalityName* locality_name = p.first;
+      locality_child_map[locality_name] = child_number;
+      child_locality_map[child_number].insert(locality_name);
+    }
+  }
+  // Construct new list of children.
+  std::vector<size_t> priority_child_numbers;
+  for (size_t priority = 0; priority < priority_list.size(); ++priority) {
+    const auto& localities = priority_list[priority].localities;
+    absl::optional<size_t> child_number;
+    // If one of the localities in this priority already existed, reuse its
+    // child number.
+    for (const auto& p : localities) {
+      XdsLocalityName* locality_name = p.first;
+      if (!child_number.has_value()) {
+        auto it = locality_child_map.find(locality_name);
+        if (it != locality_child_map.end()) {
+          child_number = it->second;
+          locality_child_map.erase(it);
+          // Remove localities that *used* to be in this child number, so
+          // that we don't incorrectly reuse this child number for a
+          // subsequent priority.
+          for (XdsLocalityName* old_locality :
+               child_locality_map[*child_number]) {
+            locality_child_map.erase(old_locality);
+          }
+        }
+      } else {
+        // Remove all localities that are now in this child number, so
+        // that we don't accidentally reuse this child number for a
+        // subsequent priority.
+        locality_child_map.erase(locality_name);
+      }
+    }
+    // If we didn't find an existing child number, assign a new one.
+    if (!child_number.has_value()) {
+      for (child_number = 0;
+           child_locality_map.find(*child_number) != child_locality_map.end();
+           ++(*child_number)) {
+      }
+      // Add entry so we know that the child number is in use.
+      // (Don't need to add the list of localities, since we won't use them.)
+      child_locality_map[*child_number];
+    }
+    priority_child_numbers.push_back(*child_number);
+  }
+  // Save update.
+  priority_list_ = std::move(priority_list);
+  priority_child_numbers_ = std::move(priority_child_numbers);
+  // Update child policy.
+  UpdateChildPolicyLocked();
+}
+
+ServerAddressList XdsClusterResolverLb::CreateChildPolicyAddressesLocked() {
+  ServerAddressList addresses;
+  for (size_t priority = 0; priority < priority_list_.size(); ++priority) {
+    const auto& localities = priority_list_[priority].localities;
+    std::string priority_child_name =
+        absl::StrCat("child", priority_child_numbers_[priority]);
+    for (const auto& p : localities) {
+      const auto& locality_name = p.first;
+      const auto& locality = p.second;
+      std::vector<std::string> hierarchical_path = {
+          priority_child_name, locality_name->AsHumanReadableString()};
+      for (const auto& endpoint : locality.endpoints) {
+        addresses.emplace_back(
+            endpoint
+                .WithAttribute(kHierarchicalPathAttributeKey,
+                               MakeHierarchicalPathAttribute(hierarchical_path))
+                .WithAttribute(kXdsLocalityNameAttributeKey,
+                               absl::make_unique<XdsLocalityAttribute>(
+                                   locality_name->Ref())));
+      }
+    }
+  }
+  return addresses;
+}
+
+RefCountedPtr<LoadBalancingPolicy::Config>
+XdsClusterResolverLb::CreateChildPolicyConfigLocked() {
+  Json::Object priority_children;
+  Json::Array priority_priorities;
+  // Setting up index to iterate through the discovery mechanisms and keeping
+  // track the discovery_mechanism each prioirty belongs to.
+  size_t discovery_index = 0;
+  // Setting up num_priorities_remaining to track the priorities in each
+  // discovery_mechanism.
+  size_t num_priorities_remaining_in_discovery =
+      discovery_mechanisms_[discovery_index].num_priorities;
+  for (size_t priority = 0; priority < priority_list_.size(); ++priority) {
+    // Each prioirty in the priority_list_ should correspond to a priority in a
+    // discovery mechanism in discovery_mechanisms_ (both in the same order).
+    // Keeping track of the discovery_mechanism each prioirty belongs to.
+    if (num_priorities_remaining_in_discovery == 0) {
+      ++discovery_index;
+      num_priorities_remaining_in_discovery =
+          discovery_mechanisms_[discovery_index].num_priorities;
+    } else {
+      --num_priorities_remaining_in_discovery;
+    }
+    const auto& localities = priority_list_[priority].localities;
+    Json::Object weighted_targets;
+    for (const auto& p : localities) {
+      XdsLocalityName* locality_name = p.first;
+      const auto& locality = p.second;
+      // Construct JSON object containing locality name.
+      Json::Object locality_name_json;
+      if (!locality_name->region().empty()) {
+        locality_name_json["region"] = locality_name->region();
+      }
+      if (!locality_name->zone().empty()) {
+        locality_name_json["zone"] = locality_name->zone();
+      }
+      if (!locality_name->sub_zone().empty()) {
+        locality_name_json["subzone"] = locality_name->sub_zone();
+      }
+      // Add weighted target entry.
+      weighted_targets[locality_name->AsHumanReadableString()] = Json::Object{
+          {"weight", locality.lb_weight},
+          {"childPolicy", config_->endpoint_picking_policy()},
+      };
+    }
+    // Construct locality-picking policy.
+    // Start with field from our config and add the "targets" field.
+    Json locality_picking_config = config_->locality_picking_policy();
+    Json::Object& config =
+        *(*locality_picking_config.mutable_array())[0].mutable_object();
+    auto it = config.begin();
+    GPR_ASSERT(it != config.end());
+    (*it->second.mutable_object())["targets"] = std::move(weighted_targets);
+    // Wrap it in the drop policy.
+    Json::Array drop_categories;
+    if (discovery_mechanisms_[discovery_index].drop_config != nullptr) {
+      for (const auto& category : discovery_mechanisms_[discovery_index]
+                                      .drop_config->drop_category_list()) {
+        drop_categories.push_back(Json::Object{
+            {"category", category.name},
+            {"requests_per_million", category.parts_per_million},
+        });
+      }
+    }
+    const auto lrs_key = discovery_mechanisms_[discovery_index]
+                             .discovery_mechanism->GetLrsClusterKey();
+    Json::Object xds_cluster_impl_config = {
+        {"clusterName", std::string(lrs_key.first)},
+        {"childPolicy", std::move(locality_picking_config)},
+        {"dropCategories", std::move(drop_categories)},
+        {"maxConcurrentRequests",
+         config_->discovery_mechanisms()[discovery_index]
+             .max_concurrent_requests},
+    };
+    if (!lrs_key.second.empty()) {
+      xds_cluster_impl_config["edsServiceName"] = std::string(lrs_key.second);
+    }
+    if (config_->discovery_mechanisms()[discovery_index]
+            .lrs_load_reporting_server_name.has_value()) {
+      xds_cluster_impl_config["lrsLoadReportingServerName"] =
+          config_->discovery_mechanisms()[discovery_index]
+              .lrs_load_reporting_server_name.value();
+    }
+    Json locality_picking_policy = Json::Array{Json::Object{
+        {"xds_cluster_impl_experimental", std::move(xds_cluster_impl_config)},
+    }};
+    // Add priority entry.
+    const size_t child_number = priority_child_numbers_[priority];
+    std::string child_name = absl::StrCat("child", child_number);
+    priority_priorities.emplace_back(child_name);
+    priority_children[child_name] = Json::Object{
+        {"config", std::move(locality_picking_policy)},
+        {"ignore_reresolution_requests", true},
+    };
+  }
+  // There should be matching number of priorities in discovery_mechanisms_ and
+  // in priority_list_; therefore at the end of looping through all the
+  // priorities, num_priorities_remaining should be down to 0, and index should
+  // be the last index in discovery_mechanisms_.
+  GPR_ASSERT(num_priorities_remaining_in_discovery == 0);
+  GPR_ASSERT(discovery_index == discovery_mechanisms_.size() - 1);
+  Json json = Json::Array{Json::Object{
+      {"priority_experimental",
+       Json::Object{
+           {"children", std::move(priority_children)},
+           {"priorities", std::move(priority_priorities)},
+       }},
+  }};
+  if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_xds_cluster_resolver_trace)) {
+    std::string json_str = json.Dump(/*indent=*/1);
+    gpr_log(
+        GPR_INFO,
+        "[xds_cluster_resolver_lb %p] generated config for child policy: %s",
+        this, json_str.c_str());
+  }
+  grpc_error* error = GRPC_ERROR_NONE;
+  RefCountedPtr<LoadBalancingPolicy::Config> config =
+      LoadBalancingPolicyRegistry::ParseLoadBalancingConfig(json, &error);
+  if (error != GRPC_ERROR_NONE) {
+    // This should never happen, but if it does, we basically have no
+    // way to fix it, so we put the channel in TRANSIENT_FAILURE.
+    gpr_log(GPR_ERROR,
+            "[xds_cluster_resolver_lb %p] error parsing generated child policy "
+            "config -- "
+            "will put channel in TRANSIENT_FAILURE: %s",
+            this, grpc_error_string(error));
+    error = grpc_error_set_int(
+        grpc_error_add_child(GRPC_ERROR_CREATE_FROM_STATIC_STRING(
+                                 "xds_cluster_resolver LB policy: error "
+                                 "parsing generated child policy config"),
+                             error),
+        GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_INTERNAL);
+    channel_control_helper()->UpdateState(
+        GRPC_CHANNEL_TRANSIENT_FAILURE, grpc_error_to_absl_status(error),
+        absl::make_unique<TransientFailurePicker>(error));
+    return nullptr;
+  }
+  return config;
+}
+
+void XdsClusterResolverLb::UpdateChildPolicyLocked() {
+  if (shutting_down_) return;
+  UpdateArgs update_args;
+  update_args.config = CreateChildPolicyConfigLocked();
+  if (update_args.config == nullptr) return;
+  update_args.addresses = CreateChildPolicyAddressesLocked();
+  update_args.args = CreateChildPolicyArgsLocked(args_);
+  if (child_policy_ == nullptr) {
+    child_policy_ = CreateChildPolicyLocked(update_args.args);
+  }
+  if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_xds_cluster_resolver_trace)) {
+    gpr_log(GPR_INFO, "[xds_cluster_resolver_lb %p] Updating child policy %p",
+            this, child_policy_.get());
+  }
+  child_policy_->UpdateLocked(std::move(update_args));
+}
+
+grpc_channel_args* XdsClusterResolverLb::CreateChildPolicyArgsLocked(
+    const grpc_channel_args* args) {
+  // Inhibit client-side health checking, since the balancer does this for us.
+  grpc_arg new_arg = grpc_channel_arg_integer_create(
+      const_cast<char*>(GRPC_ARG_INHIBIT_HEALTH_CHECKING), 1);
+  return grpc_channel_args_copy_and_add(args, &new_arg, 1);
+}
+
+OrphanablePtr<LoadBalancingPolicy>
+XdsClusterResolverLb::CreateChildPolicyLocked(const grpc_channel_args* args) {
+  LoadBalancingPolicy::Args lb_policy_args;
+  lb_policy_args.work_serializer = work_serializer();
+  lb_policy_args.args = args;
+  lb_policy_args.channel_control_helper =
+      absl::make_unique<Helper>(Ref(DEBUG_LOCATION, "Helper"));
+  OrphanablePtr<LoadBalancingPolicy> lb_policy =
+      LoadBalancingPolicyRegistry::CreateLoadBalancingPolicy(
+          "priority_experimental", std::move(lb_policy_args));
+  if (GPR_UNLIKELY(lb_policy == nullptr)) {
+    gpr_log(GPR_ERROR,
+            "[xds_cluster_resolver_lb %p] failure creating child policy", this);
+    return nullptr;
+  }
+  if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_xds_cluster_resolver_trace)) {
+    gpr_log(GPR_INFO,
+            "[xds_cluster_resolver_lb %p]: Created new child policy %p", this,
+            lb_policy.get());
+  }
+  // Add our interested_parties pollset_set to that of the newly created
+  // child policy. This will make the child policy progress upon activity on
+  // this policy, which in turn is tied to the application's call.
+  grpc_pollset_set_add_pollset_set(lb_policy->interested_parties(),
+                                   interested_parties());
+  return lb_policy;
+}
+
+//
+// factory
+//
+
+class XdsClusterResolverLbFactory : public LoadBalancingPolicyFactory {
+ public:
+  OrphanablePtr<LoadBalancingPolicy> CreateLoadBalancingPolicy(
+      LoadBalancingPolicy::Args args) const override {
+    grpc_error* error = GRPC_ERROR_NONE;
+    RefCountedPtr<XdsClient> xds_client = XdsClient::GetOrCreate(&error);
+    if (error != GRPC_ERROR_NONE) {
+      gpr_log(GPR_ERROR,
+              "cannot get XdsClient to instantiate xds_cluster_resolver LB "
+              "policy: %s",
+              grpc_error_string(error));
+      GRPC_ERROR_UNREF(error);
+      return nullptr;
+    }
+    return MakeOrphanable<XdsClusterResolverChildHandler>(std::move(xds_client),
+                                                          std::move(args));
+  }
+
+  const char* name() const override { return kXdsClusterResolver; }
+
+  RefCountedPtr<LoadBalancingPolicy::Config> ParseLoadBalancingConfig(
+      const Json& json, grpc_error** error) const override {
+    GPR_DEBUG_ASSERT(error != nullptr && *error == GRPC_ERROR_NONE);
+    if (json.type() == Json::Type::JSON_NULL) {
+      // xds_cluster_resolver was mentioned as a policy in the deprecated
+      // loadBalancingPolicy field or in the client API.
+      *error = GRPC_ERROR_CREATE_FROM_STATIC_STRING(
+          "field:loadBalancingPolicy error:xds_cluster_resolver policy "
+          "requires configuration. "
+          "Please use loadBalancingConfig field of service config instead.");
+      return nullptr;
+    }
+    std::vector<grpc_error*> error_list;
+    std::vector<XdsClusterResolverLbConfig::DiscoveryMechanism>
+        discovery_mechanisms;
+    auto it = json.object_value().find("discoveryMechanisms");
+    if (it == json.object_value().end()) {
+      error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING(
+          "field:discoveryMechanisms error:required field missing"));
+    } else if (it->second.type() != Json::Type::ARRAY) {
+      error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING(
+          "field:discoveryMechanisms error:type should be array"));
+    } else {
+      const Json::Array& array = it->second.array_value();
+      for (size_t i = 0; i < array.size(); ++i) {
+        XdsClusterResolverLbConfig::DiscoveryMechanism discovery_mechanism;
+        std::vector<grpc_error*> discovery_mechanism_errors =
+            ParseDiscoveryMechanism(array[i], &discovery_mechanism);
+        if (!discovery_mechanism_errors.empty()) {
+          grpc_error* error = GRPC_ERROR_CREATE_FROM_COPIED_STRING(
+              absl::StrCat("field:discovery_mechanism element: ", i, " error")
+                  .c_str());
+          for (grpc_error* discovery_mechanism_error :
+               discovery_mechanism_errors) {
+            error = grpc_error_add_child(error, discovery_mechanism_error);
+          }
+          error_list.push_back(error);
+        }
+        discovery_mechanisms.emplace_back(std::move(discovery_mechanism));
+      }
+    }
+    // Locality-picking policy.
+    Json locality_picking_policy;
+    it = json.object_value().find("localityPickingPolicy");
+    if (it == json.object_value().end()) {
+      locality_picking_policy = Json::Array{
+          Json::Object{
+              {"weighted_target_experimental",
+               Json::Object{
+                   {"targets", Json::Object()},
+               }},
+          },
+      };
+    } else {
+      locality_picking_policy = it->second;
+    }
+    grpc_error* parse_error = GRPC_ERROR_NONE;
+    if (LoadBalancingPolicyRegistry::ParseLoadBalancingConfig(
+            locality_picking_policy, &parse_error) == nullptr) {
+      GPR_DEBUG_ASSERT(parse_error != GRPC_ERROR_NONE);
+      error_list.push_back(GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING(
+          "localityPickingPolicy", &parse_error, 1));
+      GRPC_ERROR_UNREF(parse_error);
+    }
+    // Endpoint-picking policy.  Called "childPolicy" for xds policy.
+    Json endpoint_picking_policy;
+    it = json.object_value().find("endpointPickingPolicy");
+    if (it == json.object_value().end()) {
+      endpoint_picking_policy = Json::Array{
+          Json::Object{
+              {"round_robin", Json::Object()},
+          },
+      };
+    } else {
+      endpoint_picking_policy = it->second;
+    }
+    parse_error = GRPC_ERROR_NONE;
+    if (LoadBalancingPolicyRegistry::ParseLoadBalancingConfig(
+            endpoint_picking_policy, &parse_error) == nullptr) {
+      GPR_DEBUG_ASSERT(parse_error != GRPC_ERROR_NONE);
+      error_list.push_back(GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING(
+          "endpointPickingPolicy", &parse_error, 1));
+      GRPC_ERROR_UNREF(parse_error);
+    }
+    if (discovery_mechanisms.empty()) {
+      error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING(
+          "field:discovery_mechanism error:list is missing or empty"));
+    }
+    // Construct config.
+    if (error_list.empty()) {
+      return MakeRefCounted<XdsClusterResolverLbConfig>(
+          std::move(discovery_mechanisms), std::move(locality_picking_policy),
+          std::move(endpoint_picking_policy));
+    } else {
+      *error = GRPC_ERROR_CREATE_FROM_VECTOR(
+          "xds_cluster_resolver_experimental LB policy config", &error_list);
+      return nullptr;
+    }
+  }
+
+ private:
+  static std::vector<grpc_error*> ParseDiscoveryMechanism(
+      const Json& json,
+      XdsClusterResolverLbConfig::DiscoveryMechanism* discovery_mechanism) {
+    std::vector<grpc_error*> error_list;
+    if (json.type() != Json::Type::OBJECT) {
+      error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING(
+          "value should be of type object"));
+      return error_list;
+    }
+    // Cluster name.
+    auto it = json.object_value().find("clusterName");
+    if (it == json.object_value().end()) {
+      error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING(
+          "field:clusterName error:required field missing"));
+    } else if (it->second.type() != Json::Type::STRING) {
+      error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING(
+          "field:clusterName error:type should be string"));
+    } else {
+      discovery_mechanism->cluster_name = it->second.string_value();
+    }
+    // LRS load reporting server name.
+    it = json.object_value().find("lrsLoadReportingServerName");
+    if (it != json.object_value().end()) {
+      if (it->second.type() != Json::Type::STRING) {
+        error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING(
+            "field:lrsLoadReportingServerName error:type should be string"));
+      } else {
+        discovery_mechanism->lrs_load_reporting_server_name.emplace(
+            it->second.string_value());
+      }
+    }
+    // Max concurrent requests.
+    discovery_mechanism->max_concurrent_requests = 1024;
+    it = json.object_value().find("max_concurrent_requests");
+    if (it != json.object_value().end()) {
+      if (it->second.type() != Json::Type::NUMBER) {
+        error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING(
+            "field:max_concurrent_requests error:must be of type number"));
+      } else {
+        discovery_mechanism->max_concurrent_requests =
+            gpr_parse_nonnegative_int(it->second.string_value().c_str());
+      }
+    }
+    // Discovery Mechanism type
+    it = json.object_value().find("type");
+    if (it == json.object_value().end()) {
+      error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING(
+          "field:type error:required field missing"));
+    } else if (it->second.type() != Json::Type::STRING) {
+      error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING(
+          "field:type error:type should be string"));
+    } else {
+      if (it->second.string_value() == "EDS") {
+        discovery_mechanism->type = XdsClusterResolverLbConfig::
+            DiscoveryMechanism::DiscoveryMechanismType::EDS;
+      } else if (it->second.string_value() == "LOGICAL_DNS") {
+        discovery_mechanism->type = XdsClusterResolverLbConfig::
+            DiscoveryMechanism::DiscoveryMechanismType::LOGICAL_DNS;
+      } else {
+        error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING(
+            "field:type error:invalid type"));
+      }
+    }
+    // EDS service name.
+    it = json.object_value().find("edsServiceName");
+    if (it != json.object_value().end()) {
+      if (it->second.type() != Json::Type::STRING) {
+        error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING(
+            "field:xds_cluster_resolverServiceName error:type should be "
+            "string"));
+      } else {
+        discovery_mechanism->eds_service_name = it->second.string_value();
+      }
+    }
+    return error_list;
+  }
+
+  class XdsClusterResolverChildHandler : public ChildPolicyHandler {
+   public:
+    XdsClusterResolverChildHandler(RefCountedPtr<XdsClient> xds_client,
+                                   Args args)
+        : ChildPolicyHandler(std::move(args),
+                             &grpc_lb_xds_cluster_resolver_trace),
+          xds_client_(std::move(xds_client)) {}
+
+    bool ConfigChangeRequiresNewPolicyInstance(
+        LoadBalancingPolicy::Config* old_config,
+        LoadBalancingPolicy::Config* new_config) const override {
+      GPR_ASSERT(old_config->name() == kXdsClusterResolver);
+      GPR_ASSERT(new_config->name() == kXdsClusterResolver);
+      XdsClusterResolverLbConfig* old_xds_cluster_resolver_config =
+          static_cast<XdsClusterResolverLbConfig*>(old_config);
+      XdsClusterResolverLbConfig* new_xds_cluster_resolver_config =
+          static_cast<XdsClusterResolverLbConfig*>(new_config);
+      return old_xds_cluster_resolver_config->discovery_mechanisms() !=
+             new_xds_cluster_resolver_config->discovery_mechanisms();
+    }
+
+    OrphanablePtr<LoadBalancingPolicy> CreateLoadBalancingPolicy(
+        const char* name, LoadBalancingPolicy::Args args) const override {
+      return MakeOrphanable<XdsClusterResolverLb>(xds_client_, std::move(args));
+    }
+
+   private:
+    RefCountedPtr<XdsClient> xds_client_;
+  };
+};
+
+}  // namespace
+
+}  // namespace grpc_core
+
+//
+// Plugin registration
+//
+
+void grpc_lb_policy_xds_cluster_resolver_init() {
+  grpc_core::LoadBalancingPolicyRegistry::Builder::
+      RegisterLoadBalancingPolicyFactory(
+          absl::make_unique<grpc_core::XdsClusterResolverLbFactory>());
+}
+
+void grpc_lb_policy_xds_cluster_resolver_shutdown() {}
index f0bf0cd..0060ad9 100644 (file)
@@ -86,9 +86,9 @@ class AresDnsResolver : public Resolver {
   void OnResolvedLocked(grpc_error* error);
 
   /// DNS server to use (if not system default)
-  char* dns_server_;
+  std::string dns_server_;
   /// name to resolve (usually the same as target_name)
-  char* name_to_resolve_;
+  std::string name_to_resolve_;
   /// channel args
   grpc_channel_args* channel_args_;
   /// whether to request the service config
@@ -139,14 +139,9 @@ AresDnsResolver::AresDnsResolver(ResolverArgs args)
                     grpc_schedule_on_exec_ctx);
   GRPC_CLOSURE_INIT(&on_resolved_, OnResolved, this, grpc_schedule_on_exec_ctx);
   // Get name to resolve from URI path.
-  const char* path = args.uri->path;
-  if (path[0] == '/') ++path;
-  name_to_resolve_ = gpr_strdup(path);
+  name_to_resolve_ = std::string(absl::StripPrefix(args.uri.path(), "/"));
   // Get DNS server from URI authority.
-  dns_server_ = nullptr;
-  if (0 != strcmp(args.uri->authority, "")) {
-    dns_server_ = gpr_strdup(args.uri->authority);
-  }
+  dns_server_ = args.uri.authority();
   channel_args_ = grpc_channel_args_copy(args.args);
   // Disable service config option
   const grpc_arg* arg = grpc_channel_args_find(
@@ -175,8 +170,6 @@ AresDnsResolver::AresDnsResolver(ResolverArgs args)
 AresDnsResolver::~AresDnsResolver() {
   GRPC_CARES_TRACE_LOG("resolver:%p destroying AresDnsResolver", this);
   grpc_pollset_set_destroy(interested_parties_);
-  gpr_free(dns_server_);
-  gpr_free(name_to_resolve_);
   grpc_channel_args_destroy(channel_args_);
 }
 
@@ -439,8 +432,8 @@ void AresDnsResolver::StartResolvingLocked() {
   resolving_ = true;
   service_config_json_ = nullptr;
   pending_request_ = grpc_dns_lookup_ares_locked(
-      dns_server_, name_to_resolve_, kDefaultPort, interested_parties_,
-      &on_resolved_, &addresses_,
+      dns_server_.c_str(), name_to_resolve_.c_str(), kDefaultPort,
+      interested_parties_, &on_resolved_, &addresses_,
       enable_srv_queries_ ? &balancer_addresses_ : nullptr,
       request_service_config_ ? &service_config_json_ : nullptr,
       query_timeout_ms_, work_serializer());
@@ -455,7 +448,7 @@ void AresDnsResolver::StartResolvingLocked() {
 
 class AresDnsResolverFactory : public ResolverFactory {
  public:
-  bool IsValidUri(const grpc_uri* /*uri*/) const override { return true; }
+  bool IsValidUri(const URI& /*uri*/) const override { return true; }
 
   OrphanablePtr<Resolver> CreateResolver(ResolverArgs args) const override {
     return MakeOrphanable<AresDnsResolver>(std::move(args));
diff --git a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.cc b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.cc
deleted file mode 100644 (file)
index 0b74f71..0000000
+++ /dev/null
@@ -1,485 +0,0 @@
-/*
- *
- * Copyright 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 "src/core/lib/iomgr/port.h"
-#if GRPC_ARES == 1
-
-#include <ares.h>
-#include <string.h>
-
-#include "absl/strings/str_cat.h"
-
-#include "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.h"
-
-#include <grpc/support/alloc.h>
-#include <grpc/support/log.h>
-#include <grpc/support/string_util.h>
-#include <grpc/support/time.h>
-#include "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h"
-#include "src/core/lib/gpr/string.h"
-#include "src/core/lib/iomgr/iomgr_internal.h"
-#include "src/core/lib/iomgr/sockaddr_utils.h"
-#include "src/core/lib/iomgr/timer.h"
-
-typedef struct fd_node {
-  /** the owner of this fd node */
-  grpc_ares_ev_driver* ev_driver;
-  /** a closure wrapping on_readable_locked, which should be
-     invoked when the grpc_fd in this node becomes readable. */
-  grpc_closure read_closure;
-  /** a closure wrapping on_writable_locked, which should be
-     invoked when the grpc_fd in this node becomes writable. */
-  grpc_closure write_closure;
-  /** next fd node in the list */
-  struct fd_node* next;
-
-  /** wrapped fd that's polled by grpc's poller for the current platform */
-  grpc_core::GrpcPolledFd* grpc_polled_fd;
-  /** if the readable closure has been registered */
-  bool readable_registered;
-  /** if the writable closure has been registered */
-  bool writable_registered;
-  /** if the fd has been shutdown yet from grpc iomgr perspective */
-  bool already_shutdown;
-} fd_node;
-
-struct grpc_ares_ev_driver {
-  /** the ares_channel owned by this event driver */
-  ares_channel channel;
-  /** pollset set for driving the IO events of the channel */
-  grpc_pollset_set* pollset_set;
-  /** refcount of the event driver */
-  gpr_refcount refs;
-
-  /** work_serializer to synchronize c-ares and I/O callbacks on */
-  std::shared_ptr<grpc_core::WorkSerializer> work_serializer;
-  /** a list of grpc_fd that this event driver is currently using. */
-  fd_node* fds;
-  /** is this event driver currently working? */
-  bool working;
-  /** is this event driver being shut down */
-  bool shutting_down;
-  /** request object that's using this ev driver */
-  grpc_ares_request* request;
-  /** Owned by the ev_driver. Creates new GrpcPolledFd's */
-  std::unique_ptr<grpc_core::GrpcPolledFdFactory> polled_fd_factory;
-  /** query timeout in milliseconds */
-  int query_timeout_ms;
-  /** alarm to cancel active queries */
-  grpc_timer query_timeout;
-  /** cancels queries on a timeout */
-  grpc_closure on_timeout_locked;
-  /** alarm to poll ares_process on in case fd events don't happen */
-  grpc_timer ares_backup_poll_alarm;
-  /** polls ares_process on a periodic timer */
-  grpc_closure on_ares_backup_poll_alarm_locked;
-};
-
-static void grpc_ares_notify_on_event_locked(grpc_ares_ev_driver* ev_driver);
-
-static grpc_ares_ev_driver* grpc_ares_ev_driver_ref(
-    grpc_ares_ev_driver* ev_driver) {
-  GRPC_CARES_TRACE_LOG("request:%p Ref ev_driver %p", ev_driver->request,
-                       ev_driver);
-  gpr_ref(&ev_driver->refs);
-  return ev_driver;
-}
-
-static void grpc_ares_ev_driver_unref(grpc_ares_ev_driver* ev_driver) {
-  GRPC_CARES_TRACE_LOG("request:%p Unref ev_driver %p", ev_driver->request,
-                       ev_driver);
-  if (gpr_unref(&ev_driver->refs)) {
-    GRPC_CARES_TRACE_LOG("request:%p destroy ev_driver %p", ev_driver->request,
-                         ev_driver);
-    GPR_ASSERT(ev_driver->fds == nullptr);
-    ares_destroy(ev_driver->channel);
-    grpc_ares_complete_request_locked(ev_driver->request);
-    delete ev_driver;
-  }
-}
-
-static void fd_node_destroy_locked(fd_node* fdn) {
-  GRPC_CARES_TRACE_LOG("request:%p delete fd: %s", fdn->ev_driver->request,
-                       fdn->grpc_polled_fd->GetName());
-  GPR_ASSERT(!fdn->readable_registered);
-  GPR_ASSERT(!fdn->writable_registered);
-  GPR_ASSERT(fdn->already_shutdown);
-  delete fdn->grpc_polled_fd;
-  gpr_free(fdn);
-}
-
-static void fd_node_shutdown_locked(fd_node* fdn, const char* reason) {
-  if (!fdn->already_shutdown) {
-    fdn->already_shutdown = true;
-    fdn->grpc_polled_fd->ShutdownLocked(
-        GRPC_ERROR_CREATE_FROM_STATIC_STRING(reason));
-  }
-}
-
-static void on_timeout(void* arg, grpc_error* error);
-static void on_timeout_locked(grpc_ares_ev_driver* arg, grpc_error* error);
-
-static void on_ares_backup_poll_alarm(void* arg, grpc_error* error);
-static void on_ares_backup_poll_alarm_locked(grpc_ares_ev_driver* arg,
-                                             grpc_error* error);
-
-static void noop_inject_channel_config(ares_channel /*channel*/) {}
-
-void (*grpc_ares_test_only_inject_config)(ares_channel channel) =
-    noop_inject_channel_config;
-
-grpc_error* grpc_ares_ev_driver_create_locked(
-    grpc_ares_ev_driver** ev_driver, grpc_pollset_set* pollset_set,
-    int query_timeout_ms,
-    std::shared_ptr<grpc_core::WorkSerializer> work_serializer,
-    grpc_ares_request* request) {
-  *ev_driver = new grpc_ares_ev_driver();
-  ares_options opts;
-  memset(&opts, 0, sizeof(opts));
-  opts.flags |= ARES_FLAG_STAYOPEN;
-  int status = ares_init_options(&(*ev_driver)->channel, &opts, ARES_OPT_FLAGS);
-  grpc_ares_test_only_inject_config((*ev_driver)->channel);
-  GRPC_CARES_TRACE_LOG("request:%p grpc_ares_ev_driver_create_locked", request);
-  if (status != ARES_SUCCESS) {
-    grpc_error* err = GRPC_ERROR_CREATE_FROM_COPIED_STRING(
-        absl::StrCat("Failed to init ares channel. C-ares error: ",
-                     ares_strerror(status))
-            .c_str());
-    gpr_free(*ev_driver);
-    return err;
-  }
-  (*ev_driver)->work_serializer = std::move(work_serializer);
-  gpr_ref_init(&(*ev_driver)->refs, 1);
-  (*ev_driver)->pollset_set = pollset_set;
-  (*ev_driver)->fds = nullptr;
-  (*ev_driver)->working = false;
-  (*ev_driver)->shutting_down = false;
-  (*ev_driver)->request = request;
-  (*ev_driver)->polled_fd_factory =
-      grpc_core::NewGrpcPolledFdFactory((*ev_driver)->work_serializer);
-  (*ev_driver)
-      ->polled_fd_factory->ConfigureAresChannelLocked((*ev_driver)->channel);
-  (*ev_driver)->query_timeout_ms = query_timeout_ms;
-  return GRPC_ERROR_NONE;
-}
-
-void grpc_ares_ev_driver_on_queries_complete_locked(
-    grpc_ares_ev_driver* ev_driver) {
-  // We mark the event driver as being shut down. If the event driver
-  // is working, grpc_ares_notify_on_event_locked will shut down the
-  // fds; if it's not working, there are no fds to shut down.
-  ev_driver->shutting_down = true;
-  grpc_timer_cancel(&ev_driver->query_timeout);
-  grpc_timer_cancel(&ev_driver->ares_backup_poll_alarm);
-  grpc_ares_ev_driver_unref(ev_driver);
-}
-
-void grpc_ares_ev_driver_shutdown_locked(grpc_ares_ev_driver* ev_driver) {
-  ev_driver->shutting_down = true;
-  fd_node* fn = ev_driver->fds;
-  while (fn != nullptr) {
-    fd_node_shutdown_locked(fn, "grpc_ares_ev_driver_shutdown");
-    fn = fn->next;
-  }
-}
-
-// Search fd in the fd_node list head. This is an O(n) search, the max possible
-// value of n is ARES_GETSOCK_MAXNUM (16). n is typically 1 - 2 in our tests.
-static fd_node* pop_fd_node_locked(fd_node** head, ares_socket_t as) {
-  fd_node dummy_head;
-  dummy_head.next = *head;
-  fd_node* node = &dummy_head;
-  while (node->next != nullptr) {
-    if (node->next->grpc_polled_fd->GetWrappedAresSocketLocked() == as) {
-      fd_node* ret = node->next;
-      node->next = node->next->next;
-      *head = dummy_head.next;
-      return ret;
-    }
-    node = node->next;
-  }
-  return nullptr;
-}
-
-static grpc_millis calculate_next_ares_backup_poll_alarm_ms(
-    grpc_ares_ev_driver* driver) {
-  // An alternative here could be to use ares_timeout to try to be more
-  // accurate, but that would require using "struct timeval"'s, which just makes
-  // things a bit more complicated. So just poll every second, as suggested
-  // by the c-ares code comments.
-  grpc_millis ms_until_next_ares_backup_poll_alarm = 1000;
-  GRPC_CARES_TRACE_LOG(
-      "request:%p ev_driver=%p. next ares process poll time in "
-      "%" PRId64 " ms",
-      driver->request, driver, ms_until_next_ares_backup_poll_alarm);
-  return ms_until_next_ares_backup_poll_alarm +
-         grpc_core::ExecCtx::Get()->Now();
-}
-
-static void on_timeout(void* arg, grpc_error* error) {
-  grpc_ares_ev_driver* driver = static_cast<grpc_ares_ev_driver*>(arg);
-  GRPC_ERROR_REF(error);  // ref owned by lambda
-  driver->work_serializer->Run(
-      [driver, error]() { on_timeout_locked(driver, error); }, DEBUG_LOCATION);
-}
-
-static void on_timeout_locked(grpc_ares_ev_driver* driver, grpc_error* error) {
-  GRPC_CARES_TRACE_LOG(
-      "request:%p ev_driver=%p on_timeout_locked. driver->shutting_down=%d. "
-      "err=%s",
-      driver->request, driver, driver->shutting_down, grpc_error_string(error));
-  if (!driver->shutting_down && error == GRPC_ERROR_NONE) {
-    grpc_ares_ev_driver_shutdown_locked(driver);
-  }
-  grpc_ares_ev_driver_unref(driver);
-  GRPC_ERROR_UNREF(error);
-}
-
-static void on_ares_backup_poll_alarm(void* arg, grpc_error* error) {
-  grpc_ares_ev_driver* driver = static_cast<grpc_ares_ev_driver*>(arg);
-  GRPC_ERROR_REF(error);
-  driver->work_serializer->Run(
-      [driver, error]() { on_ares_backup_poll_alarm_locked(driver, error); },
-      DEBUG_LOCATION);
-}
-
-/* In case of non-responsive DNS servers, dropped packets, etc., c-ares has
- * intelligent timeout and retry logic, which we can take advantage of by
- * polling ares_process_fd on time intervals. Overall, the c-ares library is
- * meant to be called into and given a chance to proceed name resolution:
- *   a) when fd events happen
- *   b) when some time has passed without fd events having happened
- * For the latter, we use this backup poller. Also see
- * https://github.com/grpc/grpc/pull/17688 description for more details. */
-static void on_ares_backup_poll_alarm_locked(grpc_ares_ev_driver* driver,
-                                             grpc_error* error) {
-  GRPC_CARES_TRACE_LOG(
-      "request:%p ev_driver=%p on_ares_backup_poll_alarm_locked. "
-      "driver->shutting_down=%d. "
-      "err=%s",
-      driver->request, driver, driver->shutting_down, grpc_error_string(error));
-  if (!driver->shutting_down && error == GRPC_ERROR_NONE) {
-    fd_node* fdn = driver->fds;
-    while (fdn != nullptr) {
-      if (!fdn->already_shutdown) {
-        GRPC_CARES_TRACE_LOG(
-            "request:%p ev_driver=%p on_ares_backup_poll_alarm_locked; "
-            "ares_process_fd. fd=%s",
-            driver->request, driver, fdn->grpc_polled_fd->GetName());
-        ares_socket_t as = fdn->grpc_polled_fd->GetWrappedAresSocketLocked();
-        ares_process_fd(driver->channel, as, as);
-      }
-      fdn = fdn->next;
-    }
-    if (!driver->shutting_down) {
-      grpc_millis next_ares_backup_poll_alarm =
-          calculate_next_ares_backup_poll_alarm_ms(driver);
-      grpc_ares_ev_driver_ref(driver);
-      GRPC_CLOSURE_INIT(&driver->on_ares_backup_poll_alarm_locked,
-                        on_ares_backup_poll_alarm, driver,
-                        grpc_schedule_on_exec_ctx);
-      grpc_timer_init(&driver->ares_backup_poll_alarm,
-                      next_ares_backup_poll_alarm,
-                      &driver->on_ares_backup_poll_alarm_locked);
-    }
-    grpc_ares_notify_on_event_locked(driver);
-  }
-  grpc_ares_ev_driver_unref(driver);
-  GRPC_ERROR_UNREF(error);
-}
-
-static void on_readable_locked(fd_node* fdn, grpc_error* error) {
-  GPR_ASSERT(fdn->readable_registered);
-  grpc_ares_ev_driver* ev_driver = fdn->ev_driver;
-  const ares_socket_t as = fdn->grpc_polled_fd->GetWrappedAresSocketLocked();
-  fdn->readable_registered = false;
-  GRPC_CARES_TRACE_LOG("request:%p readable on %s", fdn->ev_driver->request,
-                       fdn->grpc_polled_fd->GetName());
-  if (error == GRPC_ERROR_NONE) {
-    do {
-      ares_process_fd(ev_driver->channel, as, ARES_SOCKET_BAD);
-    } while (fdn->grpc_polled_fd->IsFdStillReadableLocked());
-  } else {
-    // If error is not GRPC_ERROR_NONE, it means the fd has been shutdown or
-    // timed out. The pending lookups made on this ev_driver will be cancelled
-    // by the following ares_cancel() and the on_done callbacks will be invoked
-    // with a status of ARES_ECANCELLED. The remaining file descriptors in this
-    // ev_driver will be cleaned up in the follwing
-    // grpc_ares_notify_on_event_locked().
-    ares_cancel(ev_driver->channel);
-  }
-  grpc_ares_notify_on_event_locked(ev_driver);
-  grpc_ares_ev_driver_unref(ev_driver);
-  GRPC_ERROR_UNREF(error);
-}
-
-static void on_readable(void* arg, grpc_error* error) {
-  fd_node* fdn = static_cast<fd_node*>(arg);
-  GRPC_ERROR_REF(error); /* ref owned by lambda */
-  fdn->ev_driver->work_serializer->Run(
-      [fdn, error]() { on_readable_locked(fdn, error); }, DEBUG_LOCATION);
-}
-
-static void on_writable_locked(fd_node* fdn, grpc_error* error) {
-  GPR_ASSERT(fdn->writable_registered);
-  grpc_ares_ev_driver* ev_driver = fdn->ev_driver;
-  const ares_socket_t as = fdn->grpc_polled_fd->GetWrappedAresSocketLocked();
-  fdn->writable_registered = false;
-  GRPC_CARES_TRACE_LOG("request:%p writable on %s", ev_driver->request,
-                       fdn->grpc_polled_fd->GetName());
-  if (error == GRPC_ERROR_NONE) {
-    ares_process_fd(ev_driver->channel, ARES_SOCKET_BAD, as);
-  } else {
-    // If error is not GRPC_ERROR_NONE, it means the fd has been shutdown or
-    // timed out. The pending lookups made on this ev_driver will be cancelled
-    // by the following ares_cancel() and the on_done callbacks will be invoked
-    // with a status of ARES_ECANCELLED. The remaining file descriptors in this
-    // ev_driver will be cleaned up in the follwing
-    // grpc_ares_notify_on_event_locked().
-    ares_cancel(ev_driver->channel);
-  }
-  grpc_ares_notify_on_event_locked(ev_driver);
-  grpc_ares_ev_driver_unref(ev_driver);
-  GRPC_ERROR_UNREF(error);
-}
-
-static void on_writable(void* arg, grpc_error* error) {
-  fd_node* fdn = static_cast<fd_node*>(arg);
-  GRPC_ERROR_REF(error); /* ref owned by lambda */
-  fdn->ev_driver->work_serializer->Run(
-      [fdn, error]() { on_writable_locked(fdn, error); }, DEBUG_LOCATION);
-}
-
-ares_channel* grpc_ares_ev_driver_get_channel_locked(
-    grpc_ares_ev_driver* ev_driver) {
-  return &ev_driver->channel;
-}
-
-// Get the file descriptors used by the ev_driver's ares channel, register
-// driver_closure with these filedescriptors.
-static void grpc_ares_notify_on_event_locked(grpc_ares_ev_driver* ev_driver) {
-  fd_node* new_list = nullptr;
-  if (!ev_driver->shutting_down) {
-    ares_socket_t socks[ARES_GETSOCK_MAXNUM];
-    int socks_bitmask =
-        ares_getsock(ev_driver->channel, socks, ARES_GETSOCK_MAXNUM);
-    for (size_t i = 0; i < ARES_GETSOCK_MAXNUM; i++) {
-      if (ARES_GETSOCK_READABLE(socks_bitmask, i) ||
-          ARES_GETSOCK_WRITABLE(socks_bitmask, i)) {
-        fd_node* fdn = pop_fd_node_locked(&ev_driver->fds, socks[i]);
-        // Create a new fd_node if sock[i] is not in the fd_node list.
-        if (fdn == nullptr) {
-          fdn = static_cast<fd_node*>(gpr_malloc(sizeof(fd_node)));
-          fdn->grpc_polled_fd =
-              ev_driver->polled_fd_factory->NewGrpcPolledFdLocked(
-                  socks[i], ev_driver->pollset_set, ev_driver->work_serializer);
-          GRPC_CARES_TRACE_LOG("request:%p new fd: %s", ev_driver->request,
-                               fdn->grpc_polled_fd->GetName());
-          fdn->ev_driver = ev_driver;
-          fdn->readable_registered = false;
-          fdn->writable_registered = false;
-          fdn->already_shutdown = false;
-        }
-        fdn->next = new_list;
-        new_list = fdn;
-        // Register read_closure if the socket is readable and read_closure has
-        // not been registered with this socket.
-        if (ARES_GETSOCK_READABLE(socks_bitmask, i) &&
-            !fdn->readable_registered) {
-          grpc_ares_ev_driver_ref(ev_driver);
-          GRPC_CARES_TRACE_LOG("request:%p notify read on: %s",
-                               ev_driver->request,
-                               fdn->grpc_polled_fd->GetName());
-          GRPC_CLOSURE_INIT(&fdn->read_closure, on_readable, fdn,
-                            grpc_schedule_on_exec_ctx);
-          fdn->grpc_polled_fd->RegisterForOnReadableLocked(&fdn->read_closure);
-          fdn->readable_registered = true;
-        }
-        // Register write_closure if the socket is writable and write_closure
-        // has not been registered with this socket.
-        if (ARES_GETSOCK_WRITABLE(socks_bitmask, i) &&
-            !fdn->writable_registered) {
-          GRPC_CARES_TRACE_LOG("request:%p notify write on: %s",
-                               ev_driver->request,
-                               fdn->grpc_polled_fd->GetName());
-          grpc_ares_ev_driver_ref(ev_driver);
-          GRPC_CLOSURE_INIT(&fdn->write_closure, on_writable, fdn,
-                            grpc_schedule_on_exec_ctx);
-          fdn->grpc_polled_fd->RegisterForOnWriteableLocked(
-              &fdn->write_closure);
-          fdn->writable_registered = true;
-        }
-      }
-    }
-  }
-  // Any remaining fds in ev_driver->fds were not returned by ares_getsock() and
-  // are therefore no longer in use, so they can be shut down and removed from
-  // the list.
-  while (ev_driver->fds != nullptr) {
-    fd_node* cur = ev_driver->fds;
-    ev_driver->fds = ev_driver->fds->next;
-    fd_node_shutdown_locked(cur, "c-ares fd shutdown");
-    if (!cur->readable_registered && !cur->writable_registered) {
-      fd_node_destroy_locked(cur);
-    } else {
-      cur->next = new_list;
-      new_list = cur;
-    }
-  }
-  ev_driver->fds = new_list;
-  // If the ev driver has no working fd, all the tasks are done.
-  if (new_list == nullptr) {
-    ev_driver->working = false;
-    GRPC_CARES_TRACE_LOG("request:%p ev driver stop working",
-                         ev_driver->request);
-  }
-}
-
-void grpc_ares_ev_driver_start_locked(grpc_ares_ev_driver* ev_driver) {
-  if (!ev_driver->working) {
-    ev_driver->working = true;
-    grpc_ares_notify_on_event_locked(ev_driver);
-    // Initialize overall DNS resolution timeout alarm
-    grpc_millis timeout =
-        ev_driver->query_timeout_ms == 0
-            ? GRPC_MILLIS_INF_FUTURE
-            : ev_driver->query_timeout_ms + grpc_core::ExecCtx::Get()->Now();
-    GRPC_CARES_TRACE_LOG(
-        "request:%p ev_driver=%p grpc_ares_ev_driver_start_locked. timeout in "
-        "%" PRId64 " ms",
-        ev_driver->request, ev_driver, timeout);
-    grpc_ares_ev_driver_ref(ev_driver);
-    GRPC_CLOSURE_INIT(&ev_driver->on_timeout_locked, on_timeout, ev_driver,
-                      grpc_schedule_on_exec_ctx);
-    grpc_timer_init(&ev_driver->query_timeout, timeout,
-                    &ev_driver->on_timeout_locked);
-    // Initialize the backup poll alarm
-    grpc_millis next_ares_backup_poll_alarm =
-        calculate_next_ares_backup_poll_alarm_ms(ev_driver);
-    grpc_ares_ev_driver_ref(ev_driver);
-    GRPC_CLOSURE_INIT(&ev_driver->on_ares_backup_poll_alarm_locked,
-                      on_ares_backup_poll_alarm, ev_driver,
-                      grpc_schedule_on_exec_ctx);
-    grpc_timer_init(&ev_driver->ares_backup_poll_alarm,
-                    next_ares_backup_poll_alarm,
-                    &ev_driver->on_ares_backup_poll_alarm_locked);
-  }
-}
-
-#endif /* GRPC_ARES == 1 */
index cedf0c3..cc88486 100644 (file)
 #include <grpc/support/port_platform.h>
 
 #include <ares.h>
-#include "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h"
 #include "src/core/lib/iomgr/pollset_set.h"
-
-typedef struct grpc_ares_ev_driver grpc_ares_ev_driver;
-
-/* Start \a ev_driver. It will keep working until all IO on its ares_channel is
-   done, or grpc_ares_ev_driver_destroy() is called. It may notify the callbacks
-   bound to its ares_channel when necessary. */
-void grpc_ares_ev_driver_start_locked(grpc_ares_ev_driver* ev_driver);
-
-/* Returns the ares_channel owned by \a ev_driver. To bind a c-ares query to
-   \a ev_driver, use the ares_channel owned by \a ev_driver as the arg of the
-   query. */
-ares_channel* grpc_ares_ev_driver_get_channel_locked(
-    grpc_ares_ev_driver* ev_driver);
-
-/* Creates a new grpc_ares_ev_driver. Returns GRPC_ERROR_NONE if \a ev_driver is
-   created successfully. */
-grpc_error* grpc_ares_ev_driver_create_locked(
-    grpc_ares_ev_driver** ev_driver, grpc_pollset_set* pollset_set,
-    int query_timeout_ms,
-    std::shared_ptr<grpc_core::WorkSerializer> work_serializer,
-    grpc_ares_request* request);
-
-/* Called back when all DNS lookups have completed. */
-void grpc_ares_ev_driver_on_queries_complete_locked(
-    grpc_ares_ev_driver* ev_driver);
-
-/* Shutdown all the grpc_fds used by \a ev_driver */
-void grpc_ares_ev_driver_shutdown_locked(grpc_ares_ev_driver* ev_driver);
-
-/* Exposed in this header for C-core tests only */
-extern void (*grpc_ares_test_only_inject_config)(ares_channel channel);
+#include "src/core/lib/iomgr/work_serializer.h"
 
 namespace grpc_core {
 
index 062f483..ff18f76 100644 (file)
@@ -43,8 +43,8 @@ namespace grpc_core {
 class GrpcPolledFdPosix : public GrpcPolledFd {
  public:
   GrpcPolledFdPosix(ares_socket_t as, grpc_pollset_set* driver_pollset_set)
-      : name_(absl::StrCat("c-ares fd: ", (int)as)), as_(as) {
-    fd_ = grpc_fd_create((int)as, name_.c_str(), false);
+      : name_(absl::StrCat("c-ares fd: ", static_cast<int>(as))), as_(as) {
+    fd_ = grpc_fd_create(static_cast<int>(as), name_.c_str(), false);
     driver_pollset_set_ = driver_pollset_set;
     grpc_pollset_set_add_fd(driver_pollset_set_, fd_);
   }
index 27a8d75..ede8045 100644 (file)
@@ -46,6 +46,7 @@
 #include "src/core/lib/iomgr/nameser.h"
 #include "src/core/lib/iomgr/parse_address.h"
 #include "src/core/lib/iomgr/sockaddr_utils.h"
+#include "src/core/lib/iomgr/timer.h"
 #include "src/core/lib/transport/authority_override.h"
 
 using grpc_core::ServerAddress;
@@ -56,6 +57,8 @@ grpc_core::TraceFlag grpc_trace_cares_address_sorting(false,
 
 grpc_core::TraceFlag grpc_trace_cares_resolver(false, "cares_resolver");
 
+typedef struct grpc_ares_ev_driver grpc_ares_ev_driver;
+
 struct grpc_ares_request {
   /** indicates the DNS server to use, if specified */
   struct ares_addr_port_node dns_server_addr;
@@ -77,6 +80,60 @@ struct grpc_ares_request {
   grpc_error* error;
 };
 
+typedef struct fd_node {
+  /** the owner of this fd node */
+  grpc_ares_ev_driver* ev_driver;
+  /** a closure wrapping on_readable_locked, which should be
+     invoked when the grpc_fd in this node becomes readable. */
+  grpc_closure read_closure;
+  /** a closure wrapping on_writable_locked, which should be
+     invoked when the grpc_fd in this node becomes writable. */
+  grpc_closure write_closure;
+  /** next fd node in the list */
+  struct fd_node* next;
+
+  /** wrapped fd that's polled by grpc's poller for the current platform */
+  grpc_core::GrpcPolledFd* grpc_polled_fd;
+  /** if the readable closure has been registered */
+  bool readable_registered;
+  /** if the writable closure has been registered */
+  bool writable_registered;
+  /** if the fd has been shutdown yet from grpc iomgr perspective */
+  bool already_shutdown;
+} fd_node;
+
+struct grpc_ares_ev_driver {
+  /** the ares_channel owned by this event driver */
+  ares_channel channel;
+  /** pollset set for driving the IO events of the channel */
+  grpc_pollset_set* pollset_set;
+  /** refcount of the event driver */
+  gpr_refcount refs;
+
+  /** work_serializer to synchronize c-ares and I/O callbacks on */
+  std::shared_ptr<grpc_core::WorkSerializer> work_serializer;
+  /** a list of grpc_fd that this event driver is currently using. */
+  fd_node* fds;
+  /** is this event driver currently working? */
+  bool working;
+  /** is this event driver being shut down */
+  bool shutting_down;
+  /** request object that's using this ev driver */
+  grpc_ares_request* request;
+  /** Owned by the ev_driver. Creates new GrpcPolledFd's */
+  std::unique_ptr<grpc_core::GrpcPolledFdFactory> polled_fd_factory;
+  /** query timeout in milliseconds */
+  int query_timeout_ms;
+  /** alarm to cancel active queries */
+  grpc_timer query_timeout;
+  /** cancels queries on a timeout */
+  grpc_closure on_timeout_locked;
+  /** alarm to poll ares_process on in case fd events don't happen */
+  grpc_timer ares_backup_poll_alarm;
+  /** polls ares_process on a periodic timer */
+  grpc_closure on_ares_backup_poll_alarm_locked;
+};
+
 // TODO(apolcyn): make grpc_ares_hostbyname_request a sub-class
 // of GrpcAresQuery.
 typedef struct grpc_ares_hostbyname_request {
@@ -121,6 +178,390 @@ class GrpcAresQuery {
   const std::string name_;
 };
 
+static grpc_ares_ev_driver* grpc_ares_ev_driver_ref(
+    grpc_ares_ev_driver* ev_driver) {
+  GRPC_CARES_TRACE_LOG("request:%p Ref ev_driver %p", ev_driver->request,
+                       ev_driver);
+  gpr_ref(&ev_driver->refs);
+  return ev_driver;
+}
+
+static void grpc_ares_ev_driver_unref(grpc_ares_ev_driver* ev_driver) {
+  GRPC_CARES_TRACE_LOG("request:%p Unref ev_driver %p", ev_driver->request,
+                       ev_driver);
+  if (gpr_unref(&ev_driver->refs)) {
+    GRPC_CARES_TRACE_LOG("request:%p destroy ev_driver %p", ev_driver->request,
+                         ev_driver);
+    GPR_ASSERT(ev_driver->fds == nullptr);
+    ares_destroy(ev_driver->channel);
+    grpc_ares_complete_request_locked(ev_driver->request);
+    delete ev_driver;
+  }
+}
+
+static void fd_node_destroy_locked(fd_node* fdn) {
+  GRPC_CARES_TRACE_LOG("request:%p delete fd: %s", fdn->ev_driver->request,
+                       fdn->grpc_polled_fd->GetName());
+  GPR_ASSERT(!fdn->readable_registered);
+  GPR_ASSERT(!fdn->writable_registered);
+  GPR_ASSERT(fdn->already_shutdown);
+  delete fdn->grpc_polled_fd;
+  gpr_free(fdn);
+}
+
+static void fd_node_shutdown_locked(fd_node* fdn, const char* reason) {
+  if (!fdn->already_shutdown) {
+    fdn->already_shutdown = true;
+    fdn->grpc_polled_fd->ShutdownLocked(
+        GRPC_ERROR_CREATE_FROM_STATIC_STRING(reason));
+  }
+}
+
+void grpc_ares_ev_driver_on_queries_complete_locked(
+    grpc_ares_ev_driver* ev_driver) {
+  // We mark the event driver as being shut down. If the event driver
+  // is working, grpc_ares_notify_on_event_locked will shut down the
+  // fds; if it's not working, there are no fds to shut down.
+  ev_driver->shutting_down = true;
+  grpc_timer_cancel(&ev_driver->query_timeout);
+  grpc_timer_cancel(&ev_driver->ares_backup_poll_alarm);
+  grpc_ares_ev_driver_unref(ev_driver);
+}
+
+void grpc_ares_ev_driver_shutdown_locked(grpc_ares_ev_driver* ev_driver) {
+  ev_driver->shutting_down = true;
+  fd_node* fn = ev_driver->fds;
+  while (fn != nullptr) {
+    fd_node_shutdown_locked(fn, "grpc_ares_ev_driver_shutdown");
+    fn = fn->next;
+  }
+}
+
+// Search fd in the fd_node list head. This is an O(n) search, the max possible
+// value of n is ARES_GETSOCK_MAXNUM (16). n is typically 1 - 2 in our tests.
+static fd_node* pop_fd_node_locked(fd_node** head, ares_socket_t as) {
+  fd_node dummy_head;
+  dummy_head.next = *head;
+  fd_node* node = &dummy_head;
+  while (node->next != nullptr) {
+    if (node->next->grpc_polled_fd->GetWrappedAresSocketLocked() == as) {
+      fd_node* ret = node->next;
+      node->next = node->next->next;
+      *head = dummy_head.next;
+      return ret;
+    }
+    node = node->next;
+  }
+  return nullptr;
+}
+
+static grpc_millis calculate_next_ares_backup_poll_alarm_ms(
+    grpc_ares_ev_driver* driver) {
+  // An alternative here could be to use ares_timeout to try to be more
+  // accurate, but that would require using "struct timeval"'s, which just makes
+  // things a bit more complicated. So just poll every second, as suggested
+  // by the c-ares code comments.
+  grpc_millis ms_until_next_ares_backup_poll_alarm = 1000;
+  GRPC_CARES_TRACE_LOG(
+      "request:%p ev_driver=%p. next ares process poll time in "
+      "%" PRId64 " ms",
+      driver->request, driver, ms_until_next_ares_backup_poll_alarm);
+  return ms_until_next_ares_backup_poll_alarm +
+         grpc_core::ExecCtx::Get()->Now();
+}
+
+static void on_timeout_locked(grpc_ares_ev_driver* driver, grpc_error* error) {
+  GRPC_CARES_TRACE_LOG(
+      "request:%p ev_driver=%p on_timeout_locked. driver->shutting_down=%d. "
+      "err=%s",
+      driver->request, driver, driver->shutting_down, grpc_error_string(error));
+  if (!driver->shutting_down && error == GRPC_ERROR_NONE) {
+    grpc_ares_ev_driver_shutdown_locked(driver);
+  }
+  grpc_ares_ev_driver_unref(driver);
+  GRPC_ERROR_UNREF(error);
+}
+
+static void on_timeout(void* arg, grpc_error* error) {
+  grpc_ares_ev_driver* driver = static_cast<grpc_ares_ev_driver*>(arg);
+  GRPC_ERROR_REF(error);  // ref owned by lambda
+  driver->work_serializer->Run(
+      [driver, error]() { on_timeout_locked(driver, error); }, DEBUG_LOCATION);
+}
+
+static void grpc_ares_notify_on_event_locked(grpc_ares_ev_driver* ev_driver);
+
+static void on_ares_backup_poll_alarm_locked(grpc_ares_ev_driver* driver,
+                                             grpc_error* error);
+
+static void on_ares_backup_poll_alarm(void* arg, grpc_error* error) {
+  grpc_ares_ev_driver* driver = static_cast<grpc_ares_ev_driver*>(arg);
+  GRPC_ERROR_REF(error);
+  driver->work_serializer->Run(
+      [driver, error]() { on_ares_backup_poll_alarm_locked(driver, error); },
+      DEBUG_LOCATION);
+}
+
+/* In case of non-responsive DNS servers, dropped packets, etc., c-ares has
+ * intelligent timeout and retry logic, which we can take advantage of by
+ * polling ares_process_fd on time intervals. Overall, the c-ares library is
+ * meant to be called into and given a chance to proceed name resolution:
+ *   a) when fd events happen
+ *   b) when some time has passed without fd events having happened
+ * For the latter, we use this backup poller. Also see
+ * https://github.com/grpc/grpc/pull/17688 description for more details. */
+static void on_ares_backup_poll_alarm_locked(grpc_ares_ev_driver* driver,
+                                             grpc_error* error) {
+  GRPC_CARES_TRACE_LOG(
+      "request:%p ev_driver=%p on_ares_backup_poll_alarm_locked. "
+      "driver->shutting_down=%d. "
+      "err=%s",
+      driver->request, driver, driver->shutting_down, grpc_error_string(error));
+  if (!driver->shutting_down && error == GRPC_ERROR_NONE) {
+    fd_node* fdn = driver->fds;
+    while (fdn != nullptr) {
+      if (!fdn->already_shutdown) {
+        GRPC_CARES_TRACE_LOG(
+            "request:%p ev_driver=%p on_ares_backup_poll_alarm_locked; "
+            "ares_process_fd. fd=%s",
+            driver->request, driver, fdn->grpc_polled_fd->GetName());
+        ares_socket_t as = fdn->grpc_polled_fd->GetWrappedAresSocketLocked();
+        ares_process_fd(driver->channel, as, as);
+      }
+      fdn = fdn->next;
+    }
+    if (!driver->shutting_down) {
+      grpc_millis next_ares_backup_poll_alarm =
+          calculate_next_ares_backup_poll_alarm_ms(driver);
+      grpc_ares_ev_driver_ref(driver);
+      GRPC_CLOSURE_INIT(&driver->on_ares_backup_poll_alarm_locked,
+                        on_ares_backup_poll_alarm, driver,
+                        grpc_schedule_on_exec_ctx);
+      grpc_timer_init(&driver->ares_backup_poll_alarm,
+                      next_ares_backup_poll_alarm,
+                      &driver->on_ares_backup_poll_alarm_locked);
+    }
+    grpc_ares_notify_on_event_locked(driver);
+  }
+  grpc_ares_ev_driver_unref(driver);
+  GRPC_ERROR_UNREF(error);
+}
+
+static void on_readable_locked(fd_node* fdn, grpc_error* error) {
+  GPR_ASSERT(fdn->readable_registered);
+  grpc_ares_ev_driver* ev_driver = fdn->ev_driver;
+  const ares_socket_t as = fdn->grpc_polled_fd->GetWrappedAresSocketLocked();
+  fdn->readable_registered = false;
+  GRPC_CARES_TRACE_LOG("request:%p readable on %s", fdn->ev_driver->request,
+                       fdn->grpc_polled_fd->GetName());
+  if (error == GRPC_ERROR_NONE) {
+    do {
+      ares_process_fd(ev_driver->channel, as, ARES_SOCKET_BAD);
+    } while (fdn->grpc_polled_fd->IsFdStillReadableLocked());
+  } else {
+    // If error is not GRPC_ERROR_NONE, it means the fd has been shutdown or
+    // timed out. The pending lookups made on this ev_driver will be cancelled
+    // by the following ares_cancel() and the on_done callbacks will be invoked
+    // with a status of ARES_ECANCELLED. The remaining file descriptors in this
+    // ev_driver will be cleaned up in the follwing
+    // grpc_ares_notify_on_event_locked().
+    ares_cancel(ev_driver->channel);
+  }
+  grpc_ares_notify_on_event_locked(ev_driver);
+  grpc_ares_ev_driver_unref(ev_driver);
+  GRPC_ERROR_UNREF(error);
+}
+
+static void on_readable(void* arg, grpc_error* error) {
+  fd_node* fdn = static_cast<fd_node*>(arg);
+  GRPC_ERROR_REF(error); /* ref owned by lambda */
+  fdn->ev_driver->work_serializer->Run(
+      [fdn, error]() { on_readable_locked(fdn, error); }, DEBUG_LOCATION);
+}
+
+static void on_writable_locked(fd_node* fdn, grpc_error* error) {
+  GPR_ASSERT(fdn->writable_registered);
+  grpc_ares_ev_driver* ev_driver = fdn->ev_driver;
+  const ares_socket_t as = fdn->grpc_polled_fd->GetWrappedAresSocketLocked();
+  fdn->writable_registered = false;
+  GRPC_CARES_TRACE_LOG("request:%p writable on %s", ev_driver->request,
+                       fdn->grpc_polled_fd->GetName());
+  if (error == GRPC_ERROR_NONE) {
+    ares_process_fd(ev_driver->channel, ARES_SOCKET_BAD, as);
+  } else {
+    // If error is not GRPC_ERROR_NONE, it means the fd has been shutdown or
+    // timed out. The pending lookups made on this ev_driver will be cancelled
+    // by the following ares_cancel() and the on_done callbacks will be invoked
+    // with a status of ARES_ECANCELLED. The remaining file descriptors in this
+    // ev_driver will be cleaned up in the follwing
+    // grpc_ares_notify_on_event_locked().
+    ares_cancel(ev_driver->channel);
+  }
+  grpc_ares_notify_on_event_locked(ev_driver);
+  grpc_ares_ev_driver_unref(ev_driver);
+  GRPC_ERROR_UNREF(error);
+}
+
+static void on_writable(void* arg, grpc_error* error) {
+  fd_node* fdn = static_cast<fd_node*>(arg);
+  GRPC_ERROR_REF(error); /* ref owned by lambda */
+  fdn->ev_driver->work_serializer->Run(
+      [fdn, error]() { on_writable_locked(fdn, error); }, DEBUG_LOCATION);
+}
+
+// Get the file descriptors used by the ev_driver's ares channel, register
+// driver_closure with these filedescriptors.
+static void grpc_ares_notify_on_event_locked(grpc_ares_ev_driver* ev_driver) {
+  fd_node* new_list = nullptr;
+  if (!ev_driver->shutting_down) {
+    ares_socket_t socks[ARES_GETSOCK_MAXNUM];
+    int socks_bitmask =
+        ares_getsock(ev_driver->channel, socks, ARES_GETSOCK_MAXNUM);
+    for (size_t i = 0; i < ARES_GETSOCK_MAXNUM; i++) {
+      if (ARES_GETSOCK_READABLE(socks_bitmask, i) ||
+          ARES_GETSOCK_WRITABLE(socks_bitmask, i)) {
+        fd_node* fdn = pop_fd_node_locked(&ev_driver->fds, socks[i]);
+        // Create a new fd_node if sock[i] is not in the fd_node list.
+        if (fdn == nullptr) {
+          fdn = static_cast<fd_node*>(gpr_malloc(sizeof(fd_node)));
+          fdn->grpc_polled_fd =
+              ev_driver->polled_fd_factory->NewGrpcPolledFdLocked(
+                  socks[i], ev_driver->pollset_set, ev_driver->work_serializer);
+          GRPC_CARES_TRACE_LOG("request:%p new fd: %s", ev_driver->request,
+                               fdn->grpc_polled_fd->GetName());
+          fdn->ev_driver = ev_driver;
+          fdn->readable_registered = false;
+          fdn->writable_registered = false;
+          fdn->already_shutdown = false;
+        }
+        fdn->next = new_list;
+        new_list = fdn;
+        // Register read_closure if the socket is readable and read_closure has
+        // not been registered with this socket.
+        if (ARES_GETSOCK_READABLE(socks_bitmask, i) &&
+            !fdn->readable_registered) {
+          grpc_ares_ev_driver_ref(ev_driver);
+          GRPC_CARES_TRACE_LOG("request:%p notify read on: %s",
+                               ev_driver->request,
+                               fdn->grpc_polled_fd->GetName());
+          GRPC_CLOSURE_INIT(&fdn->read_closure, on_readable, fdn,
+                            grpc_schedule_on_exec_ctx);
+          fdn->grpc_polled_fd->RegisterForOnReadableLocked(&fdn->read_closure);
+          fdn->readable_registered = true;
+        }
+        // Register write_closure if the socket is writable and write_closure
+        // has not been registered with this socket.
+        if (ARES_GETSOCK_WRITABLE(socks_bitmask, i) &&
+            !fdn->writable_registered) {
+          GRPC_CARES_TRACE_LOG("request:%p notify write on: %s",
+                               ev_driver->request,
+                               fdn->grpc_polled_fd->GetName());
+          grpc_ares_ev_driver_ref(ev_driver);
+          GRPC_CLOSURE_INIT(&fdn->write_closure, on_writable, fdn,
+                            grpc_schedule_on_exec_ctx);
+          GRPC_CLOSURE_INIT(&fdn->write_closure, on_writable, fdn,
+                            grpc_schedule_on_exec_ctx);
+          fdn->grpc_polled_fd->RegisterForOnWriteableLocked(
+              &fdn->write_closure);
+          fdn->writable_registered = true;
+        }
+      }
+    }
+  }
+  // Any remaining fds in ev_driver->fds were not returned by ares_getsock() and
+  // are therefore no longer in use, so they can be shut down and removed from
+  // the list.
+  while (ev_driver->fds != nullptr) {
+    fd_node* cur = ev_driver->fds;
+    ev_driver->fds = ev_driver->fds->next;
+    fd_node_shutdown_locked(cur, "c-ares fd shutdown");
+    if (!cur->readable_registered && !cur->writable_registered) {
+      fd_node_destroy_locked(cur);
+    } else {
+      cur->next = new_list;
+      new_list = cur;
+    }
+  }
+  ev_driver->fds = new_list;
+  // If the ev driver has no working fd, all the tasks are done.
+  if (new_list == nullptr) {
+    ev_driver->working = false;
+    GRPC_CARES_TRACE_LOG("request:%p ev driver stop working",
+                         ev_driver->request);
+  }
+}
+
+void grpc_ares_ev_driver_start_locked(grpc_ares_ev_driver* ev_driver) {
+  if (!ev_driver->working) {
+    ev_driver->working = true;
+    grpc_ares_notify_on_event_locked(ev_driver);
+    // Initialize overall DNS resolution timeout alarm
+    grpc_millis timeout =
+        ev_driver->query_timeout_ms == 0
+            ? GRPC_MILLIS_INF_FUTURE
+            : ev_driver->query_timeout_ms + grpc_core::ExecCtx::Get()->Now();
+    GRPC_CARES_TRACE_LOG(
+        "request:%p ev_driver=%p grpc_ares_ev_driver_start_locked. timeout in "
+        "%" PRId64 " ms",
+        ev_driver->request, ev_driver, timeout);
+    grpc_ares_ev_driver_ref(ev_driver);
+    GRPC_CLOSURE_INIT(&ev_driver->on_timeout_locked, on_timeout, ev_driver,
+                      grpc_schedule_on_exec_ctx);
+    grpc_timer_init(&ev_driver->query_timeout, timeout,
+                    &ev_driver->on_timeout_locked);
+    // Initialize the backup poll alarm
+    grpc_millis next_ares_backup_poll_alarm =
+        calculate_next_ares_backup_poll_alarm_ms(ev_driver);
+    grpc_ares_ev_driver_ref(ev_driver);
+    GRPC_CLOSURE_INIT(&ev_driver->on_ares_backup_poll_alarm_locked,
+                      on_ares_backup_poll_alarm, ev_driver,
+                      grpc_schedule_on_exec_ctx);
+    grpc_timer_init(&ev_driver->ares_backup_poll_alarm,
+                    next_ares_backup_poll_alarm,
+                    &ev_driver->on_ares_backup_poll_alarm_locked);
+  }
+}
+
+static void noop_inject_channel_config(ares_channel /*channel*/) {}
+
+void (*grpc_ares_test_only_inject_config)(ares_channel channel) =
+    noop_inject_channel_config;
+
+grpc_error* grpc_ares_ev_driver_create_locked(
+    grpc_ares_ev_driver** ev_driver, grpc_pollset_set* pollset_set,
+    int query_timeout_ms,
+    std::shared_ptr<grpc_core::WorkSerializer> work_serializer,
+    grpc_ares_request* request) {
+  *ev_driver = new grpc_ares_ev_driver();
+  ares_options opts;
+  memset(&opts, 0, sizeof(opts));
+  opts.flags |= ARES_FLAG_STAYOPEN;
+  int status = ares_init_options(&(*ev_driver)->channel, &opts, ARES_OPT_FLAGS);
+  grpc_ares_test_only_inject_config((*ev_driver)->channel);
+  GRPC_CARES_TRACE_LOG("request:%p grpc_ares_ev_driver_create_locked", request);
+  if (status != ARES_SUCCESS) {
+    grpc_error* err = GRPC_ERROR_CREATE_FROM_COPIED_STRING(
+        absl::StrCat("Failed to init ares channel. C-ares error: ",
+                     ares_strerror(status))
+            .c_str());
+    gpr_free(*ev_driver);
+    return err;
+  }
+  (*ev_driver)->work_serializer = std::move(work_serializer);
+  gpr_ref_init(&(*ev_driver)->refs, 1);
+  (*ev_driver)->pollset_set = pollset_set;
+  (*ev_driver)->fds = nullptr;
+  (*ev_driver)->working = false;
+  (*ev_driver)->shutting_down = false;
+  (*ev_driver)->request = request;
+  (*ev_driver)->polled_fd_factory =
+      grpc_core::NewGrpcPolledFdFactory((*ev_driver)->work_serializer);
+  (*ev_driver)
+      ->polled_fd_factory->ConfigureAresChannelLocked((*ev_driver)->channel);
+  (*ev_driver)->query_timeout_ms = query_timeout_ms;
+  return GRPC_ERROR_NONE;
+}
+
 static void log_address_sorting_list(const grpc_ares_request* r,
                                      const ServerAddressList& addresses,
                                      const char* input_output_str) {
@@ -139,8 +580,8 @@ void grpc_cares_wrapper_address_sorting_sort(const grpc_ares_request* r,
   if (GRPC_TRACE_FLAG_ENABLED(grpc_trace_cares_address_sorting)) {
     log_address_sorting_list(r, *addresses, "input");
   }
-  address_sorting_sortable* sortables = (address_sorting_sortable*)gpr_zalloc(
-      sizeof(address_sorting_sortable) * addresses->size());
+  address_sorting_sortable* sortables = static_cast<address_sorting_sortable*>(
+      gpr_zalloc(sizeof(address_sorting_sortable) * addresses->size()));
   for (size_t i = 0; i < addresses->size(); ++i) {
     sortables[i].user_data = &(*addresses)[i];
     memcpy(&sortables[i].dest_addr.addr, &(*addresses)[i].address().addr,
@@ -303,20 +744,18 @@ static void on_srv_query_done_locked(void* arg, int status, int /*timeouts*/,
     GRPC_CARES_TRACE_LOG("request:%p ares_parse_srv_reply: %d", r,
                          parse_status);
     if (parse_status == ARES_SUCCESS) {
-      ares_channel* channel =
-          grpc_ares_ev_driver_get_channel_locked(r->ev_driver);
       for (struct ares_srv_reply* srv_it = reply; srv_it != nullptr;
            srv_it = srv_it->next) {
         if (grpc_ares_query_ipv6()) {
           grpc_ares_hostbyname_request* hr = create_hostbyname_request_locked(
               r, srv_it->host, htons(srv_it->port), true /* is_balancer */,
               "AAAA");
-          ares_gethostbyname(*channel, hr->host, AF_INET6,
+          ares_gethostbyname(r->ev_driver->channel, hr->host, AF_INET6,
                              on_hostbyname_done_locked, hr);
         }
         grpc_ares_hostbyname_request* hr = create_hostbyname_request_locked(
             r, srv_it->host, htons(srv_it->port), true /* is_balancer */, "A");
-        ares_gethostbyname(*channel, hr->host, AF_INET,
+        ares_gethostbyname(r->ev_driver->channel, hr->host, AF_INET,
                            on_hostbyname_done_locked, hr);
         grpc_ares_ev_driver_start_locked(r->ev_driver);
       }
@@ -400,7 +839,6 @@ void grpc_dns_lookup_ares_continue_after_check_localhost_and_ip_literals_locked(
     std::shared_ptr<grpc_core::WorkSerializer> work_serializer) {
   grpc_error* error = GRPC_ERROR_NONE;
   grpc_ares_hostbyname_request* hr = nullptr;
-  ares_channel* channel = nullptr;
   /* parse name, splitting it into host and port parts */
   std::string host;
   std::string port;
@@ -423,9 +861,8 @@ void grpc_dns_lookup_ares_continue_after_check_localhost_and_ip_literals_locked(
                                             query_timeout_ms,
                                             std::move(work_serializer), r);
   if (error != GRPC_ERROR_NONE) goto error_cleanup;
-  channel = grpc_ares_ev_driver_get_channel_locked(r->ev_driver);
   // If dns_server is specified, use it.
-  if (dns_server != nullptr) {
+  if (dns_server != nullptr && dns_server[0] != '\0') {
     GRPC_CARES_TRACE_LOG("request:%p Using DNS server %s", r, dns_server);
     grpc_resolved_address addr;
     if (grpc_parse_ipv4_hostport(dns_server, &addr, false /* log_errors */)) {
@@ -450,7 +887,8 @@ void grpc_dns_lookup_ares_continue_after_check_localhost_and_ip_literals_locked(
           GRPC_ERROR_STR_TARGET_ADDRESS, grpc_slice_from_copied_string(name));
       goto error_cleanup;
     }
-    int status = ares_set_servers_ports(*channel, &r->dns_server_addr);
+    int status =
+        ares_set_servers_ports(r->ev_driver->channel, &r->dns_server_addr);
     if (status != ARES_SUCCESS) {
       error = GRPC_ERROR_CREATE_FROM_COPIED_STRING(
           absl::StrCat("C-ares status is not ARES_SUCCESS: ",
@@ -464,25 +902,25 @@ void grpc_dns_lookup_ares_continue_after_check_localhost_and_ip_literals_locked(
     hr = create_hostbyname_request_locked(r, host.c_str(),
                                           grpc_strhtons(port.c_str()),
                                           /*is_balancer=*/false, "AAAA");
-    ares_gethostbyname(*channel, hr->host, AF_INET6, on_hostbyname_done_locked,
-                       hr);
+    ares_gethostbyname(r->ev_driver->channel, hr->host, AF_INET6,
+                       on_hostbyname_done_locked, hr);
   }
   hr = create_hostbyname_request_locked(r, host.c_str(),
                                         grpc_strhtons(port.c_str()),
                                         /*is_balancer=*/false, "A");
-  ares_gethostbyname(*channel, hr->host, AF_INET, on_hostbyname_done_locked,
-                     hr);
+  ares_gethostbyname(r->ev_driver->channel, hr->host, AF_INET,
+                     on_hostbyname_done_locked, hr);
   if (r->balancer_addresses_out != nullptr) {
     /* Query the SRV record */
     std::string service_name = absl::StrCat("_grpclb._tcp.", host);
     GrpcAresQuery* srv_query = new GrpcAresQuery(r, service_name);
-    ares_query(*channel, service_name.c_str(), ns_c_in, ns_t_srv,
+    ares_query(r->ev_driver->channel, service_name.c_str(), ns_c_in, ns_t_srv,
                on_srv_query_done_locked, srv_query);
   }
   if (r->service_config_json_out != nullptr) {
     std::string config_name = absl::StrCat("_grpc_config.", host);
     GrpcAresQuery* txt_query = new GrpcAresQuery(r, config_name);
-    ares_search(*channel, config_name.c_str(), ns_c_in, ns_t_txt,
+    ares_search(r->ev_driver->channel, config_name.c_str(), ns_c_in, ns_t_txt,
                 on_txt_done_locked, txt_query);
   }
   grpc_ares_ev_driver_start_locked(r->ev_driver);
index ddce754..6c29bb6 100644 (file)
@@ -21,6 +21,8 @@
 
 #include <grpc/support/port_platform.h>
 
+#include <ares.h>
+
 #include "src/core/ext/filters/client_channel/server_address.h"
 #include "src/core/lib/iomgr/iomgr.h"
 #include "src/core/lib/iomgr/polling_entity.h"
@@ -93,5 +95,8 @@ bool grpc_ares_query_ipv6();
 void grpc_cares_wrapper_address_sorting_sort(
     const grpc_ares_request* request, grpc_core::ServerAddressList* addresses);
 
+/* Exposed in this header for C-core tests only */
+extern void (*grpc_ares_test_only_inject_config)(ares_channel channel);
+
 #endif /* GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_RESOLVER_DNS_C_ARES_GRPC_ARES_WRAPPER_H \
         */
diff --git a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_fallback.cc b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_fallback.cc
deleted file mode 100644 (file)
index 2049f37..0000000
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- *
- * Copyright 2016-2017 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 GRPC_ARES != 1
-
-#include "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h"
-
-struct grpc_ares_request {
-  char val;
-};
-
-static grpc_ares_request* grpc_dns_lookup_ares_locked_impl(
-    const char* dns_server, const char* name, const char* default_port,
-    grpc_pollset_set* interested_parties, grpc_closure* on_done,
-    std::unique_ptr<grpc_core::ServerAddressList>* addrs,
-    std::unique_ptr<grpc_core::ServerAddressList>* balancer_addrs,
-    char** service_config_json, int query_timeout_ms,
-    std::shared_ptr<grpc_core::WorkSerializer> work_serializer) {
-  return NULL;
-}
-
-grpc_ares_request* (*grpc_dns_lookup_ares_locked)(
-    const char* dns_server, const char* name, const char* default_port,
-    grpc_pollset_set* interested_parties, grpc_closure* on_done,
-    std::unique_ptr<grpc_core::ServerAddressList>* addrs,
-    std::unique_ptr<grpc_core::ServerAddressList>* balancer_addrs,
-    char** service_config_json, int query_timeout_ms,
-    std::shared_ptr<grpc_core::WorkSerializer> work_serializer) =
-    grpc_dns_lookup_ares_locked_impl;
-
-static void grpc_cancel_ares_request_locked_impl(grpc_ares_request* r) {}
-
-void (*grpc_cancel_ares_request_locked)(grpc_ares_request* r) =
-    grpc_cancel_ares_request_locked_impl;
-
-grpc_error* grpc_ares_init(void) { return GRPC_ERROR_NONE; }
-
-void grpc_ares_cleanup(void) {}
-
-static void grpc_resolve_address_ares_impl(const char* name,
-                                           const char* default_port,
-                                           grpc_pollset_set* interested_parties,
-                                           grpc_closure* on_done,
-                                           grpc_resolved_addresses** addrs) {}
-
-void (*grpc_resolve_address_ares)(
-    const char* name, const char* default_port,
-    grpc_pollset_set* interested_parties, grpc_closure* on_done,
-    grpc_resolved_addresses** addrs) = grpc_resolve_address_ares_impl;
-
-#endif /* GRPC_ARES != 1 */
index e17d84f..3e072aa 100644 (file)
@@ -74,7 +74,7 @@ class NativeDnsResolver : public Resolver {
   void OnResolvedLocked(grpc_error* error);
 
   /// name to resolve
-  char* name_to_resolve_ = nullptr;
+  std::string name_to_resolve_;
   /// channel args
   grpc_channel_args* channel_args_ = nullptr;
   /// pollset_set to drive the name resolution process
@@ -107,9 +107,7 @@ NativeDnsResolver::NativeDnsResolver(ResolverArgs args)
               .set_multiplier(GRPC_DNS_RECONNECT_BACKOFF_MULTIPLIER)
               .set_jitter(GRPC_DNS_RECONNECT_JITTER)
               .set_max_backoff(GRPC_DNS_RECONNECT_MAX_BACKOFF_SECONDS * 1000)) {
-  char* path = args.uri->path;
-  if (path[0] == '/') ++path;
-  name_to_resolve_ = gpr_strdup(path);
+  name_to_resolve_ = std::string(absl::StripPrefix(args.uri.path(), "/"));
   channel_args_ = grpc_channel_args_copy(args.args);
   const grpc_arg* arg = grpc_channel_args_find(
       args.args, GRPC_ARG_DNS_MIN_TIME_BETWEEN_RESOLUTIONS_MS);
@@ -124,7 +122,6 @@ NativeDnsResolver::NativeDnsResolver(ResolverArgs args)
 NativeDnsResolver::~NativeDnsResolver() {
   grpc_channel_args_destroy(channel_args_);
   grpc_pollset_set_destroy(interested_parties_);
-  gpr_free(name_to_resolve_);
 }
 
 void NativeDnsResolver::StartLocked() { MaybeStartResolvingLocked(); }
@@ -269,8 +266,8 @@ void NativeDnsResolver::StartResolvingLocked() {
   addresses_ = nullptr;
   GRPC_CLOSURE_INIT(&on_resolved_, NativeDnsResolver::OnResolved, this,
                     grpc_schedule_on_exec_ctx);
-  grpc_resolve_address(name_to_resolve_, kDefaultPort, interested_parties_,
-                       &on_resolved_, &addresses_);
+  grpc_resolve_address(name_to_resolve_.c_str(), kDefaultPort,
+                       interested_parties_, &on_resolved_, &addresses_);
   last_resolution_timestamp_ = grpc_core::ExecCtx::Get()->Now();
 }
 
@@ -280,8 +277,8 @@ void NativeDnsResolver::StartResolvingLocked() {
 
 class NativeDnsResolverFactory : public ResolverFactory {
  public:
-  bool IsValidUri(const grpc_uri* uri) const override {
-    if (GPR_UNLIKELY(0 != strcmp(uri->authority, ""))) {
+  bool IsValidUri(const URI& uri) const override {
+    if (GPR_UNLIKELY(!uri.authority().empty())) {
       gpr_log(GPR_ERROR, "authority based dns uri's not supported");
       return false;
     }
index 005de55..a779cd4 100644 (file)
@@ -339,7 +339,7 @@ grpc_arg FakeResolverResponseGenerator::MakeChannelArg(
     FakeResolverResponseGenerator* generator) {
   grpc_arg arg;
   arg.type = GRPC_ARG_POINTER;
-  arg.key = (char*)GRPC_ARG_FAKE_RESOLVER_RESPONSE_GENERATOR;
+  arg.key = const_cast<char*>(GRPC_ARG_FAKE_RESOLVER_RESPONSE_GENERATOR);
   arg.value.pointer.p = generator;
   arg.value.pointer.vtable = &response_generator_arg_vtable;
   return arg;
@@ -362,7 +362,7 @@ namespace {
 
 class FakeResolverFactory : public ResolverFactory {
  public:
-  bool IsValidUri(const grpc_uri* /*uri*/) const override { return true; }
+  bool IsValidUri(const URI& /*uri*/) const override { return true; }
 
   OrphanablePtr<Resolver> CreateResolver(ResolverArgs args) const override {
     return MakeOrphanable<FakeResolver>(std::move(args));
index 4b1f0a1..dfa2dd9 100644 (file)
@@ -23,6 +23,8 @@
 #include <stdlib.h>
 #include <string.h>
 
+#include "absl/strings/str_split.h"
+
 #include <grpc/support/alloc.h>
 #include <grpc/support/string_util.h>
 
@@ -78,30 +80,20 @@ void SockaddrResolver::StartLocked() {
 // Factory
 //
 
-void DoNothing(void* /*ignored*/) {}
-
-bool ParseUri(const grpc_uri* uri,
-              bool parse(const grpc_uri* uri, grpc_resolved_address* dst),
+bool ParseUri(const URI& uri,
+              bool parse(const URI& uri, grpc_resolved_address* dst),
               ServerAddressList* addresses) {
-  if (0 != strcmp(uri->authority, "")) {
+  if (!uri.authority().empty()) {
     gpr_log(GPR_ERROR, "authority-based URIs not supported by the %s scheme",
-            uri->scheme);
+            uri.scheme().c_str());
     return false;
   }
   // Construct addresses.
-  grpc_slice path_slice =
-      grpc_slice_new(uri->path, strlen(uri->path), DoNothing);
-  grpc_slice_buffer path_parts;
-  grpc_slice_buffer_init(&path_parts);
-  grpc_slice_split(path_slice, ",", &path_parts);
   bool errors_found = false;
-  for (size_t i = 0; i < path_parts.count; i++) {
-    grpc_uri ith_uri = *uri;
-    grpc_core::UniquePtr<char> part_str(
-        grpc_slice_to_c_string(path_parts.slices[i]));
-    ith_uri.path = part_str.get();
+  for (absl::string_view ith_path : absl::StrSplit(uri.path(), ',')) {
+    URI ith_uri(uri.scheme(), "", std::string(ith_path), {}, "");
     grpc_resolved_address addr;
-    if (!parse(&ith_uri, &addr)) {
+    if (!parse(ith_uri, &addr)) {
       errors_found = true;
       break;
     }
@@ -109,14 +101,11 @@ bool ParseUri(const grpc_uri* uri,
       addresses->emplace_back(addr, nullptr /* args */);
     }
   }
-  grpc_slice_buffer_destroy_internal(&path_parts);
-  grpc_slice_unref_internal(path_slice);
   return !errors_found;
 }
 
 OrphanablePtr<Resolver> CreateSockaddrResolver(
-    ResolverArgs args,
-    bool parse(const grpc_uri* uri, grpc_resolved_address* dst)) {
+    ResolverArgs args, bool parse(const URI& uri, grpc_resolved_address* dst)) {
   ServerAddressList addresses;
   if (!ParseUri(args.uri, parse, &addresses)) return nullptr;
   // Instantiate resolver.
@@ -126,7 +115,7 @@ OrphanablePtr<Resolver> CreateSockaddrResolver(
 
 class IPv4ResolverFactory : public ResolverFactory {
  public:
-  bool IsValidUri(const grpc_uri* uri) const override {
+  bool IsValidUri(const URI& uri) const override {
     return ParseUri(uri, grpc_parse_ipv4, nullptr);
   }
 
@@ -139,7 +128,7 @@ class IPv4ResolverFactory : public ResolverFactory {
 
 class IPv6ResolverFactory : public ResolverFactory {
  public:
-  bool IsValidUri(const grpc_uri* uri) const override {
+  bool IsValidUri(const URI& uri) const override {
     return ParseUri(uri, grpc_parse_ipv6, nullptr);
   }
 
@@ -153,7 +142,7 @@ class IPv6ResolverFactory : public ResolverFactory {
 #ifdef GRPC_HAVE_UNIX_SOCKET
 class UnixResolverFactory : public ResolverFactory {
  public:
-  bool IsValidUri(const grpc_uri* uri) const override {
+  bool IsValidUri(const URI& uri) const override {
     return ParseUri(uri, grpc_parse_unix, nullptr);
   }
 
@@ -161,9 +150,8 @@ class UnixResolverFactory : public ResolverFactory {
     return CreateSockaddrResolver(std::move(args), grpc_parse_unix);
   }
 
-  grpc_core::UniquePtr<char> GetDefaultAuthority(
-      grpc_uri* /*uri*/) const override {
-    return grpc_core::UniquePtr<char>(gpr_strdup("localhost"));
+  std::string GetDefaultAuthority(const URI& uri) const override {
+    return "localhost";
   }
 
   const char* scheme() const override { return "unix"; }
@@ -171,7 +159,7 @@ class UnixResolverFactory : public ResolverFactory {
 
 class UnixAbstractResolverFactory : public ResolverFactory {
  public:
-  bool IsValidUri(const grpc_uri* uri) const override {
+  bool IsValidUri(const URI& uri) const override {
     return ParseUri(uri, grpc_parse_unix_abstract, nullptr);
   }
 
@@ -179,9 +167,8 @@ class UnixAbstractResolverFactory : public ResolverFactory {
     return CreateSockaddrResolver(std::move(args), grpc_parse_unix_abstract);
   }
 
-  grpc_core::UniquePtr<char> GetDefaultAuthority(
-      grpc_uri* /*uri*/) const override {
-    return grpc_core::UniquePtr<char>(gpr_strdup("localhost"));
+  std::string GetDefaultAuthority(const URI& /*uri*/) const override {
+    return "localhost";
   }
 
   const char* scheme() const override { return "unix-abstract"; }
index af957f7..e902809 100644 (file)
@@ -48,11 +48,9 @@ class XdsResolver : public Resolver {
   explicit XdsResolver(ResolverArgs args)
       : Resolver(std::move(args.work_serializer),
                  std::move(args.result_handler)),
+        server_name_(absl::StripPrefix(args.uri.path(), "/")),
         args_(grpc_channel_args_copy(args.args)),
         interested_parties_(args.pollset_set) {
-    char* path = args.uri->path;
-    if (path[0] == '/') ++path;
-    server_name_ = path;
     if (GRPC_TRACE_FLAG_ENABLED(grpc_xds_resolver_trace)) {
       gpr_log(GPR_INFO, "[xds_resolver %p] created for server name %s", this,
               server_name_.c_str());
@@ -762,8 +760,8 @@ void XdsResolver::MaybeRemoveUnusedClusters() {
 
 class XdsResolverFactory : public ResolverFactory {
  public:
-  bool IsValidUri(const grpc_uri* uri) const override {
-    if (GPR_UNLIKELY(0 != strcmp(uri->authority, ""))) {
+  bool IsValidUri(const URI& uri) const override {
+    if (GPR_UNLIKELY(!uri.authority().empty())) {
       gpr_log(GPR_ERROR, "URI authority not supported");
       return false;
     }
index d8dd801..7b96746 100644 (file)
@@ -21,6 +21,8 @@
 
 #include <grpc/support/port_platform.h>
 
+#include "absl/strings/strip.h"
+
 #include <grpc/support/string_util.h>
 
 #include "src/core/ext/filters/client_channel/resolver.h"
@@ -33,7 +35,7 @@ namespace grpc_core {
 
 struct ResolverArgs {
   /// The parsed URI to resolve.
-  grpc_uri* uri = nullptr;
+  URI uri;
   /// Channel args to be included in resolver results.
   const grpc_channel_args* args = nullptr;
   /// Used to drive I/O in the name resolution process.
@@ -48,17 +50,15 @@ class ResolverFactory {
  public:
   /// Returns a bool indicating whether the input uri is valid to create a
   /// resolver.
-  virtual bool IsValidUri(const grpc_uri* uri) const = 0;
+  virtual bool IsValidUri(const URI& uri) const = 0;
 
   /// Returns a new resolver instance.
   virtual OrphanablePtr<Resolver> CreateResolver(ResolverArgs args) const = 0;
 
   /// Returns a string representing the default authority to use for this
   /// scheme.
-  virtual grpc_core::UniquePtr<char> GetDefaultAuthority(grpc_uri* uri) const {
-    const char* path = uri->path;
-    if (path[0] == '/') ++path;
-    return grpc_core::UniquePtr<char>(gpr_strdup(path));
+  virtual std::string GetDefaultAuthority(const URI& uri) const {
+    return std::string(absl::StripPrefix(uri.path(), "/"));
   }
 
   /// Returns the URI scheme that this factory implements.
index 6b18205..42b69bb 100644 (file)
@@ -24,6 +24,7 @@
 
 #include "absl/container/inlined_vector.h"
 #include "absl/strings/str_cat.h"
+#include "absl/strings/str_format.h"
 
 #include <grpc/support/alloc.h>
 #include <grpc/support/log.h>
@@ -50,9 +51,9 @@ class RegistryState {
     factories_.push_back(std::move(factory));
   }
 
-  ResolverFactory* LookupResolverFactory(const char* scheme) const {
+  ResolverFactory* LookupResolverFactory(absl::string_view scheme) const {
     for (size_t i = 0; i < factories_.size(); ++i) {
-      if (strcmp(scheme, factories_[i]->scheme()) == 0) {
+      if (scheme == factories_[i]->scheme()) {
         return factories_[i].get();
       }
     }
@@ -65,26 +66,35 @@ class RegistryState {
   // point to the parsed URI.
   // If \a default_prefix_ needs to be prepended, sets \a canonical_target
   // to the canonical target string.
-  ResolverFactory* FindResolverFactory(const char* target, grpc_uri** uri,
+  ResolverFactory* FindResolverFactory(absl::string_view target, URI* uri,
                                        std::string* canonical_target) const {
     GPR_ASSERT(uri != nullptr);
-    *uri = grpc_uri_parse(target, true);
+    absl::StatusOr<URI> tmp_uri = URI::Parse(target);
     ResolverFactory* factory =
-        *uri == nullptr ? nullptr : LookupResolverFactory((*uri)->scheme);
-    if (factory == nullptr) {
-      grpc_uri_destroy(*uri);
-      *canonical_target = absl::StrCat(default_prefix_.get(), target);
-      *uri = grpc_uri_parse(canonical_target->c_str(), true);
-      factory =
-          *uri == nullptr ? nullptr : LookupResolverFactory((*uri)->scheme);
-      if (factory == nullptr) {
-        grpc_uri_destroy(grpc_uri_parse(target, false));
-        grpc_uri_destroy(grpc_uri_parse(canonical_target->c_str(), false));
-        gpr_log(GPR_ERROR, "don't know how to resolve '%s' or '%s'", target,
-                canonical_target->c_str());
-      }
+        tmp_uri.ok() ? LookupResolverFactory(tmp_uri->scheme()) : nullptr;
+    if (factory != nullptr) {
+      *uri = *tmp_uri;
+      return factory;
+    }
+    *canonical_target = absl::StrCat(default_prefix_.get(), target);
+    absl::StatusOr<URI> tmp_uri2 = URI::Parse(*canonical_target);
+    factory =
+        tmp_uri2.ok() ? LookupResolverFactory(tmp_uri2->scheme()) : nullptr;
+    if (factory != nullptr) {
+      *uri = *tmp_uri2;
+      return factory;
     }
-    return factory;
+    if (!tmp_uri.ok() || !tmp_uri2.ok()) {
+      gpr_log(GPR_ERROR, "%s",
+              absl::StrFormat("Error parsing URI(s). '%s':%s; '%s':%s", target,
+                              tmp_uri.status().ToString(), *canonical_target,
+                              tmp_uri2.status().ToString())
+                  .c_str());
+      return nullptr;
+    }
+    gpr_log(GPR_ERROR, "Don't know how to resolve '%s' or '%s'.",
+            std::string(target).c_str(), canonical_target->c_str());
+    return nullptr;
   }
 
  private:
@@ -114,10 +124,9 @@ void ResolverRegistry::Builder::ShutdownRegistry() {
   g_state = nullptr;
 }
 
-void ResolverRegistry::Builder::SetDefaultPrefix(
-    const char* default_resolver_prefix) {
+void ResolverRegistry::Builder::SetDefaultPrefix(const char* default_prefix) {
   InitRegistry();
-  g_state->SetDefaultPrefix(default_resolver_prefix);
+  g_state->SetDefaultPrefix(default_prefix);
 }
 
 void ResolverRegistry::Builder::RegisterResolverFactory(
@@ -135,14 +144,12 @@ ResolverFactory* ResolverRegistry::LookupResolverFactory(const char* scheme) {
   return g_state->LookupResolverFactory(scheme);
 }
 
-bool ResolverRegistry::IsValidTarget(const char* target) {
-  grpc_uri* uri = nullptr;
+bool ResolverRegistry::IsValidTarget(absl::string_view target) {
+  URI uri;
   std::string canonical_target;
   ResolverFactory* factory =
       g_state->FindResolverFactory(target, &uri, &canonical_target);
-  bool result = factory == nullptr ? false : factory->IsValidUri(uri);
-  grpc_uri_destroy(uri);
-  return result;
+  return factory == nullptr ? false : factory->IsValidUri(uri);
 }
 
 OrphanablePtr<Resolver> ResolverRegistry::CreateResolver(
@@ -151,12 +158,10 @@ OrphanablePtr<Resolver> ResolverRegistry::CreateResolver(
     std::shared_ptr<WorkSerializer> work_serializer,
     std::unique_ptr<Resolver::ResultHandler> result_handler) {
   GPR_ASSERT(g_state != nullptr);
-  grpc_uri* uri = nullptr;
   std::string canonical_target;
-  ResolverFactory* factory =
-      g_state->FindResolverFactory(target, &uri, &canonical_target);
   ResolverArgs resolver_args;
-  resolver_args.uri = uri;
+  ResolverFactory* factory = g_state->FindResolverFactory(
+      target, &resolver_args.uri, &canonical_target);
   resolver_args.args = args;
   resolver_args.pollset_set = pollset_set;
   resolver_args.work_serializer = std::move(work_serializer);
@@ -164,30 +169,26 @@ OrphanablePtr<Resolver> ResolverRegistry::CreateResolver(
   OrphanablePtr<Resolver> resolver =
       factory == nullptr ? nullptr
                          : factory->CreateResolver(std::move(resolver_args));
-  grpc_uri_destroy(uri);
   return resolver;
 }
 
-grpc_core::UniquePtr<char> ResolverRegistry::GetDefaultAuthority(
-    const char* target) {
+std::string ResolverRegistry::GetDefaultAuthority(absl::string_view target) {
   GPR_ASSERT(g_state != nullptr);
-  grpc_uri* uri = nullptr;
+  URI uri;
   std::string canonical_target;
   ResolverFactory* factory =
       g_state->FindResolverFactory(target, &uri, &canonical_target);
-  grpc_core::UniquePtr<char> authority =
-      factory == nullptr ? nullptr : factory->GetDefaultAuthority(uri);
-  grpc_uri_destroy(uri);
+  std::string authority =
+      factory == nullptr ? "" : factory->GetDefaultAuthority(uri);
   return authority;
 }
 
 grpc_core::UniquePtr<char> ResolverRegistry::AddDefaultPrefixIfNeeded(
     const char* target) {
   GPR_ASSERT(g_state != nullptr);
-  grpc_uri* uri = nullptr;
+  URI uri;
   std::string canonical_target;
   g_state->FindResolverFactory(target, &uri, &canonical_target);
-  grpc_uri_destroy(uri);
   return grpc_core::UniquePtr<char>(canonical_target.empty()
                                         ? gpr_strdup(target)
                                         : gpr_strdup(canonical_target.c_str()));
index bf34216..f2e5b9c 100644 (file)
@@ -51,7 +51,7 @@ class ResolverRegistry {
   };
 
   /// Checks whether the user input \a target is valid to create a resolver.
-  static bool IsValidTarget(const char* target);
+  static bool IsValidTarget(absl::string_view target);
 
   /// Creates a resolver given \a target.
   /// First tries to parse \a target as a URI. If this succeeds, tries
@@ -73,7 +73,7 @@ class ResolverRegistry {
       std::unique_ptr<Resolver::ResultHandler> result_handler);
 
   /// Returns the default authority to pass from a client for \a target.
-  static grpc_core::UniquePtr<char> GetDefaultAuthority(const char* target);
+  static std::string GetDefaultAuthority(absl::string_view target);
 
   /// Returns \a target with the default prefix prepended, if needed.
   static grpc_core::UniquePtr<char> AddDefaultPrefixIfNeeded(
index c716bc5..500c740 100644 (file)
@@ -248,27 +248,25 @@ grpc_error* ParseRetryThrottling(
   return GRPC_ERROR_CREATE_FROM_VECTOR("retryPolicy", &error_list);
 }
 
-const char* ParseHealthCheckConfig(const Json& field, grpc_error** error) {
+absl::optional<std::string> ParseHealthCheckConfig(const Json& field,
+                                                   grpc_error** error) {
   GPR_DEBUG_ASSERT(error != nullptr && *error == GRPC_ERROR_NONE);
-  const char* service_name = nullptr;
   if (field.type() != Json::Type::OBJECT) {
     *error = GRPC_ERROR_CREATE_FROM_STATIC_STRING(
         "field:healthCheckConfig error:should be of type object");
-    return nullptr;
+    return absl::nullopt;
   }
   std::vector<grpc_error*> error_list;
+  absl::optional<std::string> service_name;
   auto it = field.object_value().find("serviceName");
   if (it != field.object_value().end()) {
     if (it->second.type() != Json::Type::STRING) {
       error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING(
           "field:serviceName error:should be of type string"));
     } else {
-      service_name = it->second.string_value().c_str();
+      service_name = it->second.string_value();
     }
   }
-  if (!error_list.empty()) {
-    return nullptr;
-  }
   *error =
       GRPC_ERROR_CREATE_FROM_VECTOR("field:healthCheckConfig", &error_list);
   return service_name;
@@ -281,12 +279,8 @@ ClientChannelServiceConfigParser::ParseGlobalParams(
     const grpc_channel_args* /*args*/, const Json& json, grpc_error** error) {
   GPR_DEBUG_ASSERT(error != nullptr && *error == GRPC_ERROR_NONE);
   std::vector<grpc_error*> error_list;
-  RefCountedPtr<LoadBalancingPolicy::Config> parsed_lb_config;
-  std::string lb_policy_name;
-  absl::optional<ClientChannelGlobalParsedConfig::RetryThrottling>
-      retry_throttling;
-  const char* health_check_service_name = nullptr;
   // Parse LB config.
+  RefCountedPtr<LoadBalancingPolicy::Config> parsed_lb_config;
   auto it = json.object_value().find("loadBalancingConfig");
   if (it != json.object_value().end()) {
     grpc_error* parse_error = GRPC_ERROR_NONE;
@@ -300,6 +294,7 @@ ClientChannelServiceConfigParser::ParseGlobalParams(
     }
   }
   // Parse deprecated LB policy.
+  std::string lb_policy_name;
   it = json.object_value().find("loadBalancingPolicy");
   if (it != json.object_value().end()) {
     if (it->second.type() != Json::Type::STRING) {
@@ -325,6 +320,8 @@ ClientChannelServiceConfigParser::ParseGlobalParams(
     }
   }
   // Parse retry throttling.
+  absl::optional<ClientChannelGlobalParsedConfig::RetryThrottling>
+      retry_throttling;
   it = json.object_value().find("retryThrottling");
   if (it != json.object_value().end()) {
     ClientChannelGlobalParsedConfig::RetryThrottling data;
@@ -336,6 +333,7 @@ ClientChannelServiceConfigParser::ParseGlobalParams(
     }
   }
   // Parse health check config.
+  absl::optional<std::string> health_check_service_name;
   it = json.object_value().find("healthCheckConfig");
   if (it != json.object_value().end()) {
     grpc_error* parsing_error = GRPC_ERROR_NONE;
@@ -350,7 +348,7 @@ ClientChannelServiceConfigParser::ParseGlobalParams(
   if (*error == GRPC_ERROR_NONE) {
     return absl::make_unique<ClientChannelGlobalParsedConfig>(
         std::move(parsed_lb_config), std::move(lb_policy_name),
-        retry_throttling, health_check_service_name);
+        retry_throttling, std::move(health_check_service_name));
   }
   return nullptr;
 }
index a54209c..cdf89d3 100644 (file)
@@ -49,15 +49,11 @@ class ClientChannelGlobalParsedConfig
       RefCountedPtr<LoadBalancingPolicy::Config> parsed_lb_config,
       std::string parsed_deprecated_lb_policy,
       const absl::optional<RetryThrottling>& retry_throttling,
-      const char* health_check_service_name)
+      absl::optional<std::string> health_check_service_name)
       : parsed_lb_config_(std::move(parsed_lb_config)),
         parsed_deprecated_lb_policy_(std::move(parsed_deprecated_lb_policy)),
         retry_throttling_(retry_throttling),
-        health_check_service_name_(health_check_service_name) {}
-
-  absl::optional<RetryThrottling> retry_throttling() const {
-    return retry_throttling_;
-  }
+        health_check_service_name_(std::move(health_check_service_name)) {}
 
   RefCountedPtr<LoadBalancingPolicy::Config> parsed_lb_config() const {
     return parsed_lb_config_;
@@ -67,7 +63,11 @@ class ClientChannelGlobalParsedConfig
     return parsed_deprecated_lb_policy_;
   }
 
-  const char* health_check_service_name() const {
+  absl::optional<RetryThrottling> retry_throttling() const {
+    return retry_throttling_;
+  }
+
+  const absl::optional<std::string>& health_check_service_name() const {
     return health_check_service_name_;
   }
 
@@ -75,7 +75,7 @@ class ClientChannelGlobalParsedConfig
   RefCountedPtr<LoadBalancingPolicy::Config> parsed_lb_config_;
   std::string parsed_deprecated_lb_policy_;
   absl::optional<RetryThrottling> retry_throttling_;
-  const char* health_check_service_name_;
+  absl::optional<std::string> health_check_service_name_;
 };
 
 class ClientChannelMethodParsedConfig
diff --git a/src/core/ext/filters/client_channel/resolving_lb_policy.cc b/src/core/ext/filters/client_channel/resolving_lb_policy.cc
deleted file mode 100644 (file)
index 889c20c..0000000
+++ /dev/null
@@ -1,355 +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 "src/core/ext/filters/client_channel/resolving_lb_policy.h"
-
-#include <inttypes.h>
-#include <limits.h>
-#include <stdbool.h>
-#include <stdio.h>
-#include <string.h>
-
-#include "absl/strings/str_cat.h"
-#include "absl/strings/str_join.h"
-
-#include <grpc/support/alloc.h>
-#include <grpc/support/log.h>
-#include <grpc/support/string_util.h>
-#include <grpc/support/sync.h>
-
-#include "src/core/ext/filters/client_channel/backup_poller.h"
-#include "src/core/ext/filters/client_channel/http_connect_handshaker.h"
-#include "src/core/ext/filters/client_channel/lb_policy/child_policy_handler.h"
-#include "src/core/ext/filters/client_channel/lb_policy_registry.h"
-#include "src/core/ext/filters/client_channel/proxy_mapper_registry.h"
-#include "src/core/ext/filters/client_channel/resolver_registry.h"
-#include "src/core/ext/filters/client_channel/retry_throttle.h"
-#include "src/core/ext/filters/client_channel/server_address.h"
-#include "src/core/ext/filters/client_channel/service_config.h"
-#include "src/core/ext/filters/client_channel/subchannel.h"
-#include "src/core/ext/filters/deadline/deadline_filter.h"
-#include "src/core/lib/backoff/backoff.h"
-#include "src/core/lib/channel/channel_args.h"
-#include "src/core/lib/channel/connected_channel.h"
-#include "src/core/lib/channel/status_util.h"
-#include "src/core/lib/gpr/string.h"
-#include "src/core/lib/gprpp/manual_constructor.h"
-#include "src/core/lib/gprpp/sync.h"
-#include "src/core/lib/iomgr/iomgr.h"
-#include "src/core/lib/iomgr/polling_entity.h"
-#include "src/core/lib/profiling/timers.h"
-#include "src/core/lib/slice/slice_internal.h"
-#include "src/core/lib/slice/slice_string_helpers.h"
-#include "src/core/lib/surface/channel.h"
-#include "src/core/lib/transport/connectivity_state.h"
-#include "src/core/lib/transport/error_utils.h"
-#include "src/core/lib/transport/metadata.h"
-#include "src/core/lib/transport/metadata_batch.h"
-#include "src/core/lib/transport/static_metadata.h"
-#include "src/core/lib/transport/status_metadata.h"
-
-namespace grpc_core {
-
-//
-// ResolvingLoadBalancingPolicy::ResolverResultHandler
-//
-
-class ResolvingLoadBalancingPolicy::ResolverResultHandler
-    : public Resolver::ResultHandler {
- public:
-  explicit ResolverResultHandler(
-      RefCountedPtr<ResolvingLoadBalancingPolicy> parent)
-      : parent_(std::move(parent)) {}
-
-  ~ResolverResultHandler() override {
-    if (GRPC_TRACE_FLAG_ENABLED(*(parent_->tracer_))) {
-      gpr_log(GPR_INFO, "resolving_lb=%p: resolver shutdown complete",
-              parent_.get());
-    }
-  }
-
-  void ReturnResult(Resolver::Result result) override {
-    parent_->OnResolverResultChangedLocked(std::move(result));
-  }
-
-  void ReturnError(grpc_error* error) override {
-    parent_->OnResolverError(error);
-  }
-
- private:
-  RefCountedPtr<ResolvingLoadBalancingPolicy> parent_;
-};
-
-//
-// ResolvingLoadBalancingPolicy::ResolvingControlHelper
-//
-
-class ResolvingLoadBalancingPolicy::ResolvingControlHelper
-    : public LoadBalancingPolicy::ChannelControlHelper {
- public:
-  explicit ResolvingControlHelper(
-      RefCountedPtr<ResolvingLoadBalancingPolicy> parent)
-      : parent_(std::move(parent)) {}
-
-  RefCountedPtr<SubchannelInterface> CreateSubchannel(
-      ServerAddress address, const grpc_channel_args& args) override {
-    if (parent_->resolver_ == nullptr) return nullptr;  // Shutting down.
-    return parent_->channel_control_helper()->CreateSubchannel(
-        std::move(address), args);
-  }
-
-  void UpdateState(grpc_connectivity_state state, const absl::Status& status,
-                   std::unique_ptr<SubchannelPicker> picker) override {
-    if (parent_->resolver_ == nullptr) return;  // Shutting down.
-    parent_->channel_control_helper()->UpdateState(state, status,
-                                                   std::move(picker));
-  }
-
-  void RequestReresolution() override {
-    if (parent_->resolver_ == nullptr) return;  // Shutting down.
-    if (GRPC_TRACE_FLAG_ENABLED(*(parent_->tracer_))) {
-      gpr_log(GPR_INFO, "resolving_lb=%p: started name re-resolving",
-              parent_.get());
-    }
-    parent_->resolver_->RequestReresolutionLocked();
-  }
-
-  void AddTraceEvent(TraceSeverity severity,
-                     absl::string_view message) override {
-    if (parent_->resolver_ == nullptr) return;  // Shutting down.
-    parent_->channel_control_helper()->AddTraceEvent(severity, message);
-  }
-
- private:
-  RefCountedPtr<ResolvingLoadBalancingPolicy> parent_;
-};
-
-//
-// ResolvingLoadBalancingPolicy
-//
-
-ResolvingLoadBalancingPolicy::ResolvingLoadBalancingPolicy(
-    Args args, TraceFlag* tracer, grpc_core::UniquePtr<char> target_uri,
-    ChannelConfigHelper* helper)
-    : LoadBalancingPolicy(std::move(args)),
-      tracer_(tracer),
-      target_uri_(std::move(target_uri)),
-      helper_(helper) {
-  GPR_ASSERT(helper_ != nullptr);
-  resolver_ = ResolverRegistry::CreateResolver(
-      target_uri_.get(), args.args, interested_parties(), work_serializer(),
-      absl::make_unique<ResolverResultHandler>(Ref()));
-  // Since the validity of args has been checked when create the channel,
-  // CreateResolver() must return a non-null result.
-  GPR_ASSERT(resolver_ != nullptr);
-  if (GRPC_TRACE_FLAG_ENABLED(*tracer_)) {
-    gpr_log(GPR_INFO, "resolving_lb=%p: starting name resolution", this);
-  }
-  channel_control_helper()->UpdateState(GRPC_CHANNEL_CONNECTING, absl::Status(),
-                                        absl::make_unique<QueuePicker>(Ref()));
-  resolver_->StartLocked();
-}
-
-ResolvingLoadBalancingPolicy::~ResolvingLoadBalancingPolicy() {
-  GPR_ASSERT(resolver_ == nullptr);
-  GPR_ASSERT(lb_policy_ == nullptr);
-}
-
-void ResolvingLoadBalancingPolicy::ShutdownLocked() {
-  if (resolver_ != nullptr) {
-    if (GRPC_TRACE_FLAG_ENABLED(*tracer_)) {
-      gpr_log(GPR_INFO, "resolving_lb=%p: shutting down resolver=%p", this,
-              resolver_.get());
-    }
-    resolver_.reset();
-    if (lb_policy_ != nullptr) {
-      if (GRPC_TRACE_FLAG_ENABLED(*tracer_)) {
-        gpr_log(GPR_INFO, "resolving_lb=%p: shutting down lb_policy=%p", this,
-                lb_policy_.get());
-      }
-      grpc_pollset_set_del_pollset_set(lb_policy_->interested_parties(),
-                                       interested_parties());
-      lb_policy_.reset();
-    }
-  }
-}
-
-void ResolvingLoadBalancingPolicy::ExitIdleLocked() {
-  if (lb_policy_ != nullptr) lb_policy_->ExitIdleLocked();
-}
-
-void ResolvingLoadBalancingPolicy::ResetBackoffLocked() {
-  if (resolver_ != nullptr) {
-    resolver_->ResetBackoffLocked();
-    resolver_->RequestReresolutionLocked();
-  }
-  if (lb_policy_ != nullptr) lb_policy_->ResetBackoffLocked();
-}
-
-void ResolvingLoadBalancingPolicy::OnResolverError(grpc_error* error) {
-  if (resolver_ == nullptr) {
-    GRPC_ERROR_UNREF(error);
-    return;
-  }
-  if (GRPC_TRACE_FLAG_ENABLED(*tracer_)) {
-    gpr_log(GPR_INFO, "resolving_lb=%p: resolver transient failure: %s", this,
-            grpc_error_string(error));
-  }
-  // If we already have an LB policy from a previous resolution
-  // result, then we continue to let it set the connectivity state.
-  // Otherwise, we go into TRANSIENT_FAILURE.
-  if (lb_policy_ == nullptr) {
-    grpc_error* state_error = GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING(
-        "Resolver transient failure", &error, 1);
-    helper_->ResolverTransientFailure(GRPC_ERROR_REF(state_error));
-    channel_control_helper()->UpdateState(
-        GRPC_CHANNEL_TRANSIENT_FAILURE, grpc_error_to_absl_status(state_error),
-        absl::make_unique<TransientFailurePicker>(state_error));
-  }
-  GRPC_ERROR_UNREF(error);
-}
-
-void ResolvingLoadBalancingPolicy::CreateOrUpdateLbPolicyLocked(
-    RefCountedPtr<LoadBalancingPolicy::Config> lb_policy_config,
-    Resolver::Result result) {
-  // Construct update.
-  UpdateArgs update_args;
-  update_args.addresses = std::move(result.addresses);
-  update_args.config = std::move(lb_policy_config);
-  // Remove the config selector from channel args so that we're not holding
-  // unnecessary refs that cause it to be destroyed somewhere other than in the
-  // WorkSerializer.
-  const char* arg_name = GRPC_ARG_CONFIG_SELECTOR;
-  update_args.args =
-      grpc_channel_args_copy_and_remove(result.args, &arg_name, 1);
-  // Create policy if needed.
-  if (lb_policy_ == nullptr) {
-    lb_policy_ = CreateLbPolicyLocked(*update_args.args);
-  }
-  // Update the policy.
-  if (GRPC_TRACE_FLAG_ENABLED(*tracer_)) {
-    gpr_log(GPR_INFO, "resolving_lb=%p: Updating child policy %p", this,
-            lb_policy_.get());
-  }
-  lb_policy_->UpdateLocked(std::move(update_args));
-}
-
-// Creates a new LB policy.
-OrphanablePtr<LoadBalancingPolicy>
-ResolvingLoadBalancingPolicy::CreateLbPolicyLocked(
-    const grpc_channel_args& args) {
-  LoadBalancingPolicy::Args lb_policy_args;
-  lb_policy_args.work_serializer = work_serializer();
-  lb_policy_args.channel_control_helper =
-      absl::make_unique<ResolvingControlHelper>(Ref());
-  lb_policy_args.args = &args;
-  OrphanablePtr<LoadBalancingPolicy> lb_policy =
-      MakeOrphanable<ChildPolicyHandler>(std::move(lb_policy_args), tracer_);
-  if (GRPC_TRACE_FLAG_ENABLED(*tracer_)) {
-    gpr_log(GPR_INFO, "resolving_lb=%p: created new LB policy %p", this,
-            lb_policy.get());
-  }
-  grpc_pollset_set_add_pollset_set(lb_policy->interested_parties(),
-                                   interested_parties());
-  return lb_policy;
-}
-
-void ResolvingLoadBalancingPolicy::MaybeAddTraceMessagesForAddressChangesLocked(
-    bool resolution_contains_addresses, TraceStringVector* trace_strings) {
-  if (!resolution_contains_addresses &&
-      previous_resolution_contained_addresses_) {
-    trace_strings->push_back("Address list became empty");
-  } else if (resolution_contains_addresses &&
-             !previous_resolution_contained_addresses_) {
-    trace_strings->push_back("Address list became non-empty");
-  }
-  previous_resolution_contained_addresses_ = resolution_contains_addresses;
-}
-
-void ResolvingLoadBalancingPolicy::ConcatenateAndAddChannelTraceLocked(
-    const TraceStringVector& trace_strings) const {
-  if (!trace_strings.empty()) {
-    std::string message =
-        absl::StrCat("Resolution event: ", absl::StrJoin(trace_strings, ", "));
-    channel_control_helper()->AddTraceEvent(ChannelControlHelper::TRACE_INFO,
-                                            message);
-  }
-}
-
-void ResolvingLoadBalancingPolicy::OnResolverResultChangedLocked(
-    Resolver::Result result) {
-  // Handle race conditions.
-  if (resolver_ == nullptr) return;
-  if (GRPC_TRACE_FLAG_ENABLED(*tracer_)) {
-    gpr_log(GPR_INFO, "resolving_lb=%p: got resolver result", this);
-  }
-  // We only want to trace the address resolution in the follow cases:
-  // (a) Address resolution resulted in service config change.
-  // (b) Address resolution that causes number of backends to go from
-  //     zero to non-zero.
-  // (c) Address resolution that causes number of backends to go from
-  //     non-zero to zero.
-  // (d) Address resolution that causes a new LB policy to be created.
-  //
-  // We track a list of strings to eventually be concatenated and traced.
-  TraceStringVector trace_strings;
-  MaybeAddTraceMessagesForAddressChangesLocked(!result.addresses.empty(),
-                                               &trace_strings);
-  // The result of grpc_error_string() is owned by the error itself.
-  // We're storing that string in trace_strings, so we need to make sure
-  // that the error lives until we're done with the string.
-  grpc_error* service_config_error =
-      GRPC_ERROR_REF(result.service_config_error);
-  if (service_config_error != GRPC_ERROR_NONE) {
-    trace_strings.push_back(grpc_error_string(service_config_error));
-  }
-  // Choose the service config.
-  ChannelConfigHelper::ChooseServiceConfigResult service_config_result;
-  if (helper_ != nullptr) {
-    service_config_result = helper_->ChooseServiceConfig(result);
-  } else {
-    service_config_result.lb_policy_config = child_lb_config_;
-  }
-  if (service_config_result.no_valid_service_config) {
-    // We received an invalid service config and we don't have a
-    // previous service config to fall back to.
-    OnResolverError(GRPC_ERROR_REF(service_config_error));
-    trace_strings.push_back("no valid service config");
-  } else {
-    // Create or update LB policy, as needed.
-    CreateOrUpdateLbPolicyLocked(
-        std::move(service_config_result.lb_policy_config), std::move(result));
-    if (service_config_result.service_config_changed) {
-      // Tell channel to start using new service config for calls.
-      // This needs to happen after the LB policy has been updated, since
-      // the ConfigSelector may need the LB policy to know about new
-      // destinations before it can send RPCs to those destinations.
-      if (helper_ != nullptr) helper_->StartUsingServiceConfigForCalls();
-      // TODO(ncteisen): might be worth somehow including a snippet of the
-      // config in the trace, at the risk of bloating the trace logs.
-      trace_strings.push_back("Service config changed");
-    }
-  }
-  // Add channel trace event.
-  ConcatenateAndAddChannelTraceLocked(trace_strings);
-  GRPC_ERROR_UNREF(service_config_error);
-}
-
-}  // namespace grpc_core
diff --git a/src/core/ext/filters/client_channel/resolving_lb_policy.h b/src/core/ext/filters/client_channel/resolving_lb_policy.h
deleted file mode 100644 (file)
index dd592be..0000000
+++ /dev/null
@@ -1,138 +0,0 @@
-/*
- *
- * Copyright 2018 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_CORE_EXT_FILTERS_CLIENT_CHANNEL_RESOLVING_LB_POLICY_H
-#define GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_RESOLVING_LB_POLICY_H
-
-#include <grpc/support/port_platform.h>
-
-#include "absl/container/inlined_vector.h"
-
-#include "src/core/ext/filters/client_channel/config_selector.h"
-#include "src/core/ext/filters/client_channel/lb_policy.h"
-#include "src/core/ext/filters/client_channel/lb_policy_factory.h"
-#include "src/core/ext/filters/client_channel/resolver.h"
-#include "src/core/lib/channel/channel_args.h"
-#include "src/core/lib/channel/channel_stack.h"
-#include "src/core/lib/debug/trace.h"
-#include "src/core/lib/gprpp/orphanable.h"
-#include "src/core/lib/iomgr/call_combiner.h"
-#include "src/core/lib/iomgr/closure.h"
-#include "src/core/lib/iomgr/polling_entity.h"
-#include "src/core/lib/iomgr/pollset_set.h"
-#include "src/core/lib/transport/connectivity_state.h"
-#include "src/core/lib/transport/metadata_batch.h"
-
-namespace grpc_core {
-
-// An LB policy that wraps a resolver and a child LB policy to make use
-// of the addresses returned by the resolver.
-//
-// When used in the client_channel code, the resolver will attempt to
-// fetch the service config, and the child LB policy name and config
-// will be determined based on the service config.
-//
-// When used in an LB policy implementation that needs to do another
-// round of resolution before creating a child policy, the resolver does
-// not fetch the service config, and the caller must pre-determine the
-// child LB policy and config to use.
-class ResolvingLoadBalancingPolicy : public LoadBalancingPolicy {
- public:
-  class ChannelConfigHelper {
-   public:
-    struct ChooseServiceConfigResult {
-      // Set to true if the service config has changed since the last result.
-      bool service_config_changed = false;
-      // Set to true if we don't have a valid service config to use.
-      // This tells the ResolvingLoadBalancingPolicy to put the channel
-      // into TRANSIENT_FAILURE.
-      bool no_valid_service_config = false;
-      // The LB policy config to use.
-      RefCountedPtr<LoadBalancingPolicy::Config> lb_policy_config;
-    };
-
-    virtual ~ChannelConfigHelper() = default;
-
-    // Chooses the service config for the channel.
-    virtual ChooseServiceConfigResult ChooseServiceConfig(
-        const Resolver::Result& result) = 0;
-
-    // Starts using the service config for calls.
-    virtual void StartUsingServiceConfigForCalls() = 0;
-
-    // Indicates a resolver transient failure.
-    virtual void ResolverTransientFailure(grpc_error* error) = 0;
-  };
-
-  ResolvingLoadBalancingPolicy(Args args, TraceFlag* tracer,
-                               grpc_core::UniquePtr<char> target_uri,
-                               ChannelConfigHelper* helper);
-
-  const char* name() const override { return "resolving_lb"; }
-
-  // No-op -- should never get updates from the channel.
-  // TODO(roth): Need to support updating child LB policy's config for xds
-  // use case.
-  void UpdateLocked(UpdateArgs /*args*/) override {}
-
-  void ExitIdleLocked() override;
-
-  void ResetBackoffLocked() override;
-
- private:
-  using TraceStringVector = absl::InlinedVector<const char*, 3>;
-
-  class ResolverResultHandler;
-  class ResolvingControlHelper;
-
-  ~ResolvingLoadBalancingPolicy() override;
-
-  void ShutdownLocked() override;
-
-  void OnResolverError(grpc_error* error);
-  void CreateOrUpdateLbPolicyLocked(
-      RefCountedPtr<LoadBalancingPolicy::Config> lb_policy_config,
-      Resolver::Result result);
-  OrphanablePtr<LoadBalancingPolicy> CreateLbPolicyLocked(
-      const grpc_channel_args& args);
-  void MaybeAddTraceMessagesForAddressChangesLocked(
-      bool resolution_contains_addresses, TraceStringVector* trace_strings);
-  void ConcatenateAndAddChannelTraceLocked(
-      const TraceStringVector& trace_strings) const;
-  void OnResolverResultChangedLocked(Resolver::Result result);
-
-  // Passed in from caller at construction time.
-  TraceFlag* tracer_;
-  grpc_core::UniquePtr<char> target_uri_;
-  ChannelConfigHelper* helper_;
-
-  // Resolver and associated state.
-  OrphanablePtr<Resolver> resolver_;
-  bool previous_resolution_contained_addresses_ = false;
-
-  // Determined by resolver results.
-  grpc_core::UniquePtr<char> child_policy_name_;
-  RefCountedPtr<LoadBalancingPolicy::Config> child_lb_config_;
-
-  // Child LB policy.
-  OrphanablePtr<LoadBalancingPolicy> lb_policy_;
-};
-
-}  // namespace grpc_core
-
-#endif /* GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_RESOLVING_LB_POLICY_H */
index 65df803..03c7a67 100644 (file)
@@ -23,6 +23,8 @@
 #include <limits.h>
 #include <string.h>
 
+#include <string>
+
 #include <grpc/support/alloc.h>
 #include <grpc/support/atm.h>
 #include <grpc/support/string_util.h>
@@ -164,20 +166,20 @@ void ServerRetryThrottleMap::Shutdown() {
 }
 
 RefCountedPtr<ServerRetryThrottleData> ServerRetryThrottleMap::GetDataForServer(
-    const char* server_name, intptr_t max_milli_tokens,
+    const std::string& server_name, intptr_t max_milli_tokens,
     intptr_t milli_token_ratio) {
   RefCountedPtr<ServerRetryThrottleData> result;
   gpr_mu_lock(&g_mu);
   ServerRetryThrottleData* throttle_data =
       static_cast<ServerRetryThrottleData*>(
-          grpc_avl_get(g_avl, const_cast<char*>(server_name), nullptr));
+          grpc_avl_get(g_avl, const_cast<char*>(server_name.c_str()), nullptr));
   if (throttle_data == nullptr ||
       throttle_data->max_milli_tokens() != max_milli_tokens ||
       throttle_data->milli_token_ratio() != milli_token_ratio) {
     // Entry not found, or found with old parameters.  Create a new one.
     result = MakeRefCounted<ServerRetryThrottleData>(
         max_milli_tokens, milli_token_ratio, throttle_data);
-    g_avl = grpc_avl_add(g_avl, gpr_strdup(server_name),
+    g_avl = grpc_avl_add(g_avl, gpr_strdup(server_name.c_str()),
                          result->Ref().release(), nullptr);
   } else {
     // Entry found.  Return a new ref to it.
index e40363f..17cc7a0 100644 (file)
@@ -21,6 +21,8 @@
 
 #include <grpc/support/port_platform.h>
 
+#include <string>
+
 #include "src/core/lib/gprpp/memory.h"
 #include "src/core/lib/gprpp/ref_counted.h"
 
@@ -67,7 +69,7 @@ class ServerRetryThrottleMap {
   /// Returns the failure data for \a server_name, creating a new entry if
   /// needed.
   static RefCountedPtr<ServerRetryThrottleData> GetDataForServer(
-      const char* server_name, intptr_t max_milli_tokens,
+      const std::string& server_name, intptr_t max_milli_tokens,
       intptr_t milli_token_ratio);
 };
 
index b6b5b73..544683a 100644 (file)
 
 #include <grpc/support/port_platform.h>
 
+#include <map>
+
+#include "absl/strings/string_view.h"
+
 #include "src/core/ext/filters/client_channel/service_config.h"
 #include "src/core/ext/filters/client_channel/service_config_parser.h"
 #include "src/core/lib/channel/context.h"
@@ -35,13 +39,22 @@ class ServiceConfigCallData {
   ServiceConfigCallData(
       RefCountedPtr<ServiceConfig> service_config,
       const ServiceConfigParser::ParsedConfigVector* method_configs,
+      std::map<const char*, absl::string_view> call_attributes,
       grpc_call_context_element* call_context)
       : service_config_(std::move(service_config)),
-        method_configs_(method_configs) {
+        method_configs_(method_configs),
+        call_attributes_(std::move(call_attributes)) {
     call_context[GRPC_CONTEXT_SERVICE_CONFIG_CALL_DATA].value = this;
     call_context[GRPC_CONTEXT_SERVICE_CONFIG_CALL_DATA].destroy = Destroy;
   }
 
+  ServiceConfigCallData(
+      RefCountedPtr<ServiceConfig> service_config,
+      const ServiceConfigParser::ParsedConfigVector* method_configs,
+      grpc_call_context_element* call_context)
+      : ServiceConfigCallData(std::move(service_config), method_configs, {},
+                              call_context) {}
+
   ServiceConfig* service_config() { return service_config_.get(); }
 
   ServiceConfigParser::ParsedConfig* GetMethodParsedConfig(size_t index) const {
@@ -53,6 +66,10 @@ class ServiceConfigCallData {
     return service_config_->GetGlobalParsedConfig(index);
   }
 
+  const std::map<const char*, absl::string_view>& call_attributes() const {
+    return call_attributes_;
+  }
+
  private:
   static void Destroy(void* ptr) {
     ServiceConfigCallData* self = static_cast<ServiceConfigCallData*>(ptr);
@@ -61,6 +78,7 @@ class ServiceConfigCallData {
 
   RefCountedPtr<ServiceConfig> service_config_;
   const ServiceConfigParser::ParsedConfigVector* method_configs_ = nullptr;
+  std::map<const char*, absl::string_view> call_attributes_;
 };
 
 }  // namespace grpc_core
index d5c1760..dbac59a 100644 (file)
@@ -121,18 +121,9 @@ void ConnectedSubchannel::Ping(grpc_closure* on_initiate,
   elem->filter->start_transport_op(elem, op);
 }
 
-size_t ConnectedSubchannel::GetInitialCallSizeEstimate(
-    size_t parent_data_size) const {
-  size_t allocation_size =
-      GPR_ROUND_UP_TO_ALIGNMENT_SIZE(sizeof(SubchannelCall));
-  if (parent_data_size > 0) {
-    allocation_size +=
-        GPR_ROUND_UP_TO_ALIGNMENT_SIZE(channel_stack_->call_stack_size) +
-        parent_data_size;
-  } else {
-    allocation_size += channel_stack_->call_stack_size;
-  }
-  return allocation_size;
+size_t ConnectedSubchannel::GetInitialCallSizeEstimate() const {
+  return GPR_ROUND_UP_TO_ALIGNMENT_SIZE(sizeof(SubchannelCall)) +
+         channel_stack_->call_stack_size;
 }
 
 //
@@ -142,8 +133,7 @@ size_t ConnectedSubchannel::GetInitialCallSizeEstimate(
 RefCountedPtr<SubchannelCall> SubchannelCall::Create(Args args,
                                                      grpc_error** error) {
   const size_t allocation_size =
-      args.connected_subchannel->GetInitialCallSizeEstimate(
-          args.parent_data_size);
+      args.connected_subchannel->GetInitialCallSizeEstimate();
   Arena* arena = args.arena;
   return RefCountedPtr<SubchannelCall>(new (
       arena->Alloc(allocation_size)) SubchannelCall(std::move(args), error));
@@ -187,12 +177,6 @@ void SubchannelCall::StartTransportStreamOpBatch(
   top_elem->filter->start_transport_stream_op_batch(top_elem, batch);
 }
 
-void* SubchannelCall::GetParentData() {
-  grpc_channel_stack* chanstk = connected_subchannel_->channel_stack();
-  return (char*)this + GPR_ROUND_UP_TO_ALIGNMENT_SIZE(sizeof(SubchannelCall)) +
-         GPR_ROUND_UP_TO_ALIGNMENT_SIZE(chanstk->call_stack_size);
-}
-
 grpc_call_stack* SubchannelCall::GetCallStack() {
   return SUBCHANNEL_CALL_TO_CALL_STACK(this);
 }
@@ -440,8 +424,7 @@ void Subchannel::ConnectivityStateWatcherList::NotifyLocked(
 class Subchannel::HealthWatcherMap::HealthWatcher
     : public AsyncConnectivityStateWatcherInterface {
  public:
-  HealthWatcher(Subchannel* c,
-                grpc_core::UniquePtr<char> health_check_service_name,
+  HealthWatcher(Subchannel* c, std::string health_check_service_name,
                 grpc_connectivity_state subchannel_state)
       : subchannel_(c),
         health_check_service_name_(std::move(health_check_service_name)),
@@ -456,8 +439,8 @@ class Subchannel::HealthWatcherMap::HealthWatcher
     GRPC_SUBCHANNEL_WEAK_UNREF(subchannel_, "health_watcher");
   }
 
-  const char* health_check_service_name() const {
-    return health_check_service_name_.get();
+  const std::string& health_check_service_name() const {
+    return health_check_service_name_;
   }
 
   grpc_connectivity_state state() const { return state_; }
@@ -520,12 +503,12 @@ class Subchannel::HealthWatcherMap::HealthWatcher
   void StartHealthCheckingLocked() {
     GPR_ASSERT(health_check_client_ == nullptr);
     health_check_client_ = MakeOrphanable<HealthCheckClient>(
-        health_check_service_name_.get(), subchannel_->connected_subchannel_,
+        health_check_service_name_, subchannel_->connected_subchannel_,
         subchannel_->pollset_set_, subchannel_->channelz_node_, Ref());
   }
 
   Subchannel* subchannel_;
-  grpc_core::UniquePtr<char> health_check_service_name_;
+  std::string health_check_service_name_;
   OrphanablePtr<HealthCheckClient> health_check_client_;
   grpc_connectivity_state state_;
   absl::Status status_;
@@ -538,18 +521,17 @@ class Subchannel::HealthWatcherMap::HealthWatcher
 
 void Subchannel::HealthWatcherMap::AddWatcherLocked(
     Subchannel* subchannel, grpc_connectivity_state initial_state,
-    grpc_core::UniquePtr<char> health_check_service_name,
+    const std::string& health_check_service_name,
     RefCountedPtr<ConnectivityStateWatcherInterface> watcher) {
   // If the health check service name is not already present in the map,
   // add it.
-  auto it = map_.find(health_check_service_name.get());
+  auto it = map_.find(health_check_service_name);
   HealthWatcher* health_watcher;
   if (it == map_.end()) {
-    const char* key = health_check_service_name.get();
     auto w = MakeOrphanable<HealthWatcher>(
-        subchannel, std::move(health_check_service_name), subchannel->state_);
+        subchannel, health_check_service_name, subchannel->state_);
     health_watcher = w.get();
-    map_[key] = std::move(w);
+    map_.emplace(health_check_service_name, std::move(w));
   } else {
     health_watcher = it->second.get();
   }
@@ -558,7 +540,7 @@ void Subchannel::HealthWatcherMap::AddWatcherLocked(
 }
 
 void Subchannel::HealthWatcherMap::RemoveWatcherLocked(
-    const char* health_check_service_name,
+    const std::string& health_check_service_name,
     ConnectivityStateWatcherInterface* watcher) {
   auto it = map_.find(health_check_service_name);
   GPR_ASSERT(it != map_.end());
@@ -577,7 +559,7 @@ void Subchannel::HealthWatcherMap::NotifyLocked(grpc_connectivity_state state,
 
 grpc_connectivity_state
 Subchannel::HealthWatcherMap::CheckConnectivityStateLocked(
-    Subchannel* subchannel, const char* health_check_service_name) {
+    Subchannel* subchannel, const std::string& health_check_service_name) {
   auto it = map_.find(health_check_service_name);
   if (it == map_.end()) {
     // If the health check service name is not found in the map, we're
@@ -702,7 +684,7 @@ Subchannel::Subchannel(SubchannelKey* key,
   const grpc_integer_options options = {
       GRPC_MAX_CHANNEL_TRACE_EVENT_MEMORY_PER_NODE_DEFAULT, 0, INT_MAX};
   size_t channel_tracer_max_memory =
-      (size_t)grpc_channel_arg_get_integer(arg, options);
+      static_cast<size_t>(grpc_channel_arg_get_integer(arg, options));
   if (channelz_enabled) {
     channelz_node_ = MakeRefCounted<channelz::SubchannelNode>(
         GetTargetAddress(), channel_tracer_max_memory);
@@ -840,15 +822,15 @@ channelz::SubchannelNode* Subchannel::channelz_node() {
 }
 
 grpc_connectivity_state Subchannel::CheckConnectivityState(
-    const char* health_check_service_name,
+    const absl::optional<std::string>& health_check_service_name,
     RefCountedPtr<ConnectedSubchannel>* connected_subchannel) {
   MutexLock lock(&mu_);
   grpc_connectivity_state state;
-  if (health_check_service_name == nullptr) {
+  if (!health_check_service_name.has_value()) {
     state = state_;
   } else {
     state = health_watcher_map_.CheckConnectivityStateLocked(
-        this, health_check_service_name);
+        this, *health_check_service_name);
   }
   if (connected_subchannel != nullptr && state == GRPC_CHANNEL_READY) {
     *connected_subchannel = connected_subchannel_;
@@ -858,37 +840,37 @@ grpc_connectivity_state Subchannel::CheckConnectivityState(
 
 void Subchannel::WatchConnectivityState(
     grpc_connectivity_state initial_state,
-    grpc_core::UniquePtr<char> health_check_service_name,
+    const absl::optional<std::string>& health_check_service_name,
     RefCountedPtr<ConnectivityStateWatcherInterface> watcher) {
   MutexLock lock(&mu_);
   grpc_pollset_set* interested_parties = watcher->interested_parties();
   if (interested_parties != nullptr) {
     grpc_pollset_set_add_pollset_set(pollset_set_, interested_parties);
   }
-  if (health_check_service_name == nullptr) {
+  if (!health_check_service_name.has_value()) {
     if (state_ != initial_state) {
       new AsyncWatcherNotifierLocked(watcher, this, state_, status_);
     }
     watcher_list_.AddWatcherLocked(std::move(watcher));
   } else {
-    health_watcher_map_.AddWatcherLocked(this, initial_state,
-                                         std::move(health_check_service_name),
-                                         std::move(watcher));
+    health_watcher_map_.AddWatcherLocked(
+        this, initial_state, *health_check_service_name, std::move(watcher));
   }
 }
 
 void Subchannel::CancelConnectivityStateWatch(
-    const char* health_check_service_name,
+    const absl::optional<std::string>& health_check_service_name,
     ConnectivityStateWatcherInterface* watcher) {
   MutexLock lock(&mu_);
   grpc_pollset_set* interested_parties = watcher->interested_parties();
   if (interested_parties != nullptr) {
     grpc_pollset_set_del_pollset_set(pollset_set_, interested_parties);
   }
-  if (health_check_service_name == nullptr) {
+  if (!health_check_service_name.has_value()) {
     watcher_list_.RemoveWatcherLocked(watcher);
   } else {
-    health_watcher_map_.RemoveWatcherLocked(health_check_service_name, watcher);
+    health_watcher_map_.RemoveWatcherLocked(*health_check_service_name,
+                                            watcher);
   }
 }
 
@@ -912,7 +894,7 @@ void Subchannel::ResetBackoff() {
 grpc_arg Subchannel::CreateSubchannelAddressArg(
     const grpc_resolved_address* addr) {
   return grpc_channel_arg_string_create(
-      (char*)GRPC_ARG_SUBCHANNEL_ADDRESS,
+      const_cast<char*>(GRPC_ARG_SUBCHANNEL_ADDRESS),
       gpr_strdup(addr->len > 0 ? grpc_sockaddr_to_uri(addr).c_str() : ""));
 }
 
@@ -928,10 +910,12 @@ const char* Subchannel::GetUriFromSubchannelAddressArg(
 namespace {
 
 void UriToSockaddr(const char* uri_str, grpc_resolved_address* addr) {
-  grpc_uri* uri = grpc_uri_parse(uri_str, false /* suppress_errors */);
-  GPR_ASSERT(uri != nullptr);
-  if (!grpc_parse_uri(uri, addr)) memset(addr, 0, sizeof(*addr));
-  grpc_uri_destroy(uri);
+  absl::StatusOr<URI> uri = URI::Parse(uri_str);
+  if (!uri.ok()) {
+    gpr_log(GPR_ERROR, "%s", uri.status().ToString().c_str());
+    GPR_ASSERT(uri.ok());
+  }
+  if (!grpc_parse_uri(*uri, addr)) memset(addr, 0, sizeof(*addr));
 }
 
 }  // namespace
index 46ffb2f..952a02a 100644 (file)
@@ -30,7 +30,6 @@
 #include "src/core/lib/channel/channel_stack.h"
 #include "src/core/lib/gpr/time_precise.h"
 #include "src/core/lib/gprpp/arena.h"
-#include "src/core/lib/gprpp/map.h"
 #include "src/core/lib/gprpp/ref_counted.h"
 #include "src/core/lib/gprpp/ref_counted_ptr.h"
 #include "src/core/lib/gprpp/sync.h"
@@ -89,7 +88,7 @@ class ConnectedSubchannel : public RefCounted<ConnectedSubchannel> {
     return channelz_subchannel_.get();
   }
 
-  size_t GetInitialCallSizeEstimate(size_t parent_data_size) const;
+  size_t GetInitialCallSizeEstimate() const;
 
  private:
   grpc_channel_stack* channel_stack_;
@@ -111,18 +110,12 @@ class SubchannelCall {
     Arena* arena;
     grpc_call_context_element* context;
     CallCombiner* call_combiner;
-    size_t parent_data_size;
   };
   static RefCountedPtr<SubchannelCall> Create(Args args, grpc_error** error);
 
   // Continues processing a transport stream op batch.
   void StartTransportStreamOpBatch(grpc_transport_stream_op_batch* batch);
 
-  // Returns a pointer to the parent data associated with the subchannel call.
-  // The data will be of the size specified in \a parent_data_size field of
-  // the args passed to \a ConnectedSubchannel::CreateCall().
-  void* GetParentData();
-
   // Returns the call stack of the subchannel call.
   grpc_call_stack* GetCallStack();
 
@@ -139,8 +132,6 @@ class SubchannelCall {
   void Unref();
   void Unref(const DebugLocation& location, const char* reason);
 
-  static void Destroy(void* arg, grpc_error* error);
-
  private:
   // Allow RefCountedPtr<> to access IncrementRefCount().
   template <typename T>
@@ -159,6 +150,8 @@ class SubchannelCall {
   void IncrementRefCount();
   void IncrementRefCount(const DebugLocation& location, const char* reason);
 
+  static void Destroy(void* arg, grpc_error* error);
+
   RefCountedPtr<ConnectedSubchannel> connected_subchannel_;
   grpc_closure* after_call_stack_destroy_ = nullptr;
   // State needed to support channelz interception of recv trailing metadata.
@@ -257,7 +250,7 @@ class Subchannel {
   // service name.
   // If the return value is GRPC_CHANNEL_READY, also sets *connected_subchannel.
   grpc_connectivity_state CheckConnectivityState(
-      const char* health_check_service_name,
+      const absl::optional<std::string>& health_check_service_name,
       RefCountedPtr<ConnectedSubchannel>* connected_subchannel);
 
   // Starts watching the subchannel's connectivity state.
@@ -270,13 +263,14 @@ class Subchannel {
   // destroyed or when CancelConnectivityStateWatch() is called.
   void WatchConnectivityState(
       grpc_connectivity_state initial_state,
-      grpc_core::UniquePtr<char> health_check_service_name,
+      const absl::optional<std::string>& health_check_service_name,
       RefCountedPtr<ConnectivityStateWatcherInterface> watcher);
 
   // Cancels a connectivity state watch.
   // If the watcher has already been destroyed, this is a no-op.
-  void CancelConnectivityStateWatch(const char* health_check_service_name,
-                                    ConnectivityStateWatcherInterface* watcher);
+  void CancelConnectivityStateWatch(
+      const absl::optional<std::string>& health_check_service_name,
+      ConnectivityStateWatcherInterface* watcher);
 
   // Attempt to connect to the backend.  Has no effect if already connected.
   void AttemptToConnect();
@@ -340,9 +334,9 @@ class Subchannel {
    public:
     void AddWatcherLocked(
         Subchannel* subchannel, grpc_connectivity_state initial_state,
-        grpc_core::UniquePtr<char> health_check_service_name,
+        const std::string& health_check_service_name,
         RefCountedPtr<ConnectivityStateWatcherInterface> watcher);
-    void RemoveWatcherLocked(const char* health_check_service_name,
+    void RemoveWatcherLocked(const std::string& health_check_service_name,
                              ConnectivityStateWatcherInterface* watcher);
 
     // Notifies the watcher when the subchannel's state changes.
@@ -350,14 +344,14 @@ class Subchannel {
                       const absl::Status& status);
 
     grpc_connectivity_state CheckConnectivityStateLocked(
-        Subchannel* subchannel, const char* health_check_service_name);
+        Subchannel* subchannel, const std::string& health_check_service_name);
 
     void ShutdownLocked();
 
    private:
     class HealthWatcher;
 
-    std::map<const char*, OrphanablePtr<HealthWatcher>, StringLess> map_;
+    std::map<std::string, OrphanablePtr<HealthWatcher>> map_;
   };
 
   class ConnectedSubchannelStateWatcher;
index bd16844..837e337 100644 (file)
@@ -383,10 +383,12 @@ static bool maybe_add_deadline_filter(grpc_channel_stack_builder* builder,
 void grpc_deadline_filter_init(void) {
   grpc_channel_init_register_stage(
       GRPC_CLIENT_DIRECT_CHANNEL, GRPC_CHANNEL_INIT_BUILTIN_PRIORITY,
-      maybe_add_deadline_filter, (void*)&grpc_client_deadline_filter);
+      maybe_add_deadline_filter,
+      const_cast<grpc_channel_filter*>(&grpc_client_deadline_filter));
   grpc_channel_init_register_stage(
       GRPC_SERVER_CHANNEL, GRPC_CHANNEL_INIT_BUILTIN_PRIORITY,
-      maybe_add_deadline_filter, (void*)&grpc_server_deadline_filter);
+      maybe_add_deadline_filter,
+      const_cast<grpc_channel_filter*>(&grpc_server_deadline_filter));
 }
 
 void grpc_deadline_filter_shutdown(void) {}
index 2c3cae6..9511d25 100644 (file)
@@ -148,12 +148,12 @@ static bool add_client_authority_filter(grpc_channel_stack_builder* builder,
 }
 
 void grpc_client_authority_filter_init(void) {
-  grpc_channel_init_register_stage(GRPC_CLIENT_SUBCHANNEL, INT_MAX,
-                                   add_client_authority_filter,
-                                   (void*)&grpc_client_authority_filter);
-  grpc_channel_init_register_stage(GRPC_CLIENT_DIRECT_CHANNEL, INT_MAX,
-                                   add_client_authority_filter,
-                                   (void*)&grpc_client_authority_filter);
+  grpc_channel_init_register_stage(
+      GRPC_CLIENT_SUBCHANNEL, INT_MAX, add_client_authority_filter,
+      const_cast<grpc_channel_filter*>(&grpc_client_authority_filter));
+  grpc_channel_init_register_stage(
+      GRPC_CLIENT_DIRECT_CHANNEL, INT_MAX, add_client_authority_filter,
+      const_cast<grpc_channel_filter*>(&grpc_client_authority_filter));
 }
 
 void grpc_client_authority_filter_shutdown(void) {}
index 637dc30..d5577d5 100644 (file)
@@ -93,13 +93,16 @@ void grpc_http_filters_init(void) {
       maybe_add_optional_filter<true>, &decompress_filter);
   grpc_channel_init_register_stage(
       GRPC_CLIENT_SUBCHANNEL, GRPC_CHANNEL_INIT_BUILTIN_PRIORITY,
-      maybe_add_required_filter, (void*)&grpc_http_client_filter);
+      maybe_add_required_filter,
+      const_cast<grpc_channel_filter*>(&grpc_http_client_filter));
   grpc_channel_init_register_stage(
       GRPC_CLIENT_DIRECT_CHANNEL, GRPC_CHANNEL_INIT_BUILTIN_PRIORITY,
-      maybe_add_required_filter, (void*)&grpc_http_client_filter);
+      maybe_add_required_filter,
+      const_cast<grpc_channel_filter*>(&grpc_http_client_filter));
   grpc_channel_init_register_stage(
       GRPC_SERVER_CHANNEL, GRPC_CHANNEL_INIT_BUILTIN_PRIORITY,
-      maybe_add_required_filter, (void*)&grpc_http_server_filter);
+      maybe_add_required_filter,
+      const_cast<grpc_channel_filter*>(&grpc_http_server_filter));
 }
 
 void grpc_http_filters_shutdown(void) {}
index b3f9928..5d57830 100644 (file)
@@ -134,18 +134,18 @@ std::string ServerLoadReportingCallData::GetCensusSafeClientIpString() {
             "metadata.");
     return "";
   }
-  // Parse the client URI string into grpc_uri.
-  grpc_uri* client_uri = grpc_uri_parse(client_uri_str, true);
-  if (client_uri == nullptr) {
+  absl::StatusOr<grpc_core::URI> client_uri =
+      grpc_core::URI::Parse(client_uri_str);
+  if (!client_uri.ok()) {
     gpr_log(GPR_ERROR,
             "Unable to parse the client URI string (peer string) to a client "
-            "URI.");
+            "URI. Error: %s",
+            client_uri.status().ToString().c_str());
     return "";
   }
   // Parse the client URI into grpc_resolved_address.
   grpc_resolved_address resolved_address;
-  bool success = grpc_parse_uri(client_uri, &resolved_address);
-  grpc_uri_destroy(client_uri);
+  bool success = grpc_parse_uri(*client_uri, &resolved_address);
   if (!success) {
     gpr_log(GPR_ERROR,
             "Unable to parse client URI into a grpc_resolved_address.");
index 78e7054..10a58d9 100644 (file)
@@ -302,7 +302,7 @@ static grpc_error* message_size_init_call_elem(
 static void message_size_destroy_call_elem(
     grpc_call_element* elem, const grpc_call_final_info* /*final_info*/,
     grpc_closure* /*ignored*/) {
-  call_data* calld = (call_data*)elem->call_data;
+  call_data* calld = static_cast<call_data*>(elem->call_data);
   calld->~call_data();
 }
 
index 4dabe89..2a184ba 100644 (file)
@@ -42,7 +42,7 @@ grpc_workaround_user_agent_md* grpc_parse_user_agent(grpc_mdelem md) {
       user_agent_md->workaround_active[i] = ua_parser[i](md);
     }
   }
-  grpc_mdelem_set_user_data(md, destroy_user_agent_md, (void*)user_agent_md);
+  grpc_mdelem_set_user_data(md, destroy_user_agent_md, user_agent_md);
 
   return user_agent_md;
 }
index bad3153..8e4f8c1 100644 (file)
@@ -26,7 +26,7 @@ grpc_channel_args* grpc_default_authority_add_if_not_present(
       grpc_channel_args_find(args, GRPC_ARG_DEFAULT_AUTHORITY) != nullptr;
   grpc_arg new_args[1];
   size_t num_new_args = 0;
-  grpc_core::UniquePtr<char> default_authority;
+  std::string default_authority;
   if (!has_default_authority) {
     const grpc_arg* server_uri_arg =
         grpc_channel_args_find(args, GRPC_ARG_SERVER_URI);
@@ -34,9 +34,9 @@ grpc_channel_args* grpc_default_authority_add_if_not_present(
     GPR_ASSERT(server_uri_str != nullptr);
     default_authority =
         grpc_core::ResolverRegistry::GetDefaultAuthority(server_uri_str);
-    GPR_ASSERT(default_authority != nullptr);
     new_args[num_new_args++] = grpc_channel_arg_string_create(
-        const_cast<char*>(GRPC_ARG_DEFAULT_AUTHORITY), default_authority.get());
+        const_cast<char*>(GRPC_ARG_DEFAULT_AUTHORITY),
+        const_cast<char*>(default_authority.c_str()));
   }
   return grpc_channel_args_copy_and_add(args, new_args, num_new_args);
 }
index 189ed7d..a325533 100644 (file)
@@ -49,9 +49,13 @@ class Chttp2InsecureClientChannelFactory : public ClientChannelFactory {
 
 namespace {
 
-grpc_channel* CreateChannel(const char* target, const grpc_channel_args* args) {
+grpc_channel* CreateChannel(const char* target, const grpc_channel_args* args,
+                            grpc_error** error) {
   if (target == nullptr) {
     gpr_log(GPR_ERROR, "cannot create channel with NULL target name");
+    if (error != nullptr) {
+      *error = GRPC_ERROR_CREATE_FROM_STATIC_STRING("channel target is NULL");
+    }
     return nullptr;
   }
   // Add channel arg containing the server URI.
@@ -62,8 +66,8 @@ grpc_channel* CreateChannel(const char* target, const grpc_channel_args* args) {
   const char* to_remove[] = {GRPC_ARG_SERVER_URI};
   grpc_channel_args* new_args =
       grpc_channel_args_copy_and_add_and_remove(args, to_remove, 1, &arg, 1);
-  grpc_channel* channel =
-      grpc_channel_create(target, new_args, GRPC_CLIENT_CHANNEL, nullptr);
+  grpc_channel* channel = grpc_channel_create(
+      target, new_args, GRPC_CLIENT_CHANNEL, nullptr, nullptr, error);
   grpc_channel_args_destroy(new_args);
   return channel;
 }
@@ -101,12 +105,20 @@ grpc_channel* grpc_insecure_channel_create(const char* target,
   const char* arg_to_remove = arg.key;
   grpc_channel_args* new_args = grpc_channel_args_copy_and_add_and_remove(
       args, &arg_to_remove, 1, &arg, 1);
+  grpc_error* error = GRPC_ERROR_NONE;
   // Create channel.
-  grpc_channel* channel = grpc_core::CreateChannel(target, new_args);
+  grpc_channel* channel = grpc_core::CreateChannel(target, new_args, &error);
   // Clean up.
   grpc_channel_args_destroy(new_args);
-  return channel != nullptr ? channel
-                            : grpc_lame_client_channel_create(
-                                  target, GRPC_STATUS_INTERNAL,
-                                  "Failed to create client channel");
+  if (channel == nullptr) {
+    intptr_t integer;
+    grpc_status_code status = GRPC_STATUS_INTERNAL;
+    if (grpc_error_get_int(error, GRPC_ERROR_INT_GRPC_STATUS, &integer)) {
+      status = static_cast<grpc_status_code>(integer);
+    }
+    GRPC_ERROR_UNREF(error);
+    channel = grpc_lame_client_channel_create(
+        target, status, "Failed to create client channel");
+  }
+  return channel;
 }
index 5bdcb38..27e64fb 100644 (file)
@@ -42,7 +42,8 @@ grpc_channel* grpc_insecure_channel_create_from_fd(
                  (target, fd, args));
 
   grpc_arg default_authority_arg = grpc_channel_arg_string_create(
-      (char*)GRPC_ARG_DEFAULT_AUTHORITY, (char*)"test.authority");
+      const_cast<char*>(GRPC_ARG_DEFAULT_AUTHORITY),
+      const_cast<char*>("test.authority"));
   grpc_channel_args* final_args =
       grpc_channel_args_copy_and_add(args, &default_authority_arg, 1);
 
@@ -55,17 +56,27 @@ grpc_channel* grpc_insecure_channel_create_from_fd(
   grpc_transport* transport =
       grpc_create_chttp2_transport(final_args, client, true);
   GPR_ASSERT(transport);
-  grpc_channel* channel = grpc_channel_create(
-      target, final_args, GRPC_CLIENT_DIRECT_CHANNEL, transport);
+  grpc_error* error = nullptr;
+  grpc_channel* channel =
+      grpc_channel_create(target, final_args, GRPC_CLIENT_DIRECT_CHANNEL,
+                          transport, nullptr, &error);
   grpc_channel_args_destroy(final_args);
-  grpc_chttp2_transport_start_reading(transport, nullptr, nullptr);
+  if (channel != nullptr) {
+    grpc_chttp2_transport_start_reading(transport, nullptr, nullptr);
+    grpc_core::ExecCtx::Get()->Flush();
+  } else {
+    intptr_t integer;
+    grpc_status_code status = GRPC_STATUS_INTERNAL;
+    if (grpc_error_get_int(error, GRPC_ERROR_INT_GRPC_STATUS, &integer)) {
+      status = static_cast<grpc_status_code>(integer);
+    }
+    GRPC_ERROR_UNREF(error);
+    grpc_transport_destroy(transport);
+    channel = grpc_lame_client_channel_create(
+        target, status, "Failed to create client channel");
+  }
 
-  grpc_core::ExecCtx::Get()->Flush();
-
-  return channel != nullptr ? channel
-                            : grpc_lame_client_channel_create(
-                                  target, GRPC_STATUS_INTERNAL,
-                                  "Failed to create client channel");
+  return channel;
 }
 
 #else  // !GPR_SUPPORT_CHANNELS_FROM_FD
index 93dadf3..7edf6aa 100644 (file)
@@ -78,9 +78,8 @@ class Chttp2SecureClientChannelFactory : public ClientChannelFactory {
     // First, check the authority override channel arg.
     // Otherwise, get it from the server name used to construct the
     // channel.
-    grpc_core::UniquePtr<char> authority(
-        gpr_strdup(FindAuthorityOverrideInArgs(args)));
-    if (authority == nullptr) {
+    std::string authority(FindAuthorityOverrideInArgs(args));
+    if (authority.empty()) {
       const char* server_uri_str =
           grpc_channel_args_find_string(args, GRPC_ARG_SERVER_URI);
       GPR_ASSERT(server_uri_str != nullptr);
@@ -92,7 +91,8 @@ class Chttp2SecureClientChannelFactory : public ClientChannelFactory {
       // If the channel args don't already contain GRPC_ARG_DEFAULT_AUTHORITY,
       // add the arg, setting it to the value just obtained.
       args_to_add[num_args_to_add++] = grpc_channel_arg_string_create(
-          const_cast<char*>(GRPC_ARG_DEFAULT_AUTHORITY), authority.get());
+          const_cast<char*>(GRPC_ARG_DEFAULT_AUTHORITY),
+          const_cast<char*>(authority.c_str()));
     }
     grpc_channel_args* args_with_authority =
         grpc_channel_args_copy_and_add(args, args_to_add, num_args_to_add);
@@ -101,12 +101,12 @@ class Chttp2SecureClientChannelFactory : public ClientChannelFactory {
     RefCountedPtr<grpc_channel_security_connector>
         subchannel_security_connector =
             channel_credentials->create_security_connector(
-                /*call_creds=*/nullptr, authority.get(), args_with_authority,
+                /*call_creds=*/nullptr, authority.c_str(), args_with_authority,
                 &new_args_from_connector);
     if (subchannel_security_connector == nullptr) {
       gpr_log(GPR_ERROR,
               "Failed to create secure subchannel for secure name '%s'",
-              authority.get());
+              authority.c_str());
       grpc_channel_args_destroy(args_with_authority);
       return nullptr;
     }
@@ -127,9 +127,13 @@ class Chttp2SecureClientChannelFactory : public ClientChannelFactory {
 
 namespace {
 
-grpc_channel* CreateChannel(const char* target, const grpc_channel_args* args) {
+grpc_channel* CreateChannel(const char* target, const grpc_channel_args* args,
+                            grpc_error** error) {
   if (target == nullptr) {
     gpr_log(GPR_ERROR, "cannot create channel with NULL target name");
+    if (error != nullptr) {
+      *error = GRPC_ERROR_CREATE_FROM_STATIC_STRING("channel target is NULL");
+    }
     return nullptr;
   }
   // Add channel arg containing the server URI.
@@ -140,8 +144,8 @@ grpc_channel* CreateChannel(const char* target, const grpc_channel_args* args) {
   const char* to_remove[] = {GRPC_ARG_SERVER_URI};
   grpc_channel_args* new_args =
       grpc_channel_args_copy_and_add_and_remove(args, to_remove, 1, &arg, 1);
-  grpc_channel* channel =
-      grpc_channel_create(target, new_args, GRPC_CLIENT_CHANNEL, nullptr);
+  grpc_channel* channel = grpc_channel_create(
+      target, new_args, GRPC_CLIENT_CHANNEL, nullptr, nullptr, error);
   grpc_channel_args_destroy(new_args);
   return channel;
 }
@@ -176,6 +180,7 @@ grpc_channel* grpc_secure_channel_create(grpc_channel_credentials* creds,
       4, ((void*)creds, target, (void*)args, (void*)reserved));
   GPR_ASSERT(reserved == nullptr);
   grpc_channel* channel = nullptr;
+  grpc_error* error = GRPC_ERROR_NONE;
   if (creds != nullptr) {
     // Add channel args containing the client channel factory and channel
     // credentials.
@@ -189,12 +194,19 @@ grpc_channel* grpc_secure_channel_create(grpc_channel_credentials* creds,
         args, &arg_to_remove, 1, args_to_add, GPR_ARRAY_SIZE(args_to_add));
     new_args = creds->update_arguments(new_args);
     // Create channel.
-    channel = grpc_core::CreateChannel(target, new_args);
+    channel = grpc_core::CreateChannel(target, new_args, &error);
     // Clean up.
     grpc_channel_args_destroy(new_args);
   }
-  return channel != nullptr ? channel
-                            : grpc_lame_client_channel_create(
-                                  target, GRPC_STATUS_INTERNAL,
-                                  "Failed to create secure client channel");
+  if (channel == nullptr) {
+    intptr_t integer;
+    grpc_status_code status = GRPC_STATUS_INTERNAL;
+    if (grpc_error_get_int(error, GRPC_ERROR_INT_GRPC_STATUS, &integer)) {
+      status = static_cast<grpc_status_code>(integer);
+    }
+    GRPC_ERROR_UNREF(error);
+    channel = grpc_lame_client_channel_create(
+        target, status, "Failed to create secure client channel");
+  }
+  return channel;
 }
index d6b9d80..8446a9f 100644 (file)
@@ -46,6 +46,7 @@
 #include "src/core/lib/iomgr/endpoint.h"
 #include "src/core/lib/iomgr/resolve_address.h"
 #include "src/core/lib/iomgr/resource_quota.h"
+#include "src/core/lib/iomgr/sockaddr_utils.h"
 #include "src/core/lib/iomgr/tcp_server.h"
 #include "src/core/lib/iomgr/unix_sockets_posix.h"
 #include "src/core/lib/slice/slice_internal.h"
@@ -60,7 +61,7 @@ const char kUnixAbstractUriPrefix[] = "unix-abstract:";
 
 class Chttp2ServerListener : public Server::ListenerInterface {
  public:
-  static grpc_error* Create(Server* server, const char* addr,
+  static grpc_error* Create(Server* server, grpc_resolved_address* addr,
                             grpc_channel_args* args, int* port_num);
 
   static grpc_error* CreateWithAcceptor(Server* server, const char* name,
@@ -82,6 +83,38 @@ class Chttp2ServerListener : public Server::ListenerInterface {
   void Orphan() override;
 
  private:
+  class ConfigFetcherWatcher
+      : public grpc_server_config_fetcher::WatcherInterface {
+   public:
+    explicit ConfigFetcherWatcher(Chttp2ServerListener* listener)
+        : listener_(listener) {}
+
+    void UpdateConfig(grpc_channel_args* args) override {
+      {
+        MutexLock lock(&listener_->mu_);
+        // TODO(yashykt): Fix this
+        // grpc_channel_args_destroy(listener_->args_);
+        // listener_->args_ = args;
+        if (!listener_->shutdown_) return;  // Already started listening.
+      }
+      int port_temp;
+      grpc_error* error = grpc_tcp_server_add_port(
+          listener_->tcp_server_, &listener_->resolved_address_, &port_temp);
+      if (error != GRPC_ERROR_NONE) {
+        GRPC_ERROR_UNREF(error);
+        gpr_log(GPR_ERROR, "Error adding port to server: %s",
+                grpc_error_string(error));
+        // TODO(yashykt): We wouldn't need to assert here if we bound to the
+        // port earlier during AddPort.
+        GPR_ASSERT(0);
+      }
+      listener_->StartListening();
+    }
+
+   private:
+    Chttp2ServerListener* listener_;
+  };
+
   class ConnectionState : public RefCounted<ConnectionState> {
    public:
     ConnectionState(Chttp2ServerListener* listener,
@@ -110,6 +143,8 @@ class Chttp2ServerListener : public Server::ListenerInterface {
     grpc_pollset_set* const interested_parties_;
   };
 
+  void StartListening();
+
   static void OnAccept(void* arg, grpc_endpoint* tcp,
                        grpc_pollset* accepting_pollset,
                        grpc_tcp_server_acceptor* acceptor);
@@ -124,7 +159,9 @@ class Chttp2ServerListener : public Server::ListenerInterface {
   Server* const server_;
   grpc_channel_args* const args_;
   grpc_tcp_server* tcp_server_;
+  grpc_resolved_address resolved_address_;
   Mutex mu_;
+  ConfigFetcherWatcher* config_fetcher_watcher_ = nullptr;
   bool shutdown_ = true;
   grpc_closure tcp_server_shutdown_complete_;
   grpc_closure* on_destroy_done_ = nullptr;
@@ -227,31 +264,47 @@ void Chttp2ServerListener::ConnectionState::OnHandshakeDone(void* arg,
       if (args->endpoint != nullptr) {
         grpc_transport* transport = grpc_create_chttp2_transport(
             args->args, args->endpoint, false, resource_user);
-        self->listener_->server_->SetupTransport(
+        grpc_error* channel_init_err = self->listener_->server_->SetupTransport(
             transport, self->accepting_pollset_, args->args,
             grpc_chttp2_transport_get_socket_node(transport), resource_user);
-        // Use notify_on_receive_settings callback to enforce the
-        // handshake deadline.
-        // Note: The reinterpret_cast<>s here are safe, because
-        // grpc_chttp2_transport is a C-style extension of
-        // grpc_transport, so this is morally equivalent of a
-        // static_cast<> to a derived class.
-        // TODO(roth): Change to static_cast<> when we C++-ify the
-        // transport API.
-        self->transport_ = reinterpret_cast<grpc_chttp2_transport*>(transport);
-        self->Ref().release();  // Held by OnReceiveSettings().
-        GRPC_CLOSURE_INIT(&self->on_receive_settings_, OnReceiveSettings, self,
-                          grpc_schedule_on_exec_ctx);
-        grpc_chttp2_transport_start_reading(transport, args->read_buffer,
-                                            &self->on_receive_settings_);
-        grpc_channel_args_destroy(args->args);
-        self->Ref().release();  // Held by OnTimeout().
-        GRPC_CHTTP2_REF_TRANSPORT(
-            reinterpret_cast<grpc_chttp2_transport*>(transport),
-            "receive settings timeout");
-        GRPC_CLOSURE_INIT(&self->on_timeout_, OnTimeout, self,
-                          grpc_schedule_on_exec_ctx);
-        grpc_timer_init(&self->timer_, self->deadline_, &self->on_timeout_);
+        if (channel_init_err == GRPC_ERROR_NONE) {
+          // Use notify_on_receive_settings callback to enforce the
+          // handshake deadline.
+          // Note: The reinterpret_cast<>s here are safe, because
+          // grpc_chttp2_transport is a C-style extension of
+          // grpc_transport, so this is morally equivalent of a
+          // static_cast<> to a derived class.
+          // TODO(roth): Change to static_cast<> when we C++-ify the
+          // transport API.
+          self->transport_ =
+              reinterpret_cast<grpc_chttp2_transport*>(transport);
+          self->Ref().release();  // Held by OnReceiveSettings().
+          GRPC_CLOSURE_INIT(&self->on_receive_settings_, OnReceiveSettings,
+                            self, grpc_schedule_on_exec_ctx);
+          grpc_chttp2_transport_start_reading(transport, args->read_buffer,
+                                              &self->on_receive_settings_);
+          grpc_channel_args_destroy(args->args);
+          self->Ref().release();  // Held by OnTimeout().
+          GRPC_CHTTP2_REF_TRANSPORT(
+              reinterpret_cast<grpc_chttp2_transport*>(transport),
+              "receive settings timeout");
+          GRPC_CLOSURE_INIT(&self->on_timeout_, OnTimeout, self,
+                            grpc_schedule_on_exec_ctx);
+          grpc_timer_init(&self->timer_, self->deadline_, &self->on_timeout_);
+        } else {
+          // Failed to create channel from transport. Clean up.
+          gpr_log(GPR_ERROR, "Failed to create channel: %s",
+                  grpc_error_string(channel_init_err));
+          GRPC_ERROR_UNREF(channel_init_err);
+          grpc_transport_destroy(transport);
+          grpc_slice_buffer_destroy_internal(args->read_buffer);
+          gpr_free(args->read_buffer);
+          if (resource_user != nullptr) {
+            grpc_resource_user_free(resource_user,
+                                    GRPC_RESOURCE_QUOTA_CHANNEL_SIZE);
+          }
+          grpc_channel_args_destroy(args->args);
+        }
       } else {
         if (resource_user != nullptr) {
           grpc_resource_user_free(resource_user,
@@ -272,81 +325,44 @@ void Chttp2ServerListener::ConnectionState::OnHandshakeDone(void* arg,
 // Chttp2ServerListener
 //
 
-grpc_error* Chttp2ServerListener::Create(Server* server, const char* addr,
+grpc_error* Chttp2ServerListener::Create(Server* server,
+                                         grpc_resolved_address* addr,
                                          grpc_channel_args* args,
                                          int* port_num) {
-  std::vector<grpc_error*> error_list;
-  grpc_resolved_addresses* resolved = nullptr;
   Chttp2ServerListener* listener = nullptr;
   // The bulk of this method is inside of a lambda to make cleanup
   // easier without using goto.
   grpc_error* error = [&]() {
-    *port_num = -1;
-    /* resolve address */
-    grpc_error* error = GRPC_ERROR_NONE;
-    if (absl::StartsWith(addr, kUnixUriPrefix)) {
-      error = grpc_resolve_unix_domain_address(
-          addr + sizeof(kUnixUriPrefix) - 1, &resolved);
-    } else if (absl::StartsWith(addr, kUnixAbstractUriPrefix)) {
-      error = grpc_resolve_unix_abstract_domain_address(
-          addr + sizeof(kUnixAbstractUriPrefix) - 1, &resolved);
-    } else {
-      error = grpc_blocking_resolve_address(addr, "https", &resolved);
-    }
-    if (error != GRPC_ERROR_NONE) return error;
     // Create Chttp2ServerListener.
     listener = new Chttp2ServerListener(server, args);
     error = grpc_tcp_server_create(&listener->tcp_server_shutdown_complete_,
                                    args, &listener->tcp_server_);
     if (error != GRPC_ERROR_NONE) return error;
-    for (size_t i = 0; i < resolved->naddrs; i++) {
-      int port_temp;
-      error = grpc_tcp_server_add_port(listener->tcp_server_,
-                                       &resolved->addrs[i], &port_temp);
-      if (error != GRPC_ERROR_NONE) {
-        error_list.push_back(error);
-      } else {
-        if (*port_num == -1) {
-          *port_num = port_temp;
-        } else {
-          GPR_ASSERT(*port_num == port_temp);
-        }
-      }
-    }
-    if (error_list.size() == resolved->naddrs) {
-      std::string msg =
-          absl::StrFormat("No address added out of total %" PRIuPTR " resolved",
-                          resolved->naddrs);
-      return GRPC_ERROR_CREATE_REFERENCING_FROM_COPIED_STRING(
-          msg.c_str(), error_list.data(), error_list.size());
-    } else if (!error_list.empty()) {
-      std::string msg = absl::StrFormat(
-          "Only %" PRIuPTR " addresses added out of total %" PRIuPTR
-          " resolved",
-          resolved->naddrs - error_list.size(), resolved->naddrs);
-      error = GRPC_ERROR_CREATE_REFERENCING_FROM_COPIED_STRING(
-          msg.c_str(), error_list.data(), error_list.size());
-      gpr_log(GPR_INFO, "WARNING: %s", grpc_error_string(error));
-      GRPC_ERROR_UNREF(error);
-      /* we managed to bind some addresses: continue */
+    if (server->config_fetcher() != nullptr) {
+      listener->resolved_address_ = *addr;
+      // TODO(yashykt): Consider binding so as to be able to return the port
+      // number.
+    } else {
+      error = grpc_tcp_server_add_port(listener->tcp_server_, addr, port_num);
+      if (error != GRPC_ERROR_NONE) return error;
     }
     // Create channelz node.
     if (grpc_channel_args_find_bool(args, GRPC_ARG_ENABLE_CHANNELZ,
                                     GRPC_ENABLE_CHANNELZ_DEFAULT)) {
+      std::string string_address = grpc_sockaddr_to_string(addr, false);
       listener->channelz_listen_socket_ =
           MakeRefCounted<channelz::ListenSocketNode>(
-              addr, absl::StrFormat("chttp2 listener %s", addr));
+              string_address.c_str(),
+              absl::StrFormat("chttp2 listener %s", string_address.c_str()));
     }
-    /* Register with the server only upon success */
+    // Register with the server only upon success
     server->AddListener(OrphanablePtr<Server::ListenerInterface>(listener));
     return GRPC_ERROR_NONE;
   }();
-  if (resolved != nullptr) {
-    grpc_resolved_addresses_destroy(resolved);
-  }
   if (error != GRPC_ERROR_NONE) {
     if (listener != nullptr) {
       if (listener->tcp_server_ != nullptr) {
+        // listener is deleted when tcp_server_ is shutdown.
         grpc_tcp_server_unref(listener->tcp_server_);
       } else {
         delete listener;
@@ -354,10 +370,6 @@ grpc_error* Chttp2ServerListener::Create(Server* server, const char* addr,
     } else {
       grpc_channel_args_destroy(args);
     }
-    *port_num = 0;
-  }
-  for (grpc_error* error : error_list) {
-    GRPC_ERROR_UNREF(error);
   }
   return error;
 }
@@ -392,13 +404,25 @@ Chttp2ServerListener::~Chttp2ServerListener() {
 }
 
 /* Server callback: start listening on our ports */
-void Chttp2ServerListener::Start(Server* /*server*/,
-                                 const std::vector<grpc_pollset*>* pollsets) {
-  {
-    MutexLock lock(&mu_);
-    shutdown_ = false;
+void Chttp2ServerListener::Start(
+    Server* /*server*/, const std::vector<grpc_pollset*>* /* pollsets */) {
+  if (server_->config_fetcher() != nullptr) {
+    auto watcher = absl::make_unique<ConfigFetcherWatcher>(this);
+    {
+      MutexLock lock(&mu_);
+      config_fetcher_watcher_ = watcher.get();
+    }
+    server_->config_fetcher()->StartWatch(
+        grpc_sockaddr_to_string(&resolved_address_, false), std::move(watcher));
+  } else {
+    StartListening();
   }
-  grpc_tcp_server_start(tcp_server_, pollsets, OnAccept, this);
+}
+
+void Chttp2ServerListener::StartListening() {
+  grpc_tcp_server_start(tcp_server_, &server_->pollsets(), OnAccept, this);
+  MutexLock lock(&mu_);
+  shutdown_ = false;
 }
 
 void Chttp2ServerListener::SetOnDestroyDone(grpc_closure* on_destroy_done) {
@@ -467,6 +491,11 @@ void Chttp2ServerListener::TcpServerShutdownComplete(void* arg,
 /* Server callback: destroy the tcp listener (so we don't generate further
    callbacks) */
 void Chttp2ServerListener::Orphan() {
+  // Cancel the watch before shutting down so as to avoid holding a ref to the
+  // listener in the watcher.
+  if (config_fetcher_watcher_ != nullptr) {
+    server_->config_fetcher()->CancelWatch(config_fetcher_watcher_);
+  }
   grpc_tcp_server* tcp_server;
   {
     MutexLock lock(&mu_);
@@ -489,7 +518,70 @@ grpc_error* Chttp2ServerAddPort(Server* server, const char* addr,
     return grpc_core::Chttp2ServerListener::CreateWithAcceptor(server, addr,
                                                                args);
   }
-  return grpc_core::Chttp2ServerListener::Create(server, addr, args, port_num);
+  *port_num = -1;
+  grpc_resolved_addresses* resolved = nullptr;
+  std::vector<grpc_error*> error_list;
+  // Using lambda to avoid use of goto.
+  grpc_error* error = [&]() {
+    if (absl::StartsWith(addr, kUnixUriPrefix)) {
+      error = grpc_resolve_unix_domain_address(
+          addr + sizeof(kUnixUriPrefix) - 1, &resolved);
+    } else if (absl::StartsWith(addr, kUnixAbstractUriPrefix)) {
+      error = grpc_resolve_unix_abstract_domain_address(
+          addr + sizeof(kUnixAbstractUriPrefix) - 1, &resolved);
+    } else {
+      error = grpc_blocking_resolve_address(addr, "https", &resolved);
+    }
+    if (error != GRPC_ERROR_NONE) return error;
+    // Create a listener for each resolved address.
+    for (size_t i = 0; i < resolved->naddrs; i++) {
+      // If address has a wildcard port (0), use the same port as a previous
+      // listener.
+      if (*port_num != -1 && grpc_sockaddr_get_port(&resolved->addrs[i]) == 0) {
+        grpc_sockaddr_set_port(&resolved->addrs[i], *port_num);
+      }
+      int port_temp;
+      error = grpc_core::Chttp2ServerListener::Create(
+          server, &resolved->addrs[i], grpc_channel_args_copy(args),
+          &port_temp);
+      if (error != GRPC_ERROR_NONE) {
+        error_list.push_back(error);
+      } else {
+        if (*port_num == -1) {
+          *port_num = port_temp;
+        } else {
+          GPR_ASSERT(*port_num == port_temp);
+        }
+      }
+    }
+    if (error_list.size() == resolved->naddrs) {
+      std::string msg =
+          absl::StrFormat("No address added out of total %" PRIuPTR " resolved",
+                          resolved->naddrs);
+      return GRPC_ERROR_CREATE_REFERENCING_FROM_COPIED_STRING(
+          msg.c_str(), error_list.data(), error_list.size());
+    } else if (!error_list.empty()) {
+      std::string msg = absl::StrFormat(
+          "Only %" PRIuPTR " addresses added out of total %" PRIuPTR
+          " resolved",
+          resolved->naddrs - error_list.size(), resolved->naddrs);
+      error = GRPC_ERROR_CREATE_REFERENCING_FROM_COPIED_STRING(
+          msg.c_str(), error_list.data(), error_list.size());
+      gpr_log(GPR_INFO, "WARNING: %s", grpc_error_string(error));
+      GRPC_ERROR_UNREF(error);
+      // we managed to bind some addresses: continue without error
+    }
+    return GRPC_ERROR_NONE;
+  }();  // lambda end
+  for (grpc_error* error : error_list) {
+    GRPC_ERROR_UNREF(error);
+  }
+  grpc_channel_args_destroy(args);
+  if (resolved != nullptr) {
+    grpc_resolved_addresses_destroy(resolved);
+  }
+  if (error != GRPC_ERROR_NONE) *port_num = 0;
+  return error;
 }
 
 }  // namespace grpc_core
index f27c197..e27c907 100644 (file)
@@ -51,12 +51,19 @@ void grpc_server_add_insecure_channel_from_fd(grpc_server* server,
   grpc_transport* transport = grpc_create_chttp2_transport(
       server_args, server_endpoint, false /* is_client */);
 
-  for (grpc_pollset* pollset : core_server->pollsets()) {
-    grpc_endpoint_add_to_pollset(server_endpoint, pollset);
+  grpc_error* error =
+      core_server->SetupTransport(transport, nullptr, server_args, nullptr);
+  if (error == GRPC_ERROR_NONE) {
+    for (grpc_pollset* pollset : core_server->pollsets()) {
+      grpc_endpoint_add_to_pollset(server_endpoint, pollset);
+    }
+    grpc_chttp2_transport_start_reading(transport, nullptr, nullptr);
+  } else {
+    gpr_log(GPR_ERROR, "Failed to create channel: %s",
+            grpc_error_string(error));
+    GRPC_ERROR_UNREF(error);
+    grpc_transport_destroy(transport);
   }
-
-  core_server->SetupTransport(transport, nullptr, server_args, nullptr);
-  grpc_chttp2_transport_start_reading(transport, nullptr, nullptr);
 }
 
 #else  // !GPR_SUPPORT_CHANNELS_FROM_FD
index 836eb5f..900cd3c 100644 (file)
@@ -126,10 +126,10 @@ static void connectivity_state_set(grpc_chttp2_transport* t,
                                    const absl::Status& status,
                                    const char* reason);
 
-static void benign_reclaimer(void* t, grpc_error* error);
-static void destructive_reclaimer(void* t, grpc_error* error);
-static void benign_reclaimer_locked(void* t, grpc_error* error);
-static void destructive_reclaimer_locked(void* t, grpc_error* error);
+static void benign_reclaimer(void* arg, grpc_error* error);
+static void destructive_reclaimer(void* arg, grpc_error* error);
+static void benign_reclaimer_locked(void* arg, grpc_error* error);
+static void destructive_reclaimer_locked(void* arg, grpc_error* error);
 
 static void post_benign_reclaimer(grpc_chttp2_transport* t);
 static void post_destructive_reclaimer(grpc_chttp2_transport* t);
@@ -146,8 +146,7 @@ static void next_bdp_ping_timer_expired_locked(void* tp, grpc_error* error);
 
 static void cancel_pings(grpc_chttp2_transport* t, grpc_error* error);
 static void send_ping_locked(grpc_chttp2_transport* t,
-                             grpc_closure* on_initiate,
-                             grpc_closure* on_complete);
+                             grpc_closure* on_initiate, grpc_closure* on_ack);
 static void retry_initiate_ping_locked(void* tp, grpc_error* error);
 
 // keepalive-relevant functions
@@ -617,7 +616,7 @@ grpc_chttp2_stream::grpc_chttp2_stream(grpc_chttp2_transport* t,
       metadata_buffer{grpc_chttp2_incoming_metadata_buffer(arena),
                       grpc_chttp2_incoming_metadata_buffer(arena)} {
   if (server_data) {
-    id = static_cast<uint32_t>((uintptr_t)server_data);
+    id = static_cast<uint32_t>(reinterpret_cast<uintptr_t>(server_data));
     *t->accepting_stream = this;
     grpc_chttp2_stream_map_add(&t->stream_map, id, this);
     post_destructive_reclaimer(t);
@@ -750,7 +749,7 @@ grpc_chttp2_stream* grpc_chttp2_parsing_accept_stream(grpc_chttp2_transport* t,
   GPR_ASSERT(t->accepting_stream == nullptr);
   t->accepting_stream = &accepting;
   t->accept_stream_cb(t->accept_stream_cb_user_data, &t->base,
-                      (void*)static_cast<uintptr_t>(id));
+                      reinterpret_cast<void*>(id));
   t->accepting_stream = nullptr;
   return accepting;
 }
index 42c5986..7e05358 100644 (file)
@@ -201,7 +201,7 @@ class TransportFlowControlBase {
 class TransportFlowControlDisabled final : public TransportFlowControlBase {
  public:
   // Maxes out all values
-  TransportFlowControlDisabled(grpc_chttp2_transport* t);
+  explicit TransportFlowControlDisabled(grpc_chttp2_transport* t);
 
   bool flow_control_enabled() const override { return false; }
 
index 1814714..147d5ea 100644 (file)
@@ -43,7 +43,8 @@ struct grpc_chttp2_settings_parser {
   uint32_t incoming_settings[GRPC_CHTTP2_NUM_SETTINGS];
 };
 /* Create a settings frame by diffing old & new, and updating old to be new */
-grpc_slice grpc_chttp2_settings_create(uint32_t* old, const uint32_t* newval,
+grpc_slice grpc_chttp2_settings_create(uint32_t* old_settings,
+                                       const uint32_t* new_settings,
                                        uint32_t force_mask, size_t count);
 /* Create an ack settings frame */
 grpc_slice grpc_chttp2_settings_ack_create(void);
index 2027af6..943ea17 100644 (file)
 #include <grpc/support/log.h>
 
 grpc_slice grpc_chttp2_window_update_create(
-    uint32_t id, uint32_t window_update, grpc_transport_one_way_stats* stats) {
+    uint32_t id, uint32_t window_delta, grpc_transport_one_way_stats* stats) {
   static const size_t frame_size = 13;
   grpc_slice slice = GRPC_SLICE_MALLOC(frame_size);
   stats->header_bytes += frame_size;
   uint8_t* p = GRPC_SLICE_START_PTR(slice);
 
-  GPR_ASSERT(window_update);
+  GPR_ASSERT(window_delta);
 
   *p++ = 0;
   *p++ = 0;
@@ -45,10 +45,10 @@ grpc_slice grpc_chttp2_window_update_create(
   *p++ = static_cast<uint8_t>(id >> 16);
   *p++ = static_cast<uint8_t>(id >> 8);
   *p++ = static_cast<uint8_t>(id);
-  *p++ = static_cast<uint8_t>(window_update >> 24);
-  *p++ = static_cast<uint8_t>(window_update >> 16);
-  *p++ = static_cast<uint8_t>(window_update >> 8);
-  *p++ = static_cast<uint8_t>(window_update);
+  *p++ = static_cast<uint8_t>(window_delta >> 24);
+  *p++ = static_cast<uint8_t>(window_delta >> 16);
+  *p++ = static_cast<uint8_t>(window_delta >> 8);
+  *p++ = static_cast<uint8_t>(window_delta);
 
   return slice;
 }
index 2ce55d0..317afcc 100644 (file)
@@ -198,7 +198,7 @@ class StreamWriteContext;
 
 class WriteContext {
  public:
-  WriteContext(grpc_chttp2_transport* t) : t_(t) {
+  explicit WriteContext(grpc_chttp2_transport* t) : t_(t) {
     GRPC_STATS_INC_HTTP2_WRITES_BEGUN();
     GPR_TIMER_SCOPE("grpc_chttp2_begin_write", 0);
   }
index 1eeadb7..d6d1ed8 100644 (file)
@@ -290,9 +290,8 @@ enum cronet_net_error_code {
   // received a 302 (temporary redirect, response.  The response body might
   // include a description of why the request failed.
   //
-  // TODO(https:  //crbug.com/928551,: This is deprecated and should not be used
-  // by
-  // new code.
+  // TODO(crbug.com/928551): This is deprecated and should not be used
+  // by new code.
   CRONET_NET_ERROR_HTTPS_PROXY_TUNNEL_RESPONSE_REDIRECT = -140,
 
   // We were unable to sign the CertificateVerify data of an SSL client auth
index 6711996..b98b6a1 100644 (file)
@@ -117,7 +117,7 @@ typedef struct grpc_cronet_transport grpc_cronet_transport;
 /* TODO (makdharma): reorder structure for memory efficiency per
    http://www.catb.org/esr/structure-packing/#_structure_reordering: */
 struct read_state {
-  read_state(grpc_core::Arena* arena)
+  explicit read_state(grpc_core::Arena* arena)
       : trailing_metadata(arena), initial_metadata(arena) {
     grpc_slice_buffer_init(&read_slice_buffer);
   }
@@ -151,7 +151,7 @@ struct write_state {
 
 /* track state of one stream op */
 struct op_state {
-  op_state(grpc_core::Arena* arena) : rs(arena) {}
+  explicit op_state(grpc_core::Arena* arena) : rs(arena) {}
 
   bool state_op_done[OP_NUM_OPS] = {};
   bool state_callback_received[OP_NUM_OPS] = {};
@@ -1059,8 +1059,8 @@ static enum e_op_result execute_stream_op(struct op_and_state* oas) {
     unsigned int header_index;
     for (header_index = 0; header_index < s->header_array.count;
          header_index++) {
-      gpr_free((void*)s->header_array.headers[header_index].key);
-      gpr_free((void*)s->header_array.headers[header_index].value);
+      gpr_free(const_cast<char*>(s->header_array.headers[header_index].key));
+      gpr_free(const_cast<char*>(s->header_array.headers[header_index].value));
     }
     stream_state->state_op_done[OP_SEND_INITIAL_METADATA] = true;
     if (t->use_packet_coalescing) {
index db9a0af..213c142 100644 (file)
@@ -153,10 +153,11 @@ struct inproc_stream {
                                       // side to avoid destruction
       INPROC_LOG(GPR_INFO, "calling accept stream cb %p %p",
                  st->accept_stream_cb, st->accept_stream_data);
-      (*st->accept_stream_cb)(st->accept_stream_data, &st->base, (void*)this);
+      (*st->accept_stream_cb)(st->accept_stream_data, &st->base, this);
     } else {
       // This is the server-side and is being called through accept_stream_cb
-      inproc_stream* cs = (inproc_stream*)server_data;
+      inproc_stream* cs = const_cast<inproc_stream*>(
+          static_cast<const inproc_stream*>(server_data));
       other_side = cs;
       // Ref the server-side stream on behalf of the client now
       ref("inproc_init_stream:srv");
@@ -1281,8 +1282,8 @@ grpc_channel* grpc_inproc_channel_create(grpc_server* server,
   // Add a default authority channel argument for the client
   grpc_arg default_authority_arg;
   default_authority_arg.type = GRPC_ARG_STRING;
-  default_authority_arg.key = (char*)GRPC_ARG_DEFAULT_AUTHORITY;
-  default_authority_arg.value.string = (char*)"inproc.authority";
+  default_authority_arg.key = const_cast<char*>(GRPC_ARG_DEFAULT_AUTHORITY);
+  default_authority_arg.value.string = const_cast<char*>("inproc.authority");
   grpc_channel_args* client_args =
       grpc_channel_args_copy_and_add(args, &default_authority_arg, 1);
 
@@ -1292,10 +1293,43 @@ grpc_channel* grpc_inproc_channel_create(grpc_server* server,
                            client_args);
 
   // TODO(ncteisen): design and support channelz GetSocket for inproc.
-  server->core_server->SetupTransport(server_transport, nullptr, server_args,
-                                      nullptr);
-  grpc_channel* channel = grpc_channel_create(
-      "inproc", client_args, GRPC_CLIENT_DIRECT_CHANNEL, client_transport);
+  grpc_error* error = server->core_server->SetupTransport(
+      server_transport, nullptr, server_args, nullptr);
+  grpc_channel* channel = nullptr;
+  if (error == GRPC_ERROR_NONE) {
+    channel =
+        grpc_channel_create("inproc", client_args, GRPC_CLIENT_DIRECT_CHANNEL,
+                            client_transport, nullptr, &error);
+    if (error != GRPC_ERROR_NONE) {
+      GPR_ASSERT(!channel);
+      gpr_log(GPR_ERROR, "Failed to create client channel: %s",
+              grpc_error_string(error));
+      intptr_t integer;
+      grpc_status_code status = GRPC_STATUS_INTERNAL;
+      if (grpc_error_get_int(error, GRPC_ERROR_INT_GRPC_STATUS, &integer)) {
+        status = static_cast<grpc_status_code>(integer);
+      }
+      GRPC_ERROR_UNREF(error);
+      // client_transport was destroyed when grpc_channel_create saw an error.
+      grpc_transport_destroy(server_transport);
+      channel = grpc_lame_client_channel_create(
+          nullptr, status, "Failed to create client channel");
+    }
+  } else {
+    GPR_ASSERT(!channel);
+    gpr_log(GPR_ERROR, "Failed to create server channel: %s",
+            grpc_error_string(error));
+    intptr_t integer;
+    grpc_status_code status = GRPC_STATUS_INTERNAL;
+    if (grpc_error_get_int(error, GRPC_ERROR_INT_GRPC_STATUS, &integer)) {
+      status = static_cast<grpc_status_code>(integer);
+    }
+    GRPC_ERROR_UNREF(error);
+    grpc_transport_destroy(client_transport);
+    grpc_transport_destroy(server_transport);
+    channel = grpc_lame_client_channel_create(
+        nullptr, status, "Failed to create server channel");
+  }
 
   // Free up created channel args
   grpc_channel_args_destroy(server_args);
index cdb472f..1478843 100644 (file)
@@ -11,6 +11,7 @@
 
 #include "upb/msg.h"
 #include "upb/decode.h"
+#include "upb/decode_fast.h"
 #include "upb/encode.h"
 
 #include "upb/port_def.inc"
index 3e5712a..8f1877d 100644 (file)
@@ -20,7 +20,7 @@ static const upb_msglayout_field envoy_annotations_ResourceAnnotation__fields[1]
 const upb_msglayout envoy_annotations_ResourceAnnotation_msginit = {
   NULL,
   &envoy_annotations_ResourceAnnotation__fields[0],
-  UPB_SIZE(8, 16), 1, false,
+  UPB_SIZE(8, 16), 1, false, 255,
 };
 
 #include "upb/port_undef.inc"
index ed6660a..534eef3 100644 (file)
@@ -11,6 +11,7 @@
 
 #include "upb/msg.h"
 #include "upb/decode.h"
+#include "upb/decode_fast.h"
 #include "upb/encode.h"
 
 #include "upb/port_def.inc"
@@ -34,6 +35,12 @@ UPB_INLINE envoy_annotations_ResourceAnnotation *envoy_annotations_ResourceAnnot
   envoy_annotations_ResourceAnnotation *ret = envoy_annotations_ResourceAnnotation_new(arena);
   return (ret && upb_decode(buf, size, ret, &envoy_annotations_ResourceAnnotation_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE envoy_annotations_ResourceAnnotation *envoy_annotations_ResourceAnnotation_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  envoy_annotations_ResourceAnnotation *ret = envoy_annotations_ResourceAnnotation_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &envoy_annotations_ResourceAnnotation_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *envoy_annotations_ResourceAnnotation_serialize(const envoy_annotations_ResourceAnnotation *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &envoy_annotations_ResourceAnnotation_msginit, arena, len);
 }
index 8968072..5de540f 100644 (file)
@@ -28,15 +28,15 @@ static const upb_msglayout *const envoy_config_accesslog_v3_AccessLog_submsgs[2]
 };
 
 static const upb_msglayout_field envoy_config_accesslog_v3_AccessLog__fields[3] = {
-  {1, UPB_SIZE(0, 0), 0, 0, 9, 1},
-  {2, UPB_SIZE(8, 16), 0, 0, 11, 1},
-  {4, UPB_SIZE(12, 24), UPB_SIZE(-17, -33), 1, 11, 1},
+  {1, UPB_SIZE(4, 8), 0, 0, 9, 1},
+  {2, UPB_SIZE(12, 24), 1, 0, 11, 1},
+  {4, UPB_SIZE(16, 32), UPB_SIZE(-21, -41), 1, 11, 1},
 };
 
 const upb_msglayout envoy_config_accesslog_v3_AccessLog_msginit = {
   &envoy_config_accesslog_v3_AccessLog_submsgs[0],
   &envoy_config_accesslog_v3_AccessLog__fields[0],
-  UPB_SIZE(24, 48), 3, false,
+  UPB_SIZE(24, 48), 3, false, 255,
 };
 
 static const upb_msglayout *const envoy_config_accesslog_v3_AccessLogFilter_submsgs[12] = {
@@ -72,7 +72,7 @@ static const upb_msglayout_field envoy_config_accesslog_v3_AccessLogFilter__fiel
 const upb_msglayout envoy_config_accesslog_v3_AccessLogFilter_msginit = {
   &envoy_config_accesslog_v3_AccessLogFilter_submsgs[0],
   &envoy_config_accesslog_v3_AccessLogFilter__fields[0],
-  UPB_SIZE(8, 16), 12, false,
+  UPB_SIZE(8, 16), 12, false, 255,
 };
 
 static const upb_msglayout *const envoy_config_accesslog_v3_ComparisonFilter_submsgs[1] = {
@@ -80,14 +80,14 @@ static const upb_msglayout *const envoy_config_accesslog_v3_ComparisonFilter_sub
 };
 
 static const upb_msglayout_field envoy_config_accesslog_v3_ComparisonFilter__fields[2] = {
-  {1, UPB_SIZE(0, 0), 0, 0, 14, 1},
-  {2, UPB_SIZE(8, 8), 0, 0, 11, 1},
+  {1, UPB_SIZE(4, 4), 0, 0, 14, 1},
+  {2, UPB_SIZE(8, 8), 1, 0, 11, 1},
 };
 
 const upb_msglayout envoy_config_accesslog_v3_ComparisonFilter_msginit = {
   &envoy_config_accesslog_v3_ComparisonFilter_submsgs[0],
   &envoy_config_accesslog_v3_ComparisonFilter__fields[0],
-  UPB_SIZE(16, 16), 2, false,
+  UPB_SIZE(16, 16), 2, false, 255,
 };
 
 static const upb_msglayout *const envoy_config_accesslog_v3_StatusCodeFilter_submsgs[1] = {
@@ -95,13 +95,13 @@ static const upb_msglayout *const envoy_config_accesslog_v3_StatusCodeFilter_sub
 };
 
 static const upb_msglayout_field envoy_config_accesslog_v3_StatusCodeFilter__fields[1] = {
-  {1, UPB_SIZE(0, 0), 0, 0, 11, 1},
+  {1, UPB_SIZE(4, 8), 1, 0, 11, 1},
 };
 
 const upb_msglayout envoy_config_accesslog_v3_StatusCodeFilter_msginit = {
   &envoy_config_accesslog_v3_StatusCodeFilter_submsgs[0],
   &envoy_config_accesslog_v3_StatusCodeFilter__fields[0],
-  UPB_SIZE(4, 8), 1, false,
+  UPB_SIZE(8, 16), 1, false, 255,
 };
 
 static const upb_msglayout *const envoy_config_accesslog_v3_DurationFilter_submsgs[1] = {
@@ -109,25 +109,25 @@ static const upb_msglayout *const envoy_config_accesslog_v3_DurationFilter_subms
 };
 
 static const upb_msglayout_field envoy_config_accesslog_v3_DurationFilter__fields[1] = {
-  {1, UPB_SIZE(0, 0), 0, 0, 11, 1},
+  {1, UPB_SIZE(4, 8), 1, 0, 11, 1},
 };
 
 const upb_msglayout envoy_config_accesslog_v3_DurationFilter_msginit = {
   &envoy_config_accesslog_v3_DurationFilter_submsgs[0],
   &envoy_config_accesslog_v3_DurationFilter__fields[0],
-  UPB_SIZE(4, 8), 1, false,
+  UPB_SIZE(8, 16), 1, false, 255,
 };
 
 const upb_msglayout envoy_config_accesslog_v3_NotHealthCheckFilter_msginit = {
   NULL,
   NULL,
-  UPB_SIZE(0, 0), 0, false,
+  UPB_SIZE(0, 0), 0, false, 255,
 };
 
 const upb_msglayout envoy_config_accesslog_v3_TraceableFilter_msginit = {
   NULL,
   NULL,
-  UPB_SIZE(0, 0), 0, false,
+  UPB_SIZE(0, 0), 0, false, 255,
 };
 
 static const upb_msglayout *const envoy_config_accesslog_v3_RuntimeFilter_submsgs[1] = {
@@ -136,14 +136,14 @@ static const upb_msglayout *const envoy_config_accesslog_v3_RuntimeFilter_submsg
 
 static const upb_msglayout_field envoy_config_accesslog_v3_RuntimeFilter__fields[3] = {
   {1, UPB_SIZE(4, 8), 0, 0, 9, 1},
-  {2, UPB_SIZE(12, 24), 0, 0, 11, 1},
-  {3, UPB_SIZE(0, 0), 0, 0, 8, 1},
+  {2, UPB_SIZE(12, 24), 1, 0, 11, 1},
+  {3, UPB_SIZE(1, 1), 0, 0, 8, 1},
 };
 
 const upb_msglayout envoy_config_accesslog_v3_RuntimeFilter_msginit = {
   &envoy_config_accesslog_v3_RuntimeFilter_submsgs[0],
   &envoy_config_accesslog_v3_RuntimeFilter__fields[0],
-  UPB_SIZE(16, 32), 3, false,
+  UPB_SIZE(16, 32), 3, false, 255,
 };
 
 static const upb_msglayout *const envoy_config_accesslog_v3_AndFilter_submsgs[1] = {
@@ -157,7 +157,7 @@ static const upb_msglayout_field envoy_config_accesslog_v3_AndFilter__fields[1]
 const upb_msglayout envoy_config_accesslog_v3_AndFilter_msginit = {
   &envoy_config_accesslog_v3_AndFilter_submsgs[0],
   &envoy_config_accesslog_v3_AndFilter__fields[0],
-  UPB_SIZE(4, 8), 1, false,
+  UPB_SIZE(8, 8), 1, false, 255,
 };
 
 static const upb_msglayout *const envoy_config_accesslog_v3_OrFilter_submsgs[1] = {
@@ -171,7 +171,7 @@ static const upb_msglayout_field envoy_config_accesslog_v3_OrFilter__fields[1] =
 const upb_msglayout envoy_config_accesslog_v3_OrFilter_msginit = {
   &envoy_config_accesslog_v3_OrFilter_submsgs[0],
   &envoy_config_accesslog_v3_OrFilter__fields[0],
-  UPB_SIZE(4, 8), 1, false,
+  UPB_SIZE(8, 8), 1, false, 255,
 };
 
 static const upb_msglayout *const envoy_config_accesslog_v3_HeaderFilter_submsgs[1] = {
@@ -179,13 +179,13 @@ static const upb_msglayout *const envoy_config_accesslog_v3_HeaderFilter_submsgs
 };
 
 static const upb_msglayout_field envoy_config_accesslog_v3_HeaderFilter__fields[1] = {
-  {1, UPB_SIZE(0, 0), 0, 0, 11, 1},
+  {1, UPB_SIZE(4, 8), 1, 0, 11, 1},
 };
 
 const upb_msglayout envoy_config_accesslog_v3_HeaderFilter_msginit = {
   &envoy_config_accesslog_v3_HeaderFilter_submsgs[0],
   &envoy_config_accesslog_v3_HeaderFilter__fields[0],
-  UPB_SIZE(4, 8), 1, false,
+  UPB_SIZE(8, 16), 1, false, 255,
 };
 
 static const upb_msglayout_field envoy_config_accesslog_v3_ResponseFlagFilter__fields[1] = {
@@ -195,7 +195,7 @@ static const upb_msglayout_field envoy_config_accesslog_v3_ResponseFlagFilter__f
 const upb_msglayout envoy_config_accesslog_v3_ResponseFlagFilter_msginit = {
   NULL,
   &envoy_config_accesslog_v3_ResponseFlagFilter__fields[0],
-  UPB_SIZE(4, 8), 1, false,
+  UPB_SIZE(8, 8), 1, false, 255,
 };
 
 static const upb_msglayout_field envoy_config_accesslog_v3_GrpcStatusFilter__fields[2] = {
@@ -206,7 +206,7 @@ static const upb_msglayout_field envoy_config_accesslog_v3_GrpcStatusFilter__fie
 const upb_msglayout envoy_config_accesslog_v3_GrpcStatusFilter_msginit = {
   NULL,
   &envoy_config_accesslog_v3_GrpcStatusFilter__fields[0],
-  UPB_SIZE(8, 16), 2, false,
+  UPB_SIZE(8, 16), 2, false, 255,
 };
 
 static const upb_msglayout *const envoy_config_accesslog_v3_MetadataFilter_submsgs[2] = {
@@ -215,14 +215,14 @@ static const upb_msglayout *const envoy_config_accesslog_v3_MetadataFilter_subms
 };
 
 static const upb_msglayout_field envoy_config_accesslog_v3_MetadataFilter__fields[2] = {
-  {1, UPB_SIZE(0, 0), 0, 0, 11, 1},
-  {2, UPB_SIZE(4, 8), 0, 1, 11, 1},
+  {1, UPB_SIZE(4, 8), 1, 0, 11, 1},
+  {2, UPB_SIZE(8, 16), 2, 1, 11, 1},
 };
 
 const upb_msglayout envoy_config_accesslog_v3_MetadataFilter_msginit = {
   &envoy_config_accesslog_v3_MetadataFilter_submsgs[0],
   &envoy_config_accesslog_v3_MetadataFilter__fields[0],
-  UPB_SIZE(8, 16), 2, false,
+  UPB_SIZE(16, 24), 2, false, 255,
 };
 
 static const upb_msglayout *const envoy_config_accesslog_v3_ExtensionFilter_submsgs[1] = {
@@ -237,7 +237,7 @@ static const upb_msglayout_field envoy_config_accesslog_v3_ExtensionFilter__fiel
 const upb_msglayout envoy_config_accesslog_v3_ExtensionFilter_msginit = {
   &envoy_config_accesslog_v3_ExtensionFilter_submsgs[0],
   &envoy_config_accesslog_v3_ExtensionFilter__fields[0],
-  UPB_SIZE(16, 32), 2, false,
+  UPB_SIZE(16, 32), 2, false, 255,
 };
 
 #include "upb/port_undef.inc"
index 2e9cb7a..8e33c86 100644 (file)
@@ -11,6 +11,7 @@
 
 #include "upb/msg.h"
 #include "upb/decode.h"
+#include "upb/decode_fast.h"
 #include "upb/encode.h"
 
 #include "upb/port_def.inc"
@@ -114,6 +115,12 @@ UPB_INLINE envoy_config_accesslog_v3_AccessLog *envoy_config_accesslog_v3_Access
   envoy_config_accesslog_v3_AccessLog *ret = envoy_config_accesslog_v3_AccessLog_new(arena);
   return (ret && upb_decode(buf, size, ret, &envoy_config_accesslog_v3_AccessLog_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE envoy_config_accesslog_v3_AccessLog *envoy_config_accesslog_v3_AccessLog_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  envoy_config_accesslog_v3_AccessLog *ret = envoy_config_accesslog_v3_AccessLog_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &envoy_config_accesslog_v3_AccessLog_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *envoy_config_accesslog_v3_AccessLog_serialize(const envoy_config_accesslog_v3_AccessLog *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &envoy_config_accesslog_v3_AccessLog_msginit, arena, len);
 }
@@ -122,19 +129,20 @@ typedef enum {
   envoy_config_accesslog_v3_AccessLog_config_type_typed_config = 4,
   envoy_config_accesslog_v3_AccessLog_config_type_NOT_SET = 0
 } envoy_config_accesslog_v3_AccessLog_config_type_oneofcases;
-UPB_INLINE envoy_config_accesslog_v3_AccessLog_config_type_oneofcases envoy_config_accesslog_v3_AccessLog_config_type_case(const envoy_config_accesslog_v3_AccessLog* msg) { return (envoy_config_accesslog_v3_AccessLog_config_type_oneofcases)*UPB_PTR_AT(msg, UPB_SIZE(16, 32), int32_t); }
+UPB_INLINE envoy_config_accesslog_v3_AccessLog_config_type_oneofcases envoy_config_accesslog_v3_AccessLog_config_type_case(const envoy_config_accesslog_v3_AccessLog* msg) { return (envoy_config_accesslog_v3_AccessLog_config_type_oneofcases)*UPB_PTR_AT(msg, UPB_SIZE(20, 40), int32_t); }
 
-UPB_INLINE upb_strview envoy_config_accesslog_v3_AccessLog_name(const envoy_config_accesslog_v3_AccessLog *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(0, 0), upb_strview); }
-UPB_INLINE bool envoy_config_accesslog_v3_AccessLog_has_filter(const envoy_config_accesslog_v3_AccessLog *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(8, 16)); }
-UPB_INLINE const envoy_config_accesslog_v3_AccessLogFilter* envoy_config_accesslog_v3_AccessLog_filter(const envoy_config_accesslog_v3_AccessLog *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(8, 16), const envoy_config_accesslog_v3_AccessLogFilter*); }
-UPB_INLINE bool envoy_config_accesslog_v3_AccessLog_has_typed_config(const envoy_config_accesslog_v3_AccessLog *msg) { return _upb_getoneofcase(msg, UPB_SIZE(16, 32)) == 4; }
-UPB_INLINE const struct google_protobuf_Any* envoy_config_accesslog_v3_AccessLog_typed_config(const envoy_config_accesslog_v3_AccessLog *msg) { return UPB_READ_ONEOF(msg, const struct google_protobuf_Any*, UPB_SIZE(12, 24), UPB_SIZE(16, 32), 4, NULL); }
+UPB_INLINE upb_strview envoy_config_accesslog_v3_AccessLog_name(const envoy_config_accesslog_v3_AccessLog *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(4, 8), upb_strview); }
+UPB_INLINE bool envoy_config_accesslog_v3_AccessLog_has_filter(const envoy_config_accesslog_v3_AccessLog *msg) { return _upb_hasbit(msg, 1); }
+UPB_INLINE const envoy_config_accesslog_v3_AccessLogFilter* envoy_config_accesslog_v3_AccessLog_filter(const envoy_config_accesslog_v3_AccessLog *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(12, 24), const envoy_config_accesslog_v3_AccessLogFilter*); }
+UPB_INLINE bool envoy_config_accesslog_v3_AccessLog_has_typed_config(const envoy_config_accesslog_v3_AccessLog *msg) { return _upb_getoneofcase(msg, UPB_SIZE(20, 40)) == 4; }
+UPB_INLINE const struct google_protobuf_Any* envoy_config_accesslog_v3_AccessLog_typed_config(const envoy_config_accesslog_v3_AccessLog *msg) { return UPB_READ_ONEOF(msg, const struct google_protobuf_Any*, UPB_SIZE(16, 32), UPB_SIZE(20, 40), 4, NULL); }
 
 UPB_INLINE void envoy_config_accesslog_v3_AccessLog_set_name(envoy_config_accesslog_v3_AccessLog *msg, upb_strview value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(0, 0), upb_strview) = value;
+  *UPB_PTR_AT(msg, UPB_SIZE(4, 8), upb_strview) = value;
 }
 UPB_INLINE void envoy_config_accesslog_v3_AccessLog_set_filter(envoy_config_accesslog_v3_AccessLog *msg, envoy_config_accesslog_v3_AccessLogFilter* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(8, 16), envoy_config_accesslog_v3_AccessLogFilter*) = value;
+  _upb_sethas(msg, 1);
+  *UPB_PTR_AT(msg, UPB_SIZE(12, 24), envoy_config_accesslog_v3_AccessLogFilter*) = value;
 }
 UPB_INLINE struct envoy_config_accesslog_v3_AccessLogFilter* envoy_config_accesslog_v3_AccessLog_mutable_filter(envoy_config_accesslog_v3_AccessLog *msg, upb_arena *arena) {
   struct envoy_config_accesslog_v3_AccessLogFilter* sub = (struct envoy_config_accesslog_v3_AccessLogFilter*)envoy_config_accesslog_v3_AccessLog_filter(msg);
@@ -146,7 +154,7 @@ UPB_INLINE struct envoy_config_accesslog_v3_AccessLogFilter* envoy_config_access
   return sub;
 }
 UPB_INLINE void envoy_config_accesslog_v3_AccessLog_set_typed_config(envoy_config_accesslog_v3_AccessLog *msg, struct google_protobuf_Any* value) {
-  UPB_WRITE_ONEOF(msg, struct google_protobuf_Any*, UPB_SIZE(12, 24), value, UPB_SIZE(16, 32), 4);
+  UPB_WRITE_ONEOF(msg, struct google_protobuf_Any*, UPB_SIZE(16, 32), value, UPB_SIZE(20, 40), 4);
 }
 UPB_INLINE struct google_protobuf_Any* envoy_config_accesslog_v3_AccessLog_mutable_typed_config(envoy_config_accesslog_v3_AccessLog *msg, upb_arena *arena) {
   struct google_protobuf_Any* sub = (struct google_protobuf_Any*)envoy_config_accesslog_v3_AccessLog_typed_config(msg);
@@ -168,6 +176,12 @@ UPB_INLINE envoy_config_accesslog_v3_AccessLogFilter *envoy_config_accesslog_v3_
   envoy_config_accesslog_v3_AccessLogFilter *ret = envoy_config_accesslog_v3_AccessLogFilter_new(arena);
   return (ret && upb_decode(buf, size, ret, &envoy_config_accesslog_v3_AccessLogFilter_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE envoy_config_accesslog_v3_AccessLogFilter *envoy_config_accesslog_v3_AccessLogFilter_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  envoy_config_accesslog_v3_AccessLogFilter *ret = envoy_config_accesslog_v3_AccessLogFilter_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &envoy_config_accesslog_v3_AccessLogFilter_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *envoy_config_accesslog_v3_AccessLogFilter_serialize(const envoy_config_accesslog_v3_AccessLogFilter *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &envoy_config_accesslog_v3_AccessLogFilter_msginit, arena, len);
 }
@@ -369,18 +383,25 @@ UPB_INLINE envoy_config_accesslog_v3_ComparisonFilter *envoy_config_accesslog_v3
   envoy_config_accesslog_v3_ComparisonFilter *ret = envoy_config_accesslog_v3_ComparisonFilter_new(arena);
   return (ret && upb_decode(buf, size, ret, &envoy_config_accesslog_v3_ComparisonFilter_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE envoy_config_accesslog_v3_ComparisonFilter *envoy_config_accesslog_v3_ComparisonFilter_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  envoy_config_accesslog_v3_ComparisonFilter *ret = envoy_config_accesslog_v3_ComparisonFilter_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &envoy_config_accesslog_v3_ComparisonFilter_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *envoy_config_accesslog_v3_ComparisonFilter_serialize(const envoy_config_accesslog_v3_ComparisonFilter *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &envoy_config_accesslog_v3_ComparisonFilter_msginit, arena, len);
 }
 
-UPB_INLINE int32_t envoy_config_accesslog_v3_ComparisonFilter_op(const envoy_config_accesslog_v3_ComparisonFilter *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(0, 0), int32_t); }
-UPB_INLINE bool envoy_config_accesslog_v3_ComparisonFilter_has_value(const envoy_config_accesslog_v3_ComparisonFilter *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(8, 8)); }
+UPB_INLINE int32_t envoy_config_accesslog_v3_ComparisonFilter_op(const envoy_config_accesslog_v3_ComparisonFilter *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(4, 4), int32_t); }
+UPB_INLINE bool envoy_config_accesslog_v3_ComparisonFilter_has_value(const envoy_config_accesslog_v3_ComparisonFilter *msg) { return _upb_hasbit(msg, 1); }
 UPB_INLINE const struct envoy_config_core_v3_RuntimeUInt32* envoy_config_accesslog_v3_ComparisonFilter_value(const envoy_config_accesslog_v3_ComparisonFilter *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(8, 8), const struct envoy_config_core_v3_RuntimeUInt32*); }
 
 UPB_INLINE void envoy_config_accesslog_v3_ComparisonFilter_set_op(envoy_config_accesslog_v3_ComparisonFilter *msg, int32_t value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(0, 0), int32_t) = value;
+  *UPB_PTR_AT(msg, UPB_SIZE(4, 4), int32_t) = value;
 }
 UPB_INLINE void envoy_config_accesslog_v3_ComparisonFilter_set_value(envoy_config_accesslog_v3_ComparisonFilter *msg, struct envoy_config_core_v3_RuntimeUInt32* value) {
+  _upb_sethas(msg, 1);
   *UPB_PTR_AT(msg, UPB_SIZE(8, 8), struct envoy_config_core_v3_RuntimeUInt32*) = value;
 }
 UPB_INLINE struct envoy_config_core_v3_RuntimeUInt32* envoy_config_accesslog_v3_ComparisonFilter_mutable_value(envoy_config_accesslog_v3_ComparisonFilter *msg, upb_arena *arena) {
@@ -403,15 +424,22 @@ UPB_INLINE envoy_config_accesslog_v3_StatusCodeFilter *envoy_config_accesslog_v3
   envoy_config_accesslog_v3_StatusCodeFilter *ret = envoy_config_accesslog_v3_StatusCodeFilter_new(arena);
   return (ret && upb_decode(buf, size, ret, &envoy_config_accesslog_v3_StatusCodeFilter_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE envoy_config_accesslog_v3_StatusCodeFilter *envoy_config_accesslog_v3_StatusCodeFilter_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  envoy_config_accesslog_v3_StatusCodeFilter *ret = envoy_config_accesslog_v3_StatusCodeFilter_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &envoy_config_accesslog_v3_StatusCodeFilter_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *envoy_config_accesslog_v3_StatusCodeFilter_serialize(const envoy_config_accesslog_v3_StatusCodeFilter *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &envoy_config_accesslog_v3_StatusCodeFilter_msginit, arena, len);
 }
 
-UPB_INLINE bool envoy_config_accesslog_v3_StatusCodeFilter_has_comparison(const envoy_config_accesslog_v3_StatusCodeFilter *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(0, 0)); }
-UPB_INLINE const envoy_config_accesslog_v3_ComparisonFilter* envoy_config_accesslog_v3_StatusCodeFilter_comparison(const envoy_config_accesslog_v3_StatusCodeFilter *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(0, 0), const envoy_config_accesslog_v3_ComparisonFilter*); }
+UPB_INLINE bool envoy_config_accesslog_v3_StatusCodeFilter_has_comparison(const envoy_config_accesslog_v3_StatusCodeFilter *msg) { return _upb_hasbit(msg, 1); }
+UPB_INLINE const envoy_config_accesslog_v3_ComparisonFilter* envoy_config_accesslog_v3_StatusCodeFilter_comparison(const envoy_config_accesslog_v3_StatusCodeFilter *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(4, 8), const envoy_config_accesslog_v3_ComparisonFilter*); }
 
 UPB_INLINE void envoy_config_accesslog_v3_StatusCodeFilter_set_comparison(envoy_config_accesslog_v3_StatusCodeFilter *msg, envoy_config_accesslog_v3_ComparisonFilter* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(0, 0), envoy_config_accesslog_v3_ComparisonFilter*) = value;
+  _upb_sethas(msg, 1);
+  *UPB_PTR_AT(msg, UPB_SIZE(4, 8), envoy_config_accesslog_v3_ComparisonFilter*) = value;
 }
 UPB_INLINE struct envoy_config_accesslog_v3_ComparisonFilter* envoy_config_accesslog_v3_StatusCodeFilter_mutable_comparison(envoy_config_accesslog_v3_StatusCodeFilter *msg, upb_arena *arena) {
   struct envoy_config_accesslog_v3_ComparisonFilter* sub = (struct envoy_config_accesslog_v3_ComparisonFilter*)envoy_config_accesslog_v3_StatusCodeFilter_comparison(msg);
@@ -433,15 +461,22 @@ UPB_INLINE envoy_config_accesslog_v3_DurationFilter *envoy_config_accesslog_v3_D
   envoy_config_accesslog_v3_DurationFilter *ret = envoy_config_accesslog_v3_DurationFilter_new(arena);
   return (ret && upb_decode(buf, size, ret, &envoy_config_accesslog_v3_DurationFilter_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE envoy_config_accesslog_v3_DurationFilter *envoy_config_accesslog_v3_DurationFilter_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  envoy_config_accesslog_v3_DurationFilter *ret = envoy_config_accesslog_v3_DurationFilter_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &envoy_config_accesslog_v3_DurationFilter_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *envoy_config_accesslog_v3_DurationFilter_serialize(const envoy_config_accesslog_v3_DurationFilter *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &envoy_config_accesslog_v3_DurationFilter_msginit, arena, len);
 }
 
-UPB_INLINE bool envoy_config_accesslog_v3_DurationFilter_has_comparison(const envoy_config_accesslog_v3_DurationFilter *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(0, 0)); }
-UPB_INLINE const envoy_config_accesslog_v3_ComparisonFilter* envoy_config_accesslog_v3_DurationFilter_comparison(const envoy_config_accesslog_v3_DurationFilter *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(0, 0), const envoy_config_accesslog_v3_ComparisonFilter*); }
+UPB_INLINE bool envoy_config_accesslog_v3_DurationFilter_has_comparison(const envoy_config_accesslog_v3_DurationFilter *msg) { return _upb_hasbit(msg, 1); }
+UPB_INLINE const envoy_config_accesslog_v3_ComparisonFilter* envoy_config_accesslog_v3_DurationFilter_comparison(const envoy_config_accesslog_v3_DurationFilter *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(4, 8), const envoy_config_accesslog_v3_ComparisonFilter*); }
 
 UPB_INLINE void envoy_config_accesslog_v3_DurationFilter_set_comparison(envoy_config_accesslog_v3_DurationFilter *msg, envoy_config_accesslog_v3_ComparisonFilter* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(0, 0), envoy_config_accesslog_v3_ComparisonFilter*) = value;
+  _upb_sethas(msg, 1);
+  *UPB_PTR_AT(msg, UPB_SIZE(4, 8), envoy_config_accesslog_v3_ComparisonFilter*) = value;
 }
 UPB_INLINE struct envoy_config_accesslog_v3_ComparisonFilter* envoy_config_accesslog_v3_DurationFilter_mutable_comparison(envoy_config_accesslog_v3_DurationFilter *msg, upb_arena *arena) {
   struct envoy_config_accesslog_v3_ComparisonFilter* sub = (struct envoy_config_accesslog_v3_ComparisonFilter*)envoy_config_accesslog_v3_DurationFilter_comparison(msg);
@@ -463,6 +498,12 @@ UPB_INLINE envoy_config_accesslog_v3_NotHealthCheckFilter *envoy_config_accesslo
   envoy_config_accesslog_v3_NotHealthCheckFilter *ret = envoy_config_accesslog_v3_NotHealthCheckFilter_new(arena);
   return (ret && upb_decode(buf, size, ret, &envoy_config_accesslog_v3_NotHealthCheckFilter_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE envoy_config_accesslog_v3_NotHealthCheckFilter *envoy_config_accesslog_v3_NotHealthCheckFilter_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  envoy_config_accesslog_v3_NotHealthCheckFilter *ret = envoy_config_accesslog_v3_NotHealthCheckFilter_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &envoy_config_accesslog_v3_NotHealthCheckFilter_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *envoy_config_accesslog_v3_NotHealthCheckFilter_serialize(const envoy_config_accesslog_v3_NotHealthCheckFilter *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &envoy_config_accesslog_v3_NotHealthCheckFilter_msginit, arena, len);
 }
@@ -479,6 +520,12 @@ UPB_INLINE envoy_config_accesslog_v3_TraceableFilter *envoy_config_accesslog_v3_
   envoy_config_accesslog_v3_TraceableFilter *ret = envoy_config_accesslog_v3_TraceableFilter_new(arena);
   return (ret && upb_decode(buf, size, ret, &envoy_config_accesslog_v3_TraceableFilter_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE envoy_config_accesslog_v3_TraceableFilter *envoy_config_accesslog_v3_TraceableFilter_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  envoy_config_accesslog_v3_TraceableFilter *ret = envoy_config_accesslog_v3_TraceableFilter_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &envoy_config_accesslog_v3_TraceableFilter_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *envoy_config_accesslog_v3_TraceableFilter_serialize(const envoy_config_accesslog_v3_TraceableFilter *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &envoy_config_accesslog_v3_TraceableFilter_msginit, arena, len);
 }
@@ -495,19 +542,26 @@ UPB_INLINE envoy_config_accesslog_v3_RuntimeFilter *envoy_config_accesslog_v3_Ru
   envoy_config_accesslog_v3_RuntimeFilter *ret = envoy_config_accesslog_v3_RuntimeFilter_new(arena);
   return (ret && upb_decode(buf, size, ret, &envoy_config_accesslog_v3_RuntimeFilter_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE envoy_config_accesslog_v3_RuntimeFilter *envoy_config_accesslog_v3_RuntimeFilter_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  envoy_config_accesslog_v3_RuntimeFilter *ret = envoy_config_accesslog_v3_RuntimeFilter_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &envoy_config_accesslog_v3_RuntimeFilter_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *envoy_config_accesslog_v3_RuntimeFilter_serialize(const envoy_config_accesslog_v3_RuntimeFilter *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &envoy_config_accesslog_v3_RuntimeFilter_msginit, arena, len);
 }
 
 UPB_INLINE upb_strview envoy_config_accesslog_v3_RuntimeFilter_runtime_key(const envoy_config_accesslog_v3_RuntimeFilter *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(4, 8), upb_strview); }
-UPB_INLINE bool envoy_config_accesslog_v3_RuntimeFilter_has_percent_sampled(const envoy_config_accesslog_v3_RuntimeFilter *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(12, 24)); }
+UPB_INLINE bool envoy_config_accesslog_v3_RuntimeFilter_has_percent_sampled(const envoy_config_accesslog_v3_RuntimeFilter *msg) { return _upb_hasbit(msg, 1); }
 UPB_INLINE const struct envoy_type_v3_FractionalPercent* envoy_config_accesslog_v3_RuntimeFilter_percent_sampled(const envoy_config_accesslog_v3_RuntimeFilter *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(12, 24), const struct envoy_type_v3_FractionalPercent*); }
-UPB_INLINE bool envoy_config_accesslog_v3_RuntimeFilter_use_independent_randomness(const envoy_config_accesslog_v3_RuntimeFilter *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(0, 0), bool); }
+UPB_INLINE bool envoy_config_accesslog_v3_RuntimeFilter_use_independent_randomness(const envoy_config_accesslog_v3_RuntimeFilter *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(1, 1), bool); }
 
 UPB_INLINE void envoy_config_accesslog_v3_RuntimeFilter_set_runtime_key(envoy_config_accesslog_v3_RuntimeFilter *msg, upb_strview value) {
   *UPB_PTR_AT(msg, UPB_SIZE(4, 8), upb_strview) = value;
 }
 UPB_INLINE void envoy_config_accesslog_v3_RuntimeFilter_set_percent_sampled(envoy_config_accesslog_v3_RuntimeFilter *msg, struct envoy_type_v3_FractionalPercent* value) {
+  _upb_sethas(msg, 1);
   *UPB_PTR_AT(msg, UPB_SIZE(12, 24), struct envoy_type_v3_FractionalPercent*) = value;
 }
 UPB_INLINE struct envoy_type_v3_FractionalPercent* envoy_config_accesslog_v3_RuntimeFilter_mutable_percent_sampled(envoy_config_accesslog_v3_RuntimeFilter *msg, upb_arena *arena) {
@@ -520,7 +574,7 @@ UPB_INLINE struct envoy_type_v3_FractionalPercent* envoy_config_accesslog_v3_Run
   return sub;
 }
 UPB_INLINE void envoy_config_accesslog_v3_RuntimeFilter_set_use_independent_randomness(envoy_config_accesslog_v3_RuntimeFilter *msg, bool value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(0, 0), bool) = value;
+  *UPB_PTR_AT(msg, UPB_SIZE(1, 1), bool) = value;
 }
 
 /* envoy.config.accesslog.v3.AndFilter */
@@ -533,6 +587,12 @@ UPB_INLINE envoy_config_accesslog_v3_AndFilter *envoy_config_accesslog_v3_AndFil
   envoy_config_accesslog_v3_AndFilter *ret = envoy_config_accesslog_v3_AndFilter_new(arena);
   return (ret && upb_decode(buf, size, ret, &envoy_config_accesslog_v3_AndFilter_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE envoy_config_accesslog_v3_AndFilter *envoy_config_accesslog_v3_AndFilter_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  envoy_config_accesslog_v3_AndFilter *ret = envoy_config_accesslog_v3_AndFilter_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &envoy_config_accesslog_v3_AndFilter_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *envoy_config_accesslog_v3_AndFilter_serialize(const envoy_config_accesslog_v3_AndFilter *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &envoy_config_accesslog_v3_AndFilter_msginit, arena, len);
 }
@@ -544,12 +604,12 @@ UPB_INLINE envoy_config_accesslog_v3_AccessLogFilter** envoy_config_accesslog_v3
   return (envoy_config_accesslog_v3_AccessLogFilter**)_upb_array_mutable_accessor(msg, UPB_SIZE(0, 0), len);
 }
 UPB_INLINE envoy_config_accesslog_v3_AccessLogFilter** envoy_config_accesslog_v3_AndFilter_resize_filters(envoy_config_accesslog_v3_AndFilter *msg, size_t len, upb_arena *arena) {
-  return (envoy_config_accesslog_v3_AccessLogFilter**)_upb_array_resize_accessor(msg, UPB_SIZE(0, 0), len, UPB_TYPE_MESSAGE, arena);
+  return (envoy_config_accesslog_v3_AccessLogFilter**)_upb_array_resize_accessor2(msg, UPB_SIZE(0, 0), len, UPB_SIZE(2, 3), arena);
 }
 UPB_INLINE struct envoy_config_accesslog_v3_AccessLogFilter* envoy_config_accesslog_v3_AndFilter_add_filters(envoy_config_accesslog_v3_AndFilter *msg, upb_arena *arena) {
   struct envoy_config_accesslog_v3_AccessLogFilter* sub = (struct envoy_config_accesslog_v3_AccessLogFilter*)_upb_msg_new(&envoy_config_accesslog_v3_AccessLogFilter_msginit, arena);
-  bool ok = _upb_array_append_accessor(
-      msg, UPB_SIZE(0, 0), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena);
+  bool ok = _upb_array_append_accessor2(
+      msg, UPB_SIZE(0, 0), UPB_SIZE(2, 3), &sub, arena);
   if (!ok) return NULL;
   return sub;
 }
@@ -564,6 +624,12 @@ UPB_INLINE envoy_config_accesslog_v3_OrFilter *envoy_config_accesslog_v3_OrFilte
   envoy_config_accesslog_v3_OrFilter *ret = envoy_config_accesslog_v3_OrFilter_new(arena);
   return (ret && upb_decode(buf, size, ret, &envoy_config_accesslog_v3_OrFilter_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE envoy_config_accesslog_v3_OrFilter *envoy_config_accesslog_v3_OrFilter_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  envoy_config_accesslog_v3_OrFilter *ret = envoy_config_accesslog_v3_OrFilter_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &envoy_config_accesslog_v3_OrFilter_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *envoy_config_accesslog_v3_OrFilter_serialize(const envoy_config_accesslog_v3_OrFilter *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &envoy_config_accesslog_v3_OrFilter_msginit, arena, len);
 }
@@ -575,12 +641,12 @@ UPB_INLINE envoy_config_accesslog_v3_AccessLogFilter** envoy_config_accesslog_v3
   return (envoy_config_accesslog_v3_AccessLogFilter**)_upb_array_mutable_accessor(msg, UPB_SIZE(0, 0), len);
 }
 UPB_INLINE envoy_config_accesslog_v3_AccessLogFilter** envoy_config_accesslog_v3_OrFilter_resize_filters(envoy_config_accesslog_v3_OrFilter *msg, size_t len, upb_arena *arena) {
-  return (envoy_config_accesslog_v3_AccessLogFilter**)_upb_array_resize_accessor(msg, UPB_SIZE(0, 0), len, UPB_TYPE_MESSAGE, arena);
+  return (envoy_config_accesslog_v3_AccessLogFilter**)_upb_array_resize_accessor2(msg, UPB_SIZE(0, 0), len, UPB_SIZE(2, 3), arena);
 }
 UPB_INLINE struct envoy_config_accesslog_v3_AccessLogFilter* envoy_config_accesslog_v3_OrFilter_add_filters(envoy_config_accesslog_v3_OrFilter *msg, upb_arena *arena) {
   struct envoy_config_accesslog_v3_AccessLogFilter* sub = (struct envoy_config_accesslog_v3_AccessLogFilter*)_upb_msg_new(&envoy_config_accesslog_v3_AccessLogFilter_msginit, arena);
-  bool ok = _upb_array_append_accessor(
-      msg, UPB_SIZE(0, 0), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena);
+  bool ok = _upb_array_append_accessor2(
+      msg, UPB_SIZE(0, 0), UPB_SIZE(2, 3), &sub, arena);
   if (!ok) return NULL;
   return sub;
 }
@@ -595,15 +661,22 @@ UPB_INLINE envoy_config_accesslog_v3_HeaderFilter *envoy_config_accesslog_v3_Hea
   envoy_config_accesslog_v3_HeaderFilter *ret = envoy_config_accesslog_v3_HeaderFilter_new(arena);
   return (ret && upb_decode(buf, size, ret, &envoy_config_accesslog_v3_HeaderFilter_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE envoy_config_accesslog_v3_HeaderFilter *envoy_config_accesslog_v3_HeaderFilter_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  envoy_config_accesslog_v3_HeaderFilter *ret = envoy_config_accesslog_v3_HeaderFilter_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &envoy_config_accesslog_v3_HeaderFilter_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *envoy_config_accesslog_v3_HeaderFilter_serialize(const envoy_config_accesslog_v3_HeaderFilter *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &envoy_config_accesslog_v3_HeaderFilter_msginit, arena, len);
 }
 
-UPB_INLINE bool envoy_config_accesslog_v3_HeaderFilter_has_header(const envoy_config_accesslog_v3_HeaderFilter *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(0, 0)); }
-UPB_INLINE const struct envoy_config_route_v3_HeaderMatcher* envoy_config_accesslog_v3_HeaderFilter_header(const envoy_config_accesslog_v3_HeaderFilter *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(0, 0), const struct envoy_config_route_v3_HeaderMatcher*); }
+UPB_INLINE bool envoy_config_accesslog_v3_HeaderFilter_has_header(const envoy_config_accesslog_v3_HeaderFilter *msg) { return _upb_hasbit(msg, 1); }
+UPB_INLINE const struct envoy_config_route_v3_HeaderMatcher* envoy_config_accesslog_v3_HeaderFilter_header(const envoy_config_accesslog_v3_HeaderFilter *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(4, 8), const struct envoy_config_route_v3_HeaderMatcher*); }
 
 UPB_INLINE void envoy_config_accesslog_v3_HeaderFilter_set_header(envoy_config_accesslog_v3_HeaderFilter *msg, struct envoy_config_route_v3_HeaderMatcher* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(0, 0), struct envoy_config_route_v3_HeaderMatcher*) = value;
+  _upb_sethas(msg, 1);
+  *UPB_PTR_AT(msg, UPB_SIZE(4, 8), struct envoy_config_route_v3_HeaderMatcher*) = value;
 }
 UPB_INLINE struct envoy_config_route_v3_HeaderMatcher* envoy_config_accesslog_v3_HeaderFilter_mutable_header(envoy_config_accesslog_v3_HeaderFilter *msg, upb_arena *arena) {
   struct envoy_config_route_v3_HeaderMatcher* sub = (struct envoy_config_route_v3_HeaderMatcher*)envoy_config_accesslog_v3_HeaderFilter_header(msg);
@@ -625,6 +698,12 @@ UPB_INLINE envoy_config_accesslog_v3_ResponseFlagFilter *envoy_config_accesslog_
   envoy_config_accesslog_v3_ResponseFlagFilter *ret = envoy_config_accesslog_v3_ResponseFlagFilter_new(arena);
   return (ret && upb_decode(buf, size, ret, &envoy_config_accesslog_v3_ResponseFlagFilter_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE envoy_config_accesslog_v3_ResponseFlagFilter *envoy_config_accesslog_v3_ResponseFlagFilter_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  envoy_config_accesslog_v3_ResponseFlagFilter *ret = envoy_config_accesslog_v3_ResponseFlagFilter_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &envoy_config_accesslog_v3_ResponseFlagFilter_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *envoy_config_accesslog_v3_ResponseFlagFilter_serialize(const envoy_config_accesslog_v3_ResponseFlagFilter *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &envoy_config_accesslog_v3_ResponseFlagFilter_msginit, arena, len);
 }
@@ -635,10 +714,10 @@ UPB_INLINE upb_strview* envoy_config_accesslog_v3_ResponseFlagFilter_mutable_fla
   return (upb_strview*)_upb_array_mutable_accessor(msg, UPB_SIZE(0, 0), len);
 }
 UPB_INLINE upb_strview* envoy_config_accesslog_v3_ResponseFlagFilter_resize_flags(envoy_config_accesslog_v3_ResponseFlagFilter *msg, size_t len, upb_arena *arena) {
-  return (upb_strview*)_upb_array_resize_accessor(msg, UPB_SIZE(0, 0), len, UPB_TYPE_STRING, arena);
+  return (upb_strview*)_upb_array_resize_accessor2(msg, UPB_SIZE(0, 0), len, UPB_SIZE(3, 4), arena);
 }
 UPB_INLINE bool envoy_config_accesslog_v3_ResponseFlagFilter_add_flags(envoy_config_accesslog_v3_ResponseFlagFilter *msg, upb_strview val, upb_arena *arena) {
-  return _upb_array_append_accessor(msg, UPB_SIZE(0, 0), UPB_SIZE(8, 16), UPB_TYPE_STRING, &val,
+  return _upb_array_append_accessor2(msg, UPB_SIZE(0, 0), UPB_SIZE(3, 4), &val,
       arena);
 }
 
@@ -652,6 +731,12 @@ UPB_INLINE envoy_config_accesslog_v3_GrpcStatusFilter *envoy_config_accesslog_v3
   envoy_config_accesslog_v3_GrpcStatusFilter *ret = envoy_config_accesslog_v3_GrpcStatusFilter_new(arena);
   return (ret && upb_decode(buf, size, ret, &envoy_config_accesslog_v3_GrpcStatusFilter_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE envoy_config_accesslog_v3_GrpcStatusFilter *envoy_config_accesslog_v3_GrpcStatusFilter_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  envoy_config_accesslog_v3_GrpcStatusFilter *ret = envoy_config_accesslog_v3_GrpcStatusFilter_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &envoy_config_accesslog_v3_GrpcStatusFilter_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *envoy_config_accesslog_v3_GrpcStatusFilter_serialize(const envoy_config_accesslog_v3_GrpcStatusFilter *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &envoy_config_accesslog_v3_GrpcStatusFilter_msginit, arena, len);
 }
@@ -663,10 +748,10 @@ UPB_INLINE int32_t* envoy_config_accesslog_v3_GrpcStatusFilter_mutable_statuses(
   return (int32_t*)_upb_array_mutable_accessor(msg, UPB_SIZE(4, 8), len);
 }
 UPB_INLINE int32_t* envoy_config_accesslog_v3_GrpcStatusFilter_resize_statuses(envoy_config_accesslog_v3_GrpcStatusFilter *msg, size_t len, upb_arena *arena) {
-  return (int32_t*)_upb_array_resize_accessor(msg, UPB_SIZE(4, 8), len, UPB_TYPE_ENUM, arena);
+  return (int32_t*)_upb_array_resize_accessor2(msg, UPB_SIZE(4, 8), len, 2, arena);
 }
 UPB_INLINE bool envoy_config_accesslog_v3_GrpcStatusFilter_add_statuses(envoy_config_accesslog_v3_GrpcStatusFilter *msg, int32_t val, upb_arena *arena) {
-  return _upb_array_append_accessor(msg, UPB_SIZE(4, 8), UPB_SIZE(8, 8), UPB_TYPE_ENUM, &val,
+  return _upb_array_append_accessor2(msg, UPB_SIZE(4, 8), 2, &val,
       arena);
 }
 UPB_INLINE void envoy_config_accesslog_v3_GrpcStatusFilter_set_exclude(envoy_config_accesslog_v3_GrpcStatusFilter *msg, bool value) {
@@ -683,17 +768,24 @@ UPB_INLINE envoy_config_accesslog_v3_MetadataFilter *envoy_config_accesslog_v3_M
   envoy_config_accesslog_v3_MetadataFilter *ret = envoy_config_accesslog_v3_MetadataFilter_new(arena);
   return (ret && upb_decode(buf, size, ret, &envoy_config_accesslog_v3_MetadataFilter_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE envoy_config_accesslog_v3_MetadataFilter *envoy_config_accesslog_v3_MetadataFilter_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  envoy_config_accesslog_v3_MetadataFilter *ret = envoy_config_accesslog_v3_MetadataFilter_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &envoy_config_accesslog_v3_MetadataFilter_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *envoy_config_accesslog_v3_MetadataFilter_serialize(const envoy_config_accesslog_v3_MetadataFilter *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &envoy_config_accesslog_v3_MetadataFilter_msginit, arena, len);
 }
 
-UPB_INLINE bool envoy_config_accesslog_v3_MetadataFilter_has_matcher(const envoy_config_accesslog_v3_MetadataFilter *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(0, 0)); }
-UPB_INLINE const struct envoy_type_matcher_v3_MetadataMatcher* envoy_config_accesslog_v3_MetadataFilter_matcher(const envoy_config_accesslog_v3_MetadataFilter *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(0, 0), const struct envoy_type_matcher_v3_MetadataMatcher*); }
-UPB_INLINE bool envoy_config_accesslog_v3_MetadataFilter_has_match_if_key_not_found(const envoy_config_accesslog_v3_MetadataFilter *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(4, 8)); }
-UPB_INLINE const struct google_protobuf_BoolValue* envoy_config_accesslog_v3_MetadataFilter_match_if_key_not_found(const envoy_config_accesslog_v3_MetadataFilter *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(4, 8), const struct google_protobuf_BoolValue*); }
+UPB_INLINE bool envoy_config_accesslog_v3_MetadataFilter_has_matcher(const envoy_config_accesslog_v3_MetadataFilter *msg) { return _upb_hasbit(msg, 1); }
+UPB_INLINE const struct envoy_type_matcher_v3_MetadataMatcher* envoy_config_accesslog_v3_MetadataFilter_matcher(const envoy_config_accesslog_v3_MetadataFilter *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(4, 8), const struct envoy_type_matcher_v3_MetadataMatcher*); }
+UPB_INLINE bool envoy_config_accesslog_v3_MetadataFilter_has_match_if_key_not_found(const envoy_config_accesslog_v3_MetadataFilter *msg) { return _upb_hasbit(msg, 2); }
+UPB_INLINE const struct google_protobuf_BoolValue* envoy_config_accesslog_v3_MetadataFilter_match_if_key_not_found(const envoy_config_accesslog_v3_MetadataFilter *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(8, 16), const struct google_protobuf_BoolValue*); }
 
 UPB_INLINE void envoy_config_accesslog_v3_MetadataFilter_set_matcher(envoy_config_accesslog_v3_MetadataFilter *msg, struct envoy_type_matcher_v3_MetadataMatcher* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(0, 0), struct envoy_type_matcher_v3_MetadataMatcher*) = value;
+  _upb_sethas(msg, 1);
+  *UPB_PTR_AT(msg, UPB_SIZE(4, 8), struct envoy_type_matcher_v3_MetadataMatcher*) = value;
 }
 UPB_INLINE struct envoy_type_matcher_v3_MetadataMatcher* envoy_config_accesslog_v3_MetadataFilter_mutable_matcher(envoy_config_accesslog_v3_MetadataFilter *msg, upb_arena *arena) {
   struct envoy_type_matcher_v3_MetadataMatcher* sub = (struct envoy_type_matcher_v3_MetadataMatcher*)envoy_config_accesslog_v3_MetadataFilter_matcher(msg);
@@ -705,7 +797,8 @@ UPB_INLINE struct envoy_type_matcher_v3_MetadataMatcher* envoy_config_accesslog_
   return sub;
 }
 UPB_INLINE void envoy_config_accesslog_v3_MetadataFilter_set_match_if_key_not_found(envoy_config_accesslog_v3_MetadataFilter *msg, struct google_protobuf_BoolValue* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(4, 8), struct google_protobuf_BoolValue*) = value;
+  _upb_sethas(msg, 2);
+  *UPB_PTR_AT(msg, UPB_SIZE(8, 16), struct google_protobuf_BoolValue*) = value;
 }
 UPB_INLINE struct google_protobuf_BoolValue* envoy_config_accesslog_v3_MetadataFilter_mutable_match_if_key_not_found(envoy_config_accesslog_v3_MetadataFilter *msg, upb_arena *arena) {
   struct google_protobuf_BoolValue* sub = (struct google_protobuf_BoolValue*)envoy_config_accesslog_v3_MetadataFilter_match_if_key_not_found(msg);
@@ -727,6 +820,12 @@ UPB_INLINE envoy_config_accesslog_v3_ExtensionFilter *envoy_config_accesslog_v3_
   envoy_config_accesslog_v3_ExtensionFilter *ret = envoy_config_accesslog_v3_ExtensionFilter_new(arena);
   return (ret && upb_decode(buf, size, ret, &envoy_config_accesslog_v3_ExtensionFilter_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE envoy_config_accesslog_v3_ExtensionFilter *envoy_config_accesslog_v3_ExtensionFilter_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  envoy_config_accesslog_v3_ExtensionFilter *ret = envoy_config_accesslog_v3_ExtensionFilter_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &envoy_config_accesslog_v3_ExtensionFilter_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *envoy_config_accesslog_v3_ExtensionFilter_serialize(const envoy_config_accesslog_v3_ExtensionFilter *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &envoy_config_accesslog_v3_ExtensionFilter_msginit, arena, len);
 }
index 26304e4..b3f086d 100644 (file)
@@ -29,29 +29,29 @@ static const upb_msglayout_field envoy_config_cluster_v3_CircuitBreakers__fields
 const upb_msglayout envoy_config_cluster_v3_CircuitBreakers_msginit = {
   &envoy_config_cluster_v3_CircuitBreakers_submsgs[0],
   &envoy_config_cluster_v3_CircuitBreakers__fields[0],
-  UPB_SIZE(4, 8), 1, false,
+  UPB_SIZE(8, 8), 1, false, 255,
 };
 
-static const upb_msglayout *const envoy_config_cluster_v3_CircuitBreakers_Thresholds_submsgs[6] = {
+static const upb_msglayout *const envoy_config_cluster_v3_CircuitBreakers_Thresholds_submsgs[2] = {
   &envoy_config_cluster_v3_CircuitBreakers_Thresholds_RetryBudget_msginit,
   &google_protobuf_UInt32Value_msginit,
 };
 
 static const upb_msglayout_field envoy_config_cluster_v3_CircuitBreakers_Thresholds__fields[8] = {
-  {1, UPB_SIZE(0, 0), 0, 0, 14, 1},
-  {2, UPB_SIZE(12, 16), 0, 1, 11, 1},
-  {3, UPB_SIZE(16, 24), 0, 1, 11, 1},
-  {4, UPB_SIZE(20, 32), 0, 1, 11, 1},
-  {5, UPB_SIZE(24, 40), 0, 1, 11, 1},
+  {1, UPB_SIZE(4, 4), 0, 0, 14, 1},
+  {2, UPB_SIZE(12, 16), 1, 1, 11, 1},
+  {3, UPB_SIZE(16, 24), 2, 1, 11, 1},
+  {4, UPB_SIZE(20, 32), 3, 1, 11, 1},
+  {5, UPB_SIZE(24, 40), 4, 1, 11, 1},
   {6, UPB_SIZE(8, 8), 0, 0, 8, 1},
-  {7, UPB_SIZE(28, 48), 0, 1, 11, 1},
-  {8, UPB_SIZE(32, 56), 0, 0, 11, 1},
+  {7, UPB_SIZE(28, 48), 5, 1, 11, 1},
+  {8, UPB_SIZE(32, 56), 6, 0, 11, 1},
 };
 
 const upb_msglayout envoy_config_cluster_v3_CircuitBreakers_Thresholds_msginit = {
   &envoy_config_cluster_v3_CircuitBreakers_Thresholds_submsgs[0],
   &envoy_config_cluster_v3_CircuitBreakers_Thresholds__fields[0],
-  UPB_SIZE(40, 64), 8, false,
+  UPB_SIZE(40, 64), 8, false, 255,
 };
 
 static const upb_msglayout *const envoy_config_cluster_v3_CircuitBreakers_Thresholds_RetryBudget_submsgs[2] = {
@@ -60,14 +60,14 @@ static const upb_msglayout *const envoy_config_cluster_v3_CircuitBreakers_Thresh
 };
 
 static const upb_msglayout_field envoy_config_cluster_v3_CircuitBreakers_Thresholds_RetryBudget__fields[2] = {
-  {1, UPB_SIZE(0, 0), 0, 0, 11, 1},
-  {2, UPB_SIZE(4, 8), 0, 1, 11, 1},
+  {1, UPB_SIZE(4, 8), 1, 0, 11, 1},
+  {2, UPB_SIZE(8, 16), 2, 1, 11, 1},
 };
 
 const upb_msglayout envoy_config_cluster_v3_CircuitBreakers_Thresholds_RetryBudget_msginit = {
   &envoy_config_cluster_v3_CircuitBreakers_Thresholds_RetryBudget_submsgs[0],
   &envoy_config_cluster_v3_CircuitBreakers_Thresholds_RetryBudget__fields[0],
-  UPB_SIZE(8, 16), 2, false,
+  UPB_SIZE(16, 24), 2, false, 255,
 };
 
 #include "upb/port_undef.inc"
index c2da177..8d60996 100644 (file)
@@ -11,6 +11,7 @@
 
 #include "upb/msg.h"
 #include "upb/decode.h"
+#include "upb/decode_fast.h"
 #include "upb/encode.h"
 
 #include "upb/port_def.inc"
@@ -44,6 +45,12 @@ UPB_INLINE envoy_config_cluster_v3_CircuitBreakers *envoy_config_cluster_v3_Circ
   envoy_config_cluster_v3_CircuitBreakers *ret = envoy_config_cluster_v3_CircuitBreakers_new(arena);
   return (ret && upb_decode(buf, size, ret, &envoy_config_cluster_v3_CircuitBreakers_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE envoy_config_cluster_v3_CircuitBreakers *envoy_config_cluster_v3_CircuitBreakers_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  envoy_config_cluster_v3_CircuitBreakers *ret = envoy_config_cluster_v3_CircuitBreakers_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &envoy_config_cluster_v3_CircuitBreakers_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *envoy_config_cluster_v3_CircuitBreakers_serialize(const envoy_config_cluster_v3_CircuitBreakers *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &envoy_config_cluster_v3_CircuitBreakers_msginit, arena, len);
 }
@@ -55,12 +62,12 @@ UPB_INLINE envoy_config_cluster_v3_CircuitBreakers_Thresholds** envoy_config_clu
   return (envoy_config_cluster_v3_CircuitBreakers_Thresholds**)_upb_array_mutable_accessor(msg, UPB_SIZE(0, 0), len);
 }
 UPB_INLINE envoy_config_cluster_v3_CircuitBreakers_Thresholds** envoy_config_cluster_v3_CircuitBreakers_resize_thresholds(envoy_config_cluster_v3_CircuitBreakers *msg, size_t len, upb_arena *arena) {
-  return (envoy_config_cluster_v3_CircuitBreakers_Thresholds**)_upb_array_resize_accessor(msg, UPB_SIZE(0, 0), len, UPB_TYPE_MESSAGE, arena);
+  return (envoy_config_cluster_v3_CircuitBreakers_Thresholds**)_upb_array_resize_accessor2(msg, UPB_SIZE(0, 0), len, UPB_SIZE(2, 3), arena);
 }
 UPB_INLINE struct envoy_config_cluster_v3_CircuitBreakers_Thresholds* envoy_config_cluster_v3_CircuitBreakers_add_thresholds(envoy_config_cluster_v3_CircuitBreakers *msg, upb_arena *arena) {
   struct envoy_config_cluster_v3_CircuitBreakers_Thresholds* sub = (struct envoy_config_cluster_v3_CircuitBreakers_Thresholds*)_upb_msg_new(&envoy_config_cluster_v3_CircuitBreakers_Thresholds_msginit, arena);
-  bool ok = _upb_array_append_accessor(
-      msg, UPB_SIZE(0, 0), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena);
+  bool ok = _upb_array_append_accessor2(
+      msg, UPB_SIZE(0, 0), UPB_SIZE(2, 3), &sub, arena);
   if (!ok) return NULL;
   return sub;
 }
@@ -75,29 +82,36 @@ UPB_INLINE envoy_config_cluster_v3_CircuitBreakers_Thresholds *envoy_config_clus
   envoy_config_cluster_v3_CircuitBreakers_Thresholds *ret = envoy_config_cluster_v3_CircuitBreakers_Thresholds_new(arena);
   return (ret && upb_decode(buf, size, ret, &envoy_config_cluster_v3_CircuitBreakers_Thresholds_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE envoy_config_cluster_v3_CircuitBreakers_Thresholds *envoy_config_cluster_v3_CircuitBreakers_Thresholds_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  envoy_config_cluster_v3_CircuitBreakers_Thresholds *ret = envoy_config_cluster_v3_CircuitBreakers_Thresholds_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &envoy_config_cluster_v3_CircuitBreakers_Thresholds_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *envoy_config_cluster_v3_CircuitBreakers_Thresholds_serialize(const envoy_config_cluster_v3_CircuitBreakers_Thresholds *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &envoy_config_cluster_v3_CircuitBreakers_Thresholds_msginit, arena, len);
 }
 
-UPB_INLINE int32_t envoy_config_cluster_v3_CircuitBreakers_Thresholds_priority(const envoy_config_cluster_v3_CircuitBreakers_Thresholds *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(0, 0), int32_t); }
-UPB_INLINE bool envoy_config_cluster_v3_CircuitBreakers_Thresholds_has_max_connections(const envoy_config_cluster_v3_CircuitBreakers_Thresholds *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(12, 16)); }
+UPB_INLINE int32_t envoy_config_cluster_v3_CircuitBreakers_Thresholds_priority(const envoy_config_cluster_v3_CircuitBreakers_Thresholds *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(4, 4), int32_t); }
+UPB_INLINE bool envoy_config_cluster_v3_CircuitBreakers_Thresholds_has_max_connections(const envoy_config_cluster_v3_CircuitBreakers_Thresholds *msg) { return _upb_hasbit(msg, 1); }
 UPB_INLINE const struct google_protobuf_UInt32Value* envoy_config_cluster_v3_CircuitBreakers_Thresholds_max_connections(const envoy_config_cluster_v3_CircuitBreakers_Thresholds *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(12, 16), const struct google_protobuf_UInt32Value*); }
-UPB_INLINE bool envoy_config_cluster_v3_CircuitBreakers_Thresholds_has_max_pending_requests(const envoy_config_cluster_v3_CircuitBreakers_Thresholds *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(16, 24)); }
+UPB_INLINE bool envoy_config_cluster_v3_CircuitBreakers_Thresholds_has_max_pending_requests(const envoy_config_cluster_v3_CircuitBreakers_Thresholds *msg) { return _upb_hasbit(msg, 2); }
 UPB_INLINE const struct google_protobuf_UInt32Value* envoy_config_cluster_v3_CircuitBreakers_Thresholds_max_pending_requests(const envoy_config_cluster_v3_CircuitBreakers_Thresholds *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(16, 24), const struct google_protobuf_UInt32Value*); }
-UPB_INLINE bool envoy_config_cluster_v3_CircuitBreakers_Thresholds_has_max_requests(const envoy_config_cluster_v3_CircuitBreakers_Thresholds *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(20, 32)); }
+UPB_INLINE bool envoy_config_cluster_v3_CircuitBreakers_Thresholds_has_max_requests(const envoy_config_cluster_v3_CircuitBreakers_Thresholds *msg) { return _upb_hasbit(msg, 3); }
 UPB_INLINE const struct google_protobuf_UInt32Value* envoy_config_cluster_v3_CircuitBreakers_Thresholds_max_requests(const envoy_config_cluster_v3_CircuitBreakers_Thresholds *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(20, 32), const struct google_protobuf_UInt32Value*); }
-UPB_INLINE bool envoy_config_cluster_v3_CircuitBreakers_Thresholds_has_max_retries(const envoy_config_cluster_v3_CircuitBreakers_Thresholds *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(24, 40)); }
+UPB_INLINE bool envoy_config_cluster_v3_CircuitBreakers_Thresholds_has_max_retries(const envoy_config_cluster_v3_CircuitBreakers_Thresholds *msg) { return _upb_hasbit(msg, 4); }
 UPB_INLINE const struct google_protobuf_UInt32Value* envoy_config_cluster_v3_CircuitBreakers_Thresholds_max_retries(const envoy_config_cluster_v3_CircuitBreakers_Thresholds *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(24, 40), const struct google_protobuf_UInt32Value*); }
 UPB_INLINE bool envoy_config_cluster_v3_CircuitBreakers_Thresholds_track_remaining(const envoy_config_cluster_v3_CircuitBreakers_Thresholds *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(8, 8), bool); }
-UPB_INLINE bool envoy_config_cluster_v3_CircuitBreakers_Thresholds_has_max_connection_pools(const envoy_config_cluster_v3_CircuitBreakers_Thresholds *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(28, 48)); }
+UPB_INLINE bool envoy_config_cluster_v3_CircuitBreakers_Thresholds_has_max_connection_pools(const envoy_config_cluster_v3_CircuitBreakers_Thresholds *msg) { return _upb_hasbit(msg, 5); }
 UPB_INLINE const struct google_protobuf_UInt32Value* envoy_config_cluster_v3_CircuitBreakers_Thresholds_max_connection_pools(const envoy_config_cluster_v3_CircuitBreakers_Thresholds *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(28, 48), const struct google_protobuf_UInt32Value*); }
-UPB_INLINE bool envoy_config_cluster_v3_CircuitBreakers_Thresholds_has_retry_budget(const envoy_config_cluster_v3_CircuitBreakers_Thresholds *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(32, 56)); }
+UPB_INLINE bool envoy_config_cluster_v3_CircuitBreakers_Thresholds_has_retry_budget(const envoy_config_cluster_v3_CircuitBreakers_Thresholds *msg) { return _upb_hasbit(msg, 6); }
 UPB_INLINE const envoy_config_cluster_v3_CircuitBreakers_Thresholds_RetryBudget* envoy_config_cluster_v3_CircuitBreakers_Thresholds_retry_budget(const envoy_config_cluster_v3_CircuitBreakers_Thresholds *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(32, 56), const envoy_config_cluster_v3_CircuitBreakers_Thresholds_RetryBudget*); }
 
 UPB_INLINE void envoy_config_cluster_v3_CircuitBreakers_Thresholds_set_priority(envoy_config_cluster_v3_CircuitBreakers_Thresholds *msg, int32_t value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(0, 0), int32_t) = value;
+  *UPB_PTR_AT(msg, UPB_SIZE(4, 4), int32_t) = value;
 }
 UPB_INLINE void envoy_config_cluster_v3_CircuitBreakers_Thresholds_set_max_connections(envoy_config_cluster_v3_CircuitBreakers_Thresholds *msg, struct google_protobuf_UInt32Value* value) {
+  _upb_sethas(msg, 1);
   *UPB_PTR_AT(msg, UPB_SIZE(12, 16), struct google_protobuf_UInt32Value*) = value;
 }
 UPB_INLINE struct google_protobuf_UInt32Value* envoy_config_cluster_v3_CircuitBreakers_Thresholds_mutable_max_connections(envoy_config_cluster_v3_CircuitBreakers_Thresholds *msg, upb_arena *arena) {
@@ -110,6 +124,7 @@ UPB_INLINE struct google_protobuf_UInt32Value* envoy_config_cluster_v3_CircuitBr
   return sub;
 }
 UPB_INLINE void envoy_config_cluster_v3_CircuitBreakers_Thresholds_set_max_pending_requests(envoy_config_cluster_v3_CircuitBreakers_Thresholds *msg, struct google_protobuf_UInt32Value* value) {
+  _upb_sethas(msg, 2);
   *UPB_PTR_AT(msg, UPB_SIZE(16, 24), struct google_protobuf_UInt32Value*) = value;
 }
 UPB_INLINE struct google_protobuf_UInt32Value* envoy_config_cluster_v3_CircuitBreakers_Thresholds_mutable_max_pending_requests(envoy_config_cluster_v3_CircuitBreakers_Thresholds *msg, upb_arena *arena) {
@@ -122,6 +137,7 @@ UPB_INLINE struct google_protobuf_UInt32Value* envoy_config_cluster_v3_CircuitBr
   return sub;
 }
 UPB_INLINE void envoy_config_cluster_v3_CircuitBreakers_Thresholds_set_max_requests(envoy_config_cluster_v3_CircuitBreakers_Thresholds *msg, struct google_protobuf_UInt32Value* value) {
+  _upb_sethas(msg, 3);
   *UPB_PTR_AT(msg, UPB_SIZE(20, 32), struct google_protobuf_UInt32Value*) = value;
 }
 UPB_INLINE struct google_protobuf_UInt32Value* envoy_config_cluster_v3_CircuitBreakers_Thresholds_mutable_max_requests(envoy_config_cluster_v3_CircuitBreakers_Thresholds *msg, upb_arena *arena) {
@@ -134,6 +150,7 @@ UPB_INLINE struct google_protobuf_UInt32Value* envoy_config_cluster_v3_CircuitBr
   return sub;
 }
 UPB_INLINE void envoy_config_cluster_v3_CircuitBreakers_Thresholds_set_max_retries(envoy_config_cluster_v3_CircuitBreakers_Thresholds *msg, struct google_protobuf_UInt32Value* value) {
+  _upb_sethas(msg, 4);
   *UPB_PTR_AT(msg, UPB_SIZE(24, 40), struct google_protobuf_UInt32Value*) = value;
 }
 UPB_INLINE struct google_protobuf_UInt32Value* envoy_config_cluster_v3_CircuitBreakers_Thresholds_mutable_max_retries(envoy_config_cluster_v3_CircuitBreakers_Thresholds *msg, upb_arena *arena) {
@@ -149,6 +166,7 @@ UPB_INLINE void envoy_config_cluster_v3_CircuitBreakers_Thresholds_set_track_rem
   *UPB_PTR_AT(msg, UPB_SIZE(8, 8), bool) = value;
 }
 UPB_INLINE void envoy_config_cluster_v3_CircuitBreakers_Thresholds_set_max_connection_pools(envoy_config_cluster_v3_CircuitBreakers_Thresholds *msg, struct google_protobuf_UInt32Value* value) {
+  _upb_sethas(msg, 5);
   *UPB_PTR_AT(msg, UPB_SIZE(28, 48), struct google_protobuf_UInt32Value*) = value;
 }
 UPB_INLINE struct google_protobuf_UInt32Value* envoy_config_cluster_v3_CircuitBreakers_Thresholds_mutable_max_connection_pools(envoy_config_cluster_v3_CircuitBreakers_Thresholds *msg, upb_arena *arena) {
@@ -161,6 +179,7 @@ UPB_INLINE struct google_protobuf_UInt32Value* envoy_config_cluster_v3_CircuitBr
   return sub;
 }
 UPB_INLINE void envoy_config_cluster_v3_CircuitBreakers_Thresholds_set_retry_budget(envoy_config_cluster_v3_CircuitBreakers_Thresholds *msg, envoy_config_cluster_v3_CircuitBreakers_Thresholds_RetryBudget* value) {
+  _upb_sethas(msg, 6);
   *UPB_PTR_AT(msg, UPB_SIZE(32, 56), envoy_config_cluster_v3_CircuitBreakers_Thresholds_RetryBudget*) = value;
 }
 UPB_INLINE struct envoy_config_cluster_v3_CircuitBreakers_Thresholds_RetryBudget* envoy_config_cluster_v3_CircuitBreakers_Thresholds_mutable_retry_budget(envoy_config_cluster_v3_CircuitBreakers_Thresholds *msg, upb_arena *arena) {
@@ -183,17 +202,24 @@ UPB_INLINE envoy_config_cluster_v3_CircuitBreakers_Thresholds_RetryBudget *envoy
   envoy_config_cluster_v3_CircuitBreakers_Thresholds_RetryBudget *ret = envoy_config_cluster_v3_CircuitBreakers_Thresholds_RetryBudget_new(arena);
   return (ret && upb_decode(buf, size, ret, &envoy_config_cluster_v3_CircuitBreakers_Thresholds_RetryBudget_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE envoy_config_cluster_v3_CircuitBreakers_Thresholds_RetryBudget *envoy_config_cluster_v3_CircuitBreakers_Thresholds_RetryBudget_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  envoy_config_cluster_v3_CircuitBreakers_Thresholds_RetryBudget *ret = envoy_config_cluster_v3_CircuitBreakers_Thresholds_RetryBudget_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &envoy_config_cluster_v3_CircuitBreakers_Thresholds_RetryBudget_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *envoy_config_cluster_v3_CircuitBreakers_Thresholds_RetryBudget_serialize(const envoy_config_cluster_v3_CircuitBreakers_Thresholds_RetryBudget *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &envoy_config_cluster_v3_CircuitBreakers_Thresholds_RetryBudget_msginit, arena, len);
 }
 
-UPB_INLINE bool envoy_config_cluster_v3_CircuitBreakers_Thresholds_RetryBudget_has_budget_percent(const envoy_config_cluster_v3_CircuitBreakers_Thresholds_RetryBudget *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(0, 0)); }
-UPB_INLINE const struct envoy_type_v3_Percent* envoy_config_cluster_v3_CircuitBreakers_Thresholds_RetryBudget_budget_percent(const envoy_config_cluster_v3_CircuitBreakers_Thresholds_RetryBudget *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(0, 0), const struct envoy_type_v3_Percent*); }
-UPB_INLINE bool envoy_config_cluster_v3_CircuitBreakers_Thresholds_RetryBudget_has_min_retry_concurrency(const envoy_config_cluster_v3_CircuitBreakers_Thresholds_RetryBudget *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(4, 8)); }
-UPB_INLINE const struct google_protobuf_UInt32Value* envoy_config_cluster_v3_CircuitBreakers_Thresholds_RetryBudget_min_retry_concurrency(const envoy_config_cluster_v3_CircuitBreakers_Thresholds_RetryBudget *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(4, 8), const struct google_protobuf_UInt32Value*); }
+UPB_INLINE bool envoy_config_cluster_v3_CircuitBreakers_Thresholds_RetryBudget_has_budget_percent(const envoy_config_cluster_v3_CircuitBreakers_Thresholds_RetryBudget *msg) { return _upb_hasbit(msg, 1); }
+UPB_INLINE const struct envoy_type_v3_Percent* envoy_config_cluster_v3_CircuitBreakers_Thresholds_RetryBudget_budget_percent(const envoy_config_cluster_v3_CircuitBreakers_Thresholds_RetryBudget *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(4, 8), const struct envoy_type_v3_Percent*); }
+UPB_INLINE bool envoy_config_cluster_v3_CircuitBreakers_Thresholds_RetryBudget_has_min_retry_concurrency(const envoy_config_cluster_v3_CircuitBreakers_Thresholds_RetryBudget *msg) { return _upb_hasbit(msg, 2); }
+UPB_INLINE const struct google_protobuf_UInt32Value* envoy_config_cluster_v3_CircuitBreakers_Thresholds_RetryBudget_min_retry_concurrency(const envoy_config_cluster_v3_CircuitBreakers_Thresholds_RetryBudget *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(8, 16), const struct google_protobuf_UInt32Value*); }
 
 UPB_INLINE void envoy_config_cluster_v3_CircuitBreakers_Thresholds_RetryBudget_set_budget_percent(envoy_config_cluster_v3_CircuitBreakers_Thresholds_RetryBudget *msg, struct envoy_type_v3_Percent* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(0, 0), struct envoy_type_v3_Percent*) = value;
+  _upb_sethas(msg, 1);
+  *UPB_PTR_AT(msg, UPB_SIZE(4, 8), struct envoy_type_v3_Percent*) = value;
 }
 UPB_INLINE struct envoy_type_v3_Percent* envoy_config_cluster_v3_CircuitBreakers_Thresholds_RetryBudget_mutable_budget_percent(envoy_config_cluster_v3_CircuitBreakers_Thresholds_RetryBudget *msg, upb_arena *arena) {
   struct envoy_type_v3_Percent* sub = (struct envoy_type_v3_Percent*)envoy_config_cluster_v3_CircuitBreakers_Thresholds_RetryBudget_budget_percent(msg);
@@ -205,7 +231,8 @@ UPB_INLINE struct envoy_type_v3_Percent* envoy_config_cluster_v3_CircuitBreakers
   return sub;
 }
 UPB_INLINE void envoy_config_cluster_v3_CircuitBreakers_Thresholds_RetryBudget_set_min_retry_concurrency(envoy_config_cluster_v3_CircuitBreakers_Thresholds_RetryBudget *msg, struct google_protobuf_UInt32Value* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(4, 8), struct google_protobuf_UInt32Value*) = value;
+  _upb_sethas(msg, 2);
+  *UPB_PTR_AT(msg, UPB_SIZE(8, 16), struct google_protobuf_UInt32Value*) = value;
 }
 UPB_INLINE struct google_protobuf_UInt32Value* envoy_config_cluster_v3_CircuitBreakers_Thresholds_RetryBudget_mutable_min_retry_concurrency(envoy_config_cluster_v3_CircuitBreakers_Thresholds_RetryBudget *msg, upb_arena *arena) {
   struct google_protobuf_UInt32Value* sub = (struct google_protobuf_UInt32Value*)envoy_config_cluster_v3_CircuitBreakers_Thresholds_RetryBudget_min_retry_concurrency(msg);
index 3add43b..10bdb30 100644 (file)
@@ -40,16 +40,16 @@ static const upb_msglayout *const envoy_config_cluster_v3_ClusterCollection_subm
 };
 
 static const upb_msglayout_field envoy_config_cluster_v3_ClusterCollection__fields[1] = {
-  {1, UPB_SIZE(0, 0), 0, 0, 11, 1},
+  {1, UPB_SIZE(4, 8), 1, 0, 11, 1},
 };
 
 const upb_msglayout envoy_config_cluster_v3_ClusterCollection_msginit = {
   &envoy_config_cluster_v3_ClusterCollection_submsgs[0],
   &envoy_config_cluster_v3_ClusterCollection__fields[0],
-  UPB_SIZE(4, 8), 1, false,
+  UPB_SIZE(8, 16), 1, false, 255,
 };
 
-static const upb_msglayout *const envoy_config_cluster_v3_Cluster_submsgs[35] = {
+static const upb_msglayout *const envoy_config_cluster_v3_Cluster_submsgs[32] = {
   &envoy_config_cluster_v3_CircuitBreakers_msginit,
   &envoy_config_cluster_v3_Cluster_CommonLbConfig_msginit,
   &envoy_config_cluster_v3_Cluster_CustomClusterType_msginit,
@@ -85,59 +85,59 @@ static const upb_msglayout *const envoy_config_cluster_v3_Cluster_submsgs[35] =
 };
 
 static const upb_msglayout_field envoy_config_cluster_v3_Cluster__fields[47] = {
-  {1, UPB_SIZE(32, 32), 0, 0, 9, 1},
-  {2, UPB_SIZE(168, 304), UPB_SIZE(-177, -313), 0, 14, 1},
-  {3, UPB_SIZE(48, 64), 0, 3, 11, 1},
-  {4, UPB_SIZE(52, 72), 0, 30, 11, 1},
-  {5, UPB_SIZE(56, 80), 0, 31, 11, 1},
-  {6, UPB_SIZE(0, 0), 0, 0, 14, 1},
-  {8, UPB_SIZE(148, 264), 0, 21, 11, 3},
-  {9, UPB_SIZE(60, 88), 0, 31, 11, 1},
-  {10, UPB_SIZE(64, 96), 0, 0, 11, 1},
-  {13, UPB_SIZE(68, 104), 0, 22, 11, 1},
-  {14, UPB_SIZE(72, 112), 0, 23, 11, 1},
-  {16, UPB_SIZE(76, 120), 0, 30, 11, 1},
+  {1, UPB_SIZE(24, 24), 0, 0, 9, 1},
+  {2, UPB_SIZE(160, 296), UPB_SIZE(-165, -305), 0, 14, 1},
+  {3, UPB_SIZE(40, 56), 1, 3, 11, 1},
+  {4, UPB_SIZE(44, 64), 2, 30, 11, 1},
+  {5, UPB_SIZE(48, 72), 3, 31, 11, 1},
+  {6, UPB_SIZE(4, 4), 0, 0, 14, 1},
+  {8, UPB_SIZE(140, 256), 0, 21, 11, 3},
+  {9, UPB_SIZE(52, 80), 4, 31, 11, 1},
+  {10, UPB_SIZE(56, 88), 5, 0, 11, 1},
+  {13, UPB_SIZE(60, 96), 6, 22, 11, 1},
+  {14, UPB_SIZE(64, 104), 7, 23, 11, 1},
+  {16, UPB_SIZE(68, 112), 8, 30, 11, 1},
   {17, UPB_SIZE(8, 8), 0, 0, 14, 1},
-  {18, UPB_SIZE(152, 272), 0, 18, 11, 3},
-  {19, UPB_SIZE(80, 128), 0, 15, 11, 1},
-  {20, UPB_SIZE(84, 136), 0, 30, 11, 1},
-  {21, UPB_SIZE(88, 144), 0, 19, 11, 1},
-  {22, UPB_SIZE(92, 152), 0, 4, 11, 1},
-  {23, UPB_SIZE(180, 320), UPB_SIZE(-185, -329), 10, 11, 1},
-  {24, UPB_SIZE(96, 160), 0, 26, 11, 1},
-  {25, UPB_SIZE(100, 168), 0, 25, 11, 1},
-  {26, UPB_SIZE(16, 16), 0, 0, 14, 1},
-  {27, UPB_SIZE(104, 176), 0, 1, 11, 1},
-  {28, UPB_SIZE(40, 48), 0, 0, 9, 1},
-  {29, UPB_SIZE(108, 184), 0, 24, 11, 1},
-  {30, UPB_SIZE(112, 192), 0, 17, 11, 1},
-  {31, UPB_SIZE(24, 24), 0, 0, 8, 1},
-  {32, UPB_SIZE(25, 25), 0, 0, 8, 1},
-  {33, UPB_SIZE(116, 200), 0, 29, 11, 1},
-  {34, UPB_SIZE(180, 320), UPB_SIZE(-185, -329), 7, 11, 1},
-  {36, UPB_SIZE(156, 280), 0, 12, 11, _UPB_LABEL_MAP},
-  {37, UPB_SIZE(180, 320), UPB_SIZE(-185, -329), 5, 11, 1},
-  {38, UPB_SIZE(168, 304), UPB_SIZE(-177, -313), 2, 11, 1},
-  {39, UPB_SIZE(26, 26), 0, 0, 8, 1},
-  {40, UPB_SIZE(160, 288), 0, 13, 11, 3},
-  {41, UPB_SIZE(120, 208), 0, 14, 11, 1},
-  {42, UPB_SIZE(124, 216), 0, 20, 11, 1},
-  {43, UPB_SIZE(164, 296), 0, 11, 11, 3},
-  {44, UPB_SIZE(128, 224), 0, 9, 11, 1},
-  {45, UPB_SIZE(27, 27), 0, 0, 8, 1},
-  {46, UPB_SIZE(132, 232), 0, 28, 11, 1},
-  {47, UPB_SIZE(28, 28), 0, 0, 8, 1},
-  {48, UPB_SIZE(136, 240), 0, 27, 11, 1},
-  {49, UPB_SIZE(140, 248), 0, 16, 11, 1},
-  {50, UPB_SIZE(144, 256), 0, 8, 11, 1},
-  {51, UPB_SIZE(29, 29), 0, 0, 8, 1},
-  {52, UPB_SIZE(180, 320), UPB_SIZE(-185, -329), 6, 11, 1},
+  {18, UPB_SIZE(144, 264), 0, 18, 11, 3},
+  {19, UPB_SIZE(72, 120), 9, 15, 11, 1},
+  {20, UPB_SIZE(76, 128), 10, 30, 11, 1},
+  {21, UPB_SIZE(80, 136), 11, 19, 11, 1},
+  {22, UPB_SIZE(84, 144), 12, 4, 11, 1},
+  {23, UPB_SIZE(168, 312), UPB_SIZE(-173, -321), 10, 11, 1},
+  {24, UPB_SIZE(88, 152), 13, 26, 11, 1},
+  {25, UPB_SIZE(92, 160), 14, 25, 11, 1},
+  {26, UPB_SIZE(12, 12), 0, 0, 14, 1},
+  {27, UPB_SIZE(96, 168), 15, 1, 11, 1},
+  {28, UPB_SIZE(32, 40), 0, 0, 9, 1},
+  {29, UPB_SIZE(100, 176), 16, 24, 11, 1},
+  {30, UPB_SIZE(104, 184), 17, 17, 11, 1},
+  {31, UPB_SIZE(16, 16), 0, 0, 8, 1},
+  {32, UPB_SIZE(17, 17), 0, 0, 8, 1},
+  {33, UPB_SIZE(108, 192), 18, 29, 11, 1},
+  {34, UPB_SIZE(168, 312), UPB_SIZE(-173, -321), 7, 11, 1},
+  {36, UPB_SIZE(148, 272), 0, 12, 11, _UPB_LABEL_MAP},
+  {37, UPB_SIZE(168, 312), UPB_SIZE(-173, -321), 5, 11, 1},
+  {38, UPB_SIZE(160, 296), UPB_SIZE(-165, -305), 2, 11, 1},
+  {39, UPB_SIZE(18, 18), 0, 0, 8, 1},
+  {40, UPB_SIZE(152, 280), 0, 13, 11, 3},
+  {41, UPB_SIZE(112, 200), 19, 14, 11, 1},
+  {42, UPB_SIZE(116, 208), 20, 20, 11, 1},
+  {43, UPB_SIZE(156, 288), 0, 11, 11, 3},
+  {44, UPB_SIZE(120, 216), 21, 9, 11, 1},
+  {45, UPB_SIZE(19, 19), 0, 0, 8, 1},
+  {46, UPB_SIZE(124, 224), 22, 28, 11, 1},
+  {47, UPB_SIZE(20, 20), 0, 0, 8, 1},
+  {48, UPB_SIZE(128, 232), 23, 27, 11, 1},
+  {49, UPB_SIZE(132, 240), 24, 16, 11, 1},
+  {50, UPB_SIZE(136, 248), 25, 8, 11, 1},
+  {51, UPB_SIZE(21, 21), 0, 0, 8, 1},
+  {52, UPB_SIZE(168, 312), UPB_SIZE(-173, -321), 6, 11, 1},
 };
 
 const upb_msglayout envoy_config_cluster_v3_Cluster_msginit = {
   &envoy_config_cluster_v3_Cluster_submsgs[0],
   &envoy_config_cluster_v3_Cluster__fields[0],
-  UPB_SIZE(192, 336), 47, false,
+  UPB_SIZE(176, 336), 47, false, 255,
 };
 
 static const upb_msglayout *const envoy_config_cluster_v3_Cluster_TransportSocketMatch_submsgs[2] = {
@@ -146,15 +146,15 @@ static const upb_msglayout *const envoy_config_cluster_v3_Cluster_TransportSocke
 };
 
 static const upb_msglayout_field envoy_config_cluster_v3_Cluster_TransportSocketMatch__fields[3] = {
-  {1, UPB_SIZE(0, 0), 0, 0, 9, 1},
-  {2, UPB_SIZE(8, 16), 0, 1, 11, 1},
-  {3, UPB_SIZE(12, 24), 0, 0, 11, 1},
+  {1, UPB_SIZE(4, 8), 0, 0, 9, 1},
+  {2, UPB_SIZE(12, 24), 1, 1, 11, 1},
+  {3, UPB_SIZE(16, 32), 2, 0, 11, 1},
 };
 
 const upb_msglayout envoy_config_cluster_v3_Cluster_TransportSocketMatch_msginit = {
   &envoy_config_cluster_v3_Cluster_TransportSocketMatch_submsgs[0],
   &envoy_config_cluster_v3_Cluster_TransportSocketMatch__fields[0],
-  UPB_SIZE(16, 32), 3, false,
+  UPB_SIZE(24, 48), 3, false, 255,
 };
 
 static const upb_msglayout *const envoy_config_cluster_v3_Cluster_CustomClusterType_submsgs[1] = {
@@ -162,14 +162,14 @@ static const upb_msglayout *const envoy_config_cluster_v3_Cluster_CustomClusterT
 };
 
 static const upb_msglayout_field envoy_config_cluster_v3_Cluster_CustomClusterType__fields[2] = {
-  {1, UPB_SIZE(0, 0), 0, 0, 9, 1},
-  {2, UPB_SIZE(8, 16), 0, 0, 11, 1},
+  {1, UPB_SIZE(4, 8), 0, 0, 9, 1},
+  {2, UPB_SIZE(12, 24), 1, 0, 11, 1},
 };
 
 const upb_msglayout envoy_config_cluster_v3_Cluster_CustomClusterType_msginit = {
   &envoy_config_cluster_v3_Cluster_CustomClusterType_submsgs[0],
   &envoy_config_cluster_v3_Cluster_CustomClusterType__fields[0],
-  UPB_SIZE(16, 32), 2, false,
+  UPB_SIZE(16, 32), 2, false, 255,
 };
 
 static const upb_msglayout *const envoy_config_cluster_v3_Cluster_EdsClusterConfig_submsgs[2] = {
@@ -178,15 +178,15 @@ static const upb_msglayout *const envoy_config_cluster_v3_Cluster_EdsClusterConf
 };
 
 static const upb_msglayout_field envoy_config_cluster_v3_Cluster_EdsClusterConfig__fields[3] = {
-  {1, UPB_SIZE(8, 16), 0, 0, 11, 1},
-  {2, UPB_SIZE(0, 0), 0, 0, 9, 1},
-  {3, UPB_SIZE(12, 24), 0, 1, 11, 1},
+  {1, UPB_SIZE(12, 24), 1, 0, 11, 1},
+  {2, UPB_SIZE(4, 8), 0, 0, 9, 1},
+  {3, UPB_SIZE(16, 32), 2, 1, 11, 1},
 };
 
 const upb_msglayout envoy_config_cluster_v3_Cluster_EdsClusterConfig_msginit = {
   &envoy_config_cluster_v3_Cluster_EdsClusterConfig_submsgs[0],
   &envoy_config_cluster_v3_Cluster_EdsClusterConfig__fields[0],
-  UPB_SIZE(16, 32), 3, false,
+  UPB_SIZE(24, 48), 3, false, 255,
 };
 
 static const upb_msglayout *const envoy_config_cluster_v3_Cluster_LbSubsetConfig_submsgs[2] = {
@@ -195,8 +195,8 @@ static const upb_msglayout *const envoy_config_cluster_v3_Cluster_LbSubsetConfig
 };
 
 static const upb_msglayout_field envoy_config_cluster_v3_Cluster_LbSubsetConfig__fields[7] = {
-  {1, UPB_SIZE(0, 0), 0, 0, 14, 1},
-  {2, UPB_SIZE(12, 16), 0, 1, 11, 1},
+  {1, UPB_SIZE(4, 4), 0, 0, 14, 1},
+  {2, UPB_SIZE(12, 16), 1, 1, 11, 1},
   {3, UPB_SIZE(16, 24), 0, 0, 11, 3},
   {4, UPB_SIZE(8, 8), 0, 0, 8, 1},
   {5, UPB_SIZE(9, 9), 0, 0, 8, 1},
@@ -207,20 +207,20 @@ static const upb_msglayout_field envoy_config_cluster_v3_Cluster_LbSubsetConfig_
 const upb_msglayout envoy_config_cluster_v3_Cluster_LbSubsetConfig_msginit = {
   &envoy_config_cluster_v3_Cluster_LbSubsetConfig_submsgs[0],
   &envoy_config_cluster_v3_Cluster_LbSubsetConfig__fields[0],
-  UPB_SIZE(24, 32), 7, false,
+  UPB_SIZE(24, 32), 7, false, 255,
 };
 
 static const upb_msglayout_field envoy_config_cluster_v3_Cluster_LbSubsetConfig_LbSubsetSelector__fields[4] = {
-  {1, UPB_SIZE(12, 16), 0, 0, 9, 3},
+  {1, UPB_SIZE(8, 8), 0, 0, 9, 3},
   {2, UPB_SIZE(0, 0), 0, 0, 14, 1},
-  {3, UPB_SIZE(16, 24), 0, 0, 9, 3},
-  {4, UPB_SIZE(8, 8), 0, 0, 8, 1},
+  {3, UPB_SIZE(12, 16), 0, 0, 9, 3},
+  {4, UPB_SIZE(4, 4), 0, 0, 8, 1},
 };
 
 const upb_msglayout envoy_config_cluster_v3_Cluster_LbSubsetConfig_LbSubsetSelector_msginit = {
   NULL,
   &envoy_config_cluster_v3_Cluster_LbSubsetConfig_LbSubsetSelector__fields[0],
-  UPB_SIZE(24, 32), 4, false,
+  UPB_SIZE(16, 24), 4, false, 255,
 };
 
 static const upb_msglayout *const envoy_config_cluster_v3_Cluster_LeastRequestLbConfig_submsgs[2] = {
@@ -229,30 +229,30 @@ static const upb_msglayout *const envoy_config_cluster_v3_Cluster_LeastRequestLb
 };
 
 static const upb_msglayout_field envoy_config_cluster_v3_Cluster_LeastRequestLbConfig__fields[2] = {
-  {1, UPB_SIZE(0, 0), 0, 1, 11, 1},
-  {2, UPB_SIZE(4, 8), 0, 0, 11, 1},
+  {1, UPB_SIZE(4, 8), 1, 1, 11, 1},
+  {2, UPB_SIZE(8, 16), 2, 0, 11, 1},
 };
 
 const upb_msglayout envoy_config_cluster_v3_Cluster_LeastRequestLbConfig_msginit = {
   &envoy_config_cluster_v3_Cluster_LeastRequestLbConfig_submsgs[0],
   &envoy_config_cluster_v3_Cluster_LeastRequestLbConfig__fields[0],
-  UPB_SIZE(8, 16), 2, false,
+  UPB_SIZE(16, 24), 2, false, 255,
 };
 
-static const upb_msglayout *const envoy_config_cluster_v3_Cluster_RingHashLbConfig_submsgs[2] = {
+static const upb_msglayout *const envoy_config_cluster_v3_Cluster_RingHashLbConfig_submsgs[1] = {
   &google_protobuf_UInt64Value_msginit,
 };
 
 static const upb_msglayout_field envoy_config_cluster_v3_Cluster_RingHashLbConfig__fields[3] = {
-  {1, UPB_SIZE(8, 8), 0, 0, 11, 1},
-  {3, UPB_SIZE(0, 0), 0, 0, 14, 1},
-  {4, UPB_SIZE(12, 16), 0, 0, 11, 1},
+  {1, UPB_SIZE(8, 8), 1, 0, 11, 1},
+  {3, UPB_SIZE(4, 4), 0, 0, 14, 1},
+  {4, UPB_SIZE(12, 16), 2, 0, 11, 1},
 };
 
 const upb_msglayout envoy_config_cluster_v3_Cluster_RingHashLbConfig_msginit = {
   &envoy_config_cluster_v3_Cluster_RingHashLbConfig_submsgs[0],
   &envoy_config_cluster_v3_Cluster_RingHashLbConfig__fields[0],
-  UPB_SIZE(16, 24), 3, false,
+  UPB_SIZE(16, 24), 3, false, 255,
 };
 
 static const upb_msglayout *const envoy_config_cluster_v3_Cluster_MaglevLbConfig_submsgs[1] = {
@@ -260,13 +260,13 @@ static const upb_msglayout *const envoy_config_cluster_v3_Cluster_MaglevLbConfig
 };
 
 static const upb_msglayout_field envoy_config_cluster_v3_Cluster_MaglevLbConfig__fields[1] = {
-  {1, UPB_SIZE(0, 0), 0, 0, 11, 1},
+  {1, UPB_SIZE(4, 8), 1, 0, 11, 1},
 };
 
 const upb_msglayout envoy_config_cluster_v3_Cluster_MaglevLbConfig_msginit = {
   &envoy_config_cluster_v3_Cluster_MaglevLbConfig_submsgs[0],
   &envoy_config_cluster_v3_Cluster_MaglevLbConfig__fields[0],
-  UPB_SIZE(4, 8), 1, false,
+  UPB_SIZE(8, 16), 1, false, 255,
 };
 
 static const upb_msglayout_field envoy_config_cluster_v3_Cluster_OriginalDstLbConfig__fields[1] = {
@@ -276,7 +276,7 @@ static const upb_msglayout_field envoy_config_cluster_v3_Cluster_OriginalDstLbCo
 const upb_msglayout envoy_config_cluster_v3_Cluster_OriginalDstLbConfig_msginit = {
   NULL,
   &envoy_config_cluster_v3_Cluster_OriginalDstLbConfig__fields[0],
-  UPB_SIZE(1, 1), 1, false,
+  UPB_SIZE(8, 8), 1, false, 255,
 };
 
 static const upb_msglayout *const envoy_config_cluster_v3_Cluster_CommonLbConfig_submsgs[5] = {
@@ -288,19 +288,19 @@ static const upb_msglayout *const envoy_config_cluster_v3_Cluster_CommonLbConfig
 };
 
 static const upb_msglayout_field envoy_config_cluster_v3_Cluster_CommonLbConfig__fields[7] = {
-  {1, UPB_SIZE(4, 8), 0, 3, 11, 1},
+  {1, UPB_SIZE(4, 8), 1, 3, 11, 1},
   {2, UPB_SIZE(16, 32), UPB_SIZE(-21, -41), 2, 11, 1},
   {3, UPB_SIZE(16, 32), UPB_SIZE(-21, -41), 1, 11, 1},
-  {4, UPB_SIZE(8, 16), 0, 4, 11, 1},
-  {5, UPB_SIZE(0, 0), 0, 0, 8, 1},
-  {6, UPB_SIZE(1, 1), 0, 0, 8, 1},
-  {7, UPB_SIZE(12, 24), 0, 0, 11, 1},
+  {4, UPB_SIZE(8, 16), 2, 4, 11, 1},
+  {5, UPB_SIZE(1, 1), 0, 0, 8, 1},
+  {6, UPB_SIZE(2, 2), 0, 0, 8, 1},
+  {7, UPB_SIZE(12, 24), 3, 0, 11, 1},
 };
 
 const upb_msglayout envoy_config_cluster_v3_Cluster_CommonLbConfig_msginit = {
   &envoy_config_cluster_v3_Cluster_CommonLbConfig_submsgs[0],
   &envoy_config_cluster_v3_Cluster_CommonLbConfig__fields[0],
-  UPB_SIZE(24, 48), 7, false,
+  UPB_SIZE(24, 48), 7, false, 255,
 };
 
 static const upb_msglayout *const envoy_config_cluster_v3_Cluster_CommonLbConfig_ZoneAwareLbConfig_submsgs[2] = {
@@ -309,21 +309,21 @@ static const upb_msglayout *const envoy_config_cluster_v3_Cluster_CommonLbConfig
 };
 
 static const upb_msglayout_field envoy_config_cluster_v3_Cluster_CommonLbConfig_ZoneAwareLbConfig__fields[3] = {
-  {1, UPB_SIZE(4, 8), 0, 0, 11, 1},
-  {2, UPB_SIZE(8, 16), 0, 1, 11, 1},
-  {3, UPB_SIZE(0, 0), 0, 0, 8, 1},
+  {1, UPB_SIZE(4, 8), 1, 0, 11, 1},
+  {2, UPB_SIZE(8, 16), 2, 1, 11, 1},
+  {3, UPB_SIZE(1, 1), 0, 0, 8, 1},
 };
 
 const upb_msglayout envoy_config_cluster_v3_Cluster_CommonLbConfig_ZoneAwareLbConfig_msginit = {
   &envoy_config_cluster_v3_Cluster_CommonLbConfig_ZoneAwareLbConfig_submsgs[0],
   &envoy_config_cluster_v3_Cluster_CommonLbConfig_ZoneAwareLbConfig__fields[0],
-  UPB_SIZE(12, 24), 3, false,
+  UPB_SIZE(16, 24), 3, false, 255,
 };
 
 const upb_msglayout envoy_config_cluster_v3_Cluster_CommonLbConfig_LocalityWeightedLbConfig_msginit = {
   NULL,
   NULL,
-  UPB_SIZE(0, 0), 0, false,
+  UPB_SIZE(0, 0), 0, false, 255,
 };
 
 static const upb_msglayout *const envoy_config_cluster_v3_Cluster_CommonLbConfig_ConsistentHashingLbConfig_submsgs[1] = {
@@ -331,44 +331,44 @@ static const upb_msglayout *const envoy_config_cluster_v3_Cluster_CommonLbConfig
 };
 
 static const upb_msglayout_field envoy_config_cluster_v3_Cluster_CommonLbConfig_ConsistentHashingLbConfig__fields[2] = {
-  {1, UPB_SIZE(0, 0), 0, 0, 8, 1},
-  {2, UPB_SIZE(4, 8), 0, 0, 11, 1},
+  {1, UPB_SIZE(1, 1), 0, 0, 8, 1},
+  {2, UPB_SIZE(4, 8), 1, 0, 11, 1},
 };
 
 const upb_msglayout envoy_config_cluster_v3_Cluster_CommonLbConfig_ConsistentHashingLbConfig_msginit = {
   &envoy_config_cluster_v3_Cluster_CommonLbConfig_ConsistentHashingLbConfig_submsgs[0],
   &envoy_config_cluster_v3_Cluster_CommonLbConfig_ConsistentHashingLbConfig__fields[0],
-  UPB_SIZE(8, 16), 2, false,
+  UPB_SIZE(8, 16), 2, false, 255,
 };
 
-static const upb_msglayout *const envoy_config_cluster_v3_Cluster_RefreshRate_submsgs[2] = {
+static const upb_msglayout *const envoy_config_cluster_v3_Cluster_RefreshRate_submsgs[1] = {
   &google_protobuf_Duration_msginit,
 };
 
 static const upb_msglayout_field envoy_config_cluster_v3_Cluster_RefreshRate__fields[2] = {
-  {1, UPB_SIZE(0, 0), 0, 0, 11, 1},
-  {2, UPB_SIZE(4, 8), 0, 0, 11, 1},
+  {1, UPB_SIZE(4, 8), 1, 0, 11, 1},
+  {2, UPB_SIZE(8, 16), 2, 0, 11, 1},
 };
 
 const upb_msglayout envoy_config_cluster_v3_Cluster_RefreshRate_msginit = {
   &envoy_config_cluster_v3_Cluster_RefreshRate_submsgs[0],
   &envoy_config_cluster_v3_Cluster_RefreshRate__fields[0],
-  UPB_SIZE(8, 16), 2, false,
+  UPB_SIZE(16, 24), 2, false, 255,
 };
 
-static const upb_msglayout *const envoy_config_cluster_v3_Cluster_PrefetchPolicy_submsgs[2] = {
+static const upb_msglayout *const envoy_config_cluster_v3_Cluster_PrefetchPolicy_submsgs[1] = {
   &google_protobuf_DoubleValue_msginit,
 };
 
 static const upb_msglayout_field envoy_config_cluster_v3_Cluster_PrefetchPolicy__fields[2] = {
-  {1, UPB_SIZE(0, 0), 0, 0, 11, 1},
-  {2, UPB_SIZE(4, 8), 0, 0, 11, 1},
+  {1, UPB_SIZE(4, 8), 1, 0, 11, 1},
+  {2, UPB_SIZE(8, 16), 2, 0, 11, 1},
 };
 
 const upb_msglayout envoy_config_cluster_v3_Cluster_PrefetchPolicy_msginit = {
   &envoy_config_cluster_v3_Cluster_PrefetchPolicy_submsgs[0],
   &envoy_config_cluster_v3_Cluster_PrefetchPolicy__fields[0],
-  UPB_SIZE(8, 16), 2, false,
+  UPB_SIZE(16, 24), 2, false, 255,
 };
 
 static const upb_msglayout *const envoy_config_cluster_v3_Cluster_TypedExtensionProtocolOptionsEntry_submsgs[1] = {
@@ -383,7 +383,7 @@ static const upb_msglayout_field envoy_config_cluster_v3_Cluster_TypedExtensionP
 const upb_msglayout envoy_config_cluster_v3_Cluster_TypedExtensionProtocolOptionsEntry_msginit = {
   &envoy_config_cluster_v3_Cluster_TypedExtensionProtocolOptionsEntry_submsgs[0],
   &envoy_config_cluster_v3_Cluster_TypedExtensionProtocolOptionsEntry__fields[0],
-  UPB_SIZE(16, 32), 2, false,
+  UPB_SIZE(16, 32), 2, false, 255,
 };
 
 static const upb_msglayout *const envoy_config_cluster_v3_LoadBalancingPolicy_submsgs[1] = {
@@ -397,7 +397,7 @@ static const upb_msglayout_field envoy_config_cluster_v3_LoadBalancingPolicy__fi
 const upb_msglayout envoy_config_cluster_v3_LoadBalancingPolicy_msginit = {
   &envoy_config_cluster_v3_LoadBalancingPolicy_submsgs[0],
   &envoy_config_cluster_v3_LoadBalancingPolicy__fields[0],
-  UPB_SIZE(4, 8), 1, false,
+  UPB_SIZE(8, 8), 1, false, 255,
 };
 
 static const upb_msglayout *const envoy_config_cluster_v3_LoadBalancingPolicy_Policy_submsgs[1] = {
@@ -405,14 +405,14 @@ static const upb_msglayout *const envoy_config_cluster_v3_LoadBalancingPolicy_Po
 };
 
 static const upb_msglayout_field envoy_config_cluster_v3_LoadBalancingPolicy_Policy__fields[2] = {
-  {1, UPB_SIZE(0, 0), 0, 0, 9, 1},
-  {3, UPB_SIZE(8, 16), 0, 0, 11, 1},
+  {1, UPB_SIZE(4, 8), 0, 0, 9, 1},
+  {3, UPB_SIZE(12, 24), 1, 0, 11, 1},
 };
 
 const upb_msglayout envoy_config_cluster_v3_LoadBalancingPolicy_Policy_msginit = {
   &envoy_config_cluster_v3_LoadBalancingPolicy_Policy_submsgs[0],
   &envoy_config_cluster_v3_LoadBalancingPolicy_Policy__fields[0],
-  UPB_SIZE(16, 32), 2, false,
+  UPB_SIZE(16, 32), 2, false, 255,
 };
 
 static const upb_msglayout *const envoy_config_cluster_v3_UpstreamBindConfig_submsgs[1] = {
@@ -420,13 +420,13 @@ static const upb_msglayout *const envoy_config_cluster_v3_UpstreamBindConfig_sub
 };
 
 static const upb_msglayout_field envoy_config_cluster_v3_UpstreamBindConfig__fields[1] = {
-  {1, UPB_SIZE(0, 0), 0, 0, 11, 1},
+  {1, UPB_SIZE(4, 8), 1, 0, 11, 1},
 };
 
 const upb_msglayout envoy_config_cluster_v3_UpstreamBindConfig_msginit = {
   &envoy_config_cluster_v3_UpstreamBindConfig_submsgs[0],
   &envoy_config_cluster_v3_UpstreamBindConfig__fields[0],
-  UPB_SIZE(4, 8), 1, false,
+  UPB_SIZE(8, 16), 1, false, 255,
 };
 
 static const upb_msglayout *const envoy_config_cluster_v3_UpstreamConnectionOptions_submsgs[1] = {
@@ -434,13 +434,13 @@ static const upb_msglayout *const envoy_config_cluster_v3_UpstreamConnectionOpti
 };
 
 static const upb_msglayout_field envoy_config_cluster_v3_UpstreamConnectionOptions__fields[1] = {
-  {1, UPB_SIZE(0, 0), 0, 0, 11, 1},
+  {1, UPB_SIZE(4, 8), 1, 0, 11, 1},
 };
 
 const upb_msglayout envoy_config_cluster_v3_UpstreamConnectionOptions_msginit = {
   &envoy_config_cluster_v3_UpstreamConnectionOptions_submsgs[0],
   &envoy_config_cluster_v3_UpstreamConnectionOptions__fields[0],
-  UPB_SIZE(4, 8), 1, false,
+  UPB_SIZE(8, 16), 1, false, 255,
 };
 
 static const upb_msglayout_field envoy_config_cluster_v3_TrackClusterStats__fields[2] = {
@@ -451,7 +451,7 @@ static const upb_msglayout_field envoy_config_cluster_v3_TrackClusterStats__fiel
 const upb_msglayout envoy_config_cluster_v3_TrackClusterStats_msginit = {
   NULL,
   &envoy_config_cluster_v3_TrackClusterStats__fields[0],
-  UPB_SIZE(2, 2), 2, false,
+  UPB_SIZE(8, 8), 2, false, 255,
 };
 
 #include "upb/port_undef.inc"
index 2108fd6..6f27dc7 100644 (file)
@@ -11,6 +11,7 @@
 
 #include "upb/msg.h"
 #include "upb/decode.h"
+#include "upb/decode_fast.h"
 #include "upb/encode.h"
 
 #include "upb/port_def.inc"
@@ -200,15 +201,22 @@ UPB_INLINE envoy_config_cluster_v3_ClusterCollection *envoy_config_cluster_v3_Cl
   envoy_config_cluster_v3_ClusterCollection *ret = envoy_config_cluster_v3_ClusterCollection_new(arena);
   return (ret && upb_decode(buf, size, ret, &envoy_config_cluster_v3_ClusterCollection_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE envoy_config_cluster_v3_ClusterCollection *envoy_config_cluster_v3_ClusterCollection_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  envoy_config_cluster_v3_ClusterCollection *ret = envoy_config_cluster_v3_ClusterCollection_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &envoy_config_cluster_v3_ClusterCollection_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *envoy_config_cluster_v3_ClusterCollection_serialize(const envoy_config_cluster_v3_ClusterCollection *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &envoy_config_cluster_v3_ClusterCollection_msginit, arena, len);
 }
 
-UPB_INLINE bool envoy_config_cluster_v3_ClusterCollection_has_entries(const envoy_config_cluster_v3_ClusterCollection *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(0, 0)); }
-UPB_INLINE const struct udpa_core_v1_CollectionEntry* envoy_config_cluster_v3_ClusterCollection_entries(const envoy_config_cluster_v3_ClusterCollection *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(0, 0), const struct udpa_core_v1_CollectionEntry*); }
+UPB_INLINE bool envoy_config_cluster_v3_ClusterCollection_has_entries(const envoy_config_cluster_v3_ClusterCollection *msg) { return _upb_hasbit(msg, 1); }
+UPB_INLINE const struct udpa_core_v1_CollectionEntry* envoy_config_cluster_v3_ClusterCollection_entries(const envoy_config_cluster_v3_ClusterCollection *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(4, 8), const struct udpa_core_v1_CollectionEntry*); }
 
 UPB_INLINE void envoy_config_cluster_v3_ClusterCollection_set_entries(envoy_config_cluster_v3_ClusterCollection *msg, struct udpa_core_v1_CollectionEntry* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(0, 0), struct udpa_core_v1_CollectionEntry*) = value;
+  _upb_sethas(msg, 1);
+  *UPB_PTR_AT(msg, UPB_SIZE(4, 8), struct udpa_core_v1_CollectionEntry*) = value;
 }
 UPB_INLINE struct udpa_core_v1_CollectionEntry* envoy_config_cluster_v3_ClusterCollection_mutable_entries(envoy_config_cluster_v3_ClusterCollection *msg, upb_arena *arena) {
   struct udpa_core_v1_CollectionEntry* sub = (struct udpa_core_v1_CollectionEntry*)envoy_config_cluster_v3_ClusterCollection_entries(msg);
@@ -230,6 +238,12 @@ UPB_INLINE envoy_config_cluster_v3_Cluster *envoy_config_cluster_v3_Cluster_pars
   envoy_config_cluster_v3_Cluster *ret = envoy_config_cluster_v3_Cluster_new(arena);
   return (ret && upb_decode(buf, size, ret, &envoy_config_cluster_v3_Cluster_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE envoy_config_cluster_v3_Cluster *envoy_config_cluster_v3_Cluster_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  envoy_config_cluster_v3_Cluster *ret = envoy_config_cluster_v3_Cluster_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &envoy_config_cluster_v3_Cluster_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *envoy_config_cluster_v3_Cluster_serialize(const envoy_config_cluster_v3_Cluster *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &envoy_config_cluster_v3_Cluster_msginit, arena, len);
 }
@@ -239,7 +253,7 @@ typedef enum {
   envoy_config_cluster_v3_Cluster_cluster_discovery_type_cluster_type = 38,
   envoy_config_cluster_v3_Cluster_cluster_discovery_type_NOT_SET = 0
 } envoy_config_cluster_v3_Cluster_cluster_discovery_type_oneofcases;
-UPB_INLINE envoy_config_cluster_v3_Cluster_cluster_discovery_type_oneofcases envoy_config_cluster_v3_Cluster_cluster_discovery_type_case(const envoy_config_cluster_v3_Cluster* msg) { return (envoy_config_cluster_v3_Cluster_cluster_discovery_type_oneofcases)*UPB_PTR_AT(msg, UPB_SIZE(176, 312), int32_t); }
+UPB_INLINE envoy_config_cluster_v3_Cluster_cluster_discovery_type_oneofcases envoy_config_cluster_v3_Cluster_cluster_discovery_type_case(const envoy_config_cluster_v3_Cluster* msg) { return (envoy_config_cluster_v3_Cluster_cluster_discovery_type_oneofcases)*UPB_PTR_AT(msg, UPB_SIZE(164, 304), int32_t); }
 
 typedef enum {
   envoy_config_cluster_v3_Cluster_lb_config_ring_hash_lb_config = 23,
@@ -248,102 +262,103 @@ typedef enum {
   envoy_config_cluster_v3_Cluster_lb_config_least_request_lb_config = 37,
   envoy_config_cluster_v3_Cluster_lb_config_NOT_SET = 0
 } envoy_config_cluster_v3_Cluster_lb_config_oneofcases;
-UPB_INLINE envoy_config_cluster_v3_Cluster_lb_config_oneofcases envoy_config_cluster_v3_Cluster_lb_config_case(const envoy_config_cluster_v3_Cluster* msg) { return (envoy_config_cluster_v3_Cluster_lb_config_oneofcases)*UPB_PTR_AT(msg, UPB_SIZE(184, 328), int32_t); }
-
-UPB_INLINE upb_strview envoy_config_cluster_v3_Cluster_name(const envoy_config_cluster_v3_Cluster *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(32, 32), upb_strview); }
-UPB_INLINE bool envoy_config_cluster_v3_Cluster_has_type(const envoy_config_cluster_v3_Cluster *msg) { return _upb_getoneofcase(msg, UPB_SIZE(176, 312)) == 2; }
-UPB_INLINE int32_t envoy_config_cluster_v3_Cluster_type(const envoy_config_cluster_v3_Cluster *msg) { return UPB_READ_ONEOF(msg, int32_t, UPB_SIZE(168, 304), UPB_SIZE(176, 312), 2, 0); }
-UPB_INLINE bool envoy_config_cluster_v3_Cluster_has_eds_cluster_config(const envoy_config_cluster_v3_Cluster *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(48, 64)); }
-UPB_INLINE const envoy_config_cluster_v3_Cluster_EdsClusterConfig* envoy_config_cluster_v3_Cluster_eds_cluster_config(const envoy_config_cluster_v3_Cluster *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(48, 64), const envoy_config_cluster_v3_Cluster_EdsClusterConfig*); }
-UPB_INLINE bool envoy_config_cluster_v3_Cluster_has_connect_timeout(const envoy_config_cluster_v3_Cluster *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(52, 72)); }
-UPB_INLINE const struct google_protobuf_Duration* envoy_config_cluster_v3_Cluster_connect_timeout(const envoy_config_cluster_v3_Cluster *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(52, 72), const struct google_protobuf_Duration*); }
-UPB_INLINE bool envoy_config_cluster_v3_Cluster_has_per_connection_buffer_limit_bytes(const envoy_config_cluster_v3_Cluster *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(56, 80)); }
-UPB_INLINE const struct google_protobuf_UInt32Value* envoy_config_cluster_v3_Cluster_per_connection_buffer_limit_bytes(const envoy_config_cluster_v3_Cluster *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(56, 80), const struct google_protobuf_UInt32Value*); }
-UPB_INLINE int32_t envoy_config_cluster_v3_Cluster_lb_policy(const envoy_config_cluster_v3_Cluster *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(0, 0), int32_t); }
-UPB_INLINE bool envoy_config_cluster_v3_Cluster_has_health_checks(const envoy_config_cluster_v3_Cluster *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(148, 264)); }
-UPB_INLINE const struct envoy_config_core_v3_HealthCheck* const* envoy_config_cluster_v3_Cluster_health_checks(const envoy_config_cluster_v3_Cluster *msg, size_t *len) { return (const struct envoy_config_core_v3_HealthCheck* const*)_upb_array_accessor(msg, UPB_SIZE(148, 264), len); }
-UPB_INLINE bool envoy_config_cluster_v3_Cluster_has_max_requests_per_connection(const envoy_config_cluster_v3_Cluster *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(60, 88)); }
-UPB_INLINE const struct google_protobuf_UInt32Value* envoy_config_cluster_v3_Cluster_max_requests_per_connection(const envoy_config_cluster_v3_Cluster *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(60, 88), const struct google_protobuf_UInt32Value*); }
-UPB_INLINE bool envoy_config_cluster_v3_Cluster_has_circuit_breakers(const envoy_config_cluster_v3_Cluster *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(64, 96)); }
-UPB_INLINE const struct envoy_config_cluster_v3_CircuitBreakers* envoy_config_cluster_v3_Cluster_circuit_breakers(const envoy_config_cluster_v3_Cluster *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(64, 96), const struct envoy_config_cluster_v3_CircuitBreakers*); }
-UPB_INLINE bool envoy_config_cluster_v3_Cluster_has_http_protocol_options(const envoy_config_cluster_v3_Cluster *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(68, 104)); }
-UPB_INLINE const struct envoy_config_core_v3_Http1ProtocolOptions* envoy_config_cluster_v3_Cluster_http_protocol_options(const envoy_config_cluster_v3_Cluster *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(68, 104), const struct envoy_config_core_v3_Http1ProtocolOptions*); }
-UPB_INLINE bool envoy_config_cluster_v3_Cluster_has_http2_protocol_options(const envoy_config_cluster_v3_Cluster *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(72, 112)); }
-UPB_INLINE const struct envoy_config_core_v3_Http2ProtocolOptions* envoy_config_cluster_v3_Cluster_http2_protocol_options(const envoy_config_cluster_v3_Cluster *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(72, 112), const struct envoy_config_core_v3_Http2ProtocolOptions*); }
-UPB_INLINE bool envoy_config_cluster_v3_Cluster_has_dns_refresh_rate(const envoy_config_cluster_v3_Cluster *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(76, 120)); }
-UPB_INLINE const struct google_protobuf_Duration* envoy_config_cluster_v3_Cluster_dns_refresh_rate(const envoy_config_cluster_v3_Cluster *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(76, 120), const struct google_protobuf_Duration*); }
+UPB_INLINE envoy_config_cluster_v3_Cluster_lb_config_oneofcases envoy_config_cluster_v3_Cluster_lb_config_case(const envoy_config_cluster_v3_Cluster* msg) { return (envoy_config_cluster_v3_Cluster_lb_config_oneofcases)*UPB_PTR_AT(msg, UPB_SIZE(172, 320), int32_t); }
+
+UPB_INLINE upb_strview envoy_config_cluster_v3_Cluster_name(const envoy_config_cluster_v3_Cluster *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(24, 24), upb_strview); }
+UPB_INLINE bool envoy_config_cluster_v3_Cluster_has_type(const envoy_config_cluster_v3_Cluster *msg) { return _upb_getoneofcase(msg, UPB_SIZE(164, 304)) == 2; }
+UPB_INLINE int32_t envoy_config_cluster_v3_Cluster_type(const envoy_config_cluster_v3_Cluster *msg) { return UPB_READ_ONEOF(msg, int32_t, UPB_SIZE(160, 296), UPB_SIZE(164, 304), 2, 0); }
+UPB_INLINE bool envoy_config_cluster_v3_Cluster_has_eds_cluster_config(const envoy_config_cluster_v3_Cluster *msg) { return _upb_hasbit(msg, 1); }
+UPB_INLINE const envoy_config_cluster_v3_Cluster_EdsClusterConfig* envoy_config_cluster_v3_Cluster_eds_cluster_config(const envoy_config_cluster_v3_Cluster *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(40, 56), const envoy_config_cluster_v3_Cluster_EdsClusterConfig*); }
+UPB_INLINE bool envoy_config_cluster_v3_Cluster_has_connect_timeout(const envoy_config_cluster_v3_Cluster *msg) { return _upb_hasbit(msg, 2); }
+UPB_INLINE const struct google_protobuf_Duration* envoy_config_cluster_v3_Cluster_connect_timeout(const envoy_config_cluster_v3_Cluster *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(44, 64), const struct google_protobuf_Duration*); }
+UPB_INLINE bool envoy_config_cluster_v3_Cluster_has_per_connection_buffer_limit_bytes(const envoy_config_cluster_v3_Cluster *msg) { return _upb_hasbit(msg, 3); }
+UPB_INLINE const struct google_protobuf_UInt32Value* envoy_config_cluster_v3_Cluster_per_connection_buffer_limit_bytes(const envoy_config_cluster_v3_Cluster *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(48, 72), const struct google_protobuf_UInt32Value*); }
+UPB_INLINE int32_t envoy_config_cluster_v3_Cluster_lb_policy(const envoy_config_cluster_v3_Cluster *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(4, 4), int32_t); }
+UPB_INLINE bool envoy_config_cluster_v3_Cluster_has_health_checks(const envoy_config_cluster_v3_Cluster *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(140, 256)); }
+UPB_INLINE const struct envoy_config_core_v3_HealthCheck* const* envoy_config_cluster_v3_Cluster_health_checks(const envoy_config_cluster_v3_Cluster *msg, size_t *len) { return (const struct envoy_config_core_v3_HealthCheck* const*)_upb_array_accessor(msg, UPB_SIZE(140, 256), len); }
+UPB_INLINE bool envoy_config_cluster_v3_Cluster_has_max_requests_per_connection(const envoy_config_cluster_v3_Cluster *msg) { return _upb_hasbit(msg, 4); }
+UPB_INLINE const struct google_protobuf_UInt32Value* envoy_config_cluster_v3_Cluster_max_requests_per_connection(const envoy_config_cluster_v3_Cluster *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(52, 80), const struct google_protobuf_UInt32Value*); }
+UPB_INLINE bool envoy_config_cluster_v3_Cluster_has_circuit_breakers(const envoy_config_cluster_v3_Cluster *msg) { return _upb_hasbit(msg, 5); }
+UPB_INLINE const struct envoy_config_cluster_v3_CircuitBreakers* envoy_config_cluster_v3_Cluster_circuit_breakers(const envoy_config_cluster_v3_Cluster *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(56, 88), const struct envoy_config_cluster_v3_CircuitBreakers*); }
+UPB_INLINE bool envoy_config_cluster_v3_Cluster_has_http_protocol_options(const envoy_config_cluster_v3_Cluster *msg) { return _upb_hasbit(msg, 6); }
+UPB_INLINE const struct envoy_config_core_v3_Http1ProtocolOptions* envoy_config_cluster_v3_Cluster_http_protocol_options(const envoy_config_cluster_v3_Cluster *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(60, 96), const struct envoy_config_core_v3_Http1ProtocolOptions*); }
+UPB_INLINE bool envoy_config_cluster_v3_Cluster_has_http2_protocol_options(const envoy_config_cluster_v3_Cluster *msg) { return _upb_hasbit(msg, 7); }
+UPB_INLINE const struct envoy_config_core_v3_Http2ProtocolOptions* envoy_config_cluster_v3_Cluster_http2_protocol_options(const envoy_config_cluster_v3_Cluster *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(64, 104), const struct envoy_config_core_v3_Http2ProtocolOptions*); }
+UPB_INLINE bool envoy_config_cluster_v3_Cluster_has_dns_refresh_rate(const envoy_config_cluster_v3_Cluster *msg) { return _upb_hasbit(msg, 8); }
+UPB_INLINE const struct google_protobuf_Duration* envoy_config_cluster_v3_Cluster_dns_refresh_rate(const envoy_config_cluster_v3_Cluster *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(68, 112), const struct google_protobuf_Duration*); }
 UPB_INLINE int32_t envoy_config_cluster_v3_Cluster_dns_lookup_family(const envoy_config_cluster_v3_Cluster *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(8, 8), int32_t); }
-UPB_INLINE bool envoy_config_cluster_v3_Cluster_has_dns_resolvers(const envoy_config_cluster_v3_Cluster *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(152, 272)); }
-UPB_INLINE const struct envoy_config_core_v3_Address* const* envoy_config_cluster_v3_Cluster_dns_resolvers(const envoy_config_cluster_v3_Cluster *msg, size_t *len) { return (const struct envoy_config_core_v3_Address* const*)_upb_array_accessor(msg, UPB_SIZE(152, 272), len); }
-UPB_INLINE bool envoy_config_cluster_v3_Cluster_has_outlier_detection(const envoy_config_cluster_v3_Cluster *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(80, 128)); }
-UPB_INLINE const struct envoy_config_cluster_v3_OutlierDetection* envoy_config_cluster_v3_Cluster_outlier_detection(const envoy_config_cluster_v3_Cluster *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(80, 128), const struct envoy_config_cluster_v3_OutlierDetection*); }
-UPB_INLINE bool envoy_config_cluster_v3_Cluster_has_cleanup_interval(const envoy_config_cluster_v3_Cluster *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(84, 136)); }
-UPB_INLINE const struct google_protobuf_Duration* envoy_config_cluster_v3_Cluster_cleanup_interval(const envoy_config_cluster_v3_Cluster *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(84, 136), const struct google_protobuf_Duration*); }
-UPB_INLINE bool envoy_config_cluster_v3_Cluster_has_upstream_bind_config(const envoy_config_cluster_v3_Cluster *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(88, 144)); }
-UPB_INLINE const struct envoy_config_core_v3_BindConfig* envoy_config_cluster_v3_Cluster_upstream_bind_config(const envoy_config_cluster_v3_Cluster *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(88, 144), const struct envoy_config_core_v3_BindConfig*); }
-UPB_INLINE bool envoy_config_cluster_v3_Cluster_has_lb_subset_config(const envoy_config_cluster_v3_Cluster *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(92, 152)); }
-UPB_INLINE const envoy_config_cluster_v3_Cluster_LbSubsetConfig* envoy_config_cluster_v3_Cluster_lb_subset_config(const envoy_config_cluster_v3_Cluster *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(92, 152), const envoy_config_cluster_v3_Cluster_LbSubsetConfig*); }
-UPB_INLINE bool envoy_config_cluster_v3_Cluster_has_ring_hash_lb_config(const envoy_config_cluster_v3_Cluster *msg) { return _upb_getoneofcase(msg, UPB_SIZE(184, 328)) == 23; }
-UPB_INLINE const envoy_config_cluster_v3_Cluster_RingHashLbConfig* envoy_config_cluster_v3_Cluster_ring_hash_lb_config(const envoy_config_cluster_v3_Cluster *msg) { return UPB_READ_ONEOF(msg, const envoy_config_cluster_v3_Cluster_RingHashLbConfig*, UPB_SIZE(180, 320), UPB_SIZE(184, 328), 23, NULL); }
-UPB_INLINE bool envoy_config_cluster_v3_Cluster_has_transport_socket(const envoy_config_cluster_v3_Cluster *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(96, 160)); }
-UPB_INLINE const struct envoy_config_core_v3_TransportSocket* envoy_config_cluster_v3_Cluster_transport_socket(const envoy_config_cluster_v3_Cluster *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(96, 160), const struct envoy_config_core_v3_TransportSocket*); }
-UPB_INLINE bool envoy_config_cluster_v3_Cluster_has_metadata(const envoy_config_cluster_v3_Cluster *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(100, 168)); }
-UPB_INLINE const struct envoy_config_core_v3_Metadata* envoy_config_cluster_v3_Cluster_metadata(const envoy_config_cluster_v3_Cluster *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(100, 168), const struct envoy_config_core_v3_Metadata*); }
-UPB_INLINE int32_t envoy_config_cluster_v3_Cluster_protocol_selection(const envoy_config_cluster_v3_Cluster *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(16, 16), int32_t); }
-UPB_INLINE bool envoy_config_cluster_v3_Cluster_has_common_lb_config(const envoy_config_cluster_v3_Cluster *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(104, 176)); }
-UPB_INLINE const envoy_config_cluster_v3_Cluster_CommonLbConfig* envoy_config_cluster_v3_Cluster_common_lb_config(const envoy_config_cluster_v3_Cluster *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(104, 176), const envoy_config_cluster_v3_Cluster_CommonLbConfig*); }
-UPB_INLINE upb_strview envoy_config_cluster_v3_Cluster_alt_stat_name(const envoy_config_cluster_v3_Cluster *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(40, 48), upb_strview); }
-UPB_INLINE bool envoy_config_cluster_v3_Cluster_has_common_http_protocol_options(const envoy_config_cluster_v3_Cluster *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(108, 184)); }
-UPB_INLINE const struct envoy_config_core_v3_HttpProtocolOptions* envoy_config_cluster_v3_Cluster_common_http_protocol_options(const envoy_config_cluster_v3_Cluster *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(108, 184), const struct envoy_config_core_v3_HttpProtocolOptions*); }
-UPB_INLINE bool envoy_config_cluster_v3_Cluster_has_upstream_connection_options(const envoy_config_cluster_v3_Cluster *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(112, 192)); }
-UPB_INLINE const envoy_config_cluster_v3_UpstreamConnectionOptions* envoy_config_cluster_v3_Cluster_upstream_connection_options(const envoy_config_cluster_v3_Cluster *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(112, 192), const envoy_config_cluster_v3_UpstreamConnectionOptions*); }
-UPB_INLINE bool envoy_config_cluster_v3_Cluster_close_connections_on_host_health_failure(const envoy_config_cluster_v3_Cluster *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(24, 24), bool); }
-UPB_INLINE bool envoy_config_cluster_v3_Cluster_ignore_health_on_host_removal(const envoy_config_cluster_v3_Cluster *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(25, 25), bool); }
-UPB_INLINE bool envoy_config_cluster_v3_Cluster_has_load_assignment(const envoy_config_cluster_v3_Cluster *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(116, 200)); }
-UPB_INLINE const struct envoy_config_endpoint_v3_ClusterLoadAssignment* envoy_config_cluster_v3_Cluster_load_assignment(const envoy_config_cluster_v3_Cluster *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(116, 200), const struct envoy_config_endpoint_v3_ClusterLoadAssignment*); }
-UPB_INLINE bool envoy_config_cluster_v3_Cluster_has_original_dst_lb_config(const envoy_config_cluster_v3_Cluster *msg) { return _upb_getoneofcase(msg, UPB_SIZE(184, 328)) == 34; }
-UPB_INLINE const envoy_config_cluster_v3_Cluster_OriginalDstLbConfig* envoy_config_cluster_v3_Cluster_original_dst_lb_config(const envoy_config_cluster_v3_Cluster *msg) { return UPB_READ_ONEOF(msg, const envoy_config_cluster_v3_Cluster_OriginalDstLbConfig*, UPB_SIZE(180, 320), UPB_SIZE(184, 328), 34, NULL); }
-UPB_INLINE bool envoy_config_cluster_v3_Cluster_has_typed_extension_protocol_options(const envoy_config_cluster_v3_Cluster *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(156, 280)); }
-UPB_INLINE size_t envoy_config_cluster_v3_Cluster_typed_extension_protocol_options_size(const envoy_config_cluster_v3_Cluster *msg) {return _upb_msg_map_size(msg, UPB_SIZE(156, 280)); }
-UPB_INLINE bool envoy_config_cluster_v3_Cluster_typed_extension_protocol_options_get(const envoy_config_cluster_v3_Cluster *msg, upb_strview key, struct google_protobuf_Any* *val) { return _upb_msg_map_get(msg, UPB_SIZE(156, 280), &key, 0, val, sizeof(*val)); }
-UPB_INLINE const envoy_config_cluster_v3_Cluster_TypedExtensionProtocolOptionsEntry* envoy_config_cluster_v3_Cluster_typed_extension_protocol_options_next(const envoy_config_cluster_v3_Cluster *msg, size_t* iter) { return (const envoy_config_cluster_v3_Cluster_TypedExtensionProtocolOptionsEntry*)_upb_msg_map_next(msg, UPB_SIZE(156, 280), iter); }
-UPB_INLINE bool envoy_config_cluster_v3_Cluster_has_least_request_lb_config(const envoy_config_cluster_v3_Cluster *msg) { return _upb_getoneofcase(msg, UPB_SIZE(184, 328)) == 37; }
-UPB_INLINE const envoy_config_cluster_v3_Cluster_LeastRequestLbConfig* envoy_config_cluster_v3_Cluster_least_request_lb_config(const envoy_config_cluster_v3_Cluster *msg) { return UPB_READ_ONEOF(msg, const envoy_config_cluster_v3_Cluster_LeastRequestLbConfig*, UPB_SIZE(180, 320), UPB_SIZE(184, 328), 37, NULL); }
-UPB_INLINE bool envoy_config_cluster_v3_Cluster_has_cluster_type(const envoy_config_cluster_v3_Cluster *msg) { return _upb_getoneofcase(msg, UPB_SIZE(176, 312)) == 38; }
-UPB_INLINE const envoy_config_cluster_v3_Cluster_CustomClusterType* envoy_config_cluster_v3_Cluster_cluster_type(const envoy_config_cluster_v3_Cluster *msg) { return UPB_READ_ONEOF(msg, const envoy_config_cluster_v3_Cluster_CustomClusterType*, UPB_SIZE(168, 304), UPB_SIZE(176, 312), 38, NULL); }
-UPB_INLINE bool envoy_config_cluster_v3_Cluster_respect_dns_ttl(const envoy_config_cluster_v3_Cluster *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(26, 26), bool); }
-UPB_INLINE bool envoy_config_cluster_v3_Cluster_has_filters(const envoy_config_cluster_v3_Cluster *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(160, 288)); }
-UPB_INLINE const struct envoy_config_cluster_v3_Filter* const* envoy_config_cluster_v3_Cluster_filters(const envoy_config_cluster_v3_Cluster *msg, size_t *len) { return (const struct envoy_config_cluster_v3_Filter* const*)_upb_array_accessor(msg, UPB_SIZE(160, 288), len); }
-UPB_INLINE bool envoy_config_cluster_v3_Cluster_has_load_balancing_policy(const envoy_config_cluster_v3_Cluster *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(120, 208)); }
-UPB_INLINE const envoy_config_cluster_v3_LoadBalancingPolicy* envoy_config_cluster_v3_Cluster_load_balancing_policy(const envoy_config_cluster_v3_Cluster *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(120, 208), const envoy_config_cluster_v3_LoadBalancingPolicy*); }
-UPB_INLINE bool envoy_config_cluster_v3_Cluster_has_lrs_server(const envoy_config_cluster_v3_Cluster *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(124, 216)); }
-UPB_INLINE const struct envoy_config_core_v3_ConfigSource* envoy_config_cluster_v3_Cluster_lrs_server(const envoy_config_cluster_v3_Cluster *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(124, 216), const struct envoy_config_core_v3_ConfigSource*); }
-UPB_INLINE bool envoy_config_cluster_v3_Cluster_has_transport_socket_matches(const envoy_config_cluster_v3_Cluster *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(164, 296)); }
-UPB_INLINE const envoy_config_cluster_v3_Cluster_TransportSocketMatch* const* envoy_config_cluster_v3_Cluster_transport_socket_matches(const envoy_config_cluster_v3_Cluster *msg, size_t *len) { return (const envoy_config_cluster_v3_Cluster_TransportSocketMatch* const*)_upb_array_accessor(msg, UPB_SIZE(164, 296), len); }
-UPB_INLINE bool envoy_config_cluster_v3_Cluster_has_dns_failure_refresh_rate(const envoy_config_cluster_v3_Cluster *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(128, 224)); }
-UPB_INLINE const envoy_config_cluster_v3_Cluster_RefreshRate* envoy_config_cluster_v3_Cluster_dns_failure_refresh_rate(const envoy_config_cluster_v3_Cluster *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(128, 224), const envoy_config_cluster_v3_Cluster_RefreshRate*); }
-UPB_INLINE bool envoy_config_cluster_v3_Cluster_use_tcp_for_dns_lookups(const envoy_config_cluster_v3_Cluster *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(27, 27), bool); }
-UPB_INLINE bool envoy_config_cluster_v3_Cluster_has_upstream_http_protocol_options(const envoy_config_cluster_v3_Cluster *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(132, 232)); }
-UPB_INLINE const struct envoy_config_core_v3_UpstreamHttpProtocolOptions* envoy_config_cluster_v3_Cluster_upstream_http_protocol_options(const envoy_config_cluster_v3_Cluster *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(132, 232), const struct envoy_config_core_v3_UpstreamHttpProtocolOptions*); }
-UPB_INLINE bool envoy_config_cluster_v3_Cluster_track_timeout_budgets(const envoy_config_cluster_v3_Cluster *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(28, 28), bool); }
-UPB_INLINE bool envoy_config_cluster_v3_Cluster_has_upstream_config(const envoy_config_cluster_v3_Cluster *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(136, 240)); }
-UPB_INLINE const struct envoy_config_core_v3_TypedExtensionConfig* envoy_config_cluster_v3_Cluster_upstream_config(const envoy_config_cluster_v3_Cluster *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(136, 240), const struct envoy_config_core_v3_TypedExtensionConfig*); }
-UPB_INLINE bool envoy_config_cluster_v3_Cluster_has_track_cluster_stats(const envoy_config_cluster_v3_Cluster *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(140, 248)); }
-UPB_INLINE const envoy_config_cluster_v3_TrackClusterStats* envoy_config_cluster_v3_Cluster_track_cluster_stats(const envoy_config_cluster_v3_Cluster *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(140, 248), const envoy_config_cluster_v3_TrackClusterStats*); }
-UPB_INLINE bool envoy_config_cluster_v3_Cluster_has_prefetch_policy(const envoy_config_cluster_v3_Cluster *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(144, 256)); }
-UPB_INLINE const envoy_config_cluster_v3_Cluster_PrefetchPolicy* envoy_config_cluster_v3_Cluster_prefetch_policy(const envoy_config_cluster_v3_Cluster *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(144, 256), const envoy_config_cluster_v3_Cluster_PrefetchPolicy*); }
-UPB_INLINE bool envoy_config_cluster_v3_Cluster_connection_pool_per_downstream_connection(const envoy_config_cluster_v3_Cluster *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(29, 29), bool); }
-UPB_INLINE bool envoy_config_cluster_v3_Cluster_has_maglev_lb_config(const envoy_config_cluster_v3_Cluster *msg) { return _upb_getoneofcase(msg, UPB_SIZE(184, 328)) == 52; }
-UPB_INLINE const envoy_config_cluster_v3_Cluster_MaglevLbConfig* envoy_config_cluster_v3_Cluster_maglev_lb_config(const envoy_config_cluster_v3_Cluster *msg) { return UPB_READ_ONEOF(msg, const envoy_config_cluster_v3_Cluster_MaglevLbConfig*, UPB_SIZE(180, 320), UPB_SIZE(184, 328), 52, NULL); }
+UPB_INLINE bool envoy_config_cluster_v3_Cluster_has_dns_resolvers(const envoy_config_cluster_v3_Cluster *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(144, 264)); }
+UPB_INLINE const struct envoy_config_core_v3_Address* const* envoy_config_cluster_v3_Cluster_dns_resolvers(const envoy_config_cluster_v3_Cluster *msg, size_t *len) { return (const struct envoy_config_core_v3_Address* const*)_upb_array_accessor(msg, UPB_SIZE(144, 264), len); }
+UPB_INLINE bool envoy_config_cluster_v3_Cluster_has_outlier_detection(const envoy_config_cluster_v3_Cluster *msg) { return _upb_hasbit(msg, 9); }
+UPB_INLINE const struct envoy_config_cluster_v3_OutlierDetection* envoy_config_cluster_v3_Cluster_outlier_detection(const envoy_config_cluster_v3_Cluster *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(72, 120), const struct envoy_config_cluster_v3_OutlierDetection*); }
+UPB_INLINE bool envoy_config_cluster_v3_Cluster_has_cleanup_interval(const envoy_config_cluster_v3_Cluster *msg) { return _upb_hasbit(msg, 10); }
+UPB_INLINE const struct google_protobuf_Duration* envoy_config_cluster_v3_Cluster_cleanup_interval(const envoy_config_cluster_v3_Cluster *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(76, 128), const struct google_protobuf_Duration*); }
+UPB_INLINE bool envoy_config_cluster_v3_Cluster_has_upstream_bind_config(const envoy_config_cluster_v3_Cluster *msg) { return _upb_hasbit(msg, 11); }
+UPB_INLINE const struct envoy_config_core_v3_BindConfig* envoy_config_cluster_v3_Cluster_upstream_bind_config(const envoy_config_cluster_v3_Cluster *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(80, 136), const struct envoy_config_core_v3_BindConfig*); }
+UPB_INLINE bool envoy_config_cluster_v3_Cluster_has_lb_subset_config(const envoy_config_cluster_v3_Cluster *msg) { return _upb_hasbit(msg, 12); }
+UPB_INLINE const envoy_config_cluster_v3_Cluster_LbSubsetConfig* envoy_config_cluster_v3_Cluster_lb_subset_config(const envoy_config_cluster_v3_Cluster *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(84, 144), const envoy_config_cluster_v3_Cluster_LbSubsetConfig*); }
+UPB_INLINE bool envoy_config_cluster_v3_Cluster_has_ring_hash_lb_config(const envoy_config_cluster_v3_Cluster *msg) { return _upb_getoneofcase(msg, UPB_SIZE(172, 320)) == 23; }
+UPB_INLINE const envoy_config_cluster_v3_Cluster_RingHashLbConfig* envoy_config_cluster_v3_Cluster_ring_hash_lb_config(const envoy_config_cluster_v3_Cluster *msg) { return UPB_READ_ONEOF(msg, const envoy_config_cluster_v3_Cluster_RingHashLbConfig*, UPB_SIZE(168, 312), UPB_SIZE(172, 320), 23, NULL); }
+UPB_INLINE bool envoy_config_cluster_v3_Cluster_has_transport_socket(const envoy_config_cluster_v3_Cluster *msg) { return _upb_hasbit(msg, 13); }
+UPB_INLINE const struct envoy_config_core_v3_TransportSocket* envoy_config_cluster_v3_Cluster_transport_socket(const envoy_config_cluster_v3_Cluster *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(88, 152), const struct envoy_config_core_v3_TransportSocket*); }
+UPB_INLINE bool envoy_config_cluster_v3_Cluster_has_metadata(const envoy_config_cluster_v3_Cluster *msg) { return _upb_hasbit(msg, 14); }
+UPB_INLINE const struct envoy_config_core_v3_Metadata* envoy_config_cluster_v3_Cluster_metadata(const envoy_config_cluster_v3_Cluster *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(92, 160), const struct envoy_config_core_v3_Metadata*); }
+UPB_INLINE int32_t envoy_config_cluster_v3_Cluster_protocol_selection(const envoy_config_cluster_v3_Cluster *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(12, 12), int32_t); }
+UPB_INLINE bool envoy_config_cluster_v3_Cluster_has_common_lb_config(const envoy_config_cluster_v3_Cluster *msg) { return _upb_hasbit(msg, 15); }
+UPB_INLINE const envoy_config_cluster_v3_Cluster_CommonLbConfig* envoy_config_cluster_v3_Cluster_common_lb_config(const envoy_config_cluster_v3_Cluster *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(96, 168), const envoy_config_cluster_v3_Cluster_CommonLbConfig*); }
+UPB_INLINE upb_strview envoy_config_cluster_v3_Cluster_alt_stat_name(const envoy_config_cluster_v3_Cluster *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(32, 40), upb_strview); }
+UPB_INLINE bool envoy_config_cluster_v3_Cluster_has_common_http_protocol_options(const envoy_config_cluster_v3_Cluster *msg) { return _upb_hasbit(msg, 16); }
+UPB_INLINE const struct envoy_config_core_v3_HttpProtocolOptions* envoy_config_cluster_v3_Cluster_common_http_protocol_options(const envoy_config_cluster_v3_Cluster *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(100, 176), const struct envoy_config_core_v3_HttpProtocolOptions*); }
+UPB_INLINE bool envoy_config_cluster_v3_Cluster_has_upstream_connection_options(const envoy_config_cluster_v3_Cluster *msg) { return _upb_hasbit(msg, 17); }
+UPB_INLINE const envoy_config_cluster_v3_UpstreamConnectionOptions* envoy_config_cluster_v3_Cluster_upstream_connection_options(const envoy_config_cluster_v3_Cluster *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(104, 184), const envoy_config_cluster_v3_UpstreamConnectionOptions*); }
+UPB_INLINE bool envoy_config_cluster_v3_Cluster_close_connections_on_host_health_failure(const envoy_config_cluster_v3_Cluster *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(16, 16), bool); }
+UPB_INLINE bool envoy_config_cluster_v3_Cluster_ignore_health_on_host_removal(const envoy_config_cluster_v3_Cluster *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(17, 17), bool); }
+UPB_INLINE bool envoy_config_cluster_v3_Cluster_has_load_assignment(const envoy_config_cluster_v3_Cluster *msg) { return _upb_hasbit(msg, 18); }
+UPB_INLINE const struct envoy_config_endpoint_v3_ClusterLoadAssignment* envoy_config_cluster_v3_Cluster_load_assignment(const envoy_config_cluster_v3_Cluster *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(108, 192), const struct envoy_config_endpoint_v3_ClusterLoadAssignment*); }
+UPB_INLINE bool envoy_config_cluster_v3_Cluster_has_original_dst_lb_config(const envoy_config_cluster_v3_Cluster *msg) { return _upb_getoneofcase(msg, UPB_SIZE(172, 320)) == 34; }
+UPB_INLINE const envoy_config_cluster_v3_Cluster_OriginalDstLbConfig* envoy_config_cluster_v3_Cluster_original_dst_lb_config(const envoy_config_cluster_v3_Cluster *msg) { return UPB_READ_ONEOF(msg, const envoy_config_cluster_v3_Cluster_OriginalDstLbConfig*, UPB_SIZE(168, 312), UPB_SIZE(172, 320), 34, NULL); }
+UPB_INLINE bool envoy_config_cluster_v3_Cluster_has_typed_extension_protocol_options(const envoy_config_cluster_v3_Cluster *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(148, 272)); }
+UPB_INLINE size_t envoy_config_cluster_v3_Cluster_typed_extension_protocol_options_size(const envoy_config_cluster_v3_Cluster *msg) {return _upb_msg_map_size(msg, UPB_SIZE(148, 272)); }
+UPB_INLINE bool envoy_config_cluster_v3_Cluster_typed_extension_protocol_options_get(const envoy_config_cluster_v3_Cluster *msg, upb_strview key, struct google_protobuf_Any* *val) { return _upb_msg_map_get(msg, UPB_SIZE(148, 272), &key, 0, val, sizeof(*val)); }
+UPB_INLINE const envoy_config_cluster_v3_Cluster_TypedExtensionProtocolOptionsEntry* envoy_config_cluster_v3_Cluster_typed_extension_protocol_options_next(const envoy_config_cluster_v3_Cluster *msg, size_t* iter) { return (const envoy_config_cluster_v3_Cluster_TypedExtensionProtocolOptionsEntry*)_upb_msg_map_next(msg, UPB_SIZE(148, 272), iter); }
+UPB_INLINE bool envoy_config_cluster_v3_Cluster_has_least_request_lb_config(const envoy_config_cluster_v3_Cluster *msg) { return _upb_getoneofcase(msg, UPB_SIZE(172, 320)) == 37; }
+UPB_INLINE const envoy_config_cluster_v3_Cluster_LeastRequestLbConfig* envoy_config_cluster_v3_Cluster_least_request_lb_config(const envoy_config_cluster_v3_Cluster *msg) { return UPB_READ_ONEOF(msg, const envoy_config_cluster_v3_Cluster_LeastRequestLbConfig*, UPB_SIZE(168, 312), UPB_SIZE(172, 320), 37, NULL); }
+UPB_INLINE bool envoy_config_cluster_v3_Cluster_has_cluster_type(const envoy_config_cluster_v3_Cluster *msg) { return _upb_getoneofcase(msg, UPB_SIZE(164, 304)) == 38; }
+UPB_INLINE const envoy_config_cluster_v3_Cluster_CustomClusterType* envoy_config_cluster_v3_Cluster_cluster_type(const envoy_config_cluster_v3_Cluster *msg) { return UPB_READ_ONEOF(msg, const envoy_config_cluster_v3_Cluster_CustomClusterType*, UPB_SIZE(160, 296), UPB_SIZE(164, 304), 38, NULL); }
+UPB_INLINE bool envoy_config_cluster_v3_Cluster_respect_dns_ttl(const envoy_config_cluster_v3_Cluster *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(18, 18), bool); }
+UPB_INLINE bool envoy_config_cluster_v3_Cluster_has_filters(const envoy_config_cluster_v3_Cluster *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(152, 280)); }
+UPB_INLINE const struct envoy_config_cluster_v3_Filter* const* envoy_config_cluster_v3_Cluster_filters(const envoy_config_cluster_v3_Cluster *msg, size_t *len) { return (const struct envoy_config_cluster_v3_Filter* const*)_upb_array_accessor(msg, UPB_SIZE(152, 280), len); }
+UPB_INLINE bool envoy_config_cluster_v3_Cluster_has_load_balancing_policy(const envoy_config_cluster_v3_Cluster *msg) { return _upb_hasbit(msg, 19); }
+UPB_INLINE const envoy_config_cluster_v3_LoadBalancingPolicy* envoy_config_cluster_v3_Cluster_load_balancing_policy(const envoy_config_cluster_v3_Cluster *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(112, 200), const envoy_config_cluster_v3_LoadBalancingPolicy*); }
+UPB_INLINE bool envoy_config_cluster_v3_Cluster_has_lrs_server(const envoy_config_cluster_v3_Cluster *msg) { return _upb_hasbit(msg, 20); }
+UPB_INLINE const struct envoy_config_core_v3_ConfigSource* envoy_config_cluster_v3_Cluster_lrs_server(const envoy_config_cluster_v3_Cluster *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(116, 208), const struct envoy_config_core_v3_ConfigSource*); }
+UPB_INLINE bool envoy_config_cluster_v3_Cluster_has_transport_socket_matches(const envoy_config_cluster_v3_Cluster *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(156, 288)); }
+UPB_INLINE const envoy_config_cluster_v3_Cluster_TransportSocketMatch* const* envoy_config_cluster_v3_Cluster_transport_socket_matches(const envoy_config_cluster_v3_Cluster *msg, size_t *len) { return (const envoy_config_cluster_v3_Cluster_TransportSocketMatch* const*)_upb_array_accessor(msg, UPB_SIZE(156, 288), len); }
+UPB_INLINE bool envoy_config_cluster_v3_Cluster_has_dns_failure_refresh_rate(const envoy_config_cluster_v3_Cluster *msg) { return _upb_hasbit(msg, 21); }
+UPB_INLINE const envoy_config_cluster_v3_Cluster_RefreshRate* envoy_config_cluster_v3_Cluster_dns_failure_refresh_rate(const envoy_config_cluster_v3_Cluster *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(120, 216), const envoy_config_cluster_v3_Cluster_RefreshRate*); }
+UPB_INLINE bool envoy_config_cluster_v3_Cluster_use_tcp_for_dns_lookups(const envoy_config_cluster_v3_Cluster *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(19, 19), bool); }
+UPB_INLINE bool envoy_config_cluster_v3_Cluster_has_upstream_http_protocol_options(const envoy_config_cluster_v3_Cluster *msg) { return _upb_hasbit(msg, 22); }
+UPB_INLINE const struct envoy_config_core_v3_UpstreamHttpProtocolOptions* envoy_config_cluster_v3_Cluster_upstream_http_protocol_options(const envoy_config_cluster_v3_Cluster *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(124, 224), const struct envoy_config_core_v3_UpstreamHttpProtocolOptions*); }
+UPB_INLINE bool envoy_config_cluster_v3_Cluster_track_timeout_budgets(const envoy_config_cluster_v3_Cluster *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(20, 20), bool); }
+UPB_INLINE bool envoy_config_cluster_v3_Cluster_has_upstream_config(const envoy_config_cluster_v3_Cluster *msg) { return _upb_hasbit(msg, 23); }
+UPB_INLINE const struct envoy_config_core_v3_TypedExtensionConfig* envoy_config_cluster_v3_Cluster_upstream_config(const envoy_config_cluster_v3_Cluster *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(128, 232), const struct envoy_config_core_v3_TypedExtensionConfig*); }
+UPB_INLINE bool envoy_config_cluster_v3_Cluster_has_track_cluster_stats(const envoy_config_cluster_v3_Cluster *msg) { return _upb_hasbit(msg, 24); }
+UPB_INLINE const envoy_config_cluster_v3_TrackClusterStats* envoy_config_cluster_v3_Cluster_track_cluster_stats(const envoy_config_cluster_v3_Cluster *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(132, 240), const envoy_config_cluster_v3_TrackClusterStats*); }
+UPB_INLINE bool envoy_config_cluster_v3_Cluster_has_prefetch_policy(const envoy_config_cluster_v3_Cluster *msg) { return _upb_hasbit(msg, 25); }
+UPB_INLINE const envoy_config_cluster_v3_Cluster_PrefetchPolicy* envoy_config_cluster_v3_Cluster_prefetch_policy(const envoy_config_cluster_v3_Cluster *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(136, 248), const envoy_config_cluster_v3_Cluster_PrefetchPolicy*); }
+UPB_INLINE bool envoy_config_cluster_v3_Cluster_connection_pool_per_downstream_connection(const envoy_config_cluster_v3_Cluster *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(21, 21), bool); }
+UPB_INLINE bool envoy_config_cluster_v3_Cluster_has_maglev_lb_config(const envoy_config_cluster_v3_Cluster *msg) { return _upb_getoneofcase(msg, UPB_SIZE(172, 320)) == 52; }
+UPB_INLINE const envoy_config_cluster_v3_Cluster_MaglevLbConfig* envoy_config_cluster_v3_Cluster_maglev_lb_config(const envoy_config_cluster_v3_Cluster *msg) { return UPB_READ_ONEOF(msg, const envoy_config_cluster_v3_Cluster_MaglevLbConfig*, UPB_SIZE(168, 312), UPB_SIZE(172, 320), 52, NULL); }
 
 UPB_INLINE void envoy_config_cluster_v3_Cluster_set_name(envoy_config_cluster_v3_Cluster *msg, upb_strview value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(32, 32), upb_strview) = value;
+  *UPB_PTR_AT(msg, UPB_SIZE(24, 24), upb_strview) = value;
 }
 UPB_INLINE void envoy_config_cluster_v3_Cluster_set_type(envoy_config_cluster_v3_Cluster *msg, int32_t value) {
-  UPB_WRITE_ONEOF(msg, int32_t, UPB_SIZE(168, 304), value, UPB_SIZE(176, 312), 2);
+  UPB_WRITE_ONEOF(msg, int32_t, UPB_SIZE(160, 296), value, UPB_SIZE(164, 304), 2);
 }
 UPB_INLINE void envoy_config_cluster_v3_Cluster_set_eds_cluster_config(envoy_config_cluster_v3_Cluster *msg, envoy_config_cluster_v3_Cluster_EdsClusterConfig* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(48, 64), envoy_config_cluster_v3_Cluster_EdsClusterConfig*) = value;
+  _upb_sethas(msg, 1);
+  *UPB_PTR_AT(msg, UPB_SIZE(40, 56), envoy_config_cluster_v3_Cluster_EdsClusterConfig*) = value;
 }
 UPB_INLINE struct envoy_config_cluster_v3_Cluster_EdsClusterConfig* envoy_config_cluster_v3_Cluster_mutable_eds_cluster_config(envoy_config_cluster_v3_Cluster *msg, upb_arena *arena) {
   struct envoy_config_cluster_v3_Cluster_EdsClusterConfig* sub = (struct envoy_config_cluster_v3_Cluster_EdsClusterConfig*)envoy_config_cluster_v3_Cluster_eds_cluster_config(msg);
@@ -355,7 +370,8 @@ UPB_INLINE struct envoy_config_cluster_v3_Cluster_EdsClusterConfig* envoy_config
   return sub;
 }
 UPB_INLINE void envoy_config_cluster_v3_Cluster_set_connect_timeout(envoy_config_cluster_v3_Cluster *msg, struct google_protobuf_Duration* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(52, 72), struct google_protobuf_Duration*) = value;
+  _upb_sethas(msg, 2);
+  *UPB_PTR_AT(msg, UPB_SIZE(44, 64), struct google_protobuf_Duration*) = value;
 }
 UPB_INLINE struct google_protobuf_Duration* envoy_config_cluster_v3_Cluster_mutable_connect_timeout(envoy_config_cluster_v3_Cluster *msg, upb_arena *arena) {
   struct google_protobuf_Duration* sub = (struct google_protobuf_Duration*)envoy_config_cluster_v3_Cluster_connect_timeout(msg);
@@ -367,7 +383,8 @@ UPB_INLINE struct google_protobuf_Duration* envoy_config_cluster_v3_Cluster_muta
   return sub;
 }
 UPB_INLINE void envoy_config_cluster_v3_Cluster_set_per_connection_buffer_limit_bytes(envoy_config_cluster_v3_Cluster *msg, struct google_protobuf_UInt32Value* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(56, 80), struct google_protobuf_UInt32Value*) = value;
+  _upb_sethas(msg, 3);
+  *UPB_PTR_AT(msg, UPB_SIZE(48, 72), struct google_protobuf_UInt32Value*) = value;
 }
 UPB_INLINE struct google_protobuf_UInt32Value* envoy_config_cluster_v3_Cluster_mutable_per_connection_buffer_limit_bytes(envoy_config_cluster_v3_Cluster *msg, upb_arena *arena) {
   struct google_protobuf_UInt32Value* sub = (struct google_protobuf_UInt32Value*)envoy_config_cluster_v3_Cluster_per_connection_buffer_limit_bytes(msg);
@@ -379,23 +396,24 @@ UPB_INLINE struct google_protobuf_UInt32Value* envoy_config_cluster_v3_Cluster_m
   return sub;
 }
 UPB_INLINE void envoy_config_cluster_v3_Cluster_set_lb_policy(envoy_config_cluster_v3_Cluster *msg, int32_t value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(0, 0), int32_t) = value;
+  *UPB_PTR_AT(msg, UPB_SIZE(4, 4), int32_t) = value;
 }
 UPB_INLINE struct envoy_config_core_v3_HealthCheck** envoy_config_cluster_v3_Cluster_mutable_health_checks(envoy_config_cluster_v3_Cluster *msg, size_t *len) {
-  return (struct envoy_config_core_v3_HealthCheck**)_upb_array_mutable_accessor(msg, UPB_SIZE(148, 264), len);
+  return (struct envoy_config_core_v3_HealthCheck**)_upb_array_mutable_accessor(msg, UPB_SIZE(140, 256), len);
 }
 UPB_INLINE struct envoy_config_core_v3_HealthCheck** envoy_config_cluster_v3_Cluster_resize_health_checks(envoy_config_cluster_v3_Cluster *msg, size_t len, upb_arena *arena) {
-  return (struct envoy_config_core_v3_HealthCheck**)_upb_array_resize_accessor(msg, UPB_SIZE(148, 264), len, UPB_TYPE_MESSAGE, arena);
+  return (struct envoy_config_core_v3_HealthCheck**)_upb_array_resize_accessor2(msg, UPB_SIZE(140, 256), len, UPB_SIZE(2, 3), arena);
 }
 UPB_INLINE struct envoy_config_core_v3_HealthCheck* envoy_config_cluster_v3_Cluster_add_health_checks(envoy_config_cluster_v3_Cluster *msg, upb_arena *arena) {
   struct envoy_config_core_v3_HealthCheck* sub = (struct envoy_config_core_v3_HealthCheck*)_upb_msg_new(&envoy_config_core_v3_HealthCheck_msginit, arena);
-  bool ok = _upb_array_append_accessor(
-      msg, UPB_SIZE(148, 264), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena);
+  bool ok = _upb_array_append_accessor2(
+      msg, UPB_SIZE(140, 256), UPB_SIZE(2, 3), &sub, arena);
   if (!ok) return NULL;
   return sub;
 }
 UPB_INLINE void envoy_config_cluster_v3_Cluster_set_max_requests_per_connection(envoy_config_cluster_v3_Cluster *msg, struct google_protobuf_UInt32Value* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(60, 88), struct google_protobuf_UInt32Value*) = value;
+  _upb_sethas(msg, 4);
+  *UPB_PTR_AT(msg, UPB_SIZE(52, 80), struct google_protobuf_UInt32Value*) = value;
 }
 UPB_INLINE struct google_protobuf_UInt32Value* envoy_config_cluster_v3_Cluster_mutable_max_requests_per_connection(envoy_config_cluster_v3_Cluster *msg, upb_arena *arena) {
   struct google_protobuf_UInt32Value* sub = (struct google_protobuf_UInt32Value*)envoy_config_cluster_v3_Cluster_max_requests_per_connection(msg);
@@ -407,7 +425,8 @@ UPB_INLINE struct google_protobuf_UInt32Value* envoy_config_cluster_v3_Cluster_m
   return sub;
 }
 UPB_INLINE void envoy_config_cluster_v3_Cluster_set_circuit_breakers(envoy_config_cluster_v3_Cluster *msg, struct envoy_config_cluster_v3_CircuitBreakers* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(64, 96), struct envoy_config_cluster_v3_CircuitBreakers*) = value;
+  _upb_sethas(msg, 5);
+  *UPB_PTR_AT(msg, UPB_SIZE(56, 88), struct envoy_config_cluster_v3_CircuitBreakers*) = value;
 }
 UPB_INLINE struct envoy_config_cluster_v3_CircuitBreakers* envoy_config_cluster_v3_Cluster_mutable_circuit_breakers(envoy_config_cluster_v3_Cluster *msg, upb_arena *arena) {
   struct envoy_config_cluster_v3_CircuitBreakers* sub = (struct envoy_config_cluster_v3_CircuitBreakers*)envoy_config_cluster_v3_Cluster_circuit_breakers(msg);
@@ -419,7 +438,8 @@ UPB_INLINE struct envoy_config_cluster_v3_CircuitBreakers* envoy_config_cluster_
   return sub;
 }
 UPB_INLINE void envoy_config_cluster_v3_Cluster_set_http_protocol_options(envoy_config_cluster_v3_Cluster *msg, struct envoy_config_core_v3_Http1ProtocolOptions* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(68, 104), struct envoy_config_core_v3_Http1ProtocolOptions*) = value;
+  _upb_sethas(msg, 6);
+  *UPB_PTR_AT(msg, UPB_SIZE(60, 96), struct envoy_config_core_v3_Http1ProtocolOptions*) = value;
 }
 UPB_INLINE struct envoy_config_core_v3_Http1ProtocolOptions* envoy_config_cluster_v3_Cluster_mutable_http_protocol_options(envoy_config_cluster_v3_Cluster *msg, upb_arena *arena) {
   struct envoy_config_core_v3_Http1ProtocolOptions* sub = (struct envoy_config_core_v3_Http1ProtocolOptions*)envoy_config_cluster_v3_Cluster_http_protocol_options(msg);
@@ -431,7 +451,8 @@ UPB_INLINE struct envoy_config_core_v3_Http1ProtocolOptions* envoy_config_cluste
   return sub;
 }
 UPB_INLINE void envoy_config_cluster_v3_Cluster_set_http2_protocol_options(envoy_config_cluster_v3_Cluster *msg, struct envoy_config_core_v3_Http2ProtocolOptions* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(72, 112), struct envoy_config_core_v3_Http2ProtocolOptions*) = value;
+  _upb_sethas(msg, 7);
+  *UPB_PTR_AT(msg, UPB_SIZE(64, 104), struct envoy_config_core_v3_Http2ProtocolOptions*) = value;
 }
 UPB_INLINE struct envoy_config_core_v3_Http2ProtocolOptions* envoy_config_cluster_v3_Cluster_mutable_http2_protocol_options(envoy_config_cluster_v3_Cluster *msg, upb_arena *arena) {
   struct envoy_config_core_v3_Http2ProtocolOptions* sub = (struct envoy_config_core_v3_Http2ProtocolOptions*)envoy_config_cluster_v3_Cluster_http2_protocol_options(msg);
@@ -443,7 +464,8 @@ UPB_INLINE struct envoy_config_core_v3_Http2ProtocolOptions* envoy_config_cluste
   return sub;
 }
 UPB_INLINE void envoy_config_cluster_v3_Cluster_set_dns_refresh_rate(envoy_config_cluster_v3_Cluster *msg, struct google_protobuf_Duration* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(76, 120), struct google_protobuf_Duration*) = value;
+  _upb_sethas(msg, 8);
+  *UPB_PTR_AT(msg, UPB_SIZE(68, 112), struct google_protobuf_Duration*) = value;
 }
 UPB_INLINE struct google_protobuf_Duration* envoy_config_cluster_v3_Cluster_mutable_dns_refresh_rate(envoy_config_cluster_v3_Cluster *msg, upb_arena *arena) {
   struct google_protobuf_Duration* sub = (struct google_protobuf_Duration*)envoy_config_cluster_v3_Cluster_dns_refresh_rate(msg);
@@ -458,20 +480,21 @@ UPB_INLINE void envoy_config_cluster_v3_Cluster_set_dns_lookup_family(envoy_conf
   *UPB_PTR_AT(msg, UPB_SIZE(8, 8), int32_t) = value;
 }
 UPB_INLINE struct envoy_config_core_v3_Address** envoy_config_cluster_v3_Cluster_mutable_dns_resolvers(envoy_config_cluster_v3_Cluster *msg, size_t *len) {
-  return (struct envoy_config_core_v3_Address**)_upb_array_mutable_accessor(msg, UPB_SIZE(152, 272), len);
+  return (struct envoy_config_core_v3_Address**)_upb_array_mutable_accessor(msg, UPB_SIZE(144, 264), len);
 }
 UPB_INLINE struct envoy_config_core_v3_Address** envoy_config_cluster_v3_Cluster_resize_dns_resolvers(envoy_config_cluster_v3_Cluster *msg, size_t len, upb_arena *arena) {
-  return (struct envoy_config_core_v3_Address**)_upb_array_resize_accessor(msg, UPB_SIZE(152, 272), len, UPB_TYPE_MESSAGE, arena);
+  return (struct envoy_config_core_v3_Address**)_upb_array_resize_accessor2(msg, UPB_SIZE(144, 264), len, UPB_SIZE(2, 3), arena);
 }
 UPB_INLINE struct envoy_config_core_v3_Address* envoy_config_cluster_v3_Cluster_add_dns_resolvers(envoy_config_cluster_v3_Cluster *msg, upb_arena *arena) {
   struct envoy_config_core_v3_Address* sub = (struct envoy_config_core_v3_Address*)_upb_msg_new(&envoy_config_core_v3_Address_msginit, arena);
-  bool ok = _upb_array_append_accessor(
-      msg, UPB_SIZE(152, 272), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena);
+  bool ok = _upb_array_append_accessor2(
+      msg, UPB_SIZE(144, 264), UPB_SIZE(2, 3), &sub, arena);
   if (!ok) return NULL;
   return sub;
 }
 UPB_INLINE void envoy_config_cluster_v3_Cluster_set_outlier_detection(envoy_config_cluster_v3_Cluster *msg, struct envoy_config_cluster_v3_OutlierDetection* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(80, 128), struct envoy_config_cluster_v3_OutlierDetection*) = value;
+  _upb_sethas(msg, 9);
+  *UPB_PTR_AT(msg, UPB_SIZE(72, 120), struct envoy_config_cluster_v3_OutlierDetection*) = value;
 }
 UPB_INLINE struct envoy_config_cluster_v3_OutlierDetection* envoy_config_cluster_v3_Cluster_mutable_outlier_detection(envoy_config_cluster_v3_Cluster *msg, upb_arena *arena) {
   struct envoy_config_cluster_v3_OutlierDetection* sub = (struct envoy_config_cluster_v3_OutlierDetection*)envoy_config_cluster_v3_Cluster_outlier_detection(msg);
@@ -483,7 +506,8 @@ UPB_INLINE struct envoy_config_cluster_v3_OutlierDetection* envoy_config_cluster
   return sub;
 }
 UPB_INLINE void envoy_config_cluster_v3_Cluster_set_cleanup_interval(envoy_config_cluster_v3_Cluster *msg, struct google_protobuf_Duration* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(84, 136), struct google_protobuf_Duration*) = value;
+  _upb_sethas(msg, 10);
+  *UPB_PTR_AT(msg, UPB_SIZE(76, 128), struct google_protobuf_Duration*) = value;
 }
 UPB_INLINE struct google_protobuf_Duration* envoy_config_cluster_v3_Cluster_mutable_cleanup_interval(envoy_config_cluster_v3_Cluster *msg, upb_arena *arena) {
   struct google_protobuf_Duration* sub = (struct google_protobuf_Duration*)envoy_config_cluster_v3_Cluster_cleanup_interval(msg);
@@ -495,7 +519,8 @@ UPB_INLINE struct google_protobuf_Duration* envoy_config_cluster_v3_Cluster_muta
   return sub;
 }
 UPB_INLINE void envoy_config_cluster_v3_Cluster_set_upstream_bind_config(envoy_config_cluster_v3_Cluster *msg, struct envoy_config_core_v3_BindConfig* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(88, 144), struct envoy_config_core_v3_BindConfig*) = value;
+  _upb_sethas(msg, 11);
+  *UPB_PTR_AT(msg, UPB_SIZE(80, 136), struct envoy_config_core_v3_BindConfig*) = value;
 }
 UPB_INLINE struct envoy_config_core_v3_BindConfig* envoy_config_cluster_v3_Cluster_mutable_upstream_bind_config(envoy_config_cluster_v3_Cluster *msg, upb_arena *arena) {
   struct envoy_config_core_v3_BindConfig* sub = (struct envoy_config_core_v3_BindConfig*)envoy_config_cluster_v3_Cluster_upstream_bind_config(msg);
@@ -507,7 +532,8 @@ UPB_INLINE struct envoy_config_core_v3_BindConfig* envoy_config_cluster_v3_Clust
   return sub;
 }
 UPB_INLINE void envoy_config_cluster_v3_Cluster_set_lb_subset_config(envoy_config_cluster_v3_Cluster *msg, envoy_config_cluster_v3_Cluster_LbSubsetConfig* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(92, 152), envoy_config_cluster_v3_Cluster_LbSubsetConfig*) = value;
+  _upb_sethas(msg, 12);
+  *UPB_PTR_AT(msg, UPB_SIZE(84, 144), envoy_config_cluster_v3_Cluster_LbSubsetConfig*) = value;
 }
 UPB_INLINE struct envoy_config_cluster_v3_Cluster_LbSubsetConfig* envoy_config_cluster_v3_Cluster_mutable_lb_subset_config(envoy_config_cluster_v3_Cluster *msg, upb_arena *arena) {
   struct envoy_config_cluster_v3_Cluster_LbSubsetConfig* sub = (struct envoy_config_cluster_v3_Cluster_LbSubsetConfig*)envoy_config_cluster_v3_Cluster_lb_subset_config(msg);
@@ -519,7 +545,7 @@ UPB_INLINE struct envoy_config_cluster_v3_Cluster_LbSubsetConfig* envoy_config_c
   return sub;
 }
 UPB_INLINE void envoy_config_cluster_v3_Cluster_set_ring_hash_lb_config(envoy_config_cluster_v3_Cluster *msg, envoy_config_cluster_v3_Cluster_RingHashLbConfig* value) {
-  UPB_WRITE_ONEOF(msg, envoy_config_cluster_v3_Cluster_RingHashLbConfig*, UPB_SIZE(180, 320), value, UPB_SIZE(184, 328), 23);
+  UPB_WRITE_ONEOF(msg, envoy_config_cluster_v3_Cluster_RingHashLbConfig*, UPB_SIZE(168, 312), value, UPB_SIZE(172, 320), 23);
 }
 UPB_INLINE struct envoy_config_cluster_v3_Cluster_RingHashLbConfig* envoy_config_cluster_v3_Cluster_mutable_ring_hash_lb_config(envoy_config_cluster_v3_Cluster *msg, upb_arena *arena) {
   struct envoy_config_cluster_v3_Cluster_RingHashLbConfig* sub = (struct envoy_config_cluster_v3_Cluster_RingHashLbConfig*)envoy_config_cluster_v3_Cluster_ring_hash_lb_config(msg);
@@ -531,7 +557,8 @@ UPB_INLINE struct envoy_config_cluster_v3_Cluster_RingHashLbConfig* envoy_config
   return sub;
 }
 UPB_INLINE void envoy_config_cluster_v3_Cluster_set_transport_socket(envoy_config_cluster_v3_Cluster *msg, struct envoy_config_core_v3_TransportSocket* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(96, 160), struct envoy_config_core_v3_TransportSocket*) = value;
+  _upb_sethas(msg, 13);
+  *UPB_PTR_AT(msg, UPB_SIZE(88, 152), struct envoy_config_core_v3_TransportSocket*) = value;
 }
 UPB_INLINE struct envoy_config_core_v3_TransportSocket* envoy_config_cluster_v3_Cluster_mutable_transport_socket(envoy_config_cluster_v3_Cluster *msg, upb_arena *arena) {
   struct envoy_config_core_v3_TransportSocket* sub = (struct envoy_config_core_v3_TransportSocket*)envoy_config_cluster_v3_Cluster_transport_socket(msg);
@@ -543,7 +570,8 @@ UPB_INLINE struct envoy_config_core_v3_TransportSocket* envoy_config_cluster_v3_
   return sub;
 }
 UPB_INLINE void envoy_config_cluster_v3_Cluster_set_metadata(envoy_config_cluster_v3_Cluster *msg, struct envoy_config_core_v3_Metadata* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(100, 168), struct envoy_config_core_v3_Metadata*) = value;
+  _upb_sethas(msg, 14);
+  *UPB_PTR_AT(msg, UPB_SIZE(92, 160), struct envoy_config_core_v3_Metadata*) = value;
 }
 UPB_INLINE struct envoy_config_core_v3_Metadata* envoy_config_cluster_v3_Cluster_mutable_metadata(envoy_config_cluster_v3_Cluster *msg, upb_arena *arena) {
   struct envoy_config_core_v3_Metadata* sub = (struct envoy_config_core_v3_Metadata*)envoy_config_cluster_v3_Cluster_metadata(msg);
@@ -555,10 +583,11 @@ UPB_INLINE struct envoy_config_core_v3_Metadata* envoy_config_cluster_v3_Cluster
   return sub;
 }
 UPB_INLINE void envoy_config_cluster_v3_Cluster_set_protocol_selection(envoy_config_cluster_v3_Cluster *msg, int32_t value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(16, 16), int32_t) = value;
+  *UPB_PTR_AT(msg, UPB_SIZE(12, 12), int32_t) = value;
 }
 UPB_INLINE void envoy_config_cluster_v3_Cluster_set_common_lb_config(envoy_config_cluster_v3_Cluster *msg, envoy_config_cluster_v3_Cluster_CommonLbConfig* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(104, 176), envoy_config_cluster_v3_Cluster_CommonLbConfig*) = value;
+  _upb_sethas(msg, 15);
+  *UPB_PTR_AT(msg, UPB_SIZE(96, 168), envoy_config_cluster_v3_Cluster_CommonLbConfig*) = value;
 }
 UPB_INLINE struct envoy_config_cluster_v3_Cluster_CommonLbConfig* envoy_config_cluster_v3_Cluster_mutable_common_lb_config(envoy_config_cluster_v3_Cluster *msg, upb_arena *arena) {
   struct envoy_config_cluster_v3_Cluster_CommonLbConfig* sub = (struct envoy_config_cluster_v3_Cluster_CommonLbConfig*)envoy_config_cluster_v3_Cluster_common_lb_config(msg);
@@ -570,10 +599,11 @@ UPB_INLINE struct envoy_config_cluster_v3_Cluster_CommonLbConfig* envoy_config_c
   return sub;
 }
 UPB_INLINE void envoy_config_cluster_v3_Cluster_set_alt_stat_name(envoy_config_cluster_v3_Cluster *msg, upb_strview value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(40, 48), upb_strview) = value;
+  *UPB_PTR_AT(msg, UPB_SIZE(32, 40), upb_strview) = value;
 }
 UPB_INLINE void envoy_config_cluster_v3_Cluster_set_common_http_protocol_options(envoy_config_cluster_v3_Cluster *msg, struct envoy_config_core_v3_HttpProtocolOptions* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(108, 184), struct envoy_config_core_v3_HttpProtocolOptions*) = value;
+  _upb_sethas(msg, 16);
+  *UPB_PTR_AT(msg, UPB_SIZE(100, 176), struct envoy_config_core_v3_HttpProtocolOptions*) = value;
 }
 UPB_INLINE struct envoy_config_core_v3_HttpProtocolOptions* envoy_config_cluster_v3_Cluster_mutable_common_http_protocol_options(envoy_config_cluster_v3_Cluster *msg, upb_arena *arena) {
   struct envoy_config_core_v3_HttpProtocolOptions* sub = (struct envoy_config_core_v3_HttpProtocolOptions*)envoy_config_cluster_v3_Cluster_common_http_protocol_options(msg);
@@ -585,7 +615,8 @@ UPB_INLINE struct envoy_config_core_v3_HttpProtocolOptions* envoy_config_cluster
   return sub;
 }
 UPB_INLINE void envoy_config_cluster_v3_Cluster_set_upstream_connection_options(envoy_config_cluster_v3_Cluster *msg, envoy_config_cluster_v3_UpstreamConnectionOptions* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(112, 192), envoy_config_cluster_v3_UpstreamConnectionOptions*) = value;
+  _upb_sethas(msg, 17);
+  *UPB_PTR_AT(msg, UPB_SIZE(104, 184), envoy_config_cluster_v3_UpstreamConnectionOptions*) = value;
 }
 UPB_INLINE struct envoy_config_cluster_v3_UpstreamConnectionOptions* envoy_config_cluster_v3_Cluster_mutable_upstream_connection_options(envoy_config_cluster_v3_Cluster *msg, upb_arena *arena) {
   struct envoy_config_cluster_v3_UpstreamConnectionOptions* sub = (struct envoy_config_cluster_v3_UpstreamConnectionOptions*)envoy_config_cluster_v3_Cluster_upstream_connection_options(msg);
@@ -597,13 +628,14 @@ UPB_INLINE struct envoy_config_cluster_v3_UpstreamConnectionOptions* envoy_confi
   return sub;
 }
 UPB_INLINE void envoy_config_cluster_v3_Cluster_set_close_connections_on_host_health_failure(envoy_config_cluster_v3_Cluster *msg, bool value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(24, 24), bool) = value;
+  *UPB_PTR_AT(msg, UPB_SIZE(16, 16), bool) = value;
 }
 UPB_INLINE void envoy_config_cluster_v3_Cluster_set_ignore_health_on_host_removal(envoy_config_cluster_v3_Cluster *msg, bool value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(25, 25), bool) = value;
+  *UPB_PTR_AT(msg, UPB_SIZE(17, 17), bool) = value;
 }
 UPB_INLINE void envoy_config_cluster_v3_Cluster_set_load_assignment(envoy_config_cluster_v3_Cluster *msg, struct envoy_config_endpoint_v3_ClusterLoadAssignment* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(116, 200), struct envoy_config_endpoint_v3_ClusterLoadAssignment*) = value;
+  _upb_sethas(msg, 18);
+  *UPB_PTR_AT(msg, UPB_SIZE(108, 192), struct envoy_config_endpoint_v3_ClusterLoadAssignment*) = value;
 }
 UPB_INLINE struct envoy_config_endpoint_v3_ClusterLoadAssignment* envoy_config_cluster_v3_Cluster_mutable_load_assignment(envoy_config_cluster_v3_Cluster *msg, upb_arena *arena) {
   struct envoy_config_endpoint_v3_ClusterLoadAssignment* sub = (struct envoy_config_endpoint_v3_ClusterLoadAssignment*)envoy_config_cluster_v3_Cluster_load_assignment(msg);
@@ -615,7 +647,7 @@ UPB_INLINE struct envoy_config_endpoint_v3_ClusterLoadAssignment* envoy_config_c
   return sub;
 }
 UPB_INLINE void envoy_config_cluster_v3_Cluster_set_original_dst_lb_config(envoy_config_cluster_v3_Cluster *msg, envoy_config_cluster_v3_Cluster_OriginalDstLbConfig* value) {
-  UPB_WRITE_ONEOF(msg, envoy_config_cluster_v3_Cluster_OriginalDstLbConfig*, UPB_SIZE(180, 320), value, UPB_SIZE(184, 328), 34);
+  UPB_WRITE_ONEOF(msg, envoy_config_cluster_v3_Cluster_OriginalDstLbConfig*, UPB_SIZE(168, 312), value, UPB_SIZE(172, 320), 34);
 }
 UPB_INLINE struct envoy_config_cluster_v3_Cluster_OriginalDstLbConfig* envoy_config_cluster_v3_Cluster_mutable_original_dst_lb_config(envoy_config_cluster_v3_Cluster *msg, upb_arena *arena) {
   struct envoy_config_cluster_v3_Cluster_OriginalDstLbConfig* sub = (struct envoy_config_cluster_v3_Cluster_OriginalDstLbConfig*)envoy_config_cluster_v3_Cluster_original_dst_lb_config(msg);
@@ -626,12 +658,12 @@ UPB_INLINE struct envoy_config_cluster_v3_Cluster_OriginalDstLbConfig* envoy_con
   }
   return sub;
 }
-UPB_INLINE void envoy_config_cluster_v3_Cluster_typed_extension_protocol_options_clear(envoy_config_cluster_v3_Cluster *msg) { _upb_msg_map_clear(msg, UPB_SIZE(156, 280)); }
-UPB_INLINE bool envoy_config_cluster_v3_Cluster_typed_extension_protocol_options_set(envoy_config_cluster_v3_Cluster *msg, upb_strview key, struct google_protobuf_Any* val, upb_arena *a) { return _upb_msg_map_set(msg, UPB_SIZE(156, 280), &key, 0, &val, sizeof(val), a); }
-UPB_INLINE bool envoy_config_cluster_v3_Cluster_typed_extension_protocol_options_delete(envoy_config_cluster_v3_Cluster *msg, upb_strview key) { return _upb_msg_map_delete(msg, UPB_SIZE(156, 280), &key, 0); }
-UPB_INLINE envoy_config_cluster_v3_Cluster_TypedExtensionProtocolOptionsEntry* envoy_config_cluster_v3_Cluster_typed_extension_protocol_options_nextmutable(envoy_config_cluster_v3_Cluster *msg, size_t* iter) { return (envoy_config_cluster_v3_Cluster_TypedExtensionProtocolOptionsEntry*)_upb_msg_map_next(msg, UPB_SIZE(156, 280), iter); }
+UPB_INLINE void envoy_config_cluster_v3_Cluster_typed_extension_protocol_options_clear(envoy_config_cluster_v3_Cluster *msg) { _upb_msg_map_clear(msg, UPB_SIZE(148, 272)); }
+UPB_INLINE bool envoy_config_cluster_v3_Cluster_typed_extension_protocol_options_set(envoy_config_cluster_v3_Cluster *msg, upb_strview key, struct google_protobuf_Any* val, upb_arena *a) { return _upb_msg_map_set(msg, UPB_SIZE(148, 272), &key, 0, &val, sizeof(val), a); }
+UPB_INLINE bool envoy_config_cluster_v3_Cluster_typed_extension_protocol_options_delete(envoy_config_cluster_v3_Cluster *msg, upb_strview key) { return _upb_msg_map_delete(msg, UPB_SIZE(148, 272), &key, 0); }
+UPB_INLINE envoy_config_cluster_v3_Cluster_TypedExtensionProtocolOptionsEntry* envoy_config_cluster_v3_Cluster_typed_extension_protocol_options_nextmutable(envoy_config_cluster_v3_Cluster *msg, size_t* iter) { return (envoy_config_cluster_v3_Cluster_TypedExtensionProtocolOptionsEntry*)_upb_msg_map_next(msg, UPB_SIZE(148, 272), iter); }
 UPB_INLINE void envoy_config_cluster_v3_Cluster_set_least_request_lb_config(envoy_config_cluster_v3_Cluster *msg, envoy_config_cluster_v3_Cluster_LeastRequestLbConfig* value) {
-  UPB_WRITE_ONEOF(msg, envoy_config_cluster_v3_Cluster_LeastRequestLbConfig*, UPB_SIZE(180, 320), value, UPB_SIZE(184, 328), 37);
+  UPB_WRITE_ONEOF(msg, envoy_config_cluster_v3_Cluster_LeastRequestLbConfig*, UPB_SIZE(168, 312), value, UPB_SIZE(172, 320), 37);
 }
 UPB_INLINE struct envoy_config_cluster_v3_Cluster_LeastRequestLbConfig* envoy_config_cluster_v3_Cluster_mutable_least_request_lb_config(envoy_config_cluster_v3_Cluster *msg, upb_arena *arena) {
   struct envoy_config_cluster_v3_Cluster_LeastRequestLbConfig* sub = (struct envoy_config_cluster_v3_Cluster_LeastRequestLbConfig*)envoy_config_cluster_v3_Cluster_least_request_lb_config(msg);
@@ -643,7 +675,7 @@ UPB_INLINE struct envoy_config_cluster_v3_Cluster_LeastRequestLbConfig* envoy_co
   return sub;
 }
 UPB_INLINE void envoy_config_cluster_v3_Cluster_set_cluster_type(envoy_config_cluster_v3_Cluster *msg, envoy_config_cluster_v3_Cluster_CustomClusterType* value) {
-  UPB_WRITE_ONEOF(msg, envoy_config_cluster_v3_Cluster_CustomClusterType*, UPB_SIZE(168, 304), value, UPB_SIZE(176, 312), 38);
+  UPB_WRITE_ONEOF(msg, envoy_config_cluster_v3_Cluster_CustomClusterType*, UPB_SIZE(160, 296), value, UPB_SIZE(164, 304), 38);
 }
 UPB_INLINE struct envoy_config_cluster_v3_Cluster_CustomClusterType* envoy_config_cluster_v3_Cluster_mutable_cluster_type(envoy_config_cluster_v3_Cluster *msg, upb_arena *arena) {
   struct envoy_config_cluster_v3_Cluster_CustomClusterType* sub = (struct envoy_config_cluster_v3_Cluster_CustomClusterType*)envoy_config_cluster_v3_Cluster_cluster_type(msg);
@@ -655,23 +687,24 @@ UPB_INLINE struct envoy_config_cluster_v3_Cluster_CustomClusterType* envoy_confi
   return sub;
 }
 UPB_INLINE void envoy_config_cluster_v3_Cluster_set_respect_dns_ttl(envoy_config_cluster_v3_Cluster *msg, bool value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(26, 26), bool) = value;
+  *UPB_PTR_AT(msg, UPB_SIZE(18, 18), bool) = value;
 }
 UPB_INLINE struct envoy_config_cluster_v3_Filter** envoy_config_cluster_v3_Cluster_mutable_filters(envoy_config_cluster_v3_Cluster *msg, size_t *len) {
-  return (struct envoy_config_cluster_v3_Filter**)_upb_array_mutable_accessor(msg, UPB_SIZE(160, 288), len);
+  return (struct envoy_config_cluster_v3_Filter**)_upb_array_mutable_accessor(msg, UPB_SIZE(152, 280), len);
 }
 UPB_INLINE struct envoy_config_cluster_v3_Filter** envoy_config_cluster_v3_Cluster_resize_filters(envoy_config_cluster_v3_Cluster *msg, size_t len, upb_arena *arena) {
-  return (struct envoy_config_cluster_v3_Filter**)_upb_array_resize_accessor(msg, UPB_SIZE(160, 288), len, UPB_TYPE_MESSAGE, arena);
+  return (struct envoy_config_cluster_v3_Filter**)_upb_array_resize_accessor2(msg, UPB_SIZE(152, 280), len, UPB_SIZE(2, 3), arena);
 }
 UPB_INLINE struct envoy_config_cluster_v3_Filter* envoy_config_cluster_v3_Cluster_add_filters(envoy_config_cluster_v3_Cluster *msg, upb_arena *arena) {
   struct envoy_config_cluster_v3_Filter* sub = (struct envoy_config_cluster_v3_Filter*)_upb_msg_new(&envoy_config_cluster_v3_Filter_msginit, arena);
-  bool ok = _upb_array_append_accessor(
-      msg, UPB_SIZE(160, 288), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena);
+  bool ok = _upb_array_append_accessor2(
+      msg, UPB_SIZE(152, 280), UPB_SIZE(2, 3), &sub, arena);
   if (!ok) return NULL;
   return sub;
 }
 UPB_INLINE void envoy_config_cluster_v3_Cluster_set_load_balancing_policy(envoy_config_cluster_v3_Cluster *msg, envoy_config_cluster_v3_LoadBalancingPolicy* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(120, 208), envoy_config_cluster_v3_LoadBalancingPolicy*) = value;
+  _upb_sethas(msg, 19);
+  *UPB_PTR_AT(msg, UPB_SIZE(112, 200), envoy_config_cluster_v3_LoadBalancingPolicy*) = value;
 }
 UPB_INLINE struct envoy_config_cluster_v3_LoadBalancingPolicy* envoy_config_cluster_v3_Cluster_mutable_load_balancing_policy(envoy_config_cluster_v3_Cluster *msg, upb_arena *arena) {
   struct envoy_config_cluster_v3_LoadBalancingPolicy* sub = (struct envoy_config_cluster_v3_LoadBalancingPolicy*)envoy_config_cluster_v3_Cluster_load_balancing_policy(msg);
@@ -683,7 +716,8 @@ UPB_INLINE struct envoy_config_cluster_v3_LoadBalancingPolicy* envoy_config_clus
   return sub;
 }
 UPB_INLINE void envoy_config_cluster_v3_Cluster_set_lrs_server(envoy_config_cluster_v3_Cluster *msg, struct envoy_config_core_v3_ConfigSource* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(124, 216), struct envoy_config_core_v3_ConfigSource*) = value;
+  _upb_sethas(msg, 20);
+  *UPB_PTR_AT(msg, UPB_SIZE(116, 208), struct envoy_config_core_v3_ConfigSource*) = value;
 }
 UPB_INLINE struct envoy_config_core_v3_ConfigSource* envoy_config_cluster_v3_Cluster_mutable_lrs_server(envoy_config_cluster_v3_Cluster *msg, upb_arena *arena) {
   struct envoy_config_core_v3_ConfigSource* sub = (struct envoy_config_core_v3_ConfigSource*)envoy_config_cluster_v3_Cluster_lrs_server(msg);
@@ -695,20 +729,21 @@ UPB_INLINE struct envoy_config_core_v3_ConfigSource* envoy_config_cluster_v3_Clu
   return sub;
 }
 UPB_INLINE envoy_config_cluster_v3_Cluster_TransportSocketMatch** envoy_config_cluster_v3_Cluster_mutable_transport_socket_matches(envoy_config_cluster_v3_Cluster *msg, size_t *len) {
-  return (envoy_config_cluster_v3_Cluster_TransportSocketMatch**)_upb_array_mutable_accessor(msg, UPB_SIZE(164, 296), len);
+  return (envoy_config_cluster_v3_Cluster_TransportSocketMatch**)_upb_array_mutable_accessor(msg, UPB_SIZE(156, 288), len);
 }
 UPB_INLINE envoy_config_cluster_v3_Cluster_TransportSocketMatch** envoy_config_cluster_v3_Cluster_resize_transport_socket_matches(envoy_config_cluster_v3_Cluster *msg, size_t len, upb_arena *arena) {
-  return (envoy_config_cluster_v3_Cluster_TransportSocketMatch**)_upb_array_resize_accessor(msg, UPB_SIZE(164, 296), len, UPB_TYPE_MESSAGE, arena);
+  return (envoy_config_cluster_v3_Cluster_TransportSocketMatch**)_upb_array_resize_accessor2(msg, UPB_SIZE(156, 288), len, UPB_SIZE(2, 3), arena);
 }
 UPB_INLINE struct envoy_config_cluster_v3_Cluster_TransportSocketMatch* envoy_config_cluster_v3_Cluster_add_transport_socket_matches(envoy_config_cluster_v3_Cluster *msg, upb_arena *arena) {
   struct envoy_config_cluster_v3_Cluster_TransportSocketMatch* sub = (struct envoy_config_cluster_v3_Cluster_TransportSocketMatch*)_upb_msg_new(&envoy_config_cluster_v3_Cluster_TransportSocketMatch_msginit, arena);
-  bool ok = _upb_array_append_accessor(
-      msg, UPB_SIZE(164, 296), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena);
+  bool ok = _upb_array_append_accessor2(
+      msg, UPB_SIZE(156, 288), UPB_SIZE(2, 3), &sub, arena);
   if (!ok) return NULL;
   return sub;
 }
 UPB_INLINE void envoy_config_cluster_v3_Cluster_set_dns_failure_refresh_rate(envoy_config_cluster_v3_Cluster *msg, envoy_config_cluster_v3_Cluster_RefreshRate* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(128, 224), envoy_config_cluster_v3_Cluster_RefreshRate*) = value;
+  _upb_sethas(msg, 21);
+  *UPB_PTR_AT(msg, UPB_SIZE(120, 216), envoy_config_cluster_v3_Cluster_RefreshRate*) = value;
 }
 UPB_INLINE struct envoy_config_cluster_v3_Cluster_RefreshRate* envoy_config_cluster_v3_Cluster_mutable_dns_failure_refresh_rate(envoy_config_cluster_v3_Cluster *msg, upb_arena *arena) {
   struct envoy_config_cluster_v3_Cluster_RefreshRate* sub = (struct envoy_config_cluster_v3_Cluster_RefreshRate*)envoy_config_cluster_v3_Cluster_dns_failure_refresh_rate(msg);
@@ -720,10 +755,11 @@ UPB_INLINE struct envoy_config_cluster_v3_Cluster_RefreshRate* envoy_config_clus
   return sub;
 }
 UPB_INLINE void envoy_config_cluster_v3_Cluster_set_use_tcp_for_dns_lookups(envoy_config_cluster_v3_Cluster *msg, bool value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(27, 27), bool) = value;
+  *UPB_PTR_AT(msg, UPB_SIZE(19, 19), bool) = value;
 }
 UPB_INLINE void envoy_config_cluster_v3_Cluster_set_upstream_http_protocol_options(envoy_config_cluster_v3_Cluster *msg, struct envoy_config_core_v3_UpstreamHttpProtocolOptions* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(132, 232), struct envoy_config_core_v3_UpstreamHttpProtocolOptions*) = value;
+  _upb_sethas(msg, 22);
+  *UPB_PTR_AT(msg, UPB_SIZE(124, 224), struct envoy_config_core_v3_UpstreamHttpProtocolOptions*) = value;
 }
 UPB_INLINE struct envoy_config_core_v3_UpstreamHttpProtocolOptions* envoy_config_cluster_v3_Cluster_mutable_upstream_http_protocol_options(envoy_config_cluster_v3_Cluster *msg, upb_arena *arena) {
   struct envoy_config_core_v3_UpstreamHttpProtocolOptions* sub = (struct envoy_config_core_v3_UpstreamHttpProtocolOptions*)envoy_config_cluster_v3_Cluster_upstream_http_protocol_options(msg);
@@ -735,10 +771,11 @@ UPB_INLINE struct envoy_config_core_v3_UpstreamHttpProtocolOptions* envoy_config
   return sub;
 }
 UPB_INLINE void envoy_config_cluster_v3_Cluster_set_track_timeout_budgets(envoy_config_cluster_v3_Cluster *msg, bool value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(28, 28), bool) = value;
+  *UPB_PTR_AT(msg, UPB_SIZE(20, 20), bool) = value;
 }
 UPB_INLINE void envoy_config_cluster_v3_Cluster_set_upstream_config(envoy_config_cluster_v3_Cluster *msg, struct envoy_config_core_v3_TypedExtensionConfig* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(136, 240), struct envoy_config_core_v3_TypedExtensionConfig*) = value;
+  _upb_sethas(msg, 23);
+  *UPB_PTR_AT(msg, UPB_SIZE(128, 232), struct envoy_config_core_v3_TypedExtensionConfig*) = value;
 }
 UPB_INLINE struct envoy_config_core_v3_TypedExtensionConfig* envoy_config_cluster_v3_Cluster_mutable_upstream_config(envoy_config_cluster_v3_Cluster *msg, upb_arena *arena) {
   struct envoy_config_core_v3_TypedExtensionConfig* sub = (struct envoy_config_core_v3_TypedExtensionConfig*)envoy_config_cluster_v3_Cluster_upstream_config(msg);
@@ -750,7 +787,8 @@ UPB_INLINE struct envoy_config_core_v3_TypedExtensionConfig* envoy_config_cluste
   return sub;
 }
 UPB_INLINE void envoy_config_cluster_v3_Cluster_set_track_cluster_stats(envoy_config_cluster_v3_Cluster *msg, envoy_config_cluster_v3_TrackClusterStats* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(140, 248), envoy_config_cluster_v3_TrackClusterStats*) = value;
+  _upb_sethas(msg, 24);
+  *UPB_PTR_AT(msg, UPB_SIZE(132, 240), envoy_config_cluster_v3_TrackClusterStats*) = value;
 }
 UPB_INLINE struct envoy_config_cluster_v3_TrackClusterStats* envoy_config_cluster_v3_Cluster_mutable_track_cluster_stats(envoy_config_cluster_v3_Cluster *msg, upb_arena *arena) {
   struct envoy_config_cluster_v3_TrackClusterStats* sub = (struct envoy_config_cluster_v3_TrackClusterStats*)envoy_config_cluster_v3_Cluster_track_cluster_stats(msg);
@@ -762,7 +800,8 @@ UPB_INLINE struct envoy_config_cluster_v3_TrackClusterStats* envoy_config_cluste
   return sub;
 }
 UPB_INLINE void envoy_config_cluster_v3_Cluster_set_prefetch_policy(envoy_config_cluster_v3_Cluster *msg, envoy_config_cluster_v3_Cluster_PrefetchPolicy* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(144, 256), envoy_config_cluster_v3_Cluster_PrefetchPolicy*) = value;
+  _upb_sethas(msg, 25);
+  *UPB_PTR_AT(msg, UPB_SIZE(136, 248), envoy_config_cluster_v3_Cluster_PrefetchPolicy*) = value;
 }
 UPB_INLINE struct envoy_config_cluster_v3_Cluster_PrefetchPolicy* envoy_config_cluster_v3_Cluster_mutable_prefetch_policy(envoy_config_cluster_v3_Cluster *msg, upb_arena *arena) {
   struct envoy_config_cluster_v3_Cluster_PrefetchPolicy* sub = (struct envoy_config_cluster_v3_Cluster_PrefetchPolicy*)envoy_config_cluster_v3_Cluster_prefetch_policy(msg);
@@ -774,10 +813,10 @@ UPB_INLINE struct envoy_config_cluster_v3_Cluster_PrefetchPolicy* envoy_config_c
   return sub;
 }
 UPB_INLINE void envoy_config_cluster_v3_Cluster_set_connection_pool_per_downstream_connection(envoy_config_cluster_v3_Cluster *msg, bool value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(29, 29), bool) = value;
+  *UPB_PTR_AT(msg, UPB_SIZE(21, 21), bool) = value;
 }
 UPB_INLINE void envoy_config_cluster_v3_Cluster_set_maglev_lb_config(envoy_config_cluster_v3_Cluster *msg, envoy_config_cluster_v3_Cluster_MaglevLbConfig* value) {
-  UPB_WRITE_ONEOF(msg, envoy_config_cluster_v3_Cluster_MaglevLbConfig*, UPB_SIZE(180, 320), value, UPB_SIZE(184, 328), 52);
+  UPB_WRITE_ONEOF(msg, envoy_config_cluster_v3_Cluster_MaglevLbConfig*, UPB_SIZE(168, 312), value, UPB_SIZE(172, 320), 52);
 }
 UPB_INLINE struct envoy_config_cluster_v3_Cluster_MaglevLbConfig* envoy_config_cluster_v3_Cluster_mutable_maglev_lb_config(envoy_config_cluster_v3_Cluster *msg, upb_arena *arena) {
   struct envoy_config_cluster_v3_Cluster_MaglevLbConfig* sub = (struct envoy_config_cluster_v3_Cluster_MaglevLbConfig*)envoy_config_cluster_v3_Cluster_maglev_lb_config(msg);
@@ -799,21 +838,28 @@ UPB_INLINE envoy_config_cluster_v3_Cluster_TransportSocketMatch *envoy_config_cl
   envoy_config_cluster_v3_Cluster_TransportSocketMatch *ret = envoy_config_cluster_v3_Cluster_TransportSocketMatch_new(arena);
   return (ret && upb_decode(buf, size, ret, &envoy_config_cluster_v3_Cluster_TransportSocketMatch_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE envoy_config_cluster_v3_Cluster_TransportSocketMatch *envoy_config_cluster_v3_Cluster_TransportSocketMatch_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  envoy_config_cluster_v3_Cluster_TransportSocketMatch *ret = envoy_config_cluster_v3_Cluster_TransportSocketMatch_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &envoy_config_cluster_v3_Cluster_TransportSocketMatch_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *envoy_config_cluster_v3_Cluster_TransportSocketMatch_serialize(const envoy_config_cluster_v3_Cluster_TransportSocketMatch *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &envoy_config_cluster_v3_Cluster_TransportSocketMatch_msginit, arena, len);
 }
 
-UPB_INLINE upb_strview envoy_config_cluster_v3_Cluster_TransportSocketMatch_name(const envoy_config_cluster_v3_Cluster_TransportSocketMatch *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(0, 0), upb_strview); }
-UPB_INLINE bool envoy_config_cluster_v3_Cluster_TransportSocketMatch_has_match(const envoy_config_cluster_v3_Cluster_TransportSocketMatch *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(8, 16)); }
-UPB_INLINE const struct google_protobuf_Struct* envoy_config_cluster_v3_Cluster_TransportSocketMatch_match(const envoy_config_cluster_v3_Cluster_TransportSocketMatch *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(8, 16), const struct google_protobuf_Struct*); }
-UPB_INLINE bool envoy_config_cluster_v3_Cluster_TransportSocketMatch_has_transport_socket(const envoy_config_cluster_v3_Cluster_TransportSocketMatch *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(12, 24)); }
-UPB_INLINE const struct envoy_config_core_v3_TransportSocket* envoy_config_cluster_v3_Cluster_TransportSocketMatch_transport_socket(const envoy_config_cluster_v3_Cluster_TransportSocketMatch *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(12, 24), const struct envoy_config_core_v3_TransportSocket*); }
+UPB_INLINE upb_strview envoy_config_cluster_v3_Cluster_TransportSocketMatch_name(const envoy_config_cluster_v3_Cluster_TransportSocketMatch *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(4, 8), upb_strview); }
+UPB_INLINE bool envoy_config_cluster_v3_Cluster_TransportSocketMatch_has_match(const envoy_config_cluster_v3_Cluster_TransportSocketMatch *msg) { return _upb_hasbit(msg, 1); }
+UPB_INLINE const struct google_protobuf_Struct* envoy_config_cluster_v3_Cluster_TransportSocketMatch_match(const envoy_config_cluster_v3_Cluster_TransportSocketMatch *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(12, 24), const struct google_protobuf_Struct*); }
+UPB_INLINE bool envoy_config_cluster_v3_Cluster_TransportSocketMatch_has_transport_socket(const envoy_config_cluster_v3_Cluster_TransportSocketMatch *msg) { return _upb_hasbit(msg, 2); }
+UPB_INLINE const struct envoy_config_core_v3_TransportSocket* envoy_config_cluster_v3_Cluster_TransportSocketMatch_transport_socket(const envoy_config_cluster_v3_Cluster_TransportSocketMatch *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(16, 32), const struct envoy_config_core_v3_TransportSocket*); }
 
 UPB_INLINE void envoy_config_cluster_v3_Cluster_TransportSocketMatch_set_name(envoy_config_cluster_v3_Cluster_TransportSocketMatch *msg, upb_strview value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(0, 0), upb_strview) = value;
+  *UPB_PTR_AT(msg, UPB_SIZE(4, 8), upb_strview) = value;
 }
 UPB_INLINE void envoy_config_cluster_v3_Cluster_TransportSocketMatch_set_match(envoy_config_cluster_v3_Cluster_TransportSocketMatch *msg, struct google_protobuf_Struct* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(8, 16), struct google_protobuf_Struct*) = value;
+  _upb_sethas(msg, 1);
+  *UPB_PTR_AT(msg, UPB_SIZE(12, 24), struct google_protobuf_Struct*) = value;
 }
 UPB_INLINE struct google_protobuf_Struct* envoy_config_cluster_v3_Cluster_TransportSocketMatch_mutable_match(envoy_config_cluster_v3_Cluster_TransportSocketMatch *msg, upb_arena *arena) {
   struct google_protobuf_Struct* sub = (struct google_protobuf_Struct*)envoy_config_cluster_v3_Cluster_TransportSocketMatch_match(msg);
@@ -825,7 +871,8 @@ UPB_INLINE struct google_protobuf_Struct* envoy_config_cluster_v3_Cluster_Transp
   return sub;
 }
 UPB_INLINE void envoy_config_cluster_v3_Cluster_TransportSocketMatch_set_transport_socket(envoy_config_cluster_v3_Cluster_TransportSocketMatch *msg, struct envoy_config_core_v3_TransportSocket* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(12, 24), struct envoy_config_core_v3_TransportSocket*) = value;
+  _upb_sethas(msg, 2);
+  *UPB_PTR_AT(msg, UPB_SIZE(16, 32), struct envoy_config_core_v3_TransportSocket*) = value;
 }
 UPB_INLINE struct envoy_config_core_v3_TransportSocket* envoy_config_cluster_v3_Cluster_TransportSocketMatch_mutable_transport_socket(envoy_config_cluster_v3_Cluster_TransportSocketMatch *msg, upb_arena *arena) {
   struct envoy_config_core_v3_TransportSocket* sub = (struct envoy_config_core_v3_TransportSocket*)envoy_config_cluster_v3_Cluster_TransportSocketMatch_transport_socket(msg);
@@ -847,19 +894,26 @@ UPB_INLINE envoy_config_cluster_v3_Cluster_CustomClusterType *envoy_config_clust
   envoy_config_cluster_v3_Cluster_CustomClusterType *ret = envoy_config_cluster_v3_Cluster_CustomClusterType_new(arena);
   return (ret && upb_decode(buf, size, ret, &envoy_config_cluster_v3_Cluster_CustomClusterType_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE envoy_config_cluster_v3_Cluster_CustomClusterType *envoy_config_cluster_v3_Cluster_CustomClusterType_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  envoy_config_cluster_v3_Cluster_CustomClusterType *ret = envoy_config_cluster_v3_Cluster_CustomClusterType_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &envoy_config_cluster_v3_Cluster_CustomClusterType_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *envoy_config_cluster_v3_Cluster_CustomClusterType_serialize(const envoy_config_cluster_v3_Cluster_CustomClusterType *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &envoy_config_cluster_v3_Cluster_CustomClusterType_msginit, arena, len);
 }
 
-UPB_INLINE upb_strview envoy_config_cluster_v3_Cluster_CustomClusterType_name(const envoy_config_cluster_v3_Cluster_CustomClusterType *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(0, 0), upb_strview); }
-UPB_INLINE bool envoy_config_cluster_v3_Cluster_CustomClusterType_has_typed_config(const envoy_config_cluster_v3_Cluster_CustomClusterType *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(8, 16)); }
-UPB_INLINE const struct google_protobuf_Any* envoy_config_cluster_v3_Cluster_CustomClusterType_typed_config(const envoy_config_cluster_v3_Cluster_CustomClusterType *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(8, 16), const struct google_protobuf_Any*); }
+UPB_INLINE upb_strview envoy_config_cluster_v3_Cluster_CustomClusterType_name(const envoy_config_cluster_v3_Cluster_CustomClusterType *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(4, 8), upb_strview); }
+UPB_INLINE bool envoy_config_cluster_v3_Cluster_CustomClusterType_has_typed_config(const envoy_config_cluster_v3_Cluster_CustomClusterType *msg) { return _upb_hasbit(msg, 1); }
+UPB_INLINE const struct google_protobuf_Any* envoy_config_cluster_v3_Cluster_CustomClusterType_typed_config(const envoy_config_cluster_v3_Cluster_CustomClusterType *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(12, 24), const struct google_protobuf_Any*); }
 
 UPB_INLINE void envoy_config_cluster_v3_Cluster_CustomClusterType_set_name(envoy_config_cluster_v3_Cluster_CustomClusterType *msg, upb_strview value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(0, 0), upb_strview) = value;
+  *UPB_PTR_AT(msg, UPB_SIZE(4, 8), upb_strview) = value;
 }
 UPB_INLINE void envoy_config_cluster_v3_Cluster_CustomClusterType_set_typed_config(envoy_config_cluster_v3_Cluster_CustomClusterType *msg, struct google_protobuf_Any* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(8, 16), struct google_protobuf_Any*) = value;
+  _upb_sethas(msg, 1);
+  *UPB_PTR_AT(msg, UPB_SIZE(12, 24), struct google_protobuf_Any*) = value;
 }
 UPB_INLINE struct google_protobuf_Any* envoy_config_cluster_v3_Cluster_CustomClusterType_mutable_typed_config(envoy_config_cluster_v3_Cluster_CustomClusterType *msg, upb_arena *arena) {
   struct google_protobuf_Any* sub = (struct google_protobuf_Any*)envoy_config_cluster_v3_Cluster_CustomClusterType_typed_config(msg);
@@ -881,18 +935,25 @@ UPB_INLINE envoy_config_cluster_v3_Cluster_EdsClusterConfig *envoy_config_cluste
   envoy_config_cluster_v3_Cluster_EdsClusterConfig *ret = envoy_config_cluster_v3_Cluster_EdsClusterConfig_new(arena);
   return (ret && upb_decode(buf, size, ret, &envoy_config_cluster_v3_Cluster_EdsClusterConfig_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE envoy_config_cluster_v3_Cluster_EdsClusterConfig *envoy_config_cluster_v3_Cluster_EdsClusterConfig_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  envoy_config_cluster_v3_Cluster_EdsClusterConfig *ret = envoy_config_cluster_v3_Cluster_EdsClusterConfig_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &envoy_config_cluster_v3_Cluster_EdsClusterConfig_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *envoy_config_cluster_v3_Cluster_EdsClusterConfig_serialize(const envoy_config_cluster_v3_Cluster_EdsClusterConfig *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &envoy_config_cluster_v3_Cluster_EdsClusterConfig_msginit, arena, len);
 }
 
-UPB_INLINE bool envoy_config_cluster_v3_Cluster_EdsClusterConfig_has_eds_config(const envoy_config_cluster_v3_Cluster_EdsClusterConfig *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(8, 16)); }
-UPB_INLINE const struct envoy_config_core_v3_ConfigSource* envoy_config_cluster_v3_Cluster_EdsClusterConfig_eds_config(const envoy_config_cluster_v3_Cluster_EdsClusterConfig *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(8, 16), const struct envoy_config_core_v3_ConfigSource*); }
-UPB_INLINE upb_strview envoy_config_cluster_v3_Cluster_EdsClusterConfig_service_name(const envoy_config_cluster_v3_Cluster_EdsClusterConfig *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(0, 0), upb_strview); }
-UPB_INLINE bool envoy_config_cluster_v3_Cluster_EdsClusterConfig_has_eds_resource_locator(const envoy_config_cluster_v3_Cluster_EdsClusterConfig *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(12, 24)); }
-UPB_INLINE const struct udpa_core_v1_ResourceLocator* envoy_config_cluster_v3_Cluster_EdsClusterConfig_eds_resource_locator(const envoy_config_cluster_v3_Cluster_EdsClusterConfig *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(12, 24), const struct udpa_core_v1_ResourceLocator*); }
+UPB_INLINE bool envoy_config_cluster_v3_Cluster_EdsClusterConfig_has_eds_config(const envoy_config_cluster_v3_Cluster_EdsClusterConfig *msg) { return _upb_hasbit(msg, 1); }
+UPB_INLINE const struct envoy_config_core_v3_ConfigSource* envoy_config_cluster_v3_Cluster_EdsClusterConfig_eds_config(const envoy_config_cluster_v3_Cluster_EdsClusterConfig *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(12, 24), const struct envoy_config_core_v3_ConfigSource*); }
+UPB_INLINE upb_strview envoy_config_cluster_v3_Cluster_EdsClusterConfig_service_name(const envoy_config_cluster_v3_Cluster_EdsClusterConfig *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(4, 8), upb_strview); }
+UPB_INLINE bool envoy_config_cluster_v3_Cluster_EdsClusterConfig_has_eds_resource_locator(const envoy_config_cluster_v3_Cluster_EdsClusterConfig *msg) { return _upb_hasbit(msg, 2); }
+UPB_INLINE const struct udpa_core_v1_ResourceLocator* envoy_config_cluster_v3_Cluster_EdsClusterConfig_eds_resource_locator(const envoy_config_cluster_v3_Cluster_EdsClusterConfig *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(16, 32), const struct udpa_core_v1_ResourceLocator*); }
 
 UPB_INLINE void envoy_config_cluster_v3_Cluster_EdsClusterConfig_set_eds_config(envoy_config_cluster_v3_Cluster_EdsClusterConfig *msg, struct envoy_config_core_v3_ConfigSource* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(8, 16), struct envoy_config_core_v3_ConfigSource*) = value;
+  _upb_sethas(msg, 1);
+  *UPB_PTR_AT(msg, UPB_SIZE(12, 24), struct envoy_config_core_v3_ConfigSource*) = value;
 }
 UPB_INLINE struct envoy_config_core_v3_ConfigSource* envoy_config_cluster_v3_Cluster_EdsClusterConfig_mutable_eds_config(envoy_config_cluster_v3_Cluster_EdsClusterConfig *msg, upb_arena *arena) {
   struct envoy_config_core_v3_ConfigSource* sub = (struct envoy_config_core_v3_ConfigSource*)envoy_config_cluster_v3_Cluster_EdsClusterConfig_eds_config(msg);
@@ -904,10 +965,11 @@ UPB_INLINE struct envoy_config_core_v3_ConfigSource* envoy_config_cluster_v3_Clu
   return sub;
 }
 UPB_INLINE void envoy_config_cluster_v3_Cluster_EdsClusterConfig_set_service_name(envoy_config_cluster_v3_Cluster_EdsClusterConfig *msg, upb_strview value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(0, 0), upb_strview) = value;
+  *UPB_PTR_AT(msg, UPB_SIZE(4, 8), upb_strview) = value;
 }
 UPB_INLINE void envoy_config_cluster_v3_Cluster_EdsClusterConfig_set_eds_resource_locator(envoy_config_cluster_v3_Cluster_EdsClusterConfig *msg, struct udpa_core_v1_ResourceLocator* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(12, 24), struct udpa_core_v1_ResourceLocator*) = value;
+  _upb_sethas(msg, 2);
+  *UPB_PTR_AT(msg, UPB_SIZE(16, 32), struct udpa_core_v1_ResourceLocator*) = value;
 }
 UPB_INLINE struct udpa_core_v1_ResourceLocator* envoy_config_cluster_v3_Cluster_EdsClusterConfig_mutable_eds_resource_locator(envoy_config_cluster_v3_Cluster_EdsClusterConfig *msg, upb_arena *arena) {
   struct udpa_core_v1_ResourceLocator* sub = (struct udpa_core_v1_ResourceLocator*)envoy_config_cluster_v3_Cluster_EdsClusterConfig_eds_resource_locator(msg);
@@ -929,12 +991,18 @@ UPB_INLINE envoy_config_cluster_v3_Cluster_LbSubsetConfig *envoy_config_cluster_
   envoy_config_cluster_v3_Cluster_LbSubsetConfig *ret = envoy_config_cluster_v3_Cluster_LbSubsetConfig_new(arena);
   return (ret && upb_decode(buf, size, ret, &envoy_config_cluster_v3_Cluster_LbSubsetConfig_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE envoy_config_cluster_v3_Cluster_LbSubsetConfig *envoy_config_cluster_v3_Cluster_LbSubsetConfig_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  envoy_config_cluster_v3_Cluster_LbSubsetConfig *ret = envoy_config_cluster_v3_Cluster_LbSubsetConfig_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &envoy_config_cluster_v3_Cluster_LbSubsetConfig_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *envoy_config_cluster_v3_Cluster_LbSubsetConfig_serialize(const envoy_config_cluster_v3_Cluster_LbSubsetConfig *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &envoy_config_cluster_v3_Cluster_LbSubsetConfig_msginit, arena, len);
 }
 
-UPB_INLINE int32_t envoy_config_cluster_v3_Cluster_LbSubsetConfig_fallback_policy(const envoy_config_cluster_v3_Cluster_LbSubsetConfig *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(0, 0), int32_t); }
-UPB_INLINE bool envoy_config_cluster_v3_Cluster_LbSubsetConfig_has_default_subset(const envoy_config_cluster_v3_Cluster_LbSubsetConfig *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(12, 16)); }
+UPB_INLINE int32_t envoy_config_cluster_v3_Cluster_LbSubsetConfig_fallback_policy(const envoy_config_cluster_v3_Cluster_LbSubsetConfig *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(4, 4), int32_t); }
+UPB_INLINE bool envoy_config_cluster_v3_Cluster_LbSubsetConfig_has_default_subset(const envoy_config_cluster_v3_Cluster_LbSubsetConfig *msg) { return _upb_hasbit(msg, 1); }
 UPB_INLINE const struct google_protobuf_Struct* envoy_config_cluster_v3_Cluster_LbSubsetConfig_default_subset(const envoy_config_cluster_v3_Cluster_LbSubsetConfig *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(12, 16), const struct google_protobuf_Struct*); }
 UPB_INLINE bool envoy_config_cluster_v3_Cluster_LbSubsetConfig_has_subset_selectors(const envoy_config_cluster_v3_Cluster_LbSubsetConfig *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(16, 24)); }
 UPB_INLINE const envoy_config_cluster_v3_Cluster_LbSubsetConfig_LbSubsetSelector* const* envoy_config_cluster_v3_Cluster_LbSubsetConfig_subset_selectors(const envoy_config_cluster_v3_Cluster_LbSubsetConfig *msg, size_t *len) { return (const envoy_config_cluster_v3_Cluster_LbSubsetConfig_LbSubsetSelector* const*)_upb_array_accessor(msg, UPB_SIZE(16, 24), len); }
@@ -944,9 +1012,10 @@ UPB_INLINE bool envoy_config_cluster_v3_Cluster_LbSubsetConfig_panic_mode_any(co
 UPB_INLINE bool envoy_config_cluster_v3_Cluster_LbSubsetConfig_list_as_any(const envoy_config_cluster_v3_Cluster_LbSubsetConfig *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(11, 11), bool); }
 
 UPB_INLINE void envoy_config_cluster_v3_Cluster_LbSubsetConfig_set_fallback_policy(envoy_config_cluster_v3_Cluster_LbSubsetConfig *msg, int32_t value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(0, 0), int32_t) = value;
+  *UPB_PTR_AT(msg, UPB_SIZE(4, 4), int32_t) = value;
 }
 UPB_INLINE void envoy_config_cluster_v3_Cluster_LbSubsetConfig_set_default_subset(envoy_config_cluster_v3_Cluster_LbSubsetConfig *msg, struct google_protobuf_Struct* value) {
+  _upb_sethas(msg, 1);
   *UPB_PTR_AT(msg, UPB_SIZE(12, 16), struct google_protobuf_Struct*) = value;
 }
 UPB_INLINE struct google_protobuf_Struct* envoy_config_cluster_v3_Cluster_LbSubsetConfig_mutable_default_subset(envoy_config_cluster_v3_Cluster_LbSubsetConfig *msg, upb_arena *arena) {
@@ -962,12 +1031,12 @@ UPB_INLINE envoy_config_cluster_v3_Cluster_LbSubsetConfig_LbSubsetSelector** env
   return (envoy_config_cluster_v3_Cluster_LbSubsetConfig_LbSubsetSelector**)_upb_array_mutable_accessor(msg, UPB_SIZE(16, 24), len);
 }
 UPB_INLINE envoy_config_cluster_v3_Cluster_LbSubsetConfig_LbSubsetSelector** envoy_config_cluster_v3_Cluster_LbSubsetConfig_resize_subset_selectors(envoy_config_cluster_v3_Cluster_LbSubsetConfig *msg, size_t len, upb_arena *arena) {
-  return (envoy_config_cluster_v3_Cluster_LbSubsetConfig_LbSubsetSelector**)_upb_array_resize_accessor(msg, UPB_SIZE(16, 24), len, UPB_TYPE_MESSAGE, arena);
+  return (envoy_config_cluster_v3_Cluster_LbSubsetConfig_LbSubsetSelector**)_upb_array_resize_accessor2(msg, UPB_SIZE(16, 24), len, UPB_SIZE(2, 3), arena);
 }
 UPB_INLINE struct envoy_config_cluster_v3_Cluster_LbSubsetConfig_LbSubsetSelector* envoy_config_cluster_v3_Cluster_LbSubsetConfig_add_subset_selectors(envoy_config_cluster_v3_Cluster_LbSubsetConfig *msg, upb_arena *arena) {
   struct envoy_config_cluster_v3_Cluster_LbSubsetConfig_LbSubsetSelector* sub = (struct envoy_config_cluster_v3_Cluster_LbSubsetConfig_LbSubsetSelector*)_upb_msg_new(&envoy_config_cluster_v3_Cluster_LbSubsetConfig_LbSubsetSelector_msginit, arena);
-  bool ok = _upb_array_append_accessor(
-      msg, UPB_SIZE(16, 24), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena);
+  bool ok = _upb_array_append_accessor2(
+      msg, UPB_SIZE(16, 24), UPB_SIZE(2, 3), &sub, arena);
   if (!ok) return NULL;
   return sub;
 }
@@ -994,40 +1063,46 @@ UPB_INLINE envoy_config_cluster_v3_Cluster_LbSubsetConfig_LbSubsetSelector *envo
   envoy_config_cluster_v3_Cluster_LbSubsetConfig_LbSubsetSelector *ret = envoy_config_cluster_v3_Cluster_LbSubsetConfig_LbSubsetSelector_new(arena);
   return (ret && upb_decode(buf, size, ret, &envoy_config_cluster_v3_Cluster_LbSubsetConfig_LbSubsetSelector_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE envoy_config_cluster_v3_Cluster_LbSubsetConfig_LbSubsetSelector *envoy_config_cluster_v3_Cluster_LbSubsetConfig_LbSubsetSelector_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  envoy_config_cluster_v3_Cluster_LbSubsetConfig_LbSubsetSelector *ret = envoy_config_cluster_v3_Cluster_LbSubsetConfig_LbSubsetSelector_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &envoy_config_cluster_v3_Cluster_LbSubsetConfig_LbSubsetSelector_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *envoy_config_cluster_v3_Cluster_LbSubsetConfig_LbSubsetSelector_serialize(const envoy_config_cluster_v3_Cluster_LbSubsetConfig_LbSubsetSelector *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &envoy_config_cluster_v3_Cluster_LbSubsetConfig_LbSubsetSelector_msginit, arena, len);
 }
 
-UPB_INLINE upb_strview const* envoy_config_cluster_v3_Cluster_LbSubsetConfig_LbSubsetSelector_keys(const envoy_config_cluster_v3_Cluster_LbSubsetConfig_LbSubsetSelector *msg, size_t *len) { return (upb_strview const*)_upb_array_accessor(msg, UPB_SIZE(12, 16), len); }
+UPB_INLINE upb_strview const* envoy_config_cluster_v3_Cluster_LbSubsetConfig_LbSubsetSelector_keys(const envoy_config_cluster_v3_Cluster_LbSubsetConfig_LbSubsetSelector *msg, size_t *len) { return (upb_strview const*)_upb_array_accessor(msg, UPB_SIZE(8, 8), len); }
 UPB_INLINE int32_t envoy_config_cluster_v3_Cluster_LbSubsetConfig_LbSubsetSelector_fallback_policy(const envoy_config_cluster_v3_Cluster_LbSubsetConfig_LbSubsetSelector *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(0, 0), int32_t); }
-UPB_INLINE upb_strview const* envoy_config_cluster_v3_Cluster_LbSubsetConfig_LbSubsetSelector_fallback_keys_subset(const envoy_config_cluster_v3_Cluster_LbSubsetConfig_LbSubsetSelector *msg, size_t *len) { return (upb_strview const*)_upb_array_accessor(msg, UPB_SIZE(16, 24), len); }
-UPB_INLINE bool envoy_config_cluster_v3_Cluster_LbSubsetConfig_LbSubsetSelector_single_host_per_subset(const envoy_config_cluster_v3_Cluster_LbSubsetConfig_LbSubsetSelector *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(8, 8), bool); }
+UPB_INLINE upb_strview const* envoy_config_cluster_v3_Cluster_LbSubsetConfig_LbSubsetSelector_fallback_keys_subset(const envoy_config_cluster_v3_Cluster_LbSubsetConfig_LbSubsetSelector *msg, size_t *len) { return (upb_strview const*)_upb_array_accessor(msg, UPB_SIZE(12, 16), len); }
+UPB_INLINE bool envoy_config_cluster_v3_Cluster_LbSubsetConfig_LbSubsetSelector_single_host_per_subset(const envoy_config_cluster_v3_Cluster_LbSubsetConfig_LbSubsetSelector *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(4, 4), bool); }
 
 UPB_INLINE upb_strview* envoy_config_cluster_v3_Cluster_LbSubsetConfig_LbSubsetSelector_mutable_keys(envoy_config_cluster_v3_Cluster_LbSubsetConfig_LbSubsetSelector *msg, size_t *len) {
-  return (upb_strview*)_upb_array_mutable_accessor(msg, UPB_SIZE(12, 16), len);
+  return (upb_strview*)_upb_array_mutable_accessor(msg, UPB_SIZE(8, 8), len);
 }
 UPB_INLINE upb_strview* envoy_config_cluster_v3_Cluster_LbSubsetConfig_LbSubsetSelector_resize_keys(envoy_config_cluster_v3_Cluster_LbSubsetConfig_LbSubsetSelector *msg, size_t len, upb_arena *arena) {
-  return (upb_strview*)_upb_array_resize_accessor(msg, UPB_SIZE(12, 16), len, UPB_TYPE_STRING, arena);
+  return (upb_strview*)_upb_array_resize_accessor2(msg, UPB_SIZE(8, 8), len, UPB_SIZE(3, 4), arena);
 }
 UPB_INLINE bool envoy_config_cluster_v3_Cluster_LbSubsetConfig_LbSubsetSelector_add_keys(envoy_config_cluster_v3_Cluster_LbSubsetConfig_LbSubsetSelector *msg, upb_strview val, upb_arena *arena) {
-  return _upb_array_append_accessor(msg, UPB_SIZE(12, 16), UPB_SIZE(8, 16), UPB_TYPE_STRING, &val,
+  return _upb_array_append_accessor2(msg, UPB_SIZE(8, 8), UPB_SIZE(3, 4), &val,
       arena);
 }
 UPB_INLINE void envoy_config_cluster_v3_Cluster_LbSubsetConfig_LbSubsetSelector_set_fallback_policy(envoy_config_cluster_v3_Cluster_LbSubsetConfig_LbSubsetSelector *msg, int32_t value) {
   *UPB_PTR_AT(msg, UPB_SIZE(0, 0), int32_t) = value;
 }
 UPB_INLINE upb_strview* envoy_config_cluster_v3_Cluster_LbSubsetConfig_LbSubsetSelector_mutable_fallback_keys_subset(envoy_config_cluster_v3_Cluster_LbSubsetConfig_LbSubsetSelector *msg, size_t *len) {
-  return (upb_strview*)_upb_array_mutable_accessor(msg, UPB_SIZE(16, 24), len);
+  return (upb_strview*)_upb_array_mutable_accessor(msg, UPB_SIZE(12, 16), len);
 }
 UPB_INLINE upb_strview* envoy_config_cluster_v3_Cluster_LbSubsetConfig_LbSubsetSelector_resize_fallback_keys_subset(envoy_config_cluster_v3_Cluster_LbSubsetConfig_LbSubsetSelector *msg, size_t len, upb_arena *arena) {
-  return (upb_strview*)_upb_array_resize_accessor(msg, UPB_SIZE(16, 24), len, UPB_TYPE_STRING, arena);
+  return (upb_strview*)_upb_array_resize_accessor2(msg, UPB_SIZE(12, 16), len, UPB_SIZE(3, 4), arena);
 }
 UPB_INLINE bool envoy_config_cluster_v3_Cluster_LbSubsetConfig_LbSubsetSelector_add_fallback_keys_subset(envoy_config_cluster_v3_Cluster_LbSubsetConfig_LbSubsetSelector *msg, upb_strview val, upb_arena *arena) {
-  return _upb_array_append_accessor(msg, UPB_SIZE(16, 24), UPB_SIZE(8, 16), UPB_TYPE_STRING, &val,
+  return _upb_array_append_accessor2(msg, UPB_SIZE(12, 16), UPB_SIZE(3, 4), &val,
       arena);
 }
 UPB_INLINE void envoy_config_cluster_v3_Cluster_LbSubsetConfig_LbSubsetSelector_set_single_host_per_subset(envoy_config_cluster_v3_Cluster_LbSubsetConfig_LbSubsetSelector *msg, bool value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(8, 8), bool) = value;
+  *UPB_PTR_AT(msg, UPB_SIZE(4, 4), bool) = value;
 }
 
 /* envoy.config.cluster.v3.Cluster.LeastRequestLbConfig */
@@ -1040,17 +1115,24 @@ UPB_INLINE envoy_config_cluster_v3_Cluster_LeastRequestLbConfig *envoy_config_cl
   envoy_config_cluster_v3_Cluster_LeastRequestLbConfig *ret = envoy_config_cluster_v3_Cluster_LeastRequestLbConfig_new(arena);
   return (ret && upb_decode(buf, size, ret, &envoy_config_cluster_v3_Cluster_LeastRequestLbConfig_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE envoy_config_cluster_v3_Cluster_LeastRequestLbConfig *envoy_config_cluster_v3_Cluster_LeastRequestLbConfig_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  envoy_config_cluster_v3_Cluster_LeastRequestLbConfig *ret = envoy_config_cluster_v3_Cluster_LeastRequestLbConfig_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &envoy_config_cluster_v3_Cluster_LeastRequestLbConfig_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *envoy_config_cluster_v3_Cluster_LeastRequestLbConfig_serialize(const envoy_config_cluster_v3_Cluster_LeastRequestLbConfig *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &envoy_config_cluster_v3_Cluster_LeastRequestLbConfig_msginit, arena, len);
 }
 
-UPB_INLINE bool envoy_config_cluster_v3_Cluster_LeastRequestLbConfig_has_choice_count(const envoy_config_cluster_v3_Cluster_LeastRequestLbConfig *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(0, 0)); }
-UPB_INLINE const struct google_protobuf_UInt32Value* envoy_config_cluster_v3_Cluster_LeastRequestLbConfig_choice_count(const envoy_config_cluster_v3_Cluster_LeastRequestLbConfig *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(0, 0), const struct google_protobuf_UInt32Value*); }
-UPB_INLINE bool envoy_config_cluster_v3_Cluster_LeastRequestLbConfig_has_active_request_bias(const envoy_config_cluster_v3_Cluster_LeastRequestLbConfig *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(4, 8)); }
-UPB_INLINE const struct envoy_config_core_v3_RuntimeDouble* envoy_config_cluster_v3_Cluster_LeastRequestLbConfig_active_request_bias(const envoy_config_cluster_v3_Cluster_LeastRequestLbConfig *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(4, 8), const struct envoy_config_core_v3_RuntimeDouble*); }
+UPB_INLINE bool envoy_config_cluster_v3_Cluster_LeastRequestLbConfig_has_choice_count(const envoy_config_cluster_v3_Cluster_LeastRequestLbConfig *msg) { return _upb_hasbit(msg, 1); }
+UPB_INLINE const struct google_protobuf_UInt32Value* envoy_config_cluster_v3_Cluster_LeastRequestLbConfig_choice_count(const envoy_config_cluster_v3_Cluster_LeastRequestLbConfig *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(4, 8), const struct google_protobuf_UInt32Value*); }
+UPB_INLINE bool envoy_config_cluster_v3_Cluster_LeastRequestLbConfig_has_active_request_bias(const envoy_config_cluster_v3_Cluster_LeastRequestLbConfig *msg) { return _upb_hasbit(msg, 2); }
+UPB_INLINE const struct envoy_config_core_v3_RuntimeDouble* envoy_config_cluster_v3_Cluster_LeastRequestLbConfig_active_request_bias(const envoy_config_cluster_v3_Cluster_LeastRequestLbConfig *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(8, 16), const struct envoy_config_core_v3_RuntimeDouble*); }
 
 UPB_INLINE void envoy_config_cluster_v3_Cluster_LeastRequestLbConfig_set_choice_count(envoy_config_cluster_v3_Cluster_LeastRequestLbConfig *msg, struct google_protobuf_UInt32Value* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(0, 0), struct google_protobuf_UInt32Value*) = value;
+  _upb_sethas(msg, 1);
+  *UPB_PTR_AT(msg, UPB_SIZE(4, 8), struct google_protobuf_UInt32Value*) = value;
 }
 UPB_INLINE struct google_protobuf_UInt32Value* envoy_config_cluster_v3_Cluster_LeastRequestLbConfig_mutable_choice_count(envoy_config_cluster_v3_Cluster_LeastRequestLbConfig *msg, upb_arena *arena) {
   struct google_protobuf_UInt32Value* sub = (struct google_protobuf_UInt32Value*)envoy_config_cluster_v3_Cluster_LeastRequestLbConfig_choice_count(msg);
@@ -1062,7 +1144,8 @@ UPB_INLINE struct google_protobuf_UInt32Value* envoy_config_cluster_v3_Cluster_L
   return sub;
 }
 UPB_INLINE void envoy_config_cluster_v3_Cluster_LeastRequestLbConfig_set_active_request_bias(envoy_config_cluster_v3_Cluster_LeastRequestLbConfig *msg, struct envoy_config_core_v3_RuntimeDouble* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(4, 8), struct envoy_config_core_v3_RuntimeDouble*) = value;
+  _upb_sethas(msg, 2);
+  *UPB_PTR_AT(msg, UPB_SIZE(8, 16), struct envoy_config_core_v3_RuntimeDouble*) = value;
 }
 UPB_INLINE struct envoy_config_core_v3_RuntimeDouble* envoy_config_cluster_v3_Cluster_LeastRequestLbConfig_mutable_active_request_bias(envoy_config_cluster_v3_Cluster_LeastRequestLbConfig *msg, upb_arena *arena) {
   struct envoy_config_core_v3_RuntimeDouble* sub = (struct envoy_config_core_v3_RuntimeDouble*)envoy_config_cluster_v3_Cluster_LeastRequestLbConfig_active_request_bias(msg);
@@ -1084,17 +1167,24 @@ UPB_INLINE envoy_config_cluster_v3_Cluster_RingHashLbConfig *envoy_config_cluste
   envoy_config_cluster_v3_Cluster_RingHashLbConfig *ret = envoy_config_cluster_v3_Cluster_RingHashLbConfig_new(arena);
   return (ret && upb_decode(buf, size, ret, &envoy_config_cluster_v3_Cluster_RingHashLbConfig_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE envoy_config_cluster_v3_Cluster_RingHashLbConfig *envoy_config_cluster_v3_Cluster_RingHashLbConfig_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  envoy_config_cluster_v3_Cluster_RingHashLbConfig *ret = envoy_config_cluster_v3_Cluster_RingHashLbConfig_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &envoy_config_cluster_v3_Cluster_RingHashLbConfig_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *envoy_config_cluster_v3_Cluster_RingHashLbConfig_serialize(const envoy_config_cluster_v3_Cluster_RingHashLbConfig *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &envoy_config_cluster_v3_Cluster_RingHashLbConfig_msginit, arena, len);
 }
 
-UPB_INLINE bool envoy_config_cluster_v3_Cluster_RingHashLbConfig_has_minimum_ring_size(const envoy_config_cluster_v3_Cluster_RingHashLbConfig *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(8, 8)); }
+UPB_INLINE bool envoy_config_cluster_v3_Cluster_RingHashLbConfig_has_minimum_ring_size(const envoy_config_cluster_v3_Cluster_RingHashLbConfig *msg) { return _upb_hasbit(msg, 1); }
 UPB_INLINE const struct google_protobuf_UInt64Value* envoy_config_cluster_v3_Cluster_RingHashLbConfig_minimum_ring_size(const envoy_config_cluster_v3_Cluster_RingHashLbConfig *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(8, 8), const struct google_protobuf_UInt64Value*); }
-UPB_INLINE int32_t envoy_config_cluster_v3_Cluster_RingHashLbConfig_hash_function(const envoy_config_cluster_v3_Cluster_RingHashLbConfig *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(0, 0), int32_t); }
-UPB_INLINE bool envoy_config_cluster_v3_Cluster_RingHashLbConfig_has_maximum_ring_size(const envoy_config_cluster_v3_Cluster_RingHashLbConfig *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(12, 16)); }
+UPB_INLINE int32_t envoy_config_cluster_v3_Cluster_RingHashLbConfig_hash_function(const envoy_config_cluster_v3_Cluster_RingHashLbConfig *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(4, 4), int32_t); }
+UPB_INLINE bool envoy_config_cluster_v3_Cluster_RingHashLbConfig_has_maximum_ring_size(const envoy_config_cluster_v3_Cluster_RingHashLbConfig *msg) { return _upb_hasbit(msg, 2); }
 UPB_INLINE const struct google_protobuf_UInt64Value* envoy_config_cluster_v3_Cluster_RingHashLbConfig_maximum_ring_size(const envoy_config_cluster_v3_Cluster_RingHashLbConfig *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(12, 16), const struct google_protobuf_UInt64Value*); }
 
 UPB_INLINE void envoy_config_cluster_v3_Cluster_RingHashLbConfig_set_minimum_ring_size(envoy_config_cluster_v3_Cluster_RingHashLbConfig *msg, struct google_protobuf_UInt64Value* value) {
+  _upb_sethas(msg, 1);
   *UPB_PTR_AT(msg, UPB_SIZE(8, 8), struct google_protobuf_UInt64Value*) = value;
 }
 UPB_INLINE struct google_protobuf_UInt64Value* envoy_config_cluster_v3_Cluster_RingHashLbConfig_mutable_minimum_ring_size(envoy_config_cluster_v3_Cluster_RingHashLbConfig *msg, upb_arena *arena) {
@@ -1107,9 +1197,10 @@ UPB_INLINE struct google_protobuf_UInt64Value* envoy_config_cluster_v3_Cluster_R
   return sub;
 }
 UPB_INLINE void envoy_config_cluster_v3_Cluster_RingHashLbConfig_set_hash_function(envoy_config_cluster_v3_Cluster_RingHashLbConfig *msg, int32_t value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(0, 0), int32_t) = value;
+  *UPB_PTR_AT(msg, UPB_SIZE(4, 4), int32_t) = value;
 }
 UPB_INLINE void envoy_config_cluster_v3_Cluster_RingHashLbConfig_set_maximum_ring_size(envoy_config_cluster_v3_Cluster_RingHashLbConfig *msg, struct google_protobuf_UInt64Value* value) {
+  _upb_sethas(msg, 2);
   *UPB_PTR_AT(msg, UPB_SIZE(12, 16), struct google_protobuf_UInt64Value*) = value;
 }
 UPB_INLINE struct google_protobuf_UInt64Value* envoy_config_cluster_v3_Cluster_RingHashLbConfig_mutable_maximum_ring_size(envoy_config_cluster_v3_Cluster_RingHashLbConfig *msg, upb_arena *arena) {
@@ -1132,15 +1223,22 @@ UPB_INLINE envoy_config_cluster_v3_Cluster_MaglevLbConfig *envoy_config_cluster_
   envoy_config_cluster_v3_Cluster_MaglevLbConfig *ret = envoy_config_cluster_v3_Cluster_MaglevLbConfig_new(arena);
   return (ret && upb_decode(buf, size, ret, &envoy_config_cluster_v3_Cluster_MaglevLbConfig_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE envoy_config_cluster_v3_Cluster_MaglevLbConfig *envoy_config_cluster_v3_Cluster_MaglevLbConfig_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  envoy_config_cluster_v3_Cluster_MaglevLbConfig *ret = envoy_config_cluster_v3_Cluster_MaglevLbConfig_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &envoy_config_cluster_v3_Cluster_MaglevLbConfig_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *envoy_config_cluster_v3_Cluster_MaglevLbConfig_serialize(const envoy_config_cluster_v3_Cluster_MaglevLbConfig *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &envoy_config_cluster_v3_Cluster_MaglevLbConfig_msginit, arena, len);
 }
 
-UPB_INLINE bool envoy_config_cluster_v3_Cluster_MaglevLbConfig_has_table_size(const envoy_config_cluster_v3_Cluster_MaglevLbConfig *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(0, 0)); }
-UPB_INLINE const struct google_protobuf_UInt64Value* envoy_config_cluster_v3_Cluster_MaglevLbConfig_table_size(const envoy_config_cluster_v3_Cluster_MaglevLbConfig *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(0, 0), const struct google_protobuf_UInt64Value*); }
+UPB_INLINE bool envoy_config_cluster_v3_Cluster_MaglevLbConfig_has_table_size(const envoy_config_cluster_v3_Cluster_MaglevLbConfig *msg) { return _upb_hasbit(msg, 1); }
+UPB_INLINE const struct google_protobuf_UInt64Value* envoy_config_cluster_v3_Cluster_MaglevLbConfig_table_size(const envoy_config_cluster_v3_Cluster_MaglevLbConfig *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(4, 8), const struct google_protobuf_UInt64Value*); }
 
 UPB_INLINE void envoy_config_cluster_v3_Cluster_MaglevLbConfig_set_table_size(envoy_config_cluster_v3_Cluster_MaglevLbConfig *msg, struct google_protobuf_UInt64Value* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(0, 0), struct google_protobuf_UInt64Value*) = value;
+  _upb_sethas(msg, 1);
+  *UPB_PTR_AT(msg, UPB_SIZE(4, 8), struct google_protobuf_UInt64Value*) = value;
 }
 UPB_INLINE struct google_protobuf_UInt64Value* envoy_config_cluster_v3_Cluster_MaglevLbConfig_mutable_table_size(envoy_config_cluster_v3_Cluster_MaglevLbConfig *msg, upb_arena *arena) {
   struct google_protobuf_UInt64Value* sub = (struct google_protobuf_UInt64Value*)envoy_config_cluster_v3_Cluster_MaglevLbConfig_table_size(msg);
@@ -1162,6 +1260,12 @@ UPB_INLINE envoy_config_cluster_v3_Cluster_OriginalDstLbConfig *envoy_config_clu
   envoy_config_cluster_v3_Cluster_OriginalDstLbConfig *ret = envoy_config_cluster_v3_Cluster_OriginalDstLbConfig_new(arena);
   return (ret && upb_decode(buf, size, ret, &envoy_config_cluster_v3_Cluster_OriginalDstLbConfig_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE envoy_config_cluster_v3_Cluster_OriginalDstLbConfig *envoy_config_cluster_v3_Cluster_OriginalDstLbConfig_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  envoy_config_cluster_v3_Cluster_OriginalDstLbConfig *ret = envoy_config_cluster_v3_Cluster_OriginalDstLbConfig_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &envoy_config_cluster_v3_Cluster_OriginalDstLbConfig_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *envoy_config_cluster_v3_Cluster_OriginalDstLbConfig_serialize(const envoy_config_cluster_v3_Cluster_OriginalDstLbConfig *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &envoy_config_cluster_v3_Cluster_OriginalDstLbConfig_msginit, arena, len);
 }
@@ -1182,6 +1286,12 @@ UPB_INLINE envoy_config_cluster_v3_Cluster_CommonLbConfig *envoy_config_cluster_
   envoy_config_cluster_v3_Cluster_CommonLbConfig *ret = envoy_config_cluster_v3_Cluster_CommonLbConfig_new(arena);
   return (ret && upb_decode(buf, size, ret, &envoy_config_cluster_v3_Cluster_CommonLbConfig_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE envoy_config_cluster_v3_Cluster_CommonLbConfig *envoy_config_cluster_v3_Cluster_CommonLbConfig_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  envoy_config_cluster_v3_Cluster_CommonLbConfig *ret = envoy_config_cluster_v3_Cluster_CommonLbConfig_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &envoy_config_cluster_v3_Cluster_CommonLbConfig_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *envoy_config_cluster_v3_Cluster_CommonLbConfig_serialize(const envoy_config_cluster_v3_Cluster_CommonLbConfig *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &envoy_config_cluster_v3_Cluster_CommonLbConfig_msginit, arena, len);
 }
@@ -1193,20 +1303,21 @@ typedef enum {
 } envoy_config_cluster_v3_Cluster_CommonLbConfig_locality_config_specifier_oneofcases;
 UPB_INLINE envoy_config_cluster_v3_Cluster_CommonLbConfig_locality_config_specifier_oneofcases envoy_config_cluster_v3_Cluster_CommonLbConfig_locality_config_specifier_case(const envoy_config_cluster_v3_Cluster_CommonLbConfig* msg) { return (envoy_config_cluster_v3_Cluster_CommonLbConfig_locality_config_specifier_oneofcases)*UPB_PTR_AT(msg, UPB_SIZE(20, 40), int32_t); }
 
-UPB_INLINE bool envoy_config_cluster_v3_Cluster_CommonLbConfig_has_healthy_panic_threshold(const envoy_config_cluster_v3_Cluster_CommonLbConfig *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(4, 8)); }
+UPB_INLINE bool envoy_config_cluster_v3_Cluster_CommonLbConfig_has_healthy_panic_threshold(const envoy_config_cluster_v3_Cluster_CommonLbConfig *msg) { return _upb_hasbit(msg, 1); }
 UPB_INLINE const struct envoy_type_v3_Percent* envoy_config_cluster_v3_Cluster_CommonLbConfig_healthy_panic_threshold(const envoy_config_cluster_v3_Cluster_CommonLbConfig *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(4, 8), const struct envoy_type_v3_Percent*); }
 UPB_INLINE bool envoy_config_cluster_v3_Cluster_CommonLbConfig_has_zone_aware_lb_config(const envoy_config_cluster_v3_Cluster_CommonLbConfig *msg) { return _upb_getoneofcase(msg, UPB_SIZE(20, 40)) == 2; }
 UPB_INLINE const envoy_config_cluster_v3_Cluster_CommonLbConfig_ZoneAwareLbConfig* envoy_config_cluster_v3_Cluster_CommonLbConfig_zone_aware_lb_config(const envoy_config_cluster_v3_Cluster_CommonLbConfig *msg) { return UPB_READ_ONEOF(msg, const envoy_config_cluster_v3_Cluster_CommonLbConfig_ZoneAwareLbConfig*, UPB_SIZE(16, 32), UPB_SIZE(20, 40), 2, NULL); }
 UPB_INLINE bool envoy_config_cluster_v3_Cluster_CommonLbConfig_has_locality_weighted_lb_config(const envoy_config_cluster_v3_Cluster_CommonLbConfig *msg) { return _upb_getoneofcase(msg, UPB_SIZE(20, 40)) == 3; }
 UPB_INLINE const envoy_config_cluster_v3_Cluster_CommonLbConfig_LocalityWeightedLbConfig* envoy_config_cluster_v3_Cluster_CommonLbConfig_locality_weighted_lb_config(const envoy_config_cluster_v3_Cluster_CommonLbConfig *msg) { return UPB_READ_ONEOF(msg, const envoy_config_cluster_v3_Cluster_CommonLbConfig_LocalityWeightedLbConfig*, UPB_SIZE(16, 32), UPB_SIZE(20, 40), 3, NULL); }
-UPB_INLINE bool envoy_config_cluster_v3_Cluster_CommonLbConfig_has_update_merge_window(const envoy_config_cluster_v3_Cluster_CommonLbConfig *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(8, 16)); }
+UPB_INLINE bool envoy_config_cluster_v3_Cluster_CommonLbConfig_has_update_merge_window(const envoy_config_cluster_v3_Cluster_CommonLbConfig *msg) { return _upb_hasbit(msg, 2); }
 UPB_INLINE const struct google_protobuf_Duration* envoy_config_cluster_v3_Cluster_CommonLbConfig_update_merge_window(const envoy_config_cluster_v3_Cluster_CommonLbConfig *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(8, 16), const struct google_protobuf_Duration*); }
-UPB_INLINE bool envoy_config_cluster_v3_Cluster_CommonLbConfig_ignore_new_hosts_until_first_hc(const envoy_config_cluster_v3_Cluster_CommonLbConfig *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(0, 0), bool); }
-UPB_INLINE bool envoy_config_cluster_v3_Cluster_CommonLbConfig_close_connections_on_host_set_change(const envoy_config_cluster_v3_Cluster_CommonLbConfig *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(1, 1), bool); }
-UPB_INLINE bool envoy_config_cluster_v3_Cluster_CommonLbConfig_has_consistent_hashing_lb_config(const envoy_config_cluster_v3_Cluster_CommonLbConfig *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(12, 24)); }
+UPB_INLINE bool envoy_config_cluster_v3_Cluster_CommonLbConfig_ignore_new_hosts_until_first_hc(const envoy_config_cluster_v3_Cluster_CommonLbConfig *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(1, 1), bool); }
+UPB_INLINE bool envoy_config_cluster_v3_Cluster_CommonLbConfig_close_connections_on_host_set_change(const envoy_config_cluster_v3_Cluster_CommonLbConfig *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(2, 2), bool); }
+UPB_INLINE bool envoy_config_cluster_v3_Cluster_CommonLbConfig_has_consistent_hashing_lb_config(const envoy_config_cluster_v3_Cluster_CommonLbConfig *msg) { return _upb_hasbit(msg, 3); }
 UPB_INLINE const envoy_config_cluster_v3_Cluster_CommonLbConfig_ConsistentHashingLbConfig* envoy_config_cluster_v3_Cluster_CommonLbConfig_consistent_hashing_lb_config(const envoy_config_cluster_v3_Cluster_CommonLbConfig *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(12, 24), const envoy_config_cluster_v3_Cluster_CommonLbConfig_ConsistentHashingLbConfig*); }
 
 UPB_INLINE void envoy_config_cluster_v3_Cluster_CommonLbConfig_set_healthy_panic_threshold(envoy_config_cluster_v3_Cluster_CommonLbConfig *msg, struct envoy_type_v3_Percent* value) {
+  _upb_sethas(msg, 1);
   *UPB_PTR_AT(msg, UPB_SIZE(4, 8), struct envoy_type_v3_Percent*) = value;
 }
 UPB_INLINE struct envoy_type_v3_Percent* envoy_config_cluster_v3_Cluster_CommonLbConfig_mutable_healthy_panic_threshold(envoy_config_cluster_v3_Cluster_CommonLbConfig *msg, upb_arena *arena) {
@@ -1243,6 +1354,7 @@ UPB_INLINE struct envoy_config_cluster_v3_Cluster_CommonLbConfig_LocalityWeighte
   return sub;
 }
 UPB_INLINE void envoy_config_cluster_v3_Cluster_CommonLbConfig_set_update_merge_window(envoy_config_cluster_v3_Cluster_CommonLbConfig *msg, struct google_protobuf_Duration* value) {
+  _upb_sethas(msg, 2);
   *UPB_PTR_AT(msg, UPB_SIZE(8, 16), struct google_protobuf_Duration*) = value;
 }
 UPB_INLINE struct google_protobuf_Duration* envoy_config_cluster_v3_Cluster_CommonLbConfig_mutable_update_merge_window(envoy_config_cluster_v3_Cluster_CommonLbConfig *msg, upb_arena *arena) {
@@ -1255,12 +1367,13 @@ UPB_INLINE struct google_protobuf_Duration* envoy_config_cluster_v3_Cluster_Comm
   return sub;
 }
 UPB_INLINE void envoy_config_cluster_v3_Cluster_CommonLbConfig_set_ignore_new_hosts_until_first_hc(envoy_config_cluster_v3_Cluster_CommonLbConfig *msg, bool value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(0, 0), bool) = value;
+  *UPB_PTR_AT(msg, UPB_SIZE(1, 1), bool) = value;
 }
 UPB_INLINE void envoy_config_cluster_v3_Cluster_CommonLbConfig_set_close_connections_on_host_set_change(envoy_config_cluster_v3_Cluster_CommonLbConfig *msg, bool value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(1, 1), bool) = value;
+  *UPB_PTR_AT(msg, UPB_SIZE(2, 2), bool) = value;
 }
 UPB_INLINE void envoy_config_cluster_v3_Cluster_CommonLbConfig_set_consistent_hashing_lb_config(envoy_config_cluster_v3_Cluster_CommonLbConfig *msg, envoy_config_cluster_v3_Cluster_CommonLbConfig_ConsistentHashingLbConfig* value) {
+  _upb_sethas(msg, 3);
   *UPB_PTR_AT(msg, UPB_SIZE(12, 24), envoy_config_cluster_v3_Cluster_CommonLbConfig_ConsistentHashingLbConfig*) = value;
 }
 UPB_INLINE struct envoy_config_cluster_v3_Cluster_CommonLbConfig_ConsistentHashingLbConfig* envoy_config_cluster_v3_Cluster_CommonLbConfig_mutable_consistent_hashing_lb_config(envoy_config_cluster_v3_Cluster_CommonLbConfig *msg, upb_arena *arena) {
@@ -1283,17 +1396,24 @@ UPB_INLINE envoy_config_cluster_v3_Cluster_CommonLbConfig_ZoneAwareLbConfig *env
   envoy_config_cluster_v3_Cluster_CommonLbConfig_ZoneAwareLbConfig *ret = envoy_config_cluster_v3_Cluster_CommonLbConfig_ZoneAwareLbConfig_new(arena);
   return (ret && upb_decode(buf, size, ret, &envoy_config_cluster_v3_Cluster_CommonLbConfig_ZoneAwareLbConfig_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE envoy_config_cluster_v3_Cluster_CommonLbConfig_ZoneAwareLbConfig *envoy_config_cluster_v3_Cluster_CommonLbConfig_ZoneAwareLbConfig_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  envoy_config_cluster_v3_Cluster_CommonLbConfig_ZoneAwareLbConfig *ret = envoy_config_cluster_v3_Cluster_CommonLbConfig_ZoneAwareLbConfig_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &envoy_config_cluster_v3_Cluster_CommonLbConfig_ZoneAwareLbConfig_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *envoy_config_cluster_v3_Cluster_CommonLbConfig_ZoneAwareLbConfig_serialize(const envoy_config_cluster_v3_Cluster_CommonLbConfig_ZoneAwareLbConfig *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &envoy_config_cluster_v3_Cluster_CommonLbConfig_ZoneAwareLbConfig_msginit, arena, len);
 }
 
-UPB_INLINE bool envoy_config_cluster_v3_Cluster_CommonLbConfig_ZoneAwareLbConfig_has_routing_enabled(const envoy_config_cluster_v3_Cluster_CommonLbConfig_ZoneAwareLbConfig *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(4, 8)); }
+UPB_INLINE bool envoy_config_cluster_v3_Cluster_CommonLbConfig_ZoneAwareLbConfig_has_routing_enabled(const envoy_config_cluster_v3_Cluster_CommonLbConfig_ZoneAwareLbConfig *msg) { return _upb_hasbit(msg, 1); }
 UPB_INLINE const struct envoy_type_v3_Percent* envoy_config_cluster_v3_Cluster_CommonLbConfig_ZoneAwareLbConfig_routing_enabled(const envoy_config_cluster_v3_Cluster_CommonLbConfig_ZoneAwareLbConfig *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(4, 8), const struct envoy_type_v3_Percent*); }
-UPB_INLINE bool envoy_config_cluster_v3_Cluster_CommonLbConfig_ZoneAwareLbConfig_has_min_cluster_size(const envoy_config_cluster_v3_Cluster_CommonLbConfig_ZoneAwareLbConfig *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(8, 16)); }
+UPB_INLINE bool envoy_config_cluster_v3_Cluster_CommonLbConfig_ZoneAwareLbConfig_has_min_cluster_size(const envoy_config_cluster_v3_Cluster_CommonLbConfig_ZoneAwareLbConfig *msg) { return _upb_hasbit(msg, 2); }
 UPB_INLINE const struct google_protobuf_UInt64Value* envoy_config_cluster_v3_Cluster_CommonLbConfig_ZoneAwareLbConfig_min_cluster_size(const envoy_config_cluster_v3_Cluster_CommonLbConfig_ZoneAwareLbConfig *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(8, 16), const struct google_protobuf_UInt64Value*); }
-UPB_INLINE bool envoy_config_cluster_v3_Cluster_CommonLbConfig_ZoneAwareLbConfig_fail_traffic_on_panic(const envoy_config_cluster_v3_Cluster_CommonLbConfig_ZoneAwareLbConfig *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(0, 0), bool); }
+UPB_INLINE bool envoy_config_cluster_v3_Cluster_CommonLbConfig_ZoneAwareLbConfig_fail_traffic_on_panic(const envoy_config_cluster_v3_Cluster_CommonLbConfig_ZoneAwareLbConfig *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(1, 1), bool); }
 
 UPB_INLINE void envoy_config_cluster_v3_Cluster_CommonLbConfig_ZoneAwareLbConfig_set_routing_enabled(envoy_config_cluster_v3_Cluster_CommonLbConfig_ZoneAwareLbConfig *msg, struct envoy_type_v3_Percent* value) {
+  _upb_sethas(msg, 1);
   *UPB_PTR_AT(msg, UPB_SIZE(4, 8), struct envoy_type_v3_Percent*) = value;
 }
 UPB_INLINE struct envoy_type_v3_Percent* envoy_config_cluster_v3_Cluster_CommonLbConfig_ZoneAwareLbConfig_mutable_routing_enabled(envoy_config_cluster_v3_Cluster_CommonLbConfig_ZoneAwareLbConfig *msg, upb_arena *arena) {
@@ -1306,6 +1426,7 @@ UPB_INLINE struct envoy_type_v3_Percent* envoy_config_cluster_v3_Cluster_CommonL
   return sub;
 }
 UPB_INLINE void envoy_config_cluster_v3_Cluster_CommonLbConfig_ZoneAwareLbConfig_set_min_cluster_size(envoy_config_cluster_v3_Cluster_CommonLbConfig_ZoneAwareLbConfig *msg, struct google_protobuf_UInt64Value* value) {
+  _upb_sethas(msg, 2);
   *UPB_PTR_AT(msg, UPB_SIZE(8, 16), struct google_protobuf_UInt64Value*) = value;
 }
 UPB_INLINE struct google_protobuf_UInt64Value* envoy_config_cluster_v3_Cluster_CommonLbConfig_ZoneAwareLbConfig_mutable_min_cluster_size(envoy_config_cluster_v3_Cluster_CommonLbConfig_ZoneAwareLbConfig *msg, upb_arena *arena) {
@@ -1318,7 +1439,7 @@ UPB_INLINE struct google_protobuf_UInt64Value* envoy_config_cluster_v3_Cluster_C
   return sub;
 }
 UPB_INLINE void envoy_config_cluster_v3_Cluster_CommonLbConfig_ZoneAwareLbConfig_set_fail_traffic_on_panic(envoy_config_cluster_v3_Cluster_CommonLbConfig_ZoneAwareLbConfig *msg, bool value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(0, 0), bool) = value;
+  *UPB_PTR_AT(msg, UPB_SIZE(1, 1), bool) = value;
 }
 
 /* envoy.config.cluster.v3.Cluster.CommonLbConfig.LocalityWeightedLbConfig */
@@ -1331,6 +1452,12 @@ UPB_INLINE envoy_config_cluster_v3_Cluster_CommonLbConfig_LocalityWeightedLbConf
   envoy_config_cluster_v3_Cluster_CommonLbConfig_LocalityWeightedLbConfig *ret = envoy_config_cluster_v3_Cluster_CommonLbConfig_LocalityWeightedLbConfig_new(arena);
   return (ret && upb_decode(buf, size, ret, &envoy_config_cluster_v3_Cluster_CommonLbConfig_LocalityWeightedLbConfig_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE envoy_config_cluster_v3_Cluster_CommonLbConfig_LocalityWeightedLbConfig *envoy_config_cluster_v3_Cluster_CommonLbConfig_LocalityWeightedLbConfig_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  envoy_config_cluster_v3_Cluster_CommonLbConfig_LocalityWeightedLbConfig *ret = envoy_config_cluster_v3_Cluster_CommonLbConfig_LocalityWeightedLbConfig_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &envoy_config_cluster_v3_Cluster_CommonLbConfig_LocalityWeightedLbConfig_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *envoy_config_cluster_v3_Cluster_CommonLbConfig_LocalityWeightedLbConfig_serialize(const envoy_config_cluster_v3_Cluster_CommonLbConfig_LocalityWeightedLbConfig *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &envoy_config_cluster_v3_Cluster_CommonLbConfig_LocalityWeightedLbConfig_msginit, arena, len);
 }
@@ -1347,18 +1474,25 @@ UPB_INLINE envoy_config_cluster_v3_Cluster_CommonLbConfig_ConsistentHashingLbCon
   envoy_config_cluster_v3_Cluster_CommonLbConfig_ConsistentHashingLbConfig *ret = envoy_config_cluster_v3_Cluster_CommonLbConfig_ConsistentHashingLbConfig_new(arena);
   return (ret && upb_decode(buf, size, ret, &envoy_config_cluster_v3_Cluster_CommonLbConfig_ConsistentHashingLbConfig_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE envoy_config_cluster_v3_Cluster_CommonLbConfig_ConsistentHashingLbConfig *envoy_config_cluster_v3_Cluster_CommonLbConfig_ConsistentHashingLbConfig_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  envoy_config_cluster_v3_Cluster_CommonLbConfig_ConsistentHashingLbConfig *ret = envoy_config_cluster_v3_Cluster_CommonLbConfig_ConsistentHashingLbConfig_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &envoy_config_cluster_v3_Cluster_CommonLbConfig_ConsistentHashingLbConfig_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *envoy_config_cluster_v3_Cluster_CommonLbConfig_ConsistentHashingLbConfig_serialize(const envoy_config_cluster_v3_Cluster_CommonLbConfig_ConsistentHashingLbConfig *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &envoy_config_cluster_v3_Cluster_CommonLbConfig_ConsistentHashingLbConfig_msginit, arena, len);
 }
 
-UPB_INLINE bool envoy_config_cluster_v3_Cluster_CommonLbConfig_ConsistentHashingLbConfig_use_hostname_for_hashing(const envoy_config_cluster_v3_Cluster_CommonLbConfig_ConsistentHashingLbConfig *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(0, 0), bool); }
-UPB_INLINE bool envoy_config_cluster_v3_Cluster_CommonLbConfig_ConsistentHashingLbConfig_has_hash_balance_factor(const envoy_config_cluster_v3_Cluster_CommonLbConfig_ConsistentHashingLbConfig *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(4, 8)); }
+UPB_INLINE bool envoy_config_cluster_v3_Cluster_CommonLbConfig_ConsistentHashingLbConfig_use_hostname_for_hashing(const envoy_config_cluster_v3_Cluster_CommonLbConfig_ConsistentHashingLbConfig *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(1, 1), bool); }
+UPB_INLINE bool envoy_config_cluster_v3_Cluster_CommonLbConfig_ConsistentHashingLbConfig_has_hash_balance_factor(const envoy_config_cluster_v3_Cluster_CommonLbConfig_ConsistentHashingLbConfig *msg) { return _upb_hasbit(msg, 1); }
 UPB_INLINE const struct google_protobuf_UInt32Value* envoy_config_cluster_v3_Cluster_CommonLbConfig_ConsistentHashingLbConfig_hash_balance_factor(const envoy_config_cluster_v3_Cluster_CommonLbConfig_ConsistentHashingLbConfig *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(4, 8), const struct google_protobuf_UInt32Value*); }
 
 UPB_INLINE void envoy_config_cluster_v3_Cluster_CommonLbConfig_ConsistentHashingLbConfig_set_use_hostname_for_hashing(envoy_config_cluster_v3_Cluster_CommonLbConfig_ConsistentHashingLbConfig *msg, bool value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(0, 0), bool) = value;
+  *UPB_PTR_AT(msg, UPB_SIZE(1, 1), bool) = value;
 }
 UPB_INLINE void envoy_config_cluster_v3_Cluster_CommonLbConfig_ConsistentHashingLbConfig_set_hash_balance_factor(envoy_config_cluster_v3_Cluster_CommonLbConfig_ConsistentHashingLbConfig *msg, struct google_protobuf_UInt32Value* value) {
+  _upb_sethas(msg, 1);
   *UPB_PTR_AT(msg, UPB_SIZE(4, 8), struct google_protobuf_UInt32Value*) = value;
 }
 UPB_INLINE struct google_protobuf_UInt32Value* envoy_config_cluster_v3_Cluster_CommonLbConfig_ConsistentHashingLbConfig_mutable_hash_balance_factor(envoy_config_cluster_v3_Cluster_CommonLbConfig_ConsistentHashingLbConfig *msg, upb_arena *arena) {
@@ -1381,17 +1515,24 @@ UPB_INLINE envoy_config_cluster_v3_Cluster_RefreshRate *envoy_config_cluster_v3_
   envoy_config_cluster_v3_Cluster_RefreshRate *ret = envoy_config_cluster_v3_Cluster_RefreshRate_new(arena);
   return (ret && upb_decode(buf, size, ret, &envoy_config_cluster_v3_Cluster_RefreshRate_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE envoy_config_cluster_v3_Cluster_RefreshRate *envoy_config_cluster_v3_Cluster_RefreshRate_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  envoy_config_cluster_v3_Cluster_RefreshRate *ret = envoy_config_cluster_v3_Cluster_RefreshRate_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &envoy_config_cluster_v3_Cluster_RefreshRate_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *envoy_config_cluster_v3_Cluster_RefreshRate_serialize(const envoy_config_cluster_v3_Cluster_RefreshRate *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &envoy_config_cluster_v3_Cluster_RefreshRate_msginit, arena, len);
 }
 
-UPB_INLINE bool envoy_config_cluster_v3_Cluster_RefreshRate_has_base_interval(const envoy_config_cluster_v3_Cluster_RefreshRate *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(0, 0)); }
-UPB_INLINE const struct google_protobuf_Duration* envoy_config_cluster_v3_Cluster_RefreshRate_base_interval(const envoy_config_cluster_v3_Cluster_RefreshRate *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(0, 0), const struct google_protobuf_Duration*); }
-UPB_INLINE bool envoy_config_cluster_v3_Cluster_RefreshRate_has_max_interval(const envoy_config_cluster_v3_Cluster_RefreshRate *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(4, 8)); }
-UPB_INLINE const struct google_protobuf_Duration* envoy_config_cluster_v3_Cluster_RefreshRate_max_interval(const envoy_config_cluster_v3_Cluster_RefreshRate *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(4, 8), const struct google_protobuf_Duration*); }
+UPB_INLINE bool envoy_config_cluster_v3_Cluster_RefreshRate_has_base_interval(const envoy_config_cluster_v3_Cluster_RefreshRate *msg) { return _upb_hasbit(msg, 1); }
+UPB_INLINE const struct google_protobuf_Duration* envoy_config_cluster_v3_Cluster_RefreshRate_base_interval(const envoy_config_cluster_v3_Cluster_RefreshRate *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(4, 8), const struct google_protobuf_Duration*); }
+UPB_INLINE bool envoy_config_cluster_v3_Cluster_RefreshRate_has_max_interval(const envoy_config_cluster_v3_Cluster_RefreshRate *msg) { return _upb_hasbit(msg, 2); }
+UPB_INLINE const struct google_protobuf_Duration* envoy_config_cluster_v3_Cluster_RefreshRate_max_interval(const envoy_config_cluster_v3_Cluster_RefreshRate *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(8, 16), const struct google_protobuf_Duration*); }
 
 UPB_INLINE void envoy_config_cluster_v3_Cluster_RefreshRate_set_base_interval(envoy_config_cluster_v3_Cluster_RefreshRate *msg, struct google_protobuf_Duration* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(0, 0), struct google_protobuf_Duration*) = value;
+  _upb_sethas(msg, 1);
+  *UPB_PTR_AT(msg, UPB_SIZE(4, 8), struct google_protobuf_Duration*) = value;
 }
 UPB_INLINE struct google_protobuf_Duration* envoy_config_cluster_v3_Cluster_RefreshRate_mutable_base_interval(envoy_config_cluster_v3_Cluster_RefreshRate *msg, upb_arena *arena) {
   struct google_protobuf_Duration* sub = (struct google_protobuf_Duration*)envoy_config_cluster_v3_Cluster_RefreshRate_base_interval(msg);
@@ -1403,7 +1544,8 @@ UPB_INLINE struct google_protobuf_Duration* envoy_config_cluster_v3_Cluster_Refr
   return sub;
 }
 UPB_INLINE void envoy_config_cluster_v3_Cluster_RefreshRate_set_max_interval(envoy_config_cluster_v3_Cluster_RefreshRate *msg, struct google_protobuf_Duration* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(4, 8), struct google_protobuf_Duration*) = value;
+  _upb_sethas(msg, 2);
+  *UPB_PTR_AT(msg, UPB_SIZE(8, 16), struct google_protobuf_Duration*) = value;
 }
 UPB_INLINE struct google_protobuf_Duration* envoy_config_cluster_v3_Cluster_RefreshRate_mutable_max_interval(envoy_config_cluster_v3_Cluster_RefreshRate *msg, upb_arena *arena) {
   struct google_protobuf_Duration* sub = (struct google_protobuf_Duration*)envoy_config_cluster_v3_Cluster_RefreshRate_max_interval(msg);
@@ -1425,17 +1567,24 @@ UPB_INLINE envoy_config_cluster_v3_Cluster_PrefetchPolicy *envoy_config_cluster_
   envoy_config_cluster_v3_Cluster_PrefetchPolicy *ret = envoy_config_cluster_v3_Cluster_PrefetchPolicy_new(arena);
   return (ret && upb_decode(buf, size, ret, &envoy_config_cluster_v3_Cluster_PrefetchPolicy_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE envoy_config_cluster_v3_Cluster_PrefetchPolicy *envoy_config_cluster_v3_Cluster_PrefetchPolicy_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  envoy_config_cluster_v3_Cluster_PrefetchPolicy *ret = envoy_config_cluster_v3_Cluster_PrefetchPolicy_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &envoy_config_cluster_v3_Cluster_PrefetchPolicy_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *envoy_config_cluster_v3_Cluster_PrefetchPolicy_serialize(const envoy_config_cluster_v3_Cluster_PrefetchPolicy *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &envoy_config_cluster_v3_Cluster_PrefetchPolicy_msginit, arena, len);
 }
 
-UPB_INLINE bool envoy_config_cluster_v3_Cluster_PrefetchPolicy_has_per_upstream_prefetch_ratio(const envoy_config_cluster_v3_Cluster_PrefetchPolicy *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(0, 0)); }
-UPB_INLINE const struct google_protobuf_DoubleValue* envoy_config_cluster_v3_Cluster_PrefetchPolicy_per_upstream_prefetch_ratio(const envoy_config_cluster_v3_Cluster_PrefetchPolicy *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(0, 0), const struct google_protobuf_DoubleValue*); }
-UPB_INLINE bool envoy_config_cluster_v3_Cluster_PrefetchPolicy_has_predictive_prefetch_ratio(const envoy_config_cluster_v3_Cluster_PrefetchPolicy *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(4, 8)); }
-UPB_INLINE const struct google_protobuf_DoubleValue* envoy_config_cluster_v3_Cluster_PrefetchPolicy_predictive_prefetch_ratio(const envoy_config_cluster_v3_Cluster_PrefetchPolicy *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(4, 8), const struct google_protobuf_DoubleValue*); }
+UPB_INLINE bool envoy_config_cluster_v3_Cluster_PrefetchPolicy_has_per_upstream_prefetch_ratio(const envoy_config_cluster_v3_Cluster_PrefetchPolicy *msg) { return _upb_hasbit(msg, 1); }
+UPB_INLINE const struct google_protobuf_DoubleValue* envoy_config_cluster_v3_Cluster_PrefetchPolicy_per_upstream_prefetch_ratio(const envoy_config_cluster_v3_Cluster_PrefetchPolicy *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(4, 8), const struct google_protobuf_DoubleValue*); }
+UPB_INLINE bool envoy_config_cluster_v3_Cluster_PrefetchPolicy_has_predictive_prefetch_ratio(const envoy_config_cluster_v3_Cluster_PrefetchPolicy *msg) { return _upb_hasbit(msg, 2); }
+UPB_INLINE const struct google_protobuf_DoubleValue* envoy_config_cluster_v3_Cluster_PrefetchPolicy_predictive_prefetch_ratio(const envoy_config_cluster_v3_Cluster_PrefetchPolicy *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(8, 16), const struct google_protobuf_DoubleValue*); }
 
 UPB_INLINE void envoy_config_cluster_v3_Cluster_PrefetchPolicy_set_per_upstream_prefetch_ratio(envoy_config_cluster_v3_Cluster_PrefetchPolicy *msg, struct google_protobuf_DoubleValue* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(0, 0), struct google_protobuf_DoubleValue*) = value;
+  _upb_sethas(msg, 1);
+  *UPB_PTR_AT(msg, UPB_SIZE(4, 8), struct google_protobuf_DoubleValue*) = value;
 }
 UPB_INLINE struct google_protobuf_DoubleValue* envoy_config_cluster_v3_Cluster_PrefetchPolicy_mutable_per_upstream_prefetch_ratio(envoy_config_cluster_v3_Cluster_PrefetchPolicy *msg, upb_arena *arena) {
   struct google_protobuf_DoubleValue* sub = (struct google_protobuf_DoubleValue*)envoy_config_cluster_v3_Cluster_PrefetchPolicy_per_upstream_prefetch_ratio(msg);
@@ -1447,7 +1596,8 @@ UPB_INLINE struct google_protobuf_DoubleValue* envoy_config_cluster_v3_Cluster_P
   return sub;
 }
 UPB_INLINE void envoy_config_cluster_v3_Cluster_PrefetchPolicy_set_predictive_prefetch_ratio(envoy_config_cluster_v3_Cluster_PrefetchPolicy *msg, struct google_protobuf_DoubleValue* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(4, 8), struct google_protobuf_DoubleValue*) = value;
+  _upb_sethas(msg, 2);
+  *UPB_PTR_AT(msg, UPB_SIZE(8, 16), struct google_protobuf_DoubleValue*) = value;
 }
 UPB_INLINE struct google_protobuf_DoubleValue* envoy_config_cluster_v3_Cluster_PrefetchPolicy_mutable_predictive_prefetch_ratio(envoy_config_cluster_v3_Cluster_PrefetchPolicy *msg, upb_arena *arena) {
   struct google_protobuf_DoubleValue* sub = (struct google_protobuf_DoubleValue*)envoy_config_cluster_v3_Cluster_PrefetchPolicy_predictive_prefetch_ratio(msg);
@@ -1487,6 +1637,12 @@ UPB_INLINE envoy_config_cluster_v3_LoadBalancingPolicy *envoy_config_cluster_v3_
   envoy_config_cluster_v3_LoadBalancingPolicy *ret = envoy_config_cluster_v3_LoadBalancingPolicy_new(arena);
   return (ret && upb_decode(buf, size, ret, &envoy_config_cluster_v3_LoadBalancingPolicy_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE envoy_config_cluster_v3_LoadBalancingPolicy *envoy_config_cluster_v3_LoadBalancingPolicy_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  envoy_config_cluster_v3_LoadBalancingPolicy *ret = envoy_config_cluster_v3_LoadBalancingPolicy_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &envoy_config_cluster_v3_LoadBalancingPolicy_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *envoy_config_cluster_v3_LoadBalancingPolicy_serialize(const envoy_config_cluster_v3_LoadBalancingPolicy *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &envoy_config_cluster_v3_LoadBalancingPolicy_msginit, arena, len);
 }
@@ -1498,12 +1654,12 @@ UPB_INLINE envoy_config_cluster_v3_LoadBalancingPolicy_Policy** envoy_config_clu
   return (envoy_config_cluster_v3_LoadBalancingPolicy_Policy**)_upb_array_mutable_accessor(msg, UPB_SIZE(0, 0), len);
 }
 UPB_INLINE envoy_config_cluster_v3_LoadBalancingPolicy_Policy** envoy_config_cluster_v3_LoadBalancingPolicy_resize_policies(envoy_config_cluster_v3_LoadBalancingPolicy *msg, size_t len, upb_arena *arena) {
-  return (envoy_config_cluster_v3_LoadBalancingPolicy_Policy**)_upb_array_resize_accessor(msg, UPB_SIZE(0, 0), len, UPB_TYPE_MESSAGE, arena);
+  return (envoy_config_cluster_v3_LoadBalancingPolicy_Policy**)_upb_array_resize_accessor2(msg, UPB_SIZE(0, 0), len, UPB_SIZE(2, 3), arena);
 }
 UPB_INLINE struct envoy_config_cluster_v3_LoadBalancingPolicy_Policy* envoy_config_cluster_v3_LoadBalancingPolicy_add_policies(envoy_config_cluster_v3_LoadBalancingPolicy *msg, upb_arena *arena) {
   struct envoy_config_cluster_v3_LoadBalancingPolicy_Policy* sub = (struct envoy_config_cluster_v3_LoadBalancingPolicy_Policy*)_upb_msg_new(&envoy_config_cluster_v3_LoadBalancingPolicy_Policy_msginit, arena);
-  bool ok = _upb_array_append_accessor(
-      msg, UPB_SIZE(0, 0), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena);
+  bool ok = _upb_array_append_accessor2(
+      msg, UPB_SIZE(0, 0), UPB_SIZE(2, 3), &sub, arena);
   if (!ok) return NULL;
   return sub;
 }
@@ -1518,19 +1674,26 @@ UPB_INLINE envoy_config_cluster_v3_LoadBalancingPolicy_Policy *envoy_config_clus
   envoy_config_cluster_v3_LoadBalancingPolicy_Policy *ret = envoy_config_cluster_v3_LoadBalancingPolicy_Policy_new(arena);
   return (ret && upb_decode(buf, size, ret, &envoy_config_cluster_v3_LoadBalancingPolicy_Policy_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE envoy_config_cluster_v3_LoadBalancingPolicy_Policy *envoy_config_cluster_v3_LoadBalancingPolicy_Policy_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  envoy_config_cluster_v3_LoadBalancingPolicy_Policy *ret = envoy_config_cluster_v3_LoadBalancingPolicy_Policy_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &envoy_config_cluster_v3_LoadBalancingPolicy_Policy_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *envoy_config_cluster_v3_LoadBalancingPolicy_Policy_serialize(const envoy_config_cluster_v3_LoadBalancingPolicy_Policy *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &envoy_config_cluster_v3_LoadBalancingPolicy_Policy_msginit, arena, len);
 }
 
-UPB_INLINE upb_strview envoy_config_cluster_v3_LoadBalancingPolicy_Policy_name(const envoy_config_cluster_v3_LoadBalancingPolicy_Policy *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(0, 0), upb_strview); }
-UPB_INLINE bool envoy_config_cluster_v3_LoadBalancingPolicy_Policy_has_typed_config(const envoy_config_cluster_v3_LoadBalancingPolicy_Policy *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(8, 16)); }
-UPB_INLINE const struct google_protobuf_Any* envoy_config_cluster_v3_LoadBalancingPolicy_Policy_typed_config(const envoy_config_cluster_v3_LoadBalancingPolicy_Policy *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(8, 16), const struct google_protobuf_Any*); }
+UPB_INLINE upb_strview envoy_config_cluster_v3_LoadBalancingPolicy_Policy_name(const envoy_config_cluster_v3_LoadBalancingPolicy_Policy *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(4, 8), upb_strview); }
+UPB_INLINE bool envoy_config_cluster_v3_LoadBalancingPolicy_Policy_has_typed_config(const envoy_config_cluster_v3_LoadBalancingPolicy_Policy *msg) { return _upb_hasbit(msg, 1); }
+UPB_INLINE const struct google_protobuf_Any* envoy_config_cluster_v3_LoadBalancingPolicy_Policy_typed_config(const envoy_config_cluster_v3_LoadBalancingPolicy_Policy *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(12, 24), const struct google_protobuf_Any*); }
 
 UPB_INLINE void envoy_config_cluster_v3_LoadBalancingPolicy_Policy_set_name(envoy_config_cluster_v3_LoadBalancingPolicy_Policy *msg, upb_strview value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(0, 0), upb_strview) = value;
+  *UPB_PTR_AT(msg, UPB_SIZE(4, 8), upb_strview) = value;
 }
 UPB_INLINE void envoy_config_cluster_v3_LoadBalancingPolicy_Policy_set_typed_config(envoy_config_cluster_v3_LoadBalancingPolicy_Policy *msg, struct google_protobuf_Any* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(8, 16), struct google_protobuf_Any*) = value;
+  _upb_sethas(msg, 1);
+  *UPB_PTR_AT(msg, UPB_SIZE(12, 24), struct google_protobuf_Any*) = value;
 }
 UPB_INLINE struct google_protobuf_Any* envoy_config_cluster_v3_LoadBalancingPolicy_Policy_mutable_typed_config(envoy_config_cluster_v3_LoadBalancingPolicy_Policy *msg, upb_arena *arena) {
   struct google_protobuf_Any* sub = (struct google_protobuf_Any*)envoy_config_cluster_v3_LoadBalancingPolicy_Policy_typed_config(msg);
@@ -1552,15 +1715,22 @@ UPB_INLINE envoy_config_cluster_v3_UpstreamBindConfig *envoy_config_cluster_v3_U
   envoy_config_cluster_v3_UpstreamBindConfig *ret = envoy_config_cluster_v3_UpstreamBindConfig_new(arena);
   return (ret && upb_decode(buf, size, ret, &envoy_config_cluster_v3_UpstreamBindConfig_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE envoy_config_cluster_v3_UpstreamBindConfig *envoy_config_cluster_v3_UpstreamBindConfig_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  envoy_config_cluster_v3_UpstreamBindConfig *ret = envoy_config_cluster_v3_UpstreamBindConfig_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &envoy_config_cluster_v3_UpstreamBindConfig_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *envoy_config_cluster_v3_UpstreamBindConfig_serialize(const envoy_config_cluster_v3_UpstreamBindConfig *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &envoy_config_cluster_v3_UpstreamBindConfig_msginit, arena, len);
 }
 
-UPB_INLINE bool envoy_config_cluster_v3_UpstreamBindConfig_has_source_address(const envoy_config_cluster_v3_UpstreamBindConfig *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(0, 0)); }
-UPB_INLINE const struct envoy_config_core_v3_Address* envoy_config_cluster_v3_UpstreamBindConfig_source_address(const envoy_config_cluster_v3_UpstreamBindConfig *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(0, 0), const struct envoy_config_core_v3_Address*); }
+UPB_INLINE bool envoy_config_cluster_v3_UpstreamBindConfig_has_source_address(const envoy_config_cluster_v3_UpstreamBindConfig *msg) { return _upb_hasbit(msg, 1); }
+UPB_INLINE const struct envoy_config_core_v3_Address* envoy_config_cluster_v3_UpstreamBindConfig_source_address(const envoy_config_cluster_v3_UpstreamBindConfig *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(4, 8), const struct envoy_config_core_v3_Address*); }
 
 UPB_INLINE void envoy_config_cluster_v3_UpstreamBindConfig_set_source_address(envoy_config_cluster_v3_UpstreamBindConfig *msg, struct envoy_config_core_v3_Address* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(0, 0), struct envoy_config_core_v3_Address*) = value;
+  _upb_sethas(msg, 1);
+  *UPB_PTR_AT(msg, UPB_SIZE(4, 8), struct envoy_config_core_v3_Address*) = value;
 }
 UPB_INLINE struct envoy_config_core_v3_Address* envoy_config_cluster_v3_UpstreamBindConfig_mutable_source_address(envoy_config_cluster_v3_UpstreamBindConfig *msg, upb_arena *arena) {
   struct envoy_config_core_v3_Address* sub = (struct envoy_config_core_v3_Address*)envoy_config_cluster_v3_UpstreamBindConfig_source_address(msg);
@@ -1582,15 +1752,22 @@ UPB_INLINE envoy_config_cluster_v3_UpstreamConnectionOptions *envoy_config_clust
   envoy_config_cluster_v3_UpstreamConnectionOptions *ret = envoy_config_cluster_v3_UpstreamConnectionOptions_new(arena);
   return (ret && upb_decode(buf, size, ret, &envoy_config_cluster_v3_UpstreamConnectionOptions_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE envoy_config_cluster_v3_UpstreamConnectionOptions *envoy_config_cluster_v3_UpstreamConnectionOptions_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  envoy_config_cluster_v3_UpstreamConnectionOptions *ret = envoy_config_cluster_v3_UpstreamConnectionOptions_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &envoy_config_cluster_v3_UpstreamConnectionOptions_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *envoy_config_cluster_v3_UpstreamConnectionOptions_serialize(const envoy_config_cluster_v3_UpstreamConnectionOptions *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &envoy_config_cluster_v3_UpstreamConnectionOptions_msginit, arena, len);
 }
 
-UPB_INLINE bool envoy_config_cluster_v3_UpstreamConnectionOptions_has_tcp_keepalive(const envoy_config_cluster_v3_UpstreamConnectionOptions *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(0, 0)); }
-UPB_INLINE const struct envoy_config_core_v3_TcpKeepalive* envoy_config_cluster_v3_UpstreamConnectionOptions_tcp_keepalive(const envoy_config_cluster_v3_UpstreamConnectionOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(0, 0), const struct envoy_config_core_v3_TcpKeepalive*); }
+UPB_INLINE bool envoy_config_cluster_v3_UpstreamConnectionOptions_has_tcp_keepalive(const envoy_config_cluster_v3_UpstreamConnectionOptions *msg) { return _upb_hasbit(msg, 1); }
+UPB_INLINE const struct envoy_config_core_v3_TcpKeepalive* envoy_config_cluster_v3_UpstreamConnectionOptions_tcp_keepalive(const envoy_config_cluster_v3_UpstreamConnectionOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(4, 8), const struct envoy_config_core_v3_TcpKeepalive*); }
 
 UPB_INLINE void envoy_config_cluster_v3_UpstreamConnectionOptions_set_tcp_keepalive(envoy_config_cluster_v3_UpstreamConnectionOptions *msg, struct envoy_config_core_v3_TcpKeepalive* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(0, 0), struct envoy_config_core_v3_TcpKeepalive*) = value;
+  _upb_sethas(msg, 1);
+  *UPB_PTR_AT(msg, UPB_SIZE(4, 8), struct envoy_config_core_v3_TcpKeepalive*) = value;
 }
 UPB_INLINE struct envoy_config_core_v3_TcpKeepalive* envoy_config_cluster_v3_UpstreamConnectionOptions_mutable_tcp_keepalive(envoy_config_cluster_v3_UpstreamConnectionOptions *msg, upb_arena *arena) {
   struct envoy_config_core_v3_TcpKeepalive* sub = (struct envoy_config_core_v3_TcpKeepalive*)envoy_config_cluster_v3_UpstreamConnectionOptions_tcp_keepalive(msg);
@@ -1612,6 +1789,12 @@ UPB_INLINE envoy_config_cluster_v3_TrackClusterStats *envoy_config_cluster_v3_Tr
   envoy_config_cluster_v3_TrackClusterStats *ret = envoy_config_cluster_v3_TrackClusterStats_new(arena);
   return (ret && upb_decode(buf, size, ret, &envoy_config_cluster_v3_TrackClusterStats_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE envoy_config_cluster_v3_TrackClusterStats *envoy_config_cluster_v3_TrackClusterStats_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  envoy_config_cluster_v3_TrackClusterStats *ret = envoy_config_cluster_v3_TrackClusterStats_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &envoy_config_cluster_v3_TrackClusterStats_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *envoy_config_cluster_v3_TrackClusterStats_serialize(const envoy_config_cluster_v3_TrackClusterStats *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &envoy_config_cluster_v3_TrackClusterStats_msginit, arena, len);
 }
index 8dfe234..1423014 100644 (file)
@@ -21,14 +21,14 @@ static const upb_msglayout *const envoy_config_cluster_v3_Filter_submsgs[1] = {
 };
 
 static const upb_msglayout_field envoy_config_cluster_v3_Filter__fields[2] = {
-  {1, UPB_SIZE(0, 0), 0, 0, 9, 1},
-  {2, UPB_SIZE(8, 16), 0, 0, 11, 1},
+  {1, UPB_SIZE(4, 8), 0, 0, 9, 1},
+  {2, UPB_SIZE(12, 24), 1, 0, 11, 1},
 };
 
 const upb_msglayout envoy_config_cluster_v3_Filter_msginit = {
   &envoy_config_cluster_v3_Filter_submsgs[0],
   &envoy_config_cluster_v3_Filter__fields[0],
-  UPB_SIZE(16, 32), 2, false,
+  UPB_SIZE(16, 32), 2, false, 255,
 };
 
 #include "upb/port_undef.inc"
index 016bb95..1850b2a 100644 (file)
@@ -11,6 +11,7 @@
 
 #include "upb/msg.h"
 #include "upb/decode.h"
+#include "upb/decode_fast.h"
 #include "upb/encode.h"
 
 #include "upb/port_def.inc"
@@ -36,19 +37,26 @@ UPB_INLINE envoy_config_cluster_v3_Filter *envoy_config_cluster_v3_Filter_parse(
   envoy_config_cluster_v3_Filter *ret = envoy_config_cluster_v3_Filter_new(arena);
   return (ret && upb_decode(buf, size, ret, &envoy_config_cluster_v3_Filter_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE envoy_config_cluster_v3_Filter *envoy_config_cluster_v3_Filter_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  envoy_config_cluster_v3_Filter *ret = envoy_config_cluster_v3_Filter_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &envoy_config_cluster_v3_Filter_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *envoy_config_cluster_v3_Filter_serialize(const envoy_config_cluster_v3_Filter *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &envoy_config_cluster_v3_Filter_msginit, arena, len);
 }
 
-UPB_INLINE upb_strview envoy_config_cluster_v3_Filter_name(const envoy_config_cluster_v3_Filter *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(0, 0), upb_strview); }
-UPB_INLINE bool envoy_config_cluster_v3_Filter_has_typed_config(const envoy_config_cluster_v3_Filter *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(8, 16)); }
-UPB_INLINE const struct google_protobuf_Any* envoy_config_cluster_v3_Filter_typed_config(const envoy_config_cluster_v3_Filter *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(8, 16), const struct google_protobuf_Any*); }
+UPB_INLINE upb_strview envoy_config_cluster_v3_Filter_name(const envoy_config_cluster_v3_Filter *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(4, 8), upb_strview); }
+UPB_INLINE bool envoy_config_cluster_v3_Filter_has_typed_config(const envoy_config_cluster_v3_Filter *msg) { return _upb_hasbit(msg, 1); }
+UPB_INLINE const struct google_protobuf_Any* envoy_config_cluster_v3_Filter_typed_config(const envoy_config_cluster_v3_Filter *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(12, 24), const struct google_protobuf_Any*); }
 
 UPB_INLINE void envoy_config_cluster_v3_Filter_set_name(envoy_config_cluster_v3_Filter *msg, upb_strview value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(0, 0), upb_strview) = value;
+  *UPB_PTR_AT(msg, UPB_SIZE(4, 8), upb_strview) = value;
 }
 UPB_INLINE void envoy_config_cluster_v3_Filter_set_typed_config(envoy_config_cluster_v3_Filter *msg, struct google_protobuf_Any* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(8, 16), struct google_protobuf_Any*) = value;
+  _upb_sethas(msg, 1);
+  *UPB_PTR_AT(msg, UPB_SIZE(12, 24), struct google_protobuf_Any*) = value;
 }
 UPB_INLINE struct google_protobuf_Any* envoy_config_cluster_v3_Filter_mutable_typed_config(envoy_config_cluster_v3_Filter *msg, upb_arena *arena) {
   struct google_protobuf_Any* sub = (struct google_protobuf_Any*)envoy_config_cluster_v3_Filter_typed_config(msg);
index a6af66c..9e32e67 100644 (file)
 
 #include "upb/port_def.inc"
 
-static const upb_msglayout *const envoy_config_cluster_v3_OutlierDetection_submsgs[19] = {
+static const upb_msglayout *const envoy_config_cluster_v3_OutlierDetection_submsgs[2] = {
   &google_protobuf_Duration_msginit,
   &google_protobuf_UInt32Value_msginit,
 };
 
 static const upb_msglayout_field envoy_config_cluster_v3_OutlierDetection__fields[20] = {
-  {1, UPB_SIZE(4, 8), 0, 1, 11, 1},
-  {2, UPB_SIZE(8, 16), 0, 0, 11, 1},
-  {3, UPB_SIZE(12, 24), 0, 0, 11, 1},
-  {4, UPB_SIZE(16, 32), 0, 1, 11, 1},
-  {5, UPB_SIZE(20, 40), 0, 1, 11, 1},
-  {6, UPB_SIZE(24, 48), 0, 1, 11, 1},
-  {7, UPB_SIZE(28, 56), 0, 1, 11, 1},
-  {8, UPB_SIZE(32, 64), 0, 1, 11, 1},
-  {9, UPB_SIZE(36, 72), 0, 1, 11, 1},
-  {10, UPB_SIZE(40, 80), 0, 1, 11, 1},
-  {11, UPB_SIZE(44, 88), 0, 1, 11, 1},
-  {12, UPB_SIZE(0, 0), 0, 0, 8, 1},
-  {13, UPB_SIZE(48, 96), 0, 1, 11, 1},
-  {14, UPB_SIZE(52, 104), 0, 1, 11, 1},
-  {15, UPB_SIZE(56, 112), 0, 1, 11, 1},
-  {16, UPB_SIZE(60, 120), 0, 1, 11, 1},
-  {17, UPB_SIZE(64, 128), 0, 1, 11, 1},
-  {18, UPB_SIZE(68, 136), 0, 1, 11, 1},
-  {19, UPB_SIZE(72, 144), 0, 1, 11, 1},
-  {20, UPB_SIZE(76, 152), 0, 1, 11, 1},
+  {1, UPB_SIZE(4, 8), 1, 1, 11, 1},
+  {2, UPB_SIZE(8, 16), 2, 0, 11, 1},
+  {3, UPB_SIZE(12, 24), 3, 0, 11, 1},
+  {4, UPB_SIZE(16, 32), 4, 1, 11, 1},
+  {5, UPB_SIZE(20, 40), 5, 1, 11, 1},
+  {6, UPB_SIZE(24, 48), 6, 1, 11, 1},
+  {7, UPB_SIZE(28, 56), 7, 1, 11, 1},
+  {8, UPB_SIZE(32, 64), 8, 1, 11, 1},
+  {9, UPB_SIZE(36, 72), 9, 1, 11, 1},
+  {10, UPB_SIZE(40, 80), 10, 1, 11, 1},
+  {11, UPB_SIZE(44, 88), 11, 1, 11, 1},
+  {12, UPB_SIZE(3, 3), 0, 0, 8, 1},
+  {13, UPB_SIZE(48, 96), 12, 1, 11, 1},
+  {14, UPB_SIZE(52, 104), 13, 1, 11, 1},
+  {15, UPB_SIZE(56, 112), 14, 1, 11, 1},
+  {16, UPB_SIZE(60, 120), 15, 1, 11, 1},
+  {17, UPB_SIZE(64, 128), 16, 1, 11, 1},
+  {18, UPB_SIZE(68, 136), 17, 1, 11, 1},
+  {19, UPB_SIZE(72, 144), 18, 1, 11, 1},
+  {20, UPB_SIZE(76, 152), 19, 1, 11, 1},
 };
 
 const upb_msglayout envoy_config_cluster_v3_OutlierDetection_msginit = {
   &envoy_config_cluster_v3_OutlierDetection_submsgs[0],
   &envoy_config_cluster_v3_OutlierDetection__fields[0],
-  UPB_SIZE(80, 160), 20, false,
+  UPB_SIZE(80, 160), 20, false, 255,
 };
 
 #include "upb/port_undef.inc"
index d8b03a8..8d43fa9 100644 (file)
@@ -11,6 +11,7 @@
 
 #include "upb/msg.h"
 #include "upb/decode.h"
+#include "upb/decode_fast.h"
 #include "upb/encode.h"
 
 #include "upb/port_def.inc"
@@ -38,51 +39,58 @@ UPB_INLINE envoy_config_cluster_v3_OutlierDetection *envoy_config_cluster_v3_Out
   envoy_config_cluster_v3_OutlierDetection *ret = envoy_config_cluster_v3_OutlierDetection_new(arena);
   return (ret && upb_decode(buf, size, ret, &envoy_config_cluster_v3_OutlierDetection_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE envoy_config_cluster_v3_OutlierDetection *envoy_config_cluster_v3_OutlierDetection_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  envoy_config_cluster_v3_OutlierDetection *ret = envoy_config_cluster_v3_OutlierDetection_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &envoy_config_cluster_v3_OutlierDetection_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *envoy_config_cluster_v3_OutlierDetection_serialize(const envoy_config_cluster_v3_OutlierDetection *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &envoy_config_cluster_v3_OutlierDetection_msginit, arena, len);
 }
 
-UPB_INLINE bool envoy_config_cluster_v3_OutlierDetection_has_consecutive_5xx(const envoy_config_cluster_v3_OutlierDetection *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(4, 8)); }
+UPB_INLINE bool envoy_config_cluster_v3_OutlierDetection_has_consecutive_5xx(const envoy_config_cluster_v3_OutlierDetection *msg) { return _upb_hasbit(msg, 1); }
 UPB_INLINE const struct google_protobuf_UInt32Value* envoy_config_cluster_v3_OutlierDetection_consecutive_5xx(const envoy_config_cluster_v3_OutlierDetection *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(4, 8), const struct google_protobuf_UInt32Value*); }
-UPB_INLINE bool envoy_config_cluster_v3_OutlierDetection_has_interval(const envoy_config_cluster_v3_OutlierDetection *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(8, 16)); }
+UPB_INLINE bool envoy_config_cluster_v3_OutlierDetection_has_interval(const envoy_config_cluster_v3_OutlierDetection *msg) { return _upb_hasbit(msg, 2); }
 UPB_INLINE const struct google_protobuf_Duration* envoy_config_cluster_v3_OutlierDetection_interval(const envoy_config_cluster_v3_OutlierDetection *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(8, 16), const struct google_protobuf_Duration*); }
-UPB_INLINE bool envoy_config_cluster_v3_OutlierDetection_has_base_ejection_time(const envoy_config_cluster_v3_OutlierDetection *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(12, 24)); }
+UPB_INLINE bool envoy_config_cluster_v3_OutlierDetection_has_base_ejection_time(const envoy_config_cluster_v3_OutlierDetection *msg) { return _upb_hasbit(msg, 3); }
 UPB_INLINE const struct google_protobuf_Duration* envoy_config_cluster_v3_OutlierDetection_base_ejection_time(const envoy_config_cluster_v3_OutlierDetection *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(12, 24), const struct google_protobuf_Duration*); }
-UPB_INLINE bool envoy_config_cluster_v3_OutlierDetection_has_max_ejection_percent(const envoy_config_cluster_v3_OutlierDetection *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(16, 32)); }
+UPB_INLINE bool envoy_config_cluster_v3_OutlierDetection_has_max_ejection_percent(const envoy_config_cluster_v3_OutlierDetection *msg) { return _upb_hasbit(msg, 4); }
 UPB_INLINE const struct google_protobuf_UInt32Value* envoy_config_cluster_v3_OutlierDetection_max_ejection_percent(const envoy_config_cluster_v3_OutlierDetection *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(16, 32), const struct google_protobuf_UInt32Value*); }
-UPB_INLINE bool envoy_config_cluster_v3_OutlierDetection_has_enforcing_consecutive_5xx(const envoy_config_cluster_v3_OutlierDetection *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(20, 40)); }
+UPB_INLINE bool envoy_config_cluster_v3_OutlierDetection_has_enforcing_consecutive_5xx(const envoy_config_cluster_v3_OutlierDetection *msg) { return _upb_hasbit(msg, 5); }
 UPB_INLINE const struct google_protobuf_UInt32Value* envoy_config_cluster_v3_OutlierDetection_enforcing_consecutive_5xx(const envoy_config_cluster_v3_OutlierDetection *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(20, 40), const struct google_protobuf_UInt32Value*); }
-UPB_INLINE bool envoy_config_cluster_v3_OutlierDetection_has_enforcing_success_rate(const envoy_config_cluster_v3_OutlierDetection *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(24, 48)); }
+UPB_INLINE bool envoy_config_cluster_v3_OutlierDetection_has_enforcing_success_rate(const envoy_config_cluster_v3_OutlierDetection *msg) { return _upb_hasbit(msg, 6); }
 UPB_INLINE const struct google_protobuf_UInt32Value* envoy_config_cluster_v3_OutlierDetection_enforcing_success_rate(const envoy_config_cluster_v3_OutlierDetection *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(24, 48), const struct google_protobuf_UInt32Value*); }
-UPB_INLINE bool envoy_config_cluster_v3_OutlierDetection_has_success_rate_minimum_hosts(const envoy_config_cluster_v3_OutlierDetection *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(28, 56)); }
+UPB_INLINE bool envoy_config_cluster_v3_OutlierDetection_has_success_rate_minimum_hosts(const envoy_config_cluster_v3_OutlierDetection *msg) { return _upb_hasbit(msg, 7); }
 UPB_INLINE const struct google_protobuf_UInt32Value* envoy_config_cluster_v3_OutlierDetection_success_rate_minimum_hosts(const envoy_config_cluster_v3_OutlierDetection *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(28, 56), const struct google_protobuf_UInt32Value*); }
-UPB_INLINE bool envoy_config_cluster_v3_OutlierDetection_has_success_rate_request_volume(const envoy_config_cluster_v3_OutlierDetection *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(32, 64)); }
+UPB_INLINE bool envoy_config_cluster_v3_OutlierDetection_has_success_rate_request_volume(const envoy_config_cluster_v3_OutlierDetection *msg) { return _upb_hasbit(msg, 8); }
 UPB_INLINE const struct google_protobuf_UInt32Value* envoy_config_cluster_v3_OutlierDetection_success_rate_request_volume(const envoy_config_cluster_v3_OutlierDetection *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(32, 64), const struct google_protobuf_UInt32Value*); }
-UPB_INLINE bool envoy_config_cluster_v3_OutlierDetection_has_success_rate_stdev_factor(const envoy_config_cluster_v3_OutlierDetection *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(36, 72)); }
+UPB_INLINE bool envoy_config_cluster_v3_OutlierDetection_has_success_rate_stdev_factor(const envoy_config_cluster_v3_OutlierDetection *msg) { return _upb_hasbit(msg, 9); }
 UPB_INLINE const struct google_protobuf_UInt32Value* envoy_config_cluster_v3_OutlierDetection_success_rate_stdev_factor(const envoy_config_cluster_v3_OutlierDetection *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(36, 72), const struct google_protobuf_UInt32Value*); }
-UPB_INLINE bool envoy_config_cluster_v3_OutlierDetection_has_consecutive_gateway_failure(const envoy_config_cluster_v3_OutlierDetection *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(40, 80)); }
+UPB_INLINE bool envoy_config_cluster_v3_OutlierDetection_has_consecutive_gateway_failure(const envoy_config_cluster_v3_OutlierDetection *msg) { return _upb_hasbit(msg, 10); }
 UPB_INLINE const struct google_protobuf_UInt32Value* envoy_config_cluster_v3_OutlierDetection_consecutive_gateway_failure(const envoy_config_cluster_v3_OutlierDetection *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(40, 80), const struct google_protobuf_UInt32Value*); }
-UPB_INLINE bool envoy_config_cluster_v3_OutlierDetection_has_enforcing_consecutive_gateway_failure(const envoy_config_cluster_v3_OutlierDetection *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(44, 88)); }
+UPB_INLINE bool envoy_config_cluster_v3_OutlierDetection_has_enforcing_consecutive_gateway_failure(const envoy_config_cluster_v3_OutlierDetection *msg) { return _upb_hasbit(msg, 11); }
 UPB_INLINE const struct google_protobuf_UInt32Value* envoy_config_cluster_v3_OutlierDetection_enforcing_consecutive_gateway_failure(const envoy_config_cluster_v3_OutlierDetection *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(44, 88), const struct google_protobuf_UInt32Value*); }
-UPB_INLINE bool envoy_config_cluster_v3_OutlierDetection_split_external_local_origin_errors(const envoy_config_cluster_v3_OutlierDetection *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(0, 0), bool); }
-UPB_INLINE bool envoy_config_cluster_v3_OutlierDetection_has_consecutive_local_origin_failure(const envoy_config_cluster_v3_OutlierDetection *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(48, 96)); }
+UPB_INLINE bool envoy_config_cluster_v3_OutlierDetection_split_external_local_origin_errors(const envoy_config_cluster_v3_OutlierDetection *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(3, 3), bool); }
+UPB_INLINE bool envoy_config_cluster_v3_OutlierDetection_has_consecutive_local_origin_failure(const envoy_config_cluster_v3_OutlierDetection *msg) { return _upb_hasbit(msg, 12); }
 UPB_INLINE const struct google_protobuf_UInt32Value* envoy_config_cluster_v3_OutlierDetection_consecutive_local_origin_failure(const envoy_config_cluster_v3_OutlierDetection *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(48, 96), const struct google_protobuf_UInt32Value*); }
-UPB_INLINE bool envoy_config_cluster_v3_OutlierDetection_has_enforcing_consecutive_local_origin_failure(const envoy_config_cluster_v3_OutlierDetection *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(52, 104)); }
+UPB_INLINE bool envoy_config_cluster_v3_OutlierDetection_has_enforcing_consecutive_local_origin_failure(const envoy_config_cluster_v3_OutlierDetection *msg) { return _upb_hasbit(msg, 13); }
 UPB_INLINE const struct google_protobuf_UInt32Value* envoy_config_cluster_v3_OutlierDetection_enforcing_consecutive_local_origin_failure(const envoy_config_cluster_v3_OutlierDetection *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(52, 104), const struct google_protobuf_UInt32Value*); }
-UPB_INLINE bool envoy_config_cluster_v3_OutlierDetection_has_enforcing_local_origin_success_rate(const envoy_config_cluster_v3_OutlierDetection *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(56, 112)); }
+UPB_INLINE bool envoy_config_cluster_v3_OutlierDetection_has_enforcing_local_origin_success_rate(const envoy_config_cluster_v3_OutlierDetection *msg) { return _upb_hasbit(msg, 14); }
 UPB_INLINE const struct google_protobuf_UInt32Value* envoy_config_cluster_v3_OutlierDetection_enforcing_local_origin_success_rate(const envoy_config_cluster_v3_OutlierDetection *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(56, 112), const struct google_protobuf_UInt32Value*); }
-UPB_INLINE bool envoy_config_cluster_v3_OutlierDetection_has_failure_percentage_threshold(const envoy_config_cluster_v3_OutlierDetection *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(60, 120)); }
+UPB_INLINE bool envoy_config_cluster_v3_OutlierDetection_has_failure_percentage_threshold(const envoy_config_cluster_v3_OutlierDetection *msg) { return _upb_hasbit(msg, 15); }
 UPB_INLINE const struct google_protobuf_UInt32Value* envoy_config_cluster_v3_OutlierDetection_failure_percentage_threshold(const envoy_config_cluster_v3_OutlierDetection *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(60, 120), const struct google_protobuf_UInt32Value*); }
-UPB_INLINE bool envoy_config_cluster_v3_OutlierDetection_has_enforcing_failure_percentage(const envoy_config_cluster_v3_OutlierDetection *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(64, 128)); }
+UPB_INLINE bool envoy_config_cluster_v3_OutlierDetection_has_enforcing_failure_percentage(const envoy_config_cluster_v3_OutlierDetection *msg) { return _upb_hasbit(msg, 16); }
 UPB_INLINE const struct google_protobuf_UInt32Value* envoy_config_cluster_v3_OutlierDetection_enforcing_failure_percentage(const envoy_config_cluster_v3_OutlierDetection *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(64, 128), const struct google_protobuf_UInt32Value*); }
-UPB_INLINE bool envoy_config_cluster_v3_OutlierDetection_has_enforcing_failure_percentage_local_origin(const envoy_config_cluster_v3_OutlierDetection *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(68, 136)); }
+UPB_INLINE bool envoy_config_cluster_v3_OutlierDetection_has_enforcing_failure_percentage_local_origin(const envoy_config_cluster_v3_OutlierDetection *msg) { return _upb_hasbit(msg, 17); }
 UPB_INLINE const struct google_protobuf_UInt32Value* envoy_config_cluster_v3_OutlierDetection_enforcing_failure_percentage_local_origin(const envoy_config_cluster_v3_OutlierDetection *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(68, 136), const struct google_protobuf_UInt32Value*); }
-UPB_INLINE bool envoy_config_cluster_v3_OutlierDetection_has_failure_percentage_minimum_hosts(const envoy_config_cluster_v3_OutlierDetection *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(72, 144)); }
+UPB_INLINE bool envoy_config_cluster_v3_OutlierDetection_has_failure_percentage_minimum_hosts(const envoy_config_cluster_v3_OutlierDetection *msg) { return _upb_hasbit(msg, 18); }
 UPB_INLINE const struct google_protobuf_UInt32Value* envoy_config_cluster_v3_OutlierDetection_failure_percentage_minimum_hosts(const envoy_config_cluster_v3_OutlierDetection *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(72, 144), const struct google_protobuf_UInt32Value*); }
-UPB_INLINE bool envoy_config_cluster_v3_OutlierDetection_has_failure_percentage_request_volume(const envoy_config_cluster_v3_OutlierDetection *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(76, 152)); }
+UPB_INLINE bool envoy_config_cluster_v3_OutlierDetection_has_failure_percentage_request_volume(const envoy_config_cluster_v3_OutlierDetection *msg) { return _upb_hasbit(msg, 19); }
 UPB_INLINE const struct google_protobuf_UInt32Value* envoy_config_cluster_v3_OutlierDetection_failure_percentage_request_volume(const envoy_config_cluster_v3_OutlierDetection *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(76, 152), const struct google_protobuf_UInt32Value*); }
 
 UPB_INLINE void envoy_config_cluster_v3_OutlierDetection_set_consecutive_5xx(envoy_config_cluster_v3_OutlierDetection *msg, struct google_protobuf_UInt32Value* value) {
+  _upb_sethas(msg, 1);
   *UPB_PTR_AT(msg, UPB_SIZE(4, 8), struct google_protobuf_UInt32Value*) = value;
 }
 UPB_INLINE struct google_protobuf_UInt32Value* envoy_config_cluster_v3_OutlierDetection_mutable_consecutive_5xx(envoy_config_cluster_v3_OutlierDetection *msg, upb_arena *arena) {
@@ -95,6 +103,7 @@ UPB_INLINE struct google_protobuf_UInt32Value* envoy_config_cluster_v3_OutlierDe
   return sub;
 }
 UPB_INLINE void envoy_config_cluster_v3_OutlierDetection_set_interval(envoy_config_cluster_v3_OutlierDetection *msg, struct google_protobuf_Duration* value) {
+  _upb_sethas(msg, 2);
   *UPB_PTR_AT(msg, UPB_SIZE(8, 16), struct google_protobuf_Duration*) = value;
 }
 UPB_INLINE struct google_protobuf_Duration* envoy_config_cluster_v3_OutlierDetection_mutable_interval(envoy_config_cluster_v3_OutlierDetection *msg, upb_arena *arena) {
@@ -107,6 +116,7 @@ UPB_INLINE struct google_protobuf_Duration* envoy_config_cluster_v3_OutlierDetec
   return sub;
 }
 UPB_INLINE void envoy_config_cluster_v3_OutlierDetection_set_base_ejection_time(envoy_config_cluster_v3_OutlierDetection *msg, struct google_protobuf_Duration* value) {
+  _upb_sethas(msg, 3);
   *UPB_PTR_AT(msg, UPB_SIZE(12, 24), struct google_protobuf_Duration*) = value;
 }
 UPB_INLINE struct google_protobuf_Duration* envoy_config_cluster_v3_OutlierDetection_mutable_base_ejection_time(envoy_config_cluster_v3_OutlierDetection *msg, upb_arena *arena) {
@@ -119,6 +129,7 @@ UPB_INLINE struct google_protobuf_Duration* envoy_config_cluster_v3_OutlierDetec
   return sub;
 }
 UPB_INLINE void envoy_config_cluster_v3_OutlierDetection_set_max_ejection_percent(envoy_config_cluster_v3_OutlierDetection *msg, struct google_protobuf_UInt32Value* value) {
+  _upb_sethas(msg, 4);
   *UPB_PTR_AT(msg, UPB_SIZE(16, 32), struct google_protobuf_UInt32Value*) = value;
 }
 UPB_INLINE struct google_protobuf_UInt32Value* envoy_config_cluster_v3_OutlierDetection_mutable_max_ejection_percent(envoy_config_cluster_v3_OutlierDetection *msg, upb_arena *arena) {
@@ -131,6 +142,7 @@ UPB_INLINE struct google_protobuf_UInt32Value* envoy_config_cluster_v3_OutlierDe
   return sub;
 }
 UPB_INLINE void envoy_config_cluster_v3_OutlierDetection_set_enforcing_consecutive_5xx(envoy_config_cluster_v3_OutlierDetection *msg, struct google_protobuf_UInt32Value* value) {
+  _upb_sethas(msg, 5);
   *UPB_PTR_AT(msg, UPB_SIZE(20, 40), struct google_protobuf_UInt32Value*) = value;
 }
 UPB_INLINE struct google_protobuf_UInt32Value* envoy_config_cluster_v3_OutlierDetection_mutable_enforcing_consecutive_5xx(envoy_config_cluster_v3_OutlierDetection *msg, upb_arena *arena) {
@@ -143,6 +155,7 @@ UPB_INLINE struct google_protobuf_UInt32Value* envoy_config_cluster_v3_OutlierDe
   return sub;
 }
 UPB_INLINE void envoy_config_cluster_v3_OutlierDetection_set_enforcing_success_rate(envoy_config_cluster_v3_OutlierDetection *msg, struct google_protobuf_UInt32Value* value) {
+  _upb_sethas(msg, 6);
   *UPB_PTR_AT(msg, UPB_SIZE(24, 48), struct google_protobuf_UInt32Value*) = value;
 }
 UPB_INLINE struct google_protobuf_UInt32Value* envoy_config_cluster_v3_OutlierDetection_mutable_enforcing_success_rate(envoy_config_cluster_v3_OutlierDetection *msg, upb_arena *arena) {
@@ -155,6 +168,7 @@ UPB_INLINE struct google_protobuf_UInt32Value* envoy_config_cluster_v3_OutlierDe
   return sub;
 }
 UPB_INLINE void envoy_config_cluster_v3_OutlierDetection_set_success_rate_minimum_hosts(envoy_config_cluster_v3_OutlierDetection *msg, struct google_protobuf_UInt32Value* value) {
+  _upb_sethas(msg, 7);
   *UPB_PTR_AT(msg, UPB_SIZE(28, 56), struct google_protobuf_UInt32Value*) = value;
 }
 UPB_INLINE struct google_protobuf_UInt32Value* envoy_config_cluster_v3_OutlierDetection_mutable_success_rate_minimum_hosts(envoy_config_cluster_v3_OutlierDetection *msg, upb_arena *arena) {
@@ -167,6 +181,7 @@ UPB_INLINE struct google_protobuf_UInt32Value* envoy_config_cluster_v3_OutlierDe
   return sub;
 }
 UPB_INLINE void envoy_config_cluster_v3_OutlierDetection_set_success_rate_request_volume(envoy_config_cluster_v3_OutlierDetection *msg, struct google_protobuf_UInt32Value* value) {
+  _upb_sethas(msg, 8);
   *UPB_PTR_AT(msg, UPB_SIZE(32, 64), struct google_protobuf_UInt32Value*) = value;
 }
 UPB_INLINE struct google_protobuf_UInt32Value* envoy_config_cluster_v3_OutlierDetection_mutable_success_rate_request_volume(envoy_config_cluster_v3_OutlierDetection *msg, upb_arena *arena) {
@@ -179,6 +194,7 @@ UPB_INLINE struct google_protobuf_UInt32Value* envoy_config_cluster_v3_OutlierDe
   return sub;
 }
 UPB_INLINE void envoy_config_cluster_v3_OutlierDetection_set_success_rate_stdev_factor(envoy_config_cluster_v3_OutlierDetection *msg, struct google_protobuf_UInt32Value* value) {
+  _upb_sethas(msg, 9);
   *UPB_PTR_AT(msg, UPB_SIZE(36, 72), struct google_protobuf_UInt32Value*) = value;
 }
 UPB_INLINE struct google_protobuf_UInt32Value* envoy_config_cluster_v3_OutlierDetection_mutable_success_rate_stdev_factor(envoy_config_cluster_v3_OutlierDetection *msg, upb_arena *arena) {
@@ -191,6 +207,7 @@ UPB_INLINE struct google_protobuf_UInt32Value* envoy_config_cluster_v3_OutlierDe
   return sub;
 }
 UPB_INLINE void envoy_config_cluster_v3_OutlierDetection_set_consecutive_gateway_failure(envoy_config_cluster_v3_OutlierDetection *msg, struct google_protobuf_UInt32Value* value) {
+  _upb_sethas(msg, 10);
   *UPB_PTR_AT(msg, UPB_SIZE(40, 80), struct google_protobuf_UInt32Value*) = value;
 }
 UPB_INLINE struct google_protobuf_UInt32Value* envoy_config_cluster_v3_OutlierDetection_mutable_consecutive_gateway_failure(envoy_config_cluster_v3_OutlierDetection *msg, upb_arena *arena) {
@@ -203,6 +220,7 @@ UPB_INLINE struct google_protobuf_UInt32Value* envoy_config_cluster_v3_OutlierDe
   return sub;
 }
 UPB_INLINE void envoy_config_cluster_v3_OutlierDetection_set_enforcing_consecutive_gateway_failure(envoy_config_cluster_v3_OutlierDetection *msg, struct google_protobuf_UInt32Value* value) {
+  _upb_sethas(msg, 11);
   *UPB_PTR_AT(msg, UPB_SIZE(44, 88), struct google_protobuf_UInt32Value*) = value;
 }
 UPB_INLINE struct google_protobuf_UInt32Value* envoy_config_cluster_v3_OutlierDetection_mutable_enforcing_consecutive_gateway_failure(envoy_config_cluster_v3_OutlierDetection *msg, upb_arena *arena) {
@@ -215,9 +233,10 @@ UPB_INLINE struct google_protobuf_UInt32Value* envoy_config_cluster_v3_OutlierDe
   return sub;
 }
 UPB_INLINE void envoy_config_cluster_v3_OutlierDetection_set_split_external_local_origin_errors(envoy_config_cluster_v3_OutlierDetection *msg, bool value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(0, 0), bool) = value;
+  *UPB_PTR_AT(msg, UPB_SIZE(3, 3), bool) = value;
 }
 UPB_INLINE void envoy_config_cluster_v3_OutlierDetection_set_consecutive_local_origin_failure(envoy_config_cluster_v3_OutlierDetection *msg, struct google_protobuf_UInt32Value* value) {
+  _upb_sethas(msg, 12);
   *UPB_PTR_AT(msg, UPB_SIZE(48, 96), struct google_protobuf_UInt32Value*) = value;
 }
 UPB_INLINE struct google_protobuf_UInt32Value* envoy_config_cluster_v3_OutlierDetection_mutable_consecutive_local_origin_failure(envoy_config_cluster_v3_OutlierDetection *msg, upb_arena *arena) {
@@ -230,6 +249,7 @@ UPB_INLINE struct google_protobuf_UInt32Value* envoy_config_cluster_v3_OutlierDe
   return sub;
 }
 UPB_INLINE void envoy_config_cluster_v3_OutlierDetection_set_enforcing_consecutive_local_origin_failure(envoy_config_cluster_v3_OutlierDetection *msg, struct google_protobuf_UInt32Value* value) {
+  _upb_sethas(msg, 13);
   *UPB_PTR_AT(msg, UPB_SIZE(52, 104), struct google_protobuf_UInt32Value*) = value;
 }
 UPB_INLINE struct google_protobuf_UInt32Value* envoy_config_cluster_v3_OutlierDetection_mutable_enforcing_consecutive_local_origin_failure(envoy_config_cluster_v3_OutlierDetection *msg, upb_arena *arena) {
@@ -242,6 +262,7 @@ UPB_INLINE struct google_protobuf_UInt32Value* envoy_config_cluster_v3_OutlierDe
   return sub;
 }
 UPB_INLINE void envoy_config_cluster_v3_OutlierDetection_set_enforcing_local_origin_success_rate(envoy_config_cluster_v3_OutlierDetection *msg, struct google_protobuf_UInt32Value* value) {
+  _upb_sethas(msg, 14);
   *UPB_PTR_AT(msg, UPB_SIZE(56, 112), struct google_protobuf_UInt32Value*) = value;
 }
 UPB_INLINE struct google_protobuf_UInt32Value* envoy_config_cluster_v3_OutlierDetection_mutable_enforcing_local_origin_success_rate(envoy_config_cluster_v3_OutlierDetection *msg, upb_arena *arena) {
@@ -254,6 +275,7 @@ UPB_INLINE struct google_protobuf_UInt32Value* envoy_config_cluster_v3_OutlierDe
   return sub;
 }
 UPB_INLINE void envoy_config_cluster_v3_OutlierDetection_set_failure_percentage_threshold(envoy_config_cluster_v3_OutlierDetection *msg, struct google_protobuf_UInt32Value* value) {
+  _upb_sethas(msg, 15);
   *UPB_PTR_AT(msg, UPB_SIZE(60, 120), struct google_protobuf_UInt32Value*) = value;
 }
 UPB_INLINE struct google_protobuf_UInt32Value* envoy_config_cluster_v3_OutlierDetection_mutable_failure_percentage_threshold(envoy_config_cluster_v3_OutlierDetection *msg, upb_arena *arena) {
@@ -266,6 +288,7 @@ UPB_INLINE struct google_protobuf_UInt32Value* envoy_config_cluster_v3_OutlierDe
   return sub;
 }
 UPB_INLINE void envoy_config_cluster_v3_OutlierDetection_set_enforcing_failure_percentage(envoy_config_cluster_v3_OutlierDetection *msg, struct google_protobuf_UInt32Value* value) {
+  _upb_sethas(msg, 16);
   *UPB_PTR_AT(msg, UPB_SIZE(64, 128), struct google_protobuf_UInt32Value*) = value;
 }
 UPB_INLINE struct google_protobuf_UInt32Value* envoy_config_cluster_v3_OutlierDetection_mutable_enforcing_failure_percentage(envoy_config_cluster_v3_OutlierDetection *msg, upb_arena *arena) {
@@ -278,6 +301,7 @@ UPB_INLINE struct google_protobuf_UInt32Value* envoy_config_cluster_v3_OutlierDe
   return sub;
 }
 UPB_INLINE void envoy_config_cluster_v3_OutlierDetection_set_enforcing_failure_percentage_local_origin(envoy_config_cluster_v3_OutlierDetection *msg, struct google_protobuf_UInt32Value* value) {
+  _upb_sethas(msg, 17);
   *UPB_PTR_AT(msg, UPB_SIZE(68, 136), struct google_protobuf_UInt32Value*) = value;
 }
 UPB_INLINE struct google_protobuf_UInt32Value* envoy_config_cluster_v3_OutlierDetection_mutable_enforcing_failure_percentage_local_origin(envoy_config_cluster_v3_OutlierDetection *msg, upb_arena *arena) {
@@ -290,6 +314,7 @@ UPB_INLINE struct google_protobuf_UInt32Value* envoy_config_cluster_v3_OutlierDe
   return sub;
 }
 UPB_INLINE void envoy_config_cluster_v3_OutlierDetection_set_failure_percentage_minimum_hosts(envoy_config_cluster_v3_OutlierDetection *msg, struct google_protobuf_UInt32Value* value) {
+  _upb_sethas(msg, 18);
   *UPB_PTR_AT(msg, UPB_SIZE(72, 144), struct google_protobuf_UInt32Value*) = value;
 }
 UPB_INLINE struct google_protobuf_UInt32Value* envoy_config_cluster_v3_OutlierDetection_mutable_failure_percentage_minimum_hosts(envoy_config_cluster_v3_OutlierDetection *msg, upb_arena *arena) {
@@ -302,6 +327,7 @@ UPB_INLINE struct google_protobuf_UInt32Value* envoy_config_cluster_v3_OutlierDe
   return sub;
 }
 UPB_INLINE void envoy_config_cluster_v3_OutlierDetection_set_failure_percentage_request_volume(envoy_config_cluster_v3_OutlierDetection *msg, struct google_protobuf_UInt32Value* value) {
+  _upb_sethas(msg, 19);
   *UPB_PTR_AT(msg, UPB_SIZE(76, 152), struct google_protobuf_UInt32Value*) = value;
 }
 UPB_INLINE struct google_protobuf_UInt32Value* envoy_config_cluster_v3_OutlierDetection_mutable_failure_percentage_request_volume(envoy_config_cluster_v3_OutlierDetection *msg, upb_arena *arena) {
index d381efa..048fc05 100644 (file)
@@ -25,7 +25,7 @@ static const upb_msglayout_field envoy_config_core_v3_Pipe__fields[2] = {
 const upb_msglayout envoy_config_core_v3_Pipe_msginit = {
   NULL,
   &envoy_config_core_v3_Pipe__fields[0],
-  UPB_SIZE(16, 32), 2, false,
+  UPB_SIZE(16, 32), 2, false, 255,
 };
 
 static const upb_msglayout_field envoy_config_core_v3_EnvoyInternalAddress__fields[1] = {
@@ -35,38 +35,38 @@ static const upb_msglayout_field envoy_config_core_v3_EnvoyInternalAddress__fiel
 const upb_msglayout envoy_config_core_v3_EnvoyInternalAddress_msginit = {
   NULL,
   &envoy_config_core_v3_EnvoyInternalAddress__fields[0],
-  UPB_SIZE(16, 32), 1, false,
+  UPB_SIZE(16, 32), 1, false, 255,
 };
 
 static const upb_msglayout_field envoy_config_core_v3_SocketAddress__fields[6] = {
   {1, UPB_SIZE(0, 0), 0, 0, 14, 1},
-  {2, UPB_SIZE(12, 16), 0, 0, 9, 1},
-  {3, UPB_SIZE(28, 48), UPB_SIZE(-37, -65), 0, 13, 1},
-  {4, UPB_SIZE(28, 48), UPB_SIZE(-37, -65), 0, 9, 1},
-  {5, UPB_SIZE(20, 32), 0, 0, 9, 1},
-  {6, UPB_SIZE(8, 8), 0, 0, 8, 1},
+  {2, UPB_SIZE(8, 8), 0, 0, 9, 1},
+  {3, UPB_SIZE(24, 40), UPB_SIZE(-33, -57), 0, 13, 1},
+  {4, UPB_SIZE(24, 40), UPB_SIZE(-33, -57), 0, 9, 1},
+  {5, UPB_SIZE(16, 24), 0, 0, 9, 1},
+  {6, UPB_SIZE(4, 4), 0, 0, 8, 1},
 };
 
 const upb_msglayout envoy_config_core_v3_SocketAddress_msginit = {
   NULL,
   &envoy_config_core_v3_SocketAddress__fields[0],
-  UPB_SIZE(40, 80), 6, false,
+  UPB_SIZE(40, 64), 6, false, 255,
 };
 
-static const upb_msglayout *const envoy_config_core_v3_TcpKeepalive_submsgs[3] = {
+static const upb_msglayout *const envoy_config_core_v3_TcpKeepalive_submsgs[1] = {
   &google_protobuf_UInt32Value_msginit,
 };
 
 static const upb_msglayout_field envoy_config_core_v3_TcpKeepalive__fields[3] = {
-  {1, UPB_SIZE(0, 0), 0, 0, 11, 1},
-  {2, UPB_SIZE(4, 8), 0, 0, 11, 1},
-  {3, UPB_SIZE(8, 16), 0, 0, 11, 1},
+  {1, UPB_SIZE(4, 8), 1, 0, 11, 1},
+  {2, UPB_SIZE(8, 16), 2, 0, 11, 1},
+  {3, UPB_SIZE(12, 24), 3, 0, 11, 1},
 };
 
 const upb_msglayout envoy_config_core_v3_TcpKeepalive_msginit = {
   &envoy_config_core_v3_TcpKeepalive_submsgs[0],
   &envoy_config_core_v3_TcpKeepalive__fields[0],
-  UPB_SIZE(12, 24), 3, false,
+  UPB_SIZE(16, 32), 3, false, 255,
 };
 
 static const upb_msglayout *const envoy_config_core_v3_BindConfig_submsgs[3] = {
@@ -76,15 +76,15 @@ static const upb_msglayout *const envoy_config_core_v3_BindConfig_submsgs[3] = {
 };
 
 static const upb_msglayout_field envoy_config_core_v3_BindConfig__fields[3] = {
-  {1, UPB_SIZE(0, 0), 0, 0, 11, 1},
-  {2, UPB_SIZE(4, 8), 0, 2, 11, 1},
-  {3, UPB_SIZE(8, 16), 0, 1, 11, 3},
+  {1, UPB_SIZE(4, 8), 1, 0, 11, 1},
+  {2, UPB_SIZE(8, 16), 2, 2, 11, 1},
+  {3, UPB_SIZE(12, 24), 0, 1, 11, 3},
 };
 
 const upb_msglayout envoy_config_core_v3_BindConfig_msginit = {
   &envoy_config_core_v3_BindConfig_submsgs[0],
   &envoy_config_core_v3_BindConfig__fields[0],
-  UPB_SIZE(12, 24), 3, false,
+  UPB_SIZE(16, 32), 3, false, 255,
 };
 
 static const upb_msglayout *const envoy_config_core_v3_Address_submsgs[3] = {
@@ -102,7 +102,7 @@ static const upb_msglayout_field envoy_config_core_v3_Address__fields[3] = {
 const upb_msglayout envoy_config_core_v3_Address_msginit = {
   &envoy_config_core_v3_Address_submsgs[0],
   &envoy_config_core_v3_Address__fields[0],
-  UPB_SIZE(8, 16), 3, false,
+  UPB_SIZE(8, 16), 3, false, 255,
 };
 
 static const upb_msglayout *const envoy_config_core_v3_CidrRange_submsgs[1] = {
@@ -110,14 +110,14 @@ static const upb_msglayout *const envoy_config_core_v3_CidrRange_submsgs[1] = {
 };
 
 static const upb_msglayout_field envoy_config_core_v3_CidrRange__fields[2] = {
-  {1, UPB_SIZE(0, 0), 0, 0, 9, 1},
-  {2, UPB_SIZE(8, 16), 0, 0, 11, 1},
+  {1, UPB_SIZE(4, 8), 0, 0, 9, 1},
+  {2, UPB_SIZE(12, 24), 1, 0, 11, 1},
 };
 
 const upb_msglayout envoy_config_core_v3_CidrRange_msginit = {
   &envoy_config_core_v3_CidrRange_submsgs[0],
   &envoy_config_core_v3_CidrRange__fields[0],
-  UPB_SIZE(16, 32), 2, false,
+  UPB_SIZE(16, 32), 2, false, 255,
 };
 
 #include "upb/port_undef.inc"
index e4ccd72..c8fdbee 100644 (file)
@@ -11,6 +11,7 @@
 
 #include "upb/msg.h"
 #include "upb/decode.h"
+#include "upb/decode_fast.h"
 #include "upb/encode.h"
 
 #include "upb/port_def.inc"
@@ -63,6 +64,12 @@ UPB_INLINE envoy_config_core_v3_Pipe *envoy_config_core_v3_Pipe_parse(const char
   envoy_config_core_v3_Pipe *ret = envoy_config_core_v3_Pipe_new(arena);
   return (ret && upb_decode(buf, size, ret, &envoy_config_core_v3_Pipe_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE envoy_config_core_v3_Pipe *envoy_config_core_v3_Pipe_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  envoy_config_core_v3_Pipe *ret = envoy_config_core_v3_Pipe_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &envoy_config_core_v3_Pipe_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *envoy_config_core_v3_Pipe_serialize(const envoy_config_core_v3_Pipe *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &envoy_config_core_v3_Pipe_msginit, arena, len);
 }
@@ -87,6 +94,12 @@ UPB_INLINE envoy_config_core_v3_EnvoyInternalAddress *envoy_config_core_v3_Envoy
   envoy_config_core_v3_EnvoyInternalAddress *ret = envoy_config_core_v3_EnvoyInternalAddress_new(arena);
   return (ret && upb_decode(buf, size, ret, &envoy_config_core_v3_EnvoyInternalAddress_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE envoy_config_core_v3_EnvoyInternalAddress *envoy_config_core_v3_EnvoyInternalAddress_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  envoy_config_core_v3_EnvoyInternalAddress *ret = envoy_config_core_v3_EnvoyInternalAddress_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &envoy_config_core_v3_EnvoyInternalAddress_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *envoy_config_core_v3_EnvoyInternalAddress_serialize(const envoy_config_core_v3_EnvoyInternalAddress *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &envoy_config_core_v3_EnvoyInternalAddress_msginit, arena, len);
 }
@@ -114,6 +127,12 @@ UPB_INLINE envoy_config_core_v3_SocketAddress *envoy_config_core_v3_SocketAddres
   envoy_config_core_v3_SocketAddress *ret = envoy_config_core_v3_SocketAddress_new(arena);
   return (ret && upb_decode(buf, size, ret, &envoy_config_core_v3_SocketAddress_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE envoy_config_core_v3_SocketAddress *envoy_config_core_v3_SocketAddress_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  envoy_config_core_v3_SocketAddress *ret = envoy_config_core_v3_SocketAddress_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &envoy_config_core_v3_SocketAddress_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *envoy_config_core_v3_SocketAddress_serialize(const envoy_config_core_v3_SocketAddress *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &envoy_config_core_v3_SocketAddress_msginit, arena, len);
 }
@@ -123,34 +142,34 @@ typedef enum {
   envoy_config_core_v3_SocketAddress_port_specifier_named_port = 4,
   envoy_config_core_v3_SocketAddress_port_specifier_NOT_SET = 0
 } envoy_config_core_v3_SocketAddress_port_specifier_oneofcases;
-UPB_INLINE envoy_config_core_v3_SocketAddress_port_specifier_oneofcases envoy_config_core_v3_SocketAddress_port_specifier_case(const envoy_config_core_v3_SocketAddress* msg) { return (envoy_config_core_v3_SocketAddress_port_specifier_oneofcases)*UPB_PTR_AT(msg, UPB_SIZE(36, 64), int32_t); }
+UPB_INLINE envoy_config_core_v3_SocketAddress_port_specifier_oneofcases envoy_config_core_v3_SocketAddress_port_specifier_case(const envoy_config_core_v3_SocketAddress* msg) { return (envoy_config_core_v3_SocketAddress_port_specifier_oneofcases)*UPB_PTR_AT(msg, UPB_SIZE(32, 56), int32_t); }
 
 UPB_INLINE int32_t envoy_config_core_v3_SocketAddress_protocol(const envoy_config_core_v3_SocketAddress *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(0, 0), int32_t); }
-UPB_INLINE upb_strview envoy_config_core_v3_SocketAddress_address(const envoy_config_core_v3_SocketAddress *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(12, 16), upb_strview); }
-UPB_INLINE bool envoy_config_core_v3_SocketAddress_has_port_value(const envoy_config_core_v3_SocketAddress *msg) { return _upb_getoneofcase(msg, UPB_SIZE(36, 64)) == 3; }
-UPB_INLINE uint32_t envoy_config_core_v3_SocketAddress_port_value(const envoy_config_core_v3_SocketAddress *msg) { return UPB_READ_ONEOF(msg, uint32_t, UPB_SIZE(28, 48), UPB_SIZE(36, 64), 3, 0); }
-UPB_INLINE bool envoy_config_core_v3_SocketAddress_has_named_port(const envoy_config_core_v3_SocketAddress *msg) { return _upb_getoneofcase(msg, UPB_SIZE(36, 64)) == 4; }
-UPB_INLINE upb_strview envoy_config_core_v3_SocketAddress_named_port(const envoy_config_core_v3_SocketAddress *msg) { return UPB_READ_ONEOF(msg, upb_strview, UPB_SIZE(28, 48), UPB_SIZE(36, 64), 4, upb_strview_make("", strlen(""))); }
-UPB_INLINE upb_strview envoy_config_core_v3_SocketAddress_resolver_name(const envoy_config_core_v3_SocketAddress *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(20, 32), upb_strview); }
-UPB_INLINE bool envoy_config_core_v3_SocketAddress_ipv4_compat(const envoy_config_core_v3_SocketAddress *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(8, 8), bool); }
+UPB_INLINE upb_strview envoy_config_core_v3_SocketAddress_address(const envoy_config_core_v3_SocketAddress *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(8, 8), upb_strview); }
+UPB_INLINE bool envoy_config_core_v3_SocketAddress_has_port_value(const envoy_config_core_v3_SocketAddress *msg) { return _upb_getoneofcase(msg, UPB_SIZE(32, 56)) == 3; }
+UPB_INLINE uint32_t envoy_config_core_v3_SocketAddress_port_value(const envoy_config_core_v3_SocketAddress *msg) { return UPB_READ_ONEOF(msg, uint32_t, UPB_SIZE(24, 40), UPB_SIZE(32, 56), 3, 0); }
+UPB_INLINE bool envoy_config_core_v3_SocketAddress_has_named_port(const envoy_config_core_v3_SocketAddress *msg) { return _upb_getoneofcase(msg, UPB_SIZE(32, 56)) == 4; }
+UPB_INLINE upb_strview envoy_config_core_v3_SocketAddress_named_port(const envoy_config_core_v3_SocketAddress *msg) { return UPB_READ_ONEOF(msg, upb_strview, UPB_SIZE(24, 40), UPB_SIZE(32, 56), 4, upb_strview_make("", strlen(""))); }
+UPB_INLINE upb_strview envoy_config_core_v3_SocketAddress_resolver_name(const envoy_config_core_v3_SocketAddress *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(16, 24), upb_strview); }
+UPB_INLINE bool envoy_config_core_v3_SocketAddress_ipv4_compat(const envoy_config_core_v3_SocketAddress *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(4, 4), bool); }
 
 UPB_INLINE void envoy_config_core_v3_SocketAddress_set_protocol(envoy_config_core_v3_SocketAddress *msg, int32_t value) {
   *UPB_PTR_AT(msg, UPB_SIZE(0, 0), int32_t) = value;
 }
 UPB_INLINE void envoy_config_core_v3_SocketAddress_set_address(envoy_config_core_v3_SocketAddress *msg, upb_strview value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(12, 16), upb_strview) = value;
+  *UPB_PTR_AT(msg, UPB_SIZE(8, 8), upb_strview) = value;
 }
 UPB_INLINE void envoy_config_core_v3_SocketAddress_set_port_value(envoy_config_core_v3_SocketAddress *msg, uint32_t value) {
-  UPB_WRITE_ONEOF(msg, uint32_t, UPB_SIZE(28, 48), value, UPB_SIZE(36, 64), 3);
+  UPB_WRITE_ONEOF(msg, uint32_t, UPB_SIZE(24, 40), value, UPB_SIZE(32, 56), 3);
 }
 UPB_INLINE void envoy_config_core_v3_SocketAddress_set_named_port(envoy_config_core_v3_SocketAddress *msg, upb_strview value) {
-  UPB_WRITE_ONEOF(msg, upb_strview, UPB_SIZE(28, 48), value, UPB_SIZE(36, 64), 4);
+  UPB_WRITE_ONEOF(msg, upb_strview, UPB_SIZE(24, 40), value, UPB_SIZE(32, 56), 4);
 }
 UPB_INLINE void envoy_config_core_v3_SocketAddress_set_resolver_name(envoy_config_core_v3_SocketAddress *msg, upb_strview value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(20, 32), upb_strview) = value;
+  *UPB_PTR_AT(msg, UPB_SIZE(16, 24), upb_strview) = value;
 }
 UPB_INLINE void envoy_config_core_v3_SocketAddress_set_ipv4_compat(envoy_config_core_v3_SocketAddress *msg, bool value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(8, 8), bool) = value;
+  *UPB_PTR_AT(msg, UPB_SIZE(4, 4), bool) = value;
 }
 
 /* envoy.config.core.v3.TcpKeepalive */
@@ -163,19 +182,26 @@ UPB_INLINE envoy_config_core_v3_TcpKeepalive *envoy_config_core_v3_TcpKeepalive_
   envoy_config_core_v3_TcpKeepalive *ret = envoy_config_core_v3_TcpKeepalive_new(arena);
   return (ret && upb_decode(buf, size, ret, &envoy_config_core_v3_TcpKeepalive_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE envoy_config_core_v3_TcpKeepalive *envoy_config_core_v3_TcpKeepalive_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  envoy_config_core_v3_TcpKeepalive *ret = envoy_config_core_v3_TcpKeepalive_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &envoy_config_core_v3_TcpKeepalive_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *envoy_config_core_v3_TcpKeepalive_serialize(const envoy_config_core_v3_TcpKeepalive *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &envoy_config_core_v3_TcpKeepalive_msginit, arena, len);
 }
 
-UPB_INLINE bool envoy_config_core_v3_TcpKeepalive_has_keepalive_probes(const envoy_config_core_v3_TcpKeepalive *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(0, 0)); }
-UPB_INLINE const struct google_protobuf_UInt32Value* envoy_config_core_v3_TcpKeepalive_keepalive_probes(const envoy_config_core_v3_TcpKeepalive *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(0, 0), const struct google_protobuf_UInt32Value*); }
-UPB_INLINE bool envoy_config_core_v3_TcpKeepalive_has_keepalive_time(const envoy_config_core_v3_TcpKeepalive *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(4, 8)); }
-UPB_INLINE const struct google_protobuf_UInt32Value* envoy_config_core_v3_TcpKeepalive_keepalive_time(const envoy_config_core_v3_TcpKeepalive *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(4, 8), const struct google_protobuf_UInt32Value*); }
-UPB_INLINE bool envoy_config_core_v3_TcpKeepalive_has_keepalive_interval(const envoy_config_core_v3_TcpKeepalive *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(8, 16)); }
-UPB_INLINE const struct google_protobuf_UInt32Value* envoy_config_core_v3_TcpKeepalive_keepalive_interval(const envoy_config_core_v3_TcpKeepalive *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(8, 16), const struct google_protobuf_UInt32Value*); }
+UPB_INLINE bool envoy_config_core_v3_TcpKeepalive_has_keepalive_probes(const envoy_config_core_v3_TcpKeepalive *msg) { return _upb_hasbit(msg, 1); }
+UPB_INLINE const struct google_protobuf_UInt32Value* envoy_config_core_v3_TcpKeepalive_keepalive_probes(const envoy_config_core_v3_TcpKeepalive *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(4, 8), const struct google_protobuf_UInt32Value*); }
+UPB_INLINE bool envoy_config_core_v3_TcpKeepalive_has_keepalive_time(const envoy_config_core_v3_TcpKeepalive *msg) { return _upb_hasbit(msg, 2); }
+UPB_INLINE const struct google_protobuf_UInt32Value* envoy_config_core_v3_TcpKeepalive_keepalive_time(const envoy_config_core_v3_TcpKeepalive *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(8, 16), const struct google_protobuf_UInt32Value*); }
+UPB_INLINE bool envoy_config_core_v3_TcpKeepalive_has_keepalive_interval(const envoy_config_core_v3_TcpKeepalive *msg) { return _upb_hasbit(msg, 3); }
+UPB_INLINE const struct google_protobuf_UInt32Value* envoy_config_core_v3_TcpKeepalive_keepalive_interval(const envoy_config_core_v3_TcpKeepalive *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(12, 24), const struct google_protobuf_UInt32Value*); }
 
 UPB_INLINE void envoy_config_core_v3_TcpKeepalive_set_keepalive_probes(envoy_config_core_v3_TcpKeepalive *msg, struct google_protobuf_UInt32Value* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(0, 0), struct google_protobuf_UInt32Value*) = value;
+  _upb_sethas(msg, 1);
+  *UPB_PTR_AT(msg, UPB_SIZE(4, 8), struct google_protobuf_UInt32Value*) = value;
 }
 UPB_INLINE struct google_protobuf_UInt32Value* envoy_config_core_v3_TcpKeepalive_mutable_keepalive_probes(envoy_config_core_v3_TcpKeepalive *msg, upb_arena *arena) {
   struct google_protobuf_UInt32Value* sub = (struct google_protobuf_UInt32Value*)envoy_config_core_v3_TcpKeepalive_keepalive_probes(msg);
@@ -187,7 +213,8 @@ UPB_INLINE struct google_protobuf_UInt32Value* envoy_config_core_v3_TcpKeepalive
   return sub;
 }
 UPB_INLINE void envoy_config_core_v3_TcpKeepalive_set_keepalive_time(envoy_config_core_v3_TcpKeepalive *msg, struct google_protobuf_UInt32Value* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(4, 8), struct google_protobuf_UInt32Value*) = value;
+  _upb_sethas(msg, 2);
+  *UPB_PTR_AT(msg, UPB_SIZE(8, 16), struct google_protobuf_UInt32Value*) = value;
 }
 UPB_INLINE struct google_protobuf_UInt32Value* envoy_config_core_v3_TcpKeepalive_mutable_keepalive_time(envoy_config_core_v3_TcpKeepalive *msg, upb_arena *arena) {
   struct google_protobuf_UInt32Value* sub = (struct google_protobuf_UInt32Value*)envoy_config_core_v3_TcpKeepalive_keepalive_time(msg);
@@ -199,7 +226,8 @@ UPB_INLINE struct google_protobuf_UInt32Value* envoy_config_core_v3_TcpKeepalive
   return sub;
 }
 UPB_INLINE void envoy_config_core_v3_TcpKeepalive_set_keepalive_interval(envoy_config_core_v3_TcpKeepalive *msg, struct google_protobuf_UInt32Value* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(8, 16), struct google_protobuf_UInt32Value*) = value;
+  _upb_sethas(msg, 3);
+  *UPB_PTR_AT(msg, UPB_SIZE(12, 24), struct google_protobuf_UInt32Value*) = value;
 }
 UPB_INLINE struct google_protobuf_UInt32Value* envoy_config_core_v3_TcpKeepalive_mutable_keepalive_interval(envoy_config_core_v3_TcpKeepalive *msg, upb_arena *arena) {
   struct google_protobuf_UInt32Value* sub = (struct google_protobuf_UInt32Value*)envoy_config_core_v3_TcpKeepalive_keepalive_interval(msg);
@@ -221,19 +249,26 @@ UPB_INLINE envoy_config_core_v3_BindConfig *envoy_config_core_v3_BindConfig_pars
   envoy_config_core_v3_BindConfig *ret = envoy_config_core_v3_BindConfig_new(arena);
   return (ret && upb_decode(buf, size, ret, &envoy_config_core_v3_BindConfig_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE envoy_config_core_v3_BindConfig *envoy_config_core_v3_BindConfig_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  envoy_config_core_v3_BindConfig *ret = envoy_config_core_v3_BindConfig_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &envoy_config_core_v3_BindConfig_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *envoy_config_core_v3_BindConfig_serialize(const envoy_config_core_v3_BindConfig *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &envoy_config_core_v3_BindConfig_msginit, arena, len);
 }
 
-UPB_INLINE bool envoy_config_core_v3_BindConfig_has_source_address(const envoy_config_core_v3_BindConfig *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(0, 0)); }
-UPB_INLINE const envoy_config_core_v3_SocketAddress* envoy_config_core_v3_BindConfig_source_address(const envoy_config_core_v3_BindConfig *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(0, 0), const envoy_config_core_v3_SocketAddress*); }
-UPB_INLINE bool envoy_config_core_v3_BindConfig_has_freebind(const envoy_config_core_v3_BindConfig *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(4, 8)); }
-UPB_INLINE const struct google_protobuf_BoolValue* envoy_config_core_v3_BindConfig_freebind(const envoy_config_core_v3_BindConfig *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(4, 8), const struct google_protobuf_BoolValue*); }
-UPB_INLINE bool envoy_config_core_v3_BindConfig_has_socket_options(const envoy_config_core_v3_BindConfig *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(8, 16)); }
-UPB_INLINE const struct envoy_config_core_v3_SocketOption* const* envoy_config_core_v3_BindConfig_socket_options(const envoy_config_core_v3_BindConfig *msg, size_t *len) { return (const struct envoy_config_core_v3_SocketOption* const*)_upb_array_accessor(msg, UPB_SIZE(8, 16), len); }
+UPB_INLINE bool envoy_config_core_v3_BindConfig_has_source_address(const envoy_config_core_v3_BindConfig *msg) { return _upb_hasbit(msg, 1); }
+UPB_INLINE const envoy_config_core_v3_SocketAddress* envoy_config_core_v3_BindConfig_source_address(const envoy_config_core_v3_BindConfig *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(4, 8), const envoy_config_core_v3_SocketAddress*); }
+UPB_INLINE bool envoy_config_core_v3_BindConfig_has_freebind(const envoy_config_core_v3_BindConfig *msg) { return _upb_hasbit(msg, 2); }
+UPB_INLINE const struct google_protobuf_BoolValue* envoy_config_core_v3_BindConfig_freebind(const envoy_config_core_v3_BindConfig *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(8, 16), const struct google_protobuf_BoolValue*); }
+UPB_INLINE bool envoy_config_core_v3_BindConfig_has_socket_options(const envoy_config_core_v3_BindConfig *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(12, 24)); }
+UPB_INLINE const struct envoy_config_core_v3_SocketOption* const* envoy_config_core_v3_BindConfig_socket_options(const envoy_config_core_v3_BindConfig *msg, size_t *len) { return (const struct envoy_config_core_v3_SocketOption* const*)_upb_array_accessor(msg, UPB_SIZE(12, 24), len); }
 
 UPB_INLINE void envoy_config_core_v3_BindConfig_set_source_address(envoy_config_core_v3_BindConfig *msg, envoy_config_core_v3_SocketAddress* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(0, 0), envoy_config_core_v3_SocketAddress*) = value;
+  _upb_sethas(msg, 1);
+  *UPB_PTR_AT(msg, UPB_SIZE(4, 8), envoy_config_core_v3_SocketAddress*) = value;
 }
 UPB_INLINE struct envoy_config_core_v3_SocketAddress* envoy_config_core_v3_BindConfig_mutable_source_address(envoy_config_core_v3_BindConfig *msg, upb_arena *arena) {
   struct envoy_config_core_v3_SocketAddress* sub = (struct envoy_config_core_v3_SocketAddress*)envoy_config_core_v3_BindConfig_source_address(msg);
@@ -245,7 +280,8 @@ UPB_INLINE struct envoy_config_core_v3_SocketAddress* envoy_config_core_v3_BindC
   return sub;
 }
 UPB_INLINE void envoy_config_core_v3_BindConfig_set_freebind(envoy_config_core_v3_BindConfig *msg, struct google_protobuf_BoolValue* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(4, 8), struct google_protobuf_BoolValue*) = value;
+  _upb_sethas(msg, 2);
+  *UPB_PTR_AT(msg, UPB_SIZE(8, 16), struct google_protobuf_BoolValue*) = value;
 }
 UPB_INLINE struct google_protobuf_BoolValue* envoy_config_core_v3_BindConfig_mutable_freebind(envoy_config_core_v3_BindConfig *msg, upb_arena *arena) {
   struct google_protobuf_BoolValue* sub = (struct google_protobuf_BoolValue*)envoy_config_core_v3_BindConfig_freebind(msg);
@@ -257,15 +293,15 @@ UPB_INLINE struct google_protobuf_BoolValue* envoy_config_core_v3_BindConfig_mut
   return sub;
 }
 UPB_INLINE struct envoy_config_core_v3_SocketOption** envoy_config_core_v3_BindConfig_mutable_socket_options(envoy_config_core_v3_BindConfig *msg, size_t *len) {
-  return (struct envoy_config_core_v3_SocketOption**)_upb_array_mutable_accessor(msg, UPB_SIZE(8, 16), len);
+  return (struct envoy_config_core_v3_SocketOption**)_upb_array_mutable_accessor(msg, UPB_SIZE(12, 24), len);
 }
 UPB_INLINE struct envoy_config_core_v3_SocketOption** envoy_config_core_v3_BindConfig_resize_socket_options(envoy_config_core_v3_BindConfig *msg, size_t len, upb_arena *arena) {
-  return (struct envoy_config_core_v3_SocketOption**)_upb_array_resize_accessor(msg, UPB_SIZE(8, 16), len, UPB_TYPE_MESSAGE, arena);
+  return (struct envoy_config_core_v3_SocketOption**)_upb_array_resize_accessor2(msg, UPB_SIZE(12, 24), len, UPB_SIZE(2, 3), arena);
 }
 UPB_INLINE struct envoy_config_core_v3_SocketOption* envoy_config_core_v3_BindConfig_add_socket_options(envoy_config_core_v3_BindConfig *msg, upb_arena *arena) {
   struct envoy_config_core_v3_SocketOption* sub = (struct envoy_config_core_v3_SocketOption*)_upb_msg_new(&envoy_config_core_v3_SocketOption_msginit, arena);
-  bool ok = _upb_array_append_accessor(
-      msg, UPB_SIZE(8, 16), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena);
+  bool ok = _upb_array_append_accessor2(
+      msg, UPB_SIZE(12, 24), UPB_SIZE(2, 3), &sub, arena);
   if (!ok) return NULL;
   return sub;
 }
@@ -280,6 +316,12 @@ UPB_INLINE envoy_config_core_v3_Address *envoy_config_core_v3_Address_parse(cons
   envoy_config_core_v3_Address *ret = envoy_config_core_v3_Address_new(arena);
   return (ret && upb_decode(buf, size, ret, &envoy_config_core_v3_Address_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE envoy_config_core_v3_Address *envoy_config_core_v3_Address_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  envoy_config_core_v3_Address *ret = envoy_config_core_v3_Address_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &envoy_config_core_v3_Address_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *envoy_config_core_v3_Address_serialize(const envoy_config_core_v3_Address *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &envoy_config_core_v3_Address_msginit, arena, len);
 }
@@ -346,19 +388,26 @@ UPB_INLINE envoy_config_core_v3_CidrRange *envoy_config_core_v3_CidrRange_parse(
   envoy_config_core_v3_CidrRange *ret = envoy_config_core_v3_CidrRange_new(arena);
   return (ret && upb_decode(buf, size, ret, &envoy_config_core_v3_CidrRange_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE envoy_config_core_v3_CidrRange *envoy_config_core_v3_CidrRange_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  envoy_config_core_v3_CidrRange *ret = envoy_config_core_v3_CidrRange_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &envoy_config_core_v3_CidrRange_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *envoy_config_core_v3_CidrRange_serialize(const envoy_config_core_v3_CidrRange *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &envoy_config_core_v3_CidrRange_msginit, arena, len);
 }
 
-UPB_INLINE upb_strview envoy_config_core_v3_CidrRange_address_prefix(const envoy_config_core_v3_CidrRange *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(0, 0), upb_strview); }
-UPB_INLINE bool envoy_config_core_v3_CidrRange_has_prefix_len(const envoy_config_core_v3_CidrRange *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(8, 16)); }
-UPB_INLINE const struct google_protobuf_UInt32Value* envoy_config_core_v3_CidrRange_prefix_len(const envoy_config_core_v3_CidrRange *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(8, 16), const struct google_protobuf_UInt32Value*); }
+UPB_INLINE upb_strview envoy_config_core_v3_CidrRange_address_prefix(const envoy_config_core_v3_CidrRange *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(4, 8), upb_strview); }
+UPB_INLINE bool envoy_config_core_v3_CidrRange_has_prefix_len(const envoy_config_core_v3_CidrRange *msg) { return _upb_hasbit(msg, 1); }
+UPB_INLINE const struct google_protobuf_UInt32Value* envoy_config_core_v3_CidrRange_prefix_len(const envoy_config_core_v3_CidrRange *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(12, 24), const struct google_protobuf_UInt32Value*); }
 
 UPB_INLINE void envoy_config_core_v3_CidrRange_set_address_prefix(envoy_config_core_v3_CidrRange *msg, upb_strview value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(0, 0), upb_strview) = value;
+  *UPB_PTR_AT(msg, UPB_SIZE(4, 8), upb_strview) = value;
 }
 UPB_INLINE void envoy_config_core_v3_CidrRange_set_prefix_len(envoy_config_core_v3_CidrRange *msg, struct google_protobuf_UInt32Value* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(8, 16), struct google_protobuf_UInt32Value*) = value;
+  _upb_sethas(msg, 1);
+  *UPB_PTR_AT(msg, UPB_SIZE(12, 24), struct google_protobuf_UInt32Value*) = value;
 }
 UPB_INLINE struct google_protobuf_UInt32Value* envoy_config_core_v3_CidrRange_mutable_prefix_len(envoy_config_core_v3_CidrRange *msg, upb_arena *arena) {
   struct google_protobuf_UInt32Value* sub = (struct google_protobuf_UInt32Value*)envoy_config_core_v3_CidrRange_prefix_len(msg);
index f564f33..8e1174d 100644 (file)
 
 #include "upb/port_def.inc"
 
-static const upb_msglayout *const envoy_config_core_v3_BackoffStrategy_submsgs[2] = {
+static const upb_msglayout *const envoy_config_core_v3_BackoffStrategy_submsgs[1] = {
   &google_protobuf_Duration_msginit,
 };
 
 static const upb_msglayout_field envoy_config_core_v3_BackoffStrategy__fields[2] = {
-  {1, UPB_SIZE(0, 0), 0, 0, 11, 1},
-  {2, UPB_SIZE(4, 8), 0, 0, 11, 1},
+  {1, UPB_SIZE(4, 8), 1, 0, 11, 1},
+  {2, UPB_SIZE(8, 16), 2, 0, 11, 1},
 };
 
 const upb_msglayout envoy_config_core_v3_BackoffStrategy_msginit = {
   &envoy_config_core_v3_BackoffStrategy_submsgs[0],
   &envoy_config_core_v3_BackoffStrategy__fields[0],
-  UPB_SIZE(8, 16), 2, false,
+  UPB_SIZE(16, 24), 2, false, 255,
 };
 
 #include "upb/port_undef.inc"
index 0f843e2..3601c66 100644 (file)
@@ -11,6 +11,7 @@
 
 #include "upb/msg.h"
 #include "upb/decode.h"
+#include "upb/decode_fast.h"
 #include "upb/encode.h"
 
 #include "upb/port_def.inc"
@@ -36,17 +37,24 @@ UPB_INLINE envoy_config_core_v3_BackoffStrategy *envoy_config_core_v3_BackoffStr
   envoy_config_core_v3_BackoffStrategy *ret = envoy_config_core_v3_BackoffStrategy_new(arena);
   return (ret && upb_decode(buf, size, ret, &envoy_config_core_v3_BackoffStrategy_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE envoy_config_core_v3_BackoffStrategy *envoy_config_core_v3_BackoffStrategy_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  envoy_config_core_v3_BackoffStrategy *ret = envoy_config_core_v3_BackoffStrategy_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &envoy_config_core_v3_BackoffStrategy_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *envoy_config_core_v3_BackoffStrategy_serialize(const envoy_config_core_v3_BackoffStrategy *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &envoy_config_core_v3_BackoffStrategy_msginit, arena, len);
 }
 
-UPB_INLINE bool envoy_config_core_v3_BackoffStrategy_has_base_interval(const envoy_config_core_v3_BackoffStrategy *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(0, 0)); }
-UPB_INLINE const struct google_protobuf_Duration* envoy_config_core_v3_BackoffStrategy_base_interval(const envoy_config_core_v3_BackoffStrategy *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(0, 0), const struct google_protobuf_Duration*); }
-UPB_INLINE bool envoy_config_core_v3_BackoffStrategy_has_max_interval(const envoy_config_core_v3_BackoffStrategy *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(4, 8)); }
-UPB_INLINE const struct google_protobuf_Duration* envoy_config_core_v3_BackoffStrategy_max_interval(const envoy_config_core_v3_BackoffStrategy *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(4, 8), const struct google_protobuf_Duration*); }
+UPB_INLINE bool envoy_config_core_v3_BackoffStrategy_has_base_interval(const envoy_config_core_v3_BackoffStrategy *msg) { return _upb_hasbit(msg, 1); }
+UPB_INLINE const struct google_protobuf_Duration* envoy_config_core_v3_BackoffStrategy_base_interval(const envoy_config_core_v3_BackoffStrategy *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(4, 8), const struct google_protobuf_Duration*); }
+UPB_INLINE bool envoy_config_core_v3_BackoffStrategy_has_max_interval(const envoy_config_core_v3_BackoffStrategy *msg) { return _upb_hasbit(msg, 2); }
+UPB_INLINE const struct google_protobuf_Duration* envoy_config_core_v3_BackoffStrategy_max_interval(const envoy_config_core_v3_BackoffStrategy *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(8, 16), const struct google_protobuf_Duration*); }
 
 UPB_INLINE void envoy_config_core_v3_BackoffStrategy_set_base_interval(envoy_config_core_v3_BackoffStrategy *msg, struct google_protobuf_Duration* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(0, 0), struct google_protobuf_Duration*) = value;
+  _upb_sethas(msg, 1);
+  *UPB_PTR_AT(msg, UPB_SIZE(4, 8), struct google_protobuf_Duration*) = value;
 }
 UPB_INLINE struct google_protobuf_Duration* envoy_config_core_v3_BackoffStrategy_mutable_base_interval(envoy_config_core_v3_BackoffStrategy *msg, upb_arena *arena) {
   struct google_protobuf_Duration* sub = (struct google_protobuf_Duration*)envoy_config_core_v3_BackoffStrategy_base_interval(msg);
@@ -58,7 +66,8 @@ UPB_INLINE struct google_protobuf_Duration* envoy_config_core_v3_BackoffStrategy
   return sub;
 }
 UPB_INLINE void envoy_config_core_v3_BackoffStrategy_set_max_interval(envoy_config_core_v3_BackoffStrategy *msg, struct google_protobuf_Duration* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(4, 8), struct google_protobuf_Duration*) = value;
+  _upb_sethas(msg, 2);
+  *UPB_PTR_AT(msg, UPB_SIZE(8, 16), struct google_protobuf_Duration*) = value;
 }
 UPB_INLINE struct google_protobuf_Duration* envoy_config_core_v3_BackoffStrategy_mutable_max_interval(envoy_config_core_v3_BackoffStrategy *msg, upb_arena *arena) {
   struct google_protobuf_Duration* sub = (struct google_protobuf_Duration*)envoy_config_core_v3_BackoffStrategy_max_interval(msg);
index a651c67..355bbdc 100644 (file)
@@ -34,7 +34,7 @@ static const upb_msglayout_field envoy_config_core_v3_Locality__fields[3] = {
 const upb_msglayout envoy_config_core_v3_Locality_msginit = {
   NULL,
   &envoy_config_core_v3_Locality__fields[0],
-  UPB_SIZE(24, 48), 3, false,
+  UPB_SIZE(24, 48), 3, false, 255,
 };
 
 static const upb_msglayout *const envoy_config_core_v3_BuildVersion_submsgs[2] = {
@@ -43,14 +43,14 @@ static const upb_msglayout *const envoy_config_core_v3_BuildVersion_submsgs[2] =
 };
 
 static const upb_msglayout_field envoy_config_core_v3_BuildVersion__fields[2] = {
-  {1, UPB_SIZE(0, 0), 0, 0, 11, 1},
-  {2, UPB_SIZE(4, 8), 0, 1, 11, 1},
+  {1, UPB_SIZE(4, 8), 1, 0, 11, 1},
+  {2, UPB_SIZE(8, 16), 2, 1, 11, 1},
 };
 
 const upb_msglayout envoy_config_core_v3_BuildVersion_msginit = {
   &envoy_config_core_v3_BuildVersion_submsgs[0],
   &envoy_config_core_v3_BuildVersion__fields[0],
-  UPB_SIZE(8, 16), 2, false,
+  UPB_SIZE(16, 24), 2, false, 255,
 };
 
 static const upb_msglayout *const envoy_config_core_v3_Extension_submsgs[1] = {
@@ -61,14 +61,14 @@ static const upb_msglayout_field envoy_config_core_v3_Extension__fields[5] = {
   {1, UPB_SIZE(4, 8), 0, 0, 9, 1},
   {2, UPB_SIZE(12, 24), 0, 0, 9, 1},
   {3, UPB_SIZE(20, 40), 0, 0, 9, 1},
-  {4, UPB_SIZE(28, 56), 0, 0, 11, 1},
-  {5, UPB_SIZE(0, 0), 0, 0, 8, 1},
+  {4, UPB_SIZE(28, 56), 1, 0, 11, 1},
+  {5, UPB_SIZE(1, 1), 0, 0, 8, 1},
 };
 
 const upb_msglayout envoy_config_core_v3_Extension_msginit = {
   &envoy_config_core_v3_Extension_submsgs[0],
   &envoy_config_core_v3_Extension__fields[0],
-  UPB_SIZE(32, 64), 5, false,
+  UPB_SIZE(32, 64), 5, false, 255,
 };
 
 static const upb_msglayout *const envoy_config_core_v3_Node_submsgs[5] = {
@@ -80,22 +80,22 @@ static const upb_msglayout *const envoy_config_core_v3_Node_submsgs[5] = {
 };
 
 static const upb_msglayout_field envoy_config_core_v3_Node__fields[10] = {
-  {1, UPB_SIZE(0, 0), 0, 0, 9, 1},
-  {2, UPB_SIZE(8, 16), 0, 0, 9, 1},
-  {3, UPB_SIZE(24, 48), 0, 4, 11, 1},
-  {4, UPB_SIZE(28, 56), 0, 3, 11, 1},
-  {6, UPB_SIZE(16, 32), 0, 0, 9, 1},
-  {7, UPB_SIZE(44, 88), UPB_SIZE(-53, -105), 0, 9, 1},
-  {8, UPB_SIZE(44, 88), UPB_SIZE(-53, -105), 1, 11, 1},
-  {9, UPB_SIZE(32, 64), 0, 2, 11, 3},
-  {10, UPB_SIZE(36, 72), 0, 0, 9, 3},
-  {11, UPB_SIZE(40, 80), 0, 0, 11, 3},
+  {1, UPB_SIZE(4, 8), 0, 0, 9, 1},
+  {2, UPB_SIZE(12, 24), 0, 0, 9, 1},
+  {3, UPB_SIZE(28, 56), 1, 4, 11, 1},
+  {4, UPB_SIZE(32, 64), 2, 3, 11, 1},
+  {6, UPB_SIZE(20, 40), 0, 0, 9, 1},
+  {7, UPB_SIZE(48, 96), UPB_SIZE(-57, -113), 0, 9, 1},
+  {8, UPB_SIZE(48, 96), UPB_SIZE(-57, -113), 1, 11, 1},
+  {9, UPB_SIZE(36, 72), 0, 2, 11, 3},
+  {10, UPB_SIZE(40, 80), 0, 0, 9, 3},
+  {11, UPB_SIZE(44, 88), 0, 0, 11, 3},
 };
 
 const upb_msglayout envoy_config_core_v3_Node_msginit = {
   &envoy_config_core_v3_Node_submsgs[0],
   &envoy_config_core_v3_Node__fields[0],
-  UPB_SIZE(56, 112), 10, false,
+  UPB_SIZE(64, 128), 10, false, 255,
 };
 
 static const upb_msglayout *const envoy_config_core_v3_Metadata_submsgs[1] = {
@@ -109,7 +109,7 @@ static const upb_msglayout_field envoy_config_core_v3_Metadata__fields[1] = {
 const upb_msglayout envoy_config_core_v3_Metadata_msginit = {
   &envoy_config_core_v3_Metadata_submsgs[0],
   &envoy_config_core_v3_Metadata__fields[0],
-  UPB_SIZE(4, 8), 1, false,
+  UPB_SIZE(8, 8), 1, false, 255,
 };
 
 static const upb_msglayout *const envoy_config_core_v3_Metadata_FilterMetadataEntry_submsgs[1] = {
@@ -124,7 +124,7 @@ static const upb_msglayout_field envoy_config_core_v3_Metadata_FilterMetadataEnt
 const upb_msglayout envoy_config_core_v3_Metadata_FilterMetadataEntry_msginit = {
   &envoy_config_core_v3_Metadata_FilterMetadataEntry_submsgs[0],
   &envoy_config_core_v3_Metadata_FilterMetadataEntry__fields[0],
-  UPB_SIZE(16, 32), 2, false,
+  UPB_SIZE(16, 32), 2, false, 255,
 };
 
 static const upb_msglayout_field envoy_config_core_v3_RuntimeUInt32__fields[2] = {
@@ -135,7 +135,7 @@ static const upb_msglayout_field envoy_config_core_v3_RuntimeUInt32__fields[2] =
 const upb_msglayout envoy_config_core_v3_RuntimeUInt32_msginit = {
   NULL,
   &envoy_config_core_v3_RuntimeUInt32__fields[0],
-  UPB_SIZE(16, 32), 2, false,
+  UPB_SIZE(16, 32), 2, false, 255,
 };
 
 static const upb_msglayout_field envoy_config_core_v3_RuntimeDouble__fields[2] = {
@@ -146,7 +146,7 @@ static const upb_msglayout_field envoy_config_core_v3_RuntimeDouble__fields[2] =
 const upb_msglayout envoy_config_core_v3_RuntimeDouble_msginit = {
   NULL,
   &envoy_config_core_v3_RuntimeDouble__fields[0],
-  UPB_SIZE(16, 32), 2, false,
+  UPB_SIZE(16, 32), 2, false, 255,
 };
 
 static const upb_msglayout *const envoy_config_core_v3_RuntimeFeatureFlag_submsgs[1] = {
@@ -154,14 +154,14 @@ static const upb_msglayout *const envoy_config_core_v3_RuntimeFeatureFlag_submsg
 };
 
 static const upb_msglayout_field envoy_config_core_v3_RuntimeFeatureFlag__fields[2] = {
-  {1, UPB_SIZE(8, 16), 0, 0, 11, 1},
-  {2, UPB_SIZE(0, 0), 0, 0, 9, 1},
+  {1, UPB_SIZE(12, 24), 1, 0, 11, 1},
+  {2, UPB_SIZE(4, 8), 0, 0, 9, 1},
 };
 
 const upb_msglayout envoy_config_core_v3_RuntimeFeatureFlag_msginit = {
   &envoy_config_core_v3_RuntimeFeatureFlag_submsgs[0],
   &envoy_config_core_v3_RuntimeFeatureFlag__fields[0],
-  UPB_SIZE(16, 32), 2, false,
+  UPB_SIZE(16, 32), 2, false, 255,
 };
 
 static const upb_msglayout_field envoy_config_core_v3_HeaderValue__fields[2] = {
@@ -172,7 +172,7 @@ static const upb_msglayout_field envoy_config_core_v3_HeaderValue__fields[2] = {
 const upb_msglayout envoy_config_core_v3_HeaderValue_msginit = {
   NULL,
   &envoy_config_core_v3_HeaderValue__fields[0],
-  UPB_SIZE(16, 32), 2, false,
+  UPB_SIZE(16, 32), 2, false, 255,
 };
 
 static const upb_msglayout *const envoy_config_core_v3_HeaderValueOption_submsgs[2] = {
@@ -181,14 +181,14 @@ static const upb_msglayout *const envoy_config_core_v3_HeaderValueOption_submsgs
 };
 
 static const upb_msglayout_field envoy_config_core_v3_HeaderValueOption__fields[2] = {
-  {1, UPB_SIZE(0, 0), 0, 0, 11, 1},
-  {2, UPB_SIZE(4, 8), 0, 1, 11, 1},
+  {1, UPB_SIZE(4, 8), 1, 0, 11, 1},
+  {2, UPB_SIZE(8, 16), 2, 1, 11, 1},
 };
 
 const upb_msglayout envoy_config_core_v3_HeaderValueOption_msginit = {
   &envoy_config_core_v3_HeaderValueOption_submsgs[0],
   &envoy_config_core_v3_HeaderValueOption__fields[0],
-  UPB_SIZE(8, 16), 2, false,
+  UPB_SIZE(16, 24), 2, false, 255,
 };
 
 static const upb_msglayout *const envoy_config_core_v3_HeaderMap_submsgs[1] = {
@@ -202,7 +202,7 @@ static const upb_msglayout_field envoy_config_core_v3_HeaderMap__fields[1] = {
 const upb_msglayout envoy_config_core_v3_HeaderMap_msginit = {
   &envoy_config_core_v3_HeaderMap_submsgs[0],
   &envoy_config_core_v3_HeaderMap__fields[0],
-  UPB_SIZE(4, 8), 1, false,
+  UPB_SIZE(8, 8), 1, false, 255,
 };
 
 static const upb_msglayout_field envoy_config_core_v3_DataSource__fields[3] = {
@@ -214,7 +214,7 @@ static const upb_msglayout_field envoy_config_core_v3_DataSource__fields[3] = {
 const upb_msglayout envoy_config_core_v3_DataSource_msginit = {
   NULL,
   &envoy_config_core_v3_DataSource__fields[0],
-  UPB_SIZE(16, 32), 3, false,
+  UPB_SIZE(16, 32), 3, false, 255,
 };
 
 static const upb_msglayout *const envoy_config_core_v3_RetryPolicy_submsgs[2] = {
@@ -223,14 +223,14 @@ static const upb_msglayout *const envoy_config_core_v3_RetryPolicy_submsgs[2] =
 };
 
 static const upb_msglayout_field envoy_config_core_v3_RetryPolicy__fields[2] = {
-  {1, UPB_SIZE(0, 0), 0, 0, 11, 1},
-  {2, UPB_SIZE(4, 8), 0, 1, 11, 1},
+  {1, UPB_SIZE(4, 8), 1, 0, 11, 1},
+  {2, UPB_SIZE(8, 16), 2, 1, 11, 1},
 };
 
 const upb_msglayout envoy_config_core_v3_RetryPolicy_msginit = {
   &envoy_config_core_v3_RetryPolicy_submsgs[0],
   &envoy_config_core_v3_RetryPolicy__fields[0],
-  UPB_SIZE(8, 16), 2, false,
+  UPB_SIZE(16, 24), 2, false, 255,
 };
 
 static const upb_msglayout *const envoy_config_core_v3_RemoteDataSource_submsgs[2] = {
@@ -239,15 +239,15 @@ static const upb_msglayout *const envoy_config_core_v3_RemoteDataSource_submsgs[
 };
 
 static const upb_msglayout_field envoy_config_core_v3_RemoteDataSource__fields[3] = {
-  {1, UPB_SIZE(8, 16), 0, 0, 11, 1},
-  {2, UPB_SIZE(0, 0), 0, 0, 9, 1},
-  {3, UPB_SIZE(12, 24), 0, 1, 11, 1},
+  {1, UPB_SIZE(12, 24), 1, 0, 11, 1},
+  {2, UPB_SIZE(4, 8), 0, 0, 9, 1},
+  {3, UPB_SIZE(16, 32), 2, 1, 11, 1},
 };
 
 const upb_msglayout envoy_config_core_v3_RemoteDataSource_msginit = {
   &envoy_config_core_v3_RemoteDataSource_submsgs[0],
   &envoy_config_core_v3_RemoteDataSource__fields[0],
-  UPB_SIZE(16, 32), 3, false,
+  UPB_SIZE(24, 48), 3, false, 255,
 };
 
 static const upb_msglayout *const envoy_config_core_v3_AsyncDataSource_submsgs[2] = {
@@ -263,7 +263,7 @@ static const upb_msglayout_field envoy_config_core_v3_AsyncDataSource__fields[2]
 const upb_msglayout envoy_config_core_v3_AsyncDataSource_msginit = {
   &envoy_config_core_v3_AsyncDataSource_submsgs[0],
   &envoy_config_core_v3_AsyncDataSource__fields[0],
-  UPB_SIZE(8, 16), 2, false,
+  UPB_SIZE(8, 16), 2, false, 255,
 };
 
 static const upb_msglayout *const envoy_config_core_v3_TransportSocket_submsgs[1] = {
@@ -278,7 +278,7 @@ static const upb_msglayout_field envoy_config_core_v3_TransportSocket__fields[2]
 const upb_msglayout envoy_config_core_v3_TransportSocket_msginit = {
   &envoy_config_core_v3_TransportSocket_submsgs[0],
   &envoy_config_core_v3_TransportSocket__fields[0],
-  UPB_SIZE(16, 32), 2, false,
+  UPB_SIZE(16, 32), 2, false, 255,
 };
 
 static const upb_msglayout *const envoy_config_core_v3_RuntimeFractionalPercent_submsgs[1] = {
@@ -286,14 +286,14 @@ static const upb_msglayout *const envoy_config_core_v3_RuntimeFractionalPercent_
 };
 
 static const upb_msglayout_field envoy_config_core_v3_RuntimeFractionalPercent__fields[2] = {
-  {1, UPB_SIZE(8, 16), 0, 0, 11, 1},
-  {2, UPB_SIZE(0, 0), 0, 0, 9, 1},
+  {1, UPB_SIZE(12, 24), 1, 0, 11, 1},
+  {2, UPB_SIZE(4, 8), 0, 0, 9, 1},
 };
 
 const upb_msglayout envoy_config_core_v3_RuntimeFractionalPercent_msginit = {
   &envoy_config_core_v3_RuntimeFractionalPercent_submsgs[0],
   &envoy_config_core_v3_RuntimeFractionalPercent__fields[0],
-  UPB_SIZE(16, 32), 2, false,
+  UPB_SIZE(16, 32), 2, false, 255,
 };
 
 static const upb_msglayout_field envoy_config_core_v3_ControlPlane__fields[1] = {
@@ -303,7 +303,7 @@ static const upb_msglayout_field envoy_config_core_v3_ControlPlane__fields[1] =
 const upb_msglayout envoy_config_core_v3_ControlPlane_msginit = {
   NULL,
   &envoy_config_core_v3_ControlPlane__fields[0],
-  UPB_SIZE(8, 16), 1, false,
+  UPB_SIZE(8, 16), 1, false, 255,
 };
 
 #include "upb/port_undef.inc"
index 21852d7..07cbaf4 100644 (file)
@@ -11,6 +11,7 @@
 
 #include "upb/msg.h"
 #include "upb/decode.h"
+#include "upb/decode_fast.h"
 #include "upb/encode.h"
 
 #include "upb/port_def.inc"
@@ -130,6 +131,12 @@ UPB_INLINE envoy_config_core_v3_Locality *envoy_config_core_v3_Locality_parse(co
   envoy_config_core_v3_Locality *ret = envoy_config_core_v3_Locality_new(arena);
   return (ret && upb_decode(buf, size, ret, &envoy_config_core_v3_Locality_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE envoy_config_core_v3_Locality *envoy_config_core_v3_Locality_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  envoy_config_core_v3_Locality *ret = envoy_config_core_v3_Locality_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &envoy_config_core_v3_Locality_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *envoy_config_core_v3_Locality_serialize(const envoy_config_core_v3_Locality *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &envoy_config_core_v3_Locality_msginit, arena, len);
 }
@@ -158,17 +165,24 @@ UPB_INLINE envoy_config_core_v3_BuildVersion *envoy_config_core_v3_BuildVersion_
   envoy_config_core_v3_BuildVersion *ret = envoy_config_core_v3_BuildVersion_new(arena);
   return (ret && upb_decode(buf, size, ret, &envoy_config_core_v3_BuildVersion_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE envoy_config_core_v3_BuildVersion *envoy_config_core_v3_BuildVersion_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  envoy_config_core_v3_BuildVersion *ret = envoy_config_core_v3_BuildVersion_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &envoy_config_core_v3_BuildVersion_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *envoy_config_core_v3_BuildVersion_serialize(const envoy_config_core_v3_BuildVersion *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &envoy_config_core_v3_BuildVersion_msginit, arena, len);
 }
 
-UPB_INLINE bool envoy_config_core_v3_BuildVersion_has_version(const envoy_config_core_v3_BuildVersion *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(0, 0)); }
-UPB_INLINE const struct envoy_type_v3_SemanticVersion* envoy_config_core_v3_BuildVersion_version(const envoy_config_core_v3_BuildVersion *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(0, 0), const struct envoy_type_v3_SemanticVersion*); }
-UPB_INLINE bool envoy_config_core_v3_BuildVersion_has_metadata(const envoy_config_core_v3_BuildVersion *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(4, 8)); }
-UPB_INLINE const struct google_protobuf_Struct* envoy_config_core_v3_BuildVersion_metadata(const envoy_config_core_v3_BuildVersion *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(4, 8), const struct google_protobuf_Struct*); }
+UPB_INLINE bool envoy_config_core_v3_BuildVersion_has_version(const envoy_config_core_v3_BuildVersion *msg) { return _upb_hasbit(msg, 1); }
+UPB_INLINE const struct envoy_type_v3_SemanticVersion* envoy_config_core_v3_BuildVersion_version(const envoy_config_core_v3_BuildVersion *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(4, 8), const struct envoy_type_v3_SemanticVersion*); }
+UPB_INLINE bool envoy_config_core_v3_BuildVersion_has_metadata(const envoy_config_core_v3_BuildVersion *msg) { return _upb_hasbit(msg, 2); }
+UPB_INLINE const struct google_protobuf_Struct* envoy_config_core_v3_BuildVersion_metadata(const envoy_config_core_v3_BuildVersion *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(8, 16), const struct google_protobuf_Struct*); }
 
 UPB_INLINE void envoy_config_core_v3_BuildVersion_set_version(envoy_config_core_v3_BuildVersion *msg, struct envoy_type_v3_SemanticVersion* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(0, 0), struct envoy_type_v3_SemanticVersion*) = value;
+  _upb_sethas(msg, 1);
+  *UPB_PTR_AT(msg, UPB_SIZE(4, 8), struct envoy_type_v3_SemanticVersion*) = value;
 }
 UPB_INLINE struct envoy_type_v3_SemanticVersion* envoy_config_core_v3_BuildVersion_mutable_version(envoy_config_core_v3_BuildVersion *msg, upb_arena *arena) {
   struct envoy_type_v3_SemanticVersion* sub = (struct envoy_type_v3_SemanticVersion*)envoy_config_core_v3_BuildVersion_version(msg);
@@ -180,7 +194,8 @@ UPB_INLINE struct envoy_type_v3_SemanticVersion* envoy_config_core_v3_BuildVersi
   return sub;
 }
 UPB_INLINE void envoy_config_core_v3_BuildVersion_set_metadata(envoy_config_core_v3_BuildVersion *msg, struct google_protobuf_Struct* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(4, 8), struct google_protobuf_Struct*) = value;
+  _upb_sethas(msg, 2);
+  *UPB_PTR_AT(msg, UPB_SIZE(8, 16), struct google_protobuf_Struct*) = value;
 }
 UPB_INLINE struct google_protobuf_Struct* envoy_config_core_v3_BuildVersion_mutable_metadata(envoy_config_core_v3_BuildVersion *msg, upb_arena *arena) {
   struct google_protobuf_Struct* sub = (struct google_protobuf_Struct*)envoy_config_core_v3_BuildVersion_metadata(msg);
@@ -202,6 +217,12 @@ UPB_INLINE envoy_config_core_v3_Extension *envoy_config_core_v3_Extension_parse(
   envoy_config_core_v3_Extension *ret = envoy_config_core_v3_Extension_new(arena);
   return (ret && upb_decode(buf, size, ret, &envoy_config_core_v3_Extension_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE envoy_config_core_v3_Extension *envoy_config_core_v3_Extension_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  envoy_config_core_v3_Extension *ret = envoy_config_core_v3_Extension_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &envoy_config_core_v3_Extension_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *envoy_config_core_v3_Extension_serialize(const envoy_config_core_v3_Extension *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &envoy_config_core_v3_Extension_msginit, arena, len);
 }
@@ -209,9 +230,9 @@ UPB_INLINE char *envoy_config_core_v3_Extension_serialize(const envoy_config_cor
 UPB_INLINE upb_strview envoy_config_core_v3_Extension_name(const envoy_config_core_v3_Extension *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(4, 8), upb_strview); }
 UPB_INLINE upb_strview envoy_config_core_v3_Extension_category(const envoy_config_core_v3_Extension *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(12, 24), upb_strview); }
 UPB_INLINE upb_strview envoy_config_core_v3_Extension_type_descriptor(const envoy_config_core_v3_Extension *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(20, 40), upb_strview); }
-UPB_INLINE bool envoy_config_core_v3_Extension_has_version(const envoy_config_core_v3_Extension *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(28, 56)); }
+UPB_INLINE bool envoy_config_core_v3_Extension_has_version(const envoy_config_core_v3_Extension *msg) { return _upb_hasbit(msg, 1); }
 UPB_INLINE const envoy_config_core_v3_BuildVersion* envoy_config_core_v3_Extension_version(const envoy_config_core_v3_Extension *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(28, 56), const envoy_config_core_v3_BuildVersion*); }
-UPB_INLINE bool envoy_config_core_v3_Extension_disabled(const envoy_config_core_v3_Extension *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(0, 0), bool); }
+UPB_INLINE bool envoy_config_core_v3_Extension_disabled(const envoy_config_core_v3_Extension *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(1, 1), bool); }
 
 UPB_INLINE void envoy_config_core_v3_Extension_set_name(envoy_config_core_v3_Extension *msg, upb_strview value) {
   *UPB_PTR_AT(msg, UPB_SIZE(4, 8), upb_strview) = value;
@@ -223,6 +244,7 @@ UPB_INLINE void envoy_config_core_v3_Extension_set_type_descriptor(envoy_config_
   *UPB_PTR_AT(msg, UPB_SIZE(20, 40), upb_strview) = value;
 }
 UPB_INLINE void envoy_config_core_v3_Extension_set_version(envoy_config_core_v3_Extension *msg, envoy_config_core_v3_BuildVersion* value) {
+  _upb_sethas(msg, 1);
   *UPB_PTR_AT(msg, UPB_SIZE(28, 56), envoy_config_core_v3_BuildVersion*) = value;
 }
 UPB_INLINE struct envoy_config_core_v3_BuildVersion* envoy_config_core_v3_Extension_mutable_version(envoy_config_core_v3_Extension *msg, upb_arena *arena) {
@@ -235,7 +257,7 @@ UPB_INLINE struct envoy_config_core_v3_BuildVersion* envoy_config_core_v3_Extens
   return sub;
 }
 UPB_INLINE void envoy_config_core_v3_Extension_set_disabled(envoy_config_core_v3_Extension *msg, bool value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(0, 0), bool) = value;
+  *UPB_PTR_AT(msg, UPB_SIZE(1, 1), bool) = value;
 }
 
 /* envoy.config.core.v3.Node */
@@ -248,6 +270,12 @@ UPB_INLINE envoy_config_core_v3_Node *envoy_config_core_v3_Node_parse(const char
   envoy_config_core_v3_Node *ret = envoy_config_core_v3_Node_new(arena);
   return (ret && upb_decode(buf, size, ret, &envoy_config_core_v3_Node_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE envoy_config_core_v3_Node *envoy_config_core_v3_Node_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  envoy_config_core_v3_Node *ret = envoy_config_core_v3_Node_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &envoy_config_core_v3_Node_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *envoy_config_core_v3_Node_serialize(const envoy_config_core_v3_Node *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &envoy_config_core_v3_Node_msginit, arena, len);
 }
@@ -257,33 +285,34 @@ typedef enum {
   envoy_config_core_v3_Node_user_agent_version_type_user_agent_build_version = 8,
   envoy_config_core_v3_Node_user_agent_version_type_NOT_SET = 0
 } envoy_config_core_v3_Node_user_agent_version_type_oneofcases;
-UPB_INLINE envoy_config_core_v3_Node_user_agent_version_type_oneofcases envoy_config_core_v3_Node_user_agent_version_type_case(const envoy_config_core_v3_Node* msg) { return (envoy_config_core_v3_Node_user_agent_version_type_oneofcases)*UPB_PTR_AT(msg, UPB_SIZE(52, 104), int32_t); }
-
-UPB_INLINE upb_strview envoy_config_core_v3_Node_id(const envoy_config_core_v3_Node *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(0, 0), upb_strview); }
-UPB_INLINE upb_strview envoy_config_core_v3_Node_cluster(const envoy_config_core_v3_Node *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(8, 16), upb_strview); }
-UPB_INLINE bool envoy_config_core_v3_Node_has_metadata(const envoy_config_core_v3_Node *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(24, 48)); }
-UPB_INLINE const struct google_protobuf_Struct* envoy_config_core_v3_Node_metadata(const envoy_config_core_v3_Node *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(24, 48), const struct google_protobuf_Struct*); }
-UPB_INLINE bool envoy_config_core_v3_Node_has_locality(const envoy_config_core_v3_Node *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(28, 56)); }
-UPB_INLINE const envoy_config_core_v3_Locality* envoy_config_core_v3_Node_locality(const envoy_config_core_v3_Node *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(28, 56), const envoy_config_core_v3_Locality*); }
-UPB_INLINE upb_strview envoy_config_core_v3_Node_user_agent_name(const envoy_config_core_v3_Node *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(16, 32), upb_strview); }
-UPB_INLINE bool envoy_config_core_v3_Node_has_user_agent_version(const envoy_config_core_v3_Node *msg) { return _upb_getoneofcase(msg, UPB_SIZE(52, 104)) == 7; }
-UPB_INLINE upb_strview envoy_config_core_v3_Node_user_agent_version(const envoy_config_core_v3_Node *msg) { return UPB_READ_ONEOF(msg, upb_strview, UPB_SIZE(44, 88), UPB_SIZE(52, 104), 7, upb_strview_make("", strlen(""))); }
-UPB_INLINE bool envoy_config_core_v3_Node_has_user_agent_build_version(const envoy_config_core_v3_Node *msg) { return _upb_getoneofcase(msg, UPB_SIZE(52, 104)) == 8; }
-UPB_INLINE const envoy_config_core_v3_BuildVersion* envoy_config_core_v3_Node_user_agent_build_version(const envoy_config_core_v3_Node *msg) { return UPB_READ_ONEOF(msg, const envoy_config_core_v3_BuildVersion*, UPB_SIZE(44, 88), UPB_SIZE(52, 104), 8, NULL); }
-UPB_INLINE bool envoy_config_core_v3_Node_has_extensions(const envoy_config_core_v3_Node *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(32, 64)); }
-UPB_INLINE const envoy_config_core_v3_Extension* const* envoy_config_core_v3_Node_extensions(const envoy_config_core_v3_Node *msg, size_t *len) { return (const envoy_config_core_v3_Extension* const*)_upb_array_accessor(msg, UPB_SIZE(32, 64), len); }
-UPB_INLINE upb_strview const* envoy_config_core_v3_Node_client_features(const envoy_config_core_v3_Node *msg, size_t *len) { return (upb_strview const*)_upb_array_accessor(msg, UPB_SIZE(36, 72), len); }
-UPB_INLINE bool envoy_config_core_v3_Node_has_listening_addresses(const envoy_config_core_v3_Node *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(40, 80)); }
-UPB_INLINE const struct envoy_config_core_v3_Address* const* envoy_config_core_v3_Node_listening_addresses(const envoy_config_core_v3_Node *msg, size_t *len) { return (const struct envoy_config_core_v3_Address* const*)_upb_array_accessor(msg, UPB_SIZE(40, 80), len); }
+UPB_INLINE envoy_config_core_v3_Node_user_agent_version_type_oneofcases envoy_config_core_v3_Node_user_agent_version_type_case(const envoy_config_core_v3_Node* msg) { return (envoy_config_core_v3_Node_user_agent_version_type_oneofcases)*UPB_PTR_AT(msg, UPB_SIZE(56, 112), int32_t); }
+
+UPB_INLINE upb_strview envoy_config_core_v3_Node_id(const envoy_config_core_v3_Node *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(4, 8), upb_strview); }
+UPB_INLINE upb_strview envoy_config_core_v3_Node_cluster(const envoy_config_core_v3_Node *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(12, 24), upb_strview); }
+UPB_INLINE bool envoy_config_core_v3_Node_has_metadata(const envoy_config_core_v3_Node *msg) { return _upb_hasbit(msg, 1); }
+UPB_INLINE const struct google_protobuf_Struct* envoy_config_core_v3_Node_metadata(const envoy_config_core_v3_Node *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(28, 56), const struct google_protobuf_Struct*); }
+UPB_INLINE bool envoy_config_core_v3_Node_has_locality(const envoy_config_core_v3_Node *msg) { return _upb_hasbit(msg, 2); }
+UPB_INLINE const envoy_config_core_v3_Locality* envoy_config_core_v3_Node_locality(const envoy_config_core_v3_Node *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(32, 64), const envoy_config_core_v3_Locality*); }
+UPB_INLINE upb_strview envoy_config_core_v3_Node_user_agent_name(const envoy_config_core_v3_Node *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(20, 40), upb_strview); }
+UPB_INLINE bool envoy_config_core_v3_Node_has_user_agent_version(const envoy_config_core_v3_Node *msg) { return _upb_getoneofcase(msg, UPB_SIZE(56, 112)) == 7; }
+UPB_INLINE upb_strview envoy_config_core_v3_Node_user_agent_version(const envoy_config_core_v3_Node *msg) { return UPB_READ_ONEOF(msg, upb_strview, UPB_SIZE(48, 96), UPB_SIZE(56, 112), 7, upb_strview_make("", strlen(""))); }
+UPB_INLINE bool envoy_config_core_v3_Node_has_user_agent_build_version(const envoy_config_core_v3_Node *msg) { return _upb_getoneofcase(msg, UPB_SIZE(56, 112)) == 8; }
+UPB_INLINE const envoy_config_core_v3_BuildVersion* envoy_config_core_v3_Node_user_agent_build_version(const envoy_config_core_v3_Node *msg) { return UPB_READ_ONEOF(msg, const envoy_config_core_v3_BuildVersion*, UPB_SIZE(48, 96), UPB_SIZE(56, 112), 8, NULL); }
+UPB_INLINE bool envoy_config_core_v3_Node_has_extensions(const envoy_config_core_v3_Node *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(36, 72)); }
+UPB_INLINE const envoy_config_core_v3_Extension* const* envoy_config_core_v3_Node_extensions(const envoy_config_core_v3_Node *msg, size_t *len) { return (const envoy_config_core_v3_Extension* const*)_upb_array_accessor(msg, UPB_SIZE(36, 72), len); }
+UPB_INLINE upb_strview const* envoy_config_core_v3_Node_client_features(const envoy_config_core_v3_Node *msg, size_t *len) { return (upb_strview const*)_upb_array_accessor(msg, UPB_SIZE(40, 80), len); }
+UPB_INLINE bool envoy_config_core_v3_Node_has_listening_addresses(const envoy_config_core_v3_Node *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(44, 88)); }
+UPB_INLINE const struct envoy_config_core_v3_Address* const* envoy_config_core_v3_Node_listening_addresses(const envoy_config_core_v3_Node *msg, size_t *len) { return (const struct envoy_config_core_v3_Address* const*)_upb_array_accessor(msg, UPB_SIZE(44, 88), len); }
 
 UPB_INLINE void envoy_config_core_v3_Node_set_id(envoy_config_core_v3_Node *msg, upb_strview value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(0, 0), upb_strview) = value;
+  *UPB_PTR_AT(msg, UPB_SIZE(4, 8), upb_strview) = value;
 }
 UPB_INLINE void envoy_config_core_v3_Node_set_cluster(envoy_config_core_v3_Node *msg, upb_strview value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(8, 16), upb_strview) = value;
+  *UPB_PTR_AT(msg, UPB_SIZE(12, 24), upb_strview) = value;
 }
 UPB_INLINE void envoy_config_core_v3_Node_set_metadata(envoy_config_core_v3_Node *msg, struct google_protobuf_Struct* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(24, 48), struct google_protobuf_Struct*) = value;
+  _upb_sethas(msg, 1);
+  *UPB_PTR_AT(msg, UPB_SIZE(28, 56), struct google_protobuf_Struct*) = value;
 }
 UPB_INLINE struct google_protobuf_Struct* envoy_config_core_v3_Node_mutable_metadata(envoy_config_core_v3_Node *msg, upb_arena *arena) {
   struct google_protobuf_Struct* sub = (struct google_protobuf_Struct*)envoy_config_core_v3_Node_metadata(msg);
@@ -295,7 +324,8 @@ UPB_INLINE struct google_protobuf_Struct* envoy_config_core_v3_Node_mutable_meta
   return sub;
 }
 UPB_INLINE void envoy_config_core_v3_Node_set_locality(envoy_config_core_v3_Node *msg, envoy_config_core_v3_Locality* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(28, 56), envoy_config_core_v3_Locality*) = value;
+  _upb_sethas(msg, 2);
+  *UPB_PTR_AT(msg, UPB_SIZE(32, 64), envoy_config_core_v3_Locality*) = value;
 }
 UPB_INLINE struct envoy_config_core_v3_Locality* envoy_config_core_v3_Node_mutable_locality(envoy_config_core_v3_Node *msg, upb_arena *arena) {
   struct envoy_config_core_v3_Locality* sub = (struct envoy_config_core_v3_Locality*)envoy_config_core_v3_Node_locality(msg);
@@ -307,13 +337,13 @@ UPB_INLINE struct envoy_config_core_v3_Locality* envoy_config_core_v3_Node_mutab
   return sub;
 }
 UPB_INLINE void envoy_config_core_v3_Node_set_user_agent_name(envoy_config_core_v3_Node *msg, upb_strview value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(16, 32), upb_strview) = value;
+  *UPB_PTR_AT(msg, UPB_SIZE(20, 40), upb_strview) = value;
 }
 UPB_INLINE void envoy_config_core_v3_Node_set_user_agent_version(envoy_config_core_v3_Node *msg, upb_strview value) {
-  UPB_WRITE_ONEOF(msg, upb_strview, UPB_SIZE(44, 88), value, UPB_SIZE(52, 104), 7);
+  UPB_WRITE_ONEOF(msg, upb_strview, UPB_SIZE(48, 96), value, UPB_SIZE(56, 112), 7);
 }
 UPB_INLINE void envoy_config_core_v3_Node_set_user_agent_build_version(envoy_config_core_v3_Node *msg, envoy_config_core_v3_BuildVersion* value) {
-  UPB_WRITE_ONEOF(msg, envoy_config_core_v3_BuildVersion*, UPB_SIZE(44, 88), value, UPB_SIZE(52, 104), 8);
+  UPB_WRITE_ONEOF(msg, envoy_config_core_v3_BuildVersion*, UPB_SIZE(48, 96), value, UPB_SIZE(56, 112), 8);
 }
 UPB_INLINE struct envoy_config_core_v3_BuildVersion* envoy_config_core_v3_Node_mutable_user_agent_build_version(envoy_config_core_v3_Node *msg, upb_arena *arena) {
   struct envoy_config_core_v3_BuildVersion* sub = (struct envoy_config_core_v3_BuildVersion*)envoy_config_core_v3_Node_user_agent_build_version(msg);
@@ -325,38 +355,38 @@ UPB_INLINE struct envoy_config_core_v3_BuildVersion* envoy_config_core_v3_Node_m
   return sub;
 }
 UPB_INLINE envoy_config_core_v3_Extension** envoy_config_core_v3_Node_mutable_extensions(envoy_config_core_v3_Node *msg, size_t *len) {
-  return (envoy_config_core_v3_Extension**)_upb_array_mutable_accessor(msg, UPB_SIZE(32, 64), len);
+  return (envoy_config_core_v3_Extension**)_upb_array_mutable_accessor(msg, UPB_SIZE(36, 72), len);
 }
 UPB_INLINE envoy_config_core_v3_Extension** envoy_config_core_v3_Node_resize_extensions(envoy_config_core_v3_Node *msg, size_t len, upb_arena *arena) {
-  return (envoy_config_core_v3_Extension**)_upb_array_resize_accessor(msg, UPB_SIZE(32, 64), len, UPB_TYPE_MESSAGE, arena);
+  return (envoy_config_core_v3_Extension**)_upb_array_resize_accessor2(msg, UPB_SIZE(36, 72), len, UPB_SIZE(2, 3), arena);
 }
 UPB_INLINE struct envoy_config_core_v3_Extension* envoy_config_core_v3_Node_add_extensions(envoy_config_core_v3_Node *msg, upb_arena *arena) {
   struct envoy_config_core_v3_Extension* sub = (struct envoy_config_core_v3_Extension*)_upb_msg_new(&envoy_config_core_v3_Extension_msginit, arena);
-  bool ok = _upb_array_append_accessor(
-      msg, UPB_SIZE(32, 64), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena);
+  bool ok = _upb_array_append_accessor2(
+      msg, UPB_SIZE(36, 72), UPB_SIZE(2, 3), &sub, arena);
   if (!ok) return NULL;
   return sub;
 }
 UPB_INLINE upb_strview* envoy_config_core_v3_Node_mutable_client_features(envoy_config_core_v3_Node *msg, size_t *len) {
-  return (upb_strview*)_upb_array_mutable_accessor(msg, UPB_SIZE(36, 72), len);
+  return (upb_strview*)_upb_array_mutable_accessor(msg, UPB_SIZE(40, 80), len);
 }
 UPB_INLINE upb_strview* envoy_config_core_v3_Node_resize_client_features(envoy_config_core_v3_Node *msg, size_t len, upb_arena *arena) {
-  return (upb_strview*)_upb_array_resize_accessor(msg, UPB_SIZE(36, 72), len, UPB_TYPE_STRING, arena);
+  return (upb_strview*)_upb_array_resize_accessor2(msg, UPB_SIZE(40, 80), len, UPB_SIZE(3, 4), arena);
 }
 UPB_INLINE bool envoy_config_core_v3_Node_add_client_features(envoy_config_core_v3_Node *msg, upb_strview val, upb_arena *arena) {
-  return _upb_array_append_accessor(msg, UPB_SIZE(36, 72), UPB_SIZE(8, 16), UPB_TYPE_STRING, &val,
+  return _upb_array_append_accessor2(msg, UPB_SIZE(40, 80), UPB_SIZE(3, 4), &val,
       arena);
 }
 UPB_INLINE struct envoy_config_core_v3_Address** envoy_config_core_v3_Node_mutable_listening_addresses(envoy_config_core_v3_Node *msg, size_t *len) {
-  return (struct envoy_config_core_v3_Address**)_upb_array_mutable_accessor(msg, UPB_SIZE(40, 80), len);
+  return (struct envoy_config_core_v3_Address**)_upb_array_mutable_accessor(msg, UPB_SIZE(44, 88), len);
 }
 UPB_INLINE struct envoy_config_core_v3_Address** envoy_config_core_v3_Node_resize_listening_addresses(envoy_config_core_v3_Node *msg, size_t len, upb_arena *arena) {
-  return (struct envoy_config_core_v3_Address**)_upb_array_resize_accessor(msg, UPB_SIZE(40, 80), len, UPB_TYPE_MESSAGE, arena);
+  return (struct envoy_config_core_v3_Address**)_upb_array_resize_accessor2(msg, UPB_SIZE(44, 88), len, UPB_SIZE(2, 3), arena);
 }
 UPB_INLINE struct envoy_config_core_v3_Address* envoy_config_core_v3_Node_add_listening_addresses(envoy_config_core_v3_Node *msg, upb_arena *arena) {
   struct envoy_config_core_v3_Address* sub = (struct envoy_config_core_v3_Address*)_upb_msg_new(&envoy_config_core_v3_Address_msginit, arena);
-  bool ok = _upb_array_append_accessor(
-      msg, UPB_SIZE(40, 80), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena);
+  bool ok = _upb_array_append_accessor2(
+      msg, UPB_SIZE(44, 88), UPB_SIZE(2, 3), &sub, arena);
   if (!ok) return NULL;
   return sub;
 }
@@ -371,6 +401,12 @@ UPB_INLINE envoy_config_core_v3_Metadata *envoy_config_core_v3_Metadata_parse(co
   envoy_config_core_v3_Metadata *ret = envoy_config_core_v3_Metadata_new(arena);
   return (ret && upb_decode(buf, size, ret, &envoy_config_core_v3_Metadata_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE envoy_config_core_v3_Metadata *envoy_config_core_v3_Metadata_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  envoy_config_core_v3_Metadata *ret = envoy_config_core_v3_Metadata_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &envoy_config_core_v3_Metadata_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *envoy_config_core_v3_Metadata_serialize(const envoy_config_core_v3_Metadata *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &envoy_config_core_v3_Metadata_msginit, arena, len);
 }
@@ -413,6 +449,12 @@ UPB_INLINE envoy_config_core_v3_RuntimeUInt32 *envoy_config_core_v3_RuntimeUInt3
   envoy_config_core_v3_RuntimeUInt32 *ret = envoy_config_core_v3_RuntimeUInt32_new(arena);
   return (ret && upb_decode(buf, size, ret, &envoy_config_core_v3_RuntimeUInt32_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE envoy_config_core_v3_RuntimeUInt32 *envoy_config_core_v3_RuntimeUInt32_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  envoy_config_core_v3_RuntimeUInt32 *ret = envoy_config_core_v3_RuntimeUInt32_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &envoy_config_core_v3_RuntimeUInt32_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *envoy_config_core_v3_RuntimeUInt32_serialize(const envoy_config_core_v3_RuntimeUInt32 *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &envoy_config_core_v3_RuntimeUInt32_msginit, arena, len);
 }
@@ -437,6 +479,12 @@ UPB_INLINE envoy_config_core_v3_RuntimeDouble *envoy_config_core_v3_RuntimeDoubl
   envoy_config_core_v3_RuntimeDouble *ret = envoy_config_core_v3_RuntimeDouble_new(arena);
   return (ret && upb_decode(buf, size, ret, &envoy_config_core_v3_RuntimeDouble_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE envoy_config_core_v3_RuntimeDouble *envoy_config_core_v3_RuntimeDouble_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  envoy_config_core_v3_RuntimeDouble *ret = envoy_config_core_v3_RuntimeDouble_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &envoy_config_core_v3_RuntimeDouble_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *envoy_config_core_v3_RuntimeDouble_serialize(const envoy_config_core_v3_RuntimeDouble *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &envoy_config_core_v3_RuntimeDouble_msginit, arena, len);
 }
@@ -461,16 +509,23 @@ UPB_INLINE envoy_config_core_v3_RuntimeFeatureFlag *envoy_config_core_v3_Runtime
   envoy_config_core_v3_RuntimeFeatureFlag *ret = envoy_config_core_v3_RuntimeFeatureFlag_new(arena);
   return (ret && upb_decode(buf, size, ret, &envoy_config_core_v3_RuntimeFeatureFlag_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE envoy_config_core_v3_RuntimeFeatureFlag *envoy_config_core_v3_RuntimeFeatureFlag_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  envoy_config_core_v3_RuntimeFeatureFlag *ret = envoy_config_core_v3_RuntimeFeatureFlag_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &envoy_config_core_v3_RuntimeFeatureFlag_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *envoy_config_core_v3_RuntimeFeatureFlag_serialize(const envoy_config_core_v3_RuntimeFeatureFlag *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &envoy_config_core_v3_RuntimeFeatureFlag_msginit, arena, len);
 }
 
-UPB_INLINE bool envoy_config_core_v3_RuntimeFeatureFlag_has_default_value(const envoy_config_core_v3_RuntimeFeatureFlag *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(8, 16)); }
-UPB_INLINE const struct google_protobuf_BoolValue* envoy_config_core_v3_RuntimeFeatureFlag_default_value(const envoy_config_core_v3_RuntimeFeatureFlag *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(8, 16), const struct google_protobuf_BoolValue*); }
-UPB_INLINE upb_strview envoy_config_core_v3_RuntimeFeatureFlag_runtime_key(const envoy_config_core_v3_RuntimeFeatureFlag *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(0, 0), upb_strview); }
+UPB_INLINE bool envoy_config_core_v3_RuntimeFeatureFlag_has_default_value(const envoy_config_core_v3_RuntimeFeatureFlag *msg) { return _upb_hasbit(msg, 1); }
+UPB_INLINE const struct google_protobuf_BoolValue* envoy_config_core_v3_RuntimeFeatureFlag_default_value(const envoy_config_core_v3_RuntimeFeatureFlag *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(12, 24), const struct google_protobuf_BoolValue*); }
+UPB_INLINE upb_strview envoy_config_core_v3_RuntimeFeatureFlag_runtime_key(const envoy_config_core_v3_RuntimeFeatureFlag *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(4, 8), upb_strview); }
 
 UPB_INLINE void envoy_config_core_v3_RuntimeFeatureFlag_set_default_value(envoy_config_core_v3_RuntimeFeatureFlag *msg, struct google_protobuf_BoolValue* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(8, 16), struct google_protobuf_BoolValue*) = value;
+  _upb_sethas(msg, 1);
+  *UPB_PTR_AT(msg, UPB_SIZE(12, 24), struct google_protobuf_BoolValue*) = value;
 }
 UPB_INLINE struct google_protobuf_BoolValue* envoy_config_core_v3_RuntimeFeatureFlag_mutable_default_value(envoy_config_core_v3_RuntimeFeatureFlag *msg, upb_arena *arena) {
   struct google_protobuf_BoolValue* sub = (struct google_protobuf_BoolValue*)envoy_config_core_v3_RuntimeFeatureFlag_default_value(msg);
@@ -482,7 +537,7 @@ UPB_INLINE struct google_protobuf_BoolValue* envoy_config_core_v3_RuntimeFeature
   return sub;
 }
 UPB_INLINE void envoy_config_core_v3_RuntimeFeatureFlag_set_runtime_key(envoy_config_core_v3_RuntimeFeatureFlag *msg, upb_strview value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(0, 0), upb_strview) = value;
+  *UPB_PTR_AT(msg, UPB_SIZE(4, 8), upb_strview) = value;
 }
 
 /* envoy.config.core.v3.HeaderValue */
@@ -495,6 +550,12 @@ UPB_INLINE envoy_config_core_v3_HeaderValue *envoy_config_core_v3_HeaderValue_pa
   envoy_config_core_v3_HeaderValue *ret = envoy_config_core_v3_HeaderValue_new(arena);
   return (ret && upb_decode(buf, size, ret, &envoy_config_core_v3_HeaderValue_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE envoy_config_core_v3_HeaderValue *envoy_config_core_v3_HeaderValue_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  envoy_config_core_v3_HeaderValue *ret = envoy_config_core_v3_HeaderValue_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &envoy_config_core_v3_HeaderValue_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *envoy_config_core_v3_HeaderValue_serialize(const envoy_config_core_v3_HeaderValue *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &envoy_config_core_v3_HeaderValue_msginit, arena, len);
 }
@@ -519,17 +580,24 @@ UPB_INLINE envoy_config_core_v3_HeaderValueOption *envoy_config_core_v3_HeaderVa
   envoy_config_core_v3_HeaderValueOption *ret = envoy_config_core_v3_HeaderValueOption_new(arena);
   return (ret && upb_decode(buf, size, ret, &envoy_config_core_v3_HeaderValueOption_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE envoy_config_core_v3_HeaderValueOption *envoy_config_core_v3_HeaderValueOption_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  envoy_config_core_v3_HeaderValueOption *ret = envoy_config_core_v3_HeaderValueOption_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &envoy_config_core_v3_HeaderValueOption_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *envoy_config_core_v3_HeaderValueOption_serialize(const envoy_config_core_v3_HeaderValueOption *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &envoy_config_core_v3_HeaderValueOption_msginit, arena, len);
 }
 
-UPB_INLINE bool envoy_config_core_v3_HeaderValueOption_has_header(const envoy_config_core_v3_HeaderValueOption *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(0, 0)); }
-UPB_INLINE const envoy_config_core_v3_HeaderValue* envoy_config_core_v3_HeaderValueOption_header(const envoy_config_core_v3_HeaderValueOption *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(0, 0), const envoy_config_core_v3_HeaderValue*); }
-UPB_INLINE bool envoy_config_core_v3_HeaderValueOption_has_append(const envoy_config_core_v3_HeaderValueOption *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(4, 8)); }
-UPB_INLINE const struct google_protobuf_BoolValue* envoy_config_core_v3_HeaderValueOption_append(const envoy_config_core_v3_HeaderValueOption *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(4, 8), const struct google_protobuf_BoolValue*); }
+UPB_INLINE bool envoy_config_core_v3_HeaderValueOption_has_header(const envoy_config_core_v3_HeaderValueOption *msg) { return _upb_hasbit(msg, 1); }
+UPB_INLINE const envoy_config_core_v3_HeaderValue* envoy_config_core_v3_HeaderValueOption_header(const envoy_config_core_v3_HeaderValueOption *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(4, 8), const envoy_config_core_v3_HeaderValue*); }
+UPB_INLINE bool envoy_config_core_v3_HeaderValueOption_has_append(const envoy_config_core_v3_HeaderValueOption *msg) { return _upb_hasbit(msg, 2); }
+UPB_INLINE const struct google_protobuf_BoolValue* envoy_config_core_v3_HeaderValueOption_append(const envoy_config_core_v3_HeaderValueOption *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(8, 16), const struct google_protobuf_BoolValue*); }
 
 UPB_INLINE void envoy_config_core_v3_HeaderValueOption_set_header(envoy_config_core_v3_HeaderValueOption *msg, envoy_config_core_v3_HeaderValue* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(0, 0), envoy_config_core_v3_HeaderValue*) = value;
+  _upb_sethas(msg, 1);
+  *UPB_PTR_AT(msg, UPB_SIZE(4, 8), envoy_config_core_v3_HeaderValue*) = value;
 }
 UPB_INLINE struct envoy_config_core_v3_HeaderValue* envoy_config_core_v3_HeaderValueOption_mutable_header(envoy_config_core_v3_HeaderValueOption *msg, upb_arena *arena) {
   struct envoy_config_core_v3_HeaderValue* sub = (struct envoy_config_core_v3_HeaderValue*)envoy_config_core_v3_HeaderValueOption_header(msg);
@@ -541,7 +609,8 @@ UPB_INLINE struct envoy_config_core_v3_HeaderValue* envoy_config_core_v3_HeaderV
   return sub;
 }
 UPB_INLINE void envoy_config_core_v3_HeaderValueOption_set_append(envoy_config_core_v3_HeaderValueOption *msg, struct google_protobuf_BoolValue* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(4, 8), struct google_protobuf_BoolValue*) = value;
+  _upb_sethas(msg, 2);
+  *UPB_PTR_AT(msg, UPB_SIZE(8, 16), struct google_protobuf_BoolValue*) = value;
 }
 UPB_INLINE struct google_protobuf_BoolValue* envoy_config_core_v3_HeaderValueOption_mutable_append(envoy_config_core_v3_HeaderValueOption *msg, upb_arena *arena) {
   struct google_protobuf_BoolValue* sub = (struct google_protobuf_BoolValue*)envoy_config_core_v3_HeaderValueOption_append(msg);
@@ -563,6 +632,12 @@ UPB_INLINE envoy_config_core_v3_HeaderMap *envoy_config_core_v3_HeaderMap_parse(
   envoy_config_core_v3_HeaderMap *ret = envoy_config_core_v3_HeaderMap_new(arena);
   return (ret && upb_decode(buf, size, ret, &envoy_config_core_v3_HeaderMap_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE envoy_config_core_v3_HeaderMap *envoy_config_core_v3_HeaderMap_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  envoy_config_core_v3_HeaderMap *ret = envoy_config_core_v3_HeaderMap_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &envoy_config_core_v3_HeaderMap_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *envoy_config_core_v3_HeaderMap_serialize(const envoy_config_core_v3_HeaderMap *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &envoy_config_core_v3_HeaderMap_msginit, arena, len);
 }
@@ -574,12 +649,12 @@ UPB_INLINE envoy_config_core_v3_HeaderValue** envoy_config_core_v3_HeaderMap_mut
   return (envoy_config_core_v3_HeaderValue**)_upb_array_mutable_accessor(msg, UPB_SIZE(0, 0), len);
 }
 UPB_INLINE envoy_config_core_v3_HeaderValue** envoy_config_core_v3_HeaderMap_resize_headers(envoy_config_core_v3_HeaderMap *msg, size_t len, upb_arena *arena) {
-  return (envoy_config_core_v3_HeaderValue**)_upb_array_resize_accessor(msg, UPB_SIZE(0, 0), len, UPB_TYPE_MESSAGE, arena);
+  return (envoy_config_core_v3_HeaderValue**)_upb_array_resize_accessor2(msg, UPB_SIZE(0, 0), len, UPB_SIZE(2, 3), arena);
 }
 UPB_INLINE struct envoy_config_core_v3_HeaderValue* envoy_config_core_v3_HeaderMap_add_headers(envoy_config_core_v3_HeaderMap *msg, upb_arena *arena) {
   struct envoy_config_core_v3_HeaderValue* sub = (struct envoy_config_core_v3_HeaderValue*)_upb_msg_new(&envoy_config_core_v3_HeaderValue_msginit, arena);
-  bool ok = _upb_array_append_accessor(
-      msg, UPB_SIZE(0, 0), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena);
+  bool ok = _upb_array_append_accessor2(
+      msg, UPB_SIZE(0, 0), UPB_SIZE(2, 3), &sub, arena);
   if (!ok) return NULL;
   return sub;
 }
@@ -594,6 +669,12 @@ UPB_INLINE envoy_config_core_v3_DataSource *envoy_config_core_v3_DataSource_pars
   envoy_config_core_v3_DataSource *ret = envoy_config_core_v3_DataSource_new(arena);
   return (ret && upb_decode(buf, size, ret, &envoy_config_core_v3_DataSource_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE envoy_config_core_v3_DataSource *envoy_config_core_v3_DataSource_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  envoy_config_core_v3_DataSource *ret = envoy_config_core_v3_DataSource_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &envoy_config_core_v3_DataSource_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *envoy_config_core_v3_DataSource_serialize(const envoy_config_core_v3_DataSource *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &envoy_config_core_v3_DataSource_msginit, arena, len);
 }
@@ -633,17 +714,24 @@ UPB_INLINE envoy_config_core_v3_RetryPolicy *envoy_config_core_v3_RetryPolicy_pa
   envoy_config_core_v3_RetryPolicy *ret = envoy_config_core_v3_RetryPolicy_new(arena);
   return (ret && upb_decode(buf, size, ret, &envoy_config_core_v3_RetryPolicy_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE envoy_config_core_v3_RetryPolicy *envoy_config_core_v3_RetryPolicy_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  envoy_config_core_v3_RetryPolicy *ret = envoy_config_core_v3_RetryPolicy_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &envoy_config_core_v3_RetryPolicy_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *envoy_config_core_v3_RetryPolicy_serialize(const envoy_config_core_v3_RetryPolicy *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &envoy_config_core_v3_RetryPolicy_msginit, arena, len);
 }
 
-UPB_INLINE bool envoy_config_core_v3_RetryPolicy_has_retry_back_off(const envoy_config_core_v3_RetryPolicy *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(0, 0)); }
-UPB_INLINE const struct envoy_config_core_v3_BackoffStrategy* envoy_config_core_v3_RetryPolicy_retry_back_off(const envoy_config_core_v3_RetryPolicy *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(0, 0), const struct envoy_config_core_v3_BackoffStrategy*); }
-UPB_INLINE bool envoy_config_core_v3_RetryPolicy_has_num_retries(const envoy_config_core_v3_RetryPolicy *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(4, 8)); }
-UPB_INLINE const struct google_protobuf_UInt32Value* envoy_config_core_v3_RetryPolicy_num_retries(const envoy_config_core_v3_RetryPolicy *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(4, 8), const struct google_protobuf_UInt32Value*); }
+UPB_INLINE bool envoy_config_core_v3_RetryPolicy_has_retry_back_off(const envoy_config_core_v3_RetryPolicy *msg) { return _upb_hasbit(msg, 1); }
+UPB_INLINE const struct envoy_config_core_v3_BackoffStrategy* envoy_config_core_v3_RetryPolicy_retry_back_off(const envoy_config_core_v3_RetryPolicy *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(4, 8), const struct envoy_config_core_v3_BackoffStrategy*); }
+UPB_INLINE bool envoy_config_core_v3_RetryPolicy_has_num_retries(const envoy_config_core_v3_RetryPolicy *msg) { return _upb_hasbit(msg, 2); }
+UPB_INLINE const struct google_protobuf_UInt32Value* envoy_config_core_v3_RetryPolicy_num_retries(const envoy_config_core_v3_RetryPolicy *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(8, 16), const struct google_protobuf_UInt32Value*); }
 
 UPB_INLINE void envoy_config_core_v3_RetryPolicy_set_retry_back_off(envoy_config_core_v3_RetryPolicy *msg, struct envoy_config_core_v3_BackoffStrategy* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(0, 0), struct envoy_config_core_v3_BackoffStrategy*) = value;
+  _upb_sethas(msg, 1);
+  *UPB_PTR_AT(msg, UPB_SIZE(4, 8), struct envoy_config_core_v3_BackoffStrategy*) = value;
 }
 UPB_INLINE struct envoy_config_core_v3_BackoffStrategy* envoy_config_core_v3_RetryPolicy_mutable_retry_back_off(envoy_config_core_v3_RetryPolicy *msg, upb_arena *arena) {
   struct envoy_config_core_v3_BackoffStrategy* sub = (struct envoy_config_core_v3_BackoffStrategy*)envoy_config_core_v3_RetryPolicy_retry_back_off(msg);
@@ -655,7 +743,8 @@ UPB_INLINE struct envoy_config_core_v3_BackoffStrategy* envoy_config_core_v3_Ret
   return sub;
 }
 UPB_INLINE void envoy_config_core_v3_RetryPolicy_set_num_retries(envoy_config_core_v3_RetryPolicy *msg, struct google_protobuf_UInt32Value* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(4, 8), struct google_protobuf_UInt32Value*) = value;
+  _upb_sethas(msg, 2);
+  *UPB_PTR_AT(msg, UPB_SIZE(8, 16), struct google_protobuf_UInt32Value*) = value;
 }
 UPB_INLINE struct google_protobuf_UInt32Value* envoy_config_core_v3_RetryPolicy_mutable_num_retries(envoy_config_core_v3_RetryPolicy *msg, upb_arena *arena) {
   struct google_protobuf_UInt32Value* sub = (struct google_protobuf_UInt32Value*)envoy_config_core_v3_RetryPolicy_num_retries(msg);
@@ -677,18 +766,25 @@ UPB_INLINE envoy_config_core_v3_RemoteDataSource *envoy_config_core_v3_RemoteDat
   envoy_config_core_v3_RemoteDataSource *ret = envoy_config_core_v3_RemoteDataSource_new(arena);
   return (ret && upb_decode(buf, size, ret, &envoy_config_core_v3_RemoteDataSource_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE envoy_config_core_v3_RemoteDataSource *envoy_config_core_v3_RemoteDataSource_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  envoy_config_core_v3_RemoteDataSource *ret = envoy_config_core_v3_RemoteDataSource_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &envoy_config_core_v3_RemoteDataSource_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *envoy_config_core_v3_RemoteDataSource_serialize(const envoy_config_core_v3_RemoteDataSource *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &envoy_config_core_v3_RemoteDataSource_msginit, arena, len);
 }
 
-UPB_INLINE bool envoy_config_core_v3_RemoteDataSource_has_http_uri(const envoy_config_core_v3_RemoteDataSource *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(8, 16)); }
-UPB_INLINE const struct envoy_config_core_v3_HttpUri* envoy_config_core_v3_RemoteDataSource_http_uri(const envoy_config_core_v3_RemoteDataSource *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(8, 16), const struct envoy_config_core_v3_HttpUri*); }
-UPB_INLINE upb_strview envoy_config_core_v3_RemoteDataSource_sha256(const envoy_config_core_v3_RemoteDataSource *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(0, 0), upb_strview); }
-UPB_INLINE bool envoy_config_core_v3_RemoteDataSource_has_retry_policy(const envoy_config_core_v3_RemoteDataSource *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(12, 24)); }
-UPB_INLINE const envoy_config_core_v3_RetryPolicy* envoy_config_core_v3_RemoteDataSource_retry_policy(const envoy_config_core_v3_RemoteDataSource *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(12, 24), const envoy_config_core_v3_RetryPolicy*); }
+UPB_INLINE bool envoy_config_core_v3_RemoteDataSource_has_http_uri(const envoy_config_core_v3_RemoteDataSource *msg) { return _upb_hasbit(msg, 1); }
+UPB_INLINE const struct envoy_config_core_v3_HttpUri* envoy_config_core_v3_RemoteDataSource_http_uri(const envoy_config_core_v3_RemoteDataSource *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(12, 24), const struct envoy_config_core_v3_HttpUri*); }
+UPB_INLINE upb_strview envoy_config_core_v3_RemoteDataSource_sha256(const envoy_config_core_v3_RemoteDataSource *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(4, 8), upb_strview); }
+UPB_INLINE bool envoy_config_core_v3_RemoteDataSource_has_retry_policy(const envoy_config_core_v3_RemoteDataSource *msg) { return _upb_hasbit(msg, 2); }
+UPB_INLINE const envoy_config_core_v3_RetryPolicy* envoy_config_core_v3_RemoteDataSource_retry_policy(const envoy_config_core_v3_RemoteDataSource *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(16, 32), const envoy_config_core_v3_RetryPolicy*); }
 
 UPB_INLINE void envoy_config_core_v3_RemoteDataSource_set_http_uri(envoy_config_core_v3_RemoteDataSource *msg, struct envoy_config_core_v3_HttpUri* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(8, 16), struct envoy_config_core_v3_HttpUri*) = value;
+  _upb_sethas(msg, 1);
+  *UPB_PTR_AT(msg, UPB_SIZE(12, 24), struct envoy_config_core_v3_HttpUri*) = value;
 }
 UPB_INLINE struct envoy_config_core_v3_HttpUri* envoy_config_core_v3_RemoteDataSource_mutable_http_uri(envoy_config_core_v3_RemoteDataSource *msg, upb_arena *arena) {
   struct envoy_config_core_v3_HttpUri* sub = (struct envoy_config_core_v3_HttpUri*)envoy_config_core_v3_RemoteDataSource_http_uri(msg);
@@ -700,10 +796,11 @@ UPB_INLINE struct envoy_config_core_v3_HttpUri* envoy_config_core_v3_RemoteDataS
   return sub;
 }
 UPB_INLINE void envoy_config_core_v3_RemoteDataSource_set_sha256(envoy_config_core_v3_RemoteDataSource *msg, upb_strview value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(0, 0), upb_strview) = value;
+  *UPB_PTR_AT(msg, UPB_SIZE(4, 8), upb_strview) = value;
 }
 UPB_INLINE void envoy_config_core_v3_RemoteDataSource_set_retry_policy(envoy_config_core_v3_RemoteDataSource *msg, envoy_config_core_v3_RetryPolicy* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(12, 24), envoy_config_core_v3_RetryPolicy*) = value;
+  _upb_sethas(msg, 2);
+  *UPB_PTR_AT(msg, UPB_SIZE(16, 32), envoy_config_core_v3_RetryPolicy*) = value;
 }
 UPB_INLINE struct envoy_config_core_v3_RetryPolicy* envoy_config_core_v3_RemoteDataSource_mutable_retry_policy(envoy_config_core_v3_RemoteDataSource *msg, upb_arena *arena) {
   struct envoy_config_core_v3_RetryPolicy* sub = (struct envoy_config_core_v3_RetryPolicy*)envoy_config_core_v3_RemoteDataSource_retry_policy(msg);
@@ -725,6 +822,12 @@ UPB_INLINE envoy_config_core_v3_AsyncDataSource *envoy_config_core_v3_AsyncDataS
   envoy_config_core_v3_AsyncDataSource *ret = envoy_config_core_v3_AsyncDataSource_new(arena);
   return (ret && upb_decode(buf, size, ret, &envoy_config_core_v3_AsyncDataSource_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE envoy_config_core_v3_AsyncDataSource *envoy_config_core_v3_AsyncDataSource_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  envoy_config_core_v3_AsyncDataSource *ret = envoy_config_core_v3_AsyncDataSource_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &envoy_config_core_v3_AsyncDataSource_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *envoy_config_core_v3_AsyncDataSource_serialize(const envoy_config_core_v3_AsyncDataSource *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &envoy_config_core_v3_AsyncDataSource_msginit, arena, len);
 }
@@ -776,6 +879,12 @@ UPB_INLINE envoy_config_core_v3_TransportSocket *envoy_config_core_v3_TransportS
   envoy_config_core_v3_TransportSocket *ret = envoy_config_core_v3_TransportSocket_new(arena);
   return (ret && upb_decode(buf, size, ret, &envoy_config_core_v3_TransportSocket_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE envoy_config_core_v3_TransportSocket *envoy_config_core_v3_TransportSocket_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  envoy_config_core_v3_TransportSocket *ret = envoy_config_core_v3_TransportSocket_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &envoy_config_core_v3_TransportSocket_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *envoy_config_core_v3_TransportSocket_serialize(const envoy_config_core_v3_TransportSocket *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &envoy_config_core_v3_TransportSocket_msginit, arena, len);
 }
@@ -816,16 +925,23 @@ UPB_INLINE envoy_config_core_v3_RuntimeFractionalPercent *envoy_config_core_v3_R
   envoy_config_core_v3_RuntimeFractionalPercent *ret = envoy_config_core_v3_RuntimeFractionalPercent_new(arena);
   return (ret && upb_decode(buf, size, ret, &envoy_config_core_v3_RuntimeFractionalPercent_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE envoy_config_core_v3_RuntimeFractionalPercent *envoy_config_core_v3_RuntimeFractionalPercent_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  envoy_config_core_v3_RuntimeFractionalPercent *ret = envoy_config_core_v3_RuntimeFractionalPercent_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &envoy_config_core_v3_RuntimeFractionalPercent_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *envoy_config_core_v3_RuntimeFractionalPercent_serialize(const envoy_config_core_v3_RuntimeFractionalPercent *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &envoy_config_core_v3_RuntimeFractionalPercent_msginit, arena, len);
 }
 
-UPB_INLINE bool envoy_config_core_v3_RuntimeFractionalPercent_has_default_value(const envoy_config_core_v3_RuntimeFractionalPercent *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(8, 16)); }
-UPB_INLINE const struct envoy_type_v3_FractionalPercent* envoy_config_core_v3_RuntimeFractionalPercent_default_value(const envoy_config_core_v3_RuntimeFractionalPercent *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(8, 16), const struct envoy_type_v3_FractionalPercent*); }
-UPB_INLINE upb_strview envoy_config_core_v3_RuntimeFractionalPercent_runtime_key(const envoy_config_core_v3_RuntimeFractionalPercent *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(0, 0), upb_strview); }
+UPB_INLINE bool envoy_config_core_v3_RuntimeFractionalPercent_has_default_value(const envoy_config_core_v3_RuntimeFractionalPercent *msg) { return _upb_hasbit(msg, 1); }
+UPB_INLINE const struct envoy_type_v3_FractionalPercent* envoy_config_core_v3_RuntimeFractionalPercent_default_value(const envoy_config_core_v3_RuntimeFractionalPercent *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(12, 24), const struct envoy_type_v3_FractionalPercent*); }
+UPB_INLINE upb_strview envoy_config_core_v3_RuntimeFractionalPercent_runtime_key(const envoy_config_core_v3_RuntimeFractionalPercent *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(4, 8), upb_strview); }
 
 UPB_INLINE void envoy_config_core_v3_RuntimeFractionalPercent_set_default_value(envoy_config_core_v3_RuntimeFractionalPercent *msg, struct envoy_type_v3_FractionalPercent* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(8, 16), struct envoy_type_v3_FractionalPercent*) = value;
+  _upb_sethas(msg, 1);
+  *UPB_PTR_AT(msg, UPB_SIZE(12, 24), struct envoy_type_v3_FractionalPercent*) = value;
 }
 UPB_INLINE struct envoy_type_v3_FractionalPercent* envoy_config_core_v3_RuntimeFractionalPercent_mutable_default_value(envoy_config_core_v3_RuntimeFractionalPercent *msg, upb_arena *arena) {
   struct envoy_type_v3_FractionalPercent* sub = (struct envoy_type_v3_FractionalPercent*)envoy_config_core_v3_RuntimeFractionalPercent_default_value(msg);
@@ -837,7 +953,7 @@ UPB_INLINE struct envoy_type_v3_FractionalPercent* envoy_config_core_v3_RuntimeF
   return sub;
 }
 UPB_INLINE void envoy_config_core_v3_RuntimeFractionalPercent_set_runtime_key(envoy_config_core_v3_RuntimeFractionalPercent *msg, upb_strview value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(0, 0), upb_strview) = value;
+  *UPB_PTR_AT(msg, UPB_SIZE(4, 8), upb_strview) = value;
 }
 
 /* envoy.config.core.v3.ControlPlane */
@@ -850,6 +966,12 @@ UPB_INLINE envoy_config_core_v3_ControlPlane *envoy_config_core_v3_ControlPlane_
   envoy_config_core_v3_ControlPlane *ret = envoy_config_core_v3_ControlPlane_new(arena);
   return (ret && upb_decode(buf, size, ret, &envoy_config_core_v3_ControlPlane_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE envoy_config_core_v3_ControlPlane *envoy_config_core_v3_ControlPlane_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  envoy_config_core_v3_ControlPlane *ret = envoy_config_core_v3_ControlPlane_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &envoy_config_core_v3_ControlPlane_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *envoy_config_core_v3_ControlPlane_serialize(const envoy_config_core_v3_ControlPlane *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &envoy_config_core_v3_ControlPlane_msginit, arena, len);
 }
index 668869d..60be5fb 100644 (file)
 
 #include "upb/port_def.inc"
 
-static const upb_msglayout *const envoy_config_core_v3_ApiConfigSource_submsgs[4] = {
+static const upb_msglayout *const envoy_config_core_v3_ApiConfigSource_submsgs[3] = {
   &envoy_config_core_v3_GrpcService_msginit,
   &envoy_config_core_v3_RateLimitSettings_msginit,
   &google_protobuf_Duration_msginit,
 };
 
 static const upb_msglayout_field envoy_config_core_v3_ApiConfigSource__fields[8] = {
-  {1, UPB_SIZE(0, 0), 0, 0, 14, 1},
-  {2, UPB_SIZE(32, 48), 0, 0, 9, 3},
-  {3, UPB_SIZE(20, 24), 0, 2, 11, 1},
-  {4, UPB_SIZE(36, 56), 0, 0, 11, 3},
-  {5, UPB_SIZE(24, 32), 0, 2, 11, 1},
-  {6, UPB_SIZE(28, 40), 0, 1, 11, 1},
-  {7, UPB_SIZE(16, 16), 0, 0, 8, 1},
+  {1, UPB_SIZE(4, 4), 0, 0, 14, 1},
+  {2, UPB_SIZE(28, 40), 0, 0, 9, 3},
+  {3, UPB_SIZE(16, 16), 1, 2, 11, 1},
+  {4, UPB_SIZE(32, 48), 0, 0, 11, 3},
+  {5, UPB_SIZE(20, 24), 2, 2, 11, 1},
+  {6, UPB_SIZE(24, 32), 3, 1, 11, 1},
+  {7, UPB_SIZE(12, 12), 0, 0, 8, 1},
   {8, UPB_SIZE(8, 8), 0, 0, 14, 1},
 };
 
 const upb_msglayout envoy_config_core_v3_ApiConfigSource_msginit = {
   &envoy_config_core_v3_ApiConfigSource_submsgs[0],
   &envoy_config_core_v3_ApiConfigSource__fields[0],
-  UPB_SIZE(40, 64), 8, false,
+  UPB_SIZE(40, 56), 8, false, 255,
 };
 
 const upb_msglayout envoy_config_core_v3_AggregatedConfigSource_msginit = {
   NULL,
   NULL,
-  UPB_SIZE(0, 0), 0, false,
+  UPB_SIZE(0, 0), 0, false, 255,
 };
 
 static const upb_msglayout_field envoy_config_core_v3_SelfConfigSource__fields[1] = {
@@ -56,7 +56,7 @@ static const upb_msglayout_field envoy_config_core_v3_SelfConfigSource__fields[1
 const upb_msglayout envoy_config_core_v3_SelfConfigSource_msginit = {
   NULL,
   &envoy_config_core_v3_SelfConfigSource__fields[0],
-  UPB_SIZE(8, 8), 1, false,
+  UPB_SIZE(8, 8), 1, false, 255,
 };
 
 static const upb_msglayout *const envoy_config_core_v3_RateLimitSettings_submsgs[2] = {
@@ -65,14 +65,14 @@ static const upb_msglayout *const envoy_config_core_v3_RateLimitSettings_submsgs
 };
 
 static const upb_msglayout_field envoy_config_core_v3_RateLimitSettings__fields[2] = {
-  {1, UPB_SIZE(0, 0), 0, 1, 11, 1},
-  {2, UPB_SIZE(4, 8), 0, 0, 11, 1},
+  {1, UPB_SIZE(4, 8), 1, 1, 11, 1},
+  {2, UPB_SIZE(8, 16), 2, 0, 11, 1},
 };
 
 const upb_msglayout envoy_config_core_v3_RateLimitSettings_msginit = {
   &envoy_config_core_v3_RateLimitSettings_submsgs[0],
   &envoy_config_core_v3_RateLimitSettings__fields[0],
-  UPB_SIZE(8, 16), 2, false,
+  UPB_SIZE(16, 24), 2, false, 255,
 };
 
 static const upb_msglayout *const envoy_config_core_v3_ConfigSource_submsgs[5] = {
@@ -87,16 +87,16 @@ static const upb_msglayout_field envoy_config_core_v3_ConfigSource__fields[7] =
   {1, UPB_SIZE(16, 24), UPB_SIZE(-25, -41), 0, 9, 1},
   {2, UPB_SIZE(16, 24), UPB_SIZE(-25, -41), 1, 11, 1},
   {3, UPB_SIZE(16, 24), UPB_SIZE(-25, -41), 0, 11, 1},
-  {4, UPB_SIZE(8, 8), 0, 3, 11, 1},
+  {4, UPB_SIZE(8, 8), 1, 3, 11, 1},
   {5, UPB_SIZE(16, 24), UPB_SIZE(-25, -41), 2, 11, 1},
-  {6, UPB_SIZE(0, 0), 0, 0, 14, 1},
+  {6, UPB_SIZE(4, 4), 0, 0, 14, 1},
   {7, UPB_SIZE(12, 16), 0, 4, 11, 3},
 };
 
 const upb_msglayout envoy_config_core_v3_ConfigSource_msginit = {
   &envoy_config_core_v3_ConfigSource_submsgs[0],
   &envoy_config_core_v3_ConfigSource__fields[0],
-  UPB_SIZE(32, 48), 7, false,
+  UPB_SIZE(32, 48), 7, false, 255,
 };
 
 #include "upb/port_undef.inc"
index f57c563..bbc165f 100644 (file)
@@ -11,6 +11,7 @@
 
 #include "upb/msg.h"
 #include "upb/decode.h"
+#include "upb/decode_fast.h"
 #include "upb/encode.h"
 
 #include "upb/port_def.inc"
@@ -71,38 +72,45 @@ UPB_INLINE envoy_config_core_v3_ApiConfigSource *envoy_config_core_v3_ApiConfigS
   envoy_config_core_v3_ApiConfigSource *ret = envoy_config_core_v3_ApiConfigSource_new(arena);
   return (ret && upb_decode(buf, size, ret, &envoy_config_core_v3_ApiConfigSource_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE envoy_config_core_v3_ApiConfigSource *envoy_config_core_v3_ApiConfigSource_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  envoy_config_core_v3_ApiConfigSource *ret = envoy_config_core_v3_ApiConfigSource_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &envoy_config_core_v3_ApiConfigSource_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *envoy_config_core_v3_ApiConfigSource_serialize(const envoy_config_core_v3_ApiConfigSource *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &envoy_config_core_v3_ApiConfigSource_msginit, arena, len);
 }
 
-UPB_INLINE int32_t envoy_config_core_v3_ApiConfigSource_api_type(const envoy_config_core_v3_ApiConfigSource *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(0, 0), int32_t); }
-UPB_INLINE upb_strview const* envoy_config_core_v3_ApiConfigSource_cluster_names(const envoy_config_core_v3_ApiConfigSource *msg, size_t *len) { return (upb_strview const*)_upb_array_accessor(msg, UPB_SIZE(32, 48), len); }
-UPB_INLINE bool envoy_config_core_v3_ApiConfigSource_has_refresh_delay(const envoy_config_core_v3_ApiConfigSource *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(20, 24)); }
-UPB_INLINE const struct google_protobuf_Duration* envoy_config_core_v3_ApiConfigSource_refresh_delay(const envoy_config_core_v3_ApiConfigSource *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(20, 24), const struct google_protobuf_Duration*); }
-UPB_INLINE bool envoy_config_core_v3_ApiConfigSource_has_grpc_services(const envoy_config_core_v3_ApiConfigSource *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(36, 56)); }
-UPB_INLINE const struct envoy_config_core_v3_GrpcService* const* envoy_config_core_v3_ApiConfigSource_grpc_services(const envoy_config_core_v3_ApiConfigSource *msg, size_t *len) { return (const struct envoy_config_core_v3_GrpcService* const*)_upb_array_accessor(msg, UPB_SIZE(36, 56), len); }
-UPB_INLINE bool envoy_config_core_v3_ApiConfigSource_has_request_timeout(const envoy_config_core_v3_ApiConfigSource *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(24, 32)); }
-UPB_INLINE const struct google_protobuf_Duration* envoy_config_core_v3_ApiConfigSource_request_timeout(const envoy_config_core_v3_ApiConfigSource *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(24, 32), const struct google_protobuf_Duration*); }
-UPB_INLINE bool envoy_config_core_v3_ApiConfigSource_has_rate_limit_settings(const envoy_config_core_v3_ApiConfigSource *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(28, 40)); }
-UPB_INLINE const envoy_config_core_v3_RateLimitSettings* envoy_config_core_v3_ApiConfigSource_rate_limit_settings(const envoy_config_core_v3_ApiConfigSource *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(28, 40), const envoy_config_core_v3_RateLimitSettings*); }
-UPB_INLINE bool envoy_config_core_v3_ApiConfigSource_set_node_on_first_message_only(const envoy_config_core_v3_ApiConfigSource *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(16, 16), bool); }
+UPB_INLINE int32_t envoy_config_core_v3_ApiConfigSource_api_type(const envoy_config_core_v3_ApiConfigSource *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(4, 4), int32_t); }
+UPB_INLINE upb_strview const* envoy_config_core_v3_ApiConfigSource_cluster_names(const envoy_config_core_v3_ApiConfigSource *msg, size_t *len) { return (upb_strview const*)_upb_array_accessor(msg, UPB_SIZE(28, 40), len); }
+UPB_INLINE bool envoy_config_core_v3_ApiConfigSource_has_refresh_delay(const envoy_config_core_v3_ApiConfigSource *msg) { return _upb_hasbit(msg, 1); }
+UPB_INLINE const struct google_protobuf_Duration* envoy_config_core_v3_ApiConfigSource_refresh_delay(const envoy_config_core_v3_ApiConfigSource *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(16, 16), const struct google_protobuf_Duration*); }
+UPB_INLINE bool envoy_config_core_v3_ApiConfigSource_has_grpc_services(const envoy_config_core_v3_ApiConfigSource *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(32, 48)); }
+UPB_INLINE const struct envoy_config_core_v3_GrpcService* const* envoy_config_core_v3_ApiConfigSource_grpc_services(const envoy_config_core_v3_ApiConfigSource *msg, size_t *len) { return (const struct envoy_config_core_v3_GrpcService* const*)_upb_array_accessor(msg, UPB_SIZE(32, 48), len); }
+UPB_INLINE bool envoy_config_core_v3_ApiConfigSource_has_request_timeout(const envoy_config_core_v3_ApiConfigSource *msg) { return _upb_hasbit(msg, 2); }
+UPB_INLINE const struct google_protobuf_Duration* envoy_config_core_v3_ApiConfigSource_request_timeout(const envoy_config_core_v3_ApiConfigSource *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(20, 24), const struct google_protobuf_Duration*); }
+UPB_INLINE bool envoy_config_core_v3_ApiConfigSource_has_rate_limit_settings(const envoy_config_core_v3_ApiConfigSource *msg) { return _upb_hasbit(msg, 3); }
+UPB_INLINE const envoy_config_core_v3_RateLimitSettings* envoy_config_core_v3_ApiConfigSource_rate_limit_settings(const envoy_config_core_v3_ApiConfigSource *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(24, 32), const envoy_config_core_v3_RateLimitSettings*); }
+UPB_INLINE bool envoy_config_core_v3_ApiConfigSource_set_node_on_first_message_only(const envoy_config_core_v3_ApiConfigSource *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(12, 12), bool); }
 UPB_INLINE int32_t envoy_config_core_v3_ApiConfigSource_transport_api_version(const envoy_config_core_v3_ApiConfigSource *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(8, 8), int32_t); }
 
 UPB_INLINE void envoy_config_core_v3_ApiConfigSource_set_api_type(envoy_config_core_v3_ApiConfigSource *msg, int32_t value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(0, 0), int32_t) = value;
+  *UPB_PTR_AT(msg, UPB_SIZE(4, 4), int32_t) = value;
 }
 UPB_INLINE upb_strview* envoy_config_core_v3_ApiConfigSource_mutable_cluster_names(envoy_config_core_v3_ApiConfigSource *msg, size_t *len) {
-  return (upb_strview*)_upb_array_mutable_accessor(msg, UPB_SIZE(32, 48), len);
+  return (upb_strview*)_upb_array_mutable_accessor(msg, UPB_SIZE(28, 40), len);
 }
 UPB_INLINE upb_strview* envoy_config_core_v3_ApiConfigSource_resize_cluster_names(envoy_config_core_v3_ApiConfigSource *msg, size_t len, upb_arena *arena) {
-  return (upb_strview*)_upb_array_resize_accessor(msg, UPB_SIZE(32, 48), len, UPB_TYPE_STRING, arena);
+  return (upb_strview*)_upb_array_resize_accessor2(msg, UPB_SIZE(28, 40), len, UPB_SIZE(3, 4), arena);
 }
 UPB_INLINE bool envoy_config_core_v3_ApiConfigSource_add_cluster_names(envoy_config_core_v3_ApiConfigSource *msg, upb_strview val, upb_arena *arena) {
-  return _upb_array_append_accessor(msg, UPB_SIZE(32, 48), UPB_SIZE(8, 16), UPB_TYPE_STRING, &val,
+  return _upb_array_append_accessor2(msg, UPB_SIZE(28, 40), UPB_SIZE(3, 4), &val,
       arena);
 }
 UPB_INLINE void envoy_config_core_v3_ApiConfigSource_set_refresh_delay(envoy_config_core_v3_ApiConfigSource *msg, struct google_protobuf_Duration* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(20, 24), struct google_protobuf_Duration*) = value;
+  _upb_sethas(msg, 1);
+  *UPB_PTR_AT(msg, UPB_SIZE(16, 16), struct google_protobuf_Duration*) = value;
 }
 UPB_INLINE struct google_protobuf_Duration* envoy_config_core_v3_ApiConfigSource_mutable_refresh_delay(envoy_config_core_v3_ApiConfigSource *msg, upb_arena *arena) {
   struct google_protobuf_Duration* sub = (struct google_protobuf_Duration*)envoy_config_core_v3_ApiConfigSource_refresh_delay(msg);
@@ -114,20 +122,21 @@ UPB_INLINE struct google_protobuf_Duration* envoy_config_core_v3_ApiConfigSource
   return sub;
 }
 UPB_INLINE struct envoy_config_core_v3_GrpcService** envoy_config_core_v3_ApiConfigSource_mutable_grpc_services(envoy_config_core_v3_ApiConfigSource *msg, size_t *len) {
-  return (struct envoy_config_core_v3_GrpcService**)_upb_array_mutable_accessor(msg, UPB_SIZE(36, 56), len);
+  return (struct envoy_config_core_v3_GrpcService**)_upb_array_mutable_accessor(msg, UPB_SIZE(32, 48), len);
 }
 UPB_INLINE struct envoy_config_core_v3_GrpcService** envoy_config_core_v3_ApiConfigSource_resize_grpc_services(envoy_config_core_v3_ApiConfigSource *msg, size_t len, upb_arena *arena) {
-  return (struct envoy_config_core_v3_GrpcService**)_upb_array_resize_accessor(msg, UPB_SIZE(36, 56), len, UPB_TYPE_MESSAGE, arena);
+  return (struct envoy_config_core_v3_GrpcService**)_upb_array_resize_accessor2(msg, UPB_SIZE(32, 48), len, UPB_SIZE(2, 3), arena);
 }
 UPB_INLINE struct envoy_config_core_v3_GrpcService* envoy_config_core_v3_ApiConfigSource_add_grpc_services(envoy_config_core_v3_ApiConfigSource *msg, upb_arena *arena) {
   struct envoy_config_core_v3_GrpcService* sub = (struct envoy_config_core_v3_GrpcService*)_upb_msg_new(&envoy_config_core_v3_GrpcService_msginit, arena);
-  bool ok = _upb_array_append_accessor(
-      msg, UPB_SIZE(36, 56), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena);
+  bool ok = _upb_array_append_accessor2(
+      msg, UPB_SIZE(32, 48), UPB_SIZE(2, 3), &sub, arena);
   if (!ok) return NULL;
   return sub;
 }
 UPB_INLINE void envoy_config_core_v3_ApiConfigSource_set_request_timeout(envoy_config_core_v3_ApiConfigSource *msg, struct google_protobuf_Duration* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(24, 32), struct google_protobuf_Duration*) = value;
+  _upb_sethas(msg, 2);
+  *UPB_PTR_AT(msg, UPB_SIZE(20, 24), struct google_protobuf_Duration*) = value;
 }
 UPB_INLINE struct google_protobuf_Duration* envoy_config_core_v3_ApiConfigSource_mutable_request_timeout(envoy_config_core_v3_ApiConfigSource *msg, upb_arena *arena) {
   struct google_protobuf_Duration* sub = (struct google_protobuf_Duration*)envoy_config_core_v3_ApiConfigSource_request_timeout(msg);
@@ -139,7 +148,8 @@ UPB_INLINE struct google_protobuf_Duration* envoy_config_core_v3_ApiConfigSource
   return sub;
 }
 UPB_INLINE void envoy_config_core_v3_ApiConfigSource_set_rate_limit_settings(envoy_config_core_v3_ApiConfigSource *msg, envoy_config_core_v3_RateLimitSettings* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(28, 40), envoy_config_core_v3_RateLimitSettings*) = value;
+  _upb_sethas(msg, 3);
+  *UPB_PTR_AT(msg, UPB_SIZE(24, 32), envoy_config_core_v3_RateLimitSettings*) = value;
 }
 UPB_INLINE struct envoy_config_core_v3_RateLimitSettings* envoy_config_core_v3_ApiConfigSource_mutable_rate_limit_settings(envoy_config_core_v3_ApiConfigSource *msg, upb_arena *arena) {
   struct envoy_config_core_v3_RateLimitSettings* sub = (struct envoy_config_core_v3_RateLimitSettings*)envoy_config_core_v3_ApiConfigSource_rate_limit_settings(msg);
@@ -151,7 +161,7 @@ UPB_INLINE struct envoy_config_core_v3_RateLimitSettings* envoy_config_core_v3_A
   return sub;
 }
 UPB_INLINE void envoy_config_core_v3_ApiConfigSource_set_set_node_on_first_message_only(envoy_config_core_v3_ApiConfigSource *msg, bool value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(16, 16), bool) = value;
+  *UPB_PTR_AT(msg, UPB_SIZE(12, 12), bool) = value;
 }
 UPB_INLINE void envoy_config_core_v3_ApiConfigSource_set_transport_api_version(envoy_config_core_v3_ApiConfigSource *msg, int32_t value) {
   *UPB_PTR_AT(msg, UPB_SIZE(8, 8), int32_t) = value;
@@ -167,6 +177,12 @@ UPB_INLINE envoy_config_core_v3_AggregatedConfigSource *envoy_config_core_v3_Agg
   envoy_config_core_v3_AggregatedConfigSource *ret = envoy_config_core_v3_AggregatedConfigSource_new(arena);
   return (ret && upb_decode(buf, size, ret, &envoy_config_core_v3_AggregatedConfigSource_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE envoy_config_core_v3_AggregatedConfigSource *envoy_config_core_v3_AggregatedConfigSource_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  envoy_config_core_v3_AggregatedConfigSource *ret = envoy_config_core_v3_AggregatedConfigSource_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &envoy_config_core_v3_AggregatedConfigSource_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *envoy_config_core_v3_AggregatedConfigSource_serialize(const envoy_config_core_v3_AggregatedConfigSource *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &envoy_config_core_v3_AggregatedConfigSource_msginit, arena, len);
 }
@@ -183,6 +199,12 @@ UPB_INLINE envoy_config_core_v3_SelfConfigSource *envoy_config_core_v3_SelfConfi
   envoy_config_core_v3_SelfConfigSource *ret = envoy_config_core_v3_SelfConfigSource_new(arena);
   return (ret && upb_decode(buf, size, ret, &envoy_config_core_v3_SelfConfigSource_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE envoy_config_core_v3_SelfConfigSource *envoy_config_core_v3_SelfConfigSource_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  envoy_config_core_v3_SelfConfigSource *ret = envoy_config_core_v3_SelfConfigSource_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &envoy_config_core_v3_SelfConfigSource_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *envoy_config_core_v3_SelfConfigSource_serialize(const envoy_config_core_v3_SelfConfigSource *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &envoy_config_core_v3_SelfConfigSource_msginit, arena, len);
 }
@@ -203,17 +225,24 @@ UPB_INLINE envoy_config_core_v3_RateLimitSettings *envoy_config_core_v3_RateLimi
   envoy_config_core_v3_RateLimitSettings *ret = envoy_config_core_v3_RateLimitSettings_new(arena);
   return (ret && upb_decode(buf, size, ret, &envoy_config_core_v3_RateLimitSettings_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE envoy_config_core_v3_RateLimitSettings *envoy_config_core_v3_RateLimitSettings_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  envoy_config_core_v3_RateLimitSettings *ret = envoy_config_core_v3_RateLimitSettings_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &envoy_config_core_v3_RateLimitSettings_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *envoy_config_core_v3_RateLimitSettings_serialize(const envoy_config_core_v3_RateLimitSettings *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &envoy_config_core_v3_RateLimitSettings_msginit, arena, len);
 }
 
-UPB_INLINE bool envoy_config_core_v3_RateLimitSettings_has_max_tokens(const envoy_config_core_v3_RateLimitSettings *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(0, 0)); }
-UPB_INLINE const struct google_protobuf_UInt32Value* envoy_config_core_v3_RateLimitSettings_max_tokens(const envoy_config_core_v3_RateLimitSettings *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(0, 0), const struct google_protobuf_UInt32Value*); }
-UPB_INLINE bool envoy_config_core_v3_RateLimitSettings_has_fill_rate(const envoy_config_core_v3_RateLimitSettings *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(4, 8)); }
-UPB_INLINE const struct google_protobuf_DoubleValue* envoy_config_core_v3_RateLimitSettings_fill_rate(const envoy_config_core_v3_RateLimitSettings *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(4, 8), const struct google_protobuf_DoubleValue*); }
+UPB_INLINE bool envoy_config_core_v3_RateLimitSettings_has_max_tokens(const envoy_config_core_v3_RateLimitSettings *msg) { return _upb_hasbit(msg, 1); }
+UPB_INLINE const struct google_protobuf_UInt32Value* envoy_config_core_v3_RateLimitSettings_max_tokens(const envoy_config_core_v3_RateLimitSettings *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(4, 8), const struct google_protobuf_UInt32Value*); }
+UPB_INLINE bool envoy_config_core_v3_RateLimitSettings_has_fill_rate(const envoy_config_core_v3_RateLimitSettings *msg) { return _upb_hasbit(msg, 2); }
+UPB_INLINE const struct google_protobuf_DoubleValue* envoy_config_core_v3_RateLimitSettings_fill_rate(const envoy_config_core_v3_RateLimitSettings *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(8, 16), const struct google_protobuf_DoubleValue*); }
 
 UPB_INLINE void envoy_config_core_v3_RateLimitSettings_set_max_tokens(envoy_config_core_v3_RateLimitSettings *msg, struct google_protobuf_UInt32Value* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(0, 0), struct google_protobuf_UInt32Value*) = value;
+  _upb_sethas(msg, 1);
+  *UPB_PTR_AT(msg, UPB_SIZE(4, 8), struct google_protobuf_UInt32Value*) = value;
 }
 UPB_INLINE struct google_protobuf_UInt32Value* envoy_config_core_v3_RateLimitSettings_mutable_max_tokens(envoy_config_core_v3_RateLimitSettings *msg, upb_arena *arena) {
   struct google_protobuf_UInt32Value* sub = (struct google_protobuf_UInt32Value*)envoy_config_core_v3_RateLimitSettings_max_tokens(msg);
@@ -225,7 +254,8 @@ UPB_INLINE struct google_protobuf_UInt32Value* envoy_config_core_v3_RateLimitSet
   return sub;
 }
 UPB_INLINE void envoy_config_core_v3_RateLimitSettings_set_fill_rate(envoy_config_core_v3_RateLimitSettings *msg, struct google_protobuf_DoubleValue* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(4, 8), struct google_protobuf_DoubleValue*) = value;
+  _upb_sethas(msg, 2);
+  *UPB_PTR_AT(msg, UPB_SIZE(8, 16), struct google_protobuf_DoubleValue*) = value;
 }
 UPB_INLINE struct google_protobuf_DoubleValue* envoy_config_core_v3_RateLimitSettings_mutable_fill_rate(envoy_config_core_v3_RateLimitSettings *msg, upb_arena *arena) {
   struct google_protobuf_DoubleValue* sub = (struct google_protobuf_DoubleValue*)envoy_config_core_v3_RateLimitSettings_fill_rate(msg);
@@ -247,6 +277,12 @@ UPB_INLINE envoy_config_core_v3_ConfigSource *envoy_config_core_v3_ConfigSource_
   envoy_config_core_v3_ConfigSource *ret = envoy_config_core_v3_ConfigSource_new(arena);
   return (ret && upb_decode(buf, size, ret, &envoy_config_core_v3_ConfigSource_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE envoy_config_core_v3_ConfigSource *envoy_config_core_v3_ConfigSource_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  envoy_config_core_v3_ConfigSource *ret = envoy_config_core_v3_ConfigSource_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &envoy_config_core_v3_ConfigSource_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *envoy_config_core_v3_ConfigSource_serialize(const envoy_config_core_v3_ConfigSource *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &envoy_config_core_v3_ConfigSource_msginit, arena, len);
 }
@@ -266,11 +302,11 @@ UPB_INLINE bool envoy_config_core_v3_ConfigSource_has_api_config_source(const en
 UPB_INLINE const envoy_config_core_v3_ApiConfigSource* envoy_config_core_v3_ConfigSource_api_config_source(const envoy_config_core_v3_ConfigSource *msg) { return UPB_READ_ONEOF(msg, const envoy_config_core_v3_ApiConfigSource*, UPB_SIZE(16, 24), UPB_SIZE(24, 40), 2, NULL); }
 UPB_INLINE bool envoy_config_core_v3_ConfigSource_has_ads(const envoy_config_core_v3_ConfigSource *msg) { return _upb_getoneofcase(msg, UPB_SIZE(24, 40)) == 3; }
 UPB_INLINE const envoy_config_core_v3_AggregatedConfigSource* envoy_config_core_v3_ConfigSource_ads(const envoy_config_core_v3_ConfigSource *msg) { return UPB_READ_ONEOF(msg, const envoy_config_core_v3_AggregatedConfigSource*, UPB_SIZE(16, 24), UPB_SIZE(24, 40), 3, NULL); }
-UPB_INLINE bool envoy_config_core_v3_ConfigSource_has_initial_fetch_timeout(const envoy_config_core_v3_ConfigSource *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(8, 8)); }
+UPB_INLINE bool envoy_config_core_v3_ConfigSource_has_initial_fetch_timeout(const envoy_config_core_v3_ConfigSource *msg) { return _upb_hasbit(msg, 1); }
 UPB_INLINE const struct google_protobuf_Duration* envoy_config_core_v3_ConfigSource_initial_fetch_timeout(const envoy_config_core_v3_ConfigSource *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(8, 8), const struct google_protobuf_Duration*); }
 UPB_INLINE bool envoy_config_core_v3_ConfigSource_has_self(const envoy_config_core_v3_ConfigSource *msg) { return _upb_getoneofcase(msg, UPB_SIZE(24, 40)) == 5; }
 UPB_INLINE const envoy_config_core_v3_SelfConfigSource* envoy_config_core_v3_ConfigSource_self(const envoy_config_core_v3_ConfigSource *msg) { return UPB_READ_ONEOF(msg, const envoy_config_core_v3_SelfConfigSource*, UPB_SIZE(16, 24), UPB_SIZE(24, 40), 5, NULL); }
-UPB_INLINE int32_t envoy_config_core_v3_ConfigSource_resource_api_version(const envoy_config_core_v3_ConfigSource *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(0, 0), int32_t); }
+UPB_INLINE int32_t envoy_config_core_v3_ConfigSource_resource_api_version(const envoy_config_core_v3_ConfigSource *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(4, 4), int32_t); }
 UPB_INLINE bool envoy_config_core_v3_ConfigSource_has_authorities(const envoy_config_core_v3_ConfigSource *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(12, 16)); }
 UPB_INLINE const struct udpa_core_v1_Authority* const* envoy_config_core_v3_ConfigSource_authorities(const envoy_config_core_v3_ConfigSource *msg, size_t *len) { return (const struct udpa_core_v1_Authority* const*)_upb_array_accessor(msg, UPB_SIZE(12, 16), len); }
 
@@ -302,6 +338,7 @@ UPB_INLINE struct envoy_config_core_v3_AggregatedConfigSource* envoy_config_core
   return sub;
 }
 UPB_INLINE void envoy_config_core_v3_ConfigSource_set_initial_fetch_timeout(envoy_config_core_v3_ConfigSource *msg, struct google_protobuf_Duration* value) {
+  _upb_sethas(msg, 1);
   *UPB_PTR_AT(msg, UPB_SIZE(8, 8), struct google_protobuf_Duration*) = value;
 }
 UPB_INLINE struct google_protobuf_Duration* envoy_config_core_v3_ConfigSource_mutable_initial_fetch_timeout(envoy_config_core_v3_ConfigSource *msg, upb_arena *arena) {
@@ -326,18 +363,18 @@ UPB_INLINE struct envoy_config_core_v3_SelfConfigSource* envoy_config_core_v3_Co
   return sub;
 }
 UPB_INLINE void envoy_config_core_v3_ConfigSource_set_resource_api_version(envoy_config_core_v3_ConfigSource *msg, int32_t value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(0, 0), int32_t) = value;
+  *UPB_PTR_AT(msg, UPB_SIZE(4, 4), int32_t) = value;
 }
 UPB_INLINE struct udpa_core_v1_Authority** envoy_config_core_v3_ConfigSource_mutable_authorities(envoy_config_core_v3_ConfigSource *msg, size_t *len) {
   return (struct udpa_core_v1_Authority**)_upb_array_mutable_accessor(msg, UPB_SIZE(12, 16), len);
 }
 UPB_INLINE struct udpa_core_v1_Authority** envoy_config_core_v3_ConfigSource_resize_authorities(envoy_config_core_v3_ConfigSource *msg, size_t len, upb_arena *arena) {
-  return (struct udpa_core_v1_Authority**)_upb_array_resize_accessor(msg, UPB_SIZE(12, 16), len, UPB_TYPE_MESSAGE, arena);
+  return (struct udpa_core_v1_Authority**)_upb_array_resize_accessor2(msg, UPB_SIZE(12, 16), len, UPB_SIZE(2, 3), arena);
 }
 UPB_INLINE struct udpa_core_v1_Authority* envoy_config_core_v3_ConfigSource_add_authorities(envoy_config_core_v3_ConfigSource *msg, upb_arena *arena) {
   struct udpa_core_v1_Authority* sub = (struct udpa_core_v1_Authority*)_upb_msg_new(&udpa_core_v1_Authority_msginit, arena);
-  bool ok = _upb_array_append_accessor(
-      msg, UPB_SIZE(12, 16), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena);
+  bool ok = _upb_array_append_accessor2(
+      msg, UPB_SIZE(12, 16), UPB_SIZE(2, 3), &sub, arena);
   if (!ok) return NULL;
   return sub;
 }
index 1d02920..3f89247 100644 (file)
@@ -27,7 +27,7 @@ static const upb_msglayout_field envoy_config_core_v3_EventServiceConfig__fields
 const upb_msglayout envoy_config_core_v3_EventServiceConfig_msginit = {
   &envoy_config_core_v3_EventServiceConfig_submsgs[0],
   &envoy_config_core_v3_EventServiceConfig__fields[0],
-  UPB_SIZE(8, 16), 1, false,
+  UPB_SIZE(8, 16), 1, false, 255,
 };
 
 #include "upb/port_undef.inc"
index 3d7bb0a..3069f4c 100644 (file)
@@ -11,6 +11,7 @@
 
 #include "upb/msg.h"
 #include "upb/decode.h"
+#include "upb/decode_fast.h"
 #include "upb/encode.h"
 
 #include "upb/port_def.inc"
@@ -36,6 +37,12 @@ UPB_INLINE envoy_config_core_v3_EventServiceConfig *envoy_config_core_v3_EventSe
   envoy_config_core_v3_EventServiceConfig *ret = envoy_config_core_v3_EventServiceConfig_new(arena);
   return (ret && upb_decode(buf, size, ret, &envoy_config_core_v3_EventServiceConfig_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE envoy_config_core_v3_EventServiceConfig *envoy_config_core_v3_EventServiceConfig_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  envoy_config_core_v3_EventServiceConfig *ret = envoy_config_core_v3_EventServiceConfig_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &envoy_config_core_v3_EventServiceConfig_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *envoy_config_core_v3_EventServiceConfig_serialize(const envoy_config_core_v3_EventServiceConfig *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &envoy_config_core_v3_EventServiceConfig_msginit, arena, len);
 }
index 0fe1d60..47b8b32 100644 (file)
@@ -21,14 +21,14 @@ static const upb_msglayout *const envoy_config_core_v3_TypedExtensionConfig_subm
 };
 
 static const upb_msglayout_field envoy_config_core_v3_TypedExtensionConfig__fields[2] = {
-  {1, UPB_SIZE(0, 0), 0, 0, 9, 1},
-  {2, UPB_SIZE(8, 16), 0, 0, 11, 1},
+  {1, UPB_SIZE(4, 8), 0, 0, 9, 1},
+  {2, UPB_SIZE(12, 24), 1, 0, 11, 1},
 };
 
 const upb_msglayout envoy_config_core_v3_TypedExtensionConfig_msginit = {
   &envoy_config_core_v3_TypedExtensionConfig_submsgs[0],
   &envoy_config_core_v3_TypedExtensionConfig__fields[0],
-  UPB_SIZE(16, 32), 2, false,
+  UPB_SIZE(16, 32), 2, false, 255,
 };
 
 static const upb_msglayout *const envoy_config_core_v3_ExtensionConfigSource_submsgs[2] = {
@@ -37,16 +37,16 @@ static const upb_msglayout *const envoy_config_core_v3_ExtensionConfigSource_sub
 };
 
 static const upb_msglayout_field envoy_config_core_v3_ExtensionConfigSource__fields[4] = {
-  {1, UPB_SIZE(4, 8), 0, 0, 11, 1},
-  {2, UPB_SIZE(8, 16), 0, 1, 11, 1},
-  {3, UPB_SIZE(0, 0), 0, 0, 8, 1},
+  {1, UPB_SIZE(4, 8), 1, 0, 11, 1},
+  {2, UPB_SIZE(8, 16), 2, 1, 11, 1},
+  {3, UPB_SIZE(1, 1), 0, 0, 8, 1},
   {4, UPB_SIZE(12, 24), 0, 0, 9, 3},
 };
 
 const upb_msglayout envoy_config_core_v3_ExtensionConfigSource_msginit = {
   &envoy_config_core_v3_ExtensionConfigSource_submsgs[0],
   &envoy_config_core_v3_ExtensionConfigSource__fields[0],
-  UPB_SIZE(16, 32), 4, false,
+  UPB_SIZE(16, 32), 4, false, 255,
 };
 
 #include "upb/port_undef.inc"
index d70b5bc..8499bfc 100644 (file)
@@ -11,6 +11,7 @@
 
 #include "upb/msg.h"
 #include "upb/decode.h"
+#include "upb/decode_fast.h"
 #include "upb/encode.h"
 
 #include "upb/port_def.inc"
@@ -41,19 +42,26 @@ UPB_INLINE envoy_config_core_v3_TypedExtensionConfig *envoy_config_core_v3_Typed
   envoy_config_core_v3_TypedExtensionConfig *ret = envoy_config_core_v3_TypedExtensionConfig_new(arena);
   return (ret && upb_decode(buf, size, ret, &envoy_config_core_v3_TypedExtensionConfig_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE envoy_config_core_v3_TypedExtensionConfig *envoy_config_core_v3_TypedExtensionConfig_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  envoy_config_core_v3_TypedExtensionConfig *ret = envoy_config_core_v3_TypedExtensionConfig_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &envoy_config_core_v3_TypedExtensionConfig_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *envoy_config_core_v3_TypedExtensionConfig_serialize(const envoy_config_core_v3_TypedExtensionConfig *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &envoy_config_core_v3_TypedExtensionConfig_msginit, arena, len);
 }
 
-UPB_INLINE upb_strview envoy_config_core_v3_TypedExtensionConfig_name(const envoy_config_core_v3_TypedExtensionConfig *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(0, 0), upb_strview); }
-UPB_INLINE bool envoy_config_core_v3_TypedExtensionConfig_has_typed_config(const envoy_config_core_v3_TypedExtensionConfig *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(8, 16)); }
-UPB_INLINE const struct google_protobuf_Any* envoy_config_core_v3_TypedExtensionConfig_typed_config(const envoy_config_core_v3_TypedExtensionConfig *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(8, 16), const struct google_protobuf_Any*); }
+UPB_INLINE upb_strview envoy_config_core_v3_TypedExtensionConfig_name(const envoy_config_core_v3_TypedExtensionConfig *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(4, 8), upb_strview); }
+UPB_INLINE bool envoy_config_core_v3_TypedExtensionConfig_has_typed_config(const envoy_config_core_v3_TypedExtensionConfig *msg) { return _upb_hasbit(msg, 1); }
+UPB_INLINE const struct google_protobuf_Any* envoy_config_core_v3_TypedExtensionConfig_typed_config(const envoy_config_core_v3_TypedExtensionConfig *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(12, 24), const struct google_protobuf_Any*); }
 
 UPB_INLINE void envoy_config_core_v3_TypedExtensionConfig_set_name(envoy_config_core_v3_TypedExtensionConfig *msg, upb_strview value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(0, 0), upb_strview) = value;
+  *UPB_PTR_AT(msg, UPB_SIZE(4, 8), upb_strview) = value;
 }
 UPB_INLINE void envoy_config_core_v3_TypedExtensionConfig_set_typed_config(envoy_config_core_v3_TypedExtensionConfig *msg, struct google_protobuf_Any* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(8, 16), struct google_protobuf_Any*) = value;
+  _upb_sethas(msg, 1);
+  *UPB_PTR_AT(msg, UPB_SIZE(12, 24), struct google_protobuf_Any*) = value;
 }
 UPB_INLINE struct google_protobuf_Any* envoy_config_core_v3_TypedExtensionConfig_mutable_typed_config(envoy_config_core_v3_TypedExtensionConfig *msg, upb_arena *arena) {
   struct google_protobuf_Any* sub = (struct google_protobuf_Any*)envoy_config_core_v3_TypedExtensionConfig_typed_config(msg);
@@ -75,18 +83,25 @@ UPB_INLINE envoy_config_core_v3_ExtensionConfigSource *envoy_config_core_v3_Exte
   envoy_config_core_v3_ExtensionConfigSource *ret = envoy_config_core_v3_ExtensionConfigSource_new(arena);
   return (ret && upb_decode(buf, size, ret, &envoy_config_core_v3_ExtensionConfigSource_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE envoy_config_core_v3_ExtensionConfigSource *envoy_config_core_v3_ExtensionConfigSource_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  envoy_config_core_v3_ExtensionConfigSource *ret = envoy_config_core_v3_ExtensionConfigSource_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &envoy_config_core_v3_ExtensionConfigSource_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *envoy_config_core_v3_ExtensionConfigSource_serialize(const envoy_config_core_v3_ExtensionConfigSource *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &envoy_config_core_v3_ExtensionConfigSource_msginit, arena, len);
 }
 
-UPB_INLINE bool envoy_config_core_v3_ExtensionConfigSource_has_config_source(const envoy_config_core_v3_ExtensionConfigSource *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(4, 8)); }
+UPB_INLINE bool envoy_config_core_v3_ExtensionConfigSource_has_config_source(const envoy_config_core_v3_ExtensionConfigSource *msg) { return _upb_hasbit(msg, 1); }
 UPB_INLINE const struct envoy_config_core_v3_ConfigSource* envoy_config_core_v3_ExtensionConfigSource_config_source(const envoy_config_core_v3_ExtensionConfigSource *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(4, 8), const struct envoy_config_core_v3_ConfigSource*); }
-UPB_INLINE bool envoy_config_core_v3_ExtensionConfigSource_has_default_config(const envoy_config_core_v3_ExtensionConfigSource *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(8, 16)); }
+UPB_INLINE bool envoy_config_core_v3_ExtensionConfigSource_has_default_config(const envoy_config_core_v3_ExtensionConfigSource *msg) { return _upb_hasbit(msg, 2); }
 UPB_INLINE const struct google_protobuf_Any* envoy_config_core_v3_ExtensionConfigSource_default_config(const envoy_config_core_v3_ExtensionConfigSource *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(8, 16), const struct google_protobuf_Any*); }
-UPB_INLINE bool envoy_config_core_v3_ExtensionConfigSource_apply_default_config_without_warming(const envoy_config_core_v3_ExtensionConfigSource *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(0, 0), bool); }
+UPB_INLINE bool envoy_config_core_v3_ExtensionConfigSource_apply_default_config_without_warming(const envoy_config_core_v3_ExtensionConfigSource *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(1, 1), bool); }
 UPB_INLINE upb_strview const* envoy_config_core_v3_ExtensionConfigSource_type_urls(const envoy_config_core_v3_ExtensionConfigSource *msg, size_t *len) { return (upb_strview const*)_upb_array_accessor(msg, UPB_SIZE(12, 24), len); }
 
 UPB_INLINE void envoy_config_core_v3_ExtensionConfigSource_set_config_source(envoy_config_core_v3_ExtensionConfigSource *msg, struct envoy_config_core_v3_ConfigSource* value) {
+  _upb_sethas(msg, 1);
   *UPB_PTR_AT(msg, UPB_SIZE(4, 8), struct envoy_config_core_v3_ConfigSource*) = value;
 }
 UPB_INLINE struct envoy_config_core_v3_ConfigSource* envoy_config_core_v3_ExtensionConfigSource_mutable_config_source(envoy_config_core_v3_ExtensionConfigSource *msg, upb_arena *arena) {
@@ -99,6 +114,7 @@ UPB_INLINE struct envoy_config_core_v3_ConfigSource* envoy_config_core_v3_Extens
   return sub;
 }
 UPB_INLINE void envoy_config_core_v3_ExtensionConfigSource_set_default_config(envoy_config_core_v3_ExtensionConfigSource *msg, struct google_protobuf_Any* value) {
+  _upb_sethas(msg, 2);
   *UPB_PTR_AT(msg, UPB_SIZE(8, 16), struct google_protobuf_Any*) = value;
 }
 UPB_INLINE struct google_protobuf_Any* envoy_config_core_v3_ExtensionConfigSource_mutable_default_config(envoy_config_core_v3_ExtensionConfigSource *msg, upb_arena *arena) {
@@ -111,16 +127,16 @@ UPB_INLINE struct google_protobuf_Any* envoy_config_core_v3_ExtensionConfigSourc
   return sub;
 }
 UPB_INLINE void envoy_config_core_v3_ExtensionConfigSource_set_apply_default_config_without_warming(envoy_config_core_v3_ExtensionConfigSource *msg, bool value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(0, 0), bool) = value;
+  *UPB_PTR_AT(msg, UPB_SIZE(1, 1), bool) = value;
 }
 UPB_INLINE upb_strview* envoy_config_core_v3_ExtensionConfigSource_mutable_type_urls(envoy_config_core_v3_ExtensionConfigSource *msg, size_t *len) {
   return (upb_strview*)_upb_array_mutable_accessor(msg, UPB_SIZE(12, 24), len);
 }
 UPB_INLINE upb_strview* envoy_config_core_v3_ExtensionConfigSource_resize_type_urls(envoy_config_core_v3_ExtensionConfigSource *msg, size_t len, upb_arena *arena) {
-  return (upb_strview*)_upb_array_resize_accessor(msg, UPB_SIZE(12, 24), len, UPB_TYPE_STRING, arena);
+  return (upb_strview*)_upb_array_resize_accessor2(msg, UPB_SIZE(12, 24), len, UPB_SIZE(3, 4), arena);
 }
 UPB_INLINE bool envoy_config_core_v3_ExtensionConfigSource_add_type_urls(envoy_config_core_v3_ExtensionConfigSource *msg, upb_strview val, upb_arena *arena) {
-  return _upb_array_append_accessor(msg, UPB_SIZE(12, 24), UPB_SIZE(8, 16), UPB_TYPE_STRING, &val,
+  return _upb_array_append_accessor2(msg, UPB_SIZE(12, 24), UPB_SIZE(3, 4), &val,
       arena);
 }
 
index f956bb4..b2e99df 100644 (file)
@@ -30,16 +30,16 @@ static const upb_msglayout *const envoy_config_core_v3_GrpcService_submsgs[4] =
 };
 
 static const upb_msglayout_field envoy_config_core_v3_GrpcService__fields[4] = {
-  {1, UPB_SIZE(8, 16), UPB_SIZE(-13, -25), 0, 11, 1},
-  {2, UPB_SIZE(8, 16), UPB_SIZE(-13, -25), 1, 11, 1},
-  {3, UPB_SIZE(0, 0), 0, 3, 11, 1},
-  {5, UPB_SIZE(4, 8), 0, 2, 11, 3},
+  {1, UPB_SIZE(12, 24), UPB_SIZE(-17, -33), 0, 11, 1},
+  {2, UPB_SIZE(12, 24), UPB_SIZE(-17, -33), 1, 11, 1},
+  {3, UPB_SIZE(4, 8), 1, 3, 11, 1},
+  {5, UPB_SIZE(8, 16), 0, 2, 11, 3},
 };
 
 const upb_msglayout envoy_config_core_v3_GrpcService_msginit = {
   &envoy_config_core_v3_GrpcService_submsgs[0],
   &envoy_config_core_v3_GrpcService__fields[0],
-  UPB_SIZE(16, 32), 4, false,
+  UPB_SIZE(24, 40), 4, false, 255,
 };
 
 static const upb_msglayout_field envoy_config_core_v3_GrpcService_EnvoyGrpc__fields[2] = {
@@ -50,7 +50,7 @@ static const upb_msglayout_field envoy_config_core_v3_GrpcService_EnvoyGrpc__fie
 const upb_msglayout envoy_config_core_v3_GrpcService_EnvoyGrpc_msginit = {
   NULL,
   &envoy_config_core_v3_GrpcService_EnvoyGrpc__fields[0],
-  UPB_SIZE(16, 32), 2, false,
+  UPB_SIZE(16, 32), 2, false, 255,
 };
 
 static const upb_msglayout *const envoy_config_core_v3_GrpcService_GoogleGrpc_submsgs[5] = {
@@ -62,42 +62,42 @@ static const upb_msglayout *const envoy_config_core_v3_GrpcService_GoogleGrpc_su
 };
 
 static const upb_msglayout_field envoy_config_core_v3_GrpcService_GoogleGrpc__fields[8] = {
-  {1, UPB_SIZE(0, 0), 0, 0, 9, 1},
-  {2, UPB_SIZE(24, 48), 0, 2, 11, 1},
-  {3, UPB_SIZE(40, 80), 0, 0, 11, 3},
-  {4, UPB_SIZE(8, 16), 0, 0, 9, 1},
-  {5, UPB_SIZE(16, 32), 0, 0, 9, 1},
-  {6, UPB_SIZE(28, 56), 0, 3, 11, 1},
-  {7, UPB_SIZE(32, 64), 0, 4, 11, 1},
-  {8, UPB_SIZE(36, 72), 0, 1, 11, 1},
+  {1, UPB_SIZE(4, 8), 0, 0, 9, 1},
+  {2, UPB_SIZE(28, 56), 1, 2, 11, 1},
+  {3, UPB_SIZE(44, 88), 0, 0, 11, 3},
+  {4, UPB_SIZE(12, 24), 0, 0, 9, 1},
+  {5, UPB_SIZE(20, 40), 0, 0, 9, 1},
+  {6, UPB_SIZE(32, 64), 2, 3, 11, 1},
+  {7, UPB_SIZE(36, 72), 3, 4, 11, 1},
+  {8, UPB_SIZE(40, 80), 4, 1, 11, 1},
 };
 
 const upb_msglayout envoy_config_core_v3_GrpcService_GoogleGrpc_msginit = {
   &envoy_config_core_v3_GrpcService_GoogleGrpc_submsgs[0],
   &envoy_config_core_v3_GrpcService_GoogleGrpc__fields[0],
-  UPB_SIZE(48, 96), 8, false,
+  UPB_SIZE(48, 96), 8, false, 255,
 };
 
-static const upb_msglayout *const envoy_config_core_v3_GrpcService_GoogleGrpc_SslCredentials_submsgs[3] = {
+static const upb_msglayout *const envoy_config_core_v3_GrpcService_GoogleGrpc_SslCredentials_submsgs[1] = {
   &envoy_config_core_v3_DataSource_msginit,
 };
 
 static const upb_msglayout_field envoy_config_core_v3_GrpcService_GoogleGrpc_SslCredentials__fields[3] = {
-  {1, UPB_SIZE(0, 0), 0, 0, 11, 1},
-  {2, UPB_SIZE(4, 8), 0, 0, 11, 1},
-  {3, UPB_SIZE(8, 16), 0, 0, 11, 1},
+  {1, UPB_SIZE(4, 8), 1, 0, 11, 1},
+  {2, UPB_SIZE(8, 16), 2, 0, 11, 1},
+  {3, UPB_SIZE(12, 24), 3, 0, 11, 1},
 };
 
 const upb_msglayout envoy_config_core_v3_GrpcService_GoogleGrpc_SslCredentials_msginit = {
   &envoy_config_core_v3_GrpcService_GoogleGrpc_SslCredentials_submsgs[0],
   &envoy_config_core_v3_GrpcService_GoogleGrpc_SslCredentials__fields[0],
-  UPB_SIZE(12, 24), 3, false,
+  UPB_SIZE(16, 32), 3, false, 255,
 };
 
 const upb_msglayout envoy_config_core_v3_GrpcService_GoogleGrpc_GoogleLocalCredentials_msginit = {
   NULL,
   NULL,
-  UPB_SIZE(0, 0), 0, false,
+  UPB_SIZE(0, 0), 0, false, 255,
 };
 
 static const upb_msglayout *const envoy_config_core_v3_GrpcService_GoogleGrpc_ChannelCredentials_submsgs[3] = {
@@ -115,7 +115,7 @@ static const upb_msglayout_field envoy_config_core_v3_GrpcService_GoogleGrpc_Cha
 const upb_msglayout envoy_config_core_v3_GrpcService_GoogleGrpc_ChannelCredentials_msginit = {
   &envoy_config_core_v3_GrpcService_GoogleGrpc_ChannelCredentials_submsgs[0],
   &envoy_config_core_v3_GrpcService_GoogleGrpc_ChannelCredentials__fields[0],
-  UPB_SIZE(8, 16), 3, false,
+  UPB_SIZE(8, 16), 3, false, 255,
 };
 
 static const upb_msglayout *const envoy_config_core_v3_GrpcService_GoogleGrpc_CallCredentials_submsgs[5] = {
@@ -139,7 +139,7 @@ static const upb_msglayout_field envoy_config_core_v3_GrpcService_GoogleGrpc_Cal
 const upb_msglayout envoy_config_core_v3_GrpcService_GoogleGrpc_CallCredentials_msginit = {
   &envoy_config_core_v3_GrpcService_GoogleGrpc_CallCredentials_submsgs[0],
   &envoy_config_core_v3_GrpcService_GoogleGrpc_CallCredentials__fields[0],
-  UPB_SIZE(16, 32), 7, false,
+  UPB_SIZE(16, 32), 7, false, 255,
 };
 
 static const upb_msglayout_field envoy_config_core_v3_GrpcService_GoogleGrpc_CallCredentials_ServiceAccountJWTAccessCredentials__fields[2] = {
@@ -150,7 +150,7 @@ static const upb_msglayout_field envoy_config_core_v3_GrpcService_GoogleGrpc_Cal
 const upb_msglayout envoy_config_core_v3_GrpcService_GoogleGrpc_CallCredentials_ServiceAccountJWTAccessCredentials_msginit = {
   NULL,
   &envoy_config_core_v3_GrpcService_GoogleGrpc_CallCredentials_ServiceAccountJWTAccessCredentials__fields[0],
-  UPB_SIZE(16, 32), 2, false,
+  UPB_SIZE(16, 32), 2, false, 255,
 };
 
 static const upb_msglayout_field envoy_config_core_v3_GrpcService_GoogleGrpc_CallCredentials_GoogleIAMCredentials__fields[2] = {
@@ -161,7 +161,7 @@ static const upb_msglayout_field envoy_config_core_v3_GrpcService_GoogleGrpc_Cal
 const upb_msglayout envoy_config_core_v3_GrpcService_GoogleGrpc_CallCredentials_GoogleIAMCredentials_msginit = {
   NULL,
   &envoy_config_core_v3_GrpcService_GoogleGrpc_CallCredentials_GoogleIAMCredentials__fields[0],
-  UPB_SIZE(16, 32), 2, false,
+  UPB_SIZE(16, 32), 2, false, 255,
 };
 
 static const upb_msglayout *const envoy_config_core_v3_GrpcService_GoogleGrpc_CallCredentials_MetadataCredentialsFromPlugin_submsgs[1] = {
@@ -176,7 +176,7 @@ static const upb_msglayout_field envoy_config_core_v3_GrpcService_GoogleGrpc_Cal
 const upb_msglayout envoy_config_core_v3_GrpcService_GoogleGrpc_CallCredentials_MetadataCredentialsFromPlugin_msginit = {
   &envoy_config_core_v3_GrpcService_GoogleGrpc_CallCredentials_MetadataCredentialsFromPlugin_submsgs[0],
   &envoy_config_core_v3_GrpcService_GoogleGrpc_CallCredentials_MetadataCredentialsFromPlugin__fields[0],
-  UPB_SIZE(16, 32), 2, false,
+  UPB_SIZE(16, 32), 2, false, 255,
 };
 
 static const upb_msglayout_field envoy_config_core_v3_GrpcService_GoogleGrpc_CallCredentials_StsService__fields[9] = {
@@ -194,7 +194,7 @@ static const upb_msglayout_field envoy_config_core_v3_GrpcService_GoogleGrpc_Cal
 const upb_msglayout envoy_config_core_v3_GrpcService_GoogleGrpc_CallCredentials_StsService_msginit = {
   NULL,
   &envoy_config_core_v3_GrpcService_GoogleGrpc_CallCredentials_StsService__fields[0],
-  UPB_SIZE(72, 144), 9, false,
+  UPB_SIZE(72, 144), 9, false, 255,
 };
 
 static const upb_msglayout *const envoy_config_core_v3_GrpcService_GoogleGrpc_ChannelArgs_submsgs[1] = {
@@ -208,7 +208,7 @@ static const upb_msglayout_field envoy_config_core_v3_GrpcService_GoogleGrpc_Cha
 const upb_msglayout envoy_config_core_v3_GrpcService_GoogleGrpc_ChannelArgs_msginit = {
   &envoy_config_core_v3_GrpcService_GoogleGrpc_ChannelArgs_submsgs[0],
   &envoy_config_core_v3_GrpcService_GoogleGrpc_ChannelArgs__fields[0],
-  UPB_SIZE(4, 8), 1, false,
+  UPB_SIZE(8, 8), 1, false, 255,
 };
 
 static const upb_msglayout_field envoy_config_core_v3_GrpcService_GoogleGrpc_ChannelArgs_Value__fields[2] = {
@@ -219,7 +219,7 @@ static const upb_msglayout_field envoy_config_core_v3_GrpcService_GoogleGrpc_Cha
 const upb_msglayout envoy_config_core_v3_GrpcService_GoogleGrpc_ChannelArgs_Value_msginit = {
   NULL,
   &envoy_config_core_v3_GrpcService_GoogleGrpc_ChannelArgs_Value__fields[0],
-  UPB_SIZE(16, 32), 2, false,
+  UPB_SIZE(16, 32), 2, false, 255,
 };
 
 static const upb_msglayout *const envoy_config_core_v3_GrpcService_GoogleGrpc_ChannelArgs_ArgsEntry_submsgs[1] = {
@@ -234,7 +234,7 @@ static const upb_msglayout_field envoy_config_core_v3_GrpcService_GoogleGrpc_Cha
 const upb_msglayout envoy_config_core_v3_GrpcService_GoogleGrpc_ChannelArgs_ArgsEntry_msginit = {
   &envoy_config_core_v3_GrpcService_GoogleGrpc_ChannelArgs_ArgsEntry_submsgs[0],
   &envoy_config_core_v3_GrpcService_GoogleGrpc_ChannelArgs_ArgsEntry__fields[0],
-  UPB_SIZE(16, 32), 2, false,
+  UPB_SIZE(16, 32), 2, false, 255,
 };
 
 #include "upb/port_undef.inc"
index 0f8acca..dd9913d 100644 (file)
@@ -11,6 +11,7 @@
 
 #include "upb/msg.h"
 #include "upb/decode.h"
+#include "upb/decode_fast.h"
 #include "upb/encode.h"
 
 #include "upb/port_def.inc"
@@ -87,6 +88,12 @@ UPB_INLINE envoy_config_core_v3_GrpcService *envoy_config_core_v3_GrpcService_pa
   envoy_config_core_v3_GrpcService *ret = envoy_config_core_v3_GrpcService_new(arena);
   return (ret && upb_decode(buf, size, ret, &envoy_config_core_v3_GrpcService_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE envoy_config_core_v3_GrpcService *envoy_config_core_v3_GrpcService_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  envoy_config_core_v3_GrpcService *ret = envoy_config_core_v3_GrpcService_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &envoy_config_core_v3_GrpcService_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *envoy_config_core_v3_GrpcService_serialize(const envoy_config_core_v3_GrpcService *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &envoy_config_core_v3_GrpcService_msginit, arena, len);
 }
@@ -96,19 +103,19 @@ typedef enum {
   envoy_config_core_v3_GrpcService_target_specifier_google_grpc = 2,
   envoy_config_core_v3_GrpcService_target_specifier_NOT_SET = 0
 } envoy_config_core_v3_GrpcService_target_specifier_oneofcases;
-UPB_INLINE envoy_config_core_v3_GrpcService_target_specifier_oneofcases envoy_config_core_v3_GrpcService_target_specifier_case(const envoy_config_core_v3_GrpcService* msg) { return (envoy_config_core_v3_GrpcService_target_specifier_oneofcases)*UPB_PTR_AT(msg, UPB_SIZE(12, 24), int32_t); }
+UPB_INLINE envoy_config_core_v3_GrpcService_target_specifier_oneofcases envoy_config_core_v3_GrpcService_target_specifier_case(const envoy_config_core_v3_GrpcService* msg) { return (envoy_config_core_v3_GrpcService_target_specifier_oneofcases)*UPB_PTR_AT(msg, UPB_SIZE(16, 32), int32_t); }
 
-UPB_INLINE bool envoy_config_core_v3_GrpcService_has_envoy_grpc(const envoy_config_core_v3_GrpcService *msg) { return _upb_getoneofcase(msg, UPB_SIZE(12, 24)) == 1; }
-UPB_INLINE const envoy_config_core_v3_GrpcService_EnvoyGrpc* envoy_config_core_v3_GrpcService_envoy_grpc(const envoy_config_core_v3_GrpcService *msg) { return UPB_READ_ONEOF(msg, const envoy_config_core_v3_GrpcService_EnvoyGrpc*, UPB_SIZE(8, 16), UPB_SIZE(12, 24), 1, NULL); }
-UPB_INLINE bool envoy_config_core_v3_GrpcService_has_google_grpc(const envoy_config_core_v3_GrpcService *msg) { return _upb_getoneofcase(msg, UPB_SIZE(12, 24)) == 2; }
-UPB_INLINE const envoy_config_core_v3_GrpcService_GoogleGrpc* envoy_config_core_v3_GrpcService_google_grpc(const envoy_config_core_v3_GrpcService *msg) { return UPB_READ_ONEOF(msg, const envoy_config_core_v3_GrpcService_GoogleGrpc*, UPB_SIZE(8, 16), UPB_SIZE(12, 24), 2, NULL); }
-UPB_INLINE bool envoy_config_core_v3_GrpcService_has_timeout(const envoy_config_core_v3_GrpcService *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(0, 0)); }
-UPB_INLINE const struct google_protobuf_Duration* envoy_config_core_v3_GrpcService_timeout(const envoy_config_core_v3_GrpcService *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(0, 0), const struct google_protobuf_Duration*); }
-UPB_INLINE bool envoy_config_core_v3_GrpcService_has_initial_metadata(const envoy_config_core_v3_GrpcService *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(4, 8)); }
-UPB_INLINE const struct envoy_config_core_v3_HeaderValue* const* envoy_config_core_v3_GrpcService_initial_metadata(const envoy_config_core_v3_GrpcService *msg, size_t *len) { return (const struct envoy_config_core_v3_HeaderValue* const*)_upb_array_accessor(msg, UPB_SIZE(4, 8), len); }
+UPB_INLINE bool envoy_config_core_v3_GrpcService_has_envoy_grpc(const envoy_config_core_v3_GrpcService *msg) { return _upb_getoneofcase(msg, UPB_SIZE(16, 32)) == 1; }
+UPB_INLINE const envoy_config_core_v3_GrpcService_EnvoyGrpc* envoy_config_core_v3_GrpcService_envoy_grpc(const envoy_config_core_v3_GrpcService *msg) { return UPB_READ_ONEOF(msg, const envoy_config_core_v3_GrpcService_EnvoyGrpc*, UPB_SIZE(12, 24), UPB_SIZE(16, 32), 1, NULL); }
+UPB_INLINE bool envoy_config_core_v3_GrpcService_has_google_grpc(const envoy_config_core_v3_GrpcService *msg) { return _upb_getoneofcase(msg, UPB_SIZE(16, 32)) == 2; }
+UPB_INLINE const envoy_config_core_v3_GrpcService_GoogleGrpc* envoy_config_core_v3_GrpcService_google_grpc(const envoy_config_core_v3_GrpcService *msg) { return UPB_READ_ONEOF(msg, const envoy_config_core_v3_GrpcService_GoogleGrpc*, UPB_SIZE(12, 24), UPB_SIZE(16, 32), 2, NULL); }
+UPB_INLINE bool envoy_config_core_v3_GrpcService_has_timeout(const envoy_config_core_v3_GrpcService *msg) { return _upb_hasbit(msg, 1); }
+UPB_INLINE const struct google_protobuf_Duration* envoy_config_core_v3_GrpcService_timeout(const envoy_config_core_v3_GrpcService *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(4, 8), const struct google_protobuf_Duration*); }
+UPB_INLINE bool envoy_config_core_v3_GrpcService_has_initial_metadata(const envoy_config_core_v3_GrpcService *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(8, 16)); }
+UPB_INLINE const struct envoy_config_core_v3_HeaderValue* const* envoy_config_core_v3_GrpcService_initial_metadata(const envoy_config_core_v3_GrpcService *msg, size_t *len) { return (const struct envoy_config_core_v3_HeaderValue* const*)_upb_array_accessor(msg, UPB_SIZE(8, 16), len); }
 
 UPB_INLINE void envoy_config_core_v3_GrpcService_set_envoy_grpc(envoy_config_core_v3_GrpcService *msg, envoy_config_core_v3_GrpcService_EnvoyGrpc* value) {
-  UPB_WRITE_ONEOF(msg, envoy_config_core_v3_GrpcService_EnvoyGrpc*, UPB_SIZE(8, 16), value, UPB_SIZE(12, 24), 1);
+  UPB_WRITE_ONEOF(msg, envoy_config_core_v3_GrpcService_EnvoyGrpc*, UPB_SIZE(12, 24), value, UPB_SIZE(16, 32), 1);
 }
 UPB_INLINE struct envoy_config_core_v3_GrpcService_EnvoyGrpc* envoy_config_core_v3_GrpcService_mutable_envoy_grpc(envoy_config_core_v3_GrpcService *msg, upb_arena *arena) {
   struct envoy_config_core_v3_GrpcService_EnvoyGrpc* sub = (struct envoy_config_core_v3_GrpcService_EnvoyGrpc*)envoy_config_core_v3_GrpcService_envoy_grpc(msg);
@@ -120,7 +127,7 @@ UPB_INLINE struct envoy_config_core_v3_GrpcService_EnvoyGrpc* envoy_config_core_
   return sub;
 }
 UPB_INLINE void envoy_config_core_v3_GrpcService_set_google_grpc(envoy_config_core_v3_GrpcService *msg, envoy_config_core_v3_GrpcService_GoogleGrpc* value) {
-  UPB_WRITE_ONEOF(msg, envoy_config_core_v3_GrpcService_GoogleGrpc*, UPB_SIZE(8, 16), value, UPB_SIZE(12, 24), 2);
+  UPB_WRITE_ONEOF(msg, envoy_config_core_v3_GrpcService_GoogleGrpc*, UPB_SIZE(12, 24), value, UPB_SIZE(16, 32), 2);
 }
 UPB_INLINE struct envoy_config_core_v3_GrpcService_GoogleGrpc* envoy_config_core_v3_GrpcService_mutable_google_grpc(envoy_config_core_v3_GrpcService *msg, upb_arena *arena) {
   struct envoy_config_core_v3_GrpcService_GoogleGrpc* sub = (struct envoy_config_core_v3_GrpcService_GoogleGrpc*)envoy_config_core_v3_GrpcService_google_grpc(msg);
@@ -132,7 +139,8 @@ UPB_INLINE struct envoy_config_core_v3_GrpcService_GoogleGrpc* envoy_config_core
   return sub;
 }
 UPB_INLINE void envoy_config_core_v3_GrpcService_set_timeout(envoy_config_core_v3_GrpcService *msg, struct google_protobuf_Duration* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(0, 0), struct google_protobuf_Duration*) = value;
+  _upb_sethas(msg, 1);
+  *UPB_PTR_AT(msg, UPB_SIZE(4, 8), struct google_protobuf_Duration*) = value;
 }
 UPB_INLINE struct google_protobuf_Duration* envoy_config_core_v3_GrpcService_mutable_timeout(envoy_config_core_v3_GrpcService *msg, upb_arena *arena) {
   struct google_protobuf_Duration* sub = (struct google_protobuf_Duration*)envoy_config_core_v3_GrpcService_timeout(msg);
@@ -144,15 +152,15 @@ UPB_INLINE struct google_protobuf_Duration* envoy_config_core_v3_GrpcService_mut
   return sub;
 }
 UPB_INLINE struct envoy_config_core_v3_HeaderValue** envoy_config_core_v3_GrpcService_mutable_initial_metadata(envoy_config_core_v3_GrpcService *msg, size_t *len) {
-  return (struct envoy_config_core_v3_HeaderValue**)_upb_array_mutable_accessor(msg, UPB_SIZE(4, 8), len);
+  return (struct envoy_config_core_v3_HeaderValue**)_upb_array_mutable_accessor(msg, UPB_SIZE(8, 16), len);
 }
 UPB_INLINE struct envoy_config_core_v3_HeaderValue** envoy_config_core_v3_GrpcService_resize_initial_metadata(envoy_config_core_v3_GrpcService *msg, size_t len, upb_arena *arena) {
-  return (struct envoy_config_core_v3_HeaderValue**)_upb_array_resize_accessor(msg, UPB_SIZE(4, 8), len, UPB_TYPE_MESSAGE, arena);
+  return (struct envoy_config_core_v3_HeaderValue**)_upb_array_resize_accessor2(msg, UPB_SIZE(8, 16), len, UPB_SIZE(2, 3), arena);
 }
 UPB_INLINE struct envoy_config_core_v3_HeaderValue* envoy_config_core_v3_GrpcService_add_initial_metadata(envoy_config_core_v3_GrpcService *msg, upb_arena *arena) {
   struct envoy_config_core_v3_HeaderValue* sub = (struct envoy_config_core_v3_HeaderValue*)_upb_msg_new(&envoy_config_core_v3_HeaderValue_msginit, arena);
-  bool ok = _upb_array_append_accessor(
-      msg, UPB_SIZE(4, 8), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena);
+  bool ok = _upb_array_append_accessor2(
+      msg, UPB_SIZE(8, 16), UPB_SIZE(2, 3), &sub, arena);
   if (!ok) return NULL;
   return sub;
 }
@@ -167,6 +175,12 @@ UPB_INLINE envoy_config_core_v3_GrpcService_EnvoyGrpc *envoy_config_core_v3_Grpc
   envoy_config_core_v3_GrpcService_EnvoyGrpc *ret = envoy_config_core_v3_GrpcService_EnvoyGrpc_new(arena);
   return (ret && upb_decode(buf, size, ret, &envoy_config_core_v3_GrpcService_EnvoyGrpc_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE envoy_config_core_v3_GrpcService_EnvoyGrpc *envoy_config_core_v3_GrpcService_EnvoyGrpc_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  envoy_config_core_v3_GrpcService_EnvoyGrpc *ret = envoy_config_core_v3_GrpcService_EnvoyGrpc_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &envoy_config_core_v3_GrpcService_EnvoyGrpc_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *envoy_config_core_v3_GrpcService_EnvoyGrpc_serialize(const envoy_config_core_v3_GrpcService_EnvoyGrpc *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &envoy_config_core_v3_GrpcService_EnvoyGrpc_msginit, arena, len);
 }
@@ -191,29 +205,36 @@ UPB_INLINE envoy_config_core_v3_GrpcService_GoogleGrpc *envoy_config_core_v3_Grp
   envoy_config_core_v3_GrpcService_GoogleGrpc *ret = envoy_config_core_v3_GrpcService_GoogleGrpc_new(arena);
   return (ret && upb_decode(buf, size, ret, &envoy_config_core_v3_GrpcService_GoogleGrpc_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE envoy_config_core_v3_GrpcService_GoogleGrpc *envoy_config_core_v3_GrpcService_GoogleGrpc_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  envoy_config_core_v3_GrpcService_GoogleGrpc *ret = envoy_config_core_v3_GrpcService_GoogleGrpc_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &envoy_config_core_v3_GrpcService_GoogleGrpc_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *envoy_config_core_v3_GrpcService_GoogleGrpc_serialize(const envoy_config_core_v3_GrpcService_GoogleGrpc *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &envoy_config_core_v3_GrpcService_GoogleGrpc_msginit, arena, len);
 }
 
-UPB_INLINE upb_strview envoy_config_core_v3_GrpcService_GoogleGrpc_target_uri(const envoy_config_core_v3_GrpcService_GoogleGrpc *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(0, 0), upb_strview); }
-UPB_INLINE bool envoy_config_core_v3_GrpcService_GoogleGrpc_has_channel_credentials(const envoy_config_core_v3_GrpcService_GoogleGrpc *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(24, 48)); }
-UPB_INLINE const envoy_config_core_v3_GrpcService_GoogleGrpc_ChannelCredentials* envoy_config_core_v3_GrpcService_GoogleGrpc_channel_credentials(const envoy_config_core_v3_GrpcService_GoogleGrpc *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(24, 48), const envoy_config_core_v3_GrpcService_GoogleGrpc_ChannelCredentials*); }
-UPB_INLINE bool envoy_config_core_v3_GrpcService_GoogleGrpc_has_call_credentials(const envoy_config_core_v3_GrpcService_GoogleGrpc *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(40, 80)); }
-UPB_INLINE const envoy_config_core_v3_GrpcService_GoogleGrpc_CallCredentials* const* envoy_config_core_v3_GrpcService_GoogleGrpc_call_credentials(const envoy_config_core_v3_GrpcService_GoogleGrpc *msg, size_t *len) { return (const envoy_config_core_v3_GrpcService_GoogleGrpc_CallCredentials* const*)_upb_array_accessor(msg, UPB_SIZE(40, 80), len); }
-UPB_INLINE upb_strview envoy_config_core_v3_GrpcService_GoogleGrpc_stat_prefix(const envoy_config_core_v3_GrpcService_GoogleGrpc *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(8, 16), upb_strview); }
-UPB_INLINE upb_strview envoy_config_core_v3_GrpcService_GoogleGrpc_credentials_factory_name(const envoy_config_core_v3_GrpcService_GoogleGrpc *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(16, 32), upb_strview); }
-UPB_INLINE bool envoy_config_core_v3_GrpcService_GoogleGrpc_has_config(const envoy_config_core_v3_GrpcService_GoogleGrpc *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(28, 56)); }
-UPB_INLINE const struct google_protobuf_Struct* envoy_config_core_v3_GrpcService_GoogleGrpc_config(const envoy_config_core_v3_GrpcService_GoogleGrpc *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(28, 56), const struct google_protobuf_Struct*); }
-UPB_INLINE bool envoy_config_core_v3_GrpcService_GoogleGrpc_has_per_stream_buffer_limit_bytes(const envoy_config_core_v3_GrpcService_GoogleGrpc *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(32, 64)); }
-UPB_INLINE const struct google_protobuf_UInt32Value* envoy_config_core_v3_GrpcService_GoogleGrpc_per_stream_buffer_limit_bytes(const envoy_config_core_v3_GrpcService_GoogleGrpc *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(32, 64), const struct google_protobuf_UInt32Value*); }
-UPB_INLINE bool envoy_config_core_v3_GrpcService_GoogleGrpc_has_channel_args(const envoy_config_core_v3_GrpcService_GoogleGrpc *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(36, 72)); }
-UPB_INLINE const envoy_config_core_v3_GrpcService_GoogleGrpc_ChannelArgs* envoy_config_core_v3_GrpcService_GoogleGrpc_channel_args(const envoy_config_core_v3_GrpcService_GoogleGrpc *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(36, 72), const envoy_config_core_v3_GrpcService_GoogleGrpc_ChannelArgs*); }
+UPB_INLINE upb_strview envoy_config_core_v3_GrpcService_GoogleGrpc_target_uri(const envoy_config_core_v3_GrpcService_GoogleGrpc *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(4, 8), upb_strview); }
+UPB_INLINE bool envoy_config_core_v3_GrpcService_GoogleGrpc_has_channel_credentials(const envoy_config_core_v3_GrpcService_GoogleGrpc *msg) { return _upb_hasbit(msg, 1); }
+UPB_INLINE const envoy_config_core_v3_GrpcService_GoogleGrpc_ChannelCredentials* envoy_config_core_v3_GrpcService_GoogleGrpc_channel_credentials(const envoy_config_core_v3_GrpcService_GoogleGrpc *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(28, 56), const envoy_config_core_v3_GrpcService_GoogleGrpc_ChannelCredentials*); }
+UPB_INLINE bool envoy_config_core_v3_GrpcService_GoogleGrpc_has_call_credentials(const envoy_config_core_v3_GrpcService_GoogleGrpc *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(44, 88)); }
+UPB_INLINE const envoy_config_core_v3_GrpcService_GoogleGrpc_CallCredentials* const* envoy_config_core_v3_GrpcService_GoogleGrpc_call_credentials(const envoy_config_core_v3_GrpcService_GoogleGrpc *msg, size_t *len) { return (const envoy_config_core_v3_GrpcService_GoogleGrpc_CallCredentials* const*)_upb_array_accessor(msg, UPB_SIZE(44, 88), len); }
+UPB_INLINE upb_strview envoy_config_core_v3_GrpcService_GoogleGrpc_stat_prefix(const envoy_config_core_v3_GrpcService_GoogleGrpc *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(12, 24), upb_strview); }
+UPB_INLINE upb_strview envoy_config_core_v3_GrpcService_GoogleGrpc_credentials_factory_name(const envoy_config_core_v3_GrpcService_GoogleGrpc *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(20, 40), upb_strview); }
+UPB_INLINE bool envoy_config_core_v3_GrpcService_GoogleGrpc_has_config(const envoy_config_core_v3_GrpcService_GoogleGrpc *msg) { return _upb_hasbit(msg, 2); }
+UPB_INLINE const struct google_protobuf_Struct* envoy_config_core_v3_GrpcService_GoogleGrpc_config(const envoy_config_core_v3_GrpcService_GoogleGrpc *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(32, 64), const struct google_protobuf_Struct*); }
+UPB_INLINE bool envoy_config_core_v3_GrpcService_GoogleGrpc_has_per_stream_buffer_limit_bytes(const envoy_config_core_v3_GrpcService_GoogleGrpc *msg) { return _upb_hasbit(msg, 3); }
+UPB_INLINE const struct google_protobuf_UInt32Value* envoy_config_core_v3_GrpcService_GoogleGrpc_per_stream_buffer_limit_bytes(const envoy_config_core_v3_GrpcService_GoogleGrpc *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(36, 72), const struct google_protobuf_UInt32Value*); }
+UPB_INLINE bool envoy_config_core_v3_GrpcService_GoogleGrpc_has_channel_args(const envoy_config_core_v3_GrpcService_GoogleGrpc *msg) { return _upb_hasbit(msg, 4); }
+UPB_INLINE const envoy_config_core_v3_GrpcService_GoogleGrpc_ChannelArgs* envoy_config_core_v3_GrpcService_GoogleGrpc_channel_args(const envoy_config_core_v3_GrpcService_GoogleGrpc *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(40, 80), const envoy_config_core_v3_GrpcService_GoogleGrpc_ChannelArgs*); }
 
 UPB_INLINE void envoy_config_core_v3_GrpcService_GoogleGrpc_set_target_uri(envoy_config_core_v3_GrpcService_GoogleGrpc *msg, upb_strview value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(0, 0), upb_strview) = value;
+  *UPB_PTR_AT(msg, UPB_SIZE(4, 8), upb_strview) = value;
 }
 UPB_INLINE void envoy_config_core_v3_GrpcService_GoogleGrpc_set_channel_credentials(envoy_config_core_v3_GrpcService_GoogleGrpc *msg, envoy_config_core_v3_GrpcService_GoogleGrpc_ChannelCredentials* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(24, 48), envoy_config_core_v3_GrpcService_GoogleGrpc_ChannelCredentials*) = value;
+  _upb_sethas(msg, 1);
+  *UPB_PTR_AT(msg, UPB_SIZE(28, 56), envoy_config_core_v3_GrpcService_GoogleGrpc_ChannelCredentials*) = value;
 }
 UPB_INLINE struct envoy_config_core_v3_GrpcService_GoogleGrpc_ChannelCredentials* envoy_config_core_v3_GrpcService_GoogleGrpc_mutable_channel_credentials(envoy_config_core_v3_GrpcService_GoogleGrpc *msg, upb_arena *arena) {
   struct envoy_config_core_v3_GrpcService_GoogleGrpc_ChannelCredentials* sub = (struct envoy_config_core_v3_GrpcService_GoogleGrpc_ChannelCredentials*)envoy_config_core_v3_GrpcService_GoogleGrpc_channel_credentials(msg);
@@ -225,26 +246,27 @@ UPB_INLINE struct envoy_config_core_v3_GrpcService_GoogleGrpc_ChannelCredentials
   return sub;
 }
 UPB_INLINE envoy_config_core_v3_GrpcService_GoogleGrpc_CallCredentials** envoy_config_core_v3_GrpcService_GoogleGrpc_mutable_call_credentials(envoy_config_core_v3_GrpcService_GoogleGrpc *msg, size_t *len) {
-  return (envoy_config_core_v3_GrpcService_GoogleGrpc_CallCredentials**)_upb_array_mutable_accessor(msg, UPB_SIZE(40, 80), len);
+  return (envoy_config_core_v3_GrpcService_GoogleGrpc_CallCredentials**)_upb_array_mutable_accessor(msg, UPB_SIZE(44, 88), len);
 }
 UPB_INLINE envoy_config_core_v3_GrpcService_GoogleGrpc_CallCredentials** envoy_config_core_v3_GrpcService_GoogleGrpc_resize_call_credentials(envoy_config_core_v3_GrpcService_GoogleGrpc *msg, size_t len, upb_arena *arena) {
-  return (envoy_config_core_v3_GrpcService_GoogleGrpc_CallCredentials**)_upb_array_resize_accessor(msg, UPB_SIZE(40, 80), len, UPB_TYPE_MESSAGE, arena);
+  return (envoy_config_core_v3_GrpcService_GoogleGrpc_CallCredentials**)_upb_array_resize_accessor2(msg, UPB_SIZE(44, 88), len, UPB_SIZE(2, 3), arena);
 }
 UPB_INLINE struct envoy_config_core_v3_GrpcService_GoogleGrpc_CallCredentials* envoy_config_core_v3_GrpcService_GoogleGrpc_add_call_credentials(envoy_config_core_v3_GrpcService_GoogleGrpc *msg, upb_arena *arena) {
   struct envoy_config_core_v3_GrpcService_GoogleGrpc_CallCredentials* sub = (struct envoy_config_core_v3_GrpcService_GoogleGrpc_CallCredentials*)_upb_msg_new(&envoy_config_core_v3_GrpcService_GoogleGrpc_CallCredentials_msginit, arena);
-  bool ok = _upb_array_append_accessor(
-      msg, UPB_SIZE(40, 80), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena);
+  bool ok = _upb_array_append_accessor2(
+      msg, UPB_SIZE(44, 88), UPB_SIZE(2, 3), &sub, arena);
   if (!ok) return NULL;
   return sub;
 }
 UPB_INLINE void envoy_config_core_v3_GrpcService_GoogleGrpc_set_stat_prefix(envoy_config_core_v3_GrpcService_GoogleGrpc *msg, upb_strview value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(8, 16), upb_strview) = value;
+  *UPB_PTR_AT(msg, UPB_SIZE(12, 24), upb_strview) = value;
 }
 UPB_INLINE void envoy_config_core_v3_GrpcService_GoogleGrpc_set_credentials_factory_name(envoy_config_core_v3_GrpcService_GoogleGrpc *msg, upb_strview value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(16, 32), upb_strview) = value;
+  *UPB_PTR_AT(msg, UPB_SIZE(20, 40), upb_strview) = value;
 }
 UPB_INLINE void envoy_config_core_v3_GrpcService_GoogleGrpc_set_config(envoy_config_core_v3_GrpcService_GoogleGrpc *msg, struct google_protobuf_Struct* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(28, 56), struct google_protobuf_Struct*) = value;
+  _upb_sethas(msg, 2);
+  *UPB_PTR_AT(msg, UPB_SIZE(32, 64), struct google_protobuf_Struct*) = value;
 }
 UPB_INLINE struct google_protobuf_Struct* envoy_config_core_v3_GrpcService_GoogleGrpc_mutable_config(envoy_config_core_v3_GrpcService_GoogleGrpc *msg, upb_arena *arena) {
   struct google_protobuf_Struct* sub = (struct google_protobuf_Struct*)envoy_config_core_v3_GrpcService_GoogleGrpc_config(msg);
@@ -256,7 +278,8 @@ UPB_INLINE struct google_protobuf_Struct* envoy_config_core_v3_GrpcService_Googl
   return sub;
 }
 UPB_INLINE void envoy_config_core_v3_GrpcService_GoogleGrpc_set_per_stream_buffer_limit_bytes(envoy_config_core_v3_GrpcService_GoogleGrpc *msg, struct google_protobuf_UInt32Value* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(32, 64), struct google_protobuf_UInt32Value*) = value;
+  _upb_sethas(msg, 3);
+  *UPB_PTR_AT(msg, UPB_SIZE(36, 72), struct google_protobuf_UInt32Value*) = value;
 }
 UPB_INLINE struct google_protobuf_UInt32Value* envoy_config_core_v3_GrpcService_GoogleGrpc_mutable_per_stream_buffer_limit_bytes(envoy_config_core_v3_GrpcService_GoogleGrpc *msg, upb_arena *arena) {
   struct google_protobuf_UInt32Value* sub = (struct google_protobuf_UInt32Value*)envoy_config_core_v3_GrpcService_GoogleGrpc_per_stream_buffer_limit_bytes(msg);
@@ -268,7 +291,8 @@ UPB_INLINE struct google_protobuf_UInt32Value* envoy_config_core_v3_GrpcService_
   return sub;
 }
 UPB_INLINE void envoy_config_core_v3_GrpcService_GoogleGrpc_set_channel_args(envoy_config_core_v3_GrpcService_GoogleGrpc *msg, envoy_config_core_v3_GrpcService_GoogleGrpc_ChannelArgs* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(36, 72), envoy_config_core_v3_GrpcService_GoogleGrpc_ChannelArgs*) = value;
+  _upb_sethas(msg, 4);
+  *UPB_PTR_AT(msg, UPB_SIZE(40, 80), envoy_config_core_v3_GrpcService_GoogleGrpc_ChannelArgs*) = value;
 }
 UPB_INLINE struct envoy_config_core_v3_GrpcService_GoogleGrpc_ChannelArgs* envoy_config_core_v3_GrpcService_GoogleGrpc_mutable_channel_args(envoy_config_core_v3_GrpcService_GoogleGrpc *msg, upb_arena *arena) {
   struct envoy_config_core_v3_GrpcService_GoogleGrpc_ChannelArgs* sub = (struct envoy_config_core_v3_GrpcService_GoogleGrpc_ChannelArgs*)envoy_config_core_v3_GrpcService_GoogleGrpc_channel_args(msg);
@@ -290,19 +314,26 @@ UPB_INLINE envoy_config_core_v3_GrpcService_GoogleGrpc_SslCredentials *envoy_con
   envoy_config_core_v3_GrpcService_GoogleGrpc_SslCredentials *ret = envoy_config_core_v3_GrpcService_GoogleGrpc_SslCredentials_new(arena);
   return (ret && upb_decode(buf, size, ret, &envoy_config_core_v3_GrpcService_GoogleGrpc_SslCredentials_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE envoy_config_core_v3_GrpcService_GoogleGrpc_SslCredentials *envoy_config_core_v3_GrpcService_GoogleGrpc_SslCredentials_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  envoy_config_core_v3_GrpcService_GoogleGrpc_SslCredentials *ret = envoy_config_core_v3_GrpcService_GoogleGrpc_SslCredentials_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &envoy_config_core_v3_GrpcService_GoogleGrpc_SslCredentials_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *envoy_config_core_v3_GrpcService_GoogleGrpc_SslCredentials_serialize(const envoy_config_core_v3_GrpcService_GoogleGrpc_SslCredentials *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &envoy_config_core_v3_GrpcService_GoogleGrpc_SslCredentials_msginit, arena, len);
 }
 
-UPB_INLINE bool envoy_config_core_v3_GrpcService_GoogleGrpc_SslCredentials_has_root_certs(const envoy_config_core_v3_GrpcService_GoogleGrpc_SslCredentials *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(0, 0)); }
-UPB_INLINE const struct envoy_config_core_v3_DataSource* envoy_config_core_v3_GrpcService_GoogleGrpc_SslCredentials_root_certs(const envoy_config_core_v3_GrpcService_GoogleGrpc_SslCredentials *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(0, 0), const struct envoy_config_core_v3_DataSource*); }
-UPB_INLINE bool envoy_config_core_v3_GrpcService_GoogleGrpc_SslCredentials_has_private_key(const envoy_config_core_v3_GrpcService_GoogleGrpc_SslCredentials *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(4, 8)); }
-UPB_INLINE const struct envoy_config_core_v3_DataSource* envoy_config_core_v3_GrpcService_GoogleGrpc_SslCredentials_private_key(const envoy_config_core_v3_GrpcService_GoogleGrpc_SslCredentials *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(4, 8), const struct envoy_config_core_v3_DataSource*); }
-UPB_INLINE bool envoy_config_core_v3_GrpcService_GoogleGrpc_SslCredentials_has_cert_chain(const envoy_config_core_v3_GrpcService_GoogleGrpc_SslCredentials *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(8, 16)); }
-UPB_INLINE const struct envoy_config_core_v3_DataSource* envoy_config_core_v3_GrpcService_GoogleGrpc_SslCredentials_cert_chain(const envoy_config_core_v3_GrpcService_GoogleGrpc_SslCredentials *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(8, 16), const struct envoy_config_core_v3_DataSource*); }
+UPB_INLINE bool envoy_config_core_v3_GrpcService_GoogleGrpc_SslCredentials_has_root_certs(const envoy_config_core_v3_GrpcService_GoogleGrpc_SslCredentials *msg) { return _upb_hasbit(msg, 1); }
+UPB_INLINE const struct envoy_config_core_v3_DataSource* envoy_config_core_v3_GrpcService_GoogleGrpc_SslCredentials_root_certs(const envoy_config_core_v3_GrpcService_GoogleGrpc_SslCredentials *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(4, 8), const struct envoy_config_core_v3_DataSource*); }
+UPB_INLINE bool envoy_config_core_v3_GrpcService_GoogleGrpc_SslCredentials_has_private_key(const envoy_config_core_v3_GrpcService_GoogleGrpc_SslCredentials *msg) { return _upb_hasbit(msg, 2); }
+UPB_INLINE const struct envoy_config_core_v3_DataSource* envoy_config_core_v3_GrpcService_GoogleGrpc_SslCredentials_private_key(const envoy_config_core_v3_GrpcService_GoogleGrpc_SslCredentials *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(8, 16), const struct envoy_config_core_v3_DataSource*); }
+UPB_INLINE bool envoy_config_core_v3_GrpcService_GoogleGrpc_SslCredentials_has_cert_chain(const envoy_config_core_v3_GrpcService_GoogleGrpc_SslCredentials *msg) { return _upb_hasbit(msg, 3); }
+UPB_INLINE const struct envoy_config_core_v3_DataSource* envoy_config_core_v3_GrpcService_GoogleGrpc_SslCredentials_cert_chain(const envoy_config_core_v3_GrpcService_GoogleGrpc_SslCredentials *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(12, 24), const struct envoy_config_core_v3_DataSource*); }
 
 UPB_INLINE void envoy_config_core_v3_GrpcService_GoogleGrpc_SslCredentials_set_root_certs(envoy_config_core_v3_GrpcService_GoogleGrpc_SslCredentials *msg, struct envoy_config_core_v3_DataSource* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(0, 0), struct envoy_config_core_v3_DataSource*) = value;
+  _upb_sethas(msg, 1);
+  *UPB_PTR_AT(msg, UPB_SIZE(4, 8), struct envoy_config_core_v3_DataSource*) = value;
 }
 UPB_INLINE struct envoy_config_core_v3_DataSource* envoy_config_core_v3_GrpcService_GoogleGrpc_SslCredentials_mutable_root_certs(envoy_config_core_v3_GrpcService_GoogleGrpc_SslCredentials *msg, upb_arena *arena) {
   struct envoy_config_core_v3_DataSource* sub = (struct envoy_config_core_v3_DataSource*)envoy_config_core_v3_GrpcService_GoogleGrpc_SslCredentials_root_certs(msg);
@@ -314,7 +345,8 @@ UPB_INLINE struct envoy_config_core_v3_DataSource* envoy_config_core_v3_GrpcServ
   return sub;
 }
 UPB_INLINE void envoy_config_core_v3_GrpcService_GoogleGrpc_SslCredentials_set_private_key(envoy_config_core_v3_GrpcService_GoogleGrpc_SslCredentials *msg, struct envoy_config_core_v3_DataSource* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(4, 8), struct envoy_config_core_v3_DataSource*) = value;
+  _upb_sethas(msg, 2);
+  *UPB_PTR_AT(msg, UPB_SIZE(8, 16), struct envoy_config_core_v3_DataSource*) = value;
 }
 UPB_INLINE struct envoy_config_core_v3_DataSource* envoy_config_core_v3_GrpcService_GoogleGrpc_SslCredentials_mutable_private_key(envoy_config_core_v3_GrpcService_GoogleGrpc_SslCredentials *msg, upb_arena *arena) {
   struct envoy_config_core_v3_DataSource* sub = (struct envoy_config_core_v3_DataSource*)envoy_config_core_v3_GrpcService_GoogleGrpc_SslCredentials_private_key(msg);
@@ -326,7 +358,8 @@ UPB_INLINE struct envoy_config_core_v3_DataSource* envoy_config_core_v3_GrpcServ
   return sub;
 }
 UPB_INLINE void envoy_config_core_v3_GrpcService_GoogleGrpc_SslCredentials_set_cert_chain(envoy_config_core_v3_GrpcService_GoogleGrpc_SslCredentials *msg, struct envoy_config_core_v3_DataSource* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(8, 16), struct envoy_config_core_v3_DataSource*) = value;
+  _upb_sethas(msg, 3);
+  *UPB_PTR_AT(msg, UPB_SIZE(12, 24), struct envoy_config_core_v3_DataSource*) = value;
 }
 UPB_INLINE struct envoy_config_core_v3_DataSource* envoy_config_core_v3_GrpcService_GoogleGrpc_SslCredentials_mutable_cert_chain(envoy_config_core_v3_GrpcService_GoogleGrpc_SslCredentials *msg, upb_arena *arena) {
   struct envoy_config_core_v3_DataSource* sub = (struct envoy_config_core_v3_DataSource*)envoy_config_core_v3_GrpcService_GoogleGrpc_SslCredentials_cert_chain(msg);
@@ -348,6 +381,12 @@ UPB_INLINE envoy_config_core_v3_GrpcService_GoogleGrpc_GoogleLocalCredentials *e
   envoy_config_core_v3_GrpcService_GoogleGrpc_GoogleLocalCredentials *ret = envoy_config_core_v3_GrpcService_GoogleGrpc_GoogleLocalCredentials_new(arena);
   return (ret && upb_decode(buf, size, ret, &envoy_config_core_v3_GrpcService_GoogleGrpc_GoogleLocalCredentials_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE envoy_config_core_v3_GrpcService_GoogleGrpc_GoogleLocalCredentials *envoy_config_core_v3_GrpcService_GoogleGrpc_GoogleLocalCredentials_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  envoy_config_core_v3_GrpcService_GoogleGrpc_GoogleLocalCredentials *ret = envoy_config_core_v3_GrpcService_GoogleGrpc_GoogleLocalCredentials_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &envoy_config_core_v3_GrpcService_GoogleGrpc_GoogleLocalCredentials_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *envoy_config_core_v3_GrpcService_GoogleGrpc_GoogleLocalCredentials_serialize(const envoy_config_core_v3_GrpcService_GoogleGrpc_GoogleLocalCredentials *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &envoy_config_core_v3_GrpcService_GoogleGrpc_GoogleLocalCredentials_msginit, arena, len);
 }
@@ -364,6 +403,12 @@ UPB_INLINE envoy_config_core_v3_GrpcService_GoogleGrpc_ChannelCredentials *envoy
   envoy_config_core_v3_GrpcService_GoogleGrpc_ChannelCredentials *ret = envoy_config_core_v3_GrpcService_GoogleGrpc_ChannelCredentials_new(arena);
   return (ret && upb_decode(buf, size, ret, &envoy_config_core_v3_GrpcService_GoogleGrpc_ChannelCredentials_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE envoy_config_core_v3_GrpcService_GoogleGrpc_ChannelCredentials *envoy_config_core_v3_GrpcService_GoogleGrpc_ChannelCredentials_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  envoy_config_core_v3_GrpcService_GoogleGrpc_ChannelCredentials *ret = envoy_config_core_v3_GrpcService_GoogleGrpc_ChannelCredentials_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &envoy_config_core_v3_GrpcService_GoogleGrpc_ChannelCredentials_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *envoy_config_core_v3_GrpcService_GoogleGrpc_ChannelCredentials_serialize(const envoy_config_core_v3_GrpcService_GoogleGrpc_ChannelCredentials *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &envoy_config_core_v3_GrpcService_GoogleGrpc_ChannelCredentials_msginit, arena, len);
 }
@@ -430,6 +475,12 @@ UPB_INLINE envoy_config_core_v3_GrpcService_GoogleGrpc_CallCredentials *envoy_co
   envoy_config_core_v3_GrpcService_GoogleGrpc_CallCredentials *ret = envoy_config_core_v3_GrpcService_GoogleGrpc_CallCredentials_new(arena);
   return (ret && upb_decode(buf, size, ret, &envoy_config_core_v3_GrpcService_GoogleGrpc_CallCredentials_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE envoy_config_core_v3_GrpcService_GoogleGrpc_CallCredentials *envoy_config_core_v3_GrpcService_GoogleGrpc_CallCredentials_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  envoy_config_core_v3_GrpcService_GoogleGrpc_CallCredentials *ret = envoy_config_core_v3_GrpcService_GoogleGrpc_CallCredentials_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &envoy_config_core_v3_GrpcService_GoogleGrpc_CallCredentials_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *envoy_config_core_v3_GrpcService_GoogleGrpc_CallCredentials_serialize(const envoy_config_core_v3_GrpcService_GoogleGrpc_CallCredentials *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &envoy_config_core_v3_GrpcService_GoogleGrpc_CallCredentials_msginit, arena, len);
 }
@@ -538,6 +589,12 @@ UPB_INLINE envoy_config_core_v3_GrpcService_GoogleGrpc_CallCredentials_ServiceAc
   envoy_config_core_v3_GrpcService_GoogleGrpc_CallCredentials_ServiceAccountJWTAccessCredentials *ret = envoy_config_core_v3_GrpcService_GoogleGrpc_CallCredentials_ServiceAccountJWTAccessCredentials_new(arena);
   return (ret && upb_decode(buf, size, ret, &envoy_config_core_v3_GrpcService_GoogleGrpc_CallCredentials_ServiceAccountJWTAccessCredentials_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE envoy_config_core_v3_GrpcService_GoogleGrpc_CallCredentials_ServiceAccountJWTAccessCredentials *envoy_config_core_v3_GrpcService_GoogleGrpc_CallCredentials_ServiceAccountJWTAccessCredentials_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  envoy_config_core_v3_GrpcService_GoogleGrpc_CallCredentials_ServiceAccountJWTAccessCredentials *ret = envoy_config_core_v3_GrpcService_GoogleGrpc_CallCredentials_ServiceAccountJWTAccessCredentials_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &envoy_config_core_v3_GrpcService_GoogleGrpc_CallCredentials_ServiceAccountJWTAccessCredentials_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *envoy_config_core_v3_GrpcService_GoogleGrpc_CallCredentials_ServiceAccountJWTAccessCredentials_serialize(const envoy_config_core_v3_GrpcService_GoogleGrpc_CallCredentials_ServiceAccountJWTAccessCredentials *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &envoy_config_core_v3_GrpcService_GoogleGrpc_CallCredentials_ServiceAccountJWTAccessCredentials_msginit, arena, len);
 }
@@ -562,6 +619,12 @@ UPB_INLINE envoy_config_core_v3_GrpcService_GoogleGrpc_CallCredentials_GoogleIAM
   envoy_config_core_v3_GrpcService_GoogleGrpc_CallCredentials_GoogleIAMCredentials *ret = envoy_config_core_v3_GrpcService_GoogleGrpc_CallCredentials_GoogleIAMCredentials_new(arena);
   return (ret && upb_decode(buf, size, ret, &envoy_config_core_v3_GrpcService_GoogleGrpc_CallCredentials_GoogleIAMCredentials_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE envoy_config_core_v3_GrpcService_GoogleGrpc_CallCredentials_GoogleIAMCredentials *envoy_config_core_v3_GrpcService_GoogleGrpc_CallCredentials_GoogleIAMCredentials_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  envoy_config_core_v3_GrpcService_GoogleGrpc_CallCredentials_GoogleIAMCredentials *ret = envoy_config_core_v3_GrpcService_GoogleGrpc_CallCredentials_GoogleIAMCredentials_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &envoy_config_core_v3_GrpcService_GoogleGrpc_CallCredentials_GoogleIAMCredentials_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *envoy_config_core_v3_GrpcService_GoogleGrpc_CallCredentials_GoogleIAMCredentials_serialize(const envoy_config_core_v3_GrpcService_GoogleGrpc_CallCredentials_GoogleIAMCredentials *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &envoy_config_core_v3_GrpcService_GoogleGrpc_CallCredentials_GoogleIAMCredentials_msginit, arena, len);
 }
@@ -586,6 +649,12 @@ UPB_INLINE envoy_config_core_v3_GrpcService_GoogleGrpc_CallCredentials_MetadataC
   envoy_config_core_v3_GrpcService_GoogleGrpc_CallCredentials_MetadataCredentialsFromPlugin *ret = envoy_config_core_v3_GrpcService_GoogleGrpc_CallCredentials_MetadataCredentialsFromPlugin_new(arena);
   return (ret && upb_decode(buf, size, ret, &envoy_config_core_v3_GrpcService_GoogleGrpc_CallCredentials_MetadataCredentialsFromPlugin_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE envoy_config_core_v3_GrpcService_GoogleGrpc_CallCredentials_MetadataCredentialsFromPlugin *envoy_config_core_v3_GrpcService_GoogleGrpc_CallCredentials_MetadataCredentialsFromPlugin_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  envoy_config_core_v3_GrpcService_GoogleGrpc_CallCredentials_MetadataCredentialsFromPlugin *ret = envoy_config_core_v3_GrpcService_GoogleGrpc_CallCredentials_MetadataCredentialsFromPlugin_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &envoy_config_core_v3_GrpcService_GoogleGrpc_CallCredentials_MetadataCredentialsFromPlugin_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *envoy_config_core_v3_GrpcService_GoogleGrpc_CallCredentials_MetadataCredentialsFromPlugin_serialize(const envoy_config_core_v3_GrpcService_GoogleGrpc_CallCredentials_MetadataCredentialsFromPlugin *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &envoy_config_core_v3_GrpcService_GoogleGrpc_CallCredentials_MetadataCredentialsFromPlugin_msginit, arena, len);
 }
@@ -626,6 +695,12 @@ UPB_INLINE envoy_config_core_v3_GrpcService_GoogleGrpc_CallCredentials_StsServic
   envoy_config_core_v3_GrpcService_GoogleGrpc_CallCredentials_StsService *ret = envoy_config_core_v3_GrpcService_GoogleGrpc_CallCredentials_StsService_new(arena);
   return (ret && upb_decode(buf, size, ret, &envoy_config_core_v3_GrpcService_GoogleGrpc_CallCredentials_StsService_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE envoy_config_core_v3_GrpcService_GoogleGrpc_CallCredentials_StsService *envoy_config_core_v3_GrpcService_GoogleGrpc_CallCredentials_StsService_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  envoy_config_core_v3_GrpcService_GoogleGrpc_CallCredentials_StsService *ret = envoy_config_core_v3_GrpcService_GoogleGrpc_CallCredentials_StsService_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &envoy_config_core_v3_GrpcService_GoogleGrpc_CallCredentials_StsService_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *envoy_config_core_v3_GrpcService_GoogleGrpc_CallCredentials_StsService_serialize(const envoy_config_core_v3_GrpcService_GoogleGrpc_CallCredentials_StsService *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &envoy_config_core_v3_GrpcService_GoogleGrpc_CallCredentials_StsService_msginit, arena, len);
 }
@@ -678,6 +753,12 @@ UPB_INLINE envoy_config_core_v3_GrpcService_GoogleGrpc_ChannelArgs *envoy_config
   envoy_config_core_v3_GrpcService_GoogleGrpc_ChannelArgs *ret = envoy_config_core_v3_GrpcService_GoogleGrpc_ChannelArgs_new(arena);
   return (ret && upb_decode(buf, size, ret, &envoy_config_core_v3_GrpcService_GoogleGrpc_ChannelArgs_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE envoy_config_core_v3_GrpcService_GoogleGrpc_ChannelArgs *envoy_config_core_v3_GrpcService_GoogleGrpc_ChannelArgs_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  envoy_config_core_v3_GrpcService_GoogleGrpc_ChannelArgs *ret = envoy_config_core_v3_GrpcService_GoogleGrpc_ChannelArgs_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &envoy_config_core_v3_GrpcService_GoogleGrpc_ChannelArgs_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *envoy_config_core_v3_GrpcService_GoogleGrpc_ChannelArgs_serialize(const envoy_config_core_v3_GrpcService_GoogleGrpc_ChannelArgs *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &envoy_config_core_v3_GrpcService_GoogleGrpc_ChannelArgs_msginit, arena, len);
 }
@@ -702,6 +783,12 @@ UPB_INLINE envoy_config_core_v3_GrpcService_GoogleGrpc_ChannelArgs_Value *envoy_
   envoy_config_core_v3_GrpcService_GoogleGrpc_ChannelArgs_Value *ret = envoy_config_core_v3_GrpcService_GoogleGrpc_ChannelArgs_Value_new(arena);
   return (ret && upb_decode(buf, size, ret, &envoy_config_core_v3_GrpcService_GoogleGrpc_ChannelArgs_Value_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE envoy_config_core_v3_GrpcService_GoogleGrpc_ChannelArgs_Value *envoy_config_core_v3_GrpcService_GoogleGrpc_ChannelArgs_Value_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  envoy_config_core_v3_GrpcService_GoogleGrpc_ChannelArgs_Value *ret = envoy_config_core_v3_GrpcService_GoogleGrpc_ChannelArgs_Value_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &envoy_config_core_v3_GrpcService_GoogleGrpc_ChannelArgs_Value_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *envoy_config_core_v3_GrpcService_GoogleGrpc_ChannelArgs_Value_serialize(const envoy_config_core_v3_GrpcService_GoogleGrpc_ChannelArgs_Value *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &envoy_config_core_v3_GrpcService_GoogleGrpc_ChannelArgs_Value_msginit, arena, len);
 }
index ce69337..c3f4339 100644 (file)
@@ -25,7 +25,7 @@
 
 #include "upb/port_def.inc"
 
-static const upb_msglayout *const envoy_config_core_v3_HealthCheck_submsgs[19] = {
+static const upb_msglayout *const envoy_config_core_v3_HealthCheck_submsgs[10] = {
   &envoy_config_core_v3_EventServiceConfig_msginit,
   &envoy_config_core_v3_HealthCheck_CustomHealthCheck_msginit,
   &envoy_config_core_v3_HealthCheck_GrpcHealthCheck_msginit,
@@ -39,34 +39,34 @@ static const upb_msglayout *const envoy_config_core_v3_HealthCheck_submsgs[19] =
 };
 
 static const upb_msglayout_field envoy_config_core_v3_HealthCheck__fields[22] = {
-  {1, UPB_SIZE(16, 24), 0, 7, 11, 1},
-  {2, UPB_SIZE(20, 32), 0, 7, 11, 1},
-  {3, UPB_SIZE(24, 40), 0, 7, 11, 1},
-  {4, UPB_SIZE(28, 48), 0, 9, 11, 1},
-  {5, UPB_SIZE(32, 56), 0, 9, 11, 1},
-  {6, UPB_SIZE(36, 64), 0, 9, 11, 1},
-  {7, UPB_SIZE(40, 72), 0, 6, 11, 1},
-  {8, UPB_SIZE(76, 144), UPB_SIZE(-81, -153), 3, 11, 1},
-  {9, UPB_SIZE(76, 144), UPB_SIZE(-81, -153), 4, 11, 1},
-  {11, UPB_SIZE(76, 144), UPB_SIZE(-81, -153), 2, 11, 1},
-  {12, UPB_SIZE(44, 80), 0, 7, 11, 1},
-  {13, UPB_SIZE(76, 144), UPB_SIZE(-81, -153), 1, 11, 1},
-  {14, UPB_SIZE(48, 88), 0, 7, 11, 1},
-  {15, UPB_SIZE(52, 96), 0, 7, 11, 1},
-  {16, UPB_SIZE(56, 104), 0, 7, 11, 1},
-  {17, UPB_SIZE(8, 8), 0, 0, 9, 1},
-  {18, UPB_SIZE(0, 0), 0, 0, 13, 1},
-  {19, UPB_SIZE(4, 4), 0, 0, 8, 1},
-  {20, UPB_SIZE(60, 112), 0, 7, 11, 1},
-  {21, UPB_SIZE(64, 120), 0, 5, 11, 1},
-  {22, UPB_SIZE(68, 128), 0, 0, 11, 1},
-  {23, UPB_SIZE(72, 136), 0, 8, 11, 1},
+  {1, UPB_SIZE(20, 32), 1, 7, 11, 1},
+  {2, UPB_SIZE(24, 40), 2, 7, 11, 1},
+  {3, UPB_SIZE(28, 48), 3, 7, 11, 1},
+  {4, UPB_SIZE(32, 56), 4, 9, 11, 1},
+  {5, UPB_SIZE(36, 64), 5, 9, 11, 1},
+  {6, UPB_SIZE(40, 72), 6, 9, 11, 1},
+  {7, UPB_SIZE(44, 80), 7, 6, 11, 1},
+  {8, UPB_SIZE(80, 152), UPB_SIZE(-85, -161), 3, 11, 1},
+  {9, UPB_SIZE(80, 152), UPB_SIZE(-85, -161), 4, 11, 1},
+  {11, UPB_SIZE(80, 152), UPB_SIZE(-85, -161), 2, 11, 1},
+  {12, UPB_SIZE(48, 88), 8, 7, 11, 1},
+  {13, UPB_SIZE(80, 152), UPB_SIZE(-85, -161), 1, 11, 1},
+  {14, UPB_SIZE(52, 96), 9, 7, 11, 1},
+  {15, UPB_SIZE(56, 104), 10, 7, 11, 1},
+  {16, UPB_SIZE(60, 112), 11, 7, 11, 1},
+  {17, UPB_SIZE(12, 16), 0, 0, 9, 1},
+  {18, UPB_SIZE(4, 4), 0, 0, 13, 1},
+  {19, UPB_SIZE(8, 8), 0, 0, 8, 1},
+  {20, UPB_SIZE(64, 120), 12, 7, 11, 1},
+  {21, UPB_SIZE(68, 128), 13, 5, 11, 1},
+  {22, UPB_SIZE(72, 136), 14, 0, 11, 1},
+  {23, UPB_SIZE(76, 144), 15, 8, 11, 1},
 };
 
 const upb_msglayout envoy_config_core_v3_HealthCheck_msginit = {
   &envoy_config_core_v3_HealthCheck_submsgs[0],
   &envoy_config_core_v3_HealthCheck__fields[0],
-  UPB_SIZE(88, 160), 22, false,
+  UPB_SIZE(88, 176), 22, false, 255,
 };
 
 static const upb_msglayout_field envoy_config_core_v3_HealthCheck_Payload__fields[2] = {
@@ -77,10 +77,10 @@ static const upb_msglayout_field envoy_config_core_v3_HealthCheck_Payload__field
 const upb_msglayout envoy_config_core_v3_HealthCheck_Payload_msginit = {
   NULL,
   &envoy_config_core_v3_HealthCheck_Payload__fields[0],
-  UPB_SIZE(16, 32), 2, false,
+  UPB_SIZE(16, 32), 2, false, 255,
 };
 
-static const upb_msglayout *const envoy_config_core_v3_HealthCheck_HttpHealthCheck_submsgs[5] = {
+static const upb_msglayout *const envoy_config_core_v3_HealthCheck_HttpHealthCheck_submsgs[4] = {
   &envoy_config_core_v3_HeaderValueOption_msginit,
   &envoy_config_core_v3_HealthCheck_Payload_msginit,
   &envoy_type_matcher_v3_StringMatcher_msginit,
@@ -90,34 +90,34 @@ static const upb_msglayout *const envoy_config_core_v3_HealthCheck_HttpHealthChe
 static const upb_msglayout_field envoy_config_core_v3_HealthCheck_HttpHealthCheck__fields[9] = {
   {1, UPB_SIZE(8, 8), 0, 0, 9, 1},
   {2, UPB_SIZE(16, 24), 0, 0, 9, 1},
-  {3, UPB_SIZE(24, 40), 0, 1, 11, 1},
-  {4, UPB_SIZE(28, 48), 0, 1, 11, 1},
+  {3, UPB_SIZE(24, 40), 1, 1, 11, 1},
+  {4, UPB_SIZE(28, 48), 2, 1, 11, 1},
   {6, UPB_SIZE(36, 64), 0, 0, 11, 3},
   {8, UPB_SIZE(40, 72), 0, 0, 9, 3},
   {9, UPB_SIZE(44, 80), 0, 3, 11, 3},
-  {10, UPB_SIZE(0, 0), 0, 0, 14, 1},
-  {11, UPB_SIZE(32, 56), 0, 2, 11, 1},
+  {10, UPB_SIZE(4, 4), 0, 0, 14, 1},
+  {11, UPB_SIZE(32, 56), 3, 2, 11, 1},
 };
 
 const upb_msglayout envoy_config_core_v3_HealthCheck_HttpHealthCheck_msginit = {
   &envoy_config_core_v3_HealthCheck_HttpHealthCheck_submsgs[0],
   &envoy_config_core_v3_HealthCheck_HttpHealthCheck__fields[0],
-  UPB_SIZE(48, 96), 9, false,
+  UPB_SIZE(48, 96), 9, false, 255,
 };
 
-static const upb_msglayout *const envoy_config_core_v3_HealthCheck_TcpHealthCheck_submsgs[2] = {
+static const upb_msglayout *const envoy_config_core_v3_HealthCheck_TcpHealthCheck_submsgs[1] = {
   &envoy_config_core_v3_HealthCheck_Payload_msginit,
 };
 
 static const upb_msglayout_field envoy_config_core_v3_HealthCheck_TcpHealthCheck__fields[2] = {
-  {1, UPB_SIZE(0, 0), 0, 0, 11, 1},
-  {2, UPB_SIZE(4, 8), 0, 0, 11, 3},
+  {1, UPB_SIZE(4, 8), 1, 0, 11, 1},
+  {2, UPB_SIZE(8, 16), 0, 0, 11, 3},
 };
 
 const upb_msglayout envoy_config_core_v3_HealthCheck_TcpHealthCheck_msginit = {
   &envoy_config_core_v3_HealthCheck_TcpHealthCheck_submsgs[0],
   &envoy_config_core_v3_HealthCheck_TcpHealthCheck__fields[0],
-  UPB_SIZE(8, 16), 2, false,
+  UPB_SIZE(16, 24), 2, false, 255,
 };
 
 static const upb_msglayout_field envoy_config_core_v3_HealthCheck_RedisHealthCheck__fields[1] = {
@@ -127,7 +127,7 @@ static const upb_msglayout_field envoy_config_core_v3_HealthCheck_RedisHealthChe
 const upb_msglayout envoy_config_core_v3_HealthCheck_RedisHealthCheck_msginit = {
   NULL,
   &envoy_config_core_v3_HealthCheck_RedisHealthCheck__fields[0],
-  UPB_SIZE(8, 16), 1, false,
+  UPB_SIZE(8, 16), 1, false, 255,
 };
 
 static const upb_msglayout_field envoy_config_core_v3_HealthCheck_GrpcHealthCheck__fields[2] = {
@@ -138,7 +138,7 @@ static const upb_msglayout_field envoy_config_core_v3_HealthCheck_GrpcHealthChec
 const upb_msglayout envoy_config_core_v3_HealthCheck_GrpcHealthCheck_msginit = {
   NULL,
   &envoy_config_core_v3_HealthCheck_GrpcHealthCheck__fields[0],
-  UPB_SIZE(16, 32), 2, false,
+  UPB_SIZE(16, 32), 2, false, 255,
 };
 
 static const upb_msglayout *const envoy_config_core_v3_HealthCheck_CustomHealthCheck_submsgs[1] = {
@@ -153,7 +153,7 @@ static const upb_msglayout_field envoy_config_core_v3_HealthCheck_CustomHealthCh
 const upb_msglayout envoy_config_core_v3_HealthCheck_CustomHealthCheck_msginit = {
   &envoy_config_core_v3_HealthCheck_CustomHealthCheck_submsgs[0],
   &envoy_config_core_v3_HealthCheck_CustomHealthCheck__fields[0],
-  UPB_SIZE(16, 32), 2, false,
+  UPB_SIZE(16, 32), 2, false, 255,
 };
 
 static const upb_msglayout_field envoy_config_core_v3_HealthCheck_TlsOptions__fields[1] = {
@@ -163,7 +163,7 @@ static const upb_msglayout_field envoy_config_core_v3_HealthCheck_TlsOptions__fi
 const upb_msglayout envoy_config_core_v3_HealthCheck_TlsOptions_msginit = {
   NULL,
   &envoy_config_core_v3_HealthCheck_TlsOptions__fields[0],
-  UPB_SIZE(4, 8), 1, false,
+  UPB_SIZE(8, 8), 1, false, 255,
 };
 
 #include "upb/port_undef.inc"
index aa8c7d3..711bbfc 100644 (file)
@@ -11,6 +11,7 @@
 
 #include "upb/msg.h"
 #include "upb/decode.h"
+#include "upb/decode_fast.h"
 #include "upb/encode.h"
 
 #include "upb/port_def.inc"
@@ -82,6 +83,12 @@ UPB_INLINE envoy_config_core_v3_HealthCheck *envoy_config_core_v3_HealthCheck_pa
   envoy_config_core_v3_HealthCheck *ret = envoy_config_core_v3_HealthCheck_new(arena);
   return (ret && upb_decode(buf, size, ret, &envoy_config_core_v3_HealthCheck_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE envoy_config_core_v3_HealthCheck *envoy_config_core_v3_HealthCheck_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  envoy_config_core_v3_HealthCheck *ret = envoy_config_core_v3_HealthCheck_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &envoy_config_core_v3_HealthCheck_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *envoy_config_core_v3_HealthCheck_serialize(const envoy_config_core_v3_HealthCheck *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &envoy_config_core_v3_HealthCheck_msginit, arena, len);
 }
@@ -93,52 +100,53 @@ typedef enum {
   envoy_config_core_v3_HealthCheck_health_checker_custom_health_check = 13,
   envoy_config_core_v3_HealthCheck_health_checker_NOT_SET = 0
 } envoy_config_core_v3_HealthCheck_health_checker_oneofcases;
-UPB_INLINE envoy_config_core_v3_HealthCheck_health_checker_oneofcases envoy_config_core_v3_HealthCheck_health_checker_case(const envoy_config_core_v3_HealthCheck* msg) { return (envoy_config_core_v3_HealthCheck_health_checker_oneofcases)*UPB_PTR_AT(msg, UPB_SIZE(80, 152), int32_t); }
-
-UPB_INLINE bool envoy_config_core_v3_HealthCheck_has_timeout(const envoy_config_core_v3_HealthCheck *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(16, 24)); }
-UPB_INLINE const struct google_protobuf_Duration* envoy_config_core_v3_HealthCheck_timeout(const envoy_config_core_v3_HealthCheck *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(16, 24), const struct google_protobuf_Duration*); }
-UPB_INLINE bool envoy_config_core_v3_HealthCheck_has_interval(const envoy_config_core_v3_HealthCheck *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(20, 32)); }
-UPB_INLINE const struct google_protobuf_Duration* envoy_config_core_v3_HealthCheck_interval(const envoy_config_core_v3_HealthCheck *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(20, 32), const struct google_protobuf_Duration*); }
-UPB_INLINE bool envoy_config_core_v3_HealthCheck_has_interval_jitter(const envoy_config_core_v3_HealthCheck *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(24, 40)); }
-UPB_INLINE const struct google_protobuf_Duration* envoy_config_core_v3_HealthCheck_interval_jitter(const envoy_config_core_v3_HealthCheck *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(24, 40), const struct google_protobuf_Duration*); }
-UPB_INLINE bool envoy_config_core_v3_HealthCheck_has_unhealthy_threshold(const envoy_config_core_v3_HealthCheck *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(28, 48)); }
-UPB_INLINE const struct google_protobuf_UInt32Value* envoy_config_core_v3_HealthCheck_unhealthy_threshold(const envoy_config_core_v3_HealthCheck *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(28, 48), const struct google_protobuf_UInt32Value*); }
-UPB_INLINE bool envoy_config_core_v3_HealthCheck_has_healthy_threshold(const envoy_config_core_v3_HealthCheck *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(32, 56)); }
-UPB_INLINE const struct google_protobuf_UInt32Value* envoy_config_core_v3_HealthCheck_healthy_threshold(const envoy_config_core_v3_HealthCheck *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(32, 56), const struct google_protobuf_UInt32Value*); }
-UPB_INLINE bool envoy_config_core_v3_HealthCheck_has_alt_port(const envoy_config_core_v3_HealthCheck *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(36, 64)); }
-UPB_INLINE const struct google_protobuf_UInt32Value* envoy_config_core_v3_HealthCheck_alt_port(const envoy_config_core_v3_HealthCheck *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(36, 64), const struct google_protobuf_UInt32Value*); }
-UPB_INLINE bool envoy_config_core_v3_HealthCheck_has_reuse_connection(const envoy_config_core_v3_HealthCheck *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(40, 72)); }
-UPB_INLINE const struct google_protobuf_BoolValue* envoy_config_core_v3_HealthCheck_reuse_connection(const envoy_config_core_v3_HealthCheck *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(40, 72), const struct google_protobuf_BoolValue*); }
-UPB_INLINE bool envoy_config_core_v3_HealthCheck_has_http_health_check(const envoy_config_core_v3_HealthCheck *msg) { return _upb_getoneofcase(msg, UPB_SIZE(80, 152)) == 8; }
-UPB_INLINE const envoy_config_core_v3_HealthCheck_HttpHealthCheck* envoy_config_core_v3_HealthCheck_http_health_check(const envoy_config_core_v3_HealthCheck *msg) { return UPB_READ_ONEOF(msg, const envoy_config_core_v3_HealthCheck_HttpHealthCheck*, UPB_SIZE(76, 144), UPB_SIZE(80, 152), 8, NULL); }
-UPB_INLINE bool envoy_config_core_v3_HealthCheck_has_tcp_health_check(const envoy_config_core_v3_HealthCheck *msg) { return _upb_getoneofcase(msg, UPB_SIZE(80, 152)) == 9; }
-UPB_INLINE const envoy_config_core_v3_HealthCheck_TcpHealthCheck* envoy_config_core_v3_HealthCheck_tcp_health_check(const envoy_config_core_v3_HealthCheck *msg) { return UPB_READ_ONEOF(msg, const envoy_config_core_v3_HealthCheck_TcpHealthCheck*, UPB_SIZE(76, 144), UPB_SIZE(80, 152), 9, NULL); }
-UPB_INLINE bool envoy_config_core_v3_HealthCheck_has_grpc_health_check(const envoy_config_core_v3_HealthCheck *msg) { return _upb_getoneofcase(msg, UPB_SIZE(80, 152)) == 11; }
-UPB_INLINE const envoy_config_core_v3_HealthCheck_GrpcHealthCheck* envoy_config_core_v3_HealthCheck_grpc_health_check(const envoy_config_core_v3_HealthCheck *msg) { return UPB_READ_ONEOF(msg, const envoy_config_core_v3_HealthCheck_GrpcHealthCheck*, UPB_SIZE(76, 144), UPB_SIZE(80, 152), 11, NULL); }
-UPB_INLINE bool envoy_config_core_v3_HealthCheck_has_no_traffic_interval(const envoy_config_core_v3_HealthCheck *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(44, 80)); }
-UPB_INLINE const struct google_protobuf_Duration* envoy_config_core_v3_HealthCheck_no_traffic_interval(const envoy_config_core_v3_HealthCheck *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(44, 80), const struct google_protobuf_Duration*); }
-UPB_INLINE bool envoy_config_core_v3_HealthCheck_has_custom_health_check(const envoy_config_core_v3_HealthCheck *msg) { return _upb_getoneofcase(msg, UPB_SIZE(80, 152)) == 13; }
-UPB_INLINE const envoy_config_core_v3_HealthCheck_CustomHealthCheck* envoy_config_core_v3_HealthCheck_custom_health_check(const envoy_config_core_v3_HealthCheck *msg) { return UPB_READ_ONEOF(msg, const envoy_config_core_v3_HealthCheck_CustomHealthCheck*, UPB_SIZE(76, 144), UPB_SIZE(80, 152), 13, NULL); }
-UPB_INLINE bool envoy_config_core_v3_HealthCheck_has_unhealthy_interval(const envoy_config_core_v3_HealthCheck *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(48, 88)); }
-UPB_INLINE const struct google_protobuf_Duration* envoy_config_core_v3_HealthCheck_unhealthy_interval(const envoy_config_core_v3_HealthCheck *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(48, 88), const struct google_protobuf_Duration*); }
-UPB_INLINE bool envoy_config_core_v3_HealthCheck_has_unhealthy_edge_interval(const envoy_config_core_v3_HealthCheck *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(52, 96)); }
-UPB_INLINE const struct google_protobuf_Duration* envoy_config_core_v3_HealthCheck_unhealthy_edge_interval(const envoy_config_core_v3_HealthCheck *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(52, 96), const struct google_protobuf_Duration*); }
-UPB_INLINE bool envoy_config_core_v3_HealthCheck_has_healthy_edge_interval(const envoy_config_core_v3_HealthCheck *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(56, 104)); }
-UPB_INLINE const struct google_protobuf_Duration* envoy_config_core_v3_HealthCheck_healthy_edge_interval(const envoy_config_core_v3_HealthCheck *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(56, 104), const struct google_protobuf_Duration*); }
-UPB_INLINE upb_strview envoy_config_core_v3_HealthCheck_event_log_path(const envoy_config_core_v3_HealthCheck *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(8, 8), upb_strview); }
-UPB_INLINE uint32_t envoy_config_core_v3_HealthCheck_interval_jitter_percent(const envoy_config_core_v3_HealthCheck *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(0, 0), uint32_t); }
-UPB_INLINE bool envoy_config_core_v3_HealthCheck_always_log_health_check_failures(const envoy_config_core_v3_HealthCheck *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(4, 4), bool); }
-UPB_INLINE bool envoy_config_core_v3_HealthCheck_has_initial_jitter(const envoy_config_core_v3_HealthCheck *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(60, 112)); }
-UPB_INLINE const struct google_protobuf_Duration* envoy_config_core_v3_HealthCheck_initial_jitter(const envoy_config_core_v3_HealthCheck *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(60, 112), const struct google_protobuf_Duration*); }
-UPB_INLINE bool envoy_config_core_v3_HealthCheck_has_tls_options(const envoy_config_core_v3_HealthCheck *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(64, 120)); }
-UPB_INLINE const envoy_config_core_v3_HealthCheck_TlsOptions* envoy_config_core_v3_HealthCheck_tls_options(const envoy_config_core_v3_HealthCheck *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(64, 120), const envoy_config_core_v3_HealthCheck_TlsOptions*); }
-UPB_INLINE bool envoy_config_core_v3_HealthCheck_has_event_service(const envoy_config_core_v3_HealthCheck *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(68, 128)); }
-UPB_INLINE const struct envoy_config_core_v3_EventServiceConfig* envoy_config_core_v3_HealthCheck_event_service(const envoy_config_core_v3_HealthCheck *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(68, 128), const struct envoy_config_core_v3_EventServiceConfig*); }
-UPB_INLINE bool envoy_config_core_v3_HealthCheck_has_transport_socket_match_criteria(const envoy_config_core_v3_HealthCheck *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(72, 136)); }
-UPB_INLINE const struct google_protobuf_Struct* envoy_config_core_v3_HealthCheck_transport_socket_match_criteria(const envoy_config_core_v3_HealthCheck *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(72, 136), const struct google_protobuf_Struct*); }
+UPB_INLINE envoy_config_core_v3_HealthCheck_health_checker_oneofcases envoy_config_core_v3_HealthCheck_health_checker_case(const envoy_config_core_v3_HealthCheck* msg) { return (envoy_config_core_v3_HealthCheck_health_checker_oneofcases)*UPB_PTR_AT(msg, UPB_SIZE(84, 160), int32_t); }
+
+UPB_INLINE bool envoy_config_core_v3_HealthCheck_has_timeout(const envoy_config_core_v3_HealthCheck *msg) { return _upb_hasbit(msg, 1); }
+UPB_INLINE const struct google_protobuf_Duration* envoy_config_core_v3_HealthCheck_timeout(const envoy_config_core_v3_HealthCheck *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(20, 32), const struct google_protobuf_Duration*); }
+UPB_INLINE bool envoy_config_core_v3_HealthCheck_has_interval(const envoy_config_core_v3_HealthCheck *msg) { return _upb_hasbit(msg, 2); }
+UPB_INLINE const struct google_protobuf_Duration* envoy_config_core_v3_HealthCheck_interval(const envoy_config_core_v3_HealthCheck *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(24, 40), const struct google_protobuf_Duration*); }
+UPB_INLINE bool envoy_config_core_v3_HealthCheck_has_interval_jitter(const envoy_config_core_v3_HealthCheck *msg) { return _upb_hasbit(msg, 3); }
+UPB_INLINE const struct google_protobuf_Duration* envoy_config_core_v3_HealthCheck_interval_jitter(const envoy_config_core_v3_HealthCheck *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(28, 48), const struct google_protobuf_Duration*); }
+UPB_INLINE bool envoy_config_core_v3_HealthCheck_has_unhealthy_threshold(const envoy_config_core_v3_HealthCheck *msg) { return _upb_hasbit(msg, 4); }
+UPB_INLINE const struct google_protobuf_UInt32Value* envoy_config_core_v3_HealthCheck_unhealthy_threshold(const envoy_config_core_v3_HealthCheck *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(32, 56), const struct google_protobuf_UInt32Value*); }
+UPB_INLINE bool envoy_config_core_v3_HealthCheck_has_healthy_threshold(const envoy_config_core_v3_HealthCheck *msg) { return _upb_hasbit(msg, 5); }
+UPB_INLINE const struct google_protobuf_UInt32Value* envoy_config_core_v3_HealthCheck_healthy_threshold(const envoy_config_core_v3_HealthCheck *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(36, 64), const struct google_protobuf_UInt32Value*); }
+UPB_INLINE bool envoy_config_core_v3_HealthCheck_has_alt_port(const envoy_config_core_v3_HealthCheck *msg) { return _upb_hasbit(msg, 6); }
+UPB_INLINE const struct google_protobuf_UInt32Value* envoy_config_core_v3_HealthCheck_alt_port(const envoy_config_core_v3_HealthCheck *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(40, 72), const struct google_protobuf_UInt32Value*); }
+UPB_INLINE bool envoy_config_core_v3_HealthCheck_has_reuse_connection(const envoy_config_core_v3_HealthCheck *msg) { return _upb_hasbit(msg, 7); }
+UPB_INLINE const struct google_protobuf_BoolValue* envoy_config_core_v3_HealthCheck_reuse_connection(const envoy_config_core_v3_HealthCheck *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(44, 80), const struct google_protobuf_BoolValue*); }
+UPB_INLINE bool envoy_config_core_v3_HealthCheck_has_http_health_check(const envoy_config_core_v3_HealthCheck *msg) { return _upb_getoneofcase(msg, UPB_SIZE(84, 160)) == 8; }
+UPB_INLINE const envoy_config_core_v3_HealthCheck_HttpHealthCheck* envoy_config_core_v3_HealthCheck_http_health_check(const envoy_config_core_v3_HealthCheck *msg) { return UPB_READ_ONEOF(msg, const envoy_config_core_v3_HealthCheck_HttpHealthCheck*, UPB_SIZE(80, 152), UPB_SIZE(84, 160), 8, NULL); }
+UPB_INLINE bool envoy_config_core_v3_HealthCheck_has_tcp_health_check(const envoy_config_core_v3_HealthCheck *msg) { return _upb_getoneofcase(msg, UPB_SIZE(84, 160)) == 9; }
+UPB_INLINE const envoy_config_core_v3_HealthCheck_TcpHealthCheck* envoy_config_core_v3_HealthCheck_tcp_health_check(const envoy_config_core_v3_HealthCheck *msg) { return UPB_READ_ONEOF(msg, const envoy_config_core_v3_HealthCheck_TcpHealthCheck*, UPB_SIZE(80, 152), UPB_SIZE(84, 160), 9, NULL); }
+UPB_INLINE bool envoy_config_core_v3_HealthCheck_has_grpc_health_check(const envoy_config_core_v3_HealthCheck *msg) { return _upb_getoneofcase(msg, UPB_SIZE(84, 160)) == 11; }
+UPB_INLINE const envoy_config_core_v3_HealthCheck_GrpcHealthCheck* envoy_config_core_v3_HealthCheck_grpc_health_check(const envoy_config_core_v3_HealthCheck *msg) { return UPB_READ_ONEOF(msg, const envoy_config_core_v3_HealthCheck_GrpcHealthCheck*, UPB_SIZE(80, 152), UPB_SIZE(84, 160), 11, NULL); }
+UPB_INLINE bool envoy_config_core_v3_HealthCheck_has_no_traffic_interval(const envoy_config_core_v3_HealthCheck *msg) { return _upb_hasbit(msg, 8); }
+UPB_INLINE const struct google_protobuf_Duration* envoy_config_core_v3_HealthCheck_no_traffic_interval(const envoy_config_core_v3_HealthCheck *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(48, 88), const struct google_protobuf_Duration*); }
+UPB_INLINE bool envoy_config_core_v3_HealthCheck_has_custom_health_check(const envoy_config_core_v3_HealthCheck *msg) { return _upb_getoneofcase(msg, UPB_SIZE(84, 160)) == 13; }
+UPB_INLINE const envoy_config_core_v3_HealthCheck_CustomHealthCheck* envoy_config_core_v3_HealthCheck_custom_health_check(const envoy_config_core_v3_HealthCheck *msg) { return UPB_READ_ONEOF(msg, const envoy_config_core_v3_HealthCheck_CustomHealthCheck*, UPB_SIZE(80, 152), UPB_SIZE(84, 160), 13, NULL); }
+UPB_INLINE bool envoy_config_core_v3_HealthCheck_has_unhealthy_interval(const envoy_config_core_v3_HealthCheck *msg) { return _upb_hasbit(msg, 9); }
+UPB_INLINE const struct google_protobuf_Duration* envoy_config_core_v3_HealthCheck_unhealthy_interval(const envoy_config_core_v3_HealthCheck *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(52, 96), const struct google_protobuf_Duration*); }
+UPB_INLINE bool envoy_config_core_v3_HealthCheck_has_unhealthy_edge_interval(const envoy_config_core_v3_HealthCheck *msg) { return _upb_hasbit(msg, 10); }
+UPB_INLINE const struct google_protobuf_Duration* envoy_config_core_v3_HealthCheck_unhealthy_edge_interval(const envoy_config_core_v3_HealthCheck *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(56, 104), const struct google_protobuf_Duration*); }
+UPB_INLINE bool envoy_config_core_v3_HealthCheck_has_healthy_edge_interval(const envoy_config_core_v3_HealthCheck *msg) { return _upb_hasbit(msg, 11); }
+UPB_INLINE const struct google_protobuf_Duration* envoy_config_core_v3_HealthCheck_healthy_edge_interval(const envoy_config_core_v3_HealthCheck *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(60, 112), const struct google_protobuf_Duration*); }
+UPB_INLINE upb_strview envoy_config_core_v3_HealthCheck_event_log_path(const envoy_config_core_v3_HealthCheck *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(12, 16), upb_strview); }
+UPB_INLINE uint32_t envoy_config_core_v3_HealthCheck_interval_jitter_percent(const envoy_config_core_v3_HealthCheck *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(4, 4), uint32_t); }
+UPB_INLINE bool envoy_config_core_v3_HealthCheck_always_log_health_check_failures(const envoy_config_core_v3_HealthCheck *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(8, 8), bool); }
+UPB_INLINE bool envoy_config_core_v3_HealthCheck_has_initial_jitter(const envoy_config_core_v3_HealthCheck *msg) { return _upb_hasbit(msg, 12); }
+UPB_INLINE const struct google_protobuf_Duration* envoy_config_core_v3_HealthCheck_initial_jitter(const envoy_config_core_v3_HealthCheck *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(64, 120), const struct google_protobuf_Duration*); }
+UPB_INLINE bool envoy_config_core_v3_HealthCheck_has_tls_options(const envoy_config_core_v3_HealthCheck *msg) { return _upb_hasbit(msg, 13); }
+UPB_INLINE const envoy_config_core_v3_HealthCheck_TlsOptions* envoy_config_core_v3_HealthCheck_tls_options(const envoy_config_core_v3_HealthCheck *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(68, 128), const envoy_config_core_v3_HealthCheck_TlsOptions*); }
+UPB_INLINE bool envoy_config_core_v3_HealthCheck_has_event_service(const envoy_config_core_v3_HealthCheck *msg) { return _upb_hasbit(msg, 14); }
+UPB_INLINE const struct envoy_config_core_v3_EventServiceConfig* envoy_config_core_v3_HealthCheck_event_service(const envoy_config_core_v3_HealthCheck *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(72, 136), const struct envoy_config_core_v3_EventServiceConfig*); }
+UPB_INLINE bool envoy_config_core_v3_HealthCheck_has_transport_socket_match_criteria(const envoy_config_core_v3_HealthCheck *msg) { return _upb_hasbit(msg, 15); }
+UPB_INLINE const struct google_protobuf_Struct* envoy_config_core_v3_HealthCheck_transport_socket_match_criteria(const envoy_config_core_v3_HealthCheck *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(76, 144), const struct google_protobuf_Struct*); }
 
 UPB_INLINE void envoy_config_core_v3_HealthCheck_set_timeout(envoy_config_core_v3_HealthCheck *msg, struct google_protobuf_Duration* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(16, 24), struct google_protobuf_Duration*) = value;
+  _upb_sethas(msg, 1);
+  *UPB_PTR_AT(msg, UPB_SIZE(20, 32), struct google_protobuf_Duration*) = value;
 }
 UPB_INLINE struct google_protobuf_Duration* envoy_config_core_v3_HealthCheck_mutable_timeout(envoy_config_core_v3_HealthCheck *msg, upb_arena *arena) {
   struct google_protobuf_Duration* sub = (struct google_protobuf_Duration*)envoy_config_core_v3_HealthCheck_timeout(msg);
@@ -150,7 +158,8 @@ UPB_INLINE struct google_protobuf_Duration* envoy_config_core_v3_HealthCheck_mut
   return sub;
 }
 UPB_INLINE void envoy_config_core_v3_HealthCheck_set_interval(envoy_config_core_v3_HealthCheck *msg, struct google_protobuf_Duration* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(20, 32), struct google_protobuf_Duration*) = value;
+  _upb_sethas(msg, 2);
+  *UPB_PTR_AT(msg, UPB_SIZE(24, 40), struct google_protobuf_Duration*) = value;
 }
 UPB_INLINE struct google_protobuf_Duration* envoy_config_core_v3_HealthCheck_mutable_interval(envoy_config_core_v3_HealthCheck *msg, upb_arena *arena) {
   struct google_protobuf_Duration* sub = (struct google_protobuf_Duration*)envoy_config_core_v3_HealthCheck_interval(msg);
@@ -162,7 +171,8 @@ UPB_INLINE struct google_protobuf_Duration* envoy_config_core_v3_HealthCheck_mut
   return sub;
 }
 UPB_INLINE void envoy_config_core_v3_HealthCheck_set_interval_jitter(envoy_config_core_v3_HealthCheck *msg, struct google_protobuf_Duration* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(24, 40), struct google_protobuf_Duration*) = value;
+  _upb_sethas(msg, 3);
+  *UPB_PTR_AT(msg, UPB_SIZE(28, 48), struct google_protobuf_Duration*) = value;
 }
 UPB_INLINE struct google_protobuf_Duration* envoy_config_core_v3_HealthCheck_mutable_interval_jitter(envoy_config_core_v3_HealthCheck *msg, upb_arena *arena) {
   struct google_protobuf_Duration* sub = (struct google_protobuf_Duration*)envoy_config_core_v3_HealthCheck_interval_jitter(msg);
@@ -174,7 +184,8 @@ UPB_INLINE struct google_protobuf_Duration* envoy_config_core_v3_HealthCheck_mut
   return sub;
 }
 UPB_INLINE void envoy_config_core_v3_HealthCheck_set_unhealthy_threshold(envoy_config_core_v3_HealthCheck *msg, struct google_protobuf_UInt32Value* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(28, 48), struct google_protobuf_UInt32Value*) = value;
+  _upb_sethas(msg, 4);
+  *UPB_PTR_AT(msg, UPB_SIZE(32, 56), struct google_protobuf_UInt32Value*) = value;
 }
 UPB_INLINE struct google_protobuf_UInt32Value* envoy_config_core_v3_HealthCheck_mutable_unhealthy_threshold(envoy_config_core_v3_HealthCheck *msg, upb_arena *arena) {
   struct google_protobuf_UInt32Value* sub = (struct google_protobuf_UInt32Value*)envoy_config_core_v3_HealthCheck_unhealthy_threshold(msg);
@@ -186,7 +197,8 @@ UPB_INLINE struct google_protobuf_UInt32Value* envoy_config_core_v3_HealthCheck_
   return sub;
 }
 UPB_INLINE void envoy_config_core_v3_HealthCheck_set_healthy_threshold(envoy_config_core_v3_HealthCheck *msg, struct google_protobuf_UInt32Value* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(32, 56), struct google_protobuf_UInt32Value*) = value;
+  _upb_sethas(msg, 5);
+  *UPB_PTR_AT(msg, UPB_SIZE(36, 64), struct google_protobuf_UInt32Value*) = value;
 }
 UPB_INLINE struct google_protobuf_UInt32Value* envoy_config_core_v3_HealthCheck_mutable_healthy_threshold(envoy_config_core_v3_HealthCheck *msg, upb_arena *arena) {
   struct google_protobuf_UInt32Value* sub = (struct google_protobuf_UInt32Value*)envoy_config_core_v3_HealthCheck_healthy_threshold(msg);
@@ -198,7 +210,8 @@ UPB_INLINE struct google_protobuf_UInt32Value* envoy_config_core_v3_HealthCheck_
   return sub;
 }
 UPB_INLINE void envoy_config_core_v3_HealthCheck_set_alt_port(envoy_config_core_v3_HealthCheck *msg, struct google_protobuf_UInt32Value* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(36, 64), struct google_protobuf_UInt32Value*) = value;
+  _upb_sethas(msg, 6);
+  *UPB_PTR_AT(msg, UPB_SIZE(40, 72), struct google_protobuf_UInt32Value*) = value;
 }
 UPB_INLINE struct google_protobuf_UInt32Value* envoy_config_core_v3_HealthCheck_mutable_alt_port(envoy_config_core_v3_HealthCheck *msg, upb_arena *arena) {
   struct google_protobuf_UInt32Value* sub = (struct google_protobuf_UInt32Value*)envoy_config_core_v3_HealthCheck_alt_port(msg);
@@ -210,7 +223,8 @@ UPB_INLINE struct google_protobuf_UInt32Value* envoy_config_core_v3_HealthCheck_
   return sub;
 }
 UPB_INLINE void envoy_config_core_v3_HealthCheck_set_reuse_connection(envoy_config_core_v3_HealthCheck *msg, struct google_protobuf_BoolValue* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(40, 72), struct google_protobuf_BoolValue*) = value;
+  _upb_sethas(msg, 7);
+  *UPB_PTR_AT(msg, UPB_SIZE(44, 80), struct google_protobuf_BoolValue*) = value;
 }
 UPB_INLINE struct google_protobuf_BoolValue* envoy_config_core_v3_HealthCheck_mutable_reuse_connection(envoy_config_core_v3_HealthCheck *msg, upb_arena *arena) {
   struct google_protobuf_BoolValue* sub = (struct google_protobuf_BoolValue*)envoy_config_core_v3_HealthCheck_reuse_connection(msg);
@@ -222,7 +236,7 @@ UPB_INLINE struct google_protobuf_BoolValue* envoy_config_core_v3_HealthCheck_mu
   return sub;
 }
 UPB_INLINE void envoy_config_core_v3_HealthCheck_set_http_health_check(envoy_config_core_v3_HealthCheck *msg, envoy_config_core_v3_HealthCheck_HttpHealthCheck* value) {
-  UPB_WRITE_ONEOF(msg, envoy_config_core_v3_HealthCheck_HttpHealthCheck*, UPB_SIZE(76, 144), value, UPB_SIZE(80, 152), 8);
+  UPB_WRITE_ONEOF(msg, envoy_config_core_v3_HealthCheck_HttpHealthCheck*, UPB_SIZE(80, 152), value, UPB_SIZE(84, 160), 8);
 }
 UPB_INLINE struct envoy_config_core_v3_HealthCheck_HttpHealthCheck* envoy_config_core_v3_HealthCheck_mutable_http_health_check(envoy_config_core_v3_HealthCheck *msg, upb_arena *arena) {
   struct envoy_config_core_v3_HealthCheck_HttpHealthCheck* sub = (struct envoy_config_core_v3_HealthCheck_HttpHealthCheck*)envoy_config_core_v3_HealthCheck_http_health_check(msg);
@@ -234,7 +248,7 @@ UPB_INLINE struct envoy_config_core_v3_HealthCheck_HttpHealthCheck* envoy_config
   return sub;
 }
 UPB_INLINE void envoy_config_core_v3_HealthCheck_set_tcp_health_check(envoy_config_core_v3_HealthCheck *msg, envoy_config_core_v3_HealthCheck_TcpHealthCheck* value) {
-  UPB_WRITE_ONEOF(msg, envoy_config_core_v3_HealthCheck_TcpHealthCheck*, UPB_SIZE(76, 144), value, UPB_SIZE(80, 152), 9);
+  UPB_WRITE_ONEOF(msg, envoy_config_core_v3_HealthCheck_TcpHealthCheck*, UPB_SIZE(80, 152), value, UPB_SIZE(84, 160), 9);
 }
 UPB_INLINE struct envoy_config_core_v3_HealthCheck_TcpHealthCheck* envoy_config_core_v3_HealthCheck_mutable_tcp_health_check(envoy_config_core_v3_HealthCheck *msg, upb_arena *arena) {
   struct envoy_config_core_v3_HealthCheck_TcpHealthCheck* sub = (struct envoy_config_core_v3_HealthCheck_TcpHealthCheck*)envoy_config_core_v3_HealthCheck_tcp_health_check(msg);
@@ -246,7 +260,7 @@ UPB_INLINE struct envoy_config_core_v3_HealthCheck_TcpHealthCheck* envoy_config_
   return sub;
 }
 UPB_INLINE void envoy_config_core_v3_HealthCheck_set_grpc_health_check(envoy_config_core_v3_HealthCheck *msg, envoy_config_core_v3_HealthCheck_GrpcHealthCheck* value) {
-  UPB_WRITE_ONEOF(msg, envoy_config_core_v3_HealthCheck_GrpcHealthCheck*, UPB_SIZE(76, 144), value, UPB_SIZE(80, 152), 11);
+  UPB_WRITE_ONEOF(msg, envoy_config_core_v3_HealthCheck_GrpcHealthCheck*, UPB_SIZE(80, 152), value, UPB_SIZE(84, 160), 11);
 }
 UPB_INLINE struct envoy_config_core_v3_HealthCheck_GrpcHealthCheck* envoy_config_core_v3_HealthCheck_mutable_grpc_health_check(envoy_config_core_v3_HealthCheck *msg, upb_arena *arena) {
   struct envoy_config_core_v3_HealthCheck_GrpcHealthCheck* sub = (struct envoy_config_core_v3_HealthCheck_GrpcHealthCheck*)envoy_config_core_v3_HealthCheck_grpc_health_check(msg);
@@ -258,7 +272,8 @@ UPB_INLINE struct envoy_config_core_v3_HealthCheck_GrpcHealthCheck* envoy_config
   return sub;
 }
 UPB_INLINE void envoy_config_core_v3_HealthCheck_set_no_traffic_interval(envoy_config_core_v3_HealthCheck *msg, struct google_protobuf_Duration* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(44, 80), struct google_protobuf_Duration*) = value;
+  _upb_sethas(msg, 8);
+  *UPB_PTR_AT(msg, UPB_SIZE(48, 88), struct google_protobuf_Duration*) = value;
 }
 UPB_INLINE struct google_protobuf_Duration* envoy_config_core_v3_HealthCheck_mutable_no_traffic_interval(envoy_config_core_v3_HealthCheck *msg, upb_arena *arena) {
   struct google_protobuf_Duration* sub = (struct google_protobuf_Duration*)envoy_config_core_v3_HealthCheck_no_traffic_interval(msg);
@@ -270,7 +285,7 @@ UPB_INLINE struct google_protobuf_Duration* envoy_config_core_v3_HealthCheck_mut
   return sub;
 }
 UPB_INLINE void envoy_config_core_v3_HealthCheck_set_custom_health_check(envoy_config_core_v3_HealthCheck *msg, envoy_config_core_v3_HealthCheck_CustomHealthCheck* value) {
-  UPB_WRITE_ONEOF(msg, envoy_config_core_v3_HealthCheck_CustomHealthCheck*, UPB_SIZE(76, 144), value, UPB_SIZE(80, 152), 13);
+  UPB_WRITE_ONEOF(msg, envoy_config_core_v3_HealthCheck_CustomHealthCheck*, UPB_SIZE(80, 152), value, UPB_SIZE(84, 160), 13);
 }
 UPB_INLINE struct envoy_config_core_v3_HealthCheck_CustomHealthCheck* envoy_config_core_v3_HealthCheck_mutable_custom_health_check(envoy_config_core_v3_HealthCheck *msg, upb_arena *arena) {
   struct envoy_config_core_v3_HealthCheck_CustomHealthCheck* sub = (struct envoy_config_core_v3_HealthCheck_CustomHealthCheck*)envoy_config_core_v3_HealthCheck_custom_health_check(msg);
@@ -282,7 +297,8 @@ UPB_INLINE struct envoy_config_core_v3_HealthCheck_CustomHealthCheck* envoy_conf
   return sub;
 }
 UPB_INLINE void envoy_config_core_v3_HealthCheck_set_unhealthy_interval(envoy_config_core_v3_HealthCheck *msg, struct google_protobuf_Duration* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(48, 88), struct google_protobuf_Duration*) = value;
+  _upb_sethas(msg, 9);
+  *UPB_PTR_AT(msg, UPB_SIZE(52, 96), struct google_protobuf_Duration*) = value;
 }
 UPB_INLINE struct google_protobuf_Duration* envoy_config_core_v3_HealthCheck_mutable_unhealthy_interval(envoy_config_core_v3_HealthCheck *msg, upb_arena *arena) {
   struct google_protobuf_Duration* sub = (struct google_protobuf_Duration*)envoy_config_core_v3_HealthCheck_unhealthy_interval(msg);
@@ -294,7 +310,8 @@ UPB_INLINE struct google_protobuf_Duration* envoy_config_core_v3_HealthCheck_mut
   return sub;
 }
 UPB_INLINE void envoy_config_core_v3_HealthCheck_set_unhealthy_edge_interval(envoy_config_core_v3_HealthCheck *msg, struct google_protobuf_Duration* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(52, 96), struct google_protobuf_Duration*) = value;
+  _upb_sethas(msg, 10);
+  *UPB_PTR_AT(msg, UPB_SIZE(56, 104), struct google_protobuf_Duration*) = value;
 }
 UPB_INLINE struct google_protobuf_Duration* envoy_config_core_v3_HealthCheck_mutable_unhealthy_edge_interval(envoy_config_core_v3_HealthCheck *msg, upb_arena *arena) {
   struct google_protobuf_Duration* sub = (struct google_protobuf_Duration*)envoy_config_core_v3_HealthCheck_unhealthy_edge_interval(msg);
@@ -306,7 +323,8 @@ UPB_INLINE struct google_protobuf_Duration* envoy_config_core_v3_HealthCheck_mut
   return sub;
 }
 UPB_INLINE void envoy_config_core_v3_HealthCheck_set_healthy_edge_interval(envoy_config_core_v3_HealthCheck *msg, struct google_protobuf_Duration* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(56, 104), struct google_protobuf_Duration*) = value;
+  _upb_sethas(msg, 11);
+  *UPB_PTR_AT(msg, UPB_SIZE(60, 112), struct google_protobuf_Duration*) = value;
 }
 UPB_INLINE struct google_protobuf_Duration* envoy_config_core_v3_HealthCheck_mutable_healthy_edge_interval(envoy_config_core_v3_HealthCheck *msg, upb_arena *arena) {
   struct google_protobuf_Duration* sub = (struct google_protobuf_Duration*)envoy_config_core_v3_HealthCheck_healthy_edge_interval(msg);
@@ -318,16 +336,17 @@ UPB_INLINE struct google_protobuf_Duration* envoy_config_core_v3_HealthCheck_mut
   return sub;
 }
 UPB_INLINE void envoy_config_core_v3_HealthCheck_set_event_log_path(envoy_config_core_v3_HealthCheck *msg, upb_strview value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(8, 8), upb_strview) = value;
+  *UPB_PTR_AT(msg, UPB_SIZE(12, 16), upb_strview) = value;
 }
 UPB_INLINE void envoy_config_core_v3_HealthCheck_set_interval_jitter_percent(envoy_config_core_v3_HealthCheck *msg, uint32_t value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(0, 0), uint32_t) = value;
+  *UPB_PTR_AT(msg, UPB_SIZE(4, 4), uint32_t) = value;
 }
 UPB_INLINE void envoy_config_core_v3_HealthCheck_set_always_log_health_check_failures(envoy_config_core_v3_HealthCheck *msg, bool value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(4, 4), bool) = value;
+  *UPB_PTR_AT(msg, UPB_SIZE(8, 8), bool) = value;
 }
 UPB_INLINE void envoy_config_core_v3_HealthCheck_set_initial_jitter(envoy_config_core_v3_HealthCheck *msg, struct google_protobuf_Duration* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(60, 112), struct google_protobuf_Duration*) = value;
+  _upb_sethas(msg, 12);
+  *UPB_PTR_AT(msg, UPB_SIZE(64, 120), struct google_protobuf_Duration*) = value;
 }
 UPB_INLINE struct google_protobuf_Duration* envoy_config_core_v3_HealthCheck_mutable_initial_jitter(envoy_config_core_v3_HealthCheck *msg, upb_arena *arena) {
   struct google_protobuf_Duration* sub = (struct google_protobuf_Duration*)envoy_config_core_v3_HealthCheck_initial_jitter(msg);
@@ -339,7 +358,8 @@ UPB_INLINE struct google_protobuf_Duration* envoy_config_core_v3_HealthCheck_mut
   return sub;
 }
 UPB_INLINE void envoy_config_core_v3_HealthCheck_set_tls_options(envoy_config_core_v3_HealthCheck *msg, envoy_config_core_v3_HealthCheck_TlsOptions* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(64, 120), envoy_config_core_v3_HealthCheck_TlsOptions*) = value;
+  _upb_sethas(msg, 13);
+  *UPB_PTR_AT(msg, UPB_SIZE(68, 128), envoy_config_core_v3_HealthCheck_TlsOptions*) = value;
 }
 UPB_INLINE struct envoy_config_core_v3_HealthCheck_TlsOptions* envoy_config_core_v3_HealthCheck_mutable_tls_options(envoy_config_core_v3_HealthCheck *msg, upb_arena *arena) {
   struct envoy_config_core_v3_HealthCheck_TlsOptions* sub = (struct envoy_config_core_v3_HealthCheck_TlsOptions*)envoy_config_core_v3_HealthCheck_tls_options(msg);
@@ -351,7 +371,8 @@ UPB_INLINE struct envoy_config_core_v3_HealthCheck_TlsOptions* envoy_config_core
   return sub;
 }
 UPB_INLINE void envoy_config_core_v3_HealthCheck_set_event_service(envoy_config_core_v3_HealthCheck *msg, struct envoy_config_core_v3_EventServiceConfig* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(68, 128), struct envoy_config_core_v3_EventServiceConfig*) = value;
+  _upb_sethas(msg, 14);
+  *UPB_PTR_AT(msg, UPB_SIZE(72, 136), struct envoy_config_core_v3_EventServiceConfig*) = value;
 }
 UPB_INLINE struct envoy_config_core_v3_EventServiceConfig* envoy_config_core_v3_HealthCheck_mutable_event_service(envoy_config_core_v3_HealthCheck *msg, upb_arena *arena) {
   struct envoy_config_core_v3_EventServiceConfig* sub = (struct envoy_config_core_v3_EventServiceConfig*)envoy_config_core_v3_HealthCheck_event_service(msg);
@@ -363,7 +384,8 @@ UPB_INLINE struct envoy_config_core_v3_EventServiceConfig* envoy_config_core_v3_
   return sub;
 }
 UPB_INLINE void envoy_config_core_v3_HealthCheck_set_transport_socket_match_criteria(envoy_config_core_v3_HealthCheck *msg, struct google_protobuf_Struct* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(72, 136), struct google_protobuf_Struct*) = value;
+  _upb_sethas(msg, 15);
+  *UPB_PTR_AT(msg, UPB_SIZE(76, 144), struct google_protobuf_Struct*) = value;
 }
 UPB_INLINE struct google_protobuf_Struct* envoy_config_core_v3_HealthCheck_mutable_transport_socket_match_criteria(envoy_config_core_v3_HealthCheck *msg, upb_arena *arena) {
   struct google_protobuf_Struct* sub = (struct google_protobuf_Struct*)envoy_config_core_v3_HealthCheck_transport_socket_match_criteria(msg);
@@ -385,6 +407,12 @@ UPB_INLINE envoy_config_core_v3_HealthCheck_Payload *envoy_config_core_v3_Health
   envoy_config_core_v3_HealthCheck_Payload *ret = envoy_config_core_v3_HealthCheck_Payload_new(arena);
   return (ret && upb_decode(buf, size, ret, &envoy_config_core_v3_HealthCheck_Payload_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE envoy_config_core_v3_HealthCheck_Payload *envoy_config_core_v3_HealthCheck_Payload_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  envoy_config_core_v3_HealthCheck_Payload *ret = envoy_config_core_v3_HealthCheck_Payload_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &envoy_config_core_v3_HealthCheck_Payload_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *envoy_config_core_v3_HealthCheck_Payload_serialize(const envoy_config_core_v3_HealthCheck_Payload *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &envoy_config_core_v3_HealthCheck_Payload_msginit, arena, len);
 }
@@ -418,23 +446,29 @@ UPB_INLINE envoy_config_core_v3_HealthCheck_HttpHealthCheck *envoy_config_core_v
   envoy_config_core_v3_HealthCheck_HttpHealthCheck *ret = envoy_config_core_v3_HealthCheck_HttpHealthCheck_new(arena);
   return (ret && upb_decode(buf, size, ret, &envoy_config_core_v3_HealthCheck_HttpHealthCheck_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE envoy_config_core_v3_HealthCheck_HttpHealthCheck *envoy_config_core_v3_HealthCheck_HttpHealthCheck_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  envoy_config_core_v3_HealthCheck_HttpHealthCheck *ret = envoy_config_core_v3_HealthCheck_HttpHealthCheck_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &envoy_config_core_v3_HealthCheck_HttpHealthCheck_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *envoy_config_core_v3_HealthCheck_HttpHealthCheck_serialize(const envoy_config_core_v3_HealthCheck_HttpHealthCheck *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &envoy_config_core_v3_HealthCheck_HttpHealthCheck_msginit, arena, len);
 }
 
 UPB_INLINE upb_strview envoy_config_core_v3_HealthCheck_HttpHealthCheck_host(const envoy_config_core_v3_HealthCheck_HttpHealthCheck *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(8, 8), upb_strview); }
 UPB_INLINE upb_strview envoy_config_core_v3_HealthCheck_HttpHealthCheck_path(const envoy_config_core_v3_HealthCheck_HttpHealthCheck *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(16, 24), upb_strview); }
-UPB_INLINE bool envoy_config_core_v3_HealthCheck_HttpHealthCheck_has_send(const envoy_config_core_v3_HealthCheck_HttpHealthCheck *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(24, 40)); }
+UPB_INLINE bool envoy_config_core_v3_HealthCheck_HttpHealthCheck_has_send(const envoy_config_core_v3_HealthCheck_HttpHealthCheck *msg) { return _upb_hasbit(msg, 1); }
 UPB_INLINE const envoy_config_core_v3_HealthCheck_Payload* envoy_config_core_v3_HealthCheck_HttpHealthCheck_send(const envoy_config_core_v3_HealthCheck_HttpHealthCheck *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(24, 40), const envoy_config_core_v3_HealthCheck_Payload*); }
-UPB_INLINE bool envoy_config_core_v3_HealthCheck_HttpHealthCheck_has_receive(const envoy_config_core_v3_HealthCheck_HttpHealthCheck *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(28, 48)); }
+UPB_INLINE bool envoy_config_core_v3_HealthCheck_HttpHealthCheck_has_receive(const envoy_config_core_v3_HealthCheck_HttpHealthCheck *msg) { return _upb_hasbit(msg, 2); }
 UPB_INLINE const envoy_config_core_v3_HealthCheck_Payload* envoy_config_core_v3_HealthCheck_HttpHealthCheck_receive(const envoy_config_core_v3_HealthCheck_HttpHealthCheck *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(28, 48), const envoy_config_core_v3_HealthCheck_Payload*); }
 UPB_INLINE bool envoy_config_core_v3_HealthCheck_HttpHealthCheck_has_request_headers_to_add(const envoy_config_core_v3_HealthCheck_HttpHealthCheck *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(36, 64)); }
 UPB_INLINE const struct envoy_config_core_v3_HeaderValueOption* const* envoy_config_core_v3_HealthCheck_HttpHealthCheck_request_headers_to_add(const envoy_config_core_v3_HealthCheck_HttpHealthCheck *msg, size_t *len) { return (const struct envoy_config_core_v3_HeaderValueOption* const*)_upb_array_accessor(msg, UPB_SIZE(36, 64), len); }
 UPB_INLINE upb_strview const* envoy_config_core_v3_HealthCheck_HttpHealthCheck_request_headers_to_remove(const envoy_config_core_v3_HealthCheck_HttpHealthCheck *msg, size_t *len) { return (upb_strview const*)_upb_array_accessor(msg, UPB_SIZE(40, 72), len); }
 UPB_INLINE bool envoy_config_core_v3_HealthCheck_HttpHealthCheck_has_expected_statuses(const envoy_config_core_v3_HealthCheck_HttpHealthCheck *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(44, 80)); }
 UPB_INLINE const struct envoy_type_v3_Int64Range* const* envoy_config_core_v3_HealthCheck_HttpHealthCheck_expected_statuses(const envoy_config_core_v3_HealthCheck_HttpHealthCheck *msg, size_t *len) { return (const struct envoy_type_v3_Int64Range* const*)_upb_array_accessor(msg, UPB_SIZE(44, 80), len); }
-UPB_INLINE int32_t envoy_config_core_v3_HealthCheck_HttpHealthCheck_codec_client_type(const envoy_config_core_v3_HealthCheck_HttpHealthCheck *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(0, 0), int32_t); }
-UPB_INLINE bool envoy_config_core_v3_HealthCheck_HttpHealthCheck_has_service_name_matcher(const envoy_config_core_v3_HealthCheck_HttpHealthCheck *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(32, 56)); }
+UPB_INLINE int32_t envoy_config_core_v3_HealthCheck_HttpHealthCheck_codec_client_type(const envoy_config_core_v3_HealthCheck_HttpHealthCheck *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(4, 4), int32_t); }
+UPB_INLINE bool envoy_config_core_v3_HealthCheck_HttpHealthCheck_has_service_name_matcher(const envoy_config_core_v3_HealthCheck_HttpHealthCheck *msg) { return _upb_hasbit(msg, 3); }
 UPB_INLINE const struct envoy_type_matcher_v3_StringMatcher* envoy_config_core_v3_HealthCheck_HttpHealthCheck_service_name_matcher(const envoy_config_core_v3_HealthCheck_HttpHealthCheck *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(32, 56), const struct envoy_type_matcher_v3_StringMatcher*); }
 
 UPB_INLINE void envoy_config_core_v3_HealthCheck_HttpHealthCheck_set_host(envoy_config_core_v3_HealthCheck_HttpHealthCheck *msg, upb_strview value) {
@@ -444,6 +478,7 @@ UPB_INLINE void envoy_config_core_v3_HealthCheck_HttpHealthCheck_set_path(envoy_
   *UPB_PTR_AT(msg, UPB_SIZE(16, 24), upb_strview) = value;
 }
 UPB_INLINE void envoy_config_core_v3_HealthCheck_HttpHealthCheck_set_send(envoy_config_core_v3_HealthCheck_HttpHealthCheck *msg, envoy_config_core_v3_HealthCheck_Payload* value) {
+  _upb_sethas(msg, 1);
   *UPB_PTR_AT(msg, UPB_SIZE(24, 40), envoy_config_core_v3_HealthCheck_Payload*) = value;
 }
 UPB_INLINE struct envoy_config_core_v3_HealthCheck_Payload* envoy_config_core_v3_HealthCheck_HttpHealthCheck_mutable_send(envoy_config_core_v3_HealthCheck_HttpHealthCheck *msg, upb_arena *arena) {
@@ -456,6 +491,7 @@ UPB_INLINE struct envoy_config_core_v3_HealthCheck_Payload* envoy_config_core_v3
   return sub;
 }
 UPB_INLINE void envoy_config_core_v3_HealthCheck_HttpHealthCheck_set_receive(envoy_config_core_v3_HealthCheck_HttpHealthCheck *msg, envoy_config_core_v3_HealthCheck_Payload* value) {
+  _upb_sethas(msg, 2);
   *UPB_PTR_AT(msg, UPB_SIZE(28, 48), envoy_config_core_v3_HealthCheck_Payload*) = value;
 }
 UPB_INLINE struct envoy_config_core_v3_HealthCheck_Payload* envoy_config_core_v3_HealthCheck_HttpHealthCheck_mutable_receive(envoy_config_core_v3_HealthCheck_HttpHealthCheck *msg, upb_arena *arena) {
@@ -471,12 +507,12 @@ UPB_INLINE struct envoy_config_core_v3_HeaderValueOption** envoy_config_core_v3_
   return (struct envoy_config_core_v3_HeaderValueOption**)_upb_array_mutable_accessor(msg, UPB_SIZE(36, 64), len);
 }
 UPB_INLINE struct envoy_config_core_v3_HeaderValueOption** envoy_config_core_v3_HealthCheck_HttpHealthCheck_resize_request_headers_to_add(envoy_config_core_v3_HealthCheck_HttpHealthCheck *msg, size_t len, upb_arena *arena) {
-  return (struct envoy_config_core_v3_HeaderValueOption**)_upb_array_resize_accessor(msg, UPB_SIZE(36, 64), len, UPB_TYPE_MESSAGE, arena);
+  return (struct envoy_config_core_v3_HeaderValueOption**)_upb_array_resize_accessor2(msg, UPB_SIZE(36, 64), len, UPB_SIZE(2, 3), arena);
 }
 UPB_INLINE struct envoy_config_core_v3_HeaderValueOption* envoy_config_core_v3_HealthCheck_HttpHealthCheck_add_request_headers_to_add(envoy_config_core_v3_HealthCheck_HttpHealthCheck *msg, upb_arena *arena) {
   struct envoy_config_core_v3_HeaderValueOption* sub = (struct envoy_config_core_v3_HeaderValueOption*)_upb_msg_new(&envoy_config_core_v3_HeaderValueOption_msginit, arena);
-  bool ok = _upb_array_append_accessor(
-      msg, UPB_SIZE(36, 64), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena);
+  bool ok = _upb_array_append_accessor2(
+      msg, UPB_SIZE(36, 64), UPB_SIZE(2, 3), &sub, arena);
   if (!ok) return NULL;
   return sub;
 }
@@ -484,29 +520,30 @@ UPB_INLINE upb_strview* envoy_config_core_v3_HealthCheck_HttpHealthCheck_mutable
   return (upb_strview*)_upb_array_mutable_accessor(msg, UPB_SIZE(40, 72), len);
 }
 UPB_INLINE upb_strview* envoy_config_core_v3_HealthCheck_HttpHealthCheck_resize_request_headers_to_remove(envoy_config_core_v3_HealthCheck_HttpHealthCheck *msg, size_t len, upb_arena *arena) {
-  return (upb_strview*)_upb_array_resize_accessor(msg, UPB_SIZE(40, 72), len, UPB_TYPE_STRING, arena);
+  return (upb_strview*)_upb_array_resize_accessor2(msg, UPB_SIZE(40, 72), len, UPB_SIZE(3, 4), arena);
 }
 UPB_INLINE bool envoy_config_core_v3_HealthCheck_HttpHealthCheck_add_request_headers_to_remove(envoy_config_core_v3_HealthCheck_HttpHealthCheck *msg, upb_strview val, upb_arena *arena) {
-  return _upb_array_append_accessor(msg, UPB_SIZE(40, 72), UPB_SIZE(8, 16), UPB_TYPE_STRING, &val,
+  return _upb_array_append_accessor2(msg, UPB_SIZE(40, 72), UPB_SIZE(3, 4), &val,
       arena);
 }
 UPB_INLINE struct envoy_type_v3_Int64Range** envoy_config_core_v3_HealthCheck_HttpHealthCheck_mutable_expected_statuses(envoy_config_core_v3_HealthCheck_HttpHealthCheck *msg, size_t *len) {
   return (struct envoy_type_v3_Int64Range**)_upb_array_mutable_accessor(msg, UPB_SIZE(44, 80), len);
 }
 UPB_INLINE struct envoy_type_v3_Int64Range** envoy_config_core_v3_HealthCheck_HttpHealthCheck_resize_expected_statuses(envoy_config_core_v3_HealthCheck_HttpHealthCheck *msg, size_t len, upb_arena *arena) {
-  return (struct envoy_type_v3_Int64Range**)_upb_array_resize_accessor(msg, UPB_SIZE(44, 80), len, UPB_TYPE_MESSAGE, arena);
+  return (struct envoy_type_v3_Int64Range**)_upb_array_resize_accessor2(msg, UPB_SIZE(44, 80), len, UPB_SIZE(2, 3), arena);
 }
 UPB_INLINE struct envoy_type_v3_Int64Range* envoy_config_core_v3_HealthCheck_HttpHealthCheck_add_expected_statuses(envoy_config_core_v3_HealthCheck_HttpHealthCheck *msg, upb_arena *arena) {
   struct envoy_type_v3_Int64Range* sub = (struct envoy_type_v3_Int64Range*)_upb_msg_new(&envoy_type_v3_Int64Range_msginit, arena);
-  bool ok = _upb_array_append_accessor(
-      msg, UPB_SIZE(44, 80), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena);
+  bool ok = _upb_array_append_accessor2(
+      msg, UPB_SIZE(44, 80), UPB_SIZE(2, 3), &sub, arena);
   if (!ok) return NULL;
   return sub;
 }
 UPB_INLINE void envoy_config_core_v3_HealthCheck_HttpHealthCheck_set_codec_client_type(envoy_config_core_v3_HealthCheck_HttpHealthCheck *msg, int32_t value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(0, 0), int32_t) = value;
+  *UPB_PTR_AT(msg, UPB_SIZE(4, 4), int32_t) = value;
 }
 UPB_INLINE void envoy_config_core_v3_HealthCheck_HttpHealthCheck_set_service_name_matcher(envoy_config_core_v3_HealthCheck_HttpHealthCheck *msg, struct envoy_type_matcher_v3_StringMatcher* value) {
+  _upb_sethas(msg, 3);
   *UPB_PTR_AT(msg, UPB_SIZE(32, 56), struct envoy_type_matcher_v3_StringMatcher*) = value;
 }
 UPB_INLINE struct envoy_type_matcher_v3_StringMatcher* envoy_config_core_v3_HealthCheck_HttpHealthCheck_mutable_service_name_matcher(envoy_config_core_v3_HealthCheck_HttpHealthCheck *msg, upb_arena *arena) {
@@ -529,17 +566,24 @@ UPB_INLINE envoy_config_core_v3_HealthCheck_TcpHealthCheck *envoy_config_core_v3
   envoy_config_core_v3_HealthCheck_TcpHealthCheck *ret = envoy_config_core_v3_HealthCheck_TcpHealthCheck_new(arena);
   return (ret && upb_decode(buf, size, ret, &envoy_config_core_v3_HealthCheck_TcpHealthCheck_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE envoy_config_core_v3_HealthCheck_TcpHealthCheck *envoy_config_core_v3_HealthCheck_TcpHealthCheck_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  envoy_config_core_v3_HealthCheck_TcpHealthCheck *ret = envoy_config_core_v3_HealthCheck_TcpHealthCheck_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &envoy_config_core_v3_HealthCheck_TcpHealthCheck_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *envoy_config_core_v3_HealthCheck_TcpHealthCheck_serialize(const envoy_config_core_v3_HealthCheck_TcpHealthCheck *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &envoy_config_core_v3_HealthCheck_TcpHealthCheck_msginit, arena, len);
 }
 
-UPB_INLINE bool envoy_config_core_v3_HealthCheck_TcpHealthCheck_has_send(const envoy_config_core_v3_HealthCheck_TcpHealthCheck *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(0, 0)); }
-UPB_INLINE const envoy_config_core_v3_HealthCheck_Payload* envoy_config_core_v3_HealthCheck_TcpHealthCheck_send(const envoy_config_core_v3_HealthCheck_TcpHealthCheck *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(0, 0), const envoy_config_core_v3_HealthCheck_Payload*); }
-UPB_INLINE bool envoy_config_core_v3_HealthCheck_TcpHealthCheck_has_receive(const envoy_config_core_v3_HealthCheck_TcpHealthCheck *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(4, 8)); }
-UPB_INLINE const envoy_config_core_v3_HealthCheck_Payload* const* envoy_config_core_v3_HealthCheck_TcpHealthCheck_receive(const envoy_config_core_v3_HealthCheck_TcpHealthCheck *msg, size_t *len) { return (const envoy_config_core_v3_HealthCheck_Payload* const*)_upb_array_accessor(msg, UPB_SIZE(4, 8), len); }
+UPB_INLINE bool envoy_config_core_v3_HealthCheck_TcpHealthCheck_has_send(const envoy_config_core_v3_HealthCheck_TcpHealthCheck *msg) { return _upb_hasbit(msg, 1); }
+UPB_INLINE const envoy_config_core_v3_HealthCheck_Payload* envoy_config_core_v3_HealthCheck_TcpHealthCheck_send(const envoy_config_core_v3_HealthCheck_TcpHealthCheck *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(4, 8), const envoy_config_core_v3_HealthCheck_Payload*); }
+UPB_INLINE bool envoy_config_core_v3_HealthCheck_TcpHealthCheck_has_receive(const envoy_config_core_v3_HealthCheck_TcpHealthCheck *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(8, 16)); }
+UPB_INLINE const envoy_config_core_v3_HealthCheck_Payload* const* envoy_config_core_v3_HealthCheck_TcpHealthCheck_receive(const envoy_config_core_v3_HealthCheck_TcpHealthCheck *msg, size_t *len) { return (const envoy_config_core_v3_HealthCheck_Payload* const*)_upb_array_accessor(msg, UPB_SIZE(8, 16), len); }
 
 UPB_INLINE void envoy_config_core_v3_HealthCheck_TcpHealthCheck_set_send(envoy_config_core_v3_HealthCheck_TcpHealthCheck *msg, envoy_config_core_v3_HealthCheck_Payload* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(0, 0), envoy_config_core_v3_HealthCheck_Payload*) = value;
+  _upb_sethas(msg, 1);
+  *UPB_PTR_AT(msg, UPB_SIZE(4, 8), envoy_config_core_v3_HealthCheck_Payload*) = value;
 }
 UPB_INLINE struct envoy_config_core_v3_HealthCheck_Payload* envoy_config_core_v3_HealthCheck_TcpHealthCheck_mutable_send(envoy_config_core_v3_HealthCheck_TcpHealthCheck *msg, upb_arena *arena) {
   struct envoy_config_core_v3_HealthCheck_Payload* sub = (struct envoy_config_core_v3_HealthCheck_Payload*)envoy_config_core_v3_HealthCheck_TcpHealthCheck_send(msg);
@@ -551,15 +595,15 @@ UPB_INLINE struct envoy_config_core_v3_HealthCheck_Payload* envoy_config_core_v3
   return sub;
 }
 UPB_INLINE envoy_config_core_v3_HealthCheck_Payload** envoy_config_core_v3_HealthCheck_TcpHealthCheck_mutable_receive(envoy_config_core_v3_HealthCheck_TcpHealthCheck *msg, size_t *len) {
-  return (envoy_config_core_v3_HealthCheck_Payload**)_upb_array_mutable_accessor(msg, UPB_SIZE(4, 8), len);
+  return (envoy_config_core_v3_HealthCheck_Payload**)_upb_array_mutable_accessor(msg, UPB_SIZE(8, 16), len);
 }
 UPB_INLINE envoy_config_core_v3_HealthCheck_Payload** envoy_config_core_v3_HealthCheck_TcpHealthCheck_resize_receive(envoy_config_core_v3_HealthCheck_TcpHealthCheck *msg, size_t len, upb_arena *arena) {
-  return (envoy_config_core_v3_HealthCheck_Payload**)_upb_array_resize_accessor(msg, UPB_SIZE(4, 8), len, UPB_TYPE_MESSAGE, arena);
+  return (envoy_config_core_v3_HealthCheck_Payload**)_upb_array_resize_accessor2(msg, UPB_SIZE(8, 16), len, UPB_SIZE(2, 3), arena);
 }
 UPB_INLINE struct envoy_config_core_v3_HealthCheck_Payload* envoy_config_core_v3_HealthCheck_TcpHealthCheck_add_receive(envoy_config_core_v3_HealthCheck_TcpHealthCheck *msg, upb_arena *arena) {
   struct envoy_config_core_v3_HealthCheck_Payload* sub = (struct envoy_config_core_v3_HealthCheck_Payload*)_upb_msg_new(&envoy_config_core_v3_HealthCheck_Payload_msginit, arena);
-  bool ok = _upb_array_append_accessor(
-      msg, UPB_SIZE(4, 8), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena);
+  bool ok = _upb_array_append_accessor2(
+      msg, UPB_SIZE(8, 16), UPB_SIZE(2, 3), &sub, arena);
   if (!ok) return NULL;
   return sub;
 }
@@ -574,6 +618,12 @@ UPB_INLINE envoy_config_core_v3_HealthCheck_RedisHealthCheck *envoy_config_core_
   envoy_config_core_v3_HealthCheck_RedisHealthCheck *ret = envoy_config_core_v3_HealthCheck_RedisHealthCheck_new(arena);
   return (ret && upb_decode(buf, size, ret, &envoy_config_core_v3_HealthCheck_RedisHealthCheck_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE envoy_config_core_v3_HealthCheck_RedisHealthCheck *envoy_config_core_v3_HealthCheck_RedisHealthCheck_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  envoy_config_core_v3_HealthCheck_RedisHealthCheck *ret = envoy_config_core_v3_HealthCheck_RedisHealthCheck_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &envoy_config_core_v3_HealthCheck_RedisHealthCheck_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *envoy_config_core_v3_HealthCheck_RedisHealthCheck_serialize(const envoy_config_core_v3_HealthCheck_RedisHealthCheck *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &envoy_config_core_v3_HealthCheck_RedisHealthCheck_msginit, arena, len);
 }
@@ -594,6 +644,12 @@ UPB_INLINE envoy_config_core_v3_HealthCheck_GrpcHealthCheck *envoy_config_core_v
   envoy_config_core_v3_HealthCheck_GrpcHealthCheck *ret = envoy_config_core_v3_HealthCheck_GrpcHealthCheck_new(arena);
   return (ret && upb_decode(buf, size, ret, &envoy_config_core_v3_HealthCheck_GrpcHealthCheck_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE envoy_config_core_v3_HealthCheck_GrpcHealthCheck *envoy_config_core_v3_HealthCheck_GrpcHealthCheck_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  envoy_config_core_v3_HealthCheck_GrpcHealthCheck *ret = envoy_config_core_v3_HealthCheck_GrpcHealthCheck_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &envoy_config_core_v3_HealthCheck_GrpcHealthCheck_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *envoy_config_core_v3_HealthCheck_GrpcHealthCheck_serialize(const envoy_config_core_v3_HealthCheck_GrpcHealthCheck *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &envoy_config_core_v3_HealthCheck_GrpcHealthCheck_msginit, arena, len);
 }
@@ -618,6 +674,12 @@ UPB_INLINE envoy_config_core_v3_HealthCheck_CustomHealthCheck *envoy_config_core
   envoy_config_core_v3_HealthCheck_CustomHealthCheck *ret = envoy_config_core_v3_HealthCheck_CustomHealthCheck_new(arena);
   return (ret && upb_decode(buf, size, ret, &envoy_config_core_v3_HealthCheck_CustomHealthCheck_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE envoy_config_core_v3_HealthCheck_CustomHealthCheck *envoy_config_core_v3_HealthCheck_CustomHealthCheck_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  envoy_config_core_v3_HealthCheck_CustomHealthCheck *ret = envoy_config_core_v3_HealthCheck_CustomHealthCheck_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &envoy_config_core_v3_HealthCheck_CustomHealthCheck_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *envoy_config_core_v3_HealthCheck_CustomHealthCheck_serialize(const envoy_config_core_v3_HealthCheck_CustomHealthCheck *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &envoy_config_core_v3_HealthCheck_CustomHealthCheck_msginit, arena, len);
 }
@@ -658,6 +720,12 @@ UPB_INLINE envoy_config_core_v3_HealthCheck_TlsOptions *envoy_config_core_v3_Hea
   envoy_config_core_v3_HealthCheck_TlsOptions *ret = envoy_config_core_v3_HealthCheck_TlsOptions_new(arena);
   return (ret && upb_decode(buf, size, ret, &envoy_config_core_v3_HealthCheck_TlsOptions_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE envoy_config_core_v3_HealthCheck_TlsOptions *envoy_config_core_v3_HealthCheck_TlsOptions_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  envoy_config_core_v3_HealthCheck_TlsOptions *ret = envoy_config_core_v3_HealthCheck_TlsOptions_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &envoy_config_core_v3_HealthCheck_TlsOptions_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *envoy_config_core_v3_HealthCheck_TlsOptions_serialize(const envoy_config_core_v3_HealthCheck_TlsOptions *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &envoy_config_core_v3_HealthCheck_TlsOptions_msginit, arena, len);
 }
@@ -668,10 +736,10 @@ UPB_INLINE upb_strview* envoy_config_core_v3_HealthCheck_TlsOptions_mutable_alpn
   return (upb_strview*)_upb_array_mutable_accessor(msg, UPB_SIZE(0, 0), len);
 }
 UPB_INLINE upb_strview* envoy_config_core_v3_HealthCheck_TlsOptions_resize_alpn_protocols(envoy_config_core_v3_HealthCheck_TlsOptions *msg, size_t len, upb_arena *arena) {
-  return (upb_strview*)_upb_array_resize_accessor(msg, UPB_SIZE(0, 0), len, UPB_TYPE_STRING, arena);
+  return (upb_strview*)_upb_array_resize_accessor2(msg, UPB_SIZE(0, 0), len, UPB_SIZE(3, 4), arena);
 }
 UPB_INLINE bool envoy_config_core_v3_HealthCheck_TlsOptions_add_alpn_protocols(envoy_config_core_v3_HealthCheck_TlsOptions *msg, upb_strview val, upb_arena *arena) {
-  return _upb_array_append_accessor(msg, UPB_SIZE(0, 0), UPB_SIZE(8, 16), UPB_TYPE_STRING, &val,
+  return _upb_array_append_accessor2(msg, UPB_SIZE(0, 0), UPB_SIZE(3, 4), &val,
       arena);
 }
 
index b8ac727..c39ebef 100644 (file)
@@ -21,15 +21,15 @@ static const upb_msglayout *const envoy_config_core_v3_HttpUri_submsgs[1] = {
 };
 
 static const upb_msglayout_field envoy_config_core_v3_HttpUri__fields[3] = {
-  {1, UPB_SIZE(0, 0), 0, 0, 9, 1},
-  {2, UPB_SIZE(12, 24), UPB_SIZE(-21, -41), 0, 9, 1},
-  {3, UPB_SIZE(8, 16), 0, 0, 11, 1},
+  {1, UPB_SIZE(4, 8), 0, 0, 9, 1},
+  {2, UPB_SIZE(16, 32), UPB_SIZE(-25, -49), 0, 9, 1},
+  {3, UPB_SIZE(12, 24), 1, 0, 11, 1},
 };
 
 const upb_msglayout envoy_config_core_v3_HttpUri_msginit = {
   &envoy_config_core_v3_HttpUri_submsgs[0],
   &envoy_config_core_v3_HttpUri__fields[0],
-  UPB_SIZE(24, 48), 3, false,
+  UPB_SIZE(32, 64), 3, false, 255,
 };
 
 #include "upb/port_undef.inc"
index 8682067..c49eec1 100644 (file)
@@ -11,6 +11,7 @@
 
 #include "upb/msg.h"
 #include "upb/decode.h"
+#include "upb/decode_fast.h"
 #include "upb/encode.h"
 
 #include "upb/port_def.inc"
@@ -36,6 +37,12 @@ UPB_INLINE envoy_config_core_v3_HttpUri *envoy_config_core_v3_HttpUri_parse(cons
   envoy_config_core_v3_HttpUri *ret = envoy_config_core_v3_HttpUri_new(arena);
   return (ret && upb_decode(buf, size, ret, &envoy_config_core_v3_HttpUri_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE envoy_config_core_v3_HttpUri *envoy_config_core_v3_HttpUri_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  envoy_config_core_v3_HttpUri *ret = envoy_config_core_v3_HttpUri_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &envoy_config_core_v3_HttpUri_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *envoy_config_core_v3_HttpUri_serialize(const envoy_config_core_v3_HttpUri *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &envoy_config_core_v3_HttpUri_msginit, arena, len);
 }
@@ -44,22 +51,23 @@ typedef enum {
   envoy_config_core_v3_HttpUri_http_upstream_type_cluster = 2,
   envoy_config_core_v3_HttpUri_http_upstream_type_NOT_SET = 0
 } envoy_config_core_v3_HttpUri_http_upstream_type_oneofcases;
-UPB_INLINE envoy_config_core_v3_HttpUri_http_upstream_type_oneofcases envoy_config_core_v3_HttpUri_http_upstream_type_case(const envoy_config_core_v3_HttpUri* msg) { return (envoy_config_core_v3_HttpUri_http_upstream_type_oneofcases)*UPB_PTR_AT(msg, UPB_SIZE(20, 40), int32_t); }
+UPB_INLINE envoy_config_core_v3_HttpUri_http_upstream_type_oneofcases envoy_config_core_v3_HttpUri_http_upstream_type_case(const envoy_config_core_v3_HttpUri* msg) { return (envoy_config_core_v3_HttpUri_http_upstream_type_oneofcases)*UPB_PTR_AT(msg, UPB_SIZE(24, 48), int32_t); }
 
-UPB_INLINE upb_strview envoy_config_core_v3_HttpUri_uri(const envoy_config_core_v3_HttpUri *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(0, 0), upb_strview); }
-UPB_INLINE bool envoy_config_core_v3_HttpUri_has_cluster(const envoy_config_core_v3_HttpUri *msg) { return _upb_getoneofcase(msg, UPB_SIZE(20, 40)) == 2; }
-UPB_INLINE upb_strview envoy_config_core_v3_HttpUri_cluster(const envoy_config_core_v3_HttpUri *msg) { return UPB_READ_ONEOF(msg, upb_strview, UPB_SIZE(12, 24), UPB_SIZE(20, 40), 2, upb_strview_make("", strlen(""))); }
-UPB_INLINE bool envoy_config_core_v3_HttpUri_has_timeout(const envoy_config_core_v3_HttpUri *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(8, 16)); }
-UPB_INLINE const struct google_protobuf_Duration* envoy_config_core_v3_HttpUri_timeout(const envoy_config_core_v3_HttpUri *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(8, 16), const struct google_protobuf_Duration*); }
+UPB_INLINE upb_strview envoy_config_core_v3_HttpUri_uri(const envoy_config_core_v3_HttpUri *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(4, 8), upb_strview); }
+UPB_INLINE bool envoy_config_core_v3_HttpUri_has_cluster(const envoy_config_core_v3_HttpUri *msg) { return _upb_getoneofcase(msg, UPB_SIZE(24, 48)) == 2; }
+UPB_INLINE upb_strview envoy_config_core_v3_HttpUri_cluster(const envoy_config_core_v3_HttpUri *msg) { return UPB_READ_ONEOF(msg, upb_strview, UPB_SIZE(16, 32), UPB_SIZE(24, 48), 2, upb_strview_make("", strlen(""))); }
+UPB_INLINE bool envoy_config_core_v3_HttpUri_has_timeout(const envoy_config_core_v3_HttpUri *msg) { return _upb_hasbit(msg, 1); }
+UPB_INLINE const struct google_protobuf_Duration* envoy_config_core_v3_HttpUri_timeout(const envoy_config_core_v3_HttpUri *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(12, 24), const struct google_protobuf_Duration*); }
 
 UPB_INLINE void envoy_config_core_v3_HttpUri_set_uri(envoy_config_core_v3_HttpUri *msg, upb_strview value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(0, 0), upb_strview) = value;
+  *UPB_PTR_AT(msg, UPB_SIZE(4, 8), upb_strview) = value;
 }
 UPB_INLINE void envoy_config_core_v3_HttpUri_set_cluster(envoy_config_core_v3_HttpUri *msg, upb_strview value) {
-  UPB_WRITE_ONEOF(msg, upb_strview, UPB_SIZE(12, 24), value, UPB_SIZE(20, 40), 2);
+  UPB_WRITE_ONEOF(msg, upb_strview, UPB_SIZE(16, 32), value, UPB_SIZE(24, 48), 2);
 }
 UPB_INLINE void envoy_config_core_v3_HttpUri_set_timeout(envoy_config_core_v3_HttpUri *msg, struct google_protobuf_Duration* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(8, 16), struct google_protobuf_Duration*) = value;
+  _upb_sethas(msg, 1);
+  *UPB_PTR_AT(msg, UPB_SIZE(12, 24), struct google_protobuf_Duration*) = value;
 }
 UPB_INLINE struct google_protobuf_Duration* envoy_config_core_v3_HttpUri_mutable_timeout(envoy_config_core_v3_HttpUri *msg, upb_arena *arena) {
   struct google_protobuf_Duration* sub = (struct google_protobuf_Duration*)envoy_config_core_v3_HttpUri_timeout(msg);
index 000be10..2825011 100644 (file)
@@ -21,7 +21,7 @@
 const upb_msglayout envoy_config_core_v3_TcpProtocolOptions_msginit = {
   NULL,
   NULL,
-  UPB_SIZE(0, 0), 0, false,
+  UPB_SIZE(0, 0), 0, false, 255,
 };
 
 static const upb_msglayout_field envoy_config_core_v3_UpstreamHttpProtocolOptions__fields[2] = {
@@ -32,47 +32,47 @@ static const upb_msglayout_field envoy_config_core_v3_UpstreamHttpProtocolOption
 const upb_msglayout envoy_config_core_v3_UpstreamHttpProtocolOptions_msginit = {
   NULL,
   &envoy_config_core_v3_UpstreamHttpProtocolOptions__fields[0],
-  UPB_SIZE(2, 2), 2, false,
+  UPB_SIZE(8, 8), 2, false, 255,
 };
 
-static const upb_msglayout *const envoy_config_core_v3_HttpProtocolOptions_submsgs[4] = {
+static const upb_msglayout *const envoy_config_core_v3_HttpProtocolOptions_submsgs[2] = {
   &google_protobuf_Duration_msginit,
   &google_protobuf_UInt32Value_msginit,
 };
 
 static const upb_msglayout_field envoy_config_core_v3_HttpProtocolOptions__fields[5] = {
-  {1, UPB_SIZE(8, 8), 0, 0, 11, 1},
-  {2, UPB_SIZE(12, 16), 0, 1, 11, 1},
-  {3, UPB_SIZE(16, 24), 0, 0, 11, 1},
-  {4, UPB_SIZE(20, 32), 0, 0, 11, 1},
-  {5, UPB_SIZE(0, 0), 0, 0, 14, 1},
+  {1, UPB_SIZE(8, 8), 1, 0, 11, 1},
+  {2, UPB_SIZE(12, 16), 2, 1, 11, 1},
+  {3, UPB_SIZE(16, 24), 3, 0, 11, 1},
+  {4, UPB_SIZE(20, 32), 4, 0, 11, 1},
+  {5, UPB_SIZE(4, 4), 0, 0, 14, 1},
 };
 
 const upb_msglayout envoy_config_core_v3_HttpProtocolOptions_msginit = {
   &envoy_config_core_v3_HttpProtocolOptions_submsgs[0],
   &envoy_config_core_v3_HttpProtocolOptions__fields[0],
-  UPB_SIZE(24, 40), 5, false,
+  UPB_SIZE(24, 40), 5, false, 255,
 };
 
-static const upb_msglayout *const envoy_config_core_v3_Http1ProtocolOptions_submsgs[3] = {
+static const upb_msglayout *const envoy_config_core_v3_Http1ProtocolOptions_submsgs[2] = {
   &envoy_config_core_v3_Http1ProtocolOptions_HeaderKeyFormat_msginit,
   &google_protobuf_BoolValue_msginit,
 };
 
 static const upb_msglayout_field envoy_config_core_v3_Http1ProtocolOptions__fields[7] = {
-  {1, UPB_SIZE(12, 24), 0, 1, 11, 1},
-  {2, UPB_SIZE(0, 0), 0, 0, 8, 1},
+  {1, UPB_SIZE(12, 24), 1, 1, 11, 1},
+  {2, UPB_SIZE(1, 1), 0, 0, 8, 1},
   {3, UPB_SIZE(4, 8), 0, 0, 9, 1},
-  {4, UPB_SIZE(16, 32), 0, 0, 11, 1},
-  {5, UPB_SIZE(1, 1), 0, 0, 8, 1},
-  {6, UPB_SIZE(2, 2), 0, 0, 8, 1},
-  {7, UPB_SIZE(20, 40), 0, 1, 11, 1},
+  {4, UPB_SIZE(16, 32), 2, 0, 11, 1},
+  {5, UPB_SIZE(2, 2), 0, 0, 8, 1},
+  {6, UPB_SIZE(3, 3), 0, 0, 8, 1},
+  {7, UPB_SIZE(20, 40), 3, 1, 11, 1},
 };
 
 const upb_msglayout envoy_config_core_v3_Http1ProtocolOptions_msginit = {
   &envoy_config_core_v3_Http1ProtocolOptions_submsgs[0],
   &envoy_config_core_v3_Http1ProtocolOptions__fields[0],
-  UPB_SIZE(24, 48), 7, false,
+  UPB_SIZE(24, 48), 7, false, 255,
 };
 
 static const upb_msglayout *const envoy_config_core_v3_Http1ProtocolOptions_HeaderKeyFormat_submsgs[1] = {
@@ -86,33 +86,33 @@ static const upb_msglayout_field envoy_config_core_v3_Http1ProtocolOptions_Heade
 const upb_msglayout envoy_config_core_v3_Http1ProtocolOptions_HeaderKeyFormat_msginit = {
   &envoy_config_core_v3_Http1ProtocolOptions_HeaderKeyFormat_submsgs[0],
   &envoy_config_core_v3_Http1ProtocolOptions_HeaderKeyFormat__fields[0],
-  UPB_SIZE(8, 16), 1, false,
+  UPB_SIZE(8, 16), 1, false, 255,
 };
 
 const upb_msglayout envoy_config_core_v3_Http1ProtocolOptions_HeaderKeyFormat_ProperCaseWords_msginit = {
   NULL,
   NULL,
-  UPB_SIZE(0, 0), 0, false,
+  UPB_SIZE(0, 0), 0, false, 255,
 };
 
-static const upb_msglayout *const envoy_config_core_v3_KeepaliveSettings_submsgs[3] = {
+static const upb_msglayout *const envoy_config_core_v3_KeepaliveSettings_submsgs[2] = {
   &envoy_type_v3_Percent_msginit,
   &google_protobuf_Duration_msginit,
 };
 
 static const upb_msglayout_field envoy_config_core_v3_KeepaliveSettings__fields[3] = {
-  {1, UPB_SIZE(0, 0), 0, 1, 11, 1},
-  {2, UPB_SIZE(4, 8), 0, 1, 11, 1},
-  {3, UPB_SIZE(8, 16), 0, 0, 11, 1},
+  {1, UPB_SIZE(4, 8), 1, 1, 11, 1},
+  {2, UPB_SIZE(8, 16), 2, 1, 11, 1},
+  {3, UPB_SIZE(12, 24), 3, 0, 11, 1},
 };
 
 const upb_msglayout envoy_config_core_v3_KeepaliveSettings_msginit = {
   &envoy_config_core_v3_KeepaliveSettings_submsgs[0],
   &envoy_config_core_v3_KeepaliveSettings__fields[0],
-  UPB_SIZE(12, 24), 3, false,
+  UPB_SIZE(16, 32), 3, false, 255,
 };
 
-static const upb_msglayout *const envoy_config_core_v3_Http2ProtocolOptions_submsgs[12] = {
+static const upb_msglayout *const envoy_config_core_v3_Http2ProtocolOptions_submsgs[4] = {
   &envoy_config_core_v3_Http2ProtocolOptions_SettingsParameter_msginit,
   &envoy_config_core_v3_KeepaliveSettings_msginit,
   &google_protobuf_BoolValue_msginit,
@@ -120,42 +120,42 @@ static const upb_msglayout *const envoy_config_core_v3_Http2ProtocolOptions_subm
 };
 
 static const upb_msglayout_field envoy_config_core_v3_Http2ProtocolOptions__fields[15] = {
-  {1, UPB_SIZE(4, 8), 0, 3, 11, 1},
-  {2, UPB_SIZE(8, 16), 0, 3, 11, 1},
-  {3, UPB_SIZE(12, 24), 0, 3, 11, 1},
-  {4, UPB_SIZE(16, 32), 0, 3, 11, 1},
-  {5, UPB_SIZE(0, 0), 0, 0, 8, 1},
-  {6, UPB_SIZE(1, 1), 0, 0, 8, 1},
-  {7, UPB_SIZE(20, 40), 0, 3, 11, 1},
-  {8, UPB_SIZE(24, 48), 0, 3, 11, 1},
-  {9, UPB_SIZE(28, 56), 0, 3, 11, 1},
-  {10, UPB_SIZE(32, 64), 0, 3, 11, 1},
-  {11, UPB_SIZE(36, 72), 0, 3, 11, 1},
-  {12, UPB_SIZE(2, 2), 0, 0, 8, 1},
-  {13, UPB_SIZE(48, 96), 0, 0, 11, 3},
-  {14, UPB_SIZE(40, 80), 0, 2, 11, 1},
-  {15, UPB_SIZE(44, 88), 0, 1, 11, 1},
+  {1, UPB_SIZE(8, 8), 1, 3, 11, 1},
+  {2, UPB_SIZE(12, 16), 2, 3, 11, 1},
+  {3, UPB_SIZE(16, 24), 3, 3, 11, 1},
+  {4, UPB_SIZE(20, 32), 4, 3, 11, 1},
+  {5, UPB_SIZE(2, 2), 0, 0, 8, 1},
+  {6, UPB_SIZE(3, 3), 0, 0, 8, 1},
+  {7, UPB_SIZE(24, 40), 5, 3, 11, 1},
+  {8, UPB_SIZE(28, 48), 6, 3, 11, 1},
+  {9, UPB_SIZE(32, 56), 7, 3, 11, 1},
+  {10, UPB_SIZE(36, 64), 8, 3, 11, 1},
+  {11, UPB_SIZE(40, 72), 9, 3, 11, 1},
+  {12, UPB_SIZE(4, 4), 0, 0, 8, 1},
+  {13, UPB_SIZE(52, 96), 0, 0, 11, 3},
+  {14, UPB_SIZE(44, 80), 10, 2, 11, 1},
+  {15, UPB_SIZE(48, 88), 11, 1, 11, 1},
 };
 
 const upb_msglayout envoy_config_core_v3_Http2ProtocolOptions_msginit = {
   &envoy_config_core_v3_Http2ProtocolOptions_submsgs[0],
   &envoy_config_core_v3_Http2ProtocolOptions__fields[0],
-  UPB_SIZE(52, 104), 15, false,
+  UPB_SIZE(56, 104), 15, false, 255,
 };
 
-static const upb_msglayout *const envoy_config_core_v3_Http2ProtocolOptions_SettingsParameter_submsgs[2] = {
+static const upb_msglayout *const envoy_config_core_v3_Http2ProtocolOptions_SettingsParameter_submsgs[1] = {
   &google_protobuf_UInt32Value_msginit,
 };
 
 static const upb_msglayout_field envoy_config_core_v3_Http2ProtocolOptions_SettingsParameter__fields[2] = {
-  {1, UPB_SIZE(0, 0), 0, 0, 11, 1},
-  {2, UPB_SIZE(4, 8), 0, 0, 11, 1},
+  {1, UPB_SIZE(4, 8), 1, 0, 11, 1},
+  {2, UPB_SIZE(8, 16), 2, 0, 11, 1},
 };
 
 const upb_msglayout envoy_config_core_v3_Http2ProtocolOptions_SettingsParameter_msginit = {
   &envoy_config_core_v3_Http2ProtocolOptions_SettingsParameter_submsgs[0],
   &envoy_config_core_v3_Http2ProtocolOptions_SettingsParameter__fields[0],
-  UPB_SIZE(8, 16), 2, false,
+  UPB_SIZE(16, 24), 2, false, 255,
 };
 
 static const upb_msglayout *const envoy_config_core_v3_GrpcProtocolOptions_submsgs[1] = {
@@ -163,13 +163,13 @@ static const upb_msglayout *const envoy_config_core_v3_GrpcProtocolOptions_subms
 };
 
 static const upb_msglayout_field envoy_config_core_v3_GrpcProtocolOptions__fields[1] = {
-  {1, UPB_SIZE(0, 0), 0, 0, 11, 1},
+  {1, UPB_SIZE(4, 8), 1, 0, 11, 1},
 };
 
 const upb_msglayout envoy_config_core_v3_GrpcProtocolOptions_msginit = {
   &envoy_config_core_v3_GrpcProtocolOptions_submsgs[0],
   &envoy_config_core_v3_GrpcProtocolOptions__fields[0],
-  UPB_SIZE(4, 8), 1, false,
+  UPB_SIZE(8, 16), 1, false, 255,
 };
 
 #include "upb/port_undef.inc"
index d895036..c690693 100644 (file)
@@ -11,6 +11,7 @@
 
 #include "upb/msg.h"
 #include "upb/decode.h"
+#include "upb/decode_fast.h"
 #include "upb/encode.h"
 
 #include "upb/port_def.inc"
@@ -75,6 +76,12 @@ UPB_INLINE envoy_config_core_v3_TcpProtocolOptions *envoy_config_core_v3_TcpProt
   envoy_config_core_v3_TcpProtocolOptions *ret = envoy_config_core_v3_TcpProtocolOptions_new(arena);
   return (ret && upb_decode(buf, size, ret, &envoy_config_core_v3_TcpProtocolOptions_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE envoy_config_core_v3_TcpProtocolOptions *envoy_config_core_v3_TcpProtocolOptions_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  envoy_config_core_v3_TcpProtocolOptions *ret = envoy_config_core_v3_TcpProtocolOptions_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &envoy_config_core_v3_TcpProtocolOptions_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *envoy_config_core_v3_TcpProtocolOptions_serialize(const envoy_config_core_v3_TcpProtocolOptions *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &envoy_config_core_v3_TcpProtocolOptions_msginit, arena, len);
 }
@@ -91,6 +98,12 @@ UPB_INLINE envoy_config_core_v3_UpstreamHttpProtocolOptions *envoy_config_core_v
   envoy_config_core_v3_UpstreamHttpProtocolOptions *ret = envoy_config_core_v3_UpstreamHttpProtocolOptions_new(arena);
   return (ret && upb_decode(buf, size, ret, &envoy_config_core_v3_UpstreamHttpProtocolOptions_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE envoy_config_core_v3_UpstreamHttpProtocolOptions *envoy_config_core_v3_UpstreamHttpProtocolOptions_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  envoy_config_core_v3_UpstreamHttpProtocolOptions *ret = envoy_config_core_v3_UpstreamHttpProtocolOptions_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &envoy_config_core_v3_UpstreamHttpProtocolOptions_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *envoy_config_core_v3_UpstreamHttpProtocolOptions_serialize(const envoy_config_core_v3_UpstreamHttpProtocolOptions *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &envoy_config_core_v3_UpstreamHttpProtocolOptions_msginit, arena, len);
 }
@@ -115,21 +128,28 @@ UPB_INLINE envoy_config_core_v3_HttpProtocolOptions *envoy_config_core_v3_HttpPr
   envoy_config_core_v3_HttpProtocolOptions *ret = envoy_config_core_v3_HttpProtocolOptions_new(arena);
   return (ret && upb_decode(buf, size, ret, &envoy_config_core_v3_HttpProtocolOptions_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE envoy_config_core_v3_HttpProtocolOptions *envoy_config_core_v3_HttpProtocolOptions_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  envoy_config_core_v3_HttpProtocolOptions *ret = envoy_config_core_v3_HttpProtocolOptions_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &envoy_config_core_v3_HttpProtocolOptions_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *envoy_config_core_v3_HttpProtocolOptions_serialize(const envoy_config_core_v3_HttpProtocolOptions *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &envoy_config_core_v3_HttpProtocolOptions_msginit, arena, len);
 }
 
-UPB_INLINE bool envoy_config_core_v3_HttpProtocolOptions_has_idle_timeout(const envoy_config_core_v3_HttpProtocolOptions *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(8, 8)); }
+UPB_INLINE bool envoy_config_core_v3_HttpProtocolOptions_has_idle_timeout(const envoy_config_core_v3_HttpProtocolOptions *msg) { return _upb_hasbit(msg, 1); }
 UPB_INLINE const struct google_protobuf_Duration* envoy_config_core_v3_HttpProtocolOptions_idle_timeout(const envoy_config_core_v3_HttpProtocolOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(8, 8), const struct google_protobuf_Duration*); }
-UPB_INLINE bool envoy_config_core_v3_HttpProtocolOptions_has_max_headers_count(const envoy_config_core_v3_HttpProtocolOptions *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(12, 16)); }
+UPB_INLINE bool envoy_config_core_v3_HttpProtocolOptions_has_max_headers_count(const envoy_config_core_v3_HttpProtocolOptions *msg) { return _upb_hasbit(msg, 2); }
 UPB_INLINE const struct google_protobuf_UInt32Value* envoy_config_core_v3_HttpProtocolOptions_max_headers_count(const envoy_config_core_v3_HttpProtocolOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(12, 16), const struct google_protobuf_UInt32Value*); }
-UPB_INLINE bool envoy_config_core_v3_HttpProtocolOptions_has_max_connection_duration(const envoy_config_core_v3_HttpProtocolOptions *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(16, 24)); }
+UPB_INLINE bool envoy_config_core_v3_HttpProtocolOptions_has_max_connection_duration(const envoy_config_core_v3_HttpProtocolOptions *msg) { return _upb_hasbit(msg, 3); }
 UPB_INLINE const struct google_protobuf_Duration* envoy_config_core_v3_HttpProtocolOptions_max_connection_duration(const envoy_config_core_v3_HttpProtocolOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(16, 24), const struct google_protobuf_Duration*); }
-UPB_INLINE bool envoy_config_core_v3_HttpProtocolOptions_has_max_stream_duration(const envoy_config_core_v3_HttpProtocolOptions *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(20, 32)); }
+UPB_INLINE bool envoy_config_core_v3_HttpProtocolOptions_has_max_stream_duration(const envoy_config_core_v3_HttpProtocolOptions *msg) { return _upb_hasbit(msg, 4); }
 UPB_INLINE const struct google_protobuf_Duration* envoy_config_core_v3_HttpProtocolOptions_max_stream_duration(const envoy_config_core_v3_HttpProtocolOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(20, 32), const struct google_protobuf_Duration*); }
-UPB_INLINE int32_t envoy_config_core_v3_HttpProtocolOptions_headers_with_underscores_action(const envoy_config_core_v3_HttpProtocolOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(0, 0), int32_t); }
+UPB_INLINE int32_t envoy_config_core_v3_HttpProtocolOptions_headers_with_underscores_action(const envoy_config_core_v3_HttpProtocolOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(4, 4), int32_t); }
 
 UPB_INLINE void envoy_config_core_v3_HttpProtocolOptions_set_idle_timeout(envoy_config_core_v3_HttpProtocolOptions *msg, struct google_protobuf_Duration* value) {
+  _upb_sethas(msg, 1);
   *UPB_PTR_AT(msg, UPB_SIZE(8, 8), struct google_protobuf_Duration*) = value;
 }
 UPB_INLINE struct google_protobuf_Duration* envoy_config_core_v3_HttpProtocolOptions_mutable_idle_timeout(envoy_config_core_v3_HttpProtocolOptions *msg, upb_arena *arena) {
@@ -142,6 +162,7 @@ UPB_INLINE struct google_protobuf_Duration* envoy_config_core_v3_HttpProtocolOpt
   return sub;
 }
 UPB_INLINE void envoy_config_core_v3_HttpProtocolOptions_set_max_headers_count(envoy_config_core_v3_HttpProtocolOptions *msg, struct google_protobuf_UInt32Value* value) {
+  _upb_sethas(msg, 2);
   *UPB_PTR_AT(msg, UPB_SIZE(12, 16), struct google_protobuf_UInt32Value*) = value;
 }
 UPB_INLINE struct google_protobuf_UInt32Value* envoy_config_core_v3_HttpProtocolOptions_mutable_max_headers_count(envoy_config_core_v3_HttpProtocolOptions *msg, upb_arena *arena) {
@@ -154,6 +175,7 @@ UPB_INLINE struct google_protobuf_UInt32Value* envoy_config_core_v3_HttpProtocol
   return sub;
 }
 UPB_INLINE void envoy_config_core_v3_HttpProtocolOptions_set_max_connection_duration(envoy_config_core_v3_HttpProtocolOptions *msg, struct google_protobuf_Duration* value) {
+  _upb_sethas(msg, 3);
   *UPB_PTR_AT(msg, UPB_SIZE(16, 24), struct google_protobuf_Duration*) = value;
 }
 UPB_INLINE struct google_protobuf_Duration* envoy_config_core_v3_HttpProtocolOptions_mutable_max_connection_duration(envoy_config_core_v3_HttpProtocolOptions *msg, upb_arena *arena) {
@@ -166,6 +188,7 @@ UPB_INLINE struct google_protobuf_Duration* envoy_config_core_v3_HttpProtocolOpt
   return sub;
 }
 UPB_INLINE void envoy_config_core_v3_HttpProtocolOptions_set_max_stream_duration(envoy_config_core_v3_HttpProtocolOptions *msg, struct google_protobuf_Duration* value) {
+  _upb_sethas(msg, 4);
   *UPB_PTR_AT(msg, UPB_SIZE(20, 32), struct google_protobuf_Duration*) = value;
 }
 UPB_INLINE struct google_protobuf_Duration* envoy_config_core_v3_HttpProtocolOptions_mutable_max_stream_duration(envoy_config_core_v3_HttpProtocolOptions *msg, upb_arena *arena) {
@@ -178,7 +201,7 @@ UPB_INLINE struct google_protobuf_Duration* envoy_config_core_v3_HttpProtocolOpt
   return sub;
 }
 UPB_INLINE void envoy_config_core_v3_HttpProtocolOptions_set_headers_with_underscores_action(envoy_config_core_v3_HttpProtocolOptions *msg, int32_t value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(0, 0), int32_t) = value;
+  *UPB_PTR_AT(msg, UPB_SIZE(4, 4), int32_t) = value;
 }
 
 /* envoy.config.core.v3.Http1ProtocolOptions */
@@ -191,22 +214,29 @@ UPB_INLINE envoy_config_core_v3_Http1ProtocolOptions *envoy_config_core_v3_Http1
   envoy_config_core_v3_Http1ProtocolOptions *ret = envoy_config_core_v3_Http1ProtocolOptions_new(arena);
   return (ret && upb_decode(buf, size, ret, &envoy_config_core_v3_Http1ProtocolOptions_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE envoy_config_core_v3_Http1ProtocolOptions *envoy_config_core_v3_Http1ProtocolOptions_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  envoy_config_core_v3_Http1ProtocolOptions *ret = envoy_config_core_v3_Http1ProtocolOptions_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &envoy_config_core_v3_Http1ProtocolOptions_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *envoy_config_core_v3_Http1ProtocolOptions_serialize(const envoy_config_core_v3_Http1ProtocolOptions *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &envoy_config_core_v3_Http1ProtocolOptions_msginit, arena, len);
 }
 
-UPB_INLINE bool envoy_config_core_v3_Http1ProtocolOptions_has_allow_absolute_url(const envoy_config_core_v3_Http1ProtocolOptions *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(12, 24)); }
+UPB_INLINE bool envoy_config_core_v3_Http1ProtocolOptions_has_allow_absolute_url(const envoy_config_core_v3_Http1ProtocolOptions *msg) { return _upb_hasbit(msg, 1); }
 UPB_INLINE const struct google_protobuf_BoolValue* envoy_config_core_v3_Http1ProtocolOptions_allow_absolute_url(const envoy_config_core_v3_Http1ProtocolOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(12, 24), const struct google_protobuf_BoolValue*); }
-UPB_INLINE bool envoy_config_core_v3_Http1ProtocolOptions_accept_http_10(const envoy_config_core_v3_Http1ProtocolOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(0, 0), bool); }
+UPB_INLINE bool envoy_config_core_v3_Http1ProtocolOptions_accept_http_10(const envoy_config_core_v3_Http1ProtocolOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(1, 1), bool); }
 UPB_INLINE upb_strview envoy_config_core_v3_Http1ProtocolOptions_default_host_for_http_10(const envoy_config_core_v3_Http1ProtocolOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(4, 8), upb_strview); }
-UPB_INLINE bool envoy_config_core_v3_Http1ProtocolOptions_has_header_key_format(const envoy_config_core_v3_Http1ProtocolOptions *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(16, 32)); }
+UPB_INLINE bool envoy_config_core_v3_Http1ProtocolOptions_has_header_key_format(const envoy_config_core_v3_Http1ProtocolOptions *msg) { return _upb_hasbit(msg, 2); }
 UPB_INLINE const envoy_config_core_v3_Http1ProtocolOptions_HeaderKeyFormat* envoy_config_core_v3_Http1ProtocolOptions_header_key_format(const envoy_config_core_v3_Http1ProtocolOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(16, 32), const envoy_config_core_v3_Http1ProtocolOptions_HeaderKeyFormat*); }
-UPB_INLINE bool envoy_config_core_v3_Http1ProtocolOptions_enable_trailers(const envoy_config_core_v3_Http1ProtocolOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(1, 1), bool); }
-UPB_INLINE bool envoy_config_core_v3_Http1ProtocolOptions_allow_chunked_length(const envoy_config_core_v3_Http1ProtocolOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(2, 2), bool); }
-UPB_INLINE bool envoy_config_core_v3_Http1ProtocolOptions_has_override_stream_error_on_invalid_http_message(const envoy_config_core_v3_Http1ProtocolOptions *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(20, 40)); }
+UPB_INLINE bool envoy_config_core_v3_Http1ProtocolOptions_enable_trailers(const envoy_config_core_v3_Http1ProtocolOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(2, 2), bool); }
+UPB_INLINE bool envoy_config_core_v3_Http1ProtocolOptions_allow_chunked_length(const envoy_config_core_v3_Http1ProtocolOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(3, 3), bool); }
+UPB_INLINE bool envoy_config_core_v3_Http1ProtocolOptions_has_override_stream_error_on_invalid_http_message(const envoy_config_core_v3_Http1ProtocolOptions *msg) { return _upb_hasbit(msg, 3); }
 UPB_INLINE const struct google_protobuf_BoolValue* envoy_config_core_v3_Http1ProtocolOptions_override_stream_error_on_invalid_http_message(const envoy_config_core_v3_Http1ProtocolOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(20, 40), const struct google_protobuf_BoolValue*); }
 
 UPB_INLINE void envoy_config_core_v3_Http1ProtocolOptions_set_allow_absolute_url(envoy_config_core_v3_Http1ProtocolOptions *msg, struct google_protobuf_BoolValue* value) {
+  _upb_sethas(msg, 1);
   *UPB_PTR_AT(msg, UPB_SIZE(12, 24), struct google_protobuf_BoolValue*) = value;
 }
 UPB_INLINE struct google_protobuf_BoolValue* envoy_config_core_v3_Http1ProtocolOptions_mutable_allow_absolute_url(envoy_config_core_v3_Http1ProtocolOptions *msg, upb_arena *arena) {
@@ -219,12 +249,13 @@ UPB_INLINE struct google_protobuf_BoolValue* envoy_config_core_v3_Http1ProtocolO
   return sub;
 }
 UPB_INLINE void envoy_config_core_v3_Http1ProtocolOptions_set_accept_http_10(envoy_config_core_v3_Http1ProtocolOptions *msg, bool value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(0, 0), bool) = value;
+  *UPB_PTR_AT(msg, UPB_SIZE(1, 1), bool) = value;
 }
 UPB_INLINE void envoy_config_core_v3_Http1ProtocolOptions_set_default_host_for_http_10(envoy_config_core_v3_Http1ProtocolOptions *msg, upb_strview value) {
   *UPB_PTR_AT(msg, UPB_SIZE(4, 8), upb_strview) = value;
 }
 UPB_INLINE void envoy_config_core_v3_Http1ProtocolOptions_set_header_key_format(envoy_config_core_v3_Http1ProtocolOptions *msg, envoy_config_core_v3_Http1ProtocolOptions_HeaderKeyFormat* value) {
+  _upb_sethas(msg, 2);
   *UPB_PTR_AT(msg, UPB_SIZE(16, 32), envoy_config_core_v3_Http1ProtocolOptions_HeaderKeyFormat*) = value;
 }
 UPB_INLINE struct envoy_config_core_v3_Http1ProtocolOptions_HeaderKeyFormat* envoy_config_core_v3_Http1ProtocolOptions_mutable_header_key_format(envoy_config_core_v3_Http1ProtocolOptions *msg, upb_arena *arena) {
@@ -237,12 +268,13 @@ UPB_INLINE struct envoy_config_core_v3_Http1ProtocolOptions_HeaderKeyFormat* env
   return sub;
 }
 UPB_INLINE void envoy_config_core_v3_Http1ProtocolOptions_set_enable_trailers(envoy_config_core_v3_Http1ProtocolOptions *msg, bool value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(1, 1), bool) = value;
+  *UPB_PTR_AT(msg, UPB_SIZE(2, 2), bool) = value;
 }
 UPB_INLINE void envoy_config_core_v3_Http1ProtocolOptions_set_allow_chunked_length(envoy_config_core_v3_Http1ProtocolOptions *msg, bool value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(2, 2), bool) = value;
+  *UPB_PTR_AT(msg, UPB_SIZE(3, 3), bool) = value;
 }
 UPB_INLINE void envoy_config_core_v3_Http1ProtocolOptions_set_override_stream_error_on_invalid_http_message(envoy_config_core_v3_Http1ProtocolOptions *msg, struct google_protobuf_BoolValue* value) {
+  _upb_sethas(msg, 3);
   *UPB_PTR_AT(msg, UPB_SIZE(20, 40), struct google_protobuf_BoolValue*) = value;
 }
 UPB_INLINE struct google_protobuf_BoolValue* envoy_config_core_v3_Http1ProtocolOptions_mutable_override_stream_error_on_invalid_http_message(envoy_config_core_v3_Http1ProtocolOptions *msg, upb_arena *arena) {
@@ -265,6 +297,12 @@ UPB_INLINE envoy_config_core_v3_Http1ProtocolOptions_HeaderKeyFormat *envoy_conf
   envoy_config_core_v3_Http1ProtocolOptions_HeaderKeyFormat *ret = envoy_config_core_v3_Http1ProtocolOptions_HeaderKeyFormat_new(arena);
   return (ret && upb_decode(buf, size, ret, &envoy_config_core_v3_Http1ProtocolOptions_HeaderKeyFormat_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE envoy_config_core_v3_Http1ProtocolOptions_HeaderKeyFormat *envoy_config_core_v3_Http1ProtocolOptions_HeaderKeyFormat_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  envoy_config_core_v3_Http1ProtocolOptions_HeaderKeyFormat *ret = envoy_config_core_v3_Http1ProtocolOptions_HeaderKeyFormat_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &envoy_config_core_v3_Http1ProtocolOptions_HeaderKeyFormat_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *envoy_config_core_v3_Http1ProtocolOptions_HeaderKeyFormat_serialize(const envoy_config_core_v3_Http1ProtocolOptions_HeaderKeyFormat *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &envoy_config_core_v3_Http1ProtocolOptions_HeaderKeyFormat_msginit, arena, len);
 }
@@ -301,6 +339,12 @@ UPB_INLINE envoy_config_core_v3_Http1ProtocolOptions_HeaderKeyFormat_ProperCaseW
   envoy_config_core_v3_Http1ProtocolOptions_HeaderKeyFormat_ProperCaseWords *ret = envoy_config_core_v3_Http1ProtocolOptions_HeaderKeyFormat_ProperCaseWords_new(arena);
   return (ret && upb_decode(buf, size, ret, &envoy_config_core_v3_Http1ProtocolOptions_HeaderKeyFormat_ProperCaseWords_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE envoy_config_core_v3_Http1ProtocolOptions_HeaderKeyFormat_ProperCaseWords *envoy_config_core_v3_Http1ProtocolOptions_HeaderKeyFormat_ProperCaseWords_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  envoy_config_core_v3_Http1ProtocolOptions_HeaderKeyFormat_ProperCaseWords *ret = envoy_config_core_v3_Http1ProtocolOptions_HeaderKeyFormat_ProperCaseWords_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &envoy_config_core_v3_Http1ProtocolOptions_HeaderKeyFormat_ProperCaseWords_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *envoy_config_core_v3_Http1ProtocolOptions_HeaderKeyFormat_ProperCaseWords_serialize(const envoy_config_core_v3_Http1ProtocolOptions_HeaderKeyFormat_ProperCaseWords *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &envoy_config_core_v3_Http1ProtocolOptions_HeaderKeyFormat_ProperCaseWords_msginit, arena, len);
 }
@@ -317,19 +361,26 @@ UPB_INLINE envoy_config_core_v3_KeepaliveSettings *envoy_config_core_v3_Keepaliv
   envoy_config_core_v3_KeepaliveSettings *ret = envoy_config_core_v3_KeepaliveSettings_new(arena);
   return (ret && upb_decode(buf, size, ret, &envoy_config_core_v3_KeepaliveSettings_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE envoy_config_core_v3_KeepaliveSettings *envoy_config_core_v3_KeepaliveSettings_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  envoy_config_core_v3_KeepaliveSettings *ret = envoy_config_core_v3_KeepaliveSettings_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &envoy_config_core_v3_KeepaliveSettings_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *envoy_config_core_v3_KeepaliveSettings_serialize(const envoy_config_core_v3_KeepaliveSettings *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &envoy_config_core_v3_KeepaliveSettings_msginit, arena, len);
 }
 
-UPB_INLINE bool envoy_config_core_v3_KeepaliveSettings_has_interval(const envoy_config_core_v3_KeepaliveSettings *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(0, 0)); }
-UPB_INLINE const struct google_protobuf_Duration* envoy_config_core_v3_KeepaliveSettings_interval(const envoy_config_core_v3_KeepaliveSettings *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(0, 0), const struct google_protobuf_Duration*); }
-UPB_INLINE bool envoy_config_core_v3_KeepaliveSettings_has_timeout(const envoy_config_core_v3_KeepaliveSettings *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(4, 8)); }
-UPB_INLINE const struct google_protobuf_Duration* envoy_config_core_v3_KeepaliveSettings_timeout(const envoy_config_core_v3_KeepaliveSettings *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(4, 8), const struct google_protobuf_Duration*); }
-UPB_INLINE bool envoy_config_core_v3_KeepaliveSettings_has_interval_jitter(const envoy_config_core_v3_KeepaliveSettings *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(8, 16)); }
-UPB_INLINE const struct envoy_type_v3_Percent* envoy_config_core_v3_KeepaliveSettings_interval_jitter(const envoy_config_core_v3_KeepaliveSettings *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(8, 16), const struct envoy_type_v3_Percent*); }
+UPB_INLINE bool envoy_config_core_v3_KeepaliveSettings_has_interval(const envoy_config_core_v3_KeepaliveSettings *msg) { return _upb_hasbit(msg, 1); }
+UPB_INLINE const struct google_protobuf_Duration* envoy_config_core_v3_KeepaliveSettings_interval(const envoy_config_core_v3_KeepaliveSettings *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(4, 8), const struct google_protobuf_Duration*); }
+UPB_INLINE bool envoy_config_core_v3_KeepaliveSettings_has_timeout(const envoy_config_core_v3_KeepaliveSettings *msg) { return _upb_hasbit(msg, 2); }
+UPB_INLINE const struct google_protobuf_Duration* envoy_config_core_v3_KeepaliveSettings_timeout(const envoy_config_core_v3_KeepaliveSettings *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(8, 16), const struct google_protobuf_Duration*); }
+UPB_INLINE bool envoy_config_core_v3_KeepaliveSettings_has_interval_jitter(const envoy_config_core_v3_KeepaliveSettings *msg) { return _upb_hasbit(msg, 3); }
+UPB_INLINE const struct envoy_type_v3_Percent* envoy_config_core_v3_KeepaliveSettings_interval_jitter(const envoy_config_core_v3_KeepaliveSettings *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(12, 24), const struct envoy_type_v3_Percent*); }
 
 UPB_INLINE void envoy_config_core_v3_KeepaliveSettings_set_interval(envoy_config_core_v3_KeepaliveSettings *msg, struct google_protobuf_Duration* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(0, 0), struct google_protobuf_Duration*) = value;
+  _upb_sethas(msg, 1);
+  *UPB_PTR_AT(msg, UPB_SIZE(4, 8), struct google_protobuf_Duration*) = value;
 }
 UPB_INLINE struct google_protobuf_Duration* envoy_config_core_v3_KeepaliveSettings_mutable_interval(envoy_config_core_v3_KeepaliveSettings *msg, upb_arena *arena) {
   struct google_protobuf_Duration* sub = (struct google_protobuf_Duration*)envoy_config_core_v3_KeepaliveSettings_interval(msg);
@@ -341,7 +392,8 @@ UPB_INLINE struct google_protobuf_Duration* envoy_config_core_v3_KeepaliveSettin
   return sub;
 }
 UPB_INLINE void envoy_config_core_v3_KeepaliveSettings_set_timeout(envoy_config_core_v3_KeepaliveSettings *msg, struct google_protobuf_Duration* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(4, 8), struct google_protobuf_Duration*) = value;
+  _upb_sethas(msg, 2);
+  *UPB_PTR_AT(msg, UPB_SIZE(8, 16), struct google_protobuf_Duration*) = value;
 }
 UPB_INLINE struct google_protobuf_Duration* envoy_config_core_v3_KeepaliveSettings_mutable_timeout(envoy_config_core_v3_KeepaliveSettings *msg, upb_arena *arena) {
   struct google_protobuf_Duration* sub = (struct google_protobuf_Duration*)envoy_config_core_v3_KeepaliveSettings_timeout(msg);
@@ -353,7 +405,8 @@ UPB_INLINE struct google_protobuf_Duration* envoy_config_core_v3_KeepaliveSettin
   return sub;
 }
 UPB_INLINE void envoy_config_core_v3_KeepaliveSettings_set_interval_jitter(envoy_config_core_v3_KeepaliveSettings *msg, struct envoy_type_v3_Percent* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(8, 16), struct envoy_type_v3_Percent*) = value;
+  _upb_sethas(msg, 3);
+  *UPB_PTR_AT(msg, UPB_SIZE(12, 24), struct envoy_type_v3_Percent*) = value;
 }
 UPB_INLINE struct envoy_type_v3_Percent* envoy_config_core_v3_KeepaliveSettings_mutable_interval_jitter(envoy_config_core_v3_KeepaliveSettings *msg, upb_arena *arena) {
   struct envoy_type_v3_Percent* sub = (struct envoy_type_v3_Percent*)envoy_config_core_v3_KeepaliveSettings_interval_jitter(msg);
@@ -375,40 +428,47 @@ UPB_INLINE envoy_config_core_v3_Http2ProtocolOptions *envoy_config_core_v3_Http2
   envoy_config_core_v3_Http2ProtocolOptions *ret = envoy_config_core_v3_Http2ProtocolOptions_new(arena);
   return (ret && upb_decode(buf, size, ret, &envoy_config_core_v3_Http2ProtocolOptions_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE envoy_config_core_v3_Http2ProtocolOptions *envoy_config_core_v3_Http2ProtocolOptions_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  envoy_config_core_v3_Http2ProtocolOptions *ret = envoy_config_core_v3_Http2ProtocolOptions_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &envoy_config_core_v3_Http2ProtocolOptions_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *envoy_config_core_v3_Http2ProtocolOptions_serialize(const envoy_config_core_v3_Http2ProtocolOptions *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &envoy_config_core_v3_Http2ProtocolOptions_msginit, arena, len);
 }
 
-UPB_INLINE bool envoy_config_core_v3_Http2ProtocolOptions_has_hpack_table_size(const envoy_config_core_v3_Http2ProtocolOptions *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(4, 8)); }
-UPB_INLINE const struct google_protobuf_UInt32Value* envoy_config_core_v3_Http2ProtocolOptions_hpack_table_size(const envoy_config_core_v3_Http2ProtocolOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(4, 8), const struct google_protobuf_UInt32Value*); }
-UPB_INLINE bool envoy_config_core_v3_Http2ProtocolOptions_has_max_concurrent_streams(const envoy_config_core_v3_Http2ProtocolOptions *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(8, 16)); }
-UPB_INLINE const struct google_protobuf_UInt32Value* envoy_config_core_v3_Http2ProtocolOptions_max_concurrent_streams(const envoy_config_core_v3_Http2ProtocolOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(8, 16), const struct google_protobuf_UInt32Value*); }
-UPB_INLINE bool envoy_config_core_v3_Http2ProtocolOptions_has_initial_stream_window_size(const envoy_config_core_v3_Http2ProtocolOptions *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(12, 24)); }
-UPB_INLINE const struct google_protobuf_UInt32Value* envoy_config_core_v3_Http2ProtocolOptions_initial_stream_window_size(const envoy_config_core_v3_Http2ProtocolOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(12, 24), const struct google_protobuf_UInt32Value*); }
-UPB_INLINE bool envoy_config_core_v3_Http2ProtocolOptions_has_initial_connection_window_size(const envoy_config_core_v3_Http2ProtocolOptions *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(16, 32)); }
-UPB_INLINE const struct google_protobuf_UInt32Value* envoy_config_core_v3_Http2ProtocolOptions_initial_connection_window_size(const envoy_config_core_v3_Http2ProtocolOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(16, 32), const struct google_protobuf_UInt32Value*); }
-UPB_INLINE bool envoy_config_core_v3_Http2ProtocolOptions_allow_connect(const envoy_config_core_v3_Http2ProtocolOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(0, 0), bool); }
-UPB_INLINE bool envoy_config_core_v3_Http2ProtocolOptions_allow_metadata(const envoy_config_core_v3_Http2ProtocolOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(1, 1), bool); }
-UPB_INLINE bool envoy_config_core_v3_Http2ProtocolOptions_has_max_outbound_frames(const envoy_config_core_v3_Http2ProtocolOptions *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(20, 40)); }
-UPB_INLINE const struct google_protobuf_UInt32Value* envoy_config_core_v3_Http2ProtocolOptions_max_outbound_frames(const envoy_config_core_v3_Http2ProtocolOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(20, 40), const struct google_protobuf_UInt32Value*); }
-UPB_INLINE bool envoy_config_core_v3_Http2ProtocolOptions_has_max_outbound_control_frames(const envoy_config_core_v3_Http2ProtocolOptions *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(24, 48)); }
-UPB_INLINE const struct google_protobuf_UInt32Value* envoy_config_core_v3_Http2ProtocolOptions_max_outbound_control_frames(const envoy_config_core_v3_Http2ProtocolOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(24, 48), const struct google_protobuf_UInt32Value*); }
-UPB_INLINE bool envoy_config_core_v3_Http2ProtocolOptions_has_max_consecutive_inbound_frames_with_empty_payload(const envoy_config_core_v3_Http2ProtocolOptions *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(28, 56)); }
-UPB_INLINE const struct google_protobuf_UInt32Value* envoy_config_core_v3_Http2ProtocolOptions_max_consecutive_inbound_frames_with_empty_payload(const envoy_config_core_v3_Http2ProtocolOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(28, 56), const struct google_protobuf_UInt32Value*); }
-UPB_INLINE bool envoy_config_core_v3_Http2ProtocolOptions_has_max_inbound_priority_frames_per_stream(const envoy_config_core_v3_Http2ProtocolOptions *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(32, 64)); }
-UPB_INLINE const struct google_protobuf_UInt32Value* envoy_config_core_v3_Http2ProtocolOptions_max_inbound_priority_frames_per_stream(const envoy_config_core_v3_Http2ProtocolOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(32, 64), const struct google_protobuf_UInt32Value*); }
-UPB_INLINE bool envoy_config_core_v3_Http2ProtocolOptions_has_max_inbound_window_update_frames_per_data_frame_sent(const envoy_config_core_v3_Http2ProtocolOptions *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(36, 72)); }
-UPB_INLINE const struct google_protobuf_UInt32Value* envoy_config_core_v3_Http2ProtocolOptions_max_inbound_window_update_frames_per_data_frame_sent(const envoy_config_core_v3_Http2ProtocolOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(36, 72), const struct google_protobuf_UInt32Value*); }
-UPB_INLINE bool envoy_config_core_v3_Http2ProtocolOptions_stream_error_on_invalid_http_messaging(const envoy_config_core_v3_Http2ProtocolOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(2, 2), bool); }
-UPB_INLINE bool envoy_config_core_v3_Http2ProtocolOptions_has_custom_settings_parameters(const envoy_config_core_v3_Http2ProtocolOptions *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(48, 96)); }
-UPB_INLINE const envoy_config_core_v3_Http2ProtocolOptions_SettingsParameter* const* envoy_config_core_v3_Http2ProtocolOptions_custom_settings_parameters(const envoy_config_core_v3_Http2ProtocolOptions *msg, size_t *len) { return (const envoy_config_core_v3_Http2ProtocolOptions_SettingsParameter* const*)_upb_array_accessor(msg, UPB_SIZE(48, 96), len); }
-UPB_INLINE bool envoy_config_core_v3_Http2ProtocolOptions_has_override_stream_error_on_invalid_http_message(const envoy_config_core_v3_Http2ProtocolOptions *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(40, 80)); }
-UPB_INLINE const struct google_protobuf_BoolValue* envoy_config_core_v3_Http2ProtocolOptions_override_stream_error_on_invalid_http_message(const envoy_config_core_v3_Http2ProtocolOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(40, 80), const struct google_protobuf_BoolValue*); }
-UPB_INLINE bool envoy_config_core_v3_Http2ProtocolOptions_has_connection_keepalive(const envoy_config_core_v3_Http2ProtocolOptions *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(44, 88)); }
-UPB_INLINE const envoy_config_core_v3_KeepaliveSettings* envoy_config_core_v3_Http2ProtocolOptions_connection_keepalive(const envoy_config_core_v3_Http2ProtocolOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(44, 88), const envoy_config_core_v3_KeepaliveSettings*); }
+UPB_INLINE bool envoy_config_core_v3_Http2ProtocolOptions_has_hpack_table_size(const envoy_config_core_v3_Http2ProtocolOptions *msg) { return _upb_hasbit(msg, 1); }
+UPB_INLINE const struct google_protobuf_UInt32Value* envoy_config_core_v3_Http2ProtocolOptions_hpack_table_size(const envoy_config_core_v3_Http2ProtocolOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(8, 8), const struct google_protobuf_UInt32Value*); }
+UPB_INLINE bool envoy_config_core_v3_Http2ProtocolOptions_has_max_concurrent_streams(const envoy_config_core_v3_Http2ProtocolOptions *msg) { return _upb_hasbit(msg, 2); }
+UPB_INLINE const struct google_protobuf_UInt32Value* envoy_config_core_v3_Http2ProtocolOptions_max_concurrent_streams(const envoy_config_core_v3_Http2ProtocolOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(12, 16), const struct google_protobuf_UInt32Value*); }
+UPB_INLINE bool envoy_config_core_v3_Http2ProtocolOptions_has_initial_stream_window_size(const envoy_config_core_v3_Http2ProtocolOptions *msg) { return _upb_hasbit(msg, 3); }
+UPB_INLINE const struct google_protobuf_UInt32Value* envoy_config_core_v3_Http2ProtocolOptions_initial_stream_window_size(const envoy_config_core_v3_Http2ProtocolOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(16, 24), const struct google_protobuf_UInt32Value*); }
+UPB_INLINE bool envoy_config_core_v3_Http2ProtocolOptions_has_initial_connection_window_size(const envoy_config_core_v3_Http2ProtocolOptions *msg) { return _upb_hasbit(msg, 4); }
+UPB_INLINE const struct google_protobuf_UInt32Value* envoy_config_core_v3_Http2ProtocolOptions_initial_connection_window_size(const envoy_config_core_v3_Http2ProtocolOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(20, 32), const struct google_protobuf_UInt32Value*); }
+UPB_INLINE bool envoy_config_core_v3_Http2ProtocolOptions_allow_connect(const envoy_config_core_v3_Http2ProtocolOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(2, 2), bool); }
+UPB_INLINE bool envoy_config_core_v3_Http2ProtocolOptions_allow_metadata(const envoy_config_core_v3_Http2ProtocolOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(3, 3), bool); }
+UPB_INLINE bool envoy_config_core_v3_Http2ProtocolOptions_has_max_outbound_frames(const envoy_config_core_v3_Http2ProtocolOptions *msg) { return _upb_hasbit(msg, 5); }
+UPB_INLINE const struct google_protobuf_UInt32Value* envoy_config_core_v3_Http2ProtocolOptions_max_outbound_frames(const envoy_config_core_v3_Http2ProtocolOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(24, 40), const struct google_protobuf_UInt32Value*); }
+UPB_INLINE bool envoy_config_core_v3_Http2ProtocolOptions_has_max_outbound_control_frames(const envoy_config_core_v3_Http2ProtocolOptions *msg) { return _upb_hasbit(msg, 6); }
+UPB_INLINE const struct google_protobuf_UInt32Value* envoy_config_core_v3_Http2ProtocolOptions_max_outbound_control_frames(const envoy_config_core_v3_Http2ProtocolOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(28, 48), const struct google_protobuf_UInt32Value*); }
+UPB_INLINE bool envoy_config_core_v3_Http2ProtocolOptions_has_max_consecutive_inbound_frames_with_empty_payload(const envoy_config_core_v3_Http2ProtocolOptions *msg) { return _upb_hasbit(msg, 7); }
+UPB_INLINE const struct google_protobuf_UInt32Value* envoy_config_core_v3_Http2ProtocolOptions_max_consecutive_inbound_frames_with_empty_payload(const envoy_config_core_v3_Http2ProtocolOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(32, 56), const struct google_protobuf_UInt32Value*); }
+UPB_INLINE bool envoy_config_core_v3_Http2ProtocolOptions_has_max_inbound_priority_frames_per_stream(const envoy_config_core_v3_Http2ProtocolOptions *msg) { return _upb_hasbit(msg, 8); }
+UPB_INLINE const struct google_protobuf_UInt32Value* envoy_config_core_v3_Http2ProtocolOptions_max_inbound_priority_frames_per_stream(const envoy_config_core_v3_Http2ProtocolOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(36, 64), const struct google_protobuf_UInt32Value*); }
+UPB_INLINE bool envoy_config_core_v3_Http2ProtocolOptions_has_max_inbound_window_update_frames_per_data_frame_sent(const envoy_config_core_v3_Http2ProtocolOptions *msg) { return _upb_hasbit(msg, 9); }
+UPB_INLINE const struct google_protobuf_UInt32Value* envoy_config_core_v3_Http2ProtocolOptions_max_inbound_window_update_frames_per_data_frame_sent(const envoy_config_core_v3_Http2ProtocolOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(40, 72), const struct google_protobuf_UInt32Value*); }
+UPB_INLINE bool envoy_config_core_v3_Http2ProtocolOptions_stream_error_on_invalid_http_messaging(const envoy_config_core_v3_Http2ProtocolOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(4, 4), bool); }
+UPB_INLINE bool envoy_config_core_v3_Http2ProtocolOptions_has_custom_settings_parameters(const envoy_config_core_v3_Http2ProtocolOptions *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(52, 96)); }
+UPB_INLINE const envoy_config_core_v3_Http2ProtocolOptions_SettingsParameter* const* envoy_config_core_v3_Http2ProtocolOptions_custom_settings_parameters(const envoy_config_core_v3_Http2ProtocolOptions *msg, size_t *len) { return (const envoy_config_core_v3_Http2ProtocolOptions_SettingsParameter* const*)_upb_array_accessor(msg, UPB_SIZE(52, 96), len); }
+UPB_INLINE bool envoy_config_core_v3_Http2ProtocolOptions_has_override_stream_error_on_invalid_http_message(const envoy_config_core_v3_Http2ProtocolOptions *msg) { return _upb_hasbit(msg, 10); }
+UPB_INLINE const struct google_protobuf_BoolValue* envoy_config_core_v3_Http2ProtocolOptions_override_stream_error_on_invalid_http_message(const envoy_config_core_v3_Http2ProtocolOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(44, 80), const struct google_protobuf_BoolValue*); }
+UPB_INLINE bool envoy_config_core_v3_Http2ProtocolOptions_has_connection_keepalive(const envoy_config_core_v3_Http2ProtocolOptions *msg) { return _upb_hasbit(msg, 11); }
+UPB_INLINE const envoy_config_core_v3_KeepaliveSettings* envoy_config_core_v3_Http2ProtocolOptions_connection_keepalive(const envoy_config_core_v3_Http2ProtocolOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(48, 88), const envoy_config_core_v3_KeepaliveSettings*); }
 
 UPB_INLINE void envoy_config_core_v3_Http2ProtocolOptions_set_hpack_table_size(envoy_config_core_v3_Http2ProtocolOptions *msg, struct google_protobuf_UInt32Value* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(4, 8), struct google_protobuf_UInt32Value*) = value;
+  _upb_sethas(msg, 1);
+  *UPB_PTR_AT(msg, UPB_SIZE(8, 8), struct google_protobuf_UInt32Value*) = value;
 }
 UPB_INLINE struct google_protobuf_UInt32Value* envoy_config_core_v3_Http2ProtocolOptions_mutable_hpack_table_size(envoy_config_core_v3_Http2ProtocolOptions *msg, upb_arena *arena) {
   struct google_protobuf_UInt32Value* sub = (struct google_protobuf_UInt32Value*)envoy_config_core_v3_Http2ProtocolOptions_hpack_table_size(msg);
@@ -420,7 +480,8 @@ UPB_INLINE struct google_protobuf_UInt32Value* envoy_config_core_v3_Http2Protoco
   return sub;
 }
 UPB_INLINE void envoy_config_core_v3_Http2ProtocolOptions_set_max_concurrent_streams(envoy_config_core_v3_Http2ProtocolOptions *msg, struct google_protobuf_UInt32Value* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(8, 16), struct google_protobuf_UInt32Value*) = value;
+  _upb_sethas(msg, 2);
+  *UPB_PTR_AT(msg, UPB_SIZE(12, 16), struct google_protobuf_UInt32Value*) = value;
 }
 UPB_INLINE struct google_protobuf_UInt32Value* envoy_config_core_v3_Http2ProtocolOptions_mutable_max_concurrent_streams(envoy_config_core_v3_Http2ProtocolOptions *msg, upb_arena *arena) {
   struct google_protobuf_UInt32Value* sub = (struct google_protobuf_UInt32Value*)envoy_config_core_v3_Http2ProtocolOptions_max_concurrent_streams(msg);
@@ -432,7 +493,8 @@ UPB_INLINE struct google_protobuf_UInt32Value* envoy_config_core_v3_Http2Protoco
   return sub;
 }
 UPB_INLINE void envoy_config_core_v3_Http2ProtocolOptions_set_initial_stream_window_size(envoy_config_core_v3_Http2ProtocolOptions *msg, struct google_protobuf_UInt32Value* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(12, 24), struct google_protobuf_UInt32Value*) = value;
+  _upb_sethas(msg, 3);
+  *UPB_PTR_AT(msg, UPB_SIZE(16, 24), struct google_protobuf_UInt32Value*) = value;
 }
 UPB_INLINE struct google_protobuf_UInt32Value* envoy_config_core_v3_Http2ProtocolOptions_mutable_initial_stream_window_size(envoy_config_core_v3_Http2ProtocolOptions *msg, upb_arena *arena) {
   struct google_protobuf_UInt32Value* sub = (struct google_protobuf_UInt32Value*)envoy_config_core_v3_Http2ProtocolOptions_initial_stream_window_size(msg);
@@ -444,7 +506,8 @@ UPB_INLINE struct google_protobuf_UInt32Value* envoy_config_core_v3_Http2Protoco
   return sub;
 }
 UPB_INLINE void envoy_config_core_v3_Http2ProtocolOptions_set_initial_connection_window_size(envoy_config_core_v3_Http2ProtocolOptions *msg, struct google_protobuf_UInt32Value* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(16, 32), struct google_protobuf_UInt32Value*) = value;
+  _upb_sethas(msg, 4);
+  *UPB_PTR_AT(msg, UPB_SIZE(20, 32), struct google_protobuf_UInt32Value*) = value;
 }
 UPB_INLINE struct google_protobuf_UInt32Value* envoy_config_core_v3_Http2ProtocolOptions_mutable_initial_connection_window_size(envoy_config_core_v3_Http2ProtocolOptions *msg, upb_arena *arena) {
   struct google_protobuf_UInt32Value* sub = (struct google_protobuf_UInt32Value*)envoy_config_core_v3_Http2ProtocolOptions_initial_connection_window_size(msg);
@@ -456,13 +519,14 @@ UPB_INLINE struct google_protobuf_UInt32Value* envoy_config_core_v3_Http2Protoco
   return sub;
 }
 UPB_INLINE void envoy_config_core_v3_Http2ProtocolOptions_set_allow_connect(envoy_config_core_v3_Http2ProtocolOptions *msg, bool value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(0, 0), bool) = value;
+  *UPB_PTR_AT(msg, UPB_SIZE(2, 2), bool) = value;
 }
 UPB_INLINE void envoy_config_core_v3_Http2ProtocolOptions_set_allow_metadata(envoy_config_core_v3_Http2ProtocolOptions *msg, bool value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(1, 1), bool) = value;
+  *UPB_PTR_AT(msg, UPB_SIZE(3, 3), bool) = value;
 }
 UPB_INLINE void envoy_config_core_v3_Http2ProtocolOptions_set_max_outbound_frames(envoy_config_core_v3_Http2ProtocolOptions *msg, struct google_protobuf_UInt32Value* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(20, 40), struct google_protobuf_UInt32Value*) = value;
+  _upb_sethas(msg, 5);
+  *UPB_PTR_AT(msg, UPB_SIZE(24, 40), struct google_protobuf_UInt32Value*) = value;
 }
 UPB_INLINE struct google_protobuf_UInt32Value* envoy_config_core_v3_Http2ProtocolOptions_mutable_max_outbound_frames(envoy_config_core_v3_Http2ProtocolOptions *msg, upb_arena *arena) {
   struct google_protobuf_UInt32Value* sub = (struct google_protobuf_UInt32Value*)envoy_config_core_v3_Http2ProtocolOptions_max_outbound_frames(msg);
@@ -474,7 +538,8 @@ UPB_INLINE struct google_protobuf_UInt32Value* envoy_config_core_v3_Http2Protoco
   return sub;
 }
 UPB_INLINE void envoy_config_core_v3_Http2ProtocolOptions_set_max_outbound_control_frames(envoy_config_core_v3_Http2ProtocolOptions *msg, struct google_protobuf_UInt32Value* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(24, 48), struct google_protobuf_UInt32Value*) = value;
+  _upb_sethas(msg, 6);
+  *UPB_PTR_AT(msg, UPB_SIZE(28, 48), struct google_protobuf_UInt32Value*) = value;
 }
 UPB_INLINE struct google_protobuf_UInt32Value* envoy_config_core_v3_Http2ProtocolOptions_mutable_max_outbound_control_frames(envoy_config_core_v3_Http2ProtocolOptions *msg, upb_arena *arena) {
   struct google_protobuf_UInt32Value* sub = (struct google_protobuf_UInt32Value*)envoy_config_core_v3_Http2ProtocolOptions_max_outbound_control_frames(msg);
@@ -486,7 +551,8 @@ UPB_INLINE struct google_protobuf_UInt32Value* envoy_config_core_v3_Http2Protoco
   return sub;
 }
 UPB_INLINE void envoy_config_core_v3_Http2ProtocolOptions_set_max_consecutive_inbound_frames_with_empty_payload(envoy_config_core_v3_Http2ProtocolOptions *msg, struct google_protobuf_UInt32Value* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(28, 56), struct google_protobuf_UInt32Value*) = value;
+  _upb_sethas(msg, 7);
+  *UPB_PTR_AT(msg, UPB_SIZE(32, 56), struct google_protobuf_UInt32Value*) = value;
 }
 UPB_INLINE struct google_protobuf_UInt32Value* envoy_config_core_v3_Http2ProtocolOptions_mutable_max_consecutive_inbound_frames_with_empty_payload(envoy_config_core_v3_Http2ProtocolOptions *msg, upb_arena *arena) {
   struct google_protobuf_UInt32Value* sub = (struct google_protobuf_UInt32Value*)envoy_config_core_v3_Http2ProtocolOptions_max_consecutive_inbound_frames_with_empty_payload(msg);
@@ -498,7 +564,8 @@ UPB_INLINE struct google_protobuf_UInt32Value* envoy_config_core_v3_Http2Protoco
   return sub;
 }
 UPB_INLINE void envoy_config_core_v3_Http2ProtocolOptions_set_max_inbound_priority_frames_per_stream(envoy_config_core_v3_Http2ProtocolOptions *msg, struct google_protobuf_UInt32Value* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(32, 64), struct google_protobuf_UInt32Value*) = value;
+  _upb_sethas(msg, 8);
+  *UPB_PTR_AT(msg, UPB_SIZE(36, 64), struct google_protobuf_UInt32Value*) = value;
 }
 UPB_INLINE struct google_protobuf_UInt32Value* envoy_config_core_v3_Http2ProtocolOptions_mutable_max_inbound_priority_frames_per_stream(envoy_config_core_v3_Http2ProtocolOptions *msg, upb_arena *arena) {
   struct google_protobuf_UInt32Value* sub = (struct google_protobuf_UInt32Value*)envoy_config_core_v3_Http2ProtocolOptions_max_inbound_priority_frames_per_stream(msg);
@@ -510,7 +577,8 @@ UPB_INLINE struct google_protobuf_UInt32Value* envoy_config_core_v3_Http2Protoco
   return sub;
 }
 UPB_INLINE void envoy_config_core_v3_Http2ProtocolOptions_set_max_inbound_window_update_frames_per_data_frame_sent(envoy_config_core_v3_Http2ProtocolOptions *msg, struct google_protobuf_UInt32Value* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(36, 72), struct google_protobuf_UInt32Value*) = value;
+  _upb_sethas(msg, 9);
+  *UPB_PTR_AT(msg, UPB_SIZE(40, 72), struct google_protobuf_UInt32Value*) = value;
 }
 UPB_INLINE struct google_protobuf_UInt32Value* envoy_config_core_v3_Http2ProtocolOptions_mutable_max_inbound_window_update_frames_per_data_frame_sent(envoy_config_core_v3_Http2ProtocolOptions *msg, upb_arena *arena) {
   struct google_protobuf_UInt32Value* sub = (struct google_protobuf_UInt32Value*)envoy_config_core_v3_Http2ProtocolOptions_max_inbound_window_update_frames_per_data_frame_sent(msg);
@@ -522,23 +590,24 @@ UPB_INLINE struct google_protobuf_UInt32Value* envoy_config_core_v3_Http2Protoco
   return sub;
 }
 UPB_INLINE void envoy_config_core_v3_Http2ProtocolOptions_set_stream_error_on_invalid_http_messaging(envoy_config_core_v3_Http2ProtocolOptions *msg, bool value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(2, 2), bool) = value;
+  *UPB_PTR_AT(msg, UPB_SIZE(4, 4), bool) = value;
 }
 UPB_INLINE envoy_config_core_v3_Http2ProtocolOptions_SettingsParameter** envoy_config_core_v3_Http2ProtocolOptions_mutable_custom_settings_parameters(envoy_config_core_v3_Http2ProtocolOptions *msg, size_t *len) {
-  return (envoy_config_core_v3_Http2ProtocolOptions_SettingsParameter**)_upb_array_mutable_accessor(msg, UPB_SIZE(48, 96), len);
+  return (envoy_config_core_v3_Http2ProtocolOptions_SettingsParameter**)_upb_array_mutable_accessor(msg, UPB_SIZE(52, 96), len);
 }
 UPB_INLINE envoy_config_core_v3_Http2ProtocolOptions_SettingsParameter** envoy_config_core_v3_Http2ProtocolOptions_resize_custom_settings_parameters(envoy_config_core_v3_Http2ProtocolOptions *msg, size_t len, upb_arena *arena) {
-  return (envoy_config_core_v3_Http2ProtocolOptions_SettingsParameter**)_upb_array_resize_accessor(msg, UPB_SIZE(48, 96), len, UPB_TYPE_MESSAGE, arena);
+  return (envoy_config_core_v3_Http2ProtocolOptions_SettingsParameter**)_upb_array_resize_accessor2(msg, UPB_SIZE(52, 96), len, UPB_SIZE(2, 3), arena);
 }
 UPB_INLINE struct envoy_config_core_v3_Http2ProtocolOptions_SettingsParameter* envoy_config_core_v3_Http2ProtocolOptions_add_custom_settings_parameters(envoy_config_core_v3_Http2ProtocolOptions *msg, upb_arena *arena) {
   struct envoy_config_core_v3_Http2ProtocolOptions_SettingsParameter* sub = (struct envoy_config_core_v3_Http2ProtocolOptions_SettingsParameter*)_upb_msg_new(&envoy_config_core_v3_Http2ProtocolOptions_SettingsParameter_msginit, arena);
-  bool ok = _upb_array_append_accessor(
-      msg, UPB_SIZE(48, 96), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena);
+  bool ok = _upb_array_append_accessor2(
+      msg, UPB_SIZE(52, 96), UPB_SIZE(2, 3), &sub, arena);
   if (!ok) return NULL;
   return sub;
 }
 UPB_INLINE void envoy_config_core_v3_Http2ProtocolOptions_set_override_stream_error_on_invalid_http_message(envoy_config_core_v3_Http2ProtocolOptions *msg, struct google_protobuf_BoolValue* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(40, 80), struct google_protobuf_BoolValue*) = value;
+  _upb_sethas(msg, 10);
+  *UPB_PTR_AT(msg, UPB_SIZE(44, 80), struct google_protobuf_BoolValue*) = value;
 }
 UPB_INLINE struct google_protobuf_BoolValue* envoy_config_core_v3_Http2ProtocolOptions_mutable_override_stream_error_on_invalid_http_message(envoy_config_core_v3_Http2ProtocolOptions *msg, upb_arena *arena) {
   struct google_protobuf_BoolValue* sub = (struct google_protobuf_BoolValue*)envoy_config_core_v3_Http2ProtocolOptions_override_stream_error_on_invalid_http_message(msg);
@@ -550,7 +619,8 @@ UPB_INLINE struct google_protobuf_BoolValue* envoy_config_core_v3_Http2ProtocolO
   return sub;
 }
 UPB_INLINE void envoy_config_core_v3_Http2ProtocolOptions_set_connection_keepalive(envoy_config_core_v3_Http2ProtocolOptions *msg, envoy_config_core_v3_KeepaliveSettings* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(44, 88), envoy_config_core_v3_KeepaliveSettings*) = value;
+  _upb_sethas(msg, 11);
+  *UPB_PTR_AT(msg, UPB_SIZE(48, 88), envoy_config_core_v3_KeepaliveSettings*) = value;
 }
 UPB_INLINE struct envoy_config_core_v3_KeepaliveSettings* envoy_config_core_v3_Http2ProtocolOptions_mutable_connection_keepalive(envoy_config_core_v3_Http2ProtocolOptions *msg, upb_arena *arena) {
   struct envoy_config_core_v3_KeepaliveSettings* sub = (struct envoy_config_core_v3_KeepaliveSettings*)envoy_config_core_v3_Http2ProtocolOptions_connection_keepalive(msg);
@@ -572,17 +642,24 @@ UPB_INLINE envoy_config_core_v3_Http2ProtocolOptions_SettingsParameter *envoy_co
   envoy_config_core_v3_Http2ProtocolOptions_SettingsParameter *ret = envoy_config_core_v3_Http2ProtocolOptions_SettingsParameter_new(arena);
   return (ret && upb_decode(buf, size, ret, &envoy_config_core_v3_Http2ProtocolOptions_SettingsParameter_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE envoy_config_core_v3_Http2ProtocolOptions_SettingsParameter *envoy_config_core_v3_Http2ProtocolOptions_SettingsParameter_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  envoy_config_core_v3_Http2ProtocolOptions_SettingsParameter *ret = envoy_config_core_v3_Http2ProtocolOptions_SettingsParameter_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &envoy_config_core_v3_Http2ProtocolOptions_SettingsParameter_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *envoy_config_core_v3_Http2ProtocolOptions_SettingsParameter_serialize(const envoy_config_core_v3_Http2ProtocolOptions_SettingsParameter *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &envoy_config_core_v3_Http2ProtocolOptions_SettingsParameter_msginit, arena, len);
 }
 
-UPB_INLINE bool envoy_config_core_v3_Http2ProtocolOptions_SettingsParameter_has_identifier(const envoy_config_core_v3_Http2ProtocolOptions_SettingsParameter *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(0, 0)); }
-UPB_INLINE const struct google_protobuf_UInt32Value* envoy_config_core_v3_Http2ProtocolOptions_SettingsParameter_identifier(const envoy_config_core_v3_Http2ProtocolOptions_SettingsParameter *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(0, 0), const struct google_protobuf_UInt32Value*); }
-UPB_INLINE bool envoy_config_core_v3_Http2ProtocolOptions_SettingsParameter_has_value(const envoy_config_core_v3_Http2ProtocolOptions_SettingsParameter *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(4, 8)); }
-UPB_INLINE const struct google_protobuf_UInt32Value* envoy_config_core_v3_Http2ProtocolOptions_SettingsParameter_value(const envoy_config_core_v3_Http2ProtocolOptions_SettingsParameter *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(4, 8), const struct google_protobuf_UInt32Value*); }
+UPB_INLINE bool envoy_config_core_v3_Http2ProtocolOptions_SettingsParameter_has_identifier(const envoy_config_core_v3_Http2ProtocolOptions_SettingsParameter *msg) { return _upb_hasbit(msg, 1); }
+UPB_INLINE const struct google_protobuf_UInt32Value* envoy_config_core_v3_Http2ProtocolOptions_SettingsParameter_identifier(const envoy_config_core_v3_Http2ProtocolOptions_SettingsParameter *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(4, 8), const struct google_protobuf_UInt32Value*); }
+UPB_INLINE bool envoy_config_core_v3_Http2ProtocolOptions_SettingsParameter_has_value(const envoy_config_core_v3_Http2ProtocolOptions_SettingsParameter *msg) { return _upb_hasbit(msg, 2); }
+UPB_INLINE const struct google_protobuf_UInt32Value* envoy_config_core_v3_Http2ProtocolOptions_SettingsParameter_value(const envoy_config_core_v3_Http2ProtocolOptions_SettingsParameter *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(8, 16), const struct google_protobuf_UInt32Value*); }
 
 UPB_INLINE void envoy_config_core_v3_Http2ProtocolOptions_SettingsParameter_set_identifier(envoy_config_core_v3_Http2ProtocolOptions_SettingsParameter *msg, struct google_protobuf_UInt32Value* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(0, 0), struct google_protobuf_UInt32Value*) = value;
+  _upb_sethas(msg, 1);
+  *UPB_PTR_AT(msg, UPB_SIZE(4, 8), struct google_protobuf_UInt32Value*) = value;
 }
 UPB_INLINE struct google_protobuf_UInt32Value* envoy_config_core_v3_Http2ProtocolOptions_SettingsParameter_mutable_identifier(envoy_config_core_v3_Http2ProtocolOptions_SettingsParameter *msg, upb_arena *arena) {
   struct google_protobuf_UInt32Value* sub = (struct google_protobuf_UInt32Value*)envoy_config_core_v3_Http2ProtocolOptions_SettingsParameter_identifier(msg);
@@ -594,7 +671,8 @@ UPB_INLINE struct google_protobuf_UInt32Value* envoy_config_core_v3_Http2Protoco
   return sub;
 }
 UPB_INLINE void envoy_config_core_v3_Http2ProtocolOptions_SettingsParameter_set_value(envoy_config_core_v3_Http2ProtocolOptions_SettingsParameter *msg, struct google_protobuf_UInt32Value* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(4, 8), struct google_protobuf_UInt32Value*) = value;
+  _upb_sethas(msg, 2);
+  *UPB_PTR_AT(msg, UPB_SIZE(8, 16), struct google_protobuf_UInt32Value*) = value;
 }
 UPB_INLINE struct google_protobuf_UInt32Value* envoy_config_core_v3_Http2ProtocolOptions_SettingsParameter_mutable_value(envoy_config_core_v3_Http2ProtocolOptions_SettingsParameter *msg, upb_arena *arena) {
   struct google_protobuf_UInt32Value* sub = (struct google_protobuf_UInt32Value*)envoy_config_core_v3_Http2ProtocolOptions_SettingsParameter_value(msg);
@@ -616,15 +694,22 @@ UPB_INLINE envoy_config_core_v3_GrpcProtocolOptions *envoy_config_core_v3_GrpcPr
   envoy_config_core_v3_GrpcProtocolOptions *ret = envoy_config_core_v3_GrpcProtocolOptions_new(arena);
   return (ret && upb_decode(buf, size, ret, &envoy_config_core_v3_GrpcProtocolOptions_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE envoy_config_core_v3_GrpcProtocolOptions *envoy_config_core_v3_GrpcProtocolOptions_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  envoy_config_core_v3_GrpcProtocolOptions *ret = envoy_config_core_v3_GrpcProtocolOptions_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &envoy_config_core_v3_GrpcProtocolOptions_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *envoy_config_core_v3_GrpcProtocolOptions_serialize(const envoy_config_core_v3_GrpcProtocolOptions *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &envoy_config_core_v3_GrpcProtocolOptions_msginit, arena, len);
 }
 
-UPB_INLINE bool envoy_config_core_v3_GrpcProtocolOptions_has_http2_protocol_options(const envoy_config_core_v3_GrpcProtocolOptions *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(0, 0)); }
-UPB_INLINE const envoy_config_core_v3_Http2ProtocolOptions* envoy_config_core_v3_GrpcProtocolOptions_http2_protocol_options(const envoy_config_core_v3_GrpcProtocolOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(0, 0), const envoy_config_core_v3_Http2ProtocolOptions*); }
+UPB_INLINE bool envoy_config_core_v3_GrpcProtocolOptions_has_http2_protocol_options(const envoy_config_core_v3_GrpcProtocolOptions *msg) { return _upb_hasbit(msg, 1); }
+UPB_INLINE const envoy_config_core_v3_Http2ProtocolOptions* envoy_config_core_v3_GrpcProtocolOptions_http2_protocol_options(const envoy_config_core_v3_GrpcProtocolOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(4, 8), const envoy_config_core_v3_Http2ProtocolOptions*); }
 
 UPB_INLINE void envoy_config_core_v3_GrpcProtocolOptions_set_http2_protocol_options(envoy_config_core_v3_GrpcProtocolOptions *msg, envoy_config_core_v3_Http2ProtocolOptions* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(0, 0), envoy_config_core_v3_Http2ProtocolOptions*) = value;
+  _upb_sethas(msg, 1);
+  *UPB_PTR_AT(msg, UPB_SIZE(4, 8), envoy_config_core_v3_Http2ProtocolOptions*) = value;
 }
 UPB_INLINE struct envoy_config_core_v3_Http2ProtocolOptions* envoy_config_core_v3_GrpcProtocolOptions_mutable_http2_protocol_options(envoy_config_core_v3_GrpcProtocolOptions *msg, upb_arena *arena) {
   struct envoy_config_core_v3_Http2ProtocolOptions* sub = (struct envoy_config_core_v3_Http2ProtocolOptions*)envoy_config_core_v3_GrpcProtocolOptions_http2_protocol_options(msg);
index 7ac6d14..3434439 100644 (file)
@@ -21,7 +21,7 @@ static const upb_msglayout_field envoy_config_core_v3_ProxyProtocolConfig__field
 const upb_msglayout envoy_config_core_v3_ProxyProtocolConfig_msginit = {
   NULL,
   &envoy_config_core_v3_ProxyProtocolConfig__fields[0],
-  UPB_SIZE(8, 8), 1, false,
+  UPB_SIZE(8, 8), 1, false, 255,
 };
 
 #include "upb/port_undef.inc"
index 9eebc0e..bd56a64 100644 (file)
@@ -11,6 +11,7 @@
 
 #include "upb/msg.h"
 #include "upb/decode.h"
+#include "upb/decode_fast.h"
 #include "upb/encode.h"
 
 #include "upb/port_def.inc"
@@ -39,6 +40,12 @@ UPB_INLINE envoy_config_core_v3_ProxyProtocolConfig *envoy_config_core_v3_ProxyP
   envoy_config_core_v3_ProxyProtocolConfig *ret = envoy_config_core_v3_ProxyProtocolConfig_new(arena);
   return (ret && upb_decode(buf, size, ret, &envoy_config_core_v3_ProxyProtocolConfig_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE envoy_config_core_v3_ProxyProtocolConfig *envoy_config_core_v3_ProxyProtocolConfig_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  envoy_config_core_v3_ProxyProtocolConfig *ret = envoy_config_core_v3_ProxyProtocolConfig_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &envoy_config_core_v3_ProxyProtocolConfig_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *envoy_config_core_v3_ProxyProtocolConfig_serialize(const envoy_config_core_v3_ProxyProtocolConfig *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &envoy_config_core_v3_ProxyProtocolConfig_msginit, arena, len);
 }
index d723cd6..d4c2ea1 100644 (file)
@@ -16,7 +16,7 @@
 #include "upb/port_def.inc"
 
 static const upb_msglayout_field envoy_config_core_v3_SocketOption__fields[6] = {
-  {1, UPB_SIZE(24, 24), 0, 0, 9, 1},
+  {1, UPB_SIZE(20, 24), 0, 0, 9, 1},
   {2, UPB_SIZE(0, 0), 0, 0, 3, 1},
   {3, UPB_SIZE(8, 8), 0, 0, 3, 1},
   {4, UPB_SIZE(32, 40), UPB_SIZE(-41, -57), 0, 3, 1},
@@ -27,7 +27,7 @@ static const upb_msglayout_field envoy_config_core_v3_SocketOption__fields[6] =
 const upb_msglayout envoy_config_core_v3_SocketOption_msginit = {
   NULL,
   &envoy_config_core_v3_SocketOption__fields[0],
-  UPB_SIZE(48, 64), 6, false,
+  UPB_SIZE(48, 64), 6, false, 255,
 };
 
 #include "upb/port_undef.inc"
index 55baf60..0347443 100644 (file)
@@ -11,6 +11,7 @@
 
 #include "upb/msg.h"
 #include "upb/decode.h"
+#include "upb/decode_fast.h"
 #include "upb/encode.h"
 
 #include "upb/port_def.inc"
@@ -40,6 +41,12 @@ UPB_INLINE envoy_config_core_v3_SocketOption *envoy_config_core_v3_SocketOption_
   envoy_config_core_v3_SocketOption *ret = envoy_config_core_v3_SocketOption_new(arena);
   return (ret && upb_decode(buf, size, ret, &envoy_config_core_v3_SocketOption_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE envoy_config_core_v3_SocketOption *envoy_config_core_v3_SocketOption_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  envoy_config_core_v3_SocketOption *ret = envoy_config_core_v3_SocketOption_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &envoy_config_core_v3_SocketOption_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *envoy_config_core_v3_SocketOption_serialize(const envoy_config_core_v3_SocketOption *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &envoy_config_core_v3_SocketOption_msginit, arena, len);
 }
@@ -51,7 +58,7 @@ typedef enum {
 } envoy_config_core_v3_SocketOption_value_oneofcases;
 UPB_INLINE envoy_config_core_v3_SocketOption_value_oneofcases envoy_config_core_v3_SocketOption_value_case(const envoy_config_core_v3_SocketOption* msg) { return (envoy_config_core_v3_SocketOption_value_oneofcases)*UPB_PTR_AT(msg, UPB_SIZE(40, 56), int32_t); }
 
-UPB_INLINE upb_strview envoy_config_core_v3_SocketOption_description(const envoy_config_core_v3_SocketOption *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(24, 24), upb_strview); }
+UPB_INLINE upb_strview envoy_config_core_v3_SocketOption_description(const envoy_config_core_v3_SocketOption *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(20, 24), upb_strview); }
 UPB_INLINE int64_t envoy_config_core_v3_SocketOption_level(const envoy_config_core_v3_SocketOption *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(0, 0), int64_t); }
 UPB_INLINE int64_t envoy_config_core_v3_SocketOption_name(const envoy_config_core_v3_SocketOption *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(8, 8), int64_t); }
 UPB_INLINE bool envoy_config_core_v3_SocketOption_has_int_value(const envoy_config_core_v3_SocketOption *msg) { return _upb_getoneofcase(msg, UPB_SIZE(40, 56)) == 4; }
@@ -61,7 +68,7 @@ UPB_INLINE upb_strview envoy_config_core_v3_SocketOption_buf_value(const envoy_c
 UPB_INLINE int32_t envoy_config_core_v3_SocketOption_state(const envoy_config_core_v3_SocketOption *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(16, 16), int32_t); }
 
 UPB_INLINE void envoy_config_core_v3_SocketOption_set_description(envoy_config_core_v3_SocketOption *msg, upb_strview value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(24, 24), upb_strview) = value;
+  *UPB_PTR_AT(msg, UPB_SIZE(20, 24), upb_strview) = value;
 }
 UPB_INLINE void envoy_config_core_v3_SocketOption_set_level(envoy_config_core_v3_SocketOption *msg, int64_t value) {
   *UPB_PTR_AT(msg, UPB_SIZE(0, 0), int64_t) = value;
index 9a85f05..cf56861 100644 (file)
@@ -29,7 +29,7 @@ static const upb_msglayout_field envoy_config_core_v3_SubstitutionFormatString__
 const upb_msglayout envoy_config_core_v3_SubstitutionFormatString_msginit = {
   &envoy_config_core_v3_SubstitutionFormatString_submsgs[0],
   &envoy_config_core_v3_SubstitutionFormatString__fields[0],
-  UPB_SIZE(24, 48), 4, false,
+  UPB_SIZE(24, 48), 4, false, 255,
 };
 
 #include "upb/port_undef.inc"
index 3f78910..439b19f 100644 (file)
@@ -11,6 +11,7 @@
 
 #include "upb/msg.h"
 #include "upb/decode.h"
+#include "upb/decode_fast.h"
 #include "upb/encode.h"
 
 #include "upb/port_def.inc"
@@ -36,6 +37,12 @@ UPB_INLINE envoy_config_core_v3_SubstitutionFormatString *envoy_config_core_v3_S
   envoy_config_core_v3_SubstitutionFormatString *ret = envoy_config_core_v3_SubstitutionFormatString_new(arena);
   return (ret && upb_decode(buf, size, ret, &envoy_config_core_v3_SubstitutionFormatString_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE envoy_config_core_v3_SubstitutionFormatString *envoy_config_core_v3_SubstitutionFormatString_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  envoy_config_core_v3_SubstitutionFormatString *ret = envoy_config_core_v3_SubstitutionFormatString_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &envoy_config_core_v3_SubstitutionFormatString_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *envoy_config_core_v3_SubstitutionFormatString_serialize(const envoy_config_core_v3_SubstitutionFormatString *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &envoy_config_core_v3_SubstitutionFormatString_msginit, arena, len);
 }
index 58fbccd..b53f726 100644 (file)
@@ -27,16 +27,16 @@ static const upb_msglayout *const envoy_config_endpoint_v3_ClusterLoadAssignment
 };
 
 static const upb_msglayout_field envoy_config_endpoint_v3_ClusterLoadAssignment__fields[4] = {
-  {1, UPB_SIZE(0, 0), 0, 0, 9, 1},
-  {2, UPB_SIZE(12, 24), 0, 2, 11, 3},
-  {4, UPB_SIZE(8, 16), 0, 1, 11, 1},
-  {5, UPB_SIZE(16, 32), 0, 0, 11, _UPB_LABEL_MAP},
+  {1, UPB_SIZE(4, 8), 0, 0, 9, 1},
+  {2, UPB_SIZE(16, 32), 0, 2, 11, 3},
+  {4, UPB_SIZE(12, 24), 1, 1, 11, 1},
+  {5, UPB_SIZE(20, 40), 0, 0, 11, _UPB_LABEL_MAP},
 };
 
 const upb_msglayout envoy_config_endpoint_v3_ClusterLoadAssignment_msginit = {
   &envoy_config_endpoint_v3_ClusterLoadAssignment_submsgs[0],
   &envoy_config_endpoint_v3_ClusterLoadAssignment__fields[0],
-  UPB_SIZE(24, 48), 4, false,
+  UPB_SIZE(24, 48), 4, false, 255,
 };
 
 static const upb_msglayout *const envoy_config_endpoint_v3_ClusterLoadAssignment_Policy_submsgs[3] = {
@@ -46,15 +46,15 @@ static const upb_msglayout *const envoy_config_endpoint_v3_ClusterLoadAssignment
 };
 
 static const upb_msglayout_field envoy_config_endpoint_v3_ClusterLoadAssignment_Policy__fields[3] = {
-  {2, UPB_SIZE(8, 16), 0, 0, 11, 3},
-  {3, UPB_SIZE(0, 0), 0, 2, 11, 1},
-  {4, UPB_SIZE(4, 8), 0, 1, 11, 1},
+  {2, UPB_SIZE(12, 24), 0, 0, 11, 3},
+  {3, UPB_SIZE(4, 8), 1, 2, 11, 1},
+  {4, UPB_SIZE(8, 16), 2, 1, 11, 1},
 };
 
 const upb_msglayout envoy_config_endpoint_v3_ClusterLoadAssignment_Policy_msginit = {
   &envoy_config_endpoint_v3_ClusterLoadAssignment_Policy_submsgs[0],
   &envoy_config_endpoint_v3_ClusterLoadAssignment_Policy__fields[0],
-  UPB_SIZE(12, 24), 3, false,
+  UPB_SIZE(16, 32), 3, false, 255,
 };
 
 static const upb_msglayout *const envoy_config_endpoint_v3_ClusterLoadAssignment_Policy_DropOverload_submsgs[1] = {
@@ -62,14 +62,14 @@ static const upb_msglayout *const envoy_config_endpoint_v3_ClusterLoadAssignment
 };
 
 static const upb_msglayout_field envoy_config_endpoint_v3_ClusterLoadAssignment_Policy_DropOverload__fields[2] = {
-  {1, UPB_SIZE(0, 0), 0, 0, 9, 1},
-  {2, UPB_SIZE(8, 16), 0, 0, 11, 1},
+  {1, UPB_SIZE(4, 8), 0, 0, 9, 1},
+  {2, UPB_SIZE(12, 24), 1, 0, 11, 1},
 };
 
 const upb_msglayout envoy_config_endpoint_v3_ClusterLoadAssignment_Policy_DropOverload_msginit = {
   &envoy_config_endpoint_v3_ClusterLoadAssignment_Policy_DropOverload_submsgs[0],
   &envoy_config_endpoint_v3_ClusterLoadAssignment_Policy_DropOverload__fields[0],
-  UPB_SIZE(16, 32), 2, false,
+  UPB_SIZE(16, 32), 2, false, 255,
 };
 
 static const upb_msglayout *const envoy_config_endpoint_v3_ClusterLoadAssignment_NamedEndpointsEntry_submsgs[1] = {
@@ -84,7 +84,7 @@ static const upb_msglayout_field envoy_config_endpoint_v3_ClusterLoadAssignment_
 const upb_msglayout envoy_config_endpoint_v3_ClusterLoadAssignment_NamedEndpointsEntry_msginit = {
   &envoy_config_endpoint_v3_ClusterLoadAssignment_NamedEndpointsEntry_submsgs[0],
   &envoy_config_endpoint_v3_ClusterLoadAssignment_NamedEndpointsEntry__fields[0],
-  UPB_SIZE(16, 32), 2, false,
+  UPB_SIZE(16, 32), 2, false, 255,
 };
 
 #include "upb/port_undef.inc"
index be00783..c89e4a4 100644 (file)
@@ -11,6 +11,7 @@
 
 #include "upb/msg.h"
 #include "upb/decode.h"
+#include "upb/decode_fast.h"
 #include "upb/encode.h"
 
 #include "upb/port_def.inc"
@@ -53,38 +54,45 @@ UPB_INLINE envoy_config_endpoint_v3_ClusterLoadAssignment *envoy_config_endpoint
   envoy_config_endpoint_v3_ClusterLoadAssignment *ret = envoy_config_endpoint_v3_ClusterLoadAssignment_new(arena);
   return (ret && upb_decode(buf, size, ret, &envoy_config_endpoint_v3_ClusterLoadAssignment_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE envoy_config_endpoint_v3_ClusterLoadAssignment *envoy_config_endpoint_v3_ClusterLoadAssignment_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  envoy_config_endpoint_v3_ClusterLoadAssignment *ret = envoy_config_endpoint_v3_ClusterLoadAssignment_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &envoy_config_endpoint_v3_ClusterLoadAssignment_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *envoy_config_endpoint_v3_ClusterLoadAssignment_serialize(const envoy_config_endpoint_v3_ClusterLoadAssignment *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &envoy_config_endpoint_v3_ClusterLoadAssignment_msginit, arena, len);
 }
 
-UPB_INLINE upb_strview envoy_config_endpoint_v3_ClusterLoadAssignment_cluster_name(const envoy_config_endpoint_v3_ClusterLoadAssignment *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(0, 0), upb_strview); }
-UPB_INLINE bool envoy_config_endpoint_v3_ClusterLoadAssignment_has_endpoints(const envoy_config_endpoint_v3_ClusterLoadAssignment *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(12, 24)); }
-UPB_INLINE const struct envoy_config_endpoint_v3_LocalityLbEndpoints* const* envoy_config_endpoint_v3_ClusterLoadAssignment_endpoints(const envoy_config_endpoint_v3_ClusterLoadAssignment *msg, size_t *len) { return (const struct envoy_config_endpoint_v3_LocalityLbEndpoints* const*)_upb_array_accessor(msg, UPB_SIZE(12, 24), len); }
-UPB_INLINE bool envoy_config_endpoint_v3_ClusterLoadAssignment_has_policy(const envoy_config_endpoint_v3_ClusterLoadAssignment *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(8, 16)); }
-UPB_INLINE const envoy_config_endpoint_v3_ClusterLoadAssignment_Policy* envoy_config_endpoint_v3_ClusterLoadAssignment_policy(const envoy_config_endpoint_v3_ClusterLoadAssignment *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(8, 16), const envoy_config_endpoint_v3_ClusterLoadAssignment_Policy*); }
-UPB_INLINE bool envoy_config_endpoint_v3_ClusterLoadAssignment_has_named_endpoints(const envoy_config_endpoint_v3_ClusterLoadAssignment *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(16, 32)); }
-UPB_INLINE size_t envoy_config_endpoint_v3_ClusterLoadAssignment_named_endpoints_size(const envoy_config_endpoint_v3_ClusterLoadAssignment *msg) {return _upb_msg_map_size(msg, UPB_SIZE(16, 32)); }
-UPB_INLINE bool envoy_config_endpoint_v3_ClusterLoadAssignment_named_endpoints_get(const envoy_config_endpoint_v3_ClusterLoadAssignment *msg, upb_strview key, struct envoy_config_endpoint_v3_Endpoint* *val) { return _upb_msg_map_get(msg, UPB_SIZE(16, 32), &key, 0, val, sizeof(*val)); }
-UPB_INLINE const envoy_config_endpoint_v3_ClusterLoadAssignment_NamedEndpointsEntry* envoy_config_endpoint_v3_ClusterLoadAssignment_named_endpoints_next(const envoy_config_endpoint_v3_ClusterLoadAssignment *msg, size_t* iter) { return (const envoy_config_endpoint_v3_ClusterLoadAssignment_NamedEndpointsEntry*)_upb_msg_map_next(msg, UPB_SIZE(16, 32), iter); }
+UPB_INLINE upb_strview envoy_config_endpoint_v3_ClusterLoadAssignment_cluster_name(const envoy_config_endpoint_v3_ClusterLoadAssignment *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(4, 8), upb_strview); }
+UPB_INLINE bool envoy_config_endpoint_v3_ClusterLoadAssignment_has_endpoints(const envoy_config_endpoint_v3_ClusterLoadAssignment *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(16, 32)); }
+UPB_INLINE const struct envoy_config_endpoint_v3_LocalityLbEndpoints* const* envoy_config_endpoint_v3_ClusterLoadAssignment_endpoints(const envoy_config_endpoint_v3_ClusterLoadAssignment *msg, size_t *len) { return (const struct envoy_config_endpoint_v3_LocalityLbEndpoints* const*)_upb_array_accessor(msg, UPB_SIZE(16, 32), len); }
+UPB_INLINE bool envoy_config_endpoint_v3_ClusterLoadAssignment_has_policy(const envoy_config_endpoint_v3_ClusterLoadAssignment *msg) { return _upb_hasbit(msg, 1); }
+UPB_INLINE const envoy_config_endpoint_v3_ClusterLoadAssignment_Policy* envoy_config_endpoint_v3_ClusterLoadAssignment_policy(const envoy_config_endpoint_v3_ClusterLoadAssignment *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(12, 24), const envoy_config_endpoint_v3_ClusterLoadAssignment_Policy*); }
+UPB_INLINE bool envoy_config_endpoint_v3_ClusterLoadAssignment_has_named_endpoints(const envoy_config_endpoint_v3_ClusterLoadAssignment *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(20, 40)); }
+UPB_INLINE size_t envoy_config_endpoint_v3_ClusterLoadAssignment_named_endpoints_size(const envoy_config_endpoint_v3_ClusterLoadAssignment *msg) {return _upb_msg_map_size(msg, UPB_SIZE(20, 40)); }
+UPB_INLINE bool envoy_config_endpoint_v3_ClusterLoadAssignment_named_endpoints_get(const envoy_config_endpoint_v3_ClusterLoadAssignment *msg, upb_strview key, struct envoy_config_endpoint_v3_Endpoint* *val) { return _upb_msg_map_get(msg, UPB_SIZE(20, 40), &key, 0, val, sizeof(*val)); }
+UPB_INLINE const envoy_config_endpoint_v3_ClusterLoadAssignment_NamedEndpointsEntry* envoy_config_endpoint_v3_ClusterLoadAssignment_named_endpoints_next(const envoy_config_endpoint_v3_ClusterLoadAssignment *msg, size_t* iter) { return (const envoy_config_endpoint_v3_ClusterLoadAssignment_NamedEndpointsEntry*)_upb_msg_map_next(msg, UPB_SIZE(20, 40), iter); }
 
 UPB_INLINE void envoy_config_endpoint_v3_ClusterLoadAssignment_set_cluster_name(envoy_config_endpoint_v3_ClusterLoadAssignment *msg, upb_strview value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(0, 0), upb_strview) = value;
+  *UPB_PTR_AT(msg, UPB_SIZE(4, 8), upb_strview) = value;
 }
 UPB_INLINE struct envoy_config_endpoint_v3_LocalityLbEndpoints** envoy_config_endpoint_v3_ClusterLoadAssignment_mutable_endpoints(envoy_config_endpoint_v3_ClusterLoadAssignment *msg, size_t *len) {
-  return (struct envoy_config_endpoint_v3_LocalityLbEndpoints**)_upb_array_mutable_accessor(msg, UPB_SIZE(12, 24), len);
+  return (struct envoy_config_endpoint_v3_LocalityLbEndpoints**)_upb_array_mutable_accessor(msg, UPB_SIZE(16, 32), len);
 }
 UPB_INLINE struct envoy_config_endpoint_v3_LocalityLbEndpoints** envoy_config_endpoint_v3_ClusterLoadAssignment_resize_endpoints(envoy_config_endpoint_v3_ClusterLoadAssignment *msg, size_t len, upb_arena *arena) {
-  return (struct envoy_config_endpoint_v3_LocalityLbEndpoints**)_upb_array_resize_accessor(msg, UPB_SIZE(12, 24), len, UPB_TYPE_MESSAGE, arena);
+  return (struct envoy_config_endpoint_v3_LocalityLbEndpoints**)_upb_array_resize_accessor2(msg, UPB_SIZE(16, 32), len, UPB_SIZE(2, 3), arena);
 }
 UPB_INLINE struct envoy_config_endpoint_v3_LocalityLbEndpoints* envoy_config_endpoint_v3_ClusterLoadAssignment_add_endpoints(envoy_config_endpoint_v3_ClusterLoadAssignment *msg, upb_arena *arena) {
   struct envoy_config_endpoint_v3_LocalityLbEndpoints* sub = (struct envoy_config_endpoint_v3_LocalityLbEndpoints*)_upb_msg_new(&envoy_config_endpoint_v3_LocalityLbEndpoints_msginit, arena);
-  bool ok = _upb_array_append_accessor(
-      msg, UPB_SIZE(12, 24), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena);
+  bool ok = _upb_array_append_accessor2(
+      msg, UPB_SIZE(16, 32), UPB_SIZE(2, 3), &sub, arena);
   if (!ok) return NULL;
   return sub;
 }
 UPB_INLINE void envoy_config_endpoint_v3_ClusterLoadAssignment_set_policy(envoy_config_endpoint_v3_ClusterLoadAssignment *msg, envoy_config_endpoint_v3_ClusterLoadAssignment_Policy* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(8, 16), envoy_config_endpoint_v3_ClusterLoadAssignment_Policy*) = value;
+  _upb_sethas(msg, 1);
+  *UPB_PTR_AT(msg, UPB_SIZE(12, 24), envoy_config_endpoint_v3_ClusterLoadAssignment_Policy*) = value;
 }
 UPB_INLINE struct envoy_config_endpoint_v3_ClusterLoadAssignment_Policy* envoy_config_endpoint_v3_ClusterLoadAssignment_mutable_policy(envoy_config_endpoint_v3_ClusterLoadAssignment *msg, upb_arena *arena) {
   struct envoy_config_endpoint_v3_ClusterLoadAssignment_Policy* sub = (struct envoy_config_endpoint_v3_ClusterLoadAssignment_Policy*)envoy_config_endpoint_v3_ClusterLoadAssignment_policy(msg);
@@ -95,10 +103,10 @@ UPB_INLINE struct envoy_config_endpoint_v3_ClusterLoadAssignment_Policy* envoy_c
   }
   return sub;
 }
-UPB_INLINE void envoy_config_endpoint_v3_ClusterLoadAssignment_named_endpoints_clear(envoy_config_endpoint_v3_ClusterLoadAssignment *msg) { _upb_msg_map_clear(msg, UPB_SIZE(16, 32)); }
-UPB_INLINE bool envoy_config_endpoint_v3_ClusterLoadAssignment_named_endpoints_set(envoy_config_endpoint_v3_ClusterLoadAssignment *msg, upb_strview key, struct envoy_config_endpoint_v3_Endpoint* val, upb_arena *a) { return _upb_msg_map_set(msg, UPB_SIZE(16, 32), &key, 0, &val, sizeof(val), a); }
-UPB_INLINE bool envoy_config_endpoint_v3_ClusterLoadAssignment_named_endpoints_delete(envoy_config_endpoint_v3_ClusterLoadAssignment *msg, upb_strview key) { return _upb_msg_map_delete(msg, UPB_SIZE(16, 32), &key, 0); }
-UPB_INLINE envoy_config_endpoint_v3_ClusterLoadAssignment_NamedEndpointsEntry* envoy_config_endpoint_v3_ClusterLoadAssignment_named_endpoints_nextmutable(envoy_config_endpoint_v3_ClusterLoadAssignment *msg, size_t* iter) { return (envoy_config_endpoint_v3_ClusterLoadAssignment_NamedEndpointsEntry*)_upb_msg_map_next(msg, UPB_SIZE(16, 32), iter); }
+UPB_INLINE void envoy_config_endpoint_v3_ClusterLoadAssignment_named_endpoints_clear(envoy_config_endpoint_v3_ClusterLoadAssignment *msg) { _upb_msg_map_clear(msg, UPB_SIZE(20, 40)); }
+UPB_INLINE bool envoy_config_endpoint_v3_ClusterLoadAssignment_named_endpoints_set(envoy_config_endpoint_v3_ClusterLoadAssignment *msg, upb_strview key, struct envoy_config_endpoint_v3_Endpoint* val, upb_arena *a) { return _upb_msg_map_set(msg, UPB_SIZE(20, 40), &key, 0, &val, sizeof(val), a); }
+UPB_INLINE bool envoy_config_endpoint_v3_ClusterLoadAssignment_named_endpoints_delete(envoy_config_endpoint_v3_ClusterLoadAssignment *msg, upb_strview key) { return _upb_msg_map_delete(msg, UPB_SIZE(20, 40), &key, 0); }
+UPB_INLINE envoy_config_endpoint_v3_ClusterLoadAssignment_NamedEndpointsEntry* envoy_config_endpoint_v3_ClusterLoadAssignment_named_endpoints_nextmutable(envoy_config_endpoint_v3_ClusterLoadAssignment *msg, size_t* iter) { return (envoy_config_endpoint_v3_ClusterLoadAssignment_NamedEndpointsEntry*)_upb_msg_map_next(msg, UPB_SIZE(20, 40), iter); }
 
 /* envoy.config.endpoint.v3.ClusterLoadAssignment.Policy */
 
@@ -110,32 +118,39 @@ UPB_INLINE envoy_config_endpoint_v3_ClusterLoadAssignment_Policy *envoy_config_e
   envoy_config_endpoint_v3_ClusterLoadAssignment_Policy *ret = envoy_config_endpoint_v3_ClusterLoadAssignment_Policy_new(arena);
   return (ret && upb_decode(buf, size, ret, &envoy_config_endpoint_v3_ClusterLoadAssignment_Policy_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE envoy_config_endpoint_v3_ClusterLoadAssignment_Policy *envoy_config_endpoint_v3_ClusterLoadAssignment_Policy_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  envoy_config_endpoint_v3_ClusterLoadAssignment_Policy *ret = envoy_config_endpoint_v3_ClusterLoadAssignment_Policy_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &envoy_config_endpoint_v3_ClusterLoadAssignment_Policy_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *envoy_config_endpoint_v3_ClusterLoadAssignment_Policy_serialize(const envoy_config_endpoint_v3_ClusterLoadAssignment_Policy *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &envoy_config_endpoint_v3_ClusterLoadAssignment_Policy_msginit, arena, len);
 }
 
-UPB_INLINE bool envoy_config_endpoint_v3_ClusterLoadAssignment_Policy_has_drop_overloads(const envoy_config_endpoint_v3_ClusterLoadAssignment_Policy *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(8, 16)); }
-UPB_INLINE const envoy_config_endpoint_v3_ClusterLoadAssignment_Policy_DropOverload* const* envoy_config_endpoint_v3_ClusterLoadAssignment_Policy_drop_overloads(const envoy_config_endpoint_v3_ClusterLoadAssignment_Policy *msg, size_t *len) { return (const envoy_config_endpoint_v3_ClusterLoadAssignment_Policy_DropOverload* const*)_upb_array_accessor(msg, UPB_SIZE(8, 16), len); }
-UPB_INLINE bool envoy_config_endpoint_v3_ClusterLoadAssignment_Policy_has_overprovisioning_factor(const envoy_config_endpoint_v3_ClusterLoadAssignment_Policy *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(0, 0)); }
-UPB_INLINE const struct google_protobuf_UInt32Value* envoy_config_endpoint_v3_ClusterLoadAssignment_Policy_overprovisioning_factor(const envoy_config_endpoint_v3_ClusterLoadAssignment_Policy *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(0, 0), const struct google_protobuf_UInt32Value*); }
-UPB_INLINE bool envoy_config_endpoint_v3_ClusterLoadAssignment_Policy_has_endpoint_stale_after(const envoy_config_endpoint_v3_ClusterLoadAssignment_Policy *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(4, 8)); }
-UPB_INLINE const struct google_protobuf_Duration* envoy_config_endpoint_v3_ClusterLoadAssignment_Policy_endpoint_stale_after(const envoy_config_endpoint_v3_ClusterLoadAssignment_Policy *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(4, 8), const struct google_protobuf_Duration*); }
+UPB_INLINE bool envoy_config_endpoint_v3_ClusterLoadAssignment_Policy_has_drop_overloads(const envoy_config_endpoint_v3_ClusterLoadAssignment_Policy *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(12, 24)); }
+UPB_INLINE const envoy_config_endpoint_v3_ClusterLoadAssignment_Policy_DropOverload* const* envoy_config_endpoint_v3_ClusterLoadAssignment_Policy_drop_overloads(const envoy_config_endpoint_v3_ClusterLoadAssignment_Policy *msg, size_t *len) { return (const envoy_config_endpoint_v3_ClusterLoadAssignment_Policy_DropOverload* const*)_upb_array_accessor(msg, UPB_SIZE(12, 24), len); }
+UPB_INLINE bool envoy_config_endpoint_v3_ClusterLoadAssignment_Policy_has_overprovisioning_factor(const envoy_config_endpoint_v3_ClusterLoadAssignment_Policy *msg) { return _upb_hasbit(msg, 1); }
+UPB_INLINE const struct google_protobuf_UInt32Value* envoy_config_endpoint_v3_ClusterLoadAssignment_Policy_overprovisioning_factor(const envoy_config_endpoint_v3_ClusterLoadAssignment_Policy *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(4, 8), const struct google_protobuf_UInt32Value*); }
+UPB_INLINE bool envoy_config_endpoint_v3_ClusterLoadAssignment_Policy_has_endpoint_stale_after(const envoy_config_endpoint_v3_ClusterLoadAssignment_Policy *msg) { return _upb_hasbit(msg, 2); }
+UPB_INLINE const struct google_protobuf_Duration* envoy_config_endpoint_v3_ClusterLoadAssignment_Policy_endpoint_stale_after(const envoy_config_endpoint_v3_ClusterLoadAssignment_Policy *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(8, 16), const struct google_protobuf_Duration*); }
 
 UPB_INLINE envoy_config_endpoint_v3_ClusterLoadAssignment_Policy_DropOverload** envoy_config_endpoint_v3_ClusterLoadAssignment_Policy_mutable_drop_overloads(envoy_config_endpoint_v3_ClusterLoadAssignment_Policy *msg, size_t *len) {
-  return (envoy_config_endpoint_v3_ClusterLoadAssignment_Policy_DropOverload**)_upb_array_mutable_accessor(msg, UPB_SIZE(8, 16), len);
+  return (envoy_config_endpoint_v3_ClusterLoadAssignment_Policy_DropOverload**)_upb_array_mutable_accessor(msg, UPB_SIZE(12, 24), len);
 }
 UPB_INLINE envoy_config_endpoint_v3_ClusterLoadAssignment_Policy_DropOverload** envoy_config_endpoint_v3_ClusterLoadAssignment_Policy_resize_drop_overloads(envoy_config_endpoint_v3_ClusterLoadAssignment_Policy *msg, size_t len, upb_arena *arena) {
-  return (envoy_config_endpoint_v3_ClusterLoadAssignment_Policy_DropOverload**)_upb_array_resize_accessor(msg, UPB_SIZE(8, 16), len, UPB_TYPE_MESSAGE, arena);
+  return (envoy_config_endpoint_v3_ClusterLoadAssignment_Policy_DropOverload**)_upb_array_resize_accessor2(msg, UPB_SIZE(12, 24), len, UPB_SIZE(2, 3), arena);
 }
 UPB_INLINE struct envoy_config_endpoint_v3_ClusterLoadAssignment_Policy_DropOverload* envoy_config_endpoint_v3_ClusterLoadAssignment_Policy_add_drop_overloads(envoy_config_endpoint_v3_ClusterLoadAssignment_Policy *msg, upb_arena *arena) {
   struct envoy_config_endpoint_v3_ClusterLoadAssignment_Policy_DropOverload* sub = (struct envoy_config_endpoint_v3_ClusterLoadAssignment_Policy_DropOverload*)_upb_msg_new(&envoy_config_endpoint_v3_ClusterLoadAssignment_Policy_DropOverload_msginit, arena);
-  bool ok = _upb_array_append_accessor(
-      msg, UPB_SIZE(8, 16), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena);
+  bool ok = _upb_array_append_accessor2(
+      msg, UPB_SIZE(12, 24), UPB_SIZE(2, 3), &sub, arena);
   if (!ok) return NULL;
   return sub;
 }
 UPB_INLINE void envoy_config_endpoint_v3_ClusterLoadAssignment_Policy_set_overprovisioning_factor(envoy_config_endpoint_v3_ClusterLoadAssignment_Policy *msg, struct google_protobuf_UInt32Value* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(0, 0), struct google_protobuf_UInt32Value*) = value;
+  _upb_sethas(msg, 1);
+  *UPB_PTR_AT(msg, UPB_SIZE(4, 8), struct google_protobuf_UInt32Value*) = value;
 }
 UPB_INLINE struct google_protobuf_UInt32Value* envoy_config_endpoint_v3_ClusterLoadAssignment_Policy_mutable_overprovisioning_factor(envoy_config_endpoint_v3_ClusterLoadAssignment_Policy *msg, upb_arena *arena) {
   struct google_protobuf_UInt32Value* sub = (struct google_protobuf_UInt32Value*)envoy_config_endpoint_v3_ClusterLoadAssignment_Policy_overprovisioning_factor(msg);
@@ -147,7 +162,8 @@ UPB_INLINE struct google_protobuf_UInt32Value* envoy_config_endpoint_v3_ClusterL
   return sub;
 }
 UPB_INLINE void envoy_config_endpoint_v3_ClusterLoadAssignment_Policy_set_endpoint_stale_after(envoy_config_endpoint_v3_ClusterLoadAssignment_Policy *msg, struct google_protobuf_Duration* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(4, 8), struct google_protobuf_Duration*) = value;
+  _upb_sethas(msg, 2);
+  *UPB_PTR_AT(msg, UPB_SIZE(8, 16), struct google_protobuf_Duration*) = value;
 }
 UPB_INLINE struct google_protobuf_Duration* envoy_config_endpoint_v3_ClusterLoadAssignment_Policy_mutable_endpoint_stale_after(envoy_config_endpoint_v3_ClusterLoadAssignment_Policy *msg, upb_arena *arena) {
   struct google_protobuf_Duration* sub = (struct google_protobuf_Duration*)envoy_config_endpoint_v3_ClusterLoadAssignment_Policy_endpoint_stale_after(msg);
@@ -169,19 +185,26 @@ UPB_INLINE envoy_config_endpoint_v3_ClusterLoadAssignment_Policy_DropOverload *e
   envoy_config_endpoint_v3_ClusterLoadAssignment_Policy_DropOverload *ret = envoy_config_endpoint_v3_ClusterLoadAssignment_Policy_DropOverload_new(arena);
   return (ret && upb_decode(buf, size, ret, &envoy_config_endpoint_v3_ClusterLoadAssignment_Policy_DropOverload_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE envoy_config_endpoint_v3_ClusterLoadAssignment_Policy_DropOverload *envoy_config_endpoint_v3_ClusterLoadAssignment_Policy_DropOverload_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  envoy_config_endpoint_v3_ClusterLoadAssignment_Policy_DropOverload *ret = envoy_config_endpoint_v3_ClusterLoadAssignment_Policy_DropOverload_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &envoy_config_endpoint_v3_ClusterLoadAssignment_Policy_DropOverload_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *envoy_config_endpoint_v3_ClusterLoadAssignment_Policy_DropOverload_serialize(const envoy_config_endpoint_v3_ClusterLoadAssignment_Policy_DropOverload *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &envoy_config_endpoint_v3_ClusterLoadAssignment_Policy_DropOverload_msginit, arena, len);
 }
 
-UPB_INLINE upb_strview envoy_config_endpoint_v3_ClusterLoadAssignment_Policy_DropOverload_category(const envoy_config_endpoint_v3_ClusterLoadAssignment_Policy_DropOverload *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(0, 0), upb_strview); }
-UPB_INLINE bool envoy_config_endpoint_v3_ClusterLoadAssignment_Policy_DropOverload_has_drop_percentage(const envoy_config_endpoint_v3_ClusterLoadAssignment_Policy_DropOverload *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(8, 16)); }
-UPB_INLINE const struct envoy_type_v3_FractionalPercent* envoy_config_endpoint_v3_ClusterLoadAssignment_Policy_DropOverload_drop_percentage(const envoy_config_endpoint_v3_ClusterLoadAssignment_Policy_DropOverload *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(8, 16), const struct envoy_type_v3_FractionalPercent*); }
+UPB_INLINE upb_strview envoy_config_endpoint_v3_ClusterLoadAssignment_Policy_DropOverload_category(const envoy_config_endpoint_v3_ClusterLoadAssignment_Policy_DropOverload *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(4, 8), upb_strview); }
+UPB_INLINE bool envoy_config_endpoint_v3_ClusterLoadAssignment_Policy_DropOverload_has_drop_percentage(const envoy_config_endpoint_v3_ClusterLoadAssignment_Policy_DropOverload *msg) { return _upb_hasbit(msg, 1); }
+UPB_INLINE const struct envoy_type_v3_FractionalPercent* envoy_config_endpoint_v3_ClusterLoadAssignment_Policy_DropOverload_drop_percentage(const envoy_config_endpoint_v3_ClusterLoadAssignment_Policy_DropOverload *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(12, 24), const struct envoy_type_v3_FractionalPercent*); }
 
 UPB_INLINE void envoy_config_endpoint_v3_ClusterLoadAssignment_Policy_DropOverload_set_category(envoy_config_endpoint_v3_ClusterLoadAssignment_Policy_DropOverload *msg, upb_strview value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(0, 0), upb_strview) = value;
+  *UPB_PTR_AT(msg, UPB_SIZE(4, 8), upb_strview) = value;
 }
 UPB_INLINE void envoy_config_endpoint_v3_ClusterLoadAssignment_Policy_DropOverload_set_drop_percentage(envoy_config_endpoint_v3_ClusterLoadAssignment_Policy_DropOverload *msg, struct envoy_type_v3_FractionalPercent* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(8, 16), struct envoy_type_v3_FractionalPercent*) = value;
+  _upb_sethas(msg, 1);
+  *UPB_PTR_AT(msg, UPB_SIZE(12, 24), struct envoy_type_v3_FractionalPercent*) = value;
 }
 UPB_INLINE struct envoy_type_v3_FractionalPercent* envoy_config_endpoint_v3_ClusterLoadAssignment_Policy_DropOverload_mutable_drop_percentage(envoy_config_endpoint_v3_ClusterLoadAssignment_Policy_DropOverload *msg, upb_arena *arena) {
   struct envoy_type_v3_FractionalPercent* sub = (struct envoy_type_v3_FractionalPercent*)envoy_config_endpoint_v3_ClusterLoadAssignment_Policy_DropOverload_drop_percentage(msg);
index fbd0ce8..f12e49b 100644 (file)
@@ -25,15 +25,15 @@ static const upb_msglayout *const envoy_config_endpoint_v3_Endpoint_submsgs[2] =
 };
 
 static const upb_msglayout_field envoy_config_endpoint_v3_Endpoint__fields[3] = {
-  {1, UPB_SIZE(8, 16), 0, 0, 11, 1},
-  {2, UPB_SIZE(12, 24), 0, 1, 11, 1},
-  {3, UPB_SIZE(0, 0), 0, 0, 9, 1},
+  {1, UPB_SIZE(12, 24), 1, 0, 11, 1},
+  {2, UPB_SIZE(16, 32), 2, 1, 11, 1},
+  {3, UPB_SIZE(4, 8), 0, 0, 9, 1},
 };
 
 const upb_msglayout envoy_config_endpoint_v3_Endpoint_msginit = {
   &envoy_config_endpoint_v3_Endpoint_submsgs[0],
   &envoy_config_endpoint_v3_Endpoint__fields[0],
-  UPB_SIZE(16, 32), 3, false,
+  UPB_SIZE(24, 48), 3, false, 255,
 };
 
 static const upb_msglayout_field envoy_config_endpoint_v3_Endpoint_HealthCheckConfig__fields[2] = {
@@ -44,7 +44,7 @@ static const upb_msglayout_field envoy_config_endpoint_v3_Endpoint_HealthCheckCo
 const upb_msglayout envoy_config_endpoint_v3_Endpoint_HealthCheckConfig_msginit = {
   NULL,
   &envoy_config_endpoint_v3_Endpoint_HealthCheckConfig__fields[0],
-  UPB_SIZE(16, 32), 2, false,
+  UPB_SIZE(16, 32), 2, false, 255,
 };
 
 static const upb_msglayout *const envoy_config_endpoint_v3_LbEndpoint_submsgs[3] = {
@@ -55,36 +55,36 @@ static const upb_msglayout *const envoy_config_endpoint_v3_LbEndpoint_submsgs[3]
 
 static const upb_msglayout_field envoy_config_endpoint_v3_LbEndpoint__fields[5] = {
   {1, UPB_SIZE(16, 24), UPB_SIZE(-25, -41), 1, 11, 1},
-  {2, UPB_SIZE(0, 0), 0, 0, 14, 1},
-  {3, UPB_SIZE(8, 8), 0, 0, 11, 1},
-  {4, UPB_SIZE(12, 16), 0, 2, 11, 1},
+  {2, UPB_SIZE(4, 4), 0, 0, 14, 1},
+  {3, UPB_SIZE(8, 8), 1, 0, 11, 1},
+  {4, UPB_SIZE(12, 16), 2, 2, 11, 1},
   {5, UPB_SIZE(16, 24), UPB_SIZE(-25, -41), 0, 9, 1},
 };
 
 const upb_msglayout envoy_config_endpoint_v3_LbEndpoint_msginit = {
   &envoy_config_endpoint_v3_LbEndpoint_submsgs[0],
   &envoy_config_endpoint_v3_LbEndpoint__fields[0],
-  UPB_SIZE(32, 48), 5, false,
+  UPB_SIZE(32, 48), 5, false, 255,
 };
 
-static const upb_msglayout *const envoy_config_endpoint_v3_LocalityLbEndpoints_submsgs[4] = {
+static const upb_msglayout *const envoy_config_endpoint_v3_LocalityLbEndpoints_submsgs[3] = {
   &envoy_config_core_v3_Locality_msginit,
   &envoy_config_endpoint_v3_LbEndpoint_msginit,
   &google_protobuf_UInt32Value_msginit,
 };
 
 static const upb_msglayout_field envoy_config_endpoint_v3_LocalityLbEndpoints__fields[5] = {
-  {1, UPB_SIZE(4, 8), 0, 0, 11, 1},
-  {2, UPB_SIZE(16, 32), 0, 1, 11, 3},
-  {3, UPB_SIZE(8, 16), 0, 2, 11, 1},
-  {5, UPB_SIZE(0, 0), 0, 0, 13, 1},
-  {6, UPB_SIZE(12, 24), 0, 2, 11, 1},
+  {1, UPB_SIZE(8, 8), 1, 0, 11, 1},
+  {2, UPB_SIZE(20, 32), 0, 1, 11, 3},
+  {3, UPB_SIZE(12, 16), 2, 2, 11, 1},
+  {5, UPB_SIZE(4, 4), 0, 0, 13, 1},
+  {6, UPB_SIZE(16, 24), 3, 2, 11, 1},
 };
 
 const upb_msglayout envoy_config_endpoint_v3_LocalityLbEndpoints_msginit = {
   &envoy_config_endpoint_v3_LocalityLbEndpoints_submsgs[0],
   &envoy_config_endpoint_v3_LocalityLbEndpoints__fields[0],
-  UPB_SIZE(20, 40), 5, false,
+  UPB_SIZE(24, 40), 5, false, 255,
 };
 
 #include "upb/port_undef.inc"
index 56d2002..b6ad981 100644 (file)
@@ -11,6 +11,7 @@
 
 #include "upb/msg.h"
 #include "upb/decode.h"
+#include "upb/decode_fast.h"
 #include "upb/encode.h"
 
 #include "upb/port_def.inc"
@@ -51,18 +52,25 @@ UPB_INLINE envoy_config_endpoint_v3_Endpoint *envoy_config_endpoint_v3_Endpoint_
   envoy_config_endpoint_v3_Endpoint *ret = envoy_config_endpoint_v3_Endpoint_new(arena);
   return (ret && upb_decode(buf, size, ret, &envoy_config_endpoint_v3_Endpoint_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE envoy_config_endpoint_v3_Endpoint *envoy_config_endpoint_v3_Endpoint_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  envoy_config_endpoint_v3_Endpoint *ret = envoy_config_endpoint_v3_Endpoint_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &envoy_config_endpoint_v3_Endpoint_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *envoy_config_endpoint_v3_Endpoint_serialize(const envoy_config_endpoint_v3_Endpoint *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &envoy_config_endpoint_v3_Endpoint_msginit, arena, len);
 }
 
-UPB_INLINE bool envoy_config_endpoint_v3_Endpoint_has_address(const envoy_config_endpoint_v3_Endpoint *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(8, 16)); }
-UPB_INLINE const struct envoy_config_core_v3_Address* envoy_config_endpoint_v3_Endpoint_address(const envoy_config_endpoint_v3_Endpoint *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(8, 16), const struct envoy_config_core_v3_Address*); }
-UPB_INLINE bool envoy_config_endpoint_v3_Endpoint_has_health_check_config(const envoy_config_endpoint_v3_Endpoint *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(12, 24)); }
-UPB_INLINE const envoy_config_endpoint_v3_Endpoint_HealthCheckConfig* envoy_config_endpoint_v3_Endpoint_health_check_config(const envoy_config_endpoint_v3_Endpoint *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(12, 24), const envoy_config_endpoint_v3_Endpoint_HealthCheckConfig*); }
-UPB_INLINE upb_strview envoy_config_endpoint_v3_Endpoint_hostname(const envoy_config_endpoint_v3_Endpoint *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(0, 0), upb_strview); }
+UPB_INLINE bool envoy_config_endpoint_v3_Endpoint_has_address(const envoy_config_endpoint_v3_Endpoint *msg) { return _upb_hasbit(msg, 1); }
+UPB_INLINE const struct envoy_config_core_v3_Address* envoy_config_endpoint_v3_Endpoint_address(const envoy_config_endpoint_v3_Endpoint *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(12, 24), const struct envoy_config_core_v3_Address*); }
+UPB_INLINE bool envoy_config_endpoint_v3_Endpoint_has_health_check_config(const envoy_config_endpoint_v3_Endpoint *msg) { return _upb_hasbit(msg, 2); }
+UPB_INLINE const envoy_config_endpoint_v3_Endpoint_HealthCheckConfig* envoy_config_endpoint_v3_Endpoint_health_check_config(const envoy_config_endpoint_v3_Endpoint *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(16, 32), const envoy_config_endpoint_v3_Endpoint_HealthCheckConfig*); }
+UPB_INLINE upb_strview envoy_config_endpoint_v3_Endpoint_hostname(const envoy_config_endpoint_v3_Endpoint *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(4, 8), upb_strview); }
 
 UPB_INLINE void envoy_config_endpoint_v3_Endpoint_set_address(envoy_config_endpoint_v3_Endpoint *msg, struct envoy_config_core_v3_Address* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(8, 16), struct envoy_config_core_v3_Address*) = value;
+  _upb_sethas(msg, 1);
+  *UPB_PTR_AT(msg, UPB_SIZE(12, 24), struct envoy_config_core_v3_Address*) = value;
 }
 UPB_INLINE struct envoy_config_core_v3_Address* envoy_config_endpoint_v3_Endpoint_mutable_address(envoy_config_endpoint_v3_Endpoint *msg, upb_arena *arena) {
   struct envoy_config_core_v3_Address* sub = (struct envoy_config_core_v3_Address*)envoy_config_endpoint_v3_Endpoint_address(msg);
@@ -74,7 +82,8 @@ UPB_INLINE struct envoy_config_core_v3_Address* envoy_config_endpoint_v3_Endpoin
   return sub;
 }
 UPB_INLINE void envoy_config_endpoint_v3_Endpoint_set_health_check_config(envoy_config_endpoint_v3_Endpoint *msg, envoy_config_endpoint_v3_Endpoint_HealthCheckConfig* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(12, 24), envoy_config_endpoint_v3_Endpoint_HealthCheckConfig*) = value;
+  _upb_sethas(msg, 2);
+  *UPB_PTR_AT(msg, UPB_SIZE(16, 32), envoy_config_endpoint_v3_Endpoint_HealthCheckConfig*) = value;
 }
 UPB_INLINE struct envoy_config_endpoint_v3_Endpoint_HealthCheckConfig* envoy_config_endpoint_v3_Endpoint_mutable_health_check_config(envoy_config_endpoint_v3_Endpoint *msg, upb_arena *arena) {
   struct envoy_config_endpoint_v3_Endpoint_HealthCheckConfig* sub = (struct envoy_config_endpoint_v3_Endpoint_HealthCheckConfig*)envoy_config_endpoint_v3_Endpoint_health_check_config(msg);
@@ -86,7 +95,7 @@ UPB_INLINE struct envoy_config_endpoint_v3_Endpoint_HealthCheckConfig* envoy_con
   return sub;
 }
 UPB_INLINE void envoy_config_endpoint_v3_Endpoint_set_hostname(envoy_config_endpoint_v3_Endpoint *msg, upb_strview value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(0, 0), upb_strview) = value;
+  *UPB_PTR_AT(msg, UPB_SIZE(4, 8), upb_strview) = value;
 }
 
 /* envoy.config.endpoint.v3.Endpoint.HealthCheckConfig */
@@ -99,6 +108,12 @@ UPB_INLINE envoy_config_endpoint_v3_Endpoint_HealthCheckConfig *envoy_config_end
   envoy_config_endpoint_v3_Endpoint_HealthCheckConfig *ret = envoy_config_endpoint_v3_Endpoint_HealthCheckConfig_new(arena);
   return (ret && upb_decode(buf, size, ret, &envoy_config_endpoint_v3_Endpoint_HealthCheckConfig_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE envoy_config_endpoint_v3_Endpoint_HealthCheckConfig *envoy_config_endpoint_v3_Endpoint_HealthCheckConfig_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  envoy_config_endpoint_v3_Endpoint_HealthCheckConfig *ret = envoy_config_endpoint_v3_Endpoint_HealthCheckConfig_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &envoy_config_endpoint_v3_Endpoint_HealthCheckConfig_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *envoy_config_endpoint_v3_Endpoint_HealthCheckConfig_serialize(const envoy_config_endpoint_v3_Endpoint_HealthCheckConfig *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &envoy_config_endpoint_v3_Endpoint_HealthCheckConfig_msginit, arena, len);
 }
@@ -123,6 +138,12 @@ UPB_INLINE envoy_config_endpoint_v3_LbEndpoint *envoy_config_endpoint_v3_LbEndpo
   envoy_config_endpoint_v3_LbEndpoint *ret = envoy_config_endpoint_v3_LbEndpoint_new(arena);
   return (ret && upb_decode(buf, size, ret, &envoy_config_endpoint_v3_LbEndpoint_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE envoy_config_endpoint_v3_LbEndpoint *envoy_config_endpoint_v3_LbEndpoint_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  envoy_config_endpoint_v3_LbEndpoint *ret = envoy_config_endpoint_v3_LbEndpoint_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &envoy_config_endpoint_v3_LbEndpoint_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *envoy_config_endpoint_v3_LbEndpoint_serialize(const envoy_config_endpoint_v3_LbEndpoint *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &envoy_config_endpoint_v3_LbEndpoint_msginit, arena, len);
 }
@@ -136,10 +157,10 @@ UPB_INLINE envoy_config_endpoint_v3_LbEndpoint_host_identifier_oneofcases envoy_
 
 UPB_INLINE bool envoy_config_endpoint_v3_LbEndpoint_has_endpoint(const envoy_config_endpoint_v3_LbEndpoint *msg) { return _upb_getoneofcase(msg, UPB_SIZE(24, 40)) == 1; }
 UPB_INLINE const envoy_config_endpoint_v3_Endpoint* envoy_config_endpoint_v3_LbEndpoint_endpoint(const envoy_config_endpoint_v3_LbEndpoint *msg) { return UPB_READ_ONEOF(msg, const envoy_config_endpoint_v3_Endpoint*, UPB_SIZE(16, 24), UPB_SIZE(24, 40), 1, NULL); }
-UPB_INLINE int32_t envoy_config_endpoint_v3_LbEndpoint_health_status(const envoy_config_endpoint_v3_LbEndpoint *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(0, 0), int32_t); }
-UPB_INLINE bool envoy_config_endpoint_v3_LbEndpoint_has_metadata(const envoy_config_endpoint_v3_LbEndpoint *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(8, 8)); }
+UPB_INLINE int32_t envoy_config_endpoint_v3_LbEndpoint_health_status(const envoy_config_endpoint_v3_LbEndpoint *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(4, 4), int32_t); }
+UPB_INLINE bool envoy_config_endpoint_v3_LbEndpoint_has_metadata(const envoy_config_endpoint_v3_LbEndpoint *msg) { return _upb_hasbit(msg, 1); }
 UPB_INLINE const struct envoy_config_core_v3_Metadata* envoy_config_endpoint_v3_LbEndpoint_metadata(const envoy_config_endpoint_v3_LbEndpoint *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(8, 8), const struct envoy_config_core_v3_Metadata*); }
-UPB_INLINE bool envoy_config_endpoint_v3_LbEndpoint_has_load_balancing_weight(const envoy_config_endpoint_v3_LbEndpoint *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(12, 16)); }
+UPB_INLINE bool envoy_config_endpoint_v3_LbEndpoint_has_load_balancing_weight(const envoy_config_endpoint_v3_LbEndpoint *msg) { return _upb_hasbit(msg, 2); }
 UPB_INLINE const struct google_protobuf_UInt32Value* envoy_config_endpoint_v3_LbEndpoint_load_balancing_weight(const envoy_config_endpoint_v3_LbEndpoint *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(12, 16), const struct google_protobuf_UInt32Value*); }
 UPB_INLINE bool envoy_config_endpoint_v3_LbEndpoint_has_endpoint_name(const envoy_config_endpoint_v3_LbEndpoint *msg) { return _upb_getoneofcase(msg, UPB_SIZE(24, 40)) == 5; }
 UPB_INLINE upb_strview envoy_config_endpoint_v3_LbEndpoint_endpoint_name(const envoy_config_endpoint_v3_LbEndpoint *msg) { return UPB_READ_ONEOF(msg, upb_strview, UPB_SIZE(16, 24), UPB_SIZE(24, 40), 5, upb_strview_make("", strlen(""))); }
@@ -157,9 +178,10 @@ UPB_INLINE struct envoy_config_endpoint_v3_Endpoint* envoy_config_endpoint_v3_Lb
   return sub;
 }
 UPB_INLINE void envoy_config_endpoint_v3_LbEndpoint_set_health_status(envoy_config_endpoint_v3_LbEndpoint *msg, int32_t value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(0, 0), int32_t) = value;
+  *UPB_PTR_AT(msg, UPB_SIZE(4, 4), int32_t) = value;
 }
 UPB_INLINE void envoy_config_endpoint_v3_LbEndpoint_set_metadata(envoy_config_endpoint_v3_LbEndpoint *msg, struct envoy_config_core_v3_Metadata* value) {
+  _upb_sethas(msg, 1);
   *UPB_PTR_AT(msg, UPB_SIZE(8, 8), struct envoy_config_core_v3_Metadata*) = value;
 }
 UPB_INLINE struct envoy_config_core_v3_Metadata* envoy_config_endpoint_v3_LbEndpoint_mutable_metadata(envoy_config_endpoint_v3_LbEndpoint *msg, upb_arena *arena) {
@@ -172,6 +194,7 @@ UPB_INLINE struct envoy_config_core_v3_Metadata* envoy_config_endpoint_v3_LbEndp
   return sub;
 }
 UPB_INLINE void envoy_config_endpoint_v3_LbEndpoint_set_load_balancing_weight(envoy_config_endpoint_v3_LbEndpoint *msg, struct google_protobuf_UInt32Value* value) {
+  _upb_sethas(msg, 2);
   *UPB_PTR_AT(msg, UPB_SIZE(12, 16), struct google_protobuf_UInt32Value*) = value;
 }
 UPB_INLINE struct google_protobuf_UInt32Value* envoy_config_endpoint_v3_LbEndpoint_mutable_load_balancing_weight(envoy_config_endpoint_v3_LbEndpoint *msg, upb_arena *arena) {
@@ -197,22 +220,29 @@ UPB_INLINE envoy_config_endpoint_v3_LocalityLbEndpoints *envoy_config_endpoint_v
   envoy_config_endpoint_v3_LocalityLbEndpoints *ret = envoy_config_endpoint_v3_LocalityLbEndpoints_new(arena);
   return (ret && upb_decode(buf, size, ret, &envoy_config_endpoint_v3_LocalityLbEndpoints_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE envoy_config_endpoint_v3_LocalityLbEndpoints *envoy_config_endpoint_v3_LocalityLbEndpoints_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  envoy_config_endpoint_v3_LocalityLbEndpoints *ret = envoy_config_endpoint_v3_LocalityLbEndpoints_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &envoy_config_endpoint_v3_LocalityLbEndpoints_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *envoy_config_endpoint_v3_LocalityLbEndpoints_serialize(const envoy_config_endpoint_v3_LocalityLbEndpoints *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &envoy_config_endpoint_v3_LocalityLbEndpoints_msginit, arena, len);
 }
 
-UPB_INLINE bool envoy_config_endpoint_v3_LocalityLbEndpoints_has_locality(const envoy_config_endpoint_v3_LocalityLbEndpoints *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(4, 8)); }
-UPB_INLINE const struct envoy_config_core_v3_Locality* envoy_config_endpoint_v3_LocalityLbEndpoints_locality(const envoy_config_endpoint_v3_LocalityLbEndpoints *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(4, 8), const struct envoy_config_core_v3_Locality*); }
-UPB_INLINE bool envoy_config_endpoint_v3_LocalityLbEndpoints_has_lb_endpoints(const envoy_config_endpoint_v3_LocalityLbEndpoints *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(16, 32)); }
-UPB_INLINE const envoy_config_endpoint_v3_LbEndpoint* const* envoy_config_endpoint_v3_LocalityLbEndpoints_lb_endpoints(const envoy_config_endpoint_v3_LocalityLbEndpoints *msg, size_t *len) { return (const envoy_config_endpoint_v3_LbEndpoint* const*)_upb_array_accessor(msg, UPB_SIZE(16, 32), len); }
-UPB_INLINE bool envoy_config_endpoint_v3_LocalityLbEndpoints_has_load_balancing_weight(const envoy_config_endpoint_v3_LocalityLbEndpoints *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(8, 16)); }
-UPB_INLINE const struct google_protobuf_UInt32Value* envoy_config_endpoint_v3_LocalityLbEndpoints_load_balancing_weight(const envoy_config_endpoint_v3_LocalityLbEndpoints *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(8, 16), const struct google_protobuf_UInt32Value*); }
-UPB_INLINE uint32_t envoy_config_endpoint_v3_LocalityLbEndpoints_priority(const envoy_config_endpoint_v3_LocalityLbEndpoints *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(0, 0), uint32_t); }
-UPB_INLINE bool envoy_config_endpoint_v3_LocalityLbEndpoints_has_proximity(const envoy_config_endpoint_v3_LocalityLbEndpoints *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(12, 24)); }
-UPB_INLINE const struct google_protobuf_UInt32Value* envoy_config_endpoint_v3_LocalityLbEndpoints_proximity(const envoy_config_endpoint_v3_LocalityLbEndpoints *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(12, 24), const struct google_protobuf_UInt32Value*); }
+UPB_INLINE bool envoy_config_endpoint_v3_LocalityLbEndpoints_has_locality(const envoy_config_endpoint_v3_LocalityLbEndpoints *msg) { return _upb_hasbit(msg, 1); }
+UPB_INLINE const struct envoy_config_core_v3_Locality* envoy_config_endpoint_v3_LocalityLbEndpoints_locality(const envoy_config_endpoint_v3_LocalityLbEndpoints *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(8, 8), const struct envoy_config_core_v3_Locality*); }
+UPB_INLINE bool envoy_config_endpoint_v3_LocalityLbEndpoints_has_lb_endpoints(const envoy_config_endpoint_v3_LocalityLbEndpoints *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(20, 32)); }
+UPB_INLINE const envoy_config_endpoint_v3_LbEndpoint* const* envoy_config_endpoint_v3_LocalityLbEndpoints_lb_endpoints(const envoy_config_endpoint_v3_LocalityLbEndpoints *msg, size_t *len) { return (const envoy_config_endpoint_v3_LbEndpoint* const*)_upb_array_accessor(msg, UPB_SIZE(20, 32), len); }
+UPB_INLINE bool envoy_config_endpoint_v3_LocalityLbEndpoints_has_load_balancing_weight(const envoy_config_endpoint_v3_LocalityLbEndpoints *msg) { return _upb_hasbit(msg, 2); }
+UPB_INLINE const struct google_protobuf_UInt32Value* envoy_config_endpoint_v3_LocalityLbEndpoints_load_balancing_weight(const envoy_config_endpoint_v3_LocalityLbEndpoints *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(12, 16), const struct google_protobuf_UInt32Value*); }
+UPB_INLINE uint32_t envoy_config_endpoint_v3_LocalityLbEndpoints_priority(const envoy_config_endpoint_v3_LocalityLbEndpoints *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(4, 4), uint32_t); }
+UPB_INLINE bool envoy_config_endpoint_v3_LocalityLbEndpoints_has_proximity(const envoy_config_endpoint_v3_LocalityLbEndpoints *msg) { return _upb_hasbit(msg, 3); }
+UPB_INLINE const struct google_protobuf_UInt32Value* envoy_config_endpoint_v3_LocalityLbEndpoints_proximity(const envoy_config_endpoint_v3_LocalityLbEndpoints *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(16, 24), const struct google_protobuf_UInt32Value*); }
 
 UPB_INLINE void envoy_config_endpoint_v3_LocalityLbEndpoints_set_locality(envoy_config_endpoint_v3_LocalityLbEndpoints *msg, struct envoy_config_core_v3_Locality* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(4, 8), struct envoy_config_core_v3_Locality*) = value;
+  _upb_sethas(msg, 1);
+  *UPB_PTR_AT(msg, UPB_SIZE(8, 8), struct envoy_config_core_v3_Locality*) = value;
 }
 UPB_INLINE struct envoy_config_core_v3_Locality* envoy_config_endpoint_v3_LocalityLbEndpoints_mutable_locality(envoy_config_endpoint_v3_LocalityLbEndpoints *msg, upb_arena *arena) {
   struct envoy_config_core_v3_Locality* sub = (struct envoy_config_core_v3_Locality*)envoy_config_endpoint_v3_LocalityLbEndpoints_locality(msg);
@@ -224,20 +254,21 @@ UPB_INLINE struct envoy_config_core_v3_Locality* envoy_config_endpoint_v3_Locali
   return sub;
 }
 UPB_INLINE envoy_config_endpoint_v3_LbEndpoint** envoy_config_endpoint_v3_LocalityLbEndpoints_mutable_lb_endpoints(envoy_config_endpoint_v3_LocalityLbEndpoints *msg, size_t *len) {
-  return (envoy_config_endpoint_v3_LbEndpoint**)_upb_array_mutable_accessor(msg, UPB_SIZE(16, 32), len);
+  return (envoy_config_endpoint_v3_LbEndpoint**)_upb_array_mutable_accessor(msg, UPB_SIZE(20, 32), len);
 }
 UPB_INLINE envoy_config_endpoint_v3_LbEndpoint** envoy_config_endpoint_v3_LocalityLbEndpoints_resize_lb_endpoints(envoy_config_endpoint_v3_LocalityLbEndpoints *msg, size_t len, upb_arena *arena) {
-  return (envoy_config_endpoint_v3_LbEndpoint**)_upb_array_resize_accessor(msg, UPB_SIZE(16, 32), len, UPB_TYPE_MESSAGE, arena);
+  return (envoy_config_endpoint_v3_LbEndpoint**)_upb_array_resize_accessor2(msg, UPB_SIZE(20, 32), len, UPB_SIZE(2, 3), arena);
 }
 UPB_INLINE struct envoy_config_endpoint_v3_LbEndpoint* envoy_config_endpoint_v3_LocalityLbEndpoints_add_lb_endpoints(envoy_config_endpoint_v3_LocalityLbEndpoints *msg, upb_arena *arena) {
   struct envoy_config_endpoint_v3_LbEndpoint* sub = (struct envoy_config_endpoint_v3_LbEndpoint*)_upb_msg_new(&envoy_config_endpoint_v3_LbEndpoint_msginit, arena);
-  bool ok = _upb_array_append_accessor(
-      msg, UPB_SIZE(16, 32), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena);
+  bool ok = _upb_array_append_accessor2(
+      msg, UPB_SIZE(20, 32), UPB_SIZE(2, 3), &sub, arena);
   if (!ok) return NULL;
   return sub;
 }
 UPB_INLINE void envoy_config_endpoint_v3_LocalityLbEndpoints_set_load_balancing_weight(envoy_config_endpoint_v3_LocalityLbEndpoints *msg, struct google_protobuf_UInt32Value* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(8, 16), struct google_protobuf_UInt32Value*) = value;
+  _upb_sethas(msg, 2);
+  *UPB_PTR_AT(msg, UPB_SIZE(12, 16), struct google_protobuf_UInt32Value*) = value;
 }
 UPB_INLINE struct google_protobuf_UInt32Value* envoy_config_endpoint_v3_LocalityLbEndpoints_mutable_load_balancing_weight(envoy_config_endpoint_v3_LocalityLbEndpoints *msg, upb_arena *arena) {
   struct google_protobuf_UInt32Value* sub = (struct google_protobuf_UInt32Value*)envoy_config_endpoint_v3_LocalityLbEndpoints_load_balancing_weight(msg);
@@ -249,10 +280,11 @@ UPB_INLINE struct google_protobuf_UInt32Value* envoy_config_endpoint_v3_Locality
   return sub;
 }
 UPB_INLINE void envoy_config_endpoint_v3_LocalityLbEndpoints_set_priority(envoy_config_endpoint_v3_LocalityLbEndpoints *msg, uint32_t value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(0, 0), uint32_t) = value;
+  *UPB_PTR_AT(msg, UPB_SIZE(4, 4), uint32_t) = value;
 }
 UPB_INLINE void envoy_config_endpoint_v3_LocalityLbEndpoints_set_proximity(envoy_config_endpoint_v3_LocalityLbEndpoints *msg, struct google_protobuf_UInt32Value* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(12, 24), struct google_protobuf_UInt32Value*) = value;
+  _upb_sethas(msg, 3);
+  *UPB_PTR_AT(msg, UPB_SIZE(16, 24), struct google_protobuf_UInt32Value*) = value;
 }
 UPB_INLINE struct google_protobuf_UInt32Value* envoy_config_endpoint_v3_LocalityLbEndpoints_mutable_proximity(envoy_config_endpoint_v3_LocalityLbEndpoints *msg, upb_arena *arena) {
   struct google_protobuf_UInt32Value* sub = (struct google_protobuf_UInt32Value*)envoy_config_endpoint_v3_LocalityLbEndpoints_proximity(msg);
index 9bb6385..560826e 100644 (file)
@@ -26,20 +26,20 @@ static const upb_msglayout *const envoy_config_endpoint_v3_UpstreamLocalityStats
 };
 
 static const upb_msglayout_field envoy_config_endpoint_v3_UpstreamLocalityStats__fields[8] = {
-  {1, UPB_SIZE(36, 40), 0, 0, 11, 1},
-  {2, UPB_SIZE(0, 0), 0, 0, 4, 1},
-  {3, UPB_SIZE(8, 8), 0, 0, 4, 1},
-  {4, UPB_SIZE(16, 16), 0, 0, 4, 1},
-  {5, UPB_SIZE(40, 48), 0, 1, 11, 3},
-  {6, UPB_SIZE(32, 32), 0, 0, 13, 1},
-  {7, UPB_SIZE(44, 56), 0, 2, 11, 3},
-  {8, UPB_SIZE(24, 24), 0, 0, 4, 1},
+  {1, UPB_SIZE(44, 48), 1, 0, 11, 1},
+  {2, UPB_SIZE(8, 8), 0, 0, 4, 1},
+  {3, UPB_SIZE(16, 16), 0, 0, 4, 1},
+  {4, UPB_SIZE(24, 24), 0, 0, 4, 1},
+  {5, UPB_SIZE(48, 56), 0, 1, 11, 3},
+  {6, UPB_SIZE(40, 40), 0, 0, 13, 1},
+  {7, UPB_SIZE(52, 64), 0, 2, 11, 3},
+  {8, UPB_SIZE(32, 32), 0, 0, 4, 1},
 };
 
 const upb_msglayout envoy_config_endpoint_v3_UpstreamLocalityStats_msginit = {
   &envoy_config_endpoint_v3_UpstreamLocalityStats_submsgs[0],
   &envoy_config_endpoint_v3_UpstreamLocalityStats__fields[0],
-  UPB_SIZE(48, 64), 8, false,
+  UPB_SIZE(56, 72), 8, false, 255,
 };
 
 static const upb_msglayout *const envoy_config_endpoint_v3_UpstreamEndpointStats_submsgs[3] = {
@@ -49,19 +49,19 @@ static const upb_msglayout *const envoy_config_endpoint_v3_UpstreamEndpointStats
 };
 
 static const upb_msglayout_field envoy_config_endpoint_v3_UpstreamEndpointStats__fields[7] = {
-  {1, UPB_SIZE(32, 32), 0, 0, 11, 1},
-  {2, UPB_SIZE(0, 0), 0, 0, 4, 1},
-  {3, UPB_SIZE(8, 8), 0, 0, 4, 1},
-  {4, UPB_SIZE(16, 16), 0, 0, 4, 1},
-  {5, UPB_SIZE(40, 48), 0, 1, 11, 3},
-  {6, UPB_SIZE(36, 40), 0, 2, 11, 1},
-  {7, UPB_SIZE(24, 24), 0, 0, 4, 1},
+  {1, UPB_SIZE(40, 40), 1, 0, 11, 1},
+  {2, UPB_SIZE(8, 8), 0, 0, 4, 1},
+  {3, UPB_SIZE(16, 16), 0, 0, 4, 1},
+  {4, UPB_SIZE(24, 24), 0, 0, 4, 1},
+  {5, UPB_SIZE(48, 56), 0, 1, 11, 3},
+  {6, UPB_SIZE(44, 48), 2, 2, 11, 1},
+  {7, UPB_SIZE(32, 32), 0, 0, 4, 1},
 };
 
 const upb_msglayout envoy_config_endpoint_v3_UpstreamEndpointStats_msginit = {
   &envoy_config_endpoint_v3_UpstreamEndpointStats_submsgs[0],
   &envoy_config_endpoint_v3_UpstreamEndpointStats__fields[0],
-  UPB_SIZE(48, 56), 7, false,
+  UPB_SIZE(56, 64), 7, false, 255,
 };
 
 static const upb_msglayout_field envoy_config_endpoint_v3_EndpointLoadMetricStats__fields[3] = {
@@ -73,7 +73,7 @@ static const upb_msglayout_field envoy_config_endpoint_v3_EndpointLoadMetricStat
 const upb_msglayout envoy_config_endpoint_v3_EndpointLoadMetricStats_msginit = {
   NULL,
   &envoy_config_endpoint_v3_EndpointLoadMetricStats__fields[0],
-  UPB_SIZE(24, 32), 3, false,
+  UPB_SIZE(24, 32), 3, false, 255,
 };
 
 static const upb_msglayout *const envoy_config_endpoint_v3_ClusterStats_submsgs[3] = {
@@ -83,18 +83,18 @@ static const upb_msglayout *const envoy_config_endpoint_v3_ClusterStats_submsgs[
 };
 
 static const upb_msglayout_field envoy_config_endpoint_v3_ClusterStats__fields[6] = {
-  {1, UPB_SIZE(8, 8), 0, 0, 9, 1},
-  {2, UPB_SIZE(28, 48), 0, 1, 11, 3},
-  {3, UPB_SIZE(0, 0), 0, 0, 4, 1},
-  {4, UPB_SIZE(24, 40), 0, 2, 11, 1},
-  {5, UPB_SIZE(32, 56), 0, 0, 11, 3},
-  {6, UPB_SIZE(16, 24), 0, 0, 9, 1},
+  {1, UPB_SIZE(16, 16), 0, 0, 9, 1},
+  {2, UPB_SIZE(36, 56), 0, 1, 11, 3},
+  {3, UPB_SIZE(8, 8), 0, 0, 4, 1},
+  {4, UPB_SIZE(32, 48), 1, 2, 11, 1},
+  {5, UPB_SIZE(40, 64), 0, 0, 11, 3},
+  {6, UPB_SIZE(24, 32), 0, 0, 9, 1},
 };
 
 const upb_msglayout envoy_config_endpoint_v3_ClusterStats_msginit = {
   &envoy_config_endpoint_v3_ClusterStats_submsgs[0],
   &envoy_config_endpoint_v3_ClusterStats__fields[0],
-  UPB_SIZE(40, 64), 6, false,
+  UPB_SIZE(48, 80), 6, false, 255,
 };
 
 static const upb_msglayout_field envoy_config_endpoint_v3_ClusterStats_DroppedRequests__fields[2] = {
@@ -105,7 +105,7 @@ static const upb_msglayout_field envoy_config_endpoint_v3_ClusterStats_DroppedRe
 const upb_msglayout envoy_config_endpoint_v3_ClusterStats_DroppedRequests_msginit = {
   NULL,
   &envoy_config_endpoint_v3_ClusterStats_DroppedRequests__fields[0],
-  UPB_SIZE(16, 32), 2, false,
+  UPB_SIZE(16, 32), 2, false, 255,
 };
 
 #include "upb/port_undef.inc"
index 65c11a9..d986e18 100644 (file)
@@ -11,6 +11,7 @@
 
 #include "upb/msg.h"
 #include "upb/decode.h"
+#include "upb/decode_fast.h"
 #include "upb/encode.h"
 
 #include "upb/port_def.inc"
@@ -54,24 +55,31 @@ UPB_INLINE envoy_config_endpoint_v3_UpstreamLocalityStats *envoy_config_endpoint
   envoy_config_endpoint_v3_UpstreamLocalityStats *ret = envoy_config_endpoint_v3_UpstreamLocalityStats_new(arena);
   return (ret && upb_decode(buf, size, ret, &envoy_config_endpoint_v3_UpstreamLocalityStats_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE envoy_config_endpoint_v3_UpstreamLocalityStats *envoy_config_endpoint_v3_UpstreamLocalityStats_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  envoy_config_endpoint_v3_UpstreamLocalityStats *ret = envoy_config_endpoint_v3_UpstreamLocalityStats_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &envoy_config_endpoint_v3_UpstreamLocalityStats_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *envoy_config_endpoint_v3_UpstreamLocalityStats_serialize(const envoy_config_endpoint_v3_UpstreamLocalityStats *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &envoy_config_endpoint_v3_UpstreamLocalityStats_msginit, arena, len);
 }
 
-UPB_INLINE bool envoy_config_endpoint_v3_UpstreamLocalityStats_has_locality(const envoy_config_endpoint_v3_UpstreamLocalityStats *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(36, 40)); }
-UPB_INLINE const struct envoy_config_core_v3_Locality* envoy_config_endpoint_v3_UpstreamLocalityStats_locality(const envoy_config_endpoint_v3_UpstreamLocalityStats *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(36, 40), const struct envoy_config_core_v3_Locality*); }
-UPB_INLINE uint64_t envoy_config_endpoint_v3_UpstreamLocalityStats_total_successful_requests(const envoy_config_endpoint_v3_UpstreamLocalityStats *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(0, 0), uint64_t); }
-UPB_INLINE uint64_t envoy_config_endpoint_v3_UpstreamLocalityStats_total_requests_in_progress(const envoy_config_endpoint_v3_UpstreamLocalityStats *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(8, 8), uint64_t); }
-UPB_INLINE uint64_t envoy_config_endpoint_v3_UpstreamLocalityStats_total_error_requests(const envoy_config_endpoint_v3_UpstreamLocalityStats *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(16, 16), uint64_t); }
-UPB_INLINE bool envoy_config_endpoint_v3_UpstreamLocalityStats_has_load_metric_stats(const envoy_config_endpoint_v3_UpstreamLocalityStats *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(40, 48)); }
-UPB_INLINE const envoy_config_endpoint_v3_EndpointLoadMetricStats* const* envoy_config_endpoint_v3_UpstreamLocalityStats_load_metric_stats(const envoy_config_endpoint_v3_UpstreamLocalityStats *msg, size_t *len) { return (const envoy_config_endpoint_v3_EndpointLoadMetricStats* const*)_upb_array_accessor(msg, UPB_SIZE(40, 48), len); }
-UPB_INLINE uint32_t envoy_config_endpoint_v3_UpstreamLocalityStats_priority(const envoy_config_endpoint_v3_UpstreamLocalityStats *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(32, 32), uint32_t); }
-UPB_INLINE bool envoy_config_endpoint_v3_UpstreamLocalityStats_has_upstream_endpoint_stats(const envoy_config_endpoint_v3_UpstreamLocalityStats *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(44, 56)); }
-UPB_INLINE const envoy_config_endpoint_v3_UpstreamEndpointStats* const* envoy_config_endpoint_v3_UpstreamLocalityStats_upstream_endpoint_stats(const envoy_config_endpoint_v3_UpstreamLocalityStats *msg, size_t *len) { return (const envoy_config_endpoint_v3_UpstreamEndpointStats* const*)_upb_array_accessor(msg, UPB_SIZE(44, 56), len); }
-UPB_INLINE uint64_t envoy_config_endpoint_v3_UpstreamLocalityStats_total_issued_requests(const envoy_config_endpoint_v3_UpstreamLocalityStats *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(24, 24), uint64_t); }
+UPB_INLINE bool envoy_config_endpoint_v3_UpstreamLocalityStats_has_locality(const envoy_config_endpoint_v3_UpstreamLocalityStats *msg) { return _upb_hasbit(msg, 1); }
+UPB_INLINE const struct envoy_config_core_v3_Locality* envoy_config_endpoint_v3_UpstreamLocalityStats_locality(const envoy_config_endpoint_v3_UpstreamLocalityStats *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(44, 48), const struct envoy_config_core_v3_Locality*); }
+UPB_INLINE uint64_t envoy_config_endpoint_v3_UpstreamLocalityStats_total_successful_requests(const envoy_config_endpoint_v3_UpstreamLocalityStats *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(8, 8), uint64_t); }
+UPB_INLINE uint64_t envoy_config_endpoint_v3_UpstreamLocalityStats_total_requests_in_progress(const envoy_config_endpoint_v3_UpstreamLocalityStats *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(16, 16), uint64_t); }
+UPB_INLINE uint64_t envoy_config_endpoint_v3_UpstreamLocalityStats_total_error_requests(const envoy_config_endpoint_v3_UpstreamLocalityStats *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(24, 24), uint64_t); }
+UPB_INLINE bool envoy_config_endpoint_v3_UpstreamLocalityStats_has_load_metric_stats(const envoy_config_endpoint_v3_UpstreamLocalityStats *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(48, 56)); }
+UPB_INLINE const envoy_config_endpoint_v3_EndpointLoadMetricStats* const* envoy_config_endpoint_v3_UpstreamLocalityStats_load_metric_stats(const envoy_config_endpoint_v3_UpstreamLocalityStats *msg, size_t *len) { return (const envoy_config_endpoint_v3_EndpointLoadMetricStats* const*)_upb_array_accessor(msg, UPB_SIZE(48, 56), len); }
+UPB_INLINE uint32_t envoy_config_endpoint_v3_UpstreamLocalityStats_priority(const envoy_config_endpoint_v3_UpstreamLocalityStats *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(40, 40), uint32_t); }
+UPB_INLINE bool envoy_config_endpoint_v3_UpstreamLocalityStats_has_upstream_endpoint_stats(const envoy_config_endpoint_v3_UpstreamLocalityStats *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(52, 64)); }
+UPB_INLINE const envoy_config_endpoint_v3_UpstreamEndpointStats* const* envoy_config_endpoint_v3_UpstreamLocalityStats_upstream_endpoint_stats(const envoy_config_endpoint_v3_UpstreamLocalityStats *msg, size_t *len) { return (const envoy_config_endpoint_v3_UpstreamEndpointStats* const*)_upb_array_accessor(msg, UPB_SIZE(52, 64), len); }
+UPB_INLINE uint64_t envoy_config_endpoint_v3_UpstreamLocalityStats_total_issued_requests(const envoy_config_endpoint_v3_UpstreamLocalityStats *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(32, 32), uint64_t); }
 
 UPB_INLINE void envoy_config_endpoint_v3_UpstreamLocalityStats_set_locality(envoy_config_endpoint_v3_UpstreamLocalityStats *msg, struct envoy_config_core_v3_Locality* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(36, 40), struct envoy_config_core_v3_Locality*) = value;
+  _upb_sethas(msg, 1);
+  *UPB_PTR_AT(msg, UPB_SIZE(44, 48), struct envoy_config_core_v3_Locality*) = value;
 }
 UPB_INLINE struct envoy_config_core_v3_Locality* envoy_config_endpoint_v3_UpstreamLocalityStats_mutable_locality(envoy_config_endpoint_v3_UpstreamLocalityStats *msg, upb_arena *arena) {
   struct envoy_config_core_v3_Locality* sub = (struct envoy_config_core_v3_Locality*)envoy_config_endpoint_v3_UpstreamLocalityStats_locality(msg);
@@ -83,45 +91,45 @@ UPB_INLINE struct envoy_config_core_v3_Locality* envoy_config_endpoint_v3_Upstre
   return sub;
 }
 UPB_INLINE void envoy_config_endpoint_v3_UpstreamLocalityStats_set_total_successful_requests(envoy_config_endpoint_v3_UpstreamLocalityStats *msg, uint64_t value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(0, 0), uint64_t) = value;
+  *UPB_PTR_AT(msg, UPB_SIZE(8, 8), uint64_t) = value;
 }
 UPB_INLINE void envoy_config_endpoint_v3_UpstreamLocalityStats_set_total_requests_in_progress(envoy_config_endpoint_v3_UpstreamLocalityStats *msg, uint64_t value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(8, 8), uint64_t) = value;
+  *UPB_PTR_AT(msg, UPB_SIZE(16, 16), uint64_t) = value;
 }
 UPB_INLINE void envoy_config_endpoint_v3_UpstreamLocalityStats_set_total_error_requests(envoy_config_endpoint_v3_UpstreamLocalityStats *msg, uint64_t value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(16, 16), uint64_t) = value;
+  *UPB_PTR_AT(msg, UPB_SIZE(24, 24), uint64_t) = value;
 }
 UPB_INLINE envoy_config_endpoint_v3_EndpointLoadMetricStats** envoy_config_endpoint_v3_UpstreamLocalityStats_mutable_load_metric_stats(envoy_config_endpoint_v3_UpstreamLocalityStats *msg, size_t *len) {
-  return (envoy_config_endpoint_v3_EndpointLoadMetricStats**)_upb_array_mutable_accessor(msg, UPB_SIZE(40, 48), len);
+  return (envoy_config_endpoint_v3_EndpointLoadMetricStats**)_upb_array_mutable_accessor(msg, UPB_SIZE(48, 56), len);
 }
 UPB_INLINE envoy_config_endpoint_v3_EndpointLoadMetricStats** envoy_config_endpoint_v3_UpstreamLocalityStats_resize_load_metric_stats(envoy_config_endpoint_v3_UpstreamLocalityStats *msg, size_t len, upb_arena *arena) {
-  return (envoy_config_endpoint_v3_EndpointLoadMetricStats**)_upb_array_resize_accessor(msg, UPB_SIZE(40, 48), len, UPB_TYPE_MESSAGE, arena);
+  return (envoy_config_endpoint_v3_EndpointLoadMetricStats**)_upb_array_resize_accessor2(msg, UPB_SIZE(48, 56), len, UPB_SIZE(2, 3), arena);
 }
 UPB_INLINE struct envoy_config_endpoint_v3_EndpointLoadMetricStats* envoy_config_endpoint_v3_UpstreamLocalityStats_add_load_metric_stats(envoy_config_endpoint_v3_UpstreamLocalityStats *msg, upb_arena *arena) {
   struct envoy_config_endpoint_v3_EndpointLoadMetricStats* sub = (struct envoy_config_endpoint_v3_EndpointLoadMetricStats*)_upb_msg_new(&envoy_config_endpoint_v3_EndpointLoadMetricStats_msginit, arena);
-  bool ok = _upb_array_append_accessor(
-      msg, UPB_SIZE(40, 48), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena);
+  bool ok = _upb_array_append_accessor2(
+      msg, UPB_SIZE(48, 56), UPB_SIZE(2, 3), &sub, arena);
   if (!ok) return NULL;
   return sub;
 }
 UPB_INLINE void envoy_config_endpoint_v3_UpstreamLocalityStats_set_priority(envoy_config_endpoint_v3_UpstreamLocalityStats *msg, uint32_t value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(32, 32), uint32_t) = value;
+  *UPB_PTR_AT(msg, UPB_SIZE(40, 40), uint32_t) = value;
 }
 UPB_INLINE envoy_config_endpoint_v3_UpstreamEndpointStats** envoy_config_endpoint_v3_UpstreamLocalityStats_mutable_upstream_endpoint_stats(envoy_config_endpoint_v3_UpstreamLocalityStats *msg, size_t *len) {
-  return (envoy_config_endpoint_v3_UpstreamEndpointStats**)_upb_array_mutable_accessor(msg, UPB_SIZE(44, 56), len);
+  return (envoy_config_endpoint_v3_UpstreamEndpointStats**)_upb_array_mutable_accessor(msg, UPB_SIZE(52, 64), len);
 }
 UPB_INLINE envoy_config_endpoint_v3_UpstreamEndpointStats** envoy_config_endpoint_v3_UpstreamLocalityStats_resize_upstream_endpoint_stats(envoy_config_endpoint_v3_UpstreamLocalityStats *msg, size_t len, upb_arena *arena) {
-  return (envoy_config_endpoint_v3_UpstreamEndpointStats**)_upb_array_resize_accessor(msg, UPB_SIZE(44, 56), len, UPB_TYPE_MESSAGE, arena);
+  return (envoy_config_endpoint_v3_UpstreamEndpointStats**)_upb_array_resize_accessor2(msg, UPB_SIZE(52, 64), len, UPB_SIZE(2, 3), arena);
 }
 UPB_INLINE struct envoy_config_endpoint_v3_UpstreamEndpointStats* envoy_config_endpoint_v3_UpstreamLocalityStats_add_upstream_endpoint_stats(envoy_config_endpoint_v3_UpstreamLocalityStats *msg, upb_arena *arena) {
   struct envoy_config_endpoint_v3_UpstreamEndpointStats* sub = (struct envoy_config_endpoint_v3_UpstreamEndpointStats*)_upb_msg_new(&envoy_config_endpoint_v3_UpstreamEndpointStats_msginit, arena);
-  bool ok = _upb_array_append_accessor(
-      msg, UPB_SIZE(44, 56), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena);
+  bool ok = _upb_array_append_accessor2(
+      msg, UPB_SIZE(52, 64), UPB_SIZE(2, 3), &sub, arena);
   if (!ok) return NULL;
   return sub;
 }
 UPB_INLINE void envoy_config_endpoint_v3_UpstreamLocalityStats_set_total_issued_requests(envoy_config_endpoint_v3_UpstreamLocalityStats *msg, uint64_t value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(24, 24), uint64_t) = value;
+  *UPB_PTR_AT(msg, UPB_SIZE(32, 32), uint64_t) = value;
 }
 
 /* envoy.config.endpoint.v3.UpstreamEndpointStats */
@@ -134,23 +142,30 @@ UPB_INLINE envoy_config_endpoint_v3_UpstreamEndpointStats *envoy_config_endpoint
   envoy_config_endpoint_v3_UpstreamEndpointStats *ret = envoy_config_endpoint_v3_UpstreamEndpointStats_new(arena);
   return (ret && upb_decode(buf, size, ret, &envoy_config_endpoint_v3_UpstreamEndpointStats_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE envoy_config_endpoint_v3_UpstreamEndpointStats *envoy_config_endpoint_v3_UpstreamEndpointStats_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  envoy_config_endpoint_v3_UpstreamEndpointStats *ret = envoy_config_endpoint_v3_UpstreamEndpointStats_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &envoy_config_endpoint_v3_UpstreamEndpointStats_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *envoy_config_endpoint_v3_UpstreamEndpointStats_serialize(const envoy_config_endpoint_v3_UpstreamEndpointStats *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &envoy_config_endpoint_v3_UpstreamEndpointStats_msginit, arena, len);
 }
 
-UPB_INLINE bool envoy_config_endpoint_v3_UpstreamEndpointStats_has_address(const envoy_config_endpoint_v3_UpstreamEndpointStats *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(32, 32)); }
-UPB_INLINE const struct envoy_config_core_v3_Address* envoy_config_endpoint_v3_UpstreamEndpointStats_address(const envoy_config_endpoint_v3_UpstreamEndpointStats *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(32, 32), const struct envoy_config_core_v3_Address*); }
-UPB_INLINE uint64_t envoy_config_endpoint_v3_UpstreamEndpointStats_total_successful_requests(const envoy_config_endpoint_v3_UpstreamEndpointStats *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(0, 0), uint64_t); }
-UPB_INLINE uint64_t envoy_config_endpoint_v3_UpstreamEndpointStats_total_requests_in_progress(const envoy_config_endpoint_v3_UpstreamEndpointStats *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(8, 8), uint64_t); }
-UPB_INLINE uint64_t envoy_config_endpoint_v3_UpstreamEndpointStats_total_error_requests(const envoy_config_endpoint_v3_UpstreamEndpointStats *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(16, 16), uint64_t); }
-UPB_INLINE bool envoy_config_endpoint_v3_UpstreamEndpointStats_has_load_metric_stats(const envoy_config_endpoint_v3_UpstreamEndpointStats *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(40, 48)); }
-UPB_INLINE const envoy_config_endpoint_v3_EndpointLoadMetricStats* const* envoy_config_endpoint_v3_UpstreamEndpointStats_load_metric_stats(const envoy_config_endpoint_v3_UpstreamEndpointStats *msg, size_t *len) { return (const envoy_config_endpoint_v3_EndpointLoadMetricStats* const*)_upb_array_accessor(msg, UPB_SIZE(40, 48), len); }
-UPB_INLINE bool envoy_config_endpoint_v3_UpstreamEndpointStats_has_metadata(const envoy_config_endpoint_v3_UpstreamEndpointStats *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(36, 40)); }
-UPB_INLINE const struct google_protobuf_Struct* envoy_config_endpoint_v3_UpstreamEndpointStats_metadata(const envoy_config_endpoint_v3_UpstreamEndpointStats *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(36, 40), const struct google_protobuf_Struct*); }
-UPB_INLINE uint64_t envoy_config_endpoint_v3_UpstreamEndpointStats_total_issued_requests(const envoy_config_endpoint_v3_UpstreamEndpointStats *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(24, 24), uint64_t); }
+UPB_INLINE bool envoy_config_endpoint_v3_UpstreamEndpointStats_has_address(const envoy_config_endpoint_v3_UpstreamEndpointStats *msg) { return _upb_hasbit(msg, 1); }
+UPB_INLINE const struct envoy_config_core_v3_Address* envoy_config_endpoint_v3_UpstreamEndpointStats_address(const envoy_config_endpoint_v3_UpstreamEndpointStats *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(40, 40), const struct envoy_config_core_v3_Address*); }
+UPB_INLINE uint64_t envoy_config_endpoint_v3_UpstreamEndpointStats_total_successful_requests(const envoy_config_endpoint_v3_UpstreamEndpointStats *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(8, 8), uint64_t); }
+UPB_INLINE uint64_t envoy_config_endpoint_v3_UpstreamEndpointStats_total_requests_in_progress(const envoy_config_endpoint_v3_UpstreamEndpointStats *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(16, 16), uint64_t); }
+UPB_INLINE uint64_t envoy_config_endpoint_v3_UpstreamEndpointStats_total_error_requests(const envoy_config_endpoint_v3_UpstreamEndpointStats *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(24, 24), uint64_t); }
+UPB_INLINE bool envoy_config_endpoint_v3_UpstreamEndpointStats_has_load_metric_stats(const envoy_config_endpoint_v3_UpstreamEndpointStats *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(48, 56)); }
+UPB_INLINE const envoy_config_endpoint_v3_EndpointLoadMetricStats* const* envoy_config_endpoint_v3_UpstreamEndpointStats_load_metric_stats(const envoy_config_endpoint_v3_UpstreamEndpointStats *msg, size_t *len) { return (const envoy_config_endpoint_v3_EndpointLoadMetricStats* const*)_upb_array_accessor(msg, UPB_SIZE(48, 56), len); }
+UPB_INLINE bool envoy_config_endpoint_v3_UpstreamEndpointStats_has_metadata(const envoy_config_endpoint_v3_UpstreamEndpointStats *msg) { return _upb_hasbit(msg, 2); }
+UPB_INLINE const struct google_protobuf_Struct* envoy_config_endpoint_v3_UpstreamEndpointStats_metadata(const envoy_config_endpoint_v3_UpstreamEndpointStats *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(44, 48), const struct google_protobuf_Struct*); }
+UPB_INLINE uint64_t envoy_config_endpoint_v3_UpstreamEndpointStats_total_issued_requests(const envoy_config_endpoint_v3_UpstreamEndpointStats *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(32, 32), uint64_t); }
 
 UPB_INLINE void envoy_config_endpoint_v3_UpstreamEndpointStats_set_address(envoy_config_endpoint_v3_UpstreamEndpointStats *msg, struct envoy_config_core_v3_Address* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(32, 32), struct envoy_config_core_v3_Address*) = value;
+  _upb_sethas(msg, 1);
+  *UPB_PTR_AT(msg, UPB_SIZE(40, 40), struct envoy_config_core_v3_Address*) = value;
 }
 UPB_INLINE struct envoy_config_core_v3_Address* envoy_config_endpoint_v3_UpstreamEndpointStats_mutable_address(envoy_config_endpoint_v3_UpstreamEndpointStats *msg, upb_arena *arena) {
   struct envoy_config_core_v3_Address* sub = (struct envoy_config_core_v3_Address*)envoy_config_endpoint_v3_UpstreamEndpointStats_address(msg);
@@ -162,29 +177,30 @@ UPB_INLINE struct envoy_config_core_v3_Address* envoy_config_endpoint_v3_Upstrea
   return sub;
 }
 UPB_INLINE void envoy_config_endpoint_v3_UpstreamEndpointStats_set_total_successful_requests(envoy_config_endpoint_v3_UpstreamEndpointStats *msg, uint64_t value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(0, 0), uint64_t) = value;
+  *UPB_PTR_AT(msg, UPB_SIZE(8, 8), uint64_t) = value;
 }
 UPB_INLINE void envoy_config_endpoint_v3_UpstreamEndpointStats_set_total_requests_in_progress(envoy_config_endpoint_v3_UpstreamEndpointStats *msg, uint64_t value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(8, 8), uint64_t) = value;
+  *UPB_PTR_AT(msg, UPB_SIZE(16, 16), uint64_t) = value;
 }
 UPB_INLINE void envoy_config_endpoint_v3_UpstreamEndpointStats_set_total_error_requests(envoy_config_endpoint_v3_UpstreamEndpointStats *msg, uint64_t value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(16, 16), uint64_t) = value;
+  *UPB_PTR_AT(msg, UPB_SIZE(24, 24), uint64_t) = value;
 }
 UPB_INLINE envoy_config_endpoint_v3_EndpointLoadMetricStats** envoy_config_endpoint_v3_UpstreamEndpointStats_mutable_load_metric_stats(envoy_config_endpoint_v3_UpstreamEndpointStats *msg, size_t *len) {
-  return (envoy_config_endpoint_v3_EndpointLoadMetricStats**)_upb_array_mutable_accessor(msg, UPB_SIZE(40, 48), len);
+  return (envoy_config_endpoint_v3_EndpointLoadMetricStats**)_upb_array_mutable_accessor(msg, UPB_SIZE(48, 56), len);
 }
 UPB_INLINE envoy_config_endpoint_v3_EndpointLoadMetricStats** envoy_config_endpoint_v3_UpstreamEndpointStats_resize_load_metric_stats(envoy_config_endpoint_v3_UpstreamEndpointStats *msg, size_t len, upb_arena *arena) {
-  return (envoy_config_endpoint_v3_EndpointLoadMetricStats**)_upb_array_resize_accessor(msg, UPB_SIZE(40, 48), len, UPB_TYPE_MESSAGE, arena);
+  return (envoy_config_endpoint_v3_EndpointLoadMetricStats**)_upb_array_resize_accessor2(msg, UPB_SIZE(48, 56), len, UPB_SIZE(2, 3), arena);
 }
 UPB_INLINE struct envoy_config_endpoint_v3_EndpointLoadMetricStats* envoy_config_endpoint_v3_UpstreamEndpointStats_add_load_metric_stats(envoy_config_endpoint_v3_UpstreamEndpointStats *msg, upb_arena *arena) {
   struct envoy_config_endpoint_v3_EndpointLoadMetricStats* sub = (struct envoy_config_endpoint_v3_EndpointLoadMetricStats*)_upb_msg_new(&envoy_config_endpoint_v3_EndpointLoadMetricStats_msginit, arena);
-  bool ok = _upb_array_append_accessor(
-      msg, UPB_SIZE(40, 48), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena);
+  bool ok = _upb_array_append_accessor2(
+      msg, UPB_SIZE(48, 56), UPB_SIZE(2, 3), &sub, arena);
   if (!ok) return NULL;
   return sub;
 }
 UPB_INLINE void envoy_config_endpoint_v3_UpstreamEndpointStats_set_metadata(envoy_config_endpoint_v3_UpstreamEndpointStats *msg, struct google_protobuf_Struct* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(36, 40), struct google_protobuf_Struct*) = value;
+  _upb_sethas(msg, 2);
+  *UPB_PTR_AT(msg, UPB_SIZE(44, 48), struct google_protobuf_Struct*) = value;
 }
 UPB_INLINE struct google_protobuf_Struct* envoy_config_endpoint_v3_UpstreamEndpointStats_mutable_metadata(envoy_config_endpoint_v3_UpstreamEndpointStats *msg, upb_arena *arena) {
   struct google_protobuf_Struct* sub = (struct google_protobuf_Struct*)envoy_config_endpoint_v3_UpstreamEndpointStats_metadata(msg);
@@ -196,7 +212,7 @@ UPB_INLINE struct google_protobuf_Struct* envoy_config_endpoint_v3_UpstreamEndpo
   return sub;
 }
 UPB_INLINE void envoy_config_endpoint_v3_UpstreamEndpointStats_set_total_issued_requests(envoy_config_endpoint_v3_UpstreamEndpointStats *msg, uint64_t value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(24, 24), uint64_t) = value;
+  *UPB_PTR_AT(msg, UPB_SIZE(32, 32), uint64_t) = value;
 }
 
 /* envoy.config.endpoint.v3.EndpointLoadMetricStats */
@@ -209,6 +225,12 @@ UPB_INLINE envoy_config_endpoint_v3_EndpointLoadMetricStats *envoy_config_endpoi
   envoy_config_endpoint_v3_EndpointLoadMetricStats *ret = envoy_config_endpoint_v3_EndpointLoadMetricStats_new(arena);
   return (ret && upb_decode(buf, size, ret, &envoy_config_endpoint_v3_EndpointLoadMetricStats_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE envoy_config_endpoint_v3_EndpointLoadMetricStats *envoy_config_endpoint_v3_EndpointLoadMetricStats_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  envoy_config_endpoint_v3_EndpointLoadMetricStats *ret = envoy_config_endpoint_v3_EndpointLoadMetricStats_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &envoy_config_endpoint_v3_EndpointLoadMetricStats_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *envoy_config_endpoint_v3_EndpointLoadMetricStats_serialize(const envoy_config_endpoint_v3_EndpointLoadMetricStats *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &envoy_config_endpoint_v3_EndpointLoadMetricStats_msginit, arena, len);
 }
@@ -237,41 +259,48 @@ UPB_INLINE envoy_config_endpoint_v3_ClusterStats *envoy_config_endpoint_v3_Clust
   envoy_config_endpoint_v3_ClusterStats *ret = envoy_config_endpoint_v3_ClusterStats_new(arena);
   return (ret && upb_decode(buf, size, ret, &envoy_config_endpoint_v3_ClusterStats_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE envoy_config_endpoint_v3_ClusterStats *envoy_config_endpoint_v3_ClusterStats_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  envoy_config_endpoint_v3_ClusterStats *ret = envoy_config_endpoint_v3_ClusterStats_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &envoy_config_endpoint_v3_ClusterStats_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *envoy_config_endpoint_v3_ClusterStats_serialize(const envoy_config_endpoint_v3_ClusterStats *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &envoy_config_endpoint_v3_ClusterStats_msginit, arena, len);
 }
 
-UPB_INLINE upb_strview envoy_config_endpoint_v3_ClusterStats_cluster_name(const envoy_config_endpoint_v3_ClusterStats *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(8, 8), upb_strview); }
-UPB_INLINE bool envoy_config_endpoint_v3_ClusterStats_has_upstream_locality_stats(const envoy_config_endpoint_v3_ClusterStats *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(28, 48)); }
-UPB_INLINE const envoy_config_endpoint_v3_UpstreamLocalityStats* const* envoy_config_endpoint_v3_ClusterStats_upstream_locality_stats(const envoy_config_endpoint_v3_ClusterStats *msg, size_t *len) { return (const envoy_config_endpoint_v3_UpstreamLocalityStats* const*)_upb_array_accessor(msg, UPB_SIZE(28, 48), len); }
-UPB_INLINE uint64_t envoy_config_endpoint_v3_ClusterStats_total_dropped_requests(const envoy_config_endpoint_v3_ClusterStats *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(0, 0), uint64_t); }
-UPB_INLINE bool envoy_config_endpoint_v3_ClusterStats_has_load_report_interval(const envoy_config_endpoint_v3_ClusterStats *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(24, 40)); }
-UPB_INLINE const struct google_protobuf_Duration* envoy_config_endpoint_v3_ClusterStats_load_report_interval(const envoy_config_endpoint_v3_ClusterStats *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(24, 40), const struct google_protobuf_Duration*); }
-UPB_INLINE bool envoy_config_endpoint_v3_ClusterStats_has_dropped_requests(const envoy_config_endpoint_v3_ClusterStats *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(32, 56)); }
-UPB_INLINE const envoy_config_endpoint_v3_ClusterStats_DroppedRequests* const* envoy_config_endpoint_v3_ClusterStats_dropped_requests(const envoy_config_endpoint_v3_ClusterStats *msg, size_t *len) { return (const envoy_config_endpoint_v3_ClusterStats_DroppedRequests* const*)_upb_array_accessor(msg, UPB_SIZE(32, 56), len); }
-UPB_INLINE upb_strview envoy_config_endpoint_v3_ClusterStats_cluster_service_name(const envoy_config_endpoint_v3_ClusterStats *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(16, 24), upb_strview); }
+UPB_INLINE upb_strview envoy_config_endpoint_v3_ClusterStats_cluster_name(const envoy_config_endpoint_v3_ClusterStats *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(16, 16), upb_strview); }
+UPB_INLINE bool envoy_config_endpoint_v3_ClusterStats_has_upstream_locality_stats(const envoy_config_endpoint_v3_ClusterStats *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(36, 56)); }
+UPB_INLINE const envoy_config_endpoint_v3_UpstreamLocalityStats* const* envoy_config_endpoint_v3_ClusterStats_upstream_locality_stats(const envoy_config_endpoint_v3_ClusterStats *msg, size_t *len) { return (const envoy_config_endpoint_v3_UpstreamLocalityStats* const*)_upb_array_accessor(msg, UPB_SIZE(36, 56), len); }
+UPB_INLINE uint64_t envoy_config_endpoint_v3_ClusterStats_total_dropped_requests(const envoy_config_endpoint_v3_ClusterStats *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(8, 8), uint64_t); }
+UPB_INLINE bool envoy_config_endpoint_v3_ClusterStats_has_load_report_interval(const envoy_config_endpoint_v3_ClusterStats *msg) { return _upb_hasbit(msg, 1); }
+UPB_INLINE const struct google_protobuf_Duration* envoy_config_endpoint_v3_ClusterStats_load_report_interval(const envoy_config_endpoint_v3_ClusterStats *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(32, 48), const struct google_protobuf_Duration*); }
+UPB_INLINE bool envoy_config_endpoint_v3_ClusterStats_has_dropped_requests(const envoy_config_endpoint_v3_ClusterStats *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(40, 64)); }
+UPB_INLINE const envoy_config_endpoint_v3_ClusterStats_DroppedRequests* const* envoy_config_endpoint_v3_ClusterStats_dropped_requests(const envoy_config_endpoint_v3_ClusterStats *msg, size_t *len) { return (const envoy_config_endpoint_v3_ClusterStats_DroppedRequests* const*)_upb_array_accessor(msg, UPB_SIZE(40, 64), len); }
+UPB_INLINE upb_strview envoy_config_endpoint_v3_ClusterStats_cluster_service_name(const envoy_config_endpoint_v3_ClusterStats *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(24, 32), upb_strview); }
 
 UPB_INLINE void envoy_config_endpoint_v3_ClusterStats_set_cluster_name(envoy_config_endpoint_v3_ClusterStats *msg, upb_strview value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(8, 8), upb_strview) = value;
+  *UPB_PTR_AT(msg, UPB_SIZE(16, 16), upb_strview) = value;
 }
 UPB_INLINE envoy_config_endpoint_v3_UpstreamLocalityStats** envoy_config_endpoint_v3_ClusterStats_mutable_upstream_locality_stats(envoy_config_endpoint_v3_ClusterStats *msg, size_t *len) {
-  return (envoy_config_endpoint_v3_UpstreamLocalityStats**)_upb_array_mutable_accessor(msg, UPB_SIZE(28, 48), len);
+  return (envoy_config_endpoint_v3_UpstreamLocalityStats**)_upb_array_mutable_accessor(msg, UPB_SIZE(36, 56), len);
 }
 UPB_INLINE envoy_config_endpoint_v3_UpstreamLocalityStats** envoy_config_endpoint_v3_ClusterStats_resize_upstream_locality_stats(envoy_config_endpoint_v3_ClusterStats *msg, size_t len, upb_arena *arena) {
-  return (envoy_config_endpoint_v3_UpstreamLocalityStats**)_upb_array_resize_accessor(msg, UPB_SIZE(28, 48), len, UPB_TYPE_MESSAGE, arena);
+  return (envoy_config_endpoint_v3_UpstreamLocalityStats**)_upb_array_resize_accessor2(msg, UPB_SIZE(36, 56), len, UPB_SIZE(2, 3), arena);
 }
 UPB_INLINE struct envoy_config_endpoint_v3_UpstreamLocalityStats* envoy_config_endpoint_v3_ClusterStats_add_upstream_locality_stats(envoy_config_endpoint_v3_ClusterStats *msg, upb_arena *arena) {
   struct envoy_config_endpoint_v3_UpstreamLocalityStats* sub = (struct envoy_config_endpoint_v3_UpstreamLocalityStats*)_upb_msg_new(&envoy_config_endpoint_v3_UpstreamLocalityStats_msginit, arena);
-  bool ok = _upb_array_append_accessor(
-      msg, UPB_SIZE(28, 48), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena);
+  bool ok = _upb_array_append_accessor2(
+      msg, UPB_SIZE(36, 56), UPB_SIZE(2, 3), &sub, arena);
   if (!ok) return NULL;
   return sub;
 }
 UPB_INLINE void envoy_config_endpoint_v3_ClusterStats_set_total_dropped_requests(envoy_config_endpoint_v3_ClusterStats *msg, uint64_t value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(0, 0), uint64_t) = value;
+  *UPB_PTR_AT(msg, UPB_SIZE(8, 8), uint64_t) = value;
 }
 UPB_INLINE void envoy_config_endpoint_v3_ClusterStats_set_load_report_interval(envoy_config_endpoint_v3_ClusterStats *msg, struct google_protobuf_Duration* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(24, 40), struct google_protobuf_Duration*) = value;
+  _upb_sethas(msg, 1);
+  *UPB_PTR_AT(msg, UPB_SIZE(32, 48), struct google_protobuf_Duration*) = value;
 }
 UPB_INLINE struct google_protobuf_Duration* envoy_config_endpoint_v3_ClusterStats_mutable_load_report_interval(envoy_config_endpoint_v3_ClusterStats *msg, upb_arena *arena) {
   struct google_protobuf_Duration* sub = (struct google_protobuf_Duration*)envoy_config_endpoint_v3_ClusterStats_load_report_interval(msg);
@@ -283,20 +312,20 @@ UPB_INLINE struct google_protobuf_Duration* envoy_config_endpoint_v3_ClusterStat
   return sub;
 }
 UPB_INLINE envoy_config_endpoint_v3_ClusterStats_DroppedRequests** envoy_config_endpoint_v3_ClusterStats_mutable_dropped_requests(envoy_config_endpoint_v3_ClusterStats *msg, size_t *len) {
-  return (envoy_config_endpoint_v3_ClusterStats_DroppedRequests**)_upb_array_mutable_accessor(msg, UPB_SIZE(32, 56), len);
+  return (envoy_config_endpoint_v3_ClusterStats_DroppedRequests**)_upb_array_mutable_accessor(msg, UPB_SIZE(40, 64), len);
 }
 UPB_INLINE envoy_config_endpoint_v3_ClusterStats_DroppedRequests** envoy_config_endpoint_v3_ClusterStats_resize_dropped_requests(envoy_config_endpoint_v3_ClusterStats *msg, size_t len, upb_arena *arena) {
-  return (envoy_config_endpoint_v3_ClusterStats_DroppedRequests**)_upb_array_resize_accessor(msg, UPB_SIZE(32, 56), len, UPB_TYPE_MESSAGE, arena);
+  return (envoy_config_endpoint_v3_ClusterStats_DroppedRequests**)_upb_array_resize_accessor2(msg, UPB_SIZE(40, 64), len, UPB_SIZE(2, 3), arena);
 }
 UPB_INLINE struct envoy_config_endpoint_v3_ClusterStats_DroppedRequests* envoy_config_endpoint_v3_ClusterStats_add_dropped_requests(envoy_config_endpoint_v3_ClusterStats *msg, upb_arena *arena) {
   struct envoy_config_endpoint_v3_ClusterStats_DroppedRequests* sub = (struct envoy_config_endpoint_v3_ClusterStats_DroppedRequests*)_upb_msg_new(&envoy_config_endpoint_v3_ClusterStats_DroppedRequests_msginit, arena);
-  bool ok = _upb_array_append_accessor(
-      msg, UPB_SIZE(32, 56), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena);
+  bool ok = _upb_array_append_accessor2(
+      msg, UPB_SIZE(40, 64), UPB_SIZE(2, 3), &sub, arena);
   if (!ok) return NULL;
   return sub;
 }
 UPB_INLINE void envoy_config_endpoint_v3_ClusterStats_set_cluster_service_name(envoy_config_endpoint_v3_ClusterStats *msg, upb_strview value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(16, 24), upb_strview) = value;
+  *UPB_PTR_AT(msg, UPB_SIZE(24, 32), upb_strview) = value;
 }
 
 /* envoy.config.endpoint.v3.ClusterStats.DroppedRequests */
@@ -309,6 +338,12 @@ UPB_INLINE envoy_config_endpoint_v3_ClusterStats_DroppedRequests *envoy_config_e
   envoy_config_endpoint_v3_ClusterStats_DroppedRequests *ret = envoy_config_endpoint_v3_ClusterStats_DroppedRequests_new(arena);
   return (ret && upb_decode(buf, size, ret, &envoy_config_endpoint_v3_ClusterStats_DroppedRequests_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE envoy_config_endpoint_v3_ClusterStats_DroppedRequests *envoy_config_endpoint_v3_ClusterStats_DroppedRequests_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  envoy_config_endpoint_v3_ClusterStats_DroppedRequests *ret = envoy_config_endpoint_v3_ClusterStats_DroppedRequests_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &envoy_config_endpoint_v3_ClusterStats_DroppedRequests_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *envoy_config_endpoint_v3_ClusterStats_DroppedRequests_serialize(const envoy_config_endpoint_v3_ClusterStats_DroppedRequests *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &envoy_config_endpoint_v3_ClusterStats_DroppedRequests_msginit, arena, len);
 }
index 7d0a105..e016fff 100644 (file)
@@ -20,13 +20,13 @@ static const upb_msglayout *const envoy_config_listener_v3_ApiListener_submsgs[1
 };
 
 static const upb_msglayout_field envoy_config_listener_v3_ApiListener__fields[1] = {
-  {1, UPB_SIZE(0, 0), 0, 0, 11, 1},
+  {1, UPB_SIZE(4, 8), 1, 0, 11, 1},
 };
 
 const upb_msglayout envoy_config_listener_v3_ApiListener_msginit = {
   &envoy_config_listener_v3_ApiListener_submsgs[0],
   &envoy_config_listener_v3_ApiListener__fields[0],
-  UPB_SIZE(4, 8), 1, false,
+  UPB_SIZE(8, 16), 1, false, 255,
 };
 
 #include "upb/port_undef.inc"
index 81fbf6b..9d1372b 100644 (file)
@@ -11,6 +11,7 @@
 
 #include "upb/msg.h"
 #include "upb/decode.h"
+#include "upb/decode_fast.h"
 #include "upb/encode.h"
 
 #include "upb/port_def.inc"
@@ -36,15 +37,22 @@ UPB_INLINE envoy_config_listener_v3_ApiListener *envoy_config_listener_v3_ApiLis
   envoy_config_listener_v3_ApiListener *ret = envoy_config_listener_v3_ApiListener_new(arena);
   return (ret && upb_decode(buf, size, ret, &envoy_config_listener_v3_ApiListener_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE envoy_config_listener_v3_ApiListener *envoy_config_listener_v3_ApiListener_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  envoy_config_listener_v3_ApiListener *ret = envoy_config_listener_v3_ApiListener_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &envoy_config_listener_v3_ApiListener_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *envoy_config_listener_v3_ApiListener_serialize(const envoy_config_listener_v3_ApiListener *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &envoy_config_listener_v3_ApiListener_msginit, arena, len);
 }
 
-UPB_INLINE bool envoy_config_listener_v3_ApiListener_has_api_listener(const envoy_config_listener_v3_ApiListener *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(0, 0)); }
-UPB_INLINE const struct google_protobuf_Any* envoy_config_listener_v3_ApiListener_api_listener(const envoy_config_listener_v3_ApiListener *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(0, 0), const struct google_protobuf_Any*); }
+UPB_INLINE bool envoy_config_listener_v3_ApiListener_has_api_listener(const envoy_config_listener_v3_ApiListener *msg) { return _upb_hasbit(msg, 1); }
+UPB_INLINE const struct google_protobuf_Any* envoy_config_listener_v3_ApiListener_api_listener(const envoy_config_listener_v3_ApiListener *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(4, 8), const struct google_protobuf_Any*); }
 
 UPB_INLINE void envoy_config_listener_v3_ApiListener_set_api_listener(envoy_config_listener_v3_ApiListener *msg, struct google_protobuf_Any* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(0, 0), struct google_protobuf_Any*) = value;
+  _upb_sethas(msg, 1);
+  *UPB_PTR_AT(msg, UPB_SIZE(4, 8), struct google_protobuf_Any*) = value;
 }
 UPB_INLINE struct google_protobuf_Any* envoy_config_listener_v3_ApiListener_mutable_api_listener(envoy_config_listener_v3_ApiListener *msg, upb_arena *arena) {
   struct google_protobuf_Any* sub = (struct google_protobuf_Any*)envoy_config_listener_v3_ApiListener_api_listener(msg);
index 4fe3ca7..6a8a837 100644 (file)
@@ -39,10 +39,10 @@ static const upb_msglayout_field envoy_config_listener_v3_ListenerCollection__fi
 const upb_msglayout envoy_config_listener_v3_ListenerCollection_msginit = {
   &envoy_config_listener_v3_ListenerCollection_submsgs[0],
   &envoy_config_listener_v3_ListenerCollection__fields[0],
-  UPB_SIZE(4, 8), 1, false,
+  UPB_SIZE(8, 8), 1, false, 255,
 };
 
-static const upb_msglayout *const envoy_config_listener_v3_Listener_submsgs[17] = {
+static const upb_msglayout *const envoy_config_listener_v3_Listener_submsgs[14] = {
   &envoy_config_accesslog_v3_AccessLog_msginit,
   &envoy_config_core_v3_Address_msginit,
   &envoy_config_core_v3_Metadata_msginit,
@@ -60,34 +60,34 @@ static const upb_msglayout *const envoy_config_listener_v3_Listener_submsgs[17]
 };
 
 static const upb_msglayout_field envoy_config_listener_v3_Listener__fields[22] = {
-  {1, UPB_SIZE(20, 24), 0, 0, 9, 1},
-  {2, UPB_SIZE(28, 40), 0, 1, 11, 1},
-  {3, UPB_SIZE(80, 144), 0, 6, 11, 3},
-  {5, UPB_SIZE(32, 48), 0, 13, 11, 1},
-  {6, UPB_SIZE(36, 56), 0, 2, 11, 1},
-  {7, UPB_SIZE(40, 64), 0, 8, 11, 1},
-  {8, UPB_SIZE(0, 0), 0, 0, 14, 1},
-  {9, UPB_SIZE(84, 152), 0, 9, 11, 3},
-  {10, UPB_SIZE(44, 72), 0, 11, 11, 1},
-  {11, UPB_SIZE(48, 80), 0, 11, 11, 1},
-  {12, UPB_SIZE(52, 88), 0, 13, 11, 1},
-  {13, UPB_SIZE(88, 160), 0, 3, 11, 3},
-  {15, UPB_SIZE(56, 96), 0, 12, 11, 1},
+  {1, UPB_SIZE(16, 16), 0, 0, 9, 1},
+  {2, UPB_SIZE(24, 32), 1, 1, 11, 1},
+  {3, UPB_SIZE(76, 136), 0, 6, 11, 3},
+  {5, UPB_SIZE(28, 40), 2, 13, 11, 1},
+  {6, UPB_SIZE(32, 48), 3, 2, 11, 1},
+  {7, UPB_SIZE(36, 56), 4, 8, 11, 1},
+  {8, UPB_SIZE(4, 4), 0, 0, 14, 1},
+  {9, UPB_SIZE(80, 144), 0, 9, 11, 3},
+  {10, UPB_SIZE(40, 64), 5, 11, 11, 1},
+  {11, UPB_SIZE(44, 72), 6, 11, 11, 1},
+  {12, UPB_SIZE(48, 80), 7, 13, 11, 1},
+  {13, UPB_SIZE(84, 152), 0, 3, 11, 3},
+  {15, UPB_SIZE(52, 88), 8, 12, 11, 1},
   {16, UPB_SIZE(8, 8), 0, 0, 14, 1},
-  {17, UPB_SIZE(16, 16), 0, 0, 8, 1},
-  {18, UPB_SIZE(60, 104), 0, 10, 11, 1},
-  {19, UPB_SIZE(64, 112), 0, 5, 11, 1},
-  {20, UPB_SIZE(68, 120), 0, 7, 11, 1},
-  {21, UPB_SIZE(17, 17), 0, 0, 8, 1},
-  {22, UPB_SIZE(92, 168), 0, 0, 11, 3},
-  {23, UPB_SIZE(72, 128), 0, 4, 11, 1},
-  {24, UPB_SIZE(76, 136), 0, 13, 11, 1},
+  {17, UPB_SIZE(12, 12), 0, 0, 8, 1},
+  {18, UPB_SIZE(56, 96), 9, 10, 11, 1},
+  {19, UPB_SIZE(60, 104), 10, 5, 11, 1},
+  {20, UPB_SIZE(64, 112), 11, 7, 11, 1},
+  {21, UPB_SIZE(13, 13), 0, 0, 8, 1},
+  {22, UPB_SIZE(88, 160), 0, 0, 11, 3},
+  {23, UPB_SIZE(68, 120), 12, 4, 11, 1},
+  {24, UPB_SIZE(72, 128), 13, 13, 11, 1},
 };
 
 const upb_msglayout envoy_config_listener_v3_Listener_msginit = {
   &envoy_config_listener_v3_Listener_submsgs[0],
   &envoy_config_listener_v3_Listener__fields[0],
-  UPB_SIZE(96, 176), 22, false,
+  UPB_SIZE(96, 176), 22, false, 255,
 };
 
 static const upb_msglayout *const envoy_config_listener_v3_Listener_DeprecatedV1_submsgs[1] = {
@@ -95,13 +95,13 @@ static const upb_msglayout *const envoy_config_listener_v3_Listener_DeprecatedV1
 };
 
 static const upb_msglayout_field envoy_config_listener_v3_Listener_DeprecatedV1__fields[1] = {
-  {1, UPB_SIZE(0, 0), 0, 0, 11, 1},
+  {1, UPB_SIZE(4, 8), 1, 0, 11, 1},
 };
 
 const upb_msglayout envoy_config_listener_v3_Listener_DeprecatedV1_msginit = {
   &envoy_config_listener_v3_Listener_DeprecatedV1_submsgs[0],
   &envoy_config_listener_v3_Listener_DeprecatedV1__fields[0],
-  UPB_SIZE(4, 8), 1, false,
+  UPB_SIZE(8, 16), 1, false, 255,
 };
 
 static const upb_msglayout *const envoy_config_listener_v3_Listener_ConnectionBalanceConfig_submsgs[1] = {
@@ -115,13 +115,13 @@ static const upb_msglayout_field envoy_config_listener_v3_Listener_ConnectionBal
 const upb_msglayout envoy_config_listener_v3_Listener_ConnectionBalanceConfig_msginit = {
   &envoy_config_listener_v3_Listener_ConnectionBalanceConfig_submsgs[0],
   &envoy_config_listener_v3_Listener_ConnectionBalanceConfig__fields[0],
-  UPB_SIZE(8, 16), 1, false,
+  UPB_SIZE(8, 16), 1, false, 255,
 };
 
 const upb_msglayout envoy_config_listener_v3_Listener_ConnectionBalanceConfig_ExactBalance_msginit = {
   NULL,
   NULL,
-  UPB_SIZE(0, 0), 0, false,
+  UPB_SIZE(0, 0), 0, false, 255,
 };
 
 #include "upb/port_undef.inc"
index 0bc3ca3..7f97584 100644 (file)
@@ -11,6 +11,7 @@
 
 #include "upb/msg.h"
 #include "upb/decode.h"
+#include "upb/decode_fast.h"
 #include "upb/encode.h"
 
 #include "upb/port_def.inc"
@@ -77,6 +78,12 @@ UPB_INLINE envoy_config_listener_v3_ListenerCollection *envoy_config_listener_v3
   envoy_config_listener_v3_ListenerCollection *ret = envoy_config_listener_v3_ListenerCollection_new(arena);
   return (ret && upb_decode(buf, size, ret, &envoy_config_listener_v3_ListenerCollection_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE envoy_config_listener_v3_ListenerCollection *envoy_config_listener_v3_ListenerCollection_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  envoy_config_listener_v3_ListenerCollection *ret = envoy_config_listener_v3_ListenerCollection_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &envoy_config_listener_v3_ListenerCollection_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *envoy_config_listener_v3_ListenerCollection_serialize(const envoy_config_listener_v3_ListenerCollection *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &envoy_config_listener_v3_ListenerCollection_msginit, arena, len);
 }
@@ -88,12 +95,12 @@ UPB_INLINE struct udpa_core_v1_CollectionEntry** envoy_config_listener_v3_Listen
   return (struct udpa_core_v1_CollectionEntry**)_upb_array_mutable_accessor(msg, UPB_SIZE(0, 0), len);
 }
 UPB_INLINE struct udpa_core_v1_CollectionEntry** envoy_config_listener_v3_ListenerCollection_resize_entries(envoy_config_listener_v3_ListenerCollection *msg, size_t len, upb_arena *arena) {
-  return (struct udpa_core_v1_CollectionEntry**)_upb_array_resize_accessor(msg, UPB_SIZE(0, 0), len, UPB_TYPE_MESSAGE, arena);
+  return (struct udpa_core_v1_CollectionEntry**)_upb_array_resize_accessor2(msg, UPB_SIZE(0, 0), len, UPB_SIZE(2, 3), arena);
 }
 UPB_INLINE struct udpa_core_v1_CollectionEntry* envoy_config_listener_v3_ListenerCollection_add_entries(envoy_config_listener_v3_ListenerCollection *msg, upb_arena *arena) {
   struct udpa_core_v1_CollectionEntry* sub = (struct udpa_core_v1_CollectionEntry*)_upb_msg_new(&udpa_core_v1_CollectionEntry_msginit, arena);
-  bool ok = _upb_array_append_accessor(
-      msg, UPB_SIZE(0, 0), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena);
+  bool ok = _upb_array_append_accessor2(
+      msg, UPB_SIZE(0, 0), UPB_SIZE(2, 3), &sub, arena);
   if (!ok) return NULL;
   return sub;
 }
@@ -108,55 +115,62 @@ UPB_INLINE envoy_config_listener_v3_Listener *envoy_config_listener_v3_Listener_
   envoy_config_listener_v3_Listener *ret = envoy_config_listener_v3_Listener_new(arena);
   return (ret && upb_decode(buf, size, ret, &envoy_config_listener_v3_Listener_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE envoy_config_listener_v3_Listener *envoy_config_listener_v3_Listener_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  envoy_config_listener_v3_Listener *ret = envoy_config_listener_v3_Listener_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &envoy_config_listener_v3_Listener_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *envoy_config_listener_v3_Listener_serialize(const envoy_config_listener_v3_Listener *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &envoy_config_listener_v3_Listener_msginit, arena, len);
 }
 
-UPB_INLINE upb_strview envoy_config_listener_v3_Listener_name(const envoy_config_listener_v3_Listener *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(20, 24), upb_strview); }
-UPB_INLINE bool envoy_config_listener_v3_Listener_has_address(const envoy_config_listener_v3_Listener *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(28, 40)); }
-UPB_INLINE const struct envoy_config_core_v3_Address* envoy_config_listener_v3_Listener_address(const envoy_config_listener_v3_Listener *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(28, 40), const struct envoy_config_core_v3_Address*); }
-UPB_INLINE bool envoy_config_listener_v3_Listener_has_filter_chains(const envoy_config_listener_v3_Listener *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(80, 144)); }
-UPB_INLINE const struct envoy_config_listener_v3_FilterChain* const* envoy_config_listener_v3_Listener_filter_chains(const envoy_config_listener_v3_Listener *msg, size_t *len) { return (const struct envoy_config_listener_v3_FilterChain* const*)_upb_array_accessor(msg, UPB_SIZE(80, 144), len); }
-UPB_INLINE bool envoy_config_listener_v3_Listener_has_per_connection_buffer_limit_bytes(const envoy_config_listener_v3_Listener *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(32, 48)); }
-UPB_INLINE const struct google_protobuf_UInt32Value* envoy_config_listener_v3_Listener_per_connection_buffer_limit_bytes(const envoy_config_listener_v3_Listener *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(32, 48), const struct google_protobuf_UInt32Value*); }
-UPB_INLINE bool envoy_config_listener_v3_Listener_has_metadata(const envoy_config_listener_v3_Listener *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(36, 56)); }
-UPB_INLINE const struct envoy_config_core_v3_Metadata* envoy_config_listener_v3_Listener_metadata(const envoy_config_listener_v3_Listener *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(36, 56), const struct envoy_config_core_v3_Metadata*); }
-UPB_INLINE bool envoy_config_listener_v3_Listener_has_deprecated_v1(const envoy_config_listener_v3_Listener *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(40, 64)); }
-UPB_INLINE const envoy_config_listener_v3_Listener_DeprecatedV1* envoy_config_listener_v3_Listener_deprecated_v1(const envoy_config_listener_v3_Listener *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(40, 64), const envoy_config_listener_v3_Listener_DeprecatedV1*); }
-UPB_INLINE int32_t envoy_config_listener_v3_Listener_drain_type(const envoy_config_listener_v3_Listener *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(0, 0), int32_t); }
-UPB_INLINE bool envoy_config_listener_v3_Listener_has_listener_filters(const envoy_config_listener_v3_Listener *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(84, 152)); }
-UPB_INLINE const struct envoy_config_listener_v3_ListenerFilter* const* envoy_config_listener_v3_Listener_listener_filters(const envoy_config_listener_v3_Listener *msg, size_t *len) { return (const struct envoy_config_listener_v3_ListenerFilter* const*)_upb_array_accessor(msg, UPB_SIZE(84, 152), len); }
-UPB_INLINE bool envoy_config_listener_v3_Listener_has_transparent(const envoy_config_listener_v3_Listener *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(44, 72)); }
-UPB_INLINE const struct google_protobuf_BoolValue* envoy_config_listener_v3_Listener_transparent(const envoy_config_listener_v3_Listener *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(44, 72), const struct google_protobuf_BoolValue*); }
-UPB_INLINE bool envoy_config_listener_v3_Listener_has_freebind(const envoy_config_listener_v3_Listener *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(48, 80)); }
-UPB_INLINE const struct google_protobuf_BoolValue* envoy_config_listener_v3_Listener_freebind(const envoy_config_listener_v3_Listener *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(48, 80), const struct google_protobuf_BoolValue*); }
-UPB_INLINE bool envoy_config_listener_v3_Listener_has_tcp_fast_open_queue_length(const envoy_config_listener_v3_Listener *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(52, 88)); }
-UPB_INLINE const struct google_protobuf_UInt32Value* envoy_config_listener_v3_Listener_tcp_fast_open_queue_length(const envoy_config_listener_v3_Listener *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(52, 88), const struct google_protobuf_UInt32Value*); }
-UPB_INLINE bool envoy_config_listener_v3_Listener_has_socket_options(const envoy_config_listener_v3_Listener *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(88, 160)); }
-UPB_INLINE const struct envoy_config_core_v3_SocketOption* const* envoy_config_listener_v3_Listener_socket_options(const envoy_config_listener_v3_Listener *msg, size_t *len) { return (const struct envoy_config_core_v3_SocketOption* const*)_upb_array_accessor(msg, UPB_SIZE(88, 160), len); }
-UPB_INLINE bool envoy_config_listener_v3_Listener_has_listener_filters_timeout(const envoy_config_listener_v3_Listener *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(56, 96)); }
-UPB_INLINE const struct google_protobuf_Duration* envoy_config_listener_v3_Listener_listener_filters_timeout(const envoy_config_listener_v3_Listener *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(56, 96), const struct google_protobuf_Duration*); }
+UPB_INLINE upb_strview envoy_config_listener_v3_Listener_name(const envoy_config_listener_v3_Listener *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(16, 16), upb_strview); }
+UPB_INLINE bool envoy_config_listener_v3_Listener_has_address(const envoy_config_listener_v3_Listener *msg) { return _upb_hasbit(msg, 1); }
+UPB_INLINE const struct envoy_config_core_v3_Address* envoy_config_listener_v3_Listener_address(const envoy_config_listener_v3_Listener *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(24, 32), const struct envoy_config_core_v3_Address*); }
+UPB_INLINE bool envoy_config_listener_v3_Listener_has_filter_chains(const envoy_config_listener_v3_Listener *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(76, 136)); }
+UPB_INLINE const struct envoy_config_listener_v3_FilterChain* const* envoy_config_listener_v3_Listener_filter_chains(const envoy_config_listener_v3_Listener *msg, size_t *len) { return (const struct envoy_config_listener_v3_FilterChain* const*)_upb_array_accessor(msg, UPB_SIZE(76, 136), len); }
+UPB_INLINE bool envoy_config_listener_v3_Listener_has_per_connection_buffer_limit_bytes(const envoy_config_listener_v3_Listener *msg) { return _upb_hasbit(msg, 2); }
+UPB_INLINE const struct google_protobuf_UInt32Value* envoy_config_listener_v3_Listener_per_connection_buffer_limit_bytes(const envoy_config_listener_v3_Listener *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(28, 40), const struct google_protobuf_UInt32Value*); }
+UPB_INLINE bool envoy_config_listener_v3_Listener_has_metadata(const envoy_config_listener_v3_Listener *msg) { return _upb_hasbit(msg, 3); }
+UPB_INLINE const struct envoy_config_core_v3_Metadata* envoy_config_listener_v3_Listener_metadata(const envoy_config_listener_v3_Listener *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(32, 48), const struct envoy_config_core_v3_Metadata*); }
+UPB_INLINE bool envoy_config_listener_v3_Listener_has_deprecated_v1(const envoy_config_listener_v3_Listener *msg) { return _upb_hasbit(msg, 4); }
+UPB_INLINE const envoy_config_listener_v3_Listener_DeprecatedV1* envoy_config_listener_v3_Listener_deprecated_v1(const envoy_config_listener_v3_Listener *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(36, 56), const envoy_config_listener_v3_Listener_DeprecatedV1*); }
+UPB_INLINE int32_t envoy_config_listener_v3_Listener_drain_type(const envoy_config_listener_v3_Listener *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(4, 4), int32_t); }
+UPB_INLINE bool envoy_config_listener_v3_Listener_has_listener_filters(const envoy_config_listener_v3_Listener *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(80, 144)); }
+UPB_INLINE const struct envoy_config_listener_v3_ListenerFilter* const* envoy_config_listener_v3_Listener_listener_filters(const envoy_config_listener_v3_Listener *msg, size_t *len) { return (const struct envoy_config_listener_v3_ListenerFilter* const*)_upb_array_accessor(msg, UPB_SIZE(80, 144), len); }
+UPB_INLINE bool envoy_config_listener_v3_Listener_has_transparent(const envoy_config_listener_v3_Listener *msg) { return _upb_hasbit(msg, 5); }
+UPB_INLINE const struct google_protobuf_BoolValue* envoy_config_listener_v3_Listener_transparent(const envoy_config_listener_v3_Listener *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(40, 64), const struct google_protobuf_BoolValue*); }
+UPB_INLINE bool envoy_config_listener_v3_Listener_has_freebind(const envoy_config_listener_v3_Listener *msg) { return _upb_hasbit(msg, 6); }
+UPB_INLINE const struct google_protobuf_BoolValue* envoy_config_listener_v3_Listener_freebind(const envoy_config_listener_v3_Listener *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(44, 72), const struct google_protobuf_BoolValue*); }
+UPB_INLINE bool envoy_config_listener_v3_Listener_has_tcp_fast_open_queue_length(const envoy_config_listener_v3_Listener *msg) { return _upb_hasbit(msg, 7); }
+UPB_INLINE const struct google_protobuf_UInt32Value* envoy_config_listener_v3_Listener_tcp_fast_open_queue_length(const envoy_config_listener_v3_Listener *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(48, 80), const struct google_protobuf_UInt32Value*); }
+UPB_INLINE bool envoy_config_listener_v3_Listener_has_socket_options(const envoy_config_listener_v3_Listener *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(84, 152)); }
+UPB_INLINE const struct envoy_config_core_v3_SocketOption* const* envoy_config_listener_v3_Listener_socket_options(const envoy_config_listener_v3_Listener *msg, size_t *len) { return (const struct envoy_config_core_v3_SocketOption* const*)_upb_array_accessor(msg, UPB_SIZE(84, 152), len); }
+UPB_INLINE bool envoy_config_listener_v3_Listener_has_listener_filters_timeout(const envoy_config_listener_v3_Listener *msg) { return _upb_hasbit(msg, 8); }
+UPB_INLINE const struct google_protobuf_Duration* envoy_config_listener_v3_Listener_listener_filters_timeout(const envoy_config_listener_v3_Listener *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(52, 88), const struct google_protobuf_Duration*); }
 UPB_INLINE int32_t envoy_config_listener_v3_Listener_traffic_direction(const envoy_config_listener_v3_Listener *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(8, 8), int32_t); }
-UPB_INLINE bool envoy_config_listener_v3_Listener_continue_on_listener_filters_timeout(const envoy_config_listener_v3_Listener *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(16, 16), bool); }
-UPB_INLINE bool envoy_config_listener_v3_Listener_has_udp_listener_config(const envoy_config_listener_v3_Listener *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(60, 104)); }
-UPB_INLINE const struct envoy_config_listener_v3_UdpListenerConfig* envoy_config_listener_v3_Listener_udp_listener_config(const envoy_config_listener_v3_Listener *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(60, 104), const struct envoy_config_listener_v3_UdpListenerConfig*); }
-UPB_INLINE bool envoy_config_listener_v3_Listener_has_api_listener(const envoy_config_listener_v3_Listener *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(64, 112)); }
-UPB_INLINE const struct envoy_config_listener_v3_ApiListener* envoy_config_listener_v3_Listener_api_listener(const envoy_config_listener_v3_Listener *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(64, 112), const struct envoy_config_listener_v3_ApiListener*); }
-UPB_INLINE bool envoy_config_listener_v3_Listener_has_connection_balance_config(const envoy_config_listener_v3_Listener *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(68, 120)); }
-UPB_INLINE const envoy_config_listener_v3_Listener_ConnectionBalanceConfig* envoy_config_listener_v3_Listener_connection_balance_config(const envoy_config_listener_v3_Listener *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(68, 120), const envoy_config_listener_v3_Listener_ConnectionBalanceConfig*); }
-UPB_INLINE bool envoy_config_listener_v3_Listener_reuse_port(const envoy_config_listener_v3_Listener *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(17, 17), bool); }
-UPB_INLINE bool envoy_config_listener_v3_Listener_has_access_log(const envoy_config_listener_v3_Listener *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(92, 168)); }
-UPB_INLINE const struct envoy_config_accesslog_v3_AccessLog* const* envoy_config_listener_v3_Listener_access_log(const envoy_config_listener_v3_Listener *msg, size_t *len) { return (const struct envoy_config_accesslog_v3_AccessLog* const*)_upb_array_accessor(msg, UPB_SIZE(92, 168), len); }
-UPB_INLINE bool envoy_config_listener_v3_Listener_has_udp_writer_config(const envoy_config_listener_v3_Listener *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(72, 128)); }
-UPB_INLINE const struct envoy_config_core_v3_TypedExtensionConfig* envoy_config_listener_v3_Listener_udp_writer_config(const envoy_config_listener_v3_Listener *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(72, 128), const struct envoy_config_core_v3_TypedExtensionConfig*); }
-UPB_INLINE bool envoy_config_listener_v3_Listener_has_tcp_backlog_size(const envoy_config_listener_v3_Listener *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(76, 136)); }
-UPB_INLINE const struct google_protobuf_UInt32Value* envoy_config_listener_v3_Listener_tcp_backlog_size(const envoy_config_listener_v3_Listener *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(76, 136), const struct google_protobuf_UInt32Value*); }
+UPB_INLINE bool envoy_config_listener_v3_Listener_continue_on_listener_filters_timeout(const envoy_config_listener_v3_Listener *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(12, 12), bool); }
+UPB_INLINE bool envoy_config_listener_v3_Listener_has_udp_listener_config(const envoy_config_listener_v3_Listener *msg) { return _upb_hasbit(msg, 9); }
+UPB_INLINE const struct envoy_config_listener_v3_UdpListenerConfig* envoy_config_listener_v3_Listener_udp_listener_config(const envoy_config_listener_v3_Listener *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(56, 96), const struct envoy_config_listener_v3_UdpListenerConfig*); }
+UPB_INLINE bool envoy_config_listener_v3_Listener_has_api_listener(const envoy_config_listener_v3_Listener *msg) { return _upb_hasbit(msg, 10); }
+UPB_INLINE const struct envoy_config_listener_v3_ApiListener* envoy_config_listener_v3_Listener_api_listener(const envoy_config_listener_v3_Listener *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(60, 104), const struct envoy_config_listener_v3_ApiListener*); }
+UPB_INLINE bool envoy_config_listener_v3_Listener_has_connection_balance_config(const envoy_config_listener_v3_Listener *msg) { return _upb_hasbit(msg, 11); }
+UPB_INLINE const envoy_config_listener_v3_Listener_ConnectionBalanceConfig* envoy_config_listener_v3_Listener_connection_balance_config(const envoy_config_listener_v3_Listener *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(64, 112), const envoy_config_listener_v3_Listener_ConnectionBalanceConfig*); }
+UPB_INLINE bool envoy_config_listener_v3_Listener_reuse_port(const envoy_config_listener_v3_Listener *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(13, 13), bool); }
+UPB_INLINE bool envoy_config_listener_v3_Listener_has_access_log(const envoy_config_listener_v3_Listener *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(88, 160)); }
+UPB_INLINE const struct envoy_config_accesslog_v3_AccessLog* const* envoy_config_listener_v3_Listener_access_log(const envoy_config_listener_v3_Listener *msg, size_t *len) { return (const struct envoy_config_accesslog_v3_AccessLog* const*)_upb_array_accessor(msg, UPB_SIZE(88, 160), len); }
+UPB_INLINE bool envoy_config_listener_v3_Listener_has_udp_writer_config(const envoy_config_listener_v3_Listener *msg) { return _upb_hasbit(msg, 12); }
+UPB_INLINE const struct envoy_config_core_v3_TypedExtensionConfig* envoy_config_listener_v3_Listener_udp_writer_config(const envoy_config_listener_v3_Listener *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(68, 120), const struct envoy_config_core_v3_TypedExtensionConfig*); }
+UPB_INLINE bool envoy_config_listener_v3_Listener_has_tcp_backlog_size(const envoy_config_listener_v3_Listener *msg) { return _upb_hasbit(msg, 13); }
+UPB_INLINE const struct google_protobuf_UInt32Value* envoy_config_listener_v3_Listener_tcp_backlog_size(const envoy_config_listener_v3_Listener *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(72, 128), const struct google_protobuf_UInt32Value*); }
 
 UPB_INLINE void envoy_config_listener_v3_Listener_set_name(envoy_config_listener_v3_Listener *msg, upb_strview value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(20, 24), upb_strview) = value;
+  *UPB_PTR_AT(msg, UPB_SIZE(16, 16), upb_strview) = value;
 }
 UPB_INLINE void envoy_config_listener_v3_Listener_set_address(envoy_config_listener_v3_Listener *msg, struct envoy_config_core_v3_Address* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(28, 40), struct envoy_config_core_v3_Address*) = value;
+  _upb_sethas(msg, 1);
+  *UPB_PTR_AT(msg, UPB_SIZE(24, 32), struct envoy_config_core_v3_Address*) = value;
 }
 UPB_INLINE struct envoy_config_core_v3_Address* envoy_config_listener_v3_Listener_mutable_address(envoy_config_listener_v3_Listener *msg, upb_arena *arena) {
   struct envoy_config_core_v3_Address* sub = (struct envoy_config_core_v3_Address*)envoy_config_listener_v3_Listener_address(msg);
@@ -168,20 +182,21 @@ UPB_INLINE struct envoy_config_core_v3_Address* envoy_config_listener_v3_Listene
   return sub;
 }
 UPB_INLINE struct envoy_config_listener_v3_FilterChain** envoy_config_listener_v3_Listener_mutable_filter_chains(envoy_config_listener_v3_Listener *msg, size_t *len) {
-  return (struct envoy_config_listener_v3_FilterChain**)_upb_array_mutable_accessor(msg, UPB_SIZE(80, 144), len);
+  return (struct envoy_config_listener_v3_FilterChain**)_upb_array_mutable_accessor(msg, UPB_SIZE(76, 136), len);
 }
 UPB_INLINE struct envoy_config_listener_v3_FilterChain** envoy_config_listener_v3_Listener_resize_filter_chains(envoy_config_listener_v3_Listener *msg, size_t len, upb_arena *arena) {
-  return (struct envoy_config_listener_v3_FilterChain**)_upb_array_resize_accessor(msg, UPB_SIZE(80, 144), len, UPB_TYPE_MESSAGE, arena);
+  return (struct envoy_config_listener_v3_FilterChain**)_upb_array_resize_accessor2(msg, UPB_SIZE(76, 136), len, UPB_SIZE(2, 3), arena);
 }
 UPB_INLINE struct envoy_config_listener_v3_FilterChain* envoy_config_listener_v3_Listener_add_filter_chains(envoy_config_listener_v3_Listener *msg, upb_arena *arena) {
   struct envoy_config_listener_v3_FilterChain* sub = (struct envoy_config_listener_v3_FilterChain*)_upb_msg_new(&envoy_config_listener_v3_FilterChain_msginit, arena);
-  bool ok = _upb_array_append_accessor(
-      msg, UPB_SIZE(80, 144), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena);
+  bool ok = _upb_array_append_accessor2(
+      msg, UPB_SIZE(76, 136), UPB_SIZE(2, 3), &sub, arena);
   if (!ok) return NULL;
   return sub;
 }
 UPB_INLINE void envoy_config_listener_v3_Listener_set_per_connection_buffer_limit_bytes(envoy_config_listener_v3_Listener *msg, struct google_protobuf_UInt32Value* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(32, 48), struct google_protobuf_UInt32Value*) = value;
+  _upb_sethas(msg, 2);
+  *UPB_PTR_AT(msg, UPB_SIZE(28, 40), struct google_protobuf_UInt32Value*) = value;
 }
 UPB_INLINE struct google_protobuf_UInt32Value* envoy_config_listener_v3_Listener_mutable_per_connection_buffer_limit_bytes(envoy_config_listener_v3_Listener *msg, upb_arena *arena) {
   struct google_protobuf_UInt32Value* sub = (struct google_protobuf_UInt32Value*)envoy_config_listener_v3_Listener_per_connection_buffer_limit_bytes(msg);
@@ -193,7 +208,8 @@ UPB_INLINE struct google_protobuf_UInt32Value* envoy_config_listener_v3_Listener
   return sub;
 }
 UPB_INLINE void envoy_config_listener_v3_Listener_set_metadata(envoy_config_listener_v3_Listener *msg, struct envoy_config_core_v3_Metadata* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(36, 56), struct envoy_config_core_v3_Metadata*) = value;
+  _upb_sethas(msg, 3);
+  *UPB_PTR_AT(msg, UPB_SIZE(32, 48), struct envoy_config_core_v3_Metadata*) = value;
 }
 UPB_INLINE struct envoy_config_core_v3_Metadata* envoy_config_listener_v3_Listener_mutable_metadata(envoy_config_listener_v3_Listener *msg, upb_arena *arena) {
   struct envoy_config_core_v3_Metadata* sub = (struct envoy_config_core_v3_Metadata*)envoy_config_listener_v3_Listener_metadata(msg);
@@ -205,7 +221,8 @@ UPB_INLINE struct envoy_config_core_v3_Metadata* envoy_config_listener_v3_Listen
   return sub;
 }
 UPB_INLINE void envoy_config_listener_v3_Listener_set_deprecated_v1(envoy_config_listener_v3_Listener *msg, envoy_config_listener_v3_Listener_DeprecatedV1* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(40, 64), envoy_config_listener_v3_Listener_DeprecatedV1*) = value;
+  _upb_sethas(msg, 4);
+  *UPB_PTR_AT(msg, UPB_SIZE(36, 56), envoy_config_listener_v3_Listener_DeprecatedV1*) = value;
 }
 UPB_INLINE struct envoy_config_listener_v3_Listener_DeprecatedV1* envoy_config_listener_v3_Listener_mutable_deprecated_v1(envoy_config_listener_v3_Listener *msg, upb_arena *arena) {
   struct envoy_config_listener_v3_Listener_DeprecatedV1* sub = (struct envoy_config_listener_v3_Listener_DeprecatedV1*)envoy_config_listener_v3_Listener_deprecated_v1(msg);
@@ -217,23 +234,24 @@ UPB_INLINE struct envoy_config_listener_v3_Listener_DeprecatedV1* envoy_config_l
   return sub;
 }
 UPB_INLINE void envoy_config_listener_v3_Listener_set_drain_type(envoy_config_listener_v3_Listener *msg, int32_t value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(0, 0), int32_t) = value;
+  *UPB_PTR_AT(msg, UPB_SIZE(4, 4), int32_t) = value;
 }
 UPB_INLINE struct envoy_config_listener_v3_ListenerFilter** envoy_config_listener_v3_Listener_mutable_listener_filters(envoy_config_listener_v3_Listener *msg, size_t *len) {
-  return (struct envoy_config_listener_v3_ListenerFilter**)_upb_array_mutable_accessor(msg, UPB_SIZE(84, 152), len);
+  return (struct envoy_config_listener_v3_ListenerFilter**)_upb_array_mutable_accessor(msg, UPB_SIZE(80, 144), len);
 }
 UPB_INLINE struct envoy_config_listener_v3_ListenerFilter** envoy_config_listener_v3_Listener_resize_listener_filters(envoy_config_listener_v3_Listener *msg, size_t len, upb_arena *arena) {
-  return (struct envoy_config_listener_v3_ListenerFilter**)_upb_array_resize_accessor(msg, UPB_SIZE(84, 152), len, UPB_TYPE_MESSAGE, arena);
+  return (struct envoy_config_listener_v3_ListenerFilter**)_upb_array_resize_accessor2(msg, UPB_SIZE(80, 144), len, UPB_SIZE(2, 3), arena);
 }
 UPB_INLINE struct envoy_config_listener_v3_ListenerFilter* envoy_config_listener_v3_Listener_add_listener_filters(envoy_config_listener_v3_Listener *msg, upb_arena *arena) {
   struct envoy_config_listener_v3_ListenerFilter* sub = (struct envoy_config_listener_v3_ListenerFilter*)_upb_msg_new(&envoy_config_listener_v3_ListenerFilter_msginit, arena);
-  bool ok = _upb_array_append_accessor(
-      msg, UPB_SIZE(84, 152), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena);
+  bool ok = _upb_array_append_accessor2(
+      msg, UPB_SIZE(80, 144), UPB_SIZE(2, 3), &sub, arena);
   if (!ok) return NULL;
   return sub;
 }
 UPB_INLINE void envoy_config_listener_v3_Listener_set_transparent(envoy_config_listener_v3_Listener *msg, struct google_protobuf_BoolValue* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(44, 72), struct google_protobuf_BoolValue*) = value;
+  _upb_sethas(msg, 5);
+  *UPB_PTR_AT(msg, UPB_SIZE(40, 64), struct google_protobuf_BoolValue*) = value;
 }
 UPB_INLINE struct google_protobuf_BoolValue* envoy_config_listener_v3_Listener_mutable_transparent(envoy_config_listener_v3_Listener *msg, upb_arena *arena) {
   struct google_protobuf_BoolValue* sub = (struct google_protobuf_BoolValue*)envoy_config_listener_v3_Listener_transparent(msg);
@@ -245,7 +263,8 @@ UPB_INLINE struct google_protobuf_BoolValue* envoy_config_listener_v3_Listener_m
   return sub;
 }
 UPB_INLINE void envoy_config_listener_v3_Listener_set_freebind(envoy_config_listener_v3_Listener *msg, struct google_protobuf_BoolValue* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(48, 80), struct google_protobuf_BoolValue*) = value;
+  _upb_sethas(msg, 6);
+  *UPB_PTR_AT(msg, UPB_SIZE(44, 72), struct google_protobuf_BoolValue*) = value;
 }
 UPB_INLINE struct google_protobuf_BoolValue* envoy_config_listener_v3_Listener_mutable_freebind(envoy_config_listener_v3_Listener *msg, upb_arena *arena) {
   struct google_protobuf_BoolValue* sub = (struct google_protobuf_BoolValue*)envoy_config_listener_v3_Listener_freebind(msg);
@@ -257,7 +276,8 @@ UPB_INLINE struct google_protobuf_BoolValue* envoy_config_listener_v3_Listener_m
   return sub;
 }
 UPB_INLINE void envoy_config_listener_v3_Listener_set_tcp_fast_open_queue_length(envoy_config_listener_v3_Listener *msg, struct google_protobuf_UInt32Value* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(52, 88), struct google_protobuf_UInt32Value*) = value;
+  _upb_sethas(msg, 7);
+  *UPB_PTR_AT(msg, UPB_SIZE(48, 80), struct google_protobuf_UInt32Value*) = value;
 }
 UPB_INLINE struct google_protobuf_UInt32Value* envoy_config_listener_v3_Listener_mutable_tcp_fast_open_queue_length(envoy_config_listener_v3_Listener *msg, upb_arena *arena) {
   struct google_protobuf_UInt32Value* sub = (struct google_protobuf_UInt32Value*)envoy_config_listener_v3_Listener_tcp_fast_open_queue_length(msg);
@@ -269,20 +289,21 @@ UPB_INLINE struct google_protobuf_UInt32Value* envoy_config_listener_v3_Listener
   return sub;
 }
 UPB_INLINE struct envoy_config_core_v3_SocketOption** envoy_config_listener_v3_Listener_mutable_socket_options(envoy_config_listener_v3_Listener *msg, size_t *len) {
-  return (struct envoy_config_core_v3_SocketOption**)_upb_array_mutable_accessor(msg, UPB_SIZE(88, 160), len);
+  return (struct envoy_config_core_v3_SocketOption**)_upb_array_mutable_accessor(msg, UPB_SIZE(84, 152), len);
 }
 UPB_INLINE struct envoy_config_core_v3_SocketOption** envoy_config_listener_v3_Listener_resize_socket_options(envoy_config_listener_v3_Listener *msg, size_t len, upb_arena *arena) {
-  return (struct envoy_config_core_v3_SocketOption**)_upb_array_resize_accessor(msg, UPB_SIZE(88, 160), len, UPB_TYPE_MESSAGE, arena);
+  return (struct envoy_config_core_v3_SocketOption**)_upb_array_resize_accessor2(msg, UPB_SIZE(84, 152), len, UPB_SIZE(2, 3), arena);
 }
 UPB_INLINE struct envoy_config_core_v3_SocketOption* envoy_config_listener_v3_Listener_add_socket_options(envoy_config_listener_v3_Listener *msg, upb_arena *arena) {
   struct envoy_config_core_v3_SocketOption* sub = (struct envoy_config_core_v3_SocketOption*)_upb_msg_new(&envoy_config_core_v3_SocketOption_msginit, arena);
-  bool ok = _upb_array_append_accessor(
-      msg, UPB_SIZE(88, 160), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena);
+  bool ok = _upb_array_append_accessor2(
+      msg, UPB_SIZE(84, 152), UPB_SIZE(2, 3), &sub, arena);
   if (!ok) return NULL;
   return sub;
 }
 UPB_INLINE void envoy_config_listener_v3_Listener_set_listener_filters_timeout(envoy_config_listener_v3_Listener *msg, struct google_protobuf_Duration* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(56, 96), struct google_protobuf_Duration*) = value;
+  _upb_sethas(msg, 8);
+  *UPB_PTR_AT(msg, UPB_SIZE(52, 88), struct google_protobuf_Duration*) = value;
 }
 UPB_INLINE struct google_protobuf_Duration* envoy_config_listener_v3_Listener_mutable_listener_filters_timeout(envoy_config_listener_v3_Listener *msg, upb_arena *arena) {
   struct google_protobuf_Duration* sub = (struct google_protobuf_Duration*)envoy_config_listener_v3_Listener_listener_filters_timeout(msg);
@@ -297,10 +318,11 @@ UPB_INLINE void envoy_config_listener_v3_Listener_set_traffic_direction(envoy_co
   *UPB_PTR_AT(msg, UPB_SIZE(8, 8), int32_t) = value;
 }
 UPB_INLINE void envoy_config_listener_v3_Listener_set_continue_on_listener_filters_timeout(envoy_config_listener_v3_Listener *msg, bool value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(16, 16), bool) = value;
+  *UPB_PTR_AT(msg, UPB_SIZE(12, 12), bool) = value;
 }
 UPB_INLINE void envoy_config_listener_v3_Listener_set_udp_listener_config(envoy_config_listener_v3_Listener *msg, struct envoy_config_listener_v3_UdpListenerConfig* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(60, 104), struct envoy_config_listener_v3_UdpListenerConfig*) = value;
+  _upb_sethas(msg, 9);
+  *UPB_PTR_AT(msg, UPB_SIZE(56, 96), struct envoy_config_listener_v3_UdpListenerConfig*) = value;
 }
 UPB_INLINE struct envoy_config_listener_v3_UdpListenerConfig* envoy_config_listener_v3_Listener_mutable_udp_listener_config(envoy_config_listener_v3_Listener *msg, upb_arena *arena) {
   struct envoy_config_listener_v3_UdpListenerConfig* sub = (struct envoy_config_listener_v3_UdpListenerConfig*)envoy_config_listener_v3_Listener_udp_listener_config(msg);
@@ -312,7 +334,8 @@ UPB_INLINE struct envoy_config_listener_v3_UdpListenerConfig* envoy_config_liste
   return sub;
 }
 UPB_INLINE void envoy_config_listener_v3_Listener_set_api_listener(envoy_config_listener_v3_Listener *msg, struct envoy_config_listener_v3_ApiListener* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(64, 112), struct envoy_config_listener_v3_ApiListener*) = value;
+  _upb_sethas(msg, 10);
+  *UPB_PTR_AT(msg, UPB_SIZE(60, 104), struct envoy_config_listener_v3_ApiListener*) = value;
 }
 UPB_INLINE struct envoy_config_listener_v3_ApiListener* envoy_config_listener_v3_Listener_mutable_api_listener(envoy_config_listener_v3_Listener *msg, upb_arena *arena) {
   struct envoy_config_listener_v3_ApiListener* sub = (struct envoy_config_listener_v3_ApiListener*)envoy_config_listener_v3_Listener_api_listener(msg);
@@ -324,7 +347,8 @@ UPB_INLINE struct envoy_config_listener_v3_ApiListener* envoy_config_listener_v3
   return sub;
 }
 UPB_INLINE void envoy_config_listener_v3_Listener_set_connection_balance_config(envoy_config_listener_v3_Listener *msg, envoy_config_listener_v3_Listener_ConnectionBalanceConfig* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(68, 120), envoy_config_listener_v3_Listener_ConnectionBalanceConfig*) = value;
+  _upb_sethas(msg, 11);
+  *UPB_PTR_AT(msg, UPB_SIZE(64, 112), envoy_config_listener_v3_Listener_ConnectionBalanceConfig*) = value;
 }
 UPB_INLINE struct envoy_config_listener_v3_Listener_ConnectionBalanceConfig* envoy_config_listener_v3_Listener_mutable_connection_balance_config(envoy_config_listener_v3_Listener *msg, upb_arena *arena) {
   struct envoy_config_listener_v3_Listener_ConnectionBalanceConfig* sub = (struct envoy_config_listener_v3_Listener_ConnectionBalanceConfig*)envoy_config_listener_v3_Listener_connection_balance_config(msg);
@@ -336,23 +360,24 @@ UPB_INLINE struct envoy_config_listener_v3_Listener_ConnectionBalanceConfig* env
   return sub;
 }
 UPB_INLINE void envoy_config_listener_v3_Listener_set_reuse_port(envoy_config_listener_v3_Listener *msg, bool value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(17, 17), bool) = value;
+  *UPB_PTR_AT(msg, UPB_SIZE(13, 13), bool) = value;
 }
 UPB_INLINE struct envoy_config_accesslog_v3_AccessLog** envoy_config_listener_v3_Listener_mutable_access_log(envoy_config_listener_v3_Listener *msg, size_t *len) {
-  return (struct envoy_config_accesslog_v3_AccessLog**)_upb_array_mutable_accessor(msg, UPB_SIZE(92, 168), len);
+  return (struct envoy_config_accesslog_v3_AccessLog**)_upb_array_mutable_accessor(msg, UPB_SIZE(88, 160), len);
 }
 UPB_INLINE struct envoy_config_accesslog_v3_AccessLog** envoy_config_listener_v3_Listener_resize_access_log(envoy_config_listener_v3_Listener *msg, size_t len, upb_arena *arena) {
-  return (struct envoy_config_accesslog_v3_AccessLog**)_upb_array_resize_accessor(msg, UPB_SIZE(92, 168), len, UPB_TYPE_MESSAGE, arena);
+  return (struct envoy_config_accesslog_v3_AccessLog**)_upb_array_resize_accessor2(msg, UPB_SIZE(88, 160), len, UPB_SIZE(2, 3), arena);
 }
 UPB_INLINE struct envoy_config_accesslog_v3_AccessLog* envoy_config_listener_v3_Listener_add_access_log(envoy_config_listener_v3_Listener *msg, upb_arena *arena) {
   struct envoy_config_accesslog_v3_AccessLog* sub = (struct envoy_config_accesslog_v3_AccessLog*)_upb_msg_new(&envoy_config_accesslog_v3_AccessLog_msginit, arena);
-  bool ok = _upb_array_append_accessor(
-      msg, UPB_SIZE(92, 168), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena);
+  bool ok = _upb_array_append_accessor2(
+      msg, UPB_SIZE(88, 160), UPB_SIZE(2, 3), &sub, arena);
   if (!ok) return NULL;
   return sub;
 }
 UPB_INLINE void envoy_config_listener_v3_Listener_set_udp_writer_config(envoy_config_listener_v3_Listener *msg, struct envoy_config_core_v3_TypedExtensionConfig* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(72, 128), struct envoy_config_core_v3_TypedExtensionConfig*) = value;
+  _upb_sethas(msg, 12);
+  *UPB_PTR_AT(msg, UPB_SIZE(68, 120), struct envoy_config_core_v3_TypedExtensionConfig*) = value;
 }
 UPB_INLINE struct envoy_config_core_v3_TypedExtensionConfig* envoy_config_listener_v3_Listener_mutable_udp_writer_config(envoy_config_listener_v3_Listener *msg, upb_arena *arena) {
   struct envoy_config_core_v3_TypedExtensionConfig* sub = (struct envoy_config_core_v3_TypedExtensionConfig*)envoy_config_listener_v3_Listener_udp_writer_config(msg);
@@ -364,7 +389,8 @@ UPB_INLINE struct envoy_config_core_v3_TypedExtensionConfig* envoy_config_listen
   return sub;
 }
 UPB_INLINE void envoy_config_listener_v3_Listener_set_tcp_backlog_size(envoy_config_listener_v3_Listener *msg, struct google_protobuf_UInt32Value* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(76, 136), struct google_protobuf_UInt32Value*) = value;
+  _upb_sethas(msg, 13);
+  *UPB_PTR_AT(msg, UPB_SIZE(72, 128), struct google_protobuf_UInt32Value*) = value;
 }
 UPB_INLINE struct google_protobuf_UInt32Value* envoy_config_listener_v3_Listener_mutable_tcp_backlog_size(envoy_config_listener_v3_Listener *msg, upb_arena *arena) {
   struct google_protobuf_UInt32Value* sub = (struct google_protobuf_UInt32Value*)envoy_config_listener_v3_Listener_tcp_backlog_size(msg);
@@ -386,15 +412,22 @@ UPB_INLINE envoy_config_listener_v3_Listener_DeprecatedV1 *envoy_config_listener
   envoy_config_listener_v3_Listener_DeprecatedV1 *ret = envoy_config_listener_v3_Listener_DeprecatedV1_new(arena);
   return (ret && upb_decode(buf, size, ret, &envoy_config_listener_v3_Listener_DeprecatedV1_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE envoy_config_listener_v3_Listener_DeprecatedV1 *envoy_config_listener_v3_Listener_DeprecatedV1_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  envoy_config_listener_v3_Listener_DeprecatedV1 *ret = envoy_config_listener_v3_Listener_DeprecatedV1_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &envoy_config_listener_v3_Listener_DeprecatedV1_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *envoy_config_listener_v3_Listener_DeprecatedV1_serialize(const envoy_config_listener_v3_Listener_DeprecatedV1 *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &envoy_config_listener_v3_Listener_DeprecatedV1_msginit, arena, len);
 }
 
-UPB_INLINE bool envoy_config_listener_v3_Listener_DeprecatedV1_has_bind_to_port(const envoy_config_listener_v3_Listener_DeprecatedV1 *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(0, 0)); }
-UPB_INLINE const struct google_protobuf_BoolValue* envoy_config_listener_v3_Listener_DeprecatedV1_bind_to_port(const envoy_config_listener_v3_Listener_DeprecatedV1 *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(0, 0), const struct google_protobuf_BoolValue*); }
+UPB_INLINE bool envoy_config_listener_v3_Listener_DeprecatedV1_has_bind_to_port(const envoy_config_listener_v3_Listener_DeprecatedV1 *msg) { return _upb_hasbit(msg, 1); }
+UPB_INLINE const struct google_protobuf_BoolValue* envoy_config_listener_v3_Listener_DeprecatedV1_bind_to_port(const envoy_config_listener_v3_Listener_DeprecatedV1 *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(4, 8), const struct google_protobuf_BoolValue*); }
 
 UPB_INLINE void envoy_config_listener_v3_Listener_DeprecatedV1_set_bind_to_port(envoy_config_listener_v3_Listener_DeprecatedV1 *msg, struct google_protobuf_BoolValue* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(0, 0), struct google_protobuf_BoolValue*) = value;
+  _upb_sethas(msg, 1);
+  *UPB_PTR_AT(msg, UPB_SIZE(4, 8), struct google_protobuf_BoolValue*) = value;
 }
 UPB_INLINE struct google_protobuf_BoolValue* envoy_config_listener_v3_Listener_DeprecatedV1_mutable_bind_to_port(envoy_config_listener_v3_Listener_DeprecatedV1 *msg, upb_arena *arena) {
   struct google_protobuf_BoolValue* sub = (struct google_protobuf_BoolValue*)envoy_config_listener_v3_Listener_DeprecatedV1_bind_to_port(msg);
@@ -416,6 +449,12 @@ UPB_INLINE envoy_config_listener_v3_Listener_ConnectionBalanceConfig *envoy_conf
   envoy_config_listener_v3_Listener_ConnectionBalanceConfig *ret = envoy_config_listener_v3_Listener_ConnectionBalanceConfig_new(arena);
   return (ret && upb_decode(buf, size, ret, &envoy_config_listener_v3_Listener_ConnectionBalanceConfig_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE envoy_config_listener_v3_Listener_ConnectionBalanceConfig *envoy_config_listener_v3_Listener_ConnectionBalanceConfig_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  envoy_config_listener_v3_Listener_ConnectionBalanceConfig *ret = envoy_config_listener_v3_Listener_ConnectionBalanceConfig_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &envoy_config_listener_v3_Listener_ConnectionBalanceConfig_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *envoy_config_listener_v3_Listener_ConnectionBalanceConfig_serialize(const envoy_config_listener_v3_Listener_ConnectionBalanceConfig *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &envoy_config_listener_v3_Listener_ConnectionBalanceConfig_msginit, arena, len);
 }
@@ -452,6 +491,12 @@ UPB_INLINE envoy_config_listener_v3_Listener_ConnectionBalanceConfig_ExactBalanc
   envoy_config_listener_v3_Listener_ConnectionBalanceConfig_ExactBalance *ret = envoy_config_listener_v3_Listener_ConnectionBalanceConfig_ExactBalance_new(arena);
   return (ret && upb_decode(buf, size, ret, &envoy_config_listener_v3_Listener_ConnectionBalanceConfig_ExactBalance_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE envoy_config_listener_v3_Listener_ConnectionBalanceConfig_ExactBalance *envoy_config_listener_v3_Listener_ConnectionBalanceConfig_ExactBalance_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  envoy_config_listener_v3_Listener_ConnectionBalanceConfig_ExactBalance *ret = envoy_config_listener_v3_Listener_ConnectionBalanceConfig_ExactBalance_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &envoy_config_listener_v3_Listener_ConnectionBalanceConfig_ExactBalance_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *envoy_config_listener_v3_Listener_ConnectionBalanceConfig_ExactBalance_serialize(const envoy_config_listener_v3_Listener_ConnectionBalanceConfig_ExactBalance *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &envoy_config_listener_v3_Listener_ConnectionBalanceConfig_ExactBalance_msginit, arena, len);
 }
index c303dab..a3cc15e 100644 (file)
@@ -34,10 +34,10 @@ static const upb_msglayout_field envoy_config_listener_v3_Filter__fields[2] = {
 const upb_msglayout envoy_config_listener_v3_Filter_msginit = {
   &envoy_config_listener_v3_Filter_submsgs[0],
   &envoy_config_listener_v3_Filter__fields[0],
-  UPB_SIZE(16, 32), 2, false,
+  UPB_SIZE(16, 32), 2, false, 255,
 };
 
-static const upb_msglayout *const envoy_config_listener_v3_FilterChainMatch_submsgs[4] = {
+static const upb_msglayout *const envoy_config_listener_v3_FilterChainMatch_submsgs[2] = {
   &envoy_config_core_v3_CidrRange_msginit,
   &google_protobuf_UInt32Value_msginit,
 };
@@ -45,20 +45,20 @@ static const upb_msglayout *const envoy_config_listener_v3_FilterChainMatch_subm
 static const upb_msglayout_field envoy_config_listener_v3_FilterChainMatch__fields[10] = {
   {3, UPB_SIZE(32, 56), 0, 0, 11, 3},
   {4, UPB_SIZE(8, 8), 0, 0, 9, 1},
-  {5, UPB_SIZE(24, 40), 0, 1, 11, 1},
+  {5, UPB_SIZE(24, 40), 1, 1, 11, 1},
   {6, UPB_SIZE(36, 64), 0, 0, 11, 3},
   {7, UPB_SIZE(40, 72), 0, 0, 13, _UPB_LABEL_PACKED},
-  {8, UPB_SIZE(28, 48), 0, 1, 11, 1},
+  {8, UPB_SIZE(28, 48), 2, 1, 11, 1},
   {9, UPB_SIZE(16, 24), 0, 0, 9, 1},
   {10, UPB_SIZE(44, 80), 0, 0, 9, 3},
   {11, UPB_SIZE(48, 88), 0, 0, 9, 3},
-  {12, UPB_SIZE(0, 0), 0, 0, 14, 1},
+  {12, UPB_SIZE(4, 4), 0, 0, 14, 1},
 };
 
 const upb_msglayout envoy_config_listener_v3_FilterChainMatch_msginit = {
   &envoy_config_listener_v3_FilterChainMatch_submsgs[0],
   &envoy_config_listener_v3_FilterChainMatch__fields[0],
-  UPB_SIZE(56, 96), 10, false,
+  UPB_SIZE(56, 96), 10, false, 255,
 };
 
 static const upb_msglayout *const envoy_config_listener_v3_FilterChain_submsgs[6] = {
@@ -71,19 +71,19 @@ static const upb_msglayout *const envoy_config_listener_v3_FilterChain_submsgs[6
 };
 
 static const upb_msglayout_field envoy_config_listener_v3_FilterChain__fields[7] = {
-  {1, UPB_SIZE(8, 16), 0, 4, 11, 1},
-  {3, UPB_SIZE(28, 56), 0, 2, 11, 3},
-  {4, UPB_SIZE(12, 24), 0, 5, 11, 1},
-  {5, UPB_SIZE(16, 32), 0, 0, 11, 1},
-  {6, UPB_SIZE(20, 40), 0, 1, 11, 1},
-  {7, UPB_SIZE(0, 0), 0, 0, 9, 1},
-  {8, UPB_SIZE(24, 48), 0, 3, 11, 1},
+  {1, UPB_SIZE(12, 24), 1, 4, 11, 1},
+  {3, UPB_SIZE(32, 64), 0, 2, 11, 3},
+  {4, UPB_SIZE(16, 32), 2, 5, 11, 1},
+  {5, UPB_SIZE(20, 40), 3, 0, 11, 1},
+  {6, UPB_SIZE(24, 48), 4, 1, 11, 1},
+  {7, UPB_SIZE(4, 8), 0, 0, 9, 1},
+  {8, UPB_SIZE(28, 56), 5, 3, 11, 1},
 };
 
 const upb_msglayout envoy_config_listener_v3_FilterChain_msginit = {
   &envoy_config_listener_v3_FilterChain_submsgs[0],
   &envoy_config_listener_v3_FilterChain__fields[0],
-  UPB_SIZE(32, 64), 7, false,
+  UPB_SIZE(40, 80), 7, false, 255,
 };
 
 static const upb_msglayout *const envoy_config_listener_v3_FilterChain_OnDemandConfiguration_submsgs[1] = {
@@ -91,16 +91,16 @@ static const upb_msglayout *const envoy_config_listener_v3_FilterChain_OnDemandC
 };
 
 static const upb_msglayout_field envoy_config_listener_v3_FilterChain_OnDemandConfiguration__fields[1] = {
-  {1, UPB_SIZE(0, 0), 0, 0, 11, 1},
+  {1, UPB_SIZE(4, 8), 1, 0, 11, 1},
 };
 
 const upb_msglayout envoy_config_listener_v3_FilterChain_OnDemandConfiguration_msginit = {
   &envoy_config_listener_v3_FilterChain_OnDemandConfiguration_submsgs[0],
   &envoy_config_listener_v3_FilterChain_OnDemandConfiguration__fields[0],
-  UPB_SIZE(4, 8), 1, false,
+  UPB_SIZE(8, 16), 1, false, 255,
 };
 
-static const upb_msglayout *const envoy_config_listener_v3_ListenerFilterChainMatchPredicate_submsgs[4] = {
+static const upb_msglayout *const envoy_config_listener_v3_ListenerFilterChainMatchPredicate_submsgs[3] = {
   &envoy_config_listener_v3_ListenerFilterChainMatchPredicate_msginit,
   &envoy_config_listener_v3_ListenerFilterChainMatchPredicate_MatchSet_msginit,
   &envoy_type_v3_Int32Range_msginit,
@@ -117,7 +117,7 @@ static const upb_msglayout_field envoy_config_listener_v3_ListenerFilterChainMat
 const upb_msglayout envoy_config_listener_v3_ListenerFilterChainMatchPredicate_msginit = {
   &envoy_config_listener_v3_ListenerFilterChainMatchPredicate_submsgs[0],
   &envoy_config_listener_v3_ListenerFilterChainMatchPredicate__fields[0],
-  UPB_SIZE(8, 16), 5, false,
+  UPB_SIZE(8, 16), 5, false, 255,
 };
 
 static const upb_msglayout *const envoy_config_listener_v3_ListenerFilterChainMatchPredicate_MatchSet_submsgs[1] = {
@@ -131,7 +131,7 @@ static const upb_msglayout_field envoy_config_listener_v3_ListenerFilterChainMat
 const upb_msglayout envoy_config_listener_v3_ListenerFilterChainMatchPredicate_MatchSet_msginit = {
   &envoy_config_listener_v3_ListenerFilterChainMatchPredicate_MatchSet_submsgs[0],
   &envoy_config_listener_v3_ListenerFilterChainMatchPredicate_MatchSet__fields[0],
-  UPB_SIZE(4, 8), 1, false,
+  UPB_SIZE(8, 8), 1, false, 255,
 };
 
 static const upb_msglayout *const envoy_config_listener_v3_ListenerFilter_submsgs[2] = {
@@ -140,15 +140,15 @@ static const upb_msglayout *const envoy_config_listener_v3_ListenerFilter_submsg
 };
 
 static const upb_msglayout_field envoy_config_listener_v3_ListenerFilter__fields[3] = {
-  {1, UPB_SIZE(0, 0), 0, 0, 9, 1},
-  {3, UPB_SIZE(12, 24), UPB_SIZE(-17, -33), 1, 11, 1},
-  {4, UPB_SIZE(8, 16), 0, 0, 11, 1},
+  {1, UPB_SIZE(4, 8), 0, 0, 9, 1},
+  {3, UPB_SIZE(16, 32), UPB_SIZE(-21, -41), 1, 11, 1},
+  {4, UPB_SIZE(12, 24), 1, 0, 11, 1},
 };
 
 const upb_msglayout envoy_config_listener_v3_ListenerFilter_msginit = {
   &envoy_config_listener_v3_ListenerFilter_submsgs[0],
   &envoy_config_listener_v3_ListenerFilter__fields[0],
-  UPB_SIZE(24, 48), 3, false,
+  UPB_SIZE(24, 48), 3, false, 255,
 };
 
 #include "upb/port_undef.inc"
index 626f53c..6c2a503 100644 (file)
@@ -11,6 +11,7 @@
 
 #include "upb/msg.h"
 #include "upb/decode.h"
+#include "upb/decode_fast.h"
 #include "upb/encode.h"
 
 #include "upb/port_def.inc"
@@ -74,6 +75,12 @@ UPB_INLINE envoy_config_listener_v3_Filter *envoy_config_listener_v3_Filter_pars
   envoy_config_listener_v3_Filter *ret = envoy_config_listener_v3_Filter_new(arena);
   return (ret && upb_decode(buf, size, ret, &envoy_config_listener_v3_Filter_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE envoy_config_listener_v3_Filter *envoy_config_listener_v3_Filter_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  envoy_config_listener_v3_Filter *ret = envoy_config_listener_v3_Filter_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &envoy_config_listener_v3_Filter_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *envoy_config_listener_v3_Filter_serialize(const envoy_config_listener_v3_Filter *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &envoy_config_listener_v3_Filter_msginit, arena, len);
 }
@@ -114,6 +121,12 @@ UPB_INLINE envoy_config_listener_v3_FilterChainMatch *envoy_config_listener_v3_F
   envoy_config_listener_v3_FilterChainMatch *ret = envoy_config_listener_v3_FilterChainMatch_new(arena);
   return (ret && upb_decode(buf, size, ret, &envoy_config_listener_v3_FilterChainMatch_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE envoy_config_listener_v3_FilterChainMatch *envoy_config_listener_v3_FilterChainMatch_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  envoy_config_listener_v3_FilterChainMatch *ret = envoy_config_listener_v3_FilterChainMatch_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &envoy_config_listener_v3_FilterChainMatch_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *envoy_config_listener_v3_FilterChainMatch_serialize(const envoy_config_listener_v3_FilterChainMatch *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &envoy_config_listener_v3_FilterChainMatch_msginit, arena, len);
 }
@@ -121,28 +134,28 @@ UPB_INLINE char *envoy_config_listener_v3_FilterChainMatch_serialize(const envoy
 UPB_INLINE bool envoy_config_listener_v3_FilterChainMatch_has_prefix_ranges(const envoy_config_listener_v3_FilterChainMatch *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(32, 56)); }
 UPB_INLINE const struct envoy_config_core_v3_CidrRange* const* envoy_config_listener_v3_FilterChainMatch_prefix_ranges(const envoy_config_listener_v3_FilterChainMatch *msg, size_t *len) { return (const struct envoy_config_core_v3_CidrRange* const*)_upb_array_accessor(msg, UPB_SIZE(32, 56), len); }
 UPB_INLINE upb_strview envoy_config_listener_v3_FilterChainMatch_address_suffix(const envoy_config_listener_v3_FilterChainMatch *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(8, 8), upb_strview); }
-UPB_INLINE bool envoy_config_listener_v3_FilterChainMatch_has_suffix_len(const envoy_config_listener_v3_FilterChainMatch *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(24, 40)); }
+UPB_INLINE bool envoy_config_listener_v3_FilterChainMatch_has_suffix_len(const envoy_config_listener_v3_FilterChainMatch *msg) { return _upb_hasbit(msg, 1); }
 UPB_INLINE const struct google_protobuf_UInt32Value* envoy_config_listener_v3_FilterChainMatch_suffix_len(const envoy_config_listener_v3_FilterChainMatch *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(24, 40), const struct google_protobuf_UInt32Value*); }
 UPB_INLINE bool envoy_config_listener_v3_FilterChainMatch_has_source_prefix_ranges(const envoy_config_listener_v3_FilterChainMatch *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(36, 64)); }
 UPB_INLINE const struct envoy_config_core_v3_CidrRange* const* envoy_config_listener_v3_FilterChainMatch_source_prefix_ranges(const envoy_config_listener_v3_FilterChainMatch *msg, size_t *len) { return (const struct envoy_config_core_v3_CidrRange* const*)_upb_array_accessor(msg, UPB_SIZE(36, 64), len); }
 UPB_INLINE uint32_t const* envoy_config_listener_v3_FilterChainMatch_source_ports(const envoy_config_listener_v3_FilterChainMatch *msg, size_t *len) { return (uint32_t const*)_upb_array_accessor(msg, UPB_SIZE(40, 72), len); }
-UPB_INLINE bool envoy_config_listener_v3_FilterChainMatch_has_destination_port(const envoy_config_listener_v3_FilterChainMatch *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(28, 48)); }
+UPB_INLINE bool envoy_config_listener_v3_FilterChainMatch_has_destination_port(const envoy_config_listener_v3_FilterChainMatch *msg) { return _upb_hasbit(msg, 2); }
 UPB_INLINE const struct google_protobuf_UInt32Value* envoy_config_listener_v3_FilterChainMatch_destination_port(const envoy_config_listener_v3_FilterChainMatch *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(28, 48), const struct google_protobuf_UInt32Value*); }
 UPB_INLINE upb_strview envoy_config_listener_v3_FilterChainMatch_transport_protocol(const envoy_config_listener_v3_FilterChainMatch *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(16, 24), upb_strview); }
 UPB_INLINE upb_strview const* envoy_config_listener_v3_FilterChainMatch_application_protocols(const envoy_config_listener_v3_FilterChainMatch *msg, size_t *len) { return (upb_strview const*)_upb_array_accessor(msg, UPB_SIZE(44, 80), len); }
 UPB_INLINE upb_strview const* envoy_config_listener_v3_FilterChainMatch_server_names(const envoy_config_listener_v3_FilterChainMatch *msg, size_t *len) { return (upb_strview const*)_upb_array_accessor(msg, UPB_SIZE(48, 88), len); }
-UPB_INLINE int32_t envoy_config_listener_v3_FilterChainMatch_source_type(const envoy_config_listener_v3_FilterChainMatch *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(0, 0), int32_t); }
+UPB_INLINE int32_t envoy_config_listener_v3_FilterChainMatch_source_type(const envoy_config_listener_v3_FilterChainMatch *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(4, 4), int32_t); }
 
 UPB_INLINE struct envoy_config_core_v3_CidrRange** envoy_config_listener_v3_FilterChainMatch_mutable_prefix_ranges(envoy_config_listener_v3_FilterChainMatch *msg, size_t *len) {
   return (struct envoy_config_core_v3_CidrRange**)_upb_array_mutable_accessor(msg, UPB_SIZE(32, 56), len);
 }
 UPB_INLINE struct envoy_config_core_v3_CidrRange** envoy_config_listener_v3_FilterChainMatch_resize_prefix_ranges(envoy_config_listener_v3_FilterChainMatch *msg, size_t len, upb_arena *arena) {
-  return (struct envoy_config_core_v3_CidrRange**)_upb_array_resize_accessor(msg, UPB_SIZE(32, 56), len, UPB_TYPE_MESSAGE, arena);
+  return (struct envoy_config_core_v3_CidrRange**)_upb_array_resize_accessor2(msg, UPB_SIZE(32, 56), len, UPB_SIZE(2, 3), arena);
 }
 UPB_INLINE struct envoy_config_core_v3_CidrRange* envoy_config_listener_v3_FilterChainMatch_add_prefix_ranges(envoy_config_listener_v3_FilterChainMatch *msg, upb_arena *arena) {
   struct envoy_config_core_v3_CidrRange* sub = (struct envoy_config_core_v3_CidrRange*)_upb_msg_new(&envoy_config_core_v3_CidrRange_msginit, arena);
-  bool ok = _upb_array_append_accessor(
-      msg, UPB_SIZE(32, 56), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena);
+  bool ok = _upb_array_append_accessor2(
+      msg, UPB_SIZE(32, 56), UPB_SIZE(2, 3), &sub, arena);
   if (!ok) return NULL;
   return sub;
 }
@@ -150,6 +163,7 @@ UPB_INLINE void envoy_config_listener_v3_FilterChainMatch_set_address_suffix(env
   *UPB_PTR_AT(msg, UPB_SIZE(8, 8), upb_strview) = value;
 }
 UPB_INLINE void envoy_config_listener_v3_FilterChainMatch_set_suffix_len(envoy_config_listener_v3_FilterChainMatch *msg, struct google_protobuf_UInt32Value* value) {
+  _upb_sethas(msg, 1);
   *UPB_PTR_AT(msg, UPB_SIZE(24, 40), struct google_protobuf_UInt32Value*) = value;
 }
 UPB_INLINE struct google_protobuf_UInt32Value* envoy_config_listener_v3_FilterChainMatch_mutable_suffix_len(envoy_config_listener_v3_FilterChainMatch *msg, upb_arena *arena) {
@@ -165,12 +179,12 @@ UPB_INLINE struct envoy_config_core_v3_CidrRange** envoy_config_listener_v3_Filt
   return (struct envoy_config_core_v3_CidrRange**)_upb_array_mutable_accessor(msg, UPB_SIZE(36, 64), len);
 }
 UPB_INLINE struct envoy_config_core_v3_CidrRange** envoy_config_listener_v3_FilterChainMatch_resize_source_prefix_ranges(envoy_config_listener_v3_FilterChainMatch *msg, size_t len, upb_arena *arena) {
-  return (struct envoy_config_core_v3_CidrRange**)_upb_array_resize_accessor(msg, UPB_SIZE(36, 64), len, UPB_TYPE_MESSAGE, arena);
+  return (struct envoy_config_core_v3_CidrRange**)_upb_array_resize_accessor2(msg, UPB_SIZE(36, 64), len, UPB_SIZE(2, 3), arena);
 }
 UPB_INLINE struct envoy_config_core_v3_CidrRange* envoy_config_listener_v3_FilterChainMatch_add_source_prefix_ranges(envoy_config_listener_v3_FilterChainMatch *msg, upb_arena *arena) {
   struct envoy_config_core_v3_CidrRange* sub = (struct envoy_config_core_v3_CidrRange*)_upb_msg_new(&envoy_config_core_v3_CidrRange_msginit, arena);
-  bool ok = _upb_array_append_accessor(
-      msg, UPB_SIZE(36, 64), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena);
+  bool ok = _upb_array_append_accessor2(
+      msg, UPB_SIZE(36, 64), UPB_SIZE(2, 3), &sub, arena);
   if (!ok) return NULL;
   return sub;
 }
@@ -178,13 +192,14 @@ UPB_INLINE uint32_t* envoy_config_listener_v3_FilterChainMatch_mutable_source_po
   return (uint32_t*)_upb_array_mutable_accessor(msg, UPB_SIZE(40, 72), len);
 }
 UPB_INLINE uint32_t* envoy_config_listener_v3_FilterChainMatch_resize_source_ports(envoy_config_listener_v3_FilterChainMatch *msg, size_t len, upb_arena *arena) {
-  return (uint32_t*)_upb_array_resize_accessor(msg, UPB_SIZE(40, 72), len, UPB_TYPE_UINT32, arena);
+  return (uint32_t*)_upb_array_resize_accessor2(msg, UPB_SIZE(40, 72), len, 2, arena);
 }
 UPB_INLINE bool envoy_config_listener_v3_FilterChainMatch_add_source_ports(envoy_config_listener_v3_FilterChainMatch *msg, uint32_t val, upb_arena *arena) {
-  return _upb_array_append_accessor(msg, UPB_SIZE(40, 72), UPB_SIZE(4, 4), UPB_TYPE_UINT32, &val,
+  return _upb_array_append_accessor2(msg, UPB_SIZE(40, 72), 2, &val,
       arena);
 }
 UPB_INLINE void envoy_config_listener_v3_FilterChainMatch_set_destination_port(envoy_config_listener_v3_FilterChainMatch *msg, struct google_protobuf_UInt32Value* value) {
+  _upb_sethas(msg, 2);
   *UPB_PTR_AT(msg, UPB_SIZE(28, 48), struct google_protobuf_UInt32Value*) = value;
 }
 UPB_INLINE struct google_protobuf_UInt32Value* envoy_config_listener_v3_FilterChainMatch_mutable_destination_port(envoy_config_listener_v3_FilterChainMatch *msg, upb_arena *arena) {
@@ -203,24 +218,24 @@ UPB_INLINE upb_strview* envoy_config_listener_v3_FilterChainMatch_mutable_applic
   return (upb_strview*)_upb_array_mutable_accessor(msg, UPB_SIZE(44, 80), len);
 }
 UPB_INLINE upb_strview* envoy_config_listener_v3_FilterChainMatch_resize_application_protocols(envoy_config_listener_v3_FilterChainMatch *msg, size_t len, upb_arena *arena) {
-  return (upb_strview*)_upb_array_resize_accessor(msg, UPB_SIZE(44, 80), len, UPB_TYPE_STRING, arena);
+  return (upb_strview*)_upb_array_resize_accessor2(msg, UPB_SIZE(44, 80), len, UPB_SIZE(3, 4), arena);
 }
 UPB_INLINE bool envoy_config_listener_v3_FilterChainMatch_add_application_protocols(envoy_config_listener_v3_FilterChainMatch *msg, upb_strview val, upb_arena *arena) {
-  return _upb_array_append_accessor(msg, UPB_SIZE(44, 80), UPB_SIZE(8, 16), UPB_TYPE_STRING, &val,
+  return _upb_array_append_accessor2(msg, UPB_SIZE(44, 80), UPB_SIZE(3, 4), &val,
       arena);
 }
 UPB_INLINE upb_strview* envoy_config_listener_v3_FilterChainMatch_mutable_server_names(envoy_config_listener_v3_FilterChainMatch *msg, size_t *len) {
   return (upb_strview*)_upb_array_mutable_accessor(msg, UPB_SIZE(48, 88), len);
 }
 UPB_INLINE upb_strview* envoy_config_listener_v3_FilterChainMatch_resize_server_names(envoy_config_listener_v3_FilterChainMatch *msg, size_t len, upb_arena *arena) {
-  return (upb_strview*)_upb_array_resize_accessor(msg, UPB_SIZE(48, 88), len, UPB_TYPE_STRING, arena);
+  return (upb_strview*)_upb_array_resize_accessor2(msg, UPB_SIZE(48, 88), len, UPB_SIZE(3, 4), arena);
 }
 UPB_INLINE bool envoy_config_listener_v3_FilterChainMatch_add_server_names(envoy_config_listener_v3_FilterChainMatch *msg, upb_strview val, upb_arena *arena) {
-  return _upb_array_append_accessor(msg, UPB_SIZE(48, 88), UPB_SIZE(8, 16), UPB_TYPE_STRING, &val,
+  return _upb_array_append_accessor2(msg, UPB_SIZE(48, 88), UPB_SIZE(3, 4), &val,
       arena);
 }
 UPB_INLINE void envoy_config_listener_v3_FilterChainMatch_set_source_type(envoy_config_listener_v3_FilterChainMatch *msg, int32_t value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(0, 0), int32_t) = value;
+  *UPB_PTR_AT(msg, UPB_SIZE(4, 4), int32_t) = value;
 }
 
 /* envoy.config.listener.v3.FilterChain */
@@ -233,26 +248,33 @@ UPB_INLINE envoy_config_listener_v3_FilterChain *envoy_config_listener_v3_Filter
   envoy_config_listener_v3_FilterChain *ret = envoy_config_listener_v3_FilterChain_new(arena);
   return (ret && upb_decode(buf, size, ret, &envoy_config_listener_v3_FilterChain_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE envoy_config_listener_v3_FilterChain *envoy_config_listener_v3_FilterChain_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  envoy_config_listener_v3_FilterChain *ret = envoy_config_listener_v3_FilterChain_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &envoy_config_listener_v3_FilterChain_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *envoy_config_listener_v3_FilterChain_serialize(const envoy_config_listener_v3_FilterChain *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &envoy_config_listener_v3_FilterChain_msginit, arena, len);
 }
 
-UPB_INLINE bool envoy_config_listener_v3_FilterChain_has_filter_chain_match(const envoy_config_listener_v3_FilterChain *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(8, 16)); }
-UPB_INLINE const envoy_config_listener_v3_FilterChainMatch* envoy_config_listener_v3_FilterChain_filter_chain_match(const envoy_config_listener_v3_FilterChain *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(8, 16), const envoy_config_listener_v3_FilterChainMatch*); }
-UPB_INLINE bool envoy_config_listener_v3_FilterChain_has_filters(const envoy_config_listener_v3_FilterChain *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(28, 56)); }
-UPB_INLINE const envoy_config_listener_v3_Filter* const* envoy_config_listener_v3_FilterChain_filters(const envoy_config_listener_v3_FilterChain *msg, size_t *len) { return (const envoy_config_listener_v3_Filter* const*)_upb_array_accessor(msg, UPB_SIZE(28, 56), len); }
-UPB_INLINE bool envoy_config_listener_v3_FilterChain_has_use_proxy_proto(const envoy_config_listener_v3_FilterChain *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(12, 24)); }
-UPB_INLINE const struct google_protobuf_BoolValue* envoy_config_listener_v3_FilterChain_use_proxy_proto(const envoy_config_listener_v3_FilterChain *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(12, 24), const struct google_protobuf_BoolValue*); }
-UPB_INLINE bool envoy_config_listener_v3_FilterChain_has_metadata(const envoy_config_listener_v3_FilterChain *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(16, 32)); }
-UPB_INLINE const struct envoy_config_core_v3_Metadata* envoy_config_listener_v3_FilterChain_metadata(const envoy_config_listener_v3_FilterChain *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(16, 32), const struct envoy_config_core_v3_Metadata*); }
-UPB_INLINE bool envoy_config_listener_v3_FilterChain_has_transport_socket(const envoy_config_listener_v3_FilterChain *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(20, 40)); }
-UPB_INLINE const struct envoy_config_core_v3_TransportSocket* envoy_config_listener_v3_FilterChain_transport_socket(const envoy_config_listener_v3_FilterChain *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(20, 40), const struct envoy_config_core_v3_TransportSocket*); }
-UPB_INLINE upb_strview envoy_config_listener_v3_FilterChain_name(const envoy_config_listener_v3_FilterChain *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(0, 0), upb_strview); }
-UPB_INLINE bool envoy_config_listener_v3_FilterChain_has_on_demand_configuration(const envoy_config_listener_v3_FilterChain *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(24, 48)); }
-UPB_INLINE const envoy_config_listener_v3_FilterChain_OnDemandConfiguration* envoy_config_listener_v3_FilterChain_on_demand_configuration(const envoy_config_listener_v3_FilterChain *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(24, 48), const envoy_config_listener_v3_FilterChain_OnDemandConfiguration*); }
+UPB_INLINE bool envoy_config_listener_v3_FilterChain_has_filter_chain_match(const envoy_config_listener_v3_FilterChain *msg) { return _upb_hasbit(msg, 1); }
+UPB_INLINE const envoy_config_listener_v3_FilterChainMatch* envoy_config_listener_v3_FilterChain_filter_chain_match(const envoy_config_listener_v3_FilterChain *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(12, 24), const envoy_config_listener_v3_FilterChainMatch*); }
+UPB_INLINE bool envoy_config_listener_v3_FilterChain_has_filters(const envoy_config_listener_v3_FilterChain *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(32, 64)); }
+UPB_INLINE const envoy_config_listener_v3_Filter* const* envoy_config_listener_v3_FilterChain_filters(const envoy_config_listener_v3_FilterChain *msg, size_t *len) { return (const envoy_config_listener_v3_Filter* const*)_upb_array_accessor(msg, UPB_SIZE(32, 64), len); }
+UPB_INLINE bool envoy_config_listener_v3_FilterChain_has_use_proxy_proto(const envoy_config_listener_v3_FilterChain *msg) { return _upb_hasbit(msg, 2); }
+UPB_INLINE const struct google_protobuf_BoolValue* envoy_config_listener_v3_FilterChain_use_proxy_proto(const envoy_config_listener_v3_FilterChain *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(16, 32), const struct google_protobuf_BoolValue*); }
+UPB_INLINE bool envoy_config_listener_v3_FilterChain_has_metadata(const envoy_config_listener_v3_FilterChain *msg) { return _upb_hasbit(msg, 3); }
+UPB_INLINE const struct envoy_config_core_v3_Metadata* envoy_config_listener_v3_FilterChain_metadata(const envoy_config_listener_v3_FilterChain *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(20, 40), const struct envoy_config_core_v3_Metadata*); }
+UPB_INLINE bool envoy_config_listener_v3_FilterChain_has_transport_socket(const envoy_config_listener_v3_FilterChain *msg) { return _upb_hasbit(msg, 4); }
+UPB_INLINE const struct envoy_config_core_v3_TransportSocket* envoy_config_listener_v3_FilterChain_transport_socket(const envoy_config_listener_v3_FilterChain *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(24, 48), const struct envoy_config_core_v3_TransportSocket*); }
+UPB_INLINE upb_strview envoy_config_listener_v3_FilterChain_name(const envoy_config_listener_v3_FilterChain *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(4, 8), upb_strview); }
+UPB_INLINE bool envoy_config_listener_v3_FilterChain_has_on_demand_configuration(const envoy_config_listener_v3_FilterChain *msg) { return _upb_hasbit(msg, 5); }
+UPB_INLINE const envoy_config_listener_v3_FilterChain_OnDemandConfiguration* envoy_config_listener_v3_FilterChain_on_demand_configuration(const envoy_config_listener_v3_FilterChain *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(28, 56), const envoy_config_listener_v3_FilterChain_OnDemandConfiguration*); }
 
 UPB_INLINE void envoy_config_listener_v3_FilterChain_set_filter_chain_match(envoy_config_listener_v3_FilterChain *msg, envoy_config_listener_v3_FilterChainMatch* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(8, 16), envoy_config_listener_v3_FilterChainMatch*) = value;
+  _upb_sethas(msg, 1);
+  *UPB_PTR_AT(msg, UPB_SIZE(12, 24), envoy_config_listener_v3_FilterChainMatch*) = value;
 }
 UPB_INLINE struct envoy_config_listener_v3_FilterChainMatch* envoy_config_listener_v3_FilterChain_mutable_filter_chain_match(envoy_config_listener_v3_FilterChain *msg, upb_arena *arena) {
   struct envoy_config_listener_v3_FilterChainMatch* sub = (struct envoy_config_listener_v3_FilterChainMatch*)envoy_config_listener_v3_FilterChain_filter_chain_match(msg);
@@ -264,20 +286,21 @@ UPB_INLINE struct envoy_config_listener_v3_FilterChainMatch* envoy_config_listen
   return sub;
 }
 UPB_INLINE envoy_config_listener_v3_Filter** envoy_config_listener_v3_FilterChain_mutable_filters(envoy_config_listener_v3_FilterChain *msg, size_t *len) {
-  return (envoy_config_listener_v3_Filter**)_upb_array_mutable_accessor(msg, UPB_SIZE(28, 56), len);
+  return (envoy_config_listener_v3_Filter**)_upb_array_mutable_accessor(msg, UPB_SIZE(32, 64), len);
 }
 UPB_INLINE envoy_config_listener_v3_Filter** envoy_config_listener_v3_FilterChain_resize_filters(envoy_config_listener_v3_FilterChain *msg, size_t len, upb_arena *arena) {
-  return (envoy_config_listener_v3_Filter**)_upb_array_resize_accessor(msg, UPB_SIZE(28, 56), len, UPB_TYPE_MESSAGE, arena);
+  return (envoy_config_listener_v3_Filter**)_upb_array_resize_accessor2(msg, UPB_SIZE(32, 64), len, UPB_SIZE(2, 3), arena);
 }
 UPB_INLINE struct envoy_config_listener_v3_Filter* envoy_config_listener_v3_FilterChain_add_filters(envoy_config_listener_v3_FilterChain *msg, upb_arena *arena) {
   struct envoy_config_listener_v3_Filter* sub = (struct envoy_config_listener_v3_Filter*)_upb_msg_new(&envoy_config_listener_v3_Filter_msginit, arena);
-  bool ok = _upb_array_append_accessor(
-      msg, UPB_SIZE(28, 56), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena);
+  bool ok = _upb_array_append_accessor2(
+      msg, UPB_SIZE(32, 64), UPB_SIZE(2, 3), &sub, arena);
   if (!ok) return NULL;
   return sub;
 }
 UPB_INLINE void envoy_config_listener_v3_FilterChain_set_use_proxy_proto(envoy_config_listener_v3_FilterChain *msg, struct google_protobuf_BoolValue* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(12, 24), struct google_protobuf_BoolValue*) = value;
+  _upb_sethas(msg, 2);
+  *UPB_PTR_AT(msg, UPB_SIZE(16, 32), struct google_protobuf_BoolValue*) = value;
 }
 UPB_INLINE struct google_protobuf_BoolValue* envoy_config_listener_v3_FilterChain_mutable_use_proxy_proto(envoy_config_listener_v3_FilterChain *msg, upb_arena *arena) {
   struct google_protobuf_BoolValue* sub = (struct google_protobuf_BoolValue*)envoy_config_listener_v3_FilterChain_use_proxy_proto(msg);
@@ -289,7 +312,8 @@ UPB_INLINE struct google_protobuf_BoolValue* envoy_config_listener_v3_FilterChai
   return sub;
 }
 UPB_INLINE void envoy_config_listener_v3_FilterChain_set_metadata(envoy_config_listener_v3_FilterChain *msg, struct envoy_config_core_v3_Metadata* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(16, 32), struct envoy_config_core_v3_Metadata*) = value;
+  _upb_sethas(msg, 3);
+  *UPB_PTR_AT(msg, UPB_SIZE(20, 40), struct envoy_config_core_v3_Metadata*) = value;
 }
 UPB_INLINE struct envoy_config_core_v3_Metadata* envoy_config_listener_v3_FilterChain_mutable_metadata(envoy_config_listener_v3_FilterChain *msg, upb_arena *arena) {
   struct envoy_config_core_v3_Metadata* sub = (struct envoy_config_core_v3_Metadata*)envoy_config_listener_v3_FilterChain_metadata(msg);
@@ -301,7 +325,8 @@ UPB_INLINE struct envoy_config_core_v3_Metadata* envoy_config_listener_v3_Filter
   return sub;
 }
 UPB_INLINE void envoy_config_listener_v3_FilterChain_set_transport_socket(envoy_config_listener_v3_FilterChain *msg, struct envoy_config_core_v3_TransportSocket* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(20, 40), struct envoy_config_core_v3_TransportSocket*) = value;
+  _upb_sethas(msg, 4);
+  *UPB_PTR_AT(msg, UPB_SIZE(24, 48), struct envoy_config_core_v3_TransportSocket*) = value;
 }
 UPB_INLINE struct envoy_config_core_v3_TransportSocket* envoy_config_listener_v3_FilterChain_mutable_transport_socket(envoy_config_listener_v3_FilterChain *msg, upb_arena *arena) {
   struct envoy_config_core_v3_TransportSocket* sub = (struct envoy_config_core_v3_TransportSocket*)envoy_config_listener_v3_FilterChain_transport_socket(msg);
@@ -313,10 +338,11 @@ UPB_INLINE struct envoy_config_core_v3_TransportSocket* envoy_config_listener_v3
   return sub;
 }
 UPB_INLINE void envoy_config_listener_v3_FilterChain_set_name(envoy_config_listener_v3_FilterChain *msg, upb_strview value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(0, 0), upb_strview) = value;
+  *UPB_PTR_AT(msg, UPB_SIZE(4, 8), upb_strview) = value;
 }
 UPB_INLINE void envoy_config_listener_v3_FilterChain_set_on_demand_configuration(envoy_config_listener_v3_FilterChain *msg, envoy_config_listener_v3_FilterChain_OnDemandConfiguration* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(24, 48), envoy_config_listener_v3_FilterChain_OnDemandConfiguration*) = value;
+  _upb_sethas(msg, 5);
+  *UPB_PTR_AT(msg, UPB_SIZE(28, 56), envoy_config_listener_v3_FilterChain_OnDemandConfiguration*) = value;
 }
 UPB_INLINE struct envoy_config_listener_v3_FilterChain_OnDemandConfiguration* envoy_config_listener_v3_FilterChain_mutable_on_demand_configuration(envoy_config_listener_v3_FilterChain *msg, upb_arena *arena) {
   struct envoy_config_listener_v3_FilterChain_OnDemandConfiguration* sub = (struct envoy_config_listener_v3_FilterChain_OnDemandConfiguration*)envoy_config_listener_v3_FilterChain_on_demand_configuration(msg);
@@ -338,15 +364,22 @@ UPB_INLINE envoy_config_listener_v3_FilterChain_OnDemandConfiguration *envoy_con
   envoy_config_listener_v3_FilterChain_OnDemandConfiguration *ret = envoy_config_listener_v3_FilterChain_OnDemandConfiguration_new(arena);
   return (ret && upb_decode(buf, size, ret, &envoy_config_listener_v3_FilterChain_OnDemandConfiguration_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE envoy_config_listener_v3_FilterChain_OnDemandConfiguration *envoy_config_listener_v3_FilterChain_OnDemandConfiguration_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  envoy_config_listener_v3_FilterChain_OnDemandConfiguration *ret = envoy_config_listener_v3_FilterChain_OnDemandConfiguration_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &envoy_config_listener_v3_FilterChain_OnDemandConfiguration_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *envoy_config_listener_v3_FilterChain_OnDemandConfiguration_serialize(const envoy_config_listener_v3_FilterChain_OnDemandConfiguration *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &envoy_config_listener_v3_FilterChain_OnDemandConfiguration_msginit, arena, len);
 }
 
-UPB_INLINE bool envoy_config_listener_v3_FilterChain_OnDemandConfiguration_has_rebuild_timeout(const envoy_config_listener_v3_FilterChain_OnDemandConfiguration *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(0, 0)); }
-UPB_INLINE const struct google_protobuf_Duration* envoy_config_listener_v3_FilterChain_OnDemandConfiguration_rebuild_timeout(const envoy_config_listener_v3_FilterChain_OnDemandConfiguration *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(0, 0), const struct google_protobuf_Duration*); }
+UPB_INLINE bool envoy_config_listener_v3_FilterChain_OnDemandConfiguration_has_rebuild_timeout(const envoy_config_listener_v3_FilterChain_OnDemandConfiguration *msg) { return _upb_hasbit(msg, 1); }
+UPB_INLINE const struct google_protobuf_Duration* envoy_config_listener_v3_FilterChain_OnDemandConfiguration_rebuild_timeout(const envoy_config_listener_v3_FilterChain_OnDemandConfiguration *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(4, 8), const struct google_protobuf_Duration*); }
 
 UPB_INLINE void envoy_config_listener_v3_FilterChain_OnDemandConfiguration_set_rebuild_timeout(envoy_config_listener_v3_FilterChain_OnDemandConfiguration *msg, struct google_protobuf_Duration* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(0, 0), struct google_protobuf_Duration*) = value;
+  _upb_sethas(msg, 1);
+  *UPB_PTR_AT(msg, UPB_SIZE(4, 8), struct google_protobuf_Duration*) = value;
 }
 UPB_INLINE struct google_protobuf_Duration* envoy_config_listener_v3_FilterChain_OnDemandConfiguration_mutable_rebuild_timeout(envoy_config_listener_v3_FilterChain_OnDemandConfiguration *msg, upb_arena *arena) {
   struct google_protobuf_Duration* sub = (struct google_protobuf_Duration*)envoy_config_listener_v3_FilterChain_OnDemandConfiguration_rebuild_timeout(msg);
@@ -368,6 +401,12 @@ UPB_INLINE envoy_config_listener_v3_ListenerFilterChainMatchPredicate *envoy_con
   envoy_config_listener_v3_ListenerFilterChainMatchPredicate *ret = envoy_config_listener_v3_ListenerFilterChainMatchPredicate_new(arena);
   return (ret && upb_decode(buf, size, ret, &envoy_config_listener_v3_ListenerFilterChainMatchPredicate_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE envoy_config_listener_v3_ListenerFilterChainMatchPredicate *envoy_config_listener_v3_ListenerFilterChainMatchPredicate_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  envoy_config_listener_v3_ListenerFilterChainMatchPredicate *ret = envoy_config_listener_v3_ListenerFilterChainMatchPredicate_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &envoy_config_listener_v3_ListenerFilterChainMatchPredicate_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *envoy_config_listener_v3_ListenerFilterChainMatchPredicate_serialize(const envoy_config_listener_v3_ListenerFilterChainMatchPredicate *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &envoy_config_listener_v3_ListenerFilterChainMatchPredicate_msginit, arena, len);
 }
@@ -455,6 +494,12 @@ UPB_INLINE envoy_config_listener_v3_ListenerFilterChainMatchPredicate_MatchSet *
   envoy_config_listener_v3_ListenerFilterChainMatchPredicate_MatchSet *ret = envoy_config_listener_v3_ListenerFilterChainMatchPredicate_MatchSet_new(arena);
   return (ret && upb_decode(buf, size, ret, &envoy_config_listener_v3_ListenerFilterChainMatchPredicate_MatchSet_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE envoy_config_listener_v3_ListenerFilterChainMatchPredicate_MatchSet *envoy_config_listener_v3_ListenerFilterChainMatchPredicate_MatchSet_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  envoy_config_listener_v3_ListenerFilterChainMatchPredicate_MatchSet *ret = envoy_config_listener_v3_ListenerFilterChainMatchPredicate_MatchSet_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &envoy_config_listener_v3_ListenerFilterChainMatchPredicate_MatchSet_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *envoy_config_listener_v3_ListenerFilterChainMatchPredicate_MatchSet_serialize(const envoy_config_listener_v3_ListenerFilterChainMatchPredicate_MatchSet *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &envoy_config_listener_v3_ListenerFilterChainMatchPredicate_MatchSet_msginit, arena, len);
 }
@@ -466,12 +511,12 @@ UPB_INLINE envoy_config_listener_v3_ListenerFilterChainMatchPredicate** envoy_co
   return (envoy_config_listener_v3_ListenerFilterChainMatchPredicate**)_upb_array_mutable_accessor(msg, UPB_SIZE(0, 0), len);
 }
 UPB_INLINE envoy_config_listener_v3_ListenerFilterChainMatchPredicate** envoy_config_listener_v3_ListenerFilterChainMatchPredicate_MatchSet_resize_rules(envoy_config_listener_v3_ListenerFilterChainMatchPredicate_MatchSet *msg, size_t len, upb_arena *arena) {
-  return (envoy_config_listener_v3_ListenerFilterChainMatchPredicate**)_upb_array_resize_accessor(msg, UPB_SIZE(0, 0), len, UPB_TYPE_MESSAGE, arena);
+  return (envoy_config_listener_v3_ListenerFilterChainMatchPredicate**)_upb_array_resize_accessor2(msg, UPB_SIZE(0, 0), len, UPB_SIZE(2, 3), arena);
 }
 UPB_INLINE struct envoy_config_listener_v3_ListenerFilterChainMatchPredicate* envoy_config_listener_v3_ListenerFilterChainMatchPredicate_MatchSet_add_rules(envoy_config_listener_v3_ListenerFilterChainMatchPredicate_MatchSet *msg, upb_arena *arena) {
   struct envoy_config_listener_v3_ListenerFilterChainMatchPredicate* sub = (struct envoy_config_listener_v3_ListenerFilterChainMatchPredicate*)_upb_msg_new(&envoy_config_listener_v3_ListenerFilterChainMatchPredicate_msginit, arena);
-  bool ok = _upb_array_append_accessor(
-      msg, UPB_SIZE(0, 0), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena);
+  bool ok = _upb_array_append_accessor2(
+      msg, UPB_SIZE(0, 0), UPB_SIZE(2, 3), &sub, arena);
   if (!ok) return NULL;
   return sub;
 }
@@ -486,6 +531,12 @@ UPB_INLINE envoy_config_listener_v3_ListenerFilter *envoy_config_listener_v3_Lis
   envoy_config_listener_v3_ListenerFilter *ret = envoy_config_listener_v3_ListenerFilter_new(arena);
   return (ret && upb_decode(buf, size, ret, &envoy_config_listener_v3_ListenerFilter_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE envoy_config_listener_v3_ListenerFilter *envoy_config_listener_v3_ListenerFilter_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  envoy_config_listener_v3_ListenerFilter *ret = envoy_config_listener_v3_ListenerFilter_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &envoy_config_listener_v3_ListenerFilter_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *envoy_config_listener_v3_ListenerFilter_serialize(const envoy_config_listener_v3_ListenerFilter *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &envoy_config_listener_v3_ListenerFilter_msginit, arena, len);
 }
@@ -494,19 +545,19 @@ typedef enum {
   envoy_config_listener_v3_ListenerFilter_config_type_typed_config = 3,
   envoy_config_listener_v3_ListenerFilter_config_type_NOT_SET = 0
 } envoy_config_listener_v3_ListenerFilter_config_type_oneofcases;
-UPB_INLINE envoy_config_listener_v3_ListenerFilter_config_type_oneofcases envoy_config_listener_v3_ListenerFilter_config_type_case(const envoy_config_listener_v3_ListenerFilter* msg) { return (envoy_config_listener_v3_ListenerFilter_config_type_oneofcases)*UPB_PTR_AT(msg, UPB_SIZE(16, 32), int32_t); }
+UPB_INLINE envoy_config_listener_v3_ListenerFilter_config_type_oneofcases envoy_config_listener_v3_ListenerFilter_config_type_case(const envoy_config_listener_v3_ListenerFilter* msg) { return (envoy_config_listener_v3_ListenerFilter_config_type_oneofcases)*UPB_PTR_AT(msg, UPB_SIZE(20, 40), int32_t); }
 
-UPB_INLINE upb_strview envoy_config_listener_v3_ListenerFilter_name(const envoy_config_listener_v3_ListenerFilter *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(0, 0), upb_strview); }
-UPB_INLINE bool envoy_config_listener_v3_ListenerFilter_has_typed_config(const envoy_config_listener_v3_ListenerFilter *msg) { return _upb_getoneofcase(msg, UPB_SIZE(16, 32)) == 3; }
-UPB_INLINE const struct google_protobuf_Any* envoy_config_listener_v3_ListenerFilter_typed_config(const envoy_config_listener_v3_ListenerFilter *msg) { return UPB_READ_ONEOF(msg, const struct google_protobuf_Any*, UPB_SIZE(12, 24), UPB_SIZE(16, 32), 3, NULL); }
-UPB_INLINE bool envoy_config_listener_v3_ListenerFilter_has_filter_disabled(const envoy_config_listener_v3_ListenerFilter *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(8, 16)); }
-UPB_INLINE const envoy_config_listener_v3_ListenerFilterChainMatchPredicate* envoy_config_listener_v3_ListenerFilter_filter_disabled(const envoy_config_listener_v3_ListenerFilter *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(8, 16), const envoy_config_listener_v3_ListenerFilterChainMatchPredicate*); }
+UPB_INLINE upb_strview envoy_config_listener_v3_ListenerFilter_name(const envoy_config_listener_v3_ListenerFilter *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(4, 8), upb_strview); }
+UPB_INLINE bool envoy_config_listener_v3_ListenerFilter_has_typed_config(const envoy_config_listener_v3_ListenerFilter *msg) { return _upb_getoneofcase(msg, UPB_SIZE(20, 40)) == 3; }
+UPB_INLINE const struct google_protobuf_Any* envoy_config_listener_v3_ListenerFilter_typed_config(const envoy_config_listener_v3_ListenerFilter *msg) { return UPB_READ_ONEOF(msg, const struct google_protobuf_Any*, UPB_SIZE(16, 32), UPB_SIZE(20, 40), 3, NULL); }
+UPB_INLINE bool envoy_config_listener_v3_ListenerFilter_has_filter_disabled(const envoy_config_listener_v3_ListenerFilter *msg) { return _upb_hasbit(msg, 1); }
+UPB_INLINE const envoy_config_listener_v3_ListenerFilterChainMatchPredicate* envoy_config_listener_v3_ListenerFilter_filter_disabled(const envoy_config_listener_v3_ListenerFilter *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(12, 24), const envoy_config_listener_v3_ListenerFilterChainMatchPredicate*); }
 
 UPB_INLINE void envoy_config_listener_v3_ListenerFilter_set_name(envoy_config_listener_v3_ListenerFilter *msg, upb_strview value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(0, 0), upb_strview) = value;
+  *UPB_PTR_AT(msg, UPB_SIZE(4, 8), upb_strview) = value;
 }
 UPB_INLINE void envoy_config_listener_v3_ListenerFilter_set_typed_config(envoy_config_listener_v3_ListenerFilter *msg, struct google_protobuf_Any* value) {
-  UPB_WRITE_ONEOF(msg, struct google_protobuf_Any*, UPB_SIZE(12, 24), value, UPB_SIZE(16, 32), 3);
+  UPB_WRITE_ONEOF(msg, struct google_protobuf_Any*, UPB_SIZE(16, 32), value, UPB_SIZE(20, 40), 3);
 }
 UPB_INLINE struct google_protobuf_Any* envoy_config_listener_v3_ListenerFilter_mutable_typed_config(envoy_config_listener_v3_ListenerFilter *msg, upb_arena *arena) {
   struct google_protobuf_Any* sub = (struct google_protobuf_Any*)envoy_config_listener_v3_ListenerFilter_typed_config(msg);
@@ -518,7 +569,8 @@ UPB_INLINE struct google_protobuf_Any* envoy_config_listener_v3_ListenerFilter_m
   return sub;
 }
 UPB_INLINE void envoy_config_listener_v3_ListenerFilter_set_filter_disabled(envoy_config_listener_v3_ListenerFilter *msg, envoy_config_listener_v3_ListenerFilterChainMatchPredicate* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(8, 16), envoy_config_listener_v3_ListenerFilterChainMatchPredicate*) = value;
+  _upb_sethas(msg, 1);
+  *UPB_PTR_AT(msg, UPB_SIZE(12, 24), envoy_config_listener_v3_ListenerFilterChainMatchPredicate*) = value;
 }
 UPB_INLINE struct envoy_config_listener_v3_ListenerFilterChainMatchPredicate* envoy_config_listener_v3_ListenerFilter_mutable_filter_disabled(envoy_config_listener_v3_ListenerFilter *msg, upb_arena *arena) {
   struct envoy_config_listener_v3_ListenerFilterChainMatchPredicate* sub = (struct envoy_config_listener_v3_ListenerFilterChainMatchPredicate*)envoy_config_listener_v3_ListenerFilter_filter_disabled(msg);
index 67a5dde..e13d3e4 100644 (file)
@@ -28,13 +28,13 @@ static const upb_msglayout_field envoy_config_listener_v3_UdpListenerConfig__fie
 const upb_msglayout envoy_config_listener_v3_UdpListenerConfig_msginit = {
   &envoy_config_listener_v3_UdpListenerConfig_submsgs[0],
   &envoy_config_listener_v3_UdpListenerConfig__fields[0],
-  UPB_SIZE(16, 32), 2, false,
+  UPB_SIZE(16, 32), 2, false, 255,
 };
 
 const upb_msglayout envoy_config_listener_v3_ActiveRawUdpListenerConfig_msginit = {
   NULL,
   NULL,
-  UPB_SIZE(0, 0), 0, false,
+  UPB_SIZE(0, 0), 0, false, 255,
 };
 
 #include "upb/port_undef.inc"
index e7fe65a..3de7e08 100644 (file)
@@ -11,6 +11,7 @@
 
 #include "upb/msg.h"
 #include "upb/decode.h"
+#include "upb/decode_fast.h"
 #include "upb/encode.h"
 
 #include "upb/port_def.inc"
@@ -39,6 +40,12 @@ UPB_INLINE envoy_config_listener_v3_UdpListenerConfig *envoy_config_listener_v3_
   envoy_config_listener_v3_UdpListenerConfig *ret = envoy_config_listener_v3_UdpListenerConfig_new(arena);
   return (ret && upb_decode(buf, size, ret, &envoy_config_listener_v3_UdpListenerConfig_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE envoy_config_listener_v3_UdpListenerConfig *envoy_config_listener_v3_UdpListenerConfig_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  envoy_config_listener_v3_UdpListenerConfig *ret = envoy_config_listener_v3_UdpListenerConfig_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &envoy_config_listener_v3_UdpListenerConfig_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *envoy_config_listener_v3_UdpListenerConfig_serialize(const envoy_config_listener_v3_UdpListenerConfig *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &envoy_config_listener_v3_UdpListenerConfig_msginit, arena, len);
 }
@@ -79,6 +86,12 @@ UPB_INLINE envoy_config_listener_v3_ActiveRawUdpListenerConfig *envoy_config_lis
   envoy_config_listener_v3_ActiveRawUdpListenerConfig *ret = envoy_config_listener_v3_ActiveRawUdpListenerConfig_new(arena);
   return (ret && upb_decode(buf, size, ret, &envoy_config_listener_v3_ActiveRawUdpListenerConfig_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE envoy_config_listener_v3_ActiveRawUdpListenerConfig *envoy_config_listener_v3_ActiveRawUdpListenerConfig_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  envoy_config_listener_v3_ActiveRawUdpListenerConfig *ret = envoy_config_listener_v3_ActiveRawUdpListenerConfig_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &envoy_config_listener_v3_ActiveRawUdpListenerConfig_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *envoy_config_listener_v3_ActiveRawUdpListenerConfig_serialize(const envoy_config_listener_v3_ActiveRawUdpListenerConfig *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &envoy_config_listener_v3_ActiveRawUdpListenerConfig_msginit, arena, len);
 }
index bf4f865..f8ac2da 100644 (file)
@@ -29,13 +29,13 @@ static const upb_msglayout *const envoy_config_rbac_v3_RBAC_submsgs[1] = {
 
 static const upb_msglayout_field envoy_config_rbac_v3_RBAC__fields[2] = {
   {1, UPB_SIZE(0, 0), 0, 0, 14, 1},
-  {2, UPB_SIZE(8, 8), 0, 0, 11, _UPB_LABEL_MAP},
+  {2, UPB_SIZE(4, 8), 0, 0, 11, _UPB_LABEL_MAP},
 };
 
 const upb_msglayout envoy_config_rbac_v3_RBAC_msginit = {
   &envoy_config_rbac_v3_RBAC_submsgs[0],
   &envoy_config_rbac_v3_RBAC__fields[0],
-  UPB_SIZE(16, 16), 2, false,
+  UPB_SIZE(8, 16), 2, false, 255,
 };
 
 static const upb_msglayout *const envoy_config_rbac_v3_RBAC_PoliciesEntry_submsgs[1] = {
@@ -50,7 +50,7 @@ static const upb_msglayout_field envoy_config_rbac_v3_RBAC_PoliciesEntry__fields
 const upb_msglayout envoy_config_rbac_v3_RBAC_PoliciesEntry_msginit = {
   &envoy_config_rbac_v3_RBAC_PoliciesEntry_submsgs[0],
   &envoy_config_rbac_v3_RBAC_PoliciesEntry__fields[0],
-  UPB_SIZE(16, 32), 2, false,
+  UPB_SIZE(16, 32), 2, false, 255,
 };
 
 static const upb_msglayout *const envoy_config_rbac_v3_Policy_submsgs[4] = {
@@ -61,19 +61,19 @@ static const upb_msglayout *const envoy_config_rbac_v3_Policy_submsgs[4] = {
 };
 
 static const upb_msglayout_field envoy_config_rbac_v3_Policy__fields[4] = {
-  {1, UPB_SIZE(8, 16), 0, 0, 11, 3},
-  {2, UPB_SIZE(12, 24), 0, 1, 11, 3},
-  {3, UPB_SIZE(0, 0), 0, 3, 11, 1},
-  {4, UPB_SIZE(4, 8), 0, 2, 11, 1},
+  {1, UPB_SIZE(12, 24), 0, 0, 11, 3},
+  {2, UPB_SIZE(16, 32), 0, 1, 11, 3},
+  {3, UPB_SIZE(4, 8), 1, 3, 11, 1},
+  {4, UPB_SIZE(8, 16), 2, 2, 11, 1},
 };
 
 const upb_msglayout envoy_config_rbac_v3_Policy_msginit = {
   &envoy_config_rbac_v3_Policy_submsgs[0],
   &envoy_config_rbac_v3_Policy__fields[0],
-  UPB_SIZE(16, 32), 4, false,
+  UPB_SIZE(24, 40), 4, false, 255,
 };
 
-static const upb_msglayout *const envoy_config_rbac_v3_Permission_submsgs[8] = {
+static const upb_msglayout *const envoy_config_rbac_v3_Permission_submsgs[7] = {
   &envoy_config_core_v3_CidrRange_msginit,
   &envoy_config_rbac_v3_Permission_msginit,
   &envoy_config_rbac_v3_Permission_Set_msginit,
@@ -99,7 +99,7 @@ static const upb_msglayout_field envoy_config_rbac_v3_Permission__fields[10] = {
 const upb_msglayout envoy_config_rbac_v3_Permission_msginit = {
   &envoy_config_rbac_v3_Permission_submsgs[0],
   &envoy_config_rbac_v3_Permission__fields[0],
-  UPB_SIZE(8, 16), 10, false,
+  UPB_SIZE(8, 16), 10, false, 255,
 };
 
 static const upb_msglayout *const envoy_config_rbac_v3_Permission_Set_submsgs[1] = {
@@ -113,10 +113,10 @@ static const upb_msglayout_field envoy_config_rbac_v3_Permission_Set__fields[1]
 const upb_msglayout envoy_config_rbac_v3_Permission_Set_msginit = {
   &envoy_config_rbac_v3_Permission_Set_submsgs[0],
   &envoy_config_rbac_v3_Permission_Set__fields[0],
-  UPB_SIZE(4, 8), 1, false,
+  UPB_SIZE(8, 8), 1, false, 255,
 };
 
-static const upb_msglayout *const envoy_config_rbac_v3_Principal_submsgs[10] = {
+static const upb_msglayout *const envoy_config_rbac_v3_Principal_submsgs[7] = {
   &envoy_config_core_v3_CidrRange_msginit,
   &envoy_config_rbac_v3_Principal_msginit,
   &envoy_config_rbac_v3_Principal_Authenticated_msginit,
@@ -143,7 +143,7 @@ static const upb_msglayout_field envoy_config_rbac_v3_Principal__fields[11] = {
 const upb_msglayout envoy_config_rbac_v3_Principal_msginit = {
   &envoy_config_rbac_v3_Principal_submsgs[0],
   &envoy_config_rbac_v3_Principal__fields[0],
-  UPB_SIZE(8, 16), 11, false,
+  UPB_SIZE(8, 16), 11, false, 255,
 };
 
 static const upb_msglayout *const envoy_config_rbac_v3_Principal_Set_submsgs[1] = {
@@ -157,7 +157,7 @@ static const upb_msglayout_field envoy_config_rbac_v3_Principal_Set__fields[1] =
 const upb_msglayout envoy_config_rbac_v3_Principal_Set_msginit = {
   &envoy_config_rbac_v3_Principal_Set_submsgs[0],
   &envoy_config_rbac_v3_Principal_Set__fields[0],
-  UPB_SIZE(4, 8), 1, false,
+  UPB_SIZE(8, 8), 1, false, 255,
 };
 
 static const upb_msglayout *const envoy_config_rbac_v3_Principal_Authenticated_submsgs[1] = {
@@ -165,13 +165,13 @@ static const upb_msglayout *const envoy_config_rbac_v3_Principal_Authenticated_s
 };
 
 static const upb_msglayout_field envoy_config_rbac_v3_Principal_Authenticated__fields[1] = {
-  {2, UPB_SIZE(0, 0), 0, 0, 11, 1},
+  {2, UPB_SIZE(4, 8), 1, 0, 11, 1},
 };
 
 const upb_msglayout envoy_config_rbac_v3_Principal_Authenticated_msginit = {
   &envoy_config_rbac_v3_Principal_Authenticated_submsgs[0],
   &envoy_config_rbac_v3_Principal_Authenticated__fields[0],
-  UPB_SIZE(4, 8), 1, false,
+  UPB_SIZE(8, 16), 1, false, 255,
 };
 
 #include "upb/port_undef.inc"
index b5a3c55..befa31f 100644 (file)
@@ -11,6 +11,7 @@
 
 #include "upb/msg.h"
 #include "upb/decode.h"
+#include "upb/decode_fast.h"
 #include "upb/encode.h"
 
 #include "upb/port_def.inc"
@@ -75,23 +76,29 @@ UPB_INLINE envoy_config_rbac_v3_RBAC *envoy_config_rbac_v3_RBAC_parse(const char
   envoy_config_rbac_v3_RBAC *ret = envoy_config_rbac_v3_RBAC_new(arena);
   return (ret && upb_decode(buf, size, ret, &envoy_config_rbac_v3_RBAC_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE envoy_config_rbac_v3_RBAC *envoy_config_rbac_v3_RBAC_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  envoy_config_rbac_v3_RBAC *ret = envoy_config_rbac_v3_RBAC_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &envoy_config_rbac_v3_RBAC_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *envoy_config_rbac_v3_RBAC_serialize(const envoy_config_rbac_v3_RBAC *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &envoy_config_rbac_v3_RBAC_msginit, arena, len);
 }
 
 UPB_INLINE int32_t envoy_config_rbac_v3_RBAC_action(const envoy_config_rbac_v3_RBAC *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(0, 0), int32_t); }
-UPB_INLINE bool envoy_config_rbac_v3_RBAC_has_policies(const envoy_config_rbac_v3_RBAC *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(8, 8)); }
-UPB_INLINE size_t envoy_config_rbac_v3_RBAC_policies_size(const envoy_config_rbac_v3_RBAC *msg) {return _upb_msg_map_size(msg, UPB_SIZE(8, 8)); }
-UPB_INLINE bool envoy_config_rbac_v3_RBAC_policies_get(const envoy_config_rbac_v3_RBAC *msg, upb_strview key, envoy_config_rbac_v3_Policy* *val) { return _upb_msg_map_get(msg, UPB_SIZE(8, 8), &key, 0, val, sizeof(*val)); }
-UPB_INLINE const envoy_config_rbac_v3_RBAC_PoliciesEntry* envoy_config_rbac_v3_RBAC_policies_next(const envoy_config_rbac_v3_RBAC *msg, size_t* iter) { return (const envoy_config_rbac_v3_RBAC_PoliciesEntry*)_upb_msg_map_next(msg, UPB_SIZE(8, 8), iter); }
+UPB_INLINE bool envoy_config_rbac_v3_RBAC_has_policies(const envoy_config_rbac_v3_RBAC *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(4, 8)); }
+UPB_INLINE size_t envoy_config_rbac_v3_RBAC_policies_size(const envoy_config_rbac_v3_RBAC *msg) {return _upb_msg_map_size(msg, UPB_SIZE(4, 8)); }
+UPB_INLINE bool envoy_config_rbac_v3_RBAC_policies_get(const envoy_config_rbac_v3_RBAC *msg, upb_strview key, envoy_config_rbac_v3_Policy* *val) { return _upb_msg_map_get(msg, UPB_SIZE(4, 8), &key, 0, val, sizeof(*val)); }
+UPB_INLINE const envoy_config_rbac_v3_RBAC_PoliciesEntry* envoy_config_rbac_v3_RBAC_policies_next(const envoy_config_rbac_v3_RBAC *msg, size_t* iter) { return (const envoy_config_rbac_v3_RBAC_PoliciesEntry*)_upb_msg_map_next(msg, UPB_SIZE(4, 8), iter); }
 
 UPB_INLINE void envoy_config_rbac_v3_RBAC_set_action(envoy_config_rbac_v3_RBAC *msg, int32_t value) {
   *UPB_PTR_AT(msg, UPB_SIZE(0, 0), int32_t) = value;
 }
-UPB_INLINE void envoy_config_rbac_v3_RBAC_policies_clear(envoy_config_rbac_v3_RBAC *msg) { _upb_msg_map_clear(msg, UPB_SIZE(8, 8)); }
-UPB_INLINE bool envoy_config_rbac_v3_RBAC_policies_set(envoy_config_rbac_v3_RBAC *msg, upb_strview key, envoy_config_rbac_v3_Policy* val, upb_arena *a) { return _upb_msg_map_set(msg, UPB_SIZE(8, 8), &key, 0, &val, sizeof(val), a); }
-UPB_INLINE bool envoy_config_rbac_v3_RBAC_policies_delete(envoy_config_rbac_v3_RBAC *msg, upb_strview key) { return _upb_msg_map_delete(msg, UPB_SIZE(8, 8), &key, 0); }
-UPB_INLINE envoy_config_rbac_v3_RBAC_PoliciesEntry* envoy_config_rbac_v3_RBAC_policies_nextmutable(envoy_config_rbac_v3_RBAC *msg, size_t* iter) { return (envoy_config_rbac_v3_RBAC_PoliciesEntry*)_upb_msg_map_next(msg, UPB_SIZE(8, 8), iter); }
+UPB_INLINE void envoy_config_rbac_v3_RBAC_policies_clear(envoy_config_rbac_v3_RBAC *msg) { _upb_msg_map_clear(msg, UPB_SIZE(4, 8)); }
+UPB_INLINE bool envoy_config_rbac_v3_RBAC_policies_set(envoy_config_rbac_v3_RBAC *msg, upb_strview key, envoy_config_rbac_v3_Policy* val, upb_arena *a) { return _upb_msg_map_set(msg, UPB_SIZE(4, 8), &key, 0, &val, sizeof(val), a); }
+UPB_INLINE bool envoy_config_rbac_v3_RBAC_policies_delete(envoy_config_rbac_v3_RBAC *msg, upb_strview key) { return _upb_msg_map_delete(msg, UPB_SIZE(4, 8), &key, 0); }
+UPB_INLINE envoy_config_rbac_v3_RBAC_PoliciesEntry* envoy_config_rbac_v3_RBAC_policies_nextmutable(envoy_config_rbac_v3_RBAC *msg, size_t* iter) { return (envoy_config_rbac_v3_RBAC_PoliciesEntry*)_upb_msg_map_next(msg, UPB_SIZE(4, 8), iter); }
 
 /* envoy.config.rbac.v3.RBAC.PoliciesEntry */
 
@@ -121,47 +128,54 @@ UPB_INLINE envoy_config_rbac_v3_Policy *envoy_config_rbac_v3_Policy_parse(const
   envoy_config_rbac_v3_Policy *ret = envoy_config_rbac_v3_Policy_new(arena);
   return (ret && upb_decode(buf, size, ret, &envoy_config_rbac_v3_Policy_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE envoy_config_rbac_v3_Policy *envoy_config_rbac_v3_Policy_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  envoy_config_rbac_v3_Policy *ret = envoy_config_rbac_v3_Policy_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &envoy_config_rbac_v3_Policy_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *envoy_config_rbac_v3_Policy_serialize(const envoy_config_rbac_v3_Policy *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &envoy_config_rbac_v3_Policy_msginit, arena, len);
 }
 
-UPB_INLINE bool envoy_config_rbac_v3_Policy_has_permissions(const envoy_config_rbac_v3_Policy *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(8, 16)); }
-UPB_INLINE const envoy_config_rbac_v3_Permission* const* envoy_config_rbac_v3_Policy_permissions(const envoy_config_rbac_v3_Policy *msg, size_t *len) { return (const envoy_config_rbac_v3_Permission* const*)_upb_array_accessor(msg, UPB_SIZE(8, 16), len); }
-UPB_INLINE bool envoy_config_rbac_v3_Policy_has_principals(const envoy_config_rbac_v3_Policy *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(12, 24)); }
-UPB_INLINE const envoy_config_rbac_v3_Principal* const* envoy_config_rbac_v3_Policy_principals(const envoy_config_rbac_v3_Policy *msg, size_t *len) { return (const envoy_config_rbac_v3_Principal* const*)_upb_array_accessor(msg, UPB_SIZE(12, 24), len); }
-UPB_INLINE bool envoy_config_rbac_v3_Policy_has_condition(const envoy_config_rbac_v3_Policy *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(0, 0)); }
-UPB_INLINE const struct google_api_expr_v1alpha1_Expr* envoy_config_rbac_v3_Policy_condition(const envoy_config_rbac_v3_Policy *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(0, 0), const struct google_api_expr_v1alpha1_Expr*); }
-UPB_INLINE bool envoy_config_rbac_v3_Policy_has_checked_condition(const envoy_config_rbac_v3_Policy *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(4, 8)); }
-UPB_INLINE const struct google_api_expr_v1alpha1_CheckedExpr* envoy_config_rbac_v3_Policy_checked_condition(const envoy_config_rbac_v3_Policy *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(4, 8), const struct google_api_expr_v1alpha1_CheckedExpr*); }
+UPB_INLINE bool envoy_config_rbac_v3_Policy_has_permissions(const envoy_config_rbac_v3_Policy *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(12, 24)); }
+UPB_INLINE const envoy_config_rbac_v3_Permission* const* envoy_config_rbac_v3_Policy_permissions(const envoy_config_rbac_v3_Policy *msg, size_t *len) { return (const envoy_config_rbac_v3_Permission* const*)_upb_array_accessor(msg, UPB_SIZE(12, 24), len); }
+UPB_INLINE bool envoy_config_rbac_v3_Policy_has_principals(const envoy_config_rbac_v3_Policy *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(16, 32)); }
+UPB_INLINE const envoy_config_rbac_v3_Principal* const* envoy_config_rbac_v3_Policy_principals(const envoy_config_rbac_v3_Policy *msg, size_t *len) { return (const envoy_config_rbac_v3_Principal* const*)_upb_array_accessor(msg, UPB_SIZE(16, 32), len); }
+UPB_INLINE bool envoy_config_rbac_v3_Policy_has_condition(const envoy_config_rbac_v3_Policy *msg) { return _upb_hasbit(msg, 1); }
+UPB_INLINE const struct google_api_expr_v1alpha1_Expr* envoy_config_rbac_v3_Policy_condition(const envoy_config_rbac_v3_Policy *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(4, 8), const struct google_api_expr_v1alpha1_Expr*); }
+UPB_INLINE bool envoy_config_rbac_v3_Policy_has_checked_condition(const envoy_config_rbac_v3_Policy *msg) { return _upb_hasbit(msg, 2); }
+UPB_INLINE const struct google_api_expr_v1alpha1_CheckedExpr* envoy_config_rbac_v3_Policy_checked_condition(const envoy_config_rbac_v3_Policy *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(8, 16), const struct google_api_expr_v1alpha1_CheckedExpr*); }
 
 UPB_INLINE envoy_config_rbac_v3_Permission** envoy_config_rbac_v3_Policy_mutable_permissions(envoy_config_rbac_v3_Policy *msg, size_t *len) {
-  return (envoy_config_rbac_v3_Permission**)_upb_array_mutable_accessor(msg, UPB_SIZE(8, 16), len);
+  return (envoy_config_rbac_v3_Permission**)_upb_array_mutable_accessor(msg, UPB_SIZE(12, 24), len);
 }
 UPB_INLINE envoy_config_rbac_v3_Permission** envoy_config_rbac_v3_Policy_resize_permissions(envoy_config_rbac_v3_Policy *msg, size_t len, upb_arena *arena) {
-  return (envoy_config_rbac_v3_Permission**)_upb_array_resize_accessor(msg, UPB_SIZE(8, 16), len, UPB_TYPE_MESSAGE, arena);
+  return (envoy_config_rbac_v3_Permission**)_upb_array_resize_accessor2(msg, UPB_SIZE(12, 24), len, UPB_SIZE(2, 3), arena);
 }
 UPB_INLINE struct envoy_config_rbac_v3_Permission* envoy_config_rbac_v3_Policy_add_permissions(envoy_config_rbac_v3_Policy *msg, upb_arena *arena) {
   struct envoy_config_rbac_v3_Permission* sub = (struct envoy_config_rbac_v3_Permission*)_upb_msg_new(&envoy_config_rbac_v3_Permission_msginit, arena);
-  bool ok = _upb_array_append_accessor(
-      msg, UPB_SIZE(8, 16), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena);
+  bool ok = _upb_array_append_accessor2(
+      msg, UPB_SIZE(12, 24), UPB_SIZE(2, 3), &sub, arena);
   if (!ok) return NULL;
   return sub;
 }
 UPB_INLINE envoy_config_rbac_v3_Principal** envoy_config_rbac_v3_Policy_mutable_principals(envoy_config_rbac_v3_Policy *msg, size_t *len) {
-  return (envoy_config_rbac_v3_Principal**)_upb_array_mutable_accessor(msg, UPB_SIZE(12, 24), len);
+  return (envoy_config_rbac_v3_Principal**)_upb_array_mutable_accessor(msg, UPB_SIZE(16, 32), len);
 }
 UPB_INLINE envoy_config_rbac_v3_Principal** envoy_config_rbac_v3_Policy_resize_principals(envoy_config_rbac_v3_Policy *msg, size_t len, upb_arena *arena) {
-  return (envoy_config_rbac_v3_Principal**)_upb_array_resize_accessor(msg, UPB_SIZE(12, 24), len, UPB_TYPE_MESSAGE, arena);
+  return (envoy_config_rbac_v3_Principal**)_upb_array_resize_accessor2(msg, UPB_SIZE(16, 32), len, UPB_SIZE(2, 3), arena);
 }
 UPB_INLINE struct envoy_config_rbac_v3_Principal* envoy_config_rbac_v3_Policy_add_principals(envoy_config_rbac_v3_Policy *msg, upb_arena *arena) {
   struct envoy_config_rbac_v3_Principal* sub = (struct envoy_config_rbac_v3_Principal*)_upb_msg_new(&envoy_config_rbac_v3_Principal_msginit, arena);
-  bool ok = _upb_array_append_accessor(
-      msg, UPB_SIZE(12, 24), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena);
+  bool ok = _upb_array_append_accessor2(
+      msg, UPB_SIZE(16, 32), UPB_SIZE(2, 3), &sub, arena);
   if (!ok) return NULL;
   return sub;
 }
 UPB_INLINE void envoy_config_rbac_v3_Policy_set_condition(envoy_config_rbac_v3_Policy *msg, struct google_api_expr_v1alpha1_Expr* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(0, 0), struct google_api_expr_v1alpha1_Expr*) = value;
+  _upb_sethas(msg, 1);
+  *UPB_PTR_AT(msg, UPB_SIZE(4, 8), struct google_api_expr_v1alpha1_Expr*) = value;
 }
 UPB_INLINE struct google_api_expr_v1alpha1_Expr* envoy_config_rbac_v3_Policy_mutable_condition(envoy_config_rbac_v3_Policy *msg, upb_arena *arena) {
   struct google_api_expr_v1alpha1_Expr* sub = (struct google_api_expr_v1alpha1_Expr*)envoy_config_rbac_v3_Policy_condition(msg);
@@ -173,7 +187,8 @@ UPB_INLINE struct google_api_expr_v1alpha1_Expr* envoy_config_rbac_v3_Policy_mut
   return sub;
 }
 UPB_INLINE void envoy_config_rbac_v3_Policy_set_checked_condition(envoy_config_rbac_v3_Policy *msg, struct google_api_expr_v1alpha1_CheckedExpr* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(4, 8), struct google_api_expr_v1alpha1_CheckedExpr*) = value;
+  _upb_sethas(msg, 2);
+  *UPB_PTR_AT(msg, UPB_SIZE(8, 16), struct google_api_expr_v1alpha1_CheckedExpr*) = value;
 }
 UPB_INLINE struct google_api_expr_v1alpha1_CheckedExpr* envoy_config_rbac_v3_Policy_mutable_checked_condition(envoy_config_rbac_v3_Policy *msg, upb_arena *arena) {
   struct google_api_expr_v1alpha1_CheckedExpr* sub = (struct google_api_expr_v1alpha1_CheckedExpr*)envoy_config_rbac_v3_Policy_checked_condition(msg);
@@ -195,6 +210,12 @@ UPB_INLINE envoy_config_rbac_v3_Permission *envoy_config_rbac_v3_Permission_pars
   envoy_config_rbac_v3_Permission *ret = envoy_config_rbac_v3_Permission_new(arena);
   return (ret && upb_decode(buf, size, ret, &envoy_config_rbac_v3_Permission_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE envoy_config_rbac_v3_Permission *envoy_config_rbac_v3_Permission_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  envoy_config_rbac_v3_Permission *ret = envoy_config_rbac_v3_Permission_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &envoy_config_rbac_v3_Permission_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *envoy_config_rbac_v3_Permission_serialize(const envoy_config_rbac_v3_Permission *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &envoy_config_rbac_v3_Permission_msginit, arena, len);
 }
@@ -348,6 +369,12 @@ UPB_INLINE envoy_config_rbac_v3_Permission_Set *envoy_config_rbac_v3_Permission_
   envoy_config_rbac_v3_Permission_Set *ret = envoy_config_rbac_v3_Permission_Set_new(arena);
   return (ret && upb_decode(buf, size, ret, &envoy_config_rbac_v3_Permission_Set_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE envoy_config_rbac_v3_Permission_Set *envoy_config_rbac_v3_Permission_Set_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  envoy_config_rbac_v3_Permission_Set *ret = envoy_config_rbac_v3_Permission_Set_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &envoy_config_rbac_v3_Permission_Set_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *envoy_config_rbac_v3_Permission_Set_serialize(const envoy_config_rbac_v3_Permission_Set *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &envoy_config_rbac_v3_Permission_Set_msginit, arena, len);
 }
@@ -359,12 +386,12 @@ UPB_INLINE envoy_config_rbac_v3_Permission** envoy_config_rbac_v3_Permission_Set
   return (envoy_config_rbac_v3_Permission**)_upb_array_mutable_accessor(msg, UPB_SIZE(0, 0), len);
 }
 UPB_INLINE envoy_config_rbac_v3_Permission** envoy_config_rbac_v3_Permission_Set_resize_rules(envoy_config_rbac_v3_Permission_Set *msg, size_t len, upb_arena *arena) {
-  return (envoy_config_rbac_v3_Permission**)_upb_array_resize_accessor(msg, UPB_SIZE(0, 0), len, UPB_TYPE_MESSAGE, arena);
+  return (envoy_config_rbac_v3_Permission**)_upb_array_resize_accessor2(msg, UPB_SIZE(0, 0), len, UPB_SIZE(2, 3), arena);
 }
 UPB_INLINE struct envoy_config_rbac_v3_Permission* envoy_config_rbac_v3_Permission_Set_add_rules(envoy_config_rbac_v3_Permission_Set *msg, upb_arena *arena) {
   struct envoy_config_rbac_v3_Permission* sub = (struct envoy_config_rbac_v3_Permission*)_upb_msg_new(&envoy_config_rbac_v3_Permission_msginit, arena);
-  bool ok = _upb_array_append_accessor(
-      msg, UPB_SIZE(0, 0), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena);
+  bool ok = _upb_array_append_accessor2(
+      msg, UPB_SIZE(0, 0), UPB_SIZE(2, 3), &sub, arena);
   if (!ok) return NULL;
   return sub;
 }
@@ -379,6 +406,12 @@ UPB_INLINE envoy_config_rbac_v3_Principal *envoy_config_rbac_v3_Principal_parse(
   envoy_config_rbac_v3_Principal *ret = envoy_config_rbac_v3_Principal_new(arena);
   return (ret && upb_decode(buf, size, ret, &envoy_config_rbac_v3_Principal_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE envoy_config_rbac_v3_Principal *envoy_config_rbac_v3_Principal_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  envoy_config_rbac_v3_Principal *ret = envoy_config_rbac_v3_Principal_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &envoy_config_rbac_v3_Principal_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *envoy_config_rbac_v3_Principal_serialize(const envoy_config_rbac_v3_Principal *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &envoy_config_rbac_v3_Principal_msginit, arena, len);
 }
@@ -556,6 +589,12 @@ UPB_INLINE envoy_config_rbac_v3_Principal_Set *envoy_config_rbac_v3_Principal_Se
   envoy_config_rbac_v3_Principal_Set *ret = envoy_config_rbac_v3_Principal_Set_new(arena);
   return (ret && upb_decode(buf, size, ret, &envoy_config_rbac_v3_Principal_Set_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE envoy_config_rbac_v3_Principal_Set *envoy_config_rbac_v3_Principal_Set_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  envoy_config_rbac_v3_Principal_Set *ret = envoy_config_rbac_v3_Principal_Set_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &envoy_config_rbac_v3_Principal_Set_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *envoy_config_rbac_v3_Principal_Set_serialize(const envoy_config_rbac_v3_Principal_Set *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &envoy_config_rbac_v3_Principal_Set_msginit, arena, len);
 }
@@ -567,12 +606,12 @@ UPB_INLINE envoy_config_rbac_v3_Principal** envoy_config_rbac_v3_Principal_Set_m
   return (envoy_config_rbac_v3_Principal**)_upb_array_mutable_accessor(msg, UPB_SIZE(0, 0), len);
 }
 UPB_INLINE envoy_config_rbac_v3_Principal** envoy_config_rbac_v3_Principal_Set_resize_ids(envoy_config_rbac_v3_Principal_Set *msg, size_t len, upb_arena *arena) {
-  return (envoy_config_rbac_v3_Principal**)_upb_array_resize_accessor(msg, UPB_SIZE(0, 0), len, UPB_TYPE_MESSAGE, arena);
+  return (envoy_config_rbac_v3_Principal**)_upb_array_resize_accessor2(msg, UPB_SIZE(0, 0), len, UPB_SIZE(2, 3), arena);
 }
 UPB_INLINE struct envoy_config_rbac_v3_Principal* envoy_config_rbac_v3_Principal_Set_add_ids(envoy_config_rbac_v3_Principal_Set *msg, upb_arena *arena) {
   struct envoy_config_rbac_v3_Principal* sub = (struct envoy_config_rbac_v3_Principal*)_upb_msg_new(&envoy_config_rbac_v3_Principal_msginit, arena);
-  bool ok = _upb_array_append_accessor(
-      msg, UPB_SIZE(0, 0), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena);
+  bool ok = _upb_array_append_accessor2(
+      msg, UPB_SIZE(0, 0), UPB_SIZE(2, 3), &sub, arena);
   if (!ok) return NULL;
   return sub;
 }
@@ -587,15 +626,22 @@ UPB_INLINE envoy_config_rbac_v3_Principal_Authenticated *envoy_config_rbac_v3_Pr
   envoy_config_rbac_v3_Principal_Authenticated *ret = envoy_config_rbac_v3_Principal_Authenticated_new(arena);
   return (ret && upb_decode(buf, size, ret, &envoy_config_rbac_v3_Principal_Authenticated_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE envoy_config_rbac_v3_Principal_Authenticated *envoy_config_rbac_v3_Principal_Authenticated_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  envoy_config_rbac_v3_Principal_Authenticated *ret = envoy_config_rbac_v3_Principal_Authenticated_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &envoy_config_rbac_v3_Principal_Authenticated_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *envoy_config_rbac_v3_Principal_Authenticated_serialize(const envoy_config_rbac_v3_Principal_Authenticated *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &envoy_config_rbac_v3_Principal_Authenticated_msginit, arena, len);
 }
 
-UPB_INLINE bool envoy_config_rbac_v3_Principal_Authenticated_has_principal_name(const envoy_config_rbac_v3_Principal_Authenticated *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(0, 0)); }
-UPB_INLINE const struct envoy_type_matcher_v3_StringMatcher* envoy_config_rbac_v3_Principal_Authenticated_principal_name(const envoy_config_rbac_v3_Principal_Authenticated *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(0, 0), const struct envoy_type_matcher_v3_StringMatcher*); }
+UPB_INLINE bool envoy_config_rbac_v3_Principal_Authenticated_has_principal_name(const envoy_config_rbac_v3_Principal_Authenticated *msg) { return _upb_hasbit(msg, 1); }
+UPB_INLINE const struct envoy_type_matcher_v3_StringMatcher* envoy_config_rbac_v3_Principal_Authenticated_principal_name(const envoy_config_rbac_v3_Principal_Authenticated *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(4, 8), const struct envoy_type_matcher_v3_StringMatcher*); }
 
 UPB_INLINE void envoy_config_rbac_v3_Principal_Authenticated_set_principal_name(envoy_config_rbac_v3_Principal_Authenticated *msg, struct envoy_type_matcher_v3_StringMatcher* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(0, 0), struct envoy_type_matcher_v3_StringMatcher*) = value;
+  _upb_sethas(msg, 1);
+  *UPB_PTR_AT(msg, UPB_SIZE(4, 8), struct envoy_type_matcher_v3_StringMatcher*) = value;
 }
 UPB_INLINE struct envoy_type_matcher_v3_StringMatcher* envoy_config_rbac_v3_Principal_Authenticated_mutable_principal_name(envoy_config_rbac_v3_Principal_Authenticated *msg, upb_arena *arena) {
   struct envoy_type_matcher_v3_StringMatcher* sub = (struct envoy_type_matcher_v3_StringMatcher*)envoy_config_rbac_v3_Principal_Authenticated_principal_name(msg);
index 6ad2442..22e259c 100644 (file)
@@ -19,7 +19,7 @@
 
 #include "upb/port_def.inc"
 
-static const upb_msglayout *const envoy_config_route_v3_RouteConfiguration_submsgs[5] = {
+static const upb_msglayout *const envoy_config_route_v3_RouteConfiguration_submsgs[4] = {
   &envoy_config_core_v3_HeaderValueOption_msginit,
   &envoy_config_route_v3_Vhds_msginit,
   &envoy_config_route_v3_VirtualHost_msginit,
@@ -33,16 +33,16 @@ static const upb_msglayout_field envoy_config_route_v3_RouteConfiguration__field
   {4, UPB_SIZE(28, 56), 0, 0, 11, 3},
   {5, UPB_SIZE(32, 64), 0, 0, 9, 3},
   {6, UPB_SIZE(36, 72), 0, 0, 11, 3},
-  {7, UPB_SIZE(12, 24), 0, 3, 11, 1},
+  {7, UPB_SIZE(12, 24), 1, 3, 11, 1},
   {8, UPB_SIZE(40, 80), 0, 0, 9, 3},
-  {9, UPB_SIZE(16, 32), 0, 1, 11, 1},
-  {10, UPB_SIZE(0, 0), 0, 0, 8, 1},
+  {9, UPB_SIZE(16, 32), 2, 1, 11, 1},
+  {10, UPB_SIZE(1, 1), 0, 0, 8, 1},
 };
 
 const upb_msglayout envoy_config_route_v3_RouteConfiguration_msginit = {
   &envoy_config_route_v3_RouteConfiguration_submsgs[0],
   &envoy_config_route_v3_RouteConfiguration__fields[0],
-  UPB_SIZE(48, 96), 10, false,
+  UPB_SIZE(48, 96), 10, false, 255,
 };
 
 static const upb_msglayout *const envoy_config_route_v3_Vhds_submsgs[1] = {
@@ -50,13 +50,13 @@ static const upb_msglayout *const envoy_config_route_v3_Vhds_submsgs[1] = {
 };
 
 static const upb_msglayout_field envoy_config_route_v3_Vhds__fields[1] = {
-  {1, UPB_SIZE(0, 0), 0, 0, 11, 1},
+  {1, UPB_SIZE(4, 8), 1, 0, 11, 1},
 };
 
 const upb_msglayout envoy_config_route_v3_Vhds_msginit = {
   &envoy_config_route_v3_Vhds_submsgs[0],
   &envoy_config_route_v3_Vhds__fields[0],
-  UPB_SIZE(4, 8), 1, false,
+  UPB_SIZE(8, 16), 1, false, 255,
 };
 
 #include "upb/port_undef.inc"
index 4e5adc0..461e8c8 100644 (file)
@@ -11,6 +11,7 @@
 
 #include "upb/msg.h"
 #include "upb/decode.h"
+#include "upb/decode_fast.h"
 #include "upb/encode.h"
 
 #include "upb/port_def.inc"
@@ -45,6 +46,12 @@ UPB_INLINE envoy_config_route_v3_RouteConfiguration *envoy_config_route_v3_Route
   envoy_config_route_v3_RouteConfiguration *ret = envoy_config_route_v3_RouteConfiguration_new(arena);
   return (ret && upb_decode(buf, size, ret, &envoy_config_route_v3_RouteConfiguration_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE envoy_config_route_v3_RouteConfiguration *envoy_config_route_v3_RouteConfiguration_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  envoy_config_route_v3_RouteConfiguration *ret = envoy_config_route_v3_RouteConfiguration_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &envoy_config_route_v3_RouteConfiguration_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *envoy_config_route_v3_RouteConfiguration_serialize(const envoy_config_route_v3_RouteConfiguration *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &envoy_config_route_v3_RouteConfiguration_msginit, arena, len);
 }
@@ -58,12 +65,12 @@ UPB_INLINE const struct envoy_config_core_v3_HeaderValueOption* const* envoy_con
 UPB_INLINE upb_strview const* envoy_config_route_v3_RouteConfiguration_response_headers_to_remove(const envoy_config_route_v3_RouteConfiguration *msg, size_t *len) { return (upb_strview const*)_upb_array_accessor(msg, UPB_SIZE(32, 64), len); }
 UPB_INLINE bool envoy_config_route_v3_RouteConfiguration_has_request_headers_to_add(const envoy_config_route_v3_RouteConfiguration *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(36, 72)); }
 UPB_INLINE const struct envoy_config_core_v3_HeaderValueOption* const* envoy_config_route_v3_RouteConfiguration_request_headers_to_add(const envoy_config_route_v3_RouteConfiguration *msg, size_t *len) { return (const struct envoy_config_core_v3_HeaderValueOption* const*)_upb_array_accessor(msg, UPB_SIZE(36, 72), len); }
-UPB_INLINE bool envoy_config_route_v3_RouteConfiguration_has_validate_clusters(const envoy_config_route_v3_RouteConfiguration *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(12, 24)); }
+UPB_INLINE bool envoy_config_route_v3_RouteConfiguration_has_validate_clusters(const envoy_config_route_v3_RouteConfiguration *msg) { return _upb_hasbit(msg, 1); }
 UPB_INLINE const struct google_protobuf_BoolValue* envoy_config_route_v3_RouteConfiguration_validate_clusters(const envoy_config_route_v3_RouteConfiguration *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(12, 24), const struct google_protobuf_BoolValue*); }
 UPB_INLINE upb_strview const* envoy_config_route_v3_RouteConfiguration_request_headers_to_remove(const envoy_config_route_v3_RouteConfiguration *msg, size_t *len) { return (upb_strview const*)_upb_array_accessor(msg, UPB_SIZE(40, 80), len); }
-UPB_INLINE bool envoy_config_route_v3_RouteConfiguration_has_vhds(const envoy_config_route_v3_RouteConfiguration *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(16, 32)); }
+UPB_INLINE bool envoy_config_route_v3_RouteConfiguration_has_vhds(const envoy_config_route_v3_RouteConfiguration *msg) { return _upb_hasbit(msg, 2); }
 UPB_INLINE const envoy_config_route_v3_Vhds* envoy_config_route_v3_RouteConfiguration_vhds(const envoy_config_route_v3_RouteConfiguration *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(16, 32), const envoy_config_route_v3_Vhds*); }
-UPB_INLINE bool envoy_config_route_v3_RouteConfiguration_most_specific_header_mutations_wins(const envoy_config_route_v3_RouteConfiguration *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(0, 0), bool); }
+UPB_INLINE bool envoy_config_route_v3_RouteConfiguration_most_specific_header_mutations_wins(const envoy_config_route_v3_RouteConfiguration *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(1, 1), bool); }
 
 UPB_INLINE void envoy_config_route_v3_RouteConfiguration_set_name(envoy_config_route_v3_RouteConfiguration *msg, upb_strview value) {
   *UPB_PTR_AT(msg, UPB_SIZE(4, 8), upb_strview) = value;
@@ -72,12 +79,12 @@ UPB_INLINE struct envoy_config_route_v3_VirtualHost** envoy_config_route_v3_Rout
   return (struct envoy_config_route_v3_VirtualHost**)_upb_array_mutable_accessor(msg, UPB_SIZE(20, 40), len);
 }
 UPB_INLINE struct envoy_config_route_v3_VirtualHost** envoy_config_route_v3_RouteConfiguration_resize_virtual_hosts(envoy_config_route_v3_RouteConfiguration *msg, size_t len, upb_arena *arena) {
-  return (struct envoy_config_route_v3_VirtualHost**)_upb_array_resize_accessor(msg, UPB_SIZE(20, 40), len, UPB_TYPE_MESSAGE, arena);
+  return (struct envoy_config_route_v3_VirtualHost**)_upb_array_resize_accessor2(msg, UPB_SIZE(20, 40), len, UPB_SIZE(2, 3), arena);
 }
 UPB_INLINE struct envoy_config_route_v3_VirtualHost* envoy_config_route_v3_RouteConfiguration_add_virtual_hosts(envoy_config_route_v3_RouteConfiguration *msg, upb_arena *arena) {
   struct envoy_config_route_v3_VirtualHost* sub = (struct envoy_config_route_v3_VirtualHost*)_upb_msg_new(&envoy_config_route_v3_VirtualHost_msginit, arena);
-  bool ok = _upb_array_append_accessor(
-      msg, UPB_SIZE(20, 40), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena);
+  bool ok = _upb_array_append_accessor2(
+      msg, UPB_SIZE(20, 40), UPB_SIZE(2, 3), &sub, arena);
   if (!ok) return NULL;
   return sub;
 }
@@ -85,22 +92,22 @@ UPB_INLINE upb_strview* envoy_config_route_v3_RouteConfiguration_mutable_interna
   return (upb_strview*)_upb_array_mutable_accessor(msg, UPB_SIZE(24, 48), len);
 }
 UPB_INLINE upb_strview* envoy_config_route_v3_RouteConfiguration_resize_internal_only_headers(envoy_config_route_v3_RouteConfiguration *msg, size_t len, upb_arena *arena) {
-  return (upb_strview*)_upb_array_resize_accessor(msg, UPB_SIZE(24, 48), len, UPB_TYPE_STRING, arena);
+  return (upb_strview*)_upb_array_resize_accessor2(msg, UPB_SIZE(24, 48), len, UPB_SIZE(3, 4), arena);
 }
 UPB_INLINE bool envoy_config_route_v3_RouteConfiguration_add_internal_only_headers(envoy_config_route_v3_RouteConfiguration *msg, upb_strview val, upb_arena *arena) {
-  return _upb_array_append_accessor(msg, UPB_SIZE(24, 48), UPB_SIZE(8, 16), UPB_TYPE_STRING, &val,
+  return _upb_array_append_accessor2(msg, UPB_SIZE(24, 48), UPB_SIZE(3, 4), &val,
       arena);
 }
 UPB_INLINE struct envoy_config_core_v3_HeaderValueOption** envoy_config_route_v3_RouteConfiguration_mutable_response_headers_to_add(envoy_config_route_v3_RouteConfiguration *msg, size_t *len) {
   return (struct envoy_config_core_v3_HeaderValueOption**)_upb_array_mutable_accessor(msg, UPB_SIZE(28, 56), len);
 }
 UPB_INLINE struct envoy_config_core_v3_HeaderValueOption** envoy_config_route_v3_RouteConfiguration_resize_response_headers_to_add(envoy_config_route_v3_RouteConfiguration *msg, size_t len, upb_arena *arena) {
-  return (struct envoy_config_core_v3_HeaderValueOption**)_upb_array_resize_accessor(msg, UPB_SIZE(28, 56), len, UPB_TYPE_MESSAGE, arena);
+  return (struct envoy_config_core_v3_HeaderValueOption**)_upb_array_resize_accessor2(msg, UPB_SIZE(28, 56), len, UPB_SIZE(2, 3), arena);
 }
 UPB_INLINE struct envoy_config_core_v3_HeaderValueOption* envoy_config_route_v3_RouteConfiguration_add_response_headers_to_add(envoy_config_route_v3_RouteConfiguration *msg, upb_arena *arena) {
   struct envoy_config_core_v3_HeaderValueOption* sub = (struct envoy_config_core_v3_HeaderValueOption*)_upb_msg_new(&envoy_config_core_v3_HeaderValueOption_msginit, arena);
-  bool ok = _upb_array_append_accessor(
-      msg, UPB_SIZE(28, 56), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena);
+  bool ok = _upb_array_append_accessor2(
+      msg, UPB_SIZE(28, 56), UPB_SIZE(2, 3), &sub, arena);
   if (!ok) return NULL;
   return sub;
 }
@@ -108,26 +115,27 @@ UPB_INLINE upb_strview* envoy_config_route_v3_RouteConfiguration_mutable_respons
   return (upb_strview*)_upb_array_mutable_accessor(msg, UPB_SIZE(32, 64), len);
 }
 UPB_INLINE upb_strview* envoy_config_route_v3_RouteConfiguration_resize_response_headers_to_remove(envoy_config_route_v3_RouteConfiguration *msg, size_t len, upb_arena *arena) {
-  return (upb_strview*)_upb_array_resize_accessor(msg, UPB_SIZE(32, 64), len, UPB_TYPE_STRING, arena);
+  return (upb_strview*)_upb_array_resize_accessor2(msg, UPB_SIZE(32, 64), len, UPB_SIZE(3, 4), arena);
 }
 UPB_INLINE bool envoy_config_route_v3_RouteConfiguration_add_response_headers_to_remove(envoy_config_route_v3_RouteConfiguration *msg, upb_strview val, upb_arena *arena) {
-  return _upb_array_append_accessor(msg, UPB_SIZE(32, 64), UPB_SIZE(8, 16), UPB_TYPE_STRING, &val,
+  return _upb_array_append_accessor2(msg, UPB_SIZE(32, 64), UPB_SIZE(3, 4), &val,
       arena);
 }
 UPB_INLINE struct envoy_config_core_v3_HeaderValueOption** envoy_config_route_v3_RouteConfiguration_mutable_request_headers_to_add(envoy_config_route_v3_RouteConfiguration *msg, size_t *len) {
   return (struct envoy_config_core_v3_HeaderValueOption**)_upb_array_mutable_accessor(msg, UPB_SIZE(36, 72), len);
 }
 UPB_INLINE struct envoy_config_core_v3_HeaderValueOption** envoy_config_route_v3_RouteConfiguration_resize_request_headers_to_add(envoy_config_route_v3_RouteConfiguration *msg, size_t len, upb_arena *arena) {
-  return (struct envoy_config_core_v3_HeaderValueOption**)_upb_array_resize_accessor(msg, UPB_SIZE(36, 72), len, UPB_TYPE_MESSAGE, arena);
+  return (struct envoy_config_core_v3_HeaderValueOption**)_upb_array_resize_accessor2(msg, UPB_SIZE(36, 72), len, UPB_SIZE(2, 3), arena);
 }
 UPB_INLINE struct envoy_config_core_v3_HeaderValueOption* envoy_config_route_v3_RouteConfiguration_add_request_headers_to_add(envoy_config_route_v3_RouteConfiguration *msg, upb_arena *arena) {
   struct envoy_config_core_v3_HeaderValueOption* sub = (struct envoy_config_core_v3_HeaderValueOption*)_upb_msg_new(&envoy_config_core_v3_HeaderValueOption_msginit, arena);
-  bool ok = _upb_array_append_accessor(
-      msg, UPB_SIZE(36, 72), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena);
+  bool ok = _upb_array_append_accessor2(
+      msg, UPB_SIZE(36, 72), UPB_SIZE(2, 3), &sub, arena);
   if (!ok) return NULL;
   return sub;
 }
 UPB_INLINE void envoy_config_route_v3_RouteConfiguration_set_validate_clusters(envoy_config_route_v3_RouteConfiguration *msg, struct google_protobuf_BoolValue* value) {
+  _upb_sethas(msg, 1);
   *UPB_PTR_AT(msg, UPB_SIZE(12, 24), struct google_protobuf_BoolValue*) = value;
 }
 UPB_INLINE struct google_protobuf_BoolValue* envoy_config_route_v3_RouteConfiguration_mutable_validate_clusters(envoy_config_route_v3_RouteConfiguration *msg, upb_arena *arena) {
@@ -143,13 +151,14 @@ UPB_INLINE upb_strview* envoy_config_route_v3_RouteConfiguration_mutable_request
   return (upb_strview*)_upb_array_mutable_accessor(msg, UPB_SIZE(40, 80), len);
 }
 UPB_INLINE upb_strview* envoy_config_route_v3_RouteConfiguration_resize_request_headers_to_remove(envoy_config_route_v3_RouteConfiguration *msg, size_t len, upb_arena *arena) {
-  return (upb_strview*)_upb_array_resize_accessor(msg, UPB_SIZE(40, 80), len, UPB_TYPE_STRING, arena);
+  return (upb_strview*)_upb_array_resize_accessor2(msg, UPB_SIZE(40, 80), len, UPB_SIZE(3, 4), arena);
 }
 UPB_INLINE bool envoy_config_route_v3_RouteConfiguration_add_request_headers_to_remove(envoy_config_route_v3_RouteConfiguration *msg, upb_strview val, upb_arena *arena) {
-  return _upb_array_append_accessor(msg, UPB_SIZE(40, 80), UPB_SIZE(8, 16), UPB_TYPE_STRING, &val,
+  return _upb_array_append_accessor2(msg, UPB_SIZE(40, 80), UPB_SIZE(3, 4), &val,
       arena);
 }
 UPB_INLINE void envoy_config_route_v3_RouteConfiguration_set_vhds(envoy_config_route_v3_RouteConfiguration *msg, envoy_config_route_v3_Vhds* value) {
+  _upb_sethas(msg, 2);
   *UPB_PTR_AT(msg, UPB_SIZE(16, 32), envoy_config_route_v3_Vhds*) = value;
 }
 UPB_INLINE struct envoy_config_route_v3_Vhds* envoy_config_route_v3_RouteConfiguration_mutable_vhds(envoy_config_route_v3_RouteConfiguration *msg, upb_arena *arena) {
@@ -162,7 +171,7 @@ UPB_INLINE struct envoy_config_route_v3_Vhds* envoy_config_route_v3_RouteConfigu
   return sub;
 }
 UPB_INLINE void envoy_config_route_v3_RouteConfiguration_set_most_specific_header_mutations_wins(envoy_config_route_v3_RouteConfiguration *msg, bool value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(0, 0), bool) = value;
+  *UPB_PTR_AT(msg, UPB_SIZE(1, 1), bool) = value;
 }
 
 /* envoy.config.route.v3.Vhds */
@@ -175,15 +184,22 @@ UPB_INLINE envoy_config_route_v3_Vhds *envoy_config_route_v3_Vhds_parse(const ch
   envoy_config_route_v3_Vhds *ret = envoy_config_route_v3_Vhds_new(arena);
   return (ret && upb_decode(buf, size, ret, &envoy_config_route_v3_Vhds_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE envoy_config_route_v3_Vhds *envoy_config_route_v3_Vhds_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  envoy_config_route_v3_Vhds *ret = envoy_config_route_v3_Vhds_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &envoy_config_route_v3_Vhds_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *envoy_config_route_v3_Vhds_serialize(const envoy_config_route_v3_Vhds *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &envoy_config_route_v3_Vhds_msginit, arena, len);
 }
 
-UPB_INLINE bool envoy_config_route_v3_Vhds_has_config_source(const envoy_config_route_v3_Vhds *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(0, 0)); }
-UPB_INLINE const struct envoy_config_core_v3_ConfigSource* envoy_config_route_v3_Vhds_config_source(const envoy_config_route_v3_Vhds *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(0, 0), const struct envoy_config_core_v3_ConfigSource*); }
+UPB_INLINE bool envoy_config_route_v3_Vhds_has_config_source(const envoy_config_route_v3_Vhds *msg) { return _upb_hasbit(msg, 1); }
+UPB_INLINE const struct envoy_config_core_v3_ConfigSource* envoy_config_route_v3_Vhds_config_source(const envoy_config_route_v3_Vhds *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(4, 8), const struct envoy_config_core_v3_ConfigSource*); }
 
 UPB_INLINE void envoy_config_route_v3_Vhds_set_config_source(envoy_config_route_v3_Vhds *msg, struct envoy_config_core_v3_ConfigSource* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(0, 0), struct envoy_config_core_v3_ConfigSource*) = value;
+  _upb_sethas(msg, 1);
+  *UPB_PTR_AT(msg, UPB_SIZE(4, 8), struct envoy_config_core_v3_ConfigSource*) = value;
 }
 UPB_INLINE struct envoy_config_core_v3_ConfigSource* envoy_config_route_v3_Vhds_mutable_config_source(envoy_config_route_v3_Vhds *msg, upb_arena *arena) {
   struct envoy_config_core_v3_ConfigSource* sub = (struct envoy_config_core_v3_ConfigSource*)envoy_config_route_v3_Vhds_config_source(msg);
index 8f1675c..61efffb 100644 (file)
@@ -30,7 +30,7 @@
 
 #include "upb/port_def.inc"
 
-static const upb_msglayout *const envoy_config_route_v3_VirtualHost_submsgs[11] = {
+static const upb_msglayout *const envoy_config_route_v3_VirtualHost_submsgs[10] = {
   &envoy_config_core_v3_HeaderValueOption_msginit,
   &envoy_config_route_v3_CorsPolicy_msginit,
   &envoy_config_route_v3_HedgePolicy_msginit,
@@ -47,27 +47,27 @@ static const upb_msglayout_field envoy_config_route_v3_VirtualHost__fields[18] =
   {1, UPB_SIZE(12, 16), 0, 0, 9, 1},
   {2, UPB_SIZE(40, 72), 0, 0, 9, 3},
   {3, UPB_SIZE(44, 80), 0, 5, 11, 3},
-  {4, UPB_SIZE(0, 0), 0, 0, 14, 1},
+  {4, UPB_SIZE(4, 4), 0, 0, 14, 1},
   {5, UPB_SIZE(48, 88), 0, 6, 11, 3},
   {6, UPB_SIZE(52, 96), 0, 3, 11, 3},
   {7, UPB_SIZE(56, 104), 0, 0, 11, 3},
-  {8, UPB_SIZE(20, 32), 0, 1, 11, 1},
+  {8, UPB_SIZE(20, 32), 1, 1, 11, 1},
   {10, UPB_SIZE(60, 112), 0, 0, 11, 3},
   {11, UPB_SIZE(64, 120), 0, 0, 9, 3},
   {13, UPB_SIZE(68, 128), 0, 0, 9, 3},
   {14, UPB_SIZE(8, 8), 0, 0, 8, 1},
   {15, UPB_SIZE(72, 136), 0, 7, 11, _UPB_LABEL_MAP},
-  {16, UPB_SIZE(24, 40), 0, 4, 11, 1},
-  {17, UPB_SIZE(28, 48), 0, 2, 11, 1},
-  {18, UPB_SIZE(32, 56), 0, 9, 11, 1},
+  {16, UPB_SIZE(24, 40), 2, 4, 11, 1},
+  {17, UPB_SIZE(28, 48), 3, 2, 11, 1},
+  {18, UPB_SIZE(32, 56), 4, 9, 11, 1},
   {19, UPB_SIZE(9, 9), 0, 0, 8, 1},
-  {20, UPB_SIZE(36, 64), 0, 8, 11, 1},
+  {20, UPB_SIZE(36, 64), 5, 8, 11, 1},
 };
 
 const upb_msglayout envoy_config_route_v3_VirtualHost_msginit = {
   &envoy_config_route_v3_VirtualHost_submsgs[0],
   &envoy_config_route_v3_VirtualHost__fields[0],
-  UPB_SIZE(80, 144), 18, false,
+  UPB_SIZE(80, 144), 18, false, 255,
 };
 
 static const upb_msglayout *const envoy_config_route_v3_VirtualHost_TypedPerFilterConfigEntry_submsgs[1] = {
@@ -82,7 +82,7 @@ static const upb_msglayout_field envoy_config_route_v3_VirtualHost_TypedPerFilte
 const upb_msglayout envoy_config_route_v3_VirtualHost_TypedPerFilterConfigEntry_msginit = {
   &envoy_config_route_v3_VirtualHost_TypedPerFilterConfigEntry_submsgs[0],
   &envoy_config_route_v3_VirtualHost_TypedPerFilterConfigEntry__fields[0],
-  UPB_SIZE(16, 32), 2, false,
+  UPB_SIZE(16, 32), 2, false, 255,
 };
 
 static const upb_msglayout *const envoy_config_route_v3_FilterAction_submsgs[1] = {
@@ -90,16 +90,16 @@ static const upb_msglayout *const envoy_config_route_v3_FilterAction_submsgs[1]
 };
 
 static const upb_msglayout_field envoy_config_route_v3_FilterAction__fields[1] = {
-  {1, UPB_SIZE(0, 0), 0, 0, 11, 1},
+  {1, UPB_SIZE(4, 8), 1, 0, 11, 1},
 };
 
 const upb_msglayout envoy_config_route_v3_FilterAction_msginit = {
   &envoy_config_route_v3_FilterAction_submsgs[0],
   &envoy_config_route_v3_FilterAction__fields[0],
-  UPB_SIZE(4, 8), 1, false,
+  UPB_SIZE(8, 16), 1, false, 255,
 };
 
-static const upb_msglayout *const envoy_config_route_v3_Route_submsgs[12] = {
+static const upb_msglayout *const envoy_config_route_v3_Route_submsgs[11] = {
   &envoy_config_core_v3_HeaderValueOption_msginit,
   &envoy_config_core_v3_Metadata_msginit,
   &envoy_config_route_v3_Decorator_msginit,
@@ -114,27 +114,27 @@ static const upb_msglayout *const envoy_config_route_v3_Route_submsgs[12] = {
 };
 
 static const upb_msglayout_field envoy_config_route_v3_Route__fields[15] = {
-  {1, UPB_SIZE(8, 16), 0, 8, 11, 1},
-  {2, UPB_SIZE(48, 96), UPB_SIZE(-53, -105), 7, 11, 1},
-  {3, UPB_SIZE(48, 96), UPB_SIZE(-53, -105), 5, 11, 1},
-  {4, UPB_SIZE(12, 24), 0, 1, 11, 1},
-  {5, UPB_SIZE(16, 32), 0, 2, 11, 1},
-  {7, UPB_SIZE(48, 96), UPB_SIZE(-53, -105), 3, 11, 1},
-  {9, UPB_SIZE(28, 56), 0, 0, 11, 3},
-  {10, UPB_SIZE(32, 64), 0, 0, 11, 3},
-  {11, UPB_SIZE(36, 72), 0, 0, 9, 3},
-  {12, UPB_SIZE(40, 80), 0, 0, 9, 3},
-  {13, UPB_SIZE(44, 88), 0, 6, 11, _UPB_LABEL_MAP},
-  {14, UPB_SIZE(0, 0), 0, 0, 9, 1},
-  {15, UPB_SIZE(20, 40), 0, 9, 11, 1},
-  {16, UPB_SIZE(24, 48), 0, 10, 11, 1},
-  {17, UPB_SIZE(48, 96), UPB_SIZE(-53, -105), 4, 11, 1},
+  {1, UPB_SIZE(12, 24), 1, 8, 11, 1},
+  {2, UPB_SIZE(52, 104), UPB_SIZE(-57, -113), 7, 11, 1},
+  {3, UPB_SIZE(52, 104), UPB_SIZE(-57, -113), 5, 11, 1},
+  {4, UPB_SIZE(16, 32), 2, 1, 11, 1},
+  {5, UPB_SIZE(20, 40), 3, 2, 11, 1},
+  {7, UPB_SIZE(52, 104), UPB_SIZE(-57, -113), 3, 11, 1},
+  {9, UPB_SIZE(32, 64), 0, 0, 11, 3},
+  {10, UPB_SIZE(36, 72), 0, 0, 11, 3},
+  {11, UPB_SIZE(40, 80), 0, 0, 9, 3},
+  {12, UPB_SIZE(44, 88), 0, 0, 9, 3},
+  {13, UPB_SIZE(48, 96), 0, 6, 11, _UPB_LABEL_MAP},
+  {14, UPB_SIZE(4, 8), 0, 0, 9, 1},
+  {15, UPB_SIZE(24, 48), 4, 9, 11, 1},
+  {16, UPB_SIZE(28, 56), 5, 10, 11, 1},
+  {17, UPB_SIZE(52, 104), UPB_SIZE(-57, -113), 4, 11, 1},
 };
 
 const upb_msglayout envoy_config_route_v3_Route_msginit = {
   &envoy_config_route_v3_Route_submsgs[0],
   &envoy_config_route_v3_Route__fields[0],
-  UPB_SIZE(56, 112), 15, false,
+  UPB_SIZE(64, 128), 15, false, 255,
 };
 
 static const upb_msglayout *const envoy_config_route_v3_Route_TypedPerFilterConfigEntry_submsgs[1] = {
@@ -149,7 +149,7 @@ static const upb_msglayout_field envoy_config_route_v3_Route_TypedPerFilterConfi
 const upb_msglayout envoy_config_route_v3_Route_TypedPerFilterConfigEntry_msginit = {
   &envoy_config_route_v3_Route_TypedPerFilterConfigEntry_submsgs[0],
   &envoy_config_route_v3_Route_TypedPerFilterConfigEntry__fields[0],
-  UPB_SIZE(16, 32), 2, false,
+  UPB_SIZE(16, 32), 2, false, 255,
 };
 
 static const upb_msglayout *const envoy_config_route_v3_WeightedCluster_submsgs[2] = {
@@ -158,18 +158,18 @@ static const upb_msglayout *const envoy_config_route_v3_WeightedCluster_submsgs[
 };
 
 static const upb_msglayout_field envoy_config_route_v3_WeightedCluster__fields[3] = {
-  {1, UPB_SIZE(12, 24), 0, 0, 11, 3},
-  {2, UPB_SIZE(0, 0), 0, 0, 9, 1},
-  {3, UPB_SIZE(8, 16), 0, 1, 11, 1},
+  {1, UPB_SIZE(16, 32), 0, 0, 11, 3},
+  {2, UPB_SIZE(4, 8), 0, 0, 9, 1},
+  {3, UPB_SIZE(12, 24), 1, 1, 11, 1},
 };
 
 const upb_msglayout envoy_config_route_v3_WeightedCluster_msginit = {
   &envoy_config_route_v3_WeightedCluster_submsgs[0],
   &envoy_config_route_v3_WeightedCluster__fields[0],
-  UPB_SIZE(16, 32), 3, false,
+  UPB_SIZE(24, 48), 3, false, 255,
 };
 
-static const upb_msglayout *const envoy_config_route_v3_WeightedCluster_ClusterWeight_submsgs[5] = {
+static const upb_msglayout *const envoy_config_route_v3_WeightedCluster_ClusterWeight_submsgs[4] = {
   &envoy_config_core_v3_HeaderValueOption_msginit,
   &envoy_config_core_v3_Metadata_msginit,
   &envoy_config_route_v3_WeightedCluster_ClusterWeight_TypedPerFilterConfigEntry_msginit,
@@ -177,20 +177,20 @@ static const upb_msglayout *const envoy_config_route_v3_WeightedCluster_ClusterW
 };
 
 static const upb_msglayout_field envoy_config_route_v3_WeightedCluster_ClusterWeight__fields[8] = {
-  {1, UPB_SIZE(0, 0), 0, 0, 9, 1},
-  {2, UPB_SIZE(8, 16), 0, 3, 11, 1},
-  {3, UPB_SIZE(12, 24), 0, 1, 11, 1},
-  {4, UPB_SIZE(16, 32), 0, 0, 11, 3},
-  {5, UPB_SIZE(20, 40), 0, 0, 11, 3},
-  {6, UPB_SIZE(24, 48), 0, 0, 9, 3},
-  {9, UPB_SIZE(28, 56), 0, 0, 9, 3},
-  {10, UPB_SIZE(32, 64), 0, 2, 11, _UPB_LABEL_MAP},
+  {1, UPB_SIZE(4, 8), 0, 0, 9, 1},
+  {2, UPB_SIZE(12, 24), 1, 3, 11, 1},
+  {3, UPB_SIZE(16, 32), 2, 1, 11, 1},
+  {4, UPB_SIZE(20, 40), 0, 0, 11, 3},
+  {5, UPB_SIZE(24, 48), 0, 0, 11, 3},
+  {6, UPB_SIZE(28, 56), 0, 0, 9, 3},
+  {9, UPB_SIZE(32, 64), 0, 0, 9, 3},
+  {10, UPB_SIZE(36, 72), 0, 2, 11, _UPB_LABEL_MAP},
 };
 
 const upb_msglayout envoy_config_route_v3_WeightedCluster_ClusterWeight_msginit = {
   &envoy_config_route_v3_WeightedCluster_ClusterWeight_submsgs[0],
   &envoy_config_route_v3_WeightedCluster_ClusterWeight__fields[0],
-  UPB_SIZE(40, 80), 8, false,
+  UPB_SIZE(40, 80), 8, false, 255,
 };
 
 static const upb_msglayout *const envoy_config_route_v3_WeightedCluster_ClusterWeight_TypedPerFilterConfigEntry_submsgs[1] = {
@@ -205,7 +205,7 @@ static const upb_msglayout_field envoy_config_route_v3_WeightedCluster_ClusterWe
 const upb_msglayout envoy_config_route_v3_WeightedCluster_ClusterWeight_TypedPerFilterConfigEntry_msginit = {
   &envoy_config_route_v3_WeightedCluster_ClusterWeight_TypedPerFilterConfigEntry_submsgs[0],
   &envoy_config_route_v3_WeightedCluster_ClusterWeight_TypedPerFilterConfigEntry__fields[0],
-  UPB_SIZE(16, 32), 2, false,
+  UPB_SIZE(16, 32), 2, false, 255,
 };
 
 static const upb_msglayout *const envoy_config_route_v3_RouteMatch_submsgs[8] = {
@@ -220,75 +220,75 @@ static const upb_msglayout *const envoy_config_route_v3_RouteMatch_submsgs[8] =
 };
 
 static const upb_msglayout_field envoy_config_route_v3_RouteMatch__fields[10] = {
-  {1, UPB_SIZE(24, 48), UPB_SIZE(-33, -65), 0, 9, 1},
-  {2, UPB_SIZE(24, 48), UPB_SIZE(-33, -65), 0, 9, 1},
-  {4, UPB_SIZE(0, 0), 0, 7, 11, 1},
-  {6, UPB_SIZE(16, 32), 0, 1, 11, 3},
-  {7, UPB_SIZE(20, 40), 0, 2, 11, 3},
-  {8, UPB_SIZE(4, 8), 0, 4, 11, 1},
-  {9, UPB_SIZE(8, 16), 0, 0, 11, 1},
-  {10, UPB_SIZE(24, 48), UPB_SIZE(-33, -65), 6, 11, 1},
-  {11, UPB_SIZE(12, 24), 0, 5, 11, 1},
-  {12, UPB_SIZE(24, 48), UPB_SIZE(-33, -65), 3, 11, 1},
+  {1, UPB_SIZE(28, 56), UPB_SIZE(-37, -73), 0, 9, 1},
+  {2, UPB_SIZE(28, 56), UPB_SIZE(-37, -73), 0, 9, 1},
+  {4, UPB_SIZE(4, 8), 1, 7, 11, 1},
+  {6, UPB_SIZE(20, 40), 0, 1, 11, 3},
+  {7, UPB_SIZE(24, 48), 0, 2, 11, 3},
+  {8, UPB_SIZE(8, 16), 2, 4, 11, 1},
+  {9, UPB_SIZE(12, 24), 3, 0, 11, 1},
+  {10, UPB_SIZE(28, 56), UPB_SIZE(-37, -73), 6, 11, 1},
+  {11, UPB_SIZE(16, 32), 4, 5, 11, 1},
+  {12, UPB_SIZE(28, 56), UPB_SIZE(-37, -73), 3, 11, 1},
 };
 
 const upb_msglayout envoy_config_route_v3_RouteMatch_msginit = {
   &envoy_config_route_v3_RouteMatch_submsgs[0],
   &envoy_config_route_v3_RouteMatch__fields[0],
-  UPB_SIZE(40, 80), 10, false,
+  UPB_SIZE(40, 80), 10, false, 255,
 };
 
 const upb_msglayout envoy_config_route_v3_RouteMatch_GrpcRouteMatchOptions_msginit = {
   NULL,
   NULL,
-  UPB_SIZE(0, 0), 0, false,
+  UPB_SIZE(0, 0), 0, false, 255,
 };
 
-static const upb_msglayout *const envoy_config_route_v3_RouteMatch_TlsContextMatchOptions_submsgs[2] = {
+static const upb_msglayout *const envoy_config_route_v3_RouteMatch_TlsContextMatchOptions_submsgs[1] = {
   &google_protobuf_BoolValue_msginit,
 };
 
 static const upb_msglayout_field envoy_config_route_v3_RouteMatch_TlsContextMatchOptions__fields[2] = {
-  {1, UPB_SIZE(0, 0), 0, 0, 11, 1},
-  {2, UPB_SIZE(4, 8), 0, 0, 11, 1},
+  {1, UPB_SIZE(4, 8), 1, 0, 11, 1},
+  {2, UPB_SIZE(8, 16), 2, 0, 11, 1},
 };
 
 const upb_msglayout envoy_config_route_v3_RouteMatch_TlsContextMatchOptions_msginit = {
   &envoy_config_route_v3_RouteMatch_TlsContextMatchOptions_submsgs[0],
   &envoy_config_route_v3_RouteMatch_TlsContextMatchOptions__fields[0],
-  UPB_SIZE(8, 16), 2, false,
+  UPB_SIZE(16, 24), 2, false, 255,
 };
 
 const upb_msglayout envoy_config_route_v3_RouteMatch_ConnectMatcher_msginit = {
   NULL,
   NULL,
-  UPB_SIZE(0, 0), 0, false,
+  UPB_SIZE(0, 0), 0, false, 255,
 };
 
-static const upb_msglayout *const envoy_config_route_v3_CorsPolicy_submsgs[4] = {
+static const upb_msglayout *const envoy_config_route_v3_CorsPolicy_submsgs[3] = {
   &envoy_config_core_v3_RuntimeFractionalPercent_msginit,
   &envoy_type_matcher_v3_StringMatcher_msginit,
   &google_protobuf_BoolValue_msginit,
 };
 
 static const upb_msglayout_field envoy_config_route_v3_CorsPolicy__fields[8] = {
-  {2, UPB_SIZE(0, 0), 0, 0, 9, 1},
-  {3, UPB_SIZE(8, 16), 0, 0, 9, 1},
-  {4, UPB_SIZE(16, 32), 0, 0, 9, 1},
-  {5, UPB_SIZE(24, 48), 0, 0, 9, 1},
-  {6, UPB_SIZE(32, 64), 0, 2, 11, 1},
-  {9, UPB_SIZE(44, 88), UPB_SIZE(-49, -97), 0, 11, 1},
-  {10, UPB_SIZE(36, 72), 0, 0, 11, 1},
-  {11, UPB_SIZE(40, 80), 0, 1, 11, 3},
+  {2, UPB_SIZE(4, 8), 0, 0, 9, 1},
+  {3, UPB_SIZE(12, 24), 0, 0, 9, 1},
+  {4, UPB_SIZE(20, 40), 0, 0, 9, 1},
+  {5, UPB_SIZE(28, 56), 0, 0, 9, 1},
+  {6, UPB_SIZE(36, 72), 1, 2, 11, 1},
+  {9, UPB_SIZE(48, 96), UPB_SIZE(-53, -105), 0, 11, 1},
+  {10, UPB_SIZE(40, 80), 2, 0, 11, 1},
+  {11, UPB_SIZE(44, 88), 0, 1, 11, 3},
 };
 
 const upb_msglayout envoy_config_route_v3_CorsPolicy_msginit = {
   &envoy_config_route_v3_CorsPolicy_submsgs[0],
   &envoy_config_route_v3_CorsPolicy__fields[0],
-  UPB_SIZE(56, 112), 8, false,
+  UPB_SIZE(56, 112), 8, false, 255,
 };
 
-static const upb_msglayout *const envoy_config_route_v3_RouteAction_submsgs[21] = {
+static const upb_msglayout *const envoy_config_route_v3_RouteAction_submsgs[16] = {
   &envoy_config_core_v3_Metadata_msginit,
   &envoy_config_route_v3_CorsPolicy_msginit,
   &envoy_config_route_v3_HedgePolicy_msginit,
@@ -308,41 +308,41 @@ static const upb_msglayout *const envoy_config_route_v3_RouteAction_submsgs[21]
 };
 
 static const upb_msglayout_field envoy_config_route_v3_RouteAction__fields[29] = {
-  {1, UPB_SIZE(104, 184), UPB_SIZE(-113, -201), 0, 9, 1},
-  {2, UPB_SIZE(104, 184), UPB_SIZE(-113, -201), 0, 9, 1},
-  {3, UPB_SIZE(104, 184), UPB_SIZE(-113, -201), 10, 11, 1},
-  {4, UPB_SIZE(32, 40), 0, 0, 11, 1},
-  {5, UPB_SIZE(24, 24), 0, 0, 9, 1},
-  {6, UPB_SIZE(116, 208), UPB_SIZE(-125, -225), 0, 9, 1},
-  {7, UPB_SIZE(116, 208), UPB_SIZE(-125, -225), 13, 11, 1},
-  {8, UPB_SIZE(36, 48), 0, 14, 11, 1},
-  {9, UPB_SIZE(40, 56), 0, 5, 11, 1},
-  {11, UPB_SIZE(0, 0), 0, 0, 14, 1},
-  {13, UPB_SIZE(88, 152), 0, 4, 11, 3},
-  {14, UPB_SIZE(44, 64), 0, 13, 11, 1},
-  {15, UPB_SIZE(92, 160), 0, 6, 11, 3},
-  {17, UPB_SIZE(48, 72), 0, 1, 11, 1},
+  {1, UPB_SIZE(96, 176), UPB_SIZE(-105, -193), 0, 9, 1},
+  {2, UPB_SIZE(96, 176), UPB_SIZE(-105, -193), 0, 9, 1},
+  {3, UPB_SIZE(96, 176), UPB_SIZE(-105, -193), 10, 11, 1},
+  {4, UPB_SIZE(24, 32), 1, 0, 11, 1},
+  {5, UPB_SIZE(16, 16), 0, 0, 9, 1},
+  {6, UPB_SIZE(108, 200), UPB_SIZE(-117, -217), 0, 9, 1},
+  {7, UPB_SIZE(108, 200), UPB_SIZE(-117, -217), 13, 11, 1},
+  {8, UPB_SIZE(28, 40), 2, 14, 11, 1},
+  {9, UPB_SIZE(32, 48), 3, 5, 11, 1},
+  {11, UPB_SIZE(4, 4), 0, 0, 14, 1},
+  {13, UPB_SIZE(80, 144), 0, 4, 11, 3},
+  {14, UPB_SIZE(36, 56), 4, 13, 11, 1},
+  {15, UPB_SIZE(84, 152), 0, 6, 11, 3},
+  {17, UPB_SIZE(40, 64), 5, 1, 11, 1},
   {20, UPB_SIZE(8, 8), 0, 0, 14, 1},
-  {23, UPB_SIZE(52, 80), 0, 14, 11, 1},
-  {24, UPB_SIZE(56, 88), 0, 14, 11, 1},
-  {25, UPB_SIZE(96, 168), 0, 9, 11, 3},
-  {26, UPB_SIZE(16, 16), 0, 0, 14, 1},
-  {27, UPB_SIZE(60, 96), 0, 2, 11, 1},
-  {28, UPB_SIZE(64, 104), 0, 14, 11, 1},
-  {29, UPB_SIZE(116, 208), UPB_SIZE(-125, -225), 0, 9, 1},
-  {30, UPB_SIZE(100, 176), 0, 8, 11, 3},
-  {31, UPB_SIZE(68, 112), 0, 15, 11, 1},
-  {32, UPB_SIZE(72, 120), 0, 11, 11, 1},
-  {33, UPB_SIZE(76, 128), 0, 12, 11, 1},
-  {34, UPB_SIZE(80, 136), 0, 3, 11, 1},
-  {35, UPB_SIZE(116, 208), UPB_SIZE(-125, -225), 11, 11, 1},
-  {36, UPB_SIZE(84, 144), 0, 7, 11, 1},
+  {23, UPB_SIZE(44, 72), 6, 14, 11, 1},
+  {24, UPB_SIZE(48, 80), 7, 14, 11, 1},
+  {25, UPB_SIZE(88, 160), 0, 9, 11, 3},
+  {26, UPB_SIZE(12, 12), 0, 0, 14, 1},
+  {27, UPB_SIZE(52, 88), 8, 2, 11, 1},
+  {28, UPB_SIZE(56, 96), 9, 14, 11, 1},
+  {29, UPB_SIZE(108, 200), UPB_SIZE(-117, -217), 0, 9, 1},
+  {30, UPB_SIZE(92, 168), 0, 8, 11, 3},
+  {31, UPB_SIZE(60, 104), 10, 15, 11, 1},
+  {32, UPB_SIZE(64, 112), 11, 11, 11, 1},
+  {33, UPB_SIZE(68, 120), 12, 12, 11, 1},
+  {34, UPB_SIZE(72, 128), 13, 3, 11, 1},
+  {35, UPB_SIZE(108, 200), UPB_SIZE(-117, -217), 11, 11, 1},
+  {36, UPB_SIZE(76, 136), 14, 7, 11, 1},
 };
 
 const upb_msglayout envoy_config_route_v3_RouteAction_msginit = {
   &envoy_config_route_v3_RouteAction_submsgs[0],
   &envoy_config_route_v3_RouteAction__fields[0],
-  UPB_SIZE(128, 240), 29, false,
+  UPB_SIZE(120, 224), 29, false, 255,
 };
 
 static const upb_msglayout *const envoy_config_route_v3_RouteAction_RequestMirrorPolicy_submsgs[2] = {
@@ -351,15 +351,15 @@ static const upb_msglayout *const envoy_config_route_v3_RouteAction_RequestMirro
 };
 
 static const upb_msglayout_field envoy_config_route_v3_RouteAction_RequestMirrorPolicy__fields[3] = {
-  {1, UPB_SIZE(0, 0), 0, 0, 9, 1},
-  {3, UPB_SIZE(8, 16), 0, 0, 11, 1},
-  {4, UPB_SIZE(12, 24), 0, 1, 11, 1},
+  {1, UPB_SIZE(4, 8), 0, 0, 9, 1},
+  {3, UPB_SIZE(12, 24), 1, 0, 11, 1},
+  {4, UPB_SIZE(16, 32), 2, 1, 11, 1},
 };
 
 const upb_msglayout envoy_config_route_v3_RouteAction_RequestMirrorPolicy_msginit = {
   &envoy_config_route_v3_RouteAction_RequestMirrorPolicy_submsgs[0],
   &envoy_config_route_v3_RouteAction_RequestMirrorPolicy__fields[0],
-  UPB_SIZE(16, 32), 3, false,
+  UPB_SIZE(24, 48), 3, false, 255,
 };
 
 static const upb_msglayout *const envoy_config_route_v3_RouteAction_HashPolicy_submsgs[5] = {
@@ -382,7 +382,7 @@ static const upb_msglayout_field envoy_config_route_v3_RouteAction_HashPolicy__f
 const upb_msglayout envoy_config_route_v3_RouteAction_HashPolicy_msginit = {
   &envoy_config_route_v3_RouteAction_HashPolicy_submsgs[0],
   &envoy_config_route_v3_RouteAction_HashPolicy__fields[0],
-  UPB_SIZE(12, 24), 6, false,
+  UPB_SIZE(16, 24), 6, false, 255,
 };
 
 static const upb_msglayout *const envoy_config_route_v3_RouteAction_HashPolicy_Header_submsgs[1] = {
@@ -390,14 +390,14 @@ static const upb_msglayout *const envoy_config_route_v3_RouteAction_HashPolicy_H
 };
 
 static const upb_msglayout_field envoy_config_route_v3_RouteAction_HashPolicy_Header__fields[2] = {
-  {1, UPB_SIZE(0, 0), 0, 0, 9, 1},
-  {2, UPB_SIZE(8, 16), 0, 0, 11, 1},
+  {1, UPB_SIZE(4, 8), 0, 0, 9, 1},
+  {2, UPB_SIZE(12, 24), 1, 0, 11, 1},
 };
 
 const upb_msglayout envoy_config_route_v3_RouteAction_HashPolicy_Header_msginit = {
   &envoy_config_route_v3_RouteAction_HashPolicy_Header_submsgs[0],
   &envoy_config_route_v3_RouteAction_HashPolicy_Header__fields[0],
-  UPB_SIZE(16, 32), 2, false,
+  UPB_SIZE(16, 32), 2, false, 255,
 };
 
 static const upb_msglayout *const envoy_config_route_v3_RouteAction_HashPolicy_Cookie_submsgs[1] = {
@@ -405,15 +405,15 @@ static const upb_msglayout *const envoy_config_route_v3_RouteAction_HashPolicy_C
 };
 
 static const upb_msglayout_field envoy_config_route_v3_RouteAction_HashPolicy_Cookie__fields[3] = {
-  {1, UPB_SIZE(0, 0), 0, 0, 9, 1},
-  {2, UPB_SIZE(16, 32), 0, 0, 11, 1},
-  {3, UPB_SIZE(8, 16), 0, 0, 9, 1},
+  {1, UPB_SIZE(4, 8), 0, 0, 9, 1},
+  {2, UPB_SIZE(20, 40), 1, 0, 11, 1},
+  {3, UPB_SIZE(12, 24), 0, 0, 9, 1},
 };
 
 const upb_msglayout envoy_config_route_v3_RouteAction_HashPolicy_Cookie_msginit = {
   &envoy_config_route_v3_RouteAction_HashPolicy_Cookie_submsgs[0],
   &envoy_config_route_v3_RouteAction_HashPolicy_Cookie__fields[0],
-  UPB_SIZE(24, 48), 3, false,
+  UPB_SIZE(24, 48), 3, false, 255,
 };
 
 static const upb_msglayout_field envoy_config_route_v3_RouteAction_HashPolicy_ConnectionProperties__fields[1] = {
@@ -423,7 +423,7 @@ static const upb_msglayout_field envoy_config_route_v3_RouteAction_HashPolicy_Co
 const upb_msglayout envoy_config_route_v3_RouteAction_HashPolicy_ConnectionProperties_msginit = {
   NULL,
   &envoy_config_route_v3_RouteAction_HashPolicy_ConnectionProperties__fields[0],
-  UPB_SIZE(1, 1), 1, false,
+  UPB_SIZE(8, 8), 1, false, 255,
 };
 
 static const upb_msglayout_field envoy_config_route_v3_RouteAction_HashPolicy_QueryParameter__fields[1] = {
@@ -433,7 +433,7 @@ static const upb_msglayout_field envoy_config_route_v3_RouteAction_HashPolicy_Qu
 const upb_msglayout envoy_config_route_v3_RouteAction_HashPolicy_QueryParameter_msginit = {
   NULL,
   &envoy_config_route_v3_RouteAction_HashPolicy_QueryParameter__fields[0],
-  UPB_SIZE(8, 16), 1, false,
+  UPB_SIZE(8, 16), 1, false, 255,
 };
 
 static const upb_msglayout_field envoy_config_route_v3_RouteAction_HashPolicy_FilterState__fields[1] = {
@@ -443,7 +443,7 @@ static const upb_msglayout_field envoy_config_route_v3_RouteAction_HashPolicy_Fi
 const upb_msglayout envoy_config_route_v3_RouteAction_HashPolicy_FilterState_msginit = {
   NULL,
   &envoy_config_route_v3_RouteAction_HashPolicy_FilterState__fields[0],
-  UPB_SIZE(8, 16), 1, false,
+  UPB_SIZE(8, 16), 1, false, 255,
 };
 
 static const upb_msglayout *const envoy_config_route_v3_RouteAction_UpgradeConfig_submsgs[2] = {
@@ -452,15 +452,15 @@ static const upb_msglayout *const envoy_config_route_v3_RouteAction_UpgradeConfi
 };
 
 static const upb_msglayout_field envoy_config_route_v3_RouteAction_UpgradeConfig__fields[3] = {
-  {1, UPB_SIZE(0, 0), 0, 0, 9, 1},
-  {2, UPB_SIZE(8, 16), 0, 1, 11, 1},
-  {3, UPB_SIZE(12, 24), 0, 0, 11, 1},
+  {1, UPB_SIZE(4, 8), 0, 0, 9, 1},
+  {2, UPB_SIZE(12, 24), 1, 1, 11, 1},
+  {3, UPB_SIZE(16, 32), 2, 0, 11, 1},
 };
 
 const upb_msglayout envoy_config_route_v3_RouteAction_UpgradeConfig_msginit = {
   &envoy_config_route_v3_RouteAction_UpgradeConfig_submsgs[0],
   &envoy_config_route_v3_RouteAction_UpgradeConfig__fields[0],
-  UPB_SIZE(16, 32), 3, false,
+  UPB_SIZE(24, 48), 3, false, 255,
 };
 
 static const upb_msglayout *const envoy_config_route_v3_RouteAction_UpgradeConfig_ConnectConfig_submsgs[1] = {
@@ -468,32 +468,32 @@ static const upb_msglayout *const envoy_config_route_v3_RouteAction_UpgradeConfi
 };
 
 static const upb_msglayout_field envoy_config_route_v3_RouteAction_UpgradeConfig_ConnectConfig__fields[1] = {
-  {1, UPB_SIZE(0, 0), 0, 0, 11, 1},
+  {1, UPB_SIZE(4, 8), 1, 0, 11, 1},
 };
 
 const upb_msglayout envoy_config_route_v3_RouteAction_UpgradeConfig_ConnectConfig_msginit = {
   &envoy_config_route_v3_RouteAction_UpgradeConfig_ConnectConfig_submsgs[0],
   &envoy_config_route_v3_RouteAction_UpgradeConfig_ConnectConfig__fields[0],
-  UPB_SIZE(4, 8), 1, false,
+  UPB_SIZE(8, 16), 1, false, 255,
 };
 
-static const upb_msglayout *const envoy_config_route_v3_RouteAction_MaxStreamDuration_submsgs[3] = {
+static const upb_msglayout *const envoy_config_route_v3_RouteAction_MaxStreamDuration_submsgs[1] = {
   &google_protobuf_Duration_msginit,
 };
 
 static const upb_msglayout_field envoy_config_route_v3_RouteAction_MaxStreamDuration__fields[3] = {
-  {1, UPB_SIZE(0, 0), 0, 0, 11, 1},
-  {2, UPB_SIZE(4, 8), 0, 0, 11, 1},
-  {3, UPB_SIZE(8, 16), 0, 0, 11, 1},
+  {1, UPB_SIZE(4, 8), 1, 0, 11, 1},
+  {2, UPB_SIZE(8, 16), 2, 0, 11, 1},
+  {3, UPB_SIZE(12, 24), 3, 0, 11, 1},
 };
 
 const upb_msglayout envoy_config_route_v3_RouteAction_MaxStreamDuration_msginit = {
   &envoy_config_route_v3_RouteAction_MaxStreamDuration_submsgs[0],
   &envoy_config_route_v3_RouteAction_MaxStreamDuration__fields[0],
-  UPB_SIZE(12, 24), 3, false,
+  UPB_SIZE(16, 32), 3, false, 255,
 };
 
-static const upb_msglayout *const envoy_config_route_v3_RetryPolicy_submsgs[8] = {
+static const upb_msglayout *const envoy_config_route_v3_RetryPolicy_submsgs[7] = {
   &envoy_config_route_v3_HeaderMatcher_msginit,
   &envoy_config_route_v3_RetryPolicy_RateLimitedRetryBackOff_msginit,
   &envoy_config_route_v3_RetryPolicy_RetryBackOff_msginit,
@@ -504,23 +504,23 @@ static const upb_msglayout *const envoy_config_route_v3_RetryPolicy_submsgs[8] =
 };
 
 static const upb_msglayout_field envoy_config_route_v3_RetryPolicy__fields[11] = {
-  {1, UPB_SIZE(8, 8), 0, 0, 9, 1},
-  {2, UPB_SIZE(16, 24), 0, 6, 11, 1},
-  {3, UPB_SIZE(20, 32), 0, 5, 11, 1},
-  {4, UPB_SIZE(24, 40), 0, 4, 11, 1},
-  {5, UPB_SIZE(36, 64), 0, 3, 11, 3},
-  {6, UPB_SIZE(0, 0), 0, 0, 3, 1},
-  {7, UPB_SIZE(40, 72), 0, 0, 13, _UPB_LABEL_PACKED},
-  {8, UPB_SIZE(28, 48), 0, 2, 11, 1},
-  {9, UPB_SIZE(44, 80), 0, 0, 11, 3},
-  {10, UPB_SIZE(48, 88), 0, 0, 11, 3},
-  {11, UPB_SIZE(32, 56), 0, 1, 11, 1},
+  {1, UPB_SIZE(16, 16), 0, 0, 9, 1},
+  {2, UPB_SIZE(24, 32), 1, 6, 11, 1},
+  {3, UPB_SIZE(28, 40), 2, 5, 11, 1},
+  {4, UPB_SIZE(32, 48), 3, 4, 11, 1},
+  {5, UPB_SIZE(44, 72), 0, 3, 11, 3},
+  {6, UPB_SIZE(8, 8), 0, 0, 3, 1},
+  {7, UPB_SIZE(48, 80), 0, 0, 13, _UPB_LABEL_PACKED},
+  {8, UPB_SIZE(36, 56), 4, 2, 11, 1},
+  {9, UPB_SIZE(52, 88), 0, 0, 11, 3},
+  {10, UPB_SIZE(56, 96), 0, 0, 11, 3},
+  {11, UPB_SIZE(40, 64), 5, 1, 11, 1},
 };
 
 const upb_msglayout envoy_config_route_v3_RetryPolicy_msginit = {
   &envoy_config_route_v3_RetryPolicy_submsgs[0],
   &envoy_config_route_v3_RetryPolicy__fields[0],
-  UPB_SIZE(56, 96), 11, false,
+  UPB_SIZE(64, 112), 11, false, 255,
 };
 
 static const upb_msglayout *const envoy_config_route_v3_RetryPolicy_RetryPriority_submsgs[1] = {
@@ -535,7 +535,7 @@ static const upb_msglayout_field envoy_config_route_v3_RetryPolicy_RetryPriority
 const upb_msglayout envoy_config_route_v3_RetryPolicy_RetryPriority_msginit = {
   &envoy_config_route_v3_RetryPolicy_RetryPriority_submsgs[0],
   &envoy_config_route_v3_RetryPolicy_RetryPriority__fields[0],
-  UPB_SIZE(16, 32), 2, false,
+  UPB_SIZE(16, 32), 2, false, 255,
 };
 
 static const upb_msglayout *const envoy_config_route_v3_RetryPolicy_RetryHostPredicate_submsgs[1] = {
@@ -550,33 +550,33 @@ static const upb_msglayout_field envoy_config_route_v3_RetryPolicy_RetryHostPred
 const upb_msglayout envoy_config_route_v3_RetryPolicy_RetryHostPredicate_msginit = {
   &envoy_config_route_v3_RetryPolicy_RetryHostPredicate_submsgs[0],
   &envoy_config_route_v3_RetryPolicy_RetryHostPredicate__fields[0],
-  UPB_SIZE(16, 32), 2, false,
+  UPB_SIZE(16, 32), 2, false, 255,
 };
 
-static const upb_msglayout *const envoy_config_route_v3_RetryPolicy_RetryBackOff_submsgs[2] = {
+static const upb_msglayout *const envoy_config_route_v3_RetryPolicy_RetryBackOff_submsgs[1] = {
   &google_protobuf_Duration_msginit,
 };
 
 static const upb_msglayout_field envoy_config_route_v3_RetryPolicy_RetryBackOff__fields[2] = {
-  {1, UPB_SIZE(0, 0), 0, 0, 11, 1},
-  {2, UPB_SIZE(4, 8), 0, 0, 11, 1},
+  {1, UPB_SIZE(4, 8), 1, 0, 11, 1},
+  {2, UPB_SIZE(8, 16), 2, 0, 11, 1},
 };
 
 const upb_msglayout envoy_config_route_v3_RetryPolicy_RetryBackOff_msginit = {
   &envoy_config_route_v3_RetryPolicy_RetryBackOff_submsgs[0],
   &envoy_config_route_v3_RetryPolicy_RetryBackOff__fields[0],
-  UPB_SIZE(8, 16), 2, false,
+  UPB_SIZE(16, 24), 2, false, 255,
 };
 
 static const upb_msglayout_field envoy_config_route_v3_RetryPolicy_ResetHeader__fields[2] = {
-  {1, UPB_SIZE(8, 8), 0, 0, 9, 1},
+  {1, UPB_SIZE(4, 8), 0, 0, 9, 1},
   {2, UPB_SIZE(0, 0), 0, 0, 14, 1},
 };
 
 const upb_msglayout envoy_config_route_v3_RetryPolicy_ResetHeader_msginit = {
   NULL,
   &envoy_config_route_v3_RetryPolicy_ResetHeader__fields[0],
-  UPB_SIZE(16, 32), 2, false,
+  UPB_SIZE(16, 32), 2, false, 255,
 };
 
 static const upb_msglayout *const envoy_config_route_v3_RetryPolicy_RateLimitedRetryBackOff_submsgs[2] = {
@@ -585,14 +585,14 @@ static const upb_msglayout *const envoy_config_route_v3_RetryPolicy_RateLimitedR
 };
 
 static const upb_msglayout_field envoy_config_route_v3_RetryPolicy_RateLimitedRetryBackOff__fields[2] = {
-  {1, UPB_SIZE(4, 8), 0, 0, 11, 3},
-  {2, UPB_SIZE(0, 0), 0, 1, 11, 1},
+  {1, UPB_SIZE(8, 16), 0, 0, 11, 3},
+  {2, UPB_SIZE(4, 8), 1, 1, 11, 1},
 };
 
 const upb_msglayout envoy_config_route_v3_RetryPolicy_RateLimitedRetryBackOff_msginit = {
   &envoy_config_route_v3_RetryPolicy_RateLimitedRetryBackOff_submsgs[0],
   &envoy_config_route_v3_RetryPolicy_RateLimitedRetryBackOff__fields[0],
-  UPB_SIZE(8, 16), 2, false,
+  UPB_SIZE(16, 24), 2, false, 255,
 };
 
 static const upb_msglayout *const envoy_config_route_v3_HedgePolicy_submsgs[2] = {
@@ -601,32 +601,32 @@ static const upb_msglayout *const envoy_config_route_v3_HedgePolicy_submsgs[2] =
 };
 
 static const upb_msglayout_field envoy_config_route_v3_HedgePolicy__fields[3] = {
-  {1, UPB_SIZE(4, 8), 0, 1, 11, 1},
-  {2, UPB_SIZE(8, 16), 0, 0, 11, 1},
-  {3, UPB_SIZE(0, 0), 0, 0, 8, 1},
+  {1, UPB_SIZE(4, 8), 1, 1, 11, 1},
+  {2, UPB_SIZE(8, 16), 2, 0, 11, 1},
+  {3, UPB_SIZE(1, 1), 0, 0, 8, 1},
 };
 
 const upb_msglayout envoy_config_route_v3_HedgePolicy_msginit = {
   &envoy_config_route_v3_HedgePolicy_submsgs[0],
   &envoy_config_route_v3_HedgePolicy__fields[0],
-  UPB_SIZE(12, 24), 3, false,
+  UPB_SIZE(16, 24), 3, false, 255,
 };
 
 static const upb_msglayout_field envoy_config_route_v3_RedirectAction__fields[8] = {
-  {1, UPB_SIZE(16, 16), 0, 0, 9, 1},
-  {2, UPB_SIZE(24, 32), UPB_SIZE(-33, -49), 0, 9, 1},
+  {1, UPB_SIZE(12, 16), 0, 0, 9, 1},
+  {2, UPB_SIZE(20, 32), UPB_SIZE(-29, -49), 0, 9, 1},
   {3, UPB_SIZE(0, 0), 0, 0, 14, 1},
-  {4, UPB_SIZE(36, 56), UPB_SIZE(-45, -73), 0, 8, 1},
-  {5, UPB_SIZE(24, 32), UPB_SIZE(-33, -49), 0, 9, 1},
-  {6, UPB_SIZE(12, 12), 0, 0, 8, 1},
-  {7, UPB_SIZE(36, 56), UPB_SIZE(-45, -73), 0, 9, 1},
-  {8, UPB_SIZE(8, 8), 0, 0, 13, 1},
+  {4, UPB_SIZE(32, 56), UPB_SIZE(-41, -73), 0, 8, 1},
+  {5, UPB_SIZE(20, 32), UPB_SIZE(-29, -49), 0, 9, 1},
+  {6, UPB_SIZE(8, 8), 0, 0, 8, 1},
+  {7, UPB_SIZE(32, 56), UPB_SIZE(-41, -73), 0, 9, 1},
+  {8, UPB_SIZE(4, 4), 0, 0, 13, 1},
 };
 
 const upb_msglayout envoy_config_route_v3_RedirectAction_msginit = {
   NULL,
   &envoy_config_route_v3_RedirectAction__fields[0],
-  UPB_SIZE(48, 80), 8, false,
+  UPB_SIZE(48, 80), 8, false, 255,
 };
 
 static const upb_msglayout *const envoy_config_route_v3_DirectResponseAction_submsgs[1] = {
@@ -634,14 +634,14 @@ static const upb_msglayout *const envoy_config_route_v3_DirectResponseAction_sub
 };
 
 static const upb_msglayout_field envoy_config_route_v3_DirectResponseAction__fields[2] = {
-  {1, UPB_SIZE(0, 0), 0, 0, 13, 1},
-  {2, UPB_SIZE(4, 8), 0, 0, 11, 1},
+  {1, UPB_SIZE(4, 4), 0, 0, 13, 1},
+  {2, UPB_SIZE(8, 8), 1, 0, 11, 1},
 };
 
 const upb_msglayout envoy_config_route_v3_DirectResponseAction_msginit = {
   &envoy_config_route_v3_DirectResponseAction_submsgs[0],
   &envoy_config_route_v3_DirectResponseAction__fields[0],
-  UPB_SIZE(8, 16), 2, false,
+  UPB_SIZE(16, 16), 2, false, 255,
 };
 
 static const upb_msglayout *const envoy_config_route_v3_Decorator_submsgs[1] = {
@@ -649,32 +649,32 @@ static const upb_msglayout *const envoy_config_route_v3_Decorator_submsgs[1] = {
 };
 
 static const upb_msglayout_field envoy_config_route_v3_Decorator__fields[2] = {
-  {1, UPB_SIZE(0, 0), 0, 0, 9, 1},
-  {2, UPB_SIZE(8, 16), 0, 0, 11, 1},
+  {1, UPB_SIZE(4, 8), 0, 0, 9, 1},
+  {2, UPB_SIZE(12, 24), 1, 0, 11, 1},
 };
 
 const upb_msglayout envoy_config_route_v3_Decorator_msginit = {
   &envoy_config_route_v3_Decorator_submsgs[0],
   &envoy_config_route_v3_Decorator__fields[0],
-  UPB_SIZE(16, 32), 2, false,
+  UPB_SIZE(16, 32), 2, false, 255,
 };
 
-static const upb_msglayout *const envoy_config_route_v3_Tracing_submsgs[4] = {
+static const upb_msglayout *const envoy_config_route_v3_Tracing_submsgs[2] = {
   &envoy_type_tracing_v3_CustomTag_msginit,
   &envoy_type_v3_FractionalPercent_msginit,
 };
 
 static const upb_msglayout_field envoy_config_route_v3_Tracing__fields[4] = {
-  {1, UPB_SIZE(0, 0), 0, 1, 11, 1},
-  {2, UPB_SIZE(4, 8), 0, 1, 11, 1},
-  {3, UPB_SIZE(8, 16), 0, 1, 11, 1},
-  {4, UPB_SIZE(12, 24), 0, 0, 11, 3},
+  {1, UPB_SIZE(4, 8), 1, 1, 11, 1},
+  {2, UPB_SIZE(8, 16), 2, 1, 11, 1},
+  {3, UPB_SIZE(12, 24), 3, 1, 11, 1},
+  {4, UPB_SIZE(16, 32), 0, 0, 11, 3},
 };
 
 const upb_msglayout envoy_config_route_v3_Tracing_msginit = {
   &envoy_config_route_v3_Tracing_submsgs[0],
   &envoy_config_route_v3_Tracing__fields[0],
-  UPB_SIZE(16, 32), 4, false,
+  UPB_SIZE(24, 40), 4, false, 255,
 };
 
 static const upb_msglayout *const envoy_config_route_v3_VirtualCluster_submsgs[1] = {
@@ -689,7 +689,7 @@ static const upb_msglayout_field envoy_config_route_v3_VirtualCluster__fields[2]
 const upb_msglayout envoy_config_route_v3_VirtualCluster_msginit = {
   &envoy_config_route_v3_VirtualCluster_submsgs[0],
   &envoy_config_route_v3_VirtualCluster__fields[0],
-  UPB_SIZE(16, 32), 2, false,
+  UPB_SIZE(16, 32), 2, false, 255,
 };
 
 static const upb_msglayout *const envoy_config_route_v3_RateLimit_submsgs[3] = {
@@ -699,16 +699,16 @@ static const upb_msglayout *const envoy_config_route_v3_RateLimit_submsgs[3] = {
 };
 
 static const upb_msglayout_field envoy_config_route_v3_RateLimit__fields[4] = {
-  {1, UPB_SIZE(8, 16), 0, 2, 11, 1},
-  {2, UPB_SIZE(0, 0), 0, 0, 9, 1},
-  {3, UPB_SIZE(16, 32), 0, 0, 11, 3},
-  {4, UPB_SIZE(12, 24), 0, 1, 11, 1},
+  {1, UPB_SIZE(12, 24), 1, 2, 11, 1},
+  {2, UPB_SIZE(4, 8), 0, 0, 9, 1},
+  {3, UPB_SIZE(20, 40), 0, 0, 11, 3},
+  {4, UPB_SIZE(16, 32), 2, 1, 11, 1},
 };
 
 const upb_msglayout envoy_config_route_v3_RateLimit_msginit = {
   &envoy_config_route_v3_RateLimit_submsgs[0],
   &envoy_config_route_v3_RateLimit__fields[0],
-  UPB_SIZE(24, 48), 4, false,
+  UPB_SIZE(24, 48), 4, false, 255,
 };
 
 static const upb_msglayout *const envoy_config_route_v3_RateLimit_Action_submsgs[7] = {
@@ -734,19 +734,19 @@ static const upb_msglayout_field envoy_config_route_v3_RateLimit_Action__fields[
 const upb_msglayout envoy_config_route_v3_RateLimit_Action_msginit = {
   &envoy_config_route_v3_RateLimit_Action_submsgs[0],
   &envoy_config_route_v3_RateLimit_Action__fields[0],
-  UPB_SIZE(8, 16), 7, false,
+  UPB_SIZE(8, 16), 7, false, 255,
 };
 
 const upb_msglayout envoy_config_route_v3_RateLimit_Action_SourceCluster_msginit = {
   NULL,
   NULL,
-  UPB_SIZE(0, 0), 0, false,
+  UPB_SIZE(0, 0), 0, false, 255,
 };
 
 const upb_msglayout envoy_config_route_v3_RateLimit_Action_DestinationCluster_msginit = {
   NULL,
   NULL,
-  UPB_SIZE(0, 0), 0, false,
+  UPB_SIZE(0, 0), 0, false, 255,
 };
 
 static const upb_msglayout_field envoy_config_route_v3_RateLimit_Action_RequestHeaders__fields[3] = {
@@ -758,13 +758,13 @@ static const upb_msglayout_field envoy_config_route_v3_RateLimit_Action_RequestH
 const upb_msglayout envoy_config_route_v3_RateLimit_Action_RequestHeaders_msginit = {
   NULL,
   &envoy_config_route_v3_RateLimit_Action_RequestHeaders__fields[0],
-  UPB_SIZE(24, 48), 3, false,
+  UPB_SIZE(24, 48), 3, false, 255,
 };
 
 const upb_msglayout envoy_config_route_v3_RateLimit_Action_RemoteAddress_msginit = {
   NULL,
   NULL,
-  UPB_SIZE(0, 0), 0, false,
+  UPB_SIZE(0, 0), 0, false, 255,
 };
 
 static const upb_msglayout_field envoy_config_route_v3_RateLimit_Action_GenericKey__fields[2] = {
@@ -775,7 +775,7 @@ static const upb_msglayout_field envoy_config_route_v3_RateLimit_Action_GenericK
 const upb_msglayout envoy_config_route_v3_RateLimit_Action_GenericKey_msginit = {
   NULL,
   &envoy_config_route_v3_RateLimit_Action_GenericKey__fields[0],
-  UPB_SIZE(16, 32), 2, false,
+  UPB_SIZE(16, 32), 2, false, 255,
 };
 
 static const upb_msglayout *const envoy_config_route_v3_RateLimit_Action_HeaderValueMatch_submsgs[2] = {
@@ -784,15 +784,15 @@ static const upb_msglayout *const envoy_config_route_v3_RateLimit_Action_HeaderV
 };
 
 static const upb_msglayout_field envoy_config_route_v3_RateLimit_Action_HeaderValueMatch__fields[3] = {
-  {1, UPB_SIZE(0, 0), 0, 0, 9, 1},
-  {2, UPB_SIZE(8, 16), 0, 1, 11, 1},
-  {3, UPB_SIZE(12, 24), 0, 0, 11, 3},
+  {1, UPB_SIZE(4, 8), 0, 0, 9, 1},
+  {2, UPB_SIZE(12, 24), 1, 1, 11, 1},
+  {3, UPB_SIZE(16, 32), 0, 0, 11, 3},
 };
 
 const upb_msglayout envoy_config_route_v3_RateLimit_Action_HeaderValueMatch_msginit = {
   &envoy_config_route_v3_RateLimit_Action_HeaderValueMatch_submsgs[0],
   &envoy_config_route_v3_RateLimit_Action_HeaderValueMatch__fields[0],
-  UPB_SIZE(16, 32), 3, false,
+  UPB_SIZE(24, 48), 3, false, 255,
 };
 
 static const upb_msglayout *const envoy_config_route_v3_RateLimit_Action_DynamicMetaData_submsgs[1] = {
@@ -800,15 +800,15 @@ static const upb_msglayout *const envoy_config_route_v3_RateLimit_Action_Dynamic
 };
 
 static const upb_msglayout_field envoy_config_route_v3_RateLimit_Action_DynamicMetaData__fields[3] = {
-  {1, UPB_SIZE(0, 0), 0, 0, 9, 1},
-  {2, UPB_SIZE(16, 32), 0, 0, 11, 1},
-  {3, UPB_SIZE(8, 16), 0, 0, 9, 1},
+  {1, UPB_SIZE(4, 8), 0, 0, 9, 1},
+  {2, UPB_SIZE(20, 40), 1, 0, 11, 1},
+  {3, UPB_SIZE(12, 24), 0, 0, 9, 1},
 };
 
 const upb_msglayout envoy_config_route_v3_RateLimit_Action_DynamicMetaData_msginit = {
   &envoy_config_route_v3_RateLimit_Action_DynamicMetaData_submsgs[0],
   &envoy_config_route_v3_RateLimit_Action_DynamicMetaData__fields[0],
-  UPB_SIZE(24, 48), 3, false,
+  UPB_SIZE(24, 48), 3, false, 255,
 };
 
 static const upb_msglayout *const envoy_config_route_v3_RateLimit_Override_submsgs[1] = {
@@ -822,7 +822,7 @@ static const upb_msglayout_field envoy_config_route_v3_RateLimit_Override__field
 const upb_msglayout envoy_config_route_v3_RateLimit_Override_msginit = {
   &envoy_config_route_v3_RateLimit_Override_submsgs[0],
   &envoy_config_route_v3_RateLimit_Override__fields[0],
-  UPB_SIZE(8, 16), 1, false,
+  UPB_SIZE(8, 16), 1, false, 255,
 };
 
 static const upb_msglayout *const envoy_config_route_v3_RateLimit_Override_DynamicMetadata_submsgs[1] = {
@@ -830,13 +830,13 @@ static const upb_msglayout *const envoy_config_route_v3_RateLimit_Override_Dynam
 };
 
 static const upb_msglayout_field envoy_config_route_v3_RateLimit_Override_DynamicMetadata__fields[1] = {
-  {1, UPB_SIZE(0, 0), 0, 0, 11, 1},
+  {1, UPB_SIZE(4, 8), 1, 0, 11, 1},
 };
 
 const upb_msglayout envoy_config_route_v3_RateLimit_Override_DynamicMetadata_msginit = {
   &envoy_config_route_v3_RateLimit_Override_DynamicMetadata_submsgs[0],
   &envoy_config_route_v3_RateLimit_Override_DynamicMetadata__fields[0],
-  UPB_SIZE(4, 8), 1, false,
+  UPB_SIZE(8, 16), 1, false, 255,
 };
 
 static const upb_msglayout *const envoy_config_route_v3_HeaderMatcher_submsgs[2] = {
@@ -859,7 +859,7 @@ static const upb_msglayout_field envoy_config_route_v3_HeaderMatcher__fields[9]
 const upb_msglayout envoy_config_route_v3_HeaderMatcher_msginit = {
   &envoy_config_route_v3_HeaderMatcher_submsgs[0],
   &envoy_config_route_v3_HeaderMatcher__fields[0],
-  UPB_SIZE(24, 48), 9, false,
+  UPB_SIZE(24, 48), 9, false, 255,
 };
 
 static const upb_msglayout *const envoy_config_route_v3_QueryParameterMatcher_submsgs[1] = {
@@ -875,7 +875,7 @@ static const upb_msglayout_field envoy_config_route_v3_QueryParameterMatcher__fi
 const upb_msglayout envoy_config_route_v3_QueryParameterMatcher_msginit = {
   &envoy_config_route_v3_QueryParameterMatcher_submsgs[0],
   &envoy_config_route_v3_QueryParameterMatcher__fields[0],
-  UPB_SIZE(16, 32), 3, false,
+  UPB_SIZE(16, 32), 3, false, 255,
 };
 
 static const upb_msglayout *const envoy_config_route_v3_InternalRedirectPolicy_submsgs[2] = {
@@ -884,16 +884,16 @@ static const upb_msglayout *const envoy_config_route_v3_InternalRedirectPolicy_s
 };
 
 static const upb_msglayout_field envoy_config_route_v3_InternalRedirectPolicy__fields[4] = {
-  {1, UPB_SIZE(4, 8), 0, 1, 11, 1},
+  {1, UPB_SIZE(4, 8), 1, 1, 11, 1},
   {2, UPB_SIZE(8, 16), 0, 0, 13, _UPB_LABEL_PACKED},
   {3, UPB_SIZE(12, 24), 0, 0, 11, 3},
-  {4, UPB_SIZE(0, 0), 0, 0, 8, 1},
+  {4, UPB_SIZE(1, 1), 0, 0, 8, 1},
 };
 
 const upb_msglayout envoy_config_route_v3_InternalRedirectPolicy_msginit = {
   &envoy_config_route_v3_InternalRedirectPolicy_submsgs[0],
   &envoy_config_route_v3_InternalRedirectPolicy__fields[0],
-  UPB_SIZE(16, 32), 4, false,
+  UPB_SIZE(16, 32), 4, false, 255,
 };
 
 #include "upb/port_undef.inc"
index 863c7a6..863404e 100644 (file)
@@ -11,6 +11,7 @@
 
 #include "upb/msg.h"
 #include "upb/decode.h"
+#include "upb/decode_fast.h"
 #include "upb/encode.h"
 
 #include "upb/port_def.inc"
@@ -244,6 +245,12 @@ UPB_INLINE envoy_config_route_v3_VirtualHost *envoy_config_route_v3_VirtualHost_
   envoy_config_route_v3_VirtualHost *ret = envoy_config_route_v3_VirtualHost_new(arena);
   return (ret && upb_decode(buf, size, ret, &envoy_config_route_v3_VirtualHost_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE envoy_config_route_v3_VirtualHost *envoy_config_route_v3_VirtualHost_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  envoy_config_route_v3_VirtualHost *ret = envoy_config_route_v3_VirtualHost_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &envoy_config_route_v3_VirtualHost_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *envoy_config_route_v3_VirtualHost_serialize(const envoy_config_route_v3_VirtualHost *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &envoy_config_route_v3_VirtualHost_msginit, arena, len);
 }
@@ -252,14 +259,14 @@ UPB_INLINE upb_strview envoy_config_route_v3_VirtualHost_name(const envoy_config
 UPB_INLINE upb_strview const* envoy_config_route_v3_VirtualHost_domains(const envoy_config_route_v3_VirtualHost *msg, size_t *len) { return (upb_strview const*)_upb_array_accessor(msg, UPB_SIZE(40, 72), len); }
 UPB_INLINE bool envoy_config_route_v3_VirtualHost_has_routes(const envoy_config_route_v3_VirtualHost *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(44, 80)); }
 UPB_INLINE const envoy_config_route_v3_Route* const* envoy_config_route_v3_VirtualHost_routes(const envoy_config_route_v3_VirtualHost *msg, size_t *len) { return (const envoy_config_route_v3_Route* const*)_upb_array_accessor(msg, UPB_SIZE(44, 80), len); }
-UPB_INLINE int32_t envoy_config_route_v3_VirtualHost_require_tls(const envoy_config_route_v3_VirtualHost *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(0, 0), int32_t); }
+UPB_INLINE int32_t envoy_config_route_v3_VirtualHost_require_tls(const envoy_config_route_v3_VirtualHost *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(4, 4), int32_t); }
 UPB_INLINE bool envoy_config_route_v3_VirtualHost_has_virtual_clusters(const envoy_config_route_v3_VirtualHost *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(48, 88)); }
 UPB_INLINE const envoy_config_route_v3_VirtualCluster* const* envoy_config_route_v3_VirtualHost_virtual_clusters(const envoy_config_route_v3_VirtualHost *msg, size_t *len) { return (const envoy_config_route_v3_VirtualCluster* const*)_upb_array_accessor(msg, UPB_SIZE(48, 88), len); }
 UPB_INLINE bool envoy_config_route_v3_VirtualHost_has_rate_limits(const envoy_config_route_v3_VirtualHost *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(52, 96)); }
 UPB_INLINE const envoy_config_route_v3_RateLimit* const* envoy_config_route_v3_VirtualHost_rate_limits(const envoy_config_route_v3_VirtualHost *msg, size_t *len) { return (const envoy_config_route_v3_RateLimit* const*)_upb_array_accessor(msg, UPB_SIZE(52, 96), len); }
 UPB_INLINE bool envoy_config_route_v3_VirtualHost_has_request_headers_to_add(const envoy_config_route_v3_VirtualHost *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(56, 104)); }
 UPB_INLINE const struct envoy_config_core_v3_HeaderValueOption* const* envoy_config_route_v3_VirtualHost_request_headers_to_add(const envoy_config_route_v3_VirtualHost *msg, size_t *len) { return (const struct envoy_config_core_v3_HeaderValueOption* const*)_upb_array_accessor(msg, UPB_SIZE(56, 104), len); }
-UPB_INLINE bool envoy_config_route_v3_VirtualHost_has_cors(const envoy_config_route_v3_VirtualHost *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(20, 32)); }
+UPB_INLINE bool envoy_config_route_v3_VirtualHost_has_cors(const envoy_config_route_v3_VirtualHost *msg) { return _upb_hasbit(msg, 1); }
 UPB_INLINE const envoy_config_route_v3_CorsPolicy* envoy_config_route_v3_VirtualHost_cors(const envoy_config_route_v3_VirtualHost *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(20, 32), const envoy_config_route_v3_CorsPolicy*); }
 UPB_INLINE bool envoy_config_route_v3_VirtualHost_has_response_headers_to_add(const envoy_config_route_v3_VirtualHost *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(60, 112)); }
 UPB_INLINE const struct envoy_config_core_v3_HeaderValueOption* const* envoy_config_route_v3_VirtualHost_response_headers_to_add(const envoy_config_route_v3_VirtualHost *msg, size_t *len) { return (const struct envoy_config_core_v3_HeaderValueOption* const*)_upb_array_accessor(msg, UPB_SIZE(60, 112), len); }
@@ -270,14 +277,14 @@ UPB_INLINE bool envoy_config_route_v3_VirtualHost_has_typed_per_filter_config(co
 UPB_INLINE size_t envoy_config_route_v3_VirtualHost_typed_per_filter_config_size(const envoy_config_route_v3_VirtualHost *msg) {return _upb_msg_map_size(msg, UPB_SIZE(72, 136)); }
 UPB_INLINE bool envoy_config_route_v3_VirtualHost_typed_per_filter_config_get(const envoy_config_route_v3_VirtualHost *msg, upb_strview key, struct google_protobuf_Any* *val) { return _upb_msg_map_get(msg, UPB_SIZE(72, 136), &key, 0, val, sizeof(*val)); }
 UPB_INLINE const envoy_config_route_v3_VirtualHost_TypedPerFilterConfigEntry* envoy_config_route_v3_VirtualHost_typed_per_filter_config_next(const envoy_config_route_v3_VirtualHost *msg, size_t* iter) { return (const envoy_config_route_v3_VirtualHost_TypedPerFilterConfigEntry*)_upb_msg_map_next(msg, UPB_SIZE(72, 136), iter); }
-UPB_INLINE bool envoy_config_route_v3_VirtualHost_has_retry_policy(const envoy_config_route_v3_VirtualHost *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(24, 40)); }
+UPB_INLINE bool envoy_config_route_v3_VirtualHost_has_retry_policy(const envoy_config_route_v3_VirtualHost *msg) { return _upb_hasbit(msg, 2); }
 UPB_INLINE const envoy_config_route_v3_RetryPolicy* envoy_config_route_v3_VirtualHost_retry_policy(const envoy_config_route_v3_VirtualHost *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(24, 40), const envoy_config_route_v3_RetryPolicy*); }
-UPB_INLINE bool envoy_config_route_v3_VirtualHost_has_hedge_policy(const envoy_config_route_v3_VirtualHost *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(28, 48)); }
+UPB_INLINE bool envoy_config_route_v3_VirtualHost_has_hedge_policy(const envoy_config_route_v3_VirtualHost *msg) { return _upb_hasbit(msg, 3); }
 UPB_INLINE const envoy_config_route_v3_HedgePolicy* envoy_config_route_v3_VirtualHost_hedge_policy(const envoy_config_route_v3_VirtualHost *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(28, 48), const envoy_config_route_v3_HedgePolicy*); }
-UPB_INLINE bool envoy_config_route_v3_VirtualHost_has_per_request_buffer_limit_bytes(const envoy_config_route_v3_VirtualHost *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(32, 56)); }
+UPB_INLINE bool envoy_config_route_v3_VirtualHost_has_per_request_buffer_limit_bytes(const envoy_config_route_v3_VirtualHost *msg) { return _upb_hasbit(msg, 4); }
 UPB_INLINE const struct google_protobuf_UInt32Value* envoy_config_route_v3_VirtualHost_per_request_buffer_limit_bytes(const envoy_config_route_v3_VirtualHost *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(32, 56), const struct google_protobuf_UInt32Value*); }
 UPB_INLINE bool envoy_config_route_v3_VirtualHost_include_attempt_count_in_response(const envoy_config_route_v3_VirtualHost *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(9, 9), bool); }
-UPB_INLINE bool envoy_config_route_v3_VirtualHost_has_retry_policy_typed_config(const envoy_config_route_v3_VirtualHost *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(36, 64)); }
+UPB_INLINE bool envoy_config_route_v3_VirtualHost_has_retry_policy_typed_config(const envoy_config_route_v3_VirtualHost *msg) { return _upb_hasbit(msg, 5); }
 UPB_INLINE const struct google_protobuf_Any* envoy_config_route_v3_VirtualHost_retry_policy_typed_config(const envoy_config_route_v3_VirtualHost *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(36, 64), const struct google_protobuf_Any*); }
 
 UPB_INLINE void envoy_config_route_v3_VirtualHost_set_name(envoy_config_route_v3_VirtualHost *msg, upb_strview value) {
@@ -287,38 +294,38 @@ UPB_INLINE upb_strview* envoy_config_route_v3_VirtualHost_mutable_domains(envoy_
   return (upb_strview*)_upb_array_mutable_accessor(msg, UPB_SIZE(40, 72), len);
 }
 UPB_INLINE upb_strview* envoy_config_route_v3_VirtualHost_resize_domains(envoy_config_route_v3_VirtualHost *msg, size_t len, upb_arena *arena) {
-  return (upb_strview*)_upb_array_resize_accessor(msg, UPB_SIZE(40, 72), len, UPB_TYPE_STRING, arena);
+  return (upb_strview*)_upb_array_resize_accessor2(msg, UPB_SIZE(40, 72), len, UPB_SIZE(3, 4), arena);
 }
 UPB_INLINE bool envoy_config_route_v3_VirtualHost_add_domains(envoy_config_route_v3_VirtualHost *msg, upb_strview val, upb_arena *arena) {
-  return _upb_array_append_accessor(msg, UPB_SIZE(40, 72), UPB_SIZE(8, 16), UPB_TYPE_STRING, &val,
+  return _upb_array_append_accessor2(msg, UPB_SIZE(40, 72), UPB_SIZE(3, 4), &val,
       arena);
 }
 UPB_INLINE envoy_config_route_v3_Route** envoy_config_route_v3_VirtualHost_mutable_routes(envoy_config_route_v3_VirtualHost *msg, size_t *len) {
   return (envoy_config_route_v3_Route**)_upb_array_mutable_accessor(msg, UPB_SIZE(44, 80), len);
 }
 UPB_INLINE envoy_config_route_v3_Route** envoy_config_route_v3_VirtualHost_resize_routes(envoy_config_route_v3_VirtualHost *msg, size_t len, upb_arena *arena) {
-  return (envoy_config_route_v3_Route**)_upb_array_resize_accessor(msg, UPB_SIZE(44, 80), len, UPB_TYPE_MESSAGE, arena);
+  return (envoy_config_route_v3_Route**)_upb_array_resize_accessor2(msg, UPB_SIZE(44, 80), len, UPB_SIZE(2, 3), arena);
 }
 UPB_INLINE struct envoy_config_route_v3_Route* envoy_config_route_v3_VirtualHost_add_routes(envoy_config_route_v3_VirtualHost *msg, upb_arena *arena) {
   struct envoy_config_route_v3_Route* sub = (struct envoy_config_route_v3_Route*)_upb_msg_new(&envoy_config_route_v3_Route_msginit, arena);
-  bool ok = _upb_array_append_accessor(
-      msg, UPB_SIZE(44, 80), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena);
+  bool ok = _upb_array_append_accessor2(
+      msg, UPB_SIZE(44, 80), UPB_SIZE(2, 3), &sub, arena);
   if (!ok) return NULL;
   return sub;
 }
 UPB_INLINE void envoy_config_route_v3_VirtualHost_set_require_tls(envoy_config_route_v3_VirtualHost *msg, int32_t value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(0, 0), int32_t) = value;
+  *UPB_PTR_AT(msg, UPB_SIZE(4, 4), int32_t) = value;
 }
 UPB_INLINE envoy_config_route_v3_VirtualCluster** envoy_config_route_v3_VirtualHost_mutable_virtual_clusters(envoy_config_route_v3_VirtualHost *msg, size_t *len) {
   return (envoy_config_route_v3_VirtualCluster**)_upb_array_mutable_accessor(msg, UPB_SIZE(48, 88), len);
 }
 UPB_INLINE envoy_config_route_v3_VirtualCluster** envoy_config_route_v3_VirtualHost_resize_virtual_clusters(envoy_config_route_v3_VirtualHost *msg, size_t len, upb_arena *arena) {
-  return (envoy_config_route_v3_VirtualCluster**)_upb_array_resize_accessor(msg, UPB_SIZE(48, 88), len, UPB_TYPE_MESSAGE, arena);
+  return (envoy_config_route_v3_VirtualCluster**)_upb_array_resize_accessor2(msg, UPB_SIZE(48, 88), len, UPB_SIZE(2, 3), arena);
 }
 UPB_INLINE struct envoy_config_route_v3_VirtualCluster* envoy_config_route_v3_VirtualHost_add_virtual_clusters(envoy_config_route_v3_VirtualHost *msg, upb_arena *arena) {
   struct envoy_config_route_v3_VirtualCluster* sub = (struct envoy_config_route_v3_VirtualCluster*)_upb_msg_new(&envoy_config_route_v3_VirtualCluster_msginit, arena);
-  bool ok = _upb_array_append_accessor(
-      msg, UPB_SIZE(48, 88), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena);
+  bool ok = _upb_array_append_accessor2(
+      msg, UPB_SIZE(48, 88), UPB_SIZE(2, 3), &sub, arena);
   if (!ok) return NULL;
   return sub;
 }
@@ -326,12 +333,12 @@ UPB_INLINE envoy_config_route_v3_RateLimit** envoy_config_route_v3_VirtualHost_m
   return (envoy_config_route_v3_RateLimit**)_upb_array_mutable_accessor(msg, UPB_SIZE(52, 96), len);
 }
 UPB_INLINE envoy_config_route_v3_RateLimit** envoy_config_route_v3_VirtualHost_resize_rate_limits(envoy_config_route_v3_VirtualHost *msg, size_t len, upb_arena *arena) {
-  return (envoy_config_route_v3_RateLimit**)_upb_array_resize_accessor(msg, UPB_SIZE(52, 96), len, UPB_TYPE_MESSAGE, arena);
+  return (envoy_config_route_v3_RateLimit**)_upb_array_resize_accessor2(msg, UPB_SIZE(52, 96), len, UPB_SIZE(2, 3), arena);
 }
 UPB_INLINE struct envoy_config_route_v3_RateLimit* envoy_config_route_v3_VirtualHost_add_rate_limits(envoy_config_route_v3_VirtualHost *msg, upb_arena *arena) {
   struct envoy_config_route_v3_RateLimit* sub = (struct envoy_config_route_v3_RateLimit*)_upb_msg_new(&envoy_config_route_v3_RateLimit_msginit, arena);
-  bool ok = _upb_array_append_accessor(
-      msg, UPB_SIZE(52, 96), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena);
+  bool ok = _upb_array_append_accessor2(
+      msg, UPB_SIZE(52, 96), UPB_SIZE(2, 3), &sub, arena);
   if (!ok) return NULL;
   return sub;
 }
@@ -339,16 +346,17 @@ UPB_INLINE struct envoy_config_core_v3_HeaderValueOption** envoy_config_route_v3
   return (struct envoy_config_core_v3_HeaderValueOption**)_upb_array_mutable_accessor(msg, UPB_SIZE(56, 104), len);
 }
 UPB_INLINE struct envoy_config_core_v3_HeaderValueOption** envoy_config_route_v3_VirtualHost_resize_request_headers_to_add(envoy_config_route_v3_VirtualHost *msg, size_t len, upb_arena *arena) {
-  return (struct envoy_config_core_v3_HeaderValueOption**)_upb_array_resize_accessor(msg, UPB_SIZE(56, 104), len, UPB_TYPE_MESSAGE, arena);
+  return (struct envoy_config_core_v3_HeaderValueOption**)_upb_array_resize_accessor2(msg, UPB_SIZE(56, 104), len, UPB_SIZE(2, 3), arena);
 }
 UPB_INLINE struct envoy_config_core_v3_HeaderValueOption* envoy_config_route_v3_VirtualHost_add_request_headers_to_add(envoy_config_route_v3_VirtualHost *msg, upb_arena *arena) {
   struct envoy_config_core_v3_HeaderValueOption* sub = (struct envoy_config_core_v3_HeaderValueOption*)_upb_msg_new(&envoy_config_core_v3_HeaderValueOption_msginit, arena);
-  bool ok = _upb_array_append_accessor(
-      msg, UPB_SIZE(56, 104), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena);
+  bool ok = _upb_array_append_accessor2(
+      msg, UPB_SIZE(56, 104), UPB_SIZE(2, 3), &sub, arena);
   if (!ok) return NULL;
   return sub;
 }
 UPB_INLINE void envoy_config_route_v3_VirtualHost_set_cors(envoy_config_route_v3_VirtualHost *msg, envoy_config_route_v3_CorsPolicy* value) {
+  _upb_sethas(msg, 1);
   *UPB_PTR_AT(msg, UPB_SIZE(20, 32), envoy_config_route_v3_CorsPolicy*) = value;
 }
 UPB_INLINE struct envoy_config_route_v3_CorsPolicy* envoy_config_route_v3_VirtualHost_mutable_cors(envoy_config_route_v3_VirtualHost *msg, upb_arena *arena) {
@@ -364,12 +372,12 @@ UPB_INLINE struct envoy_config_core_v3_HeaderValueOption** envoy_config_route_v3
   return (struct envoy_config_core_v3_HeaderValueOption**)_upb_array_mutable_accessor(msg, UPB_SIZE(60, 112), len);
 }
 UPB_INLINE struct envoy_config_core_v3_HeaderValueOption** envoy_config_route_v3_VirtualHost_resize_response_headers_to_add(envoy_config_route_v3_VirtualHost *msg, size_t len, upb_arena *arena) {
-  return (struct envoy_config_core_v3_HeaderValueOption**)_upb_array_resize_accessor(msg, UPB_SIZE(60, 112), len, UPB_TYPE_MESSAGE, arena);
+  return (struct envoy_config_core_v3_HeaderValueOption**)_upb_array_resize_accessor2(msg, UPB_SIZE(60, 112), len, UPB_SIZE(2, 3), arena);
 }
 UPB_INLINE struct envoy_config_core_v3_HeaderValueOption* envoy_config_route_v3_VirtualHost_add_response_headers_to_add(envoy_config_route_v3_VirtualHost *msg, upb_arena *arena) {
   struct envoy_config_core_v3_HeaderValueOption* sub = (struct envoy_config_core_v3_HeaderValueOption*)_upb_msg_new(&envoy_config_core_v3_HeaderValueOption_msginit, arena);
-  bool ok = _upb_array_append_accessor(
-      msg, UPB_SIZE(60, 112), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena);
+  bool ok = _upb_array_append_accessor2(
+      msg, UPB_SIZE(60, 112), UPB_SIZE(2, 3), &sub, arena);
   if (!ok) return NULL;
   return sub;
 }
@@ -377,20 +385,20 @@ UPB_INLINE upb_strview* envoy_config_route_v3_VirtualHost_mutable_response_heade
   return (upb_strview*)_upb_array_mutable_accessor(msg, UPB_SIZE(64, 120), len);
 }
 UPB_INLINE upb_strview* envoy_config_route_v3_VirtualHost_resize_response_headers_to_remove(envoy_config_route_v3_VirtualHost *msg, size_t len, upb_arena *arena) {
-  return (upb_strview*)_upb_array_resize_accessor(msg, UPB_SIZE(64, 120), len, UPB_TYPE_STRING, arena);
+  return (upb_strview*)_upb_array_resize_accessor2(msg, UPB_SIZE(64, 120), len, UPB_SIZE(3, 4), arena);
 }
 UPB_INLINE bool envoy_config_route_v3_VirtualHost_add_response_headers_to_remove(envoy_config_route_v3_VirtualHost *msg, upb_strview val, upb_arena *arena) {
-  return _upb_array_append_accessor(msg, UPB_SIZE(64, 120), UPB_SIZE(8, 16), UPB_TYPE_STRING, &val,
+  return _upb_array_append_accessor2(msg, UPB_SIZE(64, 120), UPB_SIZE(3, 4), &val,
       arena);
 }
 UPB_INLINE upb_strview* envoy_config_route_v3_VirtualHost_mutable_request_headers_to_remove(envoy_config_route_v3_VirtualHost *msg, size_t *len) {
   return (upb_strview*)_upb_array_mutable_accessor(msg, UPB_SIZE(68, 128), len);
 }
 UPB_INLINE upb_strview* envoy_config_route_v3_VirtualHost_resize_request_headers_to_remove(envoy_config_route_v3_VirtualHost *msg, size_t len, upb_arena *arena) {
-  return (upb_strview*)_upb_array_resize_accessor(msg, UPB_SIZE(68, 128), len, UPB_TYPE_STRING, arena);
+  return (upb_strview*)_upb_array_resize_accessor2(msg, UPB_SIZE(68, 128), len, UPB_SIZE(3, 4), arena);
 }
 UPB_INLINE bool envoy_config_route_v3_VirtualHost_add_request_headers_to_remove(envoy_config_route_v3_VirtualHost *msg, upb_strview val, upb_arena *arena) {
-  return _upb_array_append_accessor(msg, UPB_SIZE(68, 128), UPB_SIZE(8, 16), UPB_TYPE_STRING, &val,
+  return _upb_array_append_accessor2(msg, UPB_SIZE(68, 128), UPB_SIZE(3, 4), &val,
       arena);
 }
 UPB_INLINE void envoy_config_route_v3_VirtualHost_set_include_request_attempt_count(envoy_config_route_v3_VirtualHost *msg, bool value) {
@@ -401,6 +409,7 @@ UPB_INLINE bool envoy_config_route_v3_VirtualHost_typed_per_filter_config_set(en
 UPB_INLINE bool envoy_config_route_v3_VirtualHost_typed_per_filter_config_delete(envoy_config_route_v3_VirtualHost *msg, upb_strview key) { return _upb_msg_map_delete(msg, UPB_SIZE(72, 136), &key, 0); }
 UPB_INLINE envoy_config_route_v3_VirtualHost_TypedPerFilterConfigEntry* envoy_config_route_v3_VirtualHost_typed_per_filter_config_nextmutable(envoy_config_route_v3_VirtualHost *msg, size_t* iter) { return (envoy_config_route_v3_VirtualHost_TypedPerFilterConfigEntry*)_upb_msg_map_next(msg, UPB_SIZE(72, 136), iter); }
 UPB_INLINE void envoy_config_route_v3_VirtualHost_set_retry_policy(envoy_config_route_v3_VirtualHost *msg, envoy_config_route_v3_RetryPolicy* value) {
+  _upb_sethas(msg, 2);
   *UPB_PTR_AT(msg, UPB_SIZE(24, 40), envoy_config_route_v3_RetryPolicy*) = value;
 }
 UPB_INLINE struct envoy_config_route_v3_RetryPolicy* envoy_config_route_v3_VirtualHost_mutable_retry_policy(envoy_config_route_v3_VirtualHost *msg, upb_arena *arena) {
@@ -413,6 +422,7 @@ UPB_INLINE struct envoy_config_route_v3_RetryPolicy* envoy_config_route_v3_Virtu
   return sub;
 }
 UPB_INLINE void envoy_config_route_v3_VirtualHost_set_hedge_policy(envoy_config_route_v3_VirtualHost *msg, envoy_config_route_v3_HedgePolicy* value) {
+  _upb_sethas(msg, 3);
   *UPB_PTR_AT(msg, UPB_SIZE(28, 48), envoy_config_route_v3_HedgePolicy*) = value;
 }
 UPB_INLINE struct envoy_config_route_v3_HedgePolicy* envoy_config_route_v3_VirtualHost_mutable_hedge_policy(envoy_config_route_v3_VirtualHost *msg, upb_arena *arena) {
@@ -425,6 +435,7 @@ UPB_INLINE struct envoy_config_route_v3_HedgePolicy* envoy_config_route_v3_Virtu
   return sub;
 }
 UPB_INLINE void envoy_config_route_v3_VirtualHost_set_per_request_buffer_limit_bytes(envoy_config_route_v3_VirtualHost *msg, struct google_protobuf_UInt32Value* value) {
+  _upb_sethas(msg, 4);
   *UPB_PTR_AT(msg, UPB_SIZE(32, 56), struct google_protobuf_UInt32Value*) = value;
 }
 UPB_INLINE struct google_protobuf_UInt32Value* envoy_config_route_v3_VirtualHost_mutable_per_request_buffer_limit_bytes(envoy_config_route_v3_VirtualHost *msg, upb_arena *arena) {
@@ -440,6 +451,7 @@ UPB_INLINE void envoy_config_route_v3_VirtualHost_set_include_attempt_count_in_r
   *UPB_PTR_AT(msg, UPB_SIZE(9, 9), bool) = value;
 }
 UPB_INLINE void envoy_config_route_v3_VirtualHost_set_retry_policy_typed_config(envoy_config_route_v3_VirtualHost *msg, struct google_protobuf_Any* value) {
+  _upb_sethas(msg, 5);
   *UPB_PTR_AT(msg, UPB_SIZE(36, 64), struct google_protobuf_Any*) = value;
 }
 UPB_INLINE struct google_protobuf_Any* envoy_config_route_v3_VirtualHost_mutable_retry_policy_typed_config(envoy_config_route_v3_VirtualHost *msg, upb_arena *arena) {
@@ -480,15 +492,22 @@ UPB_INLINE envoy_config_route_v3_FilterAction *envoy_config_route_v3_FilterActio
   envoy_config_route_v3_FilterAction *ret = envoy_config_route_v3_FilterAction_new(arena);
   return (ret && upb_decode(buf, size, ret, &envoy_config_route_v3_FilterAction_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE envoy_config_route_v3_FilterAction *envoy_config_route_v3_FilterAction_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  envoy_config_route_v3_FilterAction *ret = envoy_config_route_v3_FilterAction_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &envoy_config_route_v3_FilterAction_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *envoy_config_route_v3_FilterAction_serialize(const envoy_config_route_v3_FilterAction *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &envoy_config_route_v3_FilterAction_msginit, arena, len);
 }
 
-UPB_INLINE bool envoy_config_route_v3_FilterAction_has_action(const envoy_config_route_v3_FilterAction *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(0, 0)); }
-UPB_INLINE const struct google_protobuf_Any* envoy_config_route_v3_FilterAction_action(const envoy_config_route_v3_FilterAction *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(0, 0), const struct google_protobuf_Any*); }
+UPB_INLINE bool envoy_config_route_v3_FilterAction_has_action(const envoy_config_route_v3_FilterAction *msg) { return _upb_hasbit(msg, 1); }
+UPB_INLINE const struct google_protobuf_Any* envoy_config_route_v3_FilterAction_action(const envoy_config_route_v3_FilterAction *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(4, 8), const struct google_protobuf_Any*); }
 
 UPB_INLINE void envoy_config_route_v3_FilterAction_set_action(envoy_config_route_v3_FilterAction *msg, struct google_protobuf_Any* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(0, 0), struct google_protobuf_Any*) = value;
+  _upb_sethas(msg, 1);
+  *UPB_PTR_AT(msg, UPB_SIZE(4, 8), struct google_protobuf_Any*) = value;
 }
 UPB_INLINE struct google_protobuf_Any* envoy_config_route_v3_FilterAction_mutable_action(envoy_config_route_v3_FilterAction *msg, upb_arena *arena) {
   struct google_protobuf_Any* sub = (struct google_protobuf_Any*)envoy_config_route_v3_FilterAction_action(msg);
@@ -510,6 +529,12 @@ UPB_INLINE envoy_config_route_v3_Route *envoy_config_route_v3_Route_parse(const
   envoy_config_route_v3_Route *ret = envoy_config_route_v3_Route_new(arena);
   return (ret && upb_decode(buf, size, ret, &envoy_config_route_v3_Route_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE envoy_config_route_v3_Route *envoy_config_route_v3_Route_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  envoy_config_route_v3_Route *ret = envoy_config_route_v3_Route_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &envoy_config_route_v3_Route_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *envoy_config_route_v3_Route_serialize(const envoy_config_route_v3_Route *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &envoy_config_route_v3_Route_msginit, arena, len);
 }
@@ -521,40 +546,41 @@ typedef enum {
   envoy_config_route_v3_Route_action_filter_action = 17,
   envoy_config_route_v3_Route_action_NOT_SET = 0
 } envoy_config_route_v3_Route_action_oneofcases;
-UPB_INLINE envoy_config_route_v3_Route_action_oneofcases envoy_config_route_v3_Route_action_case(const envoy_config_route_v3_Route* msg) { return (envoy_config_route_v3_Route_action_oneofcases)*UPB_PTR_AT(msg, UPB_SIZE(52, 104), int32_t); }
-
-UPB_INLINE bool envoy_config_route_v3_Route_has_match(const envoy_config_route_v3_Route *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(8, 16)); }
-UPB_INLINE const envoy_config_route_v3_RouteMatch* envoy_config_route_v3_Route_match(const envoy_config_route_v3_Route *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(8, 16), const envoy_config_route_v3_RouteMatch*); }
-UPB_INLINE bool envoy_config_route_v3_Route_has_route(const envoy_config_route_v3_Route *msg) { return _upb_getoneofcase(msg, UPB_SIZE(52, 104)) == 2; }
-UPB_INLINE const envoy_config_route_v3_RouteAction* envoy_config_route_v3_Route_route(const envoy_config_route_v3_Route *msg) { return UPB_READ_ONEOF(msg, const envoy_config_route_v3_RouteAction*, UPB_SIZE(48, 96), UPB_SIZE(52, 104), 2, NULL); }
-UPB_INLINE bool envoy_config_route_v3_Route_has_redirect(const envoy_config_route_v3_Route *msg) { return _upb_getoneofcase(msg, UPB_SIZE(52, 104)) == 3; }
-UPB_INLINE const envoy_config_route_v3_RedirectAction* envoy_config_route_v3_Route_redirect(const envoy_config_route_v3_Route *msg) { return UPB_READ_ONEOF(msg, const envoy_config_route_v3_RedirectAction*, UPB_SIZE(48, 96), UPB_SIZE(52, 104), 3, NULL); }
-UPB_INLINE bool envoy_config_route_v3_Route_has_metadata(const envoy_config_route_v3_Route *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(12, 24)); }
-UPB_INLINE const struct envoy_config_core_v3_Metadata* envoy_config_route_v3_Route_metadata(const envoy_config_route_v3_Route *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(12, 24), const struct envoy_config_core_v3_Metadata*); }
-UPB_INLINE bool envoy_config_route_v3_Route_has_decorator(const envoy_config_route_v3_Route *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(16, 32)); }
-UPB_INLINE const envoy_config_route_v3_Decorator* envoy_config_route_v3_Route_decorator(const envoy_config_route_v3_Route *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(16, 32), const envoy_config_route_v3_Decorator*); }
-UPB_INLINE bool envoy_config_route_v3_Route_has_direct_response(const envoy_config_route_v3_Route *msg) { return _upb_getoneofcase(msg, UPB_SIZE(52, 104)) == 7; }
-UPB_INLINE const envoy_config_route_v3_DirectResponseAction* envoy_config_route_v3_Route_direct_response(const envoy_config_route_v3_Route *msg) { return UPB_READ_ONEOF(msg, const envoy_config_route_v3_DirectResponseAction*, UPB_SIZE(48, 96), UPB_SIZE(52, 104), 7, NULL); }
-UPB_INLINE bool envoy_config_route_v3_Route_has_request_headers_to_add(const envoy_config_route_v3_Route *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(28, 56)); }
-UPB_INLINE const struct envoy_config_core_v3_HeaderValueOption* const* envoy_config_route_v3_Route_request_headers_to_add(const envoy_config_route_v3_Route *msg, size_t *len) { return (const struct envoy_config_core_v3_HeaderValueOption* const*)_upb_array_accessor(msg, UPB_SIZE(28, 56), len); }
-UPB_INLINE bool envoy_config_route_v3_Route_has_response_headers_to_add(const envoy_config_route_v3_Route *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(32, 64)); }
-UPB_INLINE const struct envoy_config_core_v3_HeaderValueOption* const* envoy_config_route_v3_Route_response_headers_to_add(const envoy_config_route_v3_Route *msg, size_t *len) { return (const struct envoy_config_core_v3_HeaderValueOption* const*)_upb_array_accessor(msg, UPB_SIZE(32, 64), len); }
-UPB_INLINE upb_strview const* envoy_config_route_v3_Route_response_headers_to_remove(const envoy_config_route_v3_Route *msg, size_t *len) { return (upb_strview const*)_upb_array_accessor(msg, UPB_SIZE(36, 72), len); }
-UPB_INLINE upb_strview const* envoy_config_route_v3_Route_request_headers_to_remove(const envoy_config_route_v3_Route *msg, size_t *len) { return (upb_strview const*)_upb_array_accessor(msg, UPB_SIZE(40, 80), len); }
-UPB_INLINE bool envoy_config_route_v3_Route_has_typed_per_filter_config(const envoy_config_route_v3_Route *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(44, 88)); }
-UPB_INLINE size_t envoy_config_route_v3_Route_typed_per_filter_config_size(const envoy_config_route_v3_Route *msg) {return _upb_msg_map_size(msg, UPB_SIZE(44, 88)); }
-UPB_INLINE bool envoy_config_route_v3_Route_typed_per_filter_config_get(const envoy_config_route_v3_Route *msg, upb_strview key, struct google_protobuf_Any* *val) { return _upb_msg_map_get(msg, UPB_SIZE(44, 88), &key, 0, val, sizeof(*val)); }
-UPB_INLINE const envoy_config_route_v3_Route_TypedPerFilterConfigEntry* envoy_config_route_v3_Route_typed_per_filter_config_next(const envoy_config_route_v3_Route *msg, size_t* iter) { return (const envoy_config_route_v3_Route_TypedPerFilterConfigEntry*)_upb_msg_map_next(msg, UPB_SIZE(44, 88), iter); }
-UPB_INLINE upb_strview envoy_config_route_v3_Route_name(const envoy_config_route_v3_Route *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(0, 0), upb_strview); }
-UPB_INLINE bool envoy_config_route_v3_Route_has_tracing(const envoy_config_route_v3_Route *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(20, 40)); }
-UPB_INLINE const envoy_config_route_v3_Tracing* envoy_config_route_v3_Route_tracing(const envoy_config_route_v3_Route *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(20, 40), const envoy_config_route_v3_Tracing*); }
-UPB_INLINE bool envoy_config_route_v3_Route_has_per_request_buffer_limit_bytes(const envoy_config_route_v3_Route *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(24, 48)); }
-UPB_INLINE const struct google_protobuf_UInt32Value* envoy_config_route_v3_Route_per_request_buffer_limit_bytes(const envoy_config_route_v3_Route *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(24, 48), const struct google_protobuf_UInt32Value*); }
-UPB_INLINE bool envoy_config_route_v3_Route_has_filter_action(const envoy_config_route_v3_Route *msg) { return _upb_getoneofcase(msg, UPB_SIZE(52, 104)) == 17; }
-UPB_INLINE const envoy_config_route_v3_FilterAction* envoy_config_route_v3_Route_filter_action(const envoy_config_route_v3_Route *msg) { return UPB_READ_ONEOF(msg, const envoy_config_route_v3_FilterAction*, UPB_SIZE(48, 96), UPB_SIZE(52, 104), 17, NULL); }
+UPB_INLINE envoy_config_route_v3_Route_action_oneofcases envoy_config_route_v3_Route_action_case(const envoy_config_route_v3_Route* msg) { return (envoy_config_route_v3_Route_action_oneofcases)*UPB_PTR_AT(msg, UPB_SIZE(56, 112), int32_t); }
+
+UPB_INLINE bool envoy_config_route_v3_Route_has_match(const envoy_config_route_v3_Route *msg) { return _upb_hasbit(msg, 1); }
+UPB_INLINE const envoy_config_route_v3_RouteMatch* envoy_config_route_v3_Route_match(const envoy_config_route_v3_Route *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(12, 24), const envoy_config_route_v3_RouteMatch*); }
+UPB_INLINE bool envoy_config_route_v3_Route_has_route(const envoy_config_route_v3_Route *msg) { return _upb_getoneofcase(msg, UPB_SIZE(56, 112)) == 2; }
+UPB_INLINE const envoy_config_route_v3_RouteAction* envoy_config_route_v3_Route_route(const envoy_config_route_v3_Route *msg) { return UPB_READ_ONEOF(msg, const envoy_config_route_v3_RouteAction*, UPB_SIZE(52, 104), UPB_SIZE(56, 112), 2, NULL); }
+UPB_INLINE bool envoy_config_route_v3_Route_has_redirect(const envoy_config_route_v3_Route *msg) { return _upb_getoneofcase(msg, UPB_SIZE(56, 112)) == 3; }
+UPB_INLINE const envoy_config_route_v3_RedirectAction* envoy_config_route_v3_Route_redirect(const envoy_config_route_v3_Route *msg) { return UPB_READ_ONEOF(msg, const envoy_config_route_v3_RedirectAction*, UPB_SIZE(52, 104), UPB_SIZE(56, 112), 3, NULL); }
+UPB_INLINE bool envoy_config_route_v3_Route_has_metadata(const envoy_config_route_v3_Route *msg) { return _upb_hasbit(msg, 2); }
+UPB_INLINE const struct envoy_config_core_v3_Metadata* envoy_config_route_v3_Route_metadata(const envoy_config_route_v3_Route *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(16, 32), const struct envoy_config_core_v3_Metadata*); }
+UPB_INLINE bool envoy_config_route_v3_Route_has_decorator(const envoy_config_route_v3_Route *msg) { return _upb_hasbit(msg, 3); }
+UPB_INLINE const envoy_config_route_v3_Decorator* envoy_config_route_v3_Route_decorator(const envoy_config_route_v3_Route *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(20, 40), const envoy_config_route_v3_Decorator*); }
+UPB_INLINE bool envoy_config_route_v3_Route_has_direct_response(const envoy_config_route_v3_Route *msg) { return _upb_getoneofcase(msg, UPB_SIZE(56, 112)) == 7; }
+UPB_INLINE const envoy_config_route_v3_DirectResponseAction* envoy_config_route_v3_Route_direct_response(const envoy_config_route_v3_Route *msg) { return UPB_READ_ONEOF(msg, const envoy_config_route_v3_DirectResponseAction*, UPB_SIZE(52, 104), UPB_SIZE(56, 112), 7, NULL); }
+UPB_INLINE bool envoy_config_route_v3_Route_has_request_headers_to_add(const envoy_config_route_v3_Route *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(32, 64)); }
+UPB_INLINE const struct envoy_config_core_v3_HeaderValueOption* const* envoy_config_route_v3_Route_request_headers_to_add(const envoy_config_route_v3_Route *msg, size_t *len) { return (const struct envoy_config_core_v3_HeaderValueOption* const*)_upb_array_accessor(msg, UPB_SIZE(32, 64), len); }
+UPB_INLINE bool envoy_config_route_v3_Route_has_response_headers_to_add(const envoy_config_route_v3_Route *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(36, 72)); }
+UPB_INLINE const struct envoy_config_core_v3_HeaderValueOption* const* envoy_config_route_v3_Route_response_headers_to_add(const envoy_config_route_v3_Route *msg, size_t *len) { return (const struct envoy_config_core_v3_HeaderValueOption* const*)_upb_array_accessor(msg, UPB_SIZE(36, 72), len); }
+UPB_INLINE upb_strview const* envoy_config_route_v3_Route_response_headers_to_remove(const envoy_config_route_v3_Route *msg, size_t *len) { return (upb_strview const*)_upb_array_accessor(msg, UPB_SIZE(40, 80), len); }
+UPB_INLINE upb_strview const* envoy_config_route_v3_Route_request_headers_to_remove(const envoy_config_route_v3_Route *msg, size_t *len) { return (upb_strview const*)_upb_array_accessor(msg, UPB_SIZE(44, 88), len); }
+UPB_INLINE bool envoy_config_route_v3_Route_has_typed_per_filter_config(const envoy_config_route_v3_Route *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(48, 96)); }
+UPB_INLINE size_t envoy_config_route_v3_Route_typed_per_filter_config_size(const envoy_config_route_v3_Route *msg) {return _upb_msg_map_size(msg, UPB_SIZE(48, 96)); }
+UPB_INLINE bool envoy_config_route_v3_Route_typed_per_filter_config_get(const envoy_config_route_v3_Route *msg, upb_strview key, struct google_protobuf_Any* *val) { return _upb_msg_map_get(msg, UPB_SIZE(48, 96), &key, 0, val, sizeof(*val)); }
+UPB_INLINE const envoy_config_route_v3_Route_TypedPerFilterConfigEntry* envoy_config_route_v3_Route_typed_per_filter_config_next(const envoy_config_route_v3_Route *msg, size_t* iter) { return (const envoy_config_route_v3_Route_TypedPerFilterConfigEntry*)_upb_msg_map_next(msg, UPB_SIZE(48, 96), iter); }
+UPB_INLINE upb_strview envoy_config_route_v3_Route_name(const envoy_config_route_v3_Route *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(4, 8), upb_strview); }
+UPB_INLINE bool envoy_config_route_v3_Route_has_tracing(const envoy_config_route_v3_Route *msg) { return _upb_hasbit(msg, 4); }
+UPB_INLINE const envoy_config_route_v3_Tracing* envoy_config_route_v3_Route_tracing(const envoy_config_route_v3_Route *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(24, 48), const envoy_config_route_v3_Tracing*); }
+UPB_INLINE bool envoy_config_route_v3_Route_has_per_request_buffer_limit_bytes(const envoy_config_route_v3_Route *msg) { return _upb_hasbit(msg, 5); }
+UPB_INLINE const struct google_protobuf_UInt32Value* envoy_config_route_v3_Route_per_request_buffer_limit_bytes(const envoy_config_route_v3_Route *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(28, 56), const struct google_protobuf_UInt32Value*); }
+UPB_INLINE bool envoy_config_route_v3_Route_has_filter_action(const envoy_config_route_v3_Route *msg) { return _upb_getoneofcase(msg, UPB_SIZE(56, 112)) == 17; }
+UPB_INLINE const envoy_config_route_v3_FilterAction* envoy_config_route_v3_Route_filter_action(const envoy_config_route_v3_Route *msg) { return UPB_READ_ONEOF(msg, const envoy_config_route_v3_FilterAction*, UPB_SIZE(52, 104), UPB_SIZE(56, 112), 17, NULL); }
 
 UPB_INLINE void envoy_config_route_v3_Route_set_match(envoy_config_route_v3_Route *msg, envoy_config_route_v3_RouteMatch* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(8, 16), envoy_config_route_v3_RouteMatch*) = value;
+  _upb_sethas(msg, 1);
+  *UPB_PTR_AT(msg, UPB_SIZE(12, 24), envoy_config_route_v3_RouteMatch*) = value;
 }
 UPB_INLINE struct envoy_config_route_v3_RouteMatch* envoy_config_route_v3_Route_mutable_match(envoy_config_route_v3_Route *msg, upb_arena *arena) {
   struct envoy_config_route_v3_RouteMatch* sub = (struct envoy_config_route_v3_RouteMatch*)envoy_config_route_v3_Route_match(msg);
@@ -566,7 +592,7 @@ UPB_INLINE struct envoy_config_route_v3_RouteMatch* envoy_config_route_v3_Route_
   return sub;
 }
 UPB_INLINE void envoy_config_route_v3_Route_set_route(envoy_config_route_v3_Route *msg, envoy_config_route_v3_RouteAction* value) {
-  UPB_WRITE_ONEOF(msg, envoy_config_route_v3_RouteAction*, UPB_SIZE(48, 96), value, UPB_SIZE(52, 104), 2);
+  UPB_WRITE_ONEOF(msg, envoy_config_route_v3_RouteAction*, UPB_SIZE(52, 104), value, UPB_SIZE(56, 112), 2);
 }
 UPB_INLINE struct envoy_config_route_v3_RouteAction* envoy_config_route_v3_Route_mutable_route(envoy_config_route_v3_Route *msg, upb_arena *arena) {
   struct envoy_config_route_v3_RouteAction* sub = (struct envoy_config_route_v3_RouteAction*)envoy_config_route_v3_Route_route(msg);
@@ -578,7 +604,7 @@ UPB_INLINE struct envoy_config_route_v3_RouteAction* envoy_config_route_v3_Route
   return sub;
 }
 UPB_INLINE void envoy_config_route_v3_Route_set_redirect(envoy_config_route_v3_Route *msg, envoy_config_route_v3_RedirectAction* value) {
-  UPB_WRITE_ONEOF(msg, envoy_config_route_v3_RedirectAction*, UPB_SIZE(48, 96), value, UPB_SIZE(52, 104), 3);
+  UPB_WRITE_ONEOF(msg, envoy_config_route_v3_RedirectAction*, UPB_SIZE(52, 104), value, UPB_SIZE(56, 112), 3);
 }
 UPB_INLINE struct envoy_config_route_v3_RedirectAction* envoy_config_route_v3_Route_mutable_redirect(envoy_config_route_v3_Route *msg, upb_arena *arena) {
   struct envoy_config_route_v3_RedirectAction* sub = (struct envoy_config_route_v3_RedirectAction*)envoy_config_route_v3_Route_redirect(msg);
@@ -590,7 +616,8 @@ UPB_INLINE struct envoy_config_route_v3_RedirectAction* envoy_config_route_v3_Ro
   return sub;
 }
 UPB_INLINE void envoy_config_route_v3_Route_set_metadata(envoy_config_route_v3_Route *msg, struct envoy_config_core_v3_Metadata* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(12, 24), struct envoy_config_core_v3_Metadata*) = value;
+  _upb_sethas(msg, 2);
+  *UPB_PTR_AT(msg, UPB_SIZE(16, 32), struct envoy_config_core_v3_Metadata*) = value;
 }
 UPB_INLINE struct envoy_config_core_v3_Metadata* envoy_config_route_v3_Route_mutable_metadata(envoy_config_route_v3_Route *msg, upb_arena *arena) {
   struct envoy_config_core_v3_Metadata* sub = (struct envoy_config_core_v3_Metadata*)envoy_config_route_v3_Route_metadata(msg);
@@ -602,7 +629,8 @@ UPB_INLINE struct envoy_config_core_v3_Metadata* envoy_config_route_v3_Route_mut
   return sub;
 }
 UPB_INLINE void envoy_config_route_v3_Route_set_decorator(envoy_config_route_v3_Route *msg, envoy_config_route_v3_Decorator* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(16, 32), envoy_config_route_v3_Decorator*) = value;
+  _upb_sethas(msg, 3);
+  *UPB_PTR_AT(msg, UPB_SIZE(20, 40), envoy_config_route_v3_Decorator*) = value;
 }
 UPB_INLINE struct envoy_config_route_v3_Decorator* envoy_config_route_v3_Route_mutable_decorator(envoy_config_route_v3_Route *msg, upb_arena *arena) {
   struct envoy_config_route_v3_Decorator* sub = (struct envoy_config_route_v3_Decorator*)envoy_config_route_v3_Route_decorator(msg);
@@ -614,7 +642,7 @@ UPB_INLINE struct envoy_config_route_v3_Decorator* envoy_config_route_v3_Route_m
   return sub;
 }
 UPB_INLINE void envoy_config_route_v3_Route_set_direct_response(envoy_config_route_v3_Route *msg, envoy_config_route_v3_DirectResponseAction* value) {
-  UPB_WRITE_ONEOF(msg, envoy_config_route_v3_DirectResponseAction*, UPB_SIZE(48, 96), value, UPB_SIZE(52, 104), 7);
+  UPB_WRITE_ONEOF(msg, envoy_config_route_v3_DirectResponseAction*, UPB_SIZE(52, 104), value, UPB_SIZE(56, 112), 7);
 }
 UPB_INLINE struct envoy_config_route_v3_DirectResponseAction* envoy_config_route_v3_Route_mutable_direct_response(envoy_config_route_v3_Route *msg, upb_arena *arena) {
   struct envoy_config_route_v3_DirectResponseAction* sub = (struct envoy_config_route_v3_DirectResponseAction*)envoy_config_route_v3_Route_direct_response(msg);
@@ -626,60 +654,61 @@ UPB_INLINE struct envoy_config_route_v3_DirectResponseAction* envoy_config_route
   return sub;
 }
 UPB_INLINE struct envoy_config_core_v3_HeaderValueOption** envoy_config_route_v3_Route_mutable_request_headers_to_add(envoy_config_route_v3_Route *msg, size_t *len) {
-  return (struct envoy_config_core_v3_HeaderValueOption**)_upb_array_mutable_accessor(msg, UPB_SIZE(28, 56), len);
+  return (struct envoy_config_core_v3_HeaderValueOption**)_upb_array_mutable_accessor(msg, UPB_SIZE(32, 64), len);
 }
 UPB_INLINE struct envoy_config_core_v3_HeaderValueOption** envoy_config_route_v3_Route_resize_request_headers_to_add(envoy_config_route_v3_Route *msg, size_t len, upb_arena *arena) {
-  return (struct envoy_config_core_v3_HeaderValueOption**)_upb_array_resize_accessor(msg, UPB_SIZE(28, 56), len, UPB_TYPE_MESSAGE, arena);
+  return (struct envoy_config_core_v3_HeaderValueOption**)_upb_array_resize_accessor2(msg, UPB_SIZE(32, 64), len, UPB_SIZE(2, 3), arena);
 }
 UPB_INLINE struct envoy_config_core_v3_HeaderValueOption* envoy_config_route_v3_Route_add_request_headers_to_add(envoy_config_route_v3_Route *msg, upb_arena *arena) {
   struct envoy_config_core_v3_HeaderValueOption* sub = (struct envoy_config_core_v3_HeaderValueOption*)_upb_msg_new(&envoy_config_core_v3_HeaderValueOption_msginit, arena);
-  bool ok = _upb_array_append_accessor(
-      msg, UPB_SIZE(28, 56), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena);
+  bool ok = _upb_array_append_accessor2(
+      msg, UPB_SIZE(32, 64), UPB_SIZE(2, 3), &sub, arena);
   if (!ok) return NULL;
   return sub;
 }
 UPB_INLINE struct envoy_config_core_v3_HeaderValueOption** envoy_config_route_v3_Route_mutable_response_headers_to_add(envoy_config_route_v3_Route *msg, size_t *len) {
-  return (struct envoy_config_core_v3_HeaderValueOption**)_upb_array_mutable_accessor(msg, UPB_SIZE(32, 64), len);
+  return (struct envoy_config_core_v3_HeaderValueOption**)_upb_array_mutable_accessor(msg, UPB_SIZE(36, 72), len);
 }
 UPB_INLINE struct envoy_config_core_v3_HeaderValueOption** envoy_config_route_v3_Route_resize_response_headers_to_add(envoy_config_route_v3_Route *msg, size_t len, upb_arena *arena) {
-  return (struct envoy_config_core_v3_HeaderValueOption**)_upb_array_resize_accessor(msg, UPB_SIZE(32, 64), len, UPB_TYPE_MESSAGE, arena);
+  return (struct envoy_config_core_v3_HeaderValueOption**)_upb_array_resize_accessor2(msg, UPB_SIZE(36, 72), len, UPB_SIZE(2, 3), arena);
 }
 UPB_INLINE struct envoy_config_core_v3_HeaderValueOption* envoy_config_route_v3_Route_add_response_headers_to_add(envoy_config_route_v3_Route *msg, upb_arena *arena) {
   struct envoy_config_core_v3_HeaderValueOption* sub = (struct envoy_config_core_v3_HeaderValueOption*)_upb_msg_new(&envoy_config_core_v3_HeaderValueOption_msginit, arena);
-  bool ok = _upb_array_append_accessor(
-      msg, UPB_SIZE(32, 64), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena);
+  bool ok = _upb_array_append_accessor2(
+      msg, UPB_SIZE(36, 72), UPB_SIZE(2, 3), &sub, arena);
   if (!ok) return NULL;
   return sub;
 }
 UPB_INLINE upb_strview* envoy_config_route_v3_Route_mutable_response_headers_to_remove(envoy_config_route_v3_Route *msg, size_t *len) {
-  return (upb_strview*)_upb_array_mutable_accessor(msg, UPB_SIZE(36, 72), len);
+  return (upb_strview*)_upb_array_mutable_accessor(msg, UPB_SIZE(40, 80), len);
 }
 UPB_INLINE upb_strview* envoy_config_route_v3_Route_resize_response_headers_to_remove(envoy_config_route_v3_Route *msg, size_t len, upb_arena *arena) {
-  return (upb_strview*)_upb_array_resize_accessor(msg, UPB_SIZE(36, 72), len, UPB_TYPE_STRING, arena);
+  return (upb_strview*)_upb_array_resize_accessor2(msg, UPB_SIZE(40, 80), len, UPB_SIZE(3, 4), arena);
 }
 UPB_INLINE bool envoy_config_route_v3_Route_add_response_headers_to_remove(envoy_config_route_v3_Route *msg, upb_strview val, upb_arena *arena) {
-  return _upb_array_append_accessor(msg, UPB_SIZE(36, 72), UPB_SIZE(8, 16), UPB_TYPE_STRING, &val,
+  return _upb_array_append_accessor2(msg, UPB_SIZE(40, 80), UPB_SIZE(3, 4), &val,
       arena);
 }
 UPB_INLINE upb_strview* envoy_config_route_v3_Route_mutable_request_headers_to_remove(envoy_config_route_v3_Route *msg, size_t *len) {
-  return (upb_strview*)_upb_array_mutable_accessor(msg, UPB_SIZE(40, 80), len);
+  return (upb_strview*)_upb_array_mutable_accessor(msg, UPB_SIZE(44, 88), len);
 }
 UPB_INLINE upb_strview* envoy_config_route_v3_Route_resize_request_headers_to_remove(envoy_config_route_v3_Route *msg, size_t len, upb_arena *arena) {
-  return (upb_strview*)_upb_array_resize_accessor(msg, UPB_SIZE(40, 80), len, UPB_TYPE_STRING, arena);
+  return (upb_strview*)_upb_array_resize_accessor2(msg, UPB_SIZE(44, 88), len, UPB_SIZE(3, 4), arena);
 }
 UPB_INLINE bool envoy_config_route_v3_Route_add_request_headers_to_remove(envoy_config_route_v3_Route *msg, upb_strview val, upb_arena *arena) {
-  return _upb_array_append_accessor(msg, UPB_SIZE(40, 80), UPB_SIZE(8, 16), UPB_TYPE_STRING, &val,
+  return _upb_array_append_accessor2(msg, UPB_SIZE(44, 88), UPB_SIZE(3, 4), &val,
       arena);
 }
-UPB_INLINE void envoy_config_route_v3_Route_typed_per_filter_config_clear(envoy_config_route_v3_Route *msg) { _upb_msg_map_clear(msg, UPB_SIZE(44, 88)); }
-UPB_INLINE bool envoy_config_route_v3_Route_typed_per_filter_config_set(envoy_config_route_v3_Route *msg, upb_strview key, struct google_protobuf_Any* val, upb_arena *a) { return _upb_msg_map_set(msg, UPB_SIZE(44, 88), &key, 0, &val, sizeof(val), a); }
-UPB_INLINE bool envoy_config_route_v3_Route_typed_per_filter_config_delete(envoy_config_route_v3_Route *msg, upb_strview key) { return _upb_msg_map_delete(msg, UPB_SIZE(44, 88), &key, 0); }
-UPB_INLINE envoy_config_route_v3_Route_TypedPerFilterConfigEntry* envoy_config_route_v3_Route_typed_per_filter_config_nextmutable(envoy_config_route_v3_Route *msg, size_t* iter) { return (envoy_config_route_v3_Route_TypedPerFilterConfigEntry*)_upb_msg_map_next(msg, UPB_SIZE(44, 88), iter); }
+UPB_INLINE void envoy_config_route_v3_Route_typed_per_filter_config_clear(envoy_config_route_v3_Route *msg) { _upb_msg_map_clear(msg, UPB_SIZE(48, 96)); }
+UPB_INLINE bool envoy_config_route_v3_Route_typed_per_filter_config_set(envoy_config_route_v3_Route *msg, upb_strview key, struct google_protobuf_Any* val, upb_arena *a) { return _upb_msg_map_set(msg, UPB_SIZE(48, 96), &key, 0, &val, sizeof(val), a); }
+UPB_INLINE bool envoy_config_route_v3_Route_typed_per_filter_config_delete(envoy_config_route_v3_Route *msg, upb_strview key) { return _upb_msg_map_delete(msg, UPB_SIZE(48, 96), &key, 0); }
+UPB_INLINE envoy_config_route_v3_Route_TypedPerFilterConfigEntry* envoy_config_route_v3_Route_typed_per_filter_config_nextmutable(envoy_config_route_v3_Route *msg, size_t* iter) { return (envoy_config_route_v3_Route_TypedPerFilterConfigEntry*)_upb_msg_map_next(msg, UPB_SIZE(48, 96), iter); }
 UPB_INLINE void envoy_config_route_v3_Route_set_name(envoy_config_route_v3_Route *msg, upb_strview value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(0, 0), upb_strview) = value;
+  *UPB_PTR_AT(msg, UPB_SIZE(4, 8), upb_strview) = value;
 }
 UPB_INLINE void envoy_config_route_v3_Route_set_tracing(envoy_config_route_v3_Route *msg, envoy_config_route_v3_Tracing* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(20, 40), envoy_config_route_v3_Tracing*) = value;
+  _upb_sethas(msg, 4);
+  *UPB_PTR_AT(msg, UPB_SIZE(24, 48), envoy_config_route_v3_Tracing*) = value;
 }
 UPB_INLINE struct envoy_config_route_v3_Tracing* envoy_config_route_v3_Route_mutable_tracing(envoy_config_route_v3_Route *msg, upb_arena *arena) {
   struct envoy_config_route_v3_Tracing* sub = (struct envoy_config_route_v3_Tracing*)envoy_config_route_v3_Route_tracing(msg);
@@ -691,7 +720,8 @@ UPB_INLINE struct envoy_config_route_v3_Tracing* envoy_config_route_v3_Route_mut
   return sub;
 }
 UPB_INLINE void envoy_config_route_v3_Route_set_per_request_buffer_limit_bytes(envoy_config_route_v3_Route *msg, struct google_protobuf_UInt32Value* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(24, 48), struct google_protobuf_UInt32Value*) = value;
+  _upb_sethas(msg, 5);
+  *UPB_PTR_AT(msg, UPB_SIZE(28, 56), struct google_protobuf_UInt32Value*) = value;
 }
 UPB_INLINE struct google_protobuf_UInt32Value* envoy_config_route_v3_Route_mutable_per_request_buffer_limit_bytes(envoy_config_route_v3_Route *msg, upb_arena *arena) {
   struct google_protobuf_UInt32Value* sub = (struct google_protobuf_UInt32Value*)envoy_config_route_v3_Route_per_request_buffer_limit_bytes(msg);
@@ -703,7 +733,7 @@ UPB_INLINE struct google_protobuf_UInt32Value* envoy_config_route_v3_Route_mutab
   return sub;
 }
 UPB_INLINE void envoy_config_route_v3_Route_set_filter_action(envoy_config_route_v3_Route *msg, envoy_config_route_v3_FilterAction* value) {
-  UPB_WRITE_ONEOF(msg, envoy_config_route_v3_FilterAction*, UPB_SIZE(48, 96), value, UPB_SIZE(52, 104), 17);
+  UPB_WRITE_ONEOF(msg, envoy_config_route_v3_FilterAction*, UPB_SIZE(52, 104), value, UPB_SIZE(56, 112), 17);
 }
 UPB_INLINE struct envoy_config_route_v3_FilterAction* envoy_config_route_v3_Route_mutable_filter_action(envoy_config_route_v3_Route *msg, upb_arena *arena) {
   struct envoy_config_route_v3_FilterAction* sub = (struct envoy_config_route_v3_FilterAction*)envoy_config_route_v3_Route_filter_action(msg);
@@ -743,34 +773,41 @@ UPB_INLINE envoy_config_route_v3_WeightedCluster *envoy_config_route_v3_Weighted
   envoy_config_route_v3_WeightedCluster *ret = envoy_config_route_v3_WeightedCluster_new(arena);
   return (ret && upb_decode(buf, size, ret, &envoy_config_route_v3_WeightedCluster_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE envoy_config_route_v3_WeightedCluster *envoy_config_route_v3_WeightedCluster_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  envoy_config_route_v3_WeightedCluster *ret = envoy_config_route_v3_WeightedCluster_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &envoy_config_route_v3_WeightedCluster_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *envoy_config_route_v3_WeightedCluster_serialize(const envoy_config_route_v3_WeightedCluster *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &envoy_config_route_v3_WeightedCluster_msginit, arena, len);
 }
 
-UPB_INLINE bool envoy_config_route_v3_WeightedCluster_has_clusters(const envoy_config_route_v3_WeightedCluster *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(12, 24)); }
-UPB_INLINE const envoy_config_route_v3_WeightedCluster_ClusterWeight* const* envoy_config_route_v3_WeightedCluster_clusters(const envoy_config_route_v3_WeightedCluster *msg, size_t *len) { return (const envoy_config_route_v3_WeightedCluster_ClusterWeight* const*)_upb_array_accessor(msg, UPB_SIZE(12, 24), len); }
-UPB_INLINE upb_strview envoy_config_route_v3_WeightedCluster_runtime_key_prefix(const envoy_config_route_v3_WeightedCluster *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(0, 0), upb_strview); }
-UPB_INLINE bool envoy_config_route_v3_WeightedCluster_has_total_weight(const envoy_config_route_v3_WeightedCluster *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(8, 16)); }
-UPB_INLINE const struct google_protobuf_UInt32Value* envoy_config_route_v3_WeightedCluster_total_weight(const envoy_config_route_v3_WeightedCluster *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(8, 16), const struct google_protobuf_UInt32Value*); }
+UPB_INLINE bool envoy_config_route_v3_WeightedCluster_has_clusters(const envoy_config_route_v3_WeightedCluster *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(16, 32)); }
+UPB_INLINE const envoy_config_route_v3_WeightedCluster_ClusterWeight* const* envoy_config_route_v3_WeightedCluster_clusters(const envoy_config_route_v3_WeightedCluster *msg, size_t *len) { return (const envoy_config_route_v3_WeightedCluster_ClusterWeight* const*)_upb_array_accessor(msg, UPB_SIZE(16, 32), len); }
+UPB_INLINE upb_strview envoy_config_route_v3_WeightedCluster_runtime_key_prefix(const envoy_config_route_v3_WeightedCluster *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(4, 8), upb_strview); }
+UPB_INLINE bool envoy_config_route_v3_WeightedCluster_has_total_weight(const envoy_config_route_v3_WeightedCluster *msg) { return _upb_hasbit(msg, 1); }
+UPB_INLINE const struct google_protobuf_UInt32Value* envoy_config_route_v3_WeightedCluster_total_weight(const envoy_config_route_v3_WeightedCluster *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(12, 24), const struct google_protobuf_UInt32Value*); }
 
 UPB_INLINE envoy_config_route_v3_WeightedCluster_ClusterWeight** envoy_config_route_v3_WeightedCluster_mutable_clusters(envoy_config_route_v3_WeightedCluster *msg, size_t *len) {
-  return (envoy_config_route_v3_WeightedCluster_ClusterWeight**)_upb_array_mutable_accessor(msg, UPB_SIZE(12, 24), len);
+  return (envoy_config_route_v3_WeightedCluster_ClusterWeight**)_upb_array_mutable_accessor(msg, UPB_SIZE(16, 32), len);
 }
 UPB_INLINE envoy_config_route_v3_WeightedCluster_ClusterWeight** envoy_config_route_v3_WeightedCluster_resize_clusters(envoy_config_route_v3_WeightedCluster *msg, size_t len, upb_arena *arena) {
-  return (envoy_config_route_v3_WeightedCluster_ClusterWeight**)_upb_array_resize_accessor(msg, UPB_SIZE(12, 24), len, UPB_TYPE_MESSAGE, arena);
+  return (envoy_config_route_v3_WeightedCluster_ClusterWeight**)_upb_array_resize_accessor2(msg, UPB_SIZE(16, 32), len, UPB_SIZE(2, 3), arena);
 }
 UPB_INLINE struct envoy_config_route_v3_WeightedCluster_ClusterWeight* envoy_config_route_v3_WeightedCluster_add_clusters(envoy_config_route_v3_WeightedCluster *msg, upb_arena *arena) {
   struct envoy_config_route_v3_WeightedCluster_ClusterWeight* sub = (struct envoy_config_route_v3_WeightedCluster_ClusterWeight*)_upb_msg_new(&envoy_config_route_v3_WeightedCluster_ClusterWeight_msginit, arena);
-  bool ok = _upb_array_append_accessor(
-      msg, UPB_SIZE(12, 24), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena);
+  bool ok = _upb_array_append_accessor2(
+      msg, UPB_SIZE(16, 32), UPB_SIZE(2, 3), &sub, arena);
   if (!ok) return NULL;
   return sub;
 }
 UPB_INLINE void envoy_config_route_v3_WeightedCluster_set_runtime_key_prefix(envoy_config_route_v3_WeightedCluster *msg, upb_strview value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(0, 0), upb_strview) = value;
+  *UPB_PTR_AT(msg, UPB_SIZE(4, 8), upb_strview) = value;
 }
 UPB_INLINE void envoy_config_route_v3_WeightedCluster_set_total_weight(envoy_config_route_v3_WeightedCluster *msg, struct google_protobuf_UInt32Value* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(8, 16), struct google_protobuf_UInt32Value*) = value;
+  _upb_sethas(msg, 1);
+  *UPB_PTR_AT(msg, UPB_SIZE(12, 24), struct google_protobuf_UInt32Value*) = value;
 }
 UPB_INLINE struct google_protobuf_UInt32Value* envoy_config_route_v3_WeightedCluster_mutable_total_weight(envoy_config_route_v3_WeightedCluster *msg, upb_arena *arena) {
   struct google_protobuf_UInt32Value* sub = (struct google_protobuf_UInt32Value*)envoy_config_route_v3_WeightedCluster_total_weight(msg);
@@ -792,31 +829,38 @@ UPB_INLINE envoy_config_route_v3_WeightedCluster_ClusterWeight *envoy_config_rou
   envoy_config_route_v3_WeightedCluster_ClusterWeight *ret = envoy_config_route_v3_WeightedCluster_ClusterWeight_new(arena);
   return (ret && upb_decode(buf, size, ret, &envoy_config_route_v3_WeightedCluster_ClusterWeight_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE envoy_config_route_v3_WeightedCluster_ClusterWeight *envoy_config_route_v3_WeightedCluster_ClusterWeight_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  envoy_config_route_v3_WeightedCluster_ClusterWeight *ret = envoy_config_route_v3_WeightedCluster_ClusterWeight_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &envoy_config_route_v3_WeightedCluster_ClusterWeight_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *envoy_config_route_v3_WeightedCluster_ClusterWeight_serialize(const envoy_config_route_v3_WeightedCluster_ClusterWeight *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &envoy_config_route_v3_WeightedCluster_ClusterWeight_msginit, arena, len);
 }
 
-UPB_INLINE upb_strview envoy_config_route_v3_WeightedCluster_ClusterWeight_name(const envoy_config_route_v3_WeightedCluster_ClusterWeight *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(0, 0), upb_strview); }
-UPB_INLINE bool envoy_config_route_v3_WeightedCluster_ClusterWeight_has_weight(const envoy_config_route_v3_WeightedCluster_ClusterWeight *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(8, 16)); }
-UPB_INLINE const struct google_protobuf_UInt32Value* envoy_config_route_v3_WeightedCluster_ClusterWeight_weight(const envoy_config_route_v3_WeightedCluster_ClusterWeight *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(8, 16), const struct google_protobuf_UInt32Value*); }
-UPB_INLINE bool envoy_config_route_v3_WeightedCluster_ClusterWeight_has_metadata_match(const envoy_config_route_v3_WeightedCluster_ClusterWeight *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(12, 24)); }
-UPB_INLINE const struct envoy_config_core_v3_Metadata* envoy_config_route_v3_WeightedCluster_ClusterWeight_metadata_match(const envoy_config_route_v3_WeightedCluster_ClusterWeight *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(12, 24), const struct envoy_config_core_v3_Metadata*); }
-UPB_INLINE bool envoy_config_route_v3_WeightedCluster_ClusterWeight_has_request_headers_to_add(const envoy_config_route_v3_WeightedCluster_ClusterWeight *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(16, 32)); }
-UPB_INLINE const struct envoy_config_core_v3_HeaderValueOption* const* envoy_config_route_v3_WeightedCluster_ClusterWeight_request_headers_to_add(const envoy_config_route_v3_WeightedCluster_ClusterWeight *msg, size_t *len) { return (const struct envoy_config_core_v3_HeaderValueOption* const*)_upb_array_accessor(msg, UPB_SIZE(16, 32), len); }
-UPB_INLINE bool envoy_config_route_v3_WeightedCluster_ClusterWeight_has_response_headers_to_add(const envoy_config_route_v3_WeightedCluster_ClusterWeight *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(20, 40)); }
-UPB_INLINE const struct envoy_config_core_v3_HeaderValueOption* const* envoy_config_route_v3_WeightedCluster_ClusterWeight_response_headers_to_add(const envoy_config_route_v3_WeightedCluster_ClusterWeight *msg, size_t *len) { return (const struct envoy_config_core_v3_HeaderValueOption* const*)_upb_array_accessor(msg, UPB_SIZE(20, 40), len); }
-UPB_INLINE upb_strview const* envoy_config_route_v3_WeightedCluster_ClusterWeight_response_headers_to_remove(const envoy_config_route_v3_WeightedCluster_ClusterWeight *msg, size_t *len) { return (upb_strview const*)_upb_array_accessor(msg, UPB_SIZE(24, 48), len); }
-UPB_INLINE upb_strview const* envoy_config_route_v3_WeightedCluster_ClusterWeight_request_headers_to_remove(const envoy_config_route_v3_WeightedCluster_ClusterWeight *msg, size_t *len) { return (upb_strview const*)_upb_array_accessor(msg, UPB_SIZE(28, 56), len); }
-UPB_INLINE bool envoy_config_route_v3_WeightedCluster_ClusterWeight_has_typed_per_filter_config(const envoy_config_route_v3_WeightedCluster_ClusterWeight *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(32, 64)); }
-UPB_INLINE size_t envoy_config_route_v3_WeightedCluster_ClusterWeight_typed_per_filter_config_size(const envoy_config_route_v3_WeightedCluster_ClusterWeight *msg) {return _upb_msg_map_size(msg, UPB_SIZE(32, 64)); }
-UPB_INLINE bool envoy_config_route_v3_WeightedCluster_ClusterWeight_typed_per_filter_config_get(const envoy_config_route_v3_WeightedCluster_ClusterWeight *msg, upb_strview key, struct google_protobuf_Any* *val) { return _upb_msg_map_get(msg, UPB_SIZE(32, 64), &key, 0, val, sizeof(*val)); }
-UPB_INLINE const envoy_config_route_v3_WeightedCluster_ClusterWeight_TypedPerFilterConfigEntry* envoy_config_route_v3_WeightedCluster_ClusterWeight_typed_per_filter_config_next(const envoy_config_route_v3_WeightedCluster_ClusterWeight *msg, size_t* iter) { return (const envoy_config_route_v3_WeightedCluster_ClusterWeight_TypedPerFilterConfigEntry*)_upb_msg_map_next(msg, UPB_SIZE(32, 64), iter); }
+UPB_INLINE upb_strview envoy_config_route_v3_WeightedCluster_ClusterWeight_name(const envoy_config_route_v3_WeightedCluster_ClusterWeight *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(4, 8), upb_strview); }
+UPB_INLINE bool envoy_config_route_v3_WeightedCluster_ClusterWeight_has_weight(const envoy_config_route_v3_WeightedCluster_ClusterWeight *msg) { return _upb_hasbit(msg, 1); }
+UPB_INLINE const struct google_protobuf_UInt32Value* envoy_config_route_v3_WeightedCluster_ClusterWeight_weight(const envoy_config_route_v3_WeightedCluster_ClusterWeight *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(12, 24), const struct google_protobuf_UInt32Value*); }
+UPB_INLINE bool envoy_config_route_v3_WeightedCluster_ClusterWeight_has_metadata_match(const envoy_config_route_v3_WeightedCluster_ClusterWeight *msg) { return _upb_hasbit(msg, 2); }
+UPB_INLINE const struct envoy_config_core_v3_Metadata* envoy_config_route_v3_WeightedCluster_ClusterWeight_metadata_match(const envoy_config_route_v3_WeightedCluster_ClusterWeight *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(16, 32), const struct envoy_config_core_v3_Metadata*); }
+UPB_INLINE bool envoy_config_route_v3_WeightedCluster_ClusterWeight_has_request_headers_to_add(const envoy_config_route_v3_WeightedCluster_ClusterWeight *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(20, 40)); }
+UPB_INLINE const struct envoy_config_core_v3_HeaderValueOption* const* envoy_config_route_v3_WeightedCluster_ClusterWeight_request_headers_to_add(const envoy_config_route_v3_WeightedCluster_ClusterWeight *msg, size_t *len) { return (const struct envoy_config_core_v3_HeaderValueOption* const*)_upb_array_accessor(msg, UPB_SIZE(20, 40), len); }
+UPB_INLINE bool envoy_config_route_v3_WeightedCluster_ClusterWeight_has_response_headers_to_add(const envoy_config_route_v3_WeightedCluster_ClusterWeight *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(24, 48)); }
+UPB_INLINE const struct envoy_config_core_v3_HeaderValueOption* const* envoy_config_route_v3_WeightedCluster_ClusterWeight_response_headers_to_add(const envoy_config_route_v3_WeightedCluster_ClusterWeight *msg, size_t *len) { return (const struct envoy_config_core_v3_HeaderValueOption* const*)_upb_array_accessor(msg, UPB_SIZE(24, 48), len); }
+UPB_INLINE upb_strview const* envoy_config_route_v3_WeightedCluster_ClusterWeight_response_headers_to_remove(const envoy_config_route_v3_WeightedCluster_ClusterWeight *msg, size_t *len) { return (upb_strview const*)_upb_array_accessor(msg, UPB_SIZE(28, 56), len); }
+UPB_INLINE upb_strview const* envoy_config_route_v3_WeightedCluster_ClusterWeight_request_headers_to_remove(const envoy_config_route_v3_WeightedCluster_ClusterWeight *msg, size_t *len) { return (upb_strview const*)_upb_array_accessor(msg, UPB_SIZE(32, 64), len); }
+UPB_INLINE bool envoy_config_route_v3_WeightedCluster_ClusterWeight_has_typed_per_filter_config(const envoy_config_route_v3_WeightedCluster_ClusterWeight *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(36, 72)); }
+UPB_INLINE size_t envoy_config_route_v3_WeightedCluster_ClusterWeight_typed_per_filter_config_size(const envoy_config_route_v3_WeightedCluster_ClusterWeight *msg) {return _upb_msg_map_size(msg, UPB_SIZE(36, 72)); }
+UPB_INLINE bool envoy_config_route_v3_WeightedCluster_ClusterWeight_typed_per_filter_config_get(const envoy_config_route_v3_WeightedCluster_ClusterWeight *msg, upb_strview key, struct google_protobuf_Any* *val) { return _upb_msg_map_get(msg, UPB_SIZE(36, 72), &key, 0, val, sizeof(*val)); }
+UPB_INLINE const envoy_config_route_v3_WeightedCluster_ClusterWeight_TypedPerFilterConfigEntry* envoy_config_route_v3_WeightedCluster_ClusterWeight_typed_per_filter_config_next(const envoy_config_route_v3_WeightedCluster_ClusterWeight *msg, size_t* iter) { return (const envoy_config_route_v3_WeightedCluster_ClusterWeight_TypedPerFilterConfigEntry*)_upb_msg_map_next(msg, UPB_SIZE(36, 72), iter); }
 
 UPB_INLINE void envoy_config_route_v3_WeightedCluster_ClusterWeight_set_name(envoy_config_route_v3_WeightedCluster_ClusterWeight *msg, upb_strview value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(0, 0), upb_strview) = value;
+  *UPB_PTR_AT(msg, UPB_SIZE(4, 8), upb_strview) = value;
 }
 UPB_INLINE void envoy_config_route_v3_WeightedCluster_ClusterWeight_set_weight(envoy_config_route_v3_WeightedCluster_ClusterWeight *msg, struct google_protobuf_UInt32Value* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(8, 16), struct google_protobuf_UInt32Value*) = value;
+  _upb_sethas(msg, 1);
+  *UPB_PTR_AT(msg, UPB_SIZE(12, 24), struct google_protobuf_UInt32Value*) = value;
 }
 UPB_INLINE struct google_protobuf_UInt32Value* envoy_config_route_v3_WeightedCluster_ClusterWeight_mutable_weight(envoy_config_route_v3_WeightedCluster_ClusterWeight *msg, upb_arena *arena) {
   struct google_protobuf_UInt32Value* sub = (struct google_protobuf_UInt32Value*)envoy_config_route_v3_WeightedCluster_ClusterWeight_weight(msg);
@@ -828,7 +872,8 @@ UPB_INLINE struct google_protobuf_UInt32Value* envoy_config_route_v3_WeightedClu
   return sub;
 }
 UPB_INLINE void envoy_config_route_v3_WeightedCluster_ClusterWeight_set_metadata_match(envoy_config_route_v3_WeightedCluster_ClusterWeight *msg, struct envoy_config_core_v3_Metadata* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(12, 24), struct envoy_config_core_v3_Metadata*) = value;
+  _upb_sethas(msg, 2);
+  *UPB_PTR_AT(msg, UPB_SIZE(16, 32), struct envoy_config_core_v3_Metadata*) = value;
 }
 UPB_INLINE struct envoy_config_core_v3_Metadata* envoy_config_route_v3_WeightedCluster_ClusterWeight_mutable_metadata_match(envoy_config_route_v3_WeightedCluster_ClusterWeight *msg, upb_arena *arena) {
   struct envoy_config_core_v3_Metadata* sub = (struct envoy_config_core_v3_Metadata*)envoy_config_route_v3_WeightedCluster_ClusterWeight_metadata_match(msg);
@@ -840,55 +885,55 @@ UPB_INLINE struct envoy_config_core_v3_Metadata* envoy_config_route_v3_WeightedC
   return sub;
 }
 UPB_INLINE struct envoy_config_core_v3_HeaderValueOption** envoy_config_route_v3_WeightedCluster_ClusterWeight_mutable_request_headers_to_add(envoy_config_route_v3_WeightedCluster_ClusterWeight *msg, size_t *len) {
-  return (struct envoy_config_core_v3_HeaderValueOption**)_upb_array_mutable_accessor(msg, UPB_SIZE(16, 32), len);
+  return (struct envoy_config_core_v3_HeaderValueOption**)_upb_array_mutable_accessor(msg, UPB_SIZE(20, 40), len);
 }
 UPB_INLINE struct envoy_config_core_v3_HeaderValueOption** envoy_config_route_v3_WeightedCluster_ClusterWeight_resize_request_headers_to_add(envoy_config_route_v3_WeightedCluster_ClusterWeight *msg, size_t len, upb_arena *arena) {
-  return (struct envoy_config_core_v3_HeaderValueOption**)_upb_array_resize_accessor(msg, UPB_SIZE(16, 32), len, UPB_TYPE_MESSAGE, arena);
+  return (struct envoy_config_core_v3_HeaderValueOption**)_upb_array_resize_accessor2(msg, UPB_SIZE(20, 40), len, UPB_SIZE(2, 3), arena);
 }
 UPB_INLINE struct envoy_config_core_v3_HeaderValueOption* envoy_config_route_v3_WeightedCluster_ClusterWeight_add_request_headers_to_add(envoy_config_route_v3_WeightedCluster_ClusterWeight *msg, upb_arena *arena) {
   struct envoy_config_core_v3_HeaderValueOption* sub = (struct envoy_config_core_v3_HeaderValueOption*)_upb_msg_new(&envoy_config_core_v3_HeaderValueOption_msginit, arena);
-  bool ok = _upb_array_append_accessor(
-      msg, UPB_SIZE(16, 32), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena);
+  bool ok = _upb_array_append_accessor2(
+      msg, UPB_SIZE(20, 40), UPB_SIZE(2, 3), &sub, arena);
   if (!ok) return NULL;
   return sub;
 }
 UPB_INLINE struct envoy_config_core_v3_HeaderValueOption** envoy_config_route_v3_WeightedCluster_ClusterWeight_mutable_response_headers_to_add(envoy_config_route_v3_WeightedCluster_ClusterWeight *msg, size_t *len) {
-  return (struct envoy_config_core_v3_HeaderValueOption**)_upb_array_mutable_accessor(msg, UPB_SIZE(20, 40), len);
+  return (struct envoy_config_core_v3_HeaderValueOption**)_upb_array_mutable_accessor(msg, UPB_SIZE(24, 48), len);
 }
 UPB_INLINE struct envoy_config_core_v3_HeaderValueOption** envoy_config_route_v3_WeightedCluster_ClusterWeight_resize_response_headers_to_add(envoy_config_route_v3_WeightedCluster_ClusterWeight *msg, size_t len, upb_arena *arena) {
-  return (struct envoy_config_core_v3_HeaderValueOption**)_upb_array_resize_accessor(msg, UPB_SIZE(20, 40), len, UPB_TYPE_MESSAGE, arena);
+  return (struct envoy_config_core_v3_HeaderValueOption**)_upb_array_resize_accessor2(msg, UPB_SIZE(24, 48), len, UPB_SIZE(2, 3), arena);
 }
 UPB_INLINE struct envoy_config_core_v3_HeaderValueOption* envoy_config_route_v3_WeightedCluster_ClusterWeight_add_response_headers_to_add(envoy_config_route_v3_WeightedCluster_ClusterWeight *msg, upb_arena *arena) {
   struct envoy_config_core_v3_HeaderValueOption* sub = (struct envoy_config_core_v3_HeaderValueOption*)_upb_msg_new(&envoy_config_core_v3_HeaderValueOption_msginit, arena);
-  bool ok = _upb_array_append_accessor(
-      msg, UPB_SIZE(20, 40), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena);
+  bool ok = _upb_array_append_accessor2(
+      msg, UPB_SIZE(24, 48), UPB_SIZE(2, 3), &sub, arena);
   if (!ok) return NULL;
   return sub;
 }
 UPB_INLINE upb_strview* envoy_config_route_v3_WeightedCluster_ClusterWeight_mutable_response_headers_to_remove(envoy_config_route_v3_WeightedCluster_ClusterWeight *msg, size_t *len) {
-  return (upb_strview*)_upb_array_mutable_accessor(msg, UPB_SIZE(24, 48), len);
+  return (upb_strview*)_upb_array_mutable_accessor(msg, UPB_SIZE(28, 56), len);
 }
 UPB_INLINE upb_strview* envoy_config_route_v3_WeightedCluster_ClusterWeight_resize_response_headers_to_remove(envoy_config_route_v3_WeightedCluster_ClusterWeight *msg, size_t len, upb_arena *arena) {
-  return (upb_strview*)_upb_array_resize_accessor(msg, UPB_SIZE(24, 48), len, UPB_TYPE_STRING, arena);
+  return (upb_strview*)_upb_array_resize_accessor2(msg, UPB_SIZE(28, 56), len, UPB_SIZE(3, 4), arena);
 }
 UPB_INLINE bool envoy_config_route_v3_WeightedCluster_ClusterWeight_add_response_headers_to_remove(envoy_config_route_v3_WeightedCluster_ClusterWeight *msg, upb_strview val, upb_arena *arena) {
-  return _upb_array_append_accessor(msg, UPB_SIZE(24, 48), UPB_SIZE(8, 16), UPB_TYPE_STRING, &val,
+  return _upb_array_append_accessor2(msg, UPB_SIZE(28, 56), UPB_SIZE(3, 4), &val,
       arena);
 }
 UPB_INLINE upb_strview* envoy_config_route_v3_WeightedCluster_ClusterWeight_mutable_request_headers_to_remove(envoy_config_route_v3_WeightedCluster_ClusterWeight *msg, size_t *len) {
-  return (upb_strview*)_upb_array_mutable_accessor(msg, UPB_SIZE(28, 56), len);
+  return (upb_strview*)_upb_array_mutable_accessor(msg, UPB_SIZE(32, 64), len);
 }
 UPB_INLINE upb_strview* envoy_config_route_v3_WeightedCluster_ClusterWeight_resize_request_headers_to_remove(envoy_config_route_v3_WeightedCluster_ClusterWeight *msg, size_t len, upb_arena *arena) {
-  return (upb_strview*)_upb_array_resize_accessor(msg, UPB_SIZE(28, 56), len, UPB_TYPE_STRING, arena);
+  return (upb_strview*)_upb_array_resize_accessor2(msg, UPB_SIZE(32, 64), len, UPB_SIZE(3, 4), arena);
 }
 UPB_INLINE bool envoy_config_route_v3_WeightedCluster_ClusterWeight_add_request_headers_to_remove(envoy_config_route_v3_WeightedCluster_ClusterWeight *msg, upb_strview val, upb_arena *arena) {
-  return _upb_array_append_accessor(msg, UPB_SIZE(28, 56), UPB_SIZE(8, 16), UPB_TYPE_STRING, &val,
+  return _upb_array_append_accessor2(msg, UPB_SIZE(32, 64), UPB_SIZE(3, 4), &val,
       arena);
 }
-UPB_INLINE void envoy_config_route_v3_WeightedCluster_ClusterWeight_typed_per_filter_config_clear(envoy_config_route_v3_WeightedCluster_ClusterWeight *msg) { _upb_msg_map_clear(msg, UPB_SIZE(32, 64)); }
-UPB_INLINE bool envoy_config_route_v3_WeightedCluster_ClusterWeight_typed_per_filter_config_set(envoy_config_route_v3_WeightedCluster_ClusterWeight *msg, upb_strview key, struct google_protobuf_Any* val, upb_arena *a) { return _upb_msg_map_set(msg, UPB_SIZE(32, 64), &key, 0, &val, sizeof(val), a); }
-UPB_INLINE bool envoy_config_route_v3_WeightedCluster_ClusterWeight_typed_per_filter_config_delete(envoy_config_route_v3_WeightedCluster_ClusterWeight *msg, upb_strview key) { return _upb_msg_map_delete(msg, UPB_SIZE(32, 64), &key, 0); }
-UPB_INLINE envoy_config_route_v3_WeightedCluster_ClusterWeight_TypedPerFilterConfigEntry* envoy_config_route_v3_WeightedCluster_ClusterWeight_typed_per_filter_config_nextmutable(envoy_config_route_v3_WeightedCluster_ClusterWeight *msg, size_t* iter) { return (envoy_config_route_v3_WeightedCluster_ClusterWeight_TypedPerFilterConfigEntry*)_upb_msg_map_next(msg, UPB_SIZE(32, 64), iter); }
+UPB_INLINE void envoy_config_route_v3_WeightedCluster_ClusterWeight_typed_per_filter_config_clear(envoy_config_route_v3_WeightedCluster_ClusterWeight *msg) { _upb_msg_map_clear(msg, UPB_SIZE(36, 72)); }
+UPB_INLINE bool envoy_config_route_v3_WeightedCluster_ClusterWeight_typed_per_filter_config_set(envoy_config_route_v3_WeightedCluster_ClusterWeight *msg, upb_strview key, struct google_protobuf_Any* val, upb_arena *a) { return _upb_msg_map_set(msg, UPB_SIZE(36, 72), &key, 0, &val, sizeof(val), a); }
+UPB_INLINE bool envoy_config_route_v3_WeightedCluster_ClusterWeight_typed_per_filter_config_delete(envoy_config_route_v3_WeightedCluster_ClusterWeight *msg, upb_strview key) { return _upb_msg_map_delete(msg, UPB_SIZE(36, 72), &key, 0); }
+UPB_INLINE envoy_config_route_v3_WeightedCluster_ClusterWeight_TypedPerFilterConfigEntry* envoy_config_route_v3_WeightedCluster_ClusterWeight_typed_per_filter_config_nextmutable(envoy_config_route_v3_WeightedCluster_ClusterWeight *msg, size_t* iter) { return (envoy_config_route_v3_WeightedCluster_ClusterWeight_TypedPerFilterConfigEntry*)_upb_msg_map_next(msg, UPB_SIZE(36, 72), iter); }
 
 /* envoy.config.route.v3.WeightedCluster.ClusterWeight.TypedPerFilterConfigEntry */
 
@@ -918,6 +963,12 @@ UPB_INLINE envoy_config_route_v3_RouteMatch *envoy_config_route_v3_RouteMatch_pa
   envoy_config_route_v3_RouteMatch *ret = envoy_config_route_v3_RouteMatch_new(arena);
   return (ret && upb_decode(buf, size, ret, &envoy_config_route_v3_RouteMatch_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE envoy_config_route_v3_RouteMatch *envoy_config_route_v3_RouteMatch_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  envoy_config_route_v3_RouteMatch *ret = envoy_config_route_v3_RouteMatch_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &envoy_config_route_v3_RouteMatch_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *envoy_config_route_v3_RouteMatch_serialize(const envoy_config_route_v3_RouteMatch *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &envoy_config_route_v3_RouteMatch_msginit, arena, len);
 }
@@ -929,37 +980,38 @@ typedef enum {
   envoy_config_route_v3_RouteMatch_path_specifier_connect_matcher = 12,
   envoy_config_route_v3_RouteMatch_path_specifier_NOT_SET = 0
 } envoy_config_route_v3_RouteMatch_path_specifier_oneofcases;
-UPB_INLINE envoy_config_route_v3_RouteMatch_path_specifier_oneofcases envoy_config_route_v3_RouteMatch_path_specifier_case(const envoy_config_route_v3_RouteMatch* msg) { return (envoy_config_route_v3_RouteMatch_path_specifier_oneofcases)*UPB_PTR_AT(msg, UPB_SIZE(32, 64), int32_t); }
-
-UPB_INLINE bool envoy_config_route_v3_RouteMatch_has_prefix(const envoy_config_route_v3_RouteMatch *msg) { return _upb_getoneofcase(msg, UPB_SIZE(32, 64)) == 1; }
-UPB_INLINE upb_strview envoy_config_route_v3_RouteMatch_prefix(const envoy_config_route_v3_RouteMatch *msg) { return UPB_READ_ONEOF(msg, upb_strview, UPB_SIZE(24, 48), UPB_SIZE(32, 64), 1, upb_strview_make("", strlen(""))); }
-UPB_INLINE bool envoy_config_route_v3_RouteMatch_has_path(const envoy_config_route_v3_RouteMatch *msg) { return _upb_getoneofcase(msg, UPB_SIZE(32, 64)) == 2; }
-UPB_INLINE upb_strview envoy_config_route_v3_RouteMatch_path(const envoy_config_route_v3_RouteMatch *msg) { return UPB_READ_ONEOF(msg, upb_strview, UPB_SIZE(24, 48), UPB_SIZE(32, 64), 2, upb_strview_make("", strlen(""))); }
-UPB_INLINE bool envoy_config_route_v3_RouteMatch_has_case_sensitive(const envoy_config_route_v3_RouteMatch *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(0, 0)); }
-UPB_INLINE const struct google_protobuf_BoolValue* envoy_config_route_v3_RouteMatch_case_sensitive(const envoy_config_route_v3_RouteMatch *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(0, 0), const struct google_protobuf_BoolValue*); }
-UPB_INLINE bool envoy_config_route_v3_RouteMatch_has_headers(const envoy_config_route_v3_RouteMatch *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(16, 32)); }
-UPB_INLINE const envoy_config_route_v3_HeaderMatcher* const* envoy_config_route_v3_RouteMatch_headers(const envoy_config_route_v3_RouteMatch *msg, size_t *len) { return (const envoy_config_route_v3_HeaderMatcher* const*)_upb_array_accessor(msg, UPB_SIZE(16, 32), len); }
-UPB_INLINE bool envoy_config_route_v3_RouteMatch_has_query_parameters(const envoy_config_route_v3_RouteMatch *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(20, 40)); }
-UPB_INLINE const envoy_config_route_v3_QueryParameterMatcher* const* envoy_config_route_v3_RouteMatch_query_parameters(const envoy_config_route_v3_RouteMatch *msg, size_t *len) { return (const envoy_config_route_v3_QueryParameterMatcher* const*)_upb_array_accessor(msg, UPB_SIZE(20, 40), len); }
-UPB_INLINE bool envoy_config_route_v3_RouteMatch_has_grpc(const envoy_config_route_v3_RouteMatch *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(4, 8)); }
-UPB_INLINE const envoy_config_route_v3_RouteMatch_GrpcRouteMatchOptions* envoy_config_route_v3_RouteMatch_grpc(const envoy_config_route_v3_RouteMatch *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(4, 8), const envoy_config_route_v3_RouteMatch_GrpcRouteMatchOptions*); }
-UPB_INLINE bool envoy_config_route_v3_RouteMatch_has_runtime_fraction(const envoy_config_route_v3_RouteMatch *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(8, 16)); }
-UPB_INLINE const struct envoy_config_core_v3_RuntimeFractionalPercent* envoy_config_route_v3_RouteMatch_runtime_fraction(const envoy_config_route_v3_RouteMatch *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(8, 16), const struct envoy_config_core_v3_RuntimeFractionalPercent*); }
-UPB_INLINE bool envoy_config_route_v3_RouteMatch_has_safe_regex(const envoy_config_route_v3_RouteMatch *msg) { return _upb_getoneofcase(msg, UPB_SIZE(32, 64)) == 10; }
-UPB_INLINE const struct envoy_type_matcher_v3_RegexMatcher* envoy_config_route_v3_RouteMatch_safe_regex(const envoy_config_route_v3_RouteMatch *msg) { return UPB_READ_ONEOF(msg, const struct envoy_type_matcher_v3_RegexMatcher*, UPB_SIZE(24, 48), UPB_SIZE(32, 64), 10, NULL); }
-UPB_INLINE bool envoy_config_route_v3_RouteMatch_has_tls_context(const envoy_config_route_v3_RouteMatch *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(12, 24)); }
-UPB_INLINE const envoy_config_route_v3_RouteMatch_TlsContextMatchOptions* envoy_config_route_v3_RouteMatch_tls_context(const envoy_config_route_v3_RouteMatch *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(12, 24), const envoy_config_route_v3_RouteMatch_TlsContextMatchOptions*); }
-UPB_INLINE bool envoy_config_route_v3_RouteMatch_has_connect_matcher(const envoy_config_route_v3_RouteMatch *msg) { return _upb_getoneofcase(msg, UPB_SIZE(32, 64)) == 12; }
-UPB_INLINE const envoy_config_route_v3_RouteMatch_ConnectMatcher* envoy_config_route_v3_RouteMatch_connect_matcher(const envoy_config_route_v3_RouteMatch *msg) { return UPB_READ_ONEOF(msg, const envoy_config_route_v3_RouteMatch_ConnectMatcher*, UPB_SIZE(24, 48), UPB_SIZE(32, 64), 12, NULL); }
+UPB_INLINE envoy_config_route_v3_RouteMatch_path_specifier_oneofcases envoy_config_route_v3_RouteMatch_path_specifier_case(const envoy_config_route_v3_RouteMatch* msg) { return (envoy_config_route_v3_RouteMatch_path_specifier_oneofcases)*UPB_PTR_AT(msg, UPB_SIZE(36, 72), int32_t); }
+
+UPB_INLINE bool envoy_config_route_v3_RouteMatch_has_prefix(const envoy_config_route_v3_RouteMatch *msg) { return _upb_getoneofcase(msg, UPB_SIZE(36, 72)) == 1; }
+UPB_INLINE upb_strview envoy_config_route_v3_RouteMatch_prefix(const envoy_config_route_v3_RouteMatch *msg) { return UPB_READ_ONEOF(msg, upb_strview, UPB_SIZE(28, 56), UPB_SIZE(36, 72), 1, upb_strview_make("", strlen(""))); }
+UPB_INLINE bool envoy_config_route_v3_RouteMatch_has_path(const envoy_config_route_v3_RouteMatch *msg) { return _upb_getoneofcase(msg, UPB_SIZE(36, 72)) == 2; }
+UPB_INLINE upb_strview envoy_config_route_v3_RouteMatch_path(const envoy_config_route_v3_RouteMatch *msg) { return UPB_READ_ONEOF(msg, upb_strview, UPB_SIZE(28, 56), UPB_SIZE(36, 72), 2, upb_strview_make("", strlen(""))); }
+UPB_INLINE bool envoy_config_route_v3_RouteMatch_has_case_sensitive(const envoy_config_route_v3_RouteMatch *msg) { return _upb_hasbit(msg, 1); }
+UPB_INLINE const struct google_protobuf_BoolValue* envoy_config_route_v3_RouteMatch_case_sensitive(const envoy_config_route_v3_RouteMatch *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(4, 8), const struct google_protobuf_BoolValue*); }
+UPB_INLINE bool envoy_config_route_v3_RouteMatch_has_headers(const envoy_config_route_v3_RouteMatch *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(20, 40)); }
+UPB_INLINE const envoy_config_route_v3_HeaderMatcher* const* envoy_config_route_v3_RouteMatch_headers(const envoy_config_route_v3_RouteMatch *msg, size_t *len) { return (const envoy_config_route_v3_HeaderMatcher* const*)_upb_array_accessor(msg, UPB_SIZE(20, 40), len); }
+UPB_INLINE bool envoy_config_route_v3_RouteMatch_has_query_parameters(const envoy_config_route_v3_RouteMatch *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(24, 48)); }
+UPB_INLINE const envoy_config_route_v3_QueryParameterMatcher* const* envoy_config_route_v3_RouteMatch_query_parameters(const envoy_config_route_v3_RouteMatch *msg, size_t *len) { return (const envoy_config_route_v3_QueryParameterMatcher* const*)_upb_array_accessor(msg, UPB_SIZE(24, 48), len); }
+UPB_INLINE bool envoy_config_route_v3_RouteMatch_has_grpc(const envoy_config_route_v3_RouteMatch *msg) { return _upb_hasbit(msg, 2); }
+UPB_INLINE const envoy_config_route_v3_RouteMatch_GrpcRouteMatchOptions* envoy_config_route_v3_RouteMatch_grpc(const envoy_config_route_v3_RouteMatch *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(8, 16), const envoy_config_route_v3_RouteMatch_GrpcRouteMatchOptions*); }
+UPB_INLINE bool envoy_config_route_v3_RouteMatch_has_runtime_fraction(const envoy_config_route_v3_RouteMatch *msg) { return _upb_hasbit(msg, 3); }
+UPB_INLINE const struct envoy_config_core_v3_RuntimeFractionalPercent* envoy_config_route_v3_RouteMatch_runtime_fraction(const envoy_config_route_v3_RouteMatch *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(12, 24), const struct envoy_config_core_v3_RuntimeFractionalPercent*); }
+UPB_INLINE bool envoy_config_route_v3_RouteMatch_has_safe_regex(const envoy_config_route_v3_RouteMatch *msg) { return _upb_getoneofcase(msg, UPB_SIZE(36, 72)) == 10; }
+UPB_INLINE const struct envoy_type_matcher_v3_RegexMatcher* envoy_config_route_v3_RouteMatch_safe_regex(const envoy_config_route_v3_RouteMatch *msg) { return UPB_READ_ONEOF(msg, const struct envoy_type_matcher_v3_RegexMatcher*, UPB_SIZE(28, 56), UPB_SIZE(36, 72), 10, NULL); }
+UPB_INLINE bool envoy_config_route_v3_RouteMatch_has_tls_context(const envoy_config_route_v3_RouteMatch *msg) { return _upb_hasbit(msg, 4); }
+UPB_INLINE const envoy_config_route_v3_RouteMatch_TlsContextMatchOptions* envoy_config_route_v3_RouteMatch_tls_context(const envoy_config_route_v3_RouteMatch *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(16, 32), const envoy_config_route_v3_RouteMatch_TlsContextMatchOptions*); }
+UPB_INLINE bool envoy_config_route_v3_RouteMatch_has_connect_matcher(const envoy_config_route_v3_RouteMatch *msg) { return _upb_getoneofcase(msg, UPB_SIZE(36, 72)) == 12; }
+UPB_INLINE const envoy_config_route_v3_RouteMatch_ConnectMatcher* envoy_config_route_v3_RouteMatch_connect_matcher(const envoy_config_route_v3_RouteMatch *msg) { return UPB_READ_ONEOF(msg, const envoy_config_route_v3_RouteMatch_ConnectMatcher*, UPB_SIZE(28, 56), UPB_SIZE(36, 72), 12, NULL); }
 
 UPB_INLINE void envoy_config_route_v3_RouteMatch_set_prefix(envoy_config_route_v3_RouteMatch *msg, upb_strview value) {
-  UPB_WRITE_ONEOF(msg, upb_strview, UPB_SIZE(24, 48), value, UPB_SIZE(32, 64), 1);
+  UPB_WRITE_ONEOF(msg, upb_strview, UPB_SIZE(28, 56), value, UPB_SIZE(36, 72), 1);
 }
 UPB_INLINE void envoy_config_route_v3_RouteMatch_set_path(envoy_config_route_v3_RouteMatch *msg, upb_strview value) {
-  UPB_WRITE_ONEOF(msg, upb_strview, UPB_SIZE(24, 48), value, UPB_SIZE(32, 64), 2);
+  UPB_WRITE_ONEOF(msg, upb_strview, UPB_SIZE(28, 56), value, UPB_SIZE(36, 72), 2);
 }
 UPB_INLINE void envoy_config_route_v3_RouteMatch_set_case_sensitive(envoy_config_route_v3_RouteMatch *msg, struct google_protobuf_BoolValue* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(0, 0), struct google_protobuf_BoolValue*) = value;
+  _upb_sethas(msg, 1);
+  *UPB_PTR_AT(msg, UPB_SIZE(4, 8), struct google_protobuf_BoolValue*) = value;
 }
 UPB_INLINE struct google_protobuf_BoolValue* envoy_config_route_v3_RouteMatch_mutable_case_sensitive(envoy_config_route_v3_RouteMatch *msg, upb_arena *arena) {
   struct google_protobuf_BoolValue* sub = (struct google_protobuf_BoolValue*)envoy_config_route_v3_RouteMatch_case_sensitive(msg);
@@ -971,33 +1023,34 @@ UPB_INLINE struct google_protobuf_BoolValue* envoy_config_route_v3_RouteMatch_mu
   return sub;
 }
 UPB_INLINE envoy_config_route_v3_HeaderMatcher** envoy_config_route_v3_RouteMatch_mutable_headers(envoy_config_route_v3_RouteMatch *msg, size_t *len) {
-  return (envoy_config_route_v3_HeaderMatcher**)_upb_array_mutable_accessor(msg, UPB_SIZE(16, 32), len);
+  return (envoy_config_route_v3_HeaderMatcher**)_upb_array_mutable_accessor(msg, UPB_SIZE(20, 40), len);
 }
 UPB_INLINE envoy_config_route_v3_HeaderMatcher** envoy_config_route_v3_RouteMatch_resize_headers(envoy_config_route_v3_RouteMatch *msg, size_t len, upb_arena *arena) {
-  return (envoy_config_route_v3_HeaderMatcher**)_upb_array_resize_accessor(msg, UPB_SIZE(16, 32), len, UPB_TYPE_MESSAGE, arena);
+  return (envoy_config_route_v3_HeaderMatcher**)_upb_array_resize_accessor2(msg, UPB_SIZE(20, 40), len, UPB_SIZE(2, 3), arena);
 }
 UPB_INLINE struct envoy_config_route_v3_HeaderMatcher* envoy_config_route_v3_RouteMatch_add_headers(envoy_config_route_v3_RouteMatch *msg, upb_arena *arena) {
   struct envoy_config_route_v3_HeaderMatcher* sub = (struct envoy_config_route_v3_HeaderMatcher*)_upb_msg_new(&envoy_config_route_v3_HeaderMatcher_msginit, arena);
-  bool ok = _upb_array_append_accessor(
-      msg, UPB_SIZE(16, 32), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena);
+  bool ok = _upb_array_append_accessor2(
+      msg, UPB_SIZE(20, 40), UPB_SIZE(2, 3), &sub, arena);
   if (!ok) return NULL;
   return sub;
 }
 UPB_INLINE envoy_config_route_v3_QueryParameterMatcher** envoy_config_route_v3_RouteMatch_mutable_query_parameters(envoy_config_route_v3_RouteMatch *msg, size_t *len) {
-  return (envoy_config_route_v3_QueryParameterMatcher**)_upb_array_mutable_accessor(msg, UPB_SIZE(20, 40), len);
+  return (envoy_config_route_v3_QueryParameterMatcher**)_upb_array_mutable_accessor(msg, UPB_SIZE(24, 48), len);
 }
 UPB_INLINE envoy_config_route_v3_QueryParameterMatcher** envoy_config_route_v3_RouteMatch_resize_query_parameters(envoy_config_route_v3_RouteMatch *msg, size_t len, upb_arena *arena) {
-  return (envoy_config_route_v3_QueryParameterMatcher**)_upb_array_resize_accessor(msg, UPB_SIZE(20, 40), len, UPB_TYPE_MESSAGE, arena);
+  return (envoy_config_route_v3_QueryParameterMatcher**)_upb_array_resize_accessor2(msg, UPB_SIZE(24, 48), len, UPB_SIZE(2, 3), arena);
 }
 UPB_INLINE struct envoy_config_route_v3_QueryParameterMatcher* envoy_config_route_v3_RouteMatch_add_query_parameters(envoy_config_route_v3_RouteMatch *msg, upb_arena *arena) {
   struct envoy_config_route_v3_QueryParameterMatcher* sub = (struct envoy_config_route_v3_QueryParameterMatcher*)_upb_msg_new(&envoy_config_route_v3_QueryParameterMatcher_msginit, arena);
-  bool ok = _upb_array_append_accessor(
-      msg, UPB_SIZE(20, 40), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena);
+  bool ok = _upb_array_append_accessor2(
+      msg, UPB_SIZE(24, 48), UPB_SIZE(2, 3), &sub, arena);
   if (!ok) return NULL;
   return sub;
 }
 UPB_INLINE void envoy_config_route_v3_RouteMatch_set_grpc(envoy_config_route_v3_RouteMatch *msg, envoy_config_route_v3_RouteMatch_GrpcRouteMatchOptions* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(4, 8), envoy_config_route_v3_RouteMatch_GrpcRouteMatchOptions*) = value;
+  _upb_sethas(msg, 2);
+  *UPB_PTR_AT(msg, UPB_SIZE(8, 16), envoy_config_route_v3_RouteMatch_GrpcRouteMatchOptions*) = value;
 }
 UPB_INLINE struct envoy_config_route_v3_RouteMatch_GrpcRouteMatchOptions* envoy_config_route_v3_RouteMatch_mutable_grpc(envoy_config_route_v3_RouteMatch *msg, upb_arena *arena) {
   struct envoy_config_route_v3_RouteMatch_GrpcRouteMatchOptions* sub = (struct envoy_config_route_v3_RouteMatch_GrpcRouteMatchOptions*)envoy_config_route_v3_RouteMatch_grpc(msg);
@@ -1009,7 +1062,8 @@ UPB_INLINE struct envoy_config_route_v3_RouteMatch_GrpcRouteMatchOptions* envoy_
   return sub;
 }
 UPB_INLINE void envoy_config_route_v3_RouteMatch_set_runtime_fraction(envoy_config_route_v3_RouteMatch *msg, struct envoy_config_core_v3_RuntimeFractionalPercent* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(8, 16), struct envoy_config_core_v3_RuntimeFractionalPercent*) = value;
+  _upb_sethas(msg, 3);
+  *UPB_PTR_AT(msg, UPB_SIZE(12, 24), struct envoy_config_core_v3_RuntimeFractionalPercent*) = value;
 }
 UPB_INLINE struct envoy_config_core_v3_RuntimeFractionalPercent* envoy_config_route_v3_RouteMatch_mutable_runtime_fraction(envoy_config_route_v3_RouteMatch *msg, upb_arena *arena) {
   struct envoy_config_core_v3_RuntimeFractionalPercent* sub = (struct envoy_config_core_v3_RuntimeFractionalPercent*)envoy_config_route_v3_RouteMatch_runtime_fraction(msg);
@@ -1021,7 +1075,7 @@ UPB_INLINE struct envoy_config_core_v3_RuntimeFractionalPercent* envoy_config_ro
   return sub;
 }
 UPB_INLINE void envoy_config_route_v3_RouteMatch_set_safe_regex(envoy_config_route_v3_RouteMatch *msg, struct envoy_type_matcher_v3_RegexMatcher* value) {
-  UPB_WRITE_ONEOF(msg, struct envoy_type_matcher_v3_RegexMatcher*, UPB_SIZE(24, 48), value, UPB_SIZE(32, 64), 10);
+  UPB_WRITE_ONEOF(msg, struct envoy_type_matcher_v3_RegexMatcher*, UPB_SIZE(28, 56), value, UPB_SIZE(36, 72), 10);
 }
 UPB_INLINE struct envoy_type_matcher_v3_RegexMatcher* envoy_config_route_v3_RouteMatch_mutable_safe_regex(envoy_config_route_v3_RouteMatch *msg, upb_arena *arena) {
   struct envoy_type_matcher_v3_RegexMatcher* sub = (struct envoy_type_matcher_v3_RegexMatcher*)envoy_config_route_v3_RouteMatch_safe_regex(msg);
@@ -1033,7 +1087,8 @@ UPB_INLINE struct envoy_type_matcher_v3_RegexMatcher* envoy_config_route_v3_Rout
   return sub;
 }
 UPB_INLINE void envoy_config_route_v3_RouteMatch_set_tls_context(envoy_config_route_v3_RouteMatch *msg, envoy_config_route_v3_RouteMatch_TlsContextMatchOptions* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(12, 24), envoy_config_route_v3_RouteMatch_TlsContextMatchOptions*) = value;
+  _upb_sethas(msg, 4);
+  *UPB_PTR_AT(msg, UPB_SIZE(16, 32), envoy_config_route_v3_RouteMatch_TlsContextMatchOptions*) = value;
 }
 UPB_INLINE struct envoy_config_route_v3_RouteMatch_TlsContextMatchOptions* envoy_config_route_v3_RouteMatch_mutable_tls_context(envoy_config_route_v3_RouteMatch *msg, upb_arena *arena) {
   struct envoy_config_route_v3_RouteMatch_TlsContextMatchOptions* sub = (struct envoy_config_route_v3_RouteMatch_TlsContextMatchOptions*)envoy_config_route_v3_RouteMatch_tls_context(msg);
@@ -1045,7 +1100,7 @@ UPB_INLINE struct envoy_config_route_v3_RouteMatch_TlsContextMatchOptions* envoy
   return sub;
 }
 UPB_INLINE void envoy_config_route_v3_RouteMatch_set_connect_matcher(envoy_config_route_v3_RouteMatch *msg, envoy_config_route_v3_RouteMatch_ConnectMatcher* value) {
-  UPB_WRITE_ONEOF(msg, envoy_config_route_v3_RouteMatch_ConnectMatcher*, UPB_SIZE(24, 48), value, UPB_SIZE(32, 64), 12);
+  UPB_WRITE_ONEOF(msg, envoy_config_route_v3_RouteMatch_ConnectMatcher*, UPB_SIZE(28, 56), value, UPB_SIZE(36, 72), 12);
 }
 UPB_INLINE struct envoy_config_route_v3_RouteMatch_ConnectMatcher* envoy_config_route_v3_RouteMatch_mutable_connect_matcher(envoy_config_route_v3_RouteMatch *msg, upb_arena *arena) {
   struct envoy_config_route_v3_RouteMatch_ConnectMatcher* sub = (struct envoy_config_route_v3_RouteMatch_ConnectMatcher*)envoy_config_route_v3_RouteMatch_connect_matcher(msg);
@@ -1067,6 +1122,12 @@ UPB_INLINE envoy_config_route_v3_RouteMatch_GrpcRouteMatchOptions *envoy_config_
   envoy_config_route_v3_RouteMatch_GrpcRouteMatchOptions *ret = envoy_config_route_v3_RouteMatch_GrpcRouteMatchOptions_new(arena);
   return (ret && upb_decode(buf, size, ret, &envoy_config_route_v3_RouteMatch_GrpcRouteMatchOptions_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE envoy_config_route_v3_RouteMatch_GrpcRouteMatchOptions *envoy_config_route_v3_RouteMatch_GrpcRouteMatchOptions_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  envoy_config_route_v3_RouteMatch_GrpcRouteMatchOptions *ret = envoy_config_route_v3_RouteMatch_GrpcRouteMatchOptions_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &envoy_config_route_v3_RouteMatch_GrpcRouteMatchOptions_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *envoy_config_route_v3_RouteMatch_GrpcRouteMatchOptions_serialize(const envoy_config_route_v3_RouteMatch_GrpcRouteMatchOptions *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &envoy_config_route_v3_RouteMatch_GrpcRouteMatchOptions_msginit, arena, len);
 }
@@ -1083,17 +1144,24 @@ UPB_INLINE envoy_config_route_v3_RouteMatch_TlsContextMatchOptions *envoy_config
   envoy_config_route_v3_RouteMatch_TlsContextMatchOptions *ret = envoy_config_route_v3_RouteMatch_TlsContextMatchOptions_new(arena);
   return (ret && upb_decode(buf, size, ret, &envoy_config_route_v3_RouteMatch_TlsContextMatchOptions_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE envoy_config_route_v3_RouteMatch_TlsContextMatchOptions *envoy_config_route_v3_RouteMatch_TlsContextMatchOptions_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  envoy_config_route_v3_RouteMatch_TlsContextMatchOptions *ret = envoy_config_route_v3_RouteMatch_TlsContextMatchOptions_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &envoy_config_route_v3_RouteMatch_TlsContextMatchOptions_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *envoy_config_route_v3_RouteMatch_TlsContextMatchOptions_serialize(const envoy_config_route_v3_RouteMatch_TlsContextMatchOptions *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &envoy_config_route_v3_RouteMatch_TlsContextMatchOptions_msginit, arena, len);
 }
 
-UPB_INLINE bool envoy_config_route_v3_RouteMatch_TlsContextMatchOptions_has_presented(const envoy_config_route_v3_RouteMatch_TlsContextMatchOptions *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(0, 0)); }
-UPB_INLINE const struct google_protobuf_BoolValue* envoy_config_route_v3_RouteMatch_TlsContextMatchOptions_presented(const envoy_config_route_v3_RouteMatch_TlsContextMatchOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(0, 0), const struct google_protobuf_BoolValue*); }
-UPB_INLINE bool envoy_config_route_v3_RouteMatch_TlsContextMatchOptions_has_validated(const envoy_config_route_v3_RouteMatch_TlsContextMatchOptions *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(4, 8)); }
-UPB_INLINE const struct google_protobuf_BoolValue* envoy_config_route_v3_RouteMatch_TlsContextMatchOptions_validated(const envoy_config_route_v3_RouteMatch_TlsContextMatchOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(4, 8), const struct google_protobuf_BoolValue*); }
+UPB_INLINE bool envoy_config_route_v3_RouteMatch_TlsContextMatchOptions_has_presented(const envoy_config_route_v3_RouteMatch_TlsContextMatchOptions *msg) { return _upb_hasbit(msg, 1); }
+UPB_INLINE const struct google_protobuf_BoolValue* envoy_config_route_v3_RouteMatch_TlsContextMatchOptions_presented(const envoy_config_route_v3_RouteMatch_TlsContextMatchOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(4, 8), const struct google_protobuf_BoolValue*); }
+UPB_INLINE bool envoy_config_route_v3_RouteMatch_TlsContextMatchOptions_has_validated(const envoy_config_route_v3_RouteMatch_TlsContextMatchOptions *msg) { return _upb_hasbit(msg, 2); }
+UPB_INLINE const struct google_protobuf_BoolValue* envoy_config_route_v3_RouteMatch_TlsContextMatchOptions_validated(const envoy_config_route_v3_RouteMatch_TlsContextMatchOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(8, 16), const struct google_protobuf_BoolValue*); }
 
 UPB_INLINE void envoy_config_route_v3_RouteMatch_TlsContextMatchOptions_set_presented(envoy_config_route_v3_RouteMatch_TlsContextMatchOptions *msg, struct google_protobuf_BoolValue* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(0, 0), struct google_protobuf_BoolValue*) = value;
+  _upb_sethas(msg, 1);
+  *UPB_PTR_AT(msg, UPB_SIZE(4, 8), struct google_protobuf_BoolValue*) = value;
 }
 UPB_INLINE struct google_protobuf_BoolValue* envoy_config_route_v3_RouteMatch_TlsContextMatchOptions_mutable_presented(envoy_config_route_v3_RouteMatch_TlsContextMatchOptions *msg, upb_arena *arena) {
   struct google_protobuf_BoolValue* sub = (struct google_protobuf_BoolValue*)envoy_config_route_v3_RouteMatch_TlsContextMatchOptions_presented(msg);
@@ -1105,7 +1173,8 @@ UPB_INLINE struct google_protobuf_BoolValue* envoy_config_route_v3_RouteMatch_Tl
   return sub;
 }
 UPB_INLINE void envoy_config_route_v3_RouteMatch_TlsContextMatchOptions_set_validated(envoy_config_route_v3_RouteMatch_TlsContextMatchOptions *msg, struct google_protobuf_BoolValue* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(4, 8), struct google_protobuf_BoolValue*) = value;
+  _upb_sethas(msg, 2);
+  *UPB_PTR_AT(msg, UPB_SIZE(8, 16), struct google_protobuf_BoolValue*) = value;
 }
 UPB_INLINE struct google_protobuf_BoolValue* envoy_config_route_v3_RouteMatch_TlsContextMatchOptions_mutable_validated(envoy_config_route_v3_RouteMatch_TlsContextMatchOptions *msg, upb_arena *arena) {
   struct google_protobuf_BoolValue* sub = (struct google_protobuf_BoolValue*)envoy_config_route_v3_RouteMatch_TlsContextMatchOptions_validated(msg);
@@ -1127,6 +1196,12 @@ UPB_INLINE envoy_config_route_v3_RouteMatch_ConnectMatcher *envoy_config_route_v
   envoy_config_route_v3_RouteMatch_ConnectMatcher *ret = envoy_config_route_v3_RouteMatch_ConnectMatcher_new(arena);
   return (ret && upb_decode(buf, size, ret, &envoy_config_route_v3_RouteMatch_ConnectMatcher_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE envoy_config_route_v3_RouteMatch_ConnectMatcher *envoy_config_route_v3_RouteMatch_ConnectMatcher_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  envoy_config_route_v3_RouteMatch_ConnectMatcher *ret = envoy_config_route_v3_RouteMatch_ConnectMatcher_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &envoy_config_route_v3_RouteMatch_ConnectMatcher_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *envoy_config_route_v3_RouteMatch_ConnectMatcher_serialize(const envoy_config_route_v3_RouteMatch_ConnectMatcher *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &envoy_config_route_v3_RouteMatch_ConnectMatcher_msginit, arena, len);
 }
@@ -1143,6 +1218,12 @@ UPB_INLINE envoy_config_route_v3_CorsPolicy *envoy_config_route_v3_CorsPolicy_pa
   envoy_config_route_v3_CorsPolicy *ret = envoy_config_route_v3_CorsPolicy_new(arena);
   return (ret && upb_decode(buf, size, ret, &envoy_config_route_v3_CorsPolicy_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE envoy_config_route_v3_CorsPolicy *envoy_config_route_v3_CorsPolicy_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  envoy_config_route_v3_CorsPolicy *ret = envoy_config_route_v3_CorsPolicy_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &envoy_config_route_v3_CorsPolicy_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *envoy_config_route_v3_CorsPolicy_serialize(const envoy_config_route_v3_CorsPolicy *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &envoy_config_route_v3_CorsPolicy_msginit, arena, len);
 }
@@ -1151,35 +1232,36 @@ typedef enum {
   envoy_config_route_v3_CorsPolicy_enabled_specifier_filter_enabled = 9,
   envoy_config_route_v3_CorsPolicy_enabled_specifier_NOT_SET = 0
 } envoy_config_route_v3_CorsPolicy_enabled_specifier_oneofcases;
-UPB_INLINE envoy_config_route_v3_CorsPolicy_enabled_specifier_oneofcases envoy_config_route_v3_CorsPolicy_enabled_specifier_case(const envoy_config_route_v3_CorsPolicy* msg) { return (envoy_config_route_v3_CorsPolicy_enabled_specifier_oneofcases)*UPB_PTR_AT(msg, UPB_SIZE(48, 96), int32_t); }
-
-UPB_INLINE upb_strview envoy_config_route_v3_CorsPolicy_allow_methods(const envoy_config_route_v3_CorsPolicy *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(0, 0), upb_strview); }
-UPB_INLINE upb_strview envoy_config_route_v3_CorsPolicy_allow_headers(const envoy_config_route_v3_CorsPolicy *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(8, 16), upb_strview); }
-UPB_INLINE upb_strview envoy_config_route_v3_CorsPolicy_expose_headers(const envoy_config_route_v3_CorsPolicy *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(16, 32), upb_strview); }
-UPB_INLINE upb_strview envoy_config_route_v3_CorsPolicy_max_age(const envoy_config_route_v3_CorsPolicy *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(24, 48), upb_strview); }
-UPB_INLINE bool envoy_config_route_v3_CorsPolicy_has_allow_credentials(const envoy_config_route_v3_CorsPolicy *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(32, 64)); }
-UPB_INLINE const struct google_protobuf_BoolValue* envoy_config_route_v3_CorsPolicy_allow_credentials(const envoy_config_route_v3_CorsPolicy *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(32, 64), const struct google_protobuf_BoolValue*); }
-UPB_INLINE bool envoy_config_route_v3_CorsPolicy_has_filter_enabled(const envoy_config_route_v3_CorsPolicy *msg) { return _upb_getoneofcase(msg, UPB_SIZE(48, 96)) == 9; }
-UPB_INLINE const struct envoy_config_core_v3_RuntimeFractionalPercent* envoy_config_route_v3_CorsPolicy_filter_enabled(const envoy_config_route_v3_CorsPolicy *msg) { return UPB_READ_ONEOF(msg, const struct envoy_config_core_v3_RuntimeFractionalPercent*, UPB_SIZE(44, 88), UPB_SIZE(48, 96), 9, NULL); }
-UPB_INLINE bool envoy_config_route_v3_CorsPolicy_has_shadow_enabled(const envoy_config_route_v3_CorsPolicy *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(36, 72)); }
-UPB_INLINE const struct envoy_config_core_v3_RuntimeFractionalPercent* envoy_config_route_v3_CorsPolicy_shadow_enabled(const envoy_config_route_v3_CorsPolicy *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(36, 72), const struct envoy_config_core_v3_RuntimeFractionalPercent*); }
-UPB_INLINE bool envoy_config_route_v3_CorsPolicy_has_allow_origin_string_match(const envoy_config_route_v3_CorsPolicy *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(40, 80)); }
-UPB_INLINE const struct envoy_type_matcher_v3_StringMatcher* const* envoy_config_route_v3_CorsPolicy_allow_origin_string_match(const envoy_config_route_v3_CorsPolicy *msg, size_t *len) { return (const struct envoy_type_matcher_v3_StringMatcher* const*)_upb_array_accessor(msg, UPB_SIZE(40, 80), len); }
+UPB_INLINE envoy_config_route_v3_CorsPolicy_enabled_specifier_oneofcases envoy_config_route_v3_CorsPolicy_enabled_specifier_case(const envoy_config_route_v3_CorsPolicy* msg) { return (envoy_config_route_v3_CorsPolicy_enabled_specifier_oneofcases)*UPB_PTR_AT(msg, UPB_SIZE(52, 104), int32_t); }
+
+UPB_INLINE upb_strview envoy_config_route_v3_CorsPolicy_allow_methods(const envoy_config_route_v3_CorsPolicy *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(4, 8), upb_strview); }
+UPB_INLINE upb_strview envoy_config_route_v3_CorsPolicy_allow_headers(const envoy_config_route_v3_CorsPolicy *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(12, 24), upb_strview); }
+UPB_INLINE upb_strview envoy_config_route_v3_CorsPolicy_expose_headers(const envoy_config_route_v3_CorsPolicy *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(20, 40), upb_strview); }
+UPB_INLINE upb_strview envoy_config_route_v3_CorsPolicy_max_age(const envoy_config_route_v3_CorsPolicy *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(28, 56), upb_strview); }
+UPB_INLINE bool envoy_config_route_v3_CorsPolicy_has_allow_credentials(const envoy_config_route_v3_CorsPolicy *msg) { return _upb_hasbit(msg, 1); }
+UPB_INLINE const struct google_protobuf_BoolValue* envoy_config_route_v3_CorsPolicy_allow_credentials(const envoy_config_route_v3_CorsPolicy *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(36, 72), const struct google_protobuf_BoolValue*); }
+UPB_INLINE bool envoy_config_route_v3_CorsPolicy_has_filter_enabled(const envoy_config_route_v3_CorsPolicy *msg) { return _upb_getoneofcase(msg, UPB_SIZE(52, 104)) == 9; }
+UPB_INLINE const struct envoy_config_core_v3_RuntimeFractionalPercent* envoy_config_route_v3_CorsPolicy_filter_enabled(const envoy_config_route_v3_CorsPolicy *msg) { return UPB_READ_ONEOF(msg, const struct envoy_config_core_v3_RuntimeFractionalPercent*, UPB_SIZE(48, 96), UPB_SIZE(52, 104), 9, NULL); }
+UPB_INLINE bool envoy_config_route_v3_CorsPolicy_has_shadow_enabled(const envoy_config_route_v3_CorsPolicy *msg) { return _upb_hasbit(msg, 2); }
+UPB_INLINE const struct envoy_config_core_v3_RuntimeFractionalPercent* envoy_config_route_v3_CorsPolicy_shadow_enabled(const envoy_config_route_v3_CorsPolicy *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(40, 80), const struct envoy_config_core_v3_RuntimeFractionalPercent*); }
+UPB_INLINE bool envoy_config_route_v3_CorsPolicy_has_allow_origin_string_match(const envoy_config_route_v3_CorsPolicy *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(44, 88)); }
+UPB_INLINE const struct envoy_type_matcher_v3_StringMatcher* const* envoy_config_route_v3_CorsPolicy_allow_origin_string_match(const envoy_config_route_v3_CorsPolicy *msg, size_t *len) { return (const struct envoy_type_matcher_v3_StringMatcher* const*)_upb_array_accessor(msg, UPB_SIZE(44, 88), len); }
 
 UPB_INLINE void envoy_config_route_v3_CorsPolicy_set_allow_methods(envoy_config_route_v3_CorsPolicy *msg, upb_strview value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(0, 0), upb_strview) = value;
+  *UPB_PTR_AT(msg, UPB_SIZE(4, 8), upb_strview) = value;
 }
 UPB_INLINE void envoy_config_route_v3_CorsPolicy_set_allow_headers(envoy_config_route_v3_CorsPolicy *msg, upb_strview value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(8, 16), upb_strview) = value;
+  *UPB_PTR_AT(msg, UPB_SIZE(12, 24), upb_strview) = value;
 }
 UPB_INLINE void envoy_config_route_v3_CorsPolicy_set_expose_headers(envoy_config_route_v3_CorsPolicy *msg, upb_strview value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(16, 32), upb_strview) = value;
+  *UPB_PTR_AT(msg, UPB_SIZE(20, 40), upb_strview) = value;
 }
 UPB_INLINE void envoy_config_route_v3_CorsPolicy_set_max_age(envoy_config_route_v3_CorsPolicy *msg, upb_strview value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(24, 48), upb_strview) = value;
+  *UPB_PTR_AT(msg, UPB_SIZE(28, 56), upb_strview) = value;
 }
 UPB_INLINE void envoy_config_route_v3_CorsPolicy_set_allow_credentials(envoy_config_route_v3_CorsPolicy *msg, struct google_protobuf_BoolValue* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(32, 64), struct google_protobuf_BoolValue*) = value;
+  _upb_sethas(msg, 1);
+  *UPB_PTR_AT(msg, UPB_SIZE(36, 72), struct google_protobuf_BoolValue*) = value;
 }
 UPB_INLINE struct google_protobuf_BoolValue* envoy_config_route_v3_CorsPolicy_mutable_allow_credentials(envoy_config_route_v3_CorsPolicy *msg, upb_arena *arena) {
   struct google_protobuf_BoolValue* sub = (struct google_protobuf_BoolValue*)envoy_config_route_v3_CorsPolicy_allow_credentials(msg);
@@ -1191,7 +1273,7 @@ UPB_INLINE struct google_protobuf_BoolValue* envoy_config_route_v3_CorsPolicy_mu
   return sub;
 }
 UPB_INLINE void envoy_config_route_v3_CorsPolicy_set_filter_enabled(envoy_config_route_v3_CorsPolicy *msg, struct envoy_config_core_v3_RuntimeFractionalPercent* value) {
-  UPB_WRITE_ONEOF(msg, struct envoy_config_core_v3_RuntimeFractionalPercent*, UPB_SIZE(44, 88), value, UPB_SIZE(48, 96), 9);
+  UPB_WRITE_ONEOF(msg, struct envoy_config_core_v3_RuntimeFractionalPercent*, UPB_SIZE(48, 96), value, UPB_SIZE(52, 104), 9);
 }
 UPB_INLINE struct envoy_config_core_v3_RuntimeFractionalPercent* envoy_config_route_v3_CorsPolicy_mutable_filter_enabled(envoy_config_route_v3_CorsPolicy *msg, upb_arena *arena) {
   struct envoy_config_core_v3_RuntimeFractionalPercent* sub = (struct envoy_config_core_v3_RuntimeFractionalPercent*)envoy_config_route_v3_CorsPolicy_filter_enabled(msg);
@@ -1203,7 +1285,8 @@ UPB_INLINE struct envoy_config_core_v3_RuntimeFractionalPercent* envoy_config_ro
   return sub;
 }
 UPB_INLINE void envoy_config_route_v3_CorsPolicy_set_shadow_enabled(envoy_config_route_v3_CorsPolicy *msg, struct envoy_config_core_v3_RuntimeFractionalPercent* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(36, 72), struct envoy_config_core_v3_RuntimeFractionalPercent*) = value;
+  _upb_sethas(msg, 2);
+  *UPB_PTR_AT(msg, UPB_SIZE(40, 80), struct envoy_config_core_v3_RuntimeFractionalPercent*) = value;
 }
 UPB_INLINE struct envoy_config_core_v3_RuntimeFractionalPercent* envoy_config_route_v3_CorsPolicy_mutable_shadow_enabled(envoy_config_route_v3_CorsPolicy *msg, upb_arena *arena) {
   struct envoy_config_core_v3_RuntimeFractionalPercent* sub = (struct envoy_config_core_v3_RuntimeFractionalPercent*)envoy_config_route_v3_CorsPolicy_shadow_enabled(msg);
@@ -1215,15 +1298,15 @@ UPB_INLINE struct envoy_config_core_v3_RuntimeFractionalPercent* envoy_config_ro
   return sub;
 }
 UPB_INLINE struct envoy_type_matcher_v3_StringMatcher** envoy_config_route_v3_CorsPolicy_mutable_allow_origin_string_match(envoy_config_route_v3_CorsPolicy *msg, size_t *len) {
-  return (struct envoy_type_matcher_v3_StringMatcher**)_upb_array_mutable_accessor(msg, UPB_SIZE(40, 80), len);
+  return (struct envoy_type_matcher_v3_StringMatcher**)_upb_array_mutable_accessor(msg, UPB_SIZE(44, 88), len);
 }
 UPB_INLINE struct envoy_type_matcher_v3_StringMatcher** envoy_config_route_v3_CorsPolicy_resize_allow_origin_string_match(envoy_config_route_v3_CorsPolicy *msg, size_t len, upb_arena *arena) {
-  return (struct envoy_type_matcher_v3_StringMatcher**)_upb_array_resize_accessor(msg, UPB_SIZE(40, 80), len, UPB_TYPE_MESSAGE, arena);
+  return (struct envoy_type_matcher_v3_StringMatcher**)_upb_array_resize_accessor2(msg, UPB_SIZE(44, 88), len, UPB_SIZE(2, 3), arena);
 }
 UPB_INLINE struct envoy_type_matcher_v3_StringMatcher* envoy_config_route_v3_CorsPolicy_add_allow_origin_string_match(envoy_config_route_v3_CorsPolicy *msg, upb_arena *arena) {
   struct envoy_type_matcher_v3_StringMatcher* sub = (struct envoy_type_matcher_v3_StringMatcher*)_upb_msg_new(&envoy_type_matcher_v3_StringMatcher_msginit, arena);
-  bool ok = _upb_array_append_accessor(
-      msg, UPB_SIZE(40, 80), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena);
+  bool ok = _upb_array_append_accessor2(
+      msg, UPB_SIZE(44, 88), UPB_SIZE(2, 3), &sub, arena);
   if (!ok) return NULL;
   return sub;
 }
@@ -1238,6 +1321,12 @@ UPB_INLINE envoy_config_route_v3_RouteAction *envoy_config_route_v3_RouteAction_
   envoy_config_route_v3_RouteAction *ret = envoy_config_route_v3_RouteAction_new(arena);
   return (ret && upb_decode(buf, size, ret, &envoy_config_route_v3_RouteAction_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE envoy_config_route_v3_RouteAction *envoy_config_route_v3_RouteAction_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  envoy_config_route_v3_RouteAction *ret = envoy_config_route_v3_RouteAction_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &envoy_config_route_v3_RouteAction_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *envoy_config_route_v3_RouteAction_serialize(const envoy_config_route_v3_RouteAction *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &envoy_config_route_v3_RouteAction_msginit, arena, len);
 }
@@ -1248,7 +1337,7 @@ typedef enum {
   envoy_config_route_v3_RouteAction_cluster_specifier_weighted_clusters = 3,
   envoy_config_route_v3_RouteAction_cluster_specifier_NOT_SET = 0
 } envoy_config_route_v3_RouteAction_cluster_specifier_oneofcases;
-UPB_INLINE envoy_config_route_v3_RouteAction_cluster_specifier_oneofcases envoy_config_route_v3_RouteAction_cluster_specifier_case(const envoy_config_route_v3_RouteAction* msg) { return (envoy_config_route_v3_RouteAction_cluster_specifier_oneofcases)*UPB_PTR_AT(msg, UPB_SIZE(112, 200), int32_t); }
+UPB_INLINE envoy_config_route_v3_RouteAction_cluster_specifier_oneofcases envoy_config_route_v3_RouteAction_cluster_specifier_case(const envoy_config_route_v3_RouteAction* msg) { return (envoy_config_route_v3_RouteAction_cluster_specifier_oneofcases)*UPB_PTR_AT(msg, UPB_SIZE(104, 192), int32_t); }
 
 typedef enum {
   envoy_config_route_v3_RouteAction_host_rewrite_specifier_host_rewrite_literal = 6,
@@ -1257,71 +1346,71 @@ typedef enum {
   envoy_config_route_v3_RouteAction_host_rewrite_specifier_host_rewrite_path_regex = 35,
   envoy_config_route_v3_RouteAction_host_rewrite_specifier_NOT_SET = 0
 } envoy_config_route_v3_RouteAction_host_rewrite_specifier_oneofcases;
-UPB_INLINE envoy_config_route_v3_RouteAction_host_rewrite_specifier_oneofcases envoy_config_route_v3_RouteAction_host_rewrite_specifier_case(const envoy_config_route_v3_RouteAction* msg) { return (envoy_config_route_v3_RouteAction_host_rewrite_specifier_oneofcases)*UPB_PTR_AT(msg, UPB_SIZE(124, 224), int32_t); }
-
-UPB_INLINE bool envoy_config_route_v3_RouteAction_has_cluster(const envoy_config_route_v3_RouteAction *msg) { return _upb_getoneofcase(msg, UPB_SIZE(112, 200)) == 1; }
-UPB_INLINE upb_strview envoy_config_route_v3_RouteAction_cluster(const envoy_config_route_v3_RouteAction *msg) { return UPB_READ_ONEOF(msg, upb_strview, UPB_SIZE(104, 184), UPB_SIZE(112, 200), 1, upb_strview_make("", strlen(""))); }
-UPB_INLINE bool envoy_config_route_v3_RouteAction_has_cluster_header(const envoy_config_route_v3_RouteAction *msg) { return _upb_getoneofcase(msg, UPB_SIZE(112, 200)) == 2; }
-UPB_INLINE upb_strview envoy_config_route_v3_RouteAction_cluster_header(const envoy_config_route_v3_RouteAction *msg) { return UPB_READ_ONEOF(msg, upb_strview, UPB_SIZE(104, 184), UPB_SIZE(112, 200), 2, upb_strview_make("", strlen(""))); }
-UPB_INLINE bool envoy_config_route_v3_RouteAction_has_weighted_clusters(const envoy_config_route_v3_RouteAction *msg) { return _upb_getoneofcase(msg, UPB_SIZE(112, 200)) == 3; }
-UPB_INLINE const envoy_config_route_v3_WeightedCluster* envoy_config_route_v3_RouteAction_weighted_clusters(const envoy_config_route_v3_RouteAction *msg) { return UPB_READ_ONEOF(msg, const envoy_config_route_v3_WeightedCluster*, UPB_SIZE(104, 184), UPB_SIZE(112, 200), 3, NULL); }
-UPB_INLINE bool envoy_config_route_v3_RouteAction_has_metadata_match(const envoy_config_route_v3_RouteAction *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(32, 40)); }
-UPB_INLINE const struct envoy_config_core_v3_Metadata* envoy_config_route_v3_RouteAction_metadata_match(const envoy_config_route_v3_RouteAction *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(32, 40), const struct envoy_config_core_v3_Metadata*); }
-UPB_INLINE upb_strview envoy_config_route_v3_RouteAction_prefix_rewrite(const envoy_config_route_v3_RouteAction *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(24, 24), upb_strview); }
-UPB_INLINE bool envoy_config_route_v3_RouteAction_has_host_rewrite_literal(const envoy_config_route_v3_RouteAction *msg) { return _upb_getoneofcase(msg, UPB_SIZE(124, 224)) == 6; }
-UPB_INLINE upb_strview envoy_config_route_v3_RouteAction_host_rewrite_literal(const envoy_config_route_v3_RouteAction *msg) { return UPB_READ_ONEOF(msg, upb_strview, UPB_SIZE(116, 208), UPB_SIZE(124, 224), 6, upb_strview_make("", strlen(""))); }
-UPB_INLINE bool envoy_config_route_v3_RouteAction_has_auto_host_rewrite(const envoy_config_route_v3_RouteAction *msg) { return _upb_getoneofcase(msg, UPB_SIZE(124, 224)) == 7; }
-UPB_INLINE const struct google_protobuf_BoolValue* envoy_config_route_v3_RouteAction_auto_host_rewrite(const envoy_config_route_v3_RouteAction *msg) { return UPB_READ_ONEOF(msg, const struct google_protobuf_BoolValue*, UPB_SIZE(116, 208), UPB_SIZE(124, 224), 7, NULL); }
-UPB_INLINE bool envoy_config_route_v3_RouteAction_has_timeout(const envoy_config_route_v3_RouteAction *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(36, 48)); }
-UPB_INLINE const struct google_protobuf_Duration* envoy_config_route_v3_RouteAction_timeout(const envoy_config_route_v3_RouteAction *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(36, 48), const struct google_protobuf_Duration*); }
-UPB_INLINE bool envoy_config_route_v3_RouteAction_has_retry_policy(const envoy_config_route_v3_RouteAction *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(40, 56)); }
-UPB_INLINE const envoy_config_route_v3_RetryPolicy* envoy_config_route_v3_RouteAction_retry_policy(const envoy_config_route_v3_RouteAction *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(40, 56), const envoy_config_route_v3_RetryPolicy*); }
-UPB_INLINE int32_t envoy_config_route_v3_RouteAction_priority(const envoy_config_route_v3_RouteAction *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(0, 0), int32_t); }
-UPB_INLINE bool envoy_config_route_v3_RouteAction_has_rate_limits(const envoy_config_route_v3_RouteAction *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(88, 152)); }
-UPB_INLINE const envoy_config_route_v3_RateLimit* const* envoy_config_route_v3_RouteAction_rate_limits(const envoy_config_route_v3_RouteAction *msg, size_t *len) { return (const envoy_config_route_v3_RateLimit* const*)_upb_array_accessor(msg, UPB_SIZE(88, 152), len); }
-UPB_INLINE bool envoy_config_route_v3_RouteAction_has_include_vh_rate_limits(const envoy_config_route_v3_RouteAction *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(44, 64)); }
-UPB_INLINE const struct google_protobuf_BoolValue* envoy_config_route_v3_RouteAction_include_vh_rate_limits(const envoy_config_route_v3_RouteAction *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(44, 64), const struct google_protobuf_BoolValue*); }
-UPB_INLINE bool envoy_config_route_v3_RouteAction_has_hash_policy(const envoy_config_route_v3_RouteAction *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(92, 160)); }
-UPB_INLINE const envoy_config_route_v3_RouteAction_HashPolicy* const* envoy_config_route_v3_RouteAction_hash_policy(const envoy_config_route_v3_RouteAction *msg, size_t *len) { return (const envoy_config_route_v3_RouteAction_HashPolicy* const*)_upb_array_accessor(msg, UPB_SIZE(92, 160), len); }
-UPB_INLINE bool envoy_config_route_v3_RouteAction_has_cors(const envoy_config_route_v3_RouteAction *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(48, 72)); }
-UPB_INLINE const envoy_config_route_v3_CorsPolicy* envoy_config_route_v3_RouteAction_cors(const envoy_config_route_v3_RouteAction *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(48, 72), const envoy_config_route_v3_CorsPolicy*); }
+UPB_INLINE envoy_config_route_v3_RouteAction_host_rewrite_specifier_oneofcases envoy_config_route_v3_RouteAction_host_rewrite_specifier_case(const envoy_config_route_v3_RouteAction* msg) { return (envoy_config_route_v3_RouteAction_host_rewrite_specifier_oneofcases)*UPB_PTR_AT(msg, UPB_SIZE(116, 216), int32_t); }
+
+UPB_INLINE bool envoy_config_route_v3_RouteAction_has_cluster(const envoy_config_route_v3_RouteAction *msg) { return _upb_getoneofcase(msg, UPB_SIZE(104, 192)) == 1; }
+UPB_INLINE upb_strview envoy_config_route_v3_RouteAction_cluster(const envoy_config_route_v3_RouteAction *msg) { return UPB_READ_ONEOF(msg, upb_strview, UPB_SIZE(96, 176), UPB_SIZE(104, 192), 1, upb_strview_make("", strlen(""))); }
+UPB_INLINE bool envoy_config_route_v3_RouteAction_has_cluster_header(const envoy_config_route_v3_RouteAction *msg) { return _upb_getoneofcase(msg, UPB_SIZE(104, 192)) == 2; }
+UPB_INLINE upb_strview envoy_config_route_v3_RouteAction_cluster_header(const envoy_config_route_v3_RouteAction *msg) { return UPB_READ_ONEOF(msg, upb_strview, UPB_SIZE(96, 176), UPB_SIZE(104, 192), 2, upb_strview_make("", strlen(""))); }
+UPB_INLINE bool envoy_config_route_v3_RouteAction_has_weighted_clusters(const envoy_config_route_v3_RouteAction *msg) { return _upb_getoneofcase(msg, UPB_SIZE(104, 192)) == 3; }
+UPB_INLINE const envoy_config_route_v3_WeightedCluster* envoy_config_route_v3_RouteAction_weighted_clusters(const envoy_config_route_v3_RouteAction *msg) { return UPB_READ_ONEOF(msg, const envoy_config_route_v3_WeightedCluster*, UPB_SIZE(96, 176), UPB_SIZE(104, 192), 3, NULL); }
+UPB_INLINE bool envoy_config_route_v3_RouteAction_has_metadata_match(const envoy_config_route_v3_RouteAction *msg) { return _upb_hasbit(msg, 1); }
+UPB_INLINE const struct envoy_config_core_v3_Metadata* envoy_config_route_v3_RouteAction_metadata_match(const envoy_config_route_v3_RouteAction *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(24, 32), const struct envoy_config_core_v3_Metadata*); }
+UPB_INLINE upb_strview envoy_config_route_v3_RouteAction_prefix_rewrite(const envoy_config_route_v3_RouteAction *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(16, 16), upb_strview); }
+UPB_INLINE bool envoy_config_route_v3_RouteAction_has_host_rewrite_literal(const envoy_config_route_v3_RouteAction *msg) { return _upb_getoneofcase(msg, UPB_SIZE(116, 216)) == 6; }
+UPB_INLINE upb_strview envoy_config_route_v3_RouteAction_host_rewrite_literal(const envoy_config_route_v3_RouteAction *msg) { return UPB_READ_ONEOF(msg, upb_strview, UPB_SIZE(108, 200), UPB_SIZE(116, 216), 6, upb_strview_make("", strlen(""))); }
+UPB_INLINE bool envoy_config_route_v3_RouteAction_has_auto_host_rewrite(const envoy_config_route_v3_RouteAction *msg) { return _upb_getoneofcase(msg, UPB_SIZE(116, 216)) == 7; }
+UPB_INLINE const struct google_protobuf_BoolValue* envoy_config_route_v3_RouteAction_auto_host_rewrite(const envoy_config_route_v3_RouteAction *msg) { return UPB_READ_ONEOF(msg, const struct google_protobuf_BoolValue*, UPB_SIZE(108, 200), UPB_SIZE(116, 216), 7, NULL); }
+UPB_INLINE bool envoy_config_route_v3_RouteAction_has_timeout(const envoy_config_route_v3_RouteAction *msg) { return _upb_hasbit(msg, 2); }
+UPB_INLINE const struct google_protobuf_Duration* envoy_config_route_v3_RouteAction_timeout(const envoy_config_route_v3_RouteAction *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(28, 40), const struct google_protobuf_Duration*); }
+UPB_INLINE bool envoy_config_route_v3_RouteAction_has_retry_policy(const envoy_config_route_v3_RouteAction *msg) { return _upb_hasbit(msg, 3); }
+UPB_INLINE const envoy_config_route_v3_RetryPolicy* envoy_config_route_v3_RouteAction_retry_policy(const envoy_config_route_v3_RouteAction *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(32, 48), const envoy_config_route_v3_RetryPolicy*); }
+UPB_INLINE int32_t envoy_config_route_v3_RouteAction_priority(const envoy_config_route_v3_RouteAction *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(4, 4), int32_t); }
+UPB_INLINE bool envoy_config_route_v3_RouteAction_has_rate_limits(const envoy_config_route_v3_RouteAction *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(80, 144)); }
+UPB_INLINE const envoy_config_route_v3_RateLimit* const* envoy_config_route_v3_RouteAction_rate_limits(const envoy_config_route_v3_RouteAction *msg, size_t *len) { return (const envoy_config_route_v3_RateLimit* const*)_upb_array_accessor(msg, UPB_SIZE(80, 144), len); }
+UPB_INLINE bool envoy_config_route_v3_RouteAction_has_include_vh_rate_limits(const envoy_config_route_v3_RouteAction *msg) { return _upb_hasbit(msg, 4); }
+UPB_INLINE const struct google_protobuf_BoolValue* envoy_config_route_v3_RouteAction_include_vh_rate_limits(const envoy_config_route_v3_RouteAction *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(36, 56), const struct google_protobuf_BoolValue*); }
+UPB_INLINE bool envoy_config_route_v3_RouteAction_has_hash_policy(const envoy_config_route_v3_RouteAction *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(84, 152)); }
+UPB_INLINE const envoy_config_route_v3_RouteAction_HashPolicy* const* envoy_config_route_v3_RouteAction_hash_policy(const envoy_config_route_v3_RouteAction *msg, size_t *len) { return (const envoy_config_route_v3_RouteAction_HashPolicy* const*)_upb_array_accessor(msg, UPB_SIZE(84, 152), len); }
+UPB_INLINE bool envoy_config_route_v3_RouteAction_has_cors(const envoy_config_route_v3_RouteAction *msg) { return _upb_hasbit(msg, 5); }
+UPB_INLINE const envoy_config_route_v3_CorsPolicy* envoy_config_route_v3_RouteAction_cors(const envoy_config_route_v3_RouteAction *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(40, 64), const envoy_config_route_v3_CorsPolicy*); }
 UPB_INLINE int32_t envoy_config_route_v3_RouteAction_cluster_not_found_response_code(const envoy_config_route_v3_RouteAction *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(8, 8), int32_t); }
-UPB_INLINE bool envoy_config_route_v3_RouteAction_has_max_grpc_timeout(const envoy_config_route_v3_RouteAction *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(52, 80)); }
-UPB_INLINE const struct google_protobuf_Duration* envoy_config_route_v3_RouteAction_max_grpc_timeout(const envoy_config_route_v3_RouteAction *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(52, 80), const struct google_protobuf_Duration*); }
-UPB_INLINE bool envoy_config_route_v3_RouteAction_has_idle_timeout(const envoy_config_route_v3_RouteAction *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(56, 88)); }
-UPB_INLINE const struct google_protobuf_Duration* envoy_config_route_v3_RouteAction_idle_timeout(const envoy_config_route_v3_RouteAction *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(56, 88), const struct google_protobuf_Duration*); }
-UPB_INLINE bool envoy_config_route_v3_RouteAction_has_upgrade_configs(const envoy_config_route_v3_RouteAction *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(96, 168)); }
-UPB_INLINE const envoy_config_route_v3_RouteAction_UpgradeConfig* const* envoy_config_route_v3_RouteAction_upgrade_configs(const envoy_config_route_v3_RouteAction *msg, size_t *len) { return (const envoy_config_route_v3_RouteAction_UpgradeConfig* const*)_upb_array_accessor(msg, UPB_SIZE(96, 168), len); }
-UPB_INLINE int32_t envoy_config_route_v3_RouteAction_internal_redirect_action(const envoy_config_route_v3_RouteAction *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(16, 16), int32_t); }
-UPB_INLINE bool envoy_config_route_v3_RouteAction_has_hedge_policy(const envoy_config_route_v3_RouteAction *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(60, 96)); }
-UPB_INLINE const envoy_config_route_v3_HedgePolicy* envoy_config_route_v3_RouteAction_hedge_policy(const envoy_config_route_v3_RouteAction *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(60, 96), const envoy_config_route_v3_HedgePolicy*); }
-UPB_INLINE bool envoy_config_route_v3_RouteAction_has_grpc_timeout_offset(const envoy_config_route_v3_RouteAction *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(64, 104)); }
-UPB_INLINE const struct google_protobuf_Duration* envoy_config_route_v3_RouteAction_grpc_timeout_offset(const envoy_config_route_v3_RouteAction *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(64, 104), const struct google_protobuf_Duration*); }
-UPB_INLINE bool envoy_config_route_v3_RouteAction_has_host_rewrite_header(const envoy_config_route_v3_RouteAction *msg) { return _upb_getoneofcase(msg, UPB_SIZE(124, 224)) == 29; }
-UPB_INLINE upb_strview envoy_config_route_v3_RouteAction_host_rewrite_header(const envoy_config_route_v3_RouteAction *msg) { return UPB_READ_ONEOF(msg, upb_strview, UPB_SIZE(116, 208), UPB_SIZE(124, 224), 29, upb_strview_make("", strlen(""))); }
-UPB_INLINE bool envoy_config_route_v3_RouteAction_has_request_mirror_policies(const envoy_config_route_v3_RouteAction *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(100, 176)); }
-UPB_INLINE const envoy_config_route_v3_RouteAction_RequestMirrorPolicy* const* envoy_config_route_v3_RouteAction_request_mirror_policies(const envoy_config_route_v3_RouteAction *msg, size_t *len) { return (const envoy_config_route_v3_RouteAction_RequestMirrorPolicy* const*)_upb_array_accessor(msg, UPB_SIZE(100, 176), len); }
-UPB_INLINE bool envoy_config_route_v3_RouteAction_has_max_internal_redirects(const envoy_config_route_v3_RouteAction *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(68, 112)); }
-UPB_INLINE const struct google_protobuf_UInt32Value* envoy_config_route_v3_RouteAction_max_internal_redirects(const envoy_config_route_v3_RouteAction *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(68, 112), const struct google_protobuf_UInt32Value*); }
-UPB_INLINE bool envoy_config_route_v3_RouteAction_has_regex_rewrite(const envoy_config_route_v3_RouteAction *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(72, 120)); }
-UPB_INLINE const struct envoy_type_matcher_v3_RegexMatchAndSubstitute* envoy_config_route_v3_RouteAction_regex_rewrite(const envoy_config_route_v3_RouteAction *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(72, 120), const struct envoy_type_matcher_v3_RegexMatchAndSubstitute*); }
-UPB_INLINE bool envoy_config_route_v3_RouteAction_has_retry_policy_typed_config(const envoy_config_route_v3_RouteAction *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(76, 128)); }
-UPB_INLINE const struct google_protobuf_Any* envoy_config_route_v3_RouteAction_retry_policy_typed_config(const envoy_config_route_v3_RouteAction *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(76, 128), const struct google_protobuf_Any*); }
-UPB_INLINE bool envoy_config_route_v3_RouteAction_has_internal_redirect_policy(const envoy_config_route_v3_RouteAction *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(80, 136)); }
-UPB_INLINE const envoy_config_route_v3_InternalRedirectPolicy* envoy_config_route_v3_RouteAction_internal_redirect_policy(const envoy_config_route_v3_RouteAction *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(80, 136), const envoy_config_route_v3_InternalRedirectPolicy*); }
-UPB_INLINE bool envoy_config_route_v3_RouteAction_has_host_rewrite_path_regex(const envoy_config_route_v3_RouteAction *msg) { return _upb_getoneofcase(msg, UPB_SIZE(124, 224)) == 35; }
-UPB_INLINE const struct envoy_type_matcher_v3_RegexMatchAndSubstitute* envoy_config_route_v3_RouteAction_host_rewrite_path_regex(const envoy_config_route_v3_RouteAction *msg) { return UPB_READ_ONEOF(msg, const struct envoy_type_matcher_v3_RegexMatchAndSubstitute*, UPB_SIZE(116, 208), UPB_SIZE(124, 224), 35, NULL); }
-UPB_INLINE bool envoy_config_route_v3_RouteAction_has_max_stream_duration(const envoy_config_route_v3_RouteAction *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(84, 144)); }
-UPB_INLINE const envoy_config_route_v3_RouteAction_MaxStreamDuration* envoy_config_route_v3_RouteAction_max_stream_duration(const envoy_config_route_v3_RouteAction *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(84, 144), const envoy_config_route_v3_RouteAction_MaxStreamDuration*); }
+UPB_INLINE bool envoy_config_route_v3_RouteAction_has_max_grpc_timeout(const envoy_config_route_v3_RouteAction *msg) { return _upb_hasbit(msg, 6); }
+UPB_INLINE const struct google_protobuf_Duration* envoy_config_route_v3_RouteAction_max_grpc_timeout(const envoy_config_route_v3_RouteAction *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(44, 72), const struct google_protobuf_Duration*); }
+UPB_INLINE bool envoy_config_route_v3_RouteAction_has_idle_timeout(const envoy_config_route_v3_RouteAction *msg) { return _upb_hasbit(msg, 7); }
+UPB_INLINE const struct google_protobuf_Duration* envoy_config_route_v3_RouteAction_idle_timeout(const envoy_config_route_v3_RouteAction *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(48, 80), const struct google_protobuf_Duration*); }
+UPB_INLINE bool envoy_config_route_v3_RouteAction_has_upgrade_configs(const envoy_config_route_v3_RouteAction *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(88, 160)); }
+UPB_INLINE const envoy_config_route_v3_RouteAction_UpgradeConfig* const* envoy_config_route_v3_RouteAction_upgrade_configs(const envoy_config_route_v3_RouteAction *msg, size_t *len) { return (const envoy_config_route_v3_RouteAction_UpgradeConfig* const*)_upb_array_accessor(msg, UPB_SIZE(88, 160), len); }
+UPB_INLINE int32_t envoy_config_route_v3_RouteAction_internal_redirect_action(const envoy_config_route_v3_RouteAction *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(12, 12), int32_t); }
+UPB_INLINE bool envoy_config_route_v3_RouteAction_has_hedge_policy(const envoy_config_route_v3_RouteAction *msg) { return _upb_hasbit(msg, 8); }
+UPB_INLINE const envoy_config_route_v3_HedgePolicy* envoy_config_route_v3_RouteAction_hedge_policy(const envoy_config_route_v3_RouteAction *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(52, 88), const envoy_config_route_v3_HedgePolicy*); }
+UPB_INLINE bool envoy_config_route_v3_RouteAction_has_grpc_timeout_offset(const envoy_config_route_v3_RouteAction *msg) { return _upb_hasbit(msg, 9); }
+UPB_INLINE const struct google_protobuf_Duration* envoy_config_route_v3_RouteAction_grpc_timeout_offset(const envoy_config_route_v3_RouteAction *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(56, 96), const struct google_protobuf_Duration*); }
+UPB_INLINE bool envoy_config_route_v3_RouteAction_has_host_rewrite_header(const envoy_config_route_v3_RouteAction *msg) { return _upb_getoneofcase(msg, UPB_SIZE(116, 216)) == 29; }
+UPB_INLINE upb_strview envoy_config_route_v3_RouteAction_host_rewrite_header(const envoy_config_route_v3_RouteAction *msg) { return UPB_READ_ONEOF(msg, upb_strview, UPB_SIZE(108, 200), UPB_SIZE(116, 216), 29, upb_strview_make("", strlen(""))); }
+UPB_INLINE bool envoy_config_route_v3_RouteAction_has_request_mirror_policies(const envoy_config_route_v3_RouteAction *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(92, 168)); }
+UPB_INLINE const envoy_config_route_v3_RouteAction_RequestMirrorPolicy* const* envoy_config_route_v3_RouteAction_request_mirror_policies(const envoy_config_route_v3_RouteAction *msg, size_t *len) { return (const envoy_config_route_v3_RouteAction_RequestMirrorPolicy* const*)_upb_array_accessor(msg, UPB_SIZE(92, 168), len); }
+UPB_INLINE bool envoy_config_route_v3_RouteAction_has_max_internal_redirects(const envoy_config_route_v3_RouteAction *msg) { return _upb_hasbit(msg, 10); }
+UPB_INLINE const struct google_protobuf_UInt32Value* envoy_config_route_v3_RouteAction_max_internal_redirects(const envoy_config_route_v3_RouteAction *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(60, 104), const struct google_protobuf_UInt32Value*); }
+UPB_INLINE bool envoy_config_route_v3_RouteAction_has_regex_rewrite(const envoy_config_route_v3_RouteAction *msg) { return _upb_hasbit(msg, 11); }
+UPB_INLINE const struct envoy_type_matcher_v3_RegexMatchAndSubstitute* envoy_config_route_v3_RouteAction_regex_rewrite(const envoy_config_route_v3_RouteAction *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(64, 112), const struct envoy_type_matcher_v3_RegexMatchAndSubstitute*); }
+UPB_INLINE bool envoy_config_route_v3_RouteAction_has_retry_policy_typed_config(const envoy_config_route_v3_RouteAction *msg) { return _upb_hasbit(msg, 12); }
+UPB_INLINE const struct google_protobuf_Any* envoy_config_route_v3_RouteAction_retry_policy_typed_config(const envoy_config_route_v3_RouteAction *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(68, 120), const struct google_protobuf_Any*); }
+UPB_INLINE bool envoy_config_route_v3_RouteAction_has_internal_redirect_policy(const envoy_config_route_v3_RouteAction *msg) { return _upb_hasbit(msg, 13); }
+UPB_INLINE const envoy_config_route_v3_InternalRedirectPolicy* envoy_config_route_v3_RouteAction_internal_redirect_policy(const envoy_config_route_v3_RouteAction *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(72, 128), const envoy_config_route_v3_InternalRedirectPolicy*); }
+UPB_INLINE bool envoy_config_route_v3_RouteAction_has_host_rewrite_path_regex(const envoy_config_route_v3_RouteAction *msg) { return _upb_getoneofcase(msg, UPB_SIZE(116, 216)) == 35; }
+UPB_INLINE const struct envoy_type_matcher_v3_RegexMatchAndSubstitute* envoy_config_route_v3_RouteAction_host_rewrite_path_regex(const envoy_config_route_v3_RouteAction *msg) { return UPB_READ_ONEOF(msg, const struct envoy_type_matcher_v3_RegexMatchAndSubstitute*, UPB_SIZE(108, 200), UPB_SIZE(116, 216), 35, NULL); }
+UPB_INLINE bool envoy_config_route_v3_RouteAction_has_max_stream_duration(const envoy_config_route_v3_RouteAction *msg) { return _upb_hasbit(msg, 14); }
+UPB_INLINE const envoy_config_route_v3_RouteAction_MaxStreamDuration* envoy_config_route_v3_RouteAction_max_stream_duration(const envoy_config_route_v3_RouteAction *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(76, 136), const envoy_config_route_v3_RouteAction_MaxStreamDuration*); }
 
 UPB_INLINE void envoy_config_route_v3_RouteAction_set_cluster(envoy_config_route_v3_RouteAction *msg, upb_strview value) {
-  UPB_WRITE_ONEOF(msg, upb_strview, UPB_SIZE(104, 184), value, UPB_SIZE(112, 200), 1);
+  UPB_WRITE_ONEOF(msg, upb_strview, UPB_SIZE(96, 176), value, UPB_SIZE(104, 192), 1);
 }
 UPB_INLINE void envoy_config_route_v3_RouteAction_set_cluster_header(envoy_config_route_v3_RouteAction *msg, upb_strview value) {
-  UPB_WRITE_ONEOF(msg, upb_strview, UPB_SIZE(104, 184), value, UPB_SIZE(112, 200), 2);
+  UPB_WRITE_ONEOF(msg, upb_strview, UPB_SIZE(96, 176), value, UPB_SIZE(104, 192), 2);
 }
 UPB_INLINE void envoy_config_route_v3_RouteAction_set_weighted_clusters(envoy_config_route_v3_RouteAction *msg, envoy_config_route_v3_WeightedCluster* value) {
-  UPB_WRITE_ONEOF(msg, envoy_config_route_v3_WeightedCluster*, UPB_SIZE(104, 184), value, UPB_SIZE(112, 200), 3);
+  UPB_WRITE_ONEOF(msg, envoy_config_route_v3_WeightedCluster*, UPB_SIZE(96, 176), value, UPB_SIZE(104, 192), 3);
 }
 UPB_INLINE struct envoy_config_route_v3_WeightedCluster* envoy_config_route_v3_RouteAction_mutable_weighted_clusters(envoy_config_route_v3_RouteAction *msg, upb_arena *arena) {
   struct envoy_config_route_v3_WeightedCluster* sub = (struct envoy_config_route_v3_WeightedCluster*)envoy_config_route_v3_RouteAction_weighted_clusters(msg);
@@ -1333,7 +1422,8 @@ UPB_INLINE struct envoy_config_route_v3_WeightedCluster* envoy_config_route_v3_R
   return sub;
 }
 UPB_INLINE void envoy_config_route_v3_RouteAction_set_metadata_match(envoy_config_route_v3_RouteAction *msg, struct envoy_config_core_v3_Metadata* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(32, 40), struct envoy_config_core_v3_Metadata*) = value;
+  _upb_sethas(msg, 1);
+  *UPB_PTR_AT(msg, UPB_SIZE(24, 32), struct envoy_config_core_v3_Metadata*) = value;
 }
 UPB_INLINE struct envoy_config_core_v3_Metadata* envoy_config_route_v3_RouteAction_mutable_metadata_match(envoy_config_route_v3_RouteAction *msg, upb_arena *arena) {
   struct envoy_config_core_v3_Metadata* sub = (struct envoy_config_core_v3_Metadata*)envoy_config_route_v3_RouteAction_metadata_match(msg);
@@ -1345,13 +1435,13 @@ UPB_INLINE struct envoy_config_core_v3_Metadata* envoy_config_route_v3_RouteActi
   return sub;
 }
 UPB_INLINE void envoy_config_route_v3_RouteAction_set_prefix_rewrite(envoy_config_route_v3_RouteAction *msg, upb_strview value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(24, 24), upb_strview) = value;
+  *UPB_PTR_AT(msg, UPB_SIZE(16, 16), upb_strview) = value;
 }
 UPB_INLINE void envoy_config_route_v3_RouteAction_set_host_rewrite_literal(envoy_config_route_v3_RouteAction *msg, upb_strview value) {
-  UPB_WRITE_ONEOF(msg, upb_strview, UPB_SIZE(116, 208), value, UPB_SIZE(124, 224), 6);
+  UPB_WRITE_ONEOF(msg, upb_strview, UPB_SIZE(108, 200), value, UPB_SIZE(116, 216), 6);
 }
 UPB_INLINE void envoy_config_route_v3_RouteAction_set_auto_host_rewrite(envoy_config_route_v3_RouteAction *msg, struct google_protobuf_BoolValue* value) {
-  UPB_WRITE_ONEOF(msg, struct google_protobuf_BoolValue*, UPB_SIZE(116, 208), value, UPB_SIZE(124, 224), 7);
+  UPB_WRITE_ONEOF(msg, struct google_protobuf_BoolValue*, UPB_SIZE(108, 200), value, UPB_SIZE(116, 216), 7);
 }
 UPB_INLINE struct google_protobuf_BoolValue* envoy_config_route_v3_RouteAction_mutable_auto_host_rewrite(envoy_config_route_v3_RouteAction *msg, upb_arena *arena) {
   struct google_protobuf_BoolValue* sub = (struct google_protobuf_BoolValue*)envoy_config_route_v3_RouteAction_auto_host_rewrite(msg);
@@ -1363,7 +1453,8 @@ UPB_INLINE struct google_protobuf_BoolValue* envoy_config_route_v3_RouteAction_m
   return sub;
 }
 UPB_INLINE void envoy_config_route_v3_RouteAction_set_timeout(envoy_config_route_v3_RouteAction *msg, struct google_protobuf_Duration* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(36, 48), struct google_protobuf_Duration*) = value;
+  _upb_sethas(msg, 2);
+  *UPB_PTR_AT(msg, UPB_SIZE(28, 40), struct google_protobuf_Duration*) = value;
 }
 UPB_INLINE struct google_protobuf_Duration* envoy_config_route_v3_RouteAction_mutable_timeout(envoy_config_route_v3_RouteAction *msg, upb_arena *arena) {
   struct google_protobuf_Duration* sub = (struct google_protobuf_Duration*)envoy_config_route_v3_RouteAction_timeout(msg);
@@ -1375,7 +1466,8 @@ UPB_INLINE struct google_protobuf_Duration* envoy_config_route_v3_RouteAction_mu
   return sub;
 }
 UPB_INLINE void envoy_config_route_v3_RouteAction_set_retry_policy(envoy_config_route_v3_RouteAction *msg, envoy_config_route_v3_RetryPolicy* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(40, 56), envoy_config_route_v3_RetryPolicy*) = value;
+  _upb_sethas(msg, 3);
+  *UPB_PTR_AT(msg, UPB_SIZE(32, 48), envoy_config_route_v3_RetryPolicy*) = value;
 }
 UPB_INLINE struct envoy_config_route_v3_RetryPolicy* envoy_config_route_v3_RouteAction_mutable_retry_policy(envoy_config_route_v3_RouteAction *msg, upb_arena *arena) {
   struct envoy_config_route_v3_RetryPolicy* sub = (struct envoy_config_route_v3_RetryPolicy*)envoy_config_route_v3_RouteAction_retry_policy(msg);
@@ -1387,23 +1479,24 @@ UPB_INLINE struct envoy_config_route_v3_RetryPolicy* envoy_config_route_v3_Route
   return sub;
 }
 UPB_INLINE void envoy_config_route_v3_RouteAction_set_priority(envoy_config_route_v3_RouteAction *msg, int32_t value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(0, 0), int32_t) = value;
+  *UPB_PTR_AT(msg, UPB_SIZE(4, 4), int32_t) = value;
 }
 UPB_INLINE envoy_config_route_v3_RateLimit** envoy_config_route_v3_RouteAction_mutable_rate_limits(envoy_config_route_v3_RouteAction *msg, size_t *len) {
-  return (envoy_config_route_v3_RateLimit**)_upb_array_mutable_accessor(msg, UPB_SIZE(88, 152), len);
+  return (envoy_config_route_v3_RateLimit**)_upb_array_mutable_accessor(msg, UPB_SIZE(80, 144), len);
 }
 UPB_INLINE envoy_config_route_v3_RateLimit** envoy_config_route_v3_RouteAction_resize_rate_limits(envoy_config_route_v3_RouteAction *msg, size_t len, upb_arena *arena) {
-  return (envoy_config_route_v3_RateLimit**)_upb_array_resize_accessor(msg, UPB_SIZE(88, 152), len, UPB_TYPE_MESSAGE, arena);
+  return (envoy_config_route_v3_RateLimit**)_upb_array_resize_accessor2(msg, UPB_SIZE(80, 144), len, UPB_SIZE(2, 3), arena);
 }
 UPB_INLINE struct envoy_config_route_v3_RateLimit* envoy_config_route_v3_RouteAction_add_rate_limits(envoy_config_route_v3_RouteAction *msg, upb_arena *arena) {
   struct envoy_config_route_v3_RateLimit* sub = (struct envoy_config_route_v3_RateLimit*)_upb_msg_new(&envoy_config_route_v3_RateLimit_msginit, arena);
-  bool ok = _upb_array_append_accessor(
-      msg, UPB_SIZE(88, 152), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena);
+  bool ok = _upb_array_append_accessor2(
+      msg, UPB_SIZE(80, 144), UPB_SIZE(2, 3), &sub, arena);
   if (!ok) return NULL;
   return sub;
 }
 UPB_INLINE void envoy_config_route_v3_RouteAction_set_include_vh_rate_limits(envoy_config_route_v3_RouteAction *msg, struct google_protobuf_BoolValue* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(44, 64), struct google_protobuf_BoolValue*) = value;
+  _upb_sethas(msg, 4);
+  *UPB_PTR_AT(msg, UPB_SIZE(36, 56), struct google_protobuf_BoolValue*) = value;
 }
 UPB_INLINE struct google_protobuf_BoolValue* envoy_config_route_v3_RouteAction_mutable_include_vh_rate_limits(envoy_config_route_v3_RouteAction *msg, upb_arena *arena) {
   struct google_protobuf_BoolValue* sub = (struct google_protobuf_BoolValue*)envoy_config_route_v3_RouteAction_include_vh_rate_limits(msg);
@@ -1415,20 +1508,21 @@ UPB_INLINE struct google_protobuf_BoolValue* envoy_config_route_v3_RouteAction_m
   return sub;
 }
 UPB_INLINE envoy_config_route_v3_RouteAction_HashPolicy** envoy_config_route_v3_RouteAction_mutable_hash_policy(envoy_config_route_v3_RouteAction *msg, size_t *len) {
-  return (envoy_config_route_v3_RouteAction_HashPolicy**)_upb_array_mutable_accessor(msg, UPB_SIZE(92, 160), len);
+  return (envoy_config_route_v3_RouteAction_HashPolicy**)_upb_array_mutable_accessor(msg, UPB_SIZE(84, 152), len);
 }
 UPB_INLINE envoy_config_route_v3_RouteAction_HashPolicy** envoy_config_route_v3_RouteAction_resize_hash_policy(envoy_config_route_v3_RouteAction *msg, size_t len, upb_arena *arena) {
-  return (envoy_config_route_v3_RouteAction_HashPolicy**)_upb_array_resize_accessor(msg, UPB_SIZE(92, 160), len, UPB_TYPE_MESSAGE, arena);
+  return (envoy_config_route_v3_RouteAction_HashPolicy**)_upb_array_resize_accessor2(msg, UPB_SIZE(84, 152), len, UPB_SIZE(2, 3), arena);
 }
 UPB_INLINE struct envoy_config_route_v3_RouteAction_HashPolicy* envoy_config_route_v3_RouteAction_add_hash_policy(envoy_config_route_v3_RouteAction *msg, upb_arena *arena) {
   struct envoy_config_route_v3_RouteAction_HashPolicy* sub = (struct envoy_config_route_v3_RouteAction_HashPolicy*)_upb_msg_new(&envoy_config_route_v3_RouteAction_HashPolicy_msginit, arena);
-  bool ok = _upb_array_append_accessor(
-      msg, UPB_SIZE(92, 160), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena);
+  bool ok = _upb_array_append_accessor2(
+      msg, UPB_SIZE(84, 152), UPB_SIZE(2, 3), &sub, arena);
   if (!ok) return NULL;
   return sub;
 }
 UPB_INLINE void envoy_config_route_v3_RouteAction_set_cors(envoy_config_route_v3_RouteAction *msg, envoy_config_route_v3_CorsPolicy* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(48, 72), envoy_config_route_v3_CorsPolicy*) = value;
+  _upb_sethas(msg, 5);
+  *UPB_PTR_AT(msg, UPB_SIZE(40, 64), envoy_config_route_v3_CorsPolicy*) = value;
 }
 UPB_INLINE struct envoy_config_route_v3_CorsPolicy* envoy_config_route_v3_RouteAction_mutable_cors(envoy_config_route_v3_RouteAction *msg, upb_arena *arena) {
   struct envoy_config_route_v3_CorsPolicy* sub = (struct envoy_config_route_v3_CorsPolicy*)envoy_config_route_v3_RouteAction_cors(msg);
@@ -1443,7 +1537,8 @@ UPB_INLINE void envoy_config_route_v3_RouteAction_set_cluster_not_found_response
   *UPB_PTR_AT(msg, UPB_SIZE(8, 8), int32_t) = value;
 }
 UPB_INLINE void envoy_config_route_v3_RouteAction_set_max_grpc_timeout(envoy_config_route_v3_RouteAction *msg, struct google_protobuf_Duration* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(52, 80), struct google_protobuf_Duration*) = value;
+  _upb_sethas(msg, 6);
+  *UPB_PTR_AT(msg, UPB_SIZE(44, 72), struct google_protobuf_Duration*) = value;
 }
 UPB_INLINE struct google_protobuf_Duration* envoy_config_route_v3_RouteAction_mutable_max_grpc_timeout(envoy_config_route_v3_RouteAction *msg, upb_arena *arena) {
   struct google_protobuf_Duration* sub = (struct google_protobuf_Duration*)envoy_config_route_v3_RouteAction_max_grpc_timeout(msg);
@@ -1455,7 +1550,8 @@ UPB_INLINE struct google_protobuf_Duration* envoy_config_route_v3_RouteAction_mu
   return sub;
 }
 UPB_INLINE void envoy_config_route_v3_RouteAction_set_idle_timeout(envoy_config_route_v3_RouteAction *msg, struct google_protobuf_Duration* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(56, 88), struct google_protobuf_Duration*) = value;
+  _upb_sethas(msg, 7);
+  *UPB_PTR_AT(msg, UPB_SIZE(48, 80), struct google_protobuf_Duration*) = value;
 }
 UPB_INLINE struct google_protobuf_Duration* envoy_config_route_v3_RouteAction_mutable_idle_timeout(envoy_config_route_v3_RouteAction *msg, upb_arena *arena) {
   struct google_protobuf_Duration* sub = (struct google_protobuf_Duration*)envoy_config_route_v3_RouteAction_idle_timeout(msg);
@@ -1467,23 +1563,24 @@ UPB_INLINE struct google_protobuf_Duration* envoy_config_route_v3_RouteAction_mu
   return sub;
 }
 UPB_INLINE envoy_config_route_v3_RouteAction_UpgradeConfig** envoy_config_route_v3_RouteAction_mutable_upgrade_configs(envoy_config_route_v3_RouteAction *msg, size_t *len) {
-  return (envoy_config_route_v3_RouteAction_UpgradeConfig**)_upb_array_mutable_accessor(msg, UPB_SIZE(96, 168), len);
+  return (envoy_config_route_v3_RouteAction_UpgradeConfig**)_upb_array_mutable_accessor(msg, UPB_SIZE(88, 160), len);
 }
 UPB_INLINE envoy_config_route_v3_RouteAction_UpgradeConfig** envoy_config_route_v3_RouteAction_resize_upgrade_configs(envoy_config_route_v3_RouteAction *msg, size_t len, upb_arena *arena) {
-  return (envoy_config_route_v3_RouteAction_UpgradeConfig**)_upb_array_resize_accessor(msg, UPB_SIZE(96, 168), len, UPB_TYPE_MESSAGE, arena);
+  return (envoy_config_route_v3_RouteAction_UpgradeConfig**)_upb_array_resize_accessor2(msg, UPB_SIZE(88, 160), len, UPB_SIZE(2, 3), arena);
 }
 UPB_INLINE struct envoy_config_route_v3_RouteAction_UpgradeConfig* envoy_config_route_v3_RouteAction_add_upgrade_configs(envoy_config_route_v3_RouteAction *msg, upb_arena *arena) {
   struct envoy_config_route_v3_RouteAction_UpgradeConfig* sub = (struct envoy_config_route_v3_RouteAction_UpgradeConfig*)_upb_msg_new(&envoy_config_route_v3_RouteAction_UpgradeConfig_msginit, arena);
-  bool ok = _upb_array_append_accessor(
-      msg, UPB_SIZE(96, 168), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena);
+  bool ok = _upb_array_append_accessor2(
+      msg, UPB_SIZE(88, 160), UPB_SIZE(2, 3), &sub, arena);
   if (!ok) return NULL;
   return sub;
 }
 UPB_INLINE void envoy_config_route_v3_RouteAction_set_internal_redirect_action(envoy_config_route_v3_RouteAction *msg, int32_t value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(16, 16), int32_t) = value;
+  *UPB_PTR_AT(msg, UPB_SIZE(12, 12), int32_t) = value;
 }
 UPB_INLINE void envoy_config_route_v3_RouteAction_set_hedge_policy(envoy_config_route_v3_RouteAction *msg, envoy_config_route_v3_HedgePolicy* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(60, 96), envoy_config_route_v3_HedgePolicy*) = value;
+  _upb_sethas(msg, 8);
+  *UPB_PTR_AT(msg, UPB_SIZE(52, 88), envoy_config_route_v3_HedgePolicy*) = value;
 }
 UPB_INLINE struct envoy_config_route_v3_HedgePolicy* envoy_config_route_v3_RouteAction_mutable_hedge_policy(envoy_config_route_v3_RouteAction *msg, upb_arena *arena) {
   struct envoy_config_route_v3_HedgePolicy* sub = (struct envoy_config_route_v3_HedgePolicy*)envoy_config_route_v3_RouteAction_hedge_policy(msg);
@@ -1495,7 +1592,8 @@ UPB_INLINE struct envoy_config_route_v3_HedgePolicy* envoy_config_route_v3_Route
   return sub;
 }
 UPB_INLINE void envoy_config_route_v3_RouteAction_set_grpc_timeout_offset(envoy_config_route_v3_RouteAction *msg, struct google_protobuf_Duration* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(64, 104), struct google_protobuf_Duration*) = value;
+  _upb_sethas(msg, 9);
+  *UPB_PTR_AT(msg, UPB_SIZE(56, 96), struct google_protobuf_Duration*) = value;
 }
 UPB_INLINE struct google_protobuf_Duration* envoy_config_route_v3_RouteAction_mutable_grpc_timeout_offset(envoy_config_route_v3_RouteAction *msg, upb_arena *arena) {
   struct google_protobuf_Duration* sub = (struct google_protobuf_Duration*)envoy_config_route_v3_RouteAction_grpc_timeout_offset(msg);
@@ -1507,23 +1605,24 @@ UPB_INLINE struct google_protobuf_Duration* envoy_config_route_v3_RouteAction_mu
   return sub;
 }
 UPB_INLINE void envoy_config_route_v3_RouteAction_set_host_rewrite_header(envoy_config_route_v3_RouteAction *msg, upb_strview value) {
-  UPB_WRITE_ONEOF(msg, upb_strview, UPB_SIZE(116, 208), value, UPB_SIZE(124, 224), 29);
+  UPB_WRITE_ONEOF(msg, upb_strview, UPB_SIZE(108, 200), value, UPB_SIZE(116, 216), 29);
 }
 UPB_INLINE envoy_config_route_v3_RouteAction_RequestMirrorPolicy** envoy_config_route_v3_RouteAction_mutable_request_mirror_policies(envoy_config_route_v3_RouteAction *msg, size_t *len) {
-  return (envoy_config_route_v3_RouteAction_RequestMirrorPolicy**)_upb_array_mutable_accessor(msg, UPB_SIZE(100, 176), len);
+  return (envoy_config_route_v3_RouteAction_RequestMirrorPolicy**)_upb_array_mutable_accessor(msg, UPB_SIZE(92, 168), len);
 }
 UPB_INLINE envoy_config_route_v3_RouteAction_RequestMirrorPolicy** envoy_config_route_v3_RouteAction_resize_request_mirror_policies(envoy_config_route_v3_RouteAction *msg, size_t len, upb_arena *arena) {
-  return (envoy_config_route_v3_RouteAction_RequestMirrorPolicy**)_upb_array_resize_accessor(msg, UPB_SIZE(100, 176), len, UPB_TYPE_MESSAGE, arena);
+  return (envoy_config_route_v3_RouteAction_RequestMirrorPolicy**)_upb_array_resize_accessor2(msg, UPB_SIZE(92, 168), len, UPB_SIZE(2, 3), arena);
 }
 UPB_INLINE struct envoy_config_route_v3_RouteAction_RequestMirrorPolicy* envoy_config_route_v3_RouteAction_add_request_mirror_policies(envoy_config_route_v3_RouteAction *msg, upb_arena *arena) {
   struct envoy_config_route_v3_RouteAction_RequestMirrorPolicy* sub = (struct envoy_config_route_v3_RouteAction_RequestMirrorPolicy*)_upb_msg_new(&envoy_config_route_v3_RouteAction_RequestMirrorPolicy_msginit, arena);
-  bool ok = _upb_array_append_accessor(
-      msg, UPB_SIZE(100, 176), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena);
+  bool ok = _upb_array_append_accessor2(
+      msg, UPB_SIZE(92, 168), UPB_SIZE(2, 3), &sub, arena);
   if (!ok) return NULL;
   return sub;
 }
 UPB_INLINE void envoy_config_route_v3_RouteAction_set_max_internal_redirects(envoy_config_route_v3_RouteAction *msg, struct google_protobuf_UInt32Value* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(68, 112), struct google_protobuf_UInt32Value*) = value;
+  _upb_sethas(msg, 10);
+  *UPB_PTR_AT(msg, UPB_SIZE(60, 104), struct google_protobuf_UInt32Value*) = value;
 }
 UPB_INLINE struct google_protobuf_UInt32Value* envoy_config_route_v3_RouteAction_mutable_max_internal_redirects(envoy_config_route_v3_RouteAction *msg, upb_arena *arena) {
   struct google_protobuf_UInt32Value* sub = (struct google_protobuf_UInt32Value*)envoy_config_route_v3_RouteAction_max_internal_redirects(msg);
@@ -1535,7 +1634,8 @@ UPB_INLINE struct google_protobuf_UInt32Value* envoy_config_route_v3_RouteAction
   return sub;
 }
 UPB_INLINE void envoy_config_route_v3_RouteAction_set_regex_rewrite(envoy_config_route_v3_RouteAction *msg, struct envoy_type_matcher_v3_RegexMatchAndSubstitute* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(72, 120), struct envoy_type_matcher_v3_RegexMatchAndSubstitute*) = value;
+  _upb_sethas(msg, 11);
+  *UPB_PTR_AT(msg, UPB_SIZE(64, 112), struct envoy_type_matcher_v3_RegexMatchAndSubstitute*) = value;
 }
 UPB_INLINE struct envoy_type_matcher_v3_RegexMatchAndSubstitute* envoy_config_route_v3_RouteAction_mutable_regex_rewrite(envoy_config_route_v3_RouteAction *msg, upb_arena *arena) {
   struct envoy_type_matcher_v3_RegexMatchAndSubstitute* sub = (struct envoy_type_matcher_v3_RegexMatchAndSubstitute*)envoy_config_route_v3_RouteAction_regex_rewrite(msg);
@@ -1547,7 +1647,8 @@ UPB_INLINE struct envoy_type_matcher_v3_RegexMatchAndSubstitute* envoy_config_ro
   return sub;
 }
 UPB_INLINE void envoy_config_route_v3_RouteAction_set_retry_policy_typed_config(envoy_config_route_v3_RouteAction *msg, struct google_protobuf_Any* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(76, 128), struct google_protobuf_Any*) = value;
+  _upb_sethas(msg, 12);
+  *UPB_PTR_AT(msg, UPB_SIZE(68, 120), struct google_protobuf_Any*) = value;
 }
 UPB_INLINE struct google_protobuf_Any* envoy_config_route_v3_RouteAction_mutable_retry_policy_typed_config(envoy_config_route_v3_RouteAction *msg, upb_arena *arena) {
   struct google_protobuf_Any* sub = (struct google_protobuf_Any*)envoy_config_route_v3_RouteAction_retry_policy_typed_config(msg);
@@ -1559,7 +1660,8 @@ UPB_INLINE struct google_protobuf_Any* envoy_config_route_v3_RouteAction_mutable
   return sub;
 }
 UPB_INLINE void envoy_config_route_v3_RouteAction_set_internal_redirect_policy(envoy_config_route_v3_RouteAction *msg, envoy_config_route_v3_InternalRedirectPolicy* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(80, 136), envoy_config_route_v3_InternalRedirectPolicy*) = value;
+  _upb_sethas(msg, 13);
+  *UPB_PTR_AT(msg, UPB_SIZE(72, 128), envoy_config_route_v3_InternalRedirectPolicy*) = value;
 }
 UPB_INLINE struct envoy_config_route_v3_InternalRedirectPolicy* envoy_config_route_v3_RouteAction_mutable_internal_redirect_policy(envoy_config_route_v3_RouteAction *msg, upb_arena *arena) {
   struct envoy_config_route_v3_InternalRedirectPolicy* sub = (struct envoy_config_route_v3_InternalRedirectPolicy*)envoy_config_route_v3_RouteAction_internal_redirect_policy(msg);
@@ -1571,7 +1673,7 @@ UPB_INLINE struct envoy_config_route_v3_InternalRedirectPolicy* envoy_config_rou
   return sub;
 }
 UPB_INLINE void envoy_config_route_v3_RouteAction_set_host_rewrite_path_regex(envoy_config_route_v3_RouteAction *msg, struct envoy_type_matcher_v3_RegexMatchAndSubstitute* value) {
-  UPB_WRITE_ONEOF(msg, struct envoy_type_matcher_v3_RegexMatchAndSubstitute*, UPB_SIZE(116, 208), value, UPB_SIZE(124, 224), 35);
+  UPB_WRITE_ONEOF(msg, struct envoy_type_matcher_v3_RegexMatchAndSubstitute*, UPB_SIZE(108, 200), value, UPB_SIZE(116, 216), 35);
 }
 UPB_INLINE struct envoy_type_matcher_v3_RegexMatchAndSubstitute* envoy_config_route_v3_RouteAction_mutable_host_rewrite_path_regex(envoy_config_route_v3_RouteAction *msg, upb_arena *arena) {
   struct envoy_type_matcher_v3_RegexMatchAndSubstitute* sub = (struct envoy_type_matcher_v3_RegexMatchAndSubstitute*)envoy_config_route_v3_RouteAction_host_rewrite_path_regex(msg);
@@ -1583,7 +1685,8 @@ UPB_INLINE struct envoy_type_matcher_v3_RegexMatchAndSubstitute* envoy_config_ro
   return sub;
 }
 UPB_INLINE void envoy_config_route_v3_RouteAction_set_max_stream_duration(envoy_config_route_v3_RouteAction *msg, envoy_config_route_v3_RouteAction_MaxStreamDuration* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(84, 144), envoy_config_route_v3_RouteAction_MaxStreamDuration*) = value;
+  _upb_sethas(msg, 14);
+  *UPB_PTR_AT(msg, UPB_SIZE(76, 136), envoy_config_route_v3_RouteAction_MaxStreamDuration*) = value;
 }
 UPB_INLINE struct envoy_config_route_v3_RouteAction_MaxStreamDuration* envoy_config_route_v3_RouteAction_mutable_max_stream_duration(envoy_config_route_v3_RouteAction *msg, upb_arena *arena) {
   struct envoy_config_route_v3_RouteAction_MaxStreamDuration* sub = (struct envoy_config_route_v3_RouteAction_MaxStreamDuration*)envoy_config_route_v3_RouteAction_max_stream_duration(msg);
@@ -1605,21 +1708,28 @@ UPB_INLINE envoy_config_route_v3_RouteAction_RequestMirrorPolicy *envoy_config_r
   envoy_config_route_v3_RouteAction_RequestMirrorPolicy *ret = envoy_config_route_v3_RouteAction_RequestMirrorPolicy_new(arena);
   return (ret && upb_decode(buf, size, ret, &envoy_config_route_v3_RouteAction_RequestMirrorPolicy_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE envoy_config_route_v3_RouteAction_RequestMirrorPolicy *envoy_config_route_v3_RouteAction_RequestMirrorPolicy_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  envoy_config_route_v3_RouteAction_RequestMirrorPolicy *ret = envoy_config_route_v3_RouteAction_RequestMirrorPolicy_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &envoy_config_route_v3_RouteAction_RequestMirrorPolicy_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *envoy_config_route_v3_RouteAction_RequestMirrorPolicy_serialize(const envoy_config_route_v3_RouteAction_RequestMirrorPolicy *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &envoy_config_route_v3_RouteAction_RequestMirrorPolicy_msginit, arena, len);
 }
 
-UPB_INLINE upb_strview envoy_config_route_v3_RouteAction_RequestMirrorPolicy_cluster(const envoy_config_route_v3_RouteAction_RequestMirrorPolicy *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(0, 0), upb_strview); }
-UPB_INLINE bool envoy_config_route_v3_RouteAction_RequestMirrorPolicy_has_runtime_fraction(const envoy_config_route_v3_RouteAction_RequestMirrorPolicy *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(8, 16)); }
-UPB_INLINE const struct envoy_config_core_v3_RuntimeFractionalPercent* envoy_config_route_v3_RouteAction_RequestMirrorPolicy_runtime_fraction(const envoy_config_route_v3_RouteAction_RequestMirrorPolicy *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(8, 16), const struct envoy_config_core_v3_RuntimeFractionalPercent*); }
-UPB_INLINE bool envoy_config_route_v3_RouteAction_RequestMirrorPolicy_has_trace_sampled(const envoy_config_route_v3_RouteAction_RequestMirrorPolicy *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(12, 24)); }
-UPB_INLINE const struct google_protobuf_BoolValue* envoy_config_route_v3_RouteAction_RequestMirrorPolicy_trace_sampled(const envoy_config_route_v3_RouteAction_RequestMirrorPolicy *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(12, 24), const struct google_protobuf_BoolValue*); }
+UPB_INLINE upb_strview envoy_config_route_v3_RouteAction_RequestMirrorPolicy_cluster(const envoy_config_route_v3_RouteAction_RequestMirrorPolicy *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(4, 8), upb_strview); }
+UPB_INLINE bool envoy_config_route_v3_RouteAction_RequestMirrorPolicy_has_runtime_fraction(const envoy_config_route_v3_RouteAction_RequestMirrorPolicy *msg) { return _upb_hasbit(msg, 1); }
+UPB_INLINE const struct envoy_config_core_v3_RuntimeFractionalPercent* envoy_config_route_v3_RouteAction_RequestMirrorPolicy_runtime_fraction(const envoy_config_route_v3_RouteAction_RequestMirrorPolicy *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(12, 24), const struct envoy_config_core_v3_RuntimeFractionalPercent*); }
+UPB_INLINE bool envoy_config_route_v3_RouteAction_RequestMirrorPolicy_has_trace_sampled(const envoy_config_route_v3_RouteAction_RequestMirrorPolicy *msg) { return _upb_hasbit(msg, 2); }
+UPB_INLINE const struct google_protobuf_BoolValue* envoy_config_route_v3_RouteAction_RequestMirrorPolicy_trace_sampled(const envoy_config_route_v3_RouteAction_RequestMirrorPolicy *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(16, 32), const struct google_protobuf_BoolValue*); }
 
 UPB_INLINE void envoy_config_route_v3_RouteAction_RequestMirrorPolicy_set_cluster(envoy_config_route_v3_RouteAction_RequestMirrorPolicy *msg, upb_strview value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(0, 0), upb_strview) = value;
+  *UPB_PTR_AT(msg, UPB_SIZE(4, 8), upb_strview) = value;
 }
 UPB_INLINE void envoy_config_route_v3_RouteAction_RequestMirrorPolicy_set_runtime_fraction(envoy_config_route_v3_RouteAction_RequestMirrorPolicy *msg, struct envoy_config_core_v3_RuntimeFractionalPercent* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(8, 16), struct envoy_config_core_v3_RuntimeFractionalPercent*) = value;
+  _upb_sethas(msg, 1);
+  *UPB_PTR_AT(msg, UPB_SIZE(12, 24), struct envoy_config_core_v3_RuntimeFractionalPercent*) = value;
 }
 UPB_INLINE struct envoy_config_core_v3_RuntimeFractionalPercent* envoy_config_route_v3_RouteAction_RequestMirrorPolicy_mutable_runtime_fraction(envoy_config_route_v3_RouteAction_RequestMirrorPolicy *msg, upb_arena *arena) {
   struct envoy_config_core_v3_RuntimeFractionalPercent* sub = (struct envoy_config_core_v3_RuntimeFractionalPercent*)envoy_config_route_v3_RouteAction_RequestMirrorPolicy_runtime_fraction(msg);
@@ -1631,7 +1741,8 @@ UPB_INLINE struct envoy_config_core_v3_RuntimeFractionalPercent* envoy_config_ro
   return sub;
 }
 UPB_INLINE void envoy_config_route_v3_RouteAction_RequestMirrorPolicy_set_trace_sampled(envoy_config_route_v3_RouteAction_RequestMirrorPolicy *msg, struct google_protobuf_BoolValue* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(12, 24), struct google_protobuf_BoolValue*) = value;
+  _upb_sethas(msg, 2);
+  *UPB_PTR_AT(msg, UPB_SIZE(16, 32), struct google_protobuf_BoolValue*) = value;
 }
 UPB_INLINE struct google_protobuf_BoolValue* envoy_config_route_v3_RouteAction_RequestMirrorPolicy_mutable_trace_sampled(envoy_config_route_v3_RouteAction_RequestMirrorPolicy *msg, upb_arena *arena) {
   struct google_protobuf_BoolValue* sub = (struct google_protobuf_BoolValue*)envoy_config_route_v3_RouteAction_RequestMirrorPolicy_trace_sampled(msg);
@@ -1653,6 +1764,12 @@ UPB_INLINE envoy_config_route_v3_RouteAction_HashPolicy *envoy_config_route_v3_R
   envoy_config_route_v3_RouteAction_HashPolicy *ret = envoy_config_route_v3_RouteAction_HashPolicy_new(arena);
   return (ret && upb_decode(buf, size, ret, &envoy_config_route_v3_RouteAction_HashPolicy_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE envoy_config_route_v3_RouteAction_HashPolicy *envoy_config_route_v3_RouteAction_HashPolicy_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  envoy_config_route_v3_RouteAction_HashPolicy *ret = envoy_config_route_v3_RouteAction_HashPolicy_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &envoy_config_route_v3_RouteAction_HashPolicy_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *envoy_config_route_v3_RouteAction_HashPolicy_serialize(const envoy_config_route_v3_RouteAction_HashPolicy *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &envoy_config_route_v3_RouteAction_HashPolicy_msginit, arena, len);
 }
@@ -1753,19 +1870,26 @@ UPB_INLINE envoy_config_route_v3_RouteAction_HashPolicy_Header *envoy_config_rou
   envoy_config_route_v3_RouteAction_HashPolicy_Header *ret = envoy_config_route_v3_RouteAction_HashPolicy_Header_new(arena);
   return (ret && upb_decode(buf, size, ret, &envoy_config_route_v3_RouteAction_HashPolicy_Header_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE envoy_config_route_v3_RouteAction_HashPolicy_Header *envoy_config_route_v3_RouteAction_HashPolicy_Header_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  envoy_config_route_v3_RouteAction_HashPolicy_Header *ret = envoy_config_route_v3_RouteAction_HashPolicy_Header_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &envoy_config_route_v3_RouteAction_HashPolicy_Header_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *envoy_config_route_v3_RouteAction_HashPolicy_Header_serialize(const envoy_config_route_v3_RouteAction_HashPolicy_Header *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &envoy_config_route_v3_RouteAction_HashPolicy_Header_msginit, arena, len);
 }
 
-UPB_INLINE upb_strview envoy_config_route_v3_RouteAction_HashPolicy_Header_header_name(const envoy_config_route_v3_RouteAction_HashPolicy_Header *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(0, 0), upb_strview); }
-UPB_INLINE bool envoy_config_route_v3_RouteAction_HashPolicy_Header_has_regex_rewrite(const envoy_config_route_v3_RouteAction_HashPolicy_Header *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(8, 16)); }
-UPB_INLINE const struct envoy_type_matcher_v3_RegexMatchAndSubstitute* envoy_config_route_v3_RouteAction_HashPolicy_Header_regex_rewrite(const envoy_config_route_v3_RouteAction_HashPolicy_Header *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(8, 16), const struct envoy_type_matcher_v3_RegexMatchAndSubstitute*); }
+UPB_INLINE upb_strview envoy_config_route_v3_RouteAction_HashPolicy_Header_header_name(const envoy_config_route_v3_RouteAction_HashPolicy_Header *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(4, 8), upb_strview); }
+UPB_INLINE bool envoy_config_route_v3_RouteAction_HashPolicy_Header_has_regex_rewrite(const envoy_config_route_v3_RouteAction_HashPolicy_Header *msg) { return _upb_hasbit(msg, 1); }
+UPB_INLINE const struct envoy_type_matcher_v3_RegexMatchAndSubstitute* envoy_config_route_v3_RouteAction_HashPolicy_Header_regex_rewrite(const envoy_config_route_v3_RouteAction_HashPolicy_Header *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(12, 24), const struct envoy_type_matcher_v3_RegexMatchAndSubstitute*); }
 
 UPB_INLINE void envoy_config_route_v3_RouteAction_HashPolicy_Header_set_header_name(envoy_config_route_v3_RouteAction_HashPolicy_Header *msg, upb_strview value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(0, 0), upb_strview) = value;
+  *UPB_PTR_AT(msg, UPB_SIZE(4, 8), upb_strview) = value;
 }
 UPB_INLINE void envoy_config_route_v3_RouteAction_HashPolicy_Header_set_regex_rewrite(envoy_config_route_v3_RouteAction_HashPolicy_Header *msg, struct envoy_type_matcher_v3_RegexMatchAndSubstitute* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(8, 16), struct envoy_type_matcher_v3_RegexMatchAndSubstitute*) = value;
+  _upb_sethas(msg, 1);
+  *UPB_PTR_AT(msg, UPB_SIZE(12, 24), struct envoy_type_matcher_v3_RegexMatchAndSubstitute*) = value;
 }
 UPB_INLINE struct envoy_type_matcher_v3_RegexMatchAndSubstitute* envoy_config_route_v3_RouteAction_HashPolicy_Header_mutable_regex_rewrite(envoy_config_route_v3_RouteAction_HashPolicy_Header *msg, upb_arena *arena) {
   struct envoy_type_matcher_v3_RegexMatchAndSubstitute* sub = (struct envoy_type_matcher_v3_RegexMatchAndSubstitute*)envoy_config_route_v3_RouteAction_HashPolicy_Header_regex_rewrite(msg);
@@ -1787,20 +1911,27 @@ UPB_INLINE envoy_config_route_v3_RouteAction_HashPolicy_Cookie *envoy_config_rou
   envoy_config_route_v3_RouteAction_HashPolicy_Cookie *ret = envoy_config_route_v3_RouteAction_HashPolicy_Cookie_new(arena);
   return (ret && upb_decode(buf, size, ret, &envoy_config_route_v3_RouteAction_HashPolicy_Cookie_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE envoy_config_route_v3_RouteAction_HashPolicy_Cookie *envoy_config_route_v3_RouteAction_HashPolicy_Cookie_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  envoy_config_route_v3_RouteAction_HashPolicy_Cookie *ret = envoy_config_route_v3_RouteAction_HashPolicy_Cookie_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &envoy_config_route_v3_RouteAction_HashPolicy_Cookie_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *envoy_config_route_v3_RouteAction_HashPolicy_Cookie_serialize(const envoy_config_route_v3_RouteAction_HashPolicy_Cookie *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &envoy_config_route_v3_RouteAction_HashPolicy_Cookie_msginit, arena, len);
 }
 
-UPB_INLINE upb_strview envoy_config_route_v3_RouteAction_HashPolicy_Cookie_name(const envoy_config_route_v3_RouteAction_HashPolicy_Cookie *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(0, 0), upb_strview); }
-UPB_INLINE bool envoy_config_route_v3_RouteAction_HashPolicy_Cookie_has_ttl(const envoy_config_route_v3_RouteAction_HashPolicy_Cookie *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(16, 32)); }
-UPB_INLINE const struct google_protobuf_Duration* envoy_config_route_v3_RouteAction_HashPolicy_Cookie_ttl(const envoy_config_route_v3_RouteAction_HashPolicy_Cookie *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(16, 32), const struct google_protobuf_Duration*); }
-UPB_INLINE upb_strview envoy_config_route_v3_RouteAction_HashPolicy_Cookie_path(const envoy_config_route_v3_RouteAction_HashPolicy_Cookie *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(8, 16), upb_strview); }
+UPB_INLINE upb_strview envoy_config_route_v3_RouteAction_HashPolicy_Cookie_name(const envoy_config_route_v3_RouteAction_HashPolicy_Cookie *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(4, 8), upb_strview); }
+UPB_INLINE bool envoy_config_route_v3_RouteAction_HashPolicy_Cookie_has_ttl(const envoy_config_route_v3_RouteAction_HashPolicy_Cookie *msg) { return _upb_hasbit(msg, 1); }
+UPB_INLINE const struct google_protobuf_Duration* envoy_config_route_v3_RouteAction_HashPolicy_Cookie_ttl(const envoy_config_route_v3_RouteAction_HashPolicy_Cookie *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(20, 40), const struct google_protobuf_Duration*); }
+UPB_INLINE upb_strview envoy_config_route_v3_RouteAction_HashPolicy_Cookie_path(const envoy_config_route_v3_RouteAction_HashPolicy_Cookie *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(12, 24), upb_strview); }
 
 UPB_INLINE void envoy_config_route_v3_RouteAction_HashPolicy_Cookie_set_name(envoy_config_route_v3_RouteAction_HashPolicy_Cookie *msg, upb_strview value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(0, 0), upb_strview) = value;
+  *UPB_PTR_AT(msg, UPB_SIZE(4, 8), upb_strview) = value;
 }
 UPB_INLINE void envoy_config_route_v3_RouteAction_HashPolicy_Cookie_set_ttl(envoy_config_route_v3_RouteAction_HashPolicy_Cookie *msg, struct google_protobuf_Duration* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(16, 32), struct google_protobuf_Duration*) = value;
+  _upb_sethas(msg, 1);
+  *UPB_PTR_AT(msg, UPB_SIZE(20, 40), struct google_protobuf_Duration*) = value;
 }
 UPB_INLINE struct google_protobuf_Duration* envoy_config_route_v3_RouteAction_HashPolicy_Cookie_mutable_ttl(envoy_config_route_v3_RouteAction_HashPolicy_Cookie *msg, upb_arena *arena) {
   struct google_protobuf_Duration* sub = (struct google_protobuf_Duration*)envoy_config_route_v3_RouteAction_HashPolicy_Cookie_ttl(msg);
@@ -1812,7 +1943,7 @@ UPB_INLINE struct google_protobuf_Duration* envoy_config_route_v3_RouteAction_Ha
   return sub;
 }
 UPB_INLINE void envoy_config_route_v3_RouteAction_HashPolicy_Cookie_set_path(envoy_config_route_v3_RouteAction_HashPolicy_Cookie *msg, upb_strview value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(8, 16), upb_strview) = value;
+  *UPB_PTR_AT(msg, UPB_SIZE(12, 24), upb_strview) = value;
 }
 
 /* envoy.config.route.v3.RouteAction.HashPolicy.ConnectionProperties */
@@ -1825,6 +1956,12 @@ UPB_INLINE envoy_config_route_v3_RouteAction_HashPolicy_ConnectionProperties *en
   envoy_config_route_v3_RouteAction_HashPolicy_ConnectionProperties *ret = envoy_config_route_v3_RouteAction_HashPolicy_ConnectionProperties_new(arena);
   return (ret && upb_decode(buf, size, ret, &envoy_config_route_v3_RouteAction_HashPolicy_ConnectionProperties_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE envoy_config_route_v3_RouteAction_HashPolicy_ConnectionProperties *envoy_config_route_v3_RouteAction_HashPolicy_ConnectionProperties_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  envoy_config_route_v3_RouteAction_HashPolicy_ConnectionProperties *ret = envoy_config_route_v3_RouteAction_HashPolicy_ConnectionProperties_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &envoy_config_route_v3_RouteAction_HashPolicy_ConnectionProperties_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *envoy_config_route_v3_RouteAction_HashPolicy_ConnectionProperties_serialize(const envoy_config_route_v3_RouteAction_HashPolicy_ConnectionProperties *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &envoy_config_route_v3_RouteAction_HashPolicy_ConnectionProperties_msginit, arena, len);
 }
@@ -1845,6 +1982,12 @@ UPB_INLINE envoy_config_route_v3_RouteAction_HashPolicy_QueryParameter *envoy_co
   envoy_config_route_v3_RouteAction_HashPolicy_QueryParameter *ret = envoy_config_route_v3_RouteAction_HashPolicy_QueryParameter_new(arena);
   return (ret && upb_decode(buf, size, ret, &envoy_config_route_v3_RouteAction_HashPolicy_QueryParameter_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE envoy_config_route_v3_RouteAction_HashPolicy_QueryParameter *envoy_config_route_v3_RouteAction_HashPolicy_QueryParameter_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  envoy_config_route_v3_RouteAction_HashPolicy_QueryParameter *ret = envoy_config_route_v3_RouteAction_HashPolicy_QueryParameter_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &envoy_config_route_v3_RouteAction_HashPolicy_QueryParameter_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *envoy_config_route_v3_RouteAction_HashPolicy_QueryParameter_serialize(const envoy_config_route_v3_RouteAction_HashPolicy_QueryParameter *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &envoy_config_route_v3_RouteAction_HashPolicy_QueryParameter_msginit, arena, len);
 }
@@ -1865,6 +2008,12 @@ UPB_INLINE envoy_config_route_v3_RouteAction_HashPolicy_FilterState *envoy_confi
   envoy_config_route_v3_RouteAction_HashPolicy_FilterState *ret = envoy_config_route_v3_RouteAction_HashPolicy_FilterState_new(arena);
   return (ret && upb_decode(buf, size, ret, &envoy_config_route_v3_RouteAction_HashPolicy_FilterState_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE envoy_config_route_v3_RouteAction_HashPolicy_FilterState *envoy_config_route_v3_RouteAction_HashPolicy_FilterState_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  envoy_config_route_v3_RouteAction_HashPolicy_FilterState *ret = envoy_config_route_v3_RouteAction_HashPolicy_FilterState_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &envoy_config_route_v3_RouteAction_HashPolicy_FilterState_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *envoy_config_route_v3_RouteAction_HashPolicy_FilterState_serialize(const envoy_config_route_v3_RouteAction_HashPolicy_FilterState *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &envoy_config_route_v3_RouteAction_HashPolicy_FilterState_msginit, arena, len);
 }
@@ -1885,21 +2034,28 @@ UPB_INLINE envoy_config_route_v3_RouteAction_UpgradeConfig *envoy_config_route_v
   envoy_config_route_v3_RouteAction_UpgradeConfig *ret = envoy_config_route_v3_RouteAction_UpgradeConfig_new(arena);
   return (ret && upb_decode(buf, size, ret, &envoy_config_route_v3_RouteAction_UpgradeConfig_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE envoy_config_route_v3_RouteAction_UpgradeConfig *envoy_config_route_v3_RouteAction_UpgradeConfig_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  envoy_config_route_v3_RouteAction_UpgradeConfig *ret = envoy_config_route_v3_RouteAction_UpgradeConfig_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &envoy_config_route_v3_RouteAction_UpgradeConfig_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *envoy_config_route_v3_RouteAction_UpgradeConfig_serialize(const envoy_config_route_v3_RouteAction_UpgradeConfig *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &envoy_config_route_v3_RouteAction_UpgradeConfig_msginit, arena, len);
 }
 
-UPB_INLINE upb_strview envoy_config_route_v3_RouteAction_UpgradeConfig_upgrade_type(const envoy_config_route_v3_RouteAction_UpgradeConfig *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(0, 0), upb_strview); }
-UPB_INLINE bool envoy_config_route_v3_RouteAction_UpgradeConfig_has_enabled(const envoy_config_route_v3_RouteAction_UpgradeConfig *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(8, 16)); }
-UPB_INLINE const struct google_protobuf_BoolValue* envoy_config_route_v3_RouteAction_UpgradeConfig_enabled(const envoy_config_route_v3_RouteAction_UpgradeConfig *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(8, 16), const struct google_protobuf_BoolValue*); }
-UPB_INLINE bool envoy_config_route_v3_RouteAction_UpgradeConfig_has_connect_config(const envoy_config_route_v3_RouteAction_UpgradeConfig *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(12, 24)); }
-UPB_INLINE const envoy_config_route_v3_RouteAction_UpgradeConfig_ConnectConfig* envoy_config_route_v3_RouteAction_UpgradeConfig_connect_config(const envoy_config_route_v3_RouteAction_UpgradeConfig *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(12, 24), const envoy_config_route_v3_RouteAction_UpgradeConfig_ConnectConfig*); }
+UPB_INLINE upb_strview envoy_config_route_v3_RouteAction_UpgradeConfig_upgrade_type(const envoy_config_route_v3_RouteAction_UpgradeConfig *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(4, 8), upb_strview); }
+UPB_INLINE bool envoy_config_route_v3_RouteAction_UpgradeConfig_has_enabled(const envoy_config_route_v3_RouteAction_UpgradeConfig *msg) { return _upb_hasbit(msg, 1); }
+UPB_INLINE const struct google_protobuf_BoolValue* envoy_config_route_v3_RouteAction_UpgradeConfig_enabled(const envoy_config_route_v3_RouteAction_UpgradeConfig *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(12, 24), const struct google_protobuf_BoolValue*); }
+UPB_INLINE bool envoy_config_route_v3_RouteAction_UpgradeConfig_has_connect_config(const envoy_config_route_v3_RouteAction_UpgradeConfig *msg) { return _upb_hasbit(msg, 2); }
+UPB_INLINE const envoy_config_route_v3_RouteAction_UpgradeConfig_ConnectConfig* envoy_config_route_v3_RouteAction_UpgradeConfig_connect_config(const envoy_config_route_v3_RouteAction_UpgradeConfig *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(16, 32), const envoy_config_route_v3_RouteAction_UpgradeConfig_ConnectConfig*); }
 
 UPB_INLINE void envoy_config_route_v3_RouteAction_UpgradeConfig_set_upgrade_type(envoy_config_route_v3_RouteAction_UpgradeConfig *msg, upb_strview value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(0, 0), upb_strview) = value;
+  *UPB_PTR_AT(msg, UPB_SIZE(4, 8), upb_strview) = value;
 }
 UPB_INLINE void envoy_config_route_v3_RouteAction_UpgradeConfig_set_enabled(envoy_config_route_v3_RouteAction_UpgradeConfig *msg, struct google_protobuf_BoolValue* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(8, 16), struct google_protobuf_BoolValue*) = value;
+  _upb_sethas(msg, 1);
+  *UPB_PTR_AT(msg, UPB_SIZE(12, 24), struct google_protobuf_BoolValue*) = value;
 }
 UPB_INLINE struct google_protobuf_BoolValue* envoy_config_route_v3_RouteAction_UpgradeConfig_mutable_enabled(envoy_config_route_v3_RouteAction_UpgradeConfig *msg, upb_arena *arena) {
   struct google_protobuf_BoolValue* sub = (struct google_protobuf_BoolValue*)envoy_config_route_v3_RouteAction_UpgradeConfig_enabled(msg);
@@ -1911,7 +2067,8 @@ UPB_INLINE struct google_protobuf_BoolValue* envoy_config_route_v3_RouteAction_U
   return sub;
 }
 UPB_INLINE void envoy_config_route_v3_RouteAction_UpgradeConfig_set_connect_config(envoy_config_route_v3_RouteAction_UpgradeConfig *msg, envoy_config_route_v3_RouteAction_UpgradeConfig_ConnectConfig* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(12, 24), envoy_config_route_v3_RouteAction_UpgradeConfig_ConnectConfig*) = value;
+  _upb_sethas(msg, 2);
+  *UPB_PTR_AT(msg, UPB_SIZE(16, 32), envoy_config_route_v3_RouteAction_UpgradeConfig_ConnectConfig*) = value;
 }
 UPB_INLINE struct envoy_config_route_v3_RouteAction_UpgradeConfig_ConnectConfig* envoy_config_route_v3_RouteAction_UpgradeConfig_mutable_connect_config(envoy_config_route_v3_RouteAction_UpgradeConfig *msg, upb_arena *arena) {
   struct envoy_config_route_v3_RouteAction_UpgradeConfig_ConnectConfig* sub = (struct envoy_config_route_v3_RouteAction_UpgradeConfig_ConnectConfig*)envoy_config_route_v3_RouteAction_UpgradeConfig_connect_config(msg);
@@ -1933,15 +2090,22 @@ UPB_INLINE envoy_config_route_v3_RouteAction_UpgradeConfig_ConnectConfig *envoy_
   envoy_config_route_v3_RouteAction_UpgradeConfig_ConnectConfig *ret = envoy_config_route_v3_RouteAction_UpgradeConfig_ConnectConfig_new(arena);
   return (ret && upb_decode(buf, size, ret, &envoy_config_route_v3_RouteAction_UpgradeConfig_ConnectConfig_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE envoy_config_route_v3_RouteAction_UpgradeConfig_ConnectConfig *envoy_config_route_v3_RouteAction_UpgradeConfig_ConnectConfig_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  envoy_config_route_v3_RouteAction_UpgradeConfig_ConnectConfig *ret = envoy_config_route_v3_RouteAction_UpgradeConfig_ConnectConfig_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &envoy_config_route_v3_RouteAction_UpgradeConfig_ConnectConfig_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *envoy_config_route_v3_RouteAction_UpgradeConfig_ConnectConfig_serialize(const envoy_config_route_v3_RouteAction_UpgradeConfig_ConnectConfig *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &envoy_config_route_v3_RouteAction_UpgradeConfig_ConnectConfig_msginit, arena, len);
 }
 
-UPB_INLINE bool envoy_config_route_v3_RouteAction_UpgradeConfig_ConnectConfig_has_proxy_protocol_config(const envoy_config_route_v3_RouteAction_UpgradeConfig_ConnectConfig *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(0, 0)); }
-UPB_INLINE const struct envoy_config_core_v3_ProxyProtocolConfig* envoy_config_route_v3_RouteAction_UpgradeConfig_ConnectConfig_proxy_protocol_config(const envoy_config_route_v3_RouteAction_UpgradeConfig_ConnectConfig *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(0, 0), const struct envoy_config_core_v3_ProxyProtocolConfig*); }
+UPB_INLINE bool envoy_config_route_v3_RouteAction_UpgradeConfig_ConnectConfig_has_proxy_protocol_config(const envoy_config_route_v3_RouteAction_UpgradeConfig_ConnectConfig *msg) { return _upb_hasbit(msg, 1); }
+UPB_INLINE const struct envoy_config_core_v3_ProxyProtocolConfig* envoy_config_route_v3_RouteAction_UpgradeConfig_ConnectConfig_proxy_protocol_config(const envoy_config_route_v3_RouteAction_UpgradeConfig_ConnectConfig *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(4, 8), const struct envoy_config_core_v3_ProxyProtocolConfig*); }
 
 UPB_INLINE void envoy_config_route_v3_RouteAction_UpgradeConfig_ConnectConfig_set_proxy_protocol_config(envoy_config_route_v3_RouteAction_UpgradeConfig_ConnectConfig *msg, struct envoy_config_core_v3_ProxyProtocolConfig* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(0, 0), struct envoy_config_core_v3_ProxyProtocolConfig*) = value;
+  _upb_sethas(msg, 1);
+  *UPB_PTR_AT(msg, UPB_SIZE(4, 8), struct envoy_config_core_v3_ProxyProtocolConfig*) = value;
 }
 UPB_INLINE struct envoy_config_core_v3_ProxyProtocolConfig* envoy_config_route_v3_RouteAction_UpgradeConfig_ConnectConfig_mutable_proxy_protocol_config(envoy_config_route_v3_RouteAction_UpgradeConfig_ConnectConfig *msg, upb_arena *arena) {
   struct envoy_config_core_v3_ProxyProtocolConfig* sub = (struct envoy_config_core_v3_ProxyProtocolConfig*)envoy_config_route_v3_RouteAction_UpgradeConfig_ConnectConfig_proxy_protocol_config(msg);
@@ -1963,19 +2127,26 @@ UPB_INLINE envoy_config_route_v3_RouteAction_MaxStreamDuration *envoy_config_rou
   envoy_config_route_v3_RouteAction_MaxStreamDuration *ret = envoy_config_route_v3_RouteAction_MaxStreamDuration_new(arena);
   return (ret && upb_decode(buf, size, ret, &envoy_config_route_v3_RouteAction_MaxStreamDuration_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE envoy_config_route_v3_RouteAction_MaxStreamDuration *envoy_config_route_v3_RouteAction_MaxStreamDuration_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  envoy_config_route_v3_RouteAction_MaxStreamDuration *ret = envoy_config_route_v3_RouteAction_MaxStreamDuration_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &envoy_config_route_v3_RouteAction_MaxStreamDuration_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *envoy_config_route_v3_RouteAction_MaxStreamDuration_serialize(const envoy_config_route_v3_RouteAction_MaxStreamDuration *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &envoy_config_route_v3_RouteAction_MaxStreamDuration_msginit, arena, len);
 }
 
-UPB_INLINE bool envoy_config_route_v3_RouteAction_MaxStreamDuration_has_max_stream_duration(const envoy_config_route_v3_RouteAction_MaxStreamDuration *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(0, 0)); }
-UPB_INLINE const struct google_protobuf_Duration* envoy_config_route_v3_RouteAction_MaxStreamDuration_max_stream_duration(const envoy_config_route_v3_RouteAction_MaxStreamDuration *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(0, 0), const struct google_protobuf_Duration*); }
-UPB_INLINE bool envoy_config_route_v3_RouteAction_MaxStreamDuration_has_grpc_timeout_header_max(const envoy_config_route_v3_RouteAction_MaxStreamDuration *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(4, 8)); }
-UPB_INLINE const struct google_protobuf_Duration* envoy_config_route_v3_RouteAction_MaxStreamDuration_grpc_timeout_header_max(const envoy_config_route_v3_RouteAction_MaxStreamDuration *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(4, 8), const struct google_protobuf_Duration*); }
-UPB_INLINE bool envoy_config_route_v3_RouteAction_MaxStreamDuration_has_grpc_timeout_header_offset(const envoy_config_route_v3_RouteAction_MaxStreamDuration *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(8, 16)); }
-UPB_INLINE const struct google_protobuf_Duration* envoy_config_route_v3_RouteAction_MaxStreamDuration_grpc_timeout_header_offset(const envoy_config_route_v3_RouteAction_MaxStreamDuration *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(8, 16), const struct google_protobuf_Duration*); }
+UPB_INLINE bool envoy_config_route_v3_RouteAction_MaxStreamDuration_has_max_stream_duration(const envoy_config_route_v3_RouteAction_MaxStreamDuration *msg) { return _upb_hasbit(msg, 1); }
+UPB_INLINE const struct google_protobuf_Duration* envoy_config_route_v3_RouteAction_MaxStreamDuration_max_stream_duration(const envoy_config_route_v3_RouteAction_MaxStreamDuration *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(4, 8), const struct google_protobuf_Duration*); }
+UPB_INLINE bool envoy_config_route_v3_RouteAction_MaxStreamDuration_has_grpc_timeout_header_max(const envoy_config_route_v3_RouteAction_MaxStreamDuration *msg) { return _upb_hasbit(msg, 2); }
+UPB_INLINE const struct google_protobuf_Duration* envoy_config_route_v3_RouteAction_MaxStreamDuration_grpc_timeout_header_max(const envoy_config_route_v3_RouteAction_MaxStreamDuration *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(8, 16), const struct google_protobuf_Duration*); }
+UPB_INLINE bool envoy_config_route_v3_RouteAction_MaxStreamDuration_has_grpc_timeout_header_offset(const envoy_config_route_v3_RouteAction_MaxStreamDuration *msg) { return _upb_hasbit(msg, 3); }
+UPB_INLINE const struct google_protobuf_Duration* envoy_config_route_v3_RouteAction_MaxStreamDuration_grpc_timeout_header_offset(const envoy_config_route_v3_RouteAction_MaxStreamDuration *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(12, 24), const struct google_protobuf_Duration*); }
 
 UPB_INLINE void envoy_config_route_v3_RouteAction_MaxStreamDuration_set_max_stream_duration(envoy_config_route_v3_RouteAction_MaxStreamDuration *msg, struct google_protobuf_Duration* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(0, 0), struct google_protobuf_Duration*) = value;
+  _upb_sethas(msg, 1);
+  *UPB_PTR_AT(msg, UPB_SIZE(4, 8), struct google_protobuf_Duration*) = value;
 }
 UPB_INLINE struct google_protobuf_Duration* envoy_config_route_v3_RouteAction_MaxStreamDuration_mutable_max_stream_duration(envoy_config_route_v3_RouteAction_MaxStreamDuration *msg, upb_arena *arena) {
   struct google_protobuf_Duration* sub = (struct google_protobuf_Duration*)envoy_config_route_v3_RouteAction_MaxStreamDuration_max_stream_duration(msg);
@@ -1987,7 +2158,8 @@ UPB_INLINE struct google_protobuf_Duration* envoy_config_route_v3_RouteAction_Ma
   return sub;
 }
 UPB_INLINE void envoy_config_route_v3_RouteAction_MaxStreamDuration_set_grpc_timeout_header_max(envoy_config_route_v3_RouteAction_MaxStreamDuration *msg, struct google_protobuf_Duration* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(4, 8), struct google_protobuf_Duration*) = value;
+  _upb_sethas(msg, 2);
+  *UPB_PTR_AT(msg, UPB_SIZE(8, 16), struct google_protobuf_Duration*) = value;
 }
 UPB_INLINE struct google_protobuf_Duration* envoy_config_route_v3_RouteAction_MaxStreamDuration_mutable_grpc_timeout_header_max(envoy_config_route_v3_RouteAction_MaxStreamDuration *msg, upb_arena *arena) {
   struct google_protobuf_Duration* sub = (struct google_protobuf_Duration*)envoy_config_route_v3_RouteAction_MaxStreamDuration_grpc_timeout_header_max(msg);
@@ -1999,7 +2171,8 @@ UPB_INLINE struct google_protobuf_Duration* envoy_config_route_v3_RouteAction_Ma
   return sub;
 }
 UPB_INLINE void envoy_config_route_v3_RouteAction_MaxStreamDuration_set_grpc_timeout_header_offset(envoy_config_route_v3_RouteAction_MaxStreamDuration *msg, struct google_protobuf_Duration* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(8, 16), struct google_protobuf_Duration*) = value;
+  _upb_sethas(msg, 3);
+  *UPB_PTR_AT(msg, UPB_SIZE(12, 24), struct google_protobuf_Duration*) = value;
 }
 UPB_INLINE struct google_protobuf_Duration* envoy_config_route_v3_RouteAction_MaxStreamDuration_mutable_grpc_timeout_header_offset(envoy_config_route_v3_RouteAction_MaxStreamDuration *msg, upb_arena *arena) {
   struct google_protobuf_Duration* sub = (struct google_protobuf_Duration*)envoy_config_route_v3_RouteAction_MaxStreamDuration_grpc_timeout_header_offset(msg);
@@ -2021,35 +2194,42 @@ UPB_INLINE envoy_config_route_v3_RetryPolicy *envoy_config_route_v3_RetryPolicy_
   envoy_config_route_v3_RetryPolicy *ret = envoy_config_route_v3_RetryPolicy_new(arena);
   return (ret && upb_decode(buf, size, ret, &envoy_config_route_v3_RetryPolicy_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE envoy_config_route_v3_RetryPolicy *envoy_config_route_v3_RetryPolicy_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  envoy_config_route_v3_RetryPolicy *ret = envoy_config_route_v3_RetryPolicy_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &envoy_config_route_v3_RetryPolicy_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *envoy_config_route_v3_RetryPolicy_serialize(const envoy_config_route_v3_RetryPolicy *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &envoy_config_route_v3_RetryPolicy_msginit, arena, len);
 }
 
-UPB_INLINE upb_strview envoy_config_route_v3_RetryPolicy_retry_on(const envoy_config_route_v3_RetryPolicy *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(8, 8), upb_strview); }
-UPB_INLINE bool envoy_config_route_v3_RetryPolicy_has_num_retries(const envoy_config_route_v3_RetryPolicy *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(16, 24)); }
-UPB_INLINE const struct google_protobuf_UInt32Value* envoy_config_route_v3_RetryPolicy_num_retries(const envoy_config_route_v3_RetryPolicy *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(16, 24), const struct google_protobuf_UInt32Value*); }
-UPB_INLINE bool envoy_config_route_v3_RetryPolicy_has_per_try_timeout(const envoy_config_route_v3_RetryPolicy *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(20, 32)); }
-UPB_INLINE const struct google_protobuf_Duration* envoy_config_route_v3_RetryPolicy_per_try_timeout(const envoy_config_route_v3_RetryPolicy *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(20, 32), const struct google_protobuf_Duration*); }
-UPB_INLINE bool envoy_config_route_v3_RetryPolicy_has_retry_priority(const envoy_config_route_v3_RetryPolicy *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(24, 40)); }
-UPB_INLINE const envoy_config_route_v3_RetryPolicy_RetryPriority* envoy_config_route_v3_RetryPolicy_retry_priority(const envoy_config_route_v3_RetryPolicy *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(24, 40), const envoy_config_route_v3_RetryPolicy_RetryPriority*); }
-UPB_INLINE bool envoy_config_route_v3_RetryPolicy_has_retry_host_predicate(const envoy_config_route_v3_RetryPolicy *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(36, 64)); }
-UPB_INLINE const envoy_config_route_v3_RetryPolicy_RetryHostPredicate* const* envoy_config_route_v3_RetryPolicy_retry_host_predicate(const envoy_config_route_v3_RetryPolicy *msg, size_t *len) { return (const envoy_config_route_v3_RetryPolicy_RetryHostPredicate* const*)_upb_array_accessor(msg, UPB_SIZE(36, 64), len); }
-UPB_INLINE int64_t envoy_config_route_v3_RetryPolicy_host_selection_retry_max_attempts(const envoy_config_route_v3_RetryPolicy *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(0, 0), int64_t); }
-UPB_INLINE uint32_t const* envoy_config_route_v3_RetryPolicy_retriable_status_codes(const envoy_config_route_v3_RetryPolicy *msg, size_t *len) { return (uint32_t const*)_upb_array_accessor(msg, UPB_SIZE(40, 72), len); }
-UPB_INLINE bool envoy_config_route_v3_RetryPolicy_has_retry_back_off(const envoy_config_route_v3_RetryPolicy *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(28, 48)); }
-UPB_INLINE const envoy_config_route_v3_RetryPolicy_RetryBackOff* envoy_config_route_v3_RetryPolicy_retry_back_off(const envoy_config_route_v3_RetryPolicy *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(28, 48), const envoy_config_route_v3_RetryPolicy_RetryBackOff*); }
-UPB_INLINE bool envoy_config_route_v3_RetryPolicy_has_retriable_headers(const envoy_config_route_v3_RetryPolicy *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(44, 80)); }
-UPB_INLINE const envoy_config_route_v3_HeaderMatcher* const* envoy_config_route_v3_RetryPolicy_retriable_headers(const envoy_config_route_v3_RetryPolicy *msg, size_t *len) { return (const envoy_config_route_v3_HeaderMatcher* const*)_upb_array_accessor(msg, UPB_SIZE(44, 80), len); }
-UPB_INLINE bool envoy_config_route_v3_RetryPolicy_has_retriable_request_headers(const envoy_config_route_v3_RetryPolicy *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(48, 88)); }
-UPB_INLINE const envoy_config_route_v3_HeaderMatcher* const* envoy_config_route_v3_RetryPolicy_retriable_request_headers(const envoy_config_route_v3_RetryPolicy *msg, size_t *len) { return (const envoy_config_route_v3_HeaderMatcher* const*)_upb_array_accessor(msg, UPB_SIZE(48, 88), len); }
-UPB_INLINE bool envoy_config_route_v3_RetryPolicy_has_rate_limited_retry_back_off(const envoy_config_route_v3_RetryPolicy *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(32, 56)); }
-UPB_INLINE const envoy_config_route_v3_RetryPolicy_RateLimitedRetryBackOff* envoy_config_route_v3_RetryPolicy_rate_limited_retry_back_off(const envoy_config_route_v3_RetryPolicy *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(32, 56), const envoy_config_route_v3_RetryPolicy_RateLimitedRetryBackOff*); }
+UPB_INLINE upb_strview envoy_config_route_v3_RetryPolicy_retry_on(const envoy_config_route_v3_RetryPolicy *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(16, 16), upb_strview); }
+UPB_INLINE bool envoy_config_route_v3_RetryPolicy_has_num_retries(const envoy_config_route_v3_RetryPolicy *msg) { return _upb_hasbit(msg, 1); }
+UPB_INLINE const struct google_protobuf_UInt32Value* envoy_config_route_v3_RetryPolicy_num_retries(const envoy_config_route_v3_RetryPolicy *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(24, 32), const struct google_protobuf_UInt32Value*); }
+UPB_INLINE bool envoy_config_route_v3_RetryPolicy_has_per_try_timeout(const envoy_config_route_v3_RetryPolicy *msg) { return _upb_hasbit(msg, 2); }
+UPB_INLINE const struct google_protobuf_Duration* envoy_config_route_v3_RetryPolicy_per_try_timeout(const envoy_config_route_v3_RetryPolicy *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(28, 40), const struct google_protobuf_Duration*); }
+UPB_INLINE bool envoy_config_route_v3_RetryPolicy_has_retry_priority(const envoy_config_route_v3_RetryPolicy *msg) { return _upb_hasbit(msg, 3); }
+UPB_INLINE const envoy_config_route_v3_RetryPolicy_RetryPriority* envoy_config_route_v3_RetryPolicy_retry_priority(const envoy_config_route_v3_RetryPolicy *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(32, 48), const envoy_config_route_v3_RetryPolicy_RetryPriority*); }
+UPB_INLINE bool envoy_config_route_v3_RetryPolicy_has_retry_host_predicate(const envoy_config_route_v3_RetryPolicy *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(44, 72)); }
+UPB_INLINE const envoy_config_route_v3_RetryPolicy_RetryHostPredicate* const* envoy_config_route_v3_RetryPolicy_retry_host_predicate(const envoy_config_route_v3_RetryPolicy *msg, size_t *len) { return (const envoy_config_route_v3_RetryPolicy_RetryHostPredicate* const*)_upb_array_accessor(msg, UPB_SIZE(44, 72), len); }
+UPB_INLINE int64_t envoy_config_route_v3_RetryPolicy_host_selection_retry_max_attempts(const envoy_config_route_v3_RetryPolicy *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(8, 8), int64_t); }
+UPB_INLINE uint32_t const* envoy_config_route_v3_RetryPolicy_retriable_status_codes(const envoy_config_route_v3_RetryPolicy *msg, size_t *len) { return (uint32_t const*)_upb_array_accessor(msg, UPB_SIZE(48, 80), len); }
+UPB_INLINE bool envoy_config_route_v3_RetryPolicy_has_retry_back_off(const envoy_config_route_v3_RetryPolicy *msg) { return _upb_hasbit(msg, 4); }
+UPB_INLINE const envoy_config_route_v3_RetryPolicy_RetryBackOff* envoy_config_route_v3_RetryPolicy_retry_back_off(const envoy_config_route_v3_RetryPolicy *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(36, 56), const envoy_config_route_v3_RetryPolicy_RetryBackOff*); }
+UPB_INLINE bool envoy_config_route_v3_RetryPolicy_has_retriable_headers(const envoy_config_route_v3_RetryPolicy *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(52, 88)); }
+UPB_INLINE const envoy_config_route_v3_HeaderMatcher* const* envoy_config_route_v3_RetryPolicy_retriable_headers(const envoy_config_route_v3_RetryPolicy *msg, size_t *len) { return (const envoy_config_route_v3_HeaderMatcher* const*)_upb_array_accessor(msg, UPB_SIZE(52, 88), len); }
+UPB_INLINE bool envoy_config_route_v3_RetryPolicy_has_retriable_request_headers(const envoy_config_route_v3_RetryPolicy *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(56, 96)); }
+UPB_INLINE const envoy_config_route_v3_HeaderMatcher* const* envoy_config_route_v3_RetryPolicy_retriable_request_headers(const envoy_config_route_v3_RetryPolicy *msg, size_t *len) { return (const envoy_config_route_v3_HeaderMatcher* const*)_upb_array_accessor(msg, UPB_SIZE(56, 96), len); }
+UPB_INLINE bool envoy_config_route_v3_RetryPolicy_has_rate_limited_retry_back_off(const envoy_config_route_v3_RetryPolicy *msg) { return _upb_hasbit(msg, 5); }
+UPB_INLINE const envoy_config_route_v3_RetryPolicy_RateLimitedRetryBackOff* envoy_config_route_v3_RetryPolicy_rate_limited_retry_back_off(const envoy_config_route_v3_RetryPolicy *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(40, 64), const envoy_config_route_v3_RetryPolicy_RateLimitedRetryBackOff*); }
 
 UPB_INLINE void envoy_config_route_v3_RetryPolicy_set_retry_on(envoy_config_route_v3_RetryPolicy *msg, upb_strview value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(8, 8), upb_strview) = value;
+  *UPB_PTR_AT(msg, UPB_SIZE(16, 16), upb_strview) = value;
 }
 UPB_INLINE void envoy_config_route_v3_RetryPolicy_set_num_retries(envoy_config_route_v3_RetryPolicy *msg, struct google_protobuf_UInt32Value* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(16, 24), struct google_protobuf_UInt32Value*) = value;
+  _upb_sethas(msg, 1);
+  *UPB_PTR_AT(msg, UPB_SIZE(24, 32), struct google_protobuf_UInt32Value*) = value;
 }
 UPB_INLINE struct google_protobuf_UInt32Value* envoy_config_route_v3_RetryPolicy_mutable_num_retries(envoy_config_route_v3_RetryPolicy *msg, upb_arena *arena) {
   struct google_protobuf_UInt32Value* sub = (struct google_protobuf_UInt32Value*)envoy_config_route_v3_RetryPolicy_num_retries(msg);
@@ -2061,7 +2241,8 @@ UPB_INLINE struct google_protobuf_UInt32Value* envoy_config_route_v3_RetryPolicy
   return sub;
 }
 UPB_INLINE void envoy_config_route_v3_RetryPolicy_set_per_try_timeout(envoy_config_route_v3_RetryPolicy *msg, struct google_protobuf_Duration* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(20, 32), struct google_protobuf_Duration*) = value;
+  _upb_sethas(msg, 2);
+  *UPB_PTR_AT(msg, UPB_SIZE(28, 40), struct google_protobuf_Duration*) = value;
 }
 UPB_INLINE struct google_protobuf_Duration* envoy_config_route_v3_RetryPolicy_mutable_per_try_timeout(envoy_config_route_v3_RetryPolicy *msg, upb_arena *arena) {
   struct google_protobuf_Duration* sub = (struct google_protobuf_Duration*)envoy_config_route_v3_RetryPolicy_per_try_timeout(msg);
@@ -2073,7 +2254,8 @@ UPB_INLINE struct google_protobuf_Duration* envoy_config_route_v3_RetryPolicy_mu
   return sub;
 }
 UPB_INLINE void envoy_config_route_v3_RetryPolicy_set_retry_priority(envoy_config_route_v3_RetryPolicy *msg, envoy_config_route_v3_RetryPolicy_RetryPriority* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(24, 40), envoy_config_route_v3_RetryPolicy_RetryPriority*) = value;
+  _upb_sethas(msg, 3);
+  *UPB_PTR_AT(msg, UPB_SIZE(32, 48), envoy_config_route_v3_RetryPolicy_RetryPriority*) = value;
 }
 UPB_INLINE struct envoy_config_route_v3_RetryPolicy_RetryPriority* envoy_config_route_v3_RetryPolicy_mutable_retry_priority(envoy_config_route_v3_RetryPolicy *msg, upb_arena *arena) {
   struct envoy_config_route_v3_RetryPolicy_RetryPriority* sub = (struct envoy_config_route_v3_RetryPolicy_RetryPriority*)envoy_config_route_v3_RetryPolicy_retry_priority(msg);
@@ -2085,33 +2267,34 @@ UPB_INLINE struct envoy_config_route_v3_RetryPolicy_RetryPriority* envoy_config_
   return sub;
 }
 UPB_INLINE envoy_config_route_v3_RetryPolicy_RetryHostPredicate** envoy_config_route_v3_RetryPolicy_mutable_retry_host_predicate(envoy_config_route_v3_RetryPolicy *msg, size_t *len) {
-  return (envoy_config_route_v3_RetryPolicy_RetryHostPredicate**)_upb_array_mutable_accessor(msg, UPB_SIZE(36, 64), len);
+  return (envoy_config_route_v3_RetryPolicy_RetryHostPredicate**)_upb_array_mutable_accessor(msg, UPB_SIZE(44, 72), len);
 }
 UPB_INLINE envoy_config_route_v3_RetryPolicy_RetryHostPredicate** envoy_config_route_v3_RetryPolicy_resize_retry_host_predicate(envoy_config_route_v3_RetryPolicy *msg, size_t len, upb_arena *arena) {
-  return (envoy_config_route_v3_RetryPolicy_RetryHostPredicate**)_upb_array_resize_accessor(msg, UPB_SIZE(36, 64), len, UPB_TYPE_MESSAGE, arena);
+  return (envoy_config_route_v3_RetryPolicy_RetryHostPredicate**)_upb_array_resize_accessor2(msg, UPB_SIZE(44, 72), len, UPB_SIZE(2, 3), arena);
 }
 UPB_INLINE struct envoy_config_route_v3_RetryPolicy_RetryHostPredicate* envoy_config_route_v3_RetryPolicy_add_retry_host_predicate(envoy_config_route_v3_RetryPolicy *msg, upb_arena *arena) {
   struct envoy_config_route_v3_RetryPolicy_RetryHostPredicate* sub = (struct envoy_config_route_v3_RetryPolicy_RetryHostPredicate*)_upb_msg_new(&envoy_config_route_v3_RetryPolicy_RetryHostPredicate_msginit, arena);
-  bool ok = _upb_array_append_accessor(
-      msg, UPB_SIZE(36, 64), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena);
+  bool ok = _upb_array_append_accessor2(
+      msg, UPB_SIZE(44, 72), UPB_SIZE(2, 3), &sub, arena);
   if (!ok) return NULL;
   return sub;
 }
 UPB_INLINE void envoy_config_route_v3_RetryPolicy_set_host_selection_retry_max_attempts(envoy_config_route_v3_RetryPolicy *msg, int64_t value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(0, 0), int64_t) = value;
+  *UPB_PTR_AT(msg, UPB_SIZE(8, 8), int64_t) = value;
 }
 UPB_INLINE uint32_t* envoy_config_route_v3_RetryPolicy_mutable_retriable_status_codes(envoy_config_route_v3_RetryPolicy *msg, size_t *len) {
-  return (uint32_t*)_upb_array_mutable_accessor(msg, UPB_SIZE(40, 72), len);
+  return (uint32_t*)_upb_array_mutable_accessor(msg, UPB_SIZE(48, 80), len);
 }
 UPB_INLINE uint32_t* envoy_config_route_v3_RetryPolicy_resize_retriable_status_codes(envoy_config_route_v3_RetryPolicy *msg, size_t len, upb_arena *arena) {
-  return (uint32_t*)_upb_array_resize_accessor(msg, UPB_SIZE(40, 72), len, UPB_TYPE_UINT32, arena);
+  return (uint32_t*)_upb_array_resize_accessor2(msg, UPB_SIZE(48, 80), len, 2, arena);
 }
 UPB_INLINE bool envoy_config_route_v3_RetryPolicy_add_retriable_status_codes(envoy_config_route_v3_RetryPolicy *msg, uint32_t val, upb_arena *arena) {
-  return _upb_array_append_accessor(msg, UPB_SIZE(40, 72), UPB_SIZE(4, 4), UPB_TYPE_UINT32, &val,
+  return _upb_array_append_accessor2(msg, UPB_SIZE(48, 80), 2, &val,
       arena);
 }
 UPB_INLINE void envoy_config_route_v3_RetryPolicy_set_retry_back_off(envoy_config_route_v3_RetryPolicy *msg, envoy_config_route_v3_RetryPolicy_RetryBackOff* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(28, 48), envoy_config_route_v3_RetryPolicy_RetryBackOff*) = value;
+  _upb_sethas(msg, 4);
+  *UPB_PTR_AT(msg, UPB_SIZE(36, 56), envoy_config_route_v3_RetryPolicy_RetryBackOff*) = value;
 }
 UPB_INLINE struct envoy_config_route_v3_RetryPolicy_RetryBackOff* envoy_config_route_v3_RetryPolicy_mutable_retry_back_off(envoy_config_route_v3_RetryPolicy *msg, upb_arena *arena) {
   struct envoy_config_route_v3_RetryPolicy_RetryBackOff* sub = (struct envoy_config_route_v3_RetryPolicy_RetryBackOff*)envoy_config_route_v3_RetryPolicy_retry_back_off(msg);
@@ -2123,33 +2306,34 @@ UPB_INLINE struct envoy_config_route_v3_RetryPolicy_RetryBackOff* envoy_config_r
   return sub;
 }
 UPB_INLINE envoy_config_route_v3_HeaderMatcher** envoy_config_route_v3_RetryPolicy_mutable_retriable_headers(envoy_config_route_v3_RetryPolicy *msg, size_t *len) {
-  return (envoy_config_route_v3_HeaderMatcher**)_upb_array_mutable_accessor(msg, UPB_SIZE(44, 80), len);
+  return (envoy_config_route_v3_HeaderMatcher**)_upb_array_mutable_accessor(msg, UPB_SIZE(52, 88), len);
 }
 UPB_INLINE envoy_config_route_v3_HeaderMatcher** envoy_config_route_v3_RetryPolicy_resize_retriable_headers(envoy_config_route_v3_RetryPolicy *msg, size_t len, upb_arena *arena) {
-  return (envoy_config_route_v3_HeaderMatcher**)_upb_array_resize_accessor(msg, UPB_SIZE(44, 80), len, UPB_TYPE_MESSAGE, arena);
+  return (envoy_config_route_v3_HeaderMatcher**)_upb_array_resize_accessor2(msg, UPB_SIZE(52, 88), len, UPB_SIZE(2, 3), arena);
 }
 UPB_INLINE struct envoy_config_route_v3_HeaderMatcher* envoy_config_route_v3_RetryPolicy_add_retriable_headers(envoy_config_route_v3_RetryPolicy *msg, upb_arena *arena) {
   struct envoy_config_route_v3_HeaderMatcher* sub = (struct envoy_config_route_v3_HeaderMatcher*)_upb_msg_new(&envoy_config_route_v3_HeaderMatcher_msginit, arena);
-  bool ok = _upb_array_append_accessor(
-      msg, UPB_SIZE(44, 80), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena);
+  bool ok = _upb_array_append_accessor2(
+      msg, UPB_SIZE(52, 88), UPB_SIZE(2, 3), &sub, arena);
   if (!ok) return NULL;
   return sub;
 }
 UPB_INLINE envoy_config_route_v3_HeaderMatcher** envoy_config_route_v3_RetryPolicy_mutable_retriable_request_headers(envoy_config_route_v3_RetryPolicy *msg, size_t *len) {
-  return (envoy_config_route_v3_HeaderMatcher**)_upb_array_mutable_accessor(msg, UPB_SIZE(48, 88), len);
+  return (envoy_config_route_v3_HeaderMatcher**)_upb_array_mutable_accessor(msg, UPB_SIZE(56, 96), len);
 }
 UPB_INLINE envoy_config_route_v3_HeaderMatcher** envoy_config_route_v3_RetryPolicy_resize_retriable_request_headers(envoy_config_route_v3_RetryPolicy *msg, size_t len, upb_arena *arena) {
-  return (envoy_config_route_v3_HeaderMatcher**)_upb_array_resize_accessor(msg, UPB_SIZE(48, 88), len, UPB_TYPE_MESSAGE, arena);
+  return (envoy_config_route_v3_HeaderMatcher**)_upb_array_resize_accessor2(msg, UPB_SIZE(56, 96), len, UPB_SIZE(2, 3), arena);
 }
 UPB_INLINE struct envoy_config_route_v3_HeaderMatcher* envoy_config_route_v3_RetryPolicy_add_retriable_request_headers(envoy_config_route_v3_RetryPolicy *msg, upb_arena *arena) {
   struct envoy_config_route_v3_HeaderMatcher* sub = (struct envoy_config_route_v3_HeaderMatcher*)_upb_msg_new(&envoy_config_route_v3_HeaderMatcher_msginit, arena);
-  bool ok = _upb_array_append_accessor(
-      msg, UPB_SIZE(48, 88), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena);
+  bool ok = _upb_array_append_accessor2(
+      msg, UPB_SIZE(56, 96), UPB_SIZE(2, 3), &sub, arena);
   if (!ok) return NULL;
   return sub;
 }
 UPB_INLINE void envoy_config_route_v3_RetryPolicy_set_rate_limited_retry_back_off(envoy_config_route_v3_RetryPolicy *msg, envoy_config_route_v3_RetryPolicy_RateLimitedRetryBackOff* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(32, 56), envoy_config_route_v3_RetryPolicy_RateLimitedRetryBackOff*) = value;
+  _upb_sethas(msg, 5);
+  *UPB_PTR_AT(msg, UPB_SIZE(40, 64), envoy_config_route_v3_RetryPolicy_RateLimitedRetryBackOff*) = value;
 }
 UPB_INLINE struct envoy_config_route_v3_RetryPolicy_RateLimitedRetryBackOff* envoy_config_route_v3_RetryPolicy_mutable_rate_limited_retry_back_off(envoy_config_route_v3_RetryPolicy *msg, upb_arena *arena) {
   struct envoy_config_route_v3_RetryPolicy_RateLimitedRetryBackOff* sub = (struct envoy_config_route_v3_RetryPolicy_RateLimitedRetryBackOff*)envoy_config_route_v3_RetryPolicy_rate_limited_retry_back_off(msg);
@@ -2171,6 +2355,12 @@ UPB_INLINE envoy_config_route_v3_RetryPolicy_RetryPriority *envoy_config_route_v
   envoy_config_route_v3_RetryPolicy_RetryPriority *ret = envoy_config_route_v3_RetryPolicy_RetryPriority_new(arena);
   return (ret && upb_decode(buf, size, ret, &envoy_config_route_v3_RetryPolicy_RetryPriority_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE envoy_config_route_v3_RetryPolicy_RetryPriority *envoy_config_route_v3_RetryPolicy_RetryPriority_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  envoy_config_route_v3_RetryPolicy_RetryPriority *ret = envoy_config_route_v3_RetryPolicy_RetryPriority_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &envoy_config_route_v3_RetryPolicy_RetryPriority_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *envoy_config_route_v3_RetryPolicy_RetryPriority_serialize(const envoy_config_route_v3_RetryPolicy_RetryPriority *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &envoy_config_route_v3_RetryPolicy_RetryPriority_msginit, arena, len);
 }
@@ -2211,6 +2401,12 @@ UPB_INLINE envoy_config_route_v3_RetryPolicy_RetryHostPredicate *envoy_config_ro
   envoy_config_route_v3_RetryPolicy_RetryHostPredicate *ret = envoy_config_route_v3_RetryPolicy_RetryHostPredicate_new(arena);
   return (ret && upb_decode(buf, size, ret, &envoy_config_route_v3_RetryPolicy_RetryHostPredicate_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE envoy_config_route_v3_RetryPolicy_RetryHostPredicate *envoy_config_route_v3_RetryPolicy_RetryHostPredicate_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  envoy_config_route_v3_RetryPolicy_RetryHostPredicate *ret = envoy_config_route_v3_RetryPolicy_RetryHostPredicate_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &envoy_config_route_v3_RetryPolicy_RetryHostPredicate_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *envoy_config_route_v3_RetryPolicy_RetryHostPredicate_serialize(const envoy_config_route_v3_RetryPolicy_RetryHostPredicate *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &envoy_config_route_v3_RetryPolicy_RetryHostPredicate_msginit, arena, len);
 }
@@ -2251,17 +2447,24 @@ UPB_INLINE envoy_config_route_v3_RetryPolicy_RetryBackOff *envoy_config_route_v3
   envoy_config_route_v3_RetryPolicy_RetryBackOff *ret = envoy_config_route_v3_RetryPolicy_RetryBackOff_new(arena);
   return (ret && upb_decode(buf, size, ret, &envoy_config_route_v3_RetryPolicy_RetryBackOff_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE envoy_config_route_v3_RetryPolicy_RetryBackOff *envoy_config_route_v3_RetryPolicy_RetryBackOff_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  envoy_config_route_v3_RetryPolicy_RetryBackOff *ret = envoy_config_route_v3_RetryPolicy_RetryBackOff_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &envoy_config_route_v3_RetryPolicy_RetryBackOff_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *envoy_config_route_v3_RetryPolicy_RetryBackOff_serialize(const envoy_config_route_v3_RetryPolicy_RetryBackOff *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &envoy_config_route_v3_RetryPolicy_RetryBackOff_msginit, arena, len);
 }
 
-UPB_INLINE bool envoy_config_route_v3_RetryPolicy_RetryBackOff_has_base_interval(const envoy_config_route_v3_RetryPolicy_RetryBackOff *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(0, 0)); }
-UPB_INLINE const struct google_protobuf_Duration* envoy_config_route_v3_RetryPolicy_RetryBackOff_base_interval(const envoy_config_route_v3_RetryPolicy_RetryBackOff *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(0, 0), const struct google_protobuf_Duration*); }
-UPB_INLINE bool envoy_config_route_v3_RetryPolicy_RetryBackOff_has_max_interval(const envoy_config_route_v3_RetryPolicy_RetryBackOff *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(4, 8)); }
-UPB_INLINE const struct google_protobuf_Duration* envoy_config_route_v3_RetryPolicy_RetryBackOff_max_interval(const envoy_config_route_v3_RetryPolicy_RetryBackOff *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(4, 8), const struct google_protobuf_Duration*); }
+UPB_INLINE bool envoy_config_route_v3_RetryPolicy_RetryBackOff_has_base_interval(const envoy_config_route_v3_RetryPolicy_RetryBackOff *msg) { return _upb_hasbit(msg, 1); }
+UPB_INLINE const struct google_protobuf_Duration* envoy_config_route_v3_RetryPolicy_RetryBackOff_base_interval(const envoy_config_route_v3_RetryPolicy_RetryBackOff *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(4, 8), const struct google_protobuf_Duration*); }
+UPB_INLINE bool envoy_config_route_v3_RetryPolicy_RetryBackOff_has_max_interval(const envoy_config_route_v3_RetryPolicy_RetryBackOff *msg) { return _upb_hasbit(msg, 2); }
+UPB_INLINE const struct google_protobuf_Duration* envoy_config_route_v3_RetryPolicy_RetryBackOff_max_interval(const envoy_config_route_v3_RetryPolicy_RetryBackOff *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(8, 16), const struct google_protobuf_Duration*); }
 
 UPB_INLINE void envoy_config_route_v3_RetryPolicy_RetryBackOff_set_base_interval(envoy_config_route_v3_RetryPolicy_RetryBackOff *msg, struct google_protobuf_Duration* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(0, 0), struct google_protobuf_Duration*) = value;
+  _upb_sethas(msg, 1);
+  *UPB_PTR_AT(msg, UPB_SIZE(4, 8), struct google_protobuf_Duration*) = value;
 }
 UPB_INLINE struct google_protobuf_Duration* envoy_config_route_v3_RetryPolicy_RetryBackOff_mutable_base_interval(envoy_config_route_v3_RetryPolicy_RetryBackOff *msg, upb_arena *arena) {
   struct google_protobuf_Duration* sub = (struct google_protobuf_Duration*)envoy_config_route_v3_RetryPolicy_RetryBackOff_base_interval(msg);
@@ -2273,7 +2476,8 @@ UPB_INLINE struct google_protobuf_Duration* envoy_config_route_v3_RetryPolicy_Re
   return sub;
 }
 UPB_INLINE void envoy_config_route_v3_RetryPolicy_RetryBackOff_set_max_interval(envoy_config_route_v3_RetryPolicy_RetryBackOff *msg, struct google_protobuf_Duration* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(4, 8), struct google_protobuf_Duration*) = value;
+  _upb_sethas(msg, 2);
+  *UPB_PTR_AT(msg, UPB_SIZE(8, 16), struct google_protobuf_Duration*) = value;
 }
 UPB_INLINE struct google_protobuf_Duration* envoy_config_route_v3_RetryPolicy_RetryBackOff_mutable_max_interval(envoy_config_route_v3_RetryPolicy_RetryBackOff *msg, upb_arena *arena) {
   struct google_protobuf_Duration* sub = (struct google_protobuf_Duration*)envoy_config_route_v3_RetryPolicy_RetryBackOff_max_interval(msg);
@@ -2295,15 +2499,21 @@ UPB_INLINE envoy_config_route_v3_RetryPolicy_ResetHeader *envoy_config_route_v3_
   envoy_config_route_v3_RetryPolicy_ResetHeader *ret = envoy_config_route_v3_RetryPolicy_ResetHeader_new(arena);
   return (ret && upb_decode(buf, size, ret, &envoy_config_route_v3_RetryPolicy_ResetHeader_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE envoy_config_route_v3_RetryPolicy_ResetHeader *envoy_config_route_v3_RetryPolicy_ResetHeader_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  envoy_config_route_v3_RetryPolicy_ResetHeader *ret = envoy_config_route_v3_RetryPolicy_ResetHeader_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &envoy_config_route_v3_RetryPolicy_ResetHeader_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *envoy_config_route_v3_RetryPolicy_ResetHeader_serialize(const envoy_config_route_v3_RetryPolicy_ResetHeader *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &envoy_config_route_v3_RetryPolicy_ResetHeader_msginit, arena, len);
 }
 
-UPB_INLINE upb_strview envoy_config_route_v3_RetryPolicy_ResetHeader_name(const envoy_config_route_v3_RetryPolicy_ResetHeader *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(8, 8), upb_strview); }
+UPB_INLINE upb_strview envoy_config_route_v3_RetryPolicy_ResetHeader_name(const envoy_config_route_v3_RetryPolicy_ResetHeader *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(4, 8), upb_strview); }
 UPB_INLINE int32_t envoy_config_route_v3_RetryPolicy_ResetHeader_format(const envoy_config_route_v3_RetryPolicy_ResetHeader *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(0, 0), int32_t); }
 
 UPB_INLINE void envoy_config_route_v3_RetryPolicy_ResetHeader_set_name(envoy_config_route_v3_RetryPolicy_ResetHeader *msg, upb_strview value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(8, 8), upb_strview) = value;
+  *UPB_PTR_AT(msg, UPB_SIZE(4, 8), upb_strview) = value;
 }
 UPB_INLINE void envoy_config_route_v3_RetryPolicy_ResetHeader_set_format(envoy_config_route_v3_RetryPolicy_ResetHeader *msg, int32_t value) {
   *UPB_PTR_AT(msg, UPB_SIZE(0, 0), int32_t) = value;
@@ -2319,30 +2529,37 @@ UPB_INLINE envoy_config_route_v3_RetryPolicy_RateLimitedRetryBackOff *envoy_conf
   envoy_config_route_v3_RetryPolicy_RateLimitedRetryBackOff *ret = envoy_config_route_v3_RetryPolicy_RateLimitedRetryBackOff_new(arena);
   return (ret && upb_decode(buf, size, ret, &envoy_config_route_v3_RetryPolicy_RateLimitedRetryBackOff_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE envoy_config_route_v3_RetryPolicy_RateLimitedRetryBackOff *envoy_config_route_v3_RetryPolicy_RateLimitedRetryBackOff_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  envoy_config_route_v3_RetryPolicy_RateLimitedRetryBackOff *ret = envoy_config_route_v3_RetryPolicy_RateLimitedRetryBackOff_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &envoy_config_route_v3_RetryPolicy_RateLimitedRetryBackOff_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *envoy_config_route_v3_RetryPolicy_RateLimitedRetryBackOff_serialize(const envoy_config_route_v3_RetryPolicy_RateLimitedRetryBackOff *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &envoy_config_route_v3_RetryPolicy_RateLimitedRetryBackOff_msginit, arena, len);
 }
 
-UPB_INLINE bool envoy_config_route_v3_RetryPolicy_RateLimitedRetryBackOff_has_reset_headers(const envoy_config_route_v3_RetryPolicy_RateLimitedRetryBackOff *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(4, 8)); }
-UPB_INLINE const envoy_config_route_v3_RetryPolicy_ResetHeader* const* envoy_config_route_v3_RetryPolicy_RateLimitedRetryBackOff_reset_headers(const envoy_config_route_v3_RetryPolicy_RateLimitedRetryBackOff *msg, size_t *len) { return (const envoy_config_route_v3_RetryPolicy_ResetHeader* const*)_upb_array_accessor(msg, UPB_SIZE(4, 8), len); }
-UPB_INLINE bool envoy_config_route_v3_RetryPolicy_RateLimitedRetryBackOff_has_max_interval(const envoy_config_route_v3_RetryPolicy_RateLimitedRetryBackOff *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(0, 0)); }
-UPB_INLINE const struct google_protobuf_Duration* envoy_config_route_v3_RetryPolicy_RateLimitedRetryBackOff_max_interval(const envoy_config_route_v3_RetryPolicy_RateLimitedRetryBackOff *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(0, 0), const struct google_protobuf_Duration*); }
+UPB_INLINE bool envoy_config_route_v3_RetryPolicy_RateLimitedRetryBackOff_has_reset_headers(const envoy_config_route_v3_RetryPolicy_RateLimitedRetryBackOff *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(8, 16)); }
+UPB_INLINE const envoy_config_route_v3_RetryPolicy_ResetHeader* const* envoy_config_route_v3_RetryPolicy_RateLimitedRetryBackOff_reset_headers(const envoy_config_route_v3_RetryPolicy_RateLimitedRetryBackOff *msg, size_t *len) { return (const envoy_config_route_v3_RetryPolicy_ResetHeader* const*)_upb_array_accessor(msg, UPB_SIZE(8, 16), len); }
+UPB_INLINE bool envoy_config_route_v3_RetryPolicy_RateLimitedRetryBackOff_has_max_interval(const envoy_config_route_v3_RetryPolicy_RateLimitedRetryBackOff *msg) { return _upb_hasbit(msg, 1); }
+UPB_INLINE const struct google_protobuf_Duration* envoy_config_route_v3_RetryPolicy_RateLimitedRetryBackOff_max_interval(const envoy_config_route_v3_RetryPolicy_RateLimitedRetryBackOff *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(4, 8), const struct google_protobuf_Duration*); }
 
 UPB_INLINE envoy_config_route_v3_RetryPolicy_ResetHeader** envoy_config_route_v3_RetryPolicy_RateLimitedRetryBackOff_mutable_reset_headers(envoy_config_route_v3_RetryPolicy_RateLimitedRetryBackOff *msg, size_t *len) {
-  return (envoy_config_route_v3_RetryPolicy_ResetHeader**)_upb_array_mutable_accessor(msg, UPB_SIZE(4, 8), len);
+  return (envoy_config_route_v3_RetryPolicy_ResetHeader**)_upb_array_mutable_accessor(msg, UPB_SIZE(8, 16), len);
 }
 UPB_INLINE envoy_config_route_v3_RetryPolicy_ResetHeader** envoy_config_route_v3_RetryPolicy_RateLimitedRetryBackOff_resize_reset_headers(envoy_config_route_v3_RetryPolicy_RateLimitedRetryBackOff *msg, size_t len, upb_arena *arena) {
-  return (envoy_config_route_v3_RetryPolicy_ResetHeader**)_upb_array_resize_accessor(msg, UPB_SIZE(4, 8), len, UPB_TYPE_MESSAGE, arena);
+  return (envoy_config_route_v3_RetryPolicy_ResetHeader**)_upb_array_resize_accessor2(msg, UPB_SIZE(8, 16), len, UPB_SIZE(2, 3), arena);
 }
 UPB_INLINE struct envoy_config_route_v3_RetryPolicy_ResetHeader* envoy_config_route_v3_RetryPolicy_RateLimitedRetryBackOff_add_reset_headers(envoy_config_route_v3_RetryPolicy_RateLimitedRetryBackOff *msg, upb_arena *arena) {
   struct envoy_config_route_v3_RetryPolicy_ResetHeader* sub = (struct envoy_config_route_v3_RetryPolicy_ResetHeader*)_upb_msg_new(&envoy_config_route_v3_RetryPolicy_ResetHeader_msginit, arena);
-  bool ok = _upb_array_append_accessor(
-      msg, UPB_SIZE(4, 8), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena);
+  bool ok = _upb_array_append_accessor2(
+      msg, UPB_SIZE(8, 16), UPB_SIZE(2, 3), &sub, arena);
   if (!ok) return NULL;
   return sub;
 }
 UPB_INLINE void envoy_config_route_v3_RetryPolicy_RateLimitedRetryBackOff_set_max_interval(envoy_config_route_v3_RetryPolicy_RateLimitedRetryBackOff *msg, struct google_protobuf_Duration* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(0, 0), struct google_protobuf_Duration*) = value;
+  _upb_sethas(msg, 1);
+  *UPB_PTR_AT(msg, UPB_SIZE(4, 8), struct google_protobuf_Duration*) = value;
 }
 UPB_INLINE struct google_protobuf_Duration* envoy_config_route_v3_RetryPolicy_RateLimitedRetryBackOff_mutable_max_interval(envoy_config_route_v3_RetryPolicy_RateLimitedRetryBackOff *msg, upb_arena *arena) {
   struct google_protobuf_Duration* sub = (struct google_protobuf_Duration*)envoy_config_route_v3_RetryPolicy_RateLimitedRetryBackOff_max_interval(msg);
@@ -2364,17 +2581,24 @@ UPB_INLINE envoy_config_route_v3_HedgePolicy *envoy_config_route_v3_HedgePolicy_
   envoy_config_route_v3_HedgePolicy *ret = envoy_config_route_v3_HedgePolicy_new(arena);
   return (ret && upb_decode(buf, size, ret, &envoy_config_route_v3_HedgePolicy_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE envoy_config_route_v3_HedgePolicy *envoy_config_route_v3_HedgePolicy_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  envoy_config_route_v3_HedgePolicy *ret = envoy_config_route_v3_HedgePolicy_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &envoy_config_route_v3_HedgePolicy_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *envoy_config_route_v3_HedgePolicy_serialize(const envoy_config_route_v3_HedgePolicy *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &envoy_config_route_v3_HedgePolicy_msginit, arena, len);
 }
 
-UPB_INLINE bool envoy_config_route_v3_HedgePolicy_has_initial_requests(const envoy_config_route_v3_HedgePolicy *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(4, 8)); }
+UPB_INLINE bool envoy_config_route_v3_HedgePolicy_has_initial_requests(const envoy_config_route_v3_HedgePolicy *msg) { return _upb_hasbit(msg, 1); }
 UPB_INLINE const struct google_protobuf_UInt32Value* envoy_config_route_v3_HedgePolicy_initial_requests(const envoy_config_route_v3_HedgePolicy *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(4, 8), const struct google_protobuf_UInt32Value*); }
-UPB_INLINE bool envoy_config_route_v3_HedgePolicy_has_additional_request_chance(const envoy_config_route_v3_HedgePolicy *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(8, 16)); }
+UPB_INLINE bool envoy_config_route_v3_HedgePolicy_has_additional_request_chance(const envoy_config_route_v3_HedgePolicy *msg) { return _upb_hasbit(msg, 2); }
 UPB_INLINE const struct envoy_type_v3_FractionalPercent* envoy_config_route_v3_HedgePolicy_additional_request_chance(const envoy_config_route_v3_HedgePolicy *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(8, 16), const struct envoy_type_v3_FractionalPercent*); }
-UPB_INLINE bool envoy_config_route_v3_HedgePolicy_hedge_on_per_try_timeout(const envoy_config_route_v3_HedgePolicy *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(0, 0), bool); }
+UPB_INLINE bool envoy_config_route_v3_HedgePolicy_hedge_on_per_try_timeout(const envoy_config_route_v3_HedgePolicy *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(1, 1), bool); }
 
 UPB_INLINE void envoy_config_route_v3_HedgePolicy_set_initial_requests(envoy_config_route_v3_HedgePolicy *msg, struct google_protobuf_UInt32Value* value) {
+  _upb_sethas(msg, 1);
   *UPB_PTR_AT(msg, UPB_SIZE(4, 8), struct google_protobuf_UInt32Value*) = value;
 }
 UPB_INLINE struct google_protobuf_UInt32Value* envoy_config_route_v3_HedgePolicy_mutable_initial_requests(envoy_config_route_v3_HedgePolicy *msg, upb_arena *arena) {
@@ -2387,6 +2611,7 @@ UPB_INLINE struct google_protobuf_UInt32Value* envoy_config_route_v3_HedgePolicy
   return sub;
 }
 UPB_INLINE void envoy_config_route_v3_HedgePolicy_set_additional_request_chance(envoy_config_route_v3_HedgePolicy *msg, struct envoy_type_v3_FractionalPercent* value) {
+  _upb_sethas(msg, 2);
   *UPB_PTR_AT(msg, UPB_SIZE(8, 16), struct envoy_type_v3_FractionalPercent*) = value;
 }
 UPB_INLINE struct envoy_type_v3_FractionalPercent* envoy_config_route_v3_HedgePolicy_mutable_additional_request_chance(envoy_config_route_v3_HedgePolicy *msg, upb_arena *arena) {
@@ -2399,7 +2624,7 @@ UPB_INLINE struct envoy_type_v3_FractionalPercent* envoy_config_route_v3_HedgePo
   return sub;
 }
 UPB_INLINE void envoy_config_route_v3_HedgePolicy_set_hedge_on_per_try_timeout(envoy_config_route_v3_HedgePolicy *msg, bool value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(0, 0), bool) = value;
+  *UPB_PTR_AT(msg, UPB_SIZE(1, 1), bool) = value;
 }
 
 /* envoy.config.route.v3.RedirectAction */
@@ -2412,6 +2637,12 @@ UPB_INLINE envoy_config_route_v3_RedirectAction *envoy_config_route_v3_RedirectA
   envoy_config_route_v3_RedirectAction *ret = envoy_config_route_v3_RedirectAction_new(arena);
   return (ret && upb_decode(buf, size, ret, &envoy_config_route_v3_RedirectAction_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE envoy_config_route_v3_RedirectAction *envoy_config_route_v3_RedirectAction_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  envoy_config_route_v3_RedirectAction *ret = envoy_config_route_v3_RedirectAction_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &envoy_config_route_v3_RedirectAction_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *envoy_config_route_v3_RedirectAction_serialize(const envoy_config_route_v3_RedirectAction *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &envoy_config_route_v3_RedirectAction_msginit, arena, len);
 }
@@ -2421,51 +2652,51 @@ typedef enum {
   envoy_config_route_v3_RedirectAction_scheme_rewrite_specifier_scheme_redirect = 7,
   envoy_config_route_v3_RedirectAction_scheme_rewrite_specifier_NOT_SET = 0
 } envoy_config_route_v3_RedirectAction_scheme_rewrite_specifier_oneofcases;
-UPB_INLINE envoy_config_route_v3_RedirectAction_scheme_rewrite_specifier_oneofcases envoy_config_route_v3_RedirectAction_scheme_rewrite_specifier_case(const envoy_config_route_v3_RedirectAction* msg) { return (envoy_config_route_v3_RedirectAction_scheme_rewrite_specifier_oneofcases)*UPB_PTR_AT(msg, UPB_SIZE(44, 72), int32_t); }
+UPB_INLINE envoy_config_route_v3_RedirectAction_scheme_rewrite_specifier_oneofcases envoy_config_route_v3_RedirectAction_scheme_rewrite_specifier_case(const envoy_config_route_v3_RedirectAction* msg) { return (envoy_config_route_v3_RedirectAction_scheme_rewrite_specifier_oneofcases)*UPB_PTR_AT(msg, UPB_SIZE(40, 72), int32_t); }
 
 typedef enum {
   envoy_config_route_v3_RedirectAction_path_rewrite_specifier_path_redirect = 2,
   envoy_config_route_v3_RedirectAction_path_rewrite_specifier_prefix_rewrite = 5,
   envoy_config_route_v3_RedirectAction_path_rewrite_specifier_NOT_SET = 0
 } envoy_config_route_v3_RedirectAction_path_rewrite_specifier_oneofcases;
-UPB_INLINE envoy_config_route_v3_RedirectAction_path_rewrite_specifier_oneofcases envoy_config_route_v3_RedirectAction_path_rewrite_specifier_case(const envoy_config_route_v3_RedirectAction* msg) { return (envoy_config_route_v3_RedirectAction_path_rewrite_specifier_oneofcases)*UPB_PTR_AT(msg, UPB_SIZE(32, 48), int32_t); }
+UPB_INLINE envoy_config_route_v3_RedirectAction_path_rewrite_specifier_oneofcases envoy_config_route_v3_RedirectAction_path_rewrite_specifier_case(const envoy_config_route_v3_RedirectAction* msg) { return (envoy_config_route_v3_RedirectAction_path_rewrite_specifier_oneofcases)*UPB_PTR_AT(msg, UPB_SIZE(28, 48), int32_t); }
 
-UPB_INLINE upb_strview envoy_config_route_v3_RedirectAction_host_redirect(const envoy_config_route_v3_RedirectAction *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(16, 16), upb_strview); }
-UPB_INLINE bool envoy_config_route_v3_RedirectAction_has_path_redirect(const envoy_config_route_v3_RedirectAction *msg) { return _upb_getoneofcase(msg, UPB_SIZE(32, 48)) == 2; }
-UPB_INLINE upb_strview envoy_config_route_v3_RedirectAction_path_redirect(const envoy_config_route_v3_RedirectAction *msg) { return UPB_READ_ONEOF(msg, upb_strview, UPB_SIZE(24, 32), UPB_SIZE(32, 48), 2, upb_strview_make("", strlen(""))); }
+UPB_INLINE upb_strview envoy_config_route_v3_RedirectAction_host_redirect(const envoy_config_route_v3_RedirectAction *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(12, 16), upb_strview); }
+UPB_INLINE bool envoy_config_route_v3_RedirectAction_has_path_redirect(const envoy_config_route_v3_RedirectAction *msg) { return _upb_getoneofcase(msg, UPB_SIZE(28, 48)) == 2; }
+UPB_INLINE upb_strview envoy_config_route_v3_RedirectAction_path_redirect(const envoy_config_route_v3_RedirectAction *msg) { return UPB_READ_ONEOF(msg, upb_strview, UPB_SIZE(20, 32), UPB_SIZE(28, 48), 2, upb_strview_make("", strlen(""))); }
 UPB_INLINE int32_t envoy_config_route_v3_RedirectAction_response_code(const envoy_config_route_v3_RedirectAction *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(0, 0), int32_t); }
-UPB_INLINE bool envoy_config_route_v3_RedirectAction_has_https_redirect(const envoy_config_route_v3_RedirectAction *msg) { return _upb_getoneofcase(msg, UPB_SIZE(44, 72)) == 4; }
-UPB_INLINE bool envoy_config_route_v3_RedirectAction_https_redirect(const envoy_config_route_v3_RedirectAction *msg) { return UPB_READ_ONEOF(msg, bool, UPB_SIZE(36, 56), UPB_SIZE(44, 72), 4, false); }
-UPB_INLINE bool envoy_config_route_v3_RedirectAction_has_prefix_rewrite(const envoy_config_route_v3_RedirectAction *msg) { return _upb_getoneofcase(msg, UPB_SIZE(32, 48)) == 5; }
-UPB_INLINE upb_strview envoy_config_route_v3_RedirectAction_prefix_rewrite(const envoy_config_route_v3_RedirectAction *msg) { return UPB_READ_ONEOF(msg, upb_strview, UPB_SIZE(24, 32), UPB_SIZE(32, 48), 5, upb_strview_make("", strlen(""))); }
-UPB_INLINE bool envoy_config_route_v3_RedirectAction_strip_query(const envoy_config_route_v3_RedirectAction *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(12, 12), bool); }
-UPB_INLINE bool envoy_config_route_v3_RedirectAction_has_scheme_redirect(const envoy_config_route_v3_RedirectAction *msg) { return _upb_getoneofcase(msg, UPB_SIZE(44, 72)) == 7; }
-UPB_INLINE upb_strview envoy_config_route_v3_RedirectAction_scheme_redirect(const envoy_config_route_v3_RedirectAction *msg) { return UPB_READ_ONEOF(msg, upb_strview, UPB_SIZE(36, 56), UPB_SIZE(44, 72), 7, upb_strview_make("", strlen(""))); }
-UPB_INLINE uint32_t envoy_config_route_v3_RedirectAction_port_redirect(const envoy_config_route_v3_RedirectAction *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(8, 8), uint32_t); }
+UPB_INLINE bool envoy_config_route_v3_RedirectAction_has_https_redirect(const envoy_config_route_v3_RedirectAction *msg) { return _upb_getoneofcase(msg, UPB_SIZE(40, 72)) == 4; }
+UPB_INLINE bool envoy_config_route_v3_RedirectAction_https_redirect(const envoy_config_route_v3_RedirectAction *msg) { return UPB_READ_ONEOF(msg, bool, UPB_SIZE(32, 56), UPB_SIZE(40, 72), 4, false); }
+UPB_INLINE bool envoy_config_route_v3_RedirectAction_has_prefix_rewrite(const envoy_config_route_v3_RedirectAction *msg) { return _upb_getoneofcase(msg, UPB_SIZE(28, 48)) == 5; }
+UPB_INLINE upb_strview envoy_config_route_v3_RedirectAction_prefix_rewrite(const envoy_config_route_v3_RedirectAction *msg) { return UPB_READ_ONEOF(msg, upb_strview, UPB_SIZE(20, 32), UPB_SIZE(28, 48), 5, upb_strview_make("", strlen(""))); }
+UPB_INLINE bool envoy_config_route_v3_RedirectAction_strip_query(const envoy_config_route_v3_RedirectAction *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(8, 8), bool); }
+UPB_INLINE bool envoy_config_route_v3_RedirectAction_has_scheme_redirect(const envoy_config_route_v3_RedirectAction *msg) { return _upb_getoneofcase(msg, UPB_SIZE(40, 72)) == 7; }
+UPB_INLINE upb_strview envoy_config_route_v3_RedirectAction_scheme_redirect(const envoy_config_route_v3_RedirectAction *msg) { return UPB_READ_ONEOF(msg, upb_strview, UPB_SIZE(32, 56), UPB_SIZE(40, 72), 7, upb_strview_make("", strlen(""))); }
+UPB_INLINE uint32_t envoy_config_route_v3_RedirectAction_port_redirect(const envoy_config_route_v3_RedirectAction *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(4, 4), uint32_t); }
 
 UPB_INLINE void envoy_config_route_v3_RedirectAction_set_host_redirect(envoy_config_route_v3_RedirectAction *msg, upb_strview value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(16, 16), upb_strview) = value;
+  *UPB_PTR_AT(msg, UPB_SIZE(12, 16), upb_strview) = value;
 }
 UPB_INLINE void envoy_config_route_v3_RedirectAction_set_path_redirect(envoy_config_route_v3_RedirectAction *msg, upb_strview value) {
-  UPB_WRITE_ONEOF(msg, upb_strview, UPB_SIZE(24, 32), value, UPB_SIZE(32, 48), 2);
+  UPB_WRITE_ONEOF(msg, upb_strview, UPB_SIZE(20, 32), value, UPB_SIZE(28, 48), 2);
 }
 UPB_INLINE void envoy_config_route_v3_RedirectAction_set_response_code(envoy_config_route_v3_RedirectAction *msg, int32_t value) {
   *UPB_PTR_AT(msg, UPB_SIZE(0, 0), int32_t) = value;
 }
 UPB_INLINE void envoy_config_route_v3_RedirectAction_set_https_redirect(envoy_config_route_v3_RedirectAction *msg, bool value) {
-  UPB_WRITE_ONEOF(msg, bool, UPB_SIZE(36, 56), value, UPB_SIZE(44, 72), 4);
+  UPB_WRITE_ONEOF(msg, bool, UPB_SIZE(32, 56), value, UPB_SIZE(40, 72), 4);
 }
 UPB_INLINE void envoy_config_route_v3_RedirectAction_set_prefix_rewrite(envoy_config_route_v3_RedirectAction *msg, upb_strview value) {
-  UPB_WRITE_ONEOF(msg, upb_strview, UPB_SIZE(24, 32), value, UPB_SIZE(32, 48), 5);
+  UPB_WRITE_ONEOF(msg, upb_strview, UPB_SIZE(20, 32), value, UPB_SIZE(28, 48), 5);
 }
 UPB_INLINE void envoy_config_route_v3_RedirectAction_set_strip_query(envoy_config_route_v3_RedirectAction *msg, bool value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(12, 12), bool) = value;
+  *UPB_PTR_AT(msg, UPB_SIZE(8, 8), bool) = value;
 }
 UPB_INLINE void envoy_config_route_v3_RedirectAction_set_scheme_redirect(envoy_config_route_v3_RedirectAction *msg, upb_strview value) {
-  UPB_WRITE_ONEOF(msg, upb_strview, UPB_SIZE(36, 56), value, UPB_SIZE(44, 72), 7);
+  UPB_WRITE_ONEOF(msg, upb_strview, UPB_SIZE(32, 56), value, UPB_SIZE(40, 72), 7);
 }
 UPB_INLINE void envoy_config_route_v3_RedirectAction_set_port_redirect(envoy_config_route_v3_RedirectAction *msg, uint32_t value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(8, 8), uint32_t) = value;
+  *UPB_PTR_AT(msg, UPB_SIZE(4, 4), uint32_t) = value;
 }
 
 /* envoy.config.route.v3.DirectResponseAction */
@@ -2478,19 +2709,26 @@ UPB_INLINE envoy_config_route_v3_DirectResponseAction *envoy_config_route_v3_Dir
   envoy_config_route_v3_DirectResponseAction *ret = envoy_config_route_v3_DirectResponseAction_new(arena);
   return (ret && upb_decode(buf, size, ret, &envoy_config_route_v3_DirectResponseAction_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE envoy_config_route_v3_DirectResponseAction *envoy_config_route_v3_DirectResponseAction_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  envoy_config_route_v3_DirectResponseAction *ret = envoy_config_route_v3_DirectResponseAction_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &envoy_config_route_v3_DirectResponseAction_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *envoy_config_route_v3_DirectResponseAction_serialize(const envoy_config_route_v3_DirectResponseAction *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &envoy_config_route_v3_DirectResponseAction_msginit, arena, len);
 }
 
-UPB_INLINE uint32_t envoy_config_route_v3_DirectResponseAction_status(const envoy_config_route_v3_DirectResponseAction *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(0, 0), uint32_t); }
-UPB_INLINE bool envoy_config_route_v3_DirectResponseAction_has_body(const envoy_config_route_v3_DirectResponseAction *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(4, 8)); }
-UPB_INLINE const struct envoy_config_core_v3_DataSource* envoy_config_route_v3_DirectResponseAction_body(const envoy_config_route_v3_DirectResponseAction *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(4, 8), const struct envoy_config_core_v3_DataSource*); }
+UPB_INLINE uint32_t envoy_config_route_v3_DirectResponseAction_status(const envoy_config_route_v3_DirectResponseAction *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(4, 4), uint32_t); }
+UPB_INLINE bool envoy_config_route_v3_DirectResponseAction_has_body(const envoy_config_route_v3_DirectResponseAction *msg) { return _upb_hasbit(msg, 1); }
+UPB_INLINE const struct envoy_config_core_v3_DataSource* envoy_config_route_v3_DirectResponseAction_body(const envoy_config_route_v3_DirectResponseAction *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(8, 8), const struct envoy_config_core_v3_DataSource*); }
 
 UPB_INLINE void envoy_config_route_v3_DirectResponseAction_set_status(envoy_config_route_v3_DirectResponseAction *msg, uint32_t value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(0, 0), uint32_t) = value;
+  *UPB_PTR_AT(msg, UPB_SIZE(4, 4), uint32_t) = value;
 }
 UPB_INLINE void envoy_config_route_v3_DirectResponseAction_set_body(envoy_config_route_v3_DirectResponseAction *msg, struct envoy_config_core_v3_DataSource* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(4, 8), struct envoy_config_core_v3_DataSource*) = value;
+  _upb_sethas(msg, 1);
+  *UPB_PTR_AT(msg, UPB_SIZE(8, 8), struct envoy_config_core_v3_DataSource*) = value;
 }
 UPB_INLINE struct envoy_config_core_v3_DataSource* envoy_config_route_v3_DirectResponseAction_mutable_body(envoy_config_route_v3_DirectResponseAction *msg, upb_arena *arena) {
   struct envoy_config_core_v3_DataSource* sub = (struct envoy_config_core_v3_DataSource*)envoy_config_route_v3_DirectResponseAction_body(msg);
@@ -2512,19 +2750,26 @@ UPB_INLINE envoy_config_route_v3_Decorator *envoy_config_route_v3_Decorator_pars
   envoy_config_route_v3_Decorator *ret = envoy_config_route_v3_Decorator_new(arena);
   return (ret && upb_decode(buf, size, ret, &envoy_config_route_v3_Decorator_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE envoy_config_route_v3_Decorator *envoy_config_route_v3_Decorator_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  envoy_config_route_v3_Decorator *ret = envoy_config_route_v3_Decorator_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &envoy_config_route_v3_Decorator_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *envoy_config_route_v3_Decorator_serialize(const envoy_config_route_v3_Decorator *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &envoy_config_route_v3_Decorator_msginit, arena, len);
 }
 
-UPB_INLINE upb_strview envoy_config_route_v3_Decorator_operation(const envoy_config_route_v3_Decorator *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(0, 0), upb_strview); }
-UPB_INLINE bool envoy_config_route_v3_Decorator_has_propagate(const envoy_config_route_v3_Decorator *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(8, 16)); }
-UPB_INLINE const struct google_protobuf_BoolValue* envoy_config_route_v3_Decorator_propagate(const envoy_config_route_v3_Decorator *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(8, 16), const struct google_protobuf_BoolValue*); }
+UPB_INLINE upb_strview envoy_config_route_v3_Decorator_operation(const envoy_config_route_v3_Decorator *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(4, 8), upb_strview); }
+UPB_INLINE bool envoy_config_route_v3_Decorator_has_propagate(const envoy_config_route_v3_Decorator *msg) { return _upb_hasbit(msg, 1); }
+UPB_INLINE const struct google_protobuf_BoolValue* envoy_config_route_v3_Decorator_propagate(const envoy_config_route_v3_Decorator *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(12, 24), const struct google_protobuf_BoolValue*); }
 
 UPB_INLINE void envoy_config_route_v3_Decorator_set_operation(envoy_config_route_v3_Decorator *msg, upb_strview value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(0, 0), upb_strview) = value;
+  *UPB_PTR_AT(msg, UPB_SIZE(4, 8), upb_strview) = value;
 }
 UPB_INLINE void envoy_config_route_v3_Decorator_set_propagate(envoy_config_route_v3_Decorator *msg, struct google_protobuf_BoolValue* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(8, 16), struct google_protobuf_BoolValue*) = value;
+  _upb_sethas(msg, 1);
+  *UPB_PTR_AT(msg, UPB_SIZE(12, 24), struct google_protobuf_BoolValue*) = value;
 }
 UPB_INLINE struct google_protobuf_BoolValue* envoy_config_route_v3_Decorator_mutable_propagate(envoy_config_route_v3_Decorator *msg, upb_arena *arena) {
   struct google_protobuf_BoolValue* sub = (struct google_protobuf_BoolValue*)envoy_config_route_v3_Decorator_propagate(msg);
@@ -2546,21 +2791,28 @@ UPB_INLINE envoy_config_route_v3_Tracing *envoy_config_route_v3_Tracing_parse(co
   envoy_config_route_v3_Tracing *ret = envoy_config_route_v3_Tracing_new(arena);
   return (ret && upb_decode(buf, size, ret, &envoy_config_route_v3_Tracing_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE envoy_config_route_v3_Tracing *envoy_config_route_v3_Tracing_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  envoy_config_route_v3_Tracing *ret = envoy_config_route_v3_Tracing_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &envoy_config_route_v3_Tracing_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *envoy_config_route_v3_Tracing_serialize(const envoy_config_route_v3_Tracing *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &envoy_config_route_v3_Tracing_msginit, arena, len);
 }
 
-UPB_INLINE bool envoy_config_route_v3_Tracing_has_client_sampling(const envoy_config_route_v3_Tracing *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(0, 0)); }
-UPB_INLINE const struct envoy_type_v3_FractionalPercent* envoy_config_route_v3_Tracing_client_sampling(const envoy_config_route_v3_Tracing *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(0, 0), const struct envoy_type_v3_FractionalPercent*); }
-UPB_INLINE bool envoy_config_route_v3_Tracing_has_random_sampling(const envoy_config_route_v3_Tracing *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(4, 8)); }
-UPB_INLINE const struct envoy_type_v3_FractionalPercent* envoy_config_route_v3_Tracing_random_sampling(const envoy_config_route_v3_Tracing *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(4, 8), const struct envoy_type_v3_FractionalPercent*); }
-UPB_INLINE bool envoy_config_route_v3_Tracing_has_overall_sampling(const envoy_config_route_v3_Tracing *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(8, 16)); }
-UPB_INLINE const struct envoy_type_v3_FractionalPercent* envoy_config_route_v3_Tracing_overall_sampling(const envoy_config_route_v3_Tracing *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(8, 16), const struct envoy_type_v3_FractionalPercent*); }
-UPB_INLINE bool envoy_config_route_v3_Tracing_has_custom_tags(const envoy_config_route_v3_Tracing *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(12, 24)); }
-UPB_INLINE const struct envoy_type_tracing_v3_CustomTag* const* envoy_config_route_v3_Tracing_custom_tags(const envoy_config_route_v3_Tracing *msg, size_t *len) { return (const struct envoy_type_tracing_v3_CustomTag* const*)_upb_array_accessor(msg, UPB_SIZE(12, 24), len); }
+UPB_INLINE bool envoy_config_route_v3_Tracing_has_client_sampling(const envoy_config_route_v3_Tracing *msg) { return _upb_hasbit(msg, 1); }
+UPB_INLINE const struct envoy_type_v3_FractionalPercent* envoy_config_route_v3_Tracing_client_sampling(const envoy_config_route_v3_Tracing *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(4, 8), const struct envoy_type_v3_FractionalPercent*); }
+UPB_INLINE bool envoy_config_route_v3_Tracing_has_random_sampling(const envoy_config_route_v3_Tracing *msg) { return _upb_hasbit(msg, 2); }
+UPB_INLINE const struct envoy_type_v3_FractionalPercent* envoy_config_route_v3_Tracing_random_sampling(const envoy_config_route_v3_Tracing *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(8, 16), const struct envoy_type_v3_FractionalPercent*); }
+UPB_INLINE bool envoy_config_route_v3_Tracing_has_overall_sampling(const envoy_config_route_v3_Tracing *msg) { return _upb_hasbit(msg, 3); }
+UPB_INLINE const struct envoy_type_v3_FractionalPercent* envoy_config_route_v3_Tracing_overall_sampling(const envoy_config_route_v3_Tracing *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(12, 24), const struct envoy_type_v3_FractionalPercent*); }
+UPB_INLINE bool envoy_config_route_v3_Tracing_has_custom_tags(const envoy_config_route_v3_Tracing *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(16, 32)); }
+UPB_INLINE const struct envoy_type_tracing_v3_CustomTag* const* envoy_config_route_v3_Tracing_custom_tags(const envoy_config_route_v3_Tracing *msg, size_t *len) { return (const struct envoy_type_tracing_v3_CustomTag* const*)_upb_array_accessor(msg, UPB_SIZE(16, 32), len); }
 
 UPB_INLINE void envoy_config_route_v3_Tracing_set_client_sampling(envoy_config_route_v3_Tracing *msg, struct envoy_type_v3_FractionalPercent* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(0, 0), struct envoy_type_v3_FractionalPercent*) = value;
+  _upb_sethas(msg, 1);
+  *UPB_PTR_AT(msg, UPB_SIZE(4, 8), struct envoy_type_v3_FractionalPercent*) = value;
 }
 UPB_INLINE struct envoy_type_v3_FractionalPercent* envoy_config_route_v3_Tracing_mutable_client_sampling(envoy_config_route_v3_Tracing *msg, upb_arena *arena) {
   struct envoy_type_v3_FractionalPercent* sub = (struct envoy_type_v3_FractionalPercent*)envoy_config_route_v3_Tracing_client_sampling(msg);
@@ -2572,7 +2824,8 @@ UPB_INLINE struct envoy_type_v3_FractionalPercent* envoy_config_route_v3_Tracing
   return sub;
 }
 UPB_INLINE void envoy_config_route_v3_Tracing_set_random_sampling(envoy_config_route_v3_Tracing *msg, struct envoy_type_v3_FractionalPercent* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(4, 8), struct envoy_type_v3_FractionalPercent*) = value;
+  _upb_sethas(msg, 2);
+  *UPB_PTR_AT(msg, UPB_SIZE(8, 16), struct envoy_type_v3_FractionalPercent*) = value;
 }
 UPB_INLINE struct envoy_type_v3_FractionalPercent* envoy_config_route_v3_Tracing_mutable_random_sampling(envoy_config_route_v3_Tracing *msg, upb_arena *arena) {
   struct envoy_type_v3_FractionalPercent* sub = (struct envoy_type_v3_FractionalPercent*)envoy_config_route_v3_Tracing_random_sampling(msg);
@@ -2584,7 +2837,8 @@ UPB_INLINE struct envoy_type_v3_FractionalPercent* envoy_config_route_v3_Tracing
   return sub;
 }
 UPB_INLINE void envoy_config_route_v3_Tracing_set_overall_sampling(envoy_config_route_v3_Tracing *msg, struct envoy_type_v3_FractionalPercent* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(8, 16), struct envoy_type_v3_FractionalPercent*) = value;
+  _upb_sethas(msg, 3);
+  *UPB_PTR_AT(msg, UPB_SIZE(12, 24), struct envoy_type_v3_FractionalPercent*) = value;
 }
 UPB_INLINE struct envoy_type_v3_FractionalPercent* envoy_config_route_v3_Tracing_mutable_overall_sampling(envoy_config_route_v3_Tracing *msg, upb_arena *arena) {
   struct envoy_type_v3_FractionalPercent* sub = (struct envoy_type_v3_FractionalPercent*)envoy_config_route_v3_Tracing_overall_sampling(msg);
@@ -2596,15 +2850,15 @@ UPB_INLINE struct envoy_type_v3_FractionalPercent* envoy_config_route_v3_Tracing
   return sub;
 }
 UPB_INLINE struct envoy_type_tracing_v3_CustomTag** envoy_config_route_v3_Tracing_mutable_custom_tags(envoy_config_route_v3_Tracing *msg, size_t *len) {
-  return (struct envoy_type_tracing_v3_CustomTag**)_upb_array_mutable_accessor(msg, UPB_SIZE(12, 24), len);
+  return (struct envoy_type_tracing_v3_CustomTag**)_upb_array_mutable_accessor(msg, UPB_SIZE(16, 32), len);
 }
 UPB_INLINE struct envoy_type_tracing_v3_CustomTag** envoy_config_route_v3_Tracing_resize_custom_tags(envoy_config_route_v3_Tracing *msg, size_t len, upb_arena *arena) {
-  return (struct envoy_type_tracing_v3_CustomTag**)_upb_array_resize_accessor(msg, UPB_SIZE(12, 24), len, UPB_TYPE_MESSAGE, arena);
+  return (struct envoy_type_tracing_v3_CustomTag**)_upb_array_resize_accessor2(msg, UPB_SIZE(16, 32), len, UPB_SIZE(2, 3), arena);
 }
 UPB_INLINE struct envoy_type_tracing_v3_CustomTag* envoy_config_route_v3_Tracing_add_custom_tags(envoy_config_route_v3_Tracing *msg, upb_arena *arena) {
   struct envoy_type_tracing_v3_CustomTag* sub = (struct envoy_type_tracing_v3_CustomTag*)_upb_msg_new(&envoy_type_tracing_v3_CustomTag_msginit, arena);
-  bool ok = _upb_array_append_accessor(
-      msg, UPB_SIZE(12, 24), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena);
+  bool ok = _upb_array_append_accessor2(
+      msg, UPB_SIZE(16, 32), UPB_SIZE(2, 3), &sub, arena);
   if (!ok) return NULL;
   return sub;
 }
@@ -2619,6 +2873,12 @@ UPB_INLINE envoy_config_route_v3_VirtualCluster *envoy_config_route_v3_VirtualCl
   envoy_config_route_v3_VirtualCluster *ret = envoy_config_route_v3_VirtualCluster_new(arena);
   return (ret && upb_decode(buf, size, ret, &envoy_config_route_v3_VirtualCluster_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE envoy_config_route_v3_VirtualCluster *envoy_config_route_v3_VirtualCluster_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  envoy_config_route_v3_VirtualCluster *ret = envoy_config_route_v3_VirtualCluster_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &envoy_config_route_v3_VirtualCluster_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *envoy_config_route_v3_VirtualCluster_serialize(const envoy_config_route_v3_VirtualCluster *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &envoy_config_route_v3_VirtualCluster_msginit, arena, len);
 }
@@ -2634,12 +2894,12 @@ UPB_INLINE envoy_config_route_v3_HeaderMatcher** envoy_config_route_v3_VirtualCl
   return (envoy_config_route_v3_HeaderMatcher**)_upb_array_mutable_accessor(msg, UPB_SIZE(8, 16), len);
 }
 UPB_INLINE envoy_config_route_v3_HeaderMatcher** envoy_config_route_v3_VirtualCluster_resize_headers(envoy_config_route_v3_VirtualCluster *msg, size_t len, upb_arena *arena) {
-  return (envoy_config_route_v3_HeaderMatcher**)_upb_array_resize_accessor(msg, UPB_SIZE(8, 16), len, UPB_TYPE_MESSAGE, arena);
+  return (envoy_config_route_v3_HeaderMatcher**)_upb_array_resize_accessor2(msg, UPB_SIZE(8, 16), len, UPB_SIZE(2, 3), arena);
 }
 UPB_INLINE struct envoy_config_route_v3_HeaderMatcher* envoy_config_route_v3_VirtualCluster_add_headers(envoy_config_route_v3_VirtualCluster *msg, upb_arena *arena) {
   struct envoy_config_route_v3_HeaderMatcher* sub = (struct envoy_config_route_v3_HeaderMatcher*)_upb_msg_new(&envoy_config_route_v3_HeaderMatcher_msginit, arena);
-  bool ok = _upb_array_append_accessor(
-      msg, UPB_SIZE(8, 16), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena);
+  bool ok = _upb_array_append_accessor2(
+      msg, UPB_SIZE(8, 16), UPB_SIZE(2, 3), &sub, arena);
   if (!ok) return NULL;
   return sub;
 }
@@ -2654,20 +2914,27 @@ UPB_INLINE envoy_config_route_v3_RateLimit *envoy_config_route_v3_RateLimit_pars
   envoy_config_route_v3_RateLimit *ret = envoy_config_route_v3_RateLimit_new(arena);
   return (ret && upb_decode(buf, size, ret, &envoy_config_route_v3_RateLimit_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE envoy_config_route_v3_RateLimit *envoy_config_route_v3_RateLimit_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  envoy_config_route_v3_RateLimit *ret = envoy_config_route_v3_RateLimit_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &envoy_config_route_v3_RateLimit_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *envoy_config_route_v3_RateLimit_serialize(const envoy_config_route_v3_RateLimit *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &envoy_config_route_v3_RateLimit_msginit, arena, len);
 }
 
-UPB_INLINE bool envoy_config_route_v3_RateLimit_has_stage(const envoy_config_route_v3_RateLimit *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(8, 16)); }
-UPB_INLINE const struct google_protobuf_UInt32Value* envoy_config_route_v3_RateLimit_stage(const envoy_config_route_v3_RateLimit *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(8, 16), const struct google_protobuf_UInt32Value*); }
-UPB_INLINE upb_strview envoy_config_route_v3_RateLimit_disable_key(const envoy_config_route_v3_RateLimit *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(0, 0), upb_strview); }
-UPB_INLINE bool envoy_config_route_v3_RateLimit_has_actions(const envoy_config_route_v3_RateLimit *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(16, 32)); }
-UPB_INLINE const envoy_config_route_v3_RateLimit_Action* const* envoy_config_route_v3_RateLimit_actions(const envoy_config_route_v3_RateLimit *msg, size_t *len) { return (const envoy_config_route_v3_RateLimit_Action* const*)_upb_array_accessor(msg, UPB_SIZE(16, 32), len); }
-UPB_INLINE bool envoy_config_route_v3_RateLimit_has_limit(const envoy_config_route_v3_RateLimit *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(12, 24)); }
-UPB_INLINE const envoy_config_route_v3_RateLimit_Override* envoy_config_route_v3_RateLimit_limit(const envoy_config_route_v3_RateLimit *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(12, 24), const envoy_config_route_v3_RateLimit_Override*); }
+UPB_INLINE bool envoy_config_route_v3_RateLimit_has_stage(const envoy_config_route_v3_RateLimit *msg) { return _upb_hasbit(msg, 1); }
+UPB_INLINE const struct google_protobuf_UInt32Value* envoy_config_route_v3_RateLimit_stage(const envoy_config_route_v3_RateLimit *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(12, 24), const struct google_protobuf_UInt32Value*); }
+UPB_INLINE upb_strview envoy_config_route_v3_RateLimit_disable_key(const envoy_config_route_v3_RateLimit *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(4, 8), upb_strview); }
+UPB_INLINE bool envoy_config_route_v3_RateLimit_has_actions(const envoy_config_route_v3_RateLimit *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(20, 40)); }
+UPB_INLINE const envoy_config_route_v3_RateLimit_Action* const* envoy_config_route_v3_RateLimit_actions(const envoy_config_route_v3_RateLimit *msg, size_t *len) { return (const envoy_config_route_v3_RateLimit_Action* const*)_upb_array_accessor(msg, UPB_SIZE(20, 40), len); }
+UPB_INLINE bool envoy_config_route_v3_RateLimit_has_limit(const envoy_config_route_v3_RateLimit *msg) { return _upb_hasbit(msg, 2); }
+UPB_INLINE const envoy_config_route_v3_RateLimit_Override* envoy_config_route_v3_RateLimit_limit(const envoy_config_route_v3_RateLimit *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(16, 32), const envoy_config_route_v3_RateLimit_Override*); }
 
 UPB_INLINE void envoy_config_route_v3_RateLimit_set_stage(envoy_config_route_v3_RateLimit *msg, struct google_protobuf_UInt32Value* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(8, 16), struct google_protobuf_UInt32Value*) = value;
+  _upb_sethas(msg, 1);
+  *UPB_PTR_AT(msg, UPB_SIZE(12, 24), struct google_protobuf_UInt32Value*) = value;
 }
 UPB_INLINE struct google_protobuf_UInt32Value* envoy_config_route_v3_RateLimit_mutable_stage(envoy_config_route_v3_RateLimit *msg, upb_arena *arena) {
   struct google_protobuf_UInt32Value* sub = (struct google_protobuf_UInt32Value*)envoy_config_route_v3_RateLimit_stage(msg);
@@ -2679,23 +2946,24 @@ UPB_INLINE struct google_protobuf_UInt32Value* envoy_config_route_v3_RateLimit_m
   return sub;
 }
 UPB_INLINE void envoy_config_route_v3_RateLimit_set_disable_key(envoy_config_route_v3_RateLimit *msg, upb_strview value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(0, 0), upb_strview) = value;
+  *UPB_PTR_AT(msg, UPB_SIZE(4, 8), upb_strview) = value;
 }
 UPB_INLINE envoy_config_route_v3_RateLimit_Action** envoy_config_route_v3_RateLimit_mutable_actions(envoy_config_route_v3_RateLimit *msg, size_t *len) {
-  return (envoy_config_route_v3_RateLimit_Action**)_upb_array_mutable_accessor(msg, UPB_SIZE(16, 32), len);
+  return (envoy_config_route_v3_RateLimit_Action**)_upb_array_mutable_accessor(msg, UPB_SIZE(20, 40), len);
 }
 UPB_INLINE envoy_config_route_v3_RateLimit_Action** envoy_config_route_v3_RateLimit_resize_actions(envoy_config_route_v3_RateLimit *msg, size_t len, upb_arena *arena) {
-  return (envoy_config_route_v3_RateLimit_Action**)_upb_array_resize_accessor(msg, UPB_SIZE(16, 32), len, UPB_TYPE_MESSAGE, arena);
+  return (envoy_config_route_v3_RateLimit_Action**)_upb_array_resize_accessor2(msg, UPB_SIZE(20, 40), len, UPB_SIZE(2, 3), arena);
 }
 UPB_INLINE struct envoy_config_route_v3_RateLimit_Action* envoy_config_route_v3_RateLimit_add_actions(envoy_config_route_v3_RateLimit *msg, upb_arena *arena) {
   struct envoy_config_route_v3_RateLimit_Action* sub = (struct envoy_config_route_v3_RateLimit_Action*)_upb_msg_new(&envoy_config_route_v3_RateLimit_Action_msginit, arena);
-  bool ok = _upb_array_append_accessor(
-      msg, UPB_SIZE(16, 32), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena);
+  bool ok = _upb_array_append_accessor2(
+      msg, UPB_SIZE(20, 40), UPB_SIZE(2, 3), &sub, arena);
   if (!ok) return NULL;
   return sub;
 }
 UPB_INLINE void envoy_config_route_v3_RateLimit_set_limit(envoy_config_route_v3_RateLimit *msg, envoy_config_route_v3_RateLimit_Override* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(12, 24), envoy_config_route_v3_RateLimit_Override*) = value;
+  _upb_sethas(msg, 2);
+  *UPB_PTR_AT(msg, UPB_SIZE(16, 32), envoy_config_route_v3_RateLimit_Override*) = value;
 }
 UPB_INLINE struct envoy_config_route_v3_RateLimit_Override* envoy_config_route_v3_RateLimit_mutable_limit(envoy_config_route_v3_RateLimit *msg, upb_arena *arena) {
   struct envoy_config_route_v3_RateLimit_Override* sub = (struct envoy_config_route_v3_RateLimit_Override*)envoy_config_route_v3_RateLimit_limit(msg);
@@ -2717,6 +2985,12 @@ UPB_INLINE envoy_config_route_v3_RateLimit_Action *envoy_config_route_v3_RateLim
   envoy_config_route_v3_RateLimit_Action *ret = envoy_config_route_v3_RateLimit_Action_new(arena);
   return (ret && upb_decode(buf, size, ret, &envoy_config_route_v3_RateLimit_Action_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE envoy_config_route_v3_RateLimit_Action *envoy_config_route_v3_RateLimit_Action_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  envoy_config_route_v3_RateLimit_Action *ret = envoy_config_route_v3_RateLimit_Action_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &envoy_config_route_v3_RateLimit_Action_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *envoy_config_route_v3_RateLimit_Action_serialize(const envoy_config_route_v3_RateLimit_Action *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &envoy_config_route_v3_RateLimit_Action_msginit, arena, len);
 }
@@ -2843,6 +3117,12 @@ UPB_INLINE envoy_config_route_v3_RateLimit_Action_SourceCluster *envoy_config_ro
   envoy_config_route_v3_RateLimit_Action_SourceCluster *ret = envoy_config_route_v3_RateLimit_Action_SourceCluster_new(arena);
   return (ret && upb_decode(buf, size, ret, &envoy_config_route_v3_RateLimit_Action_SourceCluster_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE envoy_config_route_v3_RateLimit_Action_SourceCluster *envoy_config_route_v3_RateLimit_Action_SourceCluster_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  envoy_config_route_v3_RateLimit_Action_SourceCluster *ret = envoy_config_route_v3_RateLimit_Action_SourceCluster_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &envoy_config_route_v3_RateLimit_Action_SourceCluster_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *envoy_config_route_v3_RateLimit_Action_SourceCluster_serialize(const envoy_config_route_v3_RateLimit_Action_SourceCluster *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &envoy_config_route_v3_RateLimit_Action_SourceCluster_msginit, arena, len);
 }
@@ -2859,6 +3139,12 @@ UPB_INLINE envoy_config_route_v3_RateLimit_Action_DestinationCluster *envoy_conf
   envoy_config_route_v3_RateLimit_Action_DestinationCluster *ret = envoy_config_route_v3_RateLimit_Action_DestinationCluster_new(arena);
   return (ret && upb_decode(buf, size, ret, &envoy_config_route_v3_RateLimit_Action_DestinationCluster_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE envoy_config_route_v3_RateLimit_Action_DestinationCluster *envoy_config_route_v3_RateLimit_Action_DestinationCluster_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  envoy_config_route_v3_RateLimit_Action_DestinationCluster *ret = envoy_config_route_v3_RateLimit_Action_DestinationCluster_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &envoy_config_route_v3_RateLimit_Action_DestinationCluster_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *envoy_config_route_v3_RateLimit_Action_DestinationCluster_serialize(const envoy_config_route_v3_RateLimit_Action_DestinationCluster *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &envoy_config_route_v3_RateLimit_Action_DestinationCluster_msginit, arena, len);
 }
@@ -2875,6 +3161,12 @@ UPB_INLINE envoy_config_route_v3_RateLimit_Action_RequestHeaders *envoy_config_r
   envoy_config_route_v3_RateLimit_Action_RequestHeaders *ret = envoy_config_route_v3_RateLimit_Action_RequestHeaders_new(arena);
   return (ret && upb_decode(buf, size, ret, &envoy_config_route_v3_RateLimit_Action_RequestHeaders_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE envoy_config_route_v3_RateLimit_Action_RequestHeaders *envoy_config_route_v3_RateLimit_Action_RequestHeaders_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  envoy_config_route_v3_RateLimit_Action_RequestHeaders *ret = envoy_config_route_v3_RateLimit_Action_RequestHeaders_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &envoy_config_route_v3_RateLimit_Action_RequestHeaders_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *envoy_config_route_v3_RateLimit_Action_RequestHeaders_serialize(const envoy_config_route_v3_RateLimit_Action_RequestHeaders *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &envoy_config_route_v3_RateLimit_Action_RequestHeaders_msginit, arena, len);
 }
@@ -2903,6 +3195,12 @@ UPB_INLINE envoy_config_route_v3_RateLimit_Action_RemoteAddress *envoy_config_ro
   envoy_config_route_v3_RateLimit_Action_RemoteAddress *ret = envoy_config_route_v3_RateLimit_Action_RemoteAddress_new(arena);
   return (ret && upb_decode(buf, size, ret, &envoy_config_route_v3_RateLimit_Action_RemoteAddress_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE envoy_config_route_v3_RateLimit_Action_RemoteAddress *envoy_config_route_v3_RateLimit_Action_RemoteAddress_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  envoy_config_route_v3_RateLimit_Action_RemoteAddress *ret = envoy_config_route_v3_RateLimit_Action_RemoteAddress_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &envoy_config_route_v3_RateLimit_Action_RemoteAddress_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *envoy_config_route_v3_RateLimit_Action_RemoteAddress_serialize(const envoy_config_route_v3_RateLimit_Action_RemoteAddress *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &envoy_config_route_v3_RateLimit_Action_RemoteAddress_msginit, arena, len);
 }
@@ -2919,6 +3217,12 @@ UPB_INLINE envoy_config_route_v3_RateLimit_Action_GenericKey *envoy_config_route
   envoy_config_route_v3_RateLimit_Action_GenericKey *ret = envoy_config_route_v3_RateLimit_Action_GenericKey_new(arena);
   return (ret && upb_decode(buf, size, ret, &envoy_config_route_v3_RateLimit_Action_GenericKey_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE envoy_config_route_v3_RateLimit_Action_GenericKey *envoy_config_route_v3_RateLimit_Action_GenericKey_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  envoy_config_route_v3_RateLimit_Action_GenericKey *ret = envoy_config_route_v3_RateLimit_Action_GenericKey_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &envoy_config_route_v3_RateLimit_Action_GenericKey_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *envoy_config_route_v3_RateLimit_Action_GenericKey_serialize(const envoy_config_route_v3_RateLimit_Action_GenericKey *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &envoy_config_route_v3_RateLimit_Action_GenericKey_msginit, arena, len);
 }
@@ -2943,21 +3247,28 @@ UPB_INLINE envoy_config_route_v3_RateLimit_Action_HeaderValueMatch *envoy_config
   envoy_config_route_v3_RateLimit_Action_HeaderValueMatch *ret = envoy_config_route_v3_RateLimit_Action_HeaderValueMatch_new(arena);
   return (ret && upb_decode(buf, size, ret, &envoy_config_route_v3_RateLimit_Action_HeaderValueMatch_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE envoy_config_route_v3_RateLimit_Action_HeaderValueMatch *envoy_config_route_v3_RateLimit_Action_HeaderValueMatch_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  envoy_config_route_v3_RateLimit_Action_HeaderValueMatch *ret = envoy_config_route_v3_RateLimit_Action_HeaderValueMatch_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &envoy_config_route_v3_RateLimit_Action_HeaderValueMatch_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *envoy_config_route_v3_RateLimit_Action_HeaderValueMatch_serialize(const envoy_config_route_v3_RateLimit_Action_HeaderValueMatch *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &envoy_config_route_v3_RateLimit_Action_HeaderValueMatch_msginit, arena, len);
 }
 
-UPB_INLINE upb_strview envoy_config_route_v3_RateLimit_Action_HeaderValueMatch_descriptor_value(const envoy_config_route_v3_RateLimit_Action_HeaderValueMatch *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(0, 0), upb_strview); }
-UPB_INLINE bool envoy_config_route_v3_RateLimit_Action_HeaderValueMatch_has_expect_match(const envoy_config_route_v3_RateLimit_Action_HeaderValueMatch *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(8, 16)); }
-UPB_INLINE const struct google_protobuf_BoolValue* envoy_config_route_v3_RateLimit_Action_HeaderValueMatch_expect_match(const envoy_config_route_v3_RateLimit_Action_HeaderValueMatch *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(8, 16), const struct google_protobuf_BoolValue*); }
-UPB_INLINE bool envoy_config_route_v3_RateLimit_Action_HeaderValueMatch_has_headers(const envoy_config_route_v3_RateLimit_Action_HeaderValueMatch *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(12, 24)); }
-UPB_INLINE const envoy_config_route_v3_HeaderMatcher* const* envoy_config_route_v3_RateLimit_Action_HeaderValueMatch_headers(const envoy_config_route_v3_RateLimit_Action_HeaderValueMatch *msg, size_t *len) { return (const envoy_config_route_v3_HeaderMatcher* const*)_upb_array_accessor(msg, UPB_SIZE(12, 24), len); }
+UPB_INLINE upb_strview envoy_config_route_v3_RateLimit_Action_HeaderValueMatch_descriptor_value(const envoy_config_route_v3_RateLimit_Action_HeaderValueMatch *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(4, 8), upb_strview); }
+UPB_INLINE bool envoy_config_route_v3_RateLimit_Action_HeaderValueMatch_has_expect_match(const envoy_config_route_v3_RateLimit_Action_HeaderValueMatch *msg) { return _upb_hasbit(msg, 1); }
+UPB_INLINE const struct google_protobuf_BoolValue* envoy_config_route_v3_RateLimit_Action_HeaderValueMatch_expect_match(const envoy_config_route_v3_RateLimit_Action_HeaderValueMatch *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(12, 24), const struct google_protobuf_BoolValue*); }
+UPB_INLINE bool envoy_config_route_v3_RateLimit_Action_HeaderValueMatch_has_headers(const envoy_config_route_v3_RateLimit_Action_HeaderValueMatch *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(16, 32)); }
+UPB_INLINE const envoy_config_route_v3_HeaderMatcher* const* envoy_config_route_v3_RateLimit_Action_HeaderValueMatch_headers(const envoy_config_route_v3_RateLimit_Action_HeaderValueMatch *msg, size_t *len) { return (const envoy_config_route_v3_HeaderMatcher* const*)_upb_array_accessor(msg, UPB_SIZE(16, 32), len); }
 
 UPB_INLINE void envoy_config_route_v3_RateLimit_Action_HeaderValueMatch_set_descriptor_value(envoy_config_route_v3_RateLimit_Action_HeaderValueMatch *msg, upb_strview value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(0, 0), upb_strview) = value;
+  *UPB_PTR_AT(msg, UPB_SIZE(4, 8), upb_strview) = value;
 }
 UPB_INLINE void envoy_config_route_v3_RateLimit_Action_HeaderValueMatch_set_expect_match(envoy_config_route_v3_RateLimit_Action_HeaderValueMatch *msg, struct google_protobuf_BoolValue* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(8, 16), struct google_protobuf_BoolValue*) = value;
+  _upb_sethas(msg, 1);
+  *UPB_PTR_AT(msg, UPB_SIZE(12, 24), struct google_protobuf_BoolValue*) = value;
 }
 UPB_INLINE struct google_protobuf_BoolValue* envoy_config_route_v3_RateLimit_Action_HeaderValueMatch_mutable_expect_match(envoy_config_route_v3_RateLimit_Action_HeaderValueMatch *msg, upb_arena *arena) {
   struct google_protobuf_BoolValue* sub = (struct google_protobuf_BoolValue*)envoy_config_route_v3_RateLimit_Action_HeaderValueMatch_expect_match(msg);
@@ -2969,15 +3280,15 @@ UPB_INLINE struct google_protobuf_BoolValue* envoy_config_route_v3_RateLimit_Act
   return sub;
 }
 UPB_INLINE envoy_config_route_v3_HeaderMatcher** envoy_config_route_v3_RateLimit_Action_HeaderValueMatch_mutable_headers(envoy_config_route_v3_RateLimit_Action_HeaderValueMatch *msg, size_t *len) {
-  return (envoy_config_route_v3_HeaderMatcher**)_upb_array_mutable_accessor(msg, UPB_SIZE(12, 24), len);
+  return (envoy_config_route_v3_HeaderMatcher**)_upb_array_mutable_accessor(msg, UPB_SIZE(16, 32), len);
 }
 UPB_INLINE envoy_config_route_v3_HeaderMatcher** envoy_config_route_v3_RateLimit_Action_HeaderValueMatch_resize_headers(envoy_config_route_v3_RateLimit_Action_HeaderValueMatch *msg, size_t len, upb_arena *arena) {
-  return (envoy_config_route_v3_HeaderMatcher**)_upb_array_resize_accessor(msg, UPB_SIZE(12, 24), len, UPB_TYPE_MESSAGE, arena);
+  return (envoy_config_route_v3_HeaderMatcher**)_upb_array_resize_accessor2(msg, UPB_SIZE(16, 32), len, UPB_SIZE(2, 3), arena);
 }
 UPB_INLINE struct envoy_config_route_v3_HeaderMatcher* envoy_config_route_v3_RateLimit_Action_HeaderValueMatch_add_headers(envoy_config_route_v3_RateLimit_Action_HeaderValueMatch *msg, upb_arena *arena) {
   struct envoy_config_route_v3_HeaderMatcher* sub = (struct envoy_config_route_v3_HeaderMatcher*)_upb_msg_new(&envoy_config_route_v3_HeaderMatcher_msginit, arena);
-  bool ok = _upb_array_append_accessor(
-      msg, UPB_SIZE(12, 24), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena);
+  bool ok = _upb_array_append_accessor2(
+      msg, UPB_SIZE(16, 32), UPB_SIZE(2, 3), &sub, arena);
   if (!ok) return NULL;
   return sub;
 }
@@ -2992,20 +3303,27 @@ UPB_INLINE envoy_config_route_v3_RateLimit_Action_DynamicMetaData *envoy_config_
   envoy_config_route_v3_RateLimit_Action_DynamicMetaData *ret = envoy_config_route_v3_RateLimit_Action_DynamicMetaData_new(arena);
   return (ret && upb_decode(buf, size, ret, &envoy_config_route_v3_RateLimit_Action_DynamicMetaData_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE envoy_config_route_v3_RateLimit_Action_DynamicMetaData *envoy_config_route_v3_RateLimit_Action_DynamicMetaData_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  envoy_config_route_v3_RateLimit_Action_DynamicMetaData *ret = envoy_config_route_v3_RateLimit_Action_DynamicMetaData_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &envoy_config_route_v3_RateLimit_Action_DynamicMetaData_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *envoy_config_route_v3_RateLimit_Action_DynamicMetaData_serialize(const envoy_config_route_v3_RateLimit_Action_DynamicMetaData *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &envoy_config_route_v3_RateLimit_Action_DynamicMetaData_msginit, arena, len);
 }
 
-UPB_INLINE upb_strview envoy_config_route_v3_RateLimit_Action_DynamicMetaData_descriptor_key(const envoy_config_route_v3_RateLimit_Action_DynamicMetaData *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(0, 0), upb_strview); }
-UPB_INLINE bool envoy_config_route_v3_RateLimit_Action_DynamicMetaData_has_metadata_key(const envoy_config_route_v3_RateLimit_Action_DynamicMetaData *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(16, 32)); }
-UPB_INLINE const struct envoy_type_metadata_v3_MetadataKey* envoy_config_route_v3_RateLimit_Action_DynamicMetaData_metadata_key(const envoy_config_route_v3_RateLimit_Action_DynamicMetaData *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(16, 32), const struct envoy_type_metadata_v3_MetadataKey*); }
-UPB_INLINE upb_strview envoy_config_route_v3_RateLimit_Action_DynamicMetaData_default_value(const envoy_config_route_v3_RateLimit_Action_DynamicMetaData *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(8, 16), upb_strview); }
+UPB_INLINE upb_strview envoy_config_route_v3_RateLimit_Action_DynamicMetaData_descriptor_key(const envoy_config_route_v3_RateLimit_Action_DynamicMetaData *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(4, 8), upb_strview); }
+UPB_INLINE bool envoy_config_route_v3_RateLimit_Action_DynamicMetaData_has_metadata_key(const envoy_config_route_v3_RateLimit_Action_DynamicMetaData *msg) { return _upb_hasbit(msg, 1); }
+UPB_INLINE const struct envoy_type_metadata_v3_MetadataKey* envoy_config_route_v3_RateLimit_Action_DynamicMetaData_metadata_key(const envoy_config_route_v3_RateLimit_Action_DynamicMetaData *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(20, 40), const struct envoy_type_metadata_v3_MetadataKey*); }
+UPB_INLINE upb_strview envoy_config_route_v3_RateLimit_Action_DynamicMetaData_default_value(const envoy_config_route_v3_RateLimit_Action_DynamicMetaData *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(12, 24), upb_strview); }
 
 UPB_INLINE void envoy_config_route_v3_RateLimit_Action_DynamicMetaData_set_descriptor_key(envoy_config_route_v3_RateLimit_Action_DynamicMetaData *msg, upb_strview value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(0, 0), upb_strview) = value;
+  *UPB_PTR_AT(msg, UPB_SIZE(4, 8), upb_strview) = value;
 }
 UPB_INLINE void envoy_config_route_v3_RateLimit_Action_DynamicMetaData_set_metadata_key(envoy_config_route_v3_RateLimit_Action_DynamicMetaData *msg, struct envoy_type_metadata_v3_MetadataKey* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(16, 32), struct envoy_type_metadata_v3_MetadataKey*) = value;
+  _upb_sethas(msg, 1);
+  *UPB_PTR_AT(msg, UPB_SIZE(20, 40), struct envoy_type_metadata_v3_MetadataKey*) = value;
 }
 UPB_INLINE struct envoy_type_metadata_v3_MetadataKey* envoy_config_route_v3_RateLimit_Action_DynamicMetaData_mutable_metadata_key(envoy_config_route_v3_RateLimit_Action_DynamicMetaData *msg, upb_arena *arena) {
   struct envoy_type_metadata_v3_MetadataKey* sub = (struct envoy_type_metadata_v3_MetadataKey*)envoy_config_route_v3_RateLimit_Action_DynamicMetaData_metadata_key(msg);
@@ -3017,7 +3335,7 @@ UPB_INLINE struct envoy_type_metadata_v3_MetadataKey* envoy_config_route_v3_Rate
   return sub;
 }
 UPB_INLINE void envoy_config_route_v3_RateLimit_Action_DynamicMetaData_set_default_value(envoy_config_route_v3_RateLimit_Action_DynamicMetaData *msg, upb_strview value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(8, 16), upb_strview) = value;
+  *UPB_PTR_AT(msg, UPB_SIZE(12, 24), upb_strview) = value;
 }
 
 /* envoy.config.route.v3.RateLimit.Override */
@@ -3030,6 +3348,12 @@ UPB_INLINE envoy_config_route_v3_RateLimit_Override *envoy_config_route_v3_RateL
   envoy_config_route_v3_RateLimit_Override *ret = envoy_config_route_v3_RateLimit_Override_new(arena);
   return (ret && upb_decode(buf, size, ret, &envoy_config_route_v3_RateLimit_Override_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE envoy_config_route_v3_RateLimit_Override *envoy_config_route_v3_RateLimit_Override_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  envoy_config_route_v3_RateLimit_Override *ret = envoy_config_route_v3_RateLimit_Override_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &envoy_config_route_v3_RateLimit_Override_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *envoy_config_route_v3_RateLimit_Override_serialize(const envoy_config_route_v3_RateLimit_Override *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &envoy_config_route_v3_RateLimit_Override_msginit, arena, len);
 }
@@ -3066,15 +3390,22 @@ UPB_INLINE envoy_config_route_v3_RateLimit_Override_DynamicMetadata *envoy_confi
   envoy_config_route_v3_RateLimit_Override_DynamicMetadata *ret = envoy_config_route_v3_RateLimit_Override_DynamicMetadata_new(arena);
   return (ret && upb_decode(buf, size, ret, &envoy_config_route_v3_RateLimit_Override_DynamicMetadata_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE envoy_config_route_v3_RateLimit_Override_DynamicMetadata *envoy_config_route_v3_RateLimit_Override_DynamicMetadata_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  envoy_config_route_v3_RateLimit_Override_DynamicMetadata *ret = envoy_config_route_v3_RateLimit_Override_DynamicMetadata_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &envoy_config_route_v3_RateLimit_Override_DynamicMetadata_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *envoy_config_route_v3_RateLimit_Override_DynamicMetadata_serialize(const envoy_config_route_v3_RateLimit_Override_DynamicMetadata *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &envoy_config_route_v3_RateLimit_Override_DynamicMetadata_msginit, arena, len);
 }
 
-UPB_INLINE bool envoy_config_route_v3_RateLimit_Override_DynamicMetadata_has_metadata_key(const envoy_config_route_v3_RateLimit_Override_DynamicMetadata *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(0, 0)); }
-UPB_INLINE const struct envoy_type_metadata_v3_MetadataKey* envoy_config_route_v3_RateLimit_Override_DynamicMetadata_metadata_key(const envoy_config_route_v3_RateLimit_Override_DynamicMetadata *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(0, 0), const struct envoy_type_metadata_v3_MetadataKey*); }
+UPB_INLINE bool envoy_config_route_v3_RateLimit_Override_DynamicMetadata_has_metadata_key(const envoy_config_route_v3_RateLimit_Override_DynamicMetadata *msg) { return _upb_hasbit(msg, 1); }
+UPB_INLINE const struct envoy_type_metadata_v3_MetadataKey* envoy_config_route_v3_RateLimit_Override_DynamicMetadata_metadata_key(const envoy_config_route_v3_RateLimit_Override_DynamicMetadata *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(4, 8), const struct envoy_type_metadata_v3_MetadataKey*); }
 
 UPB_INLINE void envoy_config_route_v3_RateLimit_Override_DynamicMetadata_set_metadata_key(envoy_config_route_v3_RateLimit_Override_DynamicMetadata *msg, struct envoy_type_metadata_v3_MetadataKey* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(0, 0), struct envoy_type_metadata_v3_MetadataKey*) = value;
+  _upb_sethas(msg, 1);
+  *UPB_PTR_AT(msg, UPB_SIZE(4, 8), struct envoy_type_metadata_v3_MetadataKey*) = value;
 }
 UPB_INLINE struct envoy_type_metadata_v3_MetadataKey* envoy_config_route_v3_RateLimit_Override_DynamicMetadata_mutable_metadata_key(envoy_config_route_v3_RateLimit_Override_DynamicMetadata *msg, upb_arena *arena) {
   struct envoy_type_metadata_v3_MetadataKey* sub = (struct envoy_type_metadata_v3_MetadataKey*)envoy_config_route_v3_RateLimit_Override_DynamicMetadata_metadata_key(msg);
@@ -3096,6 +3427,12 @@ UPB_INLINE envoy_config_route_v3_HeaderMatcher *envoy_config_route_v3_HeaderMatc
   envoy_config_route_v3_HeaderMatcher *ret = envoy_config_route_v3_HeaderMatcher_new(arena);
   return (ret && upb_decode(buf, size, ret, &envoy_config_route_v3_HeaderMatcher_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE envoy_config_route_v3_HeaderMatcher *envoy_config_route_v3_HeaderMatcher_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  envoy_config_route_v3_HeaderMatcher *ret = envoy_config_route_v3_HeaderMatcher_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &envoy_config_route_v3_HeaderMatcher_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *envoy_config_route_v3_HeaderMatcher_serialize(const envoy_config_route_v3_HeaderMatcher *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &envoy_config_route_v3_HeaderMatcher_msginit, arena, len);
 }
@@ -3185,6 +3522,12 @@ UPB_INLINE envoy_config_route_v3_QueryParameterMatcher *envoy_config_route_v3_Qu
   envoy_config_route_v3_QueryParameterMatcher *ret = envoy_config_route_v3_QueryParameterMatcher_new(arena);
   return (ret && upb_decode(buf, size, ret, &envoy_config_route_v3_QueryParameterMatcher_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE envoy_config_route_v3_QueryParameterMatcher *envoy_config_route_v3_QueryParameterMatcher_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  envoy_config_route_v3_QueryParameterMatcher *ret = envoy_config_route_v3_QueryParameterMatcher_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &envoy_config_route_v3_QueryParameterMatcher_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *envoy_config_route_v3_QueryParameterMatcher_serialize(const envoy_config_route_v3_QueryParameterMatcher *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &envoy_config_route_v3_QueryParameterMatcher_msginit, arena, len);
 }
@@ -3231,18 +3574,25 @@ UPB_INLINE envoy_config_route_v3_InternalRedirectPolicy *envoy_config_route_v3_I
   envoy_config_route_v3_InternalRedirectPolicy *ret = envoy_config_route_v3_InternalRedirectPolicy_new(arena);
   return (ret && upb_decode(buf, size, ret, &envoy_config_route_v3_InternalRedirectPolicy_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE envoy_config_route_v3_InternalRedirectPolicy *envoy_config_route_v3_InternalRedirectPolicy_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  envoy_config_route_v3_InternalRedirectPolicy *ret = envoy_config_route_v3_InternalRedirectPolicy_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &envoy_config_route_v3_InternalRedirectPolicy_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *envoy_config_route_v3_InternalRedirectPolicy_serialize(const envoy_config_route_v3_InternalRedirectPolicy *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &envoy_config_route_v3_InternalRedirectPolicy_msginit, arena, len);
 }
 
-UPB_INLINE bool envoy_config_route_v3_InternalRedirectPolicy_has_max_internal_redirects(const envoy_config_route_v3_InternalRedirectPolicy *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(4, 8)); }
+UPB_INLINE bool envoy_config_route_v3_InternalRedirectPolicy_has_max_internal_redirects(const envoy_config_route_v3_InternalRedirectPolicy *msg) { return _upb_hasbit(msg, 1); }
 UPB_INLINE const struct google_protobuf_UInt32Value* envoy_config_route_v3_InternalRedirectPolicy_max_internal_redirects(const envoy_config_route_v3_InternalRedirectPolicy *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(4, 8), const struct google_protobuf_UInt32Value*); }
 UPB_INLINE uint32_t const* envoy_config_route_v3_InternalRedirectPolicy_redirect_response_codes(const envoy_config_route_v3_InternalRedirectPolicy *msg, size_t *len) { return (uint32_t const*)_upb_array_accessor(msg, UPB_SIZE(8, 16), len); }
 UPB_INLINE bool envoy_config_route_v3_InternalRedirectPolicy_has_predicates(const envoy_config_route_v3_InternalRedirectPolicy *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(12, 24)); }
 UPB_INLINE const struct envoy_config_core_v3_TypedExtensionConfig* const* envoy_config_route_v3_InternalRedirectPolicy_predicates(const envoy_config_route_v3_InternalRedirectPolicy *msg, size_t *len) { return (const struct envoy_config_core_v3_TypedExtensionConfig* const*)_upb_array_accessor(msg, UPB_SIZE(12, 24), len); }
-UPB_INLINE bool envoy_config_route_v3_InternalRedirectPolicy_allow_cross_scheme_redirect(const envoy_config_route_v3_InternalRedirectPolicy *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(0, 0), bool); }
+UPB_INLINE bool envoy_config_route_v3_InternalRedirectPolicy_allow_cross_scheme_redirect(const envoy_config_route_v3_InternalRedirectPolicy *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(1, 1), bool); }
 
 UPB_INLINE void envoy_config_route_v3_InternalRedirectPolicy_set_max_internal_redirects(envoy_config_route_v3_InternalRedirectPolicy *msg, struct google_protobuf_UInt32Value* value) {
+  _upb_sethas(msg, 1);
   *UPB_PTR_AT(msg, UPB_SIZE(4, 8), struct google_protobuf_UInt32Value*) = value;
 }
 UPB_INLINE struct google_protobuf_UInt32Value* envoy_config_route_v3_InternalRedirectPolicy_mutable_max_internal_redirects(envoy_config_route_v3_InternalRedirectPolicy *msg, upb_arena *arena) {
@@ -3258,27 +3608,27 @@ UPB_INLINE uint32_t* envoy_config_route_v3_InternalRedirectPolicy_mutable_redire
   return (uint32_t*)_upb_array_mutable_accessor(msg, UPB_SIZE(8, 16), len);
 }
 UPB_INLINE uint32_t* envoy_config_route_v3_InternalRedirectPolicy_resize_redirect_response_codes(envoy_config_route_v3_InternalRedirectPolicy *msg, size_t len, upb_arena *arena) {
-  return (uint32_t*)_upb_array_resize_accessor(msg, UPB_SIZE(8, 16), len, UPB_TYPE_UINT32, arena);
+  return (uint32_t*)_upb_array_resize_accessor2(msg, UPB_SIZE(8, 16), len, 2, arena);
 }
 UPB_INLINE bool envoy_config_route_v3_InternalRedirectPolicy_add_redirect_response_codes(envoy_config_route_v3_InternalRedirectPolicy *msg, uint32_t val, upb_arena *arena) {
-  return _upb_array_append_accessor(msg, UPB_SIZE(8, 16), UPB_SIZE(4, 4), UPB_TYPE_UINT32, &val,
+  return _upb_array_append_accessor2(msg, UPB_SIZE(8, 16), 2, &val,
       arena);
 }
 UPB_INLINE struct envoy_config_core_v3_TypedExtensionConfig** envoy_config_route_v3_InternalRedirectPolicy_mutable_predicates(envoy_config_route_v3_InternalRedirectPolicy *msg, size_t *len) {
   return (struct envoy_config_core_v3_TypedExtensionConfig**)_upb_array_mutable_accessor(msg, UPB_SIZE(12, 24), len);
 }
 UPB_INLINE struct envoy_config_core_v3_TypedExtensionConfig** envoy_config_route_v3_InternalRedirectPolicy_resize_predicates(envoy_config_route_v3_InternalRedirectPolicy *msg, size_t len, upb_arena *arena) {
-  return (struct envoy_config_core_v3_TypedExtensionConfig**)_upb_array_resize_accessor(msg, UPB_SIZE(12, 24), len, UPB_TYPE_MESSAGE, arena);
+  return (struct envoy_config_core_v3_TypedExtensionConfig**)_upb_array_resize_accessor2(msg, UPB_SIZE(12, 24), len, UPB_SIZE(2, 3), arena);
 }
 UPB_INLINE struct envoy_config_core_v3_TypedExtensionConfig* envoy_config_route_v3_InternalRedirectPolicy_add_predicates(envoy_config_route_v3_InternalRedirectPolicy *msg, upb_arena *arena) {
   struct envoy_config_core_v3_TypedExtensionConfig* sub = (struct envoy_config_core_v3_TypedExtensionConfig*)_upb_msg_new(&envoy_config_core_v3_TypedExtensionConfig_msginit, arena);
-  bool ok = _upb_array_append_accessor(
-      msg, UPB_SIZE(12, 24), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena);
+  bool ok = _upb_array_append_accessor2(
+      msg, UPB_SIZE(12, 24), UPB_SIZE(2, 3), &sub, arena);
   if (!ok) return NULL;
   return sub;
 }
 UPB_INLINE void envoy_config_route_v3_InternalRedirectPolicy_set_allow_cross_scheme_redirect(envoy_config_route_v3_InternalRedirectPolicy *msg, bool value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(0, 0), bool) = value;
+  *UPB_PTR_AT(msg, UPB_SIZE(1, 1), bool) = value;
 }
 
 #ifdef __cplusplus
index 0dd0a70..301441e 100644 (file)
@@ -22,14 +22,14 @@ static const upb_msglayout *const envoy_config_route_v3_ScopedRouteConfiguration
 static const upb_msglayout_field envoy_config_route_v3_ScopedRouteConfiguration__fields[4] = {
   {1, UPB_SIZE(4, 8), 0, 0, 9, 1},
   {2, UPB_SIZE(12, 24), 0, 0, 9, 1},
-  {3, UPB_SIZE(20, 40), 0, 0, 11, 1},
-  {4, UPB_SIZE(0, 0), 0, 0, 8, 1},
+  {3, UPB_SIZE(20, 40), 1, 0, 11, 1},
+  {4, UPB_SIZE(1, 1), 0, 0, 8, 1},
 };
 
 const upb_msglayout envoy_config_route_v3_ScopedRouteConfiguration_msginit = {
   &envoy_config_route_v3_ScopedRouteConfiguration_submsgs[0],
   &envoy_config_route_v3_ScopedRouteConfiguration__fields[0],
-  UPB_SIZE(24, 48), 4, false,
+  UPB_SIZE(24, 48), 4, false, 255,
 };
 
 static const upb_msglayout *const envoy_config_route_v3_ScopedRouteConfiguration_Key_submsgs[1] = {
@@ -43,7 +43,7 @@ static const upb_msglayout_field envoy_config_route_v3_ScopedRouteConfiguration_
 const upb_msglayout envoy_config_route_v3_ScopedRouteConfiguration_Key_msginit = {
   &envoy_config_route_v3_ScopedRouteConfiguration_Key_submsgs[0],
   &envoy_config_route_v3_ScopedRouteConfiguration_Key__fields[0],
-  UPB_SIZE(4, 8), 1, false,
+  UPB_SIZE(8, 8), 1, false, 255,
 };
 
 static const upb_msglayout_field envoy_config_route_v3_ScopedRouteConfiguration_Key_Fragment__fields[1] = {
@@ -53,7 +53,7 @@ static const upb_msglayout_field envoy_config_route_v3_ScopedRouteConfiguration_
 const upb_msglayout envoy_config_route_v3_ScopedRouteConfiguration_Key_Fragment_msginit = {
   NULL,
   &envoy_config_route_v3_ScopedRouteConfiguration_Key_Fragment__fields[0],
-  UPB_SIZE(16, 32), 1, false,
+  UPB_SIZE(16, 32), 1, false, 255,
 };
 
 #include "upb/port_undef.inc"
index 979510e..72d1622 100644 (file)
@@ -11,6 +11,7 @@
 
 #include "upb/msg.h"
 #include "upb/decode.h"
+#include "upb/decode_fast.h"
 #include "upb/encode.h"
 
 #include "upb/port_def.inc"
@@ -40,15 +41,21 @@ UPB_INLINE envoy_config_route_v3_ScopedRouteConfiguration *envoy_config_route_v3
   envoy_config_route_v3_ScopedRouteConfiguration *ret = envoy_config_route_v3_ScopedRouteConfiguration_new(arena);
   return (ret && upb_decode(buf, size, ret, &envoy_config_route_v3_ScopedRouteConfiguration_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE envoy_config_route_v3_ScopedRouteConfiguration *envoy_config_route_v3_ScopedRouteConfiguration_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  envoy_config_route_v3_ScopedRouteConfiguration *ret = envoy_config_route_v3_ScopedRouteConfiguration_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &envoy_config_route_v3_ScopedRouteConfiguration_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *envoy_config_route_v3_ScopedRouteConfiguration_serialize(const envoy_config_route_v3_ScopedRouteConfiguration *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &envoy_config_route_v3_ScopedRouteConfiguration_msginit, arena, len);
 }
 
 UPB_INLINE upb_strview envoy_config_route_v3_ScopedRouteConfiguration_name(const envoy_config_route_v3_ScopedRouteConfiguration *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(4, 8), upb_strview); }
 UPB_INLINE upb_strview envoy_config_route_v3_ScopedRouteConfiguration_route_configuration_name(const envoy_config_route_v3_ScopedRouteConfiguration *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(12, 24), upb_strview); }
-UPB_INLINE bool envoy_config_route_v3_ScopedRouteConfiguration_has_key(const envoy_config_route_v3_ScopedRouteConfiguration *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(20, 40)); }
+UPB_INLINE bool envoy_config_route_v3_ScopedRouteConfiguration_has_key(const envoy_config_route_v3_ScopedRouteConfiguration *msg) { return _upb_hasbit(msg, 1); }
 UPB_INLINE const envoy_config_route_v3_ScopedRouteConfiguration_Key* envoy_config_route_v3_ScopedRouteConfiguration_key(const envoy_config_route_v3_ScopedRouteConfiguration *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(20, 40), const envoy_config_route_v3_ScopedRouteConfiguration_Key*); }
-UPB_INLINE bool envoy_config_route_v3_ScopedRouteConfiguration_on_demand(const envoy_config_route_v3_ScopedRouteConfiguration *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(0, 0), bool); }
+UPB_INLINE bool envoy_config_route_v3_ScopedRouteConfiguration_on_demand(const envoy_config_route_v3_ScopedRouteConfiguration *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(1, 1), bool); }
 
 UPB_INLINE void envoy_config_route_v3_ScopedRouteConfiguration_set_name(envoy_config_route_v3_ScopedRouteConfiguration *msg, upb_strview value) {
   *UPB_PTR_AT(msg, UPB_SIZE(4, 8), upb_strview) = value;
@@ -57,6 +64,7 @@ UPB_INLINE void envoy_config_route_v3_ScopedRouteConfiguration_set_route_configu
   *UPB_PTR_AT(msg, UPB_SIZE(12, 24), upb_strview) = value;
 }
 UPB_INLINE void envoy_config_route_v3_ScopedRouteConfiguration_set_key(envoy_config_route_v3_ScopedRouteConfiguration *msg, envoy_config_route_v3_ScopedRouteConfiguration_Key* value) {
+  _upb_sethas(msg, 1);
   *UPB_PTR_AT(msg, UPB_SIZE(20, 40), envoy_config_route_v3_ScopedRouteConfiguration_Key*) = value;
 }
 UPB_INLINE struct envoy_config_route_v3_ScopedRouteConfiguration_Key* envoy_config_route_v3_ScopedRouteConfiguration_mutable_key(envoy_config_route_v3_ScopedRouteConfiguration *msg, upb_arena *arena) {
@@ -69,7 +77,7 @@ UPB_INLINE struct envoy_config_route_v3_ScopedRouteConfiguration_Key* envoy_conf
   return sub;
 }
 UPB_INLINE void envoy_config_route_v3_ScopedRouteConfiguration_set_on_demand(envoy_config_route_v3_ScopedRouteConfiguration *msg, bool value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(0, 0), bool) = value;
+  *UPB_PTR_AT(msg, UPB_SIZE(1, 1), bool) = value;
 }
 
 /* envoy.config.route.v3.ScopedRouteConfiguration.Key */
@@ -82,6 +90,12 @@ UPB_INLINE envoy_config_route_v3_ScopedRouteConfiguration_Key *envoy_config_rout
   envoy_config_route_v3_ScopedRouteConfiguration_Key *ret = envoy_config_route_v3_ScopedRouteConfiguration_Key_new(arena);
   return (ret && upb_decode(buf, size, ret, &envoy_config_route_v3_ScopedRouteConfiguration_Key_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE envoy_config_route_v3_ScopedRouteConfiguration_Key *envoy_config_route_v3_ScopedRouteConfiguration_Key_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  envoy_config_route_v3_ScopedRouteConfiguration_Key *ret = envoy_config_route_v3_ScopedRouteConfiguration_Key_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &envoy_config_route_v3_ScopedRouteConfiguration_Key_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *envoy_config_route_v3_ScopedRouteConfiguration_Key_serialize(const envoy_config_route_v3_ScopedRouteConfiguration_Key *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &envoy_config_route_v3_ScopedRouteConfiguration_Key_msginit, arena, len);
 }
@@ -93,12 +107,12 @@ UPB_INLINE envoy_config_route_v3_ScopedRouteConfiguration_Key_Fragment** envoy_c
   return (envoy_config_route_v3_ScopedRouteConfiguration_Key_Fragment**)_upb_array_mutable_accessor(msg, UPB_SIZE(0, 0), len);
 }
 UPB_INLINE envoy_config_route_v3_ScopedRouteConfiguration_Key_Fragment** envoy_config_route_v3_ScopedRouteConfiguration_Key_resize_fragments(envoy_config_route_v3_ScopedRouteConfiguration_Key *msg, size_t len, upb_arena *arena) {
-  return (envoy_config_route_v3_ScopedRouteConfiguration_Key_Fragment**)_upb_array_resize_accessor(msg, UPB_SIZE(0, 0), len, UPB_TYPE_MESSAGE, arena);
+  return (envoy_config_route_v3_ScopedRouteConfiguration_Key_Fragment**)_upb_array_resize_accessor2(msg, UPB_SIZE(0, 0), len, UPB_SIZE(2, 3), arena);
 }
 UPB_INLINE struct envoy_config_route_v3_ScopedRouteConfiguration_Key_Fragment* envoy_config_route_v3_ScopedRouteConfiguration_Key_add_fragments(envoy_config_route_v3_ScopedRouteConfiguration_Key *msg, upb_arena *arena) {
   struct envoy_config_route_v3_ScopedRouteConfiguration_Key_Fragment* sub = (struct envoy_config_route_v3_ScopedRouteConfiguration_Key_Fragment*)_upb_msg_new(&envoy_config_route_v3_ScopedRouteConfiguration_Key_Fragment_msginit, arena);
-  bool ok = _upb_array_append_accessor(
-      msg, UPB_SIZE(0, 0), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena);
+  bool ok = _upb_array_append_accessor2(
+      msg, UPB_SIZE(0, 0), UPB_SIZE(2, 3), &sub, arena);
   if (!ok) return NULL;
   return sub;
 }
@@ -113,6 +127,12 @@ UPB_INLINE envoy_config_route_v3_ScopedRouteConfiguration_Key_Fragment *envoy_co
   envoy_config_route_v3_ScopedRouteConfiguration_Key_Fragment *ret = envoy_config_route_v3_ScopedRouteConfiguration_Key_Fragment_new(arena);
   return (ret && upb_decode(buf, size, ret, &envoy_config_route_v3_ScopedRouteConfiguration_Key_Fragment_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE envoy_config_route_v3_ScopedRouteConfiguration_Key_Fragment *envoy_config_route_v3_ScopedRouteConfiguration_Key_Fragment_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  envoy_config_route_v3_ScopedRouteConfiguration_Key_Fragment *ret = envoy_config_route_v3_ScopedRouteConfiguration_Key_Fragment_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &envoy_config_route_v3_ScopedRouteConfiguration_Key_Fragment_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *envoy_config_route_v3_ScopedRouteConfiguration_Key_Fragment_serialize(const envoy_config_route_v3_ScopedRouteConfiguration_Key_Fragment *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &envoy_config_route_v3_ScopedRouteConfiguration_Key_Fragment_msginit, arena, len);
 }
index 8771e2c..6729533 100644 (file)
@@ -22,13 +22,13 @@ static const upb_msglayout *const envoy_config_trace_v3_Tracing_submsgs[1] = {
 };
 
 static const upb_msglayout_field envoy_config_trace_v3_Tracing__fields[1] = {
-  {1, UPB_SIZE(0, 0), 0, 0, 11, 1},
+  {1, UPB_SIZE(4, 8), 1, 0, 11, 1},
 };
 
 const upb_msglayout envoy_config_trace_v3_Tracing_msginit = {
   &envoy_config_trace_v3_Tracing_submsgs[0],
   &envoy_config_trace_v3_Tracing__fields[0],
-  UPB_SIZE(4, 8), 1, false,
+  UPB_SIZE(8, 16), 1, false, 255,
 };
 
 static const upb_msglayout *const envoy_config_trace_v3_Tracing_Http_submsgs[1] = {
@@ -43,7 +43,7 @@ static const upb_msglayout_field envoy_config_trace_v3_Tracing_Http__fields[2] =
 const upb_msglayout envoy_config_trace_v3_Tracing_Http_msginit = {
   &envoy_config_trace_v3_Tracing_Http_submsgs[0],
   &envoy_config_trace_v3_Tracing_Http__fields[0],
-  UPB_SIZE(16, 32), 2, false,
+  UPB_SIZE(16, 32), 2, false, 255,
 };
 
 #include "upb/port_undef.inc"
index 7f97cac..21240fa 100644 (file)
@@ -11,6 +11,7 @@
 
 #include "upb/msg.h"
 #include "upb/decode.h"
+#include "upb/decode_fast.h"
 #include "upb/encode.h"
 
 #include "upb/port_def.inc"
@@ -39,15 +40,22 @@ UPB_INLINE envoy_config_trace_v3_Tracing *envoy_config_trace_v3_Tracing_parse(co
   envoy_config_trace_v3_Tracing *ret = envoy_config_trace_v3_Tracing_new(arena);
   return (ret && upb_decode(buf, size, ret, &envoy_config_trace_v3_Tracing_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE envoy_config_trace_v3_Tracing *envoy_config_trace_v3_Tracing_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  envoy_config_trace_v3_Tracing *ret = envoy_config_trace_v3_Tracing_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &envoy_config_trace_v3_Tracing_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *envoy_config_trace_v3_Tracing_serialize(const envoy_config_trace_v3_Tracing *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &envoy_config_trace_v3_Tracing_msginit, arena, len);
 }
 
-UPB_INLINE bool envoy_config_trace_v3_Tracing_has_http(const envoy_config_trace_v3_Tracing *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(0, 0)); }
-UPB_INLINE const envoy_config_trace_v3_Tracing_Http* envoy_config_trace_v3_Tracing_http(const envoy_config_trace_v3_Tracing *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(0, 0), const envoy_config_trace_v3_Tracing_Http*); }
+UPB_INLINE bool envoy_config_trace_v3_Tracing_has_http(const envoy_config_trace_v3_Tracing *msg) { return _upb_hasbit(msg, 1); }
+UPB_INLINE const envoy_config_trace_v3_Tracing_Http* envoy_config_trace_v3_Tracing_http(const envoy_config_trace_v3_Tracing *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(4, 8), const envoy_config_trace_v3_Tracing_Http*); }
 
 UPB_INLINE void envoy_config_trace_v3_Tracing_set_http(envoy_config_trace_v3_Tracing *msg, envoy_config_trace_v3_Tracing_Http* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(0, 0), envoy_config_trace_v3_Tracing_Http*) = value;
+  _upb_sethas(msg, 1);
+  *UPB_PTR_AT(msg, UPB_SIZE(4, 8), envoy_config_trace_v3_Tracing_Http*) = value;
 }
 UPB_INLINE struct envoy_config_trace_v3_Tracing_Http* envoy_config_trace_v3_Tracing_mutable_http(envoy_config_trace_v3_Tracing *msg, upb_arena *arena) {
   struct envoy_config_trace_v3_Tracing_Http* sub = (struct envoy_config_trace_v3_Tracing_Http*)envoy_config_trace_v3_Tracing_http(msg);
@@ -69,6 +77,12 @@ UPB_INLINE envoy_config_trace_v3_Tracing_Http *envoy_config_trace_v3_Tracing_Htt
   envoy_config_trace_v3_Tracing_Http *ret = envoy_config_trace_v3_Tracing_Http_new(arena);
   return (ret && upb_decode(buf, size, ret, &envoy_config_trace_v3_Tracing_Http_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE envoy_config_trace_v3_Tracing_Http *envoy_config_trace_v3_Tracing_Http_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  envoy_config_trace_v3_Tracing_Http *ret = envoy_config_trace_v3_Tracing_Http_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &envoy_config_trace_v3_Tracing_Http_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *envoy_config_trace_v3_Tracing_Http_serialize(const envoy_config_trace_v3_Tracing_Http *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &envoy_config_trace_v3_Tracing_Http_msginit, arena, len);
 }
index 2adecb7..9d5c452 100644 (file)
@@ -34,7 +34,7 @@
 
 #include "upb/port_def.inc"
 
-static const upb_msglayout *const envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_submsgs[24] = {
+static const upb_msglayout *const envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_submsgs[17] = {
   &envoy_config_accesslog_v3_AccessLog_msginit,
   &envoy_config_core_v3_Http1ProtocolOptions_msginit,
   &envoy_config_core_v3_Http2ProtocolOptions_msginit,
@@ -55,53 +55,53 @@ static const upb_msglayout *const envoy_extensions_filters_network_http_connecti
 };
 
 static const upb_msglayout_field envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager__fields[38] = {
-  {1, UPB_SIZE(0, 0), 0, 0, 14, 1},
-  {2, UPB_SIZE(36, 40), 0, 0, 9, 1},
-  {3, UPB_SIZE(144, 256), UPB_SIZE(-149, -265), 11, 11, 1},
-  {4, UPB_SIZE(144, 256), UPB_SIZE(-149, -265), 4, 11, 1},
-  {5, UPB_SIZE(132, 232), 0, 9, 11, 3},
-  {6, UPB_SIZE(60, 88), 0, 14, 11, 1},
-  {7, UPB_SIZE(64, 96), 0, 7, 11, 1},
-  {8, UPB_SIZE(68, 104), 0, 1, 11, 1},
-  {9, UPB_SIZE(72, 112), 0, 2, 11, 1},
-  {10, UPB_SIZE(44, 56), 0, 0, 9, 1},
-  {12, UPB_SIZE(76, 120), 0, 15, 11, 1},
-  {13, UPB_SIZE(136, 240), 0, 0, 11, 3},
-  {14, UPB_SIZE(80, 128), 0, 14, 11, 1},
-  {15, UPB_SIZE(84, 136), 0, 14, 11, 1},
+  {1, UPB_SIZE(4, 4), 0, 0, 14, 1},
+  {2, UPB_SIZE(28, 32), 0, 0, 9, 1},
+  {3, UPB_SIZE(136, 248), UPB_SIZE(-141, -257), 11, 11, 1},
+  {4, UPB_SIZE(136, 248), UPB_SIZE(-141, -257), 4, 11, 1},
+  {5, UPB_SIZE(124, 224), 0, 9, 11, 3},
+  {6, UPB_SIZE(52, 80), 1, 14, 11, 1},
+  {7, UPB_SIZE(56, 88), 2, 7, 11, 1},
+  {8, UPB_SIZE(60, 96), 3, 1, 11, 1},
+  {9, UPB_SIZE(64, 104), 4, 2, 11, 1},
+  {10, UPB_SIZE(36, 48), 0, 0, 9, 1},
+  {12, UPB_SIZE(68, 112), 5, 15, 11, 1},
+  {13, UPB_SIZE(128, 232), 0, 0, 11, 3},
+  {14, UPB_SIZE(72, 120), 6, 14, 11, 1},
+  {15, UPB_SIZE(76, 128), 7, 14, 11, 1},
   {16, UPB_SIZE(8, 8), 0, 0, 14, 1},
-  {17, UPB_SIZE(88, 144), 0, 6, 11, 1},
-  {18, UPB_SIZE(28, 28), 0, 0, 8, 1},
-  {19, UPB_SIZE(24, 24), 0, 0, 13, 1},
-  {20, UPB_SIZE(29, 29), 0, 0, 8, 1},
-  {21, UPB_SIZE(30, 30), 0, 0, 8, 1},
-  {22, UPB_SIZE(52, 72), 0, 0, 9, 1},
-  {23, UPB_SIZE(140, 248), 0, 8, 11, 3},
-  {24, UPB_SIZE(92, 152), 0, 15, 11, 1},
-  {25, UPB_SIZE(96, 160), 0, 5, 11, 1},
-  {26, UPB_SIZE(100, 168), 0, 15, 11, 1},
-  {28, UPB_SIZE(104, 176), 0, 15, 11, 1},
-  {29, UPB_SIZE(108, 184), 0, 16, 11, 1},
-  {30, UPB_SIZE(112, 192), 0, 14, 11, 1},
-  {31, UPB_SIZE(144, 256), UPB_SIZE(-149, -265), 13, 11, 1},
-  {32, UPB_SIZE(31, 31), 0, 0, 8, 1},
-  {33, UPB_SIZE(32, 32), 0, 0, 8, 1},
-  {34, UPB_SIZE(16, 16), 0, 0, 14, 1},
-  {35, UPB_SIZE(116, 200), 0, 3, 11, 1},
-  {36, UPB_SIZE(120, 208), 0, 12, 11, 1},
-  {37, UPB_SIZE(33, 33), 0, 0, 8, 1},
-  {38, UPB_SIZE(124, 216), 0, 10, 11, 1},
-  {39, UPB_SIZE(34, 34), 0, 0, 8, 1},
-  {40, UPB_SIZE(128, 224), 0, 14, 11, 1},
+  {17, UPB_SIZE(80, 136), 8, 6, 11, 1},
+  {18, UPB_SIZE(20, 20), 0, 0, 8, 1},
+  {19, UPB_SIZE(16, 16), 0, 0, 13, 1},
+  {20, UPB_SIZE(21, 21), 0, 0, 8, 1},
+  {21, UPB_SIZE(22, 22), 0, 0, 8, 1},
+  {22, UPB_SIZE(44, 64), 0, 0, 9, 1},
+  {23, UPB_SIZE(132, 240), 0, 8, 11, 3},
+  {24, UPB_SIZE(84, 144), 9, 15, 11, 1},
+  {25, UPB_SIZE(88, 152), 10, 5, 11, 1},
+  {26, UPB_SIZE(92, 160), 11, 15, 11, 1},
+  {28, UPB_SIZE(96, 168), 12, 15, 11, 1},
+  {29, UPB_SIZE(100, 176), 13, 16, 11, 1},
+  {30, UPB_SIZE(104, 184), 14, 14, 11, 1},
+  {31, UPB_SIZE(136, 248), UPB_SIZE(-141, -257), 13, 11, 1},
+  {32, UPB_SIZE(23, 23), 0, 0, 8, 1},
+  {33, UPB_SIZE(24, 24), 0, 0, 8, 1},
+  {34, UPB_SIZE(12, 12), 0, 0, 14, 1},
+  {35, UPB_SIZE(108, 192), 15, 3, 11, 1},
+  {36, UPB_SIZE(112, 200), 16, 12, 11, 1},
+  {37, UPB_SIZE(25, 25), 0, 0, 8, 1},
+  {38, UPB_SIZE(116, 208), 17, 10, 11, 1},
+  {39, UPB_SIZE(26, 26), 0, 0, 8, 1},
+  {40, UPB_SIZE(120, 216), 18, 14, 11, 1},
 };
 
 const upb_msglayout envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_msginit = {
   &envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_submsgs[0],
   &envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager__fields[0],
-  UPB_SIZE(152, 272), 38, false,
+  UPB_SIZE(144, 272), 38, false, 255,
 };
 
-static const upb_msglayout *const envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_Tracing_submsgs[6] = {
+static const upb_msglayout *const envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_Tracing_submsgs[4] = {
   &envoy_config_trace_v3_Tracing_Http_msginit,
   &envoy_type_tracing_v3_CustomTag_msginit,
   &envoy_type_v3_Percent_msginit,
@@ -109,19 +109,19 @@ static const upb_msglayout *const envoy_extensions_filters_network_http_connecti
 };
 
 static const upb_msglayout_field envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_Tracing__fields[7] = {
-  {3, UPB_SIZE(4, 8), 0, 2, 11, 1},
-  {4, UPB_SIZE(8, 16), 0, 2, 11, 1},
-  {5, UPB_SIZE(12, 24), 0, 2, 11, 1},
-  {6, UPB_SIZE(0, 0), 0, 0, 8, 1},
-  {7, UPB_SIZE(16, 32), 0, 3, 11, 1},
+  {3, UPB_SIZE(4, 8), 1, 2, 11, 1},
+  {4, UPB_SIZE(8, 16), 2, 2, 11, 1},
+  {5, UPB_SIZE(12, 24), 3, 2, 11, 1},
+  {6, UPB_SIZE(1, 1), 0, 0, 8, 1},
+  {7, UPB_SIZE(16, 32), 4, 3, 11, 1},
   {8, UPB_SIZE(24, 48), 0, 1, 11, 3},
-  {9, UPB_SIZE(20, 40), 0, 0, 11, 1},
+  {9, UPB_SIZE(20, 40), 5, 0, 11, 1},
 };
 
 const upb_msglayout envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_Tracing_msginit = {
   &envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_Tracing_submsgs[0],
   &envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_Tracing__fields[0],
-  UPB_SIZE(28, 56), 7, false,
+  UPB_SIZE(32, 56), 7, false, 255,
 };
 
 static const upb_msglayout_field envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_InternalAddressConfig__fields[1] = {
@@ -131,7 +131,7 @@ static const upb_msglayout_field envoy_extensions_filters_network_http_connectio
 const upb_msglayout envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_InternalAddressConfig_msginit = {
   NULL,
   &envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_InternalAddressConfig__fields[0],
-  UPB_SIZE(1, 1), 1, false,
+  UPB_SIZE(8, 8), 1, false, 255,
 };
 
 static const upb_msglayout *const envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_SetCurrentClientCertDetails_submsgs[1] = {
@@ -139,17 +139,17 @@ static const upb_msglayout *const envoy_extensions_filters_network_http_connecti
 };
 
 static const upb_msglayout_field envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_SetCurrentClientCertDetails__fields[5] = {
-  {1, UPB_SIZE(4, 8), 0, 0, 11, 1},
-  {3, UPB_SIZE(0, 0), 0, 0, 8, 1},
-  {4, UPB_SIZE(1, 1), 0, 0, 8, 1},
-  {5, UPB_SIZE(2, 2), 0, 0, 8, 1},
-  {6, UPB_SIZE(3, 3), 0, 0, 8, 1},
+  {1, UPB_SIZE(8, 8), 1, 0, 11, 1},
+  {3, UPB_SIZE(1, 1), 0, 0, 8, 1},
+  {4, UPB_SIZE(2, 2), 0, 0, 8, 1},
+  {5, UPB_SIZE(3, 3), 0, 0, 8, 1},
+  {6, UPB_SIZE(4, 4), 0, 0, 8, 1},
 };
 
 const upb_msglayout envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_SetCurrentClientCertDetails_msginit = {
   &envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_SetCurrentClientCertDetails_submsgs[0],
   &envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_SetCurrentClientCertDetails__fields[0],
-  UPB_SIZE(8, 16), 5, false,
+  UPB_SIZE(16, 16), 5, false, 255,
 };
 
 static const upb_msglayout *const envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_UpgradeConfig_submsgs[2] = {
@@ -158,15 +158,15 @@ static const upb_msglayout *const envoy_extensions_filters_network_http_connecti
 };
 
 static const upb_msglayout_field envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_UpgradeConfig__fields[3] = {
-  {1, UPB_SIZE(0, 0), 0, 0, 9, 1},
-  {2, UPB_SIZE(12, 24), 0, 0, 11, 3},
-  {3, UPB_SIZE(8, 16), 0, 1, 11, 1},
+  {1, UPB_SIZE(4, 8), 0, 0, 9, 1},
+  {2, UPB_SIZE(16, 32), 0, 0, 11, 3},
+  {3, UPB_SIZE(12, 24), 1, 1, 11, 1},
 };
 
 const upb_msglayout envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_UpgradeConfig_msginit = {
   &envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_UpgradeConfig_submsgs[0],
   &envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_UpgradeConfig__fields[0],
-  UPB_SIZE(16, 32), 3, false,
+  UPB_SIZE(24, 48), 3, false, 255,
 };
 
 static const upb_msglayout *const envoy_extensions_filters_network_http_connection_manager_v3_LocalReplyConfig_submsgs[2] = {
@@ -175,14 +175,14 @@ static const upb_msglayout *const envoy_extensions_filters_network_http_connecti
 };
 
 static const upb_msglayout_field envoy_extensions_filters_network_http_connection_manager_v3_LocalReplyConfig__fields[2] = {
-  {1, UPB_SIZE(4, 8), 0, 1, 11, 3},
-  {2, UPB_SIZE(0, 0), 0, 0, 11, 1},
+  {1, UPB_SIZE(8, 16), 0, 1, 11, 3},
+  {2, UPB_SIZE(4, 8), 1, 0, 11, 1},
 };
 
 const upb_msglayout envoy_extensions_filters_network_http_connection_manager_v3_LocalReplyConfig_msginit = {
   &envoy_extensions_filters_network_http_connection_manager_v3_LocalReplyConfig_submsgs[0],
   &envoy_extensions_filters_network_http_connection_manager_v3_LocalReplyConfig__fields[0],
-  UPB_SIZE(8, 16), 2, false,
+  UPB_SIZE(16, 24), 2, false, 255,
 };
 
 static const upb_msglayout *const envoy_extensions_filters_network_http_connection_manager_v3_ResponseMapper_submsgs[5] = {
@@ -194,17 +194,17 @@ static const upb_msglayout *const envoy_extensions_filters_network_http_connecti
 };
 
 static const upb_msglayout_field envoy_extensions_filters_network_http_connection_manager_v3_ResponseMapper__fields[5] = {
-  {1, UPB_SIZE(0, 0), 0, 0, 11, 1},
-  {2, UPB_SIZE(4, 8), 0, 4, 11, 1},
-  {3, UPB_SIZE(8, 16), 0, 1, 11, 1},
-  {4, UPB_SIZE(12, 24), 0, 3, 11, 1},
-  {5, UPB_SIZE(16, 32), 0, 2, 11, 3},
+  {1, UPB_SIZE(4, 8), 1, 0, 11, 1},
+  {2, UPB_SIZE(8, 16), 2, 4, 11, 1},
+  {3, UPB_SIZE(12, 24), 3, 1, 11, 1},
+  {4, UPB_SIZE(16, 32), 4, 3, 11, 1},
+  {5, UPB_SIZE(20, 40), 0, 2, 11, 3},
 };
 
 const upb_msglayout envoy_extensions_filters_network_http_connection_manager_v3_ResponseMapper_msginit = {
   &envoy_extensions_filters_network_http_connection_manager_v3_ResponseMapper_submsgs[0],
   &envoy_extensions_filters_network_http_connection_manager_v3_ResponseMapper__fields[0],
-  UPB_SIZE(20, 40), 5, false,
+  UPB_SIZE(24, 48), 5, false, 255,
 };
 
 static const upb_msglayout *const envoy_extensions_filters_network_http_connection_manager_v3_Rds_submsgs[2] = {
@@ -213,15 +213,15 @@ static const upb_msglayout *const envoy_extensions_filters_network_http_connecti
 };
 
 static const upb_msglayout_field envoy_extensions_filters_network_http_connection_manager_v3_Rds__fields[3] = {
-  {1, UPB_SIZE(8, 16), 0, 0, 11, 1},
-  {2, UPB_SIZE(0, 0), 0, 0, 9, 1},
-  {3, UPB_SIZE(12, 24), 0, 1, 11, 1},
+  {1, UPB_SIZE(12, 24), 1, 0, 11, 1},
+  {2, UPB_SIZE(4, 8), 0, 0, 9, 1},
+  {3, UPB_SIZE(16, 32), 2, 1, 11, 1},
 };
 
 const upb_msglayout envoy_extensions_filters_network_http_connection_manager_v3_Rds_msginit = {
   &envoy_extensions_filters_network_http_connection_manager_v3_Rds_submsgs[0],
   &envoy_extensions_filters_network_http_connection_manager_v3_Rds__fields[0],
-  UPB_SIZE(16, 32), 3, false,
+  UPB_SIZE(24, 48), 3, false, 255,
 };
 
 static const upb_msglayout *const envoy_extensions_filters_network_http_connection_manager_v3_ScopedRouteConfigurationsList_submsgs[1] = {
@@ -235,7 +235,7 @@ static const upb_msglayout_field envoy_extensions_filters_network_http_connectio
 const upb_msglayout envoy_extensions_filters_network_http_connection_manager_v3_ScopedRouteConfigurationsList_msginit = {
   &envoy_extensions_filters_network_http_connection_manager_v3_ScopedRouteConfigurationsList_submsgs[0],
   &envoy_extensions_filters_network_http_connection_manager_v3_ScopedRouteConfigurationsList__fields[0],
-  UPB_SIZE(4, 8), 1, false,
+  UPB_SIZE(8, 8), 1, false, 255,
 };
 
 static const upb_msglayout *const envoy_extensions_filters_network_http_connection_manager_v3_ScopedRoutes_submsgs[4] = {
@@ -246,17 +246,17 @@ static const upb_msglayout *const envoy_extensions_filters_network_http_connecti
 };
 
 static const upb_msglayout_field envoy_extensions_filters_network_http_connection_manager_v3_ScopedRoutes__fields[5] = {
-  {1, UPB_SIZE(0, 0), 0, 0, 9, 1},
-  {2, UPB_SIZE(8, 16), 0, 3, 11, 1},
-  {3, UPB_SIZE(12, 24), 0, 0, 11, 1},
-  {4, UPB_SIZE(16, 32), UPB_SIZE(-21, -41), 2, 11, 1},
-  {5, UPB_SIZE(16, 32), UPB_SIZE(-21, -41), 1, 11, 1},
+  {1, UPB_SIZE(4, 8), 0, 0, 9, 1},
+  {2, UPB_SIZE(12, 24), 1, 3, 11, 1},
+  {3, UPB_SIZE(16, 32), 2, 0, 11, 1},
+  {4, UPB_SIZE(20, 40), UPB_SIZE(-25, -49), 2, 11, 1},
+  {5, UPB_SIZE(20, 40), UPB_SIZE(-25, -49), 1, 11, 1},
 };
 
 const upb_msglayout envoy_extensions_filters_network_http_connection_manager_v3_ScopedRoutes_msginit = {
   &envoy_extensions_filters_network_http_connection_manager_v3_ScopedRoutes_submsgs[0],
   &envoy_extensions_filters_network_http_connection_manager_v3_ScopedRoutes__fields[0],
-  UPB_SIZE(24, 48), 5, false,
+  UPB_SIZE(32, 64), 5, false, 255,
 };
 
 static const upb_msglayout *const envoy_extensions_filters_network_http_connection_manager_v3_ScopedRoutes_ScopeKeyBuilder_submsgs[1] = {
@@ -270,7 +270,7 @@ static const upb_msglayout_field envoy_extensions_filters_network_http_connectio
 const upb_msglayout envoy_extensions_filters_network_http_connection_manager_v3_ScopedRoutes_ScopeKeyBuilder_msginit = {
   &envoy_extensions_filters_network_http_connection_manager_v3_ScopedRoutes_ScopeKeyBuilder_submsgs[0],
   &envoy_extensions_filters_network_http_connection_manager_v3_ScopedRoutes_ScopeKeyBuilder__fields[0],
-  UPB_SIZE(4, 8), 1, false,
+  UPB_SIZE(8, 8), 1, false, 255,
 };
 
 static const upb_msglayout *const envoy_extensions_filters_network_http_connection_manager_v3_ScopedRoutes_ScopeKeyBuilder_FragmentBuilder_submsgs[1] = {
@@ -284,7 +284,7 @@ static const upb_msglayout_field envoy_extensions_filters_network_http_connectio
 const upb_msglayout envoy_extensions_filters_network_http_connection_manager_v3_ScopedRoutes_ScopeKeyBuilder_FragmentBuilder_msginit = {
   &envoy_extensions_filters_network_http_connection_manager_v3_ScopedRoutes_ScopeKeyBuilder_FragmentBuilder_submsgs[0],
   &envoy_extensions_filters_network_http_connection_manager_v3_ScopedRoutes_ScopeKeyBuilder_FragmentBuilder__fields[0],
-  UPB_SIZE(8, 16), 1, false,
+  UPB_SIZE(8, 16), 1, false, 255,
 };
 
 static const upb_msglayout *const envoy_extensions_filters_network_http_connection_manager_v3_ScopedRoutes_ScopeKeyBuilder_FragmentBuilder_HeaderValueExtractor_submsgs[1] = {
@@ -301,7 +301,7 @@ static const upb_msglayout_field envoy_extensions_filters_network_http_connectio
 const upb_msglayout envoy_extensions_filters_network_http_connection_manager_v3_ScopedRoutes_ScopeKeyBuilder_FragmentBuilder_HeaderValueExtractor_msginit = {
   &envoy_extensions_filters_network_http_connection_manager_v3_ScopedRoutes_ScopeKeyBuilder_FragmentBuilder_HeaderValueExtractor_submsgs[0],
   &envoy_extensions_filters_network_http_connection_manager_v3_ScopedRoutes_ScopeKeyBuilder_FragmentBuilder_HeaderValueExtractor__fields[0],
-  UPB_SIZE(24, 48), 4, false,
+  UPB_SIZE(24, 48), 4, false, 255,
 };
 
 static const upb_msglayout_field envoy_extensions_filters_network_http_connection_manager_v3_ScopedRoutes_ScopeKeyBuilder_FragmentBuilder_HeaderValueExtractor_KvElement__fields[2] = {
@@ -312,7 +312,7 @@ static const upb_msglayout_field envoy_extensions_filters_network_http_connectio
 const upb_msglayout envoy_extensions_filters_network_http_connection_manager_v3_ScopedRoutes_ScopeKeyBuilder_FragmentBuilder_HeaderValueExtractor_KvElement_msginit = {
   NULL,
   &envoy_extensions_filters_network_http_connection_manager_v3_ScopedRoutes_ScopeKeyBuilder_FragmentBuilder_HeaderValueExtractor_KvElement__fields[0],
-  UPB_SIZE(16, 32), 2, false,
+  UPB_SIZE(16, 32), 2, false, 255,
 };
 
 static const upb_msglayout *const envoy_extensions_filters_network_http_connection_manager_v3_ScopedRds_submsgs[1] = {
@@ -320,13 +320,13 @@ static const upb_msglayout *const envoy_extensions_filters_network_http_connecti
 };
 
 static const upb_msglayout_field envoy_extensions_filters_network_http_connection_manager_v3_ScopedRds__fields[1] = {
-  {1, UPB_SIZE(0, 0), 0, 0, 11, 1},
+  {1, UPB_SIZE(4, 8), 1, 0, 11, 1},
 };
 
 const upb_msglayout envoy_extensions_filters_network_http_connection_manager_v3_ScopedRds_msginit = {
   &envoy_extensions_filters_network_http_connection_manager_v3_ScopedRds_submsgs[0],
   &envoy_extensions_filters_network_http_connection_manager_v3_ScopedRds__fields[0],
-  UPB_SIZE(4, 8), 1, false,
+  UPB_SIZE(8, 16), 1, false, 255,
 };
 
 static const upb_msglayout *const envoy_extensions_filters_network_http_connection_manager_v3_HttpFilter_submsgs[2] = {
@@ -343,7 +343,7 @@ static const upb_msglayout_field envoy_extensions_filters_network_http_connectio
 const upb_msglayout envoy_extensions_filters_network_http_connection_manager_v3_HttpFilter_msginit = {
   &envoy_extensions_filters_network_http_connection_manager_v3_HttpFilter_submsgs[0],
   &envoy_extensions_filters_network_http_connection_manager_v3_HttpFilter__fields[0],
-  UPB_SIZE(16, 32), 3, false,
+  UPB_SIZE(16, 32), 3, false, 255,
 };
 
 static const upb_msglayout *const envoy_extensions_filters_network_http_connection_manager_v3_RequestIDExtension_submsgs[1] = {
@@ -351,13 +351,13 @@ static const upb_msglayout *const envoy_extensions_filters_network_http_connecti
 };
 
 static const upb_msglayout_field envoy_extensions_filters_network_http_connection_manager_v3_RequestIDExtension__fields[1] = {
-  {1, UPB_SIZE(0, 0), 0, 0, 11, 1},
+  {1, UPB_SIZE(4, 8), 1, 0, 11, 1},
 };
 
 const upb_msglayout envoy_extensions_filters_network_http_connection_manager_v3_RequestIDExtension_msginit = {
   &envoy_extensions_filters_network_http_connection_manager_v3_RequestIDExtension_submsgs[0],
   &envoy_extensions_filters_network_http_connection_manager_v3_RequestIDExtension__fields[0],
-  UPB_SIZE(4, 8), 1, false,
+  UPB_SIZE(8, 16), 1, false, 255,
 };
 
 #include "upb/port_undef.inc"
index 87005ae..7a4d971 100644 (file)
@@ -11,6 +11,7 @@
 
 #include "upb/msg.h"
 #include "upb/decode.h"
+#include "upb/decode_fast.h"
 #include "upb/encode.h"
 
 #include "upb/port_def.inc"
@@ -148,6 +149,12 @@ UPB_INLINE envoy_extensions_filters_network_http_connection_manager_v3_HttpConne
   envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager *ret = envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_new(arena);
   return (ret && upb_decode(buf, size, ret, &envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager *envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager *ret = envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_serialize(const envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_msginit, arena, len);
 }
@@ -158,79 +165,79 @@ typedef enum {
   envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_route_specifier_scoped_routes = 31,
   envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_route_specifier_NOT_SET = 0
 } envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_route_specifier_oneofcases;
-UPB_INLINE envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_route_specifier_oneofcases envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_route_specifier_case(const envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager* msg) { return (envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_route_specifier_oneofcases)*UPB_PTR_AT(msg, UPB_SIZE(148, 264), int32_t); }
-
-UPB_INLINE int32_t envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_codec_type(const envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(0, 0), int32_t); }
-UPB_INLINE upb_strview envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_stat_prefix(const envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(36, 40), upb_strview); }
-UPB_INLINE bool envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_has_rds(const envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager *msg) { return _upb_getoneofcase(msg, UPB_SIZE(148, 264)) == 3; }
-UPB_INLINE const envoy_extensions_filters_network_http_connection_manager_v3_Rds* envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_rds(const envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager *msg) { return UPB_READ_ONEOF(msg, const envoy_extensions_filters_network_http_connection_manager_v3_Rds*, UPB_SIZE(144, 256), UPB_SIZE(148, 264), 3, NULL); }
-UPB_INLINE bool envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_has_route_config(const envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager *msg) { return _upb_getoneofcase(msg, UPB_SIZE(148, 264)) == 4; }
-UPB_INLINE const struct envoy_config_route_v3_RouteConfiguration* envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_route_config(const envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager *msg) { return UPB_READ_ONEOF(msg, const struct envoy_config_route_v3_RouteConfiguration*, UPB_SIZE(144, 256), UPB_SIZE(148, 264), 4, NULL); }
-UPB_INLINE bool envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_has_http_filters(const envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(132, 232)); }
-UPB_INLINE const envoy_extensions_filters_network_http_connection_manager_v3_HttpFilter* const* envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_http_filters(const envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager *msg, size_t *len) { return (const envoy_extensions_filters_network_http_connection_manager_v3_HttpFilter* const*)_upb_array_accessor(msg, UPB_SIZE(132, 232), len); }
-UPB_INLINE bool envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_has_add_user_agent(const envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(60, 88)); }
-UPB_INLINE const struct google_protobuf_BoolValue* envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_add_user_agent(const envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(60, 88), const struct google_protobuf_BoolValue*); }
-UPB_INLINE bool envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_has_tracing(const envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(64, 96)); }
-UPB_INLINE const envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_Tracing* envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_tracing(const envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(64, 96), const envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_Tracing*); }
-UPB_INLINE bool envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_has_http_protocol_options(const envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(68, 104)); }
-UPB_INLINE const struct envoy_config_core_v3_Http1ProtocolOptions* envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_http_protocol_options(const envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(68, 104), const struct envoy_config_core_v3_Http1ProtocolOptions*); }
-UPB_INLINE bool envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_has_http2_protocol_options(const envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(72, 112)); }
-UPB_INLINE const struct envoy_config_core_v3_Http2ProtocolOptions* envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_http2_protocol_options(const envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(72, 112), const struct envoy_config_core_v3_Http2ProtocolOptions*); }
-UPB_INLINE upb_strview envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_server_name(const envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(44, 56), upb_strview); }
-UPB_INLINE bool envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_has_drain_timeout(const envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(76, 120)); }
-UPB_INLINE const struct google_protobuf_Duration* envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_drain_timeout(const envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(76, 120), const struct google_protobuf_Duration*); }
-UPB_INLINE bool envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_has_access_log(const envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(136, 240)); }
-UPB_INLINE const struct envoy_config_accesslog_v3_AccessLog* const* envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_access_log(const envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager *msg, size_t *len) { return (const struct envoy_config_accesslog_v3_AccessLog* const*)_upb_array_accessor(msg, UPB_SIZE(136, 240), len); }
-UPB_INLINE bool envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_has_use_remote_address(const envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(80, 128)); }
-UPB_INLINE const struct google_protobuf_BoolValue* envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_use_remote_address(const envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(80, 128), const struct google_protobuf_BoolValue*); }
-UPB_INLINE bool envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_has_generate_request_id(const envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(84, 136)); }
-UPB_INLINE const struct google_protobuf_BoolValue* envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_generate_request_id(const envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(84, 136), const struct google_protobuf_BoolValue*); }
+UPB_INLINE envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_route_specifier_oneofcases envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_route_specifier_case(const envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager* msg) { return (envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_route_specifier_oneofcases)*UPB_PTR_AT(msg, UPB_SIZE(140, 256), int32_t); }
+
+UPB_INLINE int32_t envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_codec_type(const envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(4, 4), int32_t); }
+UPB_INLINE upb_strview envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_stat_prefix(const envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(28, 32), upb_strview); }
+UPB_INLINE bool envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_has_rds(const envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager *msg) { return _upb_getoneofcase(msg, UPB_SIZE(140, 256)) == 3; }
+UPB_INLINE const envoy_extensions_filters_network_http_connection_manager_v3_Rds* envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_rds(const envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager *msg) { return UPB_READ_ONEOF(msg, const envoy_extensions_filters_network_http_connection_manager_v3_Rds*, UPB_SIZE(136, 248), UPB_SIZE(140, 256), 3, NULL); }
+UPB_INLINE bool envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_has_route_config(const envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager *msg) { return _upb_getoneofcase(msg, UPB_SIZE(140, 256)) == 4; }
+UPB_INLINE const struct envoy_config_route_v3_RouteConfiguration* envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_route_config(const envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager *msg) { return UPB_READ_ONEOF(msg, const struct envoy_config_route_v3_RouteConfiguration*, UPB_SIZE(136, 248), UPB_SIZE(140, 256), 4, NULL); }
+UPB_INLINE bool envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_has_http_filters(const envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(124, 224)); }
+UPB_INLINE const envoy_extensions_filters_network_http_connection_manager_v3_HttpFilter* const* envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_http_filters(const envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager *msg, size_t *len) { return (const envoy_extensions_filters_network_http_connection_manager_v3_HttpFilter* const*)_upb_array_accessor(msg, UPB_SIZE(124, 224), len); }
+UPB_INLINE bool envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_has_add_user_agent(const envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager *msg) { return _upb_hasbit(msg, 1); }
+UPB_INLINE const struct google_protobuf_BoolValue* envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_add_user_agent(const envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(52, 80), const struct google_protobuf_BoolValue*); }
+UPB_INLINE bool envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_has_tracing(const envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager *msg) { return _upb_hasbit(msg, 2); }
+UPB_INLINE const envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_Tracing* envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_tracing(const envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(56, 88), const envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_Tracing*); }
+UPB_INLINE bool envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_has_http_protocol_options(const envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager *msg) { return _upb_hasbit(msg, 3); }
+UPB_INLINE const struct envoy_config_core_v3_Http1ProtocolOptions* envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_http_protocol_options(const envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(60, 96), const struct envoy_config_core_v3_Http1ProtocolOptions*); }
+UPB_INLINE bool envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_has_http2_protocol_options(const envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager *msg) { return _upb_hasbit(msg, 4); }
+UPB_INLINE const struct envoy_config_core_v3_Http2ProtocolOptions* envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_http2_protocol_options(const envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(64, 104), const struct envoy_config_core_v3_Http2ProtocolOptions*); }
+UPB_INLINE upb_strview envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_server_name(const envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(36, 48), upb_strview); }
+UPB_INLINE bool envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_has_drain_timeout(const envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager *msg) { return _upb_hasbit(msg, 5); }
+UPB_INLINE const struct google_protobuf_Duration* envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_drain_timeout(const envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(68, 112), const struct google_protobuf_Duration*); }
+UPB_INLINE bool envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_has_access_log(const envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(128, 232)); }
+UPB_INLINE const struct envoy_config_accesslog_v3_AccessLog* const* envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_access_log(const envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager *msg, size_t *len) { return (const struct envoy_config_accesslog_v3_AccessLog* const*)_upb_array_accessor(msg, UPB_SIZE(128, 232), len); }
+UPB_INLINE bool envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_has_use_remote_address(const envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager *msg) { return _upb_hasbit(msg, 6); }
+UPB_INLINE const struct google_protobuf_BoolValue* envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_use_remote_address(const envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(72, 120), const struct google_protobuf_BoolValue*); }
+UPB_INLINE bool envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_has_generate_request_id(const envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager *msg) { return _upb_hasbit(msg, 7); }
+UPB_INLINE const struct google_protobuf_BoolValue* envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_generate_request_id(const envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(76, 128), const struct google_protobuf_BoolValue*); }
 UPB_INLINE int32_t envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_forward_client_cert_details(const envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(8, 8), int32_t); }
-UPB_INLINE bool envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_has_set_current_client_cert_details(const envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(88, 144)); }
-UPB_INLINE const envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_SetCurrentClientCertDetails* envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_set_current_client_cert_details(const envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(88, 144), const envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_SetCurrentClientCertDetails*); }
-UPB_INLINE bool envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_proxy_100_continue(const envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(28, 28), bool); }
-UPB_INLINE uint32_t envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_xff_num_trusted_hops(const envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(24, 24), uint32_t); }
-UPB_INLINE bool envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_represent_ipv4_remote_address_as_ipv4_mapped_ipv6(const envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(29, 29), bool); }
-UPB_INLINE bool envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_skip_xff_append(const envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(30, 30), bool); }
-UPB_INLINE upb_strview envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_via(const envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(52, 72), upb_strview); }
-UPB_INLINE bool envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_has_upgrade_configs(const envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(140, 248)); }
-UPB_INLINE const envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_UpgradeConfig* const* envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_upgrade_configs(const envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager *msg, size_t *len) { return (const envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_UpgradeConfig* const*)_upb_array_accessor(msg, UPB_SIZE(140, 248), len); }
-UPB_INLINE bool envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_has_stream_idle_timeout(const envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(92, 152)); }
-UPB_INLINE const struct google_protobuf_Duration* envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_stream_idle_timeout(const envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(92, 152), const struct google_protobuf_Duration*); }
-UPB_INLINE bool envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_has_internal_address_config(const envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(96, 160)); }
-UPB_INLINE const envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_InternalAddressConfig* envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_internal_address_config(const envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(96, 160), const envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_InternalAddressConfig*); }
-UPB_INLINE bool envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_has_delayed_close_timeout(const envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(100, 168)); }
-UPB_INLINE const struct google_protobuf_Duration* envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_delayed_close_timeout(const envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(100, 168), const struct google_protobuf_Duration*); }
-UPB_INLINE bool envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_has_request_timeout(const envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(104, 176)); }
-UPB_INLINE const struct google_protobuf_Duration* envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_request_timeout(const envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(104, 176), const struct google_protobuf_Duration*); }
-UPB_INLINE bool envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_has_max_request_headers_kb(const envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(108, 184)); }
-UPB_INLINE const struct google_protobuf_UInt32Value* envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_max_request_headers_kb(const envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(108, 184), const struct google_protobuf_UInt32Value*); }
-UPB_INLINE bool envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_has_normalize_path(const envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(112, 192)); }
-UPB_INLINE const struct google_protobuf_BoolValue* envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_normalize_path(const envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(112, 192), const struct google_protobuf_BoolValue*); }
-UPB_INLINE bool envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_has_scoped_routes(const envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager *msg) { return _upb_getoneofcase(msg, UPB_SIZE(148, 264)) == 31; }
-UPB_INLINE const envoy_extensions_filters_network_http_connection_manager_v3_ScopedRoutes* envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_scoped_routes(const envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager *msg) { return UPB_READ_ONEOF(msg, const envoy_extensions_filters_network_http_connection_manager_v3_ScopedRoutes*, UPB_SIZE(144, 256), UPB_SIZE(148, 264), 31, NULL); }
-UPB_INLINE bool envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_preserve_external_request_id(const envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(31, 31), bool); }
-UPB_INLINE bool envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_merge_slashes(const envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(32, 32), bool); }
-UPB_INLINE int32_t envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_server_header_transformation(const envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(16, 16), int32_t); }
-UPB_INLINE bool envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_has_common_http_protocol_options(const envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(116, 200)); }
-UPB_INLINE const struct envoy_config_core_v3_HttpProtocolOptions* envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_common_http_protocol_options(const envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(116, 200), const struct envoy_config_core_v3_HttpProtocolOptions*); }
-UPB_INLINE bool envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_has_request_id_extension(const envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(120, 208)); }
-UPB_INLINE const envoy_extensions_filters_network_http_connection_manager_v3_RequestIDExtension* envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_request_id_extension(const envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(120, 208), const envoy_extensions_filters_network_http_connection_manager_v3_RequestIDExtension*); }
-UPB_INLINE bool envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_always_set_request_id_in_response(const envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(33, 33), bool); }
-UPB_INLINE bool envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_has_local_reply_config(const envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(124, 216)); }
-UPB_INLINE const envoy_extensions_filters_network_http_connection_manager_v3_LocalReplyConfig* envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_local_reply_config(const envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(124, 216), const envoy_extensions_filters_network_http_connection_manager_v3_LocalReplyConfig*); }
-UPB_INLINE bool envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_strip_matching_host_port(const envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(34, 34), bool); }
-UPB_INLINE bool envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_has_stream_error_on_invalid_http_message(const envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(128, 224)); }
-UPB_INLINE const struct google_protobuf_BoolValue* envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_stream_error_on_invalid_http_message(const envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(128, 224), const struct google_protobuf_BoolValue*); }
+UPB_INLINE bool envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_has_set_current_client_cert_details(const envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager *msg) { return _upb_hasbit(msg, 8); }
+UPB_INLINE const envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_SetCurrentClientCertDetails* envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_set_current_client_cert_details(const envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(80, 136), const envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_SetCurrentClientCertDetails*); }
+UPB_INLINE bool envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_proxy_100_continue(const envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(20, 20), bool); }
+UPB_INLINE uint32_t envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_xff_num_trusted_hops(const envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(16, 16), uint32_t); }
+UPB_INLINE bool envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_represent_ipv4_remote_address_as_ipv4_mapped_ipv6(const envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(21, 21), bool); }
+UPB_INLINE bool envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_skip_xff_append(const envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(22, 22), bool); }
+UPB_INLINE upb_strview envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_via(const envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(44, 64), upb_strview); }
+UPB_INLINE bool envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_has_upgrade_configs(const envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(132, 240)); }
+UPB_INLINE const envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_UpgradeConfig* const* envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_upgrade_configs(const envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager *msg, size_t *len) { return (const envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_UpgradeConfig* const*)_upb_array_accessor(msg, UPB_SIZE(132, 240), len); }
+UPB_INLINE bool envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_has_stream_idle_timeout(const envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager *msg) { return _upb_hasbit(msg, 9); }
+UPB_INLINE const struct google_protobuf_Duration* envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_stream_idle_timeout(const envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(84, 144), const struct google_protobuf_Duration*); }
+UPB_INLINE bool envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_has_internal_address_config(const envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager *msg) { return _upb_hasbit(msg, 10); }
+UPB_INLINE const envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_InternalAddressConfig* envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_internal_address_config(const envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(88, 152), const envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_InternalAddressConfig*); }
+UPB_INLINE bool envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_has_delayed_close_timeout(const envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager *msg) { return _upb_hasbit(msg, 11); }
+UPB_INLINE const struct google_protobuf_Duration* envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_delayed_close_timeout(const envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(92, 160), const struct google_protobuf_Duration*); }
+UPB_INLINE bool envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_has_request_timeout(const envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager *msg) { return _upb_hasbit(msg, 12); }
+UPB_INLINE const struct google_protobuf_Duration* envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_request_timeout(const envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(96, 168), const struct google_protobuf_Duration*); }
+UPB_INLINE bool envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_has_max_request_headers_kb(const envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager *msg) { return _upb_hasbit(msg, 13); }
+UPB_INLINE const struct google_protobuf_UInt32Value* envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_max_request_headers_kb(const envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(100, 176), const struct google_protobuf_UInt32Value*); }
+UPB_INLINE bool envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_has_normalize_path(const envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager *msg) { return _upb_hasbit(msg, 14); }
+UPB_INLINE const struct google_protobuf_BoolValue* envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_normalize_path(const envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(104, 184), const struct google_protobuf_BoolValue*); }
+UPB_INLINE bool envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_has_scoped_routes(const envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager *msg) { return _upb_getoneofcase(msg, UPB_SIZE(140, 256)) == 31; }
+UPB_INLINE const envoy_extensions_filters_network_http_connection_manager_v3_ScopedRoutes* envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_scoped_routes(const envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager *msg) { return UPB_READ_ONEOF(msg, const envoy_extensions_filters_network_http_connection_manager_v3_ScopedRoutes*, UPB_SIZE(136, 248), UPB_SIZE(140, 256), 31, NULL); }
+UPB_INLINE bool envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_preserve_external_request_id(const envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(23, 23), bool); }
+UPB_INLINE bool envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_merge_slashes(const envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(24, 24), bool); }
+UPB_INLINE int32_t envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_server_header_transformation(const envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(12, 12), int32_t); }
+UPB_INLINE bool envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_has_common_http_protocol_options(const envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager *msg) { return _upb_hasbit(msg, 15); }
+UPB_INLINE const struct envoy_config_core_v3_HttpProtocolOptions* envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_common_http_protocol_options(const envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(108, 192), const struct envoy_config_core_v3_HttpProtocolOptions*); }
+UPB_INLINE bool envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_has_request_id_extension(const envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager *msg) { return _upb_hasbit(msg, 16); }
+UPB_INLINE const envoy_extensions_filters_network_http_connection_manager_v3_RequestIDExtension* envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_request_id_extension(const envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(112, 200), const envoy_extensions_filters_network_http_connection_manager_v3_RequestIDExtension*); }
+UPB_INLINE bool envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_always_set_request_id_in_response(const envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(25, 25), bool); }
+UPB_INLINE bool envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_has_local_reply_config(const envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager *msg) { return _upb_hasbit(msg, 17); }
+UPB_INLINE const envoy_extensions_filters_network_http_connection_manager_v3_LocalReplyConfig* envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_local_reply_config(const envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(116, 208), const envoy_extensions_filters_network_http_connection_manager_v3_LocalReplyConfig*); }
+UPB_INLINE bool envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_strip_matching_host_port(const envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(26, 26), bool); }
+UPB_INLINE bool envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_has_stream_error_on_invalid_http_message(const envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager *msg) { return _upb_hasbit(msg, 18); }
+UPB_INLINE const struct google_protobuf_BoolValue* envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_stream_error_on_invalid_http_message(const envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(120, 216), const struct google_protobuf_BoolValue*); }
 
 UPB_INLINE void envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_set_codec_type(envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager *msg, int32_t value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(0, 0), int32_t) = value;
+  *UPB_PTR_AT(msg, UPB_SIZE(4, 4), int32_t) = value;
 }
 UPB_INLINE void envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_set_stat_prefix(envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager *msg, upb_strview value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(36, 40), upb_strview) = value;
+  *UPB_PTR_AT(msg, UPB_SIZE(28, 32), upb_strview) = value;
 }
 UPB_INLINE void envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_set_rds(envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager *msg, envoy_extensions_filters_network_http_connection_manager_v3_Rds* value) {
-  UPB_WRITE_ONEOF(msg, envoy_extensions_filters_network_http_connection_manager_v3_Rds*, UPB_SIZE(144, 256), value, UPB_SIZE(148, 264), 3);
+  UPB_WRITE_ONEOF(msg, envoy_extensions_filters_network_http_connection_manager_v3_Rds*, UPB_SIZE(136, 248), value, UPB_SIZE(140, 256), 3);
 }
 UPB_INLINE struct envoy_extensions_filters_network_http_connection_manager_v3_Rds* envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_mutable_rds(envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager *msg, upb_arena *arena) {
   struct envoy_extensions_filters_network_http_connection_manager_v3_Rds* sub = (struct envoy_extensions_filters_network_http_connection_manager_v3_Rds*)envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_rds(msg);
@@ -242,7 +249,7 @@ UPB_INLINE struct envoy_extensions_filters_network_http_connection_manager_v3_Rd
   return sub;
 }
 UPB_INLINE void envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_set_route_config(envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager *msg, struct envoy_config_route_v3_RouteConfiguration* value) {
-  UPB_WRITE_ONEOF(msg, struct envoy_config_route_v3_RouteConfiguration*, UPB_SIZE(144, 256), value, UPB_SIZE(148, 264), 4);
+  UPB_WRITE_ONEOF(msg, struct envoy_config_route_v3_RouteConfiguration*, UPB_SIZE(136, 248), value, UPB_SIZE(140, 256), 4);
 }
 UPB_INLINE struct envoy_config_route_v3_RouteConfiguration* envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_mutable_route_config(envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager *msg, upb_arena *arena) {
   struct envoy_config_route_v3_RouteConfiguration* sub = (struct envoy_config_route_v3_RouteConfiguration*)envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_route_config(msg);
@@ -254,20 +261,21 @@ UPB_INLINE struct envoy_config_route_v3_RouteConfiguration* envoy_extensions_fil
   return sub;
 }
 UPB_INLINE envoy_extensions_filters_network_http_connection_manager_v3_HttpFilter** envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_mutable_http_filters(envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager *msg, size_t *len) {
-  return (envoy_extensions_filters_network_http_connection_manager_v3_HttpFilter**)_upb_array_mutable_accessor(msg, UPB_SIZE(132, 232), len);
+  return (envoy_extensions_filters_network_http_connection_manager_v3_HttpFilter**)_upb_array_mutable_accessor(msg, UPB_SIZE(124, 224), len);
 }
 UPB_INLINE envoy_extensions_filters_network_http_connection_manager_v3_HttpFilter** envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_resize_http_filters(envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager *msg, size_t len, upb_arena *arena) {
-  return (envoy_extensions_filters_network_http_connection_manager_v3_HttpFilter**)_upb_array_resize_accessor(msg, UPB_SIZE(132, 232), len, UPB_TYPE_MESSAGE, arena);
+  return (envoy_extensions_filters_network_http_connection_manager_v3_HttpFilter**)_upb_array_resize_accessor2(msg, UPB_SIZE(124, 224), len, UPB_SIZE(2, 3), arena);
 }
 UPB_INLINE struct envoy_extensions_filters_network_http_connection_manager_v3_HttpFilter* envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_add_http_filters(envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager *msg, upb_arena *arena) {
   struct envoy_extensions_filters_network_http_connection_manager_v3_HttpFilter* sub = (struct envoy_extensions_filters_network_http_connection_manager_v3_HttpFilter*)_upb_msg_new(&envoy_extensions_filters_network_http_connection_manager_v3_HttpFilter_msginit, arena);
-  bool ok = _upb_array_append_accessor(
-      msg, UPB_SIZE(132, 232), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena);
+  bool ok = _upb_array_append_accessor2(
+      msg, UPB_SIZE(124, 224), UPB_SIZE(2, 3), &sub, arena);
   if (!ok) return NULL;
   return sub;
 }
 UPB_INLINE void envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_set_add_user_agent(envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager *msg, struct google_protobuf_BoolValue* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(60, 88), struct google_protobuf_BoolValue*) = value;
+  _upb_sethas(msg, 1);
+  *UPB_PTR_AT(msg, UPB_SIZE(52, 80), struct google_protobuf_BoolValue*) = value;
 }
 UPB_INLINE struct google_protobuf_BoolValue* envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_mutable_add_user_agent(envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager *msg, upb_arena *arena) {
   struct google_protobuf_BoolValue* sub = (struct google_protobuf_BoolValue*)envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_add_user_agent(msg);
@@ -279,7 +287,8 @@ UPB_INLINE struct google_protobuf_BoolValue* envoy_extensions_filters_network_ht
   return sub;
 }
 UPB_INLINE void envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_set_tracing(envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager *msg, envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_Tracing* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(64, 96), envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_Tracing*) = value;
+  _upb_sethas(msg, 2);
+  *UPB_PTR_AT(msg, UPB_SIZE(56, 88), envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_Tracing*) = value;
 }
 UPB_INLINE struct envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_Tracing* envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_mutable_tracing(envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager *msg, upb_arena *arena) {
   struct envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_Tracing* sub = (struct envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_Tracing*)envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_tracing(msg);
@@ -291,7 +300,8 @@ UPB_INLINE struct envoy_extensions_filters_network_http_connection_manager_v3_Ht
   return sub;
 }
 UPB_INLINE void envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_set_http_protocol_options(envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager *msg, struct envoy_config_core_v3_Http1ProtocolOptions* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(68, 104), struct envoy_config_core_v3_Http1ProtocolOptions*) = value;
+  _upb_sethas(msg, 3);
+  *UPB_PTR_AT(msg, UPB_SIZE(60, 96), struct envoy_config_core_v3_Http1ProtocolOptions*) = value;
 }
 UPB_INLINE struct envoy_config_core_v3_Http1ProtocolOptions* envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_mutable_http_protocol_options(envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager *msg, upb_arena *arena) {
   struct envoy_config_core_v3_Http1ProtocolOptions* sub = (struct envoy_config_core_v3_Http1ProtocolOptions*)envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_http_protocol_options(msg);
@@ -303,7 +313,8 @@ UPB_INLINE struct envoy_config_core_v3_Http1ProtocolOptions* envoy_extensions_fi
   return sub;
 }
 UPB_INLINE void envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_set_http2_protocol_options(envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager *msg, struct envoy_config_core_v3_Http2ProtocolOptions* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(72, 112), struct envoy_config_core_v3_Http2ProtocolOptions*) = value;
+  _upb_sethas(msg, 4);
+  *UPB_PTR_AT(msg, UPB_SIZE(64, 104), struct envoy_config_core_v3_Http2ProtocolOptions*) = value;
 }
 UPB_INLINE struct envoy_config_core_v3_Http2ProtocolOptions* envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_mutable_http2_protocol_options(envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager *msg, upb_arena *arena) {
   struct envoy_config_core_v3_Http2ProtocolOptions* sub = (struct envoy_config_core_v3_Http2ProtocolOptions*)envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_http2_protocol_options(msg);
@@ -315,10 +326,11 @@ UPB_INLINE struct envoy_config_core_v3_Http2ProtocolOptions* envoy_extensions_fi
   return sub;
 }
 UPB_INLINE void envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_set_server_name(envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager *msg, upb_strview value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(44, 56), upb_strview) = value;
+  *UPB_PTR_AT(msg, UPB_SIZE(36, 48), upb_strview) = value;
 }
 UPB_INLINE void envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_set_drain_timeout(envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager *msg, struct google_protobuf_Duration* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(76, 120), struct google_protobuf_Duration*) = value;
+  _upb_sethas(msg, 5);
+  *UPB_PTR_AT(msg, UPB_SIZE(68, 112), struct google_protobuf_Duration*) = value;
 }
 UPB_INLINE struct google_protobuf_Duration* envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_mutable_drain_timeout(envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager *msg, upb_arena *arena) {
   struct google_protobuf_Duration* sub = (struct google_protobuf_Duration*)envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_drain_timeout(msg);
@@ -330,20 +342,21 @@ UPB_INLINE struct google_protobuf_Duration* envoy_extensions_filters_network_htt
   return sub;
 }
 UPB_INLINE struct envoy_config_accesslog_v3_AccessLog** envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_mutable_access_log(envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager *msg, size_t *len) {
-  return (struct envoy_config_accesslog_v3_AccessLog**)_upb_array_mutable_accessor(msg, UPB_SIZE(136, 240), len);
+  return (struct envoy_config_accesslog_v3_AccessLog**)_upb_array_mutable_accessor(msg, UPB_SIZE(128, 232), len);
 }
 UPB_INLINE struct envoy_config_accesslog_v3_AccessLog** envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_resize_access_log(envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager *msg, size_t len, upb_arena *arena) {
-  return (struct envoy_config_accesslog_v3_AccessLog**)_upb_array_resize_accessor(msg, UPB_SIZE(136, 240), len, UPB_TYPE_MESSAGE, arena);
+  return (struct envoy_config_accesslog_v3_AccessLog**)_upb_array_resize_accessor2(msg, UPB_SIZE(128, 232), len, UPB_SIZE(2, 3), arena);
 }
 UPB_INLINE struct envoy_config_accesslog_v3_AccessLog* envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_add_access_log(envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager *msg, upb_arena *arena) {
   struct envoy_config_accesslog_v3_AccessLog* sub = (struct envoy_config_accesslog_v3_AccessLog*)_upb_msg_new(&envoy_config_accesslog_v3_AccessLog_msginit, arena);
-  bool ok = _upb_array_append_accessor(
-      msg, UPB_SIZE(136, 240), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena);
+  bool ok = _upb_array_append_accessor2(
+      msg, UPB_SIZE(128, 232), UPB_SIZE(2, 3), &sub, arena);
   if (!ok) return NULL;
   return sub;
 }
 UPB_INLINE void envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_set_use_remote_address(envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager *msg, struct google_protobuf_BoolValue* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(80, 128), struct google_protobuf_BoolValue*) = value;
+  _upb_sethas(msg, 6);
+  *UPB_PTR_AT(msg, UPB_SIZE(72, 120), struct google_protobuf_BoolValue*) = value;
 }
 UPB_INLINE struct google_protobuf_BoolValue* envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_mutable_use_remote_address(envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager *msg, upb_arena *arena) {
   struct google_protobuf_BoolValue* sub = (struct google_protobuf_BoolValue*)envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_use_remote_address(msg);
@@ -355,7 +368,8 @@ UPB_INLINE struct google_protobuf_BoolValue* envoy_extensions_filters_network_ht
   return sub;
 }
 UPB_INLINE void envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_set_generate_request_id(envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager *msg, struct google_protobuf_BoolValue* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(84, 136), struct google_protobuf_BoolValue*) = value;
+  _upb_sethas(msg, 7);
+  *UPB_PTR_AT(msg, UPB_SIZE(76, 128), struct google_protobuf_BoolValue*) = value;
 }
 UPB_INLINE struct google_protobuf_BoolValue* envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_mutable_generate_request_id(envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager *msg, upb_arena *arena) {
   struct google_protobuf_BoolValue* sub = (struct google_protobuf_BoolValue*)envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_generate_request_id(msg);
@@ -370,7 +384,8 @@ UPB_INLINE void envoy_extensions_filters_network_http_connection_manager_v3_Http
   *UPB_PTR_AT(msg, UPB_SIZE(8, 8), int32_t) = value;
 }
 UPB_INLINE void envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_set_set_current_client_cert_details(envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager *msg, envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_SetCurrentClientCertDetails* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(88, 144), envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_SetCurrentClientCertDetails*) = value;
+  _upb_sethas(msg, 8);
+  *UPB_PTR_AT(msg, UPB_SIZE(80, 136), envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_SetCurrentClientCertDetails*) = value;
 }
 UPB_INLINE struct envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_SetCurrentClientCertDetails* envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_mutable_set_current_client_cert_details(envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager *msg, upb_arena *arena) {
   struct envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_SetCurrentClientCertDetails* sub = (struct envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_SetCurrentClientCertDetails*)envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_set_current_client_cert_details(msg);
@@ -382,35 +397,36 @@ UPB_INLINE struct envoy_extensions_filters_network_http_connection_manager_v3_Ht
   return sub;
 }
 UPB_INLINE void envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_set_proxy_100_continue(envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager *msg, bool value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(28, 28), bool) = value;
+  *UPB_PTR_AT(msg, UPB_SIZE(20, 20), bool) = value;
 }
 UPB_INLINE void envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_set_xff_num_trusted_hops(envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager *msg, uint32_t value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(24, 24), uint32_t) = value;
+  *UPB_PTR_AT(msg, UPB_SIZE(16, 16), uint32_t) = value;
 }
 UPB_INLINE void envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_set_represent_ipv4_remote_address_as_ipv4_mapped_ipv6(envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager *msg, bool value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(29, 29), bool) = value;
+  *UPB_PTR_AT(msg, UPB_SIZE(21, 21), bool) = value;
 }
 UPB_INLINE void envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_set_skip_xff_append(envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager *msg, bool value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(30, 30), bool) = value;
+  *UPB_PTR_AT(msg, UPB_SIZE(22, 22), bool) = value;
 }
 UPB_INLINE void envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_set_via(envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager *msg, upb_strview value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(52, 72), upb_strview) = value;
+  *UPB_PTR_AT(msg, UPB_SIZE(44, 64), upb_strview) = value;
 }
 UPB_INLINE envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_UpgradeConfig** envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_mutable_upgrade_configs(envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager *msg, size_t *len) {
-  return (envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_UpgradeConfig**)_upb_array_mutable_accessor(msg, UPB_SIZE(140, 248), len);
+  return (envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_UpgradeConfig**)_upb_array_mutable_accessor(msg, UPB_SIZE(132, 240), len);
 }
 UPB_INLINE envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_UpgradeConfig** envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_resize_upgrade_configs(envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager *msg, size_t len, upb_arena *arena) {
-  return (envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_UpgradeConfig**)_upb_array_resize_accessor(msg, UPB_SIZE(140, 248), len, UPB_TYPE_MESSAGE, arena);
+  return (envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_UpgradeConfig**)_upb_array_resize_accessor2(msg, UPB_SIZE(132, 240), len, UPB_SIZE(2, 3), arena);
 }
 UPB_INLINE struct envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_UpgradeConfig* envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_add_upgrade_configs(envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager *msg, upb_arena *arena) {
   struct envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_UpgradeConfig* sub = (struct envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_UpgradeConfig*)_upb_msg_new(&envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_UpgradeConfig_msginit, arena);
-  bool ok = _upb_array_append_accessor(
-      msg, UPB_SIZE(140, 248), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena);
+  bool ok = _upb_array_append_accessor2(
+      msg, UPB_SIZE(132, 240), UPB_SIZE(2, 3), &sub, arena);
   if (!ok) return NULL;
   return sub;
 }
 UPB_INLINE void envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_set_stream_idle_timeout(envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager *msg, struct google_protobuf_Duration* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(92, 152), struct google_protobuf_Duration*) = value;
+  _upb_sethas(msg, 9);
+  *UPB_PTR_AT(msg, UPB_SIZE(84, 144), struct google_protobuf_Duration*) = value;
 }
 UPB_INLINE struct google_protobuf_Duration* envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_mutable_stream_idle_timeout(envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager *msg, upb_arena *arena) {
   struct google_protobuf_Duration* sub = (struct google_protobuf_Duration*)envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_stream_idle_timeout(msg);
@@ -422,7 +438,8 @@ UPB_INLINE struct google_protobuf_Duration* envoy_extensions_filters_network_htt
   return sub;
 }
 UPB_INLINE void envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_set_internal_address_config(envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager *msg, envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_InternalAddressConfig* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(96, 160), envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_InternalAddressConfig*) = value;
+  _upb_sethas(msg, 10);
+  *UPB_PTR_AT(msg, UPB_SIZE(88, 152), envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_InternalAddressConfig*) = value;
 }
 UPB_INLINE struct envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_InternalAddressConfig* envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_mutable_internal_address_config(envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager *msg, upb_arena *arena) {
   struct envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_InternalAddressConfig* sub = (struct envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_InternalAddressConfig*)envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_internal_address_config(msg);
@@ -434,7 +451,8 @@ UPB_INLINE struct envoy_extensions_filters_network_http_connection_manager_v3_Ht
   return sub;
 }
 UPB_INLINE void envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_set_delayed_close_timeout(envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager *msg, struct google_protobuf_Duration* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(100, 168), struct google_protobuf_Duration*) = value;
+  _upb_sethas(msg, 11);
+  *UPB_PTR_AT(msg, UPB_SIZE(92, 160), struct google_protobuf_Duration*) = value;
 }
 UPB_INLINE struct google_protobuf_Duration* envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_mutable_delayed_close_timeout(envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager *msg, upb_arena *arena) {
   struct google_protobuf_Duration* sub = (struct google_protobuf_Duration*)envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_delayed_close_timeout(msg);
@@ -446,7 +464,8 @@ UPB_INLINE struct google_protobuf_Duration* envoy_extensions_filters_network_htt
   return sub;
 }
 UPB_INLINE void envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_set_request_timeout(envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager *msg, struct google_protobuf_Duration* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(104, 176), struct google_protobuf_Duration*) = value;
+  _upb_sethas(msg, 12);
+  *UPB_PTR_AT(msg, UPB_SIZE(96, 168), struct google_protobuf_Duration*) = value;
 }
 UPB_INLINE struct google_protobuf_Duration* envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_mutable_request_timeout(envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager *msg, upb_arena *arena) {
   struct google_protobuf_Duration* sub = (struct google_protobuf_Duration*)envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_request_timeout(msg);
@@ -458,7 +477,8 @@ UPB_INLINE struct google_protobuf_Duration* envoy_extensions_filters_network_htt
   return sub;
 }
 UPB_INLINE void envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_set_max_request_headers_kb(envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager *msg, struct google_protobuf_UInt32Value* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(108, 184), struct google_protobuf_UInt32Value*) = value;
+  _upb_sethas(msg, 13);
+  *UPB_PTR_AT(msg, UPB_SIZE(100, 176), struct google_protobuf_UInt32Value*) = value;
 }
 UPB_INLINE struct google_protobuf_UInt32Value* envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_mutable_max_request_headers_kb(envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager *msg, upb_arena *arena) {
   struct google_protobuf_UInt32Value* sub = (struct google_protobuf_UInt32Value*)envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_max_request_headers_kb(msg);
@@ -470,7 +490,8 @@ UPB_INLINE struct google_protobuf_UInt32Value* envoy_extensions_filters_network_
   return sub;
 }
 UPB_INLINE void envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_set_normalize_path(envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager *msg, struct google_protobuf_BoolValue* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(112, 192), struct google_protobuf_BoolValue*) = value;
+  _upb_sethas(msg, 14);
+  *UPB_PTR_AT(msg, UPB_SIZE(104, 184), struct google_protobuf_BoolValue*) = value;
 }
 UPB_INLINE struct google_protobuf_BoolValue* envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_mutable_normalize_path(envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager *msg, upb_arena *arena) {
   struct google_protobuf_BoolValue* sub = (struct google_protobuf_BoolValue*)envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_normalize_path(msg);
@@ -482,7 +503,7 @@ UPB_INLINE struct google_protobuf_BoolValue* envoy_extensions_filters_network_ht
   return sub;
 }
 UPB_INLINE void envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_set_scoped_routes(envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager *msg, envoy_extensions_filters_network_http_connection_manager_v3_ScopedRoutes* value) {
-  UPB_WRITE_ONEOF(msg, envoy_extensions_filters_network_http_connection_manager_v3_ScopedRoutes*, UPB_SIZE(144, 256), value, UPB_SIZE(148, 264), 31);
+  UPB_WRITE_ONEOF(msg, envoy_extensions_filters_network_http_connection_manager_v3_ScopedRoutes*, UPB_SIZE(136, 248), value, UPB_SIZE(140, 256), 31);
 }
 UPB_INLINE struct envoy_extensions_filters_network_http_connection_manager_v3_ScopedRoutes* envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_mutable_scoped_routes(envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager *msg, upb_arena *arena) {
   struct envoy_extensions_filters_network_http_connection_manager_v3_ScopedRoutes* sub = (struct envoy_extensions_filters_network_http_connection_manager_v3_ScopedRoutes*)envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_scoped_routes(msg);
@@ -494,16 +515,17 @@ UPB_INLINE struct envoy_extensions_filters_network_http_connection_manager_v3_Sc
   return sub;
 }
 UPB_INLINE void envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_set_preserve_external_request_id(envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager *msg, bool value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(31, 31), bool) = value;
+  *UPB_PTR_AT(msg, UPB_SIZE(23, 23), bool) = value;
 }
 UPB_INLINE void envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_set_merge_slashes(envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager *msg, bool value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(32, 32), bool) = value;
+  *UPB_PTR_AT(msg, UPB_SIZE(24, 24), bool) = value;
 }
 UPB_INLINE void envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_set_server_header_transformation(envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager *msg, int32_t value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(16, 16), int32_t) = value;
+  *UPB_PTR_AT(msg, UPB_SIZE(12, 12), int32_t) = value;
 }
 UPB_INLINE void envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_set_common_http_protocol_options(envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager *msg, struct envoy_config_core_v3_HttpProtocolOptions* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(116, 200), struct envoy_config_core_v3_HttpProtocolOptions*) = value;
+  _upb_sethas(msg, 15);
+  *UPB_PTR_AT(msg, UPB_SIZE(108, 192), struct envoy_config_core_v3_HttpProtocolOptions*) = value;
 }
 UPB_INLINE struct envoy_config_core_v3_HttpProtocolOptions* envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_mutable_common_http_protocol_options(envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager *msg, upb_arena *arena) {
   struct envoy_config_core_v3_HttpProtocolOptions* sub = (struct envoy_config_core_v3_HttpProtocolOptions*)envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_common_http_protocol_options(msg);
@@ -515,7 +537,8 @@ UPB_INLINE struct envoy_config_core_v3_HttpProtocolOptions* envoy_extensions_fil
   return sub;
 }
 UPB_INLINE void envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_set_request_id_extension(envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager *msg, envoy_extensions_filters_network_http_connection_manager_v3_RequestIDExtension* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(120, 208), envoy_extensions_filters_network_http_connection_manager_v3_RequestIDExtension*) = value;
+  _upb_sethas(msg, 16);
+  *UPB_PTR_AT(msg, UPB_SIZE(112, 200), envoy_extensions_filters_network_http_connection_manager_v3_RequestIDExtension*) = value;
 }
 UPB_INLINE struct envoy_extensions_filters_network_http_connection_manager_v3_RequestIDExtension* envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_mutable_request_id_extension(envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager *msg, upb_arena *arena) {
   struct envoy_extensions_filters_network_http_connection_manager_v3_RequestIDExtension* sub = (struct envoy_extensions_filters_network_http_connection_manager_v3_RequestIDExtension*)envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_request_id_extension(msg);
@@ -527,10 +550,11 @@ UPB_INLINE struct envoy_extensions_filters_network_http_connection_manager_v3_Re
   return sub;
 }
 UPB_INLINE void envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_set_always_set_request_id_in_response(envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager *msg, bool value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(33, 33), bool) = value;
+  *UPB_PTR_AT(msg, UPB_SIZE(25, 25), bool) = value;
 }
 UPB_INLINE void envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_set_local_reply_config(envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager *msg, envoy_extensions_filters_network_http_connection_manager_v3_LocalReplyConfig* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(124, 216), envoy_extensions_filters_network_http_connection_manager_v3_LocalReplyConfig*) = value;
+  _upb_sethas(msg, 17);
+  *UPB_PTR_AT(msg, UPB_SIZE(116, 208), envoy_extensions_filters_network_http_connection_manager_v3_LocalReplyConfig*) = value;
 }
 UPB_INLINE struct envoy_extensions_filters_network_http_connection_manager_v3_LocalReplyConfig* envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_mutable_local_reply_config(envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager *msg, upb_arena *arena) {
   struct envoy_extensions_filters_network_http_connection_manager_v3_LocalReplyConfig* sub = (struct envoy_extensions_filters_network_http_connection_manager_v3_LocalReplyConfig*)envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_local_reply_config(msg);
@@ -542,10 +566,11 @@ UPB_INLINE struct envoy_extensions_filters_network_http_connection_manager_v3_Lo
   return sub;
 }
 UPB_INLINE void envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_set_strip_matching_host_port(envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager *msg, bool value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(34, 34), bool) = value;
+  *UPB_PTR_AT(msg, UPB_SIZE(26, 26), bool) = value;
 }
 UPB_INLINE void envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_set_stream_error_on_invalid_http_message(envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager *msg, struct google_protobuf_BoolValue* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(128, 224), struct google_protobuf_BoolValue*) = value;
+  _upb_sethas(msg, 18);
+  *UPB_PTR_AT(msg, UPB_SIZE(120, 216), struct google_protobuf_BoolValue*) = value;
 }
 UPB_INLINE struct google_protobuf_BoolValue* envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_mutable_stream_error_on_invalid_http_message(envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager *msg, upb_arena *arena) {
   struct google_protobuf_BoolValue* sub = (struct google_protobuf_BoolValue*)envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_stream_error_on_invalid_http_message(msg);
@@ -567,25 +592,32 @@ UPB_INLINE envoy_extensions_filters_network_http_connection_manager_v3_HttpConne
   envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_Tracing *ret = envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_Tracing_new(arena);
   return (ret && upb_decode(buf, size, ret, &envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_Tracing_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_Tracing *envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_Tracing_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_Tracing *ret = envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_Tracing_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_Tracing_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_Tracing_serialize(const envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_Tracing *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_Tracing_msginit, arena, len);
 }
 
-UPB_INLINE bool envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_Tracing_has_client_sampling(const envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_Tracing *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(4, 8)); }
+UPB_INLINE bool envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_Tracing_has_client_sampling(const envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_Tracing *msg) { return _upb_hasbit(msg, 1); }
 UPB_INLINE const struct envoy_type_v3_Percent* envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_Tracing_client_sampling(const envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_Tracing *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(4, 8), const struct envoy_type_v3_Percent*); }
-UPB_INLINE bool envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_Tracing_has_random_sampling(const envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_Tracing *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(8, 16)); }
+UPB_INLINE bool envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_Tracing_has_random_sampling(const envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_Tracing *msg) { return _upb_hasbit(msg, 2); }
 UPB_INLINE const struct envoy_type_v3_Percent* envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_Tracing_random_sampling(const envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_Tracing *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(8, 16), const struct envoy_type_v3_Percent*); }
-UPB_INLINE bool envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_Tracing_has_overall_sampling(const envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_Tracing *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(12, 24)); }
+UPB_INLINE bool envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_Tracing_has_overall_sampling(const envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_Tracing *msg) { return _upb_hasbit(msg, 3); }
 UPB_INLINE const struct envoy_type_v3_Percent* envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_Tracing_overall_sampling(const envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_Tracing *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(12, 24), const struct envoy_type_v3_Percent*); }
-UPB_INLINE bool envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_Tracing_verbose(const envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_Tracing *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(0, 0), bool); }
-UPB_INLINE bool envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_Tracing_has_max_path_tag_length(const envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_Tracing *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(16, 32)); }
+UPB_INLINE bool envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_Tracing_verbose(const envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_Tracing *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(1, 1), bool); }
+UPB_INLINE bool envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_Tracing_has_max_path_tag_length(const envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_Tracing *msg) { return _upb_hasbit(msg, 4); }
 UPB_INLINE const struct google_protobuf_UInt32Value* envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_Tracing_max_path_tag_length(const envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_Tracing *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(16, 32), const struct google_protobuf_UInt32Value*); }
 UPB_INLINE bool envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_Tracing_has_custom_tags(const envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_Tracing *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(24, 48)); }
 UPB_INLINE const struct envoy_type_tracing_v3_CustomTag* const* envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_Tracing_custom_tags(const envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_Tracing *msg, size_t *len) { return (const struct envoy_type_tracing_v3_CustomTag* const*)_upb_array_accessor(msg, UPB_SIZE(24, 48), len); }
-UPB_INLINE bool envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_Tracing_has_provider(const envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_Tracing *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(20, 40)); }
+UPB_INLINE bool envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_Tracing_has_provider(const envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_Tracing *msg) { return _upb_hasbit(msg, 5); }
 UPB_INLINE const struct envoy_config_trace_v3_Tracing_Http* envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_Tracing_provider(const envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_Tracing *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(20, 40), const struct envoy_config_trace_v3_Tracing_Http*); }
 
 UPB_INLINE void envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_Tracing_set_client_sampling(envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_Tracing *msg, struct envoy_type_v3_Percent* value) {
+  _upb_sethas(msg, 1);
   *UPB_PTR_AT(msg, UPB_SIZE(4, 8), struct envoy_type_v3_Percent*) = value;
 }
 UPB_INLINE struct envoy_type_v3_Percent* envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_Tracing_mutable_client_sampling(envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_Tracing *msg, upb_arena *arena) {
@@ -598,6 +630,7 @@ UPB_INLINE struct envoy_type_v3_Percent* envoy_extensions_filters_network_http_c
   return sub;
 }
 UPB_INLINE void envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_Tracing_set_random_sampling(envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_Tracing *msg, struct envoy_type_v3_Percent* value) {
+  _upb_sethas(msg, 2);
   *UPB_PTR_AT(msg, UPB_SIZE(8, 16), struct envoy_type_v3_Percent*) = value;
 }
 UPB_INLINE struct envoy_type_v3_Percent* envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_Tracing_mutable_random_sampling(envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_Tracing *msg, upb_arena *arena) {
@@ -610,6 +643,7 @@ UPB_INLINE struct envoy_type_v3_Percent* envoy_extensions_filters_network_http_c
   return sub;
 }
 UPB_INLINE void envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_Tracing_set_overall_sampling(envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_Tracing *msg, struct envoy_type_v3_Percent* value) {
+  _upb_sethas(msg, 3);
   *UPB_PTR_AT(msg, UPB_SIZE(12, 24), struct envoy_type_v3_Percent*) = value;
 }
 UPB_INLINE struct envoy_type_v3_Percent* envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_Tracing_mutable_overall_sampling(envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_Tracing *msg, upb_arena *arena) {
@@ -622,9 +656,10 @@ UPB_INLINE struct envoy_type_v3_Percent* envoy_extensions_filters_network_http_c
   return sub;
 }
 UPB_INLINE void envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_Tracing_set_verbose(envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_Tracing *msg, bool value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(0, 0), bool) = value;
+  *UPB_PTR_AT(msg, UPB_SIZE(1, 1), bool) = value;
 }
 UPB_INLINE void envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_Tracing_set_max_path_tag_length(envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_Tracing *msg, struct google_protobuf_UInt32Value* value) {
+  _upb_sethas(msg, 4);
   *UPB_PTR_AT(msg, UPB_SIZE(16, 32), struct google_protobuf_UInt32Value*) = value;
 }
 UPB_INLINE struct google_protobuf_UInt32Value* envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_Tracing_mutable_max_path_tag_length(envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_Tracing *msg, upb_arena *arena) {
@@ -640,16 +675,17 @@ UPB_INLINE struct envoy_type_tracing_v3_CustomTag** envoy_extensions_filters_net
   return (struct envoy_type_tracing_v3_CustomTag**)_upb_array_mutable_accessor(msg, UPB_SIZE(24, 48), len);
 }
 UPB_INLINE struct envoy_type_tracing_v3_CustomTag** envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_Tracing_resize_custom_tags(envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_Tracing *msg, size_t len, upb_arena *arena) {
-  return (struct envoy_type_tracing_v3_CustomTag**)_upb_array_resize_accessor(msg, UPB_SIZE(24, 48), len, UPB_TYPE_MESSAGE, arena);
+  return (struct envoy_type_tracing_v3_CustomTag**)_upb_array_resize_accessor2(msg, UPB_SIZE(24, 48), len, UPB_SIZE(2, 3), arena);
 }
 UPB_INLINE struct envoy_type_tracing_v3_CustomTag* envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_Tracing_add_custom_tags(envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_Tracing *msg, upb_arena *arena) {
   struct envoy_type_tracing_v3_CustomTag* sub = (struct envoy_type_tracing_v3_CustomTag*)_upb_msg_new(&envoy_type_tracing_v3_CustomTag_msginit, arena);
-  bool ok = _upb_array_append_accessor(
-      msg, UPB_SIZE(24, 48), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena);
+  bool ok = _upb_array_append_accessor2(
+      msg, UPB_SIZE(24, 48), UPB_SIZE(2, 3), &sub, arena);
   if (!ok) return NULL;
   return sub;
 }
 UPB_INLINE void envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_Tracing_set_provider(envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_Tracing *msg, struct envoy_config_trace_v3_Tracing_Http* value) {
+  _upb_sethas(msg, 5);
   *UPB_PTR_AT(msg, UPB_SIZE(20, 40), struct envoy_config_trace_v3_Tracing_Http*) = value;
 }
 UPB_INLINE struct envoy_config_trace_v3_Tracing_Http* envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_Tracing_mutable_provider(envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_Tracing *msg, upb_arena *arena) {
@@ -672,6 +708,12 @@ UPB_INLINE envoy_extensions_filters_network_http_connection_manager_v3_HttpConne
   envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_InternalAddressConfig *ret = envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_InternalAddressConfig_new(arena);
   return (ret && upb_decode(buf, size, ret, &envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_InternalAddressConfig_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_InternalAddressConfig *envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_InternalAddressConfig_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_InternalAddressConfig *ret = envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_InternalAddressConfig_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_InternalAddressConfig_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_InternalAddressConfig_serialize(const envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_InternalAddressConfig *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_InternalAddressConfig_msginit, arena, len);
 }
@@ -692,19 +734,26 @@ UPB_INLINE envoy_extensions_filters_network_http_connection_manager_v3_HttpConne
   envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_SetCurrentClientCertDetails *ret = envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_SetCurrentClientCertDetails_new(arena);
   return (ret && upb_decode(buf, size, ret, &envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_SetCurrentClientCertDetails_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_SetCurrentClientCertDetails *envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_SetCurrentClientCertDetails_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_SetCurrentClientCertDetails *ret = envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_SetCurrentClientCertDetails_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_SetCurrentClientCertDetails_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_SetCurrentClientCertDetails_serialize(const envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_SetCurrentClientCertDetails *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_SetCurrentClientCertDetails_msginit, arena, len);
 }
 
-UPB_INLINE bool envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_SetCurrentClientCertDetails_has_subject(const envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_SetCurrentClientCertDetails *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(4, 8)); }
-UPB_INLINE const struct google_protobuf_BoolValue* envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_SetCurrentClientCertDetails_subject(const envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_SetCurrentClientCertDetails *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(4, 8), const struct google_protobuf_BoolValue*); }
-UPB_INLINE bool envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_SetCurrentClientCertDetails_cert(const envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_SetCurrentClientCertDetails *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(0, 0), bool); }
-UPB_INLINE bool envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_SetCurrentClientCertDetails_dns(const envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_SetCurrentClientCertDetails *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(1, 1), bool); }
-UPB_INLINE bool envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_SetCurrentClientCertDetails_uri(const envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_SetCurrentClientCertDetails *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(2, 2), bool); }
-UPB_INLINE bool envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_SetCurrentClientCertDetails_chain(const envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_SetCurrentClientCertDetails *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(3, 3), bool); }
+UPB_INLINE bool envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_SetCurrentClientCertDetails_has_subject(const envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_SetCurrentClientCertDetails *msg) { return _upb_hasbit(msg, 1); }
+UPB_INLINE const struct google_protobuf_BoolValue* envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_SetCurrentClientCertDetails_subject(const envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_SetCurrentClientCertDetails *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(8, 8), const struct google_protobuf_BoolValue*); }
+UPB_INLINE bool envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_SetCurrentClientCertDetails_cert(const envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_SetCurrentClientCertDetails *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(1, 1), bool); }
+UPB_INLINE bool envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_SetCurrentClientCertDetails_dns(const envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_SetCurrentClientCertDetails *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(2, 2), bool); }
+UPB_INLINE bool envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_SetCurrentClientCertDetails_uri(const envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_SetCurrentClientCertDetails *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(3, 3), bool); }
+UPB_INLINE bool envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_SetCurrentClientCertDetails_chain(const envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_SetCurrentClientCertDetails *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(4, 4), bool); }
 
 UPB_INLINE void envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_SetCurrentClientCertDetails_set_subject(envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_SetCurrentClientCertDetails *msg, struct google_protobuf_BoolValue* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(4, 8), struct google_protobuf_BoolValue*) = value;
+  _upb_sethas(msg, 1);
+  *UPB_PTR_AT(msg, UPB_SIZE(8, 8), struct google_protobuf_BoolValue*) = value;
 }
 UPB_INLINE struct google_protobuf_BoolValue* envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_SetCurrentClientCertDetails_mutable_subject(envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_SetCurrentClientCertDetails *msg, upb_arena *arena) {
   struct google_protobuf_BoolValue* sub = (struct google_protobuf_BoolValue*)envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_SetCurrentClientCertDetails_subject(msg);
@@ -716,16 +765,16 @@ UPB_INLINE struct google_protobuf_BoolValue* envoy_extensions_filters_network_ht
   return sub;
 }
 UPB_INLINE void envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_SetCurrentClientCertDetails_set_cert(envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_SetCurrentClientCertDetails *msg, bool value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(0, 0), bool) = value;
+  *UPB_PTR_AT(msg, UPB_SIZE(1, 1), bool) = value;
 }
 UPB_INLINE void envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_SetCurrentClientCertDetails_set_dns(envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_SetCurrentClientCertDetails *msg, bool value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(1, 1), bool) = value;
+  *UPB_PTR_AT(msg, UPB_SIZE(2, 2), bool) = value;
 }
 UPB_INLINE void envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_SetCurrentClientCertDetails_set_uri(envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_SetCurrentClientCertDetails *msg, bool value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(2, 2), bool) = value;
+  *UPB_PTR_AT(msg, UPB_SIZE(3, 3), bool) = value;
 }
 UPB_INLINE void envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_SetCurrentClientCertDetails_set_chain(envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_SetCurrentClientCertDetails *msg, bool value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(3, 3), bool) = value;
+  *UPB_PTR_AT(msg, UPB_SIZE(4, 4), bool) = value;
 }
 
 /* envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager.UpgradeConfig */
@@ -738,34 +787,41 @@ UPB_INLINE envoy_extensions_filters_network_http_connection_manager_v3_HttpConne
   envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_UpgradeConfig *ret = envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_UpgradeConfig_new(arena);
   return (ret && upb_decode(buf, size, ret, &envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_UpgradeConfig_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_UpgradeConfig *envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_UpgradeConfig_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_UpgradeConfig *ret = envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_UpgradeConfig_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_UpgradeConfig_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_UpgradeConfig_serialize(const envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_UpgradeConfig *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_UpgradeConfig_msginit, arena, len);
 }
 
-UPB_INLINE upb_strview envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_UpgradeConfig_upgrade_type(const envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_UpgradeConfig *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(0, 0), upb_strview); }
-UPB_INLINE bool envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_UpgradeConfig_has_filters(const envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_UpgradeConfig *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(12, 24)); }
-UPB_INLINE const envoy_extensions_filters_network_http_connection_manager_v3_HttpFilter* const* envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_UpgradeConfig_filters(const envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_UpgradeConfig *msg, size_t *len) { return (const envoy_extensions_filters_network_http_connection_manager_v3_HttpFilter* const*)_upb_array_accessor(msg, UPB_SIZE(12, 24), len); }
-UPB_INLINE bool envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_UpgradeConfig_has_enabled(const envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_UpgradeConfig *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(8, 16)); }
-UPB_INLINE const struct google_protobuf_BoolValue* envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_UpgradeConfig_enabled(const envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_UpgradeConfig *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(8, 16), const struct google_protobuf_BoolValue*); }
+UPB_INLINE upb_strview envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_UpgradeConfig_upgrade_type(const envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_UpgradeConfig *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(4, 8), upb_strview); }
+UPB_INLINE bool envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_UpgradeConfig_has_filters(const envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_UpgradeConfig *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(16, 32)); }
+UPB_INLINE const envoy_extensions_filters_network_http_connection_manager_v3_HttpFilter* const* envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_UpgradeConfig_filters(const envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_UpgradeConfig *msg, size_t *len) { return (const envoy_extensions_filters_network_http_connection_manager_v3_HttpFilter* const*)_upb_array_accessor(msg, UPB_SIZE(16, 32), len); }
+UPB_INLINE bool envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_UpgradeConfig_has_enabled(const envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_UpgradeConfig *msg) { return _upb_hasbit(msg, 1); }
+UPB_INLINE const struct google_protobuf_BoolValue* envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_UpgradeConfig_enabled(const envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_UpgradeConfig *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(12, 24), const struct google_protobuf_BoolValue*); }
 
 UPB_INLINE void envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_UpgradeConfig_set_upgrade_type(envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_UpgradeConfig *msg, upb_strview value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(0, 0), upb_strview) = value;
+  *UPB_PTR_AT(msg, UPB_SIZE(4, 8), upb_strview) = value;
 }
 UPB_INLINE envoy_extensions_filters_network_http_connection_manager_v3_HttpFilter** envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_UpgradeConfig_mutable_filters(envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_UpgradeConfig *msg, size_t *len) {
-  return (envoy_extensions_filters_network_http_connection_manager_v3_HttpFilter**)_upb_array_mutable_accessor(msg, UPB_SIZE(12, 24), len);
+  return (envoy_extensions_filters_network_http_connection_manager_v3_HttpFilter**)_upb_array_mutable_accessor(msg, UPB_SIZE(16, 32), len);
 }
 UPB_INLINE envoy_extensions_filters_network_http_connection_manager_v3_HttpFilter** envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_UpgradeConfig_resize_filters(envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_UpgradeConfig *msg, size_t len, upb_arena *arena) {
-  return (envoy_extensions_filters_network_http_connection_manager_v3_HttpFilter**)_upb_array_resize_accessor(msg, UPB_SIZE(12, 24), len, UPB_TYPE_MESSAGE, arena);
+  return (envoy_extensions_filters_network_http_connection_manager_v3_HttpFilter**)_upb_array_resize_accessor2(msg, UPB_SIZE(16, 32), len, UPB_SIZE(2, 3), arena);
 }
 UPB_INLINE struct envoy_extensions_filters_network_http_connection_manager_v3_HttpFilter* envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_UpgradeConfig_add_filters(envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_UpgradeConfig *msg, upb_arena *arena) {
   struct envoy_extensions_filters_network_http_connection_manager_v3_HttpFilter* sub = (struct envoy_extensions_filters_network_http_connection_manager_v3_HttpFilter*)_upb_msg_new(&envoy_extensions_filters_network_http_connection_manager_v3_HttpFilter_msginit, arena);
-  bool ok = _upb_array_append_accessor(
-      msg, UPB_SIZE(12, 24), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena);
+  bool ok = _upb_array_append_accessor2(
+      msg, UPB_SIZE(16, 32), UPB_SIZE(2, 3), &sub, arena);
   if (!ok) return NULL;
   return sub;
 }
 UPB_INLINE void envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_UpgradeConfig_set_enabled(envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_UpgradeConfig *msg, struct google_protobuf_BoolValue* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(8, 16), struct google_protobuf_BoolValue*) = value;
+  _upb_sethas(msg, 1);
+  *UPB_PTR_AT(msg, UPB_SIZE(12, 24), struct google_protobuf_BoolValue*) = value;
 }
 UPB_INLINE struct google_protobuf_BoolValue* envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_UpgradeConfig_mutable_enabled(envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_UpgradeConfig *msg, upb_arena *arena) {
   struct google_protobuf_BoolValue* sub = (struct google_protobuf_BoolValue*)envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_UpgradeConfig_enabled(msg);
@@ -787,30 +843,37 @@ UPB_INLINE envoy_extensions_filters_network_http_connection_manager_v3_LocalRepl
   envoy_extensions_filters_network_http_connection_manager_v3_LocalReplyConfig *ret = envoy_extensions_filters_network_http_connection_manager_v3_LocalReplyConfig_new(arena);
   return (ret && upb_decode(buf, size, ret, &envoy_extensions_filters_network_http_connection_manager_v3_LocalReplyConfig_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE envoy_extensions_filters_network_http_connection_manager_v3_LocalReplyConfig *envoy_extensions_filters_network_http_connection_manager_v3_LocalReplyConfig_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  envoy_extensions_filters_network_http_connection_manager_v3_LocalReplyConfig *ret = envoy_extensions_filters_network_http_connection_manager_v3_LocalReplyConfig_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &envoy_extensions_filters_network_http_connection_manager_v3_LocalReplyConfig_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *envoy_extensions_filters_network_http_connection_manager_v3_LocalReplyConfig_serialize(const envoy_extensions_filters_network_http_connection_manager_v3_LocalReplyConfig *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &envoy_extensions_filters_network_http_connection_manager_v3_LocalReplyConfig_msginit, arena, len);
 }
 
-UPB_INLINE bool envoy_extensions_filters_network_http_connection_manager_v3_LocalReplyConfig_has_mappers(const envoy_extensions_filters_network_http_connection_manager_v3_LocalReplyConfig *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(4, 8)); }
-UPB_INLINE const envoy_extensions_filters_network_http_connection_manager_v3_ResponseMapper* const* envoy_extensions_filters_network_http_connection_manager_v3_LocalReplyConfig_mappers(const envoy_extensions_filters_network_http_connection_manager_v3_LocalReplyConfig *msg, size_t *len) { return (const envoy_extensions_filters_network_http_connection_manager_v3_ResponseMapper* const*)_upb_array_accessor(msg, UPB_SIZE(4, 8), len); }
-UPB_INLINE bool envoy_extensions_filters_network_http_connection_manager_v3_LocalReplyConfig_has_body_format(const envoy_extensions_filters_network_http_connection_manager_v3_LocalReplyConfig *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(0, 0)); }
-UPB_INLINE const struct envoy_config_core_v3_SubstitutionFormatString* envoy_extensions_filters_network_http_connection_manager_v3_LocalReplyConfig_body_format(const envoy_extensions_filters_network_http_connection_manager_v3_LocalReplyConfig *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(0, 0), const struct envoy_config_core_v3_SubstitutionFormatString*); }
+UPB_INLINE bool envoy_extensions_filters_network_http_connection_manager_v3_LocalReplyConfig_has_mappers(const envoy_extensions_filters_network_http_connection_manager_v3_LocalReplyConfig *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(8, 16)); }
+UPB_INLINE const envoy_extensions_filters_network_http_connection_manager_v3_ResponseMapper* const* envoy_extensions_filters_network_http_connection_manager_v3_LocalReplyConfig_mappers(const envoy_extensions_filters_network_http_connection_manager_v3_LocalReplyConfig *msg, size_t *len) { return (const envoy_extensions_filters_network_http_connection_manager_v3_ResponseMapper* const*)_upb_array_accessor(msg, UPB_SIZE(8, 16), len); }
+UPB_INLINE bool envoy_extensions_filters_network_http_connection_manager_v3_LocalReplyConfig_has_body_format(const envoy_extensions_filters_network_http_connection_manager_v3_LocalReplyConfig *msg) { return _upb_hasbit(msg, 1); }
+UPB_INLINE const struct envoy_config_core_v3_SubstitutionFormatString* envoy_extensions_filters_network_http_connection_manager_v3_LocalReplyConfig_body_format(const envoy_extensions_filters_network_http_connection_manager_v3_LocalReplyConfig *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(4, 8), const struct envoy_config_core_v3_SubstitutionFormatString*); }
 
 UPB_INLINE envoy_extensions_filters_network_http_connection_manager_v3_ResponseMapper** envoy_extensions_filters_network_http_connection_manager_v3_LocalReplyConfig_mutable_mappers(envoy_extensions_filters_network_http_connection_manager_v3_LocalReplyConfig *msg, size_t *len) {
-  return (envoy_extensions_filters_network_http_connection_manager_v3_ResponseMapper**)_upb_array_mutable_accessor(msg, UPB_SIZE(4, 8), len);
+  return (envoy_extensions_filters_network_http_connection_manager_v3_ResponseMapper**)_upb_array_mutable_accessor(msg, UPB_SIZE(8, 16), len);
 }
 UPB_INLINE envoy_extensions_filters_network_http_connection_manager_v3_ResponseMapper** envoy_extensions_filters_network_http_connection_manager_v3_LocalReplyConfig_resize_mappers(envoy_extensions_filters_network_http_connection_manager_v3_LocalReplyConfig *msg, size_t len, upb_arena *arena) {
-  return (envoy_extensions_filters_network_http_connection_manager_v3_ResponseMapper**)_upb_array_resize_accessor(msg, UPB_SIZE(4, 8), len, UPB_TYPE_MESSAGE, arena);
+  return (envoy_extensions_filters_network_http_connection_manager_v3_ResponseMapper**)_upb_array_resize_accessor2(msg, UPB_SIZE(8, 16), len, UPB_SIZE(2, 3), arena);
 }
 UPB_INLINE struct envoy_extensions_filters_network_http_connection_manager_v3_ResponseMapper* envoy_extensions_filters_network_http_connection_manager_v3_LocalReplyConfig_add_mappers(envoy_extensions_filters_network_http_connection_manager_v3_LocalReplyConfig *msg, upb_arena *arena) {
   struct envoy_extensions_filters_network_http_connection_manager_v3_ResponseMapper* sub = (struct envoy_extensions_filters_network_http_connection_manager_v3_ResponseMapper*)_upb_msg_new(&envoy_extensions_filters_network_http_connection_manager_v3_ResponseMapper_msginit, arena);
-  bool ok = _upb_array_append_accessor(
-      msg, UPB_SIZE(4, 8), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena);
+  bool ok = _upb_array_append_accessor2(
+      msg, UPB_SIZE(8, 16), UPB_SIZE(2, 3), &sub, arena);
   if (!ok) return NULL;
   return sub;
 }
 UPB_INLINE void envoy_extensions_filters_network_http_connection_manager_v3_LocalReplyConfig_set_body_format(envoy_extensions_filters_network_http_connection_manager_v3_LocalReplyConfig *msg, struct envoy_config_core_v3_SubstitutionFormatString* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(0, 0), struct envoy_config_core_v3_SubstitutionFormatString*) = value;
+  _upb_sethas(msg, 1);
+  *UPB_PTR_AT(msg, UPB_SIZE(4, 8), struct envoy_config_core_v3_SubstitutionFormatString*) = value;
 }
 UPB_INLINE struct envoy_config_core_v3_SubstitutionFormatString* envoy_extensions_filters_network_http_connection_manager_v3_LocalReplyConfig_mutable_body_format(envoy_extensions_filters_network_http_connection_manager_v3_LocalReplyConfig *msg, upb_arena *arena) {
   struct envoy_config_core_v3_SubstitutionFormatString* sub = (struct envoy_config_core_v3_SubstitutionFormatString*)envoy_extensions_filters_network_http_connection_manager_v3_LocalReplyConfig_body_format(msg);
@@ -832,23 +895,30 @@ UPB_INLINE envoy_extensions_filters_network_http_connection_manager_v3_ResponseM
   envoy_extensions_filters_network_http_connection_manager_v3_ResponseMapper *ret = envoy_extensions_filters_network_http_connection_manager_v3_ResponseMapper_new(arena);
   return (ret && upb_decode(buf, size, ret, &envoy_extensions_filters_network_http_connection_manager_v3_ResponseMapper_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE envoy_extensions_filters_network_http_connection_manager_v3_ResponseMapper *envoy_extensions_filters_network_http_connection_manager_v3_ResponseMapper_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  envoy_extensions_filters_network_http_connection_manager_v3_ResponseMapper *ret = envoy_extensions_filters_network_http_connection_manager_v3_ResponseMapper_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &envoy_extensions_filters_network_http_connection_manager_v3_ResponseMapper_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *envoy_extensions_filters_network_http_connection_manager_v3_ResponseMapper_serialize(const envoy_extensions_filters_network_http_connection_manager_v3_ResponseMapper *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &envoy_extensions_filters_network_http_connection_manager_v3_ResponseMapper_msginit, arena, len);
 }
 
-UPB_INLINE bool envoy_extensions_filters_network_http_connection_manager_v3_ResponseMapper_has_filter(const envoy_extensions_filters_network_http_connection_manager_v3_ResponseMapper *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(0, 0)); }
-UPB_INLINE const struct envoy_config_accesslog_v3_AccessLogFilter* envoy_extensions_filters_network_http_connection_manager_v3_ResponseMapper_filter(const envoy_extensions_filters_network_http_connection_manager_v3_ResponseMapper *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(0, 0), const struct envoy_config_accesslog_v3_AccessLogFilter*); }
-UPB_INLINE bool envoy_extensions_filters_network_http_connection_manager_v3_ResponseMapper_has_status_code(const envoy_extensions_filters_network_http_connection_manager_v3_ResponseMapper *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(4, 8)); }
-UPB_INLINE const struct google_protobuf_UInt32Value* envoy_extensions_filters_network_http_connection_manager_v3_ResponseMapper_status_code(const envoy_extensions_filters_network_http_connection_manager_v3_ResponseMapper *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(4, 8), const struct google_protobuf_UInt32Value*); }
-UPB_INLINE bool envoy_extensions_filters_network_http_connection_manager_v3_ResponseMapper_has_body(const envoy_extensions_filters_network_http_connection_manager_v3_ResponseMapper *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(8, 16)); }
-UPB_INLINE const struct envoy_config_core_v3_DataSource* envoy_extensions_filters_network_http_connection_manager_v3_ResponseMapper_body(const envoy_extensions_filters_network_http_connection_manager_v3_ResponseMapper *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(8, 16), const struct envoy_config_core_v3_DataSource*); }
-UPB_INLINE bool envoy_extensions_filters_network_http_connection_manager_v3_ResponseMapper_has_body_format_override(const envoy_extensions_filters_network_http_connection_manager_v3_ResponseMapper *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(12, 24)); }
-UPB_INLINE const struct envoy_config_core_v3_SubstitutionFormatString* envoy_extensions_filters_network_http_connection_manager_v3_ResponseMapper_body_format_override(const envoy_extensions_filters_network_http_connection_manager_v3_ResponseMapper *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(12, 24), const struct envoy_config_core_v3_SubstitutionFormatString*); }
-UPB_INLINE bool envoy_extensions_filters_network_http_connection_manager_v3_ResponseMapper_has_headers_to_add(const envoy_extensions_filters_network_http_connection_manager_v3_ResponseMapper *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(16, 32)); }
-UPB_INLINE const struct envoy_config_core_v3_HeaderValueOption* const* envoy_extensions_filters_network_http_connection_manager_v3_ResponseMapper_headers_to_add(const envoy_extensions_filters_network_http_connection_manager_v3_ResponseMapper *msg, size_t *len) { return (const struct envoy_config_core_v3_HeaderValueOption* const*)_upb_array_accessor(msg, UPB_SIZE(16, 32), len); }
+UPB_INLINE bool envoy_extensions_filters_network_http_connection_manager_v3_ResponseMapper_has_filter(const envoy_extensions_filters_network_http_connection_manager_v3_ResponseMapper *msg) { return _upb_hasbit(msg, 1); }
+UPB_INLINE const struct envoy_config_accesslog_v3_AccessLogFilter* envoy_extensions_filters_network_http_connection_manager_v3_ResponseMapper_filter(const envoy_extensions_filters_network_http_connection_manager_v3_ResponseMapper *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(4, 8), const struct envoy_config_accesslog_v3_AccessLogFilter*); }
+UPB_INLINE bool envoy_extensions_filters_network_http_connection_manager_v3_ResponseMapper_has_status_code(const envoy_extensions_filters_network_http_connection_manager_v3_ResponseMapper *msg) { return _upb_hasbit(msg, 2); }
+UPB_INLINE const struct google_protobuf_UInt32Value* envoy_extensions_filters_network_http_connection_manager_v3_ResponseMapper_status_code(const envoy_extensions_filters_network_http_connection_manager_v3_ResponseMapper *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(8, 16), const struct google_protobuf_UInt32Value*); }
+UPB_INLINE bool envoy_extensions_filters_network_http_connection_manager_v3_ResponseMapper_has_body(const envoy_extensions_filters_network_http_connection_manager_v3_ResponseMapper *msg) { return _upb_hasbit(msg, 3); }
+UPB_INLINE const struct envoy_config_core_v3_DataSource* envoy_extensions_filters_network_http_connection_manager_v3_ResponseMapper_body(const envoy_extensions_filters_network_http_connection_manager_v3_ResponseMapper *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(12, 24), const struct envoy_config_core_v3_DataSource*); }
+UPB_INLINE bool envoy_extensions_filters_network_http_connection_manager_v3_ResponseMapper_has_body_format_override(const envoy_extensions_filters_network_http_connection_manager_v3_ResponseMapper *msg) { return _upb_hasbit(msg, 4); }
+UPB_INLINE const struct envoy_config_core_v3_SubstitutionFormatString* envoy_extensions_filters_network_http_connection_manager_v3_ResponseMapper_body_format_override(const envoy_extensions_filters_network_http_connection_manager_v3_ResponseMapper *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(16, 32), const struct envoy_config_core_v3_SubstitutionFormatString*); }
+UPB_INLINE bool envoy_extensions_filters_network_http_connection_manager_v3_ResponseMapper_has_headers_to_add(const envoy_extensions_filters_network_http_connection_manager_v3_ResponseMapper *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(20, 40)); }
+UPB_INLINE const struct envoy_config_core_v3_HeaderValueOption* const* envoy_extensions_filters_network_http_connection_manager_v3_ResponseMapper_headers_to_add(const envoy_extensions_filters_network_http_connection_manager_v3_ResponseMapper *msg, size_t *len) { return (const struct envoy_config_core_v3_HeaderValueOption* const*)_upb_array_accessor(msg, UPB_SIZE(20, 40), len); }
 
 UPB_INLINE void envoy_extensions_filters_network_http_connection_manager_v3_ResponseMapper_set_filter(envoy_extensions_filters_network_http_connection_manager_v3_ResponseMapper *msg, struct envoy_config_accesslog_v3_AccessLogFilter* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(0, 0), struct envoy_config_accesslog_v3_AccessLogFilter*) = value;
+  _upb_sethas(msg, 1);
+  *UPB_PTR_AT(msg, UPB_SIZE(4, 8), struct envoy_config_accesslog_v3_AccessLogFilter*) = value;
 }
 UPB_INLINE struct envoy_config_accesslog_v3_AccessLogFilter* envoy_extensions_filters_network_http_connection_manager_v3_ResponseMapper_mutable_filter(envoy_extensions_filters_network_http_connection_manager_v3_ResponseMapper *msg, upb_arena *arena) {
   struct envoy_config_accesslog_v3_AccessLogFilter* sub = (struct envoy_config_accesslog_v3_AccessLogFilter*)envoy_extensions_filters_network_http_connection_manager_v3_ResponseMapper_filter(msg);
@@ -860,7 +930,8 @@ UPB_INLINE struct envoy_config_accesslog_v3_AccessLogFilter* envoy_extensions_fi
   return sub;
 }
 UPB_INLINE void envoy_extensions_filters_network_http_connection_manager_v3_ResponseMapper_set_status_code(envoy_extensions_filters_network_http_connection_manager_v3_ResponseMapper *msg, struct google_protobuf_UInt32Value* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(4, 8), struct google_protobuf_UInt32Value*) = value;
+  _upb_sethas(msg, 2);
+  *UPB_PTR_AT(msg, UPB_SIZE(8, 16), struct google_protobuf_UInt32Value*) = value;
 }
 UPB_INLINE struct google_protobuf_UInt32Value* envoy_extensions_filters_network_http_connection_manager_v3_ResponseMapper_mutable_status_code(envoy_extensions_filters_network_http_connection_manager_v3_ResponseMapper *msg, upb_arena *arena) {
   struct google_protobuf_UInt32Value* sub = (struct google_protobuf_UInt32Value*)envoy_extensions_filters_network_http_connection_manager_v3_ResponseMapper_status_code(msg);
@@ -872,7 +943,8 @@ UPB_INLINE struct google_protobuf_UInt32Value* envoy_extensions_filters_network_
   return sub;
 }
 UPB_INLINE void envoy_extensions_filters_network_http_connection_manager_v3_ResponseMapper_set_body(envoy_extensions_filters_network_http_connection_manager_v3_ResponseMapper *msg, struct envoy_config_core_v3_DataSource* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(8, 16), struct envoy_config_core_v3_DataSource*) = value;
+  _upb_sethas(msg, 3);
+  *UPB_PTR_AT(msg, UPB_SIZE(12, 24), struct envoy_config_core_v3_DataSource*) = value;
 }
 UPB_INLINE struct envoy_config_core_v3_DataSource* envoy_extensions_filters_network_http_connection_manager_v3_ResponseMapper_mutable_body(envoy_extensions_filters_network_http_connection_manager_v3_ResponseMapper *msg, upb_arena *arena) {
   struct envoy_config_core_v3_DataSource* sub = (struct envoy_config_core_v3_DataSource*)envoy_extensions_filters_network_http_connection_manager_v3_ResponseMapper_body(msg);
@@ -884,7 +956,8 @@ UPB_INLINE struct envoy_config_core_v3_DataSource* envoy_extensions_filters_netw
   return sub;
 }
 UPB_INLINE void envoy_extensions_filters_network_http_connection_manager_v3_ResponseMapper_set_body_format_override(envoy_extensions_filters_network_http_connection_manager_v3_ResponseMapper *msg, struct envoy_config_core_v3_SubstitutionFormatString* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(12, 24), struct envoy_config_core_v3_SubstitutionFormatString*) = value;
+  _upb_sethas(msg, 4);
+  *UPB_PTR_AT(msg, UPB_SIZE(16, 32), struct envoy_config_core_v3_SubstitutionFormatString*) = value;
 }
 UPB_INLINE struct envoy_config_core_v3_SubstitutionFormatString* envoy_extensions_filters_network_http_connection_manager_v3_ResponseMapper_mutable_body_format_override(envoy_extensions_filters_network_http_connection_manager_v3_ResponseMapper *msg, upb_arena *arena) {
   struct envoy_config_core_v3_SubstitutionFormatString* sub = (struct envoy_config_core_v3_SubstitutionFormatString*)envoy_extensions_filters_network_http_connection_manager_v3_ResponseMapper_body_format_override(msg);
@@ -896,15 +969,15 @@ UPB_INLINE struct envoy_config_core_v3_SubstitutionFormatString* envoy_extension
   return sub;
 }
 UPB_INLINE struct envoy_config_core_v3_HeaderValueOption** envoy_extensions_filters_network_http_connection_manager_v3_ResponseMapper_mutable_headers_to_add(envoy_extensions_filters_network_http_connection_manager_v3_ResponseMapper *msg, size_t *len) {
-  return (struct envoy_config_core_v3_HeaderValueOption**)_upb_array_mutable_accessor(msg, UPB_SIZE(16, 32), len);
+  return (struct envoy_config_core_v3_HeaderValueOption**)_upb_array_mutable_accessor(msg, UPB_SIZE(20, 40), len);
 }
 UPB_INLINE struct envoy_config_core_v3_HeaderValueOption** envoy_extensions_filters_network_http_connection_manager_v3_ResponseMapper_resize_headers_to_add(envoy_extensions_filters_network_http_connection_manager_v3_ResponseMapper *msg, size_t len, upb_arena *arena) {
-  return (struct envoy_config_core_v3_HeaderValueOption**)_upb_array_resize_accessor(msg, UPB_SIZE(16, 32), len, UPB_TYPE_MESSAGE, arena);
+  return (struct envoy_config_core_v3_HeaderValueOption**)_upb_array_resize_accessor2(msg, UPB_SIZE(20, 40), len, UPB_SIZE(2, 3), arena);
 }
 UPB_INLINE struct envoy_config_core_v3_HeaderValueOption* envoy_extensions_filters_network_http_connection_manager_v3_ResponseMapper_add_headers_to_add(envoy_extensions_filters_network_http_connection_manager_v3_ResponseMapper *msg, upb_arena *arena) {
   struct envoy_config_core_v3_HeaderValueOption* sub = (struct envoy_config_core_v3_HeaderValueOption*)_upb_msg_new(&envoy_config_core_v3_HeaderValueOption_msginit, arena);
-  bool ok = _upb_array_append_accessor(
-      msg, UPB_SIZE(16, 32), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena);
+  bool ok = _upb_array_append_accessor2(
+      msg, UPB_SIZE(20, 40), UPB_SIZE(2, 3), &sub, arena);
   if (!ok) return NULL;
   return sub;
 }
@@ -919,18 +992,25 @@ UPB_INLINE envoy_extensions_filters_network_http_connection_manager_v3_Rds *envo
   envoy_extensions_filters_network_http_connection_manager_v3_Rds *ret = envoy_extensions_filters_network_http_connection_manager_v3_Rds_new(arena);
   return (ret && upb_decode(buf, size, ret, &envoy_extensions_filters_network_http_connection_manager_v3_Rds_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE envoy_extensions_filters_network_http_connection_manager_v3_Rds *envoy_extensions_filters_network_http_connection_manager_v3_Rds_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  envoy_extensions_filters_network_http_connection_manager_v3_Rds *ret = envoy_extensions_filters_network_http_connection_manager_v3_Rds_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &envoy_extensions_filters_network_http_connection_manager_v3_Rds_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *envoy_extensions_filters_network_http_connection_manager_v3_Rds_serialize(const envoy_extensions_filters_network_http_connection_manager_v3_Rds *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &envoy_extensions_filters_network_http_connection_manager_v3_Rds_msginit, arena, len);
 }
 
-UPB_INLINE bool envoy_extensions_filters_network_http_connection_manager_v3_Rds_has_config_source(const envoy_extensions_filters_network_http_connection_manager_v3_Rds *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(8, 16)); }
-UPB_INLINE const struct envoy_config_core_v3_ConfigSource* envoy_extensions_filters_network_http_connection_manager_v3_Rds_config_source(const envoy_extensions_filters_network_http_connection_manager_v3_Rds *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(8, 16), const struct envoy_config_core_v3_ConfigSource*); }
-UPB_INLINE upb_strview envoy_extensions_filters_network_http_connection_manager_v3_Rds_route_config_name(const envoy_extensions_filters_network_http_connection_manager_v3_Rds *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(0, 0), upb_strview); }
-UPB_INLINE bool envoy_extensions_filters_network_http_connection_manager_v3_Rds_has_rds_resource_locator(const envoy_extensions_filters_network_http_connection_manager_v3_Rds *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(12, 24)); }
-UPB_INLINE const struct udpa_core_v1_ResourceLocator* envoy_extensions_filters_network_http_connection_manager_v3_Rds_rds_resource_locator(const envoy_extensions_filters_network_http_connection_manager_v3_Rds *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(12, 24), const struct udpa_core_v1_ResourceLocator*); }
+UPB_INLINE bool envoy_extensions_filters_network_http_connection_manager_v3_Rds_has_config_source(const envoy_extensions_filters_network_http_connection_manager_v3_Rds *msg) { return _upb_hasbit(msg, 1); }
+UPB_INLINE const struct envoy_config_core_v3_ConfigSource* envoy_extensions_filters_network_http_connection_manager_v3_Rds_config_source(const envoy_extensions_filters_network_http_connection_manager_v3_Rds *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(12, 24), const struct envoy_config_core_v3_ConfigSource*); }
+UPB_INLINE upb_strview envoy_extensions_filters_network_http_connection_manager_v3_Rds_route_config_name(const envoy_extensions_filters_network_http_connection_manager_v3_Rds *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(4, 8), upb_strview); }
+UPB_INLINE bool envoy_extensions_filters_network_http_connection_manager_v3_Rds_has_rds_resource_locator(const envoy_extensions_filters_network_http_connection_manager_v3_Rds *msg) { return _upb_hasbit(msg, 2); }
+UPB_INLINE const struct udpa_core_v1_ResourceLocator* envoy_extensions_filters_network_http_connection_manager_v3_Rds_rds_resource_locator(const envoy_extensions_filters_network_http_connection_manager_v3_Rds *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(16, 32), const struct udpa_core_v1_ResourceLocator*); }
 
 UPB_INLINE void envoy_extensions_filters_network_http_connection_manager_v3_Rds_set_config_source(envoy_extensions_filters_network_http_connection_manager_v3_Rds *msg, struct envoy_config_core_v3_ConfigSource* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(8, 16), struct envoy_config_core_v3_ConfigSource*) = value;
+  _upb_sethas(msg, 1);
+  *UPB_PTR_AT(msg, UPB_SIZE(12, 24), struct envoy_config_core_v3_ConfigSource*) = value;
 }
 UPB_INLINE struct envoy_config_core_v3_ConfigSource* envoy_extensions_filters_network_http_connection_manager_v3_Rds_mutable_config_source(envoy_extensions_filters_network_http_connection_manager_v3_Rds *msg, upb_arena *arena) {
   struct envoy_config_core_v3_ConfigSource* sub = (struct envoy_config_core_v3_ConfigSource*)envoy_extensions_filters_network_http_connection_manager_v3_Rds_config_source(msg);
@@ -942,10 +1022,11 @@ UPB_INLINE struct envoy_config_core_v3_ConfigSource* envoy_extensions_filters_ne
   return sub;
 }
 UPB_INLINE void envoy_extensions_filters_network_http_connection_manager_v3_Rds_set_route_config_name(envoy_extensions_filters_network_http_connection_manager_v3_Rds *msg, upb_strview value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(0, 0), upb_strview) = value;
+  *UPB_PTR_AT(msg, UPB_SIZE(4, 8), upb_strview) = value;
 }
 UPB_INLINE void envoy_extensions_filters_network_http_connection_manager_v3_Rds_set_rds_resource_locator(envoy_extensions_filters_network_http_connection_manager_v3_Rds *msg, struct udpa_core_v1_ResourceLocator* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(12, 24), struct udpa_core_v1_ResourceLocator*) = value;
+  _upb_sethas(msg, 2);
+  *UPB_PTR_AT(msg, UPB_SIZE(16, 32), struct udpa_core_v1_ResourceLocator*) = value;
 }
 UPB_INLINE struct udpa_core_v1_ResourceLocator* envoy_extensions_filters_network_http_connection_manager_v3_Rds_mutable_rds_resource_locator(envoy_extensions_filters_network_http_connection_manager_v3_Rds *msg, upb_arena *arena) {
   struct udpa_core_v1_ResourceLocator* sub = (struct udpa_core_v1_ResourceLocator*)envoy_extensions_filters_network_http_connection_manager_v3_Rds_rds_resource_locator(msg);
@@ -967,6 +1048,12 @@ UPB_INLINE envoy_extensions_filters_network_http_connection_manager_v3_ScopedRou
   envoy_extensions_filters_network_http_connection_manager_v3_ScopedRouteConfigurationsList *ret = envoy_extensions_filters_network_http_connection_manager_v3_ScopedRouteConfigurationsList_new(arena);
   return (ret && upb_decode(buf, size, ret, &envoy_extensions_filters_network_http_connection_manager_v3_ScopedRouteConfigurationsList_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE envoy_extensions_filters_network_http_connection_manager_v3_ScopedRouteConfigurationsList *envoy_extensions_filters_network_http_connection_manager_v3_ScopedRouteConfigurationsList_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  envoy_extensions_filters_network_http_connection_manager_v3_ScopedRouteConfigurationsList *ret = envoy_extensions_filters_network_http_connection_manager_v3_ScopedRouteConfigurationsList_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &envoy_extensions_filters_network_http_connection_manager_v3_ScopedRouteConfigurationsList_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *envoy_extensions_filters_network_http_connection_manager_v3_ScopedRouteConfigurationsList_serialize(const envoy_extensions_filters_network_http_connection_manager_v3_ScopedRouteConfigurationsList *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &envoy_extensions_filters_network_http_connection_manager_v3_ScopedRouteConfigurationsList_msginit, arena, len);
 }
@@ -978,12 +1065,12 @@ UPB_INLINE struct envoy_config_route_v3_ScopedRouteConfiguration** envoy_extensi
   return (struct envoy_config_route_v3_ScopedRouteConfiguration**)_upb_array_mutable_accessor(msg, UPB_SIZE(0, 0), len);
 }
 UPB_INLINE struct envoy_config_route_v3_ScopedRouteConfiguration** envoy_extensions_filters_network_http_connection_manager_v3_ScopedRouteConfigurationsList_resize_scoped_route_configurations(envoy_extensions_filters_network_http_connection_manager_v3_ScopedRouteConfigurationsList *msg, size_t len, upb_arena *arena) {
-  return (struct envoy_config_route_v3_ScopedRouteConfiguration**)_upb_array_resize_accessor(msg, UPB_SIZE(0, 0), len, UPB_TYPE_MESSAGE, arena);
+  return (struct envoy_config_route_v3_ScopedRouteConfiguration**)_upb_array_resize_accessor2(msg, UPB_SIZE(0, 0), len, UPB_SIZE(2, 3), arena);
 }
 UPB_INLINE struct envoy_config_route_v3_ScopedRouteConfiguration* envoy_extensions_filters_network_http_connection_manager_v3_ScopedRouteConfigurationsList_add_scoped_route_configurations(envoy_extensions_filters_network_http_connection_manager_v3_ScopedRouteConfigurationsList *msg, upb_arena *arena) {
   struct envoy_config_route_v3_ScopedRouteConfiguration* sub = (struct envoy_config_route_v3_ScopedRouteConfiguration*)_upb_msg_new(&envoy_config_route_v3_ScopedRouteConfiguration_msginit, arena);
-  bool ok = _upb_array_append_accessor(
-      msg, UPB_SIZE(0, 0), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena);
+  bool ok = _upb_array_append_accessor2(
+      msg, UPB_SIZE(0, 0), UPB_SIZE(2, 3), &sub, arena);
   if (!ok) return NULL;
   return sub;
 }
@@ -998,6 +1085,12 @@ UPB_INLINE envoy_extensions_filters_network_http_connection_manager_v3_ScopedRou
   envoy_extensions_filters_network_http_connection_manager_v3_ScopedRoutes *ret = envoy_extensions_filters_network_http_connection_manager_v3_ScopedRoutes_new(arena);
   return (ret && upb_decode(buf, size, ret, &envoy_extensions_filters_network_http_connection_manager_v3_ScopedRoutes_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE envoy_extensions_filters_network_http_connection_manager_v3_ScopedRoutes *envoy_extensions_filters_network_http_connection_manager_v3_ScopedRoutes_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  envoy_extensions_filters_network_http_connection_manager_v3_ScopedRoutes *ret = envoy_extensions_filters_network_http_connection_manager_v3_ScopedRoutes_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &envoy_extensions_filters_network_http_connection_manager_v3_ScopedRoutes_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *envoy_extensions_filters_network_http_connection_manager_v3_ScopedRoutes_serialize(const envoy_extensions_filters_network_http_connection_manager_v3_ScopedRoutes *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &envoy_extensions_filters_network_http_connection_manager_v3_ScopedRoutes_msginit, arena, len);
 }
@@ -1007,23 +1100,24 @@ typedef enum {
   envoy_extensions_filters_network_http_connection_manager_v3_ScopedRoutes_config_specifier_scoped_rds = 5,
   envoy_extensions_filters_network_http_connection_manager_v3_ScopedRoutes_config_specifier_NOT_SET = 0
 } envoy_extensions_filters_network_http_connection_manager_v3_ScopedRoutes_config_specifier_oneofcases;
-UPB_INLINE envoy_extensions_filters_network_http_connection_manager_v3_ScopedRoutes_config_specifier_oneofcases envoy_extensions_filters_network_http_connection_manager_v3_ScopedRoutes_config_specifier_case(const envoy_extensions_filters_network_http_connection_manager_v3_ScopedRoutes* msg) { return (envoy_extensions_filters_network_http_connection_manager_v3_ScopedRoutes_config_specifier_oneofcases)*UPB_PTR_AT(msg, UPB_SIZE(20, 40), int32_t); }
-
-UPB_INLINE upb_strview envoy_extensions_filters_network_http_connection_manager_v3_ScopedRoutes_name(const envoy_extensions_filters_network_http_connection_manager_v3_ScopedRoutes *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(0, 0), upb_strview); }
-UPB_INLINE bool envoy_extensions_filters_network_http_connection_manager_v3_ScopedRoutes_has_scope_key_builder(const envoy_extensions_filters_network_http_connection_manager_v3_ScopedRoutes *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(8, 16)); }
-UPB_INLINE const envoy_extensions_filters_network_http_connection_manager_v3_ScopedRoutes_ScopeKeyBuilder* envoy_extensions_filters_network_http_connection_manager_v3_ScopedRoutes_scope_key_builder(const envoy_extensions_filters_network_http_connection_manager_v3_ScopedRoutes *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(8, 16), const envoy_extensions_filters_network_http_connection_manager_v3_ScopedRoutes_ScopeKeyBuilder*); }
-UPB_INLINE bool envoy_extensions_filters_network_http_connection_manager_v3_ScopedRoutes_has_rds_config_source(const envoy_extensions_filters_network_http_connection_manager_v3_ScopedRoutes *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(12, 24)); }
-UPB_INLINE const struct envoy_config_core_v3_ConfigSource* envoy_extensions_filters_network_http_connection_manager_v3_ScopedRoutes_rds_config_source(const envoy_extensions_filters_network_http_connection_manager_v3_ScopedRoutes *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(12, 24), const struct envoy_config_core_v3_ConfigSource*); }
-UPB_INLINE bool envoy_extensions_filters_network_http_connection_manager_v3_ScopedRoutes_has_scoped_route_configurations_list(const envoy_extensions_filters_network_http_connection_manager_v3_ScopedRoutes *msg) { return _upb_getoneofcase(msg, UPB_SIZE(20, 40)) == 4; }
-UPB_INLINE const envoy_extensions_filters_network_http_connection_manager_v3_ScopedRouteConfigurationsList* envoy_extensions_filters_network_http_connection_manager_v3_ScopedRoutes_scoped_route_configurations_list(const envoy_extensions_filters_network_http_connection_manager_v3_ScopedRoutes *msg) { return UPB_READ_ONEOF(msg, const envoy_extensions_filters_network_http_connection_manager_v3_ScopedRouteConfigurationsList*, UPB_SIZE(16, 32), UPB_SIZE(20, 40), 4, NULL); }
-UPB_INLINE bool envoy_extensions_filters_network_http_connection_manager_v3_ScopedRoutes_has_scoped_rds(const envoy_extensions_filters_network_http_connection_manager_v3_ScopedRoutes *msg) { return _upb_getoneofcase(msg, UPB_SIZE(20, 40)) == 5; }
-UPB_INLINE const envoy_extensions_filters_network_http_connection_manager_v3_ScopedRds* envoy_extensions_filters_network_http_connection_manager_v3_ScopedRoutes_scoped_rds(const envoy_extensions_filters_network_http_connection_manager_v3_ScopedRoutes *msg) { return UPB_READ_ONEOF(msg, const envoy_extensions_filters_network_http_connection_manager_v3_ScopedRds*, UPB_SIZE(16, 32), UPB_SIZE(20, 40), 5, NULL); }
+UPB_INLINE envoy_extensions_filters_network_http_connection_manager_v3_ScopedRoutes_config_specifier_oneofcases envoy_extensions_filters_network_http_connection_manager_v3_ScopedRoutes_config_specifier_case(const envoy_extensions_filters_network_http_connection_manager_v3_ScopedRoutes* msg) { return (envoy_extensions_filters_network_http_connection_manager_v3_ScopedRoutes_config_specifier_oneofcases)*UPB_PTR_AT(msg, UPB_SIZE(24, 48), int32_t); }
+
+UPB_INLINE upb_strview envoy_extensions_filters_network_http_connection_manager_v3_ScopedRoutes_name(const envoy_extensions_filters_network_http_connection_manager_v3_ScopedRoutes *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(4, 8), upb_strview); }
+UPB_INLINE bool envoy_extensions_filters_network_http_connection_manager_v3_ScopedRoutes_has_scope_key_builder(const envoy_extensions_filters_network_http_connection_manager_v3_ScopedRoutes *msg) { return _upb_hasbit(msg, 1); }
+UPB_INLINE const envoy_extensions_filters_network_http_connection_manager_v3_ScopedRoutes_ScopeKeyBuilder* envoy_extensions_filters_network_http_connection_manager_v3_ScopedRoutes_scope_key_builder(const envoy_extensions_filters_network_http_connection_manager_v3_ScopedRoutes *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(12, 24), const envoy_extensions_filters_network_http_connection_manager_v3_ScopedRoutes_ScopeKeyBuilder*); }
+UPB_INLINE bool envoy_extensions_filters_network_http_connection_manager_v3_ScopedRoutes_has_rds_config_source(const envoy_extensions_filters_network_http_connection_manager_v3_ScopedRoutes *msg) { return _upb_hasbit(msg, 2); }
+UPB_INLINE const struct envoy_config_core_v3_ConfigSource* envoy_extensions_filters_network_http_connection_manager_v3_ScopedRoutes_rds_config_source(const envoy_extensions_filters_network_http_connection_manager_v3_ScopedRoutes *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(16, 32), const struct envoy_config_core_v3_ConfigSource*); }
+UPB_INLINE bool envoy_extensions_filters_network_http_connection_manager_v3_ScopedRoutes_has_scoped_route_configurations_list(const envoy_extensions_filters_network_http_connection_manager_v3_ScopedRoutes *msg) { return _upb_getoneofcase(msg, UPB_SIZE(24, 48)) == 4; }
+UPB_INLINE const envoy_extensions_filters_network_http_connection_manager_v3_ScopedRouteConfigurationsList* envoy_extensions_filters_network_http_connection_manager_v3_ScopedRoutes_scoped_route_configurations_list(const envoy_extensions_filters_network_http_connection_manager_v3_ScopedRoutes *msg) { return UPB_READ_ONEOF(msg, const envoy_extensions_filters_network_http_connection_manager_v3_ScopedRouteConfigurationsList*, UPB_SIZE(20, 40), UPB_SIZE(24, 48), 4, NULL); }
+UPB_INLINE bool envoy_extensions_filters_network_http_connection_manager_v3_ScopedRoutes_has_scoped_rds(const envoy_extensions_filters_network_http_connection_manager_v3_ScopedRoutes *msg) { return _upb_getoneofcase(msg, UPB_SIZE(24, 48)) == 5; }
+UPB_INLINE const envoy_extensions_filters_network_http_connection_manager_v3_ScopedRds* envoy_extensions_filters_network_http_connection_manager_v3_ScopedRoutes_scoped_rds(const envoy_extensions_filters_network_http_connection_manager_v3_ScopedRoutes *msg) { return UPB_READ_ONEOF(msg, const envoy_extensions_filters_network_http_connection_manager_v3_ScopedRds*, UPB_SIZE(20, 40), UPB_SIZE(24, 48), 5, NULL); }
 
 UPB_INLINE void envoy_extensions_filters_network_http_connection_manager_v3_ScopedRoutes_set_name(envoy_extensions_filters_network_http_connection_manager_v3_ScopedRoutes *msg, upb_strview value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(0, 0), upb_strview) = value;
+  *UPB_PTR_AT(msg, UPB_SIZE(4, 8), upb_strview) = value;
 }
 UPB_INLINE void envoy_extensions_filters_network_http_connection_manager_v3_ScopedRoutes_set_scope_key_builder(envoy_extensions_filters_network_http_connection_manager_v3_ScopedRoutes *msg, envoy_extensions_filters_network_http_connection_manager_v3_ScopedRoutes_ScopeKeyBuilder* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(8, 16), envoy_extensions_filters_network_http_connection_manager_v3_ScopedRoutes_ScopeKeyBuilder*) = value;
+  _upb_sethas(msg, 1);
+  *UPB_PTR_AT(msg, UPB_SIZE(12, 24), envoy_extensions_filters_network_http_connection_manager_v3_ScopedRoutes_ScopeKeyBuilder*) = value;
 }
 UPB_INLINE struct envoy_extensions_filters_network_http_connection_manager_v3_ScopedRoutes_ScopeKeyBuilder* envoy_extensions_filters_network_http_connection_manager_v3_ScopedRoutes_mutable_scope_key_builder(envoy_extensions_filters_network_http_connection_manager_v3_ScopedRoutes *msg, upb_arena *arena) {
   struct envoy_extensions_filters_network_http_connection_manager_v3_ScopedRoutes_ScopeKeyBuilder* sub = (struct envoy_extensions_filters_network_http_connection_manager_v3_ScopedRoutes_ScopeKeyBuilder*)envoy_extensions_filters_network_http_connection_manager_v3_ScopedRoutes_scope_key_builder(msg);
@@ -1035,7 +1129,8 @@ UPB_INLINE struct envoy_extensions_filters_network_http_connection_manager_v3_Sc
   return sub;
 }
 UPB_INLINE void envoy_extensions_filters_network_http_connection_manager_v3_ScopedRoutes_set_rds_config_source(envoy_extensions_filters_network_http_connection_manager_v3_ScopedRoutes *msg, struct envoy_config_core_v3_ConfigSource* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(12, 24), struct envoy_config_core_v3_ConfigSource*) = value;
+  _upb_sethas(msg, 2);
+  *UPB_PTR_AT(msg, UPB_SIZE(16, 32), struct envoy_config_core_v3_ConfigSource*) = value;
 }
 UPB_INLINE struct envoy_config_core_v3_ConfigSource* envoy_extensions_filters_network_http_connection_manager_v3_ScopedRoutes_mutable_rds_config_source(envoy_extensions_filters_network_http_connection_manager_v3_ScopedRoutes *msg, upb_arena *arena) {
   struct envoy_config_core_v3_ConfigSource* sub = (struct envoy_config_core_v3_ConfigSource*)envoy_extensions_filters_network_http_connection_manager_v3_ScopedRoutes_rds_config_source(msg);
@@ -1047,7 +1142,7 @@ UPB_INLINE struct envoy_config_core_v3_ConfigSource* envoy_extensions_filters_ne
   return sub;
 }
 UPB_INLINE void envoy_extensions_filters_network_http_connection_manager_v3_ScopedRoutes_set_scoped_route_configurations_list(envoy_extensions_filters_network_http_connection_manager_v3_ScopedRoutes *msg, envoy_extensions_filters_network_http_connection_manager_v3_ScopedRouteConfigurationsList* value) {
-  UPB_WRITE_ONEOF(msg, envoy_extensions_filters_network_http_connection_manager_v3_ScopedRouteConfigurationsList*, UPB_SIZE(16, 32), value, UPB_SIZE(20, 40), 4);
+  UPB_WRITE_ONEOF(msg, envoy_extensions_filters_network_http_connection_manager_v3_ScopedRouteConfigurationsList*, UPB_SIZE(20, 40), value, UPB_SIZE(24, 48), 4);
 }
 UPB_INLINE struct envoy_extensions_filters_network_http_connection_manager_v3_ScopedRouteConfigurationsList* envoy_extensions_filters_network_http_connection_manager_v3_ScopedRoutes_mutable_scoped_route_configurations_list(envoy_extensions_filters_network_http_connection_manager_v3_ScopedRoutes *msg, upb_arena *arena) {
   struct envoy_extensions_filters_network_http_connection_manager_v3_ScopedRouteConfigurationsList* sub = (struct envoy_extensions_filters_network_http_connection_manager_v3_ScopedRouteConfigurationsList*)envoy_extensions_filters_network_http_connection_manager_v3_ScopedRoutes_scoped_route_configurations_list(msg);
@@ -1059,7 +1154,7 @@ UPB_INLINE struct envoy_extensions_filters_network_http_connection_manager_v3_Sc
   return sub;
 }
 UPB_INLINE void envoy_extensions_filters_network_http_connection_manager_v3_ScopedRoutes_set_scoped_rds(envoy_extensions_filters_network_http_connection_manager_v3_ScopedRoutes *msg, envoy_extensions_filters_network_http_connection_manager_v3_ScopedRds* value) {
-  UPB_WRITE_ONEOF(msg, envoy_extensions_filters_network_http_connection_manager_v3_ScopedRds*, UPB_SIZE(16, 32), value, UPB_SIZE(20, 40), 5);
+  UPB_WRITE_ONEOF(msg, envoy_extensions_filters_network_http_connection_manager_v3_ScopedRds*, UPB_SIZE(20, 40), value, UPB_SIZE(24, 48), 5);
 }
 UPB_INLINE struct envoy_extensions_filters_network_http_connection_manager_v3_ScopedRds* envoy_extensions_filters_network_http_connection_manager_v3_ScopedRoutes_mutable_scoped_rds(envoy_extensions_filters_network_http_connection_manager_v3_ScopedRoutes *msg, upb_arena *arena) {
   struct envoy_extensions_filters_network_http_connection_manager_v3_ScopedRds* sub = (struct envoy_extensions_filters_network_http_connection_manager_v3_ScopedRds*)envoy_extensions_filters_network_http_connection_manager_v3_ScopedRoutes_scoped_rds(msg);
@@ -1081,6 +1176,12 @@ UPB_INLINE envoy_extensions_filters_network_http_connection_manager_v3_ScopedRou
   envoy_extensions_filters_network_http_connection_manager_v3_ScopedRoutes_ScopeKeyBuilder *ret = envoy_extensions_filters_network_http_connection_manager_v3_ScopedRoutes_ScopeKeyBuilder_new(arena);
   return (ret && upb_decode(buf, size, ret, &envoy_extensions_filters_network_http_connection_manager_v3_ScopedRoutes_ScopeKeyBuilder_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE envoy_extensions_filters_network_http_connection_manager_v3_ScopedRoutes_ScopeKeyBuilder *envoy_extensions_filters_network_http_connection_manager_v3_ScopedRoutes_ScopeKeyBuilder_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  envoy_extensions_filters_network_http_connection_manager_v3_ScopedRoutes_ScopeKeyBuilder *ret = envoy_extensions_filters_network_http_connection_manager_v3_ScopedRoutes_ScopeKeyBuilder_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &envoy_extensions_filters_network_http_connection_manager_v3_ScopedRoutes_ScopeKeyBuilder_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *envoy_extensions_filters_network_http_connection_manager_v3_ScopedRoutes_ScopeKeyBuilder_serialize(const envoy_extensions_filters_network_http_connection_manager_v3_ScopedRoutes_ScopeKeyBuilder *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &envoy_extensions_filters_network_http_connection_manager_v3_ScopedRoutes_ScopeKeyBuilder_msginit, arena, len);
 }
@@ -1092,12 +1193,12 @@ UPB_INLINE envoy_extensions_filters_network_http_connection_manager_v3_ScopedRou
   return (envoy_extensions_filters_network_http_connection_manager_v3_ScopedRoutes_ScopeKeyBuilder_FragmentBuilder**)_upb_array_mutable_accessor(msg, UPB_SIZE(0, 0), len);
 }
 UPB_INLINE envoy_extensions_filters_network_http_connection_manager_v3_ScopedRoutes_ScopeKeyBuilder_FragmentBuilder** envoy_extensions_filters_network_http_connection_manager_v3_ScopedRoutes_ScopeKeyBuilder_resize_fragments(envoy_extensions_filters_network_http_connection_manager_v3_ScopedRoutes_ScopeKeyBuilder *msg, size_t len, upb_arena *arena) {
-  return (envoy_extensions_filters_network_http_connection_manager_v3_ScopedRoutes_ScopeKeyBuilder_FragmentBuilder**)_upb_array_resize_accessor(msg, UPB_SIZE(0, 0), len, UPB_TYPE_MESSAGE, arena);
+  return (envoy_extensions_filters_network_http_connection_manager_v3_ScopedRoutes_ScopeKeyBuilder_FragmentBuilder**)_upb_array_resize_accessor2(msg, UPB_SIZE(0, 0), len, UPB_SIZE(2, 3), arena);
 }
 UPB_INLINE struct envoy_extensions_filters_network_http_connection_manager_v3_ScopedRoutes_ScopeKeyBuilder_FragmentBuilder* envoy_extensions_filters_network_http_connection_manager_v3_ScopedRoutes_ScopeKeyBuilder_add_fragments(envoy_extensions_filters_network_http_connection_manager_v3_ScopedRoutes_ScopeKeyBuilder *msg, upb_arena *arena) {
   struct envoy_extensions_filters_network_http_connection_manager_v3_ScopedRoutes_ScopeKeyBuilder_FragmentBuilder* sub = (struct envoy_extensions_filters_network_http_connection_manager_v3_ScopedRoutes_ScopeKeyBuilder_FragmentBuilder*)_upb_msg_new(&envoy_extensions_filters_network_http_connection_manager_v3_ScopedRoutes_ScopeKeyBuilder_FragmentBuilder_msginit, arena);
-  bool ok = _upb_array_append_accessor(
-      msg, UPB_SIZE(0, 0), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena);
+  bool ok = _upb_array_append_accessor2(
+      msg, UPB_SIZE(0, 0), UPB_SIZE(2, 3), &sub, arena);
   if (!ok) return NULL;
   return sub;
 }
@@ -1112,6 +1213,12 @@ UPB_INLINE envoy_extensions_filters_network_http_connection_manager_v3_ScopedRou
   envoy_extensions_filters_network_http_connection_manager_v3_ScopedRoutes_ScopeKeyBuilder_FragmentBuilder *ret = envoy_extensions_filters_network_http_connection_manager_v3_ScopedRoutes_ScopeKeyBuilder_FragmentBuilder_new(arena);
   return (ret && upb_decode(buf, size, ret, &envoy_extensions_filters_network_http_connection_manager_v3_ScopedRoutes_ScopeKeyBuilder_FragmentBuilder_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE envoy_extensions_filters_network_http_connection_manager_v3_ScopedRoutes_ScopeKeyBuilder_FragmentBuilder *envoy_extensions_filters_network_http_connection_manager_v3_ScopedRoutes_ScopeKeyBuilder_FragmentBuilder_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  envoy_extensions_filters_network_http_connection_manager_v3_ScopedRoutes_ScopeKeyBuilder_FragmentBuilder *ret = envoy_extensions_filters_network_http_connection_manager_v3_ScopedRoutes_ScopeKeyBuilder_FragmentBuilder_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &envoy_extensions_filters_network_http_connection_manager_v3_ScopedRoutes_ScopeKeyBuilder_FragmentBuilder_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *envoy_extensions_filters_network_http_connection_manager_v3_ScopedRoutes_ScopeKeyBuilder_FragmentBuilder_serialize(const envoy_extensions_filters_network_http_connection_manager_v3_ScopedRoutes_ScopeKeyBuilder_FragmentBuilder *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &envoy_extensions_filters_network_http_connection_manager_v3_ScopedRoutes_ScopeKeyBuilder_FragmentBuilder_msginit, arena, len);
 }
@@ -1148,6 +1255,12 @@ UPB_INLINE envoy_extensions_filters_network_http_connection_manager_v3_ScopedRou
   envoy_extensions_filters_network_http_connection_manager_v3_ScopedRoutes_ScopeKeyBuilder_FragmentBuilder_HeaderValueExtractor *ret = envoy_extensions_filters_network_http_connection_manager_v3_ScopedRoutes_ScopeKeyBuilder_FragmentBuilder_HeaderValueExtractor_new(arena);
   return (ret && upb_decode(buf, size, ret, &envoy_extensions_filters_network_http_connection_manager_v3_ScopedRoutes_ScopeKeyBuilder_FragmentBuilder_HeaderValueExtractor_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE envoy_extensions_filters_network_http_connection_manager_v3_ScopedRoutes_ScopeKeyBuilder_FragmentBuilder_HeaderValueExtractor *envoy_extensions_filters_network_http_connection_manager_v3_ScopedRoutes_ScopeKeyBuilder_FragmentBuilder_HeaderValueExtractor_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  envoy_extensions_filters_network_http_connection_manager_v3_ScopedRoutes_ScopeKeyBuilder_FragmentBuilder_HeaderValueExtractor *ret = envoy_extensions_filters_network_http_connection_manager_v3_ScopedRoutes_ScopeKeyBuilder_FragmentBuilder_HeaderValueExtractor_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &envoy_extensions_filters_network_http_connection_manager_v3_ScopedRoutes_ScopeKeyBuilder_FragmentBuilder_HeaderValueExtractor_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *envoy_extensions_filters_network_http_connection_manager_v3_ScopedRoutes_ScopeKeyBuilder_FragmentBuilder_HeaderValueExtractor_serialize(const envoy_extensions_filters_network_http_connection_manager_v3_ScopedRoutes_ScopeKeyBuilder_FragmentBuilder_HeaderValueExtractor *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &envoy_extensions_filters_network_http_connection_manager_v3_ScopedRoutes_ScopeKeyBuilder_FragmentBuilder_HeaderValueExtractor_msginit, arena, len);
 }
@@ -1198,6 +1311,12 @@ UPB_INLINE envoy_extensions_filters_network_http_connection_manager_v3_ScopedRou
   envoy_extensions_filters_network_http_connection_manager_v3_ScopedRoutes_ScopeKeyBuilder_FragmentBuilder_HeaderValueExtractor_KvElement *ret = envoy_extensions_filters_network_http_connection_manager_v3_ScopedRoutes_ScopeKeyBuilder_FragmentBuilder_HeaderValueExtractor_KvElement_new(arena);
   return (ret && upb_decode(buf, size, ret, &envoy_extensions_filters_network_http_connection_manager_v3_ScopedRoutes_ScopeKeyBuilder_FragmentBuilder_HeaderValueExtractor_KvElement_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE envoy_extensions_filters_network_http_connection_manager_v3_ScopedRoutes_ScopeKeyBuilder_FragmentBuilder_HeaderValueExtractor_KvElement *envoy_extensions_filters_network_http_connection_manager_v3_ScopedRoutes_ScopeKeyBuilder_FragmentBuilder_HeaderValueExtractor_KvElement_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  envoy_extensions_filters_network_http_connection_manager_v3_ScopedRoutes_ScopeKeyBuilder_FragmentBuilder_HeaderValueExtractor_KvElement *ret = envoy_extensions_filters_network_http_connection_manager_v3_ScopedRoutes_ScopeKeyBuilder_FragmentBuilder_HeaderValueExtractor_KvElement_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &envoy_extensions_filters_network_http_connection_manager_v3_ScopedRoutes_ScopeKeyBuilder_FragmentBuilder_HeaderValueExtractor_KvElement_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *envoy_extensions_filters_network_http_connection_manager_v3_ScopedRoutes_ScopeKeyBuilder_FragmentBuilder_HeaderValueExtractor_KvElement_serialize(const envoy_extensions_filters_network_http_connection_manager_v3_ScopedRoutes_ScopeKeyBuilder_FragmentBuilder_HeaderValueExtractor_KvElement *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &envoy_extensions_filters_network_http_connection_manager_v3_ScopedRoutes_ScopeKeyBuilder_FragmentBuilder_HeaderValueExtractor_KvElement_msginit, arena, len);
 }
@@ -1222,15 +1341,22 @@ UPB_INLINE envoy_extensions_filters_network_http_connection_manager_v3_ScopedRds
   envoy_extensions_filters_network_http_connection_manager_v3_ScopedRds *ret = envoy_extensions_filters_network_http_connection_manager_v3_ScopedRds_new(arena);
   return (ret && upb_decode(buf, size, ret, &envoy_extensions_filters_network_http_connection_manager_v3_ScopedRds_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE envoy_extensions_filters_network_http_connection_manager_v3_ScopedRds *envoy_extensions_filters_network_http_connection_manager_v3_ScopedRds_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  envoy_extensions_filters_network_http_connection_manager_v3_ScopedRds *ret = envoy_extensions_filters_network_http_connection_manager_v3_ScopedRds_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &envoy_extensions_filters_network_http_connection_manager_v3_ScopedRds_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *envoy_extensions_filters_network_http_connection_manager_v3_ScopedRds_serialize(const envoy_extensions_filters_network_http_connection_manager_v3_ScopedRds *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &envoy_extensions_filters_network_http_connection_manager_v3_ScopedRds_msginit, arena, len);
 }
 
-UPB_INLINE bool envoy_extensions_filters_network_http_connection_manager_v3_ScopedRds_has_scoped_rds_config_source(const envoy_extensions_filters_network_http_connection_manager_v3_ScopedRds *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(0, 0)); }
-UPB_INLINE const struct envoy_config_core_v3_ConfigSource* envoy_extensions_filters_network_http_connection_manager_v3_ScopedRds_scoped_rds_config_source(const envoy_extensions_filters_network_http_connection_manager_v3_ScopedRds *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(0, 0), const struct envoy_config_core_v3_ConfigSource*); }
+UPB_INLINE bool envoy_extensions_filters_network_http_connection_manager_v3_ScopedRds_has_scoped_rds_config_source(const envoy_extensions_filters_network_http_connection_manager_v3_ScopedRds *msg) { return _upb_hasbit(msg, 1); }
+UPB_INLINE const struct envoy_config_core_v3_ConfigSource* envoy_extensions_filters_network_http_connection_manager_v3_ScopedRds_scoped_rds_config_source(const envoy_extensions_filters_network_http_connection_manager_v3_ScopedRds *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(4, 8), const struct envoy_config_core_v3_ConfigSource*); }
 
 UPB_INLINE void envoy_extensions_filters_network_http_connection_manager_v3_ScopedRds_set_scoped_rds_config_source(envoy_extensions_filters_network_http_connection_manager_v3_ScopedRds *msg, struct envoy_config_core_v3_ConfigSource* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(0, 0), struct envoy_config_core_v3_ConfigSource*) = value;
+  _upb_sethas(msg, 1);
+  *UPB_PTR_AT(msg, UPB_SIZE(4, 8), struct envoy_config_core_v3_ConfigSource*) = value;
 }
 UPB_INLINE struct envoy_config_core_v3_ConfigSource* envoy_extensions_filters_network_http_connection_manager_v3_ScopedRds_mutable_scoped_rds_config_source(envoy_extensions_filters_network_http_connection_manager_v3_ScopedRds *msg, upb_arena *arena) {
   struct envoy_config_core_v3_ConfigSource* sub = (struct envoy_config_core_v3_ConfigSource*)envoy_extensions_filters_network_http_connection_manager_v3_ScopedRds_scoped_rds_config_source(msg);
@@ -1252,6 +1378,12 @@ UPB_INLINE envoy_extensions_filters_network_http_connection_manager_v3_HttpFilte
   envoy_extensions_filters_network_http_connection_manager_v3_HttpFilter *ret = envoy_extensions_filters_network_http_connection_manager_v3_HttpFilter_new(arena);
   return (ret && upb_decode(buf, size, ret, &envoy_extensions_filters_network_http_connection_manager_v3_HttpFilter_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE envoy_extensions_filters_network_http_connection_manager_v3_HttpFilter *envoy_extensions_filters_network_http_connection_manager_v3_HttpFilter_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  envoy_extensions_filters_network_http_connection_manager_v3_HttpFilter *ret = envoy_extensions_filters_network_http_connection_manager_v3_HttpFilter_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &envoy_extensions_filters_network_http_connection_manager_v3_HttpFilter_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *envoy_extensions_filters_network_http_connection_manager_v3_HttpFilter_serialize(const envoy_extensions_filters_network_http_connection_manager_v3_HttpFilter *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &envoy_extensions_filters_network_http_connection_manager_v3_HttpFilter_msginit, arena, len);
 }
@@ -1307,15 +1439,22 @@ UPB_INLINE envoy_extensions_filters_network_http_connection_manager_v3_RequestID
   envoy_extensions_filters_network_http_connection_manager_v3_RequestIDExtension *ret = envoy_extensions_filters_network_http_connection_manager_v3_RequestIDExtension_new(arena);
   return (ret && upb_decode(buf, size, ret, &envoy_extensions_filters_network_http_connection_manager_v3_RequestIDExtension_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE envoy_extensions_filters_network_http_connection_manager_v3_RequestIDExtension *envoy_extensions_filters_network_http_connection_manager_v3_RequestIDExtension_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  envoy_extensions_filters_network_http_connection_manager_v3_RequestIDExtension *ret = envoy_extensions_filters_network_http_connection_manager_v3_RequestIDExtension_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &envoy_extensions_filters_network_http_connection_manager_v3_RequestIDExtension_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *envoy_extensions_filters_network_http_connection_manager_v3_RequestIDExtension_serialize(const envoy_extensions_filters_network_http_connection_manager_v3_RequestIDExtension *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &envoy_extensions_filters_network_http_connection_manager_v3_RequestIDExtension_msginit, arena, len);
 }
 
-UPB_INLINE bool envoy_extensions_filters_network_http_connection_manager_v3_RequestIDExtension_has_typed_config(const envoy_extensions_filters_network_http_connection_manager_v3_RequestIDExtension *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(0, 0)); }
-UPB_INLINE const struct google_protobuf_Any* envoy_extensions_filters_network_http_connection_manager_v3_RequestIDExtension_typed_config(const envoy_extensions_filters_network_http_connection_manager_v3_RequestIDExtension *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(0, 0), const struct google_protobuf_Any*); }
+UPB_INLINE bool envoy_extensions_filters_network_http_connection_manager_v3_RequestIDExtension_has_typed_config(const envoy_extensions_filters_network_http_connection_manager_v3_RequestIDExtension *msg) { return _upb_hasbit(msg, 1); }
+UPB_INLINE const struct google_protobuf_Any* envoy_extensions_filters_network_http_connection_manager_v3_RequestIDExtension_typed_config(const envoy_extensions_filters_network_http_connection_manager_v3_RequestIDExtension *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(4, 8), const struct google_protobuf_Any*); }
 
 UPB_INLINE void envoy_extensions_filters_network_http_connection_manager_v3_RequestIDExtension_set_typed_config(envoy_extensions_filters_network_http_connection_manager_v3_RequestIDExtension *msg, struct google_protobuf_Any* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(0, 0), struct google_protobuf_Any*) = value;
+  _upb_sethas(msg, 1);
+  *UPB_PTR_AT(msg, UPB_SIZE(4, 8), struct google_protobuf_Any*) = value;
 }
 UPB_INLINE struct google_protobuf_Any* envoy_extensions_filters_network_http_connection_manager_v3_RequestIDExtension_mutable_typed_config(envoy_extensions_filters_network_http_connection_manager_v3_RequestIDExtension *msg, upb_arena *arena) {
   struct google_protobuf_Any* sub = (struct google_protobuf_Any*)envoy_extensions_filters_network_http_connection_manager_v3_RequestIDExtension_typed_config(msg);
index f292720..f2dd45c 100644 (file)
 
 static const upb_msglayout_field envoy_extensions_transport_sockets_tls_v3_TlsParameters__fields[4] = {
   {1, UPB_SIZE(0, 0), 0, 0, 14, 1},
-  {2, UPB_SIZE(8, 8), 0, 0, 14, 1},
-  {3, UPB_SIZE(16, 16), 0, 0, 9, 3},
-  {4, UPB_SIZE(20, 24), 0, 0, 9, 3},
+  {2, UPB_SIZE(4, 4), 0, 0, 14, 1},
+  {3, UPB_SIZE(8, 8), 0, 0, 9, 3},
+  {4, UPB_SIZE(12, 16), 0, 0, 9, 3},
 };
 
 const upb_msglayout envoy_extensions_transport_sockets_tls_v3_TlsParameters_msginit = {
   NULL,
   &envoy_extensions_transport_sockets_tls_v3_TlsParameters__fields[0],
-  UPB_SIZE(24, 32), 4, false,
+  UPB_SIZE(16, 24), 4, false, 255,
 };
 
 static const upb_msglayout *const envoy_extensions_transport_sockets_tls_v3_PrivateKeyProvider_submsgs[1] = {
@@ -46,27 +46,27 @@ static const upb_msglayout_field envoy_extensions_transport_sockets_tls_v3_Priva
 const upb_msglayout envoy_extensions_transport_sockets_tls_v3_PrivateKeyProvider_msginit = {
   &envoy_extensions_transport_sockets_tls_v3_PrivateKeyProvider_submsgs[0],
   &envoy_extensions_transport_sockets_tls_v3_PrivateKeyProvider__fields[0],
-  UPB_SIZE(16, 32), 2, false,
+  UPB_SIZE(16, 32), 2, false, 255,
 };
 
-static const upb_msglayout *const envoy_extensions_transport_sockets_tls_v3_TlsCertificate_submsgs[6] = {
+static const upb_msglayout *const envoy_extensions_transport_sockets_tls_v3_TlsCertificate_submsgs[2] = {
   &envoy_config_core_v3_DataSource_msginit,
   &envoy_extensions_transport_sockets_tls_v3_PrivateKeyProvider_msginit,
 };
 
 static const upb_msglayout_field envoy_extensions_transport_sockets_tls_v3_TlsCertificate__fields[6] = {
-  {1, UPB_SIZE(0, 0), 0, 0, 11, 1},
-  {2, UPB_SIZE(4, 8), 0, 0, 11, 1},
-  {3, UPB_SIZE(8, 16), 0, 0, 11, 1},
-  {4, UPB_SIZE(12, 24), 0, 0, 11, 1},
-  {5, UPB_SIZE(20, 40), 0, 0, 11, 3},
-  {6, UPB_SIZE(16, 32), 0, 1, 11, 1},
+  {1, UPB_SIZE(4, 8), 1, 0, 11, 1},
+  {2, UPB_SIZE(8, 16), 2, 0, 11, 1},
+  {3, UPB_SIZE(12, 24), 3, 0, 11, 1},
+  {4, UPB_SIZE(16, 32), 4, 0, 11, 1},
+  {5, UPB_SIZE(24, 48), 0, 0, 11, 3},
+  {6, UPB_SIZE(20, 40), 5, 1, 11, 1},
 };
 
 const upb_msglayout envoy_extensions_transport_sockets_tls_v3_TlsCertificate_msginit = {
   &envoy_extensions_transport_sockets_tls_v3_TlsCertificate_submsgs[0],
   &envoy_extensions_transport_sockets_tls_v3_TlsCertificate__fields[0],
-  UPB_SIZE(24, 48), 6, false,
+  UPB_SIZE(32, 56), 6, false, 255,
 };
 
 static const upb_msglayout *const envoy_extensions_transport_sockets_tls_v3_TlsSessionTicketKeys_submsgs[1] = {
@@ -80,30 +80,30 @@ static const upb_msglayout_field envoy_extensions_transport_sockets_tls_v3_TlsSe
 const upb_msglayout envoy_extensions_transport_sockets_tls_v3_TlsSessionTicketKeys_msginit = {
   &envoy_extensions_transport_sockets_tls_v3_TlsSessionTicketKeys_submsgs[0],
   &envoy_extensions_transport_sockets_tls_v3_TlsSessionTicketKeys__fields[0],
-  UPB_SIZE(4, 8), 1, false,
+  UPB_SIZE(8, 8), 1, false, 255,
 };
 
-static const upb_msglayout *const envoy_extensions_transport_sockets_tls_v3_CertificateValidationContext_submsgs[4] = {
+static const upb_msglayout *const envoy_extensions_transport_sockets_tls_v3_CertificateValidationContext_submsgs[3] = {
   &envoy_config_core_v3_DataSource_msginit,
   &envoy_type_matcher_v3_StringMatcher_msginit,
   &google_protobuf_BoolValue_msginit,
 };
 
 static const upb_msglayout_field envoy_extensions_transport_sockets_tls_v3_CertificateValidationContext__fields[8] = {
-  {1, UPB_SIZE(12, 16), 0, 0, 11, 1},
+  {1, UPB_SIZE(12, 16), 1, 0, 11, 1},
   {2, UPB_SIZE(24, 40), 0, 0, 9, 3},
   {3, UPB_SIZE(28, 48), 0, 0, 9, 3},
-  {6, UPB_SIZE(16, 24), 0, 2, 11, 1},
-  {7, UPB_SIZE(20, 32), 0, 0, 11, 1},
+  {6, UPB_SIZE(16, 24), 2, 2, 11, 1},
+  {7, UPB_SIZE(20, 32), 3, 0, 11, 1},
   {8, UPB_SIZE(8, 8), 0, 0, 8, 1},
   {9, UPB_SIZE(32, 56), 0, 1, 11, 3},
-  {10, UPB_SIZE(0, 0), 0, 0, 14, 1},
+  {10, UPB_SIZE(4, 4), 0, 0, 14, 1},
 };
 
 const upb_msglayout envoy_extensions_transport_sockets_tls_v3_CertificateValidationContext_msginit = {
   &envoy_extensions_transport_sockets_tls_v3_CertificateValidationContext_submsgs[0],
   &envoy_extensions_transport_sockets_tls_v3_CertificateValidationContext__fields[0],
-  UPB_SIZE(40, 64), 8, false,
+  UPB_SIZE(40, 64), 8, false, 255,
 };
 
 #include "upb/port_undef.inc"
index c2d2581..59b0edb 100644 (file)
@@ -11,6 +11,7 @@
 
 #include "upb/msg.h"
 #include "upb/decode.h"
+#include "upb/decode_fast.h"
 #include "upb/encode.h"
 
 #include "upb/port_def.inc"
@@ -67,39 +68,45 @@ UPB_INLINE envoy_extensions_transport_sockets_tls_v3_TlsParameters *envoy_extens
   envoy_extensions_transport_sockets_tls_v3_TlsParameters *ret = envoy_extensions_transport_sockets_tls_v3_TlsParameters_new(arena);
   return (ret && upb_decode(buf, size, ret, &envoy_extensions_transport_sockets_tls_v3_TlsParameters_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE envoy_extensions_transport_sockets_tls_v3_TlsParameters *envoy_extensions_transport_sockets_tls_v3_TlsParameters_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  envoy_extensions_transport_sockets_tls_v3_TlsParameters *ret = envoy_extensions_transport_sockets_tls_v3_TlsParameters_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &envoy_extensions_transport_sockets_tls_v3_TlsParameters_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *envoy_extensions_transport_sockets_tls_v3_TlsParameters_serialize(const envoy_extensions_transport_sockets_tls_v3_TlsParameters *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &envoy_extensions_transport_sockets_tls_v3_TlsParameters_msginit, arena, len);
 }
 
 UPB_INLINE int32_t envoy_extensions_transport_sockets_tls_v3_TlsParameters_tls_minimum_protocol_version(const envoy_extensions_transport_sockets_tls_v3_TlsParameters *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(0, 0), int32_t); }
-UPB_INLINE int32_t envoy_extensions_transport_sockets_tls_v3_TlsParameters_tls_maximum_protocol_version(const envoy_extensions_transport_sockets_tls_v3_TlsParameters *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(8, 8), int32_t); }
-UPB_INLINE upb_strview const* envoy_extensions_transport_sockets_tls_v3_TlsParameters_cipher_suites(const envoy_extensions_transport_sockets_tls_v3_TlsParameters *msg, size_t *len) { return (upb_strview const*)_upb_array_accessor(msg, UPB_SIZE(16, 16), len); }
-UPB_INLINE upb_strview const* envoy_extensions_transport_sockets_tls_v3_TlsParameters_ecdh_curves(const envoy_extensions_transport_sockets_tls_v3_TlsParameters *msg, size_t *len) { return (upb_strview const*)_upb_array_accessor(msg, UPB_SIZE(20, 24), len); }
+UPB_INLINE int32_t envoy_extensions_transport_sockets_tls_v3_TlsParameters_tls_maximum_protocol_version(const envoy_extensions_transport_sockets_tls_v3_TlsParameters *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(4, 4), int32_t); }
+UPB_INLINE upb_strview const* envoy_extensions_transport_sockets_tls_v3_TlsParameters_cipher_suites(const envoy_extensions_transport_sockets_tls_v3_TlsParameters *msg, size_t *len) { return (upb_strview const*)_upb_array_accessor(msg, UPB_SIZE(8, 8), len); }
+UPB_INLINE upb_strview const* envoy_extensions_transport_sockets_tls_v3_TlsParameters_ecdh_curves(const envoy_extensions_transport_sockets_tls_v3_TlsParameters *msg, size_t *len) { return (upb_strview const*)_upb_array_accessor(msg, UPB_SIZE(12, 16), len); }
 
 UPB_INLINE void envoy_extensions_transport_sockets_tls_v3_TlsParameters_set_tls_minimum_protocol_version(envoy_extensions_transport_sockets_tls_v3_TlsParameters *msg, int32_t value) {
   *UPB_PTR_AT(msg, UPB_SIZE(0, 0), int32_t) = value;
 }
 UPB_INLINE void envoy_extensions_transport_sockets_tls_v3_TlsParameters_set_tls_maximum_protocol_version(envoy_extensions_transport_sockets_tls_v3_TlsParameters *msg, int32_t value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(8, 8), int32_t) = value;
+  *UPB_PTR_AT(msg, UPB_SIZE(4, 4), int32_t) = value;
 }
 UPB_INLINE upb_strview* envoy_extensions_transport_sockets_tls_v3_TlsParameters_mutable_cipher_suites(envoy_extensions_transport_sockets_tls_v3_TlsParameters *msg, size_t *len) {
-  return (upb_strview*)_upb_array_mutable_accessor(msg, UPB_SIZE(16, 16), len);
+  return (upb_strview*)_upb_array_mutable_accessor(msg, UPB_SIZE(8, 8), len);
 }
 UPB_INLINE upb_strview* envoy_extensions_transport_sockets_tls_v3_TlsParameters_resize_cipher_suites(envoy_extensions_transport_sockets_tls_v3_TlsParameters *msg, size_t len, upb_arena *arena) {
-  return (upb_strview*)_upb_array_resize_accessor(msg, UPB_SIZE(16, 16), len, UPB_TYPE_STRING, arena);
+  return (upb_strview*)_upb_array_resize_accessor2(msg, UPB_SIZE(8, 8), len, UPB_SIZE(3, 4), arena);
 }
 UPB_INLINE bool envoy_extensions_transport_sockets_tls_v3_TlsParameters_add_cipher_suites(envoy_extensions_transport_sockets_tls_v3_TlsParameters *msg, upb_strview val, upb_arena *arena) {
-  return _upb_array_append_accessor(msg, UPB_SIZE(16, 16), UPB_SIZE(8, 16), UPB_TYPE_STRING, &val,
+  return _upb_array_append_accessor2(msg, UPB_SIZE(8, 8), UPB_SIZE(3, 4), &val,
       arena);
 }
 UPB_INLINE upb_strview* envoy_extensions_transport_sockets_tls_v3_TlsParameters_mutable_ecdh_curves(envoy_extensions_transport_sockets_tls_v3_TlsParameters *msg, size_t *len) {
-  return (upb_strview*)_upb_array_mutable_accessor(msg, UPB_SIZE(20, 24), len);
+  return (upb_strview*)_upb_array_mutable_accessor(msg, UPB_SIZE(12, 16), len);
 }
 UPB_INLINE upb_strview* envoy_extensions_transport_sockets_tls_v3_TlsParameters_resize_ecdh_curves(envoy_extensions_transport_sockets_tls_v3_TlsParameters *msg, size_t len, upb_arena *arena) {
-  return (upb_strview*)_upb_array_resize_accessor(msg, UPB_SIZE(20, 24), len, UPB_TYPE_STRING, arena);
+  return (upb_strview*)_upb_array_resize_accessor2(msg, UPB_SIZE(12, 16), len, UPB_SIZE(3, 4), arena);
 }
 UPB_INLINE bool envoy_extensions_transport_sockets_tls_v3_TlsParameters_add_ecdh_curves(envoy_extensions_transport_sockets_tls_v3_TlsParameters *msg, upb_strview val, upb_arena *arena) {
-  return _upb_array_append_accessor(msg, UPB_SIZE(20, 24), UPB_SIZE(8, 16), UPB_TYPE_STRING, &val,
+  return _upb_array_append_accessor2(msg, UPB_SIZE(12, 16), UPB_SIZE(3, 4), &val,
       arena);
 }
 
@@ -113,6 +120,12 @@ UPB_INLINE envoy_extensions_transport_sockets_tls_v3_PrivateKeyProvider *envoy_e
   envoy_extensions_transport_sockets_tls_v3_PrivateKeyProvider *ret = envoy_extensions_transport_sockets_tls_v3_PrivateKeyProvider_new(arena);
   return (ret && upb_decode(buf, size, ret, &envoy_extensions_transport_sockets_tls_v3_PrivateKeyProvider_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE envoy_extensions_transport_sockets_tls_v3_PrivateKeyProvider *envoy_extensions_transport_sockets_tls_v3_PrivateKeyProvider_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  envoy_extensions_transport_sockets_tls_v3_PrivateKeyProvider *ret = envoy_extensions_transport_sockets_tls_v3_PrivateKeyProvider_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &envoy_extensions_transport_sockets_tls_v3_PrivateKeyProvider_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *envoy_extensions_transport_sockets_tls_v3_PrivateKeyProvider_serialize(const envoy_extensions_transport_sockets_tls_v3_PrivateKeyProvider *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &envoy_extensions_transport_sockets_tls_v3_PrivateKeyProvider_msginit, arena, len);
 }
@@ -153,25 +166,32 @@ UPB_INLINE envoy_extensions_transport_sockets_tls_v3_TlsCertificate *envoy_exten
   envoy_extensions_transport_sockets_tls_v3_TlsCertificate *ret = envoy_extensions_transport_sockets_tls_v3_TlsCertificate_new(arena);
   return (ret && upb_decode(buf, size, ret, &envoy_extensions_transport_sockets_tls_v3_TlsCertificate_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE envoy_extensions_transport_sockets_tls_v3_TlsCertificate *envoy_extensions_transport_sockets_tls_v3_TlsCertificate_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  envoy_extensions_transport_sockets_tls_v3_TlsCertificate *ret = envoy_extensions_transport_sockets_tls_v3_TlsCertificate_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &envoy_extensions_transport_sockets_tls_v3_TlsCertificate_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *envoy_extensions_transport_sockets_tls_v3_TlsCertificate_serialize(const envoy_extensions_transport_sockets_tls_v3_TlsCertificate *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &envoy_extensions_transport_sockets_tls_v3_TlsCertificate_msginit, arena, len);
 }
 
-UPB_INLINE bool envoy_extensions_transport_sockets_tls_v3_TlsCertificate_has_certificate_chain(const envoy_extensions_transport_sockets_tls_v3_TlsCertificate *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(0, 0)); }
-UPB_INLINE const struct envoy_config_core_v3_DataSource* envoy_extensions_transport_sockets_tls_v3_TlsCertificate_certificate_chain(const envoy_extensions_transport_sockets_tls_v3_TlsCertificate *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(0, 0), const struct envoy_config_core_v3_DataSource*); }
-UPB_INLINE bool envoy_extensions_transport_sockets_tls_v3_TlsCertificate_has_private_key(const envoy_extensions_transport_sockets_tls_v3_TlsCertificate *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(4, 8)); }
-UPB_INLINE const struct envoy_config_core_v3_DataSource* envoy_extensions_transport_sockets_tls_v3_TlsCertificate_private_key(const envoy_extensions_transport_sockets_tls_v3_TlsCertificate *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(4, 8), const struct envoy_config_core_v3_DataSource*); }
-UPB_INLINE bool envoy_extensions_transport_sockets_tls_v3_TlsCertificate_has_password(const envoy_extensions_transport_sockets_tls_v3_TlsCertificate *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(8, 16)); }
-UPB_INLINE const struct envoy_config_core_v3_DataSource* envoy_extensions_transport_sockets_tls_v3_TlsCertificate_password(const envoy_extensions_transport_sockets_tls_v3_TlsCertificate *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(8, 16), const struct envoy_config_core_v3_DataSource*); }
-UPB_INLINE bool envoy_extensions_transport_sockets_tls_v3_TlsCertificate_has_ocsp_staple(const envoy_extensions_transport_sockets_tls_v3_TlsCertificate *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(12, 24)); }
-UPB_INLINE const struct envoy_config_core_v3_DataSource* envoy_extensions_transport_sockets_tls_v3_TlsCertificate_ocsp_staple(const envoy_extensions_transport_sockets_tls_v3_TlsCertificate *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(12, 24), const struct envoy_config_core_v3_DataSource*); }
-UPB_INLINE bool envoy_extensions_transport_sockets_tls_v3_TlsCertificate_has_signed_certificate_timestamp(const envoy_extensions_transport_sockets_tls_v3_TlsCertificate *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(20, 40)); }
-UPB_INLINE const struct envoy_config_core_v3_DataSource* const* envoy_extensions_transport_sockets_tls_v3_TlsCertificate_signed_certificate_timestamp(const envoy_extensions_transport_sockets_tls_v3_TlsCertificate *msg, size_t *len) { return (const struct envoy_config_core_v3_DataSource* const*)_upb_array_accessor(msg, UPB_SIZE(20, 40), len); }
-UPB_INLINE bool envoy_extensions_transport_sockets_tls_v3_TlsCertificate_has_private_key_provider(const envoy_extensions_transport_sockets_tls_v3_TlsCertificate *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(16, 32)); }
-UPB_INLINE const envoy_extensions_transport_sockets_tls_v3_PrivateKeyProvider* envoy_extensions_transport_sockets_tls_v3_TlsCertificate_private_key_provider(const envoy_extensions_transport_sockets_tls_v3_TlsCertificate *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(16, 32), const envoy_extensions_transport_sockets_tls_v3_PrivateKeyProvider*); }
+UPB_INLINE bool envoy_extensions_transport_sockets_tls_v3_TlsCertificate_has_certificate_chain(const envoy_extensions_transport_sockets_tls_v3_TlsCertificate *msg) { return _upb_hasbit(msg, 1); }
+UPB_INLINE const struct envoy_config_core_v3_DataSource* envoy_extensions_transport_sockets_tls_v3_TlsCertificate_certificate_chain(const envoy_extensions_transport_sockets_tls_v3_TlsCertificate *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(4, 8), const struct envoy_config_core_v3_DataSource*); }
+UPB_INLINE bool envoy_extensions_transport_sockets_tls_v3_TlsCertificate_has_private_key(const envoy_extensions_transport_sockets_tls_v3_TlsCertificate *msg) { return _upb_hasbit(msg, 2); }
+UPB_INLINE const struct envoy_config_core_v3_DataSource* envoy_extensions_transport_sockets_tls_v3_TlsCertificate_private_key(const envoy_extensions_transport_sockets_tls_v3_TlsCertificate *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(8, 16), const struct envoy_config_core_v3_DataSource*); }
+UPB_INLINE bool envoy_extensions_transport_sockets_tls_v3_TlsCertificate_has_password(const envoy_extensions_transport_sockets_tls_v3_TlsCertificate *msg) { return _upb_hasbit(msg, 3); }
+UPB_INLINE const struct envoy_config_core_v3_DataSource* envoy_extensions_transport_sockets_tls_v3_TlsCertificate_password(const envoy_extensions_transport_sockets_tls_v3_TlsCertificate *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(12, 24), const struct envoy_config_core_v3_DataSource*); }
+UPB_INLINE bool envoy_extensions_transport_sockets_tls_v3_TlsCertificate_has_ocsp_staple(const envoy_extensions_transport_sockets_tls_v3_TlsCertificate *msg) { return _upb_hasbit(msg, 4); }
+UPB_INLINE const struct envoy_config_core_v3_DataSource* envoy_extensions_transport_sockets_tls_v3_TlsCertificate_ocsp_staple(const envoy_extensions_transport_sockets_tls_v3_TlsCertificate *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(16, 32), const struct envoy_config_core_v3_DataSource*); }
+UPB_INLINE bool envoy_extensions_transport_sockets_tls_v3_TlsCertificate_has_signed_certificate_timestamp(const envoy_extensions_transport_sockets_tls_v3_TlsCertificate *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(24, 48)); }
+UPB_INLINE const struct envoy_config_core_v3_DataSource* const* envoy_extensions_transport_sockets_tls_v3_TlsCertificate_signed_certificate_timestamp(const envoy_extensions_transport_sockets_tls_v3_TlsCertificate *msg, size_t *len) { return (const struct envoy_config_core_v3_DataSource* const*)_upb_array_accessor(msg, UPB_SIZE(24, 48), len); }
+UPB_INLINE bool envoy_extensions_transport_sockets_tls_v3_TlsCertificate_has_private_key_provider(const envoy_extensions_transport_sockets_tls_v3_TlsCertificate *msg) { return _upb_hasbit(msg, 5); }
+UPB_INLINE const envoy_extensions_transport_sockets_tls_v3_PrivateKeyProvider* envoy_extensions_transport_sockets_tls_v3_TlsCertificate_private_key_provider(const envoy_extensions_transport_sockets_tls_v3_TlsCertificate *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(20, 40), const envoy_extensions_transport_sockets_tls_v3_PrivateKeyProvider*); }
 
 UPB_INLINE void envoy_extensions_transport_sockets_tls_v3_TlsCertificate_set_certificate_chain(envoy_extensions_transport_sockets_tls_v3_TlsCertificate *msg, struct envoy_config_core_v3_DataSource* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(0, 0), struct envoy_config_core_v3_DataSource*) = value;
+  _upb_sethas(msg, 1);
+  *UPB_PTR_AT(msg, UPB_SIZE(4, 8), struct envoy_config_core_v3_DataSource*) = value;
 }
 UPB_INLINE struct envoy_config_core_v3_DataSource* envoy_extensions_transport_sockets_tls_v3_TlsCertificate_mutable_certificate_chain(envoy_extensions_transport_sockets_tls_v3_TlsCertificate *msg, upb_arena *arena) {
   struct envoy_config_core_v3_DataSource* sub = (struct envoy_config_core_v3_DataSource*)envoy_extensions_transport_sockets_tls_v3_TlsCertificate_certificate_chain(msg);
@@ -183,7 +203,8 @@ UPB_INLINE struct envoy_config_core_v3_DataSource* envoy_extensions_transport_so
   return sub;
 }
 UPB_INLINE void envoy_extensions_transport_sockets_tls_v3_TlsCertificate_set_private_key(envoy_extensions_transport_sockets_tls_v3_TlsCertificate *msg, struct envoy_config_core_v3_DataSource* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(4, 8), struct envoy_config_core_v3_DataSource*) = value;
+  _upb_sethas(msg, 2);
+  *UPB_PTR_AT(msg, UPB_SIZE(8, 16), struct envoy_config_core_v3_DataSource*) = value;
 }
 UPB_INLINE struct envoy_config_core_v3_DataSource* envoy_extensions_transport_sockets_tls_v3_TlsCertificate_mutable_private_key(envoy_extensions_transport_sockets_tls_v3_TlsCertificate *msg, upb_arena *arena) {
   struct envoy_config_core_v3_DataSource* sub = (struct envoy_config_core_v3_DataSource*)envoy_extensions_transport_sockets_tls_v3_TlsCertificate_private_key(msg);
@@ -195,7 +216,8 @@ UPB_INLINE struct envoy_config_core_v3_DataSource* envoy_extensions_transport_so
   return sub;
 }
 UPB_INLINE void envoy_extensions_transport_sockets_tls_v3_TlsCertificate_set_password(envoy_extensions_transport_sockets_tls_v3_TlsCertificate *msg, struct envoy_config_core_v3_DataSource* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(8, 16), struct envoy_config_core_v3_DataSource*) = value;
+  _upb_sethas(msg, 3);
+  *UPB_PTR_AT(msg, UPB_SIZE(12, 24), struct envoy_config_core_v3_DataSource*) = value;
 }
 UPB_INLINE struct envoy_config_core_v3_DataSource* envoy_extensions_transport_sockets_tls_v3_TlsCertificate_mutable_password(envoy_extensions_transport_sockets_tls_v3_TlsCertificate *msg, upb_arena *arena) {
   struct envoy_config_core_v3_DataSource* sub = (struct envoy_config_core_v3_DataSource*)envoy_extensions_transport_sockets_tls_v3_TlsCertificate_password(msg);
@@ -207,7 +229,8 @@ UPB_INLINE struct envoy_config_core_v3_DataSource* envoy_extensions_transport_so
   return sub;
 }
 UPB_INLINE void envoy_extensions_transport_sockets_tls_v3_TlsCertificate_set_ocsp_staple(envoy_extensions_transport_sockets_tls_v3_TlsCertificate *msg, struct envoy_config_core_v3_DataSource* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(12, 24), struct envoy_config_core_v3_DataSource*) = value;
+  _upb_sethas(msg, 4);
+  *UPB_PTR_AT(msg, UPB_SIZE(16, 32), struct envoy_config_core_v3_DataSource*) = value;
 }
 UPB_INLINE struct envoy_config_core_v3_DataSource* envoy_extensions_transport_sockets_tls_v3_TlsCertificate_mutable_ocsp_staple(envoy_extensions_transport_sockets_tls_v3_TlsCertificate *msg, upb_arena *arena) {
   struct envoy_config_core_v3_DataSource* sub = (struct envoy_config_core_v3_DataSource*)envoy_extensions_transport_sockets_tls_v3_TlsCertificate_ocsp_staple(msg);
@@ -219,20 +242,21 @@ UPB_INLINE struct envoy_config_core_v3_DataSource* envoy_extensions_transport_so
   return sub;
 }
 UPB_INLINE struct envoy_config_core_v3_DataSource** envoy_extensions_transport_sockets_tls_v3_TlsCertificate_mutable_signed_certificate_timestamp(envoy_extensions_transport_sockets_tls_v3_TlsCertificate *msg, size_t *len) {
-  return (struct envoy_config_core_v3_DataSource**)_upb_array_mutable_accessor(msg, UPB_SIZE(20, 40), len);
+  return (struct envoy_config_core_v3_DataSource**)_upb_array_mutable_accessor(msg, UPB_SIZE(24, 48), len);
 }
 UPB_INLINE struct envoy_config_core_v3_DataSource** envoy_extensions_transport_sockets_tls_v3_TlsCertificate_resize_signed_certificate_timestamp(envoy_extensions_transport_sockets_tls_v3_TlsCertificate *msg, size_t len, upb_arena *arena) {
-  return (struct envoy_config_core_v3_DataSource**)_upb_array_resize_accessor(msg, UPB_SIZE(20, 40), len, UPB_TYPE_MESSAGE, arena);
+  return (struct envoy_config_core_v3_DataSource**)_upb_array_resize_accessor2(msg, UPB_SIZE(24, 48), len, UPB_SIZE(2, 3), arena);
 }
 UPB_INLINE struct envoy_config_core_v3_DataSource* envoy_extensions_transport_sockets_tls_v3_TlsCertificate_add_signed_certificate_timestamp(envoy_extensions_transport_sockets_tls_v3_TlsCertificate *msg, upb_arena *arena) {
   struct envoy_config_core_v3_DataSource* sub = (struct envoy_config_core_v3_DataSource*)_upb_msg_new(&envoy_config_core_v3_DataSource_msginit, arena);
-  bool ok = _upb_array_append_accessor(
-      msg, UPB_SIZE(20, 40), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena);
+  bool ok = _upb_array_append_accessor2(
+      msg, UPB_SIZE(24, 48), UPB_SIZE(2, 3), &sub, arena);
   if (!ok) return NULL;
   return sub;
 }
 UPB_INLINE void envoy_extensions_transport_sockets_tls_v3_TlsCertificate_set_private_key_provider(envoy_extensions_transport_sockets_tls_v3_TlsCertificate *msg, envoy_extensions_transport_sockets_tls_v3_PrivateKeyProvider* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(16, 32), envoy_extensions_transport_sockets_tls_v3_PrivateKeyProvider*) = value;
+  _upb_sethas(msg, 5);
+  *UPB_PTR_AT(msg, UPB_SIZE(20, 40), envoy_extensions_transport_sockets_tls_v3_PrivateKeyProvider*) = value;
 }
 UPB_INLINE struct envoy_extensions_transport_sockets_tls_v3_PrivateKeyProvider* envoy_extensions_transport_sockets_tls_v3_TlsCertificate_mutable_private_key_provider(envoy_extensions_transport_sockets_tls_v3_TlsCertificate *msg, upb_arena *arena) {
   struct envoy_extensions_transport_sockets_tls_v3_PrivateKeyProvider* sub = (struct envoy_extensions_transport_sockets_tls_v3_PrivateKeyProvider*)envoy_extensions_transport_sockets_tls_v3_TlsCertificate_private_key_provider(msg);
@@ -254,6 +278,12 @@ UPB_INLINE envoy_extensions_transport_sockets_tls_v3_TlsSessionTicketKeys *envoy
   envoy_extensions_transport_sockets_tls_v3_TlsSessionTicketKeys *ret = envoy_extensions_transport_sockets_tls_v3_TlsSessionTicketKeys_new(arena);
   return (ret && upb_decode(buf, size, ret, &envoy_extensions_transport_sockets_tls_v3_TlsSessionTicketKeys_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE envoy_extensions_transport_sockets_tls_v3_TlsSessionTicketKeys *envoy_extensions_transport_sockets_tls_v3_TlsSessionTicketKeys_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  envoy_extensions_transport_sockets_tls_v3_TlsSessionTicketKeys *ret = envoy_extensions_transport_sockets_tls_v3_TlsSessionTicketKeys_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &envoy_extensions_transport_sockets_tls_v3_TlsSessionTicketKeys_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *envoy_extensions_transport_sockets_tls_v3_TlsSessionTicketKeys_serialize(const envoy_extensions_transport_sockets_tls_v3_TlsSessionTicketKeys *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &envoy_extensions_transport_sockets_tls_v3_TlsSessionTicketKeys_msginit, arena, len);
 }
@@ -265,12 +295,12 @@ UPB_INLINE struct envoy_config_core_v3_DataSource** envoy_extensions_transport_s
   return (struct envoy_config_core_v3_DataSource**)_upb_array_mutable_accessor(msg, UPB_SIZE(0, 0), len);
 }
 UPB_INLINE struct envoy_config_core_v3_DataSource** envoy_extensions_transport_sockets_tls_v3_TlsSessionTicketKeys_resize_keys(envoy_extensions_transport_sockets_tls_v3_TlsSessionTicketKeys *msg, size_t len, upb_arena *arena) {
-  return (struct envoy_config_core_v3_DataSource**)_upb_array_resize_accessor(msg, UPB_SIZE(0, 0), len, UPB_TYPE_MESSAGE, arena);
+  return (struct envoy_config_core_v3_DataSource**)_upb_array_resize_accessor2(msg, UPB_SIZE(0, 0), len, UPB_SIZE(2, 3), arena);
 }
 UPB_INLINE struct envoy_config_core_v3_DataSource* envoy_extensions_transport_sockets_tls_v3_TlsSessionTicketKeys_add_keys(envoy_extensions_transport_sockets_tls_v3_TlsSessionTicketKeys *msg, upb_arena *arena) {
   struct envoy_config_core_v3_DataSource* sub = (struct envoy_config_core_v3_DataSource*)_upb_msg_new(&envoy_config_core_v3_DataSource_msginit, arena);
-  bool ok = _upb_array_append_accessor(
-      msg, UPB_SIZE(0, 0), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena);
+  bool ok = _upb_array_append_accessor2(
+      msg, UPB_SIZE(0, 0), UPB_SIZE(2, 3), &sub, arena);
   if (!ok) return NULL;
   return sub;
 }
@@ -285,24 +315,31 @@ UPB_INLINE envoy_extensions_transport_sockets_tls_v3_CertificateValidationContex
   envoy_extensions_transport_sockets_tls_v3_CertificateValidationContext *ret = envoy_extensions_transport_sockets_tls_v3_CertificateValidationContext_new(arena);
   return (ret && upb_decode(buf, size, ret, &envoy_extensions_transport_sockets_tls_v3_CertificateValidationContext_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE envoy_extensions_transport_sockets_tls_v3_CertificateValidationContext *envoy_extensions_transport_sockets_tls_v3_CertificateValidationContext_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  envoy_extensions_transport_sockets_tls_v3_CertificateValidationContext *ret = envoy_extensions_transport_sockets_tls_v3_CertificateValidationContext_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &envoy_extensions_transport_sockets_tls_v3_CertificateValidationContext_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *envoy_extensions_transport_sockets_tls_v3_CertificateValidationContext_serialize(const envoy_extensions_transport_sockets_tls_v3_CertificateValidationContext *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &envoy_extensions_transport_sockets_tls_v3_CertificateValidationContext_msginit, arena, len);
 }
 
-UPB_INLINE bool envoy_extensions_transport_sockets_tls_v3_CertificateValidationContext_has_trusted_ca(const envoy_extensions_transport_sockets_tls_v3_CertificateValidationContext *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(12, 16)); }
+UPB_INLINE bool envoy_extensions_transport_sockets_tls_v3_CertificateValidationContext_has_trusted_ca(const envoy_extensions_transport_sockets_tls_v3_CertificateValidationContext *msg) { return _upb_hasbit(msg, 1); }
 UPB_INLINE const struct envoy_config_core_v3_DataSource* envoy_extensions_transport_sockets_tls_v3_CertificateValidationContext_trusted_ca(const envoy_extensions_transport_sockets_tls_v3_CertificateValidationContext *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(12, 16), const struct envoy_config_core_v3_DataSource*); }
 UPB_INLINE upb_strview const* envoy_extensions_transport_sockets_tls_v3_CertificateValidationContext_verify_certificate_hash(const envoy_extensions_transport_sockets_tls_v3_CertificateValidationContext *msg, size_t *len) { return (upb_strview const*)_upb_array_accessor(msg, UPB_SIZE(24, 40), len); }
 UPB_INLINE upb_strview const* envoy_extensions_transport_sockets_tls_v3_CertificateValidationContext_verify_certificate_spki(const envoy_extensions_transport_sockets_tls_v3_CertificateValidationContext *msg, size_t *len) { return (upb_strview const*)_upb_array_accessor(msg, UPB_SIZE(28, 48), len); }
-UPB_INLINE bool envoy_extensions_transport_sockets_tls_v3_CertificateValidationContext_has_require_signed_certificate_timestamp(const envoy_extensions_transport_sockets_tls_v3_CertificateValidationContext *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(16, 24)); }
+UPB_INLINE bool envoy_extensions_transport_sockets_tls_v3_CertificateValidationContext_has_require_signed_certificate_timestamp(const envoy_extensions_transport_sockets_tls_v3_CertificateValidationContext *msg) { return _upb_hasbit(msg, 2); }
 UPB_INLINE const struct google_protobuf_BoolValue* envoy_extensions_transport_sockets_tls_v3_CertificateValidationContext_require_signed_certificate_timestamp(const envoy_extensions_transport_sockets_tls_v3_CertificateValidationContext *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(16, 24), const struct google_protobuf_BoolValue*); }
-UPB_INLINE bool envoy_extensions_transport_sockets_tls_v3_CertificateValidationContext_has_crl(const envoy_extensions_transport_sockets_tls_v3_CertificateValidationContext *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(20, 32)); }
+UPB_INLINE bool envoy_extensions_transport_sockets_tls_v3_CertificateValidationContext_has_crl(const envoy_extensions_transport_sockets_tls_v3_CertificateValidationContext *msg) { return _upb_hasbit(msg, 3); }
 UPB_INLINE const struct envoy_config_core_v3_DataSource* envoy_extensions_transport_sockets_tls_v3_CertificateValidationContext_crl(const envoy_extensions_transport_sockets_tls_v3_CertificateValidationContext *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(20, 32), const struct envoy_config_core_v3_DataSource*); }
 UPB_INLINE bool envoy_extensions_transport_sockets_tls_v3_CertificateValidationContext_allow_expired_certificate(const envoy_extensions_transport_sockets_tls_v3_CertificateValidationContext *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(8, 8), bool); }
 UPB_INLINE bool envoy_extensions_transport_sockets_tls_v3_CertificateValidationContext_has_match_subject_alt_names(const envoy_extensions_transport_sockets_tls_v3_CertificateValidationContext *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(32, 56)); }
 UPB_INLINE const struct envoy_type_matcher_v3_StringMatcher* const* envoy_extensions_transport_sockets_tls_v3_CertificateValidationContext_match_subject_alt_names(const envoy_extensions_transport_sockets_tls_v3_CertificateValidationContext *msg, size_t *len) { return (const struct envoy_type_matcher_v3_StringMatcher* const*)_upb_array_accessor(msg, UPB_SIZE(32, 56), len); }
-UPB_INLINE int32_t envoy_extensions_transport_sockets_tls_v3_CertificateValidationContext_trust_chain_verification(const envoy_extensions_transport_sockets_tls_v3_CertificateValidationContext *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(0, 0), int32_t); }
+UPB_INLINE int32_t envoy_extensions_transport_sockets_tls_v3_CertificateValidationContext_trust_chain_verification(const envoy_extensions_transport_sockets_tls_v3_CertificateValidationContext *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(4, 4), int32_t); }
 
 UPB_INLINE void envoy_extensions_transport_sockets_tls_v3_CertificateValidationContext_set_trusted_ca(envoy_extensions_transport_sockets_tls_v3_CertificateValidationContext *msg, struct envoy_config_core_v3_DataSource* value) {
+  _upb_sethas(msg, 1);
   *UPB_PTR_AT(msg, UPB_SIZE(12, 16), struct envoy_config_core_v3_DataSource*) = value;
 }
 UPB_INLINE struct envoy_config_core_v3_DataSource* envoy_extensions_transport_sockets_tls_v3_CertificateValidationContext_mutable_trusted_ca(envoy_extensions_transport_sockets_tls_v3_CertificateValidationContext *msg, upb_arena *arena) {
@@ -318,23 +355,24 @@ UPB_INLINE upb_strview* envoy_extensions_transport_sockets_tls_v3_CertificateVal
   return (upb_strview*)_upb_array_mutable_accessor(msg, UPB_SIZE(24, 40), len);
 }
 UPB_INLINE upb_strview* envoy_extensions_transport_sockets_tls_v3_CertificateValidationContext_resize_verify_certificate_hash(envoy_extensions_transport_sockets_tls_v3_CertificateValidationContext *msg, size_t len, upb_arena *arena) {
-  return (upb_strview*)_upb_array_resize_accessor(msg, UPB_SIZE(24, 40), len, UPB_TYPE_STRING, arena);
+  return (upb_strview*)_upb_array_resize_accessor2(msg, UPB_SIZE(24, 40), len, UPB_SIZE(3, 4), arena);
 }
 UPB_INLINE bool envoy_extensions_transport_sockets_tls_v3_CertificateValidationContext_add_verify_certificate_hash(envoy_extensions_transport_sockets_tls_v3_CertificateValidationContext *msg, upb_strview val, upb_arena *arena) {
-  return _upb_array_append_accessor(msg, UPB_SIZE(24, 40), UPB_SIZE(8, 16), UPB_TYPE_STRING, &val,
+  return _upb_array_append_accessor2(msg, UPB_SIZE(24, 40), UPB_SIZE(3, 4), &val,
       arena);
 }
 UPB_INLINE upb_strview* envoy_extensions_transport_sockets_tls_v3_CertificateValidationContext_mutable_verify_certificate_spki(envoy_extensions_transport_sockets_tls_v3_CertificateValidationContext *msg, size_t *len) {
   return (upb_strview*)_upb_array_mutable_accessor(msg, UPB_SIZE(28, 48), len);
 }
 UPB_INLINE upb_strview* envoy_extensions_transport_sockets_tls_v3_CertificateValidationContext_resize_verify_certificate_spki(envoy_extensions_transport_sockets_tls_v3_CertificateValidationContext *msg, size_t len, upb_arena *arena) {
-  return (upb_strview*)_upb_array_resize_accessor(msg, UPB_SIZE(28, 48), len, UPB_TYPE_STRING, arena);
+  return (upb_strview*)_upb_array_resize_accessor2(msg, UPB_SIZE(28, 48), len, UPB_SIZE(3, 4), arena);
 }
 UPB_INLINE bool envoy_extensions_transport_sockets_tls_v3_CertificateValidationContext_add_verify_certificate_spki(envoy_extensions_transport_sockets_tls_v3_CertificateValidationContext *msg, upb_strview val, upb_arena *arena) {
-  return _upb_array_append_accessor(msg, UPB_SIZE(28, 48), UPB_SIZE(8, 16), UPB_TYPE_STRING, &val,
+  return _upb_array_append_accessor2(msg, UPB_SIZE(28, 48), UPB_SIZE(3, 4), &val,
       arena);
 }
 UPB_INLINE void envoy_extensions_transport_sockets_tls_v3_CertificateValidationContext_set_require_signed_certificate_timestamp(envoy_extensions_transport_sockets_tls_v3_CertificateValidationContext *msg, struct google_protobuf_BoolValue* value) {
+  _upb_sethas(msg, 2);
   *UPB_PTR_AT(msg, UPB_SIZE(16, 24), struct google_protobuf_BoolValue*) = value;
 }
 UPB_INLINE struct google_protobuf_BoolValue* envoy_extensions_transport_sockets_tls_v3_CertificateValidationContext_mutable_require_signed_certificate_timestamp(envoy_extensions_transport_sockets_tls_v3_CertificateValidationContext *msg, upb_arena *arena) {
@@ -347,6 +385,7 @@ UPB_INLINE struct google_protobuf_BoolValue* envoy_extensions_transport_sockets_
   return sub;
 }
 UPB_INLINE void envoy_extensions_transport_sockets_tls_v3_CertificateValidationContext_set_crl(envoy_extensions_transport_sockets_tls_v3_CertificateValidationContext *msg, struct envoy_config_core_v3_DataSource* value) {
+  _upb_sethas(msg, 3);
   *UPB_PTR_AT(msg, UPB_SIZE(20, 32), struct envoy_config_core_v3_DataSource*) = value;
 }
 UPB_INLINE struct envoy_config_core_v3_DataSource* envoy_extensions_transport_sockets_tls_v3_CertificateValidationContext_mutable_crl(envoy_extensions_transport_sockets_tls_v3_CertificateValidationContext *msg, upb_arena *arena) {
@@ -365,17 +404,17 @@ UPB_INLINE struct envoy_type_matcher_v3_StringMatcher** envoy_extensions_transpo
   return (struct envoy_type_matcher_v3_StringMatcher**)_upb_array_mutable_accessor(msg, UPB_SIZE(32, 56), len);
 }
 UPB_INLINE struct envoy_type_matcher_v3_StringMatcher** envoy_extensions_transport_sockets_tls_v3_CertificateValidationContext_resize_match_subject_alt_names(envoy_extensions_transport_sockets_tls_v3_CertificateValidationContext *msg, size_t len, upb_arena *arena) {
-  return (struct envoy_type_matcher_v3_StringMatcher**)_upb_array_resize_accessor(msg, UPB_SIZE(32, 56), len, UPB_TYPE_MESSAGE, arena);
+  return (struct envoy_type_matcher_v3_StringMatcher**)_upb_array_resize_accessor2(msg, UPB_SIZE(32, 56), len, UPB_SIZE(2, 3), arena);
 }
 UPB_INLINE struct envoy_type_matcher_v3_StringMatcher* envoy_extensions_transport_sockets_tls_v3_CertificateValidationContext_add_match_subject_alt_names(envoy_extensions_transport_sockets_tls_v3_CertificateValidationContext *msg, upb_arena *arena) {
   struct envoy_type_matcher_v3_StringMatcher* sub = (struct envoy_type_matcher_v3_StringMatcher*)_upb_msg_new(&envoy_type_matcher_v3_StringMatcher_msginit, arena);
-  bool ok = _upb_array_append_accessor(
-      msg, UPB_SIZE(32, 56), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena);
+  bool ok = _upb_array_append_accessor2(
+      msg, UPB_SIZE(32, 56), UPB_SIZE(2, 3), &sub, arena);
   if (!ok) return NULL;
   return sub;
 }
 UPB_INLINE void envoy_extensions_transport_sockets_tls_v3_CertificateValidationContext_set_trust_chain_verification(envoy_extensions_transport_sockets_tls_v3_CertificateValidationContext *msg, int32_t value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(0, 0), int32_t) = value;
+  *UPB_PTR_AT(msg, UPB_SIZE(4, 4), int32_t) = value;
 }
 
 #ifdef __cplusplus
index cbd77b5..6dd0296 100644 (file)
@@ -25,13 +25,13 @@ static const upb_msglayout *const envoy_extensions_transport_sockets_tls_v3_Gene
 };
 
 static const upb_msglayout_field envoy_extensions_transport_sockets_tls_v3_GenericSecret__fields[1] = {
-  {1, UPB_SIZE(0, 0), 0, 0, 11, 1},
+  {1, UPB_SIZE(4, 8), 1, 0, 11, 1},
 };
 
 const upb_msglayout envoy_extensions_transport_sockets_tls_v3_GenericSecret_msginit = {
   &envoy_extensions_transport_sockets_tls_v3_GenericSecret_submsgs[0],
   &envoy_extensions_transport_sockets_tls_v3_GenericSecret__fields[0],
-  UPB_SIZE(4, 8), 1, false,
+  UPB_SIZE(8, 16), 1, false, 255,
 };
 
 static const upb_msglayout *const envoy_extensions_transport_sockets_tls_v3_SdsSecretConfig_submsgs[2] = {
@@ -40,15 +40,15 @@ static const upb_msglayout *const envoy_extensions_transport_sockets_tls_v3_SdsS
 };
 
 static const upb_msglayout_field envoy_extensions_transport_sockets_tls_v3_SdsSecretConfig__fields[3] = {
-  {1, UPB_SIZE(0, 0), 0, 0, 9, 1},
-  {2, UPB_SIZE(8, 16), 0, 0, 11, 1},
-  {3, UPB_SIZE(12, 24), 0, 1, 11, 1},
+  {1, UPB_SIZE(4, 8), 0, 0, 9, 1},
+  {2, UPB_SIZE(12, 24), 1, 0, 11, 1},
+  {3, UPB_SIZE(16, 32), 2, 1, 11, 1},
 };
 
 const upb_msglayout envoy_extensions_transport_sockets_tls_v3_SdsSecretConfig_msginit = {
   &envoy_extensions_transport_sockets_tls_v3_SdsSecretConfig_submsgs[0],
   &envoy_extensions_transport_sockets_tls_v3_SdsSecretConfig__fields[0],
-  UPB_SIZE(16, 32), 3, false,
+  UPB_SIZE(24, 48), 3, false, 255,
 };
 
 static const upb_msglayout *const envoy_extensions_transport_sockets_tls_v3_Secret_submsgs[4] = {
@@ -69,7 +69,7 @@ static const upb_msglayout_field envoy_extensions_transport_sockets_tls_v3_Secre
 const upb_msglayout envoy_extensions_transport_sockets_tls_v3_Secret_msginit = {
   &envoy_extensions_transport_sockets_tls_v3_Secret_submsgs[0],
   &envoy_extensions_transport_sockets_tls_v3_Secret__fields[0],
-  UPB_SIZE(16, 32), 5, false,
+  UPB_SIZE(16, 32), 5, false, 255,
 };
 
 #include "upb/port_undef.inc"
index 2a4438d..fa33aa9 100644 (file)
@@ -11,6 +11,7 @@
 
 #include "upb/msg.h"
 #include "upb/decode.h"
+#include "upb/decode_fast.h"
 #include "upb/encode.h"
 
 #include "upb/port_def.inc"
@@ -52,15 +53,22 @@ UPB_INLINE envoy_extensions_transport_sockets_tls_v3_GenericSecret *envoy_extens
   envoy_extensions_transport_sockets_tls_v3_GenericSecret *ret = envoy_extensions_transport_sockets_tls_v3_GenericSecret_new(arena);
   return (ret && upb_decode(buf, size, ret, &envoy_extensions_transport_sockets_tls_v3_GenericSecret_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE envoy_extensions_transport_sockets_tls_v3_GenericSecret *envoy_extensions_transport_sockets_tls_v3_GenericSecret_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  envoy_extensions_transport_sockets_tls_v3_GenericSecret *ret = envoy_extensions_transport_sockets_tls_v3_GenericSecret_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &envoy_extensions_transport_sockets_tls_v3_GenericSecret_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *envoy_extensions_transport_sockets_tls_v3_GenericSecret_serialize(const envoy_extensions_transport_sockets_tls_v3_GenericSecret *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &envoy_extensions_transport_sockets_tls_v3_GenericSecret_msginit, arena, len);
 }
 
-UPB_INLINE bool envoy_extensions_transport_sockets_tls_v3_GenericSecret_has_secret(const envoy_extensions_transport_sockets_tls_v3_GenericSecret *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(0, 0)); }
-UPB_INLINE const struct envoy_config_core_v3_DataSource* envoy_extensions_transport_sockets_tls_v3_GenericSecret_secret(const envoy_extensions_transport_sockets_tls_v3_GenericSecret *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(0, 0), const struct envoy_config_core_v3_DataSource*); }
+UPB_INLINE bool envoy_extensions_transport_sockets_tls_v3_GenericSecret_has_secret(const envoy_extensions_transport_sockets_tls_v3_GenericSecret *msg) { return _upb_hasbit(msg, 1); }
+UPB_INLINE const struct envoy_config_core_v3_DataSource* envoy_extensions_transport_sockets_tls_v3_GenericSecret_secret(const envoy_extensions_transport_sockets_tls_v3_GenericSecret *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(4, 8), const struct envoy_config_core_v3_DataSource*); }
 
 UPB_INLINE void envoy_extensions_transport_sockets_tls_v3_GenericSecret_set_secret(envoy_extensions_transport_sockets_tls_v3_GenericSecret *msg, struct envoy_config_core_v3_DataSource* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(0, 0), struct envoy_config_core_v3_DataSource*) = value;
+  _upb_sethas(msg, 1);
+  *UPB_PTR_AT(msg, UPB_SIZE(4, 8), struct envoy_config_core_v3_DataSource*) = value;
 }
 UPB_INLINE struct envoy_config_core_v3_DataSource* envoy_extensions_transport_sockets_tls_v3_GenericSecret_mutable_secret(envoy_extensions_transport_sockets_tls_v3_GenericSecret *msg, upb_arena *arena) {
   struct envoy_config_core_v3_DataSource* sub = (struct envoy_config_core_v3_DataSource*)envoy_extensions_transport_sockets_tls_v3_GenericSecret_secret(msg);
@@ -82,21 +90,28 @@ UPB_INLINE envoy_extensions_transport_sockets_tls_v3_SdsSecretConfig *envoy_exte
   envoy_extensions_transport_sockets_tls_v3_SdsSecretConfig *ret = envoy_extensions_transport_sockets_tls_v3_SdsSecretConfig_new(arena);
   return (ret && upb_decode(buf, size, ret, &envoy_extensions_transport_sockets_tls_v3_SdsSecretConfig_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE envoy_extensions_transport_sockets_tls_v3_SdsSecretConfig *envoy_extensions_transport_sockets_tls_v3_SdsSecretConfig_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  envoy_extensions_transport_sockets_tls_v3_SdsSecretConfig *ret = envoy_extensions_transport_sockets_tls_v3_SdsSecretConfig_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &envoy_extensions_transport_sockets_tls_v3_SdsSecretConfig_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *envoy_extensions_transport_sockets_tls_v3_SdsSecretConfig_serialize(const envoy_extensions_transport_sockets_tls_v3_SdsSecretConfig *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &envoy_extensions_transport_sockets_tls_v3_SdsSecretConfig_msginit, arena, len);
 }
 
-UPB_INLINE upb_strview envoy_extensions_transport_sockets_tls_v3_SdsSecretConfig_name(const envoy_extensions_transport_sockets_tls_v3_SdsSecretConfig *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(0, 0), upb_strview); }
-UPB_INLINE bool envoy_extensions_transport_sockets_tls_v3_SdsSecretConfig_has_sds_config(const envoy_extensions_transport_sockets_tls_v3_SdsSecretConfig *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(8, 16)); }
-UPB_INLINE const struct envoy_config_core_v3_ConfigSource* envoy_extensions_transport_sockets_tls_v3_SdsSecretConfig_sds_config(const envoy_extensions_transport_sockets_tls_v3_SdsSecretConfig *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(8, 16), const struct envoy_config_core_v3_ConfigSource*); }
-UPB_INLINE bool envoy_extensions_transport_sockets_tls_v3_SdsSecretConfig_has_sds_resource_locator(const envoy_extensions_transport_sockets_tls_v3_SdsSecretConfig *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(12, 24)); }
-UPB_INLINE const struct udpa_core_v1_ResourceLocator* envoy_extensions_transport_sockets_tls_v3_SdsSecretConfig_sds_resource_locator(const envoy_extensions_transport_sockets_tls_v3_SdsSecretConfig *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(12, 24), const struct udpa_core_v1_ResourceLocator*); }
+UPB_INLINE upb_strview envoy_extensions_transport_sockets_tls_v3_SdsSecretConfig_name(const envoy_extensions_transport_sockets_tls_v3_SdsSecretConfig *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(4, 8), upb_strview); }
+UPB_INLINE bool envoy_extensions_transport_sockets_tls_v3_SdsSecretConfig_has_sds_config(const envoy_extensions_transport_sockets_tls_v3_SdsSecretConfig *msg) { return _upb_hasbit(msg, 1); }
+UPB_INLINE const struct envoy_config_core_v3_ConfigSource* envoy_extensions_transport_sockets_tls_v3_SdsSecretConfig_sds_config(const envoy_extensions_transport_sockets_tls_v3_SdsSecretConfig *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(12, 24), const struct envoy_config_core_v3_ConfigSource*); }
+UPB_INLINE bool envoy_extensions_transport_sockets_tls_v3_SdsSecretConfig_has_sds_resource_locator(const envoy_extensions_transport_sockets_tls_v3_SdsSecretConfig *msg) { return _upb_hasbit(msg, 2); }
+UPB_INLINE const struct udpa_core_v1_ResourceLocator* envoy_extensions_transport_sockets_tls_v3_SdsSecretConfig_sds_resource_locator(const envoy_extensions_transport_sockets_tls_v3_SdsSecretConfig *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(16, 32), const struct udpa_core_v1_ResourceLocator*); }
 
 UPB_INLINE void envoy_extensions_transport_sockets_tls_v3_SdsSecretConfig_set_name(envoy_extensions_transport_sockets_tls_v3_SdsSecretConfig *msg, upb_strview value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(0, 0), upb_strview) = value;
+  *UPB_PTR_AT(msg, UPB_SIZE(4, 8), upb_strview) = value;
 }
 UPB_INLINE void envoy_extensions_transport_sockets_tls_v3_SdsSecretConfig_set_sds_config(envoy_extensions_transport_sockets_tls_v3_SdsSecretConfig *msg, struct envoy_config_core_v3_ConfigSource* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(8, 16), struct envoy_config_core_v3_ConfigSource*) = value;
+  _upb_sethas(msg, 1);
+  *UPB_PTR_AT(msg, UPB_SIZE(12, 24), struct envoy_config_core_v3_ConfigSource*) = value;
 }
 UPB_INLINE struct envoy_config_core_v3_ConfigSource* envoy_extensions_transport_sockets_tls_v3_SdsSecretConfig_mutable_sds_config(envoy_extensions_transport_sockets_tls_v3_SdsSecretConfig *msg, upb_arena *arena) {
   struct envoy_config_core_v3_ConfigSource* sub = (struct envoy_config_core_v3_ConfigSource*)envoy_extensions_transport_sockets_tls_v3_SdsSecretConfig_sds_config(msg);
@@ -108,7 +123,8 @@ UPB_INLINE struct envoy_config_core_v3_ConfigSource* envoy_extensions_transport_
   return sub;
 }
 UPB_INLINE void envoy_extensions_transport_sockets_tls_v3_SdsSecretConfig_set_sds_resource_locator(envoy_extensions_transport_sockets_tls_v3_SdsSecretConfig *msg, struct udpa_core_v1_ResourceLocator* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(12, 24), struct udpa_core_v1_ResourceLocator*) = value;
+  _upb_sethas(msg, 2);
+  *UPB_PTR_AT(msg, UPB_SIZE(16, 32), struct udpa_core_v1_ResourceLocator*) = value;
 }
 UPB_INLINE struct udpa_core_v1_ResourceLocator* envoy_extensions_transport_sockets_tls_v3_SdsSecretConfig_mutable_sds_resource_locator(envoy_extensions_transport_sockets_tls_v3_SdsSecretConfig *msg, upb_arena *arena) {
   struct udpa_core_v1_ResourceLocator* sub = (struct udpa_core_v1_ResourceLocator*)envoy_extensions_transport_sockets_tls_v3_SdsSecretConfig_sds_resource_locator(msg);
@@ -130,6 +146,12 @@ UPB_INLINE envoy_extensions_transport_sockets_tls_v3_Secret *envoy_extensions_tr
   envoy_extensions_transport_sockets_tls_v3_Secret *ret = envoy_extensions_transport_sockets_tls_v3_Secret_new(arena);
   return (ret && upb_decode(buf, size, ret, &envoy_extensions_transport_sockets_tls_v3_Secret_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE envoy_extensions_transport_sockets_tls_v3_Secret *envoy_extensions_transport_sockets_tls_v3_Secret_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  envoy_extensions_transport_sockets_tls_v3_Secret *ret = envoy_extensions_transport_sockets_tls_v3_Secret_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &envoy_extensions_transport_sockets_tls_v3_Secret_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *envoy_extensions_transport_sockets_tls_v3_Secret_serialize(const envoy_extensions_transport_sockets_tls_v3_Secret *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &envoy_extensions_transport_sockets_tls_v3_Secret_msginit, arena, len);
 }
index c38e5d9..7a5072b 100644 (file)
@@ -28,19 +28,19 @@ static const upb_msglayout *const envoy_extensions_transport_sockets_tls_v3_Upst
 };
 
 static const upb_msglayout_field envoy_extensions_transport_sockets_tls_v3_UpstreamTlsContext__fields[4] = {
-  {1, UPB_SIZE(12, 24), 0, 0, 11, 1},
+  {1, UPB_SIZE(12, 24), 1, 0, 11, 1},
   {2, UPB_SIZE(4, 8), 0, 0, 9, 1},
-  {3, UPB_SIZE(0, 0), 0, 0, 8, 1},
-  {4, UPB_SIZE(16, 32), 0, 1, 11, 1},
+  {3, UPB_SIZE(1, 1), 0, 0, 8, 1},
+  {4, UPB_SIZE(16, 32), 2, 1, 11, 1},
 };
 
 const upb_msglayout envoy_extensions_transport_sockets_tls_v3_UpstreamTlsContext_msginit = {
   &envoy_extensions_transport_sockets_tls_v3_UpstreamTlsContext_submsgs[0],
   &envoy_extensions_transport_sockets_tls_v3_UpstreamTlsContext__fields[0],
-  UPB_SIZE(24, 48), 4, false,
+  UPB_SIZE(24, 48), 4, false, 255,
 };
 
-static const upb_msglayout *const envoy_extensions_transport_sockets_tls_v3_DownstreamTlsContext_submsgs[6] = {
+static const upb_msglayout *const envoy_extensions_transport_sockets_tls_v3_DownstreamTlsContext_submsgs[5] = {
   &envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_msginit,
   &envoy_extensions_transport_sockets_tls_v3_SdsSecretConfig_msginit,
   &envoy_extensions_transport_sockets_tls_v3_TlsSessionTicketKeys_msginit,
@@ -49,23 +49,23 @@ static const upb_msglayout *const envoy_extensions_transport_sockets_tls_v3_Down
 };
 
 static const upb_msglayout_field envoy_extensions_transport_sockets_tls_v3_DownstreamTlsContext__fields[8] = {
-  {1, UPB_SIZE(8, 8), 0, 0, 11, 1},
-  {2, UPB_SIZE(12, 16), 0, 3, 11, 1},
-  {3, UPB_SIZE(16, 24), 0, 3, 11, 1},
+  {1, UPB_SIZE(8, 8), 1, 0, 11, 1},
+  {2, UPB_SIZE(12, 16), 2, 3, 11, 1},
+  {3, UPB_SIZE(16, 24), 3, 3, 11, 1},
   {4, UPB_SIZE(24, 40), UPB_SIZE(-29, -49), 2, 11, 1},
   {5, UPB_SIZE(24, 40), UPB_SIZE(-29, -49), 1, 11, 1},
-  {6, UPB_SIZE(20, 32), 0, 4, 11, 1},
+  {6, UPB_SIZE(20, 32), 4, 4, 11, 1},
   {7, UPB_SIZE(24, 40), UPB_SIZE(-29, -49), 0, 8, 1},
-  {8, UPB_SIZE(0, 0), 0, 0, 14, 1},
+  {8, UPB_SIZE(4, 4), 0, 0, 14, 1},
 };
 
 const upb_msglayout envoy_extensions_transport_sockets_tls_v3_DownstreamTlsContext_msginit = {
   &envoy_extensions_transport_sockets_tls_v3_DownstreamTlsContext_submsgs[0],
   &envoy_extensions_transport_sockets_tls_v3_DownstreamTlsContext__fields[0],
-  UPB_SIZE(32, 56), 8, false,
+  UPB_SIZE(32, 56), 8, false, 255,
 };
 
-static const upb_msglayout *const envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_submsgs[11] = {
+static const upb_msglayout *const envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_submsgs[8] = {
   &envoy_config_core_v3_TypedExtensionConfig_msginit,
   &envoy_extensions_transport_sockets_tls_v3_CertificateValidationContext_msginit,
   &envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_CertificateProvider_msginit,
@@ -77,24 +77,24 @@ static const upb_msglayout *const envoy_extensions_transport_sockets_tls_v3_Comm
 };
 
 static const upb_msglayout_field envoy_extensions_transport_sockets_tls_v3_CommonTlsContext__fields[12] = {
-  {1, UPB_SIZE(0, 0), 0, 7, 11, 1},
-  {2, UPB_SIZE(16, 32), 0, 6, 11, 3},
-  {3, UPB_SIZE(28, 56), UPB_SIZE(-33, -65), 1, 11, 1},
-  {4, UPB_SIZE(20, 40), 0, 0, 9, 3},
-  {6, UPB_SIZE(24, 48), 0, 5, 11, 3},
-  {7, UPB_SIZE(28, 56), UPB_SIZE(-33, -65), 5, 11, 1},
-  {8, UPB_SIZE(28, 56), UPB_SIZE(-33, -65), 4, 11, 1},
-  {9, UPB_SIZE(4, 8), 0, 2, 11, 1},
-  {10, UPB_SIZE(28, 56), UPB_SIZE(-33, -65), 2, 11, 1},
-  {11, UPB_SIZE(8, 16), 0, 3, 11, 1},
-  {12, UPB_SIZE(28, 56), UPB_SIZE(-33, -65), 3, 11, 1},
-  {13, UPB_SIZE(12, 24), 0, 0, 11, 1},
+  {1, UPB_SIZE(4, 8), 1, 7, 11, 1},
+  {2, UPB_SIZE(20, 40), 0, 6, 11, 3},
+  {3, UPB_SIZE(32, 64), UPB_SIZE(-37, -73), 1, 11, 1},
+  {4, UPB_SIZE(24, 48), 0, 0, 9, 3},
+  {6, UPB_SIZE(28, 56), 0, 5, 11, 3},
+  {7, UPB_SIZE(32, 64), UPB_SIZE(-37, -73), 5, 11, 1},
+  {8, UPB_SIZE(32, 64), UPB_SIZE(-37, -73), 4, 11, 1},
+  {9, UPB_SIZE(8, 16), 2, 2, 11, 1},
+  {10, UPB_SIZE(32, 64), UPB_SIZE(-37, -73), 2, 11, 1},
+  {11, UPB_SIZE(12, 24), 3, 3, 11, 1},
+  {12, UPB_SIZE(32, 64), UPB_SIZE(-37, -73), 3, 11, 1},
+  {13, UPB_SIZE(16, 32), 4, 0, 11, 1},
 };
 
 const upb_msglayout envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_msginit = {
   &envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_submsgs[0],
   &envoy_extensions_transport_sockets_tls_v3_CommonTlsContext__fields[0],
-  UPB_SIZE(36, 72), 12, false,
+  UPB_SIZE(40, 80), 12, false, 255,
 };
 
 static const upb_msglayout *const envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_CertificateProvider_submsgs[1] = {
@@ -109,7 +109,7 @@ static const upb_msglayout_field envoy_extensions_transport_sockets_tls_v3_Commo
 const upb_msglayout envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_CertificateProvider_msginit = {
   &envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_CertificateProvider_submsgs[0],
   &envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_CertificateProvider__fields[0],
-  UPB_SIZE(16, 32), 2, false,
+  UPB_SIZE(16, 32), 2, false, 255,
 };
 
 static const upb_msglayout_field envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_CertificateProviderInstance__fields[2] = {
@@ -120,7 +120,7 @@ static const upb_msglayout_field envoy_extensions_transport_sockets_tls_v3_Commo
 const upb_msglayout envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_CertificateProviderInstance_msginit = {
   NULL,
   &envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_CertificateProviderInstance__fields[0],
-  UPB_SIZE(16, 32), 2, false,
+  UPB_SIZE(16, 32), 2, false, 255,
 };
 
 static const upb_msglayout *const envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_CombinedCertificateValidationContext_submsgs[4] = {
@@ -131,16 +131,16 @@ static const upb_msglayout *const envoy_extensions_transport_sockets_tls_v3_Comm
 };
 
 static const upb_msglayout_field envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_CombinedCertificateValidationContext__fields[4] = {
-  {1, UPB_SIZE(0, 0), 0, 0, 11, 1},
-  {2, UPB_SIZE(4, 8), 0, 3, 11, 1},
-  {3, UPB_SIZE(8, 16), 0, 1, 11, 1},
-  {4, UPB_SIZE(12, 24), 0, 2, 11, 1},
+  {1, UPB_SIZE(4, 8), 1, 0, 11, 1},
+  {2, UPB_SIZE(8, 16), 2, 3, 11, 1},
+  {3, UPB_SIZE(12, 24), 3, 1, 11, 1},
+  {4, UPB_SIZE(16, 32), 4, 2, 11, 1},
 };
 
 const upb_msglayout envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_CombinedCertificateValidationContext_msginit = {
   &envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_CombinedCertificateValidationContext_submsgs[0],
   &envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_CombinedCertificateValidationContext__fields[0],
-  UPB_SIZE(16, 32), 4, false,
+  UPB_SIZE(24, 40), 4, false, 255,
 };
 
 #include "upb/port_undef.inc"
index 8fc0ad2..8a8ba90 100644 (file)
@@ -11,6 +11,7 @@
 
 #include "upb/msg.h"
 #include "upb/decode.h"
+#include "upb/decode_fast.h"
 #include "upb/encode.h"
 
 #include "upb/port_def.inc"
@@ -73,18 +74,25 @@ UPB_INLINE envoy_extensions_transport_sockets_tls_v3_UpstreamTlsContext *envoy_e
   envoy_extensions_transport_sockets_tls_v3_UpstreamTlsContext *ret = envoy_extensions_transport_sockets_tls_v3_UpstreamTlsContext_new(arena);
   return (ret && upb_decode(buf, size, ret, &envoy_extensions_transport_sockets_tls_v3_UpstreamTlsContext_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE envoy_extensions_transport_sockets_tls_v3_UpstreamTlsContext *envoy_extensions_transport_sockets_tls_v3_UpstreamTlsContext_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  envoy_extensions_transport_sockets_tls_v3_UpstreamTlsContext *ret = envoy_extensions_transport_sockets_tls_v3_UpstreamTlsContext_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &envoy_extensions_transport_sockets_tls_v3_UpstreamTlsContext_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *envoy_extensions_transport_sockets_tls_v3_UpstreamTlsContext_serialize(const envoy_extensions_transport_sockets_tls_v3_UpstreamTlsContext *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &envoy_extensions_transport_sockets_tls_v3_UpstreamTlsContext_msginit, arena, len);
 }
 
-UPB_INLINE bool envoy_extensions_transport_sockets_tls_v3_UpstreamTlsContext_has_common_tls_context(const envoy_extensions_transport_sockets_tls_v3_UpstreamTlsContext *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(12, 24)); }
+UPB_INLINE bool envoy_extensions_transport_sockets_tls_v3_UpstreamTlsContext_has_common_tls_context(const envoy_extensions_transport_sockets_tls_v3_UpstreamTlsContext *msg) { return _upb_hasbit(msg, 1); }
 UPB_INLINE const envoy_extensions_transport_sockets_tls_v3_CommonTlsContext* envoy_extensions_transport_sockets_tls_v3_UpstreamTlsContext_common_tls_context(const envoy_extensions_transport_sockets_tls_v3_UpstreamTlsContext *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(12, 24), const envoy_extensions_transport_sockets_tls_v3_CommonTlsContext*); }
 UPB_INLINE upb_strview envoy_extensions_transport_sockets_tls_v3_UpstreamTlsContext_sni(const envoy_extensions_transport_sockets_tls_v3_UpstreamTlsContext *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(4, 8), upb_strview); }
-UPB_INLINE bool envoy_extensions_transport_sockets_tls_v3_UpstreamTlsContext_allow_renegotiation(const envoy_extensions_transport_sockets_tls_v3_UpstreamTlsContext *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(0, 0), bool); }
-UPB_INLINE bool envoy_extensions_transport_sockets_tls_v3_UpstreamTlsContext_has_max_session_keys(const envoy_extensions_transport_sockets_tls_v3_UpstreamTlsContext *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(16, 32)); }
+UPB_INLINE bool envoy_extensions_transport_sockets_tls_v3_UpstreamTlsContext_allow_renegotiation(const envoy_extensions_transport_sockets_tls_v3_UpstreamTlsContext *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(1, 1), bool); }
+UPB_INLINE bool envoy_extensions_transport_sockets_tls_v3_UpstreamTlsContext_has_max_session_keys(const envoy_extensions_transport_sockets_tls_v3_UpstreamTlsContext *msg) { return _upb_hasbit(msg, 2); }
 UPB_INLINE const struct google_protobuf_UInt32Value* envoy_extensions_transport_sockets_tls_v3_UpstreamTlsContext_max_session_keys(const envoy_extensions_transport_sockets_tls_v3_UpstreamTlsContext *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(16, 32), const struct google_protobuf_UInt32Value*); }
 
 UPB_INLINE void envoy_extensions_transport_sockets_tls_v3_UpstreamTlsContext_set_common_tls_context(envoy_extensions_transport_sockets_tls_v3_UpstreamTlsContext *msg, envoy_extensions_transport_sockets_tls_v3_CommonTlsContext* value) {
+  _upb_sethas(msg, 1);
   *UPB_PTR_AT(msg, UPB_SIZE(12, 24), envoy_extensions_transport_sockets_tls_v3_CommonTlsContext*) = value;
 }
 UPB_INLINE struct envoy_extensions_transport_sockets_tls_v3_CommonTlsContext* envoy_extensions_transport_sockets_tls_v3_UpstreamTlsContext_mutable_common_tls_context(envoy_extensions_transport_sockets_tls_v3_UpstreamTlsContext *msg, upb_arena *arena) {
@@ -100,9 +108,10 @@ UPB_INLINE void envoy_extensions_transport_sockets_tls_v3_UpstreamTlsContext_set
   *UPB_PTR_AT(msg, UPB_SIZE(4, 8), upb_strview) = value;
 }
 UPB_INLINE void envoy_extensions_transport_sockets_tls_v3_UpstreamTlsContext_set_allow_renegotiation(envoy_extensions_transport_sockets_tls_v3_UpstreamTlsContext *msg, bool value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(0, 0), bool) = value;
+  *UPB_PTR_AT(msg, UPB_SIZE(1, 1), bool) = value;
 }
 UPB_INLINE void envoy_extensions_transport_sockets_tls_v3_UpstreamTlsContext_set_max_session_keys(envoy_extensions_transport_sockets_tls_v3_UpstreamTlsContext *msg, struct google_protobuf_UInt32Value* value) {
+  _upb_sethas(msg, 2);
   *UPB_PTR_AT(msg, UPB_SIZE(16, 32), struct google_protobuf_UInt32Value*) = value;
 }
 UPB_INLINE struct google_protobuf_UInt32Value* envoy_extensions_transport_sockets_tls_v3_UpstreamTlsContext_mutable_max_session_keys(envoy_extensions_transport_sockets_tls_v3_UpstreamTlsContext *msg, upb_arena *arena) {
@@ -125,6 +134,12 @@ UPB_INLINE envoy_extensions_transport_sockets_tls_v3_DownstreamTlsContext *envoy
   envoy_extensions_transport_sockets_tls_v3_DownstreamTlsContext *ret = envoy_extensions_transport_sockets_tls_v3_DownstreamTlsContext_new(arena);
   return (ret && upb_decode(buf, size, ret, &envoy_extensions_transport_sockets_tls_v3_DownstreamTlsContext_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE envoy_extensions_transport_sockets_tls_v3_DownstreamTlsContext *envoy_extensions_transport_sockets_tls_v3_DownstreamTlsContext_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  envoy_extensions_transport_sockets_tls_v3_DownstreamTlsContext *ret = envoy_extensions_transport_sockets_tls_v3_DownstreamTlsContext_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &envoy_extensions_transport_sockets_tls_v3_DownstreamTlsContext_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *envoy_extensions_transport_sockets_tls_v3_DownstreamTlsContext_serialize(const envoy_extensions_transport_sockets_tls_v3_DownstreamTlsContext *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &envoy_extensions_transport_sockets_tls_v3_DownstreamTlsContext_msginit, arena, len);
 }
@@ -137,23 +152,24 @@ typedef enum {
 } envoy_extensions_transport_sockets_tls_v3_DownstreamTlsContext_session_ticket_keys_type_oneofcases;
 UPB_INLINE envoy_extensions_transport_sockets_tls_v3_DownstreamTlsContext_session_ticket_keys_type_oneofcases envoy_extensions_transport_sockets_tls_v3_DownstreamTlsContext_session_ticket_keys_type_case(const envoy_extensions_transport_sockets_tls_v3_DownstreamTlsContext* msg) { return (envoy_extensions_transport_sockets_tls_v3_DownstreamTlsContext_session_ticket_keys_type_oneofcases)*UPB_PTR_AT(msg, UPB_SIZE(28, 48), int32_t); }
 
-UPB_INLINE bool envoy_extensions_transport_sockets_tls_v3_DownstreamTlsContext_has_common_tls_context(const envoy_extensions_transport_sockets_tls_v3_DownstreamTlsContext *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(8, 8)); }
+UPB_INLINE bool envoy_extensions_transport_sockets_tls_v3_DownstreamTlsContext_has_common_tls_context(const envoy_extensions_transport_sockets_tls_v3_DownstreamTlsContext *msg) { return _upb_hasbit(msg, 1); }
 UPB_INLINE const envoy_extensions_transport_sockets_tls_v3_CommonTlsContext* envoy_extensions_transport_sockets_tls_v3_DownstreamTlsContext_common_tls_context(const envoy_extensions_transport_sockets_tls_v3_DownstreamTlsContext *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(8, 8), const envoy_extensions_transport_sockets_tls_v3_CommonTlsContext*); }
-UPB_INLINE bool envoy_extensions_transport_sockets_tls_v3_DownstreamTlsContext_has_require_client_certificate(const envoy_extensions_transport_sockets_tls_v3_DownstreamTlsContext *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(12, 16)); }
+UPB_INLINE bool envoy_extensions_transport_sockets_tls_v3_DownstreamTlsContext_has_require_client_certificate(const envoy_extensions_transport_sockets_tls_v3_DownstreamTlsContext *msg) { return _upb_hasbit(msg, 2); }
 UPB_INLINE const struct google_protobuf_BoolValue* envoy_extensions_transport_sockets_tls_v3_DownstreamTlsContext_require_client_certificate(const envoy_extensions_transport_sockets_tls_v3_DownstreamTlsContext *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(12, 16), const struct google_protobuf_BoolValue*); }
-UPB_INLINE bool envoy_extensions_transport_sockets_tls_v3_DownstreamTlsContext_has_require_sni(const envoy_extensions_transport_sockets_tls_v3_DownstreamTlsContext *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(16, 24)); }
+UPB_INLINE bool envoy_extensions_transport_sockets_tls_v3_DownstreamTlsContext_has_require_sni(const envoy_extensions_transport_sockets_tls_v3_DownstreamTlsContext *msg) { return _upb_hasbit(msg, 3); }
 UPB_INLINE const struct google_protobuf_BoolValue* envoy_extensions_transport_sockets_tls_v3_DownstreamTlsContext_require_sni(const envoy_extensions_transport_sockets_tls_v3_DownstreamTlsContext *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(16, 24), const struct google_protobuf_BoolValue*); }
 UPB_INLINE bool envoy_extensions_transport_sockets_tls_v3_DownstreamTlsContext_has_session_ticket_keys(const envoy_extensions_transport_sockets_tls_v3_DownstreamTlsContext *msg) { return _upb_getoneofcase(msg, UPB_SIZE(28, 48)) == 4; }
 UPB_INLINE const struct envoy_extensions_transport_sockets_tls_v3_TlsSessionTicketKeys* envoy_extensions_transport_sockets_tls_v3_DownstreamTlsContext_session_ticket_keys(const envoy_extensions_transport_sockets_tls_v3_DownstreamTlsContext *msg) { return UPB_READ_ONEOF(msg, const struct envoy_extensions_transport_sockets_tls_v3_TlsSessionTicketKeys*, UPB_SIZE(24, 40), UPB_SIZE(28, 48), 4, NULL); }
 UPB_INLINE bool envoy_extensions_transport_sockets_tls_v3_DownstreamTlsContext_has_session_ticket_keys_sds_secret_config(const envoy_extensions_transport_sockets_tls_v3_DownstreamTlsContext *msg) { return _upb_getoneofcase(msg, UPB_SIZE(28, 48)) == 5; }
 UPB_INLINE const struct envoy_extensions_transport_sockets_tls_v3_SdsSecretConfig* envoy_extensions_transport_sockets_tls_v3_DownstreamTlsContext_session_ticket_keys_sds_secret_config(const envoy_extensions_transport_sockets_tls_v3_DownstreamTlsContext *msg) { return UPB_READ_ONEOF(msg, const struct envoy_extensions_transport_sockets_tls_v3_SdsSecretConfig*, UPB_SIZE(24, 40), UPB_SIZE(28, 48), 5, NULL); }
-UPB_INLINE bool envoy_extensions_transport_sockets_tls_v3_DownstreamTlsContext_has_session_timeout(const envoy_extensions_transport_sockets_tls_v3_DownstreamTlsContext *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(20, 32)); }
+UPB_INLINE bool envoy_extensions_transport_sockets_tls_v3_DownstreamTlsContext_has_session_timeout(const envoy_extensions_transport_sockets_tls_v3_DownstreamTlsContext *msg) { return _upb_hasbit(msg, 4); }
 UPB_INLINE const struct google_protobuf_Duration* envoy_extensions_transport_sockets_tls_v3_DownstreamTlsContext_session_timeout(const envoy_extensions_transport_sockets_tls_v3_DownstreamTlsContext *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(20, 32), const struct google_protobuf_Duration*); }
 UPB_INLINE bool envoy_extensions_transport_sockets_tls_v3_DownstreamTlsContext_has_disable_stateless_session_resumption(const envoy_extensions_transport_sockets_tls_v3_DownstreamTlsContext *msg) { return _upb_getoneofcase(msg, UPB_SIZE(28, 48)) == 7; }
 UPB_INLINE bool envoy_extensions_transport_sockets_tls_v3_DownstreamTlsContext_disable_stateless_session_resumption(const envoy_extensions_transport_sockets_tls_v3_DownstreamTlsContext *msg) { return UPB_READ_ONEOF(msg, bool, UPB_SIZE(24, 40), UPB_SIZE(28, 48), 7, false); }
-UPB_INLINE int32_t envoy_extensions_transport_sockets_tls_v3_DownstreamTlsContext_ocsp_staple_policy(const envoy_extensions_transport_sockets_tls_v3_DownstreamTlsContext *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(0, 0), int32_t); }
+UPB_INLINE int32_t envoy_extensions_transport_sockets_tls_v3_DownstreamTlsContext_ocsp_staple_policy(const envoy_extensions_transport_sockets_tls_v3_DownstreamTlsContext *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(4, 4), int32_t); }
 
 UPB_INLINE void envoy_extensions_transport_sockets_tls_v3_DownstreamTlsContext_set_common_tls_context(envoy_extensions_transport_sockets_tls_v3_DownstreamTlsContext *msg, envoy_extensions_transport_sockets_tls_v3_CommonTlsContext* value) {
+  _upb_sethas(msg, 1);
   *UPB_PTR_AT(msg, UPB_SIZE(8, 8), envoy_extensions_transport_sockets_tls_v3_CommonTlsContext*) = value;
 }
 UPB_INLINE struct envoy_extensions_transport_sockets_tls_v3_CommonTlsContext* envoy_extensions_transport_sockets_tls_v3_DownstreamTlsContext_mutable_common_tls_context(envoy_extensions_transport_sockets_tls_v3_DownstreamTlsContext *msg, upb_arena *arena) {
@@ -166,6 +182,7 @@ UPB_INLINE struct envoy_extensions_transport_sockets_tls_v3_CommonTlsContext* en
   return sub;
 }
 UPB_INLINE void envoy_extensions_transport_sockets_tls_v3_DownstreamTlsContext_set_require_client_certificate(envoy_extensions_transport_sockets_tls_v3_DownstreamTlsContext *msg, struct google_protobuf_BoolValue* value) {
+  _upb_sethas(msg, 2);
   *UPB_PTR_AT(msg, UPB_SIZE(12, 16), struct google_protobuf_BoolValue*) = value;
 }
 UPB_INLINE struct google_protobuf_BoolValue* envoy_extensions_transport_sockets_tls_v3_DownstreamTlsContext_mutable_require_client_certificate(envoy_extensions_transport_sockets_tls_v3_DownstreamTlsContext *msg, upb_arena *arena) {
@@ -178,6 +195,7 @@ UPB_INLINE struct google_protobuf_BoolValue* envoy_extensions_transport_sockets_
   return sub;
 }
 UPB_INLINE void envoy_extensions_transport_sockets_tls_v3_DownstreamTlsContext_set_require_sni(envoy_extensions_transport_sockets_tls_v3_DownstreamTlsContext *msg, struct google_protobuf_BoolValue* value) {
+  _upb_sethas(msg, 3);
   *UPB_PTR_AT(msg, UPB_SIZE(16, 24), struct google_protobuf_BoolValue*) = value;
 }
 UPB_INLINE struct google_protobuf_BoolValue* envoy_extensions_transport_sockets_tls_v3_DownstreamTlsContext_mutable_require_sni(envoy_extensions_transport_sockets_tls_v3_DownstreamTlsContext *msg, upb_arena *arena) {
@@ -214,6 +232,7 @@ UPB_INLINE struct envoy_extensions_transport_sockets_tls_v3_SdsSecretConfig* env
   return sub;
 }
 UPB_INLINE void envoy_extensions_transport_sockets_tls_v3_DownstreamTlsContext_set_session_timeout(envoy_extensions_transport_sockets_tls_v3_DownstreamTlsContext *msg, struct google_protobuf_Duration* value) {
+  _upb_sethas(msg, 4);
   *UPB_PTR_AT(msg, UPB_SIZE(20, 32), struct google_protobuf_Duration*) = value;
 }
 UPB_INLINE struct google_protobuf_Duration* envoy_extensions_transport_sockets_tls_v3_DownstreamTlsContext_mutable_session_timeout(envoy_extensions_transport_sockets_tls_v3_DownstreamTlsContext *msg, upb_arena *arena) {
@@ -229,7 +248,7 @@ UPB_INLINE void envoy_extensions_transport_sockets_tls_v3_DownstreamTlsContext_s
   UPB_WRITE_ONEOF(msg, bool, UPB_SIZE(24, 40), value, UPB_SIZE(28, 48), 7);
 }
 UPB_INLINE void envoy_extensions_transport_sockets_tls_v3_DownstreamTlsContext_set_ocsp_staple_policy(envoy_extensions_transport_sockets_tls_v3_DownstreamTlsContext *msg, int32_t value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(0, 0), int32_t) = value;
+  *UPB_PTR_AT(msg, UPB_SIZE(4, 4), int32_t) = value;
 }
 
 /* envoy.extensions.transport_sockets.tls.v3.CommonTlsContext */
@@ -242,6 +261,12 @@ UPB_INLINE envoy_extensions_transport_sockets_tls_v3_CommonTlsContext *envoy_ext
   envoy_extensions_transport_sockets_tls_v3_CommonTlsContext *ret = envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_new(arena);
   return (ret && upb_decode(buf, size, ret, &envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE envoy_extensions_transport_sockets_tls_v3_CommonTlsContext *envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  envoy_extensions_transport_sockets_tls_v3_CommonTlsContext *ret = envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_serialize(const envoy_extensions_transport_sockets_tls_v3_CommonTlsContext *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_msginit, arena, len);
 }
@@ -254,34 +279,35 @@ typedef enum {
   envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_validation_context_type_validation_context_certificate_provider_instance = 12,
   envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_validation_context_type_NOT_SET = 0
 } envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_validation_context_type_oneofcases;
-UPB_INLINE envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_validation_context_type_oneofcases envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_validation_context_type_case(const envoy_extensions_transport_sockets_tls_v3_CommonTlsContext* msg) { return (envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_validation_context_type_oneofcases)*UPB_PTR_AT(msg, UPB_SIZE(32, 64), int32_t); }
-
-UPB_INLINE bool envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_has_tls_params(const envoy_extensions_transport_sockets_tls_v3_CommonTlsContext *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(0, 0)); }
-UPB_INLINE const struct envoy_extensions_transport_sockets_tls_v3_TlsParameters* envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_tls_params(const envoy_extensions_transport_sockets_tls_v3_CommonTlsContext *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(0, 0), const struct envoy_extensions_transport_sockets_tls_v3_TlsParameters*); }
-UPB_INLINE bool envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_has_tls_certificates(const envoy_extensions_transport_sockets_tls_v3_CommonTlsContext *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(16, 32)); }
-UPB_INLINE const struct envoy_extensions_transport_sockets_tls_v3_TlsCertificate* const* envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_tls_certificates(const envoy_extensions_transport_sockets_tls_v3_CommonTlsContext *msg, size_t *len) { return (const struct envoy_extensions_transport_sockets_tls_v3_TlsCertificate* const*)_upb_array_accessor(msg, UPB_SIZE(16, 32), len); }
-UPB_INLINE bool envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_has_validation_context(const envoy_extensions_transport_sockets_tls_v3_CommonTlsContext *msg) { return _upb_getoneofcase(msg, UPB_SIZE(32, 64)) == 3; }
-UPB_INLINE const struct envoy_extensions_transport_sockets_tls_v3_CertificateValidationContext* envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_validation_context(const envoy_extensions_transport_sockets_tls_v3_CommonTlsContext *msg) { return UPB_READ_ONEOF(msg, const struct envoy_extensions_transport_sockets_tls_v3_CertificateValidationContext*, UPB_SIZE(28, 56), UPB_SIZE(32, 64), 3, NULL); }
-UPB_INLINE upb_strview const* envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_alpn_protocols(const envoy_extensions_transport_sockets_tls_v3_CommonTlsContext *msg, size_t *len) { return (upb_strview const*)_upb_array_accessor(msg, UPB_SIZE(20, 40), len); }
-UPB_INLINE bool envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_has_tls_certificate_sds_secret_configs(const envoy_extensions_transport_sockets_tls_v3_CommonTlsContext *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(24, 48)); }
-UPB_INLINE const struct envoy_extensions_transport_sockets_tls_v3_SdsSecretConfig* const* envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_tls_certificate_sds_secret_configs(const envoy_extensions_transport_sockets_tls_v3_CommonTlsContext *msg, size_t *len) { return (const struct envoy_extensions_transport_sockets_tls_v3_SdsSecretConfig* const*)_upb_array_accessor(msg, UPB_SIZE(24, 48), len); }
-UPB_INLINE bool envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_has_validation_context_sds_secret_config(const envoy_extensions_transport_sockets_tls_v3_CommonTlsContext *msg) { return _upb_getoneofcase(msg, UPB_SIZE(32, 64)) == 7; }
-UPB_INLINE const struct envoy_extensions_transport_sockets_tls_v3_SdsSecretConfig* envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_validation_context_sds_secret_config(const envoy_extensions_transport_sockets_tls_v3_CommonTlsContext *msg) { return UPB_READ_ONEOF(msg, const struct envoy_extensions_transport_sockets_tls_v3_SdsSecretConfig*, UPB_SIZE(28, 56), UPB_SIZE(32, 64), 7, NULL); }
-UPB_INLINE bool envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_has_combined_validation_context(const envoy_extensions_transport_sockets_tls_v3_CommonTlsContext *msg) { return _upb_getoneofcase(msg, UPB_SIZE(32, 64)) == 8; }
-UPB_INLINE const envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_CombinedCertificateValidationContext* envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_combined_validation_context(const envoy_extensions_transport_sockets_tls_v3_CommonTlsContext *msg) { return UPB_READ_ONEOF(msg, const envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_CombinedCertificateValidationContext*, UPB_SIZE(28, 56), UPB_SIZE(32, 64), 8, NULL); }
-UPB_INLINE bool envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_has_tls_certificate_certificate_provider(const envoy_extensions_transport_sockets_tls_v3_CommonTlsContext *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(4, 8)); }
-UPB_INLINE const envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_CertificateProvider* envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_tls_certificate_certificate_provider(const envoy_extensions_transport_sockets_tls_v3_CommonTlsContext *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(4, 8), const envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_CertificateProvider*); }
-UPB_INLINE bool envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_has_validation_context_certificate_provider(const envoy_extensions_transport_sockets_tls_v3_CommonTlsContext *msg) { return _upb_getoneofcase(msg, UPB_SIZE(32, 64)) == 10; }
-UPB_INLINE const envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_CertificateProvider* envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_validation_context_certificate_provider(const envoy_extensions_transport_sockets_tls_v3_CommonTlsContext *msg) { return UPB_READ_ONEOF(msg, const envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_CertificateProvider*, UPB_SIZE(28, 56), UPB_SIZE(32, 64), 10, NULL); }
-UPB_INLINE bool envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_has_tls_certificate_certificate_provider_instance(const envoy_extensions_transport_sockets_tls_v3_CommonTlsContext *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(8, 16)); }
-UPB_INLINE const envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_CertificateProviderInstance* envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_tls_certificate_certificate_provider_instance(const envoy_extensions_transport_sockets_tls_v3_CommonTlsContext *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(8, 16), const envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_CertificateProviderInstance*); }
-UPB_INLINE bool envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_has_validation_context_certificate_provider_instance(const envoy_extensions_transport_sockets_tls_v3_CommonTlsContext *msg) { return _upb_getoneofcase(msg, UPB_SIZE(32, 64)) == 12; }
-UPB_INLINE const envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_CertificateProviderInstance* envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_validation_context_certificate_provider_instance(const envoy_extensions_transport_sockets_tls_v3_CommonTlsContext *msg) { return UPB_READ_ONEOF(msg, const envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_CertificateProviderInstance*, UPB_SIZE(28, 56), UPB_SIZE(32, 64), 12, NULL); }
-UPB_INLINE bool envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_has_custom_handshaker(const envoy_extensions_transport_sockets_tls_v3_CommonTlsContext *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(12, 24)); }
-UPB_INLINE const struct envoy_config_core_v3_TypedExtensionConfig* envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_custom_handshaker(const envoy_extensions_transport_sockets_tls_v3_CommonTlsContext *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(12, 24), const struct envoy_config_core_v3_TypedExtensionConfig*); }
+UPB_INLINE envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_validation_context_type_oneofcases envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_validation_context_type_case(const envoy_extensions_transport_sockets_tls_v3_CommonTlsContext* msg) { return (envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_validation_context_type_oneofcases)*UPB_PTR_AT(msg, UPB_SIZE(36, 72), int32_t); }
+
+UPB_INLINE bool envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_has_tls_params(const envoy_extensions_transport_sockets_tls_v3_CommonTlsContext *msg) { return _upb_hasbit(msg, 1); }
+UPB_INLINE const struct envoy_extensions_transport_sockets_tls_v3_TlsParameters* envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_tls_params(const envoy_extensions_transport_sockets_tls_v3_CommonTlsContext *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(4, 8), const struct envoy_extensions_transport_sockets_tls_v3_TlsParameters*); }
+UPB_INLINE bool envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_has_tls_certificates(const envoy_extensions_transport_sockets_tls_v3_CommonTlsContext *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(20, 40)); }
+UPB_INLINE const struct envoy_extensions_transport_sockets_tls_v3_TlsCertificate* const* envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_tls_certificates(const envoy_extensions_transport_sockets_tls_v3_CommonTlsContext *msg, size_t *len) { return (const struct envoy_extensions_transport_sockets_tls_v3_TlsCertificate* const*)_upb_array_accessor(msg, UPB_SIZE(20, 40), len); }
+UPB_INLINE bool envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_has_validation_context(const envoy_extensions_transport_sockets_tls_v3_CommonTlsContext *msg) { return _upb_getoneofcase(msg, UPB_SIZE(36, 72)) == 3; }
+UPB_INLINE const struct envoy_extensions_transport_sockets_tls_v3_CertificateValidationContext* envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_validation_context(const envoy_extensions_transport_sockets_tls_v3_CommonTlsContext *msg) { return UPB_READ_ONEOF(msg, const struct envoy_extensions_transport_sockets_tls_v3_CertificateValidationContext*, UPB_SIZE(32, 64), UPB_SIZE(36, 72), 3, NULL); }
+UPB_INLINE upb_strview const* envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_alpn_protocols(const envoy_extensions_transport_sockets_tls_v3_CommonTlsContext *msg, size_t *len) { return (upb_strview const*)_upb_array_accessor(msg, UPB_SIZE(24, 48), len); }
+UPB_INLINE bool envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_has_tls_certificate_sds_secret_configs(const envoy_extensions_transport_sockets_tls_v3_CommonTlsContext *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(28, 56)); }
+UPB_INLINE const struct envoy_extensions_transport_sockets_tls_v3_SdsSecretConfig* const* envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_tls_certificate_sds_secret_configs(const envoy_extensions_transport_sockets_tls_v3_CommonTlsContext *msg, size_t *len) { return (const struct envoy_extensions_transport_sockets_tls_v3_SdsSecretConfig* const*)_upb_array_accessor(msg, UPB_SIZE(28, 56), len); }
+UPB_INLINE bool envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_has_validation_context_sds_secret_config(const envoy_extensions_transport_sockets_tls_v3_CommonTlsContext *msg) { return _upb_getoneofcase(msg, UPB_SIZE(36, 72)) == 7; }
+UPB_INLINE const struct envoy_extensions_transport_sockets_tls_v3_SdsSecretConfig* envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_validation_context_sds_secret_config(const envoy_extensions_transport_sockets_tls_v3_CommonTlsContext *msg) { return UPB_READ_ONEOF(msg, const struct envoy_extensions_transport_sockets_tls_v3_SdsSecretConfig*, UPB_SIZE(32, 64), UPB_SIZE(36, 72), 7, NULL); }
+UPB_INLINE bool envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_has_combined_validation_context(const envoy_extensions_transport_sockets_tls_v3_CommonTlsContext *msg) { return _upb_getoneofcase(msg, UPB_SIZE(36, 72)) == 8; }
+UPB_INLINE const envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_CombinedCertificateValidationContext* envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_combined_validation_context(const envoy_extensions_transport_sockets_tls_v3_CommonTlsContext *msg) { return UPB_READ_ONEOF(msg, const envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_CombinedCertificateValidationContext*, UPB_SIZE(32, 64), UPB_SIZE(36, 72), 8, NULL); }
+UPB_INLINE bool envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_has_tls_certificate_certificate_provider(const envoy_extensions_transport_sockets_tls_v3_CommonTlsContext *msg) { return _upb_hasbit(msg, 2); }
+UPB_INLINE const envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_CertificateProvider* envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_tls_certificate_certificate_provider(const envoy_extensions_transport_sockets_tls_v3_CommonTlsContext *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(8, 16), const envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_CertificateProvider*); }
+UPB_INLINE bool envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_has_validation_context_certificate_provider(const envoy_extensions_transport_sockets_tls_v3_CommonTlsContext *msg) { return _upb_getoneofcase(msg, UPB_SIZE(36, 72)) == 10; }
+UPB_INLINE const envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_CertificateProvider* envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_validation_context_certificate_provider(const envoy_extensions_transport_sockets_tls_v3_CommonTlsContext *msg) { return UPB_READ_ONEOF(msg, const envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_CertificateProvider*, UPB_SIZE(32, 64), UPB_SIZE(36, 72), 10, NULL); }
+UPB_INLINE bool envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_has_tls_certificate_certificate_provider_instance(const envoy_extensions_transport_sockets_tls_v3_CommonTlsContext *msg) { return _upb_hasbit(msg, 3); }
+UPB_INLINE const envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_CertificateProviderInstance* envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_tls_certificate_certificate_provider_instance(const envoy_extensions_transport_sockets_tls_v3_CommonTlsContext *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(12, 24), const envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_CertificateProviderInstance*); }
+UPB_INLINE bool envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_has_validation_context_certificate_provider_instance(const envoy_extensions_transport_sockets_tls_v3_CommonTlsContext *msg) { return _upb_getoneofcase(msg, UPB_SIZE(36, 72)) == 12; }
+UPB_INLINE const envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_CertificateProviderInstance* envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_validation_context_certificate_provider_instance(const envoy_extensions_transport_sockets_tls_v3_CommonTlsContext *msg) { return UPB_READ_ONEOF(msg, const envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_CertificateProviderInstance*, UPB_SIZE(32, 64), UPB_SIZE(36, 72), 12, NULL); }
+UPB_INLINE bool envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_has_custom_handshaker(const envoy_extensions_transport_sockets_tls_v3_CommonTlsContext *msg) { return _upb_hasbit(msg, 4); }
+UPB_INLINE const struct envoy_config_core_v3_TypedExtensionConfig* envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_custom_handshaker(const envoy_extensions_transport_sockets_tls_v3_CommonTlsContext *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(16, 32), const struct envoy_config_core_v3_TypedExtensionConfig*); }
 
 UPB_INLINE void envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_set_tls_params(envoy_extensions_transport_sockets_tls_v3_CommonTlsContext *msg, struct envoy_extensions_transport_sockets_tls_v3_TlsParameters* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(0, 0), struct envoy_extensions_transport_sockets_tls_v3_TlsParameters*) = value;
+  _upb_sethas(msg, 1);
+  *UPB_PTR_AT(msg, UPB_SIZE(4, 8), struct envoy_extensions_transport_sockets_tls_v3_TlsParameters*) = value;
 }
 UPB_INLINE struct envoy_extensions_transport_sockets_tls_v3_TlsParameters* envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_mutable_tls_params(envoy_extensions_transport_sockets_tls_v3_CommonTlsContext *msg, upb_arena *arena) {
   struct envoy_extensions_transport_sockets_tls_v3_TlsParameters* sub = (struct envoy_extensions_transport_sockets_tls_v3_TlsParameters*)envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_tls_params(msg);
@@ -293,20 +319,20 @@ UPB_INLINE struct envoy_extensions_transport_sockets_tls_v3_TlsParameters* envoy
   return sub;
 }
 UPB_INLINE struct envoy_extensions_transport_sockets_tls_v3_TlsCertificate** envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_mutable_tls_certificates(envoy_extensions_transport_sockets_tls_v3_CommonTlsContext *msg, size_t *len) {
-  return (struct envoy_extensions_transport_sockets_tls_v3_TlsCertificate**)_upb_array_mutable_accessor(msg, UPB_SIZE(16, 32), len);
+  return (struct envoy_extensions_transport_sockets_tls_v3_TlsCertificate**)_upb_array_mutable_accessor(msg, UPB_SIZE(20, 40), len);
 }
 UPB_INLINE struct envoy_extensions_transport_sockets_tls_v3_TlsCertificate** envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_resize_tls_certificates(envoy_extensions_transport_sockets_tls_v3_CommonTlsContext *msg, size_t len, upb_arena *arena) {
-  return (struct envoy_extensions_transport_sockets_tls_v3_TlsCertificate**)_upb_array_resize_accessor(msg, UPB_SIZE(16, 32), len, UPB_TYPE_MESSAGE, arena);
+  return (struct envoy_extensions_transport_sockets_tls_v3_TlsCertificate**)_upb_array_resize_accessor2(msg, UPB_SIZE(20, 40), len, UPB_SIZE(2, 3), arena);
 }
 UPB_INLINE struct envoy_extensions_transport_sockets_tls_v3_TlsCertificate* envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_add_tls_certificates(envoy_extensions_transport_sockets_tls_v3_CommonTlsContext *msg, upb_arena *arena) {
   struct envoy_extensions_transport_sockets_tls_v3_TlsCertificate* sub = (struct envoy_extensions_transport_sockets_tls_v3_TlsCertificate*)_upb_msg_new(&envoy_extensions_transport_sockets_tls_v3_TlsCertificate_msginit, arena);
-  bool ok = _upb_array_append_accessor(
-      msg, UPB_SIZE(16, 32), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena);
+  bool ok = _upb_array_append_accessor2(
+      msg, UPB_SIZE(20, 40), UPB_SIZE(2, 3), &sub, arena);
   if (!ok) return NULL;
   return sub;
 }
 UPB_INLINE void envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_set_validation_context(envoy_extensions_transport_sockets_tls_v3_CommonTlsContext *msg, struct envoy_extensions_transport_sockets_tls_v3_CertificateValidationContext* value) {
-  UPB_WRITE_ONEOF(msg, struct envoy_extensions_transport_sockets_tls_v3_CertificateValidationContext*, UPB_SIZE(28, 56), value, UPB_SIZE(32, 64), 3);
+  UPB_WRITE_ONEOF(msg, struct envoy_extensions_transport_sockets_tls_v3_CertificateValidationContext*, UPB_SIZE(32, 64), value, UPB_SIZE(36, 72), 3);
 }
 UPB_INLINE struct envoy_extensions_transport_sockets_tls_v3_CertificateValidationContext* envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_mutable_validation_context(envoy_extensions_transport_sockets_tls_v3_CommonTlsContext *msg, upb_arena *arena) {
   struct envoy_extensions_transport_sockets_tls_v3_CertificateValidationContext* sub = (struct envoy_extensions_transport_sockets_tls_v3_CertificateValidationContext*)envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_validation_context(msg);
@@ -318,30 +344,30 @@ UPB_INLINE struct envoy_extensions_transport_sockets_tls_v3_CertificateValidatio
   return sub;
 }
 UPB_INLINE upb_strview* envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_mutable_alpn_protocols(envoy_extensions_transport_sockets_tls_v3_CommonTlsContext *msg, size_t *len) {
-  return (upb_strview*)_upb_array_mutable_accessor(msg, UPB_SIZE(20, 40), len);
+  return (upb_strview*)_upb_array_mutable_accessor(msg, UPB_SIZE(24, 48), len);
 }
 UPB_INLINE upb_strview* envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_resize_alpn_protocols(envoy_extensions_transport_sockets_tls_v3_CommonTlsContext *msg, size_t len, upb_arena *arena) {
-  return (upb_strview*)_upb_array_resize_accessor(msg, UPB_SIZE(20, 40), len, UPB_TYPE_STRING, arena);
+  return (upb_strview*)_upb_array_resize_accessor2(msg, UPB_SIZE(24, 48), len, UPB_SIZE(3, 4), arena);
 }
 UPB_INLINE bool envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_add_alpn_protocols(envoy_extensions_transport_sockets_tls_v3_CommonTlsContext *msg, upb_strview val, upb_arena *arena) {
-  return _upb_array_append_accessor(msg, UPB_SIZE(20, 40), UPB_SIZE(8, 16), UPB_TYPE_STRING, &val,
+  return _upb_array_append_accessor2(msg, UPB_SIZE(24, 48), UPB_SIZE(3, 4), &val,
       arena);
 }
 UPB_INLINE struct envoy_extensions_transport_sockets_tls_v3_SdsSecretConfig** envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_mutable_tls_certificate_sds_secret_configs(envoy_extensions_transport_sockets_tls_v3_CommonTlsContext *msg, size_t *len) {
-  return (struct envoy_extensions_transport_sockets_tls_v3_SdsSecretConfig**)_upb_array_mutable_accessor(msg, UPB_SIZE(24, 48), len);
+  return (struct envoy_extensions_transport_sockets_tls_v3_SdsSecretConfig**)_upb_array_mutable_accessor(msg, UPB_SIZE(28, 56), len);
 }
 UPB_INLINE struct envoy_extensions_transport_sockets_tls_v3_SdsSecretConfig** envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_resize_tls_certificate_sds_secret_configs(envoy_extensions_transport_sockets_tls_v3_CommonTlsContext *msg, size_t len, upb_arena *arena) {
-  return (struct envoy_extensions_transport_sockets_tls_v3_SdsSecretConfig**)_upb_array_resize_accessor(msg, UPB_SIZE(24, 48), len, UPB_TYPE_MESSAGE, arena);
+  return (struct envoy_extensions_transport_sockets_tls_v3_SdsSecretConfig**)_upb_array_resize_accessor2(msg, UPB_SIZE(28, 56), len, UPB_SIZE(2, 3), arena);
 }
 UPB_INLINE struct envoy_extensions_transport_sockets_tls_v3_SdsSecretConfig* envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_add_tls_certificate_sds_secret_configs(envoy_extensions_transport_sockets_tls_v3_CommonTlsContext *msg, upb_arena *arena) {
   struct envoy_extensions_transport_sockets_tls_v3_SdsSecretConfig* sub = (struct envoy_extensions_transport_sockets_tls_v3_SdsSecretConfig*)_upb_msg_new(&envoy_extensions_transport_sockets_tls_v3_SdsSecretConfig_msginit, arena);
-  bool ok = _upb_array_append_accessor(
-      msg, UPB_SIZE(24, 48), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena);
+  bool ok = _upb_array_append_accessor2(
+      msg, UPB_SIZE(28, 56), UPB_SIZE(2, 3), &sub, arena);
   if (!ok) return NULL;
   return sub;
 }
 UPB_INLINE void envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_set_validation_context_sds_secret_config(envoy_extensions_transport_sockets_tls_v3_CommonTlsContext *msg, struct envoy_extensions_transport_sockets_tls_v3_SdsSecretConfig* value) {
-  UPB_WRITE_ONEOF(msg, struct envoy_extensions_transport_sockets_tls_v3_SdsSecretConfig*, UPB_SIZE(28, 56), value, UPB_SIZE(32, 64), 7);
+  UPB_WRITE_ONEOF(msg, struct envoy_extensions_transport_sockets_tls_v3_SdsSecretConfig*, UPB_SIZE(32, 64), value, UPB_SIZE(36, 72), 7);
 }
 UPB_INLINE struct envoy_extensions_transport_sockets_tls_v3_SdsSecretConfig* envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_mutable_validation_context_sds_secret_config(envoy_extensions_transport_sockets_tls_v3_CommonTlsContext *msg, upb_arena *arena) {
   struct envoy_extensions_transport_sockets_tls_v3_SdsSecretConfig* sub = (struct envoy_extensions_transport_sockets_tls_v3_SdsSecretConfig*)envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_validation_context_sds_secret_config(msg);
@@ -353,7 +379,7 @@ UPB_INLINE struct envoy_extensions_transport_sockets_tls_v3_SdsSecretConfig* env
   return sub;
 }
 UPB_INLINE void envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_set_combined_validation_context(envoy_extensions_transport_sockets_tls_v3_CommonTlsContext *msg, envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_CombinedCertificateValidationContext* value) {
-  UPB_WRITE_ONEOF(msg, envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_CombinedCertificateValidationContext*, UPB_SIZE(28, 56), value, UPB_SIZE(32, 64), 8);
+  UPB_WRITE_ONEOF(msg, envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_CombinedCertificateValidationContext*, UPB_SIZE(32, 64), value, UPB_SIZE(36, 72), 8);
 }
 UPB_INLINE struct envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_CombinedCertificateValidationContext* envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_mutable_combined_validation_context(envoy_extensions_transport_sockets_tls_v3_CommonTlsContext *msg, upb_arena *arena) {
   struct envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_CombinedCertificateValidationContext* sub = (struct envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_CombinedCertificateValidationContext*)envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_combined_validation_context(msg);
@@ -365,7 +391,8 @@ UPB_INLINE struct envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_Com
   return sub;
 }
 UPB_INLINE void envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_set_tls_certificate_certificate_provider(envoy_extensions_transport_sockets_tls_v3_CommonTlsContext *msg, envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_CertificateProvider* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(4, 8), envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_CertificateProvider*) = value;
+  _upb_sethas(msg, 2);
+  *UPB_PTR_AT(msg, UPB_SIZE(8, 16), envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_CertificateProvider*) = value;
 }
 UPB_INLINE struct envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_CertificateProvider* envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_mutable_tls_certificate_certificate_provider(envoy_extensions_transport_sockets_tls_v3_CommonTlsContext *msg, upb_arena *arena) {
   struct envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_CertificateProvider* sub = (struct envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_CertificateProvider*)envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_tls_certificate_certificate_provider(msg);
@@ -377,7 +404,7 @@ UPB_INLINE struct envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_Cer
   return sub;
 }
 UPB_INLINE void envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_set_validation_context_certificate_provider(envoy_extensions_transport_sockets_tls_v3_CommonTlsContext *msg, envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_CertificateProvider* value) {
-  UPB_WRITE_ONEOF(msg, envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_CertificateProvider*, UPB_SIZE(28, 56), value, UPB_SIZE(32, 64), 10);
+  UPB_WRITE_ONEOF(msg, envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_CertificateProvider*, UPB_SIZE(32, 64), value, UPB_SIZE(36, 72), 10);
 }
 UPB_INLINE struct envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_CertificateProvider* envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_mutable_validation_context_certificate_provider(envoy_extensions_transport_sockets_tls_v3_CommonTlsContext *msg, upb_arena *arena) {
   struct envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_CertificateProvider* sub = (struct envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_CertificateProvider*)envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_validation_context_certificate_provider(msg);
@@ -389,7 +416,8 @@ UPB_INLINE struct envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_Cer
   return sub;
 }
 UPB_INLINE void envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_set_tls_certificate_certificate_provider_instance(envoy_extensions_transport_sockets_tls_v3_CommonTlsContext *msg, envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_CertificateProviderInstance* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(8, 16), envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_CertificateProviderInstance*) = value;
+  _upb_sethas(msg, 3);
+  *UPB_PTR_AT(msg, UPB_SIZE(12, 24), envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_CertificateProviderInstance*) = value;
 }
 UPB_INLINE struct envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_CertificateProviderInstance* envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_mutable_tls_certificate_certificate_provider_instance(envoy_extensions_transport_sockets_tls_v3_CommonTlsContext *msg, upb_arena *arena) {
   struct envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_CertificateProviderInstance* sub = (struct envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_CertificateProviderInstance*)envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_tls_certificate_certificate_provider_instance(msg);
@@ -401,7 +429,7 @@ UPB_INLINE struct envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_Cer
   return sub;
 }
 UPB_INLINE void envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_set_validation_context_certificate_provider_instance(envoy_extensions_transport_sockets_tls_v3_CommonTlsContext *msg, envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_CertificateProviderInstance* value) {
-  UPB_WRITE_ONEOF(msg, envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_CertificateProviderInstance*, UPB_SIZE(28, 56), value, UPB_SIZE(32, 64), 12);
+  UPB_WRITE_ONEOF(msg, envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_CertificateProviderInstance*, UPB_SIZE(32, 64), value, UPB_SIZE(36, 72), 12);
 }
 UPB_INLINE struct envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_CertificateProviderInstance* envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_mutable_validation_context_certificate_provider_instance(envoy_extensions_transport_sockets_tls_v3_CommonTlsContext *msg, upb_arena *arena) {
   struct envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_CertificateProviderInstance* sub = (struct envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_CertificateProviderInstance*)envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_validation_context_certificate_provider_instance(msg);
@@ -413,7 +441,8 @@ UPB_INLINE struct envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_Cer
   return sub;
 }
 UPB_INLINE void envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_set_custom_handshaker(envoy_extensions_transport_sockets_tls_v3_CommonTlsContext *msg, struct envoy_config_core_v3_TypedExtensionConfig* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(12, 24), struct envoy_config_core_v3_TypedExtensionConfig*) = value;
+  _upb_sethas(msg, 4);
+  *UPB_PTR_AT(msg, UPB_SIZE(16, 32), struct envoy_config_core_v3_TypedExtensionConfig*) = value;
 }
 UPB_INLINE struct envoy_config_core_v3_TypedExtensionConfig* envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_mutable_custom_handshaker(envoy_extensions_transport_sockets_tls_v3_CommonTlsContext *msg, upb_arena *arena) {
   struct envoy_config_core_v3_TypedExtensionConfig* sub = (struct envoy_config_core_v3_TypedExtensionConfig*)envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_custom_handshaker(msg);
@@ -435,6 +464,12 @@ UPB_INLINE envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_Certificat
   envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_CertificateProvider *ret = envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_CertificateProvider_new(arena);
   return (ret && upb_decode(buf, size, ret, &envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_CertificateProvider_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_CertificateProvider *envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_CertificateProvider_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_CertificateProvider *ret = envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_CertificateProvider_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_CertificateProvider_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_CertificateProvider_serialize(const envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_CertificateProvider *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_CertificateProvider_msginit, arena, len);
 }
@@ -475,6 +510,12 @@ UPB_INLINE envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_Certificat
   envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_CertificateProviderInstance *ret = envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_CertificateProviderInstance_new(arena);
   return (ret && upb_decode(buf, size, ret, &envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_CertificateProviderInstance_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_CertificateProviderInstance *envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_CertificateProviderInstance_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_CertificateProviderInstance *ret = envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_CertificateProviderInstance_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_CertificateProviderInstance_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_CertificateProviderInstance_serialize(const envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_CertificateProviderInstance *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_CertificateProviderInstance_msginit, arena, len);
 }
@@ -499,21 +540,28 @@ UPB_INLINE envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_CombinedCe
   envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_CombinedCertificateValidationContext *ret = envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_CombinedCertificateValidationContext_new(arena);
   return (ret && upb_decode(buf, size, ret, &envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_CombinedCertificateValidationContext_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_CombinedCertificateValidationContext *envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_CombinedCertificateValidationContext_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_CombinedCertificateValidationContext *ret = envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_CombinedCertificateValidationContext_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_CombinedCertificateValidationContext_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_CombinedCertificateValidationContext_serialize(const envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_CombinedCertificateValidationContext *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_CombinedCertificateValidationContext_msginit, arena, len);
 }
 
-UPB_INLINE bool envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_CombinedCertificateValidationContext_has_default_validation_context(const envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_CombinedCertificateValidationContext *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(0, 0)); }
-UPB_INLINE const struct envoy_extensions_transport_sockets_tls_v3_CertificateValidationContext* envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_CombinedCertificateValidationContext_default_validation_context(const envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_CombinedCertificateValidationContext *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(0, 0), const struct envoy_extensions_transport_sockets_tls_v3_CertificateValidationContext*); }
-UPB_INLINE bool envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_CombinedCertificateValidationContext_has_validation_context_sds_secret_config(const envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_CombinedCertificateValidationContext *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(4, 8)); }
-UPB_INLINE const struct envoy_extensions_transport_sockets_tls_v3_SdsSecretConfig* envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_CombinedCertificateValidationContext_validation_context_sds_secret_config(const envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_CombinedCertificateValidationContext *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(4, 8), const struct envoy_extensions_transport_sockets_tls_v3_SdsSecretConfig*); }
-UPB_INLINE bool envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_CombinedCertificateValidationContext_has_validation_context_certificate_provider(const envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_CombinedCertificateValidationContext *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(8, 16)); }
-UPB_INLINE const envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_CertificateProvider* envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_CombinedCertificateValidationContext_validation_context_certificate_provider(const envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_CombinedCertificateValidationContext *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(8, 16), const envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_CertificateProvider*); }
-UPB_INLINE bool envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_CombinedCertificateValidationContext_has_validation_context_certificate_provider_instance(const envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_CombinedCertificateValidationContext *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(12, 24)); }
-UPB_INLINE const envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_CertificateProviderInstance* envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_CombinedCertificateValidationContext_validation_context_certificate_provider_instance(const envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_CombinedCertificateValidationContext *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(12, 24), const envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_CertificateProviderInstance*); }
+UPB_INLINE bool envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_CombinedCertificateValidationContext_has_default_validation_context(const envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_CombinedCertificateValidationContext *msg) { return _upb_hasbit(msg, 1); }
+UPB_INLINE const struct envoy_extensions_transport_sockets_tls_v3_CertificateValidationContext* envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_CombinedCertificateValidationContext_default_validation_context(const envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_CombinedCertificateValidationContext *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(4, 8), const struct envoy_extensions_transport_sockets_tls_v3_CertificateValidationContext*); }
+UPB_INLINE bool envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_CombinedCertificateValidationContext_has_validation_context_sds_secret_config(const envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_CombinedCertificateValidationContext *msg) { return _upb_hasbit(msg, 2); }
+UPB_INLINE const struct envoy_extensions_transport_sockets_tls_v3_SdsSecretConfig* envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_CombinedCertificateValidationContext_validation_context_sds_secret_config(const envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_CombinedCertificateValidationContext *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(8, 16), const struct envoy_extensions_transport_sockets_tls_v3_SdsSecretConfig*); }
+UPB_INLINE bool envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_CombinedCertificateValidationContext_has_validation_context_certificate_provider(const envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_CombinedCertificateValidationContext *msg) { return _upb_hasbit(msg, 3); }
+UPB_INLINE const envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_CertificateProvider* envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_CombinedCertificateValidationContext_validation_context_certificate_provider(const envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_CombinedCertificateValidationContext *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(12, 24), const envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_CertificateProvider*); }
+UPB_INLINE bool envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_CombinedCertificateValidationContext_has_validation_context_certificate_provider_instance(const envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_CombinedCertificateValidationContext *msg) { return _upb_hasbit(msg, 4); }
+UPB_INLINE const envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_CertificateProviderInstance* envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_CombinedCertificateValidationContext_validation_context_certificate_provider_instance(const envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_CombinedCertificateValidationContext *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(16, 32), const envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_CertificateProviderInstance*); }
 
 UPB_INLINE void envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_CombinedCertificateValidationContext_set_default_validation_context(envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_CombinedCertificateValidationContext *msg, struct envoy_extensions_transport_sockets_tls_v3_CertificateValidationContext* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(0, 0), struct envoy_extensions_transport_sockets_tls_v3_CertificateValidationContext*) = value;
+  _upb_sethas(msg, 1);
+  *UPB_PTR_AT(msg, UPB_SIZE(4, 8), struct envoy_extensions_transport_sockets_tls_v3_CertificateValidationContext*) = value;
 }
 UPB_INLINE struct envoy_extensions_transport_sockets_tls_v3_CertificateValidationContext* envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_CombinedCertificateValidationContext_mutable_default_validation_context(envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_CombinedCertificateValidationContext *msg, upb_arena *arena) {
   struct envoy_extensions_transport_sockets_tls_v3_CertificateValidationContext* sub = (struct envoy_extensions_transport_sockets_tls_v3_CertificateValidationContext*)envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_CombinedCertificateValidationContext_default_validation_context(msg);
@@ -525,7 +573,8 @@ UPB_INLINE struct envoy_extensions_transport_sockets_tls_v3_CertificateValidatio
   return sub;
 }
 UPB_INLINE void envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_CombinedCertificateValidationContext_set_validation_context_sds_secret_config(envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_CombinedCertificateValidationContext *msg, struct envoy_extensions_transport_sockets_tls_v3_SdsSecretConfig* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(4, 8), struct envoy_extensions_transport_sockets_tls_v3_SdsSecretConfig*) = value;
+  _upb_sethas(msg, 2);
+  *UPB_PTR_AT(msg, UPB_SIZE(8, 16), struct envoy_extensions_transport_sockets_tls_v3_SdsSecretConfig*) = value;
 }
 UPB_INLINE struct envoy_extensions_transport_sockets_tls_v3_SdsSecretConfig* envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_CombinedCertificateValidationContext_mutable_validation_context_sds_secret_config(envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_CombinedCertificateValidationContext *msg, upb_arena *arena) {
   struct envoy_extensions_transport_sockets_tls_v3_SdsSecretConfig* sub = (struct envoy_extensions_transport_sockets_tls_v3_SdsSecretConfig*)envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_CombinedCertificateValidationContext_validation_context_sds_secret_config(msg);
@@ -537,7 +586,8 @@ UPB_INLINE struct envoy_extensions_transport_sockets_tls_v3_SdsSecretConfig* env
   return sub;
 }
 UPB_INLINE void envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_CombinedCertificateValidationContext_set_validation_context_certificate_provider(envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_CombinedCertificateValidationContext *msg, envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_CertificateProvider* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(8, 16), envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_CertificateProvider*) = value;
+  _upb_sethas(msg, 3);
+  *UPB_PTR_AT(msg, UPB_SIZE(12, 24), envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_CertificateProvider*) = value;
 }
 UPB_INLINE struct envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_CertificateProvider* envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_CombinedCertificateValidationContext_mutable_validation_context_certificate_provider(envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_CombinedCertificateValidationContext *msg, upb_arena *arena) {
   struct envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_CertificateProvider* sub = (struct envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_CertificateProvider*)envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_CombinedCertificateValidationContext_validation_context_certificate_provider(msg);
@@ -549,7 +599,8 @@ UPB_INLINE struct envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_Cer
   return sub;
 }
 UPB_INLINE void envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_CombinedCertificateValidationContext_set_validation_context_certificate_provider_instance(envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_CombinedCertificateValidationContext *msg, envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_CertificateProviderInstance* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(12, 24), envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_CertificateProviderInstance*) = value;
+  _upb_sethas(msg, 4);
+  *UPB_PTR_AT(msg, UPB_SIZE(16, 32), envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_CertificateProviderInstance*) = value;
 }
 UPB_INLINE struct envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_CertificateProviderInstance* envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_CombinedCertificateValidationContext_mutable_validation_context_certificate_provider_instance(envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_CombinedCertificateValidationContext *msg, upb_arena *arena) {
   struct envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_CertificateProviderInstance* sub = (struct envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_CertificateProviderInstance*)envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_CombinedCertificateValidationContext_validation_context_certificate_provider_instance(msg);
index c8660db..cc8dcc4 100644 (file)
@@ -20,7 +20,7 @@
 const upb_msglayout envoy_service_cluster_v3_CdsDummy_msginit = {
   NULL,
   NULL,
-  UPB_SIZE(0, 0), 0, false,
+  UPB_SIZE(0, 0), 0, false, 255,
 };
 
 #include "upb/port_undef.inc"
index 11d8572..86fa302 100644 (file)
@@ -11,6 +11,7 @@
 
 #include "upb/msg.h"
 #include "upb/decode.h"
+#include "upb/decode_fast.h"
 #include "upb/encode.h"
 
 #include "upb/port_def.inc"
@@ -34,6 +35,12 @@ UPB_INLINE envoy_service_cluster_v3_CdsDummy *envoy_service_cluster_v3_CdsDummy_
   envoy_service_cluster_v3_CdsDummy *ret = envoy_service_cluster_v3_CdsDummy_new(arena);
   return (ret && upb_decode(buf, size, ret, &envoy_service_cluster_v3_CdsDummy_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE envoy_service_cluster_v3_CdsDummy *envoy_service_cluster_v3_CdsDummy_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  envoy_service_cluster_v3_CdsDummy *ret = envoy_service_cluster_v3_CdsDummy_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &envoy_service_cluster_v3_CdsDummy_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *envoy_service_cluster_v3_CdsDummy_serialize(const envoy_service_cluster_v3_CdsDummy *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &envoy_service_cluster_v3_CdsDummy_msginit, arena, len);
 }
index 959e3cb..7fb8ac9 100644 (file)
@@ -18,7 +18,7 @@
 const upb_msglayout envoy_service_discovery_v3_AdsDummy_msginit = {
   NULL,
   NULL,
-  UPB_SIZE(0, 0), 0, false,
+  UPB_SIZE(0, 0), 0, false, 255,
 };
 
 #include "upb/port_undef.inc"
index 41dc642..0d26bd9 100644 (file)
@@ -11,6 +11,7 @@
 
 #include "upb/msg.h"
 #include "upb/decode.h"
+#include "upb/decode_fast.h"
 #include "upb/encode.h"
 
 #include "upb/port_def.inc"
@@ -34,6 +35,12 @@ UPB_INLINE envoy_service_discovery_v3_AdsDummy *envoy_service_discovery_v3_AdsDu
   envoy_service_discovery_v3_AdsDummy *ret = envoy_service_discovery_v3_AdsDummy_new(arena);
   return (ret && upb_decode(buf, size, ret, &envoy_service_discovery_v3_AdsDummy_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE envoy_service_discovery_v3_AdsDummy *envoy_service_discovery_v3_AdsDummy_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  envoy_service_discovery_v3_AdsDummy *ret = envoy_service_discovery_v3_AdsDummy_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &envoy_service_discovery_v3_AdsDummy_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *envoy_service_discovery_v3_AdsDummy_serialize(const envoy_service_discovery_v3_AdsDummy *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &envoy_service_discovery_v3_AdsDummy_msginit, arena, len);
 }
index 2c76a98..9bed2c3 100644 (file)
@@ -26,18 +26,18 @@ static const upb_msglayout *const envoy_service_discovery_v3_DiscoveryRequest_su
 };
 
 static const upb_msglayout_field envoy_service_discovery_v3_DiscoveryRequest__fields[6] = {
-  {1, UPB_SIZE(0, 0), 0, 0, 9, 1},
-  {2, UPB_SIZE(24, 48), 0, 0, 11, 1},
-  {3, UPB_SIZE(32, 64), 0, 0, 9, 3},
-  {4, UPB_SIZE(8, 16), 0, 0, 9, 1},
-  {5, UPB_SIZE(16, 32), 0, 0, 9, 1},
-  {6, UPB_SIZE(28, 56), 0, 1, 11, 1},
+  {1, UPB_SIZE(4, 8), 0, 0, 9, 1},
+  {2, UPB_SIZE(28, 56), 1, 0, 11, 1},
+  {3, UPB_SIZE(36, 72), 0, 0, 9, 3},
+  {4, UPB_SIZE(12, 24), 0, 0, 9, 1},
+  {5, UPB_SIZE(20, 40), 0, 0, 9, 1},
+  {6, UPB_SIZE(32, 64), 2, 1, 11, 1},
 };
 
 const upb_msglayout envoy_service_discovery_v3_DiscoveryRequest_msginit = {
   &envoy_service_discovery_v3_DiscoveryRequest_submsgs[0],
   &envoy_service_discovery_v3_DiscoveryRequest__fields[0],
-  UPB_SIZE(40, 80), 6, false,
+  UPB_SIZE(40, 80), 6, false, 255,
 };
 
 static const upb_msglayout *const envoy_service_discovery_v3_DiscoveryResponse_submsgs[2] = {
@@ -48,19 +48,19 @@ static const upb_msglayout *const envoy_service_discovery_v3_DiscoveryResponse_s
 static const upb_msglayout_field envoy_service_discovery_v3_DiscoveryResponse__fields[6] = {
   {1, UPB_SIZE(4, 8), 0, 0, 9, 1},
   {2, UPB_SIZE(32, 64), 0, 1, 11, 3},
-  {3, UPB_SIZE(0, 0), 0, 0, 8, 1},
+  {3, UPB_SIZE(1, 1), 0, 0, 8, 1},
   {4, UPB_SIZE(12, 24), 0, 0, 9, 1},
   {5, UPB_SIZE(20, 40), 0, 0, 9, 1},
-  {6, UPB_SIZE(28, 56), 0, 0, 11, 1},
+  {6, UPB_SIZE(28, 56), 1, 0, 11, 1},
 };
 
 const upb_msglayout envoy_service_discovery_v3_DiscoveryResponse_msginit = {
   &envoy_service_discovery_v3_DiscoveryResponse_submsgs[0],
   &envoy_service_discovery_v3_DiscoveryResponse__fields[0],
-  UPB_SIZE(40, 80), 6, false,
+  UPB_SIZE(40, 80), 6, false, 255,
 };
 
-static const upb_msglayout *const envoy_service_discovery_v3_DeltaDiscoveryRequest_submsgs[5] = {
+static const upb_msglayout *const envoy_service_discovery_v3_DeltaDiscoveryRequest_submsgs[4] = {
   &envoy_config_core_v3_Node_msginit,
   &envoy_service_discovery_v3_DeltaDiscoveryRequest_InitialResourceVersionsEntry_msginit,
   &google_rpc_Status_msginit,
@@ -68,21 +68,21 @@ static const upb_msglayout *const envoy_service_discovery_v3_DeltaDiscoveryReque
 };
 
 static const upb_msglayout_field envoy_service_discovery_v3_DeltaDiscoveryRequest__fields[9] = {
-  {1, UPB_SIZE(16, 32), 0, 0, 11, 1},
-  {2, UPB_SIZE(0, 0), 0, 0, 9, 1},
-  {3, UPB_SIZE(24, 48), 0, 0, 9, 3},
-  {4, UPB_SIZE(28, 56), 0, 0, 9, 3},
-  {5, UPB_SIZE(32, 64), 0, 1, 11, _UPB_LABEL_MAP},
-  {6, UPB_SIZE(8, 16), 0, 0, 9, 1},
-  {7, UPB_SIZE(20, 40), 0, 2, 11, 1},
-  {8, UPB_SIZE(36, 72), 0, 3, 11, 3},
-  {9, UPB_SIZE(40, 80), 0, 3, 11, 3},
+  {1, UPB_SIZE(20, 40), 1, 0, 11, 1},
+  {2, UPB_SIZE(4, 8), 0, 0, 9, 1},
+  {3, UPB_SIZE(28, 56), 0, 0, 9, 3},
+  {4, UPB_SIZE(32, 64), 0, 0, 9, 3},
+  {5, UPB_SIZE(36, 72), 0, 1, 11, _UPB_LABEL_MAP},
+  {6, UPB_SIZE(12, 24), 0, 0, 9, 1},
+  {7, UPB_SIZE(24, 48), 2, 2, 11, 1},
+  {8, UPB_SIZE(40, 80), 0, 3, 11, 3},
+  {9, UPB_SIZE(44, 88), 0, 3, 11, 3},
 };
 
 const upb_msglayout envoy_service_discovery_v3_DeltaDiscoveryRequest_msginit = {
   &envoy_service_discovery_v3_DeltaDiscoveryRequest_submsgs[0],
   &envoy_service_discovery_v3_DeltaDiscoveryRequest__fields[0],
-  UPB_SIZE(48, 96), 9, false,
+  UPB_SIZE(48, 96), 9, false, 255,
 };
 
 static const upb_msglayout_field envoy_service_discovery_v3_DeltaDiscoveryRequest_InitialResourceVersionsEntry__fields[2] = {
@@ -93,7 +93,7 @@ static const upb_msglayout_field envoy_service_discovery_v3_DeltaDiscoveryReques
 const upb_msglayout envoy_service_discovery_v3_DeltaDiscoveryRequest_InitialResourceVersionsEntry_msginit = {
   NULL,
   &envoy_service_discovery_v3_DeltaDiscoveryRequest_InitialResourceVersionsEntry__fields[0],
-  UPB_SIZE(16, 32), 2, false,
+  UPB_SIZE(16, 32), 2, false, 255,
 };
 
 static const upb_msglayout *const envoy_service_discovery_v3_DeltaDiscoveryResponse_submsgs[2] = {
@@ -113,7 +113,7 @@ static const upb_msglayout_field envoy_service_discovery_v3_DeltaDiscoveryRespon
 const upb_msglayout envoy_service_discovery_v3_DeltaDiscoveryResponse_msginit = {
   &envoy_service_discovery_v3_DeltaDiscoveryResponse_submsgs[0],
   &envoy_service_discovery_v3_DeltaDiscoveryResponse__fields[0],
-  UPB_SIZE(40, 80), 6, false,
+  UPB_SIZE(40, 80), 6, false, 255,
 };
 
 static const upb_msglayout *const envoy_service_discovery_v3_Resource_submsgs[2] = {
@@ -122,17 +122,17 @@ static const upb_msglayout *const envoy_service_discovery_v3_Resource_submsgs[2]
 };
 
 static const upb_msglayout_field envoy_service_discovery_v3_Resource__fields[5] = {
-  {1, UPB_SIZE(0, 0), 0, 0, 9, 1},
-  {2, UPB_SIZE(16, 32), 0, 0, 11, 1},
-  {3, UPB_SIZE(8, 16), 0, 0, 9, 1},
-  {4, UPB_SIZE(24, 48), 0, 0, 9, 3},
-  {5, UPB_SIZE(20, 40), 0, 1, 11, 1},
+  {1, UPB_SIZE(4, 8), 0, 0, 9, 1},
+  {2, UPB_SIZE(20, 40), 1, 0, 11, 1},
+  {3, UPB_SIZE(12, 24), 0, 0, 9, 1},
+  {4, UPB_SIZE(28, 56), 0, 0, 9, 3},
+  {5, UPB_SIZE(24, 48), 2, 1, 11, 1},
 };
 
 const upb_msglayout envoy_service_discovery_v3_Resource_msginit = {
   &envoy_service_discovery_v3_Resource_submsgs[0],
   &envoy_service_discovery_v3_Resource__fields[0],
-  UPB_SIZE(32, 64), 5, false,
+  UPB_SIZE(32, 64), 5, false, 255,
 };
 
 #include "upb/port_undef.inc"
index 87af22d..715319b 100644 (file)
@@ -11,6 +11,7 @@
 
 #include "upb/msg.h"
 #include "upb/decode.h"
+#include "upb/decode_fast.h"
 #include "upb/encode.h"
 
 #include "upb/port_def.inc"
@@ -61,24 +62,31 @@ UPB_INLINE envoy_service_discovery_v3_DiscoveryRequest *envoy_service_discovery_
   envoy_service_discovery_v3_DiscoveryRequest *ret = envoy_service_discovery_v3_DiscoveryRequest_new(arena);
   return (ret && upb_decode(buf, size, ret, &envoy_service_discovery_v3_DiscoveryRequest_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE envoy_service_discovery_v3_DiscoveryRequest *envoy_service_discovery_v3_DiscoveryRequest_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  envoy_service_discovery_v3_DiscoveryRequest *ret = envoy_service_discovery_v3_DiscoveryRequest_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &envoy_service_discovery_v3_DiscoveryRequest_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *envoy_service_discovery_v3_DiscoveryRequest_serialize(const envoy_service_discovery_v3_DiscoveryRequest *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &envoy_service_discovery_v3_DiscoveryRequest_msginit, arena, len);
 }
 
-UPB_INLINE upb_strview envoy_service_discovery_v3_DiscoveryRequest_version_info(const envoy_service_discovery_v3_DiscoveryRequest *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(0, 0), upb_strview); }
-UPB_INLINE bool envoy_service_discovery_v3_DiscoveryRequest_has_node(const envoy_service_discovery_v3_DiscoveryRequest *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(24, 48)); }
-UPB_INLINE const struct envoy_config_core_v3_Node* envoy_service_discovery_v3_DiscoveryRequest_node(const envoy_service_discovery_v3_DiscoveryRequest *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(24, 48), const struct envoy_config_core_v3_Node*); }
-UPB_INLINE upb_strview const* envoy_service_discovery_v3_DiscoveryRequest_resource_names(const envoy_service_discovery_v3_DiscoveryRequest *msg, size_t *len) { return (upb_strview const*)_upb_array_accessor(msg, UPB_SIZE(32, 64), len); }
-UPB_INLINE upb_strview envoy_service_discovery_v3_DiscoveryRequest_type_url(const envoy_service_discovery_v3_DiscoveryRequest *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(8, 16), upb_strview); }
-UPB_INLINE upb_strview envoy_service_discovery_v3_DiscoveryRequest_response_nonce(const envoy_service_discovery_v3_DiscoveryRequest *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(16, 32), upb_strview); }
-UPB_INLINE bool envoy_service_discovery_v3_DiscoveryRequest_has_error_detail(const envoy_service_discovery_v3_DiscoveryRequest *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(28, 56)); }
-UPB_INLINE const struct google_rpc_Status* envoy_service_discovery_v3_DiscoveryRequest_error_detail(const envoy_service_discovery_v3_DiscoveryRequest *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(28, 56), const struct google_rpc_Status*); }
+UPB_INLINE upb_strview envoy_service_discovery_v3_DiscoveryRequest_version_info(const envoy_service_discovery_v3_DiscoveryRequest *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(4, 8), upb_strview); }
+UPB_INLINE bool envoy_service_discovery_v3_DiscoveryRequest_has_node(const envoy_service_discovery_v3_DiscoveryRequest *msg) { return _upb_hasbit(msg, 1); }
+UPB_INLINE const struct envoy_config_core_v3_Node* envoy_service_discovery_v3_DiscoveryRequest_node(const envoy_service_discovery_v3_DiscoveryRequest *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(28, 56), const struct envoy_config_core_v3_Node*); }
+UPB_INLINE upb_strview const* envoy_service_discovery_v3_DiscoveryRequest_resource_names(const envoy_service_discovery_v3_DiscoveryRequest *msg, size_t *len) { return (upb_strview const*)_upb_array_accessor(msg, UPB_SIZE(36, 72), len); }
+UPB_INLINE upb_strview envoy_service_discovery_v3_DiscoveryRequest_type_url(const envoy_service_discovery_v3_DiscoveryRequest *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(12, 24), upb_strview); }
+UPB_INLINE upb_strview envoy_service_discovery_v3_DiscoveryRequest_response_nonce(const envoy_service_discovery_v3_DiscoveryRequest *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(20, 40), upb_strview); }
+UPB_INLINE bool envoy_service_discovery_v3_DiscoveryRequest_has_error_detail(const envoy_service_discovery_v3_DiscoveryRequest *msg) { return _upb_hasbit(msg, 2); }
+UPB_INLINE const struct google_rpc_Status* envoy_service_discovery_v3_DiscoveryRequest_error_detail(const envoy_service_discovery_v3_DiscoveryRequest *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(32, 64), const struct google_rpc_Status*); }
 
 UPB_INLINE void envoy_service_discovery_v3_DiscoveryRequest_set_version_info(envoy_service_discovery_v3_DiscoveryRequest *msg, upb_strview value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(0, 0), upb_strview) = value;
+  *UPB_PTR_AT(msg, UPB_SIZE(4, 8), upb_strview) = value;
 }
 UPB_INLINE void envoy_service_discovery_v3_DiscoveryRequest_set_node(envoy_service_discovery_v3_DiscoveryRequest *msg, struct envoy_config_core_v3_Node* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(24, 48), struct envoy_config_core_v3_Node*) = value;
+  _upb_sethas(msg, 1);
+  *UPB_PTR_AT(msg, UPB_SIZE(28, 56), struct envoy_config_core_v3_Node*) = value;
 }
 UPB_INLINE struct envoy_config_core_v3_Node* envoy_service_discovery_v3_DiscoveryRequest_mutable_node(envoy_service_discovery_v3_DiscoveryRequest *msg, upb_arena *arena) {
   struct envoy_config_core_v3_Node* sub = (struct envoy_config_core_v3_Node*)envoy_service_discovery_v3_DiscoveryRequest_node(msg);
@@ -90,23 +98,24 @@ UPB_INLINE struct envoy_config_core_v3_Node* envoy_service_discovery_v3_Discover
   return sub;
 }
 UPB_INLINE upb_strview* envoy_service_discovery_v3_DiscoveryRequest_mutable_resource_names(envoy_service_discovery_v3_DiscoveryRequest *msg, size_t *len) {
-  return (upb_strview*)_upb_array_mutable_accessor(msg, UPB_SIZE(32, 64), len);
+  return (upb_strview*)_upb_array_mutable_accessor(msg, UPB_SIZE(36, 72), len);
 }
 UPB_INLINE upb_strview* envoy_service_discovery_v3_DiscoveryRequest_resize_resource_names(envoy_service_discovery_v3_DiscoveryRequest *msg, size_t len, upb_arena *arena) {
-  return (upb_strview*)_upb_array_resize_accessor(msg, UPB_SIZE(32, 64), len, UPB_TYPE_STRING, arena);
+  return (upb_strview*)_upb_array_resize_accessor2(msg, UPB_SIZE(36, 72), len, UPB_SIZE(3, 4), arena);
 }
 UPB_INLINE bool envoy_service_discovery_v3_DiscoveryRequest_add_resource_names(envoy_service_discovery_v3_DiscoveryRequest *msg, upb_strview val, upb_arena *arena) {
-  return _upb_array_append_accessor(msg, UPB_SIZE(32, 64), UPB_SIZE(8, 16), UPB_TYPE_STRING, &val,
+  return _upb_array_append_accessor2(msg, UPB_SIZE(36, 72), UPB_SIZE(3, 4), &val,
       arena);
 }
 UPB_INLINE void envoy_service_discovery_v3_DiscoveryRequest_set_type_url(envoy_service_discovery_v3_DiscoveryRequest *msg, upb_strview value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(8, 16), upb_strview) = value;
+  *UPB_PTR_AT(msg, UPB_SIZE(12, 24), upb_strview) = value;
 }
 UPB_INLINE void envoy_service_discovery_v3_DiscoveryRequest_set_response_nonce(envoy_service_discovery_v3_DiscoveryRequest *msg, upb_strview value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(16, 32), upb_strview) = value;
+  *UPB_PTR_AT(msg, UPB_SIZE(20, 40), upb_strview) = value;
 }
 UPB_INLINE void envoy_service_discovery_v3_DiscoveryRequest_set_error_detail(envoy_service_discovery_v3_DiscoveryRequest *msg, struct google_rpc_Status* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(28, 56), struct google_rpc_Status*) = value;
+  _upb_sethas(msg, 2);
+  *UPB_PTR_AT(msg, UPB_SIZE(32, 64), struct google_rpc_Status*) = value;
 }
 UPB_INLINE struct google_rpc_Status* envoy_service_discovery_v3_DiscoveryRequest_mutable_error_detail(envoy_service_discovery_v3_DiscoveryRequest *msg, upb_arena *arena) {
   struct google_rpc_Status* sub = (struct google_rpc_Status*)envoy_service_discovery_v3_DiscoveryRequest_error_detail(msg);
@@ -128,6 +137,12 @@ UPB_INLINE envoy_service_discovery_v3_DiscoveryResponse *envoy_service_discovery
   envoy_service_discovery_v3_DiscoveryResponse *ret = envoy_service_discovery_v3_DiscoveryResponse_new(arena);
   return (ret && upb_decode(buf, size, ret, &envoy_service_discovery_v3_DiscoveryResponse_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE envoy_service_discovery_v3_DiscoveryResponse *envoy_service_discovery_v3_DiscoveryResponse_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  envoy_service_discovery_v3_DiscoveryResponse *ret = envoy_service_discovery_v3_DiscoveryResponse_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &envoy_service_discovery_v3_DiscoveryResponse_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *envoy_service_discovery_v3_DiscoveryResponse_serialize(const envoy_service_discovery_v3_DiscoveryResponse *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &envoy_service_discovery_v3_DiscoveryResponse_msginit, arena, len);
 }
@@ -135,10 +150,10 @@ UPB_INLINE char *envoy_service_discovery_v3_DiscoveryResponse_serialize(const en
 UPB_INLINE upb_strview envoy_service_discovery_v3_DiscoveryResponse_version_info(const envoy_service_discovery_v3_DiscoveryResponse *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(4, 8), upb_strview); }
 UPB_INLINE bool envoy_service_discovery_v3_DiscoveryResponse_has_resources(const envoy_service_discovery_v3_DiscoveryResponse *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(32, 64)); }
 UPB_INLINE const struct google_protobuf_Any* const* envoy_service_discovery_v3_DiscoveryResponse_resources(const envoy_service_discovery_v3_DiscoveryResponse *msg, size_t *len) { return (const struct google_protobuf_Any* const*)_upb_array_accessor(msg, UPB_SIZE(32, 64), len); }
-UPB_INLINE bool envoy_service_discovery_v3_DiscoveryResponse_canary(const envoy_service_discovery_v3_DiscoveryResponse *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(0, 0), bool); }
+UPB_INLINE bool envoy_service_discovery_v3_DiscoveryResponse_canary(const envoy_service_discovery_v3_DiscoveryResponse *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(1, 1), bool); }
 UPB_INLINE upb_strview envoy_service_discovery_v3_DiscoveryResponse_type_url(const envoy_service_discovery_v3_DiscoveryResponse *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(12, 24), upb_strview); }
 UPB_INLINE upb_strview envoy_service_discovery_v3_DiscoveryResponse_nonce(const envoy_service_discovery_v3_DiscoveryResponse *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(20, 40), upb_strview); }
-UPB_INLINE bool envoy_service_discovery_v3_DiscoveryResponse_has_control_plane(const envoy_service_discovery_v3_DiscoveryResponse *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(28, 56)); }
+UPB_INLINE bool envoy_service_discovery_v3_DiscoveryResponse_has_control_plane(const envoy_service_discovery_v3_DiscoveryResponse *msg) { return _upb_hasbit(msg, 1); }
 UPB_INLINE const struct envoy_config_core_v3_ControlPlane* envoy_service_discovery_v3_DiscoveryResponse_control_plane(const envoy_service_discovery_v3_DiscoveryResponse *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(28, 56), const struct envoy_config_core_v3_ControlPlane*); }
 
 UPB_INLINE void envoy_service_discovery_v3_DiscoveryResponse_set_version_info(envoy_service_discovery_v3_DiscoveryResponse *msg, upb_strview value) {
@@ -148,17 +163,17 @@ UPB_INLINE struct google_protobuf_Any** envoy_service_discovery_v3_DiscoveryResp
   return (struct google_protobuf_Any**)_upb_array_mutable_accessor(msg, UPB_SIZE(32, 64), len);
 }
 UPB_INLINE struct google_protobuf_Any** envoy_service_discovery_v3_DiscoveryResponse_resize_resources(envoy_service_discovery_v3_DiscoveryResponse *msg, size_t len, upb_arena *arena) {
-  return (struct google_protobuf_Any**)_upb_array_resize_accessor(msg, UPB_SIZE(32, 64), len, UPB_TYPE_MESSAGE, arena);
+  return (struct google_protobuf_Any**)_upb_array_resize_accessor2(msg, UPB_SIZE(32, 64), len, UPB_SIZE(2, 3), arena);
 }
 UPB_INLINE struct google_protobuf_Any* envoy_service_discovery_v3_DiscoveryResponse_add_resources(envoy_service_discovery_v3_DiscoveryResponse *msg, upb_arena *arena) {
   struct google_protobuf_Any* sub = (struct google_protobuf_Any*)_upb_msg_new(&google_protobuf_Any_msginit, arena);
-  bool ok = _upb_array_append_accessor(
-      msg, UPB_SIZE(32, 64), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena);
+  bool ok = _upb_array_append_accessor2(
+      msg, UPB_SIZE(32, 64), UPB_SIZE(2, 3), &sub, arena);
   if (!ok) return NULL;
   return sub;
 }
 UPB_INLINE void envoy_service_discovery_v3_DiscoveryResponse_set_canary(envoy_service_discovery_v3_DiscoveryResponse *msg, bool value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(0, 0), bool) = value;
+  *UPB_PTR_AT(msg, UPB_SIZE(1, 1), bool) = value;
 }
 UPB_INLINE void envoy_service_discovery_v3_DiscoveryResponse_set_type_url(envoy_service_discovery_v3_DiscoveryResponse *msg, upb_strview value) {
   *UPB_PTR_AT(msg, UPB_SIZE(12, 24), upb_strview) = value;
@@ -167,6 +182,7 @@ UPB_INLINE void envoy_service_discovery_v3_DiscoveryResponse_set_nonce(envoy_ser
   *UPB_PTR_AT(msg, UPB_SIZE(20, 40), upb_strview) = value;
 }
 UPB_INLINE void envoy_service_discovery_v3_DiscoveryResponse_set_control_plane(envoy_service_discovery_v3_DiscoveryResponse *msg, struct envoy_config_core_v3_ControlPlane* value) {
+  _upb_sethas(msg, 1);
   *UPB_PTR_AT(msg, UPB_SIZE(28, 56), struct envoy_config_core_v3_ControlPlane*) = value;
 }
 UPB_INLINE struct envoy_config_core_v3_ControlPlane* envoy_service_discovery_v3_DiscoveryResponse_mutable_control_plane(envoy_service_discovery_v3_DiscoveryResponse *msg, upb_arena *arena) {
@@ -189,29 +205,36 @@ UPB_INLINE envoy_service_discovery_v3_DeltaDiscoveryRequest *envoy_service_disco
   envoy_service_discovery_v3_DeltaDiscoveryRequest *ret = envoy_service_discovery_v3_DeltaDiscoveryRequest_new(arena);
   return (ret && upb_decode(buf, size, ret, &envoy_service_discovery_v3_DeltaDiscoveryRequest_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE envoy_service_discovery_v3_DeltaDiscoveryRequest *envoy_service_discovery_v3_DeltaDiscoveryRequest_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  envoy_service_discovery_v3_DeltaDiscoveryRequest *ret = envoy_service_discovery_v3_DeltaDiscoveryRequest_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &envoy_service_discovery_v3_DeltaDiscoveryRequest_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *envoy_service_discovery_v3_DeltaDiscoveryRequest_serialize(const envoy_service_discovery_v3_DeltaDiscoveryRequest *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &envoy_service_discovery_v3_DeltaDiscoveryRequest_msginit, arena, len);
 }
 
-UPB_INLINE bool envoy_service_discovery_v3_DeltaDiscoveryRequest_has_node(const envoy_service_discovery_v3_DeltaDiscoveryRequest *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(16, 32)); }
-UPB_INLINE const struct envoy_config_core_v3_Node* envoy_service_discovery_v3_DeltaDiscoveryRequest_node(const envoy_service_discovery_v3_DeltaDiscoveryRequest *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(16, 32), const struct envoy_config_core_v3_Node*); }
-UPB_INLINE upb_strview envoy_service_discovery_v3_DeltaDiscoveryRequest_type_url(const envoy_service_discovery_v3_DeltaDiscoveryRequest *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(0, 0), upb_strview); }
-UPB_INLINE upb_strview const* envoy_service_discovery_v3_DeltaDiscoveryRequest_resource_names_subscribe(const envoy_service_discovery_v3_DeltaDiscoveryRequest *msg, size_t *len) { return (upb_strview const*)_upb_array_accessor(msg, UPB_SIZE(24, 48), len); }
-UPB_INLINE upb_strview const* envoy_service_discovery_v3_DeltaDiscoveryRequest_resource_names_unsubscribe(const envoy_service_discovery_v3_DeltaDiscoveryRequest *msg, size_t *len) { return (upb_strview const*)_upb_array_accessor(msg, UPB_SIZE(28, 56), len); }
-UPB_INLINE bool envoy_service_discovery_v3_DeltaDiscoveryRequest_has_initial_resource_versions(const envoy_service_discovery_v3_DeltaDiscoveryRequest *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(32, 64)); }
-UPB_INLINE size_t envoy_service_discovery_v3_DeltaDiscoveryRequest_initial_resource_versions_size(const envoy_service_discovery_v3_DeltaDiscoveryRequest *msg) {return _upb_msg_map_size(msg, UPB_SIZE(32, 64)); }
-UPB_INLINE bool envoy_service_discovery_v3_DeltaDiscoveryRequest_initial_resource_versions_get(const envoy_service_discovery_v3_DeltaDiscoveryRequest *msg, upb_strview key, upb_strview *val) { return _upb_msg_map_get(msg, UPB_SIZE(32, 64), &key, 0, val, 0); }
-UPB_INLINE const envoy_service_discovery_v3_DeltaDiscoveryRequest_InitialResourceVersionsEntry* envoy_service_discovery_v3_DeltaDiscoveryRequest_initial_resource_versions_next(const envoy_service_discovery_v3_DeltaDiscoveryRequest *msg, size_t* iter) { return (const envoy_service_discovery_v3_DeltaDiscoveryRequest_InitialResourceVersionsEntry*)_upb_msg_map_next(msg, UPB_SIZE(32, 64), iter); }
-UPB_INLINE upb_strview envoy_service_discovery_v3_DeltaDiscoveryRequest_response_nonce(const envoy_service_discovery_v3_DeltaDiscoveryRequest *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(8, 16), upb_strview); }
-UPB_INLINE bool envoy_service_discovery_v3_DeltaDiscoveryRequest_has_error_detail(const envoy_service_discovery_v3_DeltaDiscoveryRequest *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(20, 40)); }
-UPB_INLINE const struct google_rpc_Status* envoy_service_discovery_v3_DeltaDiscoveryRequest_error_detail(const envoy_service_discovery_v3_DeltaDiscoveryRequest *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(20, 40), const struct google_rpc_Status*); }
-UPB_INLINE bool envoy_service_discovery_v3_DeltaDiscoveryRequest_has_udpa_resources_subscribe(const envoy_service_discovery_v3_DeltaDiscoveryRequest *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(36, 72)); }
-UPB_INLINE const struct udpa_core_v1_ResourceLocator* const* envoy_service_discovery_v3_DeltaDiscoveryRequest_udpa_resources_subscribe(const envoy_service_discovery_v3_DeltaDiscoveryRequest *msg, size_t *len) { return (const struct udpa_core_v1_ResourceLocator* const*)_upb_array_accessor(msg, UPB_SIZE(36, 72), len); }
-UPB_INLINE bool envoy_service_discovery_v3_DeltaDiscoveryRequest_has_udpa_resources_unsubscribe(const envoy_service_discovery_v3_DeltaDiscoveryRequest *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(40, 80)); }
-UPB_INLINE const struct udpa_core_v1_ResourceLocator* const* envoy_service_discovery_v3_DeltaDiscoveryRequest_udpa_resources_unsubscribe(const envoy_service_discovery_v3_DeltaDiscoveryRequest *msg, size_t *len) { return (const struct udpa_core_v1_ResourceLocator* const*)_upb_array_accessor(msg, UPB_SIZE(40, 80), len); }
+UPB_INLINE bool envoy_service_discovery_v3_DeltaDiscoveryRequest_has_node(const envoy_service_discovery_v3_DeltaDiscoveryRequest *msg) { return _upb_hasbit(msg, 1); }
+UPB_INLINE const struct envoy_config_core_v3_Node* envoy_service_discovery_v3_DeltaDiscoveryRequest_node(const envoy_service_discovery_v3_DeltaDiscoveryRequest *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(20, 40), const struct envoy_config_core_v3_Node*); }
+UPB_INLINE upb_strview envoy_service_discovery_v3_DeltaDiscoveryRequest_type_url(const envoy_service_discovery_v3_DeltaDiscoveryRequest *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(4, 8), upb_strview); }
+UPB_INLINE upb_strview const* envoy_service_discovery_v3_DeltaDiscoveryRequest_resource_names_subscribe(const envoy_service_discovery_v3_DeltaDiscoveryRequest *msg, size_t *len) { return (upb_strview const*)_upb_array_accessor(msg, UPB_SIZE(28, 56), len); }
+UPB_INLINE upb_strview const* envoy_service_discovery_v3_DeltaDiscoveryRequest_resource_names_unsubscribe(const envoy_service_discovery_v3_DeltaDiscoveryRequest *msg, size_t *len) { return (upb_strview const*)_upb_array_accessor(msg, UPB_SIZE(32, 64), len); }
+UPB_INLINE bool envoy_service_discovery_v3_DeltaDiscoveryRequest_has_initial_resource_versions(const envoy_service_discovery_v3_DeltaDiscoveryRequest *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(36, 72)); }
+UPB_INLINE size_t envoy_service_discovery_v3_DeltaDiscoveryRequest_initial_resource_versions_size(const envoy_service_discovery_v3_DeltaDiscoveryRequest *msg) {return _upb_msg_map_size(msg, UPB_SIZE(36, 72)); }
+UPB_INLINE bool envoy_service_discovery_v3_DeltaDiscoveryRequest_initial_resource_versions_get(const envoy_service_discovery_v3_DeltaDiscoveryRequest *msg, upb_strview key, upb_strview *val) { return _upb_msg_map_get(msg, UPB_SIZE(36, 72), &key, 0, val, 0); }
+UPB_INLINE const envoy_service_discovery_v3_DeltaDiscoveryRequest_InitialResourceVersionsEntry* envoy_service_discovery_v3_DeltaDiscoveryRequest_initial_resource_versions_next(const envoy_service_discovery_v3_DeltaDiscoveryRequest *msg, size_t* iter) { return (const envoy_service_discovery_v3_DeltaDiscoveryRequest_InitialResourceVersionsEntry*)_upb_msg_map_next(msg, UPB_SIZE(36, 72), iter); }
+UPB_INLINE upb_strview envoy_service_discovery_v3_DeltaDiscoveryRequest_response_nonce(const envoy_service_discovery_v3_DeltaDiscoveryRequest *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(12, 24), upb_strview); }
+UPB_INLINE bool envoy_service_discovery_v3_DeltaDiscoveryRequest_has_error_detail(const envoy_service_discovery_v3_DeltaDiscoveryRequest *msg) { return _upb_hasbit(msg, 2); }
+UPB_INLINE const struct google_rpc_Status* envoy_service_discovery_v3_DeltaDiscoveryRequest_error_detail(const envoy_service_discovery_v3_DeltaDiscoveryRequest *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(24, 48), const struct google_rpc_Status*); }
+UPB_INLINE bool envoy_service_discovery_v3_DeltaDiscoveryRequest_has_udpa_resources_subscribe(const envoy_service_discovery_v3_DeltaDiscoveryRequest *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(40, 80)); }
+UPB_INLINE const struct udpa_core_v1_ResourceLocator* const* envoy_service_discovery_v3_DeltaDiscoveryRequest_udpa_resources_subscribe(const envoy_service_discovery_v3_DeltaDiscoveryRequest *msg, size_t *len) { return (const struct udpa_core_v1_ResourceLocator* const*)_upb_array_accessor(msg, UPB_SIZE(40, 80), len); }
+UPB_INLINE bool envoy_service_discovery_v3_DeltaDiscoveryRequest_has_udpa_resources_unsubscribe(const envoy_service_discovery_v3_DeltaDiscoveryRequest *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(44, 88)); }
+UPB_INLINE const struct udpa_core_v1_ResourceLocator* const* envoy_service_discovery_v3_DeltaDiscoveryRequest_udpa_resources_unsubscribe(const envoy_service_discovery_v3_DeltaDiscoveryRequest *msg, size_t *len) { return (const struct udpa_core_v1_ResourceLocator* const*)_upb_array_accessor(msg, UPB_SIZE(44, 88), len); }
 
 UPB_INLINE void envoy_service_discovery_v3_DeltaDiscoveryRequest_set_node(envoy_service_discovery_v3_DeltaDiscoveryRequest *msg, struct envoy_config_core_v3_Node* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(16, 32), struct envoy_config_core_v3_Node*) = value;
+  _upb_sethas(msg, 1);
+  *UPB_PTR_AT(msg, UPB_SIZE(20, 40), struct envoy_config_core_v3_Node*) = value;
 }
 UPB_INLINE struct envoy_config_core_v3_Node* envoy_service_discovery_v3_DeltaDiscoveryRequest_mutable_node(envoy_service_discovery_v3_DeltaDiscoveryRequest *msg, upb_arena *arena) {
   struct envoy_config_core_v3_Node* sub = (struct envoy_config_core_v3_Node*)envoy_service_discovery_v3_DeltaDiscoveryRequest_node(msg);
@@ -223,37 +246,38 @@ UPB_INLINE struct envoy_config_core_v3_Node* envoy_service_discovery_v3_DeltaDis
   return sub;
 }
 UPB_INLINE void envoy_service_discovery_v3_DeltaDiscoveryRequest_set_type_url(envoy_service_discovery_v3_DeltaDiscoveryRequest *msg, upb_strview value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(0, 0), upb_strview) = value;
+  *UPB_PTR_AT(msg, UPB_SIZE(4, 8), upb_strview) = value;
 }
 UPB_INLINE upb_strview* envoy_service_discovery_v3_DeltaDiscoveryRequest_mutable_resource_names_subscribe(envoy_service_discovery_v3_DeltaDiscoveryRequest *msg, size_t *len) {
-  return (upb_strview*)_upb_array_mutable_accessor(msg, UPB_SIZE(24, 48), len);
+  return (upb_strview*)_upb_array_mutable_accessor(msg, UPB_SIZE(28, 56), len);
 }
 UPB_INLINE upb_strview* envoy_service_discovery_v3_DeltaDiscoveryRequest_resize_resource_names_subscribe(envoy_service_discovery_v3_DeltaDiscoveryRequest *msg, size_t len, upb_arena *arena) {
-  return (upb_strview*)_upb_array_resize_accessor(msg, UPB_SIZE(24, 48), len, UPB_TYPE_STRING, arena);
+  return (upb_strview*)_upb_array_resize_accessor2(msg, UPB_SIZE(28, 56), len, UPB_SIZE(3, 4), arena);
 }
 UPB_INLINE bool envoy_service_discovery_v3_DeltaDiscoveryRequest_add_resource_names_subscribe(envoy_service_discovery_v3_DeltaDiscoveryRequest *msg, upb_strview val, upb_arena *arena) {
-  return _upb_array_append_accessor(msg, UPB_SIZE(24, 48), UPB_SIZE(8, 16), UPB_TYPE_STRING, &val,
+  return _upb_array_append_accessor2(msg, UPB_SIZE(28, 56), UPB_SIZE(3, 4), &val,
       arena);
 }
 UPB_INLINE upb_strview* envoy_service_discovery_v3_DeltaDiscoveryRequest_mutable_resource_names_unsubscribe(envoy_service_discovery_v3_DeltaDiscoveryRequest *msg, size_t *len) {
-  return (upb_strview*)_upb_array_mutable_accessor(msg, UPB_SIZE(28, 56), len);
+  return (upb_strview*)_upb_array_mutable_accessor(msg, UPB_SIZE(32, 64), len);
 }
 UPB_INLINE upb_strview* envoy_service_discovery_v3_DeltaDiscoveryRequest_resize_resource_names_unsubscribe(envoy_service_discovery_v3_DeltaDiscoveryRequest *msg, size_t len, upb_arena *arena) {
-  return (upb_strview*)_upb_array_resize_accessor(msg, UPB_SIZE(28, 56), len, UPB_TYPE_STRING, arena);
+  return (upb_strview*)_upb_array_resize_accessor2(msg, UPB_SIZE(32, 64), len, UPB_SIZE(3, 4), arena);
 }
 UPB_INLINE bool envoy_service_discovery_v3_DeltaDiscoveryRequest_add_resource_names_unsubscribe(envoy_service_discovery_v3_DeltaDiscoveryRequest *msg, upb_strview val, upb_arena *arena) {
-  return _upb_array_append_accessor(msg, UPB_SIZE(28, 56), UPB_SIZE(8, 16), UPB_TYPE_STRING, &val,
+  return _upb_array_append_accessor2(msg, UPB_SIZE(32, 64), UPB_SIZE(3, 4), &val,
       arena);
 }
-UPB_INLINE void envoy_service_discovery_v3_DeltaDiscoveryRequest_initial_resource_versions_clear(envoy_service_discovery_v3_DeltaDiscoveryRequest *msg) { _upb_msg_map_clear(msg, UPB_SIZE(32, 64)); }
-UPB_INLINE bool envoy_service_discovery_v3_DeltaDiscoveryRequest_initial_resource_versions_set(envoy_service_discovery_v3_DeltaDiscoveryRequest *msg, upb_strview key, upb_strview val, upb_arena *a) { return _upb_msg_map_set(msg, UPB_SIZE(32, 64), &key, 0, &val, 0, a); }
-UPB_INLINE bool envoy_service_discovery_v3_DeltaDiscoveryRequest_initial_resource_versions_delete(envoy_service_discovery_v3_DeltaDiscoveryRequest *msg, upb_strview key) { return _upb_msg_map_delete(msg, UPB_SIZE(32, 64), &key, 0); }
-UPB_INLINE envoy_service_discovery_v3_DeltaDiscoveryRequest_InitialResourceVersionsEntry* envoy_service_discovery_v3_DeltaDiscoveryRequest_initial_resource_versions_nextmutable(envoy_service_discovery_v3_DeltaDiscoveryRequest *msg, size_t* iter) { return (envoy_service_discovery_v3_DeltaDiscoveryRequest_InitialResourceVersionsEntry*)_upb_msg_map_next(msg, UPB_SIZE(32, 64), iter); }
+UPB_INLINE void envoy_service_discovery_v3_DeltaDiscoveryRequest_initial_resource_versions_clear(envoy_service_discovery_v3_DeltaDiscoveryRequest *msg) { _upb_msg_map_clear(msg, UPB_SIZE(36, 72)); }
+UPB_INLINE bool envoy_service_discovery_v3_DeltaDiscoveryRequest_initial_resource_versions_set(envoy_service_discovery_v3_DeltaDiscoveryRequest *msg, upb_strview key, upb_strview val, upb_arena *a) { return _upb_msg_map_set(msg, UPB_SIZE(36, 72), &key, 0, &val, 0, a); }
+UPB_INLINE bool envoy_service_discovery_v3_DeltaDiscoveryRequest_initial_resource_versions_delete(envoy_service_discovery_v3_DeltaDiscoveryRequest *msg, upb_strview key) { return _upb_msg_map_delete(msg, UPB_SIZE(36, 72), &key, 0); }
+UPB_INLINE envoy_service_discovery_v3_DeltaDiscoveryRequest_InitialResourceVersionsEntry* envoy_service_discovery_v3_DeltaDiscoveryRequest_initial_resource_versions_nextmutable(envoy_service_discovery_v3_DeltaDiscoveryRequest *msg, size_t* iter) { return (envoy_service_discovery_v3_DeltaDiscoveryRequest_InitialResourceVersionsEntry*)_upb_msg_map_next(msg, UPB_SIZE(36, 72), iter); }
 UPB_INLINE void envoy_service_discovery_v3_DeltaDiscoveryRequest_set_response_nonce(envoy_service_discovery_v3_DeltaDiscoveryRequest *msg, upb_strview value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(8, 16), upb_strview) = value;
+  *UPB_PTR_AT(msg, UPB_SIZE(12, 24), upb_strview) = value;
 }
 UPB_INLINE void envoy_service_discovery_v3_DeltaDiscoveryRequest_set_error_detail(envoy_service_discovery_v3_DeltaDiscoveryRequest *msg, struct google_rpc_Status* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(20, 40), struct google_rpc_Status*) = value;
+  _upb_sethas(msg, 2);
+  *UPB_PTR_AT(msg, UPB_SIZE(24, 48), struct google_rpc_Status*) = value;
 }
 UPB_INLINE struct google_rpc_Status* envoy_service_discovery_v3_DeltaDiscoveryRequest_mutable_error_detail(envoy_service_discovery_v3_DeltaDiscoveryRequest *msg, upb_arena *arena) {
   struct google_rpc_Status* sub = (struct google_rpc_Status*)envoy_service_discovery_v3_DeltaDiscoveryRequest_error_detail(msg);
@@ -265,28 +289,28 @@ UPB_INLINE struct google_rpc_Status* envoy_service_discovery_v3_DeltaDiscoveryRe
   return sub;
 }
 UPB_INLINE struct udpa_core_v1_ResourceLocator** envoy_service_discovery_v3_DeltaDiscoveryRequest_mutable_udpa_resources_subscribe(envoy_service_discovery_v3_DeltaDiscoveryRequest *msg, size_t *len) {
-  return (struct udpa_core_v1_ResourceLocator**)_upb_array_mutable_accessor(msg, UPB_SIZE(36, 72), len);
+  return (struct udpa_core_v1_ResourceLocator**)_upb_array_mutable_accessor(msg, UPB_SIZE(40, 80), len);
 }
 UPB_INLINE struct udpa_core_v1_ResourceLocator** envoy_service_discovery_v3_DeltaDiscoveryRequest_resize_udpa_resources_subscribe(envoy_service_discovery_v3_DeltaDiscoveryRequest *msg, size_t len, upb_arena *arena) {
-  return (struct udpa_core_v1_ResourceLocator**)_upb_array_resize_accessor(msg, UPB_SIZE(36, 72), len, UPB_TYPE_MESSAGE, arena);
+  return (struct udpa_core_v1_ResourceLocator**)_upb_array_resize_accessor2(msg, UPB_SIZE(40, 80), len, UPB_SIZE(2, 3), arena);
 }
 UPB_INLINE struct udpa_core_v1_ResourceLocator* envoy_service_discovery_v3_DeltaDiscoveryRequest_add_udpa_resources_subscribe(envoy_service_discovery_v3_DeltaDiscoveryRequest *msg, upb_arena *arena) {
   struct udpa_core_v1_ResourceLocator* sub = (struct udpa_core_v1_ResourceLocator*)_upb_msg_new(&udpa_core_v1_ResourceLocator_msginit, arena);
-  bool ok = _upb_array_append_accessor(
-      msg, UPB_SIZE(36, 72), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena);
+  bool ok = _upb_array_append_accessor2(
+      msg, UPB_SIZE(40, 80), UPB_SIZE(2, 3), &sub, arena);
   if (!ok) return NULL;
   return sub;
 }
 UPB_INLINE struct udpa_core_v1_ResourceLocator** envoy_service_discovery_v3_DeltaDiscoveryRequest_mutable_udpa_resources_unsubscribe(envoy_service_discovery_v3_DeltaDiscoveryRequest *msg, size_t *len) {
-  return (struct udpa_core_v1_ResourceLocator**)_upb_array_mutable_accessor(msg, UPB_SIZE(40, 80), len);
+  return (struct udpa_core_v1_ResourceLocator**)_upb_array_mutable_accessor(msg, UPB_SIZE(44, 88), len);
 }
 UPB_INLINE struct udpa_core_v1_ResourceLocator** envoy_service_discovery_v3_DeltaDiscoveryRequest_resize_udpa_resources_unsubscribe(envoy_service_discovery_v3_DeltaDiscoveryRequest *msg, size_t len, upb_arena *arena) {
-  return (struct udpa_core_v1_ResourceLocator**)_upb_array_resize_accessor(msg, UPB_SIZE(40, 80), len, UPB_TYPE_MESSAGE, arena);
+  return (struct udpa_core_v1_ResourceLocator**)_upb_array_resize_accessor2(msg, UPB_SIZE(44, 88), len, UPB_SIZE(2, 3), arena);
 }
 UPB_INLINE struct udpa_core_v1_ResourceLocator* envoy_service_discovery_v3_DeltaDiscoveryRequest_add_udpa_resources_unsubscribe(envoy_service_discovery_v3_DeltaDiscoveryRequest *msg, upb_arena *arena) {
   struct udpa_core_v1_ResourceLocator* sub = (struct udpa_core_v1_ResourceLocator*)_upb_msg_new(&udpa_core_v1_ResourceLocator_msginit, arena);
-  bool ok = _upb_array_append_accessor(
-      msg, UPB_SIZE(40, 80), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena);
+  bool ok = _upb_array_append_accessor2(
+      msg, UPB_SIZE(44, 88), UPB_SIZE(2, 3), &sub, arena);
   if (!ok) return NULL;
   return sub;
 }
@@ -318,6 +342,12 @@ UPB_INLINE envoy_service_discovery_v3_DeltaDiscoveryResponse *envoy_service_disc
   envoy_service_discovery_v3_DeltaDiscoveryResponse *ret = envoy_service_discovery_v3_DeltaDiscoveryResponse_new(arena);
   return (ret && upb_decode(buf, size, ret, &envoy_service_discovery_v3_DeltaDiscoveryResponse_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE envoy_service_discovery_v3_DeltaDiscoveryResponse *envoy_service_discovery_v3_DeltaDiscoveryResponse_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  envoy_service_discovery_v3_DeltaDiscoveryResponse *ret = envoy_service_discovery_v3_DeltaDiscoveryResponse_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &envoy_service_discovery_v3_DeltaDiscoveryResponse_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *envoy_service_discovery_v3_DeltaDiscoveryResponse_serialize(const envoy_service_discovery_v3_DeltaDiscoveryResponse *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &envoy_service_discovery_v3_DeltaDiscoveryResponse_msginit, arena, len);
 }
@@ -338,12 +368,12 @@ UPB_INLINE envoy_service_discovery_v3_Resource** envoy_service_discovery_v3_Delt
   return (envoy_service_discovery_v3_Resource**)_upb_array_mutable_accessor(msg, UPB_SIZE(24, 48), len);
 }
 UPB_INLINE envoy_service_discovery_v3_Resource** envoy_service_discovery_v3_DeltaDiscoveryResponse_resize_resources(envoy_service_discovery_v3_DeltaDiscoveryResponse *msg, size_t len, upb_arena *arena) {
-  return (envoy_service_discovery_v3_Resource**)_upb_array_resize_accessor(msg, UPB_SIZE(24, 48), len, UPB_TYPE_MESSAGE, arena);
+  return (envoy_service_discovery_v3_Resource**)_upb_array_resize_accessor2(msg, UPB_SIZE(24, 48), len, UPB_SIZE(2, 3), arena);
 }
 UPB_INLINE struct envoy_service_discovery_v3_Resource* envoy_service_discovery_v3_DeltaDiscoveryResponse_add_resources(envoy_service_discovery_v3_DeltaDiscoveryResponse *msg, upb_arena *arena) {
   struct envoy_service_discovery_v3_Resource* sub = (struct envoy_service_discovery_v3_Resource*)_upb_msg_new(&envoy_service_discovery_v3_Resource_msginit, arena);
-  bool ok = _upb_array_append_accessor(
-      msg, UPB_SIZE(24, 48), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena);
+  bool ok = _upb_array_append_accessor2(
+      msg, UPB_SIZE(24, 48), UPB_SIZE(2, 3), &sub, arena);
   if (!ok) return NULL;
   return sub;
 }
@@ -357,22 +387,22 @@ UPB_INLINE upb_strview* envoy_service_discovery_v3_DeltaDiscoveryResponse_mutabl
   return (upb_strview*)_upb_array_mutable_accessor(msg, UPB_SIZE(28, 56), len);
 }
 UPB_INLINE upb_strview* envoy_service_discovery_v3_DeltaDiscoveryResponse_resize_removed_resources(envoy_service_discovery_v3_DeltaDiscoveryResponse *msg, size_t len, upb_arena *arena) {
-  return (upb_strview*)_upb_array_resize_accessor(msg, UPB_SIZE(28, 56), len, UPB_TYPE_STRING, arena);
+  return (upb_strview*)_upb_array_resize_accessor2(msg, UPB_SIZE(28, 56), len, UPB_SIZE(3, 4), arena);
 }
 UPB_INLINE bool envoy_service_discovery_v3_DeltaDiscoveryResponse_add_removed_resources(envoy_service_discovery_v3_DeltaDiscoveryResponse *msg, upb_strview val, upb_arena *arena) {
-  return _upb_array_append_accessor(msg, UPB_SIZE(28, 56), UPB_SIZE(8, 16), UPB_TYPE_STRING, &val,
+  return _upb_array_append_accessor2(msg, UPB_SIZE(28, 56), UPB_SIZE(3, 4), &val,
       arena);
 }
 UPB_INLINE struct udpa_core_v1_ResourceName** envoy_service_discovery_v3_DeltaDiscoveryResponse_mutable_udpa_removed_resources(envoy_service_discovery_v3_DeltaDiscoveryResponse *msg, size_t *len) {
   return (struct udpa_core_v1_ResourceName**)_upb_array_mutable_accessor(msg, UPB_SIZE(32, 64), len);
 }
 UPB_INLINE struct udpa_core_v1_ResourceName** envoy_service_discovery_v3_DeltaDiscoveryResponse_resize_udpa_removed_resources(envoy_service_discovery_v3_DeltaDiscoveryResponse *msg, size_t len, upb_arena *arena) {
-  return (struct udpa_core_v1_ResourceName**)_upb_array_resize_accessor(msg, UPB_SIZE(32, 64), len, UPB_TYPE_MESSAGE, arena);
+  return (struct udpa_core_v1_ResourceName**)_upb_array_resize_accessor2(msg, UPB_SIZE(32, 64), len, UPB_SIZE(2, 3), arena);
 }
 UPB_INLINE struct udpa_core_v1_ResourceName* envoy_service_discovery_v3_DeltaDiscoveryResponse_add_udpa_removed_resources(envoy_service_discovery_v3_DeltaDiscoveryResponse *msg, upb_arena *arena) {
   struct udpa_core_v1_ResourceName* sub = (struct udpa_core_v1_ResourceName*)_upb_msg_new(&udpa_core_v1_ResourceName_msginit, arena);
-  bool ok = _upb_array_append_accessor(
-      msg, UPB_SIZE(32, 64), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena);
+  bool ok = _upb_array_append_accessor2(
+      msg, UPB_SIZE(32, 64), UPB_SIZE(2, 3), &sub, arena);
   if (!ok) return NULL;
   return sub;
 }
@@ -387,23 +417,30 @@ UPB_INLINE envoy_service_discovery_v3_Resource *envoy_service_discovery_v3_Resou
   envoy_service_discovery_v3_Resource *ret = envoy_service_discovery_v3_Resource_new(arena);
   return (ret && upb_decode(buf, size, ret, &envoy_service_discovery_v3_Resource_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE envoy_service_discovery_v3_Resource *envoy_service_discovery_v3_Resource_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  envoy_service_discovery_v3_Resource *ret = envoy_service_discovery_v3_Resource_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &envoy_service_discovery_v3_Resource_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *envoy_service_discovery_v3_Resource_serialize(const envoy_service_discovery_v3_Resource *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &envoy_service_discovery_v3_Resource_msginit, arena, len);
 }
 
-UPB_INLINE upb_strview envoy_service_discovery_v3_Resource_version(const envoy_service_discovery_v3_Resource *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(0, 0), upb_strview); }
-UPB_INLINE bool envoy_service_discovery_v3_Resource_has_resource(const envoy_service_discovery_v3_Resource *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(16, 32)); }
-UPB_INLINE const struct google_protobuf_Any* envoy_service_discovery_v3_Resource_resource(const envoy_service_discovery_v3_Resource *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(16, 32), const struct google_protobuf_Any*); }
-UPB_INLINE upb_strview envoy_service_discovery_v3_Resource_name(const envoy_service_discovery_v3_Resource *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(8, 16), upb_strview); }
-UPB_INLINE upb_strview const* envoy_service_discovery_v3_Resource_aliases(const envoy_service_discovery_v3_Resource *msg, size_t *len) { return (upb_strview const*)_upb_array_accessor(msg, UPB_SIZE(24, 48), len); }
-UPB_INLINE bool envoy_service_discovery_v3_Resource_has_udpa_resource_name(const envoy_service_discovery_v3_Resource *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(20, 40)); }
-UPB_INLINE const struct udpa_core_v1_ResourceName* envoy_service_discovery_v3_Resource_udpa_resource_name(const envoy_service_discovery_v3_Resource *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(20, 40), const struct udpa_core_v1_ResourceName*); }
+UPB_INLINE upb_strview envoy_service_discovery_v3_Resource_version(const envoy_service_discovery_v3_Resource *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(4, 8), upb_strview); }
+UPB_INLINE bool envoy_service_discovery_v3_Resource_has_resource(const envoy_service_discovery_v3_Resource *msg) { return _upb_hasbit(msg, 1); }
+UPB_INLINE const struct google_protobuf_Any* envoy_service_discovery_v3_Resource_resource(const envoy_service_discovery_v3_Resource *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(20, 40), const struct google_protobuf_Any*); }
+UPB_INLINE upb_strview envoy_service_discovery_v3_Resource_name(const envoy_service_discovery_v3_Resource *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(12, 24), upb_strview); }
+UPB_INLINE upb_strview const* envoy_service_discovery_v3_Resource_aliases(const envoy_service_discovery_v3_Resource *msg, size_t *len) { return (upb_strview const*)_upb_array_accessor(msg, UPB_SIZE(28, 56), len); }
+UPB_INLINE bool envoy_service_discovery_v3_Resource_has_udpa_resource_name(const envoy_service_discovery_v3_Resource *msg) { return _upb_hasbit(msg, 2); }
+UPB_INLINE const struct udpa_core_v1_ResourceName* envoy_service_discovery_v3_Resource_udpa_resource_name(const envoy_service_discovery_v3_Resource *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(24, 48), const struct udpa_core_v1_ResourceName*); }
 
 UPB_INLINE void envoy_service_discovery_v3_Resource_set_version(envoy_service_discovery_v3_Resource *msg, upb_strview value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(0, 0), upb_strview) = value;
+  *UPB_PTR_AT(msg, UPB_SIZE(4, 8), upb_strview) = value;
 }
 UPB_INLINE void envoy_service_discovery_v3_Resource_set_resource(envoy_service_discovery_v3_Resource *msg, struct google_protobuf_Any* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(16, 32), struct google_protobuf_Any*) = value;
+  _upb_sethas(msg, 1);
+  *UPB_PTR_AT(msg, UPB_SIZE(20, 40), struct google_protobuf_Any*) = value;
 }
 UPB_INLINE struct google_protobuf_Any* envoy_service_discovery_v3_Resource_mutable_resource(envoy_service_discovery_v3_Resource *msg, upb_arena *arena) {
   struct google_protobuf_Any* sub = (struct google_protobuf_Any*)envoy_service_discovery_v3_Resource_resource(msg);
@@ -415,20 +452,21 @@ UPB_INLINE struct google_protobuf_Any* envoy_service_discovery_v3_Resource_mutab
   return sub;
 }
 UPB_INLINE void envoy_service_discovery_v3_Resource_set_name(envoy_service_discovery_v3_Resource *msg, upb_strview value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(8, 16), upb_strview) = value;
+  *UPB_PTR_AT(msg, UPB_SIZE(12, 24), upb_strview) = value;
 }
 UPB_INLINE upb_strview* envoy_service_discovery_v3_Resource_mutable_aliases(envoy_service_discovery_v3_Resource *msg, size_t *len) {
-  return (upb_strview*)_upb_array_mutable_accessor(msg, UPB_SIZE(24, 48), len);
+  return (upb_strview*)_upb_array_mutable_accessor(msg, UPB_SIZE(28, 56), len);
 }
 UPB_INLINE upb_strview* envoy_service_discovery_v3_Resource_resize_aliases(envoy_service_discovery_v3_Resource *msg, size_t len, upb_arena *arena) {
-  return (upb_strview*)_upb_array_resize_accessor(msg, UPB_SIZE(24, 48), len, UPB_TYPE_STRING, arena);
+  return (upb_strview*)_upb_array_resize_accessor2(msg, UPB_SIZE(28, 56), len, UPB_SIZE(3, 4), arena);
 }
 UPB_INLINE bool envoy_service_discovery_v3_Resource_add_aliases(envoy_service_discovery_v3_Resource *msg, upb_strview val, upb_arena *arena) {
-  return _upb_array_append_accessor(msg, UPB_SIZE(24, 48), UPB_SIZE(8, 16), UPB_TYPE_STRING, &val,
+  return _upb_array_append_accessor2(msg, UPB_SIZE(28, 56), UPB_SIZE(3, 4), &val,
       arena);
 }
 UPB_INLINE void envoy_service_discovery_v3_Resource_set_udpa_resource_name(envoy_service_discovery_v3_Resource *msg, struct udpa_core_v1_ResourceName* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(20, 40), struct udpa_core_v1_ResourceName*) = value;
+  _upb_sethas(msg, 2);
+  *UPB_PTR_AT(msg, UPB_SIZE(24, 48), struct udpa_core_v1_ResourceName*) = value;
 }
 UPB_INLINE struct udpa_core_v1_ResourceName* envoy_service_discovery_v3_Resource_mutable_udpa_resource_name(envoy_service_discovery_v3_Resource *msg, upb_arena *arena) {
   struct udpa_core_v1_ResourceName* sub = (struct udpa_core_v1_ResourceName*)envoy_service_discovery_v3_Resource_udpa_resource_name(msg);
index 3006037..1e22923 100644 (file)
@@ -23,7 +23,7 @@
 const upb_msglayout envoy_service_endpoint_v3_EdsDummy_msginit = {
   NULL,
   NULL,
-  UPB_SIZE(0, 0), 0, false,
+  UPB_SIZE(0, 0), 0, false, 255,
 };
 
 #include "upb/port_undef.inc"
index f9c36a0..1b1fd3d 100644 (file)
@@ -11,6 +11,7 @@
 
 #include "upb/msg.h"
 #include "upb/decode.h"
+#include "upb/decode_fast.h"
 #include "upb/encode.h"
 
 #include "upb/port_def.inc"
@@ -34,6 +35,12 @@ UPB_INLINE envoy_service_endpoint_v3_EdsDummy *envoy_service_endpoint_v3_EdsDumm
   envoy_service_endpoint_v3_EdsDummy *ret = envoy_service_endpoint_v3_EdsDummy_new(arena);
   return (ret && upb_decode(buf, size, ret, &envoy_service_endpoint_v3_EdsDummy_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE envoy_service_endpoint_v3_EdsDummy *envoy_service_endpoint_v3_EdsDummy_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  envoy_service_endpoint_v3_EdsDummy *ret = envoy_service_endpoint_v3_EdsDummy_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &envoy_service_endpoint_v3_EdsDummy_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *envoy_service_endpoint_v3_EdsDummy_serialize(const envoy_service_endpoint_v3_EdsDummy *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &envoy_service_endpoint_v3_EdsDummy_msginit, arena, len);
 }
index a0f7024..e00bfc2 100644 (file)
@@ -23,7 +23,7 @@
 const upb_msglayout envoy_service_listener_v3_LdsDummy_msginit = {
   NULL,
   NULL,
-  UPB_SIZE(0, 0), 0, false,
+  UPB_SIZE(0, 0), 0, false, 255,
 };
 
 #include "upb/port_undef.inc"
index c427dc3..9b8988c 100644 (file)
@@ -11,6 +11,7 @@
 
 #include "upb/msg.h"
 #include "upb/decode.h"
+#include "upb/decode_fast.h"
 #include "upb/encode.h"
 
 #include "upb/port_def.inc"
@@ -34,6 +35,12 @@ UPB_INLINE envoy_service_listener_v3_LdsDummy *envoy_service_listener_v3_LdsDumm
   envoy_service_listener_v3_LdsDummy *ret = envoy_service_listener_v3_LdsDummy_new(arena);
   return (ret && upb_decode(buf, size, ret, &envoy_service_listener_v3_LdsDummy_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE envoy_service_listener_v3_LdsDummy *envoy_service_listener_v3_LdsDummy_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  envoy_service_listener_v3_LdsDummy *ret = envoy_service_listener_v3_LdsDummy_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &envoy_service_listener_v3_LdsDummy_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *envoy_service_listener_v3_LdsDummy_serialize(const envoy_service_listener_v3_LdsDummy *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &envoy_service_listener_v3_LdsDummy_msginit, arena, len);
 }
index 0b08414..c806a85 100644 (file)
@@ -24,14 +24,14 @@ static const upb_msglayout *const envoy_service_load_stats_v3_LoadStatsRequest_s
 };
 
 static const upb_msglayout_field envoy_service_load_stats_v3_LoadStatsRequest__fields[2] = {
-  {1, UPB_SIZE(0, 0), 0, 0, 11, 1},
-  {2, UPB_SIZE(4, 8), 0, 1, 11, 3},
+  {1, UPB_SIZE(4, 8), 1, 0, 11, 1},
+  {2, UPB_SIZE(8, 16), 0, 1, 11, 3},
 };
 
 const upb_msglayout envoy_service_load_stats_v3_LoadStatsRequest_msginit = {
   &envoy_service_load_stats_v3_LoadStatsRequest_submsgs[0],
   &envoy_service_load_stats_v3_LoadStatsRequest__fields[0],
-  UPB_SIZE(8, 16), 2, false,
+  UPB_SIZE(16, 24), 2, false, 255,
 };
 
 static const upb_msglayout *const envoy_service_load_stats_v3_LoadStatsResponse_submsgs[1] = {
@@ -40,15 +40,15 @@ static const upb_msglayout *const envoy_service_load_stats_v3_LoadStatsResponse_
 
 static const upb_msglayout_field envoy_service_load_stats_v3_LoadStatsResponse__fields[4] = {
   {1, UPB_SIZE(8, 16), 0, 0, 9, 3},
-  {2, UPB_SIZE(4, 8), 0, 0, 11, 1},
-  {3, UPB_SIZE(0, 0), 0, 0, 8, 1},
-  {4, UPB_SIZE(1, 1), 0, 0, 8, 1},
+  {2, UPB_SIZE(4, 8), 1, 0, 11, 1},
+  {3, UPB_SIZE(1, 1), 0, 0, 8, 1},
+  {4, UPB_SIZE(2, 2), 0, 0, 8, 1},
 };
 
 const upb_msglayout envoy_service_load_stats_v3_LoadStatsResponse_msginit = {
   &envoy_service_load_stats_v3_LoadStatsResponse_submsgs[0],
   &envoy_service_load_stats_v3_LoadStatsResponse__fields[0],
-  UPB_SIZE(12, 24), 4, false,
+  UPB_SIZE(16, 24), 4, false, 255,
 };
 
 #include "upb/port_undef.inc"
index 0ec4da5..f74a023 100644 (file)
@@ -11,6 +11,7 @@
 
 #include "upb/msg.h"
 #include "upb/decode.h"
+#include "upb/decode_fast.h"
 #include "upb/encode.h"
 
 #include "upb/port_def.inc"
@@ -43,17 +44,24 @@ UPB_INLINE envoy_service_load_stats_v3_LoadStatsRequest *envoy_service_load_stat
   envoy_service_load_stats_v3_LoadStatsRequest *ret = envoy_service_load_stats_v3_LoadStatsRequest_new(arena);
   return (ret && upb_decode(buf, size, ret, &envoy_service_load_stats_v3_LoadStatsRequest_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE envoy_service_load_stats_v3_LoadStatsRequest *envoy_service_load_stats_v3_LoadStatsRequest_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  envoy_service_load_stats_v3_LoadStatsRequest *ret = envoy_service_load_stats_v3_LoadStatsRequest_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &envoy_service_load_stats_v3_LoadStatsRequest_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *envoy_service_load_stats_v3_LoadStatsRequest_serialize(const envoy_service_load_stats_v3_LoadStatsRequest *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &envoy_service_load_stats_v3_LoadStatsRequest_msginit, arena, len);
 }
 
-UPB_INLINE bool envoy_service_load_stats_v3_LoadStatsRequest_has_node(const envoy_service_load_stats_v3_LoadStatsRequest *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(0, 0)); }
-UPB_INLINE const struct envoy_config_core_v3_Node* envoy_service_load_stats_v3_LoadStatsRequest_node(const envoy_service_load_stats_v3_LoadStatsRequest *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(0, 0), const struct envoy_config_core_v3_Node*); }
-UPB_INLINE bool envoy_service_load_stats_v3_LoadStatsRequest_has_cluster_stats(const envoy_service_load_stats_v3_LoadStatsRequest *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(4, 8)); }
-UPB_INLINE const struct envoy_config_endpoint_v3_ClusterStats* const* envoy_service_load_stats_v3_LoadStatsRequest_cluster_stats(const envoy_service_load_stats_v3_LoadStatsRequest *msg, size_t *len) { return (const struct envoy_config_endpoint_v3_ClusterStats* const*)_upb_array_accessor(msg, UPB_SIZE(4, 8), len); }
+UPB_INLINE bool envoy_service_load_stats_v3_LoadStatsRequest_has_node(const envoy_service_load_stats_v3_LoadStatsRequest *msg) { return _upb_hasbit(msg, 1); }
+UPB_INLINE const struct envoy_config_core_v3_Node* envoy_service_load_stats_v3_LoadStatsRequest_node(const envoy_service_load_stats_v3_LoadStatsRequest *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(4, 8), const struct envoy_config_core_v3_Node*); }
+UPB_INLINE bool envoy_service_load_stats_v3_LoadStatsRequest_has_cluster_stats(const envoy_service_load_stats_v3_LoadStatsRequest *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(8, 16)); }
+UPB_INLINE const struct envoy_config_endpoint_v3_ClusterStats* const* envoy_service_load_stats_v3_LoadStatsRequest_cluster_stats(const envoy_service_load_stats_v3_LoadStatsRequest *msg, size_t *len) { return (const struct envoy_config_endpoint_v3_ClusterStats* const*)_upb_array_accessor(msg, UPB_SIZE(8, 16), len); }
 
 UPB_INLINE void envoy_service_load_stats_v3_LoadStatsRequest_set_node(envoy_service_load_stats_v3_LoadStatsRequest *msg, struct envoy_config_core_v3_Node* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(0, 0), struct envoy_config_core_v3_Node*) = value;
+  _upb_sethas(msg, 1);
+  *UPB_PTR_AT(msg, UPB_SIZE(4, 8), struct envoy_config_core_v3_Node*) = value;
 }
 UPB_INLINE struct envoy_config_core_v3_Node* envoy_service_load_stats_v3_LoadStatsRequest_mutable_node(envoy_service_load_stats_v3_LoadStatsRequest *msg, upb_arena *arena) {
   struct envoy_config_core_v3_Node* sub = (struct envoy_config_core_v3_Node*)envoy_service_load_stats_v3_LoadStatsRequest_node(msg);
@@ -65,15 +73,15 @@ UPB_INLINE struct envoy_config_core_v3_Node* envoy_service_load_stats_v3_LoadSta
   return sub;
 }
 UPB_INLINE struct envoy_config_endpoint_v3_ClusterStats** envoy_service_load_stats_v3_LoadStatsRequest_mutable_cluster_stats(envoy_service_load_stats_v3_LoadStatsRequest *msg, size_t *len) {
-  return (struct envoy_config_endpoint_v3_ClusterStats**)_upb_array_mutable_accessor(msg, UPB_SIZE(4, 8), len);
+  return (struct envoy_config_endpoint_v3_ClusterStats**)_upb_array_mutable_accessor(msg, UPB_SIZE(8, 16), len);
 }
 UPB_INLINE struct envoy_config_endpoint_v3_ClusterStats** envoy_service_load_stats_v3_LoadStatsRequest_resize_cluster_stats(envoy_service_load_stats_v3_LoadStatsRequest *msg, size_t len, upb_arena *arena) {
-  return (struct envoy_config_endpoint_v3_ClusterStats**)_upb_array_resize_accessor(msg, UPB_SIZE(4, 8), len, UPB_TYPE_MESSAGE, arena);
+  return (struct envoy_config_endpoint_v3_ClusterStats**)_upb_array_resize_accessor2(msg, UPB_SIZE(8, 16), len, UPB_SIZE(2, 3), arena);
 }
 UPB_INLINE struct envoy_config_endpoint_v3_ClusterStats* envoy_service_load_stats_v3_LoadStatsRequest_add_cluster_stats(envoy_service_load_stats_v3_LoadStatsRequest *msg, upb_arena *arena) {
   struct envoy_config_endpoint_v3_ClusterStats* sub = (struct envoy_config_endpoint_v3_ClusterStats*)_upb_msg_new(&envoy_config_endpoint_v3_ClusterStats_msginit, arena);
-  bool ok = _upb_array_append_accessor(
-      msg, UPB_SIZE(4, 8), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena);
+  bool ok = _upb_array_append_accessor2(
+      msg, UPB_SIZE(8, 16), UPB_SIZE(2, 3), &sub, arena);
   if (!ok) return NULL;
   return sub;
 }
@@ -88,27 +96,34 @@ UPB_INLINE envoy_service_load_stats_v3_LoadStatsResponse *envoy_service_load_sta
   envoy_service_load_stats_v3_LoadStatsResponse *ret = envoy_service_load_stats_v3_LoadStatsResponse_new(arena);
   return (ret && upb_decode(buf, size, ret, &envoy_service_load_stats_v3_LoadStatsResponse_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE envoy_service_load_stats_v3_LoadStatsResponse *envoy_service_load_stats_v3_LoadStatsResponse_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  envoy_service_load_stats_v3_LoadStatsResponse *ret = envoy_service_load_stats_v3_LoadStatsResponse_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &envoy_service_load_stats_v3_LoadStatsResponse_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *envoy_service_load_stats_v3_LoadStatsResponse_serialize(const envoy_service_load_stats_v3_LoadStatsResponse *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &envoy_service_load_stats_v3_LoadStatsResponse_msginit, arena, len);
 }
 
 UPB_INLINE upb_strview const* envoy_service_load_stats_v3_LoadStatsResponse_clusters(const envoy_service_load_stats_v3_LoadStatsResponse *msg, size_t *len) { return (upb_strview const*)_upb_array_accessor(msg, UPB_SIZE(8, 16), len); }
-UPB_INLINE bool envoy_service_load_stats_v3_LoadStatsResponse_has_load_reporting_interval(const envoy_service_load_stats_v3_LoadStatsResponse *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(4, 8)); }
+UPB_INLINE bool envoy_service_load_stats_v3_LoadStatsResponse_has_load_reporting_interval(const envoy_service_load_stats_v3_LoadStatsResponse *msg) { return _upb_hasbit(msg, 1); }
 UPB_INLINE const struct google_protobuf_Duration* envoy_service_load_stats_v3_LoadStatsResponse_load_reporting_interval(const envoy_service_load_stats_v3_LoadStatsResponse *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(4, 8), const struct google_protobuf_Duration*); }
-UPB_INLINE bool envoy_service_load_stats_v3_LoadStatsResponse_report_endpoint_granularity(const envoy_service_load_stats_v3_LoadStatsResponse *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(0, 0), bool); }
-UPB_INLINE bool envoy_service_load_stats_v3_LoadStatsResponse_send_all_clusters(const envoy_service_load_stats_v3_LoadStatsResponse *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(1, 1), bool); }
+UPB_INLINE bool envoy_service_load_stats_v3_LoadStatsResponse_report_endpoint_granularity(const envoy_service_load_stats_v3_LoadStatsResponse *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(1, 1), bool); }
+UPB_INLINE bool envoy_service_load_stats_v3_LoadStatsResponse_send_all_clusters(const envoy_service_load_stats_v3_LoadStatsResponse *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(2, 2), bool); }
 
 UPB_INLINE upb_strview* envoy_service_load_stats_v3_LoadStatsResponse_mutable_clusters(envoy_service_load_stats_v3_LoadStatsResponse *msg, size_t *len) {
   return (upb_strview*)_upb_array_mutable_accessor(msg, UPB_SIZE(8, 16), len);
 }
 UPB_INLINE upb_strview* envoy_service_load_stats_v3_LoadStatsResponse_resize_clusters(envoy_service_load_stats_v3_LoadStatsResponse *msg, size_t len, upb_arena *arena) {
-  return (upb_strview*)_upb_array_resize_accessor(msg, UPB_SIZE(8, 16), len, UPB_TYPE_STRING, arena);
+  return (upb_strview*)_upb_array_resize_accessor2(msg, UPB_SIZE(8, 16), len, UPB_SIZE(3, 4), arena);
 }
 UPB_INLINE bool envoy_service_load_stats_v3_LoadStatsResponse_add_clusters(envoy_service_load_stats_v3_LoadStatsResponse *msg, upb_strview val, upb_arena *arena) {
-  return _upb_array_append_accessor(msg, UPB_SIZE(8, 16), UPB_SIZE(8, 16), UPB_TYPE_STRING, &val,
+  return _upb_array_append_accessor2(msg, UPB_SIZE(8, 16), UPB_SIZE(3, 4), &val,
       arena);
 }
 UPB_INLINE void envoy_service_load_stats_v3_LoadStatsResponse_set_load_reporting_interval(envoy_service_load_stats_v3_LoadStatsResponse *msg, struct google_protobuf_Duration* value) {
+  _upb_sethas(msg, 1);
   *UPB_PTR_AT(msg, UPB_SIZE(4, 8), struct google_protobuf_Duration*) = value;
 }
 UPB_INLINE struct google_protobuf_Duration* envoy_service_load_stats_v3_LoadStatsResponse_mutable_load_reporting_interval(envoy_service_load_stats_v3_LoadStatsResponse *msg, upb_arena *arena) {
@@ -121,10 +136,10 @@ UPB_INLINE struct google_protobuf_Duration* envoy_service_load_stats_v3_LoadStat
   return sub;
 }
 UPB_INLINE void envoy_service_load_stats_v3_LoadStatsResponse_set_report_endpoint_granularity(envoy_service_load_stats_v3_LoadStatsResponse *msg, bool value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(0, 0), bool) = value;
+  *UPB_PTR_AT(msg, UPB_SIZE(1, 1), bool) = value;
 }
 UPB_INLINE void envoy_service_load_stats_v3_LoadStatsResponse_set_send_all_clusters(envoy_service_load_stats_v3_LoadStatsResponse *msg, bool value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(1, 1), bool) = value;
+  *UPB_PTR_AT(msg, UPB_SIZE(2, 2), bool) = value;
 }
 
 #ifdef __cplusplus
index 56e83f9..93970b1 100644 (file)
@@ -22,7 +22,7 @@
 const upb_msglayout envoy_service_route_v3_RdsDummy_msginit = {
   NULL,
   NULL,
-  UPB_SIZE(0, 0), 0, false,
+  UPB_SIZE(0, 0), 0, false, 255,
 };
 
 #include "upb/port_undef.inc"
index c7e4fa4..40a6d42 100644 (file)
@@ -11,6 +11,7 @@
 
 #include "upb/msg.h"
 #include "upb/decode.h"
+#include "upb/decode_fast.h"
 #include "upb/encode.h"
 
 #include "upb/port_def.inc"
@@ -34,6 +35,12 @@ UPB_INLINE envoy_service_route_v3_RdsDummy *envoy_service_route_v3_RdsDummy_pars
   envoy_service_route_v3_RdsDummy *ret = envoy_service_route_v3_RdsDummy_new(arena);
   return (ret && upb_decode(buf, size, ret, &envoy_service_route_v3_RdsDummy_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE envoy_service_route_v3_RdsDummy *envoy_service_route_v3_RdsDummy_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  envoy_service_route_v3_RdsDummy *ret = envoy_service_route_v3_RdsDummy_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &envoy_service_route_v3_RdsDummy_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *envoy_service_route_v3_RdsDummy_serialize(const envoy_service_route_v3_RdsDummy *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &envoy_service_route_v3_RdsDummy_msginit, arena, len);
 }
index 1214537..6dbaa81 100644 (file)
@@ -20,7 +20,7 @@
 const upb_msglayout envoy_service_route_v3_SrdsDummy_msginit = {
   NULL,
   NULL,
-  UPB_SIZE(0, 0), 0, false,
+  UPB_SIZE(0, 0), 0, false, 255,
 };
 
 #include "upb/port_undef.inc"
index 504cffc..e86154b 100644 (file)
@@ -11,6 +11,7 @@
 
 #include "upb/msg.h"
 #include "upb/decode.h"
+#include "upb/decode_fast.h"
 #include "upb/encode.h"
 
 #include "upb/port_def.inc"
@@ -34,6 +35,12 @@ UPB_INLINE envoy_service_route_v3_SrdsDummy *envoy_service_route_v3_SrdsDummy_pa
   envoy_service_route_v3_SrdsDummy *ret = envoy_service_route_v3_SrdsDummy_new(arena);
   return (ret && upb_decode(buf, size, ret, &envoy_service_route_v3_SrdsDummy_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE envoy_service_route_v3_SrdsDummy *envoy_service_route_v3_SrdsDummy_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  envoy_service_route_v3_SrdsDummy *ret = envoy_service_route_v3_SrdsDummy_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &envoy_service_route_v3_SrdsDummy_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *envoy_service_route_v3_SrdsDummy_serialize(const envoy_service_route_v3_SrdsDummy *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &envoy_service_route_v3_SrdsDummy_msginit, arena, len);
 }
index e5e4720..7fdf5b9 100644 (file)
@@ -22,15 +22,15 @@ static const upb_msglayout *const envoy_type_matcher_v3_MetadataMatcher_submsgs[
 };
 
 static const upb_msglayout_field envoy_type_matcher_v3_MetadataMatcher__fields[3] = {
-  {1, UPB_SIZE(0, 0), 0, 0, 9, 1},
-  {2, UPB_SIZE(12, 24), 0, 0, 11, 3},
-  {3, UPB_SIZE(8, 16), 0, 1, 11, 1},
+  {1, UPB_SIZE(4, 8), 0, 0, 9, 1},
+  {2, UPB_SIZE(16, 32), 0, 0, 11, 3},
+  {3, UPB_SIZE(12, 24), 1, 1, 11, 1},
 };
 
 const upb_msglayout envoy_type_matcher_v3_MetadataMatcher_msginit = {
   &envoy_type_matcher_v3_MetadataMatcher_submsgs[0],
   &envoy_type_matcher_v3_MetadataMatcher__fields[0],
-  UPB_SIZE(16, 32), 3, false,
+  UPB_SIZE(24, 48), 3, false, 255,
 };
 
 static const upb_msglayout_field envoy_type_matcher_v3_MetadataMatcher_PathSegment__fields[1] = {
@@ -40,7 +40,7 @@ static const upb_msglayout_field envoy_type_matcher_v3_MetadataMatcher_PathSegme
 const upb_msglayout envoy_type_matcher_v3_MetadataMatcher_PathSegment_msginit = {
   NULL,
   &envoy_type_matcher_v3_MetadataMatcher_PathSegment__fields[0],
-  UPB_SIZE(16, 32), 1, false,
+  UPB_SIZE(16, 32), 1, false, 255,
 };
 
 #include "upb/port_undef.inc"
index 71111ff..a7f17c1 100644 (file)
@@ -11,6 +11,7 @@
 
 #include "upb/msg.h"
 #include "upb/decode.h"
+#include "upb/decode_fast.h"
 #include "upb/encode.h"
 
 #include "upb/port_def.inc"
@@ -39,34 +40,41 @@ UPB_INLINE envoy_type_matcher_v3_MetadataMatcher *envoy_type_matcher_v3_Metadata
   envoy_type_matcher_v3_MetadataMatcher *ret = envoy_type_matcher_v3_MetadataMatcher_new(arena);
   return (ret && upb_decode(buf, size, ret, &envoy_type_matcher_v3_MetadataMatcher_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE envoy_type_matcher_v3_MetadataMatcher *envoy_type_matcher_v3_MetadataMatcher_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  envoy_type_matcher_v3_MetadataMatcher *ret = envoy_type_matcher_v3_MetadataMatcher_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &envoy_type_matcher_v3_MetadataMatcher_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *envoy_type_matcher_v3_MetadataMatcher_serialize(const envoy_type_matcher_v3_MetadataMatcher *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &envoy_type_matcher_v3_MetadataMatcher_msginit, arena, len);
 }
 
-UPB_INLINE upb_strview envoy_type_matcher_v3_MetadataMatcher_filter(const envoy_type_matcher_v3_MetadataMatcher *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(0, 0), upb_strview); }
-UPB_INLINE bool envoy_type_matcher_v3_MetadataMatcher_has_path(const envoy_type_matcher_v3_MetadataMatcher *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(12, 24)); }
-UPB_INLINE const envoy_type_matcher_v3_MetadataMatcher_PathSegment* const* envoy_type_matcher_v3_MetadataMatcher_path(const envoy_type_matcher_v3_MetadataMatcher *msg, size_t *len) { return (const envoy_type_matcher_v3_MetadataMatcher_PathSegment* const*)_upb_array_accessor(msg, UPB_SIZE(12, 24), len); }
-UPB_INLINE bool envoy_type_matcher_v3_MetadataMatcher_has_value(const envoy_type_matcher_v3_MetadataMatcher *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(8, 16)); }
-UPB_INLINE const struct envoy_type_matcher_v3_ValueMatcher* envoy_type_matcher_v3_MetadataMatcher_value(const envoy_type_matcher_v3_MetadataMatcher *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(8, 16), const struct envoy_type_matcher_v3_ValueMatcher*); }
+UPB_INLINE upb_strview envoy_type_matcher_v3_MetadataMatcher_filter(const envoy_type_matcher_v3_MetadataMatcher *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(4, 8), upb_strview); }
+UPB_INLINE bool envoy_type_matcher_v3_MetadataMatcher_has_path(const envoy_type_matcher_v3_MetadataMatcher *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(16, 32)); }
+UPB_INLINE const envoy_type_matcher_v3_MetadataMatcher_PathSegment* const* envoy_type_matcher_v3_MetadataMatcher_path(const envoy_type_matcher_v3_MetadataMatcher *msg, size_t *len) { return (const envoy_type_matcher_v3_MetadataMatcher_PathSegment* const*)_upb_array_accessor(msg, UPB_SIZE(16, 32), len); }
+UPB_INLINE bool envoy_type_matcher_v3_MetadataMatcher_has_value(const envoy_type_matcher_v3_MetadataMatcher *msg) { return _upb_hasbit(msg, 1); }
+UPB_INLINE const struct envoy_type_matcher_v3_ValueMatcher* envoy_type_matcher_v3_MetadataMatcher_value(const envoy_type_matcher_v3_MetadataMatcher *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(12, 24), const struct envoy_type_matcher_v3_ValueMatcher*); }
 
 UPB_INLINE void envoy_type_matcher_v3_MetadataMatcher_set_filter(envoy_type_matcher_v3_MetadataMatcher *msg, upb_strview value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(0, 0), upb_strview) = value;
+  *UPB_PTR_AT(msg, UPB_SIZE(4, 8), upb_strview) = value;
 }
 UPB_INLINE envoy_type_matcher_v3_MetadataMatcher_PathSegment** envoy_type_matcher_v3_MetadataMatcher_mutable_path(envoy_type_matcher_v3_MetadataMatcher *msg, size_t *len) {
-  return (envoy_type_matcher_v3_MetadataMatcher_PathSegment**)_upb_array_mutable_accessor(msg, UPB_SIZE(12, 24), len);
+  return (envoy_type_matcher_v3_MetadataMatcher_PathSegment**)_upb_array_mutable_accessor(msg, UPB_SIZE(16, 32), len);
 }
 UPB_INLINE envoy_type_matcher_v3_MetadataMatcher_PathSegment** envoy_type_matcher_v3_MetadataMatcher_resize_path(envoy_type_matcher_v3_MetadataMatcher *msg, size_t len, upb_arena *arena) {
-  return (envoy_type_matcher_v3_MetadataMatcher_PathSegment**)_upb_array_resize_accessor(msg, UPB_SIZE(12, 24), len, UPB_TYPE_MESSAGE, arena);
+  return (envoy_type_matcher_v3_MetadataMatcher_PathSegment**)_upb_array_resize_accessor2(msg, UPB_SIZE(16, 32), len, UPB_SIZE(2, 3), arena);
 }
 UPB_INLINE struct envoy_type_matcher_v3_MetadataMatcher_PathSegment* envoy_type_matcher_v3_MetadataMatcher_add_path(envoy_type_matcher_v3_MetadataMatcher *msg, upb_arena *arena) {
   struct envoy_type_matcher_v3_MetadataMatcher_PathSegment* sub = (struct envoy_type_matcher_v3_MetadataMatcher_PathSegment*)_upb_msg_new(&envoy_type_matcher_v3_MetadataMatcher_PathSegment_msginit, arena);
-  bool ok = _upb_array_append_accessor(
-      msg, UPB_SIZE(12, 24), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena);
+  bool ok = _upb_array_append_accessor2(
+      msg, UPB_SIZE(16, 32), UPB_SIZE(2, 3), &sub, arena);
   if (!ok) return NULL;
   return sub;
 }
 UPB_INLINE void envoy_type_matcher_v3_MetadataMatcher_set_value(envoy_type_matcher_v3_MetadataMatcher *msg, struct envoy_type_matcher_v3_ValueMatcher* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(8, 16), struct envoy_type_matcher_v3_ValueMatcher*) = value;
+  _upb_sethas(msg, 1);
+  *UPB_PTR_AT(msg, UPB_SIZE(12, 24), struct envoy_type_matcher_v3_ValueMatcher*) = value;
 }
 UPB_INLINE struct envoy_type_matcher_v3_ValueMatcher* envoy_type_matcher_v3_MetadataMatcher_mutable_value(envoy_type_matcher_v3_MetadataMatcher *msg, upb_arena *arena) {
   struct envoy_type_matcher_v3_ValueMatcher* sub = (struct envoy_type_matcher_v3_ValueMatcher*)envoy_type_matcher_v3_MetadataMatcher_value(msg);
@@ -88,6 +96,12 @@ UPB_INLINE envoy_type_matcher_v3_MetadataMatcher_PathSegment *envoy_type_matcher
   envoy_type_matcher_v3_MetadataMatcher_PathSegment *ret = envoy_type_matcher_v3_MetadataMatcher_PathSegment_new(arena);
   return (ret && upb_decode(buf, size, ret, &envoy_type_matcher_v3_MetadataMatcher_PathSegment_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE envoy_type_matcher_v3_MetadataMatcher_PathSegment *envoy_type_matcher_v3_MetadataMatcher_PathSegment_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  envoy_type_matcher_v3_MetadataMatcher_PathSegment *ret = envoy_type_matcher_v3_MetadataMatcher_PathSegment_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &envoy_type_matcher_v3_MetadataMatcher_PathSegment_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *envoy_type_matcher_v3_MetadataMatcher_PathSegment_serialize(const envoy_type_matcher_v3_MetadataMatcher_PathSegment *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &envoy_type_matcher_v3_MetadataMatcher_PathSegment_msginit, arena, len);
 }
index 7d61b98..516755b 100644 (file)
@@ -28,7 +28,7 @@ static const upb_msglayout_field envoy_type_matcher_v3_DoubleMatcher__fields[2]
 const upb_msglayout envoy_type_matcher_v3_DoubleMatcher_msginit = {
   &envoy_type_matcher_v3_DoubleMatcher_submsgs[0],
   &envoy_type_matcher_v3_DoubleMatcher__fields[0],
-  UPB_SIZE(16, 16), 2, false,
+  UPB_SIZE(16, 16), 2, false, 255,
 };
 
 #include "upb/port_undef.inc"
index a6112da..ebca303 100644 (file)
@@ -11,6 +11,7 @@
 
 #include "upb/msg.h"
 #include "upb/decode.h"
+#include "upb/decode_fast.h"
 #include "upb/encode.h"
 
 #include "upb/port_def.inc"
@@ -36,6 +37,12 @@ UPB_INLINE envoy_type_matcher_v3_DoubleMatcher *envoy_type_matcher_v3_DoubleMatc
   envoy_type_matcher_v3_DoubleMatcher *ret = envoy_type_matcher_v3_DoubleMatcher_new(arena);
   return (ret && upb_decode(buf, size, ret, &envoy_type_matcher_v3_DoubleMatcher_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE envoy_type_matcher_v3_DoubleMatcher *envoy_type_matcher_v3_DoubleMatcher_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  envoy_type_matcher_v3_DoubleMatcher *ret = envoy_type_matcher_v3_DoubleMatcher_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &envoy_type_matcher_v3_DoubleMatcher_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *envoy_type_matcher_v3_DoubleMatcher_serialize(const envoy_type_matcher_v3_DoubleMatcher *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &envoy_type_matcher_v3_DoubleMatcher_msginit, arena, len);
 }
index 0f0f080..caef339 100644 (file)
@@ -27,7 +27,7 @@ static const upb_msglayout_field envoy_type_matcher_v3_PathMatcher__fields[1] =
 const upb_msglayout envoy_type_matcher_v3_PathMatcher_msginit = {
   &envoy_type_matcher_v3_PathMatcher_submsgs[0],
   &envoy_type_matcher_v3_PathMatcher__fields[0],
-  UPB_SIZE(8, 16), 1, false,
+  UPB_SIZE(8, 16), 1, false, 255,
 };
 
 #include "upb/port_undef.inc"
index fb9910f..defbcf0 100644 (file)
@@ -11,6 +11,7 @@
 
 #include "upb/msg.h"
 #include "upb/decode.h"
+#include "upb/decode_fast.h"
 #include "upb/encode.h"
 
 #include "upb/port_def.inc"
@@ -36,6 +37,12 @@ UPB_INLINE envoy_type_matcher_v3_PathMatcher *envoy_type_matcher_v3_PathMatcher_
   envoy_type_matcher_v3_PathMatcher *ret = envoy_type_matcher_v3_PathMatcher_new(arena);
   return (ret && upb_decode(buf, size, ret, &envoy_type_matcher_v3_PathMatcher_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE envoy_type_matcher_v3_PathMatcher *envoy_type_matcher_v3_PathMatcher_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  envoy_type_matcher_v3_PathMatcher *ret = envoy_type_matcher_v3_PathMatcher_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &envoy_type_matcher_v3_PathMatcher_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *envoy_type_matcher_v3_PathMatcher_serialize(const envoy_type_matcher_v3_PathMatcher *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &envoy_type_matcher_v3_PathMatcher_msginit, arena, len);
 }
index ba64257..1e4232b 100644 (file)
@@ -28,7 +28,7 @@ static const upb_msglayout_field envoy_type_matcher_v3_RegexMatcher__fields[2] =
 const upb_msglayout envoy_type_matcher_v3_RegexMatcher_msginit = {
   &envoy_type_matcher_v3_RegexMatcher_submsgs[0],
   &envoy_type_matcher_v3_RegexMatcher__fields[0],
-  UPB_SIZE(16, 32), 2, false,
+  UPB_SIZE(16, 32), 2, false, 255,
 };
 
 static const upb_msglayout *const envoy_type_matcher_v3_RegexMatcher_GoogleRE2_submsgs[1] = {
@@ -36,13 +36,13 @@ static const upb_msglayout *const envoy_type_matcher_v3_RegexMatcher_GoogleRE2_s
 };
 
 static const upb_msglayout_field envoy_type_matcher_v3_RegexMatcher_GoogleRE2__fields[1] = {
-  {1, UPB_SIZE(0, 0), 0, 0, 11, 1},
+  {1, UPB_SIZE(4, 8), 1, 0, 11, 1},
 };
 
 const upb_msglayout envoy_type_matcher_v3_RegexMatcher_GoogleRE2_msginit = {
   &envoy_type_matcher_v3_RegexMatcher_GoogleRE2_submsgs[0],
   &envoy_type_matcher_v3_RegexMatcher_GoogleRE2__fields[0],
-  UPB_SIZE(4, 8), 1, false,
+  UPB_SIZE(8, 16), 1, false, 255,
 };
 
 static const upb_msglayout *const envoy_type_matcher_v3_RegexMatchAndSubstitute_submsgs[1] = {
@@ -50,14 +50,14 @@ static const upb_msglayout *const envoy_type_matcher_v3_RegexMatchAndSubstitute_
 };
 
 static const upb_msglayout_field envoy_type_matcher_v3_RegexMatchAndSubstitute__fields[2] = {
-  {1, UPB_SIZE(8, 16), 0, 0, 11, 1},
-  {2, UPB_SIZE(0, 0), 0, 0, 9, 1},
+  {1, UPB_SIZE(12, 24), 1, 0, 11, 1},
+  {2, UPB_SIZE(4, 8), 0, 0, 9, 1},
 };
 
 const upb_msglayout envoy_type_matcher_v3_RegexMatchAndSubstitute_msginit = {
   &envoy_type_matcher_v3_RegexMatchAndSubstitute_submsgs[0],
   &envoy_type_matcher_v3_RegexMatchAndSubstitute__fields[0],
-  UPB_SIZE(16, 32), 2, false,
+  UPB_SIZE(16, 32), 2, false, 255,
 };
 
 #include "upb/port_undef.inc"
index def56ed..5e00d13 100644 (file)
@@ -11,6 +11,7 @@
 
 #include "upb/msg.h"
 #include "upb/decode.h"
+#include "upb/decode_fast.h"
 #include "upb/encode.h"
 
 #include "upb/port_def.inc"
@@ -42,6 +43,12 @@ UPB_INLINE envoy_type_matcher_v3_RegexMatcher *envoy_type_matcher_v3_RegexMatche
   envoy_type_matcher_v3_RegexMatcher *ret = envoy_type_matcher_v3_RegexMatcher_new(arena);
   return (ret && upb_decode(buf, size, ret, &envoy_type_matcher_v3_RegexMatcher_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE envoy_type_matcher_v3_RegexMatcher *envoy_type_matcher_v3_RegexMatcher_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  envoy_type_matcher_v3_RegexMatcher *ret = envoy_type_matcher_v3_RegexMatcher_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &envoy_type_matcher_v3_RegexMatcher_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *envoy_type_matcher_v3_RegexMatcher_serialize(const envoy_type_matcher_v3_RegexMatcher *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &envoy_type_matcher_v3_RegexMatcher_msginit, arena, len);
 }
@@ -82,15 +89,22 @@ UPB_INLINE envoy_type_matcher_v3_RegexMatcher_GoogleRE2 *envoy_type_matcher_v3_R
   envoy_type_matcher_v3_RegexMatcher_GoogleRE2 *ret = envoy_type_matcher_v3_RegexMatcher_GoogleRE2_new(arena);
   return (ret && upb_decode(buf, size, ret, &envoy_type_matcher_v3_RegexMatcher_GoogleRE2_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE envoy_type_matcher_v3_RegexMatcher_GoogleRE2 *envoy_type_matcher_v3_RegexMatcher_GoogleRE2_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  envoy_type_matcher_v3_RegexMatcher_GoogleRE2 *ret = envoy_type_matcher_v3_RegexMatcher_GoogleRE2_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &envoy_type_matcher_v3_RegexMatcher_GoogleRE2_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *envoy_type_matcher_v3_RegexMatcher_GoogleRE2_serialize(const envoy_type_matcher_v3_RegexMatcher_GoogleRE2 *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &envoy_type_matcher_v3_RegexMatcher_GoogleRE2_msginit, arena, len);
 }
 
-UPB_INLINE bool envoy_type_matcher_v3_RegexMatcher_GoogleRE2_has_max_program_size(const envoy_type_matcher_v3_RegexMatcher_GoogleRE2 *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(0, 0)); }
-UPB_INLINE const struct google_protobuf_UInt32Value* envoy_type_matcher_v3_RegexMatcher_GoogleRE2_max_program_size(const envoy_type_matcher_v3_RegexMatcher_GoogleRE2 *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(0, 0), const struct google_protobuf_UInt32Value*); }
+UPB_INLINE bool envoy_type_matcher_v3_RegexMatcher_GoogleRE2_has_max_program_size(const envoy_type_matcher_v3_RegexMatcher_GoogleRE2 *msg) { return _upb_hasbit(msg, 1); }
+UPB_INLINE const struct google_protobuf_UInt32Value* envoy_type_matcher_v3_RegexMatcher_GoogleRE2_max_program_size(const envoy_type_matcher_v3_RegexMatcher_GoogleRE2 *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(4, 8), const struct google_protobuf_UInt32Value*); }
 
 UPB_INLINE void envoy_type_matcher_v3_RegexMatcher_GoogleRE2_set_max_program_size(envoy_type_matcher_v3_RegexMatcher_GoogleRE2 *msg, struct google_protobuf_UInt32Value* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(0, 0), struct google_protobuf_UInt32Value*) = value;
+  _upb_sethas(msg, 1);
+  *UPB_PTR_AT(msg, UPB_SIZE(4, 8), struct google_protobuf_UInt32Value*) = value;
 }
 UPB_INLINE struct google_protobuf_UInt32Value* envoy_type_matcher_v3_RegexMatcher_GoogleRE2_mutable_max_program_size(envoy_type_matcher_v3_RegexMatcher_GoogleRE2 *msg, upb_arena *arena) {
   struct google_protobuf_UInt32Value* sub = (struct google_protobuf_UInt32Value*)envoy_type_matcher_v3_RegexMatcher_GoogleRE2_max_program_size(msg);
@@ -112,16 +126,23 @@ UPB_INLINE envoy_type_matcher_v3_RegexMatchAndSubstitute *envoy_type_matcher_v3_
   envoy_type_matcher_v3_RegexMatchAndSubstitute *ret = envoy_type_matcher_v3_RegexMatchAndSubstitute_new(arena);
   return (ret && upb_decode(buf, size, ret, &envoy_type_matcher_v3_RegexMatchAndSubstitute_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE envoy_type_matcher_v3_RegexMatchAndSubstitute *envoy_type_matcher_v3_RegexMatchAndSubstitute_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  envoy_type_matcher_v3_RegexMatchAndSubstitute *ret = envoy_type_matcher_v3_RegexMatchAndSubstitute_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &envoy_type_matcher_v3_RegexMatchAndSubstitute_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *envoy_type_matcher_v3_RegexMatchAndSubstitute_serialize(const envoy_type_matcher_v3_RegexMatchAndSubstitute *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &envoy_type_matcher_v3_RegexMatchAndSubstitute_msginit, arena, len);
 }
 
-UPB_INLINE bool envoy_type_matcher_v3_RegexMatchAndSubstitute_has_pattern(const envoy_type_matcher_v3_RegexMatchAndSubstitute *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(8, 16)); }
-UPB_INLINE const envoy_type_matcher_v3_RegexMatcher* envoy_type_matcher_v3_RegexMatchAndSubstitute_pattern(const envoy_type_matcher_v3_RegexMatchAndSubstitute *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(8, 16), const envoy_type_matcher_v3_RegexMatcher*); }
-UPB_INLINE upb_strview envoy_type_matcher_v3_RegexMatchAndSubstitute_substitution(const envoy_type_matcher_v3_RegexMatchAndSubstitute *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(0, 0), upb_strview); }
+UPB_INLINE bool envoy_type_matcher_v3_RegexMatchAndSubstitute_has_pattern(const envoy_type_matcher_v3_RegexMatchAndSubstitute *msg) { return _upb_hasbit(msg, 1); }
+UPB_INLINE const envoy_type_matcher_v3_RegexMatcher* envoy_type_matcher_v3_RegexMatchAndSubstitute_pattern(const envoy_type_matcher_v3_RegexMatchAndSubstitute *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(12, 24), const envoy_type_matcher_v3_RegexMatcher*); }
+UPB_INLINE upb_strview envoy_type_matcher_v3_RegexMatchAndSubstitute_substitution(const envoy_type_matcher_v3_RegexMatchAndSubstitute *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(4, 8), upb_strview); }
 
 UPB_INLINE void envoy_type_matcher_v3_RegexMatchAndSubstitute_set_pattern(envoy_type_matcher_v3_RegexMatchAndSubstitute *msg, envoy_type_matcher_v3_RegexMatcher* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(8, 16), envoy_type_matcher_v3_RegexMatcher*) = value;
+  _upb_sethas(msg, 1);
+  *UPB_PTR_AT(msg, UPB_SIZE(12, 24), envoy_type_matcher_v3_RegexMatcher*) = value;
 }
 UPB_INLINE struct envoy_type_matcher_v3_RegexMatcher* envoy_type_matcher_v3_RegexMatchAndSubstitute_mutable_pattern(envoy_type_matcher_v3_RegexMatchAndSubstitute *msg, upb_arena *arena) {
   struct envoy_type_matcher_v3_RegexMatcher* sub = (struct envoy_type_matcher_v3_RegexMatcher*)envoy_type_matcher_v3_RegexMatchAndSubstitute_pattern(msg);
@@ -133,7 +154,7 @@ UPB_INLINE struct envoy_type_matcher_v3_RegexMatcher* envoy_type_matcher_v3_Rege
   return sub;
 }
 UPB_INLINE void envoy_type_matcher_v3_RegexMatchAndSubstitute_set_substitution(envoy_type_matcher_v3_RegexMatchAndSubstitute *msg, upb_strview value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(0, 0), upb_strview) = value;
+  *UPB_PTR_AT(msg, UPB_SIZE(4, 8), upb_strview) = value;
 }
 
 #ifdef __cplusplus
index 969d45b..073e506 100644 (file)
@@ -33,7 +33,7 @@ static const upb_msglayout_field envoy_type_matcher_v3_StringMatcher__fields[6]
 const upb_msglayout envoy_type_matcher_v3_StringMatcher_msginit = {
   &envoy_type_matcher_v3_StringMatcher_submsgs[0],
   &envoy_type_matcher_v3_StringMatcher__fields[0],
-  UPB_SIZE(16, 32), 6, false,
+  UPB_SIZE(16, 32), 6, false, 255,
 };
 
 static const upb_msglayout *const envoy_type_matcher_v3_ListStringMatcher_submsgs[1] = {
@@ -47,7 +47,7 @@ static const upb_msglayout_field envoy_type_matcher_v3_ListStringMatcher__fields
 const upb_msglayout envoy_type_matcher_v3_ListStringMatcher_msginit = {
   &envoy_type_matcher_v3_ListStringMatcher_submsgs[0],
   &envoy_type_matcher_v3_ListStringMatcher__fields[0],
-  UPB_SIZE(4, 8), 1, false,
+  UPB_SIZE(8, 8), 1, false, 255,
 };
 
 #include "upb/port_undef.inc"
index 760956b..4bce450 100644 (file)
@@ -11,6 +11,7 @@
 
 #include "upb/msg.h"
 #include "upb/decode.h"
+#include "upb/decode_fast.h"
 #include "upb/encode.h"
 
 #include "upb/port_def.inc"
@@ -39,6 +40,12 @@ UPB_INLINE envoy_type_matcher_v3_StringMatcher *envoy_type_matcher_v3_StringMatc
   envoy_type_matcher_v3_StringMatcher *ret = envoy_type_matcher_v3_StringMatcher_new(arena);
   return (ret && upb_decode(buf, size, ret, &envoy_type_matcher_v3_StringMatcher_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE envoy_type_matcher_v3_StringMatcher *envoy_type_matcher_v3_StringMatcher_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  envoy_type_matcher_v3_StringMatcher *ret = envoy_type_matcher_v3_StringMatcher_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &envoy_type_matcher_v3_StringMatcher_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *envoy_type_matcher_v3_StringMatcher_serialize(const envoy_type_matcher_v3_StringMatcher *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &envoy_type_matcher_v3_StringMatcher_msginit, arena, len);
 }
@@ -103,6 +110,12 @@ UPB_INLINE envoy_type_matcher_v3_ListStringMatcher *envoy_type_matcher_v3_ListSt
   envoy_type_matcher_v3_ListStringMatcher *ret = envoy_type_matcher_v3_ListStringMatcher_new(arena);
   return (ret && upb_decode(buf, size, ret, &envoy_type_matcher_v3_ListStringMatcher_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE envoy_type_matcher_v3_ListStringMatcher *envoy_type_matcher_v3_ListStringMatcher_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  envoy_type_matcher_v3_ListStringMatcher *ret = envoy_type_matcher_v3_ListStringMatcher_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &envoy_type_matcher_v3_ListStringMatcher_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *envoy_type_matcher_v3_ListStringMatcher_serialize(const envoy_type_matcher_v3_ListStringMatcher *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &envoy_type_matcher_v3_ListStringMatcher_msginit, arena, len);
 }
@@ -114,12 +127,12 @@ UPB_INLINE envoy_type_matcher_v3_StringMatcher** envoy_type_matcher_v3_ListStrin
   return (envoy_type_matcher_v3_StringMatcher**)_upb_array_mutable_accessor(msg, UPB_SIZE(0, 0), len);
 }
 UPB_INLINE envoy_type_matcher_v3_StringMatcher** envoy_type_matcher_v3_ListStringMatcher_resize_patterns(envoy_type_matcher_v3_ListStringMatcher *msg, size_t len, upb_arena *arena) {
-  return (envoy_type_matcher_v3_StringMatcher**)_upb_array_resize_accessor(msg, UPB_SIZE(0, 0), len, UPB_TYPE_MESSAGE, arena);
+  return (envoy_type_matcher_v3_StringMatcher**)_upb_array_resize_accessor2(msg, UPB_SIZE(0, 0), len, UPB_SIZE(2, 3), arena);
 }
 UPB_INLINE struct envoy_type_matcher_v3_StringMatcher* envoy_type_matcher_v3_ListStringMatcher_add_patterns(envoy_type_matcher_v3_ListStringMatcher *msg, upb_arena *arena) {
   struct envoy_type_matcher_v3_StringMatcher* sub = (struct envoy_type_matcher_v3_StringMatcher*)_upb_msg_new(&envoy_type_matcher_v3_StringMatcher_msginit, arena);
-  bool ok = _upb_array_append_accessor(
-      msg, UPB_SIZE(0, 0), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena);
+  bool ok = _upb_array_append_accessor2(
+      msg, UPB_SIZE(0, 0), UPB_SIZE(2, 3), &sub, arena);
   if (!ok) return NULL;
   return sub;
 }
index a2ab19e..0195307 100644 (file)
@@ -36,13 +36,13 @@ static const upb_msglayout_field envoy_type_matcher_v3_ValueMatcher__fields[6] =
 const upb_msglayout envoy_type_matcher_v3_ValueMatcher_msginit = {
   &envoy_type_matcher_v3_ValueMatcher_submsgs[0],
   &envoy_type_matcher_v3_ValueMatcher__fields[0],
-  UPB_SIZE(8, 16), 6, false,
+  UPB_SIZE(8, 16), 6, false, 255,
 };
 
 const upb_msglayout envoy_type_matcher_v3_ValueMatcher_NullMatch_msginit = {
   NULL,
   NULL,
-  UPB_SIZE(0, 0), 0, false,
+  UPB_SIZE(0, 0), 0, false, 255,
 };
 
 static const upb_msglayout *const envoy_type_matcher_v3_ListMatcher_submsgs[1] = {
@@ -56,7 +56,7 @@ static const upb_msglayout_field envoy_type_matcher_v3_ListMatcher__fields[1] =
 const upb_msglayout envoy_type_matcher_v3_ListMatcher_msginit = {
   &envoy_type_matcher_v3_ListMatcher_submsgs[0],
   &envoy_type_matcher_v3_ListMatcher__fields[0],
-  UPB_SIZE(8, 16), 1, false,
+  UPB_SIZE(8, 16), 1, false, 255,
 };
 
 #include "upb/port_undef.inc"
index 5ff8ccd..dc44445 100644 (file)
@@ -11,6 +11,7 @@
 
 #include "upb/msg.h"
 #include "upb/decode.h"
+#include "upb/decode_fast.h"
 #include "upb/encode.h"
 
 #include "upb/port_def.inc"
@@ -44,6 +45,12 @@ UPB_INLINE envoy_type_matcher_v3_ValueMatcher *envoy_type_matcher_v3_ValueMatche
   envoy_type_matcher_v3_ValueMatcher *ret = envoy_type_matcher_v3_ValueMatcher_new(arena);
   return (ret && upb_decode(buf, size, ret, &envoy_type_matcher_v3_ValueMatcher_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE envoy_type_matcher_v3_ValueMatcher *envoy_type_matcher_v3_ValueMatcher_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  envoy_type_matcher_v3_ValueMatcher *ret = envoy_type_matcher_v3_ValueMatcher_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &envoy_type_matcher_v3_ValueMatcher_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *envoy_type_matcher_v3_ValueMatcher_serialize(const envoy_type_matcher_v3_ValueMatcher *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &envoy_type_matcher_v3_ValueMatcher_msginit, arena, len);
 }
@@ -137,6 +144,12 @@ UPB_INLINE envoy_type_matcher_v3_ValueMatcher_NullMatch *envoy_type_matcher_v3_V
   envoy_type_matcher_v3_ValueMatcher_NullMatch *ret = envoy_type_matcher_v3_ValueMatcher_NullMatch_new(arena);
   return (ret && upb_decode(buf, size, ret, &envoy_type_matcher_v3_ValueMatcher_NullMatch_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE envoy_type_matcher_v3_ValueMatcher_NullMatch *envoy_type_matcher_v3_ValueMatcher_NullMatch_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  envoy_type_matcher_v3_ValueMatcher_NullMatch *ret = envoy_type_matcher_v3_ValueMatcher_NullMatch_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &envoy_type_matcher_v3_ValueMatcher_NullMatch_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *envoy_type_matcher_v3_ValueMatcher_NullMatch_serialize(const envoy_type_matcher_v3_ValueMatcher_NullMatch *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &envoy_type_matcher_v3_ValueMatcher_NullMatch_msginit, arena, len);
 }
@@ -153,6 +166,12 @@ UPB_INLINE envoy_type_matcher_v3_ListMatcher *envoy_type_matcher_v3_ListMatcher_
   envoy_type_matcher_v3_ListMatcher *ret = envoy_type_matcher_v3_ListMatcher_new(arena);
   return (ret && upb_decode(buf, size, ret, &envoy_type_matcher_v3_ListMatcher_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE envoy_type_matcher_v3_ListMatcher *envoy_type_matcher_v3_ListMatcher_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  envoy_type_matcher_v3_ListMatcher *ret = envoy_type_matcher_v3_ListMatcher_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &envoy_type_matcher_v3_ListMatcher_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *envoy_type_matcher_v3_ListMatcher_serialize(const envoy_type_matcher_v3_ListMatcher *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &envoy_type_matcher_v3_ListMatcher_msginit, arena, len);
 }
index 1dbd48d..e692eda 100644 (file)
@@ -27,7 +27,7 @@ static const upb_msglayout_field envoy_type_metadata_v3_MetadataKey__fields[2] =
 const upb_msglayout envoy_type_metadata_v3_MetadataKey_msginit = {
   &envoy_type_metadata_v3_MetadataKey_submsgs[0],
   &envoy_type_metadata_v3_MetadataKey__fields[0],
-  UPB_SIZE(16, 32), 2, false,
+  UPB_SIZE(16, 32), 2, false, 255,
 };
 
 static const upb_msglayout_field envoy_type_metadata_v3_MetadataKey_PathSegment__fields[1] = {
@@ -37,7 +37,7 @@ static const upb_msglayout_field envoy_type_metadata_v3_MetadataKey_PathSegment_
 const upb_msglayout envoy_type_metadata_v3_MetadataKey_PathSegment_msginit = {
   NULL,
   &envoy_type_metadata_v3_MetadataKey_PathSegment__fields[0],
-  UPB_SIZE(16, 32), 1, false,
+  UPB_SIZE(16, 32), 1, false, 255,
 };
 
 static const upb_msglayout *const envoy_type_metadata_v3_MetadataKind_submsgs[4] = {
@@ -57,31 +57,31 @@ static const upb_msglayout_field envoy_type_metadata_v3_MetadataKind__fields[4]
 const upb_msglayout envoy_type_metadata_v3_MetadataKind_msginit = {
   &envoy_type_metadata_v3_MetadataKind_submsgs[0],
   &envoy_type_metadata_v3_MetadataKind__fields[0],
-  UPB_SIZE(8, 16), 4, false,
+  UPB_SIZE(8, 16), 4, false, 255,
 };
 
 const upb_msglayout envoy_type_metadata_v3_MetadataKind_Request_msginit = {
   NULL,
   NULL,
-  UPB_SIZE(0, 0), 0, false,
+  UPB_SIZE(0, 0), 0, false, 255,
 };
 
 const upb_msglayout envoy_type_metadata_v3_MetadataKind_Route_msginit = {
   NULL,
   NULL,
-  UPB_SIZE(0, 0), 0, false,
+  UPB_SIZE(0, 0), 0, false, 255,
 };
 
 const upb_msglayout envoy_type_metadata_v3_MetadataKind_Cluster_msginit = {
   NULL,
   NULL,
-  UPB_SIZE(0, 0), 0, false,
+  UPB_SIZE(0, 0), 0, false, 255,
 };
 
 const upb_msglayout envoy_type_metadata_v3_MetadataKind_Host_msginit = {
   NULL,
   NULL,
-  UPB_SIZE(0, 0), 0, false,
+  UPB_SIZE(0, 0), 0, false, 255,
 };
 
 #include "upb/port_undef.inc"
index 4aeccf5..83ac93c 100644 (file)
@@ -11,6 +11,7 @@
 
 #include "upb/msg.h"
 #include "upb/decode.h"
+#include "upb/decode_fast.h"
 #include "upb/encode.h"
 
 #include "upb/port_def.inc"
@@ -52,6 +53,12 @@ UPB_INLINE envoy_type_metadata_v3_MetadataKey *envoy_type_metadata_v3_MetadataKe
   envoy_type_metadata_v3_MetadataKey *ret = envoy_type_metadata_v3_MetadataKey_new(arena);
   return (ret && upb_decode(buf, size, ret, &envoy_type_metadata_v3_MetadataKey_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE envoy_type_metadata_v3_MetadataKey *envoy_type_metadata_v3_MetadataKey_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  envoy_type_metadata_v3_MetadataKey *ret = envoy_type_metadata_v3_MetadataKey_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &envoy_type_metadata_v3_MetadataKey_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *envoy_type_metadata_v3_MetadataKey_serialize(const envoy_type_metadata_v3_MetadataKey *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &envoy_type_metadata_v3_MetadataKey_msginit, arena, len);
 }
@@ -67,12 +74,12 @@ UPB_INLINE envoy_type_metadata_v3_MetadataKey_PathSegment** envoy_type_metadata_
   return (envoy_type_metadata_v3_MetadataKey_PathSegment**)_upb_array_mutable_accessor(msg, UPB_SIZE(8, 16), len);
 }
 UPB_INLINE envoy_type_metadata_v3_MetadataKey_PathSegment** envoy_type_metadata_v3_MetadataKey_resize_path(envoy_type_metadata_v3_MetadataKey *msg, size_t len, upb_arena *arena) {
-  return (envoy_type_metadata_v3_MetadataKey_PathSegment**)_upb_array_resize_accessor(msg, UPB_SIZE(8, 16), len, UPB_TYPE_MESSAGE, arena);
+  return (envoy_type_metadata_v3_MetadataKey_PathSegment**)_upb_array_resize_accessor2(msg, UPB_SIZE(8, 16), len, UPB_SIZE(2, 3), arena);
 }
 UPB_INLINE struct envoy_type_metadata_v3_MetadataKey_PathSegment* envoy_type_metadata_v3_MetadataKey_add_path(envoy_type_metadata_v3_MetadataKey *msg, upb_arena *arena) {
   struct envoy_type_metadata_v3_MetadataKey_PathSegment* sub = (struct envoy_type_metadata_v3_MetadataKey_PathSegment*)_upb_msg_new(&envoy_type_metadata_v3_MetadataKey_PathSegment_msginit, arena);
-  bool ok = _upb_array_append_accessor(
-      msg, UPB_SIZE(8, 16), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena);
+  bool ok = _upb_array_append_accessor2(
+      msg, UPB_SIZE(8, 16), UPB_SIZE(2, 3), &sub, arena);
   if (!ok) return NULL;
   return sub;
 }
@@ -87,6 +94,12 @@ UPB_INLINE envoy_type_metadata_v3_MetadataKey_PathSegment *envoy_type_metadata_v
   envoy_type_metadata_v3_MetadataKey_PathSegment *ret = envoy_type_metadata_v3_MetadataKey_PathSegment_new(arena);
   return (ret && upb_decode(buf, size, ret, &envoy_type_metadata_v3_MetadataKey_PathSegment_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE envoy_type_metadata_v3_MetadataKey_PathSegment *envoy_type_metadata_v3_MetadataKey_PathSegment_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  envoy_type_metadata_v3_MetadataKey_PathSegment *ret = envoy_type_metadata_v3_MetadataKey_PathSegment_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &envoy_type_metadata_v3_MetadataKey_PathSegment_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *envoy_type_metadata_v3_MetadataKey_PathSegment_serialize(const envoy_type_metadata_v3_MetadataKey_PathSegment *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &envoy_type_metadata_v3_MetadataKey_PathSegment_msginit, arena, len);
 }
@@ -114,6 +127,12 @@ UPB_INLINE envoy_type_metadata_v3_MetadataKind *envoy_type_metadata_v3_MetadataK
   envoy_type_metadata_v3_MetadataKind *ret = envoy_type_metadata_v3_MetadataKind_new(arena);
   return (ret && upb_decode(buf, size, ret, &envoy_type_metadata_v3_MetadataKind_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE envoy_type_metadata_v3_MetadataKind *envoy_type_metadata_v3_MetadataKind_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  envoy_type_metadata_v3_MetadataKind *ret = envoy_type_metadata_v3_MetadataKind_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &envoy_type_metadata_v3_MetadataKind_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *envoy_type_metadata_v3_MetadataKind_serialize(const envoy_type_metadata_v3_MetadataKind *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &envoy_type_metadata_v3_MetadataKind_msginit, arena, len);
 }
@@ -195,6 +214,12 @@ UPB_INLINE envoy_type_metadata_v3_MetadataKind_Request *envoy_type_metadata_v3_M
   envoy_type_metadata_v3_MetadataKind_Request *ret = envoy_type_metadata_v3_MetadataKind_Request_new(arena);
   return (ret && upb_decode(buf, size, ret, &envoy_type_metadata_v3_MetadataKind_Request_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE envoy_type_metadata_v3_MetadataKind_Request *envoy_type_metadata_v3_MetadataKind_Request_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  envoy_type_metadata_v3_MetadataKind_Request *ret = envoy_type_metadata_v3_MetadataKind_Request_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &envoy_type_metadata_v3_MetadataKind_Request_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *envoy_type_metadata_v3_MetadataKind_Request_serialize(const envoy_type_metadata_v3_MetadataKind_Request *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &envoy_type_metadata_v3_MetadataKind_Request_msginit, arena, len);
 }
@@ -211,6 +236,12 @@ UPB_INLINE envoy_type_metadata_v3_MetadataKind_Route *envoy_type_metadata_v3_Met
   envoy_type_metadata_v3_MetadataKind_Route *ret = envoy_type_metadata_v3_MetadataKind_Route_new(arena);
   return (ret && upb_decode(buf, size, ret, &envoy_type_metadata_v3_MetadataKind_Route_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE envoy_type_metadata_v3_MetadataKind_Route *envoy_type_metadata_v3_MetadataKind_Route_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  envoy_type_metadata_v3_MetadataKind_Route *ret = envoy_type_metadata_v3_MetadataKind_Route_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &envoy_type_metadata_v3_MetadataKind_Route_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *envoy_type_metadata_v3_MetadataKind_Route_serialize(const envoy_type_metadata_v3_MetadataKind_Route *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &envoy_type_metadata_v3_MetadataKind_Route_msginit, arena, len);
 }
@@ -227,6 +258,12 @@ UPB_INLINE envoy_type_metadata_v3_MetadataKind_Cluster *envoy_type_metadata_v3_M
   envoy_type_metadata_v3_MetadataKind_Cluster *ret = envoy_type_metadata_v3_MetadataKind_Cluster_new(arena);
   return (ret && upb_decode(buf, size, ret, &envoy_type_metadata_v3_MetadataKind_Cluster_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE envoy_type_metadata_v3_MetadataKind_Cluster *envoy_type_metadata_v3_MetadataKind_Cluster_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  envoy_type_metadata_v3_MetadataKind_Cluster *ret = envoy_type_metadata_v3_MetadataKind_Cluster_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &envoy_type_metadata_v3_MetadataKind_Cluster_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *envoy_type_metadata_v3_MetadataKind_Cluster_serialize(const envoy_type_metadata_v3_MetadataKind_Cluster *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &envoy_type_metadata_v3_MetadataKind_Cluster_msginit, arena, len);
 }
@@ -243,6 +280,12 @@ UPB_INLINE envoy_type_metadata_v3_MetadataKind_Host *envoy_type_metadata_v3_Meta
   envoy_type_metadata_v3_MetadataKind_Host *ret = envoy_type_metadata_v3_MetadataKind_Host_new(arena);
   return (ret && upb_decode(buf, size, ret, &envoy_type_metadata_v3_MetadataKind_Host_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE envoy_type_metadata_v3_MetadataKind_Host *envoy_type_metadata_v3_MetadataKind_Host_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  envoy_type_metadata_v3_MetadataKind_Host *ret = envoy_type_metadata_v3_MetadataKind_Host_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &envoy_type_metadata_v3_MetadataKind_Host_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *envoy_type_metadata_v3_MetadataKind_Host_serialize(const envoy_type_metadata_v3_MetadataKind_Host *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &envoy_type_metadata_v3_MetadataKind_Host_msginit, arena, len);
 }
index 6db0846..fa53e43 100644 (file)
@@ -34,7 +34,7 @@ static const upb_msglayout_field envoy_type_tracing_v3_CustomTag__fields[5] = {
 const upb_msglayout envoy_type_tracing_v3_CustomTag_msginit = {
   &envoy_type_tracing_v3_CustomTag_submsgs[0],
   &envoy_type_tracing_v3_CustomTag__fields[0],
-  UPB_SIZE(16, 32), 5, false,
+  UPB_SIZE(16, 32), 5, false, 255,
 };
 
 static const upb_msglayout_field envoy_type_tracing_v3_CustomTag_Literal__fields[1] = {
@@ -44,7 +44,7 @@ static const upb_msglayout_field envoy_type_tracing_v3_CustomTag_Literal__fields
 const upb_msglayout envoy_type_tracing_v3_CustomTag_Literal_msginit = {
   NULL,
   &envoy_type_tracing_v3_CustomTag_Literal__fields[0],
-  UPB_SIZE(8, 16), 1, false,
+  UPB_SIZE(8, 16), 1, false, 255,
 };
 
 static const upb_msglayout_field envoy_type_tracing_v3_CustomTag_Environment__fields[2] = {
@@ -55,7 +55,7 @@ static const upb_msglayout_field envoy_type_tracing_v3_CustomTag_Environment__fi
 const upb_msglayout envoy_type_tracing_v3_CustomTag_Environment_msginit = {
   NULL,
   &envoy_type_tracing_v3_CustomTag_Environment__fields[0],
-  UPB_SIZE(16, 32), 2, false,
+  UPB_SIZE(16, 32), 2, false, 255,
 };
 
 static const upb_msglayout_field envoy_type_tracing_v3_CustomTag_Header__fields[2] = {
@@ -66,7 +66,7 @@ static const upb_msglayout_field envoy_type_tracing_v3_CustomTag_Header__fields[
 const upb_msglayout envoy_type_tracing_v3_CustomTag_Header_msginit = {
   NULL,
   &envoy_type_tracing_v3_CustomTag_Header__fields[0],
-  UPB_SIZE(16, 32), 2, false,
+  UPB_SIZE(16, 32), 2, false, 255,
 };
 
 static const upb_msglayout *const envoy_type_tracing_v3_CustomTag_Metadata_submsgs[2] = {
@@ -75,15 +75,15 @@ static const upb_msglayout *const envoy_type_tracing_v3_CustomTag_Metadata_subms
 };
 
 static const upb_msglayout_field envoy_type_tracing_v3_CustomTag_Metadata__fields[3] = {
-  {1, UPB_SIZE(8, 16), 0, 1, 11, 1},
-  {2, UPB_SIZE(12, 24), 0, 0, 11, 1},
-  {3, UPB_SIZE(0, 0), 0, 0, 9, 1},
+  {1, UPB_SIZE(12, 24), 1, 1, 11, 1},
+  {2, UPB_SIZE(16, 32), 2, 0, 11, 1},
+  {3, UPB_SIZE(4, 8), 0, 0, 9, 1},
 };
 
 const upb_msglayout envoy_type_tracing_v3_CustomTag_Metadata_msginit = {
   &envoy_type_tracing_v3_CustomTag_Metadata_submsgs[0],
   &envoy_type_tracing_v3_CustomTag_Metadata__fields[0],
-  UPB_SIZE(16, 32), 3, false,
+  UPB_SIZE(24, 48), 3, false, 255,
 };
 
 #include "upb/port_undef.inc"
index f72eac4..666ed7b 100644 (file)
@@ -11,6 +11,7 @@
 
 #include "upb/msg.h"
 #include "upb/decode.h"
+#include "upb/decode_fast.h"
 #include "upb/encode.h"
 
 #include "upb/port_def.inc"
@@ -50,6 +51,12 @@ UPB_INLINE envoy_type_tracing_v3_CustomTag *envoy_type_tracing_v3_CustomTag_pars
   envoy_type_tracing_v3_CustomTag *ret = envoy_type_tracing_v3_CustomTag_new(arena);
   return (ret && upb_decode(buf, size, ret, &envoy_type_tracing_v3_CustomTag_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE envoy_type_tracing_v3_CustomTag *envoy_type_tracing_v3_CustomTag_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  envoy_type_tracing_v3_CustomTag *ret = envoy_type_tracing_v3_CustomTag_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &envoy_type_tracing_v3_CustomTag_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *envoy_type_tracing_v3_CustomTag_serialize(const envoy_type_tracing_v3_CustomTag *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &envoy_type_tracing_v3_CustomTag_msginit, arena, len);
 }
@@ -135,6 +142,12 @@ UPB_INLINE envoy_type_tracing_v3_CustomTag_Literal *envoy_type_tracing_v3_Custom
   envoy_type_tracing_v3_CustomTag_Literal *ret = envoy_type_tracing_v3_CustomTag_Literal_new(arena);
   return (ret && upb_decode(buf, size, ret, &envoy_type_tracing_v3_CustomTag_Literal_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE envoy_type_tracing_v3_CustomTag_Literal *envoy_type_tracing_v3_CustomTag_Literal_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  envoy_type_tracing_v3_CustomTag_Literal *ret = envoy_type_tracing_v3_CustomTag_Literal_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &envoy_type_tracing_v3_CustomTag_Literal_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *envoy_type_tracing_v3_CustomTag_Literal_serialize(const envoy_type_tracing_v3_CustomTag_Literal *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &envoy_type_tracing_v3_CustomTag_Literal_msginit, arena, len);
 }
@@ -155,6 +168,12 @@ UPB_INLINE envoy_type_tracing_v3_CustomTag_Environment *envoy_type_tracing_v3_Cu
   envoy_type_tracing_v3_CustomTag_Environment *ret = envoy_type_tracing_v3_CustomTag_Environment_new(arena);
   return (ret && upb_decode(buf, size, ret, &envoy_type_tracing_v3_CustomTag_Environment_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE envoy_type_tracing_v3_CustomTag_Environment *envoy_type_tracing_v3_CustomTag_Environment_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  envoy_type_tracing_v3_CustomTag_Environment *ret = envoy_type_tracing_v3_CustomTag_Environment_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &envoy_type_tracing_v3_CustomTag_Environment_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *envoy_type_tracing_v3_CustomTag_Environment_serialize(const envoy_type_tracing_v3_CustomTag_Environment *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &envoy_type_tracing_v3_CustomTag_Environment_msginit, arena, len);
 }
@@ -179,6 +198,12 @@ UPB_INLINE envoy_type_tracing_v3_CustomTag_Header *envoy_type_tracing_v3_CustomT
   envoy_type_tracing_v3_CustomTag_Header *ret = envoy_type_tracing_v3_CustomTag_Header_new(arena);
   return (ret && upb_decode(buf, size, ret, &envoy_type_tracing_v3_CustomTag_Header_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE envoy_type_tracing_v3_CustomTag_Header *envoy_type_tracing_v3_CustomTag_Header_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  envoy_type_tracing_v3_CustomTag_Header *ret = envoy_type_tracing_v3_CustomTag_Header_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &envoy_type_tracing_v3_CustomTag_Header_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *envoy_type_tracing_v3_CustomTag_Header_serialize(const envoy_type_tracing_v3_CustomTag_Header *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &envoy_type_tracing_v3_CustomTag_Header_msginit, arena, len);
 }
@@ -203,18 +228,25 @@ UPB_INLINE envoy_type_tracing_v3_CustomTag_Metadata *envoy_type_tracing_v3_Custo
   envoy_type_tracing_v3_CustomTag_Metadata *ret = envoy_type_tracing_v3_CustomTag_Metadata_new(arena);
   return (ret && upb_decode(buf, size, ret, &envoy_type_tracing_v3_CustomTag_Metadata_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE envoy_type_tracing_v3_CustomTag_Metadata *envoy_type_tracing_v3_CustomTag_Metadata_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  envoy_type_tracing_v3_CustomTag_Metadata *ret = envoy_type_tracing_v3_CustomTag_Metadata_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &envoy_type_tracing_v3_CustomTag_Metadata_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *envoy_type_tracing_v3_CustomTag_Metadata_serialize(const envoy_type_tracing_v3_CustomTag_Metadata *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &envoy_type_tracing_v3_CustomTag_Metadata_msginit, arena, len);
 }
 
-UPB_INLINE bool envoy_type_tracing_v3_CustomTag_Metadata_has_kind(const envoy_type_tracing_v3_CustomTag_Metadata *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(8, 16)); }
-UPB_INLINE const struct envoy_type_metadata_v3_MetadataKind* envoy_type_tracing_v3_CustomTag_Metadata_kind(const envoy_type_tracing_v3_CustomTag_Metadata *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(8, 16), const struct envoy_type_metadata_v3_MetadataKind*); }
-UPB_INLINE bool envoy_type_tracing_v3_CustomTag_Metadata_has_metadata_key(const envoy_type_tracing_v3_CustomTag_Metadata *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(12, 24)); }
-UPB_INLINE const struct envoy_type_metadata_v3_MetadataKey* envoy_type_tracing_v3_CustomTag_Metadata_metadata_key(const envoy_type_tracing_v3_CustomTag_Metadata *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(12, 24), const struct envoy_type_metadata_v3_MetadataKey*); }
-UPB_INLINE upb_strview envoy_type_tracing_v3_CustomTag_Metadata_default_value(const envoy_type_tracing_v3_CustomTag_Metadata *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(0, 0), upb_strview); }
+UPB_INLINE bool envoy_type_tracing_v3_CustomTag_Metadata_has_kind(const envoy_type_tracing_v3_CustomTag_Metadata *msg) { return _upb_hasbit(msg, 1); }
+UPB_INLINE const struct envoy_type_metadata_v3_MetadataKind* envoy_type_tracing_v3_CustomTag_Metadata_kind(const envoy_type_tracing_v3_CustomTag_Metadata *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(12, 24), const struct envoy_type_metadata_v3_MetadataKind*); }
+UPB_INLINE bool envoy_type_tracing_v3_CustomTag_Metadata_has_metadata_key(const envoy_type_tracing_v3_CustomTag_Metadata *msg) { return _upb_hasbit(msg, 2); }
+UPB_INLINE const struct envoy_type_metadata_v3_MetadataKey* envoy_type_tracing_v3_CustomTag_Metadata_metadata_key(const envoy_type_tracing_v3_CustomTag_Metadata *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(16, 32), const struct envoy_type_metadata_v3_MetadataKey*); }
+UPB_INLINE upb_strview envoy_type_tracing_v3_CustomTag_Metadata_default_value(const envoy_type_tracing_v3_CustomTag_Metadata *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(4, 8), upb_strview); }
 
 UPB_INLINE void envoy_type_tracing_v3_CustomTag_Metadata_set_kind(envoy_type_tracing_v3_CustomTag_Metadata *msg, struct envoy_type_metadata_v3_MetadataKind* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(8, 16), struct envoy_type_metadata_v3_MetadataKind*) = value;
+  _upb_sethas(msg, 1);
+  *UPB_PTR_AT(msg, UPB_SIZE(12, 24), struct envoy_type_metadata_v3_MetadataKind*) = value;
 }
 UPB_INLINE struct envoy_type_metadata_v3_MetadataKind* envoy_type_tracing_v3_CustomTag_Metadata_mutable_kind(envoy_type_tracing_v3_CustomTag_Metadata *msg, upb_arena *arena) {
   struct envoy_type_metadata_v3_MetadataKind* sub = (struct envoy_type_metadata_v3_MetadataKind*)envoy_type_tracing_v3_CustomTag_Metadata_kind(msg);
@@ -226,7 +258,8 @@ UPB_INLINE struct envoy_type_metadata_v3_MetadataKind* envoy_type_tracing_v3_Cus
   return sub;
 }
 UPB_INLINE void envoy_type_tracing_v3_CustomTag_Metadata_set_metadata_key(envoy_type_tracing_v3_CustomTag_Metadata *msg, struct envoy_type_metadata_v3_MetadataKey* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(12, 24), struct envoy_type_metadata_v3_MetadataKey*) = value;
+  _upb_sethas(msg, 2);
+  *UPB_PTR_AT(msg, UPB_SIZE(16, 32), struct envoy_type_metadata_v3_MetadataKey*) = value;
 }
 UPB_INLINE struct envoy_type_metadata_v3_MetadataKey* envoy_type_tracing_v3_CustomTag_Metadata_mutable_metadata_key(envoy_type_tracing_v3_CustomTag_Metadata *msg, upb_arena *arena) {
   struct envoy_type_metadata_v3_MetadataKey* sub = (struct envoy_type_metadata_v3_MetadataKey*)envoy_type_tracing_v3_CustomTag_Metadata_metadata_key(msg);
@@ -238,7 +271,7 @@ UPB_INLINE struct envoy_type_metadata_v3_MetadataKey* envoy_type_tracing_v3_Cust
   return sub;
 }
 UPB_INLINE void envoy_type_tracing_v3_CustomTag_Metadata_set_default_value(envoy_type_tracing_v3_CustomTag_Metadata *msg, upb_strview value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(0, 0), upb_strview) = value;
+  *UPB_PTR_AT(msg, UPB_SIZE(4, 8), upb_strview) = value;
 }
 
 #ifdef __cplusplus
index 9e505a4..25b033f 100644 (file)
@@ -11,6 +11,7 @@
 
 #include "upb/msg.h"
 #include "upb/decode.h"
+#include "upb/decode_fast.h"
 #include "upb/encode.h"
 
 #include "upb/port_def.inc"
index e538792..9e4a87c 100644 (file)
@@ -22,18 +22,18 @@ static const upb_msglayout_field envoy_type_v3_Percent__fields[1] = {
 const upb_msglayout envoy_type_v3_Percent_msginit = {
   NULL,
   &envoy_type_v3_Percent__fields[0],
-  UPB_SIZE(8, 8), 1, false,
+  UPB_SIZE(8, 8), 1, false, 255,
 };
 
 static const upb_msglayout_field envoy_type_v3_FractionalPercent__fields[2] = {
-  {1, UPB_SIZE(8, 8), 0, 0, 13, 1},
+  {1, UPB_SIZE(4, 4), 0, 0, 13, 1},
   {2, UPB_SIZE(0, 0), 0, 0, 14, 1},
 };
 
 const upb_msglayout envoy_type_v3_FractionalPercent_msginit = {
   NULL,
   &envoy_type_v3_FractionalPercent__fields[0],
-  UPB_SIZE(16, 16), 2, false,
+  UPB_SIZE(8, 8), 2, false, 255,
 };
 
 #include "upb/port_undef.inc"
index fd111fe..6155e23 100644 (file)
@@ -11,6 +11,7 @@
 
 #include "upb/msg.h"
 #include "upb/decode.h"
+#include "upb/decode_fast.h"
 #include "upb/encode.h"
 
 #include "upb/port_def.inc"
@@ -43,6 +44,12 @@ UPB_INLINE envoy_type_v3_Percent *envoy_type_v3_Percent_parse(const char *buf, s
   envoy_type_v3_Percent *ret = envoy_type_v3_Percent_new(arena);
   return (ret && upb_decode(buf, size, ret, &envoy_type_v3_Percent_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE envoy_type_v3_Percent *envoy_type_v3_Percent_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  envoy_type_v3_Percent *ret = envoy_type_v3_Percent_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &envoy_type_v3_Percent_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *envoy_type_v3_Percent_serialize(const envoy_type_v3_Percent *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &envoy_type_v3_Percent_msginit, arena, len);
 }
@@ -63,15 +70,21 @@ UPB_INLINE envoy_type_v3_FractionalPercent *envoy_type_v3_FractionalPercent_pars
   envoy_type_v3_FractionalPercent *ret = envoy_type_v3_FractionalPercent_new(arena);
   return (ret && upb_decode(buf, size, ret, &envoy_type_v3_FractionalPercent_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE envoy_type_v3_FractionalPercent *envoy_type_v3_FractionalPercent_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  envoy_type_v3_FractionalPercent *ret = envoy_type_v3_FractionalPercent_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &envoy_type_v3_FractionalPercent_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *envoy_type_v3_FractionalPercent_serialize(const envoy_type_v3_FractionalPercent *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &envoy_type_v3_FractionalPercent_msginit, arena, len);
 }
 
-UPB_INLINE uint32_t envoy_type_v3_FractionalPercent_numerator(const envoy_type_v3_FractionalPercent *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(8, 8), uint32_t); }
+UPB_INLINE uint32_t envoy_type_v3_FractionalPercent_numerator(const envoy_type_v3_FractionalPercent *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(4, 4), uint32_t); }
 UPB_INLINE int32_t envoy_type_v3_FractionalPercent_denominator(const envoy_type_v3_FractionalPercent *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(0, 0), int32_t); }
 
 UPB_INLINE void envoy_type_v3_FractionalPercent_set_numerator(envoy_type_v3_FractionalPercent *msg, uint32_t value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(8, 8), uint32_t) = value;
+  *UPB_PTR_AT(msg, UPB_SIZE(4, 4), uint32_t) = value;
 }
 UPB_INLINE void envoy_type_v3_FractionalPercent_set_denominator(envoy_type_v3_FractionalPercent *msg, int32_t value) {
   *UPB_PTR_AT(msg, UPB_SIZE(0, 0), int32_t) = value;
index 0e21fed..e4222be 100644 (file)
@@ -22,7 +22,7 @@ static const upb_msglayout_field envoy_type_v3_Int64Range__fields[2] = {
 const upb_msglayout envoy_type_v3_Int64Range_msginit = {
   NULL,
   &envoy_type_v3_Int64Range__fields[0],
-  UPB_SIZE(16, 16), 2, false,
+  UPB_SIZE(16, 16), 2, false, 255,
 };
 
 static const upb_msglayout_field envoy_type_v3_Int32Range__fields[2] = {
@@ -33,7 +33,7 @@ static const upb_msglayout_field envoy_type_v3_Int32Range__fields[2] = {
 const upb_msglayout envoy_type_v3_Int32Range_msginit = {
   NULL,
   &envoy_type_v3_Int32Range__fields[0],
-  UPB_SIZE(8, 8), 2, false,
+  UPB_SIZE(8, 8), 2, false, 255,
 };
 
 static const upb_msglayout_field envoy_type_v3_DoubleRange__fields[2] = {
@@ -44,7 +44,7 @@ static const upb_msglayout_field envoy_type_v3_DoubleRange__fields[2] = {
 const upb_msglayout envoy_type_v3_DoubleRange_msginit = {
   NULL,
   &envoy_type_v3_DoubleRange__fields[0],
-  UPB_SIZE(16, 16), 2, false,
+  UPB_SIZE(16, 16), 2, false, 255,
 };
 
 #include "upb/port_undef.inc"
index 71453aa..9ff396d 100644 (file)
@@ -11,6 +11,7 @@
 
 #include "upb/msg.h"
 #include "upb/decode.h"
+#include "upb/decode_fast.h"
 #include "upb/encode.h"
 
 #include "upb/port_def.inc"
@@ -40,6 +41,12 @@ UPB_INLINE envoy_type_v3_Int64Range *envoy_type_v3_Int64Range_parse(const char *
   envoy_type_v3_Int64Range *ret = envoy_type_v3_Int64Range_new(arena);
   return (ret && upb_decode(buf, size, ret, &envoy_type_v3_Int64Range_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE envoy_type_v3_Int64Range *envoy_type_v3_Int64Range_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  envoy_type_v3_Int64Range *ret = envoy_type_v3_Int64Range_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &envoy_type_v3_Int64Range_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *envoy_type_v3_Int64Range_serialize(const envoy_type_v3_Int64Range *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &envoy_type_v3_Int64Range_msginit, arena, len);
 }
@@ -64,6 +71,12 @@ UPB_INLINE envoy_type_v3_Int32Range *envoy_type_v3_Int32Range_parse(const char *
   envoy_type_v3_Int32Range *ret = envoy_type_v3_Int32Range_new(arena);
   return (ret && upb_decode(buf, size, ret, &envoy_type_v3_Int32Range_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE envoy_type_v3_Int32Range *envoy_type_v3_Int32Range_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  envoy_type_v3_Int32Range *ret = envoy_type_v3_Int32Range_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &envoy_type_v3_Int32Range_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *envoy_type_v3_Int32Range_serialize(const envoy_type_v3_Int32Range *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &envoy_type_v3_Int32Range_msginit, arena, len);
 }
@@ -88,6 +101,12 @@ UPB_INLINE envoy_type_v3_DoubleRange *envoy_type_v3_DoubleRange_parse(const char
   envoy_type_v3_DoubleRange *ret = envoy_type_v3_DoubleRange_new(arena);
   return (ret && upb_decode(buf, size, ret, &envoy_type_v3_DoubleRange_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE envoy_type_v3_DoubleRange *envoy_type_v3_DoubleRange_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  envoy_type_v3_DoubleRange *ret = envoy_type_v3_DoubleRange_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &envoy_type_v3_DoubleRange_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *envoy_type_v3_DoubleRange_serialize(const envoy_type_v3_DoubleRange *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &envoy_type_v3_DoubleRange_msginit, arena, len);
 }
index 5eb014a..8984ac7 100644 (file)
@@ -23,7 +23,7 @@ static const upb_msglayout_field envoy_type_v3_SemanticVersion__fields[3] = {
 const upb_msglayout envoy_type_v3_SemanticVersion_msginit = {
   NULL,
   &envoy_type_v3_SemanticVersion__fields[0],
-  UPB_SIZE(12, 12), 3, false,
+  UPB_SIZE(16, 16), 3, false, 255,
 };
 
 #include "upb/port_undef.inc"
index 8d53bab..e1dd329 100644 (file)
@@ -11,6 +11,7 @@
 
 #include "upb/msg.h"
 #include "upb/decode.h"
+#include "upb/decode_fast.h"
 #include "upb/encode.h"
 
 #include "upb/port_def.inc"
@@ -34,6 +35,12 @@ UPB_INLINE envoy_type_v3_SemanticVersion *envoy_type_v3_SemanticVersion_parse(co
   envoy_type_v3_SemanticVersion *ret = envoy_type_v3_SemanticVersion_new(arena);
   return (ret && upb_decode(buf, size, ret, &envoy_type_v3_SemanticVersion_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE envoy_type_v3_SemanticVersion *envoy_type_v3_SemanticVersion_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  envoy_type_v3_SemanticVersion *ret = envoy_type_v3_SemanticVersion_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &envoy_type_v3_SemanticVersion_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *envoy_type_v3_SemanticVersion_serialize(const envoy_type_v3_SemanticVersion *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &envoy_type_v3_SemanticVersion_msginit, arena, len);
 }
index ea05f25..fcbe640 100644 (file)
@@ -11,6 +11,7 @@
 
 #include "upb/msg.h"
 #include "upb/decode.h"
+#include "upb/decode_fast.h"
 #include "upb/encode.h"
 
 #include "upb/port_def.inc"
index 5728a10..16fd52a 100644 (file)
@@ -23,16 +23,16 @@ static const upb_msglayout *const google_api_expr_v1alpha1_CheckedExpr_submsgs[4
 };
 
 static const upb_msglayout_field google_api_expr_v1alpha1_CheckedExpr__fields[4] = {
-  {2, UPB_SIZE(8, 16), 0, 0, 11, _UPB_LABEL_MAP},
-  {3, UPB_SIZE(12, 24), 0, 1, 11, _UPB_LABEL_MAP},
-  {4, UPB_SIZE(0, 0), 0, 2, 11, 1},
-  {5, UPB_SIZE(4, 8), 0, 3, 11, 1},
+  {2, UPB_SIZE(12, 24), 0, 0, 11, _UPB_LABEL_MAP},
+  {3, UPB_SIZE(16, 32), 0, 1, 11, _UPB_LABEL_MAP},
+  {4, UPB_SIZE(4, 8), 1, 2, 11, 1},
+  {5, UPB_SIZE(8, 16), 2, 3, 11, 1},
 };
 
 const upb_msglayout google_api_expr_v1alpha1_CheckedExpr_msginit = {
   &google_api_expr_v1alpha1_CheckedExpr_submsgs[0],
   &google_api_expr_v1alpha1_CheckedExpr__fields[0],
-  UPB_SIZE(16, 32), 4, false,
+  UPB_SIZE(24, 40), 4, false, 255,
 };
 
 static const upb_msglayout *const google_api_expr_v1alpha1_CheckedExpr_ReferenceMapEntry_submsgs[1] = {
@@ -47,7 +47,7 @@ static const upb_msglayout_field google_api_expr_v1alpha1_CheckedExpr_ReferenceM
 const upb_msglayout google_api_expr_v1alpha1_CheckedExpr_ReferenceMapEntry_msginit = {
   &google_api_expr_v1alpha1_CheckedExpr_ReferenceMapEntry_submsgs[0],
   &google_api_expr_v1alpha1_CheckedExpr_ReferenceMapEntry__fields[0],
-  UPB_SIZE(16, 32), 2, false,
+  UPB_SIZE(16, 32), 2, false, 255,
 };
 
 static const upb_msglayout *const google_api_expr_v1alpha1_CheckedExpr_TypeMapEntry_submsgs[1] = {
@@ -62,10 +62,10 @@ static const upb_msglayout_field google_api_expr_v1alpha1_CheckedExpr_TypeMapEnt
 const upb_msglayout google_api_expr_v1alpha1_CheckedExpr_TypeMapEntry_msginit = {
   &google_api_expr_v1alpha1_CheckedExpr_TypeMapEntry_submsgs[0],
   &google_api_expr_v1alpha1_CheckedExpr_TypeMapEntry__fields[0],
-  UPB_SIZE(16, 32), 2, false,
+  UPB_SIZE(16, 32), 2, false, 255,
 };
 
-static const upb_msglayout *const google_api_expr_v1alpha1_Type_submsgs[7] = {
+static const upb_msglayout *const google_api_expr_v1alpha1_Type_submsgs[6] = {
   &google_api_expr_v1alpha1_Type_msginit,
   &google_api_expr_v1alpha1_Type_AbstractType_msginit,
   &google_api_expr_v1alpha1_Type_FunctionType_msginit,
@@ -93,7 +93,7 @@ static const upb_msglayout_field google_api_expr_v1alpha1_Type__fields[13] = {
 const upb_msglayout google_api_expr_v1alpha1_Type_msginit = {
   &google_api_expr_v1alpha1_Type_submsgs[0],
   &google_api_expr_v1alpha1_Type__fields[0],
-  UPB_SIZE(16, 32), 13, false,
+  UPB_SIZE(16, 32), 13, false, 255,
 };
 
 static const upb_msglayout *const google_api_expr_v1alpha1_Type_ListType_submsgs[1] = {
@@ -101,43 +101,43 @@ static const upb_msglayout *const google_api_expr_v1alpha1_Type_ListType_submsgs
 };
 
 static const upb_msglayout_field google_api_expr_v1alpha1_Type_ListType__fields[1] = {
-  {1, UPB_SIZE(0, 0), 0, 0, 11, 1},
+  {1, UPB_SIZE(4, 8), 1, 0, 11, 1},
 };
 
 const upb_msglayout google_api_expr_v1alpha1_Type_ListType_msginit = {
   &google_api_expr_v1alpha1_Type_ListType_submsgs[0],
   &google_api_expr_v1alpha1_Type_ListType__fields[0],
-  UPB_SIZE(4, 8), 1, false,
+  UPB_SIZE(8, 16), 1, false, 255,
 };
 
-static const upb_msglayout *const google_api_expr_v1alpha1_Type_MapType_submsgs[2] = {
+static const upb_msglayout *const google_api_expr_v1alpha1_Type_MapType_submsgs[1] = {
   &google_api_expr_v1alpha1_Type_msginit,
 };
 
 static const upb_msglayout_field google_api_expr_v1alpha1_Type_MapType__fields[2] = {
-  {1, UPB_SIZE(0, 0), 0, 0, 11, 1},
-  {2, UPB_SIZE(4, 8), 0, 0, 11, 1},
+  {1, UPB_SIZE(4, 8), 1, 0, 11, 1},
+  {2, UPB_SIZE(8, 16), 2, 0, 11, 1},
 };
 
 const upb_msglayout google_api_expr_v1alpha1_Type_MapType_msginit = {
   &google_api_expr_v1alpha1_Type_MapType_submsgs[0],
   &google_api_expr_v1alpha1_Type_MapType__fields[0],
-  UPB_SIZE(8, 16), 2, false,
+  UPB_SIZE(16, 24), 2, false, 255,
 };
 
-static const upb_msglayout *const google_api_expr_v1alpha1_Type_FunctionType_submsgs[2] = {
+static const upb_msglayout *const google_api_expr_v1alpha1_Type_FunctionType_submsgs[1] = {
   &google_api_expr_v1alpha1_Type_msginit,
 };
 
 static const upb_msglayout_field google_api_expr_v1alpha1_Type_FunctionType__fields[2] = {
-  {1, UPB_SIZE(0, 0), 0, 0, 11, 1},
-  {2, UPB_SIZE(4, 8), 0, 0, 11, 3},
+  {1, UPB_SIZE(4, 8), 1, 0, 11, 1},
+  {2, UPB_SIZE(8, 16), 0, 0, 11, 3},
 };
 
 const upb_msglayout google_api_expr_v1alpha1_Type_FunctionType_msginit = {
   &google_api_expr_v1alpha1_Type_FunctionType_submsgs[0],
   &google_api_expr_v1alpha1_Type_FunctionType__fields[0],
-  UPB_SIZE(8, 16), 2, false,
+  UPB_SIZE(16, 24), 2, false, 255,
 };
 
 static const upb_msglayout *const google_api_expr_v1alpha1_Type_AbstractType_submsgs[1] = {
@@ -152,7 +152,7 @@ static const upb_msglayout_field google_api_expr_v1alpha1_Type_AbstractType__fie
 const upb_msglayout google_api_expr_v1alpha1_Type_AbstractType_msginit = {
   &google_api_expr_v1alpha1_Type_AbstractType_submsgs[0],
   &google_api_expr_v1alpha1_Type_AbstractType__fields[0],
-  UPB_SIZE(16, 32), 2, false,
+  UPB_SIZE(16, 32), 2, false, 255,
 };
 
 static const upb_msglayout *const google_api_expr_v1alpha1_Decl_submsgs[2] = {
@@ -169,7 +169,7 @@ static const upb_msglayout_field google_api_expr_v1alpha1_Decl__fields[3] = {
 const upb_msglayout google_api_expr_v1alpha1_Decl_msginit = {
   &google_api_expr_v1alpha1_Decl_submsgs[0],
   &google_api_expr_v1alpha1_Decl__fields[0],
-  UPB_SIZE(16, 32), 3, false,
+  UPB_SIZE(16, 32), 3, false, 255,
 };
 
 static const upb_msglayout *const google_api_expr_v1alpha1_Decl_IdentDecl_submsgs[2] = {
@@ -178,15 +178,15 @@ static const upb_msglayout *const google_api_expr_v1alpha1_Decl_IdentDecl_submsg
 };
 
 static const upb_msglayout_field google_api_expr_v1alpha1_Decl_IdentDecl__fields[3] = {
-  {1, UPB_SIZE(8, 16), 0, 1, 11, 1},
-  {2, UPB_SIZE(12, 24), 0, 0, 11, 1},
-  {3, UPB_SIZE(0, 0), 0, 0, 9, 1},
+  {1, UPB_SIZE(12, 24), 1, 1, 11, 1},
+  {2, UPB_SIZE(16, 32), 2, 0, 11, 1},
+  {3, UPB_SIZE(4, 8), 0, 0, 9, 1},
 };
 
 const upb_msglayout google_api_expr_v1alpha1_Decl_IdentDecl_msginit = {
   &google_api_expr_v1alpha1_Decl_IdentDecl_submsgs[0],
   &google_api_expr_v1alpha1_Decl_IdentDecl__fields[0],
-  UPB_SIZE(16, 32), 3, false,
+  UPB_SIZE(24, 48), 3, false, 255,
 };
 
 static const upb_msglayout *const google_api_expr_v1alpha1_Decl_FunctionDecl_submsgs[1] = {
@@ -200,10 +200,10 @@ static const upb_msglayout_field google_api_expr_v1alpha1_Decl_FunctionDecl__fie
 const upb_msglayout google_api_expr_v1alpha1_Decl_FunctionDecl_msginit = {
   &google_api_expr_v1alpha1_Decl_FunctionDecl_submsgs[0],
   &google_api_expr_v1alpha1_Decl_FunctionDecl__fields[0],
-  UPB_SIZE(4, 8), 1, false,
+  UPB_SIZE(8, 8), 1, false, 255,
 };
 
-static const upb_msglayout *const google_api_expr_v1alpha1_Decl_FunctionDecl_Overload_submsgs[2] = {
+static const upb_msglayout *const google_api_expr_v1alpha1_Decl_FunctionDecl_Overload_submsgs[1] = {
   &google_api_expr_v1alpha1_Type_msginit,
 };
 
@@ -211,15 +211,15 @@ static const upb_msglayout_field google_api_expr_v1alpha1_Decl_FunctionDecl_Over
   {1, UPB_SIZE(4, 8), 0, 0, 9, 1},
   {2, UPB_SIZE(24, 48), 0, 0, 11, 3},
   {3, UPB_SIZE(28, 56), 0, 0, 9, 3},
-  {4, UPB_SIZE(20, 40), 0, 0, 11, 1},
-  {5, UPB_SIZE(0, 0), 0, 0, 8, 1},
+  {4, UPB_SIZE(20, 40), 1, 0, 11, 1},
+  {5, UPB_SIZE(1, 1), 0, 0, 8, 1},
   {6, UPB_SIZE(12, 24), 0, 0, 9, 1},
 };
 
 const upb_msglayout google_api_expr_v1alpha1_Decl_FunctionDecl_Overload_msginit = {
   &google_api_expr_v1alpha1_Decl_FunctionDecl_Overload_submsgs[0],
   &google_api_expr_v1alpha1_Decl_FunctionDecl_Overload__fields[0],
-  UPB_SIZE(32, 64), 6, false,
+  UPB_SIZE(32, 64), 6, false, 255,
 };
 
 static const upb_msglayout *const google_api_expr_v1alpha1_Reference_submsgs[1] = {
@@ -227,15 +227,15 @@ static const upb_msglayout *const google_api_expr_v1alpha1_Reference_submsgs[1]
 };
 
 static const upb_msglayout_field google_api_expr_v1alpha1_Reference__fields[3] = {
-  {1, UPB_SIZE(0, 0), 0, 0, 9, 1},
-  {3, UPB_SIZE(12, 24), 0, 0, 9, 3},
-  {4, UPB_SIZE(8, 16), 0, 0, 11, 1},
+  {1, UPB_SIZE(4, 8), 0, 0, 9, 1},
+  {3, UPB_SIZE(16, 32), 0, 0, 9, 3},
+  {4, UPB_SIZE(12, 24), 1, 0, 11, 1},
 };
 
 const upb_msglayout google_api_expr_v1alpha1_Reference_msginit = {
   &google_api_expr_v1alpha1_Reference_submsgs[0],
   &google_api_expr_v1alpha1_Reference__fields[0],
-  UPB_SIZE(16, 32), 3, false,
+  UPB_SIZE(24, 48), 3, false, 255,
 };
 
 #include "upb/port_undef.inc"
index a5b9f0c..43a88f7 100644 (file)
@@ -11,6 +11,7 @@
 
 #include "upb/msg.h"
 #include "upb/decode.h"
+#include "upb/decode_fast.h"
 #include "upb/encode.h"
 
 #include "upb/port_def.inc"
@@ -95,33 +96,40 @@ UPB_INLINE google_api_expr_v1alpha1_CheckedExpr *google_api_expr_v1alpha1_Checke
   google_api_expr_v1alpha1_CheckedExpr *ret = google_api_expr_v1alpha1_CheckedExpr_new(arena);
   return (ret && upb_decode(buf, size, ret, &google_api_expr_v1alpha1_CheckedExpr_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE google_api_expr_v1alpha1_CheckedExpr *google_api_expr_v1alpha1_CheckedExpr_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  google_api_expr_v1alpha1_CheckedExpr *ret = google_api_expr_v1alpha1_CheckedExpr_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &google_api_expr_v1alpha1_CheckedExpr_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *google_api_expr_v1alpha1_CheckedExpr_serialize(const google_api_expr_v1alpha1_CheckedExpr *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &google_api_expr_v1alpha1_CheckedExpr_msginit, arena, len);
 }
 
-UPB_INLINE bool google_api_expr_v1alpha1_CheckedExpr_has_reference_map(const google_api_expr_v1alpha1_CheckedExpr *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(8, 16)); }
-UPB_INLINE size_t google_api_expr_v1alpha1_CheckedExpr_reference_map_size(const google_api_expr_v1alpha1_CheckedExpr *msg) {return _upb_msg_map_size(msg, UPB_SIZE(8, 16)); }
-UPB_INLINE bool google_api_expr_v1alpha1_CheckedExpr_reference_map_get(const google_api_expr_v1alpha1_CheckedExpr *msg, int64_t key, google_api_expr_v1alpha1_Reference* *val) { return _upb_msg_map_get(msg, UPB_SIZE(8, 16), &key, sizeof(key), val, sizeof(*val)); }
-UPB_INLINE const google_api_expr_v1alpha1_CheckedExpr_ReferenceMapEntry* google_api_expr_v1alpha1_CheckedExpr_reference_map_next(const google_api_expr_v1alpha1_CheckedExpr *msg, size_t* iter) { return (const google_api_expr_v1alpha1_CheckedExpr_ReferenceMapEntry*)_upb_msg_map_next(msg, UPB_SIZE(8, 16), iter); }
-UPB_INLINE bool google_api_expr_v1alpha1_CheckedExpr_has_type_map(const google_api_expr_v1alpha1_CheckedExpr *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(12, 24)); }
-UPB_INLINE size_t google_api_expr_v1alpha1_CheckedExpr_type_map_size(const google_api_expr_v1alpha1_CheckedExpr *msg) {return _upb_msg_map_size(msg, UPB_SIZE(12, 24)); }
-UPB_INLINE bool google_api_expr_v1alpha1_CheckedExpr_type_map_get(const google_api_expr_v1alpha1_CheckedExpr *msg, int64_t key, google_api_expr_v1alpha1_Type* *val) { return _upb_msg_map_get(msg, UPB_SIZE(12, 24), &key, sizeof(key), val, sizeof(*val)); }
-UPB_INLINE const google_api_expr_v1alpha1_CheckedExpr_TypeMapEntry* google_api_expr_v1alpha1_CheckedExpr_type_map_next(const google_api_expr_v1alpha1_CheckedExpr *msg, size_t* iter) { return (const google_api_expr_v1alpha1_CheckedExpr_TypeMapEntry*)_upb_msg_map_next(msg, UPB_SIZE(12, 24), iter); }
-UPB_INLINE bool google_api_expr_v1alpha1_CheckedExpr_has_expr(const google_api_expr_v1alpha1_CheckedExpr *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(0, 0)); }
-UPB_INLINE const struct google_api_expr_v1alpha1_Expr* google_api_expr_v1alpha1_CheckedExpr_expr(const google_api_expr_v1alpha1_CheckedExpr *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(0, 0), const struct google_api_expr_v1alpha1_Expr*); }
-UPB_INLINE bool google_api_expr_v1alpha1_CheckedExpr_has_source_info(const google_api_expr_v1alpha1_CheckedExpr *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(4, 8)); }
-UPB_INLINE const struct google_api_expr_v1alpha1_SourceInfo* google_api_expr_v1alpha1_CheckedExpr_source_info(const google_api_expr_v1alpha1_CheckedExpr *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(4, 8), const struct google_api_expr_v1alpha1_SourceInfo*); }
-
-UPB_INLINE void google_api_expr_v1alpha1_CheckedExpr_reference_map_clear(google_api_expr_v1alpha1_CheckedExpr *msg) { _upb_msg_map_clear(msg, UPB_SIZE(8, 16)); }
-UPB_INLINE bool google_api_expr_v1alpha1_CheckedExpr_reference_map_set(google_api_expr_v1alpha1_CheckedExpr *msg, int64_t key, google_api_expr_v1alpha1_Reference* val, upb_arena *a) { return _upb_msg_map_set(msg, UPB_SIZE(8, 16), &key, sizeof(key), &val, sizeof(val), a); }
-UPB_INLINE bool google_api_expr_v1alpha1_CheckedExpr_reference_map_delete(google_api_expr_v1alpha1_CheckedExpr *msg, int64_t key) { return _upb_msg_map_delete(msg, UPB_SIZE(8, 16), &key, sizeof(key)); }
-UPB_INLINE google_api_expr_v1alpha1_CheckedExpr_ReferenceMapEntry* google_api_expr_v1alpha1_CheckedExpr_reference_map_nextmutable(google_api_expr_v1alpha1_CheckedExpr *msg, size_t* iter) { return (google_api_expr_v1alpha1_CheckedExpr_ReferenceMapEntry*)_upb_msg_map_next(msg, UPB_SIZE(8, 16), iter); }
-UPB_INLINE void google_api_expr_v1alpha1_CheckedExpr_type_map_clear(google_api_expr_v1alpha1_CheckedExpr *msg) { _upb_msg_map_clear(msg, UPB_SIZE(12, 24)); }
-UPB_INLINE bool google_api_expr_v1alpha1_CheckedExpr_type_map_set(google_api_expr_v1alpha1_CheckedExpr *msg, int64_t key, google_api_expr_v1alpha1_Type* val, upb_arena *a) { return _upb_msg_map_set(msg, UPB_SIZE(12, 24), &key, sizeof(key), &val, sizeof(val), a); }
-UPB_INLINE bool google_api_expr_v1alpha1_CheckedExpr_type_map_delete(google_api_expr_v1alpha1_CheckedExpr *msg, int64_t key) { return _upb_msg_map_delete(msg, UPB_SIZE(12, 24), &key, sizeof(key)); }
-UPB_INLINE google_api_expr_v1alpha1_CheckedExpr_TypeMapEntry* google_api_expr_v1alpha1_CheckedExpr_type_map_nextmutable(google_api_expr_v1alpha1_CheckedExpr *msg, size_t* iter) { return (google_api_expr_v1alpha1_CheckedExpr_TypeMapEntry*)_upb_msg_map_next(msg, UPB_SIZE(12, 24), iter); }
+UPB_INLINE bool google_api_expr_v1alpha1_CheckedExpr_has_reference_map(const google_api_expr_v1alpha1_CheckedExpr *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(12, 24)); }
+UPB_INLINE size_t google_api_expr_v1alpha1_CheckedExpr_reference_map_size(const google_api_expr_v1alpha1_CheckedExpr *msg) {return _upb_msg_map_size(msg, UPB_SIZE(12, 24)); }
+UPB_INLINE bool google_api_expr_v1alpha1_CheckedExpr_reference_map_get(const google_api_expr_v1alpha1_CheckedExpr *msg, int64_t key, google_api_expr_v1alpha1_Reference* *val) { return _upb_msg_map_get(msg, UPB_SIZE(12, 24), &key, sizeof(key), val, sizeof(*val)); }
+UPB_INLINE const google_api_expr_v1alpha1_CheckedExpr_ReferenceMapEntry* google_api_expr_v1alpha1_CheckedExpr_reference_map_next(const google_api_expr_v1alpha1_CheckedExpr *msg, size_t* iter) { return (const google_api_expr_v1alpha1_CheckedExpr_ReferenceMapEntry*)_upb_msg_map_next(msg, UPB_SIZE(12, 24), iter); }
+UPB_INLINE bool google_api_expr_v1alpha1_CheckedExpr_has_type_map(const google_api_expr_v1alpha1_CheckedExpr *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(16, 32)); }
+UPB_INLINE size_t google_api_expr_v1alpha1_CheckedExpr_type_map_size(const google_api_expr_v1alpha1_CheckedExpr *msg) {return _upb_msg_map_size(msg, UPB_SIZE(16, 32)); }
+UPB_INLINE bool google_api_expr_v1alpha1_CheckedExpr_type_map_get(const google_api_expr_v1alpha1_CheckedExpr *msg, int64_t key, google_api_expr_v1alpha1_Type* *val) { return _upb_msg_map_get(msg, UPB_SIZE(16, 32), &key, sizeof(key), val, sizeof(*val)); }
+UPB_INLINE const google_api_expr_v1alpha1_CheckedExpr_TypeMapEntry* google_api_expr_v1alpha1_CheckedExpr_type_map_next(const google_api_expr_v1alpha1_CheckedExpr *msg, size_t* iter) { return (const google_api_expr_v1alpha1_CheckedExpr_TypeMapEntry*)_upb_msg_map_next(msg, UPB_SIZE(16, 32), iter); }
+UPB_INLINE bool google_api_expr_v1alpha1_CheckedExpr_has_expr(const google_api_expr_v1alpha1_CheckedExpr *msg) { return _upb_hasbit(msg, 1); }
+UPB_INLINE const struct google_api_expr_v1alpha1_Expr* google_api_expr_v1alpha1_CheckedExpr_expr(const google_api_expr_v1alpha1_CheckedExpr *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(4, 8), const struct google_api_expr_v1alpha1_Expr*); }
+UPB_INLINE bool google_api_expr_v1alpha1_CheckedExpr_has_source_info(const google_api_expr_v1alpha1_CheckedExpr *msg) { return _upb_hasbit(msg, 2); }
+UPB_INLINE const struct google_api_expr_v1alpha1_SourceInfo* google_api_expr_v1alpha1_CheckedExpr_source_info(const google_api_expr_v1alpha1_CheckedExpr *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(8, 16), const struct google_api_expr_v1alpha1_SourceInfo*); }
+
+UPB_INLINE void google_api_expr_v1alpha1_CheckedExpr_reference_map_clear(google_api_expr_v1alpha1_CheckedExpr *msg) { _upb_msg_map_clear(msg, UPB_SIZE(12, 24)); }
+UPB_INLINE bool google_api_expr_v1alpha1_CheckedExpr_reference_map_set(google_api_expr_v1alpha1_CheckedExpr *msg, int64_t key, google_api_expr_v1alpha1_Reference* val, upb_arena *a) { return _upb_msg_map_set(msg, UPB_SIZE(12, 24), &key, sizeof(key), &val, sizeof(val), a); }
+UPB_INLINE bool google_api_expr_v1alpha1_CheckedExpr_reference_map_delete(google_api_expr_v1alpha1_CheckedExpr *msg, int64_t key) { return _upb_msg_map_delete(msg, UPB_SIZE(12, 24), &key, sizeof(key)); }
+UPB_INLINE google_api_expr_v1alpha1_CheckedExpr_ReferenceMapEntry* google_api_expr_v1alpha1_CheckedExpr_reference_map_nextmutable(google_api_expr_v1alpha1_CheckedExpr *msg, size_t* iter) { return (google_api_expr_v1alpha1_CheckedExpr_ReferenceMapEntry*)_upb_msg_map_next(msg, UPB_SIZE(12, 24), iter); }
+UPB_INLINE void google_api_expr_v1alpha1_CheckedExpr_type_map_clear(google_api_expr_v1alpha1_CheckedExpr *msg) { _upb_msg_map_clear(msg, UPB_SIZE(16, 32)); }
+UPB_INLINE bool google_api_expr_v1alpha1_CheckedExpr_type_map_set(google_api_expr_v1alpha1_CheckedExpr *msg, int64_t key, google_api_expr_v1alpha1_Type* val, upb_arena *a) { return _upb_msg_map_set(msg, UPB_SIZE(16, 32), &key, sizeof(key), &val, sizeof(val), a); }
+UPB_INLINE bool google_api_expr_v1alpha1_CheckedExpr_type_map_delete(google_api_expr_v1alpha1_CheckedExpr *msg, int64_t key) { return _upb_msg_map_delete(msg, UPB_SIZE(16, 32), &key, sizeof(key)); }
+UPB_INLINE google_api_expr_v1alpha1_CheckedExpr_TypeMapEntry* google_api_expr_v1alpha1_CheckedExpr_type_map_nextmutable(google_api_expr_v1alpha1_CheckedExpr *msg, size_t* iter) { return (google_api_expr_v1alpha1_CheckedExpr_TypeMapEntry*)_upb_msg_map_next(msg, UPB_SIZE(16, 32), iter); }
 UPB_INLINE void google_api_expr_v1alpha1_CheckedExpr_set_expr(google_api_expr_v1alpha1_CheckedExpr *msg, struct google_api_expr_v1alpha1_Expr* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(0, 0), struct google_api_expr_v1alpha1_Expr*) = value;
+  _upb_sethas(msg, 1);
+  *UPB_PTR_AT(msg, UPB_SIZE(4, 8), struct google_api_expr_v1alpha1_Expr*) = value;
 }
 UPB_INLINE struct google_api_expr_v1alpha1_Expr* google_api_expr_v1alpha1_CheckedExpr_mutable_expr(google_api_expr_v1alpha1_CheckedExpr *msg, upb_arena *arena) {
   struct google_api_expr_v1alpha1_Expr* sub = (struct google_api_expr_v1alpha1_Expr*)google_api_expr_v1alpha1_CheckedExpr_expr(msg);
@@ -133,7 +141,8 @@ UPB_INLINE struct google_api_expr_v1alpha1_Expr* google_api_expr_v1alpha1_Checke
   return sub;
 }
 UPB_INLINE void google_api_expr_v1alpha1_CheckedExpr_set_source_info(google_api_expr_v1alpha1_CheckedExpr *msg, struct google_api_expr_v1alpha1_SourceInfo* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(4, 8), struct google_api_expr_v1alpha1_SourceInfo*) = value;
+  _upb_sethas(msg, 2);
+  *UPB_PTR_AT(msg, UPB_SIZE(8, 16), struct google_api_expr_v1alpha1_SourceInfo*) = value;
 }
 UPB_INLINE struct google_api_expr_v1alpha1_SourceInfo* google_api_expr_v1alpha1_CheckedExpr_mutable_source_info(google_api_expr_v1alpha1_CheckedExpr *msg, upb_arena *arena) {
   struct google_api_expr_v1alpha1_SourceInfo* sub = (struct google_api_expr_v1alpha1_SourceInfo*)google_api_expr_v1alpha1_CheckedExpr_source_info(msg);
@@ -191,6 +200,12 @@ UPB_INLINE google_api_expr_v1alpha1_Type *google_api_expr_v1alpha1_Type_parse(co
   google_api_expr_v1alpha1_Type *ret = google_api_expr_v1alpha1_Type_new(arena);
   return (ret && upb_decode(buf, size, ret, &google_api_expr_v1alpha1_Type_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE google_api_expr_v1alpha1_Type *google_api_expr_v1alpha1_Type_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  google_api_expr_v1alpha1_Type *ret = google_api_expr_v1alpha1_Type_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &google_api_expr_v1alpha1_Type_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *google_api_expr_v1alpha1_Type_serialize(const google_api_expr_v1alpha1_Type *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &google_api_expr_v1alpha1_Type_msginit, arena, len);
 }
@@ -353,15 +368,22 @@ UPB_INLINE google_api_expr_v1alpha1_Type_ListType *google_api_expr_v1alpha1_Type
   google_api_expr_v1alpha1_Type_ListType *ret = google_api_expr_v1alpha1_Type_ListType_new(arena);
   return (ret && upb_decode(buf, size, ret, &google_api_expr_v1alpha1_Type_ListType_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE google_api_expr_v1alpha1_Type_ListType *google_api_expr_v1alpha1_Type_ListType_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  google_api_expr_v1alpha1_Type_ListType *ret = google_api_expr_v1alpha1_Type_ListType_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &google_api_expr_v1alpha1_Type_ListType_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *google_api_expr_v1alpha1_Type_ListType_serialize(const google_api_expr_v1alpha1_Type_ListType *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &google_api_expr_v1alpha1_Type_ListType_msginit, arena, len);
 }
 
-UPB_INLINE bool google_api_expr_v1alpha1_Type_ListType_has_elem_type(const google_api_expr_v1alpha1_Type_ListType *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(0, 0)); }
-UPB_INLINE const google_api_expr_v1alpha1_Type* google_api_expr_v1alpha1_Type_ListType_elem_type(const google_api_expr_v1alpha1_Type_ListType *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(0, 0), const google_api_expr_v1alpha1_Type*); }
+UPB_INLINE bool google_api_expr_v1alpha1_Type_ListType_has_elem_type(const google_api_expr_v1alpha1_Type_ListType *msg) { return _upb_hasbit(msg, 1); }
+UPB_INLINE const google_api_expr_v1alpha1_Type* google_api_expr_v1alpha1_Type_ListType_elem_type(const google_api_expr_v1alpha1_Type_ListType *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(4, 8), const google_api_expr_v1alpha1_Type*); }
 
 UPB_INLINE void google_api_expr_v1alpha1_Type_ListType_set_elem_type(google_api_expr_v1alpha1_Type_ListType *msg, google_api_expr_v1alpha1_Type* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(0, 0), google_api_expr_v1alpha1_Type*) = value;
+  _upb_sethas(msg, 1);
+  *UPB_PTR_AT(msg, UPB_SIZE(4, 8), google_api_expr_v1alpha1_Type*) = value;
 }
 UPB_INLINE struct google_api_expr_v1alpha1_Type* google_api_expr_v1alpha1_Type_ListType_mutable_elem_type(google_api_expr_v1alpha1_Type_ListType *msg, upb_arena *arena) {
   struct google_api_expr_v1alpha1_Type* sub = (struct google_api_expr_v1alpha1_Type*)google_api_expr_v1alpha1_Type_ListType_elem_type(msg);
@@ -383,17 +405,24 @@ UPB_INLINE google_api_expr_v1alpha1_Type_MapType *google_api_expr_v1alpha1_Type_
   google_api_expr_v1alpha1_Type_MapType *ret = google_api_expr_v1alpha1_Type_MapType_new(arena);
   return (ret && upb_decode(buf, size, ret, &google_api_expr_v1alpha1_Type_MapType_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE google_api_expr_v1alpha1_Type_MapType *google_api_expr_v1alpha1_Type_MapType_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  google_api_expr_v1alpha1_Type_MapType *ret = google_api_expr_v1alpha1_Type_MapType_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &google_api_expr_v1alpha1_Type_MapType_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *google_api_expr_v1alpha1_Type_MapType_serialize(const google_api_expr_v1alpha1_Type_MapType *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &google_api_expr_v1alpha1_Type_MapType_msginit, arena, len);
 }
 
-UPB_INLINE bool google_api_expr_v1alpha1_Type_MapType_has_key_type(const google_api_expr_v1alpha1_Type_MapType *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(0, 0)); }
-UPB_INLINE const google_api_expr_v1alpha1_Type* google_api_expr_v1alpha1_Type_MapType_key_type(const google_api_expr_v1alpha1_Type_MapType *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(0, 0), const google_api_expr_v1alpha1_Type*); }
-UPB_INLINE bool google_api_expr_v1alpha1_Type_MapType_has_value_type(const google_api_expr_v1alpha1_Type_MapType *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(4, 8)); }
-UPB_INLINE const google_api_expr_v1alpha1_Type* google_api_expr_v1alpha1_Type_MapType_value_type(const google_api_expr_v1alpha1_Type_MapType *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(4, 8), const google_api_expr_v1alpha1_Type*); }
+UPB_INLINE bool google_api_expr_v1alpha1_Type_MapType_has_key_type(const google_api_expr_v1alpha1_Type_MapType *msg) { return _upb_hasbit(msg, 1); }
+UPB_INLINE const google_api_expr_v1alpha1_Type* google_api_expr_v1alpha1_Type_MapType_key_type(const google_api_expr_v1alpha1_Type_MapType *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(4, 8), const google_api_expr_v1alpha1_Type*); }
+UPB_INLINE bool google_api_expr_v1alpha1_Type_MapType_has_value_type(const google_api_expr_v1alpha1_Type_MapType *msg) { return _upb_hasbit(msg, 2); }
+UPB_INLINE const google_api_expr_v1alpha1_Type* google_api_expr_v1alpha1_Type_MapType_value_type(const google_api_expr_v1alpha1_Type_MapType *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(8, 16), const google_api_expr_v1alpha1_Type*); }
 
 UPB_INLINE void google_api_expr_v1alpha1_Type_MapType_set_key_type(google_api_expr_v1alpha1_Type_MapType *msg, google_api_expr_v1alpha1_Type* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(0, 0), google_api_expr_v1alpha1_Type*) = value;
+  _upb_sethas(msg, 1);
+  *UPB_PTR_AT(msg, UPB_SIZE(4, 8), google_api_expr_v1alpha1_Type*) = value;
 }
 UPB_INLINE struct google_api_expr_v1alpha1_Type* google_api_expr_v1alpha1_Type_MapType_mutable_key_type(google_api_expr_v1alpha1_Type_MapType *msg, upb_arena *arena) {
   struct google_api_expr_v1alpha1_Type* sub = (struct google_api_expr_v1alpha1_Type*)google_api_expr_v1alpha1_Type_MapType_key_type(msg);
@@ -405,7 +434,8 @@ UPB_INLINE struct google_api_expr_v1alpha1_Type* google_api_expr_v1alpha1_Type_M
   return sub;
 }
 UPB_INLINE void google_api_expr_v1alpha1_Type_MapType_set_value_type(google_api_expr_v1alpha1_Type_MapType *msg, google_api_expr_v1alpha1_Type* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(4, 8), google_api_expr_v1alpha1_Type*) = value;
+  _upb_sethas(msg, 2);
+  *UPB_PTR_AT(msg, UPB_SIZE(8, 16), google_api_expr_v1alpha1_Type*) = value;
 }
 UPB_INLINE struct google_api_expr_v1alpha1_Type* google_api_expr_v1alpha1_Type_MapType_mutable_value_type(google_api_expr_v1alpha1_Type_MapType *msg, upb_arena *arena) {
   struct google_api_expr_v1alpha1_Type* sub = (struct google_api_expr_v1alpha1_Type*)google_api_expr_v1alpha1_Type_MapType_value_type(msg);
@@ -427,17 +457,24 @@ UPB_INLINE google_api_expr_v1alpha1_Type_FunctionType *google_api_expr_v1alpha1_
   google_api_expr_v1alpha1_Type_FunctionType *ret = google_api_expr_v1alpha1_Type_FunctionType_new(arena);
   return (ret && upb_decode(buf, size, ret, &google_api_expr_v1alpha1_Type_FunctionType_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE google_api_expr_v1alpha1_Type_FunctionType *google_api_expr_v1alpha1_Type_FunctionType_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  google_api_expr_v1alpha1_Type_FunctionType *ret = google_api_expr_v1alpha1_Type_FunctionType_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &google_api_expr_v1alpha1_Type_FunctionType_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *google_api_expr_v1alpha1_Type_FunctionType_serialize(const google_api_expr_v1alpha1_Type_FunctionType *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &google_api_expr_v1alpha1_Type_FunctionType_msginit, arena, len);
 }
 
-UPB_INLINE bool google_api_expr_v1alpha1_Type_FunctionType_has_result_type(const google_api_expr_v1alpha1_Type_FunctionType *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(0, 0)); }
-UPB_INLINE const google_api_expr_v1alpha1_Type* google_api_expr_v1alpha1_Type_FunctionType_result_type(const google_api_expr_v1alpha1_Type_FunctionType *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(0, 0), const google_api_expr_v1alpha1_Type*); }
-UPB_INLINE bool google_api_expr_v1alpha1_Type_FunctionType_has_arg_types(const google_api_expr_v1alpha1_Type_FunctionType *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(4, 8)); }
-UPB_INLINE const google_api_expr_v1alpha1_Type* const* google_api_expr_v1alpha1_Type_FunctionType_arg_types(const google_api_expr_v1alpha1_Type_FunctionType *msg, size_t *len) { return (const google_api_expr_v1alpha1_Type* const*)_upb_array_accessor(msg, UPB_SIZE(4, 8), len); }
+UPB_INLINE bool google_api_expr_v1alpha1_Type_FunctionType_has_result_type(const google_api_expr_v1alpha1_Type_FunctionType *msg) { return _upb_hasbit(msg, 1); }
+UPB_INLINE const google_api_expr_v1alpha1_Type* google_api_expr_v1alpha1_Type_FunctionType_result_type(const google_api_expr_v1alpha1_Type_FunctionType *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(4, 8), const google_api_expr_v1alpha1_Type*); }
+UPB_INLINE bool google_api_expr_v1alpha1_Type_FunctionType_has_arg_types(const google_api_expr_v1alpha1_Type_FunctionType *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(8, 16)); }
+UPB_INLINE const google_api_expr_v1alpha1_Type* const* google_api_expr_v1alpha1_Type_FunctionType_arg_types(const google_api_expr_v1alpha1_Type_FunctionType *msg, size_t *len) { return (const google_api_expr_v1alpha1_Type* const*)_upb_array_accessor(msg, UPB_SIZE(8, 16), len); }
 
 UPB_INLINE void google_api_expr_v1alpha1_Type_FunctionType_set_result_type(google_api_expr_v1alpha1_Type_FunctionType *msg, google_api_expr_v1alpha1_Type* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(0, 0), google_api_expr_v1alpha1_Type*) = value;
+  _upb_sethas(msg, 1);
+  *UPB_PTR_AT(msg, UPB_SIZE(4, 8), google_api_expr_v1alpha1_Type*) = value;
 }
 UPB_INLINE struct google_api_expr_v1alpha1_Type* google_api_expr_v1alpha1_Type_FunctionType_mutable_result_type(google_api_expr_v1alpha1_Type_FunctionType *msg, upb_arena *arena) {
   struct google_api_expr_v1alpha1_Type* sub = (struct google_api_expr_v1alpha1_Type*)google_api_expr_v1alpha1_Type_FunctionType_result_type(msg);
@@ -449,15 +486,15 @@ UPB_INLINE struct google_api_expr_v1alpha1_Type* google_api_expr_v1alpha1_Type_F
   return sub;
 }
 UPB_INLINE google_api_expr_v1alpha1_Type** google_api_expr_v1alpha1_Type_FunctionType_mutable_arg_types(google_api_expr_v1alpha1_Type_FunctionType *msg, size_t *len) {
-  return (google_api_expr_v1alpha1_Type**)_upb_array_mutable_accessor(msg, UPB_SIZE(4, 8), len);
+  return (google_api_expr_v1alpha1_Type**)_upb_array_mutable_accessor(msg, UPB_SIZE(8, 16), len);
 }
 UPB_INLINE google_api_expr_v1alpha1_Type** google_api_expr_v1alpha1_Type_FunctionType_resize_arg_types(google_api_expr_v1alpha1_Type_FunctionType *msg, size_t len, upb_arena *arena) {
-  return (google_api_expr_v1alpha1_Type**)_upb_array_resize_accessor(msg, UPB_SIZE(4, 8), len, UPB_TYPE_MESSAGE, arena);
+  return (google_api_expr_v1alpha1_Type**)_upb_array_resize_accessor2(msg, UPB_SIZE(8, 16), len, UPB_SIZE(2, 3), arena);
 }
 UPB_INLINE struct google_api_expr_v1alpha1_Type* google_api_expr_v1alpha1_Type_FunctionType_add_arg_types(google_api_expr_v1alpha1_Type_FunctionType *msg, upb_arena *arena) {
   struct google_api_expr_v1alpha1_Type* sub = (struct google_api_expr_v1alpha1_Type*)_upb_msg_new(&google_api_expr_v1alpha1_Type_msginit, arena);
-  bool ok = _upb_array_append_accessor(
-      msg, UPB_SIZE(4, 8), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena);
+  bool ok = _upb_array_append_accessor2(
+      msg, UPB_SIZE(8, 16), UPB_SIZE(2, 3), &sub, arena);
   if (!ok) return NULL;
   return sub;
 }
@@ -472,6 +509,12 @@ UPB_INLINE google_api_expr_v1alpha1_Type_AbstractType *google_api_expr_v1alpha1_
   google_api_expr_v1alpha1_Type_AbstractType *ret = google_api_expr_v1alpha1_Type_AbstractType_new(arena);
   return (ret && upb_decode(buf, size, ret, &google_api_expr_v1alpha1_Type_AbstractType_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE google_api_expr_v1alpha1_Type_AbstractType *google_api_expr_v1alpha1_Type_AbstractType_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  google_api_expr_v1alpha1_Type_AbstractType *ret = google_api_expr_v1alpha1_Type_AbstractType_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &google_api_expr_v1alpha1_Type_AbstractType_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *google_api_expr_v1alpha1_Type_AbstractType_serialize(const google_api_expr_v1alpha1_Type_AbstractType *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &google_api_expr_v1alpha1_Type_AbstractType_msginit, arena, len);
 }
@@ -487,12 +530,12 @@ UPB_INLINE google_api_expr_v1alpha1_Type** google_api_expr_v1alpha1_Type_Abstrac
   return (google_api_expr_v1alpha1_Type**)_upb_array_mutable_accessor(msg, UPB_SIZE(8, 16), len);
 }
 UPB_INLINE google_api_expr_v1alpha1_Type** google_api_expr_v1alpha1_Type_AbstractType_resize_parameter_types(google_api_expr_v1alpha1_Type_AbstractType *msg, size_t len, upb_arena *arena) {
-  return (google_api_expr_v1alpha1_Type**)_upb_array_resize_accessor(msg, UPB_SIZE(8, 16), len, UPB_TYPE_MESSAGE, arena);
+  return (google_api_expr_v1alpha1_Type**)_upb_array_resize_accessor2(msg, UPB_SIZE(8, 16), len, UPB_SIZE(2, 3), arena);
 }
 UPB_INLINE struct google_api_expr_v1alpha1_Type* google_api_expr_v1alpha1_Type_AbstractType_add_parameter_types(google_api_expr_v1alpha1_Type_AbstractType *msg, upb_arena *arena) {
   struct google_api_expr_v1alpha1_Type* sub = (struct google_api_expr_v1alpha1_Type*)_upb_msg_new(&google_api_expr_v1alpha1_Type_msginit, arena);
-  bool ok = _upb_array_append_accessor(
-      msg, UPB_SIZE(8, 16), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena);
+  bool ok = _upb_array_append_accessor2(
+      msg, UPB_SIZE(8, 16), UPB_SIZE(2, 3), &sub, arena);
   if (!ok) return NULL;
   return sub;
 }
@@ -507,6 +550,12 @@ UPB_INLINE google_api_expr_v1alpha1_Decl *google_api_expr_v1alpha1_Decl_parse(co
   google_api_expr_v1alpha1_Decl *ret = google_api_expr_v1alpha1_Decl_new(arena);
   return (ret && upb_decode(buf, size, ret, &google_api_expr_v1alpha1_Decl_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE google_api_expr_v1alpha1_Decl *google_api_expr_v1alpha1_Decl_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  google_api_expr_v1alpha1_Decl *ret = google_api_expr_v1alpha1_Decl_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &google_api_expr_v1alpha1_Decl_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *google_api_expr_v1alpha1_Decl_serialize(const google_api_expr_v1alpha1_Decl *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &google_api_expr_v1alpha1_Decl_msginit, arena, len);
 }
@@ -562,18 +611,25 @@ UPB_INLINE google_api_expr_v1alpha1_Decl_IdentDecl *google_api_expr_v1alpha1_Dec
   google_api_expr_v1alpha1_Decl_IdentDecl *ret = google_api_expr_v1alpha1_Decl_IdentDecl_new(arena);
   return (ret && upb_decode(buf, size, ret, &google_api_expr_v1alpha1_Decl_IdentDecl_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE google_api_expr_v1alpha1_Decl_IdentDecl *google_api_expr_v1alpha1_Decl_IdentDecl_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  google_api_expr_v1alpha1_Decl_IdentDecl *ret = google_api_expr_v1alpha1_Decl_IdentDecl_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &google_api_expr_v1alpha1_Decl_IdentDecl_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *google_api_expr_v1alpha1_Decl_IdentDecl_serialize(const google_api_expr_v1alpha1_Decl_IdentDecl *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &google_api_expr_v1alpha1_Decl_IdentDecl_msginit, arena, len);
 }
 
-UPB_INLINE bool google_api_expr_v1alpha1_Decl_IdentDecl_has_type(const google_api_expr_v1alpha1_Decl_IdentDecl *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(8, 16)); }
-UPB_INLINE const google_api_expr_v1alpha1_Type* google_api_expr_v1alpha1_Decl_IdentDecl_type(const google_api_expr_v1alpha1_Decl_IdentDecl *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(8, 16), const google_api_expr_v1alpha1_Type*); }
-UPB_INLINE bool google_api_expr_v1alpha1_Decl_IdentDecl_has_value(const google_api_expr_v1alpha1_Decl_IdentDecl *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(12, 24)); }
-UPB_INLINE const struct google_api_expr_v1alpha1_Constant* google_api_expr_v1alpha1_Decl_IdentDecl_value(const google_api_expr_v1alpha1_Decl_IdentDecl *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(12, 24), const struct google_api_expr_v1alpha1_Constant*); }
-UPB_INLINE upb_strview google_api_expr_v1alpha1_Decl_IdentDecl_doc(const google_api_expr_v1alpha1_Decl_IdentDecl *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(0, 0), upb_strview); }
+UPB_INLINE bool google_api_expr_v1alpha1_Decl_IdentDecl_has_type(const google_api_expr_v1alpha1_Decl_IdentDecl *msg) { return _upb_hasbit(msg, 1); }
+UPB_INLINE const google_api_expr_v1alpha1_Type* google_api_expr_v1alpha1_Decl_IdentDecl_type(const google_api_expr_v1alpha1_Decl_IdentDecl *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(12, 24), const google_api_expr_v1alpha1_Type*); }
+UPB_INLINE bool google_api_expr_v1alpha1_Decl_IdentDecl_has_value(const google_api_expr_v1alpha1_Decl_IdentDecl *msg) { return _upb_hasbit(msg, 2); }
+UPB_INLINE const struct google_api_expr_v1alpha1_Constant* google_api_expr_v1alpha1_Decl_IdentDecl_value(const google_api_expr_v1alpha1_Decl_IdentDecl *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(16, 32), const struct google_api_expr_v1alpha1_Constant*); }
+UPB_INLINE upb_strview google_api_expr_v1alpha1_Decl_IdentDecl_doc(const google_api_expr_v1alpha1_Decl_IdentDecl *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(4, 8), upb_strview); }
 
 UPB_INLINE void google_api_expr_v1alpha1_Decl_IdentDecl_set_type(google_api_expr_v1alpha1_Decl_IdentDecl *msg, google_api_expr_v1alpha1_Type* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(8, 16), google_api_expr_v1alpha1_Type*) = value;
+  _upb_sethas(msg, 1);
+  *UPB_PTR_AT(msg, UPB_SIZE(12, 24), google_api_expr_v1alpha1_Type*) = value;
 }
 UPB_INLINE struct google_api_expr_v1alpha1_Type* google_api_expr_v1alpha1_Decl_IdentDecl_mutable_type(google_api_expr_v1alpha1_Decl_IdentDecl *msg, upb_arena *arena) {
   struct google_api_expr_v1alpha1_Type* sub = (struct google_api_expr_v1alpha1_Type*)google_api_expr_v1alpha1_Decl_IdentDecl_type(msg);
@@ -585,7 +641,8 @@ UPB_INLINE struct google_api_expr_v1alpha1_Type* google_api_expr_v1alpha1_Decl_I
   return sub;
 }
 UPB_INLINE void google_api_expr_v1alpha1_Decl_IdentDecl_set_value(google_api_expr_v1alpha1_Decl_IdentDecl *msg, struct google_api_expr_v1alpha1_Constant* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(12, 24), struct google_api_expr_v1alpha1_Constant*) = value;
+  _upb_sethas(msg, 2);
+  *UPB_PTR_AT(msg, UPB_SIZE(16, 32), struct google_api_expr_v1alpha1_Constant*) = value;
 }
 UPB_INLINE struct google_api_expr_v1alpha1_Constant* google_api_expr_v1alpha1_Decl_IdentDecl_mutable_value(google_api_expr_v1alpha1_Decl_IdentDecl *msg, upb_arena *arena) {
   struct google_api_expr_v1alpha1_Constant* sub = (struct google_api_expr_v1alpha1_Constant*)google_api_expr_v1alpha1_Decl_IdentDecl_value(msg);
@@ -597,7 +654,7 @@ UPB_INLINE struct google_api_expr_v1alpha1_Constant* google_api_expr_v1alpha1_De
   return sub;
 }
 UPB_INLINE void google_api_expr_v1alpha1_Decl_IdentDecl_set_doc(google_api_expr_v1alpha1_Decl_IdentDecl *msg, upb_strview value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(0, 0), upb_strview) = value;
+  *UPB_PTR_AT(msg, UPB_SIZE(4, 8), upb_strview) = value;
 }
 
 /* google.api.expr.v1alpha1.Decl.FunctionDecl */
@@ -610,6 +667,12 @@ UPB_INLINE google_api_expr_v1alpha1_Decl_FunctionDecl *google_api_expr_v1alpha1_
   google_api_expr_v1alpha1_Decl_FunctionDecl *ret = google_api_expr_v1alpha1_Decl_FunctionDecl_new(arena);
   return (ret && upb_decode(buf, size, ret, &google_api_expr_v1alpha1_Decl_FunctionDecl_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE google_api_expr_v1alpha1_Decl_FunctionDecl *google_api_expr_v1alpha1_Decl_FunctionDecl_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  google_api_expr_v1alpha1_Decl_FunctionDecl *ret = google_api_expr_v1alpha1_Decl_FunctionDecl_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &google_api_expr_v1alpha1_Decl_FunctionDecl_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *google_api_expr_v1alpha1_Decl_FunctionDecl_serialize(const google_api_expr_v1alpha1_Decl_FunctionDecl *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &google_api_expr_v1alpha1_Decl_FunctionDecl_msginit, arena, len);
 }
@@ -621,12 +684,12 @@ UPB_INLINE google_api_expr_v1alpha1_Decl_FunctionDecl_Overload** google_api_expr
   return (google_api_expr_v1alpha1_Decl_FunctionDecl_Overload**)_upb_array_mutable_accessor(msg, UPB_SIZE(0, 0), len);
 }
 UPB_INLINE google_api_expr_v1alpha1_Decl_FunctionDecl_Overload** google_api_expr_v1alpha1_Decl_FunctionDecl_resize_overloads(google_api_expr_v1alpha1_Decl_FunctionDecl *msg, size_t len, upb_arena *arena) {
-  return (google_api_expr_v1alpha1_Decl_FunctionDecl_Overload**)_upb_array_resize_accessor(msg, UPB_SIZE(0, 0), len, UPB_TYPE_MESSAGE, arena);
+  return (google_api_expr_v1alpha1_Decl_FunctionDecl_Overload**)_upb_array_resize_accessor2(msg, UPB_SIZE(0, 0), len, UPB_SIZE(2, 3), arena);
 }
 UPB_INLINE struct google_api_expr_v1alpha1_Decl_FunctionDecl_Overload* google_api_expr_v1alpha1_Decl_FunctionDecl_add_overloads(google_api_expr_v1alpha1_Decl_FunctionDecl *msg, upb_arena *arena) {
   struct google_api_expr_v1alpha1_Decl_FunctionDecl_Overload* sub = (struct google_api_expr_v1alpha1_Decl_FunctionDecl_Overload*)_upb_msg_new(&google_api_expr_v1alpha1_Decl_FunctionDecl_Overload_msginit, arena);
-  bool ok = _upb_array_append_accessor(
-      msg, UPB_SIZE(0, 0), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena);
+  bool ok = _upb_array_append_accessor2(
+      msg, UPB_SIZE(0, 0), UPB_SIZE(2, 3), &sub, arena);
   if (!ok) return NULL;
   return sub;
 }
@@ -641,6 +704,12 @@ UPB_INLINE google_api_expr_v1alpha1_Decl_FunctionDecl_Overload *google_api_expr_
   google_api_expr_v1alpha1_Decl_FunctionDecl_Overload *ret = google_api_expr_v1alpha1_Decl_FunctionDecl_Overload_new(arena);
   return (ret && upb_decode(buf, size, ret, &google_api_expr_v1alpha1_Decl_FunctionDecl_Overload_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE google_api_expr_v1alpha1_Decl_FunctionDecl_Overload *google_api_expr_v1alpha1_Decl_FunctionDecl_Overload_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  google_api_expr_v1alpha1_Decl_FunctionDecl_Overload *ret = google_api_expr_v1alpha1_Decl_FunctionDecl_Overload_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &google_api_expr_v1alpha1_Decl_FunctionDecl_Overload_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *google_api_expr_v1alpha1_Decl_FunctionDecl_Overload_serialize(const google_api_expr_v1alpha1_Decl_FunctionDecl_Overload *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &google_api_expr_v1alpha1_Decl_FunctionDecl_Overload_msginit, arena, len);
 }
@@ -649,9 +718,9 @@ UPB_INLINE upb_strview google_api_expr_v1alpha1_Decl_FunctionDecl_Overload_overl
 UPB_INLINE bool google_api_expr_v1alpha1_Decl_FunctionDecl_Overload_has_params(const google_api_expr_v1alpha1_Decl_FunctionDecl_Overload *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(24, 48)); }
 UPB_INLINE const google_api_expr_v1alpha1_Type* const* google_api_expr_v1alpha1_Decl_FunctionDecl_Overload_params(const google_api_expr_v1alpha1_Decl_FunctionDecl_Overload *msg, size_t *len) { return (const google_api_expr_v1alpha1_Type* const*)_upb_array_accessor(msg, UPB_SIZE(24, 48), len); }
 UPB_INLINE upb_strview const* google_api_expr_v1alpha1_Decl_FunctionDecl_Overload_type_params(const google_api_expr_v1alpha1_Decl_FunctionDecl_Overload *msg, size_t *len) { return (upb_strview const*)_upb_array_accessor(msg, UPB_SIZE(28, 56), len); }
-UPB_INLINE bool google_api_expr_v1alpha1_Decl_FunctionDecl_Overload_has_result_type(const google_api_expr_v1alpha1_Decl_FunctionDecl_Overload *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(20, 40)); }
+UPB_INLINE bool google_api_expr_v1alpha1_Decl_FunctionDecl_Overload_has_result_type(const google_api_expr_v1alpha1_Decl_FunctionDecl_Overload *msg) { return _upb_hasbit(msg, 1); }
 UPB_INLINE const google_api_expr_v1alpha1_Type* google_api_expr_v1alpha1_Decl_FunctionDecl_Overload_result_type(const google_api_expr_v1alpha1_Decl_FunctionDecl_Overload *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(20, 40), const google_api_expr_v1alpha1_Type*); }
-UPB_INLINE bool google_api_expr_v1alpha1_Decl_FunctionDecl_Overload_is_instance_function(const google_api_expr_v1alpha1_Decl_FunctionDecl_Overload *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(0, 0), bool); }
+UPB_INLINE bool google_api_expr_v1alpha1_Decl_FunctionDecl_Overload_is_instance_function(const google_api_expr_v1alpha1_Decl_FunctionDecl_Overload *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(1, 1), bool); }
 UPB_INLINE upb_strview google_api_expr_v1alpha1_Decl_FunctionDecl_Overload_doc(const google_api_expr_v1alpha1_Decl_FunctionDecl_Overload *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(12, 24), upb_strview); }
 
 UPB_INLINE void google_api_expr_v1alpha1_Decl_FunctionDecl_Overload_set_overload_id(google_api_expr_v1alpha1_Decl_FunctionDecl_Overload *msg, upb_strview value) {
@@ -661,12 +730,12 @@ UPB_INLINE google_api_expr_v1alpha1_Type** google_api_expr_v1alpha1_Decl_Functio
   return (google_api_expr_v1alpha1_Type**)_upb_array_mutable_accessor(msg, UPB_SIZE(24, 48), len);
 }
 UPB_INLINE google_api_expr_v1alpha1_Type** google_api_expr_v1alpha1_Decl_FunctionDecl_Overload_resize_params(google_api_expr_v1alpha1_Decl_FunctionDecl_Overload *msg, size_t len, upb_arena *arena) {
-  return (google_api_expr_v1alpha1_Type**)_upb_array_resize_accessor(msg, UPB_SIZE(24, 48), len, UPB_TYPE_MESSAGE, arena);
+  return (google_api_expr_v1alpha1_Type**)_upb_array_resize_accessor2(msg, UPB_SIZE(24, 48), len, UPB_SIZE(2, 3), arena);
 }
 UPB_INLINE struct google_api_expr_v1alpha1_Type* google_api_expr_v1alpha1_Decl_FunctionDecl_Overload_add_params(google_api_expr_v1alpha1_Decl_FunctionDecl_Overload *msg, upb_arena *arena) {
   struct google_api_expr_v1alpha1_Type* sub = (struct google_api_expr_v1alpha1_Type*)_upb_msg_new(&google_api_expr_v1alpha1_Type_msginit, arena);
-  bool ok = _upb_array_append_accessor(
-      msg, UPB_SIZE(24, 48), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena);
+  bool ok = _upb_array_append_accessor2(
+      msg, UPB_SIZE(24, 48), UPB_SIZE(2, 3), &sub, arena);
   if (!ok) return NULL;
   return sub;
 }
@@ -674,13 +743,14 @@ UPB_INLINE upb_strview* google_api_expr_v1alpha1_Decl_FunctionDecl_Overload_muta
   return (upb_strview*)_upb_array_mutable_accessor(msg, UPB_SIZE(28, 56), len);
 }
 UPB_INLINE upb_strview* google_api_expr_v1alpha1_Decl_FunctionDecl_Overload_resize_type_params(google_api_expr_v1alpha1_Decl_FunctionDecl_Overload *msg, size_t len, upb_arena *arena) {
-  return (upb_strview*)_upb_array_resize_accessor(msg, UPB_SIZE(28, 56), len, UPB_TYPE_STRING, arena);
+  return (upb_strview*)_upb_array_resize_accessor2(msg, UPB_SIZE(28, 56), len, UPB_SIZE(3, 4), arena);
 }
 UPB_INLINE bool google_api_expr_v1alpha1_Decl_FunctionDecl_Overload_add_type_params(google_api_expr_v1alpha1_Decl_FunctionDecl_Overload *msg, upb_strview val, upb_arena *arena) {
-  return _upb_array_append_accessor(msg, UPB_SIZE(28, 56), UPB_SIZE(8, 16), UPB_TYPE_STRING, &val,
+  return _upb_array_append_accessor2(msg, UPB_SIZE(28, 56), UPB_SIZE(3, 4), &val,
       arena);
 }
 UPB_INLINE void google_api_expr_v1alpha1_Decl_FunctionDecl_Overload_set_result_type(google_api_expr_v1alpha1_Decl_FunctionDecl_Overload *msg, google_api_expr_v1alpha1_Type* value) {
+  _upb_sethas(msg, 1);
   *UPB_PTR_AT(msg, UPB_SIZE(20, 40), google_api_expr_v1alpha1_Type*) = value;
 }
 UPB_INLINE struct google_api_expr_v1alpha1_Type* google_api_expr_v1alpha1_Decl_FunctionDecl_Overload_mutable_result_type(google_api_expr_v1alpha1_Decl_FunctionDecl_Overload *msg, upb_arena *arena) {
@@ -693,7 +763,7 @@ UPB_INLINE struct google_api_expr_v1alpha1_Type* google_api_expr_v1alpha1_Decl_F
   return sub;
 }
 UPB_INLINE void google_api_expr_v1alpha1_Decl_FunctionDecl_Overload_set_is_instance_function(google_api_expr_v1alpha1_Decl_FunctionDecl_Overload *msg, bool value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(0, 0), bool) = value;
+  *UPB_PTR_AT(msg, UPB_SIZE(1, 1), bool) = value;
 }
 UPB_INLINE void google_api_expr_v1alpha1_Decl_FunctionDecl_Overload_set_doc(google_api_expr_v1alpha1_Decl_FunctionDecl_Overload *msg, upb_strview value) {
   *UPB_PTR_AT(msg, UPB_SIZE(12, 24), upb_strview) = value;
@@ -709,30 +779,37 @@ UPB_INLINE google_api_expr_v1alpha1_Reference *google_api_expr_v1alpha1_Referenc
   google_api_expr_v1alpha1_Reference *ret = google_api_expr_v1alpha1_Reference_new(arena);
   return (ret && upb_decode(buf, size, ret, &google_api_expr_v1alpha1_Reference_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE google_api_expr_v1alpha1_Reference *google_api_expr_v1alpha1_Reference_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  google_api_expr_v1alpha1_Reference *ret = google_api_expr_v1alpha1_Reference_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &google_api_expr_v1alpha1_Reference_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *google_api_expr_v1alpha1_Reference_serialize(const google_api_expr_v1alpha1_Reference *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &google_api_expr_v1alpha1_Reference_msginit, arena, len);
 }
 
-UPB_INLINE upb_strview google_api_expr_v1alpha1_Reference_name(const google_api_expr_v1alpha1_Reference *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(0, 0), upb_strview); }
-UPB_INLINE upb_strview const* google_api_expr_v1alpha1_Reference_overload_id(const google_api_expr_v1alpha1_Reference *msg, size_t *len) { return (upb_strview const*)_upb_array_accessor(msg, UPB_SIZE(12, 24), len); }
-UPB_INLINE bool google_api_expr_v1alpha1_Reference_has_value(const google_api_expr_v1alpha1_Reference *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(8, 16)); }
-UPB_INLINE const struct google_api_expr_v1alpha1_Constant* google_api_expr_v1alpha1_Reference_value(const google_api_expr_v1alpha1_Reference *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(8, 16), const struct google_api_expr_v1alpha1_Constant*); }
+UPB_INLINE upb_strview google_api_expr_v1alpha1_Reference_name(const google_api_expr_v1alpha1_Reference *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(4, 8), upb_strview); }
+UPB_INLINE upb_strview const* google_api_expr_v1alpha1_Reference_overload_id(const google_api_expr_v1alpha1_Reference *msg, size_t *len) { return (upb_strview const*)_upb_array_accessor(msg, UPB_SIZE(16, 32), len); }
+UPB_INLINE bool google_api_expr_v1alpha1_Reference_has_value(const google_api_expr_v1alpha1_Reference *msg) { return _upb_hasbit(msg, 1); }
+UPB_INLINE const struct google_api_expr_v1alpha1_Constant* google_api_expr_v1alpha1_Reference_value(const google_api_expr_v1alpha1_Reference *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(12, 24), const struct google_api_expr_v1alpha1_Constant*); }
 
 UPB_INLINE void google_api_expr_v1alpha1_Reference_set_name(google_api_expr_v1alpha1_Reference *msg, upb_strview value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(0, 0), upb_strview) = value;
+  *UPB_PTR_AT(msg, UPB_SIZE(4, 8), upb_strview) = value;
 }
 UPB_INLINE upb_strview* google_api_expr_v1alpha1_Reference_mutable_overload_id(google_api_expr_v1alpha1_Reference *msg, size_t *len) {
-  return (upb_strview*)_upb_array_mutable_accessor(msg, UPB_SIZE(12, 24), len);
+  return (upb_strview*)_upb_array_mutable_accessor(msg, UPB_SIZE(16, 32), len);
 }
 UPB_INLINE upb_strview* google_api_expr_v1alpha1_Reference_resize_overload_id(google_api_expr_v1alpha1_Reference *msg, size_t len, upb_arena *arena) {
-  return (upb_strview*)_upb_array_resize_accessor(msg, UPB_SIZE(12, 24), len, UPB_TYPE_STRING, arena);
+  return (upb_strview*)_upb_array_resize_accessor2(msg, UPB_SIZE(16, 32), len, UPB_SIZE(3, 4), arena);
 }
 UPB_INLINE bool google_api_expr_v1alpha1_Reference_add_overload_id(google_api_expr_v1alpha1_Reference *msg, upb_strview val, upb_arena *arena) {
-  return _upb_array_append_accessor(msg, UPB_SIZE(12, 24), UPB_SIZE(8, 16), UPB_TYPE_STRING, &val,
+  return _upb_array_append_accessor2(msg, UPB_SIZE(16, 32), UPB_SIZE(3, 4), &val,
       arena);
 }
 UPB_INLINE void google_api_expr_v1alpha1_Reference_set_value(google_api_expr_v1alpha1_Reference *msg, struct google_api_expr_v1alpha1_Constant* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(8, 16), struct google_api_expr_v1alpha1_Constant*) = value;
+  _upb_sethas(msg, 1);
+  *UPB_PTR_AT(msg, UPB_SIZE(12, 24), struct google_api_expr_v1alpha1_Constant*) = value;
 }
 UPB_INLINE struct google_api_expr_v1alpha1_Constant* google_api_expr_v1alpha1_Reference_mutable_value(google_api_expr_v1alpha1_Reference *msg, upb_arena *arena) {
   struct google_api_expr_v1alpha1_Constant* sub = (struct google_api_expr_v1alpha1_Constant*)google_api_expr_v1alpha1_Reference_value(msg);
index 0169d39..d3962ea 100644 (file)
@@ -21,14 +21,14 @@ static const upb_msglayout *const google_api_expr_v1alpha1_ParsedExpr_submsgs[2]
 };
 
 static const upb_msglayout_field google_api_expr_v1alpha1_ParsedExpr__fields[2] = {
-  {2, UPB_SIZE(0, 0), 0, 0, 11, 1},
-  {3, UPB_SIZE(4, 8), 0, 1, 11, 1},
+  {2, UPB_SIZE(4, 8), 1, 0, 11, 1},
+  {3, UPB_SIZE(8, 16), 2, 1, 11, 1},
 };
 
 const upb_msglayout google_api_expr_v1alpha1_ParsedExpr_msginit = {
   &google_api_expr_v1alpha1_ParsedExpr_submsgs[0],
   &google_api_expr_v1alpha1_ParsedExpr__fields[0],
-  UPB_SIZE(8, 16), 2, false,
+  UPB_SIZE(16, 24), 2, false, 255,
 };
 
 static const upb_msglayout *const google_api_expr_v1alpha1_Expr_submsgs[7] = {
@@ -55,7 +55,7 @@ static const upb_msglayout_field google_api_expr_v1alpha1_Expr__fields[8] = {
 const upb_msglayout google_api_expr_v1alpha1_Expr_msginit = {
   &google_api_expr_v1alpha1_Expr_submsgs[0],
   &google_api_expr_v1alpha1_Expr__fields[0],
-  UPB_SIZE(16, 24), 8, false,
+  UPB_SIZE(16, 24), 8, false, 255,
 };
 
 static const upb_msglayout_field google_api_expr_v1alpha1_Expr_Ident__fields[1] = {
@@ -65,7 +65,7 @@ static const upb_msglayout_field google_api_expr_v1alpha1_Expr_Ident__fields[1]
 const upb_msglayout google_api_expr_v1alpha1_Expr_Ident_msginit = {
   NULL,
   &google_api_expr_v1alpha1_Expr_Ident__fields[0],
-  UPB_SIZE(8, 16), 1, false,
+  UPB_SIZE(8, 16), 1, false, 255,
 };
 
 static const upb_msglayout *const google_api_expr_v1alpha1_Expr_Select_submsgs[1] = {
@@ -73,31 +73,31 @@ static const upb_msglayout *const google_api_expr_v1alpha1_Expr_Select_submsgs[1
 };
 
 static const upb_msglayout_field google_api_expr_v1alpha1_Expr_Select__fields[3] = {
-  {1, UPB_SIZE(12, 24), 0, 0, 11, 1},
+  {1, UPB_SIZE(12, 24), 1, 0, 11, 1},
   {2, UPB_SIZE(4, 8), 0, 0, 9, 1},
-  {3, UPB_SIZE(0, 0), 0, 0, 8, 1},
+  {3, UPB_SIZE(1, 1), 0, 0, 8, 1},
 };
 
 const upb_msglayout google_api_expr_v1alpha1_Expr_Select_msginit = {
   &google_api_expr_v1alpha1_Expr_Select_submsgs[0],
   &google_api_expr_v1alpha1_Expr_Select__fields[0],
-  UPB_SIZE(16, 32), 3, false,
+  UPB_SIZE(16, 32), 3, false, 255,
 };
 
-static const upb_msglayout *const google_api_expr_v1alpha1_Expr_Call_submsgs[2] = {
+static const upb_msglayout *const google_api_expr_v1alpha1_Expr_Call_submsgs[1] = {
   &google_api_expr_v1alpha1_Expr_msginit,
 };
 
 static const upb_msglayout_field google_api_expr_v1alpha1_Expr_Call__fields[3] = {
-  {1, UPB_SIZE(8, 16), 0, 0, 11, 1},
-  {2, UPB_SIZE(0, 0), 0, 0, 9, 1},
-  {3, UPB_SIZE(12, 24), 0, 0, 11, 3},
+  {1, UPB_SIZE(12, 24), 1, 0, 11, 1},
+  {2, UPB_SIZE(4, 8), 0, 0, 9, 1},
+  {3, UPB_SIZE(16, 32), 0, 0, 11, 3},
 };
 
 const upb_msglayout google_api_expr_v1alpha1_Expr_Call_msginit = {
   &google_api_expr_v1alpha1_Expr_Call_submsgs[0],
   &google_api_expr_v1alpha1_Expr_Call__fields[0],
-  UPB_SIZE(16, 32), 3, false,
+  UPB_SIZE(24, 48), 3, false, 255,
 };
 
 static const upb_msglayout *const google_api_expr_v1alpha1_Expr_CreateList_submsgs[1] = {
@@ -111,7 +111,7 @@ static const upb_msglayout_field google_api_expr_v1alpha1_Expr_CreateList__field
 const upb_msglayout google_api_expr_v1alpha1_Expr_CreateList_msginit = {
   &google_api_expr_v1alpha1_Expr_CreateList_submsgs[0],
   &google_api_expr_v1alpha1_Expr_CreateList__fields[0],
-  UPB_SIZE(4, 8), 1, false,
+  UPB_SIZE(8, 8), 1, false, 255,
 };
 
 static const upb_msglayout *const google_api_expr_v1alpha1_Expr_CreateStruct_submsgs[1] = {
@@ -126,44 +126,44 @@ static const upb_msglayout_field google_api_expr_v1alpha1_Expr_CreateStruct__fie
 const upb_msglayout google_api_expr_v1alpha1_Expr_CreateStruct_msginit = {
   &google_api_expr_v1alpha1_Expr_CreateStruct_submsgs[0],
   &google_api_expr_v1alpha1_Expr_CreateStruct__fields[0],
-  UPB_SIZE(16, 32), 2, false,
+  UPB_SIZE(16, 32), 2, false, 255,
 };
 
-static const upb_msglayout *const google_api_expr_v1alpha1_Expr_CreateStruct_Entry_submsgs[2] = {
+static const upb_msglayout *const google_api_expr_v1alpha1_Expr_CreateStruct_Entry_submsgs[1] = {
   &google_api_expr_v1alpha1_Expr_msginit,
 };
 
 static const upb_msglayout_field google_api_expr_v1alpha1_Expr_CreateStruct_Entry__fields[4] = {
-  {1, UPB_SIZE(0, 0), 0, 0, 3, 1},
-  {2, UPB_SIZE(12, 16), UPB_SIZE(-21, -33), 0, 9, 1},
-  {3, UPB_SIZE(12, 16), UPB_SIZE(-21, -33), 0, 11, 1},
-  {4, UPB_SIZE(8, 8), 0, 0, 11, 1},
+  {1, UPB_SIZE(8, 8), 0, 0, 3, 1},
+  {2, UPB_SIZE(20, 24), UPB_SIZE(-29, -41), 0, 9, 1},
+  {3, UPB_SIZE(20, 24), UPB_SIZE(-29, -41), 0, 11, 1},
+  {4, UPB_SIZE(16, 16), 1, 0, 11, 1},
 };
 
 const upb_msglayout google_api_expr_v1alpha1_Expr_CreateStruct_Entry_msginit = {
   &google_api_expr_v1alpha1_Expr_CreateStruct_Entry_submsgs[0],
   &google_api_expr_v1alpha1_Expr_CreateStruct_Entry__fields[0],
-  UPB_SIZE(24, 48), 4, false,
+  UPB_SIZE(32, 48), 4, false, 255,
 };
 
-static const upb_msglayout *const google_api_expr_v1alpha1_Expr_Comprehension_submsgs[5] = {
+static const upb_msglayout *const google_api_expr_v1alpha1_Expr_Comprehension_submsgs[1] = {
   &google_api_expr_v1alpha1_Expr_msginit,
 };
 
 static const upb_msglayout_field google_api_expr_v1alpha1_Expr_Comprehension__fields[7] = {
-  {1, UPB_SIZE(0, 0), 0, 0, 9, 1},
-  {2, UPB_SIZE(16, 32), 0, 0, 11, 1},
-  {3, UPB_SIZE(8, 16), 0, 0, 9, 1},
-  {4, UPB_SIZE(20, 40), 0, 0, 11, 1},
-  {5, UPB_SIZE(24, 48), 0, 0, 11, 1},
-  {6, UPB_SIZE(28, 56), 0, 0, 11, 1},
-  {7, UPB_SIZE(32, 64), 0, 0, 11, 1},
+  {1, UPB_SIZE(4, 8), 0, 0, 9, 1},
+  {2, UPB_SIZE(20, 40), 1, 0, 11, 1},
+  {3, UPB_SIZE(12, 24), 0, 0, 9, 1},
+  {4, UPB_SIZE(24, 48), 2, 0, 11, 1},
+  {5, UPB_SIZE(28, 56), 3, 0, 11, 1},
+  {6, UPB_SIZE(32, 64), 4, 0, 11, 1},
+  {7, UPB_SIZE(36, 72), 5, 0, 11, 1},
 };
 
 const upb_msglayout google_api_expr_v1alpha1_Expr_Comprehension_msginit = {
   &google_api_expr_v1alpha1_Expr_Comprehension_submsgs[0],
   &google_api_expr_v1alpha1_Expr_Comprehension__fields[0],
-  UPB_SIZE(40, 80), 7, false,
+  UPB_SIZE(40, 80), 7, false, 255,
 };
 
 static const upb_msglayout *const google_api_expr_v1alpha1_Constant_submsgs[2] = {
@@ -186,7 +186,7 @@ static const upb_msglayout_field google_api_expr_v1alpha1_Constant__fields[9] =
 const upb_msglayout google_api_expr_v1alpha1_Constant_msginit = {
   &google_api_expr_v1alpha1_Constant_submsgs[0],
   &google_api_expr_v1alpha1_Constant__fields[0],
-  UPB_SIZE(16, 32), 9, false,
+  UPB_SIZE(16, 32), 9, false, 255,
 };
 
 static const upb_msglayout *const google_api_expr_v1alpha1_SourceInfo_submsgs[1] = {
@@ -203,7 +203,7 @@ static const upb_msglayout_field google_api_expr_v1alpha1_SourceInfo__fields[4]
 const upb_msglayout google_api_expr_v1alpha1_SourceInfo_msginit = {
   &google_api_expr_v1alpha1_SourceInfo_submsgs[0],
   &google_api_expr_v1alpha1_SourceInfo__fields[0],
-  UPB_SIZE(24, 48), 4, false,
+  UPB_SIZE(24, 48), 4, false, 255,
 };
 
 static const upb_msglayout_field google_api_expr_v1alpha1_SourceInfo_PositionsEntry__fields[2] = {
@@ -214,7 +214,7 @@ static const upb_msglayout_field google_api_expr_v1alpha1_SourceInfo_PositionsEn
 const upb_msglayout google_api_expr_v1alpha1_SourceInfo_PositionsEntry_msginit = {
   NULL,
   &google_api_expr_v1alpha1_SourceInfo_PositionsEntry__fields[0],
-  UPB_SIZE(16, 32), 2, false,
+  UPB_SIZE(16, 32), 2, false, 255,
 };
 
 static const upb_msglayout_field google_api_expr_v1alpha1_SourcePosition__fields[4] = {
@@ -227,7 +227,7 @@ static const upb_msglayout_field google_api_expr_v1alpha1_SourcePosition__fields
 const upb_msglayout google_api_expr_v1alpha1_SourcePosition_msginit = {
   NULL,
   &google_api_expr_v1alpha1_SourcePosition__fields[0],
-  UPB_SIZE(24, 32), 4, false,
+  UPB_SIZE(24, 32), 4, false, 255,
 };
 
 #include "upb/port_undef.inc"
index 6c4b7f8..861c3a5 100644 (file)
@@ -11,6 +11,7 @@
 
 #include "upb/msg.h"
 #include "upb/decode.h"
+#include "upb/decode_fast.h"
 #include "upb/encode.h"
 
 #include "upb/port_def.inc"
@@ -74,17 +75,24 @@ UPB_INLINE google_api_expr_v1alpha1_ParsedExpr *google_api_expr_v1alpha1_ParsedE
   google_api_expr_v1alpha1_ParsedExpr *ret = google_api_expr_v1alpha1_ParsedExpr_new(arena);
   return (ret && upb_decode(buf, size, ret, &google_api_expr_v1alpha1_ParsedExpr_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE google_api_expr_v1alpha1_ParsedExpr *google_api_expr_v1alpha1_ParsedExpr_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  google_api_expr_v1alpha1_ParsedExpr *ret = google_api_expr_v1alpha1_ParsedExpr_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &google_api_expr_v1alpha1_ParsedExpr_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *google_api_expr_v1alpha1_ParsedExpr_serialize(const google_api_expr_v1alpha1_ParsedExpr *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &google_api_expr_v1alpha1_ParsedExpr_msginit, arena, len);
 }
 
-UPB_INLINE bool google_api_expr_v1alpha1_ParsedExpr_has_expr(const google_api_expr_v1alpha1_ParsedExpr *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(0, 0)); }
-UPB_INLINE const google_api_expr_v1alpha1_Expr* google_api_expr_v1alpha1_ParsedExpr_expr(const google_api_expr_v1alpha1_ParsedExpr *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(0, 0), const google_api_expr_v1alpha1_Expr*); }
-UPB_INLINE bool google_api_expr_v1alpha1_ParsedExpr_has_source_info(const google_api_expr_v1alpha1_ParsedExpr *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(4, 8)); }
-UPB_INLINE const google_api_expr_v1alpha1_SourceInfo* google_api_expr_v1alpha1_ParsedExpr_source_info(const google_api_expr_v1alpha1_ParsedExpr *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(4, 8), const google_api_expr_v1alpha1_SourceInfo*); }
+UPB_INLINE bool google_api_expr_v1alpha1_ParsedExpr_has_expr(const google_api_expr_v1alpha1_ParsedExpr *msg) { return _upb_hasbit(msg, 1); }
+UPB_INLINE const google_api_expr_v1alpha1_Expr* google_api_expr_v1alpha1_ParsedExpr_expr(const google_api_expr_v1alpha1_ParsedExpr *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(4, 8), const google_api_expr_v1alpha1_Expr*); }
+UPB_INLINE bool google_api_expr_v1alpha1_ParsedExpr_has_source_info(const google_api_expr_v1alpha1_ParsedExpr *msg) { return _upb_hasbit(msg, 2); }
+UPB_INLINE const google_api_expr_v1alpha1_SourceInfo* google_api_expr_v1alpha1_ParsedExpr_source_info(const google_api_expr_v1alpha1_ParsedExpr *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(8, 16), const google_api_expr_v1alpha1_SourceInfo*); }
 
 UPB_INLINE void google_api_expr_v1alpha1_ParsedExpr_set_expr(google_api_expr_v1alpha1_ParsedExpr *msg, google_api_expr_v1alpha1_Expr* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(0, 0), google_api_expr_v1alpha1_Expr*) = value;
+  _upb_sethas(msg, 1);
+  *UPB_PTR_AT(msg, UPB_SIZE(4, 8), google_api_expr_v1alpha1_Expr*) = value;
 }
 UPB_INLINE struct google_api_expr_v1alpha1_Expr* google_api_expr_v1alpha1_ParsedExpr_mutable_expr(google_api_expr_v1alpha1_ParsedExpr *msg, upb_arena *arena) {
   struct google_api_expr_v1alpha1_Expr* sub = (struct google_api_expr_v1alpha1_Expr*)google_api_expr_v1alpha1_ParsedExpr_expr(msg);
@@ -96,7 +104,8 @@ UPB_INLINE struct google_api_expr_v1alpha1_Expr* google_api_expr_v1alpha1_Parsed
   return sub;
 }
 UPB_INLINE void google_api_expr_v1alpha1_ParsedExpr_set_source_info(google_api_expr_v1alpha1_ParsedExpr *msg, google_api_expr_v1alpha1_SourceInfo* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(4, 8), google_api_expr_v1alpha1_SourceInfo*) = value;
+  _upb_sethas(msg, 2);
+  *UPB_PTR_AT(msg, UPB_SIZE(8, 16), google_api_expr_v1alpha1_SourceInfo*) = value;
 }
 UPB_INLINE struct google_api_expr_v1alpha1_SourceInfo* google_api_expr_v1alpha1_ParsedExpr_mutable_source_info(google_api_expr_v1alpha1_ParsedExpr *msg, upb_arena *arena) {
   struct google_api_expr_v1alpha1_SourceInfo* sub = (struct google_api_expr_v1alpha1_SourceInfo*)google_api_expr_v1alpha1_ParsedExpr_source_info(msg);
@@ -118,6 +127,12 @@ UPB_INLINE google_api_expr_v1alpha1_Expr *google_api_expr_v1alpha1_Expr_parse(co
   google_api_expr_v1alpha1_Expr *ret = google_api_expr_v1alpha1_Expr_new(arena);
   return (ret && upb_decode(buf, size, ret, &google_api_expr_v1alpha1_Expr_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE google_api_expr_v1alpha1_Expr *google_api_expr_v1alpha1_Expr_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  google_api_expr_v1alpha1_Expr *ret = google_api_expr_v1alpha1_Expr_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &google_api_expr_v1alpha1_Expr_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *google_api_expr_v1alpha1_Expr_serialize(const google_api_expr_v1alpha1_Expr *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &google_api_expr_v1alpha1_Expr_msginit, arena, len);
 }
@@ -248,6 +263,12 @@ UPB_INLINE google_api_expr_v1alpha1_Expr_Ident *google_api_expr_v1alpha1_Expr_Id
   google_api_expr_v1alpha1_Expr_Ident *ret = google_api_expr_v1alpha1_Expr_Ident_new(arena);
   return (ret && upb_decode(buf, size, ret, &google_api_expr_v1alpha1_Expr_Ident_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE google_api_expr_v1alpha1_Expr_Ident *google_api_expr_v1alpha1_Expr_Ident_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  google_api_expr_v1alpha1_Expr_Ident *ret = google_api_expr_v1alpha1_Expr_Ident_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &google_api_expr_v1alpha1_Expr_Ident_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *google_api_expr_v1alpha1_Expr_Ident_serialize(const google_api_expr_v1alpha1_Expr_Ident *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &google_api_expr_v1alpha1_Expr_Ident_msginit, arena, len);
 }
@@ -268,16 +289,23 @@ UPB_INLINE google_api_expr_v1alpha1_Expr_Select *google_api_expr_v1alpha1_Expr_S
   google_api_expr_v1alpha1_Expr_Select *ret = google_api_expr_v1alpha1_Expr_Select_new(arena);
   return (ret && upb_decode(buf, size, ret, &google_api_expr_v1alpha1_Expr_Select_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE google_api_expr_v1alpha1_Expr_Select *google_api_expr_v1alpha1_Expr_Select_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  google_api_expr_v1alpha1_Expr_Select *ret = google_api_expr_v1alpha1_Expr_Select_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &google_api_expr_v1alpha1_Expr_Select_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *google_api_expr_v1alpha1_Expr_Select_serialize(const google_api_expr_v1alpha1_Expr_Select *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &google_api_expr_v1alpha1_Expr_Select_msginit, arena, len);
 }
 
-UPB_INLINE bool google_api_expr_v1alpha1_Expr_Select_has_operand(const google_api_expr_v1alpha1_Expr_Select *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(12, 24)); }
+UPB_INLINE bool google_api_expr_v1alpha1_Expr_Select_has_operand(const google_api_expr_v1alpha1_Expr_Select *msg) { return _upb_hasbit(msg, 1); }
 UPB_INLINE const google_api_expr_v1alpha1_Expr* google_api_expr_v1alpha1_Expr_Select_operand(const google_api_expr_v1alpha1_Expr_Select *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(12, 24), const google_api_expr_v1alpha1_Expr*); }
 UPB_INLINE upb_strview google_api_expr_v1alpha1_Expr_Select_field(const google_api_expr_v1alpha1_Expr_Select *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(4, 8), upb_strview); }
-UPB_INLINE bool google_api_expr_v1alpha1_Expr_Select_test_only(const google_api_expr_v1alpha1_Expr_Select *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(0, 0), bool); }
+UPB_INLINE bool google_api_expr_v1alpha1_Expr_Select_test_only(const google_api_expr_v1alpha1_Expr_Select *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(1, 1), bool); }
 
 UPB_INLINE void google_api_expr_v1alpha1_Expr_Select_set_operand(google_api_expr_v1alpha1_Expr_Select *msg, google_api_expr_v1alpha1_Expr* value) {
+  _upb_sethas(msg, 1);
   *UPB_PTR_AT(msg, UPB_SIZE(12, 24), google_api_expr_v1alpha1_Expr*) = value;
 }
 UPB_INLINE struct google_api_expr_v1alpha1_Expr* google_api_expr_v1alpha1_Expr_Select_mutable_operand(google_api_expr_v1alpha1_Expr_Select *msg, upb_arena *arena) {
@@ -293,7 +321,7 @@ UPB_INLINE void google_api_expr_v1alpha1_Expr_Select_set_field(google_api_expr_v
   *UPB_PTR_AT(msg, UPB_SIZE(4, 8), upb_strview) = value;
 }
 UPB_INLINE void google_api_expr_v1alpha1_Expr_Select_set_test_only(google_api_expr_v1alpha1_Expr_Select *msg, bool value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(0, 0), bool) = value;
+  *UPB_PTR_AT(msg, UPB_SIZE(1, 1), bool) = value;
 }
 
 /* google.api.expr.v1alpha1.Expr.Call */
@@ -306,18 +334,25 @@ UPB_INLINE google_api_expr_v1alpha1_Expr_Call *google_api_expr_v1alpha1_Expr_Cal
   google_api_expr_v1alpha1_Expr_Call *ret = google_api_expr_v1alpha1_Expr_Call_new(arena);
   return (ret && upb_decode(buf, size, ret, &google_api_expr_v1alpha1_Expr_Call_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE google_api_expr_v1alpha1_Expr_Call *google_api_expr_v1alpha1_Expr_Call_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  google_api_expr_v1alpha1_Expr_Call *ret = google_api_expr_v1alpha1_Expr_Call_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &google_api_expr_v1alpha1_Expr_Call_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *google_api_expr_v1alpha1_Expr_Call_serialize(const google_api_expr_v1alpha1_Expr_Call *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &google_api_expr_v1alpha1_Expr_Call_msginit, arena, len);
 }
 
-UPB_INLINE bool google_api_expr_v1alpha1_Expr_Call_has_target(const google_api_expr_v1alpha1_Expr_Call *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(8, 16)); }
-UPB_INLINE const google_api_expr_v1alpha1_Expr* google_api_expr_v1alpha1_Expr_Call_target(const google_api_expr_v1alpha1_Expr_Call *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(8, 16), const google_api_expr_v1alpha1_Expr*); }
-UPB_INLINE upb_strview google_api_expr_v1alpha1_Expr_Call_function(const google_api_expr_v1alpha1_Expr_Call *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(0, 0), upb_strview); }
-UPB_INLINE bool google_api_expr_v1alpha1_Expr_Call_has_args(const google_api_expr_v1alpha1_Expr_Call *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(12, 24)); }
-UPB_INLINE const google_api_expr_v1alpha1_Expr* const* google_api_expr_v1alpha1_Expr_Call_args(const google_api_expr_v1alpha1_Expr_Call *msg, size_t *len) { return (const google_api_expr_v1alpha1_Expr* const*)_upb_array_accessor(msg, UPB_SIZE(12, 24), len); }
+UPB_INLINE bool google_api_expr_v1alpha1_Expr_Call_has_target(const google_api_expr_v1alpha1_Expr_Call *msg) { return _upb_hasbit(msg, 1); }
+UPB_INLINE const google_api_expr_v1alpha1_Expr* google_api_expr_v1alpha1_Expr_Call_target(const google_api_expr_v1alpha1_Expr_Call *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(12, 24), const google_api_expr_v1alpha1_Expr*); }
+UPB_INLINE upb_strview google_api_expr_v1alpha1_Expr_Call_function(const google_api_expr_v1alpha1_Expr_Call *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(4, 8), upb_strview); }
+UPB_INLINE bool google_api_expr_v1alpha1_Expr_Call_has_args(const google_api_expr_v1alpha1_Expr_Call *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(16, 32)); }
+UPB_INLINE const google_api_expr_v1alpha1_Expr* const* google_api_expr_v1alpha1_Expr_Call_args(const google_api_expr_v1alpha1_Expr_Call *msg, size_t *len) { return (const google_api_expr_v1alpha1_Expr* const*)_upb_array_accessor(msg, UPB_SIZE(16, 32), len); }
 
 UPB_INLINE void google_api_expr_v1alpha1_Expr_Call_set_target(google_api_expr_v1alpha1_Expr_Call *msg, google_api_expr_v1alpha1_Expr* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(8, 16), google_api_expr_v1alpha1_Expr*) = value;
+  _upb_sethas(msg, 1);
+  *UPB_PTR_AT(msg, UPB_SIZE(12, 24), google_api_expr_v1alpha1_Expr*) = value;
 }
 UPB_INLINE struct google_api_expr_v1alpha1_Expr* google_api_expr_v1alpha1_Expr_Call_mutable_target(google_api_expr_v1alpha1_Expr_Call *msg, upb_arena *arena) {
   struct google_api_expr_v1alpha1_Expr* sub = (struct google_api_expr_v1alpha1_Expr*)google_api_expr_v1alpha1_Expr_Call_target(msg);
@@ -329,18 +364,18 @@ UPB_INLINE struct google_api_expr_v1alpha1_Expr* google_api_expr_v1alpha1_Expr_C
   return sub;
 }
 UPB_INLINE void google_api_expr_v1alpha1_Expr_Call_set_function(google_api_expr_v1alpha1_Expr_Call *msg, upb_strview value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(0, 0), upb_strview) = value;
+  *UPB_PTR_AT(msg, UPB_SIZE(4, 8), upb_strview) = value;
 }
 UPB_INLINE google_api_expr_v1alpha1_Expr** google_api_expr_v1alpha1_Expr_Call_mutable_args(google_api_expr_v1alpha1_Expr_Call *msg, size_t *len) {
-  return (google_api_expr_v1alpha1_Expr**)_upb_array_mutable_accessor(msg, UPB_SIZE(12, 24), len);
+  return (google_api_expr_v1alpha1_Expr**)_upb_array_mutable_accessor(msg, UPB_SIZE(16, 32), len);
 }
 UPB_INLINE google_api_expr_v1alpha1_Expr** google_api_expr_v1alpha1_Expr_Call_resize_args(google_api_expr_v1alpha1_Expr_Call *msg, size_t len, upb_arena *arena) {
-  return (google_api_expr_v1alpha1_Expr**)_upb_array_resize_accessor(msg, UPB_SIZE(12, 24), len, UPB_TYPE_MESSAGE, arena);
+  return (google_api_expr_v1alpha1_Expr**)_upb_array_resize_accessor2(msg, UPB_SIZE(16, 32), len, UPB_SIZE(2, 3), arena);
 }
 UPB_INLINE struct google_api_expr_v1alpha1_Expr* google_api_expr_v1alpha1_Expr_Call_add_args(google_api_expr_v1alpha1_Expr_Call *msg, upb_arena *arena) {
   struct google_api_expr_v1alpha1_Expr* sub = (struct google_api_expr_v1alpha1_Expr*)_upb_msg_new(&google_api_expr_v1alpha1_Expr_msginit, arena);
-  bool ok = _upb_array_append_accessor(
-      msg, UPB_SIZE(12, 24), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena);
+  bool ok = _upb_array_append_accessor2(
+      msg, UPB_SIZE(16, 32), UPB_SIZE(2, 3), &sub, arena);
   if (!ok) return NULL;
   return sub;
 }
@@ -355,6 +390,12 @@ UPB_INLINE google_api_expr_v1alpha1_Expr_CreateList *google_api_expr_v1alpha1_Ex
   google_api_expr_v1alpha1_Expr_CreateList *ret = google_api_expr_v1alpha1_Expr_CreateList_new(arena);
   return (ret && upb_decode(buf, size, ret, &google_api_expr_v1alpha1_Expr_CreateList_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE google_api_expr_v1alpha1_Expr_CreateList *google_api_expr_v1alpha1_Expr_CreateList_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  google_api_expr_v1alpha1_Expr_CreateList *ret = google_api_expr_v1alpha1_Expr_CreateList_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &google_api_expr_v1alpha1_Expr_CreateList_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *google_api_expr_v1alpha1_Expr_CreateList_serialize(const google_api_expr_v1alpha1_Expr_CreateList *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &google_api_expr_v1alpha1_Expr_CreateList_msginit, arena, len);
 }
@@ -366,12 +407,12 @@ UPB_INLINE google_api_expr_v1alpha1_Expr** google_api_expr_v1alpha1_Expr_CreateL
   return (google_api_expr_v1alpha1_Expr**)_upb_array_mutable_accessor(msg, UPB_SIZE(0, 0), len);
 }
 UPB_INLINE google_api_expr_v1alpha1_Expr** google_api_expr_v1alpha1_Expr_CreateList_resize_elements(google_api_expr_v1alpha1_Expr_CreateList *msg, size_t len, upb_arena *arena) {
-  return (google_api_expr_v1alpha1_Expr**)_upb_array_resize_accessor(msg, UPB_SIZE(0, 0), len, UPB_TYPE_MESSAGE, arena);
+  return (google_api_expr_v1alpha1_Expr**)_upb_array_resize_accessor2(msg, UPB_SIZE(0, 0), len, UPB_SIZE(2, 3), arena);
 }
 UPB_INLINE struct google_api_expr_v1alpha1_Expr* google_api_expr_v1alpha1_Expr_CreateList_add_elements(google_api_expr_v1alpha1_Expr_CreateList *msg, upb_arena *arena) {
   struct google_api_expr_v1alpha1_Expr* sub = (struct google_api_expr_v1alpha1_Expr*)_upb_msg_new(&google_api_expr_v1alpha1_Expr_msginit, arena);
-  bool ok = _upb_array_append_accessor(
-      msg, UPB_SIZE(0, 0), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena);
+  bool ok = _upb_array_append_accessor2(
+      msg, UPB_SIZE(0, 0), UPB_SIZE(2, 3), &sub, arena);
   if (!ok) return NULL;
   return sub;
 }
@@ -386,6 +427,12 @@ UPB_INLINE google_api_expr_v1alpha1_Expr_CreateStruct *google_api_expr_v1alpha1_
   google_api_expr_v1alpha1_Expr_CreateStruct *ret = google_api_expr_v1alpha1_Expr_CreateStruct_new(arena);
   return (ret && upb_decode(buf, size, ret, &google_api_expr_v1alpha1_Expr_CreateStruct_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE google_api_expr_v1alpha1_Expr_CreateStruct *google_api_expr_v1alpha1_Expr_CreateStruct_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  google_api_expr_v1alpha1_Expr_CreateStruct *ret = google_api_expr_v1alpha1_Expr_CreateStruct_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &google_api_expr_v1alpha1_Expr_CreateStruct_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *google_api_expr_v1alpha1_Expr_CreateStruct_serialize(const google_api_expr_v1alpha1_Expr_CreateStruct *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &google_api_expr_v1alpha1_Expr_CreateStruct_msginit, arena, len);
 }
@@ -401,12 +448,12 @@ UPB_INLINE google_api_expr_v1alpha1_Expr_CreateStruct_Entry** google_api_expr_v1
   return (google_api_expr_v1alpha1_Expr_CreateStruct_Entry**)_upb_array_mutable_accessor(msg, UPB_SIZE(8, 16), len);
 }
 UPB_INLINE google_api_expr_v1alpha1_Expr_CreateStruct_Entry** google_api_expr_v1alpha1_Expr_CreateStruct_resize_entries(google_api_expr_v1alpha1_Expr_CreateStruct *msg, size_t len, upb_arena *arena) {
-  return (google_api_expr_v1alpha1_Expr_CreateStruct_Entry**)_upb_array_resize_accessor(msg, UPB_SIZE(8, 16), len, UPB_TYPE_MESSAGE, arena);
+  return (google_api_expr_v1alpha1_Expr_CreateStruct_Entry**)_upb_array_resize_accessor2(msg, UPB_SIZE(8, 16), len, UPB_SIZE(2, 3), arena);
 }
 UPB_INLINE struct google_api_expr_v1alpha1_Expr_CreateStruct_Entry* google_api_expr_v1alpha1_Expr_CreateStruct_add_entries(google_api_expr_v1alpha1_Expr_CreateStruct *msg, upb_arena *arena) {
   struct google_api_expr_v1alpha1_Expr_CreateStruct_Entry* sub = (struct google_api_expr_v1alpha1_Expr_CreateStruct_Entry*)_upb_msg_new(&google_api_expr_v1alpha1_Expr_CreateStruct_Entry_msginit, arena);
-  bool ok = _upb_array_append_accessor(
-      msg, UPB_SIZE(8, 16), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena);
+  bool ok = _upb_array_append_accessor2(
+      msg, UPB_SIZE(8, 16), UPB_SIZE(2, 3), &sub, arena);
   if (!ok) return NULL;
   return sub;
 }
@@ -421,6 +468,12 @@ UPB_INLINE google_api_expr_v1alpha1_Expr_CreateStruct_Entry *google_api_expr_v1a
   google_api_expr_v1alpha1_Expr_CreateStruct_Entry *ret = google_api_expr_v1alpha1_Expr_CreateStruct_Entry_new(arena);
   return (ret && upb_decode(buf, size, ret, &google_api_expr_v1alpha1_Expr_CreateStruct_Entry_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE google_api_expr_v1alpha1_Expr_CreateStruct_Entry *google_api_expr_v1alpha1_Expr_CreateStruct_Entry_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  google_api_expr_v1alpha1_Expr_CreateStruct_Entry *ret = google_api_expr_v1alpha1_Expr_CreateStruct_Entry_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &google_api_expr_v1alpha1_Expr_CreateStruct_Entry_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *google_api_expr_v1alpha1_Expr_CreateStruct_Entry_serialize(const google_api_expr_v1alpha1_Expr_CreateStruct_Entry *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &google_api_expr_v1alpha1_Expr_CreateStruct_Entry_msginit, arena, len);
 }
@@ -430,24 +483,24 @@ typedef enum {
   google_api_expr_v1alpha1_Expr_CreateStruct_Entry_key_kind_map_key = 3,
   google_api_expr_v1alpha1_Expr_CreateStruct_Entry_key_kind_NOT_SET = 0
 } google_api_expr_v1alpha1_Expr_CreateStruct_Entry_key_kind_oneofcases;
-UPB_INLINE google_api_expr_v1alpha1_Expr_CreateStruct_Entry_key_kind_oneofcases google_api_expr_v1alpha1_Expr_CreateStruct_Entry_key_kind_case(const google_api_expr_v1alpha1_Expr_CreateStruct_Entry* msg) { return (google_api_expr_v1alpha1_Expr_CreateStruct_Entry_key_kind_oneofcases)*UPB_PTR_AT(msg, UPB_SIZE(20, 32), int32_t); }
+UPB_INLINE google_api_expr_v1alpha1_Expr_CreateStruct_Entry_key_kind_oneofcases google_api_expr_v1alpha1_Expr_CreateStruct_Entry_key_kind_case(const google_api_expr_v1alpha1_Expr_CreateStruct_Entry* msg) { return (google_api_expr_v1alpha1_Expr_CreateStruct_Entry_key_kind_oneofcases)*UPB_PTR_AT(msg, UPB_SIZE(28, 40), int32_t); }
 
-UPB_INLINE int64_t google_api_expr_v1alpha1_Expr_CreateStruct_Entry_id(const google_api_expr_v1alpha1_Expr_CreateStruct_Entry *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(0, 0), int64_t); }
-UPB_INLINE bool google_api_expr_v1alpha1_Expr_CreateStruct_Entry_has_field_key(const google_api_expr_v1alpha1_Expr_CreateStruct_Entry *msg) { return _upb_getoneofcase(msg, UPB_SIZE(20, 32)) == 2; }
-UPB_INLINE upb_strview google_api_expr_v1alpha1_Expr_CreateStruct_Entry_field_key(const google_api_expr_v1alpha1_Expr_CreateStruct_Entry *msg) { return UPB_READ_ONEOF(msg, upb_strview, UPB_SIZE(12, 16), UPB_SIZE(20, 32), 2, upb_strview_make("", strlen(""))); }
-UPB_INLINE bool google_api_expr_v1alpha1_Expr_CreateStruct_Entry_has_map_key(const google_api_expr_v1alpha1_Expr_CreateStruct_Entry *msg) { return _upb_getoneofcase(msg, UPB_SIZE(20, 32)) == 3; }
-UPB_INLINE const google_api_expr_v1alpha1_Expr* google_api_expr_v1alpha1_Expr_CreateStruct_Entry_map_key(const google_api_expr_v1alpha1_Expr_CreateStruct_Entry *msg) { return UPB_READ_ONEOF(msg, const google_api_expr_v1alpha1_Expr*, UPB_SIZE(12, 16), UPB_SIZE(20, 32), 3, NULL); }
-UPB_INLINE bool google_api_expr_v1alpha1_Expr_CreateStruct_Entry_has_value(const google_api_expr_v1alpha1_Expr_CreateStruct_Entry *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(8, 8)); }
-UPB_INLINE const google_api_expr_v1alpha1_Expr* google_api_expr_v1alpha1_Expr_CreateStruct_Entry_value(const google_api_expr_v1alpha1_Expr_CreateStruct_Entry *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(8, 8), const google_api_expr_v1alpha1_Expr*); }
+UPB_INLINE int64_t google_api_expr_v1alpha1_Expr_CreateStruct_Entry_id(const google_api_expr_v1alpha1_Expr_CreateStruct_Entry *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(8, 8), int64_t); }
+UPB_INLINE bool google_api_expr_v1alpha1_Expr_CreateStruct_Entry_has_field_key(const google_api_expr_v1alpha1_Expr_CreateStruct_Entry *msg) { return _upb_getoneofcase(msg, UPB_SIZE(28, 40)) == 2; }
+UPB_INLINE upb_strview google_api_expr_v1alpha1_Expr_CreateStruct_Entry_field_key(const google_api_expr_v1alpha1_Expr_CreateStruct_Entry *msg) { return UPB_READ_ONEOF(msg, upb_strview, UPB_SIZE(20, 24), UPB_SIZE(28, 40), 2, upb_strview_make("", strlen(""))); }
+UPB_INLINE bool google_api_expr_v1alpha1_Expr_CreateStruct_Entry_has_map_key(const google_api_expr_v1alpha1_Expr_CreateStruct_Entry *msg) { return _upb_getoneofcase(msg, UPB_SIZE(28, 40)) == 3; }
+UPB_INLINE const google_api_expr_v1alpha1_Expr* google_api_expr_v1alpha1_Expr_CreateStruct_Entry_map_key(const google_api_expr_v1alpha1_Expr_CreateStruct_Entry *msg) { return UPB_READ_ONEOF(msg, const google_api_expr_v1alpha1_Expr*, UPB_SIZE(20, 24), UPB_SIZE(28, 40), 3, NULL); }
+UPB_INLINE bool google_api_expr_v1alpha1_Expr_CreateStruct_Entry_has_value(const google_api_expr_v1alpha1_Expr_CreateStruct_Entry *msg) { return _upb_hasbit(msg, 1); }
+UPB_INLINE const google_api_expr_v1alpha1_Expr* google_api_expr_v1alpha1_Expr_CreateStruct_Entry_value(const google_api_expr_v1alpha1_Expr_CreateStruct_Entry *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(16, 16), const google_api_expr_v1alpha1_Expr*); }
 
 UPB_INLINE void google_api_expr_v1alpha1_Expr_CreateStruct_Entry_set_id(google_api_expr_v1alpha1_Expr_CreateStruct_Entry *msg, int64_t value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(0, 0), int64_t) = value;
+  *UPB_PTR_AT(msg, UPB_SIZE(8, 8), int64_t) = value;
 }
 UPB_INLINE void google_api_expr_v1alpha1_Expr_CreateStruct_Entry_set_field_key(google_api_expr_v1alpha1_Expr_CreateStruct_Entry *msg, upb_strview value) {
-  UPB_WRITE_ONEOF(msg, upb_strview, UPB_SIZE(12, 16), value, UPB_SIZE(20, 32), 2);
+  UPB_WRITE_ONEOF(msg, upb_strview, UPB_SIZE(20, 24), value, UPB_SIZE(28, 40), 2);
 }
 UPB_INLINE void google_api_expr_v1alpha1_Expr_CreateStruct_Entry_set_map_key(google_api_expr_v1alpha1_Expr_CreateStruct_Entry *msg, google_api_expr_v1alpha1_Expr* value) {
-  UPB_WRITE_ONEOF(msg, google_api_expr_v1alpha1_Expr*, UPB_SIZE(12, 16), value, UPB_SIZE(20, 32), 3);
+  UPB_WRITE_ONEOF(msg, google_api_expr_v1alpha1_Expr*, UPB_SIZE(20, 24), value, UPB_SIZE(28, 40), 3);
 }
 UPB_INLINE struct google_api_expr_v1alpha1_Expr* google_api_expr_v1alpha1_Expr_CreateStruct_Entry_mutable_map_key(google_api_expr_v1alpha1_Expr_CreateStruct_Entry *msg, upb_arena *arena) {
   struct google_api_expr_v1alpha1_Expr* sub = (struct google_api_expr_v1alpha1_Expr*)google_api_expr_v1alpha1_Expr_CreateStruct_Entry_map_key(msg);
@@ -459,7 +512,8 @@ UPB_INLINE struct google_api_expr_v1alpha1_Expr* google_api_expr_v1alpha1_Expr_C
   return sub;
 }
 UPB_INLINE void google_api_expr_v1alpha1_Expr_CreateStruct_Entry_set_value(google_api_expr_v1alpha1_Expr_CreateStruct_Entry *msg, google_api_expr_v1alpha1_Expr* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(8, 8), google_api_expr_v1alpha1_Expr*) = value;
+  _upb_sethas(msg, 1);
+  *UPB_PTR_AT(msg, UPB_SIZE(16, 16), google_api_expr_v1alpha1_Expr*) = value;
 }
 UPB_INLINE struct google_api_expr_v1alpha1_Expr* google_api_expr_v1alpha1_Expr_CreateStruct_Entry_mutable_value(google_api_expr_v1alpha1_Expr_CreateStruct_Entry *msg, upb_arena *arena) {
   struct google_api_expr_v1alpha1_Expr* sub = (struct google_api_expr_v1alpha1_Expr*)google_api_expr_v1alpha1_Expr_CreateStruct_Entry_value(msg);
@@ -481,28 +535,35 @@ UPB_INLINE google_api_expr_v1alpha1_Expr_Comprehension *google_api_expr_v1alpha1
   google_api_expr_v1alpha1_Expr_Comprehension *ret = google_api_expr_v1alpha1_Expr_Comprehension_new(arena);
   return (ret && upb_decode(buf, size, ret, &google_api_expr_v1alpha1_Expr_Comprehension_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE google_api_expr_v1alpha1_Expr_Comprehension *google_api_expr_v1alpha1_Expr_Comprehension_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  google_api_expr_v1alpha1_Expr_Comprehension *ret = google_api_expr_v1alpha1_Expr_Comprehension_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &google_api_expr_v1alpha1_Expr_Comprehension_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *google_api_expr_v1alpha1_Expr_Comprehension_serialize(const google_api_expr_v1alpha1_Expr_Comprehension *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &google_api_expr_v1alpha1_Expr_Comprehension_msginit, arena, len);
 }
 
-UPB_INLINE upb_strview google_api_expr_v1alpha1_Expr_Comprehension_iter_var(const google_api_expr_v1alpha1_Expr_Comprehension *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(0, 0), upb_strview); }
-UPB_INLINE bool google_api_expr_v1alpha1_Expr_Comprehension_has_iter_range(const google_api_expr_v1alpha1_Expr_Comprehension *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(16, 32)); }
-UPB_INLINE const google_api_expr_v1alpha1_Expr* google_api_expr_v1alpha1_Expr_Comprehension_iter_range(const google_api_expr_v1alpha1_Expr_Comprehension *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(16, 32), const google_api_expr_v1alpha1_Expr*); }
-UPB_INLINE upb_strview google_api_expr_v1alpha1_Expr_Comprehension_accu_var(const google_api_expr_v1alpha1_Expr_Comprehension *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(8, 16), upb_strview); }
-UPB_INLINE bool google_api_expr_v1alpha1_Expr_Comprehension_has_accu_init(const google_api_expr_v1alpha1_Expr_Comprehension *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(20, 40)); }
-UPB_INLINE const google_api_expr_v1alpha1_Expr* google_api_expr_v1alpha1_Expr_Comprehension_accu_init(const google_api_expr_v1alpha1_Expr_Comprehension *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(20, 40), const google_api_expr_v1alpha1_Expr*); }
-UPB_INLINE bool google_api_expr_v1alpha1_Expr_Comprehension_has_loop_condition(const google_api_expr_v1alpha1_Expr_Comprehension *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(24, 48)); }
-UPB_INLINE const google_api_expr_v1alpha1_Expr* google_api_expr_v1alpha1_Expr_Comprehension_loop_condition(const google_api_expr_v1alpha1_Expr_Comprehension *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(24, 48), const google_api_expr_v1alpha1_Expr*); }
-UPB_INLINE bool google_api_expr_v1alpha1_Expr_Comprehension_has_loop_step(const google_api_expr_v1alpha1_Expr_Comprehension *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(28, 56)); }
-UPB_INLINE const google_api_expr_v1alpha1_Expr* google_api_expr_v1alpha1_Expr_Comprehension_loop_step(const google_api_expr_v1alpha1_Expr_Comprehension *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(28, 56), const google_api_expr_v1alpha1_Expr*); }
-UPB_INLINE bool google_api_expr_v1alpha1_Expr_Comprehension_has_result(const google_api_expr_v1alpha1_Expr_Comprehension *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(32, 64)); }
-UPB_INLINE const google_api_expr_v1alpha1_Expr* google_api_expr_v1alpha1_Expr_Comprehension_result(const google_api_expr_v1alpha1_Expr_Comprehension *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(32, 64), const google_api_expr_v1alpha1_Expr*); }
+UPB_INLINE upb_strview google_api_expr_v1alpha1_Expr_Comprehension_iter_var(const google_api_expr_v1alpha1_Expr_Comprehension *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(4, 8), upb_strview); }
+UPB_INLINE bool google_api_expr_v1alpha1_Expr_Comprehension_has_iter_range(const google_api_expr_v1alpha1_Expr_Comprehension *msg) { return _upb_hasbit(msg, 1); }
+UPB_INLINE const google_api_expr_v1alpha1_Expr* google_api_expr_v1alpha1_Expr_Comprehension_iter_range(const google_api_expr_v1alpha1_Expr_Comprehension *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(20, 40), const google_api_expr_v1alpha1_Expr*); }
+UPB_INLINE upb_strview google_api_expr_v1alpha1_Expr_Comprehension_accu_var(const google_api_expr_v1alpha1_Expr_Comprehension *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(12, 24), upb_strview); }
+UPB_INLINE bool google_api_expr_v1alpha1_Expr_Comprehension_has_accu_init(const google_api_expr_v1alpha1_Expr_Comprehension *msg) { return _upb_hasbit(msg, 2); }
+UPB_INLINE const google_api_expr_v1alpha1_Expr* google_api_expr_v1alpha1_Expr_Comprehension_accu_init(const google_api_expr_v1alpha1_Expr_Comprehension *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(24, 48), const google_api_expr_v1alpha1_Expr*); }
+UPB_INLINE bool google_api_expr_v1alpha1_Expr_Comprehension_has_loop_condition(const google_api_expr_v1alpha1_Expr_Comprehension *msg) { return _upb_hasbit(msg, 3); }
+UPB_INLINE const google_api_expr_v1alpha1_Expr* google_api_expr_v1alpha1_Expr_Comprehension_loop_condition(const google_api_expr_v1alpha1_Expr_Comprehension *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(28, 56), const google_api_expr_v1alpha1_Expr*); }
+UPB_INLINE bool google_api_expr_v1alpha1_Expr_Comprehension_has_loop_step(const google_api_expr_v1alpha1_Expr_Comprehension *msg) { return _upb_hasbit(msg, 4); }
+UPB_INLINE const google_api_expr_v1alpha1_Expr* google_api_expr_v1alpha1_Expr_Comprehension_loop_step(const google_api_expr_v1alpha1_Expr_Comprehension *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(32, 64), const google_api_expr_v1alpha1_Expr*); }
+UPB_INLINE bool google_api_expr_v1alpha1_Expr_Comprehension_has_result(const google_api_expr_v1alpha1_Expr_Comprehension *msg) { return _upb_hasbit(msg, 5); }
+UPB_INLINE const google_api_expr_v1alpha1_Expr* google_api_expr_v1alpha1_Expr_Comprehension_result(const google_api_expr_v1alpha1_Expr_Comprehension *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(36, 72), const google_api_expr_v1alpha1_Expr*); }
 
 UPB_INLINE void google_api_expr_v1alpha1_Expr_Comprehension_set_iter_var(google_api_expr_v1alpha1_Expr_Comprehension *msg, upb_strview value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(0, 0), upb_strview) = value;
+  *UPB_PTR_AT(msg, UPB_SIZE(4, 8), upb_strview) = value;
 }
 UPB_INLINE void google_api_expr_v1alpha1_Expr_Comprehension_set_iter_range(google_api_expr_v1alpha1_Expr_Comprehension *msg, google_api_expr_v1alpha1_Expr* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(16, 32), google_api_expr_v1alpha1_Expr*) = value;
+  _upb_sethas(msg, 1);
+  *UPB_PTR_AT(msg, UPB_SIZE(20, 40), google_api_expr_v1alpha1_Expr*) = value;
 }
 UPB_INLINE struct google_api_expr_v1alpha1_Expr* google_api_expr_v1alpha1_Expr_Comprehension_mutable_iter_range(google_api_expr_v1alpha1_Expr_Comprehension *msg, upb_arena *arena) {
   struct google_api_expr_v1alpha1_Expr* sub = (struct google_api_expr_v1alpha1_Expr*)google_api_expr_v1alpha1_Expr_Comprehension_iter_range(msg);
@@ -514,10 +575,11 @@ UPB_INLINE struct google_api_expr_v1alpha1_Expr* google_api_expr_v1alpha1_Expr_C
   return sub;
 }
 UPB_INLINE void google_api_expr_v1alpha1_Expr_Comprehension_set_accu_var(google_api_expr_v1alpha1_Expr_Comprehension *msg, upb_strview value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(8, 16), upb_strview) = value;
+  *UPB_PTR_AT(msg, UPB_SIZE(12, 24), upb_strview) = value;
 }
 UPB_INLINE void google_api_expr_v1alpha1_Expr_Comprehension_set_accu_init(google_api_expr_v1alpha1_Expr_Comprehension *msg, google_api_expr_v1alpha1_Expr* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(20, 40), google_api_expr_v1alpha1_Expr*) = value;
+  _upb_sethas(msg, 2);
+  *UPB_PTR_AT(msg, UPB_SIZE(24, 48), google_api_expr_v1alpha1_Expr*) = value;
 }
 UPB_INLINE struct google_api_expr_v1alpha1_Expr* google_api_expr_v1alpha1_Expr_Comprehension_mutable_accu_init(google_api_expr_v1alpha1_Expr_Comprehension *msg, upb_arena *arena) {
   struct google_api_expr_v1alpha1_Expr* sub = (struct google_api_expr_v1alpha1_Expr*)google_api_expr_v1alpha1_Expr_Comprehension_accu_init(msg);
@@ -529,7 +591,8 @@ UPB_INLINE struct google_api_expr_v1alpha1_Expr* google_api_expr_v1alpha1_Expr_C
   return sub;
 }
 UPB_INLINE void google_api_expr_v1alpha1_Expr_Comprehension_set_loop_condition(google_api_expr_v1alpha1_Expr_Comprehension *msg, google_api_expr_v1alpha1_Expr* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(24, 48), google_api_expr_v1alpha1_Expr*) = value;
+  _upb_sethas(msg, 3);
+  *UPB_PTR_AT(msg, UPB_SIZE(28, 56), google_api_expr_v1alpha1_Expr*) = value;
 }
 UPB_INLINE struct google_api_expr_v1alpha1_Expr* google_api_expr_v1alpha1_Expr_Comprehension_mutable_loop_condition(google_api_expr_v1alpha1_Expr_Comprehension *msg, upb_arena *arena) {
   struct google_api_expr_v1alpha1_Expr* sub = (struct google_api_expr_v1alpha1_Expr*)google_api_expr_v1alpha1_Expr_Comprehension_loop_condition(msg);
@@ -541,7 +604,8 @@ UPB_INLINE struct google_api_expr_v1alpha1_Expr* google_api_expr_v1alpha1_Expr_C
   return sub;
 }
 UPB_INLINE void google_api_expr_v1alpha1_Expr_Comprehension_set_loop_step(google_api_expr_v1alpha1_Expr_Comprehension *msg, google_api_expr_v1alpha1_Expr* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(28, 56), google_api_expr_v1alpha1_Expr*) = value;
+  _upb_sethas(msg, 4);
+  *UPB_PTR_AT(msg, UPB_SIZE(32, 64), google_api_expr_v1alpha1_Expr*) = value;
 }
 UPB_INLINE struct google_api_expr_v1alpha1_Expr* google_api_expr_v1alpha1_Expr_Comprehension_mutable_loop_step(google_api_expr_v1alpha1_Expr_Comprehension *msg, upb_arena *arena) {
   struct google_api_expr_v1alpha1_Expr* sub = (struct google_api_expr_v1alpha1_Expr*)google_api_expr_v1alpha1_Expr_Comprehension_loop_step(msg);
@@ -553,7 +617,8 @@ UPB_INLINE struct google_api_expr_v1alpha1_Expr* google_api_expr_v1alpha1_Expr_C
   return sub;
 }
 UPB_INLINE void google_api_expr_v1alpha1_Expr_Comprehension_set_result(google_api_expr_v1alpha1_Expr_Comprehension *msg, google_api_expr_v1alpha1_Expr* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(32, 64), google_api_expr_v1alpha1_Expr*) = value;
+  _upb_sethas(msg, 5);
+  *UPB_PTR_AT(msg, UPB_SIZE(36, 72), google_api_expr_v1alpha1_Expr*) = value;
 }
 UPB_INLINE struct google_api_expr_v1alpha1_Expr* google_api_expr_v1alpha1_Expr_Comprehension_mutable_result(google_api_expr_v1alpha1_Expr_Comprehension *msg, upb_arena *arena) {
   struct google_api_expr_v1alpha1_Expr* sub = (struct google_api_expr_v1alpha1_Expr*)google_api_expr_v1alpha1_Expr_Comprehension_result(msg);
@@ -575,6 +640,12 @@ UPB_INLINE google_api_expr_v1alpha1_Constant *google_api_expr_v1alpha1_Constant_
   google_api_expr_v1alpha1_Constant *ret = google_api_expr_v1alpha1_Constant_new(arena);
   return (ret && upb_decode(buf, size, ret, &google_api_expr_v1alpha1_Constant_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE google_api_expr_v1alpha1_Constant *google_api_expr_v1alpha1_Constant_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  google_api_expr_v1alpha1_Constant *ret = google_api_expr_v1alpha1_Constant_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &google_api_expr_v1alpha1_Constant_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *google_api_expr_v1alpha1_Constant_serialize(const google_api_expr_v1alpha1_Constant *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &google_api_expr_v1alpha1_Constant_msginit, arena, len);
 }
@@ -668,6 +739,12 @@ UPB_INLINE google_api_expr_v1alpha1_SourceInfo *google_api_expr_v1alpha1_SourceI
   google_api_expr_v1alpha1_SourceInfo *ret = google_api_expr_v1alpha1_SourceInfo_new(arena);
   return (ret && upb_decode(buf, size, ret, &google_api_expr_v1alpha1_SourceInfo_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE google_api_expr_v1alpha1_SourceInfo *google_api_expr_v1alpha1_SourceInfo_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  google_api_expr_v1alpha1_SourceInfo *ret = google_api_expr_v1alpha1_SourceInfo_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &google_api_expr_v1alpha1_SourceInfo_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *google_api_expr_v1alpha1_SourceInfo_serialize(const google_api_expr_v1alpha1_SourceInfo *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &google_api_expr_v1alpha1_SourceInfo_msginit, arena, len);
 }
@@ -690,10 +767,10 @@ UPB_INLINE int32_t* google_api_expr_v1alpha1_SourceInfo_mutable_line_offsets(goo
   return (int32_t*)_upb_array_mutable_accessor(msg, UPB_SIZE(16, 32), len);
 }
 UPB_INLINE int32_t* google_api_expr_v1alpha1_SourceInfo_resize_line_offsets(google_api_expr_v1alpha1_SourceInfo *msg, size_t len, upb_arena *arena) {
-  return (int32_t*)_upb_array_resize_accessor(msg, UPB_SIZE(16, 32), len, UPB_TYPE_INT32, arena);
+  return (int32_t*)_upb_array_resize_accessor2(msg, UPB_SIZE(16, 32), len, 2, arena);
 }
 UPB_INLINE bool google_api_expr_v1alpha1_SourceInfo_add_line_offsets(google_api_expr_v1alpha1_SourceInfo *msg, int32_t val, upb_arena *arena) {
-  return _upb_array_append_accessor(msg, UPB_SIZE(16, 32), UPB_SIZE(4, 4), UPB_TYPE_INT32, &val,
+  return _upb_array_append_accessor2(msg, UPB_SIZE(16, 32), 2, &val,
       arena);
 }
 UPB_INLINE void google_api_expr_v1alpha1_SourceInfo_positions_clear(google_api_expr_v1alpha1_SourceInfo *msg) { _upb_msg_map_clear(msg, UPB_SIZE(20, 40)); }
@@ -728,6 +805,12 @@ UPB_INLINE google_api_expr_v1alpha1_SourcePosition *google_api_expr_v1alpha1_Sou
   google_api_expr_v1alpha1_SourcePosition *ret = google_api_expr_v1alpha1_SourcePosition_new(arena);
   return (ret && upb_decode(buf, size, ret, &google_api_expr_v1alpha1_SourcePosition_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE google_api_expr_v1alpha1_SourcePosition *google_api_expr_v1alpha1_SourcePosition_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  google_api_expr_v1alpha1_SourcePosition *ret = google_api_expr_v1alpha1_SourcePosition_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &google_api_expr_v1alpha1_SourcePosition_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *google_api_expr_v1alpha1_SourcePosition_serialize(const google_api_expr_v1alpha1_SourcePosition *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &google_api_expr_v1alpha1_SourcePosition_msginit, arena, len);
 }
index 8ad07dc..f17613a 100644 (file)
@@ -24,7 +24,7 @@ static const upb_msglayout_field google_api_Http__fields[2] = {
 const upb_msglayout google_api_Http_msginit = {
   &google_api_Http_submsgs[0],
   &google_api_Http__fields[0],
-  UPB_SIZE(8, 16), 2, false,
+  UPB_SIZE(8, 16), 2, false, 255,
 };
 
 static const upb_msglayout *const google_api_HttpRule_submsgs[2] = {
@@ -48,7 +48,7 @@ static const upb_msglayout_field google_api_HttpRule__fields[10] = {
 const upb_msglayout google_api_HttpRule_msginit = {
   &google_api_HttpRule_submsgs[0],
   &google_api_HttpRule__fields[0],
-  UPB_SIZE(40, 80), 10, false,
+  UPB_SIZE(40, 80), 10, false, 255,
 };
 
 static const upb_msglayout_field google_api_CustomHttpPattern__fields[2] = {
@@ -59,7 +59,7 @@ static const upb_msglayout_field google_api_CustomHttpPattern__fields[2] = {
 const upb_msglayout google_api_CustomHttpPattern_msginit = {
   NULL,
   &google_api_CustomHttpPattern__fields[0],
-  UPB_SIZE(16, 32), 2, false,
+  UPB_SIZE(16, 32), 2, false, 255,
 };
 
 #include "upb/port_undef.inc"
index 9012b9f..ed4e6d1 100644 (file)
@@ -11,6 +11,7 @@
 
 #include "upb/msg.h"
 #include "upb/decode.h"
+#include "upb/decode_fast.h"
 #include "upb/encode.h"
 
 #include "upb/port_def.inc"
@@ -40,6 +41,12 @@ UPB_INLINE google_api_Http *google_api_Http_parse(const char *buf, size_t size,
   google_api_Http *ret = google_api_Http_new(arena);
   return (ret && upb_decode(buf, size, ret, &google_api_Http_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE google_api_Http *google_api_Http_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  google_api_Http *ret = google_api_Http_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &google_api_Http_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *google_api_Http_serialize(const google_api_Http *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &google_api_Http_msginit, arena, len);
 }
@@ -52,12 +59,12 @@ UPB_INLINE google_api_HttpRule** google_api_Http_mutable_rules(google_api_Http *
   return (google_api_HttpRule**)_upb_array_mutable_accessor(msg, UPB_SIZE(4, 8), len);
 }
 UPB_INLINE google_api_HttpRule** google_api_Http_resize_rules(google_api_Http *msg, size_t len, upb_arena *arena) {
-  return (google_api_HttpRule**)_upb_array_resize_accessor(msg, UPB_SIZE(4, 8), len, UPB_TYPE_MESSAGE, arena);
+  return (google_api_HttpRule**)_upb_array_resize_accessor2(msg, UPB_SIZE(4, 8), len, UPB_SIZE(2, 3), arena);
 }
 UPB_INLINE struct google_api_HttpRule* google_api_Http_add_rules(google_api_Http *msg, upb_arena *arena) {
   struct google_api_HttpRule* sub = (struct google_api_HttpRule*)_upb_msg_new(&google_api_HttpRule_msginit, arena);
-  bool ok = _upb_array_append_accessor(
-      msg, UPB_SIZE(4, 8), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena);
+  bool ok = _upb_array_append_accessor2(
+      msg, UPB_SIZE(4, 8), UPB_SIZE(2, 3), &sub, arena);
   if (!ok) return NULL;
   return sub;
 }
@@ -75,6 +82,12 @@ UPB_INLINE google_api_HttpRule *google_api_HttpRule_parse(const char *buf, size_
   google_api_HttpRule *ret = google_api_HttpRule_new(arena);
   return (ret && upb_decode(buf, size, ret, &google_api_HttpRule_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE google_api_HttpRule *google_api_HttpRule_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  google_api_HttpRule *ret = google_api_HttpRule_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &google_api_HttpRule_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *google_api_HttpRule_serialize(const google_api_HttpRule *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &google_api_HttpRule_msginit, arena, len);
 }
@@ -145,12 +158,12 @@ UPB_INLINE google_api_HttpRule** google_api_HttpRule_mutable_additional_bindings
   return (google_api_HttpRule**)_upb_array_mutable_accessor(msg, UPB_SIZE(24, 48), len);
 }
 UPB_INLINE google_api_HttpRule** google_api_HttpRule_resize_additional_bindings(google_api_HttpRule *msg, size_t len, upb_arena *arena) {
-  return (google_api_HttpRule**)_upb_array_resize_accessor(msg, UPB_SIZE(24, 48), len, UPB_TYPE_MESSAGE, arena);
+  return (google_api_HttpRule**)_upb_array_resize_accessor2(msg, UPB_SIZE(24, 48), len, UPB_SIZE(2, 3), arena);
 }
 UPB_INLINE struct google_api_HttpRule* google_api_HttpRule_add_additional_bindings(google_api_HttpRule *msg, upb_arena *arena) {
   struct google_api_HttpRule* sub = (struct google_api_HttpRule*)_upb_msg_new(&google_api_HttpRule_msginit, arena);
-  bool ok = _upb_array_append_accessor(
-      msg, UPB_SIZE(24, 48), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena);
+  bool ok = _upb_array_append_accessor2(
+      msg, UPB_SIZE(24, 48), UPB_SIZE(2, 3), &sub, arena);
   if (!ok) return NULL;
   return sub;
 }
@@ -168,6 +181,12 @@ UPB_INLINE google_api_CustomHttpPattern *google_api_CustomHttpPattern_parse(cons
   google_api_CustomHttpPattern *ret = google_api_CustomHttpPattern_new(arena);
   return (ret && upb_decode(buf, size, ret, &google_api_CustomHttpPattern_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE google_api_CustomHttpPattern *google_api_CustomHttpPattern_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  google_api_CustomHttpPattern *ret = google_api_CustomHttpPattern_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &google_api_CustomHttpPattern_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *google_api_CustomHttpPattern_serialize(const google_api_CustomHttpPattern *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &google_api_CustomHttpPattern_msginit, arena, len);
 }
index 14badf7..93eaa60 100644 (file)
@@ -20,7 +20,7 @@ static const upb_msglayout_field google_protobuf_Any__fields[2] = {
 const upb_msglayout google_protobuf_Any_msginit = {
   NULL,
   &google_protobuf_Any__fields[0],
-  UPB_SIZE(16, 32), 2, false,
+  UPB_SIZE(16, 32), 2, false, 255,
 };
 
 #include "upb/port_undef.inc"
index bf8394e..2bd44f7 100644 (file)
@@ -11,6 +11,7 @@
 
 #include "upb/msg.h"
 #include "upb/decode.h"
+#include "upb/decode_fast.h"
 #include "upb/encode.h"
 
 #include "upb/port_def.inc"
@@ -34,6 +35,12 @@ UPB_INLINE google_protobuf_Any *google_protobuf_Any_parse(const char *buf, size_
   google_protobuf_Any *ret = google_protobuf_Any_new(arena);
   return (ret && upb_decode(buf, size, ret, &google_protobuf_Any_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE google_protobuf_Any *google_protobuf_Any_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  google_protobuf_Any *ret = google_protobuf_Any_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &google_protobuf_Any_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *google_protobuf_Any_serialize(const google_protobuf_Any *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &google_protobuf_Any_msginit, arena, len);
 }
index 44cd3ae..339fafa 100644 (file)
@@ -23,7 +23,7 @@ static const upb_msglayout_field google_protobuf_FileDescriptorSet__fields[1] =
 const upb_msglayout google_protobuf_FileDescriptorSet_msginit = {
   &google_protobuf_FileDescriptorSet_submsgs[0],
   &google_protobuf_FileDescriptorSet__fields[0],
-  UPB_SIZE(4, 8), 1, false,
+  UPB_SIZE(8, 8), 1, false, 255,
 };
 
 static const upb_msglayout *const google_protobuf_FileDescriptorProto_submsgs[6] = {
@@ -43,20 +43,20 @@ static const upb_msglayout_field google_protobuf_FileDescriptorProto__fields[12]
   {5, UPB_SIZE(44, 88), 0, 1, 11, 3},
   {6, UPB_SIZE(48, 96), 0, 4, 11, 3},
   {7, UPB_SIZE(52, 104), 0, 2, 11, 3},
-  {8, UPB_SIZE(28, 56), 4, 3, 11, 1},
-  {9, UPB_SIZE(32, 64), 5, 5, 11, 1},
+  {8, UPB_SIZE(28, 56), 3, 3, 11, 1},
+  {9, UPB_SIZE(32, 64), 4, 5, 11, 1},
   {10, UPB_SIZE(56, 112), 0, 0, 5, 3},
   {11, UPB_SIZE(60, 120), 0, 0, 5, 3},
-  {12, UPB_SIZE(20, 40), 3, 0, 12, 1},
+  {12, UPB_SIZE(20, 40), 5, 0, 12, 1},
 };
 
 const upb_msglayout google_protobuf_FileDescriptorProto_msginit = {
   &google_protobuf_FileDescriptorProto_submsgs[0],
   &google_protobuf_FileDescriptorProto__fields[0],
-  UPB_SIZE(64, 128), 12, false,
+  UPB_SIZE(64, 128), 12, false, 255,
 };
 
-static const upb_msglayout *const google_protobuf_DescriptorProto_submsgs[8] = {
+static const upb_msglayout *const google_protobuf_DescriptorProto_submsgs[7] = {
   &google_protobuf_DescriptorProto_msginit,
   &google_protobuf_DescriptorProto_ExtensionRange_msginit,
   &google_protobuf_DescriptorProto_ReservedRange_msginit,
@@ -82,7 +82,7 @@ static const upb_msglayout_field google_protobuf_DescriptorProto__fields[10] = {
 const upb_msglayout google_protobuf_DescriptorProto_msginit = {
   &google_protobuf_DescriptorProto_submsgs[0],
   &google_protobuf_DescriptorProto__fields[0],
-  UPB_SIZE(48, 96), 10, false,
+  UPB_SIZE(48, 96), 10, false, 255,
 };
 
 static const upb_msglayout *const google_protobuf_DescriptorProto_ExtensionRange_submsgs[1] = {
@@ -98,7 +98,7 @@ static const upb_msglayout_field google_protobuf_DescriptorProto_ExtensionRange_
 const upb_msglayout google_protobuf_DescriptorProto_ExtensionRange_msginit = {
   &google_protobuf_DescriptorProto_ExtensionRange_submsgs[0],
   &google_protobuf_DescriptorProto_ExtensionRange__fields[0],
-  UPB_SIZE(16, 24), 3, false,
+  UPB_SIZE(16, 24), 3, false, 255,
 };
 
 static const upb_msglayout_field google_protobuf_DescriptorProto_ReservedRange__fields[2] = {
@@ -109,7 +109,7 @@ static const upb_msglayout_field google_protobuf_DescriptorProto_ReservedRange__
 const upb_msglayout google_protobuf_DescriptorProto_ReservedRange_msginit = {
   NULL,
   &google_protobuf_DescriptorProto_ReservedRange__fields[0],
-  UPB_SIZE(12, 12), 2, false,
+  UPB_SIZE(16, 16), 2, false, 255,
 };
 
 static const upb_msglayout *const google_protobuf_ExtensionRangeOptions_submsgs[1] = {
@@ -123,7 +123,7 @@ static const upb_msglayout_field google_protobuf_ExtensionRangeOptions__fields[1
 const upb_msglayout google_protobuf_ExtensionRangeOptions_msginit = {
   &google_protobuf_ExtensionRangeOptions_submsgs[0],
   &google_protobuf_ExtensionRangeOptions__fields[0],
-  UPB_SIZE(4, 8), 1, false,
+  UPB_SIZE(8, 8), 1, false, 255,
 };
 
 static const upb_msglayout *const google_protobuf_FieldDescriptorProto_submsgs[1] = {
@@ -131,23 +131,23 @@ static const upb_msglayout *const google_protobuf_FieldDescriptorProto_submsgs[1
 };
 
 static const upb_msglayout_field google_protobuf_FieldDescriptorProto__fields[11] = {
-  {1, UPB_SIZE(36, 40), 6, 0, 12, 1},
-  {2, UPB_SIZE(44, 56), 7, 0, 12, 1},
-  {3, UPB_SIZE(24, 24), 3, 0, 5, 1},
-  {4, UPB_SIZE(8, 8), 1, 0, 14, 1},
-  {5, UPB_SIZE(16, 16), 2, 0, 14, 1},
-  {6, UPB_SIZE(52, 72), 8, 0, 12, 1},
-  {7, UPB_SIZE(60, 88), 9, 0, 12, 1},
-  {8, UPB_SIZE(76, 120), 11, 0, 11, 1},
-  {9, UPB_SIZE(28, 28), 4, 0, 5, 1},
-  {10, UPB_SIZE(68, 104), 10, 0, 12, 1},
-  {17, UPB_SIZE(32, 32), 5, 0, 8, 1},
+  {1, UPB_SIZE(24, 24), 1, 0, 12, 1},
+  {2, UPB_SIZE(32, 40), 2, 0, 12, 1},
+  {3, UPB_SIZE(12, 12), 3, 0, 5, 1},
+  {4, UPB_SIZE(4, 4), 4, 0, 14, 1},
+  {5, UPB_SIZE(8, 8), 5, 0, 14, 1},
+  {6, UPB_SIZE(40, 56), 6, 0, 12, 1},
+  {7, UPB_SIZE(48, 72), 7, 0, 12, 1},
+  {8, UPB_SIZE(64, 104), 8, 0, 11, 1},
+  {9, UPB_SIZE(16, 16), 9, 0, 5, 1},
+  {10, UPB_SIZE(56, 88), 10, 0, 12, 1},
+  {17, UPB_SIZE(20, 20), 11, 0, 8, 1},
 };
 
 const upb_msglayout google_protobuf_FieldDescriptorProto_msginit = {
   &google_protobuf_FieldDescriptorProto_submsgs[0],
   &google_protobuf_FieldDescriptorProto__fields[0],
-  UPB_SIZE(80, 128), 11, false,
+  UPB_SIZE(72, 112), 11, false, 255,
 };
 
 static const upb_msglayout *const google_protobuf_OneofDescriptorProto_submsgs[1] = {
@@ -162,7 +162,7 @@ static const upb_msglayout_field google_protobuf_OneofDescriptorProto__fields[2]
 const upb_msglayout google_protobuf_OneofDescriptorProto_msginit = {
   &google_protobuf_OneofDescriptorProto_submsgs[0],
   &google_protobuf_OneofDescriptorProto__fields[0],
-  UPB_SIZE(16, 32), 2, false,
+  UPB_SIZE(16, 32), 2, false, 255,
 };
 
 static const upb_msglayout *const google_protobuf_EnumDescriptorProto_submsgs[3] = {
@@ -182,7 +182,7 @@ static const upb_msglayout_field google_protobuf_EnumDescriptorProto__fields[5]
 const upb_msglayout google_protobuf_EnumDescriptorProto_msginit = {
   &google_protobuf_EnumDescriptorProto_submsgs[0],
   &google_protobuf_EnumDescriptorProto__fields[0],
-  UPB_SIZE(32, 64), 5, false,
+  UPB_SIZE(32, 64), 5, false, 255,
 };
 
 static const upb_msglayout_field google_protobuf_EnumDescriptorProto_EnumReservedRange__fields[2] = {
@@ -193,7 +193,7 @@ static const upb_msglayout_field google_protobuf_EnumDescriptorProto_EnumReserve
 const upb_msglayout google_protobuf_EnumDescriptorProto_EnumReservedRange_msginit = {
   NULL,
   &google_protobuf_EnumDescriptorProto_EnumReservedRange__fields[0],
-  UPB_SIZE(12, 12), 2, false,
+  UPB_SIZE(16, 16), 2, false, 255,
 };
 
 static const upb_msglayout *const google_protobuf_EnumValueDescriptorProto_submsgs[1] = {
@@ -201,15 +201,15 @@ static const upb_msglayout *const google_protobuf_EnumValueDescriptorProto_subms
 };
 
 static const upb_msglayout_field google_protobuf_EnumValueDescriptorProto__fields[3] = {
-  {1, UPB_SIZE(8, 8), 2, 0, 12, 1},
-  {2, UPB_SIZE(4, 4), 1, 0, 5, 1},
+  {1, UPB_SIZE(8, 8), 1, 0, 12, 1},
+  {2, UPB_SIZE(4, 4), 2, 0, 5, 1},
   {3, UPB_SIZE(16, 24), 3, 0, 11, 1},
 };
 
 const upb_msglayout google_protobuf_EnumValueDescriptorProto_msginit = {
   &google_protobuf_EnumValueDescriptorProto_submsgs[0],
   &google_protobuf_EnumValueDescriptorProto__fields[0],
-  UPB_SIZE(24, 32), 3, false,
+  UPB_SIZE(24, 32), 3, false, 255,
 };
 
 static const upb_msglayout *const google_protobuf_ServiceDescriptorProto_submsgs[2] = {
@@ -226,7 +226,7 @@ static const upb_msglayout_field google_protobuf_ServiceDescriptorProto__fields[
 const upb_msglayout google_protobuf_ServiceDescriptorProto_msginit = {
   &google_protobuf_ServiceDescriptorProto_submsgs[0],
   &google_protobuf_ServiceDescriptorProto__fields[0],
-  UPB_SIZE(24, 48), 3, false,
+  UPB_SIZE(24, 48), 3, false, 255,
 };
 
 static const upb_msglayout *const google_protobuf_MethodDescriptorProto_submsgs[1] = {
@@ -234,18 +234,18 @@ static const upb_msglayout *const google_protobuf_MethodDescriptorProto_submsgs[
 };
 
 static const upb_msglayout_field google_protobuf_MethodDescriptorProto__fields[6] = {
-  {1, UPB_SIZE(4, 8), 3, 0, 12, 1},
-  {2, UPB_SIZE(12, 24), 4, 0, 12, 1},
-  {3, UPB_SIZE(20, 40), 5, 0, 12, 1},
-  {4, UPB_SIZE(28, 56), 6, 0, 11, 1},
-  {5, UPB_SIZE(1, 1), 1, 0, 8, 1},
-  {6, UPB_SIZE(2, 2), 2, 0, 8, 1},
+  {1, UPB_SIZE(4, 8), 1, 0, 12, 1},
+  {2, UPB_SIZE(12, 24), 2, 0, 12, 1},
+  {3, UPB_SIZE(20, 40), 3, 0, 12, 1},
+  {4, UPB_SIZE(28, 56), 4, 0, 11, 1},
+  {5, UPB_SIZE(1, 1), 5, 0, 8, 1},
+  {6, UPB_SIZE(2, 2), 6, 0, 8, 1},
 };
 
 const upb_msglayout google_protobuf_MethodDescriptorProto_msginit = {
   &google_protobuf_MethodDescriptorProto_submsgs[0],
   &google_protobuf_MethodDescriptorProto__fields[0],
-  UPB_SIZE(32, 64), 6, false,
+  UPB_SIZE(32, 64), 6, false, 255,
 };
 
 static const upb_msglayout *const google_protobuf_FileOptions_submsgs[1] = {
@@ -253,33 +253,33 @@ static const upb_msglayout *const google_protobuf_FileOptions_submsgs[1] = {
 };
 
 static const upb_msglayout_field google_protobuf_FileOptions__fields[21] = {
-  {1, UPB_SIZE(28, 32), 11, 0, 12, 1},
-  {8, UPB_SIZE(36, 48), 12, 0, 12, 1},
-  {9, UPB_SIZE(8, 8), 1, 0, 14, 1},
-  {10, UPB_SIZE(16, 16), 2, 0, 8, 1},
-  {11, UPB_SIZE(44, 64), 13, 0, 12, 1},
-  {16, UPB_SIZE(17, 17), 3, 0, 8, 1},
-  {17, UPB_SIZE(18, 18), 4, 0, 8, 1},
-  {18, UPB_SIZE(19, 19), 5, 0, 8, 1},
-  {20, UPB_SIZE(20, 20), 6, 0, 8, 1},
-  {23, UPB_SIZE(21, 21), 7, 0, 8, 1},
-  {27, UPB_SIZE(22, 22), 8, 0, 8, 1},
-  {31, UPB_SIZE(23, 23), 9, 0, 8, 1},
-  {36, UPB_SIZE(52, 80), 14, 0, 12, 1},
-  {37, UPB_SIZE(60, 96), 15, 0, 12, 1},
-  {39, UPB_SIZE(68, 112), 16, 0, 12, 1},
-  {40, UPB_SIZE(76, 128), 17, 0, 12, 1},
-  {41, UPB_SIZE(84, 144), 18, 0, 12, 1},
-  {42, UPB_SIZE(24, 24), 10, 0, 8, 1},
-  {44, UPB_SIZE(92, 160), 19, 0, 12, 1},
-  {45, UPB_SIZE(100, 176), 20, 0, 12, 1},
-  {999, UPB_SIZE(108, 192), 0, 0, 11, 3},
+  {1, UPB_SIZE(20, 24), 1, 0, 12, 1},
+  {8, UPB_SIZE(28, 40), 2, 0, 12, 1},
+  {9, UPB_SIZE(4, 4), 3, 0, 14, 1},
+  {10, UPB_SIZE(8, 8), 4, 0, 8, 1},
+  {11, UPB_SIZE(36, 56), 5, 0, 12, 1},
+  {16, UPB_SIZE(9, 9), 6, 0, 8, 1},
+  {17, UPB_SIZE(10, 10), 7, 0, 8, 1},
+  {18, UPB_SIZE(11, 11), 8, 0, 8, 1},
+  {20, UPB_SIZE(12, 12), 9, 0, 8, 1},
+  {23, UPB_SIZE(13, 13), 10, 0, 8, 1},
+  {27, UPB_SIZE(14, 14), 11, 0, 8, 1},
+  {31, UPB_SIZE(15, 15), 12, 0, 8, 1},
+  {36, UPB_SIZE(44, 72), 13, 0, 12, 1},
+  {37, UPB_SIZE(52, 88), 14, 0, 12, 1},
+  {39, UPB_SIZE(60, 104), 15, 0, 12, 1},
+  {40, UPB_SIZE(68, 120), 16, 0, 12, 1},
+  {41, UPB_SIZE(76, 136), 17, 0, 12, 1},
+  {42, UPB_SIZE(16, 16), 18, 0, 8, 1},
+  {44, UPB_SIZE(84, 152), 19, 0, 12, 1},
+  {45, UPB_SIZE(92, 168), 20, 0, 12, 1},
+  {999, UPB_SIZE(100, 184), 0, 0, 11, 3},
 };
 
 const upb_msglayout google_protobuf_FileOptions_msginit = {
   &google_protobuf_FileOptions_submsgs[0],
   &google_protobuf_FileOptions__fields[0],
-  UPB_SIZE(112, 208), 21, false,
+  UPB_SIZE(104, 192), 21, false, 255,
 };
 
 static const upb_msglayout *const google_protobuf_MessageOptions_submsgs[1] = {
@@ -297,7 +297,7 @@ static const upb_msglayout_field google_protobuf_MessageOptions__fields[5] = {
 const upb_msglayout google_protobuf_MessageOptions_msginit = {
   &google_protobuf_MessageOptions_submsgs[0],
   &google_protobuf_MessageOptions__fields[0],
-  UPB_SIZE(12, 16), 5, false,
+  UPB_SIZE(16, 16), 5, false, 255,
 };
 
 static const upb_msglayout *const google_protobuf_FieldOptions_submsgs[1] = {
@@ -305,19 +305,19 @@ static const upb_msglayout *const google_protobuf_FieldOptions_submsgs[1] = {
 };
 
 static const upb_msglayout_field google_protobuf_FieldOptions__fields[7] = {
-  {1, UPB_SIZE(8, 8), 1, 0, 14, 1},
-  {2, UPB_SIZE(24, 24), 3, 0, 8, 1},
-  {3, UPB_SIZE(25, 25), 4, 0, 8, 1},
-  {5, UPB_SIZE(26, 26), 5, 0, 8, 1},
-  {6, UPB_SIZE(16, 16), 2, 0, 14, 1},
-  {10, UPB_SIZE(27, 27), 6, 0, 8, 1},
-  {999, UPB_SIZE(28, 32), 0, 0, 11, 3},
+  {1, UPB_SIZE(4, 4), 1, 0, 14, 1},
+  {2, UPB_SIZE(12, 12), 2, 0, 8, 1},
+  {3, UPB_SIZE(13, 13), 3, 0, 8, 1},
+  {5, UPB_SIZE(14, 14), 4, 0, 8, 1},
+  {6, UPB_SIZE(8, 8), 5, 0, 14, 1},
+  {10, UPB_SIZE(15, 15), 6, 0, 8, 1},
+  {999, UPB_SIZE(16, 16), 0, 0, 11, 3},
 };
 
 const upb_msglayout google_protobuf_FieldOptions_msginit = {
   &google_protobuf_FieldOptions_submsgs[0],
   &google_protobuf_FieldOptions__fields[0],
-  UPB_SIZE(32, 40), 7, false,
+  UPB_SIZE(24, 24), 7, false, 255,
 };
 
 static const upb_msglayout *const google_protobuf_OneofOptions_submsgs[1] = {
@@ -331,7 +331,7 @@ static const upb_msglayout_field google_protobuf_OneofOptions__fields[1] = {
 const upb_msglayout google_protobuf_OneofOptions_msginit = {
   &google_protobuf_OneofOptions_submsgs[0],
   &google_protobuf_OneofOptions__fields[0],
-  UPB_SIZE(4, 8), 1, false,
+  UPB_SIZE(8, 8), 1, false, 255,
 };
 
 static const upb_msglayout *const google_protobuf_EnumOptions_submsgs[1] = {
@@ -347,7 +347,7 @@ static const upb_msglayout_field google_protobuf_EnumOptions__fields[3] = {
 const upb_msglayout google_protobuf_EnumOptions_msginit = {
   &google_protobuf_EnumOptions_submsgs[0],
   &google_protobuf_EnumOptions__fields[0],
-  UPB_SIZE(8, 16), 3, false,
+  UPB_SIZE(8, 16), 3, false, 255,
 };
 
 static const upb_msglayout *const google_protobuf_EnumValueOptions_submsgs[1] = {
@@ -362,7 +362,7 @@ static const upb_msglayout_field google_protobuf_EnumValueOptions__fields[2] = {
 const upb_msglayout google_protobuf_EnumValueOptions_msginit = {
   &google_protobuf_EnumValueOptions_submsgs[0],
   &google_protobuf_EnumValueOptions__fields[0],
-  UPB_SIZE(8, 16), 2, false,
+  UPB_SIZE(8, 16), 2, false, 255,
 };
 
 static const upb_msglayout *const google_protobuf_ServiceOptions_submsgs[1] = {
@@ -377,7 +377,7 @@ static const upb_msglayout_field google_protobuf_ServiceOptions__fields[2] = {
 const upb_msglayout google_protobuf_ServiceOptions_msginit = {
   &google_protobuf_ServiceOptions_submsgs[0],
   &google_protobuf_ServiceOptions__fields[0],
-  UPB_SIZE(8, 16), 2, false,
+  UPB_SIZE(8, 16), 2, false, 255,
 };
 
 static const upb_msglayout *const google_protobuf_MethodOptions_submsgs[1] = {
@@ -385,15 +385,15 @@ static const upb_msglayout *const google_protobuf_MethodOptions_submsgs[1] = {
 };
 
 static const upb_msglayout_field google_protobuf_MethodOptions__fields[3] = {
-  {33, UPB_SIZE(16, 16), 2, 0, 8, 1},
-  {34, UPB_SIZE(8, 8), 1, 0, 14, 1},
-  {999, UPB_SIZE(20, 24), 0, 0, 11, 3},
+  {33, UPB_SIZE(8, 8), 1, 0, 8, 1},
+  {34, UPB_SIZE(4, 4), 2, 0, 14, 1},
+  {999, UPB_SIZE(12, 16), 0, 0, 11, 3},
 };
 
 const upb_msglayout google_protobuf_MethodOptions_msginit = {
   &google_protobuf_MethodOptions_submsgs[0],
   &google_protobuf_MethodOptions__fields[0],
-  UPB_SIZE(24, 32), 3, false,
+  UPB_SIZE(16, 24), 3, false, 255,
 };
 
 static const upb_msglayout *const google_protobuf_UninterpretedOption_submsgs[1] = {
@@ -402,10 +402,10 @@ static const upb_msglayout *const google_protobuf_UninterpretedOption_submsgs[1]
 
 static const upb_msglayout_field google_protobuf_UninterpretedOption__fields[7] = {
   {2, UPB_SIZE(56, 80), 0, 0, 11, 3},
-  {3, UPB_SIZE(32, 32), 4, 0, 12, 1},
-  {4, UPB_SIZE(8, 8), 1, 0, 4, 1},
-  {5, UPB_SIZE(16, 16), 2, 0, 3, 1},
-  {6, UPB_SIZE(24, 24), 3, 0, 1, 1},
+  {3, UPB_SIZE(32, 32), 1, 0, 12, 1},
+  {4, UPB_SIZE(8, 8), 2, 0, 4, 1},
+  {5, UPB_SIZE(16, 16), 3, 0, 3, 1},
+  {6, UPB_SIZE(24, 24), 4, 0, 1, 1},
   {7, UPB_SIZE(40, 48), 5, 0, 12, 1},
   {8, UPB_SIZE(48, 64), 6, 0, 12, 1},
 };
@@ -413,18 +413,18 @@ static const upb_msglayout_field google_protobuf_UninterpretedOption__fields[7]
 const upb_msglayout google_protobuf_UninterpretedOption_msginit = {
   &google_protobuf_UninterpretedOption_submsgs[0],
   &google_protobuf_UninterpretedOption__fields[0],
-  UPB_SIZE(64, 96), 7, false,
+  UPB_SIZE(64, 96), 7, false, 255,
 };
 
 static const upb_msglayout_field google_protobuf_UninterpretedOption_NamePart__fields[2] = {
-  {1, UPB_SIZE(4, 8), 2, 0, 12, 2},
-  {2, UPB_SIZE(1, 1), 1, 0, 8, 2},
+  {1, UPB_SIZE(4, 8), 1, 0, 12, 2},
+  {2, UPB_SIZE(1, 1), 2, 0, 8, 2},
 };
 
 const upb_msglayout google_protobuf_UninterpretedOption_NamePart_msginit = {
   NULL,
   &google_protobuf_UninterpretedOption_NamePart__fields[0],
-  UPB_SIZE(16, 32), 2, false,
+  UPB_SIZE(16, 32), 2, false, 255,
 };
 
 static const upb_msglayout *const google_protobuf_SourceCodeInfo_submsgs[1] = {
@@ -438,7 +438,7 @@ static const upb_msglayout_field google_protobuf_SourceCodeInfo__fields[1] = {
 const upb_msglayout google_protobuf_SourceCodeInfo_msginit = {
   &google_protobuf_SourceCodeInfo_submsgs[0],
   &google_protobuf_SourceCodeInfo__fields[0],
-  UPB_SIZE(4, 8), 1, false,
+  UPB_SIZE(8, 8), 1, false, 255,
 };
 
 static const upb_msglayout_field google_protobuf_SourceCodeInfo_Location__fields[5] = {
@@ -452,7 +452,7 @@ static const upb_msglayout_field google_protobuf_SourceCodeInfo_Location__fields
 const upb_msglayout google_protobuf_SourceCodeInfo_Location_msginit = {
   NULL,
   &google_protobuf_SourceCodeInfo_Location__fields[0],
-  UPB_SIZE(32, 64), 5, false,
+  UPB_SIZE(32, 64), 5, false, 255,
 };
 
 static const upb_msglayout *const google_protobuf_GeneratedCodeInfo_submsgs[1] = {
@@ -466,20 +466,20 @@ static const upb_msglayout_field google_protobuf_GeneratedCodeInfo__fields[1] =
 const upb_msglayout google_protobuf_GeneratedCodeInfo_msginit = {
   &google_protobuf_GeneratedCodeInfo_submsgs[0],
   &google_protobuf_GeneratedCodeInfo__fields[0],
-  UPB_SIZE(4, 8), 1, false,
+  UPB_SIZE(8, 8), 1, false, 255,
 };
 
 static const upb_msglayout_field google_protobuf_GeneratedCodeInfo_Annotation__fields[4] = {
   {1, UPB_SIZE(20, 32), 0, 0, 5, _UPB_LABEL_PACKED},
-  {2, UPB_SIZE(12, 16), 3, 0, 12, 1},
-  {3, UPB_SIZE(4, 4), 1, 0, 5, 1},
-  {4, UPB_SIZE(8, 8), 2, 0, 5, 1},
+  {2, UPB_SIZE(12, 16), 1, 0, 12, 1},
+  {3, UPB_SIZE(4, 4), 2, 0, 5, 1},
+  {4, UPB_SIZE(8, 8), 3, 0, 5, 1},
 };
 
 const upb_msglayout google_protobuf_GeneratedCodeInfo_Annotation_msginit = {
   NULL,
   &google_protobuf_GeneratedCodeInfo_Annotation__fields[0],
-  UPB_SIZE(24, 48), 4, false,
+  UPB_SIZE(24, 48), 4, false, 255,
 };
 
 #include "upb/port_undef.inc"
index 64701a0..a8ed71a 100644 (file)
@@ -11,6 +11,7 @@
 
 #include "upb/msg.h"
 #include "upb/decode.h"
+#include "upb/decode_fast.h"
 #include "upb/encode.h"
 
 #include "upb/port_def.inc"
@@ -163,6 +164,12 @@ UPB_INLINE google_protobuf_FileDescriptorSet *google_protobuf_FileDescriptorSet_
   google_protobuf_FileDescriptorSet *ret = google_protobuf_FileDescriptorSet_new(arena);
   return (ret && upb_decode(buf, size, ret, &google_protobuf_FileDescriptorSet_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE google_protobuf_FileDescriptorSet *google_protobuf_FileDescriptorSet_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  google_protobuf_FileDescriptorSet *ret = google_protobuf_FileDescriptorSet_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &google_protobuf_FileDescriptorSet_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *google_protobuf_FileDescriptorSet_serialize(const google_protobuf_FileDescriptorSet *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &google_protobuf_FileDescriptorSet_msginit, arena, len);
 }
@@ -174,12 +181,12 @@ UPB_INLINE google_protobuf_FileDescriptorProto** google_protobuf_FileDescriptorS
   return (google_protobuf_FileDescriptorProto**)_upb_array_mutable_accessor(msg, UPB_SIZE(0, 0), len);
 }
 UPB_INLINE google_protobuf_FileDescriptorProto** google_protobuf_FileDescriptorSet_resize_file(google_protobuf_FileDescriptorSet *msg, size_t len, upb_arena *arena) {
-  return (google_protobuf_FileDescriptorProto**)_upb_array_resize_accessor(msg, UPB_SIZE(0, 0), len, UPB_TYPE_MESSAGE, arena);
+  return (google_protobuf_FileDescriptorProto**)_upb_array_resize_accessor2(msg, UPB_SIZE(0, 0), len, UPB_SIZE(2, 3), arena);
 }
 UPB_INLINE struct google_protobuf_FileDescriptorProto* google_protobuf_FileDescriptorSet_add_file(google_protobuf_FileDescriptorSet *msg, upb_arena *arena) {
   struct google_protobuf_FileDescriptorProto* sub = (struct google_protobuf_FileDescriptorProto*)_upb_msg_new(&google_protobuf_FileDescriptorProto_msginit, arena);
-  bool ok = _upb_array_append_accessor(
-      msg, UPB_SIZE(0, 0), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena);
+  bool ok = _upb_array_append_accessor2(
+      msg, UPB_SIZE(0, 0), UPB_SIZE(2, 3), &sub, arena);
   if (!ok) return NULL;
   return sub;
 }
@@ -194,6 +201,12 @@ UPB_INLINE google_protobuf_FileDescriptorProto *google_protobuf_FileDescriptorPr
   google_protobuf_FileDescriptorProto *ret = google_protobuf_FileDescriptorProto_new(arena);
   return (ret && upb_decode(buf, size, ret, &google_protobuf_FileDescriptorProto_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE google_protobuf_FileDescriptorProto *google_protobuf_FileDescriptorProto_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  google_protobuf_FileDescriptorProto *ret = google_protobuf_FileDescriptorProto_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &google_protobuf_FileDescriptorProto_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *google_protobuf_FileDescriptorProto_serialize(const google_protobuf_FileDescriptorProto *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &google_protobuf_FileDescriptorProto_msginit, arena, len);
 }
@@ -211,13 +224,13 @@ UPB_INLINE bool google_protobuf_FileDescriptorProto_has_service(const google_pro
 UPB_INLINE const google_protobuf_ServiceDescriptorProto* const* google_protobuf_FileDescriptorProto_service(const google_protobuf_FileDescriptorProto *msg, size_t *len) { return (const google_protobuf_ServiceDescriptorProto* const*)_upb_array_accessor(msg, UPB_SIZE(48, 96), len); }
 UPB_INLINE bool google_protobuf_FileDescriptorProto_has_extension(const google_protobuf_FileDescriptorProto *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(52, 104)); }
 UPB_INLINE const google_protobuf_FieldDescriptorProto* const* google_protobuf_FileDescriptorProto_extension(const google_protobuf_FileDescriptorProto *msg, size_t *len) { return (const google_protobuf_FieldDescriptorProto* const*)_upb_array_accessor(msg, UPB_SIZE(52, 104), len); }
-UPB_INLINE bool google_protobuf_FileDescriptorProto_has_options(const google_protobuf_FileDescriptorProto *msg) { return _upb_hasbit(msg, 4); }
+UPB_INLINE bool google_protobuf_FileDescriptorProto_has_options(const google_protobuf_FileDescriptorProto *msg) { return _upb_hasbit(msg, 3); }
 UPB_INLINE const google_protobuf_FileOptions* google_protobuf_FileDescriptorProto_options(const google_protobuf_FileDescriptorProto *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(28, 56), const google_protobuf_FileOptions*); }
-UPB_INLINE bool google_protobuf_FileDescriptorProto_has_source_code_info(const google_protobuf_FileDescriptorProto *msg) { return _upb_hasbit(msg, 5); }
+UPB_INLINE bool google_protobuf_FileDescriptorProto_has_source_code_info(const google_protobuf_FileDescriptorProto *msg) { return _upb_hasbit(msg, 4); }
 UPB_INLINE const google_protobuf_SourceCodeInfo* google_protobuf_FileDescriptorProto_source_code_info(const google_protobuf_FileDescriptorProto *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(32, 64), const google_protobuf_SourceCodeInfo*); }
 UPB_INLINE int32_t const* google_protobuf_FileDescriptorProto_public_dependency(const google_protobuf_FileDescriptorProto *msg, size_t *len) { return (int32_t const*)_upb_array_accessor(msg, UPB_SIZE(56, 112), len); }
 UPB_INLINE int32_t const* google_protobuf_FileDescriptorProto_weak_dependency(const google_protobuf_FileDescriptorProto *msg, size_t *len) { return (int32_t const*)_upb_array_accessor(msg, UPB_SIZE(60, 120), len); }
-UPB_INLINE bool google_protobuf_FileDescriptorProto_has_syntax(const google_protobuf_FileDescriptorProto *msg) { return _upb_hasbit(msg, 3); }
+UPB_INLINE bool google_protobuf_FileDescriptorProto_has_syntax(const google_protobuf_FileDescriptorProto *msg) { return _upb_hasbit(msg, 5); }
 UPB_INLINE upb_strview google_protobuf_FileDescriptorProto_syntax(const google_protobuf_FileDescriptorProto *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(20, 40), upb_strview); }
 
 UPB_INLINE void google_protobuf_FileDescriptorProto_set_name(google_protobuf_FileDescriptorProto *msg, upb_strview value) {
@@ -232,22 +245,22 @@ UPB_INLINE upb_strview* google_protobuf_FileDescriptorProto_mutable_dependency(g
   return (upb_strview*)_upb_array_mutable_accessor(msg, UPB_SIZE(36, 72), len);
 }
 UPB_INLINE upb_strview* google_protobuf_FileDescriptorProto_resize_dependency(google_protobuf_FileDescriptorProto *msg, size_t len, upb_arena *arena) {
-  return (upb_strview*)_upb_array_resize_accessor(msg, UPB_SIZE(36, 72), len, UPB_TYPE_STRING, arena);
+  return (upb_strview*)_upb_array_resize_accessor2(msg, UPB_SIZE(36, 72), len, UPB_SIZE(3, 4), arena);
 }
 UPB_INLINE bool google_protobuf_FileDescriptorProto_add_dependency(google_protobuf_FileDescriptorProto *msg, upb_strview val, upb_arena *arena) {
-  return _upb_array_append_accessor(msg, UPB_SIZE(36, 72), UPB_SIZE(8, 16), UPB_TYPE_STRING, &val,
+  return _upb_array_append_accessor2(msg, UPB_SIZE(36, 72), UPB_SIZE(3, 4), &val,
       arena);
 }
 UPB_INLINE google_protobuf_DescriptorProto** google_protobuf_FileDescriptorProto_mutable_message_type(google_protobuf_FileDescriptorProto *msg, size_t *len) {
   return (google_protobuf_DescriptorProto**)_upb_array_mutable_accessor(msg, UPB_SIZE(40, 80), len);
 }
 UPB_INLINE google_protobuf_DescriptorProto** google_protobuf_FileDescriptorProto_resize_message_type(google_protobuf_FileDescriptorProto *msg, size_t len, upb_arena *arena) {
-  return (google_protobuf_DescriptorProto**)_upb_array_resize_accessor(msg, UPB_SIZE(40, 80), len, UPB_TYPE_MESSAGE, arena);
+  return (google_protobuf_DescriptorProto**)_upb_array_resize_accessor2(msg, UPB_SIZE(40, 80), len, UPB_SIZE(2, 3), arena);
 }
 UPB_INLINE struct google_protobuf_DescriptorProto* google_protobuf_FileDescriptorProto_add_message_type(google_protobuf_FileDescriptorProto *msg, upb_arena *arena) {
   struct google_protobuf_DescriptorProto* sub = (struct google_protobuf_DescriptorProto*)_upb_msg_new(&google_protobuf_DescriptorProto_msginit, arena);
-  bool ok = _upb_array_append_accessor(
-      msg, UPB_SIZE(40, 80), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena);
+  bool ok = _upb_array_append_accessor2(
+      msg, UPB_SIZE(40, 80), UPB_SIZE(2, 3), &sub, arena);
   if (!ok) return NULL;
   return sub;
 }
@@ -255,12 +268,12 @@ UPB_INLINE google_protobuf_EnumDescriptorProto** google_protobuf_FileDescriptorP
   return (google_protobuf_EnumDescriptorProto**)_upb_array_mutable_accessor(msg, UPB_SIZE(44, 88), len);
 }
 UPB_INLINE google_protobuf_EnumDescriptorProto** google_protobuf_FileDescriptorProto_resize_enum_type(google_protobuf_FileDescriptorProto *msg, size_t len, upb_arena *arena) {
-  return (google_protobuf_EnumDescriptorProto**)_upb_array_resize_accessor(msg, UPB_SIZE(44, 88), len, UPB_TYPE_MESSAGE, arena);
+  return (google_protobuf_EnumDescriptorProto**)_upb_array_resize_accessor2(msg, UPB_SIZE(44, 88), len, UPB_SIZE(2, 3), arena);
 }
 UPB_INLINE struct google_protobuf_EnumDescriptorProto* google_protobuf_FileDescriptorProto_add_enum_type(google_protobuf_FileDescriptorProto *msg, upb_arena *arena) {
   struct google_protobuf_EnumDescriptorProto* sub = (struct google_protobuf_EnumDescriptorProto*)_upb_msg_new(&google_protobuf_EnumDescriptorProto_msginit, arena);
-  bool ok = _upb_array_append_accessor(
-      msg, UPB_SIZE(44, 88), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena);
+  bool ok = _upb_array_append_accessor2(
+      msg, UPB_SIZE(44, 88), UPB_SIZE(2, 3), &sub, arena);
   if (!ok) return NULL;
   return sub;
 }
@@ -268,12 +281,12 @@ UPB_INLINE google_protobuf_ServiceDescriptorProto** google_protobuf_FileDescript
   return (google_protobuf_ServiceDescriptorProto**)_upb_array_mutable_accessor(msg, UPB_SIZE(48, 96), len);
 }
 UPB_INLINE google_protobuf_ServiceDescriptorProto** google_protobuf_FileDescriptorProto_resize_service(google_protobuf_FileDescriptorProto *msg, size_t len, upb_arena *arena) {
-  return (google_protobuf_ServiceDescriptorProto**)_upb_array_resize_accessor(msg, UPB_SIZE(48, 96), len, UPB_TYPE_MESSAGE, arena);
+  return (google_protobuf_ServiceDescriptorProto**)_upb_array_resize_accessor2(msg, UPB_SIZE(48, 96), len, UPB_SIZE(2, 3), arena);
 }
 UPB_INLINE struct google_protobuf_ServiceDescriptorProto* google_protobuf_FileDescriptorProto_add_service(google_protobuf_FileDescriptorProto *msg, upb_arena *arena) {
   struct google_protobuf_ServiceDescriptorProto* sub = (struct google_protobuf_ServiceDescriptorProto*)_upb_msg_new(&google_protobuf_ServiceDescriptorProto_msginit, arena);
-  bool ok = _upb_array_append_accessor(
-      msg, UPB_SIZE(48, 96), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena);
+  bool ok = _upb_array_append_accessor2(
+      msg, UPB_SIZE(48, 96), UPB_SIZE(2, 3), &sub, arena);
   if (!ok) return NULL;
   return sub;
 }
@@ -281,17 +294,17 @@ UPB_INLINE google_protobuf_FieldDescriptorProto** google_protobuf_FileDescriptor
   return (google_protobuf_FieldDescriptorProto**)_upb_array_mutable_accessor(msg, UPB_SIZE(52, 104), len);
 }
 UPB_INLINE google_protobuf_FieldDescriptorProto** google_protobuf_FileDescriptorProto_resize_extension(google_protobuf_FileDescriptorProto *msg, size_t len, upb_arena *arena) {
-  return (google_protobuf_FieldDescriptorProto**)_upb_array_resize_accessor(msg, UPB_SIZE(52, 104), len, UPB_TYPE_MESSAGE, arena);
+  return (google_protobuf_FieldDescriptorProto**)_upb_array_resize_accessor2(msg, UPB_SIZE(52, 104), len, UPB_SIZE(2, 3), arena);
 }
 UPB_INLINE struct google_protobuf_FieldDescriptorProto* google_protobuf_FileDescriptorProto_add_extension(google_protobuf_FileDescriptorProto *msg, upb_arena *arena) {
   struct google_protobuf_FieldDescriptorProto* sub = (struct google_protobuf_FieldDescriptorProto*)_upb_msg_new(&google_protobuf_FieldDescriptorProto_msginit, arena);
-  bool ok = _upb_array_append_accessor(
-      msg, UPB_SIZE(52, 104), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena);
+  bool ok = _upb_array_append_accessor2(
+      msg, UPB_SIZE(52, 104), UPB_SIZE(2, 3), &sub, arena);
   if (!ok) return NULL;
   return sub;
 }
 UPB_INLINE void google_protobuf_FileDescriptorProto_set_options(google_protobuf_FileDescriptorProto *msg, google_protobuf_FileOptions* value) {
-  _upb_sethas(msg, 4);
+  _upb_sethas(msg, 3);
   *UPB_PTR_AT(msg, UPB_SIZE(28, 56), google_protobuf_FileOptions*) = value;
 }
 UPB_INLINE struct google_protobuf_FileOptions* google_protobuf_FileDescriptorProto_mutable_options(google_protobuf_FileDescriptorProto *msg, upb_arena *arena) {
@@ -304,7 +317,7 @@ UPB_INLINE struct google_protobuf_FileOptions* google_protobuf_FileDescriptorPro
   return sub;
 }
 UPB_INLINE void google_protobuf_FileDescriptorProto_set_source_code_info(google_protobuf_FileDescriptorProto *msg, google_protobuf_SourceCodeInfo* value) {
-  _upb_sethas(msg, 5);
+  _upb_sethas(msg, 4);
   *UPB_PTR_AT(msg, UPB_SIZE(32, 64), google_protobuf_SourceCodeInfo*) = value;
 }
 UPB_INLINE struct google_protobuf_SourceCodeInfo* google_protobuf_FileDescriptorProto_mutable_source_code_info(google_protobuf_FileDescriptorProto *msg, upb_arena *arena) {
@@ -320,24 +333,24 @@ UPB_INLINE int32_t* google_protobuf_FileDescriptorProto_mutable_public_dependenc
   return (int32_t*)_upb_array_mutable_accessor(msg, UPB_SIZE(56, 112), len);
 }
 UPB_INLINE int32_t* google_protobuf_FileDescriptorProto_resize_public_dependency(google_protobuf_FileDescriptorProto *msg, size_t len, upb_arena *arena) {
-  return (int32_t*)_upb_array_resize_accessor(msg, UPB_SIZE(56, 112), len, UPB_TYPE_INT32, arena);
+  return (int32_t*)_upb_array_resize_accessor2(msg, UPB_SIZE(56, 112), len, 2, arena);
 }
 UPB_INLINE bool google_protobuf_FileDescriptorProto_add_public_dependency(google_protobuf_FileDescriptorProto *msg, int32_t val, upb_arena *arena) {
-  return _upb_array_append_accessor(msg, UPB_SIZE(56, 112), UPB_SIZE(4, 4), UPB_TYPE_INT32, &val,
+  return _upb_array_append_accessor2(msg, UPB_SIZE(56, 112), 2, &val,
       arena);
 }
 UPB_INLINE int32_t* google_protobuf_FileDescriptorProto_mutable_weak_dependency(google_protobuf_FileDescriptorProto *msg, size_t *len) {
   return (int32_t*)_upb_array_mutable_accessor(msg, UPB_SIZE(60, 120), len);
 }
 UPB_INLINE int32_t* google_protobuf_FileDescriptorProto_resize_weak_dependency(google_protobuf_FileDescriptorProto *msg, size_t len, upb_arena *arena) {
-  return (int32_t*)_upb_array_resize_accessor(msg, UPB_SIZE(60, 120), len, UPB_TYPE_INT32, arena);
+  return (int32_t*)_upb_array_resize_accessor2(msg, UPB_SIZE(60, 120), len, 2, arena);
 }
 UPB_INLINE bool google_protobuf_FileDescriptorProto_add_weak_dependency(google_protobuf_FileDescriptorProto *msg, int32_t val, upb_arena *arena) {
-  return _upb_array_append_accessor(msg, UPB_SIZE(60, 120), UPB_SIZE(4, 4), UPB_TYPE_INT32, &val,
+  return _upb_array_append_accessor2(msg, UPB_SIZE(60, 120), 2, &val,
       arena);
 }
 UPB_INLINE void google_protobuf_FileDescriptorProto_set_syntax(google_protobuf_FileDescriptorProto *msg, upb_strview value) {
-  _upb_sethas(msg, 3);
+  _upb_sethas(msg, 5);
   *UPB_PTR_AT(msg, UPB_SIZE(20, 40), upb_strview) = value;
 }
 
@@ -351,6 +364,12 @@ UPB_INLINE google_protobuf_DescriptorProto *google_protobuf_DescriptorProto_pars
   google_protobuf_DescriptorProto *ret = google_protobuf_DescriptorProto_new(arena);
   return (ret && upb_decode(buf, size, ret, &google_protobuf_DescriptorProto_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE google_protobuf_DescriptorProto *google_protobuf_DescriptorProto_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  google_protobuf_DescriptorProto *ret = google_protobuf_DescriptorProto_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &google_protobuf_DescriptorProto_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *google_protobuf_DescriptorProto_serialize(const google_protobuf_DescriptorProto *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &google_protobuf_DescriptorProto_msginit, arena, len);
 }
@@ -383,12 +402,12 @@ UPB_INLINE google_protobuf_FieldDescriptorProto** google_protobuf_DescriptorProt
   return (google_protobuf_FieldDescriptorProto**)_upb_array_mutable_accessor(msg, UPB_SIZE(16, 32), len);
 }
 UPB_INLINE google_protobuf_FieldDescriptorProto** google_protobuf_DescriptorProto_resize_field(google_protobuf_DescriptorProto *msg, size_t len, upb_arena *arena) {
-  return (google_protobuf_FieldDescriptorProto**)_upb_array_resize_accessor(msg, UPB_SIZE(16, 32), len, UPB_TYPE_MESSAGE, arena);
+  return (google_protobuf_FieldDescriptorProto**)_upb_array_resize_accessor2(msg, UPB_SIZE(16, 32), len, UPB_SIZE(2, 3), arena);
 }
 UPB_INLINE struct google_protobuf_FieldDescriptorProto* google_protobuf_DescriptorProto_add_field(google_protobuf_DescriptorProto *msg, upb_arena *arena) {
   struct google_protobuf_FieldDescriptorProto* sub = (struct google_protobuf_FieldDescriptorProto*)_upb_msg_new(&google_protobuf_FieldDescriptorProto_msginit, arena);
-  bool ok = _upb_array_append_accessor(
-      msg, UPB_SIZE(16, 32), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena);
+  bool ok = _upb_array_append_accessor2(
+      msg, UPB_SIZE(16, 32), UPB_SIZE(2, 3), &sub, arena);
   if (!ok) return NULL;
   return sub;
 }
@@ -396,12 +415,12 @@ UPB_INLINE google_protobuf_DescriptorProto** google_protobuf_DescriptorProto_mut
   return (google_protobuf_DescriptorProto**)_upb_array_mutable_accessor(msg, UPB_SIZE(20, 40), len);
 }
 UPB_INLINE google_protobuf_DescriptorProto** google_protobuf_DescriptorProto_resize_nested_type(google_protobuf_DescriptorProto *msg, size_t len, upb_arena *arena) {
-  return (google_protobuf_DescriptorProto**)_upb_array_resize_accessor(msg, UPB_SIZE(20, 40), len, UPB_TYPE_MESSAGE, arena);
+  return (google_protobuf_DescriptorProto**)_upb_array_resize_accessor2(msg, UPB_SIZE(20, 40), len, UPB_SIZE(2, 3), arena);
 }
 UPB_INLINE struct google_protobuf_DescriptorProto* google_protobuf_DescriptorProto_add_nested_type(google_protobuf_DescriptorProto *msg, upb_arena *arena) {
   struct google_protobuf_DescriptorProto* sub = (struct google_protobuf_DescriptorProto*)_upb_msg_new(&google_protobuf_DescriptorProto_msginit, arena);
-  bool ok = _upb_array_append_accessor(
-      msg, UPB_SIZE(20, 40), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena);
+  bool ok = _upb_array_append_accessor2(
+      msg, UPB_SIZE(20, 40), UPB_SIZE(2, 3), &sub, arena);
   if (!ok) return NULL;
   return sub;
 }
@@ -409,12 +428,12 @@ UPB_INLINE google_protobuf_EnumDescriptorProto** google_protobuf_DescriptorProto
   return (google_protobuf_EnumDescriptorProto**)_upb_array_mutable_accessor(msg, UPB_SIZE(24, 48), len);
 }
 UPB_INLINE google_protobuf_EnumDescriptorProto** google_protobuf_DescriptorProto_resize_enum_type(google_protobuf_DescriptorProto *msg, size_t len, upb_arena *arena) {
-  return (google_protobuf_EnumDescriptorProto**)_upb_array_resize_accessor(msg, UPB_SIZE(24, 48), len, UPB_TYPE_MESSAGE, arena);
+  return (google_protobuf_EnumDescriptorProto**)_upb_array_resize_accessor2(msg, UPB_SIZE(24, 48), len, UPB_SIZE(2, 3), arena);
 }
 UPB_INLINE struct google_protobuf_EnumDescriptorProto* google_protobuf_DescriptorProto_add_enum_type(google_protobuf_DescriptorProto *msg, upb_arena *arena) {
   struct google_protobuf_EnumDescriptorProto* sub = (struct google_protobuf_EnumDescriptorProto*)_upb_msg_new(&google_protobuf_EnumDescriptorProto_msginit, arena);
-  bool ok = _upb_array_append_accessor(
-      msg, UPB_SIZE(24, 48), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena);
+  bool ok = _upb_array_append_accessor2(
+      msg, UPB_SIZE(24, 48), UPB_SIZE(2, 3), &sub, arena);
   if (!ok) return NULL;
   return sub;
 }
@@ -422,12 +441,12 @@ UPB_INLINE google_protobuf_DescriptorProto_ExtensionRange** google_protobuf_Desc
   return (google_protobuf_DescriptorProto_ExtensionRange**)_upb_array_mutable_accessor(msg, UPB_SIZE(28, 56), len);
 }
 UPB_INLINE google_protobuf_DescriptorProto_ExtensionRange** google_protobuf_DescriptorProto_resize_extension_range(google_protobuf_DescriptorProto *msg, size_t len, upb_arena *arena) {
-  return (google_protobuf_DescriptorProto_ExtensionRange**)_upb_array_resize_accessor(msg, UPB_SIZE(28, 56), len, UPB_TYPE_MESSAGE, arena);
+  return (google_protobuf_DescriptorProto_ExtensionRange**)_upb_array_resize_accessor2(msg, UPB_SIZE(28, 56), len, UPB_SIZE(2, 3), arena);
 }
 UPB_INLINE struct google_protobuf_DescriptorProto_ExtensionRange* google_protobuf_DescriptorProto_add_extension_range(google_protobuf_DescriptorProto *msg, upb_arena *arena) {
   struct google_protobuf_DescriptorProto_ExtensionRange* sub = (struct google_protobuf_DescriptorProto_ExtensionRange*)_upb_msg_new(&google_protobuf_DescriptorProto_ExtensionRange_msginit, arena);
-  bool ok = _upb_array_append_accessor(
-      msg, UPB_SIZE(28, 56), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena);
+  bool ok = _upb_array_append_accessor2(
+      msg, UPB_SIZE(28, 56), UPB_SIZE(2, 3), &sub, arena);
   if (!ok) return NULL;
   return sub;
 }
@@ -435,12 +454,12 @@ UPB_INLINE google_protobuf_FieldDescriptorProto** google_protobuf_DescriptorProt
   return (google_protobuf_FieldDescriptorProto**)_upb_array_mutable_accessor(msg, UPB_SIZE(32, 64), len);
 }
 UPB_INLINE google_protobuf_FieldDescriptorProto** google_protobuf_DescriptorProto_resize_extension(google_protobuf_DescriptorProto *msg, size_t len, upb_arena *arena) {
-  return (google_protobuf_FieldDescriptorProto**)_upb_array_resize_accessor(msg, UPB_SIZE(32, 64), len, UPB_TYPE_MESSAGE, arena);
+  return (google_protobuf_FieldDescriptorProto**)_upb_array_resize_accessor2(msg, UPB_SIZE(32, 64), len, UPB_SIZE(2, 3), arena);
 }
 UPB_INLINE struct google_protobuf_FieldDescriptorProto* google_protobuf_DescriptorProto_add_extension(google_protobuf_DescriptorProto *msg, upb_arena *arena) {
   struct google_protobuf_FieldDescriptorProto* sub = (struct google_protobuf_FieldDescriptorProto*)_upb_msg_new(&google_protobuf_FieldDescriptorProto_msginit, arena);
-  bool ok = _upb_array_append_accessor(
-      msg, UPB_SIZE(32, 64), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena);
+  bool ok = _upb_array_append_accessor2(
+      msg, UPB_SIZE(32, 64), UPB_SIZE(2, 3), &sub, arena);
   if (!ok) return NULL;
   return sub;
 }
@@ -461,12 +480,12 @@ UPB_INLINE google_protobuf_OneofDescriptorProto** google_protobuf_DescriptorProt
   return (google_protobuf_OneofDescriptorProto**)_upb_array_mutable_accessor(msg, UPB_SIZE(36, 72), len);
 }
 UPB_INLINE google_protobuf_OneofDescriptorProto** google_protobuf_DescriptorProto_resize_oneof_decl(google_protobuf_DescriptorProto *msg, size_t len, upb_arena *arena) {
-  return (google_protobuf_OneofDescriptorProto**)_upb_array_resize_accessor(msg, UPB_SIZE(36, 72), len, UPB_TYPE_MESSAGE, arena);
+  return (google_protobuf_OneofDescriptorProto**)_upb_array_resize_accessor2(msg, UPB_SIZE(36, 72), len, UPB_SIZE(2, 3), arena);
 }
 UPB_INLINE struct google_protobuf_OneofDescriptorProto* google_protobuf_DescriptorProto_add_oneof_decl(google_protobuf_DescriptorProto *msg, upb_arena *arena) {
   struct google_protobuf_OneofDescriptorProto* sub = (struct google_protobuf_OneofDescriptorProto*)_upb_msg_new(&google_protobuf_OneofDescriptorProto_msginit, arena);
-  bool ok = _upb_array_append_accessor(
-      msg, UPB_SIZE(36, 72), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena);
+  bool ok = _upb_array_append_accessor2(
+      msg, UPB_SIZE(36, 72), UPB_SIZE(2, 3), &sub, arena);
   if (!ok) return NULL;
   return sub;
 }
@@ -474,12 +493,12 @@ UPB_INLINE google_protobuf_DescriptorProto_ReservedRange** google_protobuf_Descr
   return (google_protobuf_DescriptorProto_ReservedRange**)_upb_array_mutable_accessor(msg, UPB_SIZE(40, 80), len);
 }
 UPB_INLINE google_protobuf_DescriptorProto_ReservedRange** google_protobuf_DescriptorProto_resize_reserved_range(google_protobuf_DescriptorProto *msg, size_t len, upb_arena *arena) {
-  return (google_protobuf_DescriptorProto_ReservedRange**)_upb_array_resize_accessor(msg, UPB_SIZE(40, 80), len, UPB_TYPE_MESSAGE, arena);
+  return (google_protobuf_DescriptorProto_ReservedRange**)_upb_array_resize_accessor2(msg, UPB_SIZE(40, 80), len, UPB_SIZE(2, 3), arena);
 }
 UPB_INLINE struct google_protobuf_DescriptorProto_ReservedRange* google_protobuf_DescriptorProto_add_reserved_range(google_protobuf_DescriptorProto *msg, upb_arena *arena) {
   struct google_protobuf_DescriptorProto_ReservedRange* sub = (struct google_protobuf_DescriptorProto_ReservedRange*)_upb_msg_new(&google_protobuf_DescriptorProto_ReservedRange_msginit, arena);
-  bool ok = _upb_array_append_accessor(
-      msg, UPB_SIZE(40, 80), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena);
+  bool ok = _upb_array_append_accessor2(
+      msg, UPB_SIZE(40, 80), UPB_SIZE(2, 3), &sub, arena);
   if (!ok) return NULL;
   return sub;
 }
@@ -487,10 +506,10 @@ UPB_INLINE upb_strview* google_protobuf_DescriptorProto_mutable_reserved_name(go
   return (upb_strview*)_upb_array_mutable_accessor(msg, UPB_SIZE(44, 88), len);
 }
 UPB_INLINE upb_strview* google_protobuf_DescriptorProto_resize_reserved_name(google_protobuf_DescriptorProto *msg, size_t len, upb_arena *arena) {
-  return (upb_strview*)_upb_array_resize_accessor(msg, UPB_SIZE(44, 88), len, UPB_TYPE_STRING, arena);
+  return (upb_strview*)_upb_array_resize_accessor2(msg, UPB_SIZE(44, 88), len, UPB_SIZE(3, 4), arena);
 }
 UPB_INLINE bool google_protobuf_DescriptorProto_add_reserved_name(google_protobuf_DescriptorProto *msg, upb_strview val, upb_arena *arena) {
-  return _upb_array_append_accessor(msg, UPB_SIZE(44, 88), UPB_SIZE(8, 16), UPB_TYPE_STRING, &val,
+  return _upb_array_append_accessor2(msg, UPB_SIZE(44, 88), UPB_SIZE(3, 4), &val,
       arena);
 }
 
@@ -504,6 +523,12 @@ UPB_INLINE google_protobuf_DescriptorProto_ExtensionRange *google_protobuf_Descr
   google_protobuf_DescriptorProto_ExtensionRange *ret = google_protobuf_DescriptorProto_ExtensionRange_new(arena);
   return (ret && upb_decode(buf, size, ret, &google_protobuf_DescriptorProto_ExtensionRange_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE google_protobuf_DescriptorProto_ExtensionRange *google_protobuf_DescriptorProto_ExtensionRange_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  google_protobuf_DescriptorProto_ExtensionRange *ret = google_protobuf_DescriptorProto_ExtensionRange_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &google_protobuf_DescriptorProto_ExtensionRange_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *google_protobuf_DescriptorProto_ExtensionRange_serialize(const google_protobuf_DescriptorProto_ExtensionRange *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &google_protobuf_DescriptorProto_ExtensionRange_msginit, arena, len);
 }
@@ -547,6 +572,12 @@ UPB_INLINE google_protobuf_DescriptorProto_ReservedRange *google_protobuf_Descri
   google_protobuf_DescriptorProto_ReservedRange *ret = google_protobuf_DescriptorProto_ReservedRange_new(arena);
   return (ret && upb_decode(buf, size, ret, &google_protobuf_DescriptorProto_ReservedRange_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE google_protobuf_DescriptorProto_ReservedRange *google_protobuf_DescriptorProto_ReservedRange_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  google_protobuf_DescriptorProto_ReservedRange *ret = google_protobuf_DescriptorProto_ReservedRange_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &google_protobuf_DescriptorProto_ReservedRange_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *google_protobuf_DescriptorProto_ReservedRange_serialize(const google_protobuf_DescriptorProto_ReservedRange *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &google_protobuf_DescriptorProto_ReservedRange_msginit, arena, len);
 }
@@ -575,6 +606,12 @@ UPB_INLINE google_protobuf_ExtensionRangeOptions *google_protobuf_ExtensionRange
   google_protobuf_ExtensionRangeOptions *ret = google_protobuf_ExtensionRangeOptions_new(arena);
   return (ret && upb_decode(buf, size, ret, &google_protobuf_ExtensionRangeOptions_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE google_protobuf_ExtensionRangeOptions *google_protobuf_ExtensionRangeOptions_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  google_protobuf_ExtensionRangeOptions *ret = google_protobuf_ExtensionRangeOptions_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &google_protobuf_ExtensionRangeOptions_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *google_protobuf_ExtensionRangeOptions_serialize(const google_protobuf_ExtensionRangeOptions *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &google_protobuf_ExtensionRangeOptions_msginit, arena, len);
 }
@@ -586,12 +623,12 @@ UPB_INLINE google_protobuf_UninterpretedOption** google_protobuf_ExtensionRangeO
   return (google_protobuf_UninterpretedOption**)_upb_array_mutable_accessor(msg, UPB_SIZE(0, 0), len);
 }
 UPB_INLINE google_protobuf_UninterpretedOption** google_protobuf_ExtensionRangeOptions_resize_uninterpreted_option(google_protobuf_ExtensionRangeOptions *msg, size_t len, upb_arena *arena) {
-  return (google_protobuf_UninterpretedOption**)_upb_array_resize_accessor(msg, UPB_SIZE(0, 0), len, UPB_TYPE_MESSAGE, arena);
+  return (google_protobuf_UninterpretedOption**)_upb_array_resize_accessor2(msg, UPB_SIZE(0, 0), len, UPB_SIZE(2, 3), arena);
 }
 UPB_INLINE struct google_protobuf_UninterpretedOption* google_protobuf_ExtensionRangeOptions_add_uninterpreted_option(google_protobuf_ExtensionRangeOptions *msg, upb_arena *arena) {
   struct google_protobuf_UninterpretedOption* sub = (struct google_protobuf_UninterpretedOption*)_upb_msg_new(&google_protobuf_UninterpretedOption_msginit, arena);
-  bool ok = _upb_array_append_accessor(
-      msg, UPB_SIZE(0, 0), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena);
+  bool ok = _upb_array_append_accessor2(
+      msg, UPB_SIZE(0, 0), UPB_SIZE(2, 3), &sub, arena);
   if (!ok) return NULL;
   return sub;
 }
@@ -606,64 +643,70 @@ UPB_INLINE google_protobuf_FieldDescriptorProto *google_protobuf_FieldDescriptor
   google_protobuf_FieldDescriptorProto *ret = google_protobuf_FieldDescriptorProto_new(arena);
   return (ret && upb_decode(buf, size, ret, &google_protobuf_FieldDescriptorProto_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE google_protobuf_FieldDescriptorProto *google_protobuf_FieldDescriptorProto_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  google_protobuf_FieldDescriptorProto *ret = google_protobuf_FieldDescriptorProto_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &google_protobuf_FieldDescriptorProto_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *google_protobuf_FieldDescriptorProto_serialize(const google_protobuf_FieldDescriptorProto *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &google_protobuf_FieldDescriptorProto_msginit, arena, len);
 }
 
-UPB_INLINE bool google_protobuf_FieldDescriptorProto_has_name(const google_protobuf_FieldDescriptorProto *msg) { return _upb_hasbit(msg, 6); }
-UPB_INLINE upb_strview google_protobuf_FieldDescriptorProto_name(const google_protobuf_FieldDescriptorProto *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(36, 40), upb_strview); }
-UPB_INLINE bool google_protobuf_FieldDescriptorProto_has_extendee(const google_protobuf_FieldDescriptorProto *msg) { return _upb_hasbit(msg, 7); }
-UPB_INLINE upb_strview google_protobuf_FieldDescriptorProto_extendee(const google_protobuf_FieldDescriptorProto *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(44, 56), upb_strview); }
+UPB_INLINE bool google_protobuf_FieldDescriptorProto_has_name(const google_protobuf_FieldDescriptorProto *msg) { return _upb_hasbit(msg, 1); }
+UPB_INLINE upb_strview google_protobuf_FieldDescriptorProto_name(const google_protobuf_FieldDescriptorProto *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(24, 24), upb_strview); }
+UPB_INLINE bool google_protobuf_FieldDescriptorProto_has_extendee(const google_protobuf_FieldDescriptorProto *msg) { return _upb_hasbit(msg, 2); }
+UPB_INLINE upb_strview google_protobuf_FieldDescriptorProto_extendee(const google_protobuf_FieldDescriptorProto *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(32, 40), upb_strview); }
 UPB_INLINE bool google_protobuf_FieldDescriptorProto_has_number(const google_protobuf_FieldDescriptorProto *msg) { return _upb_hasbit(msg, 3); }
-UPB_INLINE int32_t google_protobuf_FieldDescriptorProto_number(const google_protobuf_FieldDescriptorProto *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(24, 24), int32_t); }
-UPB_INLINE bool google_protobuf_FieldDescriptorProto_has_label(const google_protobuf_FieldDescriptorProto *msg) { return _upb_hasbit(msg, 1); }
-UPB_INLINE int32_t google_protobuf_FieldDescriptorProto_label(const google_protobuf_FieldDescriptorProto *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(8, 8), int32_t); }
-UPB_INLINE bool google_protobuf_FieldDescriptorProto_has_type(const google_protobuf_FieldDescriptorProto *msg) { return _upb_hasbit(msg, 2); }
-UPB_INLINE int32_t google_protobuf_FieldDescriptorProto_type(const google_protobuf_FieldDescriptorProto *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(16, 16), int32_t); }
-UPB_INLINE bool google_protobuf_FieldDescriptorProto_has_type_name(const google_protobuf_FieldDescriptorProto *msg) { return _upb_hasbit(msg, 8); }
-UPB_INLINE upb_strview google_protobuf_FieldDescriptorProto_type_name(const google_protobuf_FieldDescriptorProto *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(52, 72), upb_strview); }
-UPB_INLINE bool google_protobuf_FieldDescriptorProto_has_default_value(const google_protobuf_FieldDescriptorProto *msg) { return _upb_hasbit(msg, 9); }
-UPB_INLINE upb_strview google_protobuf_FieldDescriptorProto_default_value(const google_protobuf_FieldDescriptorProto *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(60, 88), upb_strview); }
-UPB_INLINE bool google_protobuf_FieldDescriptorProto_has_options(const google_protobuf_FieldDescriptorProto *msg) { return _upb_hasbit(msg, 11); }
-UPB_INLINE const google_protobuf_FieldOptions* google_protobuf_FieldDescriptorProto_options(const google_protobuf_FieldDescriptorProto *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(76, 120), const google_protobuf_FieldOptions*); }
-UPB_INLINE bool google_protobuf_FieldDescriptorProto_has_oneof_index(const google_protobuf_FieldDescriptorProto *msg) { return _upb_hasbit(msg, 4); }
-UPB_INLINE int32_t google_protobuf_FieldDescriptorProto_oneof_index(const google_protobuf_FieldDescriptorProto *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(28, 28), int32_t); }
+UPB_INLINE int32_t google_protobuf_FieldDescriptorProto_number(const google_protobuf_FieldDescriptorProto *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(12, 12), int32_t); }
+UPB_INLINE bool google_protobuf_FieldDescriptorProto_has_label(const google_protobuf_FieldDescriptorProto *msg) { return _upb_hasbit(msg, 4); }
+UPB_INLINE int32_t google_protobuf_FieldDescriptorProto_label(const google_protobuf_FieldDescriptorProto *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(4, 4), int32_t); }
+UPB_INLINE bool google_protobuf_FieldDescriptorProto_has_type(const google_protobuf_FieldDescriptorProto *msg) { return _upb_hasbit(msg, 5); }
+UPB_INLINE int32_t google_protobuf_FieldDescriptorProto_type(const google_protobuf_FieldDescriptorProto *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(8, 8), int32_t); }
+UPB_INLINE bool google_protobuf_FieldDescriptorProto_has_type_name(const google_protobuf_FieldDescriptorProto *msg) { return _upb_hasbit(msg, 6); }
+UPB_INLINE upb_strview google_protobuf_FieldDescriptorProto_type_name(const google_protobuf_FieldDescriptorProto *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(40, 56), upb_strview); }
+UPB_INLINE bool google_protobuf_FieldDescriptorProto_has_default_value(const google_protobuf_FieldDescriptorProto *msg) { return _upb_hasbit(msg, 7); }
+UPB_INLINE upb_strview google_protobuf_FieldDescriptorProto_default_value(const google_protobuf_FieldDescriptorProto *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(48, 72), upb_strview); }
+UPB_INLINE bool google_protobuf_FieldDescriptorProto_has_options(const google_protobuf_FieldDescriptorProto *msg) { return _upb_hasbit(msg, 8); }
+UPB_INLINE const google_protobuf_FieldOptions* google_protobuf_FieldDescriptorProto_options(const google_protobuf_FieldDescriptorProto *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(64, 104), const google_protobuf_FieldOptions*); }
+UPB_INLINE bool google_protobuf_FieldDescriptorProto_has_oneof_index(const google_protobuf_FieldDescriptorProto *msg) { return _upb_hasbit(msg, 9); }
+UPB_INLINE int32_t google_protobuf_FieldDescriptorProto_oneof_index(const google_protobuf_FieldDescriptorProto *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(16, 16), int32_t); }
 UPB_INLINE bool google_protobuf_FieldDescriptorProto_has_json_name(const google_protobuf_FieldDescriptorProto *msg) { return _upb_hasbit(msg, 10); }
-UPB_INLINE upb_strview google_protobuf_FieldDescriptorProto_json_name(const google_protobuf_FieldDescriptorProto *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(68, 104), upb_strview); }
-UPB_INLINE bool google_protobuf_FieldDescriptorProto_has_proto3_optional(const google_protobuf_FieldDescriptorProto *msg) { return _upb_hasbit(msg, 5); }
-UPB_INLINE bool google_protobuf_FieldDescriptorProto_proto3_optional(const google_protobuf_FieldDescriptorProto *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(32, 32), bool); }
+UPB_INLINE upb_strview google_protobuf_FieldDescriptorProto_json_name(const google_protobuf_FieldDescriptorProto *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(56, 88), upb_strview); }
+UPB_INLINE bool google_protobuf_FieldDescriptorProto_has_proto3_optional(const google_protobuf_FieldDescriptorProto *msg) { return _upb_hasbit(msg, 11); }
+UPB_INLINE bool google_protobuf_FieldDescriptorProto_proto3_optional(const google_protobuf_FieldDescriptorProto *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(20, 20), bool); }
 
 UPB_INLINE void google_protobuf_FieldDescriptorProto_set_name(google_protobuf_FieldDescriptorProto *msg, upb_strview value) {
-  _upb_sethas(msg, 6);
-  *UPB_PTR_AT(msg, UPB_SIZE(36, 40), upb_strview) = value;
+  _upb_sethas(msg, 1);
+  *UPB_PTR_AT(msg, UPB_SIZE(24, 24), upb_strview) = value;
 }
 UPB_INLINE void google_protobuf_FieldDescriptorProto_set_extendee(google_protobuf_FieldDescriptorProto *msg, upb_strview value) {
-  _upb_sethas(msg, 7);
-  *UPB_PTR_AT(msg, UPB_SIZE(44, 56), upb_strview) = value;
+  _upb_sethas(msg, 2);
+  *UPB_PTR_AT(msg, UPB_SIZE(32, 40), upb_strview) = value;
 }
 UPB_INLINE void google_protobuf_FieldDescriptorProto_set_number(google_protobuf_FieldDescriptorProto *msg, int32_t value) {
   _upb_sethas(msg, 3);
-  *UPB_PTR_AT(msg, UPB_SIZE(24, 24), int32_t) = value;
+  *UPB_PTR_AT(msg, UPB_SIZE(12, 12), int32_t) = value;
 }
 UPB_INLINE void google_protobuf_FieldDescriptorProto_set_label(google_protobuf_FieldDescriptorProto *msg, int32_t value) {
-  _upb_sethas(msg, 1);
-  *UPB_PTR_AT(msg, UPB_SIZE(8, 8), int32_t) = value;
+  _upb_sethas(msg, 4);
+  *UPB_PTR_AT(msg, UPB_SIZE(4, 4), int32_t) = value;
 }
 UPB_INLINE void google_protobuf_FieldDescriptorProto_set_type(google_protobuf_FieldDescriptorProto *msg, int32_t value) {
-  _upb_sethas(msg, 2);
-  *UPB_PTR_AT(msg, UPB_SIZE(16, 16), int32_t) = value;
+  _upb_sethas(msg, 5);
+  *UPB_PTR_AT(msg, UPB_SIZE(8, 8), int32_t) = value;
 }
 UPB_INLINE void google_protobuf_FieldDescriptorProto_set_type_name(google_protobuf_FieldDescriptorProto *msg, upb_strview value) {
-  _upb_sethas(msg, 8);
-  *UPB_PTR_AT(msg, UPB_SIZE(52, 72), upb_strview) = value;
+  _upb_sethas(msg, 6);
+  *UPB_PTR_AT(msg, UPB_SIZE(40, 56), upb_strview) = value;
 }
 UPB_INLINE void google_protobuf_FieldDescriptorProto_set_default_value(google_protobuf_FieldDescriptorProto *msg, upb_strview value) {
-  _upb_sethas(msg, 9);
-  *UPB_PTR_AT(msg, UPB_SIZE(60, 88), upb_strview) = value;
+  _upb_sethas(msg, 7);
+  *UPB_PTR_AT(msg, UPB_SIZE(48, 72), upb_strview) = value;
 }
 UPB_INLINE void google_protobuf_FieldDescriptorProto_set_options(google_protobuf_FieldDescriptorProto *msg, google_protobuf_FieldOptions* value) {
-  _upb_sethas(msg, 11);
-  *UPB_PTR_AT(msg, UPB_SIZE(76, 120), google_protobuf_FieldOptions*) = value;
+  _upb_sethas(msg, 8);
+  *UPB_PTR_AT(msg, UPB_SIZE(64, 104), google_protobuf_FieldOptions*) = value;
 }
 UPB_INLINE struct google_protobuf_FieldOptions* google_protobuf_FieldDescriptorProto_mutable_options(google_protobuf_FieldDescriptorProto *msg, upb_arena *arena) {
   struct google_protobuf_FieldOptions* sub = (struct google_protobuf_FieldOptions*)google_protobuf_FieldDescriptorProto_options(msg);
@@ -675,16 +718,16 @@ UPB_INLINE struct google_protobuf_FieldOptions* google_protobuf_FieldDescriptorP
   return sub;
 }
 UPB_INLINE void google_protobuf_FieldDescriptorProto_set_oneof_index(google_protobuf_FieldDescriptorProto *msg, int32_t value) {
-  _upb_sethas(msg, 4);
-  *UPB_PTR_AT(msg, UPB_SIZE(28, 28), int32_t) = value;
+  _upb_sethas(msg, 9);
+  *UPB_PTR_AT(msg, UPB_SIZE(16, 16), int32_t) = value;
 }
 UPB_INLINE void google_protobuf_FieldDescriptorProto_set_json_name(google_protobuf_FieldDescriptorProto *msg, upb_strview value) {
   _upb_sethas(msg, 10);
-  *UPB_PTR_AT(msg, UPB_SIZE(68, 104), upb_strview) = value;
+  *UPB_PTR_AT(msg, UPB_SIZE(56, 88), upb_strview) = value;
 }
 UPB_INLINE void google_protobuf_FieldDescriptorProto_set_proto3_optional(google_protobuf_FieldDescriptorProto *msg, bool value) {
-  _upb_sethas(msg, 5);
-  *UPB_PTR_AT(msg, UPB_SIZE(32, 32), bool) = value;
+  _upb_sethas(msg, 11);
+  *UPB_PTR_AT(msg, UPB_SIZE(20, 20), bool) = value;
 }
 
 /* google.protobuf.OneofDescriptorProto */
@@ -697,6 +740,12 @@ UPB_INLINE google_protobuf_OneofDescriptorProto *google_protobuf_OneofDescriptor
   google_protobuf_OneofDescriptorProto *ret = google_protobuf_OneofDescriptorProto_new(arena);
   return (ret && upb_decode(buf, size, ret, &google_protobuf_OneofDescriptorProto_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE google_protobuf_OneofDescriptorProto *google_protobuf_OneofDescriptorProto_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  google_protobuf_OneofDescriptorProto *ret = google_protobuf_OneofDescriptorProto_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &google_protobuf_OneofDescriptorProto_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *google_protobuf_OneofDescriptorProto_serialize(const google_protobuf_OneofDescriptorProto *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &google_protobuf_OneofDescriptorProto_msginit, arena, len);
 }
@@ -734,6 +783,12 @@ UPB_INLINE google_protobuf_EnumDescriptorProto *google_protobuf_EnumDescriptorPr
   google_protobuf_EnumDescriptorProto *ret = google_protobuf_EnumDescriptorProto_new(arena);
   return (ret && upb_decode(buf, size, ret, &google_protobuf_EnumDescriptorProto_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE google_protobuf_EnumDescriptorProto *google_protobuf_EnumDescriptorProto_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  google_protobuf_EnumDescriptorProto *ret = google_protobuf_EnumDescriptorProto_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &google_protobuf_EnumDescriptorProto_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *google_protobuf_EnumDescriptorProto_serialize(const google_protobuf_EnumDescriptorProto *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &google_protobuf_EnumDescriptorProto_msginit, arena, len);
 }
@@ -756,12 +811,12 @@ UPB_INLINE google_protobuf_EnumValueDescriptorProto** google_protobuf_EnumDescri
   return (google_protobuf_EnumValueDescriptorProto**)_upb_array_mutable_accessor(msg, UPB_SIZE(16, 32), len);
 }
 UPB_INLINE google_protobuf_EnumValueDescriptorProto** google_protobuf_EnumDescriptorProto_resize_value(google_protobuf_EnumDescriptorProto *msg, size_t len, upb_arena *arena) {
-  return (google_protobuf_EnumValueDescriptorProto**)_upb_array_resize_accessor(msg, UPB_SIZE(16, 32), len, UPB_TYPE_MESSAGE, arena);
+  return (google_protobuf_EnumValueDescriptorProto**)_upb_array_resize_accessor2(msg, UPB_SIZE(16, 32), len, UPB_SIZE(2, 3), arena);
 }
 UPB_INLINE struct google_protobuf_EnumValueDescriptorProto* google_protobuf_EnumDescriptorProto_add_value(google_protobuf_EnumDescriptorProto *msg, upb_arena *arena) {
   struct google_protobuf_EnumValueDescriptorProto* sub = (struct google_protobuf_EnumValueDescriptorProto*)_upb_msg_new(&google_protobuf_EnumValueDescriptorProto_msginit, arena);
-  bool ok = _upb_array_append_accessor(
-      msg, UPB_SIZE(16, 32), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena);
+  bool ok = _upb_array_append_accessor2(
+      msg, UPB_SIZE(16, 32), UPB_SIZE(2, 3), &sub, arena);
   if (!ok) return NULL;
   return sub;
 }
@@ -782,12 +837,12 @@ UPB_INLINE google_protobuf_EnumDescriptorProto_EnumReservedRange** google_protob
   return (google_protobuf_EnumDescriptorProto_EnumReservedRange**)_upb_array_mutable_accessor(msg, UPB_SIZE(20, 40), len);
 }
 UPB_INLINE google_protobuf_EnumDescriptorProto_EnumReservedRange** google_protobuf_EnumDescriptorProto_resize_reserved_range(google_protobuf_EnumDescriptorProto *msg, size_t len, upb_arena *arena) {
-  return (google_protobuf_EnumDescriptorProto_EnumReservedRange**)_upb_array_resize_accessor(msg, UPB_SIZE(20, 40), len, UPB_TYPE_MESSAGE, arena);
+  return (google_protobuf_EnumDescriptorProto_EnumReservedRange**)_upb_array_resize_accessor2(msg, UPB_SIZE(20, 40), len, UPB_SIZE(2, 3), arena);
 }
 UPB_INLINE struct google_protobuf_EnumDescriptorProto_EnumReservedRange* google_protobuf_EnumDescriptorProto_add_reserved_range(google_protobuf_EnumDescriptorProto *msg, upb_arena *arena) {
   struct google_protobuf_EnumDescriptorProto_EnumReservedRange* sub = (struct google_protobuf_EnumDescriptorProto_EnumReservedRange*)_upb_msg_new(&google_protobuf_EnumDescriptorProto_EnumReservedRange_msginit, arena);
-  bool ok = _upb_array_append_accessor(
-      msg, UPB_SIZE(20, 40), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena);
+  bool ok = _upb_array_append_accessor2(
+      msg, UPB_SIZE(20, 40), UPB_SIZE(2, 3), &sub, arena);
   if (!ok) return NULL;
   return sub;
 }
@@ -795,10 +850,10 @@ UPB_INLINE upb_strview* google_protobuf_EnumDescriptorProto_mutable_reserved_nam
   return (upb_strview*)_upb_array_mutable_accessor(msg, UPB_SIZE(24, 48), len);
 }
 UPB_INLINE upb_strview* google_protobuf_EnumDescriptorProto_resize_reserved_name(google_protobuf_EnumDescriptorProto *msg, size_t len, upb_arena *arena) {
-  return (upb_strview*)_upb_array_resize_accessor(msg, UPB_SIZE(24, 48), len, UPB_TYPE_STRING, arena);
+  return (upb_strview*)_upb_array_resize_accessor2(msg, UPB_SIZE(24, 48), len, UPB_SIZE(3, 4), arena);
 }
 UPB_INLINE bool google_protobuf_EnumDescriptorProto_add_reserved_name(google_protobuf_EnumDescriptorProto *msg, upb_strview val, upb_arena *arena) {
-  return _upb_array_append_accessor(msg, UPB_SIZE(24, 48), UPB_SIZE(8, 16), UPB_TYPE_STRING, &val,
+  return _upb_array_append_accessor2(msg, UPB_SIZE(24, 48), UPB_SIZE(3, 4), &val,
       arena);
 }
 
@@ -812,6 +867,12 @@ UPB_INLINE google_protobuf_EnumDescriptorProto_EnumReservedRange *google_protobu
   google_protobuf_EnumDescriptorProto_EnumReservedRange *ret = google_protobuf_EnumDescriptorProto_EnumReservedRange_new(arena);
   return (ret && upb_decode(buf, size, ret, &google_protobuf_EnumDescriptorProto_EnumReservedRange_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE google_protobuf_EnumDescriptorProto_EnumReservedRange *google_protobuf_EnumDescriptorProto_EnumReservedRange_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  google_protobuf_EnumDescriptorProto_EnumReservedRange *ret = google_protobuf_EnumDescriptorProto_EnumReservedRange_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &google_protobuf_EnumDescriptorProto_EnumReservedRange_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *google_protobuf_EnumDescriptorProto_EnumReservedRange_serialize(const google_protobuf_EnumDescriptorProto_EnumReservedRange *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &google_protobuf_EnumDescriptorProto_EnumReservedRange_msginit, arena, len);
 }
@@ -840,23 +901,29 @@ UPB_INLINE google_protobuf_EnumValueDescriptorProto *google_protobuf_EnumValueDe
   google_protobuf_EnumValueDescriptorProto *ret = google_protobuf_EnumValueDescriptorProto_new(arena);
   return (ret && upb_decode(buf, size, ret, &google_protobuf_EnumValueDescriptorProto_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE google_protobuf_EnumValueDescriptorProto *google_protobuf_EnumValueDescriptorProto_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  google_protobuf_EnumValueDescriptorProto *ret = google_protobuf_EnumValueDescriptorProto_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &google_protobuf_EnumValueDescriptorProto_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *google_protobuf_EnumValueDescriptorProto_serialize(const google_protobuf_EnumValueDescriptorProto *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &google_protobuf_EnumValueDescriptorProto_msginit, arena, len);
 }
 
-UPB_INLINE bool google_protobuf_EnumValueDescriptorProto_has_name(const google_protobuf_EnumValueDescriptorProto *msg) { return _upb_hasbit(msg, 2); }
+UPB_INLINE bool google_protobuf_EnumValueDescriptorProto_has_name(const google_protobuf_EnumValueDescriptorProto *msg) { return _upb_hasbit(msg, 1); }
 UPB_INLINE upb_strview google_protobuf_EnumValueDescriptorProto_name(const google_protobuf_EnumValueDescriptorProto *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(8, 8), upb_strview); }
-UPB_INLINE bool google_protobuf_EnumValueDescriptorProto_has_number(const google_protobuf_EnumValueDescriptorProto *msg) { return _upb_hasbit(msg, 1); }
+UPB_INLINE bool google_protobuf_EnumValueDescriptorProto_has_number(const google_protobuf_EnumValueDescriptorProto *msg) { return _upb_hasbit(msg, 2); }
 UPB_INLINE int32_t google_protobuf_EnumValueDescriptorProto_number(const google_protobuf_EnumValueDescriptorProto *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(4, 4), int32_t); }
 UPB_INLINE bool google_protobuf_EnumValueDescriptorProto_has_options(const google_protobuf_EnumValueDescriptorProto *msg) { return _upb_hasbit(msg, 3); }
 UPB_INLINE const google_protobuf_EnumValueOptions* google_protobuf_EnumValueDescriptorProto_options(const google_protobuf_EnumValueDescriptorProto *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(16, 24), const google_protobuf_EnumValueOptions*); }
 
 UPB_INLINE void google_protobuf_EnumValueDescriptorProto_set_name(google_protobuf_EnumValueDescriptorProto *msg, upb_strview value) {
-  _upb_sethas(msg, 2);
+  _upb_sethas(msg, 1);
   *UPB_PTR_AT(msg, UPB_SIZE(8, 8), upb_strview) = value;
 }
 UPB_INLINE void google_protobuf_EnumValueDescriptorProto_set_number(google_protobuf_EnumValueDescriptorProto *msg, int32_t value) {
-  _upb_sethas(msg, 1);
+  _upb_sethas(msg, 2);
   *UPB_PTR_AT(msg, UPB_SIZE(4, 4), int32_t) = value;
 }
 UPB_INLINE void google_protobuf_EnumValueDescriptorProto_set_options(google_protobuf_EnumValueDescriptorProto *msg, google_protobuf_EnumValueOptions* value) {
@@ -883,6 +950,12 @@ UPB_INLINE google_protobuf_ServiceDescriptorProto *google_protobuf_ServiceDescri
   google_protobuf_ServiceDescriptorProto *ret = google_protobuf_ServiceDescriptorProto_new(arena);
   return (ret && upb_decode(buf, size, ret, &google_protobuf_ServiceDescriptorProto_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE google_protobuf_ServiceDescriptorProto *google_protobuf_ServiceDescriptorProto_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  google_protobuf_ServiceDescriptorProto *ret = google_protobuf_ServiceDescriptorProto_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &google_protobuf_ServiceDescriptorProto_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *google_protobuf_ServiceDescriptorProto_serialize(const google_protobuf_ServiceDescriptorProto *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &google_protobuf_ServiceDescriptorProto_msginit, arena, len);
 }
@@ -902,12 +975,12 @@ UPB_INLINE google_protobuf_MethodDescriptorProto** google_protobuf_ServiceDescri
   return (google_protobuf_MethodDescriptorProto**)_upb_array_mutable_accessor(msg, UPB_SIZE(16, 32), len);
 }
 UPB_INLINE google_protobuf_MethodDescriptorProto** google_protobuf_ServiceDescriptorProto_resize_method(google_protobuf_ServiceDescriptorProto *msg, size_t len, upb_arena *arena) {
-  return (google_protobuf_MethodDescriptorProto**)_upb_array_resize_accessor(msg, UPB_SIZE(16, 32), len, UPB_TYPE_MESSAGE, arena);
+  return (google_protobuf_MethodDescriptorProto**)_upb_array_resize_accessor2(msg, UPB_SIZE(16, 32), len, UPB_SIZE(2, 3), arena);
 }
 UPB_INLINE struct google_protobuf_MethodDescriptorProto* google_protobuf_ServiceDescriptorProto_add_method(google_protobuf_ServiceDescriptorProto *msg, upb_arena *arena) {
   struct google_protobuf_MethodDescriptorProto* sub = (struct google_protobuf_MethodDescriptorProto*)_upb_msg_new(&google_protobuf_MethodDescriptorProto_msginit, arena);
-  bool ok = _upb_array_append_accessor(
-      msg, UPB_SIZE(16, 32), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena);
+  bool ok = _upb_array_append_accessor2(
+      msg, UPB_SIZE(16, 32), UPB_SIZE(2, 3), &sub, arena);
   if (!ok) return NULL;
   return sub;
 }
@@ -935,37 +1008,43 @@ UPB_INLINE google_protobuf_MethodDescriptorProto *google_protobuf_MethodDescript
   google_protobuf_MethodDescriptorProto *ret = google_protobuf_MethodDescriptorProto_new(arena);
   return (ret && upb_decode(buf, size, ret, &google_protobuf_MethodDescriptorProto_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE google_protobuf_MethodDescriptorProto *google_protobuf_MethodDescriptorProto_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  google_protobuf_MethodDescriptorProto *ret = google_protobuf_MethodDescriptorProto_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &google_protobuf_MethodDescriptorProto_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *google_protobuf_MethodDescriptorProto_serialize(const google_protobuf_MethodDescriptorProto *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &google_protobuf_MethodDescriptorProto_msginit, arena, len);
 }
 
-UPB_INLINE bool google_protobuf_MethodDescriptorProto_has_name(const google_protobuf_MethodDescriptorProto *msg) { return _upb_hasbit(msg, 3); }
+UPB_INLINE bool google_protobuf_MethodDescriptorProto_has_name(const google_protobuf_MethodDescriptorProto *msg) { return _upb_hasbit(msg, 1); }
 UPB_INLINE upb_strview google_protobuf_MethodDescriptorProto_name(const google_protobuf_MethodDescriptorProto *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(4, 8), upb_strview); }
-UPB_INLINE bool google_protobuf_MethodDescriptorProto_has_input_type(const google_protobuf_MethodDescriptorProto *msg) { return _upb_hasbit(msg, 4); }
+UPB_INLINE bool google_protobuf_MethodDescriptorProto_has_input_type(const google_protobuf_MethodDescriptorProto *msg) { return _upb_hasbit(msg, 2); }
 UPB_INLINE upb_strview google_protobuf_MethodDescriptorProto_input_type(const google_protobuf_MethodDescriptorProto *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(12, 24), upb_strview); }
-UPB_INLINE bool google_protobuf_MethodDescriptorProto_has_output_type(const google_protobuf_MethodDescriptorProto *msg) { return _upb_hasbit(msg, 5); }
+UPB_INLINE bool google_protobuf_MethodDescriptorProto_has_output_type(const google_protobuf_MethodDescriptorProto *msg) { return _upb_hasbit(msg, 3); }
 UPB_INLINE upb_strview google_protobuf_MethodDescriptorProto_output_type(const google_protobuf_MethodDescriptorProto *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(20, 40), upb_strview); }
-UPB_INLINE bool google_protobuf_MethodDescriptorProto_has_options(const google_protobuf_MethodDescriptorProto *msg) { return _upb_hasbit(msg, 6); }
+UPB_INLINE bool google_protobuf_MethodDescriptorProto_has_options(const google_protobuf_MethodDescriptorProto *msg) { return _upb_hasbit(msg, 4); }
 UPB_INLINE const google_protobuf_MethodOptions* google_protobuf_MethodDescriptorProto_options(const google_protobuf_MethodDescriptorProto *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(28, 56), const google_protobuf_MethodOptions*); }
-UPB_INLINE bool google_protobuf_MethodDescriptorProto_has_client_streaming(const google_protobuf_MethodDescriptorProto *msg) { return _upb_hasbit(msg, 1); }
+UPB_INLINE bool google_protobuf_MethodDescriptorProto_has_client_streaming(const google_protobuf_MethodDescriptorProto *msg) { return _upb_hasbit(msg, 5); }
 UPB_INLINE bool google_protobuf_MethodDescriptorProto_client_streaming(const google_protobuf_MethodDescriptorProto *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(1, 1), bool); }
-UPB_INLINE bool google_protobuf_MethodDescriptorProto_has_server_streaming(const google_protobuf_MethodDescriptorProto *msg) { return _upb_hasbit(msg, 2); }
+UPB_INLINE bool google_protobuf_MethodDescriptorProto_has_server_streaming(const google_protobuf_MethodDescriptorProto *msg) { return _upb_hasbit(msg, 6); }
 UPB_INLINE bool google_protobuf_MethodDescriptorProto_server_streaming(const google_protobuf_MethodDescriptorProto *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(2, 2), bool); }
 
 UPB_INLINE void google_protobuf_MethodDescriptorProto_set_name(google_protobuf_MethodDescriptorProto *msg, upb_strview value) {
-  _upb_sethas(msg, 3);
+  _upb_sethas(msg, 1);
   *UPB_PTR_AT(msg, UPB_SIZE(4, 8), upb_strview) = value;
 }
 UPB_INLINE void google_protobuf_MethodDescriptorProto_set_input_type(google_protobuf_MethodDescriptorProto *msg, upb_strview value) {
-  _upb_sethas(msg, 4);
+  _upb_sethas(msg, 2);
   *UPB_PTR_AT(msg, UPB_SIZE(12, 24), upb_strview) = value;
 }
 UPB_INLINE void google_protobuf_MethodDescriptorProto_set_output_type(google_protobuf_MethodDescriptorProto *msg, upb_strview value) {
-  _upb_sethas(msg, 5);
+  _upb_sethas(msg, 3);
   *UPB_PTR_AT(msg, UPB_SIZE(20, 40), upb_strview) = value;
 }
 UPB_INLINE void google_protobuf_MethodDescriptorProto_set_options(google_protobuf_MethodDescriptorProto *msg, google_protobuf_MethodOptions* value) {
-  _upb_sethas(msg, 6);
+  _upb_sethas(msg, 4);
   *UPB_PTR_AT(msg, UPB_SIZE(28, 56), google_protobuf_MethodOptions*) = value;
 }
 UPB_INLINE struct google_protobuf_MethodOptions* google_protobuf_MethodDescriptorProto_mutable_options(google_protobuf_MethodDescriptorProto *msg, upb_arena *arena) {
@@ -978,11 +1057,11 @@ UPB_INLINE struct google_protobuf_MethodOptions* google_protobuf_MethodDescripto
   return sub;
 }
 UPB_INLINE void google_protobuf_MethodDescriptorProto_set_client_streaming(google_protobuf_MethodDescriptorProto *msg, bool value) {
-  _upb_sethas(msg, 1);
+  _upb_sethas(msg, 5);
   *UPB_PTR_AT(msg, UPB_SIZE(1, 1), bool) = value;
 }
 UPB_INLINE void google_protobuf_MethodDescriptorProto_set_server_streaming(google_protobuf_MethodDescriptorProto *msg, bool value) {
-  _upb_sethas(msg, 2);
+  _upb_sethas(msg, 6);
   *UPB_PTR_AT(msg, UPB_SIZE(2, 2), bool) = value;
 }
 
@@ -996,143 +1075,149 @@ UPB_INLINE google_protobuf_FileOptions *google_protobuf_FileOptions_parse(const
   google_protobuf_FileOptions *ret = google_protobuf_FileOptions_new(arena);
   return (ret && upb_decode(buf, size, ret, &google_protobuf_FileOptions_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE google_protobuf_FileOptions *google_protobuf_FileOptions_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  google_protobuf_FileOptions *ret = google_protobuf_FileOptions_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &google_protobuf_FileOptions_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *google_protobuf_FileOptions_serialize(const google_protobuf_FileOptions *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &google_protobuf_FileOptions_msginit, arena, len);
 }
 
-UPB_INLINE bool google_protobuf_FileOptions_has_java_package(const google_protobuf_FileOptions *msg) { return _upb_hasbit(msg, 11); }
-UPB_INLINE upb_strview google_protobuf_FileOptions_java_package(const google_protobuf_FileOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(28, 32), upb_strview); }
-UPB_INLINE bool google_protobuf_FileOptions_has_java_outer_classname(const google_protobuf_FileOptions *msg) { return _upb_hasbit(msg, 12); }
-UPB_INLINE upb_strview google_protobuf_FileOptions_java_outer_classname(const google_protobuf_FileOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(36, 48), upb_strview); }
-UPB_INLINE bool google_protobuf_FileOptions_has_optimize_for(const google_protobuf_FileOptions *msg) { return _upb_hasbit(msg, 1); }
-UPB_INLINE int32_t google_protobuf_FileOptions_optimize_for(const google_protobuf_FileOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(8, 8), int32_t); }
-UPB_INLINE bool google_protobuf_FileOptions_has_java_multiple_files(const google_protobuf_FileOptions *msg) { return _upb_hasbit(msg, 2); }
-UPB_INLINE bool google_protobuf_FileOptions_java_multiple_files(const google_protobuf_FileOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(16, 16), bool); }
-UPB_INLINE bool google_protobuf_FileOptions_has_go_package(const google_protobuf_FileOptions *msg) { return _upb_hasbit(msg, 13); }
-UPB_INLINE upb_strview google_protobuf_FileOptions_go_package(const google_protobuf_FileOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(44, 64), upb_strview); }
-UPB_INLINE bool google_protobuf_FileOptions_has_cc_generic_services(const google_protobuf_FileOptions *msg) { return _upb_hasbit(msg, 3); }
-UPB_INLINE bool google_protobuf_FileOptions_cc_generic_services(const google_protobuf_FileOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(17, 17), bool); }
-UPB_INLINE bool google_protobuf_FileOptions_has_java_generic_services(const google_protobuf_FileOptions *msg) { return _upb_hasbit(msg, 4); }
-UPB_INLINE bool google_protobuf_FileOptions_java_generic_services(const google_protobuf_FileOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(18, 18), bool); }
-UPB_INLINE bool google_protobuf_FileOptions_has_py_generic_services(const google_protobuf_FileOptions *msg) { return _upb_hasbit(msg, 5); }
-UPB_INLINE bool google_protobuf_FileOptions_py_generic_services(const google_protobuf_FileOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(19, 19), bool); }
-UPB_INLINE bool google_protobuf_FileOptions_has_java_generate_equals_and_hash(const google_protobuf_FileOptions *msg) { return _upb_hasbit(msg, 6); }
-UPB_INLINE bool google_protobuf_FileOptions_java_generate_equals_and_hash(const google_protobuf_FileOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(20, 20), bool); }
-UPB_INLINE bool google_protobuf_FileOptions_has_deprecated(const google_protobuf_FileOptions *msg) { return _upb_hasbit(msg, 7); }
-UPB_INLINE bool google_protobuf_FileOptions_deprecated(const google_protobuf_FileOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(21, 21), bool); }
-UPB_INLINE bool google_protobuf_FileOptions_has_java_string_check_utf8(const google_protobuf_FileOptions *msg) { return _upb_hasbit(msg, 8); }
-UPB_INLINE bool google_protobuf_FileOptions_java_string_check_utf8(const google_protobuf_FileOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(22, 22), bool); }
-UPB_INLINE bool google_protobuf_FileOptions_has_cc_enable_arenas(const google_protobuf_FileOptions *msg) { return _upb_hasbit(msg, 9); }
-UPB_INLINE bool google_protobuf_FileOptions_cc_enable_arenas(const google_protobuf_FileOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(23, 23), bool); }
-UPB_INLINE bool google_protobuf_FileOptions_has_objc_class_prefix(const google_protobuf_FileOptions *msg) { return _upb_hasbit(msg, 14); }
-UPB_INLINE upb_strview google_protobuf_FileOptions_objc_class_prefix(const google_protobuf_FileOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(52, 80), upb_strview); }
-UPB_INLINE bool google_protobuf_FileOptions_has_csharp_namespace(const google_protobuf_FileOptions *msg) { return _upb_hasbit(msg, 15); }
-UPB_INLINE upb_strview google_protobuf_FileOptions_csharp_namespace(const google_protobuf_FileOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(60, 96), upb_strview); }
-UPB_INLINE bool google_protobuf_FileOptions_has_swift_prefix(const google_protobuf_FileOptions *msg) { return _upb_hasbit(msg, 16); }
-UPB_INLINE upb_strview google_protobuf_FileOptions_swift_prefix(const google_protobuf_FileOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(68, 112), upb_strview); }
-UPB_INLINE bool google_protobuf_FileOptions_has_php_class_prefix(const google_protobuf_FileOptions *msg) { return _upb_hasbit(msg, 17); }
-UPB_INLINE upb_strview google_protobuf_FileOptions_php_class_prefix(const google_protobuf_FileOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(76, 128), upb_strview); }
-UPB_INLINE bool google_protobuf_FileOptions_has_php_namespace(const google_protobuf_FileOptions *msg) { return _upb_hasbit(msg, 18); }
-UPB_INLINE upb_strview google_protobuf_FileOptions_php_namespace(const google_protobuf_FileOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(84, 144), upb_strview); }
-UPB_INLINE bool google_protobuf_FileOptions_has_php_generic_services(const google_protobuf_FileOptions *msg) { return _upb_hasbit(msg, 10); }
-UPB_INLINE bool google_protobuf_FileOptions_php_generic_services(const google_protobuf_FileOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(24, 24), bool); }
+UPB_INLINE bool google_protobuf_FileOptions_has_java_package(const google_protobuf_FileOptions *msg) { return _upb_hasbit(msg, 1); }
+UPB_INLINE upb_strview google_protobuf_FileOptions_java_package(const google_protobuf_FileOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(20, 24), upb_strview); }
+UPB_INLINE bool google_protobuf_FileOptions_has_java_outer_classname(const google_protobuf_FileOptions *msg) { return _upb_hasbit(msg, 2); }
+UPB_INLINE upb_strview google_protobuf_FileOptions_java_outer_classname(const google_protobuf_FileOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(28, 40), upb_strview); }
+UPB_INLINE bool google_protobuf_FileOptions_has_optimize_for(const google_protobuf_FileOptions *msg) { return _upb_hasbit(msg, 3); }
+UPB_INLINE int32_t google_protobuf_FileOptions_optimize_for(const google_protobuf_FileOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(4, 4), int32_t); }
+UPB_INLINE bool google_protobuf_FileOptions_has_java_multiple_files(const google_protobuf_FileOptions *msg) { return _upb_hasbit(msg, 4); }
+UPB_INLINE bool google_protobuf_FileOptions_java_multiple_files(const google_protobuf_FileOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(8, 8), bool); }
+UPB_INLINE bool google_protobuf_FileOptions_has_go_package(const google_protobuf_FileOptions *msg) { return _upb_hasbit(msg, 5); }
+UPB_INLINE upb_strview google_protobuf_FileOptions_go_package(const google_protobuf_FileOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(36, 56), upb_strview); }
+UPB_INLINE bool google_protobuf_FileOptions_has_cc_generic_services(const google_protobuf_FileOptions *msg) { return _upb_hasbit(msg, 6); }
+UPB_INLINE bool google_protobuf_FileOptions_cc_generic_services(const google_protobuf_FileOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(9, 9), bool); }
+UPB_INLINE bool google_protobuf_FileOptions_has_java_generic_services(const google_protobuf_FileOptions *msg) { return _upb_hasbit(msg, 7); }
+UPB_INLINE bool google_protobuf_FileOptions_java_generic_services(const google_protobuf_FileOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(10, 10), bool); }
+UPB_INLINE bool google_protobuf_FileOptions_has_py_generic_services(const google_protobuf_FileOptions *msg) { return _upb_hasbit(msg, 8); }
+UPB_INLINE bool google_protobuf_FileOptions_py_generic_services(const google_protobuf_FileOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(11, 11), bool); }
+UPB_INLINE bool google_protobuf_FileOptions_has_java_generate_equals_and_hash(const google_protobuf_FileOptions *msg) { return _upb_hasbit(msg, 9); }
+UPB_INLINE bool google_protobuf_FileOptions_java_generate_equals_and_hash(const google_protobuf_FileOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(12, 12), bool); }
+UPB_INLINE bool google_protobuf_FileOptions_has_deprecated(const google_protobuf_FileOptions *msg) { return _upb_hasbit(msg, 10); }
+UPB_INLINE bool google_protobuf_FileOptions_deprecated(const google_protobuf_FileOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(13, 13), bool); }
+UPB_INLINE bool google_protobuf_FileOptions_has_java_string_check_utf8(const google_protobuf_FileOptions *msg) { return _upb_hasbit(msg, 11); }
+UPB_INLINE bool google_protobuf_FileOptions_java_string_check_utf8(const google_protobuf_FileOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(14, 14), bool); }
+UPB_INLINE bool google_protobuf_FileOptions_has_cc_enable_arenas(const google_protobuf_FileOptions *msg) { return _upb_hasbit(msg, 12); }
+UPB_INLINE bool google_protobuf_FileOptions_cc_enable_arenas(const google_protobuf_FileOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(15, 15), bool); }
+UPB_INLINE bool google_protobuf_FileOptions_has_objc_class_prefix(const google_protobuf_FileOptions *msg) { return _upb_hasbit(msg, 13); }
+UPB_INLINE upb_strview google_protobuf_FileOptions_objc_class_prefix(const google_protobuf_FileOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(44, 72), upb_strview); }
+UPB_INLINE bool google_protobuf_FileOptions_has_csharp_namespace(const google_protobuf_FileOptions *msg) { return _upb_hasbit(msg, 14); }
+UPB_INLINE upb_strview google_protobuf_FileOptions_csharp_namespace(const google_protobuf_FileOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(52, 88), upb_strview); }
+UPB_INLINE bool google_protobuf_FileOptions_has_swift_prefix(const google_protobuf_FileOptions *msg) { return _upb_hasbit(msg, 15); }
+UPB_INLINE upb_strview google_protobuf_FileOptions_swift_prefix(const google_protobuf_FileOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(60, 104), upb_strview); }
+UPB_INLINE bool google_protobuf_FileOptions_has_php_class_prefix(const google_protobuf_FileOptions *msg) { return _upb_hasbit(msg, 16); }
+UPB_INLINE upb_strview google_protobuf_FileOptions_php_class_prefix(const google_protobuf_FileOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(68, 120), upb_strview); }
+UPB_INLINE bool google_protobuf_FileOptions_has_php_namespace(const google_protobuf_FileOptions *msg) { return _upb_hasbit(msg, 17); }
+UPB_INLINE upb_strview google_protobuf_FileOptions_php_namespace(const google_protobuf_FileOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(76, 136), upb_strview); }
+UPB_INLINE bool google_protobuf_FileOptions_has_php_generic_services(const google_protobuf_FileOptions *msg) { return _upb_hasbit(msg, 18); }
+UPB_INLINE bool google_protobuf_FileOptions_php_generic_services(const google_protobuf_FileOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(16, 16), bool); }
 UPB_INLINE bool google_protobuf_FileOptions_has_php_metadata_namespace(const google_protobuf_FileOptions *msg) { return _upb_hasbit(msg, 19); }
-UPB_INLINE upb_strview google_protobuf_FileOptions_php_metadata_namespace(const google_protobuf_FileOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(92, 160), upb_strview); }
+UPB_INLINE upb_strview google_protobuf_FileOptions_php_metadata_namespace(const google_protobuf_FileOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(84, 152), upb_strview); }
 UPB_INLINE bool google_protobuf_FileOptions_has_ruby_package(const google_protobuf_FileOptions *msg) { return _upb_hasbit(msg, 20); }
-UPB_INLINE upb_strview google_protobuf_FileOptions_ruby_package(const google_protobuf_FileOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(100, 176), upb_strview); }
-UPB_INLINE bool google_protobuf_FileOptions_has_uninterpreted_option(const google_protobuf_FileOptions *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(108, 192)); }
-UPB_INLINE const google_protobuf_UninterpretedOption* const* google_protobuf_FileOptions_uninterpreted_option(const google_protobuf_FileOptions *msg, size_t *len) { return (const google_protobuf_UninterpretedOption* const*)_upb_array_accessor(msg, UPB_SIZE(108, 192), len); }
+UPB_INLINE upb_strview google_protobuf_FileOptions_ruby_package(const google_protobuf_FileOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(92, 168), upb_strview); }
+UPB_INLINE bool google_protobuf_FileOptions_has_uninterpreted_option(const google_protobuf_FileOptions *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(100, 184)); }
+UPB_INLINE const google_protobuf_UninterpretedOption* const* google_protobuf_FileOptions_uninterpreted_option(const google_protobuf_FileOptions *msg, size_t *len) { return (const google_protobuf_UninterpretedOption* const*)_upb_array_accessor(msg, UPB_SIZE(100, 184), len); }
 
 UPB_INLINE void google_protobuf_FileOptions_set_java_package(google_protobuf_FileOptions *msg, upb_strview value) {
-  _upb_sethas(msg, 11);
-  *UPB_PTR_AT(msg, UPB_SIZE(28, 32), upb_strview) = value;
+  _upb_sethas(msg, 1);
+  *UPB_PTR_AT(msg, UPB_SIZE(20, 24), upb_strview) = value;
 }
 UPB_INLINE void google_protobuf_FileOptions_set_java_outer_classname(google_protobuf_FileOptions *msg, upb_strview value) {
-  _upb_sethas(msg, 12);
-  *UPB_PTR_AT(msg, UPB_SIZE(36, 48), upb_strview) = value;
+  _upb_sethas(msg, 2);
+  *UPB_PTR_AT(msg, UPB_SIZE(28, 40), upb_strview) = value;
 }
 UPB_INLINE void google_protobuf_FileOptions_set_optimize_for(google_protobuf_FileOptions *msg, int32_t value) {
-  _upb_sethas(msg, 1);
-  *UPB_PTR_AT(msg, UPB_SIZE(8, 8), int32_t) = value;
+  _upb_sethas(msg, 3);
+  *UPB_PTR_AT(msg, UPB_SIZE(4, 4), int32_t) = value;
 }
 UPB_INLINE void google_protobuf_FileOptions_set_java_multiple_files(google_protobuf_FileOptions *msg, bool value) {
-  _upb_sethas(msg, 2);
-  *UPB_PTR_AT(msg, UPB_SIZE(16, 16), bool) = value;
+  _upb_sethas(msg, 4);
+  *UPB_PTR_AT(msg, UPB_SIZE(8, 8), bool) = value;
 }
 UPB_INLINE void google_protobuf_FileOptions_set_go_package(google_protobuf_FileOptions *msg, upb_strview value) {
-  _upb_sethas(msg, 13);
-  *UPB_PTR_AT(msg, UPB_SIZE(44, 64), upb_strview) = value;
+  _upb_sethas(msg, 5);
+  *UPB_PTR_AT(msg, UPB_SIZE(36, 56), upb_strview) = value;
 }
 UPB_INLINE void google_protobuf_FileOptions_set_cc_generic_services(google_protobuf_FileOptions *msg, bool value) {
-  _upb_sethas(msg, 3);
-  *UPB_PTR_AT(msg, UPB_SIZE(17, 17), bool) = value;
+  _upb_sethas(msg, 6);
+  *UPB_PTR_AT(msg, UPB_SIZE(9, 9), bool) = value;
 }
 UPB_INLINE void google_protobuf_FileOptions_set_java_generic_services(google_protobuf_FileOptions *msg, bool value) {
-  _upb_sethas(msg, 4);
-  *UPB_PTR_AT(msg, UPB_SIZE(18, 18), bool) = value;
+  _upb_sethas(msg, 7);
+  *UPB_PTR_AT(msg, UPB_SIZE(10, 10), bool) = value;
 }
 UPB_INLINE void google_protobuf_FileOptions_set_py_generic_services(google_protobuf_FileOptions *msg, bool value) {
-  _upb_sethas(msg, 5);
-  *UPB_PTR_AT(msg, UPB_SIZE(19, 19), bool) = value;
+  _upb_sethas(msg, 8);
+  *UPB_PTR_AT(msg, UPB_SIZE(11, 11), bool) = value;
 }
 UPB_INLINE void google_protobuf_FileOptions_set_java_generate_equals_and_hash(google_protobuf_FileOptions *msg, bool value) {
-  _upb_sethas(msg, 6);
-  *UPB_PTR_AT(msg, UPB_SIZE(20, 20), bool) = value;
+  _upb_sethas(msg, 9);
+  *UPB_PTR_AT(msg, UPB_SIZE(12, 12), bool) = value;
 }
 UPB_INLINE void google_protobuf_FileOptions_set_deprecated(google_protobuf_FileOptions *msg, bool value) {
-  _upb_sethas(msg, 7);
-  *UPB_PTR_AT(msg, UPB_SIZE(21, 21), bool) = value;
+  _upb_sethas(msg, 10);
+  *UPB_PTR_AT(msg, UPB_SIZE(13, 13), bool) = value;
 }
 UPB_INLINE void google_protobuf_FileOptions_set_java_string_check_utf8(google_protobuf_FileOptions *msg, bool value) {
-  _upb_sethas(msg, 8);
-  *UPB_PTR_AT(msg, UPB_SIZE(22, 22), bool) = value;
+  _upb_sethas(msg, 11);
+  *UPB_PTR_AT(msg, UPB_SIZE(14, 14), bool) = value;
 }
 UPB_INLINE void google_protobuf_FileOptions_set_cc_enable_arenas(google_protobuf_FileOptions *msg, bool value) {
-  _upb_sethas(msg, 9);
-  *UPB_PTR_AT(msg, UPB_SIZE(23, 23), bool) = value;
+  _upb_sethas(msg, 12);
+  *UPB_PTR_AT(msg, UPB_SIZE(15, 15), bool) = value;
 }
 UPB_INLINE void google_protobuf_FileOptions_set_objc_class_prefix(google_protobuf_FileOptions *msg, upb_strview value) {
-  _upb_sethas(msg, 14);
-  *UPB_PTR_AT(msg, UPB_SIZE(52, 80), upb_strview) = value;
+  _upb_sethas(msg, 13);
+  *UPB_PTR_AT(msg, UPB_SIZE(44, 72), upb_strview) = value;
 }
 UPB_INLINE void google_protobuf_FileOptions_set_csharp_namespace(google_protobuf_FileOptions *msg, upb_strview value) {
-  _upb_sethas(msg, 15);
-  *UPB_PTR_AT(msg, UPB_SIZE(60, 96), upb_strview) = value;
+  _upb_sethas(msg, 14);
+  *UPB_PTR_AT(msg, UPB_SIZE(52, 88), upb_strview) = value;
 }
 UPB_INLINE void google_protobuf_FileOptions_set_swift_prefix(google_protobuf_FileOptions *msg, upb_strview value) {
-  _upb_sethas(msg, 16);
-  *UPB_PTR_AT(msg, UPB_SIZE(68, 112), upb_strview) = value;
+  _upb_sethas(msg, 15);
+  *UPB_PTR_AT(msg, UPB_SIZE(60, 104), upb_strview) = value;
 }
 UPB_INLINE void google_protobuf_FileOptions_set_php_class_prefix(google_protobuf_FileOptions *msg, upb_strview value) {
-  _upb_sethas(msg, 17);
-  *UPB_PTR_AT(msg, UPB_SIZE(76, 128), upb_strview) = value;
+  _upb_sethas(msg, 16);
+  *UPB_PTR_AT(msg, UPB_SIZE(68, 120), upb_strview) = value;
 }
 UPB_INLINE void google_protobuf_FileOptions_set_php_namespace(google_protobuf_FileOptions *msg, upb_strview value) {
-  _upb_sethas(msg, 18);
-  *UPB_PTR_AT(msg, UPB_SIZE(84, 144), upb_strview) = value;
+  _upb_sethas(msg, 17);
+  *UPB_PTR_AT(msg, UPB_SIZE(76, 136), upb_strview) = value;
 }
 UPB_INLINE void google_protobuf_FileOptions_set_php_generic_services(google_protobuf_FileOptions *msg, bool value) {
-  _upb_sethas(msg, 10);
-  *UPB_PTR_AT(msg, UPB_SIZE(24, 24), bool) = value;
+  _upb_sethas(msg, 18);
+  *UPB_PTR_AT(msg, UPB_SIZE(16, 16), bool) = value;
 }
 UPB_INLINE void google_protobuf_FileOptions_set_php_metadata_namespace(google_protobuf_FileOptions *msg, upb_strview value) {
   _upb_sethas(msg, 19);
-  *UPB_PTR_AT(msg, UPB_SIZE(92, 160), upb_strview) = value;
+  *UPB_PTR_AT(msg, UPB_SIZE(84, 152), upb_strview) = value;
 }
 UPB_INLINE void google_protobuf_FileOptions_set_ruby_package(google_protobuf_FileOptions *msg, upb_strview value) {
   _upb_sethas(msg, 20);
-  *UPB_PTR_AT(msg, UPB_SIZE(100, 176), upb_strview) = value;
+  *UPB_PTR_AT(msg, UPB_SIZE(92, 168), upb_strview) = value;
 }
 UPB_INLINE google_protobuf_UninterpretedOption** google_protobuf_FileOptions_mutable_uninterpreted_option(google_protobuf_FileOptions *msg, size_t *len) {
-  return (google_protobuf_UninterpretedOption**)_upb_array_mutable_accessor(msg, UPB_SIZE(108, 192), len);
+  return (google_protobuf_UninterpretedOption**)_upb_array_mutable_accessor(msg, UPB_SIZE(100, 184), len);
 }
 UPB_INLINE google_protobuf_UninterpretedOption** google_protobuf_FileOptions_resize_uninterpreted_option(google_protobuf_FileOptions *msg, size_t len, upb_arena *arena) {
-  return (google_protobuf_UninterpretedOption**)_upb_array_resize_accessor(msg, UPB_SIZE(108, 192), len, UPB_TYPE_MESSAGE, arena);
+  return (google_protobuf_UninterpretedOption**)_upb_array_resize_accessor2(msg, UPB_SIZE(100, 184), len, UPB_SIZE(2, 3), arena);
 }
 UPB_INLINE struct google_protobuf_UninterpretedOption* google_protobuf_FileOptions_add_uninterpreted_option(google_protobuf_FileOptions *msg, upb_arena *arena) {
   struct google_protobuf_UninterpretedOption* sub = (struct google_protobuf_UninterpretedOption*)_upb_msg_new(&google_protobuf_UninterpretedOption_msginit, arena);
-  bool ok = _upb_array_append_accessor(
-      msg, UPB_SIZE(108, 192), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena);
+  bool ok = _upb_array_append_accessor2(
+      msg, UPB_SIZE(100, 184), UPB_SIZE(2, 3), &sub, arena);
   if (!ok) return NULL;
   return sub;
 }
@@ -1147,6 +1232,12 @@ UPB_INLINE google_protobuf_MessageOptions *google_protobuf_MessageOptions_parse(
   google_protobuf_MessageOptions *ret = google_protobuf_MessageOptions_new(arena);
   return (ret && upb_decode(buf, size, ret, &google_protobuf_MessageOptions_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE google_protobuf_MessageOptions *google_protobuf_MessageOptions_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  google_protobuf_MessageOptions *ret = google_protobuf_MessageOptions_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &google_protobuf_MessageOptions_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *google_protobuf_MessageOptions_serialize(const google_protobuf_MessageOptions *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &google_protobuf_MessageOptions_msginit, arena, len);
 }
@@ -1182,12 +1273,12 @@ UPB_INLINE google_protobuf_UninterpretedOption** google_protobuf_MessageOptions_
   return (google_protobuf_UninterpretedOption**)_upb_array_mutable_accessor(msg, UPB_SIZE(8, 8), len);
 }
 UPB_INLINE google_protobuf_UninterpretedOption** google_protobuf_MessageOptions_resize_uninterpreted_option(google_protobuf_MessageOptions *msg, size_t len, upb_arena *arena) {
-  return (google_protobuf_UninterpretedOption**)_upb_array_resize_accessor(msg, UPB_SIZE(8, 8), len, UPB_TYPE_MESSAGE, arena);
+  return (google_protobuf_UninterpretedOption**)_upb_array_resize_accessor2(msg, UPB_SIZE(8, 8), len, UPB_SIZE(2, 3), arena);
 }
 UPB_INLINE struct google_protobuf_UninterpretedOption* google_protobuf_MessageOptions_add_uninterpreted_option(google_protobuf_MessageOptions *msg, upb_arena *arena) {
   struct google_protobuf_UninterpretedOption* sub = (struct google_protobuf_UninterpretedOption*)_upb_msg_new(&google_protobuf_UninterpretedOption_msginit, arena);
-  bool ok = _upb_array_append_accessor(
-      msg, UPB_SIZE(8, 8), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena);
+  bool ok = _upb_array_append_accessor2(
+      msg, UPB_SIZE(8, 8), UPB_SIZE(2, 3), &sub, arena);
   if (!ok) return NULL;
   return sub;
 }
@@ -1202,59 +1293,65 @@ UPB_INLINE google_protobuf_FieldOptions *google_protobuf_FieldOptions_parse(cons
   google_protobuf_FieldOptions *ret = google_protobuf_FieldOptions_new(arena);
   return (ret && upb_decode(buf, size, ret, &google_protobuf_FieldOptions_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE google_protobuf_FieldOptions *google_protobuf_FieldOptions_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  google_protobuf_FieldOptions *ret = google_protobuf_FieldOptions_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &google_protobuf_FieldOptions_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *google_protobuf_FieldOptions_serialize(const google_protobuf_FieldOptions *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &google_protobuf_FieldOptions_msginit, arena, len);
 }
 
 UPB_INLINE bool google_protobuf_FieldOptions_has_ctype(const google_protobuf_FieldOptions *msg) { return _upb_hasbit(msg, 1); }
-UPB_INLINE int32_t google_protobuf_FieldOptions_ctype(const google_protobuf_FieldOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(8, 8), int32_t); }
-UPB_INLINE bool google_protobuf_FieldOptions_has_packed(const google_protobuf_FieldOptions *msg) { return _upb_hasbit(msg, 3); }
-UPB_INLINE bool google_protobuf_FieldOptions_packed(const google_protobuf_FieldOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(24, 24), bool); }
-UPB_INLINE bool google_protobuf_FieldOptions_has_deprecated(const google_protobuf_FieldOptions *msg) { return _upb_hasbit(msg, 4); }
-UPB_INLINE bool google_protobuf_FieldOptions_deprecated(const google_protobuf_FieldOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(25, 25), bool); }
-UPB_INLINE bool google_protobuf_FieldOptions_has_lazy(const google_protobuf_FieldOptions *msg) { return _upb_hasbit(msg, 5); }
-UPB_INLINE bool google_protobuf_FieldOptions_lazy(const google_protobuf_FieldOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(26, 26), bool); }
-UPB_INLINE bool google_protobuf_FieldOptions_has_jstype(const google_protobuf_FieldOptions *msg) { return _upb_hasbit(msg, 2); }
-UPB_INLINE int32_t google_protobuf_FieldOptions_jstype(const google_protobuf_FieldOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(16, 16), int32_t); }
+UPB_INLINE int32_t google_protobuf_FieldOptions_ctype(const google_protobuf_FieldOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(4, 4), int32_t); }
+UPB_INLINE bool google_protobuf_FieldOptions_has_packed(const google_protobuf_FieldOptions *msg) { return _upb_hasbit(msg, 2); }
+UPB_INLINE bool google_protobuf_FieldOptions_packed(const google_protobuf_FieldOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(12, 12), bool); }
+UPB_INLINE bool google_protobuf_FieldOptions_has_deprecated(const google_protobuf_FieldOptions *msg) { return _upb_hasbit(msg, 3); }
+UPB_INLINE bool google_protobuf_FieldOptions_deprecated(const google_protobuf_FieldOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(13, 13), bool); }
+UPB_INLINE bool google_protobuf_FieldOptions_has_lazy(const google_protobuf_FieldOptions *msg) { return _upb_hasbit(msg, 4); }
+UPB_INLINE bool google_protobuf_FieldOptions_lazy(const google_protobuf_FieldOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(14, 14), bool); }
+UPB_INLINE bool google_protobuf_FieldOptions_has_jstype(const google_protobuf_FieldOptions *msg) { return _upb_hasbit(msg, 5); }
+UPB_INLINE int32_t google_protobuf_FieldOptions_jstype(const google_protobuf_FieldOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(8, 8), int32_t); }
 UPB_INLINE bool google_protobuf_FieldOptions_has_weak(const google_protobuf_FieldOptions *msg) { return _upb_hasbit(msg, 6); }
-UPB_INLINE bool google_protobuf_FieldOptions_weak(const google_protobuf_FieldOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(27, 27), bool); }
-UPB_INLINE bool google_protobuf_FieldOptions_has_uninterpreted_option(const google_protobuf_FieldOptions *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(28, 32)); }
-UPB_INLINE const google_protobuf_UninterpretedOption* const* google_protobuf_FieldOptions_uninterpreted_option(const google_protobuf_FieldOptions *msg, size_t *len) { return (const google_protobuf_UninterpretedOption* const*)_upb_array_accessor(msg, UPB_SIZE(28, 32), len); }
+UPB_INLINE bool google_protobuf_FieldOptions_weak(const google_protobuf_FieldOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(15, 15), bool); }
+UPB_INLINE bool google_protobuf_FieldOptions_has_uninterpreted_option(const google_protobuf_FieldOptions *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(16, 16)); }
+UPB_INLINE const google_protobuf_UninterpretedOption* const* google_protobuf_FieldOptions_uninterpreted_option(const google_protobuf_FieldOptions *msg, size_t *len) { return (const google_protobuf_UninterpretedOption* const*)_upb_array_accessor(msg, UPB_SIZE(16, 16), len); }
 
 UPB_INLINE void google_protobuf_FieldOptions_set_ctype(google_protobuf_FieldOptions *msg, int32_t value) {
   _upb_sethas(msg, 1);
-  *UPB_PTR_AT(msg, UPB_SIZE(8, 8), int32_t) = value;
+  *UPB_PTR_AT(msg, UPB_SIZE(4, 4), int32_t) = value;
 }
 UPB_INLINE void google_protobuf_FieldOptions_set_packed(google_protobuf_FieldOptions *msg, bool value) {
-  _upb_sethas(msg, 3);
-  *UPB_PTR_AT(msg, UPB_SIZE(24, 24), bool) = value;
+  _upb_sethas(msg, 2);
+  *UPB_PTR_AT(msg, UPB_SIZE(12, 12), bool) = value;
 }
 UPB_INLINE void google_protobuf_FieldOptions_set_deprecated(google_protobuf_FieldOptions *msg, bool value) {
-  _upb_sethas(msg, 4);
-  *UPB_PTR_AT(msg, UPB_SIZE(25, 25), bool) = value;
+  _upb_sethas(msg, 3);
+  *UPB_PTR_AT(msg, UPB_SIZE(13, 13), bool) = value;
 }
 UPB_INLINE void google_protobuf_FieldOptions_set_lazy(google_protobuf_FieldOptions *msg, bool value) {
-  _upb_sethas(msg, 5);
-  *UPB_PTR_AT(msg, UPB_SIZE(26, 26), bool) = value;
+  _upb_sethas(msg, 4);
+  *UPB_PTR_AT(msg, UPB_SIZE(14, 14), bool) = value;
 }
 UPB_INLINE void google_protobuf_FieldOptions_set_jstype(google_protobuf_FieldOptions *msg, int32_t value) {
-  _upb_sethas(msg, 2);
-  *UPB_PTR_AT(msg, UPB_SIZE(16, 16), int32_t) = value;
+  _upb_sethas(msg, 5);
+  *UPB_PTR_AT(msg, UPB_SIZE(8, 8), int32_t) = value;
 }
 UPB_INLINE void google_protobuf_FieldOptions_set_weak(google_protobuf_FieldOptions *msg, bool value) {
   _upb_sethas(msg, 6);
-  *UPB_PTR_AT(msg, UPB_SIZE(27, 27), bool) = value;
+  *UPB_PTR_AT(msg, UPB_SIZE(15, 15), bool) = value;
 }
 UPB_INLINE google_protobuf_UninterpretedOption** google_protobuf_FieldOptions_mutable_uninterpreted_option(google_protobuf_FieldOptions *msg, size_t *len) {
-  return (google_protobuf_UninterpretedOption**)_upb_array_mutable_accessor(msg, UPB_SIZE(28, 32), len);
+  return (google_protobuf_UninterpretedOption**)_upb_array_mutable_accessor(msg, UPB_SIZE(16, 16), len);
 }
 UPB_INLINE google_protobuf_UninterpretedOption** google_protobuf_FieldOptions_resize_uninterpreted_option(google_protobuf_FieldOptions *msg, size_t len, upb_arena *arena) {
-  return (google_protobuf_UninterpretedOption**)_upb_array_resize_accessor(msg, UPB_SIZE(28, 32), len, UPB_TYPE_MESSAGE, arena);
+  return (google_protobuf_UninterpretedOption**)_upb_array_resize_accessor2(msg, UPB_SIZE(16, 16), len, UPB_SIZE(2, 3), arena);
 }
 UPB_INLINE struct google_protobuf_UninterpretedOption* google_protobuf_FieldOptions_add_uninterpreted_option(google_protobuf_FieldOptions *msg, upb_arena *arena) {
   struct google_protobuf_UninterpretedOption* sub = (struct google_protobuf_UninterpretedOption*)_upb_msg_new(&google_protobuf_UninterpretedOption_msginit, arena);
-  bool ok = _upb_array_append_accessor(
-      msg, UPB_SIZE(28, 32), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena);
+  bool ok = _upb_array_append_accessor2(
+      msg, UPB_SIZE(16, 16), UPB_SIZE(2, 3), &sub, arena);
   if (!ok) return NULL;
   return sub;
 }
@@ -1269,6 +1366,12 @@ UPB_INLINE google_protobuf_OneofOptions *google_protobuf_OneofOptions_parse(cons
   google_protobuf_OneofOptions *ret = google_protobuf_OneofOptions_new(arena);
   return (ret && upb_decode(buf, size, ret, &google_protobuf_OneofOptions_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE google_protobuf_OneofOptions *google_protobuf_OneofOptions_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  google_protobuf_OneofOptions *ret = google_protobuf_OneofOptions_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &google_protobuf_OneofOptions_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *google_protobuf_OneofOptions_serialize(const google_protobuf_OneofOptions *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &google_protobuf_OneofOptions_msginit, arena, len);
 }
@@ -1280,12 +1383,12 @@ UPB_INLINE google_protobuf_UninterpretedOption** google_protobuf_OneofOptions_mu
   return (google_protobuf_UninterpretedOption**)_upb_array_mutable_accessor(msg, UPB_SIZE(0, 0), len);
 }
 UPB_INLINE google_protobuf_UninterpretedOption** google_protobuf_OneofOptions_resize_uninterpreted_option(google_protobuf_OneofOptions *msg, size_t len, upb_arena *arena) {
-  return (google_protobuf_UninterpretedOption**)_upb_array_resize_accessor(msg, UPB_SIZE(0, 0), len, UPB_TYPE_MESSAGE, arena);
+  return (google_protobuf_UninterpretedOption**)_upb_array_resize_accessor2(msg, UPB_SIZE(0, 0), len, UPB_SIZE(2, 3), arena);
 }
 UPB_INLINE struct google_protobuf_UninterpretedOption* google_protobuf_OneofOptions_add_uninterpreted_option(google_protobuf_OneofOptions *msg, upb_arena *arena) {
   struct google_protobuf_UninterpretedOption* sub = (struct google_protobuf_UninterpretedOption*)_upb_msg_new(&google_protobuf_UninterpretedOption_msginit, arena);
-  bool ok = _upb_array_append_accessor(
-      msg, UPB_SIZE(0, 0), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena);
+  bool ok = _upb_array_append_accessor2(
+      msg, UPB_SIZE(0, 0), UPB_SIZE(2, 3), &sub, arena);
   if (!ok) return NULL;
   return sub;
 }
@@ -1300,6 +1403,12 @@ UPB_INLINE google_protobuf_EnumOptions *google_protobuf_EnumOptions_parse(const
   google_protobuf_EnumOptions *ret = google_protobuf_EnumOptions_new(arena);
   return (ret && upb_decode(buf, size, ret, &google_protobuf_EnumOptions_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE google_protobuf_EnumOptions *google_protobuf_EnumOptions_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  google_protobuf_EnumOptions *ret = google_protobuf_EnumOptions_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &google_protobuf_EnumOptions_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *google_protobuf_EnumOptions_serialize(const google_protobuf_EnumOptions *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &google_protobuf_EnumOptions_msginit, arena, len);
 }
@@ -1323,12 +1432,12 @@ UPB_INLINE google_protobuf_UninterpretedOption** google_protobuf_EnumOptions_mut
   return (google_protobuf_UninterpretedOption**)_upb_array_mutable_accessor(msg, UPB_SIZE(4, 8), len);
 }
 UPB_INLINE google_protobuf_UninterpretedOption** google_protobuf_EnumOptions_resize_uninterpreted_option(google_protobuf_EnumOptions *msg, size_t len, upb_arena *arena) {
-  return (google_protobuf_UninterpretedOption**)_upb_array_resize_accessor(msg, UPB_SIZE(4, 8), len, UPB_TYPE_MESSAGE, arena);
+  return (google_protobuf_UninterpretedOption**)_upb_array_resize_accessor2(msg, UPB_SIZE(4, 8), len, UPB_SIZE(2, 3), arena);
 }
 UPB_INLINE struct google_protobuf_UninterpretedOption* google_protobuf_EnumOptions_add_uninterpreted_option(google_protobuf_EnumOptions *msg, upb_arena *arena) {
   struct google_protobuf_UninterpretedOption* sub = (struct google_protobuf_UninterpretedOption*)_upb_msg_new(&google_protobuf_UninterpretedOption_msginit, arena);
-  bool ok = _upb_array_append_accessor(
-      msg, UPB_SIZE(4, 8), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena);
+  bool ok = _upb_array_append_accessor2(
+      msg, UPB_SIZE(4, 8), UPB_SIZE(2, 3), &sub, arena);
   if (!ok) return NULL;
   return sub;
 }
@@ -1343,6 +1452,12 @@ UPB_INLINE google_protobuf_EnumValueOptions *google_protobuf_EnumValueOptions_pa
   google_protobuf_EnumValueOptions *ret = google_protobuf_EnumValueOptions_new(arena);
   return (ret && upb_decode(buf, size, ret, &google_protobuf_EnumValueOptions_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE google_protobuf_EnumValueOptions *google_protobuf_EnumValueOptions_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  google_protobuf_EnumValueOptions *ret = google_protobuf_EnumValueOptions_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &google_protobuf_EnumValueOptions_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *google_protobuf_EnumValueOptions_serialize(const google_protobuf_EnumValueOptions *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &google_protobuf_EnumValueOptions_msginit, arena, len);
 }
@@ -1360,12 +1475,12 @@ UPB_INLINE google_protobuf_UninterpretedOption** google_protobuf_EnumValueOption
   return (google_protobuf_UninterpretedOption**)_upb_array_mutable_accessor(msg, UPB_SIZE(4, 8), len);
 }
 UPB_INLINE google_protobuf_UninterpretedOption** google_protobuf_EnumValueOptions_resize_uninterpreted_option(google_protobuf_EnumValueOptions *msg, size_t len, upb_arena *arena) {
-  return (google_protobuf_UninterpretedOption**)_upb_array_resize_accessor(msg, UPB_SIZE(4, 8), len, UPB_TYPE_MESSAGE, arena);
+  return (google_protobuf_UninterpretedOption**)_upb_array_resize_accessor2(msg, UPB_SIZE(4, 8), len, UPB_SIZE(2, 3), arena);
 }
 UPB_INLINE struct google_protobuf_UninterpretedOption* google_protobuf_EnumValueOptions_add_uninterpreted_option(google_protobuf_EnumValueOptions *msg, upb_arena *arena) {
   struct google_protobuf_UninterpretedOption* sub = (struct google_protobuf_UninterpretedOption*)_upb_msg_new(&google_protobuf_UninterpretedOption_msginit, arena);
-  bool ok = _upb_array_append_accessor(
-      msg, UPB_SIZE(4, 8), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena);
+  bool ok = _upb_array_append_accessor2(
+      msg, UPB_SIZE(4, 8), UPB_SIZE(2, 3), &sub, arena);
   if (!ok) return NULL;
   return sub;
 }
@@ -1380,6 +1495,12 @@ UPB_INLINE google_protobuf_ServiceOptions *google_protobuf_ServiceOptions_parse(
   google_protobuf_ServiceOptions *ret = google_protobuf_ServiceOptions_new(arena);
   return (ret && upb_decode(buf, size, ret, &google_protobuf_ServiceOptions_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE google_protobuf_ServiceOptions *google_protobuf_ServiceOptions_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  google_protobuf_ServiceOptions *ret = google_protobuf_ServiceOptions_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &google_protobuf_ServiceOptions_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *google_protobuf_ServiceOptions_serialize(const google_protobuf_ServiceOptions *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &google_protobuf_ServiceOptions_msginit, arena, len);
 }
@@ -1397,12 +1518,12 @@ UPB_INLINE google_protobuf_UninterpretedOption** google_protobuf_ServiceOptions_
   return (google_protobuf_UninterpretedOption**)_upb_array_mutable_accessor(msg, UPB_SIZE(4, 8), len);
 }
 UPB_INLINE google_protobuf_UninterpretedOption** google_protobuf_ServiceOptions_resize_uninterpreted_option(google_protobuf_ServiceOptions *msg, size_t len, upb_arena *arena) {
-  return (google_protobuf_UninterpretedOption**)_upb_array_resize_accessor(msg, UPB_SIZE(4, 8), len, UPB_TYPE_MESSAGE, arena);
+  return (google_protobuf_UninterpretedOption**)_upb_array_resize_accessor2(msg, UPB_SIZE(4, 8), len, UPB_SIZE(2, 3), arena);
 }
 UPB_INLINE struct google_protobuf_UninterpretedOption* google_protobuf_ServiceOptions_add_uninterpreted_option(google_protobuf_ServiceOptions *msg, upb_arena *arena) {
   struct google_protobuf_UninterpretedOption* sub = (struct google_protobuf_UninterpretedOption*)_upb_msg_new(&google_protobuf_UninterpretedOption_msginit, arena);
-  bool ok = _upb_array_append_accessor(
-      msg, UPB_SIZE(4, 8), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena);
+  bool ok = _upb_array_append_accessor2(
+      msg, UPB_SIZE(4, 8), UPB_SIZE(2, 3), &sub, arena);
   if (!ok) return NULL;
   return sub;
 }
@@ -1417,35 +1538,41 @@ UPB_INLINE google_protobuf_MethodOptions *google_protobuf_MethodOptions_parse(co
   google_protobuf_MethodOptions *ret = google_protobuf_MethodOptions_new(arena);
   return (ret && upb_decode(buf, size, ret, &google_protobuf_MethodOptions_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE google_protobuf_MethodOptions *google_protobuf_MethodOptions_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  google_protobuf_MethodOptions *ret = google_protobuf_MethodOptions_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &google_protobuf_MethodOptions_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *google_protobuf_MethodOptions_serialize(const google_protobuf_MethodOptions *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &google_protobuf_MethodOptions_msginit, arena, len);
 }
 
-UPB_INLINE bool google_protobuf_MethodOptions_has_deprecated(const google_protobuf_MethodOptions *msg) { return _upb_hasbit(msg, 2); }
-UPB_INLINE bool google_protobuf_MethodOptions_deprecated(const google_protobuf_MethodOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(16, 16), bool); }
-UPB_INLINE bool google_protobuf_MethodOptions_has_idempotency_level(const google_protobuf_MethodOptions *msg) { return _upb_hasbit(msg, 1); }
-UPB_INLINE int32_t google_protobuf_MethodOptions_idempotency_level(const google_protobuf_MethodOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(8, 8), int32_t); }
-UPB_INLINE bool google_protobuf_MethodOptions_has_uninterpreted_option(const google_protobuf_MethodOptions *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(20, 24)); }
-UPB_INLINE const google_protobuf_UninterpretedOption* const* google_protobuf_MethodOptions_uninterpreted_option(const google_protobuf_MethodOptions *msg, size_t *len) { return (const google_protobuf_UninterpretedOption* const*)_upb_array_accessor(msg, UPB_SIZE(20, 24), len); }
+UPB_INLINE bool google_protobuf_MethodOptions_has_deprecated(const google_protobuf_MethodOptions *msg) { return _upb_hasbit(msg, 1); }
+UPB_INLINE bool google_protobuf_MethodOptions_deprecated(const google_protobuf_MethodOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(8, 8), bool); }
+UPB_INLINE bool google_protobuf_MethodOptions_has_idempotency_level(const google_protobuf_MethodOptions *msg) { return _upb_hasbit(msg, 2); }
+UPB_INLINE int32_t google_protobuf_MethodOptions_idempotency_level(const google_protobuf_MethodOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(4, 4), int32_t); }
+UPB_INLINE bool google_protobuf_MethodOptions_has_uninterpreted_option(const google_protobuf_MethodOptions *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(12, 16)); }
+UPB_INLINE const google_protobuf_UninterpretedOption* const* google_protobuf_MethodOptions_uninterpreted_option(const google_protobuf_MethodOptions *msg, size_t *len) { return (const google_protobuf_UninterpretedOption* const*)_upb_array_accessor(msg, UPB_SIZE(12, 16), len); }
 
 UPB_INLINE void google_protobuf_MethodOptions_set_deprecated(google_protobuf_MethodOptions *msg, bool value) {
-  _upb_sethas(msg, 2);
-  *UPB_PTR_AT(msg, UPB_SIZE(16, 16), bool) = value;
+  _upb_sethas(msg, 1);
+  *UPB_PTR_AT(msg, UPB_SIZE(8, 8), bool) = value;
 }
 UPB_INLINE void google_protobuf_MethodOptions_set_idempotency_level(google_protobuf_MethodOptions *msg, int32_t value) {
-  _upb_sethas(msg, 1);
-  *UPB_PTR_AT(msg, UPB_SIZE(8, 8), int32_t) = value;
+  _upb_sethas(msg, 2);
+  *UPB_PTR_AT(msg, UPB_SIZE(4, 4), int32_t) = value;
 }
 UPB_INLINE google_protobuf_UninterpretedOption** google_protobuf_MethodOptions_mutable_uninterpreted_option(google_protobuf_MethodOptions *msg, size_t *len) {
-  return (google_protobuf_UninterpretedOption**)_upb_array_mutable_accessor(msg, UPB_SIZE(20, 24), len);
+  return (google_protobuf_UninterpretedOption**)_upb_array_mutable_accessor(msg, UPB_SIZE(12, 16), len);
 }
 UPB_INLINE google_protobuf_UninterpretedOption** google_protobuf_MethodOptions_resize_uninterpreted_option(google_protobuf_MethodOptions *msg, size_t len, upb_arena *arena) {
-  return (google_protobuf_UninterpretedOption**)_upb_array_resize_accessor(msg, UPB_SIZE(20, 24), len, UPB_TYPE_MESSAGE, arena);
+  return (google_protobuf_UninterpretedOption**)_upb_array_resize_accessor2(msg, UPB_SIZE(12, 16), len, UPB_SIZE(2, 3), arena);
 }
 UPB_INLINE struct google_protobuf_UninterpretedOption* google_protobuf_MethodOptions_add_uninterpreted_option(google_protobuf_MethodOptions *msg, upb_arena *arena) {
   struct google_protobuf_UninterpretedOption* sub = (struct google_protobuf_UninterpretedOption*)_upb_msg_new(&google_protobuf_UninterpretedOption_msginit, arena);
-  bool ok = _upb_array_append_accessor(
-      msg, UPB_SIZE(20, 24), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena);
+  bool ok = _upb_array_append_accessor2(
+      msg, UPB_SIZE(12, 16), UPB_SIZE(2, 3), &sub, arena);
   if (!ok) return NULL;
   return sub;
 }
@@ -1460,19 +1587,25 @@ UPB_INLINE google_protobuf_UninterpretedOption *google_protobuf_UninterpretedOpt
   google_protobuf_UninterpretedOption *ret = google_protobuf_UninterpretedOption_new(arena);
   return (ret && upb_decode(buf, size, ret, &google_protobuf_UninterpretedOption_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE google_protobuf_UninterpretedOption *google_protobuf_UninterpretedOption_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  google_protobuf_UninterpretedOption *ret = google_protobuf_UninterpretedOption_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &google_protobuf_UninterpretedOption_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *google_protobuf_UninterpretedOption_serialize(const google_protobuf_UninterpretedOption *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &google_protobuf_UninterpretedOption_msginit, arena, len);
 }
 
 UPB_INLINE bool google_protobuf_UninterpretedOption_has_name(const google_protobuf_UninterpretedOption *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(56, 80)); }
 UPB_INLINE const google_protobuf_UninterpretedOption_NamePart* const* google_protobuf_UninterpretedOption_name(const google_protobuf_UninterpretedOption *msg, size_t *len) { return (const google_protobuf_UninterpretedOption_NamePart* const*)_upb_array_accessor(msg, UPB_SIZE(56, 80), len); }
-UPB_INLINE bool google_protobuf_UninterpretedOption_has_identifier_value(const google_protobuf_UninterpretedOption *msg) { return _upb_hasbit(msg, 4); }
+UPB_INLINE bool google_protobuf_UninterpretedOption_has_identifier_value(const google_protobuf_UninterpretedOption *msg) { return _upb_hasbit(msg, 1); }
 UPB_INLINE upb_strview google_protobuf_UninterpretedOption_identifier_value(const google_protobuf_UninterpretedOption *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(32, 32), upb_strview); }
-UPB_INLINE bool google_protobuf_UninterpretedOption_has_positive_int_value(const google_protobuf_UninterpretedOption *msg) { return _upb_hasbit(msg, 1); }
+UPB_INLINE bool google_protobuf_UninterpretedOption_has_positive_int_value(const google_protobuf_UninterpretedOption *msg) { return _upb_hasbit(msg, 2); }
 UPB_INLINE uint64_t google_protobuf_UninterpretedOption_positive_int_value(const google_protobuf_UninterpretedOption *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(8, 8), uint64_t); }
-UPB_INLINE bool google_protobuf_UninterpretedOption_has_negative_int_value(const google_protobuf_UninterpretedOption *msg) { return _upb_hasbit(msg, 2); }
+UPB_INLINE bool google_protobuf_UninterpretedOption_has_negative_int_value(const google_protobuf_UninterpretedOption *msg) { return _upb_hasbit(msg, 3); }
 UPB_INLINE int64_t google_protobuf_UninterpretedOption_negative_int_value(const google_protobuf_UninterpretedOption *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(16, 16), int64_t); }
-UPB_INLINE bool google_protobuf_UninterpretedOption_has_double_value(const google_protobuf_UninterpretedOption *msg) { return _upb_hasbit(msg, 3); }
+UPB_INLINE bool google_protobuf_UninterpretedOption_has_double_value(const google_protobuf_UninterpretedOption *msg) { return _upb_hasbit(msg, 4); }
 UPB_INLINE double google_protobuf_UninterpretedOption_double_value(const google_protobuf_UninterpretedOption *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(24, 24), double); }
 UPB_INLINE bool google_protobuf_UninterpretedOption_has_string_value(const google_protobuf_UninterpretedOption *msg) { return _upb_hasbit(msg, 5); }
 UPB_INLINE upb_strview google_protobuf_UninterpretedOption_string_value(const google_protobuf_UninterpretedOption *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(40, 48), upb_strview); }
@@ -1483,29 +1616,29 @@ UPB_INLINE google_protobuf_UninterpretedOption_NamePart** google_protobuf_Uninte
   return (google_protobuf_UninterpretedOption_NamePart**)_upb_array_mutable_accessor(msg, UPB_SIZE(56, 80), len);
 }
 UPB_INLINE google_protobuf_UninterpretedOption_NamePart** google_protobuf_UninterpretedOption_resize_name(google_protobuf_UninterpretedOption *msg, size_t len, upb_arena *arena) {
-  return (google_protobuf_UninterpretedOption_NamePart**)_upb_array_resize_accessor(msg, UPB_SIZE(56, 80), len, UPB_TYPE_MESSAGE, arena);
+  return (google_protobuf_UninterpretedOption_NamePart**)_upb_array_resize_accessor2(msg, UPB_SIZE(56, 80), len, UPB_SIZE(2, 3), arena);
 }
 UPB_INLINE struct google_protobuf_UninterpretedOption_NamePart* google_protobuf_UninterpretedOption_add_name(google_protobuf_UninterpretedOption *msg, upb_arena *arena) {
   struct google_protobuf_UninterpretedOption_NamePart* sub = (struct google_protobuf_UninterpretedOption_NamePart*)_upb_msg_new(&google_protobuf_UninterpretedOption_NamePart_msginit, arena);
-  bool ok = _upb_array_append_accessor(
-      msg, UPB_SIZE(56, 80), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena);
+  bool ok = _upb_array_append_accessor2(
+      msg, UPB_SIZE(56, 80), UPB_SIZE(2, 3), &sub, arena);
   if (!ok) return NULL;
   return sub;
 }
 UPB_INLINE void google_protobuf_UninterpretedOption_set_identifier_value(google_protobuf_UninterpretedOption *msg, upb_strview value) {
-  _upb_sethas(msg, 4);
+  _upb_sethas(msg, 1);
   *UPB_PTR_AT(msg, UPB_SIZE(32, 32), upb_strview) = value;
 }
 UPB_INLINE void google_protobuf_UninterpretedOption_set_positive_int_value(google_protobuf_UninterpretedOption *msg, uint64_t value) {
-  _upb_sethas(msg, 1);
+  _upb_sethas(msg, 2);
   *UPB_PTR_AT(msg, UPB_SIZE(8, 8), uint64_t) = value;
 }
 UPB_INLINE void google_protobuf_UninterpretedOption_set_negative_int_value(google_protobuf_UninterpretedOption *msg, int64_t value) {
-  _upb_sethas(msg, 2);
+  _upb_sethas(msg, 3);
   *UPB_PTR_AT(msg, UPB_SIZE(16, 16), int64_t) = value;
 }
 UPB_INLINE void google_protobuf_UninterpretedOption_set_double_value(google_protobuf_UninterpretedOption *msg, double value) {
-  _upb_sethas(msg, 3);
+  _upb_sethas(msg, 4);
   *UPB_PTR_AT(msg, UPB_SIZE(24, 24), double) = value;
 }
 UPB_INLINE void google_protobuf_UninterpretedOption_set_string_value(google_protobuf_UninterpretedOption *msg, upb_strview value) {
@@ -1527,21 +1660,27 @@ UPB_INLINE google_protobuf_UninterpretedOption_NamePart *google_protobuf_Uninter
   google_protobuf_UninterpretedOption_NamePart *ret = google_protobuf_UninterpretedOption_NamePart_new(arena);
   return (ret && upb_decode(buf, size, ret, &google_protobuf_UninterpretedOption_NamePart_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE google_protobuf_UninterpretedOption_NamePart *google_protobuf_UninterpretedOption_NamePart_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  google_protobuf_UninterpretedOption_NamePart *ret = google_protobuf_UninterpretedOption_NamePart_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &google_protobuf_UninterpretedOption_NamePart_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *google_protobuf_UninterpretedOption_NamePart_serialize(const google_protobuf_UninterpretedOption_NamePart *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &google_protobuf_UninterpretedOption_NamePart_msginit, arena, len);
 }
 
-UPB_INLINE bool google_protobuf_UninterpretedOption_NamePart_has_name_part(const google_protobuf_UninterpretedOption_NamePart *msg) { return _upb_hasbit(msg, 2); }
+UPB_INLINE bool google_protobuf_UninterpretedOption_NamePart_has_name_part(const google_protobuf_UninterpretedOption_NamePart *msg) { return _upb_hasbit(msg, 1); }
 UPB_INLINE upb_strview google_protobuf_UninterpretedOption_NamePart_name_part(const google_protobuf_UninterpretedOption_NamePart *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(4, 8), upb_strview); }
-UPB_INLINE bool google_protobuf_UninterpretedOption_NamePart_has_is_extension(const google_protobuf_UninterpretedOption_NamePart *msg) { return _upb_hasbit(msg, 1); }
+UPB_INLINE bool google_protobuf_UninterpretedOption_NamePart_has_is_extension(const google_protobuf_UninterpretedOption_NamePart *msg) { return _upb_hasbit(msg, 2); }
 UPB_INLINE bool google_protobuf_UninterpretedOption_NamePart_is_extension(const google_protobuf_UninterpretedOption_NamePart *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(1, 1), bool); }
 
 UPB_INLINE void google_protobuf_UninterpretedOption_NamePart_set_name_part(google_protobuf_UninterpretedOption_NamePart *msg, upb_strview value) {
-  _upb_sethas(msg, 2);
+  _upb_sethas(msg, 1);
   *UPB_PTR_AT(msg, UPB_SIZE(4, 8), upb_strview) = value;
 }
 UPB_INLINE void google_protobuf_UninterpretedOption_NamePart_set_is_extension(google_protobuf_UninterpretedOption_NamePart *msg, bool value) {
-  _upb_sethas(msg, 1);
+  _upb_sethas(msg, 2);
   *UPB_PTR_AT(msg, UPB_SIZE(1, 1), bool) = value;
 }
 
@@ -1555,6 +1694,12 @@ UPB_INLINE google_protobuf_SourceCodeInfo *google_protobuf_SourceCodeInfo_parse(
   google_protobuf_SourceCodeInfo *ret = google_protobuf_SourceCodeInfo_new(arena);
   return (ret && upb_decode(buf, size, ret, &google_protobuf_SourceCodeInfo_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE google_protobuf_SourceCodeInfo *google_protobuf_SourceCodeInfo_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  google_protobuf_SourceCodeInfo *ret = google_protobuf_SourceCodeInfo_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &google_protobuf_SourceCodeInfo_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *google_protobuf_SourceCodeInfo_serialize(const google_protobuf_SourceCodeInfo *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &google_protobuf_SourceCodeInfo_msginit, arena, len);
 }
@@ -1566,12 +1711,12 @@ UPB_INLINE google_protobuf_SourceCodeInfo_Location** google_protobuf_SourceCodeI
   return (google_protobuf_SourceCodeInfo_Location**)_upb_array_mutable_accessor(msg, UPB_SIZE(0, 0), len);
 }
 UPB_INLINE google_protobuf_SourceCodeInfo_Location** google_protobuf_SourceCodeInfo_resize_location(google_protobuf_SourceCodeInfo *msg, size_t len, upb_arena *arena) {
-  return (google_protobuf_SourceCodeInfo_Location**)_upb_array_resize_accessor(msg, UPB_SIZE(0, 0), len, UPB_TYPE_MESSAGE, arena);
+  return (google_protobuf_SourceCodeInfo_Location**)_upb_array_resize_accessor2(msg, UPB_SIZE(0, 0), len, UPB_SIZE(2, 3), arena);
 }
 UPB_INLINE struct google_protobuf_SourceCodeInfo_Location* google_protobuf_SourceCodeInfo_add_location(google_protobuf_SourceCodeInfo *msg, upb_arena *arena) {
   struct google_protobuf_SourceCodeInfo_Location* sub = (struct google_protobuf_SourceCodeInfo_Location*)_upb_msg_new(&google_protobuf_SourceCodeInfo_Location_msginit, arena);
-  bool ok = _upb_array_append_accessor(
-      msg, UPB_SIZE(0, 0), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena);
+  bool ok = _upb_array_append_accessor2(
+      msg, UPB_SIZE(0, 0), UPB_SIZE(2, 3), &sub, arena);
   if (!ok) return NULL;
   return sub;
 }
@@ -1586,6 +1731,12 @@ UPB_INLINE google_protobuf_SourceCodeInfo_Location *google_protobuf_SourceCodeIn
   google_protobuf_SourceCodeInfo_Location *ret = google_protobuf_SourceCodeInfo_Location_new(arena);
   return (ret && upb_decode(buf, size, ret, &google_protobuf_SourceCodeInfo_Location_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE google_protobuf_SourceCodeInfo_Location *google_protobuf_SourceCodeInfo_Location_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  google_protobuf_SourceCodeInfo_Location *ret = google_protobuf_SourceCodeInfo_Location_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &google_protobuf_SourceCodeInfo_Location_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *google_protobuf_SourceCodeInfo_Location_serialize(const google_protobuf_SourceCodeInfo_Location *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &google_protobuf_SourceCodeInfo_Location_msginit, arena, len);
 }
@@ -1602,20 +1753,20 @@ UPB_INLINE int32_t* google_protobuf_SourceCodeInfo_Location_mutable_path(google_
   return (int32_t*)_upb_array_mutable_accessor(msg, UPB_SIZE(20, 40), len);
 }
 UPB_INLINE int32_t* google_protobuf_SourceCodeInfo_Location_resize_path(google_protobuf_SourceCodeInfo_Location *msg, size_t len, upb_arena *arena) {
-  return (int32_t*)_upb_array_resize_accessor(msg, UPB_SIZE(20, 40), len, UPB_TYPE_INT32, arena);
+  return (int32_t*)_upb_array_resize_accessor2(msg, UPB_SIZE(20, 40), len, 2, arena);
 }
 UPB_INLINE bool google_protobuf_SourceCodeInfo_Location_add_path(google_protobuf_SourceCodeInfo_Location *msg, int32_t val, upb_arena *arena) {
-  return _upb_array_append_accessor(msg, UPB_SIZE(20, 40), UPB_SIZE(4, 4), UPB_TYPE_INT32, &val,
+  return _upb_array_append_accessor2(msg, UPB_SIZE(20, 40), 2, &val,
       arena);
 }
 UPB_INLINE int32_t* google_protobuf_SourceCodeInfo_Location_mutable_span(google_protobuf_SourceCodeInfo_Location *msg, size_t *len) {
   return (int32_t*)_upb_array_mutable_accessor(msg, UPB_SIZE(24, 48), len);
 }
 UPB_INLINE int32_t* google_protobuf_SourceCodeInfo_Location_resize_span(google_protobuf_SourceCodeInfo_Location *msg, size_t len, upb_arena *arena) {
-  return (int32_t*)_upb_array_resize_accessor(msg, UPB_SIZE(24, 48), len, UPB_TYPE_INT32, arena);
+  return (int32_t*)_upb_array_resize_accessor2(msg, UPB_SIZE(24, 48), len, 2, arena);
 }
 UPB_INLINE bool google_protobuf_SourceCodeInfo_Location_add_span(google_protobuf_SourceCodeInfo_Location *msg, int32_t val, upb_arena *arena) {
-  return _upb_array_append_accessor(msg, UPB_SIZE(24, 48), UPB_SIZE(4, 4), UPB_TYPE_INT32, &val,
+  return _upb_array_append_accessor2(msg, UPB_SIZE(24, 48), 2, &val,
       arena);
 }
 UPB_INLINE void google_protobuf_SourceCodeInfo_Location_set_leading_comments(google_protobuf_SourceCodeInfo_Location *msg, upb_strview value) {
@@ -1630,10 +1781,10 @@ UPB_INLINE upb_strview* google_protobuf_SourceCodeInfo_Location_mutable_leading_
   return (upb_strview*)_upb_array_mutable_accessor(msg, UPB_SIZE(28, 56), len);
 }
 UPB_INLINE upb_strview* google_protobuf_SourceCodeInfo_Location_resize_leading_detached_comments(google_protobuf_SourceCodeInfo_Location *msg, size_t len, upb_arena *arena) {
-  return (upb_strview*)_upb_array_resize_accessor(msg, UPB_SIZE(28, 56), len, UPB_TYPE_STRING, arena);
+  return (upb_strview*)_upb_array_resize_accessor2(msg, UPB_SIZE(28, 56), len, UPB_SIZE(3, 4), arena);
 }
 UPB_INLINE bool google_protobuf_SourceCodeInfo_Location_add_leading_detached_comments(google_protobuf_SourceCodeInfo_Location *msg, upb_strview val, upb_arena *arena) {
-  return _upb_array_append_accessor(msg, UPB_SIZE(28, 56), UPB_SIZE(8, 16), UPB_TYPE_STRING, &val,
+  return _upb_array_append_accessor2(msg, UPB_SIZE(28, 56), UPB_SIZE(3, 4), &val,
       arena);
 }
 
@@ -1647,6 +1798,12 @@ UPB_INLINE google_protobuf_GeneratedCodeInfo *google_protobuf_GeneratedCodeInfo_
   google_protobuf_GeneratedCodeInfo *ret = google_protobuf_GeneratedCodeInfo_new(arena);
   return (ret && upb_decode(buf, size, ret, &google_protobuf_GeneratedCodeInfo_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE google_protobuf_GeneratedCodeInfo *google_protobuf_GeneratedCodeInfo_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  google_protobuf_GeneratedCodeInfo *ret = google_protobuf_GeneratedCodeInfo_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &google_protobuf_GeneratedCodeInfo_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *google_protobuf_GeneratedCodeInfo_serialize(const google_protobuf_GeneratedCodeInfo *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &google_protobuf_GeneratedCodeInfo_msginit, arena, len);
 }
@@ -1658,12 +1815,12 @@ UPB_INLINE google_protobuf_GeneratedCodeInfo_Annotation** google_protobuf_Genera
   return (google_protobuf_GeneratedCodeInfo_Annotation**)_upb_array_mutable_accessor(msg, UPB_SIZE(0, 0), len);
 }
 UPB_INLINE google_protobuf_GeneratedCodeInfo_Annotation** google_protobuf_GeneratedCodeInfo_resize_annotation(google_protobuf_GeneratedCodeInfo *msg, size_t len, upb_arena *arena) {
-  return (google_protobuf_GeneratedCodeInfo_Annotation**)_upb_array_resize_accessor(msg, UPB_SIZE(0, 0), len, UPB_TYPE_MESSAGE, arena);
+  return (google_protobuf_GeneratedCodeInfo_Annotation**)_upb_array_resize_accessor2(msg, UPB_SIZE(0, 0), len, UPB_SIZE(2, 3), arena);
 }
 UPB_INLINE struct google_protobuf_GeneratedCodeInfo_Annotation* google_protobuf_GeneratedCodeInfo_add_annotation(google_protobuf_GeneratedCodeInfo *msg, upb_arena *arena) {
   struct google_protobuf_GeneratedCodeInfo_Annotation* sub = (struct google_protobuf_GeneratedCodeInfo_Annotation*)_upb_msg_new(&google_protobuf_GeneratedCodeInfo_Annotation_msginit, arena);
-  bool ok = _upb_array_append_accessor(
-      msg, UPB_SIZE(0, 0), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena);
+  bool ok = _upb_array_append_accessor2(
+      msg, UPB_SIZE(0, 0), UPB_SIZE(2, 3), &sub, arena);
   if (!ok) return NULL;
   return sub;
 }
@@ -1678,38 +1835,44 @@ UPB_INLINE google_protobuf_GeneratedCodeInfo_Annotation *google_protobuf_Generat
   google_protobuf_GeneratedCodeInfo_Annotation *ret = google_protobuf_GeneratedCodeInfo_Annotation_new(arena);
   return (ret && upb_decode(buf, size, ret, &google_protobuf_GeneratedCodeInfo_Annotation_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE google_protobuf_GeneratedCodeInfo_Annotation *google_protobuf_GeneratedCodeInfo_Annotation_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  google_protobuf_GeneratedCodeInfo_Annotation *ret = google_protobuf_GeneratedCodeInfo_Annotation_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &google_protobuf_GeneratedCodeInfo_Annotation_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *google_protobuf_GeneratedCodeInfo_Annotation_serialize(const google_protobuf_GeneratedCodeInfo_Annotation *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &google_protobuf_GeneratedCodeInfo_Annotation_msginit, arena, len);
 }
 
 UPB_INLINE int32_t const* google_protobuf_GeneratedCodeInfo_Annotation_path(const google_protobuf_GeneratedCodeInfo_Annotation *msg, size_t *len) { return (int32_t const*)_upb_array_accessor(msg, UPB_SIZE(20, 32), len); }
-UPB_INLINE bool google_protobuf_GeneratedCodeInfo_Annotation_has_source_file(const google_protobuf_GeneratedCodeInfo_Annotation *msg) { return _upb_hasbit(msg, 3); }
+UPB_INLINE bool google_protobuf_GeneratedCodeInfo_Annotation_has_source_file(const google_protobuf_GeneratedCodeInfo_Annotation *msg) { return _upb_hasbit(msg, 1); }
 UPB_INLINE upb_strview google_protobuf_GeneratedCodeInfo_Annotation_source_file(const google_protobuf_GeneratedCodeInfo_Annotation *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(12, 16), upb_strview); }
-UPB_INLINE bool google_protobuf_GeneratedCodeInfo_Annotation_has_begin(const google_protobuf_GeneratedCodeInfo_Annotation *msg) { return _upb_hasbit(msg, 1); }
+UPB_INLINE bool google_protobuf_GeneratedCodeInfo_Annotation_has_begin(const google_protobuf_GeneratedCodeInfo_Annotation *msg) { return _upb_hasbit(msg, 2); }
 UPB_INLINE int32_t google_protobuf_GeneratedCodeInfo_Annotation_begin(const google_protobuf_GeneratedCodeInfo_Annotation *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(4, 4), int32_t); }
-UPB_INLINE bool google_protobuf_GeneratedCodeInfo_Annotation_has_end(const google_protobuf_GeneratedCodeInfo_Annotation *msg) { return _upb_hasbit(msg, 2); }
+UPB_INLINE bool google_protobuf_GeneratedCodeInfo_Annotation_has_end(const google_protobuf_GeneratedCodeInfo_Annotation *msg) { return _upb_hasbit(msg, 3); }
 UPB_INLINE int32_t google_protobuf_GeneratedCodeInfo_Annotation_end(const google_protobuf_GeneratedCodeInfo_Annotation *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(8, 8), int32_t); }
 
 UPB_INLINE int32_t* google_protobuf_GeneratedCodeInfo_Annotation_mutable_path(google_protobuf_GeneratedCodeInfo_Annotation *msg, size_t *len) {
   return (int32_t*)_upb_array_mutable_accessor(msg, UPB_SIZE(20, 32), len);
 }
 UPB_INLINE int32_t* google_protobuf_GeneratedCodeInfo_Annotation_resize_path(google_protobuf_GeneratedCodeInfo_Annotation *msg, size_t len, upb_arena *arena) {
-  return (int32_t*)_upb_array_resize_accessor(msg, UPB_SIZE(20, 32), len, UPB_TYPE_INT32, arena);
+  return (int32_t*)_upb_array_resize_accessor2(msg, UPB_SIZE(20, 32), len, 2, arena);
 }
 UPB_INLINE bool google_protobuf_GeneratedCodeInfo_Annotation_add_path(google_protobuf_GeneratedCodeInfo_Annotation *msg, int32_t val, upb_arena *arena) {
-  return _upb_array_append_accessor(msg, UPB_SIZE(20, 32), UPB_SIZE(4, 4), UPB_TYPE_INT32, &val,
+  return _upb_array_append_accessor2(msg, UPB_SIZE(20, 32), 2, &val,
       arena);
 }
 UPB_INLINE void google_protobuf_GeneratedCodeInfo_Annotation_set_source_file(google_protobuf_GeneratedCodeInfo_Annotation *msg, upb_strview value) {
-  _upb_sethas(msg, 3);
+  _upb_sethas(msg, 1);
   *UPB_PTR_AT(msg, UPB_SIZE(12, 16), upb_strview) = value;
 }
 UPB_INLINE void google_protobuf_GeneratedCodeInfo_Annotation_set_begin(google_protobuf_GeneratedCodeInfo_Annotation *msg, int32_t value) {
-  _upb_sethas(msg, 1);
+  _upb_sethas(msg, 2);
   *UPB_PTR_AT(msg, UPB_SIZE(4, 4), int32_t) = value;
 }
 UPB_INLINE void google_protobuf_GeneratedCodeInfo_Annotation_set_end(google_protobuf_GeneratedCodeInfo_Annotation *msg, int32_t value) {
-  _upb_sethas(msg, 2);
+  _upb_sethas(msg, 3);
   *UPB_PTR_AT(msg, UPB_SIZE(8, 8), int32_t) = value;
 }
 
index 7384c06..03d463a 100644 (file)
@@ -20,7 +20,7 @@ static const upb_msglayout_field google_protobuf_Duration__fields[2] = {
 const upb_msglayout google_protobuf_Duration_msginit = {
   NULL,
   &google_protobuf_Duration__fields[0],
-  UPB_SIZE(16, 16), 2, false,
+  UPB_SIZE(16, 16), 2, false, 255,
 };
 
 #include "upb/port_undef.inc"
index f3fa035..4692fd7 100644 (file)
@@ -11,6 +11,7 @@
 
 #include "upb/msg.h"
 #include "upb/decode.h"
+#include "upb/decode_fast.h"
 #include "upb/encode.h"
 
 #include "upb/port_def.inc"
@@ -34,6 +35,12 @@ UPB_INLINE google_protobuf_Duration *google_protobuf_Duration_parse(const char *
   google_protobuf_Duration *ret = google_protobuf_Duration_new(arena);
   return (ret && upb_decode(buf, size, ret, &google_protobuf_Duration_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE google_protobuf_Duration *google_protobuf_Duration_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  google_protobuf_Duration *ret = google_protobuf_Duration_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &google_protobuf_Duration_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *google_protobuf_Duration_serialize(const google_protobuf_Duration *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &google_protobuf_Duration_msginit, arena, len);
 }
index 51ac7ed..f634b2b 100644 (file)
@@ -15,7 +15,7 @@
 const upb_msglayout google_protobuf_Empty_msginit = {
   NULL,
   NULL,
-  UPB_SIZE(0, 0), 0, false,
+  UPB_SIZE(0, 0), 0, false, 255,
 };
 
 #include "upb/port_undef.inc"
index a7471dc..9202b83 100644 (file)
@@ -11,6 +11,7 @@
 
 #include "upb/msg.h"
 #include "upb/decode.h"
+#include "upb/decode_fast.h"
 #include "upb/encode.h"
 
 #include "upb/port_def.inc"
@@ -34,6 +35,12 @@ UPB_INLINE google_protobuf_Empty *google_protobuf_Empty_parse(const char *buf, s
   google_protobuf_Empty *ret = google_protobuf_Empty_new(arena);
   return (ret && upb_decode(buf, size, ret, &google_protobuf_Empty_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE google_protobuf_Empty *google_protobuf_Empty_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  google_protobuf_Empty *ret = google_protobuf_Empty_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &google_protobuf_Empty_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *google_protobuf_Empty_serialize(const google_protobuf_Empty *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &google_protobuf_Empty_msginit, arena, len);
 }
index a0d20a4..04b9167 100644 (file)
@@ -23,7 +23,7 @@ static const upb_msglayout_field google_protobuf_Struct__fields[1] = {
 const upb_msglayout google_protobuf_Struct_msginit = {
   &google_protobuf_Struct_submsgs[0],
   &google_protobuf_Struct__fields[0],
-  UPB_SIZE(4, 8), 1, false,
+  UPB_SIZE(8, 8), 1, false, 255,
 };
 
 static const upb_msglayout *const google_protobuf_Struct_FieldsEntry_submsgs[1] = {
@@ -38,7 +38,7 @@ static const upb_msglayout_field google_protobuf_Struct_FieldsEntry__fields[2] =
 const upb_msglayout google_protobuf_Struct_FieldsEntry_msginit = {
   &google_protobuf_Struct_FieldsEntry_submsgs[0],
   &google_protobuf_Struct_FieldsEntry__fields[0],
-  UPB_SIZE(16, 32), 2, false,
+  UPB_SIZE(16, 32), 2, false, 255,
 };
 
 static const upb_msglayout *const google_protobuf_Value_submsgs[2] = {
@@ -58,7 +58,7 @@ static const upb_msglayout_field google_protobuf_Value__fields[6] = {
 const upb_msglayout google_protobuf_Value_msginit = {
   &google_protobuf_Value_submsgs[0],
   &google_protobuf_Value__fields[0],
-  UPB_SIZE(16, 32), 6, false,
+  UPB_SIZE(16, 32), 6, false, 255,
 };
 
 static const upb_msglayout *const google_protobuf_ListValue_submsgs[1] = {
@@ -72,7 +72,7 @@ static const upb_msglayout_field google_protobuf_ListValue__fields[1] = {
 const upb_msglayout google_protobuf_ListValue_msginit = {
   &google_protobuf_ListValue_submsgs[0],
   &google_protobuf_ListValue__fields[0],
-  UPB_SIZE(4, 8), 1, false,
+  UPB_SIZE(8, 8), 1, false, 255,
 };
 
 #include "upb/port_undef.inc"
index b25201d..29fec82 100644 (file)
@@ -11,6 +11,7 @@
 
 #include "upb/msg.h"
 #include "upb/decode.h"
+#include "upb/decode_fast.h"
 #include "upb/encode.h"
 
 #include "upb/port_def.inc"
@@ -47,6 +48,12 @@ UPB_INLINE google_protobuf_Struct *google_protobuf_Struct_parse(const char *buf,
   google_protobuf_Struct *ret = google_protobuf_Struct_new(arena);
   return (ret && upb_decode(buf, size, ret, &google_protobuf_Struct_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE google_protobuf_Struct *google_protobuf_Struct_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  google_protobuf_Struct *ret = google_protobuf_Struct_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &google_protobuf_Struct_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *google_protobuf_Struct_serialize(const google_protobuf_Struct *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &google_protobuf_Struct_msginit, arena, len);
 }
@@ -89,6 +96,12 @@ UPB_INLINE google_protobuf_Value *google_protobuf_Value_parse(const char *buf, s
   google_protobuf_Value *ret = google_protobuf_Value_new(arena);
   return (ret && upb_decode(buf, size, ret, &google_protobuf_Value_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE google_protobuf_Value *google_protobuf_Value_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  google_protobuf_Value *ret = google_protobuf_Value_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &google_protobuf_Value_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *google_protobuf_Value_serialize(const google_protobuf_Value *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &google_protobuf_Value_msginit, arena, len);
 }
@@ -164,6 +177,12 @@ UPB_INLINE google_protobuf_ListValue *google_protobuf_ListValue_parse(const char
   google_protobuf_ListValue *ret = google_protobuf_ListValue_new(arena);
   return (ret && upb_decode(buf, size, ret, &google_protobuf_ListValue_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE google_protobuf_ListValue *google_protobuf_ListValue_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  google_protobuf_ListValue *ret = google_protobuf_ListValue_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &google_protobuf_ListValue_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *google_protobuf_ListValue_serialize(const google_protobuf_ListValue *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &google_protobuf_ListValue_msginit, arena, len);
 }
@@ -175,12 +194,12 @@ UPB_INLINE google_protobuf_Value** google_protobuf_ListValue_mutable_values(goog
   return (google_protobuf_Value**)_upb_array_mutable_accessor(msg, UPB_SIZE(0, 0), len);
 }
 UPB_INLINE google_protobuf_Value** google_protobuf_ListValue_resize_values(google_protobuf_ListValue *msg, size_t len, upb_arena *arena) {
-  return (google_protobuf_Value**)_upb_array_resize_accessor(msg, UPB_SIZE(0, 0), len, UPB_TYPE_MESSAGE, arena);
+  return (google_protobuf_Value**)_upb_array_resize_accessor2(msg, UPB_SIZE(0, 0), len, UPB_SIZE(2, 3), arena);
 }
 UPB_INLINE struct google_protobuf_Value* google_protobuf_ListValue_add_values(google_protobuf_ListValue *msg, upb_arena *arena) {
   struct google_protobuf_Value* sub = (struct google_protobuf_Value*)_upb_msg_new(&google_protobuf_Value_msginit, arena);
-  bool ok = _upb_array_append_accessor(
-      msg, UPB_SIZE(0, 0), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena);
+  bool ok = _upb_array_append_accessor2(
+      msg, UPB_SIZE(0, 0), UPB_SIZE(2, 3), &sub, arena);
   if (!ok) return NULL;
   return sub;
 }
index edc7af5..718ce3b 100644 (file)
@@ -20,7 +20,7 @@ static const upb_msglayout_field google_protobuf_Timestamp__fields[2] = {
 const upb_msglayout google_protobuf_Timestamp_msginit = {
   NULL,
   &google_protobuf_Timestamp__fields[0],
-  UPB_SIZE(16, 16), 2, false,
+  UPB_SIZE(16, 16), 2, false, 255,
 };
 
 #include "upb/port_undef.inc"
index f5166de..31c1145 100644 (file)
@@ -11,6 +11,7 @@
 
 #include "upb/msg.h"
 #include "upb/decode.h"
+#include "upb/decode_fast.h"
 #include "upb/encode.h"
 
 #include "upb/port_def.inc"
@@ -34,6 +35,12 @@ UPB_INLINE google_protobuf_Timestamp *google_protobuf_Timestamp_parse(const char
   google_protobuf_Timestamp *ret = google_protobuf_Timestamp_new(arena);
   return (ret && upb_decode(buf, size, ret, &google_protobuf_Timestamp_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE google_protobuf_Timestamp *google_protobuf_Timestamp_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  google_protobuf_Timestamp *ret = google_protobuf_Timestamp_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &google_protobuf_Timestamp_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *google_protobuf_Timestamp_serialize(const google_protobuf_Timestamp *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &google_protobuf_Timestamp_msginit, arena, len);
 }
index 1b93ef4..aabc174 100644 (file)
@@ -19,7 +19,7 @@ static const upb_msglayout_field google_protobuf_DoubleValue__fields[1] = {
 const upb_msglayout google_protobuf_DoubleValue_msginit = {
   NULL,
   &google_protobuf_DoubleValue__fields[0],
-  UPB_SIZE(8, 8), 1, false,
+  UPB_SIZE(8, 8), 1, false, 255,
 };
 
 static const upb_msglayout_field google_protobuf_FloatValue__fields[1] = {
@@ -29,7 +29,7 @@ static const upb_msglayout_field google_protobuf_FloatValue__fields[1] = {
 const upb_msglayout google_protobuf_FloatValue_msginit = {
   NULL,
   &google_protobuf_FloatValue__fields[0],
-  UPB_SIZE(4, 4), 1, false,
+  UPB_SIZE(8, 8), 1, false, 255,
 };
 
 static const upb_msglayout_field google_protobuf_Int64Value__fields[1] = {
@@ -39,7 +39,7 @@ static const upb_msglayout_field google_protobuf_Int64Value__fields[1] = {
 const upb_msglayout google_protobuf_Int64Value_msginit = {
   NULL,
   &google_protobuf_Int64Value__fields[0],
-  UPB_SIZE(8, 8), 1, false,
+  UPB_SIZE(8, 8), 1, false, 255,
 };
 
 static const upb_msglayout_field google_protobuf_UInt64Value__fields[1] = {
@@ -49,7 +49,7 @@ static const upb_msglayout_field google_protobuf_UInt64Value__fields[1] = {
 const upb_msglayout google_protobuf_UInt64Value_msginit = {
   NULL,
   &google_protobuf_UInt64Value__fields[0],
-  UPB_SIZE(8, 8), 1, false,
+  UPB_SIZE(8, 8), 1, false, 255,
 };
 
 static const upb_msglayout_field google_protobuf_Int32Value__fields[1] = {
@@ -59,7 +59,7 @@ static const upb_msglayout_field google_protobuf_Int32Value__fields[1] = {
 const upb_msglayout google_protobuf_Int32Value_msginit = {
   NULL,
   &google_protobuf_Int32Value__fields[0],
-  UPB_SIZE(4, 4), 1, false,
+  UPB_SIZE(8, 8), 1, false, 255,
 };
 
 static const upb_msglayout_field google_protobuf_UInt32Value__fields[1] = {
@@ -69,7 +69,7 @@ static const upb_msglayout_field google_protobuf_UInt32Value__fields[1] = {
 const upb_msglayout google_protobuf_UInt32Value_msginit = {
   NULL,
   &google_protobuf_UInt32Value__fields[0],
-  UPB_SIZE(4, 4), 1, false,
+  UPB_SIZE(8, 8), 1, false, 255,
 };
 
 static const upb_msglayout_field google_protobuf_BoolValue__fields[1] = {
@@ -79,7 +79,7 @@ static const upb_msglayout_field google_protobuf_BoolValue__fields[1] = {
 const upb_msglayout google_protobuf_BoolValue_msginit = {
   NULL,
   &google_protobuf_BoolValue__fields[0],
-  UPB_SIZE(1, 1), 1, false,
+  UPB_SIZE(8, 8), 1, false, 255,
 };
 
 static const upb_msglayout_field google_protobuf_StringValue__fields[1] = {
@@ -89,7 +89,7 @@ static const upb_msglayout_field google_protobuf_StringValue__fields[1] = {
 const upb_msglayout google_protobuf_StringValue_msginit = {
   NULL,
   &google_protobuf_StringValue__fields[0],
-  UPB_SIZE(8, 16), 1, false,
+  UPB_SIZE(8, 16), 1, false, 255,
 };
 
 static const upb_msglayout_field google_protobuf_BytesValue__fields[1] = {
@@ -99,7 +99,7 @@ static const upb_msglayout_field google_protobuf_BytesValue__fields[1] = {
 const upb_msglayout google_protobuf_BytesValue_msginit = {
   NULL,
   &google_protobuf_BytesValue__fields[0],
-  UPB_SIZE(8, 16), 1, false,
+  UPB_SIZE(8, 16), 1, false, 255,
 };
 
 #include "upb/port_undef.inc"
index 761eeeb..c184b80 100644 (file)
@@ -11,6 +11,7 @@
 
 #include "upb/msg.h"
 #include "upb/decode.h"
+#include "upb/decode_fast.h"
 #include "upb/encode.h"
 
 #include "upb/port_def.inc"
@@ -58,6 +59,12 @@ UPB_INLINE google_protobuf_DoubleValue *google_protobuf_DoubleValue_parse(const
   google_protobuf_DoubleValue *ret = google_protobuf_DoubleValue_new(arena);
   return (ret && upb_decode(buf, size, ret, &google_protobuf_DoubleValue_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE google_protobuf_DoubleValue *google_protobuf_DoubleValue_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  google_protobuf_DoubleValue *ret = google_protobuf_DoubleValue_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &google_protobuf_DoubleValue_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *google_protobuf_DoubleValue_serialize(const google_protobuf_DoubleValue *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &google_protobuf_DoubleValue_msginit, arena, len);
 }
@@ -78,6 +85,12 @@ UPB_INLINE google_protobuf_FloatValue *google_protobuf_FloatValue_parse(const ch
   google_protobuf_FloatValue *ret = google_protobuf_FloatValue_new(arena);
   return (ret && upb_decode(buf, size, ret, &google_protobuf_FloatValue_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE google_protobuf_FloatValue *google_protobuf_FloatValue_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  google_protobuf_FloatValue *ret = google_protobuf_FloatValue_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &google_protobuf_FloatValue_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *google_protobuf_FloatValue_serialize(const google_protobuf_FloatValue *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &google_protobuf_FloatValue_msginit, arena, len);
 }
@@ -98,6 +111,12 @@ UPB_INLINE google_protobuf_Int64Value *google_protobuf_Int64Value_parse(const ch
   google_protobuf_Int64Value *ret = google_protobuf_Int64Value_new(arena);
   return (ret && upb_decode(buf, size, ret, &google_protobuf_Int64Value_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE google_protobuf_Int64Value *google_protobuf_Int64Value_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  google_protobuf_Int64Value *ret = google_protobuf_Int64Value_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &google_protobuf_Int64Value_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *google_protobuf_Int64Value_serialize(const google_protobuf_Int64Value *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &google_protobuf_Int64Value_msginit, arena, len);
 }
@@ -118,6 +137,12 @@ UPB_INLINE google_protobuf_UInt64Value *google_protobuf_UInt64Value_parse(const
   google_protobuf_UInt64Value *ret = google_protobuf_UInt64Value_new(arena);
   return (ret && upb_decode(buf, size, ret, &google_protobuf_UInt64Value_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE google_protobuf_UInt64Value *google_protobuf_UInt64Value_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  google_protobuf_UInt64Value *ret = google_protobuf_UInt64Value_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &google_protobuf_UInt64Value_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *google_protobuf_UInt64Value_serialize(const google_protobuf_UInt64Value *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &google_protobuf_UInt64Value_msginit, arena, len);
 }
@@ -138,6 +163,12 @@ UPB_INLINE google_protobuf_Int32Value *google_protobuf_Int32Value_parse(const ch
   google_protobuf_Int32Value *ret = google_protobuf_Int32Value_new(arena);
   return (ret && upb_decode(buf, size, ret, &google_protobuf_Int32Value_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE google_protobuf_Int32Value *google_protobuf_Int32Value_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  google_protobuf_Int32Value *ret = google_protobuf_Int32Value_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &google_protobuf_Int32Value_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *google_protobuf_Int32Value_serialize(const google_protobuf_Int32Value *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &google_protobuf_Int32Value_msginit, arena, len);
 }
@@ -158,6 +189,12 @@ UPB_INLINE google_protobuf_UInt32Value *google_protobuf_UInt32Value_parse(const
   google_protobuf_UInt32Value *ret = google_protobuf_UInt32Value_new(arena);
   return (ret && upb_decode(buf, size, ret, &google_protobuf_UInt32Value_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE google_protobuf_UInt32Value *google_protobuf_UInt32Value_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  google_protobuf_UInt32Value *ret = google_protobuf_UInt32Value_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &google_protobuf_UInt32Value_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *google_protobuf_UInt32Value_serialize(const google_protobuf_UInt32Value *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &google_protobuf_UInt32Value_msginit, arena, len);
 }
@@ -178,6 +215,12 @@ UPB_INLINE google_protobuf_BoolValue *google_protobuf_BoolValue_parse(const char
   google_protobuf_BoolValue *ret = google_protobuf_BoolValue_new(arena);
   return (ret && upb_decode(buf, size, ret, &google_protobuf_BoolValue_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE google_protobuf_BoolValue *google_protobuf_BoolValue_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  google_protobuf_BoolValue *ret = google_protobuf_BoolValue_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &google_protobuf_BoolValue_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *google_protobuf_BoolValue_serialize(const google_protobuf_BoolValue *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &google_protobuf_BoolValue_msginit, arena, len);
 }
@@ -198,6 +241,12 @@ UPB_INLINE google_protobuf_StringValue *google_protobuf_StringValue_parse(const
   google_protobuf_StringValue *ret = google_protobuf_StringValue_new(arena);
   return (ret && upb_decode(buf, size, ret, &google_protobuf_StringValue_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE google_protobuf_StringValue *google_protobuf_StringValue_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  google_protobuf_StringValue *ret = google_protobuf_StringValue_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &google_protobuf_StringValue_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *google_protobuf_StringValue_serialize(const google_protobuf_StringValue *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &google_protobuf_StringValue_msginit, arena, len);
 }
@@ -218,6 +267,12 @@ UPB_INLINE google_protobuf_BytesValue *google_protobuf_BytesValue_parse(const ch
   google_protobuf_BytesValue *ret = google_protobuf_BytesValue_new(arena);
   return (ret && upb_decode(buf, size, ret, &google_protobuf_BytesValue_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE google_protobuf_BytesValue *google_protobuf_BytesValue_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  google_protobuf_BytesValue *ret = google_protobuf_BytesValue_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &google_protobuf_BytesValue_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *google_protobuf_BytesValue_serialize(const google_protobuf_BytesValue *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &google_protobuf_BytesValue_msginit, arena, len);
 }
index 25ac146..e276a0d 100644 (file)
@@ -26,7 +26,7 @@ static const upb_msglayout_field google_rpc_Status__fields[3] = {
 const upb_msglayout google_rpc_Status_msginit = {
   &google_rpc_Status_submsgs[0],
   &google_rpc_Status__fields[0],
-  UPB_SIZE(16, 32), 3, false,
+  UPB_SIZE(16, 32), 3, false, 255,
 };
 
 #include "upb/port_undef.inc"
index 2c5fb02..4cc29b3 100644 (file)
@@ -11,6 +11,7 @@
 
 #include "upb/msg.h"
 #include "upb/decode.h"
+#include "upb/decode_fast.h"
 #include "upb/encode.h"
 
 #include "upb/port_def.inc"
@@ -36,6 +37,12 @@ UPB_INLINE google_rpc_Status *google_rpc_Status_parse(const char *buf, size_t si
   google_rpc_Status *ret = google_rpc_Status_new(arena);
   return (ret && upb_decode(buf, size, ret, &google_rpc_Status_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE google_rpc_Status *google_rpc_Status_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  google_rpc_Status *ret = google_rpc_Status_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &google_rpc_Status_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *google_rpc_Status_serialize(const google_rpc_Status *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &google_rpc_Status_msginit, arena, len);
 }
@@ -55,12 +62,12 @@ UPB_INLINE struct google_protobuf_Any** google_rpc_Status_mutable_details(google
   return (struct google_protobuf_Any**)_upb_array_mutable_accessor(msg, UPB_SIZE(12, 24), len);
 }
 UPB_INLINE struct google_protobuf_Any** google_rpc_Status_resize_details(google_rpc_Status *msg, size_t len, upb_arena *arena) {
-  return (struct google_protobuf_Any**)_upb_array_resize_accessor(msg, UPB_SIZE(12, 24), len, UPB_TYPE_MESSAGE, arena);
+  return (struct google_protobuf_Any**)_upb_array_resize_accessor2(msg, UPB_SIZE(12, 24), len, UPB_SIZE(2, 3), arena);
 }
 UPB_INLINE struct google_protobuf_Any* google_rpc_Status_add_details(google_rpc_Status *msg, upb_arena *arena) {
   struct google_protobuf_Any* sub = (struct google_protobuf_Any*)_upb_msg_new(&google_protobuf_Any_msginit, arena);
-  bool ok = _upb_array_append_accessor(
-      msg, UPB_SIZE(12, 24), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena);
+  bool ok = _upb_array_append_accessor2(
+      msg, UPB_SIZE(12, 24), UPB_SIZE(2, 3), &sub, arena);
   if (!ok) return NULL;
   return sub;
 }
index 6c917ad..8b6de3f 100644 (file)
@@ -21,17 +21,17 @@ static const upb_msglayout *const grpc_gcp_AltsContext_submsgs[2] = {
 static const upb_msglayout_field grpc_gcp_AltsContext__fields[7] = {
   {1, UPB_SIZE(8, 8), 0, 0, 9, 1},
   {2, UPB_SIZE(16, 24), 0, 0, 9, 1},
-  {3, UPB_SIZE(0, 0), 0, 0, 14, 1},
+  {3, UPB_SIZE(4, 4), 0, 0, 14, 1},
   {4, UPB_SIZE(24, 40), 0, 0, 9, 1},
   {5, UPB_SIZE(32, 56), 0, 0, 9, 1},
-  {6, UPB_SIZE(40, 72), 0, 1, 11, 1},
+  {6, UPB_SIZE(40, 72), 1, 1, 11, 1},
   {7, UPB_SIZE(44, 80), 0, 0, 11, _UPB_LABEL_MAP},
 };
 
 const upb_msglayout grpc_gcp_AltsContext_msginit = {
   &grpc_gcp_AltsContext_submsgs[0],
   &grpc_gcp_AltsContext__fields[0],
-  UPB_SIZE(48, 96), 7, false,
+  UPB_SIZE(48, 96), 7, false, 255,
 };
 
 static const upb_msglayout_field grpc_gcp_AltsContext_PeerAttributesEntry__fields[2] = {
@@ -42,7 +42,7 @@ static const upb_msglayout_field grpc_gcp_AltsContext_PeerAttributesEntry__field
 const upb_msglayout grpc_gcp_AltsContext_PeerAttributesEntry_msginit = {
   NULL,
   &grpc_gcp_AltsContext_PeerAttributesEntry__fields[0],
-  UPB_SIZE(16, 32), 2, false,
+  UPB_SIZE(16, 32), 2, false, 255,
 };
 
 #include "upb/port_undef.inc"
index 33c1b2f..3a91b53 100644 (file)
@@ -11,6 +11,7 @@
 
 #include "upb/msg.h"
 #include "upb/decode.h"
+#include "upb/decode_fast.h"
 #include "upb/encode.h"
 
 #include "upb/port_def.inc"
@@ -39,16 +40,22 @@ UPB_INLINE grpc_gcp_AltsContext *grpc_gcp_AltsContext_parse(const char *buf, siz
   grpc_gcp_AltsContext *ret = grpc_gcp_AltsContext_new(arena);
   return (ret && upb_decode(buf, size, ret, &grpc_gcp_AltsContext_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE grpc_gcp_AltsContext *grpc_gcp_AltsContext_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  grpc_gcp_AltsContext *ret = grpc_gcp_AltsContext_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &grpc_gcp_AltsContext_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *grpc_gcp_AltsContext_serialize(const grpc_gcp_AltsContext *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &grpc_gcp_AltsContext_msginit, arena, len);
 }
 
 UPB_INLINE upb_strview grpc_gcp_AltsContext_application_protocol(const grpc_gcp_AltsContext *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(8, 8), upb_strview); }
 UPB_INLINE upb_strview grpc_gcp_AltsContext_record_protocol(const grpc_gcp_AltsContext *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(16, 24), upb_strview); }
-UPB_INLINE int32_t grpc_gcp_AltsContext_security_level(const grpc_gcp_AltsContext *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(0, 0), int32_t); }
+UPB_INLINE int32_t grpc_gcp_AltsContext_security_level(const grpc_gcp_AltsContext *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(4, 4), int32_t); }
 UPB_INLINE upb_strview grpc_gcp_AltsContext_peer_service_account(const grpc_gcp_AltsContext *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(24, 40), upb_strview); }
 UPB_INLINE upb_strview grpc_gcp_AltsContext_local_service_account(const grpc_gcp_AltsContext *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(32, 56), upb_strview); }
-UPB_INLINE bool grpc_gcp_AltsContext_has_peer_rpc_versions(const grpc_gcp_AltsContext *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(40, 72)); }
+UPB_INLINE bool grpc_gcp_AltsContext_has_peer_rpc_versions(const grpc_gcp_AltsContext *msg) { return _upb_hasbit(msg, 1); }
 UPB_INLINE const struct grpc_gcp_RpcProtocolVersions* grpc_gcp_AltsContext_peer_rpc_versions(const grpc_gcp_AltsContext *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(40, 72), const struct grpc_gcp_RpcProtocolVersions*); }
 UPB_INLINE bool grpc_gcp_AltsContext_has_peer_attributes(const grpc_gcp_AltsContext *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(44, 80)); }
 UPB_INLINE size_t grpc_gcp_AltsContext_peer_attributes_size(const grpc_gcp_AltsContext *msg) {return _upb_msg_map_size(msg, UPB_SIZE(44, 80)); }
@@ -62,7 +69,7 @@ UPB_INLINE void grpc_gcp_AltsContext_set_record_protocol(grpc_gcp_AltsContext *m
   *UPB_PTR_AT(msg, UPB_SIZE(16, 24), upb_strview) = value;
 }
 UPB_INLINE void grpc_gcp_AltsContext_set_security_level(grpc_gcp_AltsContext *msg, int32_t value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(0, 0), int32_t) = value;
+  *UPB_PTR_AT(msg, UPB_SIZE(4, 4), int32_t) = value;
 }
 UPB_INLINE void grpc_gcp_AltsContext_set_peer_service_account(grpc_gcp_AltsContext *msg, upb_strview value) {
   *UPB_PTR_AT(msg, UPB_SIZE(24, 40), upb_strview) = value;
@@ -71,6 +78,7 @@ UPB_INLINE void grpc_gcp_AltsContext_set_local_service_account(grpc_gcp_AltsCont
   *UPB_PTR_AT(msg, UPB_SIZE(32, 56), upb_strview) = value;
 }
 UPB_INLINE void grpc_gcp_AltsContext_set_peer_rpc_versions(grpc_gcp_AltsContext *msg, struct grpc_gcp_RpcProtocolVersions* value) {
+  _upb_sethas(msg, 1);
   *UPB_PTR_AT(msg, UPB_SIZE(40, 72), struct grpc_gcp_RpcProtocolVersions*) = value;
 }
 UPB_INLINE struct grpc_gcp_RpcProtocolVersions* grpc_gcp_AltsContext_mutable_peer_rpc_versions(grpc_gcp_AltsContext *msg, upb_arena *arena) {
index 036b66f..998f2d8 100644 (file)
 #include "upb/port_def.inc"
 
 static const upb_msglayout_field grpc_gcp_Endpoint__fields[3] = {
-  {1, UPB_SIZE(12, 16), 0, 0, 9, 1},
-  {2, UPB_SIZE(8, 8), 0, 0, 5, 1},
+  {1, UPB_SIZE(8, 8), 0, 0, 9, 1},
+  {2, UPB_SIZE(4, 4), 0, 0, 5, 1},
   {3, UPB_SIZE(0, 0), 0, 0, 14, 1},
 };
 
 const upb_msglayout grpc_gcp_Endpoint_msginit = {
   NULL,
   &grpc_gcp_Endpoint__fields[0],
-  UPB_SIZE(24, 32), 3, false,
+  UPB_SIZE(16, 32), 3, false, 255,
 };
 
 static const upb_msglayout *const grpc_gcp_Identity_submsgs[1] = {
@@ -38,7 +38,7 @@ static const upb_msglayout_field grpc_gcp_Identity__fields[3] = {
 const upb_msglayout grpc_gcp_Identity_msginit = {
   &grpc_gcp_Identity_submsgs[0],
   &grpc_gcp_Identity__fields[0],
-  UPB_SIZE(16, 32), 3, false,
+  UPB_SIZE(16, 32), 3, false, 255,
 };
 
 static const upb_msglayout_field grpc_gcp_Identity_AttributesEntry__fields[2] = {
@@ -49,32 +49,32 @@ static const upb_msglayout_field grpc_gcp_Identity_AttributesEntry__fields[2] =
 const upb_msglayout grpc_gcp_Identity_AttributesEntry_msginit = {
   NULL,
   &grpc_gcp_Identity_AttributesEntry__fields[0],
-  UPB_SIZE(16, 32), 2, false,
+  UPB_SIZE(16, 32), 2, false, 255,
 };
 
-static const upb_msglayout *const grpc_gcp_StartClientHandshakeReq_submsgs[5] = {
+static const upb_msglayout *const grpc_gcp_StartClientHandshakeReq_submsgs[3] = {
   &grpc_gcp_Endpoint_msginit,
   &grpc_gcp_Identity_msginit,
   &grpc_gcp_RpcProtocolVersions_msginit,
 };
 
 static const upb_msglayout_field grpc_gcp_StartClientHandshakeReq__fields[10] = {
-  {1, UPB_SIZE(0, 0), 0, 0, 14, 1},
+  {1, UPB_SIZE(4, 4), 0, 0, 14, 1},
   {2, UPB_SIZE(36, 64), 0, 0, 9, 3},
   {3, UPB_SIZE(40, 72), 0, 0, 9, 3},
   {4, UPB_SIZE(44, 80), 0, 1, 11, 3},
-  {5, UPB_SIZE(20, 32), 0, 1, 11, 1},
-  {6, UPB_SIZE(24, 40), 0, 0, 11, 1},
-  {7, UPB_SIZE(28, 48), 0, 0, 11, 1},
+  {5, UPB_SIZE(20, 32), 1, 1, 11, 1},
+  {6, UPB_SIZE(24, 40), 2, 0, 11, 1},
+  {7, UPB_SIZE(28, 48), 3, 0, 11, 1},
   {8, UPB_SIZE(12, 16), 0, 0, 9, 1},
-  {9, UPB_SIZE(32, 56), 0, 2, 11, 1},
+  {9, UPB_SIZE(32, 56), 4, 2, 11, 1},
   {10, UPB_SIZE(8, 8), 0, 0, 13, 1},
 };
 
 const upb_msglayout grpc_gcp_StartClientHandshakeReq_msginit = {
   &grpc_gcp_StartClientHandshakeReq_submsgs[0],
   &grpc_gcp_StartClientHandshakeReq__fields[0],
-  UPB_SIZE(48, 96), 10, false,
+  UPB_SIZE(48, 96), 10, false, 255,
 };
 
 static const upb_msglayout *const grpc_gcp_ServerHandshakeParameters_submsgs[1] = {
@@ -89,29 +89,29 @@ static const upb_msglayout_field grpc_gcp_ServerHandshakeParameters__fields[2] =
 const upb_msglayout grpc_gcp_ServerHandshakeParameters_msginit = {
   &grpc_gcp_ServerHandshakeParameters_submsgs[0],
   &grpc_gcp_ServerHandshakeParameters__fields[0],
-  UPB_SIZE(8, 16), 2, false,
+  UPB_SIZE(8, 16), 2, false, 255,
 };
 
-static const upb_msglayout *const grpc_gcp_StartServerHandshakeReq_submsgs[4] = {
+static const upb_msglayout *const grpc_gcp_StartServerHandshakeReq_submsgs[3] = {
   &grpc_gcp_Endpoint_msginit,
   &grpc_gcp_RpcProtocolVersions_msginit,
   &grpc_gcp_StartServerHandshakeReq_HandshakeParametersEntry_msginit,
 };
 
 static const upb_msglayout_field grpc_gcp_StartServerHandshakeReq__fields[7] = {
-  {1, UPB_SIZE(24, 48), 0, 0, 9, 3},
-  {2, UPB_SIZE(28, 56), 0, 2, 11, _UPB_LABEL_MAP},
-  {3, UPB_SIZE(4, 8), 0, 0, 12, 1},
-  {4, UPB_SIZE(12, 24), 0, 0, 11, 1},
-  {5, UPB_SIZE(16, 32), 0, 0, 11, 1},
-  {6, UPB_SIZE(20, 40), 0, 1, 11, 1},
-  {7, UPB_SIZE(0, 0), 0, 0, 13, 1},
+  {1, UPB_SIZE(28, 48), 0, 0, 9, 3},
+  {2, UPB_SIZE(32, 56), 0, 2, 11, _UPB_LABEL_MAP},
+  {3, UPB_SIZE(8, 8), 0, 0, 12, 1},
+  {4, UPB_SIZE(16, 24), 1, 0, 11, 1},
+  {5, UPB_SIZE(20, 32), 2, 0, 11, 1},
+  {6, UPB_SIZE(24, 40), 3, 1, 11, 1},
+  {7, UPB_SIZE(4, 4), 0, 0, 13, 1},
 };
 
 const upb_msglayout grpc_gcp_StartServerHandshakeReq_msginit = {
   &grpc_gcp_StartServerHandshakeReq_submsgs[0],
   &grpc_gcp_StartServerHandshakeReq__fields[0],
-  UPB_SIZE(32, 64), 7, false,
+  UPB_SIZE(40, 64), 7, false, 255,
 };
 
 static const upb_msglayout *const grpc_gcp_StartServerHandshakeReq_HandshakeParametersEntry_submsgs[1] = {
@@ -126,7 +126,7 @@ static const upb_msglayout_field grpc_gcp_StartServerHandshakeReq_HandshakeParam
 const upb_msglayout grpc_gcp_StartServerHandshakeReq_HandshakeParametersEntry_msginit = {
   &grpc_gcp_StartServerHandshakeReq_HandshakeParametersEntry_submsgs[0],
   &grpc_gcp_StartServerHandshakeReq_HandshakeParametersEntry__fields[0],
-  UPB_SIZE(16, 32), 2, false,
+  UPB_SIZE(16, 32), 2, false, 255,
 };
 
 static const upb_msglayout_field grpc_gcp_NextHandshakeMessageReq__fields[1] = {
@@ -136,7 +136,7 @@ static const upb_msglayout_field grpc_gcp_NextHandshakeMessageReq__fields[1] = {
 const upb_msglayout grpc_gcp_NextHandshakeMessageReq_msginit = {
   NULL,
   &grpc_gcp_NextHandshakeMessageReq__fields[0],
-  UPB_SIZE(8, 16), 1, false,
+  UPB_SIZE(8, 16), 1, false, 255,
 };
 
 static const upb_msglayout *const grpc_gcp_HandshakerReq_submsgs[3] = {
@@ -154,29 +154,29 @@ static const upb_msglayout_field grpc_gcp_HandshakerReq__fields[3] = {
 const upb_msglayout grpc_gcp_HandshakerReq_msginit = {
   &grpc_gcp_HandshakerReq_submsgs[0],
   &grpc_gcp_HandshakerReq__fields[0],
-  UPB_SIZE(8, 16), 3, false,
+  UPB_SIZE(8, 16), 3, false, 255,
 };
 
-static const upb_msglayout *const grpc_gcp_HandshakerResult_submsgs[3] = {
+static const upb_msglayout *const grpc_gcp_HandshakerResult_submsgs[2] = {
   &grpc_gcp_Identity_msginit,
   &grpc_gcp_RpcProtocolVersions_msginit,
 };
 
 static const upb_msglayout_field grpc_gcp_HandshakerResult__fields[8] = {
-  {1, UPB_SIZE(8, 8), 0, 0, 9, 1},
-  {2, UPB_SIZE(16, 24), 0, 0, 9, 1},
-  {3, UPB_SIZE(24, 40), 0, 0, 12, 1},
-  {4, UPB_SIZE(32, 56), 0, 0, 11, 1},
-  {5, UPB_SIZE(36, 64), 0, 0, 11, 1},
-  {6, UPB_SIZE(4, 4), 0, 0, 8, 1},
-  {7, UPB_SIZE(40, 72), 0, 1, 11, 1},
-  {8, UPB_SIZE(0, 0), 0, 0, 13, 1},
+  {1, UPB_SIZE(12, 16), 0, 0, 9, 1},
+  {2, UPB_SIZE(20, 32), 0, 0, 9, 1},
+  {3, UPB_SIZE(28, 48), 0, 0, 12, 1},
+  {4, UPB_SIZE(36, 64), 1, 0, 11, 1},
+  {5, UPB_SIZE(40, 72), 2, 0, 11, 1},
+  {6, UPB_SIZE(8, 8), 0, 0, 8, 1},
+  {7, UPB_SIZE(44, 80), 3, 1, 11, 1},
+  {8, UPB_SIZE(4, 4), 0, 0, 13, 1},
 };
 
 const upb_msglayout grpc_gcp_HandshakerResult_msginit = {
   &grpc_gcp_HandshakerResult_submsgs[0],
   &grpc_gcp_HandshakerResult__fields[0],
-  UPB_SIZE(48, 80), 8, false,
+  UPB_SIZE(48, 96), 8, false, 255,
 };
 
 static const upb_msglayout_field grpc_gcp_HandshakerStatus__fields[2] = {
@@ -187,7 +187,7 @@ static const upb_msglayout_field grpc_gcp_HandshakerStatus__fields[2] = {
 const upb_msglayout grpc_gcp_HandshakerStatus_msginit = {
   NULL,
   &grpc_gcp_HandshakerStatus__fields[0],
-  UPB_SIZE(16, 32), 2, false,
+  UPB_SIZE(16, 32), 2, false, 255,
 };
 
 static const upb_msglayout *const grpc_gcp_HandshakerResp_submsgs[2] = {
@@ -196,16 +196,16 @@ static const upb_msglayout *const grpc_gcp_HandshakerResp_submsgs[2] = {
 };
 
 static const upb_msglayout_field grpc_gcp_HandshakerResp__fields[4] = {
-  {1, UPB_SIZE(4, 8), 0, 0, 12, 1},
-  {2, UPB_SIZE(0, 0), 0, 0, 13, 1},
-  {3, UPB_SIZE(12, 24), 0, 0, 11, 1},
-  {4, UPB_SIZE(16, 32), 0, 1, 11, 1},
+  {1, UPB_SIZE(8, 8), 0, 0, 12, 1},
+  {2, UPB_SIZE(4, 4), 0, 0, 13, 1},
+  {3, UPB_SIZE(16, 24), 1, 0, 11, 1},
+  {4, UPB_SIZE(20, 32), 2, 1, 11, 1},
 };
 
 const upb_msglayout grpc_gcp_HandshakerResp_msginit = {
   &grpc_gcp_HandshakerResp_submsgs[0],
   &grpc_gcp_HandshakerResp__fields[0],
-  UPB_SIZE(24, 48), 4, false,
+  UPB_SIZE(24, 48), 4, false, 255,
 };
 
 #include "upb/port_undef.inc"
index 323f3cd..e4c5bf6 100644 (file)
@@ -11,6 +11,7 @@
 
 #include "upb/msg.h"
 #include "upb/decode.h"
+#include "upb/decode_fast.h"
 #include "upb/encode.h"
 
 #include "upb/port_def.inc"
@@ -81,19 +82,25 @@ UPB_INLINE grpc_gcp_Endpoint *grpc_gcp_Endpoint_parse(const char *buf, size_t si
   grpc_gcp_Endpoint *ret = grpc_gcp_Endpoint_new(arena);
   return (ret && upb_decode(buf, size, ret, &grpc_gcp_Endpoint_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE grpc_gcp_Endpoint *grpc_gcp_Endpoint_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  grpc_gcp_Endpoint *ret = grpc_gcp_Endpoint_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &grpc_gcp_Endpoint_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *grpc_gcp_Endpoint_serialize(const grpc_gcp_Endpoint *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &grpc_gcp_Endpoint_msginit, arena, len);
 }
 
-UPB_INLINE upb_strview grpc_gcp_Endpoint_ip_address(const grpc_gcp_Endpoint *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(12, 16), upb_strview); }
-UPB_INLINE int32_t grpc_gcp_Endpoint_port(const grpc_gcp_Endpoint *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(8, 8), int32_t); }
+UPB_INLINE upb_strview grpc_gcp_Endpoint_ip_address(const grpc_gcp_Endpoint *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(8, 8), upb_strview); }
+UPB_INLINE int32_t grpc_gcp_Endpoint_port(const grpc_gcp_Endpoint *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(4, 4), int32_t); }
 UPB_INLINE int32_t grpc_gcp_Endpoint_protocol(const grpc_gcp_Endpoint *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(0, 0), int32_t); }
 
 UPB_INLINE void grpc_gcp_Endpoint_set_ip_address(grpc_gcp_Endpoint *msg, upb_strview value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(12, 16), upb_strview) = value;
+  *UPB_PTR_AT(msg, UPB_SIZE(8, 8), upb_strview) = value;
 }
 UPB_INLINE void grpc_gcp_Endpoint_set_port(grpc_gcp_Endpoint *msg, int32_t value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(8, 8), int32_t) = value;
+  *UPB_PTR_AT(msg, UPB_SIZE(4, 4), int32_t) = value;
 }
 UPB_INLINE void grpc_gcp_Endpoint_set_protocol(grpc_gcp_Endpoint *msg, int32_t value) {
   *UPB_PTR_AT(msg, UPB_SIZE(0, 0), int32_t) = value;
@@ -109,6 +116,12 @@ UPB_INLINE grpc_gcp_Identity *grpc_gcp_Identity_parse(const char *buf, size_t si
   grpc_gcp_Identity *ret = grpc_gcp_Identity_new(arena);
   return (ret && upb_decode(buf, size, ret, &grpc_gcp_Identity_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE grpc_gcp_Identity *grpc_gcp_Identity_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  grpc_gcp_Identity *ret = grpc_gcp_Identity_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &grpc_gcp_Identity_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *grpc_gcp_Identity_serialize(const grpc_gcp_Identity *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &grpc_gcp_Identity_msginit, arena, len);
 }
@@ -167,63 +180,70 @@ UPB_INLINE grpc_gcp_StartClientHandshakeReq *grpc_gcp_StartClientHandshakeReq_pa
   grpc_gcp_StartClientHandshakeReq *ret = grpc_gcp_StartClientHandshakeReq_new(arena);
   return (ret && upb_decode(buf, size, ret, &grpc_gcp_StartClientHandshakeReq_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE grpc_gcp_StartClientHandshakeReq *grpc_gcp_StartClientHandshakeReq_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  grpc_gcp_StartClientHandshakeReq *ret = grpc_gcp_StartClientHandshakeReq_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &grpc_gcp_StartClientHandshakeReq_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *grpc_gcp_StartClientHandshakeReq_serialize(const grpc_gcp_StartClientHandshakeReq *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &grpc_gcp_StartClientHandshakeReq_msginit, arena, len);
 }
 
-UPB_INLINE int32_t grpc_gcp_StartClientHandshakeReq_handshake_security_protocol(const grpc_gcp_StartClientHandshakeReq *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(0, 0), int32_t); }
+UPB_INLINE int32_t grpc_gcp_StartClientHandshakeReq_handshake_security_protocol(const grpc_gcp_StartClientHandshakeReq *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(4, 4), int32_t); }
 UPB_INLINE upb_strview const* grpc_gcp_StartClientHandshakeReq_application_protocols(const grpc_gcp_StartClientHandshakeReq *msg, size_t *len) { return (upb_strview const*)_upb_array_accessor(msg, UPB_SIZE(36, 64), len); }
 UPB_INLINE upb_strview const* grpc_gcp_StartClientHandshakeReq_record_protocols(const grpc_gcp_StartClientHandshakeReq *msg, size_t *len) { return (upb_strview const*)_upb_array_accessor(msg, UPB_SIZE(40, 72), len); }
 UPB_INLINE bool grpc_gcp_StartClientHandshakeReq_has_target_identities(const grpc_gcp_StartClientHandshakeReq *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(44, 80)); }
 UPB_INLINE const grpc_gcp_Identity* const* grpc_gcp_StartClientHandshakeReq_target_identities(const grpc_gcp_StartClientHandshakeReq *msg, size_t *len) { return (const grpc_gcp_Identity* const*)_upb_array_accessor(msg, UPB_SIZE(44, 80), len); }
-UPB_INLINE bool grpc_gcp_StartClientHandshakeReq_has_local_identity(const grpc_gcp_StartClientHandshakeReq *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(20, 32)); }
+UPB_INLINE bool grpc_gcp_StartClientHandshakeReq_has_local_identity(const grpc_gcp_StartClientHandshakeReq *msg) { return _upb_hasbit(msg, 1); }
 UPB_INLINE const grpc_gcp_Identity* grpc_gcp_StartClientHandshakeReq_local_identity(const grpc_gcp_StartClientHandshakeReq *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(20, 32), const grpc_gcp_Identity*); }
-UPB_INLINE bool grpc_gcp_StartClientHandshakeReq_has_local_endpoint(const grpc_gcp_StartClientHandshakeReq *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(24, 40)); }
+UPB_INLINE bool grpc_gcp_StartClientHandshakeReq_has_local_endpoint(const grpc_gcp_StartClientHandshakeReq *msg) { return _upb_hasbit(msg, 2); }
 UPB_INLINE const grpc_gcp_Endpoint* grpc_gcp_StartClientHandshakeReq_local_endpoint(const grpc_gcp_StartClientHandshakeReq *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(24, 40), const grpc_gcp_Endpoint*); }
-UPB_INLINE bool grpc_gcp_StartClientHandshakeReq_has_remote_endpoint(const grpc_gcp_StartClientHandshakeReq *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(28, 48)); }
+UPB_INLINE bool grpc_gcp_StartClientHandshakeReq_has_remote_endpoint(const grpc_gcp_StartClientHandshakeReq *msg) { return _upb_hasbit(msg, 3); }
 UPB_INLINE const grpc_gcp_Endpoint* grpc_gcp_StartClientHandshakeReq_remote_endpoint(const grpc_gcp_StartClientHandshakeReq *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(28, 48), const grpc_gcp_Endpoint*); }
 UPB_INLINE upb_strview grpc_gcp_StartClientHandshakeReq_target_name(const grpc_gcp_StartClientHandshakeReq *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(12, 16), upb_strview); }
-UPB_INLINE bool grpc_gcp_StartClientHandshakeReq_has_rpc_versions(const grpc_gcp_StartClientHandshakeReq *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(32, 56)); }
+UPB_INLINE bool grpc_gcp_StartClientHandshakeReq_has_rpc_versions(const grpc_gcp_StartClientHandshakeReq *msg) { return _upb_hasbit(msg, 4); }
 UPB_INLINE const struct grpc_gcp_RpcProtocolVersions* grpc_gcp_StartClientHandshakeReq_rpc_versions(const grpc_gcp_StartClientHandshakeReq *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(32, 56), const struct grpc_gcp_RpcProtocolVersions*); }
 UPB_INLINE uint32_t grpc_gcp_StartClientHandshakeReq_max_frame_size(const grpc_gcp_StartClientHandshakeReq *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(8, 8), uint32_t); }
 
 UPB_INLINE void grpc_gcp_StartClientHandshakeReq_set_handshake_security_protocol(grpc_gcp_StartClientHandshakeReq *msg, int32_t value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(0, 0), int32_t) = value;
+  *UPB_PTR_AT(msg, UPB_SIZE(4, 4), int32_t) = value;
 }
 UPB_INLINE upb_strview* grpc_gcp_StartClientHandshakeReq_mutable_application_protocols(grpc_gcp_StartClientHandshakeReq *msg, size_t *len) {
   return (upb_strview*)_upb_array_mutable_accessor(msg, UPB_SIZE(36, 64), len);
 }
 UPB_INLINE upb_strview* grpc_gcp_StartClientHandshakeReq_resize_application_protocols(grpc_gcp_StartClientHandshakeReq *msg, size_t len, upb_arena *arena) {
-  return (upb_strview*)_upb_array_resize_accessor(msg, UPB_SIZE(36, 64), len, UPB_TYPE_STRING, arena);
+  return (upb_strview*)_upb_array_resize_accessor2(msg, UPB_SIZE(36, 64), len, UPB_SIZE(3, 4), arena);
 }
 UPB_INLINE bool grpc_gcp_StartClientHandshakeReq_add_application_protocols(grpc_gcp_StartClientHandshakeReq *msg, upb_strview val, upb_arena *arena) {
-  return _upb_array_append_accessor(msg, UPB_SIZE(36, 64), UPB_SIZE(8, 16), UPB_TYPE_STRING, &val,
+  return _upb_array_append_accessor2(msg, UPB_SIZE(36, 64), UPB_SIZE(3, 4), &val,
       arena);
 }
 UPB_INLINE upb_strview* grpc_gcp_StartClientHandshakeReq_mutable_record_protocols(grpc_gcp_StartClientHandshakeReq *msg, size_t *len) {
   return (upb_strview*)_upb_array_mutable_accessor(msg, UPB_SIZE(40, 72), len);
 }
 UPB_INLINE upb_strview* grpc_gcp_StartClientHandshakeReq_resize_record_protocols(grpc_gcp_StartClientHandshakeReq *msg, size_t len, upb_arena *arena) {
-  return (upb_strview*)_upb_array_resize_accessor(msg, UPB_SIZE(40, 72), len, UPB_TYPE_STRING, arena);
+  return (upb_strview*)_upb_array_resize_accessor2(msg, UPB_SIZE(40, 72), len, UPB_SIZE(3, 4), arena);
 }
 UPB_INLINE bool grpc_gcp_StartClientHandshakeReq_add_record_protocols(grpc_gcp_StartClientHandshakeReq *msg, upb_strview val, upb_arena *arena) {
-  return _upb_array_append_accessor(msg, UPB_SIZE(40, 72), UPB_SIZE(8, 16), UPB_TYPE_STRING, &val,
+  return _upb_array_append_accessor2(msg, UPB_SIZE(40, 72), UPB_SIZE(3, 4), &val,
       arena);
 }
 UPB_INLINE grpc_gcp_Identity** grpc_gcp_StartClientHandshakeReq_mutable_target_identities(grpc_gcp_StartClientHandshakeReq *msg, size_t *len) {
   return (grpc_gcp_Identity**)_upb_array_mutable_accessor(msg, UPB_SIZE(44, 80), len);
 }
 UPB_INLINE grpc_gcp_Identity** grpc_gcp_StartClientHandshakeReq_resize_target_identities(grpc_gcp_StartClientHandshakeReq *msg, size_t len, upb_arena *arena) {
-  return (grpc_gcp_Identity**)_upb_array_resize_accessor(msg, UPB_SIZE(44, 80), len, UPB_TYPE_MESSAGE, arena);
+  return (grpc_gcp_Identity**)_upb_array_resize_accessor2(msg, UPB_SIZE(44, 80), len, UPB_SIZE(2, 3), arena);
 }
 UPB_INLINE struct grpc_gcp_Identity* grpc_gcp_StartClientHandshakeReq_add_target_identities(grpc_gcp_StartClientHandshakeReq *msg, upb_arena *arena) {
   struct grpc_gcp_Identity* sub = (struct grpc_gcp_Identity*)_upb_msg_new(&grpc_gcp_Identity_msginit, arena);
-  bool ok = _upb_array_append_accessor(
-      msg, UPB_SIZE(44, 80), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena);
+  bool ok = _upb_array_append_accessor2(
+      msg, UPB_SIZE(44, 80), UPB_SIZE(2, 3), &sub, arena);
   if (!ok) return NULL;
   return sub;
 }
 UPB_INLINE void grpc_gcp_StartClientHandshakeReq_set_local_identity(grpc_gcp_StartClientHandshakeReq *msg, grpc_gcp_Identity* value) {
+  _upb_sethas(msg, 1);
   *UPB_PTR_AT(msg, UPB_SIZE(20, 32), grpc_gcp_Identity*) = value;
 }
 UPB_INLINE struct grpc_gcp_Identity* grpc_gcp_StartClientHandshakeReq_mutable_local_identity(grpc_gcp_StartClientHandshakeReq *msg, upb_arena *arena) {
@@ -236,6 +256,7 @@ UPB_INLINE struct grpc_gcp_Identity* grpc_gcp_StartClientHandshakeReq_mutable_lo
   return sub;
 }
 UPB_INLINE void grpc_gcp_StartClientHandshakeReq_set_local_endpoint(grpc_gcp_StartClientHandshakeReq *msg, grpc_gcp_Endpoint* value) {
+  _upb_sethas(msg, 2);
   *UPB_PTR_AT(msg, UPB_SIZE(24, 40), grpc_gcp_Endpoint*) = value;
 }
 UPB_INLINE struct grpc_gcp_Endpoint* grpc_gcp_StartClientHandshakeReq_mutable_local_endpoint(grpc_gcp_StartClientHandshakeReq *msg, upb_arena *arena) {
@@ -248,6 +269,7 @@ UPB_INLINE struct grpc_gcp_Endpoint* grpc_gcp_StartClientHandshakeReq_mutable_lo
   return sub;
 }
 UPB_INLINE void grpc_gcp_StartClientHandshakeReq_set_remote_endpoint(grpc_gcp_StartClientHandshakeReq *msg, grpc_gcp_Endpoint* value) {
+  _upb_sethas(msg, 3);
   *UPB_PTR_AT(msg, UPB_SIZE(28, 48), grpc_gcp_Endpoint*) = value;
 }
 UPB_INLINE struct grpc_gcp_Endpoint* grpc_gcp_StartClientHandshakeReq_mutable_remote_endpoint(grpc_gcp_StartClientHandshakeReq *msg, upb_arena *arena) {
@@ -263,6 +285,7 @@ UPB_INLINE void grpc_gcp_StartClientHandshakeReq_set_target_name(grpc_gcp_StartC
   *UPB_PTR_AT(msg, UPB_SIZE(12, 16), upb_strview) = value;
 }
 UPB_INLINE void grpc_gcp_StartClientHandshakeReq_set_rpc_versions(grpc_gcp_StartClientHandshakeReq *msg, struct grpc_gcp_RpcProtocolVersions* value) {
+  _upb_sethas(msg, 4);
   *UPB_PTR_AT(msg, UPB_SIZE(32, 56), struct grpc_gcp_RpcProtocolVersions*) = value;
 }
 UPB_INLINE struct grpc_gcp_RpcProtocolVersions* grpc_gcp_StartClientHandshakeReq_mutable_rpc_versions(grpc_gcp_StartClientHandshakeReq *msg, upb_arena *arena) {
@@ -288,6 +311,12 @@ UPB_INLINE grpc_gcp_ServerHandshakeParameters *grpc_gcp_ServerHandshakeParameter
   grpc_gcp_ServerHandshakeParameters *ret = grpc_gcp_ServerHandshakeParameters_new(arena);
   return (ret && upb_decode(buf, size, ret, &grpc_gcp_ServerHandshakeParameters_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE grpc_gcp_ServerHandshakeParameters *grpc_gcp_ServerHandshakeParameters_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  grpc_gcp_ServerHandshakeParameters *ret = grpc_gcp_ServerHandshakeParameters_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &grpc_gcp_ServerHandshakeParameters_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *grpc_gcp_ServerHandshakeParameters_serialize(const grpc_gcp_ServerHandshakeParameters *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &grpc_gcp_ServerHandshakeParameters_msginit, arena, len);
 }
@@ -300,22 +329,22 @@ UPB_INLINE upb_strview* grpc_gcp_ServerHandshakeParameters_mutable_record_protoc
   return (upb_strview*)_upb_array_mutable_accessor(msg, UPB_SIZE(0, 0), len);
 }
 UPB_INLINE upb_strview* grpc_gcp_ServerHandshakeParameters_resize_record_protocols(grpc_gcp_ServerHandshakeParameters *msg, size_t len, upb_arena *arena) {
-  return (upb_strview*)_upb_array_resize_accessor(msg, UPB_SIZE(0, 0), len, UPB_TYPE_STRING, arena);
+  return (upb_strview*)_upb_array_resize_accessor2(msg, UPB_SIZE(0, 0), len, UPB_SIZE(3, 4), arena);
 }
 UPB_INLINE bool grpc_gcp_ServerHandshakeParameters_add_record_protocols(grpc_gcp_ServerHandshakeParameters *msg, upb_strview val, upb_arena *arena) {
-  return _upb_array_append_accessor(msg, UPB_SIZE(0, 0), UPB_SIZE(8, 16), UPB_TYPE_STRING, &val,
+  return _upb_array_append_accessor2(msg, UPB_SIZE(0, 0), UPB_SIZE(3, 4), &val,
       arena);
 }
 UPB_INLINE grpc_gcp_Identity** grpc_gcp_ServerHandshakeParameters_mutable_local_identities(grpc_gcp_ServerHandshakeParameters *msg, size_t *len) {
   return (grpc_gcp_Identity**)_upb_array_mutable_accessor(msg, UPB_SIZE(4, 8), len);
 }
 UPB_INLINE grpc_gcp_Identity** grpc_gcp_ServerHandshakeParameters_resize_local_identities(grpc_gcp_ServerHandshakeParameters *msg, size_t len, upb_arena *arena) {
-  return (grpc_gcp_Identity**)_upb_array_resize_accessor(msg, UPB_SIZE(4, 8), len, UPB_TYPE_MESSAGE, arena);
+  return (grpc_gcp_Identity**)_upb_array_resize_accessor2(msg, UPB_SIZE(4, 8), len, UPB_SIZE(2, 3), arena);
 }
 UPB_INLINE struct grpc_gcp_Identity* grpc_gcp_ServerHandshakeParameters_add_local_identities(grpc_gcp_ServerHandshakeParameters *msg, upb_arena *arena) {
   struct grpc_gcp_Identity* sub = (struct grpc_gcp_Identity*)_upb_msg_new(&grpc_gcp_Identity_msginit, arena);
-  bool ok = _upb_array_append_accessor(
-      msg, UPB_SIZE(4, 8), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena);
+  bool ok = _upb_array_append_accessor2(
+      msg, UPB_SIZE(4, 8), UPB_SIZE(2, 3), &sub, arena);
   if (!ok) return NULL;
   return sub;
 }
@@ -330,43 +359,50 @@ UPB_INLINE grpc_gcp_StartServerHandshakeReq *grpc_gcp_StartServerHandshakeReq_pa
   grpc_gcp_StartServerHandshakeReq *ret = grpc_gcp_StartServerHandshakeReq_new(arena);
   return (ret && upb_decode(buf, size, ret, &grpc_gcp_StartServerHandshakeReq_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE grpc_gcp_StartServerHandshakeReq *grpc_gcp_StartServerHandshakeReq_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  grpc_gcp_StartServerHandshakeReq *ret = grpc_gcp_StartServerHandshakeReq_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &grpc_gcp_StartServerHandshakeReq_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *grpc_gcp_StartServerHandshakeReq_serialize(const grpc_gcp_StartServerHandshakeReq *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &grpc_gcp_StartServerHandshakeReq_msginit, arena, len);
 }
 
-UPB_INLINE upb_strview const* grpc_gcp_StartServerHandshakeReq_application_protocols(const grpc_gcp_StartServerHandshakeReq *msg, size_t *len) { return (upb_strview const*)_upb_array_accessor(msg, UPB_SIZE(24, 48), len); }
-UPB_INLINE bool grpc_gcp_StartServerHandshakeReq_has_handshake_parameters(const grpc_gcp_StartServerHandshakeReq *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(28, 56)); }
-UPB_INLINE size_t grpc_gcp_StartServerHandshakeReq_handshake_parameters_size(const grpc_gcp_StartServerHandshakeReq *msg) {return _upb_msg_map_size(msg, UPB_SIZE(28, 56)); }
-UPB_INLINE bool grpc_gcp_StartServerHandshakeReq_handshake_parameters_get(const grpc_gcp_StartServerHandshakeReq *msg, int32_t key, grpc_gcp_ServerHandshakeParameters* *val) { return _upb_msg_map_get(msg, UPB_SIZE(28, 56), &key, sizeof(key), val, sizeof(*val)); }
-UPB_INLINE const grpc_gcp_StartServerHandshakeReq_HandshakeParametersEntry* grpc_gcp_StartServerHandshakeReq_handshake_parameters_next(const grpc_gcp_StartServerHandshakeReq *msg, size_t* iter) { return (const grpc_gcp_StartServerHandshakeReq_HandshakeParametersEntry*)_upb_msg_map_next(msg, UPB_SIZE(28, 56), iter); }
-UPB_INLINE upb_strview grpc_gcp_StartServerHandshakeReq_in_bytes(const grpc_gcp_StartServerHandshakeReq *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(4, 8), upb_strview); }
-UPB_INLINE bool grpc_gcp_StartServerHandshakeReq_has_local_endpoint(const grpc_gcp_StartServerHandshakeReq *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(12, 24)); }
-UPB_INLINE const grpc_gcp_Endpoint* grpc_gcp_StartServerHandshakeReq_local_endpoint(const grpc_gcp_StartServerHandshakeReq *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(12, 24), const grpc_gcp_Endpoint*); }
-UPB_INLINE bool grpc_gcp_StartServerHandshakeReq_has_remote_endpoint(const grpc_gcp_StartServerHandshakeReq *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(16, 32)); }
-UPB_INLINE const grpc_gcp_Endpoint* grpc_gcp_StartServerHandshakeReq_remote_endpoint(const grpc_gcp_StartServerHandshakeReq *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(16, 32), const grpc_gcp_Endpoint*); }
-UPB_INLINE bool grpc_gcp_StartServerHandshakeReq_has_rpc_versions(const grpc_gcp_StartServerHandshakeReq *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(20, 40)); }
-UPB_INLINE const struct grpc_gcp_RpcProtocolVersions* grpc_gcp_StartServerHandshakeReq_rpc_versions(const grpc_gcp_StartServerHandshakeReq *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(20, 40), const struct grpc_gcp_RpcProtocolVersions*); }
-UPB_INLINE uint32_t grpc_gcp_StartServerHandshakeReq_max_frame_size(const grpc_gcp_StartServerHandshakeReq *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(0, 0), uint32_t); }
+UPB_INLINE upb_strview const* grpc_gcp_StartServerHandshakeReq_application_protocols(const grpc_gcp_StartServerHandshakeReq *msg, size_t *len) { return (upb_strview const*)_upb_array_accessor(msg, UPB_SIZE(28, 48), len); }
+UPB_INLINE bool grpc_gcp_StartServerHandshakeReq_has_handshake_parameters(const grpc_gcp_StartServerHandshakeReq *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(32, 56)); }
+UPB_INLINE size_t grpc_gcp_StartServerHandshakeReq_handshake_parameters_size(const grpc_gcp_StartServerHandshakeReq *msg) {return _upb_msg_map_size(msg, UPB_SIZE(32, 56)); }
+UPB_INLINE bool grpc_gcp_StartServerHandshakeReq_handshake_parameters_get(const grpc_gcp_StartServerHandshakeReq *msg, int32_t key, grpc_gcp_ServerHandshakeParameters* *val) { return _upb_msg_map_get(msg, UPB_SIZE(32, 56), &key, sizeof(key), val, sizeof(*val)); }
+UPB_INLINE const grpc_gcp_StartServerHandshakeReq_HandshakeParametersEntry* grpc_gcp_StartServerHandshakeReq_handshake_parameters_next(const grpc_gcp_StartServerHandshakeReq *msg, size_t* iter) { return (const grpc_gcp_StartServerHandshakeReq_HandshakeParametersEntry*)_upb_msg_map_next(msg, UPB_SIZE(32, 56), iter); }
+UPB_INLINE upb_strview grpc_gcp_StartServerHandshakeReq_in_bytes(const grpc_gcp_StartServerHandshakeReq *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(8, 8), upb_strview); }
+UPB_INLINE bool grpc_gcp_StartServerHandshakeReq_has_local_endpoint(const grpc_gcp_StartServerHandshakeReq *msg) { return _upb_hasbit(msg, 1); }
+UPB_INLINE const grpc_gcp_Endpoint* grpc_gcp_StartServerHandshakeReq_local_endpoint(const grpc_gcp_StartServerHandshakeReq *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(16, 24), const grpc_gcp_Endpoint*); }
+UPB_INLINE bool grpc_gcp_StartServerHandshakeReq_has_remote_endpoint(const grpc_gcp_StartServerHandshakeReq *msg) { return _upb_hasbit(msg, 2); }
+UPB_INLINE const grpc_gcp_Endpoint* grpc_gcp_StartServerHandshakeReq_remote_endpoint(const grpc_gcp_StartServerHandshakeReq *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(20, 32), const grpc_gcp_Endpoint*); }
+UPB_INLINE bool grpc_gcp_StartServerHandshakeReq_has_rpc_versions(const grpc_gcp_StartServerHandshakeReq *msg) { return _upb_hasbit(msg, 3); }
+UPB_INLINE const struct grpc_gcp_RpcProtocolVersions* grpc_gcp_StartServerHandshakeReq_rpc_versions(const grpc_gcp_StartServerHandshakeReq *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(24, 40), const struct grpc_gcp_RpcProtocolVersions*); }
+UPB_INLINE uint32_t grpc_gcp_StartServerHandshakeReq_max_frame_size(const grpc_gcp_StartServerHandshakeReq *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(4, 4), uint32_t); }
 
 UPB_INLINE upb_strview* grpc_gcp_StartServerHandshakeReq_mutable_application_protocols(grpc_gcp_StartServerHandshakeReq *msg, size_t *len) {
-  return (upb_strview*)_upb_array_mutable_accessor(msg, UPB_SIZE(24, 48), len);
+  return (upb_strview*)_upb_array_mutable_accessor(msg, UPB_SIZE(28, 48), len);
 }
 UPB_INLINE upb_strview* grpc_gcp_StartServerHandshakeReq_resize_application_protocols(grpc_gcp_StartServerHandshakeReq *msg, size_t len, upb_arena *arena) {
-  return (upb_strview*)_upb_array_resize_accessor(msg, UPB_SIZE(24, 48), len, UPB_TYPE_STRING, arena);
+  return (upb_strview*)_upb_array_resize_accessor2(msg, UPB_SIZE(28, 48), len, UPB_SIZE(3, 4), arena);
 }
 UPB_INLINE bool grpc_gcp_StartServerHandshakeReq_add_application_protocols(grpc_gcp_StartServerHandshakeReq *msg, upb_strview val, upb_arena *arena) {
-  return _upb_array_append_accessor(msg, UPB_SIZE(24, 48), UPB_SIZE(8, 16), UPB_TYPE_STRING, &val,
+  return _upb_array_append_accessor2(msg, UPB_SIZE(28, 48), UPB_SIZE(3, 4), &val,
       arena);
 }
-UPB_INLINE void grpc_gcp_StartServerHandshakeReq_handshake_parameters_clear(grpc_gcp_StartServerHandshakeReq *msg) { _upb_msg_map_clear(msg, UPB_SIZE(28, 56)); }
-UPB_INLINE bool grpc_gcp_StartServerHandshakeReq_handshake_parameters_set(grpc_gcp_StartServerHandshakeReq *msg, int32_t key, grpc_gcp_ServerHandshakeParameters* val, upb_arena *a) { return _upb_msg_map_set(msg, UPB_SIZE(28, 56), &key, sizeof(key), &val, sizeof(val), a); }
-UPB_INLINE bool grpc_gcp_StartServerHandshakeReq_handshake_parameters_delete(grpc_gcp_StartServerHandshakeReq *msg, int32_t key) { return _upb_msg_map_delete(msg, UPB_SIZE(28, 56), &key, sizeof(key)); }
-UPB_INLINE grpc_gcp_StartServerHandshakeReq_HandshakeParametersEntry* grpc_gcp_StartServerHandshakeReq_handshake_parameters_nextmutable(grpc_gcp_StartServerHandshakeReq *msg, size_t* iter) { return (grpc_gcp_StartServerHandshakeReq_HandshakeParametersEntry*)_upb_msg_map_next(msg, UPB_SIZE(28, 56), iter); }
+UPB_INLINE void grpc_gcp_StartServerHandshakeReq_handshake_parameters_clear(grpc_gcp_StartServerHandshakeReq *msg) { _upb_msg_map_clear(msg, UPB_SIZE(32, 56)); }
+UPB_INLINE bool grpc_gcp_StartServerHandshakeReq_handshake_parameters_set(grpc_gcp_StartServerHandshakeReq *msg, int32_t key, grpc_gcp_ServerHandshakeParameters* val, upb_arena *a) { return _upb_msg_map_set(msg, UPB_SIZE(32, 56), &key, sizeof(key), &val, sizeof(val), a); }
+UPB_INLINE bool grpc_gcp_StartServerHandshakeReq_handshake_parameters_delete(grpc_gcp_StartServerHandshakeReq *msg, int32_t key) { return _upb_msg_map_delete(msg, UPB_SIZE(32, 56), &key, sizeof(key)); }
+UPB_INLINE grpc_gcp_StartServerHandshakeReq_HandshakeParametersEntry* grpc_gcp_StartServerHandshakeReq_handshake_parameters_nextmutable(grpc_gcp_StartServerHandshakeReq *msg, size_t* iter) { return (grpc_gcp_StartServerHandshakeReq_HandshakeParametersEntry*)_upb_msg_map_next(msg, UPB_SIZE(32, 56), iter); }
 UPB_INLINE void grpc_gcp_StartServerHandshakeReq_set_in_bytes(grpc_gcp_StartServerHandshakeReq *msg, upb_strview value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(4, 8), upb_strview) = value;
+  *UPB_PTR_AT(msg, UPB_SIZE(8, 8), upb_strview) = value;
 }
 UPB_INLINE void grpc_gcp_StartServerHandshakeReq_set_local_endpoint(grpc_gcp_StartServerHandshakeReq *msg, grpc_gcp_Endpoint* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(12, 24), grpc_gcp_Endpoint*) = value;
+  _upb_sethas(msg, 1);
+  *UPB_PTR_AT(msg, UPB_SIZE(16, 24), grpc_gcp_Endpoint*) = value;
 }
 UPB_INLINE struct grpc_gcp_Endpoint* grpc_gcp_StartServerHandshakeReq_mutable_local_endpoint(grpc_gcp_StartServerHandshakeReq *msg, upb_arena *arena) {
   struct grpc_gcp_Endpoint* sub = (struct grpc_gcp_Endpoint*)grpc_gcp_StartServerHandshakeReq_local_endpoint(msg);
@@ -378,7 +414,8 @@ UPB_INLINE struct grpc_gcp_Endpoint* grpc_gcp_StartServerHandshakeReq_mutable_lo
   return sub;
 }
 UPB_INLINE void grpc_gcp_StartServerHandshakeReq_set_remote_endpoint(grpc_gcp_StartServerHandshakeReq *msg, grpc_gcp_Endpoint* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(16, 32), grpc_gcp_Endpoint*) = value;
+  _upb_sethas(msg, 2);
+  *UPB_PTR_AT(msg, UPB_SIZE(20, 32), grpc_gcp_Endpoint*) = value;
 }
 UPB_INLINE struct grpc_gcp_Endpoint* grpc_gcp_StartServerHandshakeReq_mutable_remote_endpoint(grpc_gcp_StartServerHandshakeReq *msg, upb_arena *arena) {
   struct grpc_gcp_Endpoint* sub = (struct grpc_gcp_Endpoint*)grpc_gcp_StartServerHandshakeReq_remote_endpoint(msg);
@@ -390,7 +427,8 @@ UPB_INLINE struct grpc_gcp_Endpoint* grpc_gcp_StartServerHandshakeReq_mutable_re
   return sub;
 }
 UPB_INLINE void grpc_gcp_StartServerHandshakeReq_set_rpc_versions(grpc_gcp_StartServerHandshakeReq *msg, struct grpc_gcp_RpcProtocolVersions* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(20, 40), struct grpc_gcp_RpcProtocolVersions*) = value;
+  _upb_sethas(msg, 3);
+  *UPB_PTR_AT(msg, UPB_SIZE(24, 40), struct grpc_gcp_RpcProtocolVersions*) = value;
 }
 UPB_INLINE struct grpc_gcp_RpcProtocolVersions* grpc_gcp_StartServerHandshakeReq_mutable_rpc_versions(grpc_gcp_StartServerHandshakeReq *msg, upb_arena *arena) {
   struct grpc_gcp_RpcProtocolVersions* sub = (struct grpc_gcp_RpcProtocolVersions*)grpc_gcp_StartServerHandshakeReq_rpc_versions(msg);
@@ -402,7 +440,7 @@ UPB_INLINE struct grpc_gcp_RpcProtocolVersions* grpc_gcp_StartServerHandshakeReq
   return sub;
 }
 UPB_INLINE void grpc_gcp_StartServerHandshakeReq_set_max_frame_size(grpc_gcp_StartServerHandshakeReq *msg, uint32_t value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(0, 0), uint32_t) = value;
+  *UPB_PTR_AT(msg, UPB_SIZE(4, 4), uint32_t) = value;
 }
 
 /* grpc.gcp.StartServerHandshakeReq.HandshakeParametersEntry */
@@ -433,6 +471,12 @@ UPB_INLINE grpc_gcp_NextHandshakeMessageReq *grpc_gcp_NextHandshakeMessageReq_pa
   grpc_gcp_NextHandshakeMessageReq *ret = grpc_gcp_NextHandshakeMessageReq_new(arena);
   return (ret && upb_decode(buf, size, ret, &grpc_gcp_NextHandshakeMessageReq_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE grpc_gcp_NextHandshakeMessageReq *grpc_gcp_NextHandshakeMessageReq_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  grpc_gcp_NextHandshakeMessageReq *ret = grpc_gcp_NextHandshakeMessageReq_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &grpc_gcp_NextHandshakeMessageReq_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *grpc_gcp_NextHandshakeMessageReq_serialize(const grpc_gcp_NextHandshakeMessageReq *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &grpc_gcp_NextHandshakeMessageReq_msginit, arena, len);
 }
@@ -453,6 +497,12 @@ UPB_INLINE grpc_gcp_HandshakerReq *grpc_gcp_HandshakerReq_parse(const char *buf,
   grpc_gcp_HandshakerReq *ret = grpc_gcp_HandshakerReq_new(arena);
   return (ret && upb_decode(buf, size, ret, &grpc_gcp_HandshakerReq_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE grpc_gcp_HandshakerReq *grpc_gcp_HandshakerReq_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  grpc_gcp_HandshakerReq *ret = grpc_gcp_HandshakerReq_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &grpc_gcp_HandshakerReq_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *grpc_gcp_HandshakerReq_serialize(const grpc_gcp_HandshakerReq *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &grpc_gcp_HandshakerReq_msginit, arena, len);
 }
@@ -519,33 +569,40 @@ UPB_INLINE grpc_gcp_HandshakerResult *grpc_gcp_HandshakerResult_parse(const char
   grpc_gcp_HandshakerResult *ret = grpc_gcp_HandshakerResult_new(arena);
   return (ret && upb_decode(buf, size, ret, &grpc_gcp_HandshakerResult_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE grpc_gcp_HandshakerResult *grpc_gcp_HandshakerResult_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  grpc_gcp_HandshakerResult *ret = grpc_gcp_HandshakerResult_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &grpc_gcp_HandshakerResult_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *grpc_gcp_HandshakerResult_serialize(const grpc_gcp_HandshakerResult *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &grpc_gcp_HandshakerResult_msginit, arena, len);
 }
 
-UPB_INLINE upb_strview grpc_gcp_HandshakerResult_application_protocol(const grpc_gcp_HandshakerResult *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(8, 8), upb_strview); }
-UPB_INLINE upb_strview grpc_gcp_HandshakerResult_record_protocol(const grpc_gcp_HandshakerResult *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(16, 24), upb_strview); }
-UPB_INLINE upb_strview grpc_gcp_HandshakerResult_key_data(const grpc_gcp_HandshakerResult *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(24, 40), upb_strview); }
-UPB_INLINE bool grpc_gcp_HandshakerResult_has_peer_identity(const grpc_gcp_HandshakerResult *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(32, 56)); }
-UPB_INLINE const grpc_gcp_Identity* grpc_gcp_HandshakerResult_peer_identity(const grpc_gcp_HandshakerResult *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(32, 56), const grpc_gcp_Identity*); }
-UPB_INLINE bool grpc_gcp_HandshakerResult_has_local_identity(const grpc_gcp_HandshakerResult *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(36, 64)); }
-UPB_INLINE const grpc_gcp_Identity* grpc_gcp_HandshakerResult_local_identity(const grpc_gcp_HandshakerResult *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(36, 64), const grpc_gcp_Identity*); }
-UPB_INLINE bool grpc_gcp_HandshakerResult_keep_channel_open(const grpc_gcp_HandshakerResult *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(4, 4), bool); }
-UPB_INLINE bool grpc_gcp_HandshakerResult_has_peer_rpc_versions(const grpc_gcp_HandshakerResult *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(40, 72)); }
-UPB_INLINE const struct grpc_gcp_RpcProtocolVersions* grpc_gcp_HandshakerResult_peer_rpc_versions(const grpc_gcp_HandshakerResult *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(40, 72), const struct grpc_gcp_RpcProtocolVersions*); }
-UPB_INLINE uint32_t grpc_gcp_HandshakerResult_max_frame_size(const grpc_gcp_HandshakerResult *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(0, 0), uint32_t); }
+UPB_INLINE upb_strview grpc_gcp_HandshakerResult_application_protocol(const grpc_gcp_HandshakerResult *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(12, 16), upb_strview); }
+UPB_INLINE upb_strview grpc_gcp_HandshakerResult_record_protocol(const grpc_gcp_HandshakerResult *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(20, 32), upb_strview); }
+UPB_INLINE upb_strview grpc_gcp_HandshakerResult_key_data(const grpc_gcp_HandshakerResult *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(28, 48), upb_strview); }
+UPB_INLINE bool grpc_gcp_HandshakerResult_has_peer_identity(const grpc_gcp_HandshakerResult *msg) { return _upb_hasbit(msg, 1); }
+UPB_INLINE const grpc_gcp_Identity* grpc_gcp_HandshakerResult_peer_identity(const grpc_gcp_HandshakerResult *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(36, 64), const grpc_gcp_Identity*); }
+UPB_INLINE bool grpc_gcp_HandshakerResult_has_local_identity(const grpc_gcp_HandshakerResult *msg) { return _upb_hasbit(msg, 2); }
+UPB_INLINE const grpc_gcp_Identity* grpc_gcp_HandshakerResult_local_identity(const grpc_gcp_HandshakerResult *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(40, 72), const grpc_gcp_Identity*); }
+UPB_INLINE bool grpc_gcp_HandshakerResult_keep_channel_open(const grpc_gcp_HandshakerResult *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(8, 8), bool); }
+UPB_INLINE bool grpc_gcp_HandshakerResult_has_peer_rpc_versions(const grpc_gcp_HandshakerResult *msg) { return _upb_hasbit(msg, 3); }
+UPB_INLINE const struct grpc_gcp_RpcProtocolVersions* grpc_gcp_HandshakerResult_peer_rpc_versions(const grpc_gcp_HandshakerResult *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(44, 80), const struct grpc_gcp_RpcProtocolVersions*); }
+UPB_INLINE uint32_t grpc_gcp_HandshakerResult_max_frame_size(const grpc_gcp_HandshakerResult *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(4, 4), uint32_t); }
 
 UPB_INLINE void grpc_gcp_HandshakerResult_set_application_protocol(grpc_gcp_HandshakerResult *msg, upb_strview value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(8, 8), upb_strview) = value;
+  *UPB_PTR_AT(msg, UPB_SIZE(12, 16), upb_strview) = value;
 }
 UPB_INLINE void grpc_gcp_HandshakerResult_set_record_protocol(grpc_gcp_HandshakerResult *msg, upb_strview value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(16, 24), upb_strview) = value;
+  *UPB_PTR_AT(msg, UPB_SIZE(20, 32), upb_strview) = value;
 }
 UPB_INLINE void grpc_gcp_HandshakerResult_set_key_data(grpc_gcp_HandshakerResult *msg, upb_strview value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(24, 40), upb_strview) = value;
+  *UPB_PTR_AT(msg, UPB_SIZE(28, 48), upb_strview) = value;
 }
 UPB_INLINE void grpc_gcp_HandshakerResult_set_peer_identity(grpc_gcp_HandshakerResult *msg, grpc_gcp_Identity* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(32, 56), grpc_gcp_Identity*) = value;
+  _upb_sethas(msg, 1);
+  *UPB_PTR_AT(msg, UPB_SIZE(36, 64), grpc_gcp_Identity*) = value;
 }
 UPB_INLINE struct grpc_gcp_Identity* grpc_gcp_HandshakerResult_mutable_peer_identity(grpc_gcp_HandshakerResult *msg, upb_arena *arena) {
   struct grpc_gcp_Identity* sub = (struct grpc_gcp_Identity*)grpc_gcp_HandshakerResult_peer_identity(msg);
@@ -557,7 +614,8 @@ UPB_INLINE struct grpc_gcp_Identity* grpc_gcp_HandshakerResult_mutable_peer_iden
   return sub;
 }
 UPB_INLINE void grpc_gcp_HandshakerResult_set_local_identity(grpc_gcp_HandshakerResult *msg, grpc_gcp_Identity* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(36, 64), grpc_gcp_Identity*) = value;
+  _upb_sethas(msg, 2);
+  *UPB_PTR_AT(msg, UPB_SIZE(40, 72), grpc_gcp_Identity*) = value;
 }
 UPB_INLINE struct grpc_gcp_Identity* grpc_gcp_HandshakerResult_mutable_local_identity(grpc_gcp_HandshakerResult *msg, upb_arena *arena) {
   struct grpc_gcp_Identity* sub = (struct grpc_gcp_Identity*)grpc_gcp_HandshakerResult_local_identity(msg);
@@ -569,10 +627,11 @@ UPB_INLINE struct grpc_gcp_Identity* grpc_gcp_HandshakerResult_mutable_local_ide
   return sub;
 }
 UPB_INLINE void grpc_gcp_HandshakerResult_set_keep_channel_open(grpc_gcp_HandshakerResult *msg, bool value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(4, 4), bool) = value;
+  *UPB_PTR_AT(msg, UPB_SIZE(8, 8), bool) = value;
 }
 UPB_INLINE void grpc_gcp_HandshakerResult_set_peer_rpc_versions(grpc_gcp_HandshakerResult *msg, struct grpc_gcp_RpcProtocolVersions* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(40, 72), struct grpc_gcp_RpcProtocolVersions*) = value;
+  _upb_sethas(msg, 3);
+  *UPB_PTR_AT(msg, UPB_SIZE(44, 80), struct grpc_gcp_RpcProtocolVersions*) = value;
 }
 UPB_INLINE struct grpc_gcp_RpcProtocolVersions* grpc_gcp_HandshakerResult_mutable_peer_rpc_versions(grpc_gcp_HandshakerResult *msg, upb_arena *arena) {
   struct grpc_gcp_RpcProtocolVersions* sub = (struct grpc_gcp_RpcProtocolVersions*)grpc_gcp_HandshakerResult_peer_rpc_versions(msg);
@@ -584,7 +643,7 @@ UPB_INLINE struct grpc_gcp_RpcProtocolVersions* grpc_gcp_HandshakerResult_mutabl
   return sub;
 }
 UPB_INLINE void grpc_gcp_HandshakerResult_set_max_frame_size(grpc_gcp_HandshakerResult *msg, uint32_t value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(0, 0), uint32_t) = value;
+  *UPB_PTR_AT(msg, UPB_SIZE(4, 4), uint32_t) = value;
 }
 
 /* grpc.gcp.HandshakerStatus */
@@ -597,6 +656,12 @@ UPB_INLINE grpc_gcp_HandshakerStatus *grpc_gcp_HandshakerStatus_parse(const char
   grpc_gcp_HandshakerStatus *ret = grpc_gcp_HandshakerStatus_new(arena);
   return (ret && upb_decode(buf, size, ret, &grpc_gcp_HandshakerStatus_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE grpc_gcp_HandshakerStatus *grpc_gcp_HandshakerStatus_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  grpc_gcp_HandshakerStatus *ret = grpc_gcp_HandshakerStatus_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &grpc_gcp_HandshakerStatus_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *grpc_gcp_HandshakerStatus_serialize(const grpc_gcp_HandshakerStatus *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &grpc_gcp_HandshakerStatus_msginit, arena, len);
 }
@@ -621,25 +686,32 @@ UPB_INLINE grpc_gcp_HandshakerResp *grpc_gcp_HandshakerResp_parse(const char *bu
   grpc_gcp_HandshakerResp *ret = grpc_gcp_HandshakerResp_new(arena);
   return (ret && upb_decode(buf, size, ret, &grpc_gcp_HandshakerResp_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE grpc_gcp_HandshakerResp *grpc_gcp_HandshakerResp_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  grpc_gcp_HandshakerResp *ret = grpc_gcp_HandshakerResp_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &grpc_gcp_HandshakerResp_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *grpc_gcp_HandshakerResp_serialize(const grpc_gcp_HandshakerResp *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &grpc_gcp_HandshakerResp_msginit, arena, len);
 }
 
-UPB_INLINE upb_strview grpc_gcp_HandshakerResp_out_frames(const grpc_gcp_HandshakerResp *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(4, 8), upb_strview); }
-UPB_INLINE uint32_t grpc_gcp_HandshakerResp_bytes_consumed(const grpc_gcp_HandshakerResp *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(0, 0), uint32_t); }
-UPB_INLINE bool grpc_gcp_HandshakerResp_has_result(const grpc_gcp_HandshakerResp *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(12, 24)); }
-UPB_INLINE const grpc_gcp_HandshakerResult* grpc_gcp_HandshakerResp_result(const grpc_gcp_HandshakerResp *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(12, 24), const grpc_gcp_HandshakerResult*); }
-UPB_INLINE bool grpc_gcp_HandshakerResp_has_status(const grpc_gcp_HandshakerResp *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(16, 32)); }
-UPB_INLINE const grpc_gcp_HandshakerStatus* grpc_gcp_HandshakerResp_status(const grpc_gcp_HandshakerResp *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(16, 32), const grpc_gcp_HandshakerStatus*); }
+UPB_INLINE upb_strview grpc_gcp_HandshakerResp_out_frames(const grpc_gcp_HandshakerResp *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(8, 8), upb_strview); }
+UPB_INLINE uint32_t grpc_gcp_HandshakerResp_bytes_consumed(const grpc_gcp_HandshakerResp *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(4, 4), uint32_t); }
+UPB_INLINE bool grpc_gcp_HandshakerResp_has_result(const grpc_gcp_HandshakerResp *msg) { return _upb_hasbit(msg, 1); }
+UPB_INLINE const grpc_gcp_HandshakerResult* grpc_gcp_HandshakerResp_result(const grpc_gcp_HandshakerResp *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(16, 24), const grpc_gcp_HandshakerResult*); }
+UPB_INLINE bool grpc_gcp_HandshakerResp_has_status(const grpc_gcp_HandshakerResp *msg) { return _upb_hasbit(msg, 2); }
+UPB_INLINE const grpc_gcp_HandshakerStatus* grpc_gcp_HandshakerResp_status(const grpc_gcp_HandshakerResp *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(20, 32), const grpc_gcp_HandshakerStatus*); }
 
 UPB_INLINE void grpc_gcp_HandshakerResp_set_out_frames(grpc_gcp_HandshakerResp *msg, upb_strview value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(4, 8), upb_strview) = value;
+  *UPB_PTR_AT(msg, UPB_SIZE(8, 8), upb_strview) = value;
 }
 UPB_INLINE void grpc_gcp_HandshakerResp_set_bytes_consumed(grpc_gcp_HandshakerResp *msg, uint32_t value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(0, 0), uint32_t) = value;
+  *UPB_PTR_AT(msg, UPB_SIZE(4, 4), uint32_t) = value;
 }
 UPB_INLINE void grpc_gcp_HandshakerResp_set_result(grpc_gcp_HandshakerResp *msg, grpc_gcp_HandshakerResult* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(12, 24), grpc_gcp_HandshakerResult*) = value;
+  _upb_sethas(msg, 1);
+  *UPB_PTR_AT(msg, UPB_SIZE(16, 24), grpc_gcp_HandshakerResult*) = value;
 }
 UPB_INLINE struct grpc_gcp_HandshakerResult* grpc_gcp_HandshakerResp_mutable_result(grpc_gcp_HandshakerResp *msg, upb_arena *arena) {
   struct grpc_gcp_HandshakerResult* sub = (struct grpc_gcp_HandshakerResult*)grpc_gcp_HandshakerResp_result(msg);
@@ -651,7 +723,8 @@ UPB_INLINE struct grpc_gcp_HandshakerResult* grpc_gcp_HandshakerResp_mutable_res
   return sub;
 }
 UPB_INLINE void grpc_gcp_HandshakerResp_set_status(grpc_gcp_HandshakerResp *msg, grpc_gcp_HandshakerStatus* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(16, 32), grpc_gcp_HandshakerStatus*) = value;
+  _upb_sethas(msg, 2);
+  *UPB_PTR_AT(msg, UPB_SIZE(20, 32), grpc_gcp_HandshakerStatus*) = value;
 }
 UPB_INLINE struct grpc_gcp_HandshakerStatus* grpc_gcp_HandshakerResp_mutable_status(grpc_gcp_HandshakerResp *msg, upb_arena *arena) {
   struct grpc_gcp_HandshakerStatus* sub = (struct grpc_gcp_HandshakerStatus*)grpc_gcp_HandshakerResp_status(msg);
index 9b63034..136c30d 100644 (file)
 
 #include "upb/port_def.inc"
 
-static const upb_msglayout *const grpc_gcp_RpcProtocolVersions_submsgs[2] = {
+static const upb_msglayout *const grpc_gcp_RpcProtocolVersions_submsgs[1] = {
   &grpc_gcp_RpcProtocolVersions_Version_msginit,
 };
 
 static const upb_msglayout_field grpc_gcp_RpcProtocolVersions__fields[2] = {
-  {1, UPB_SIZE(0, 0), 0, 0, 11, 1},
-  {2, UPB_SIZE(4, 8), 0, 0, 11, 1},
+  {1, UPB_SIZE(4, 8), 1, 0, 11, 1},
+  {2, UPB_SIZE(8, 16), 2, 0, 11, 1},
 };
 
 const upb_msglayout grpc_gcp_RpcProtocolVersions_msginit = {
   &grpc_gcp_RpcProtocolVersions_submsgs[0],
   &grpc_gcp_RpcProtocolVersions__fields[0],
-  UPB_SIZE(8, 16), 2, false,
+  UPB_SIZE(16, 24), 2, false, 255,
 };
 
 static const upb_msglayout_field grpc_gcp_RpcProtocolVersions_Version__fields[2] = {
@@ -35,7 +35,7 @@ static const upb_msglayout_field grpc_gcp_RpcProtocolVersions_Version__fields[2]
 const upb_msglayout grpc_gcp_RpcProtocolVersions_Version_msginit = {
   NULL,
   &grpc_gcp_RpcProtocolVersions_Version__fields[0],
-  UPB_SIZE(8, 8), 2, false,
+  UPB_SIZE(8, 8), 2, false, 255,
 };
 
 #include "upb/port_undef.inc"
index 5296398..9e02e0b 100644 (file)
@@ -11,6 +11,7 @@
 
 #include "upb/msg.h"
 #include "upb/decode.h"
+#include "upb/decode_fast.h"
 #include "upb/encode.h"
 
 #include "upb/port_def.inc"
@@ -43,17 +44,24 @@ UPB_INLINE grpc_gcp_RpcProtocolVersions *grpc_gcp_RpcProtocolVersions_parse(cons
   grpc_gcp_RpcProtocolVersions *ret = grpc_gcp_RpcProtocolVersions_new(arena);
   return (ret && upb_decode(buf, size, ret, &grpc_gcp_RpcProtocolVersions_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE grpc_gcp_RpcProtocolVersions *grpc_gcp_RpcProtocolVersions_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  grpc_gcp_RpcProtocolVersions *ret = grpc_gcp_RpcProtocolVersions_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &grpc_gcp_RpcProtocolVersions_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *grpc_gcp_RpcProtocolVersions_serialize(const grpc_gcp_RpcProtocolVersions *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &grpc_gcp_RpcProtocolVersions_msginit, arena, len);
 }
 
-UPB_INLINE bool grpc_gcp_RpcProtocolVersions_has_max_rpc_version(const grpc_gcp_RpcProtocolVersions *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(0, 0)); }
-UPB_INLINE const grpc_gcp_RpcProtocolVersions_Version* grpc_gcp_RpcProtocolVersions_max_rpc_version(const grpc_gcp_RpcProtocolVersions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(0, 0), const grpc_gcp_RpcProtocolVersions_Version*); }
-UPB_INLINE bool grpc_gcp_RpcProtocolVersions_has_min_rpc_version(const grpc_gcp_RpcProtocolVersions *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(4, 8)); }
-UPB_INLINE const grpc_gcp_RpcProtocolVersions_Version* grpc_gcp_RpcProtocolVersions_min_rpc_version(const grpc_gcp_RpcProtocolVersions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(4, 8), const grpc_gcp_RpcProtocolVersions_Version*); }
+UPB_INLINE bool grpc_gcp_RpcProtocolVersions_has_max_rpc_version(const grpc_gcp_RpcProtocolVersions *msg) { return _upb_hasbit(msg, 1); }
+UPB_INLINE const grpc_gcp_RpcProtocolVersions_Version* grpc_gcp_RpcProtocolVersions_max_rpc_version(const grpc_gcp_RpcProtocolVersions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(4, 8), const grpc_gcp_RpcProtocolVersions_Version*); }
+UPB_INLINE bool grpc_gcp_RpcProtocolVersions_has_min_rpc_version(const grpc_gcp_RpcProtocolVersions *msg) { return _upb_hasbit(msg, 2); }
+UPB_INLINE const grpc_gcp_RpcProtocolVersions_Version* grpc_gcp_RpcProtocolVersions_min_rpc_version(const grpc_gcp_RpcProtocolVersions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(8, 16), const grpc_gcp_RpcProtocolVersions_Version*); }
 
 UPB_INLINE void grpc_gcp_RpcProtocolVersions_set_max_rpc_version(grpc_gcp_RpcProtocolVersions *msg, grpc_gcp_RpcProtocolVersions_Version* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(0, 0), grpc_gcp_RpcProtocolVersions_Version*) = value;
+  _upb_sethas(msg, 1);
+  *UPB_PTR_AT(msg, UPB_SIZE(4, 8), grpc_gcp_RpcProtocolVersions_Version*) = value;
 }
 UPB_INLINE struct grpc_gcp_RpcProtocolVersions_Version* grpc_gcp_RpcProtocolVersions_mutable_max_rpc_version(grpc_gcp_RpcProtocolVersions *msg, upb_arena *arena) {
   struct grpc_gcp_RpcProtocolVersions_Version* sub = (struct grpc_gcp_RpcProtocolVersions_Version*)grpc_gcp_RpcProtocolVersions_max_rpc_version(msg);
@@ -65,7 +73,8 @@ UPB_INLINE struct grpc_gcp_RpcProtocolVersions_Version* grpc_gcp_RpcProtocolVers
   return sub;
 }
 UPB_INLINE void grpc_gcp_RpcProtocolVersions_set_min_rpc_version(grpc_gcp_RpcProtocolVersions *msg, grpc_gcp_RpcProtocolVersions_Version* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(4, 8), grpc_gcp_RpcProtocolVersions_Version*) = value;
+  _upb_sethas(msg, 2);
+  *UPB_PTR_AT(msg, UPB_SIZE(8, 16), grpc_gcp_RpcProtocolVersions_Version*) = value;
 }
 UPB_INLINE struct grpc_gcp_RpcProtocolVersions_Version* grpc_gcp_RpcProtocolVersions_mutable_min_rpc_version(grpc_gcp_RpcProtocolVersions *msg, upb_arena *arena) {
   struct grpc_gcp_RpcProtocolVersions_Version* sub = (struct grpc_gcp_RpcProtocolVersions_Version*)grpc_gcp_RpcProtocolVersions_min_rpc_version(msg);
@@ -87,6 +96,12 @@ UPB_INLINE grpc_gcp_RpcProtocolVersions_Version *grpc_gcp_RpcProtocolVersions_Ve
   grpc_gcp_RpcProtocolVersions_Version *ret = grpc_gcp_RpcProtocolVersions_Version_new(arena);
   return (ret && upb_decode(buf, size, ret, &grpc_gcp_RpcProtocolVersions_Version_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE grpc_gcp_RpcProtocolVersions_Version *grpc_gcp_RpcProtocolVersions_Version_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  grpc_gcp_RpcProtocolVersions_Version *ret = grpc_gcp_RpcProtocolVersions_Version_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &grpc_gcp_RpcProtocolVersions_Version_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *grpc_gcp_RpcProtocolVersions_Version_serialize(const grpc_gcp_RpcProtocolVersions_Version *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &grpc_gcp_RpcProtocolVersions_Version_msginit, arena, len);
 }
index 8a3359b..df8d846 100644 (file)
@@ -19,7 +19,7 @@ static const upb_msglayout_field grpc_health_v1_HealthCheckRequest__fields[1] =
 const upb_msglayout grpc_health_v1_HealthCheckRequest_msginit = {
   NULL,
   &grpc_health_v1_HealthCheckRequest__fields[0],
-  UPB_SIZE(8, 16), 1, false,
+  UPB_SIZE(8, 16), 1, false, 255,
 };
 
 static const upb_msglayout_field grpc_health_v1_HealthCheckResponse__fields[1] = {
@@ -29,7 +29,7 @@ static const upb_msglayout_field grpc_health_v1_HealthCheckResponse__fields[1] =
 const upb_msglayout grpc_health_v1_HealthCheckResponse_msginit = {
   NULL,
   &grpc_health_v1_HealthCheckResponse__fields[0],
-  UPB_SIZE(8, 8), 1, false,
+  UPB_SIZE(8, 8), 1, false, 255,
 };
 
 #include "upb/port_undef.inc"
index d3f6471..361b221 100644 (file)
@@ -11,6 +11,7 @@
 
 #include "upb/msg.h"
 #include "upb/decode.h"
+#include "upb/decode_fast.h"
 #include "upb/encode.h"
 
 #include "upb/port_def.inc"
@@ -44,6 +45,12 @@ UPB_INLINE grpc_health_v1_HealthCheckRequest *grpc_health_v1_HealthCheckRequest_
   grpc_health_v1_HealthCheckRequest *ret = grpc_health_v1_HealthCheckRequest_new(arena);
   return (ret && upb_decode(buf, size, ret, &grpc_health_v1_HealthCheckRequest_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE grpc_health_v1_HealthCheckRequest *grpc_health_v1_HealthCheckRequest_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  grpc_health_v1_HealthCheckRequest *ret = grpc_health_v1_HealthCheckRequest_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &grpc_health_v1_HealthCheckRequest_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *grpc_health_v1_HealthCheckRequest_serialize(const grpc_health_v1_HealthCheckRequest *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &grpc_health_v1_HealthCheckRequest_msginit, arena, len);
 }
@@ -64,6 +71,12 @@ UPB_INLINE grpc_health_v1_HealthCheckResponse *grpc_health_v1_HealthCheckRespons
   grpc_health_v1_HealthCheckResponse *ret = grpc_health_v1_HealthCheckResponse_new(arena);
   return (ret && upb_decode(buf, size, ret, &grpc_health_v1_HealthCheckResponse_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE grpc_health_v1_HealthCheckResponse *grpc_health_v1_HealthCheckResponse_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  grpc_health_v1_HealthCheckResponse *ret = grpc_health_v1_HealthCheckResponse_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &grpc_health_v1_HealthCheckResponse_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *grpc_health_v1_HealthCheckResponse_serialize(const grpc_health_v1_HealthCheckResponse *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &grpc_health_v1_HealthCheckResponse_msginit, arena, len);
 }
index 90b7cb7..3ecf09f 100644 (file)
@@ -27,7 +27,7 @@ static const upb_msglayout_field grpc_lb_v1_LoadBalanceRequest__fields[2] = {
 const upb_msglayout grpc_lb_v1_LoadBalanceRequest_msginit = {
   &grpc_lb_v1_LoadBalanceRequest_submsgs[0],
   &grpc_lb_v1_LoadBalanceRequest__fields[0],
-  UPB_SIZE(8, 16), 2, false,
+  UPB_SIZE(8, 16), 2, false, 255,
 };
 
 static const upb_msglayout_field grpc_lb_v1_InitialLoadBalanceRequest__fields[1] = {
@@ -37,7 +37,7 @@ static const upb_msglayout_field grpc_lb_v1_InitialLoadBalanceRequest__fields[1]
 const upb_msglayout grpc_lb_v1_InitialLoadBalanceRequest_msginit = {
   NULL,
   &grpc_lb_v1_InitialLoadBalanceRequest__fields[0],
-  UPB_SIZE(8, 16), 1, false,
+  UPB_SIZE(8, 16), 1, false, 255,
 };
 
 static const upb_msglayout_field grpc_lb_v1_ClientStatsPerToken__fields[2] = {
@@ -48,7 +48,7 @@ static const upb_msglayout_field grpc_lb_v1_ClientStatsPerToken__fields[2] = {
 const upb_msglayout grpc_lb_v1_ClientStatsPerToken_msginit = {
   NULL,
   &grpc_lb_v1_ClientStatsPerToken__fields[0],
-  UPB_SIZE(16, 32), 2, false,
+  UPB_SIZE(16, 32), 2, false, 255,
 };
 
 static const upb_msglayout *const grpc_lb_v1_ClientStats_submsgs[2] = {
@@ -57,18 +57,18 @@ static const upb_msglayout *const grpc_lb_v1_ClientStats_submsgs[2] = {
 };
 
 static const upb_msglayout_field grpc_lb_v1_ClientStats__fields[6] = {
-  {1, UPB_SIZE(32, 32), 0, 0, 11, 1},
-  {2, UPB_SIZE(0, 0), 0, 0, 3, 1},
-  {3, UPB_SIZE(8, 8), 0, 0, 3, 1},
-  {6, UPB_SIZE(16, 16), 0, 0, 3, 1},
-  {7, UPB_SIZE(24, 24), 0, 0, 3, 1},
-  {8, UPB_SIZE(36, 40), 0, 1, 11, 3},
+  {1, UPB_SIZE(40, 40), 1, 0, 11, 1},
+  {2, UPB_SIZE(8, 8), 0, 0, 3, 1},
+  {3, UPB_SIZE(16, 16), 0, 0, 3, 1},
+  {6, UPB_SIZE(24, 24), 0, 0, 3, 1},
+  {7, UPB_SIZE(32, 32), 0, 0, 3, 1},
+  {8, UPB_SIZE(44, 48), 0, 1, 11, 3},
 };
 
 const upb_msglayout grpc_lb_v1_ClientStats_msginit = {
   &grpc_lb_v1_ClientStats_submsgs[0],
   &grpc_lb_v1_ClientStats__fields[0],
-  UPB_SIZE(40, 48), 6, false,
+  UPB_SIZE(48, 56), 6, false, 255,
 };
 
 static const upb_msglayout *const grpc_lb_v1_LoadBalanceResponse_submsgs[3] = {
@@ -86,7 +86,7 @@ static const upb_msglayout_field grpc_lb_v1_LoadBalanceResponse__fields[3] = {
 const upb_msglayout grpc_lb_v1_LoadBalanceResponse_msginit = {
   &grpc_lb_v1_LoadBalanceResponse_submsgs[0],
   &grpc_lb_v1_LoadBalanceResponse__fields[0],
-  UPB_SIZE(8, 16), 3, false,
+  UPB_SIZE(8, 16), 3, false, 255,
 };
 
 static const upb_msglayout *const grpc_lb_v1_InitialLoadBalanceResponse_submsgs[1] = {
@@ -94,14 +94,14 @@ static const upb_msglayout *const grpc_lb_v1_InitialLoadBalanceResponse_submsgs[
 };
 
 static const upb_msglayout_field grpc_lb_v1_InitialLoadBalanceResponse__fields[2] = {
-  {1, UPB_SIZE(0, 0), 0, 0, 9, 1},
-  {2, UPB_SIZE(8, 16), 0, 0, 11, 1},
+  {1, UPB_SIZE(4, 8), 0, 0, 9, 1},
+  {2, UPB_SIZE(12, 24), 1, 0, 11, 1},
 };
 
 const upb_msglayout grpc_lb_v1_InitialLoadBalanceResponse_msginit = {
   &grpc_lb_v1_InitialLoadBalanceResponse_submsgs[0],
   &grpc_lb_v1_InitialLoadBalanceResponse__fields[0],
-  UPB_SIZE(16, 32), 2, false,
+  UPB_SIZE(16, 32), 2, false, 255,
 };
 
 static const upb_msglayout *const grpc_lb_v1_ServerList_submsgs[1] = {
@@ -115,7 +115,7 @@ static const upb_msglayout_field grpc_lb_v1_ServerList__fields[1] = {
 const upb_msglayout grpc_lb_v1_ServerList_msginit = {
   &grpc_lb_v1_ServerList_submsgs[0],
   &grpc_lb_v1_ServerList__fields[0],
-  UPB_SIZE(4, 8), 1, false,
+  UPB_SIZE(8, 8), 1, false, 255,
 };
 
 static const upb_msglayout_field grpc_lb_v1_Server__fields[4] = {
@@ -128,13 +128,13 @@ static const upb_msglayout_field grpc_lb_v1_Server__fields[4] = {
 const upb_msglayout grpc_lb_v1_Server_msginit = {
   NULL,
   &grpc_lb_v1_Server__fields[0],
-  UPB_SIZE(24, 48), 4, false,
+  UPB_SIZE(24, 48), 4, false, 255,
 };
 
 const upb_msglayout grpc_lb_v1_FallbackResponse_msginit = {
   NULL,
   NULL,
-  UPB_SIZE(0, 0), 0, false,
+  UPB_SIZE(0, 0), 0, false, 255,
 };
 
 #include "upb/port_undef.inc"
index 2ce5afc..c8c352c 100644 (file)
@@ -11,6 +11,7 @@
 
 #include "upb/msg.h"
 #include "upb/decode.h"
+#include "upb/decode_fast.h"
 #include "upb/encode.h"
 
 #include "upb/port_def.inc"
@@ -62,6 +63,12 @@ UPB_INLINE grpc_lb_v1_LoadBalanceRequest *grpc_lb_v1_LoadBalanceRequest_parse(co
   grpc_lb_v1_LoadBalanceRequest *ret = grpc_lb_v1_LoadBalanceRequest_new(arena);
   return (ret && upb_decode(buf, size, ret, &grpc_lb_v1_LoadBalanceRequest_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE grpc_lb_v1_LoadBalanceRequest *grpc_lb_v1_LoadBalanceRequest_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  grpc_lb_v1_LoadBalanceRequest *ret = grpc_lb_v1_LoadBalanceRequest_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &grpc_lb_v1_LoadBalanceRequest_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *grpc_lb_v1_LoadBalanceRequest_serialize(const grpc_lb_v1_LoadBalanceRequest *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &grpc_lb_v1_LoadBalanceRequest_msginit, arena, len);
 }
@@ -113,6 +120,12 @@ UPB_INLINE grpc_lb_v1_InitialLoadBalanceRequest *grpc_lb_v1_InitialLoadBalanceRe
   grpc_lb_v1_InitialLoadBalanceRequest *ret = grpc_lb_v1_InitialLoadBalanceRequest_new(arena);
   return (ret && upb_decode(buf, size, ret, &grpc_lb_v1_InitialLoadBalanceRequest_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE grpc_lb_v1_InitialLoadBalanceRequest *grpc_lb_v1_InitialLoadBalanceRequest_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  grpc_lb_v1_InitialLoadBalanceRequest *ret = grpc_lb_v1_InitialLoadBalanceRequest_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &grpc_lb_v1_InitialLoadBalanceRequest_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *grpc_lb_v1_InitialLoadBalanceRequest_serialize(const grpc_lb_v1_InitialLoadBalanceRequest *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &grpc_lb_v1_InitialLoadBalanceRequest_msginit, arena, len);
 }
@@ -133,6 +146,12 @@ UPB_INLINE grpc_lb_v1_ClientStatsPerToken *grpc_lb_v1_ClientStatsPerToken_parse(
   grpc_lb_v1_ClientStatsPerToken *ret = grpc_lb_v1_ClientStatsPerToken_new(arena);
   return (ret && upb_decode(buf, size, ret, &grpc_lb_v1_ClientStatsPerToken_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE grpc_lb_v1_ClientStatsPerToken *grpc_lb_v1_ClientStatsPerToken_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  grpc_lb_v1_ClientStatsPerToken *ret = grpc_lb_v1_ClientStatsPerToken_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &grpc_lb_v1_ClientStatsPerToken_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *grpc_lb_v1_ClientStatsPerToken_serialize(const grpc_lb_v1_ClientStatsPerToken *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &grpc_lb_v1_ClientStatsPerToken_msginit, arena, len);
 }
@@ -157,21 +176,28 @@ UPB_INLINE grpc_lb_v1_ClientStats *grpc_lb_v1_ClientStats_parse(const char *buf,
   grpc_lb_v1_ClientStats *ret = grpc_lb_v1_ClientStats_new(arena);
   return (ret && upb_decode(buf, size, ret, &grpc_lb_v1_ClientStats_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE grpc_lb_v1_ClientStats *grpc_lb_v1_ClientStats_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  grpc_lb_v1_ClientStats *ret = grpc_lb_v1_ClientStats_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &grpc_lb_v1_ClientStats_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *grpc_lb_v1_ClientStats_serialize(const grpc_lb_v1_ClientStats *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &grpc_lb_v1_ClientStats_msginit, arena, len);
 }
 
-UPB_INLINE bool grpc_lb_v1_ClientStats_has_timestamp(const grpc_lb_v1_ClientStats *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(32, 32)); }
-UPB_INLINE const struct google_protobuf_Timestamp* grpc_lb_v1_ClientStats_timestamp(const grpc_lb_v1_ClientStats *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(32, 32), const struct google_protobuf_Timestamp*); }
-UPB_INLINE int64_t grpc_lb_v1_ClientStats_num_calls_started(const grpc_lb_v1_ClientStats *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(0, 0), int64_t); }
-UPB_INLINE int64_t grpc_lb_v1_ClientStats_num_calls_finished(const grpc_lb_v1_ClientStats *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(8, 8), int64_t); }
-UPB_INLINE int64_t grpc_lb_v1_ClientStats_num_calls_finished_with_client_failed_to_send(const grpc_lb_v1_ClientStats *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(16, 16), int64_t); }
-UPB_INLINE int64_t grpc_lb_v1_ClientStats_num_calls_finished_known_received(const grpc_lb_v1_ClientStats *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(24, 24), int64_t); }
-UPB_INLINE bool grpc_lb_v1_ClientStats_has_calls_finished_with_drop(const grpc_lb_v1_ClientStats *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(36, 40)); }
-UPB_INLINE const grpc_lb_v1_ClientStatsPerToken* const* grpc_lb_v1_ClientStats_calls_finished_with_drop(const grpc_lb_v1_ClientStats *msg, size_t *len) { return (const grpc_lb_v1_ClientStatsPerToken* const*)_upb_array_accessor(msg, UPB_SIZE(36, 40), len); }
+UPB_INLINE bool grpc_lb_v1_ClientStats_has_timestamp(const grpc_lb_v1_ClientStats *msg) { return _upb_hasbit(msg, 1); }
+UPB_INLINE const struct google_protobuf_Timestamp* grpc_lb_v1_ClientStats_timestamp(const grpc_lb_v1_ClientStats *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(40, 40), const struct google_protobuf_Timestamp*); }
+UPB_INLINE int64_t grpc_lb_v1_ClientStats_num_calls_started(const grpc_lb_v1_ClientStats *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(8, 8), int64_t); }
+UPB_INLINE int64_t grpc_lb_v1_ClientStats_num_calls_finished(const grpc_lb_v1_ClientStats *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(16, 16), int64_t); }
+UPB_INLINE int64_t grpc_lb_v1_ClientStats_num_calls_finished_with_client_failed_to_send(const grpc_lb_v1_ClientStats *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(24, 24), int64_t); }
+UPB_INLINE int64_t grpc_lb_v1_ClientStats_num_calls_finished_known_received(const grpc_lb_v1_ClientStats *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(32, 32), int64_t); }
+UPB_INLINE bool grpc_lb_v1_ClientStats_has_calls_finished_with_drop(const grpc_lb_v1_ClientStats *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(44, 48)); }
+UPB_INLINE const grpc_lb_v1_ClientStatsPerToken* const* grpc_lb_v1_ClientStats_calls_finished_with_drop(const grpc_lb_v1_ClientStats *msg, size_t *len) { return (const grpc_lb_v1_ClientStatsPerToken* const*)_upb_array_accessor(msg, UPB_SIZE(44, 48), len); }
 
 UPB_INLINE void grpc_lb_v1_ClientStats_set_timestamp(grpc_lb_v1_ClientStats *msg, struct google_protobuf_Timestamp* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(32, 32), struct google_protobuf_Timestamp*) = value;
+  _upb_sethas(msg, 1);
+  *UPB_PTR_AT(msg, UPB_SIZE(40, 40), struct google_protobuf_Timestamp*) = value;
 }
 UPB_INLINE struct google_protobuf_Timestamp* grpc_lb_v1_ClientStats_mutable_timestamp(grpc_lb_v1_ClientStats *msg, upb_arena *arena) {
   struct google_protobuf_Timestamp* sub = (struct google_protobuf_Timestamp*)grpc_lb_v1_ClientStats_timestamp(msg);
@@ -183,27 +209,27 @@ UPB_INLINE struct google_protobuf_Timestamp* grpc_lb_v1_ClientStats_mutable_time
   return sub;
 }
 UPB_INLINE void grpc_lb_v1_ClientStats_set_num_calls_started(grpc_lb_v1_ClientStats *msg, int64_t value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(0, 0), int64_t) = value;
+  *UPB_PTR_AT(msg, UPB_SIZE(8, 8), int64_t) = value;
 }
 UPB_INLINE void grpc_lb_v1_ClientStats_set_num_calls_finished(grpc_lb_v1_ClientStats *msg, int64_t value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(8, 8), int64_t) = value;
+  *UPB_PTR_AT(msg, UPB_SIZE(16, 16), int64_t) = value;
 }
 UPB_INLINE void grpc_lb_v1_ClientStats_set_num_calls_finished_with_client_failed_to_send(grpc_lb_v1_ClientStats *msg, int64_t value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(16, 16), int64_t) = value;
+  *UPB_PTR_AT(msg, UPB_SIZE(24, 24), int64_t) = value;
 }
 UPB_INLINE void grpc_lb_v1_ClientStats_set_num_calls_finished_known_received(grpc_lb_v1_ClientStats *msg, int64_t value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(24, 24), int64_t) = value;
+  *UPB_PTR_AT(msg, UPB_SIZE(32, 32), int64_t) = value;
 }
 UPB_INLINE grpc_lb_v1_ClientStatsPerToken** grpc_lb_v1_ClientStats_mutable_calls_finished_with_drop(grpc_lb_v1_ClientStats *msg, size_t *len) {
-  return (grpc_lb_v1_ClientStatsPerToken**)_upb_array_mutable_accessor(msg, UPB_SIZE(36, 40), len);
+  return (grpc_lb_v1_ClientStatsPerToken**)_upb_array_mutable_accessor(msg, UPB_SIZE(44, 48), len);
 }
 UPB_INLINE grpc_lb_v1_ClientStatsPerToken** grpc_lb_v1_ClientStats_resize_calls_finished_with_drop(grpc_lb_v1_ClientStats *msg, size_t len, upb_arena *arena) {
-  return (grpc_lb_v1_ClientStatsPerToken**)_upb_array_resize_accessor(msg, UPB_SIZE(36, 40), len, UPB_TYPE_MESSAGE, arena);
+  return (grpc_lb_v1_ClientStatsPerToken**)_upb_array_resize_accessor2(msg, UPB_SIZE(44, 48), len, UPB_SIZE(2, 3), arena);
 }
 UPB_INLINE struct grpc_lb_v1_ClientStatsPerToken* grpc_lb_v1_ClientStats_add_calls_finished_with_drop(grpc_lb_v1_ClientStats *msg, upb_arena *arena) {
   struct grpc_lb_v1_ClientStatsPerToken* sub = (struct grpc_lb_v1_ClientStatsPerToken*)_upb_msg_new(&grpc_lb_v1_ClientStatsPerToken_msginit, arena);
-  bool ok = _upb_array_append_accessor(
-      msg, UPB_SIZE(36, 40), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena);
+  bool ok = _upb_array_append_accessor2(
+      msg, UPB_SIZE(44, 48), UPB_SIZE(2, 3), &sub, arena);
   if (!ok) return NULL;
   return sub;
 }
@@ -218,6 +244,12 @@ UPB_INLINE grpc_lb_v1_LoadBalanceResponse *grpc_lb_v1_LoadBalanceResponse_parse(
   grpc_lb_v1_LoadBalanceResponse *ret = grpc_lb_v1_LoadBalanceResponse_new(arena);
   return (ret && upb_decode(buf, size, ret, &grpc_lb_v1_LoadBalanceResponse_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE grpc_lb_v1_LoadBalanceResponse *grpc_lb_v1_LoadBalanceResponse_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  grpc_lb_v1_LoadBalanceResponse *ret = grpc_lb_v1_LoadBalanceResponse_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &grpc_lb_v1_LoadBalanceResponse_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *grpc_lb_v1_LoadBalanceResponse_serialize(const grpc_lb_v1_LoadBalanceResponse *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &grpc_lb_v1_LoadBalanceResponse_msginit, arena, len);
 }
@@ -284,19 +316,26 @@ UPB_INLINE grpc_lb_v1_InitialLoadBalanceResponse *grpc_lb_v1_InitialLoadBalanceR
   grpc_lb_v1_InitialLoadBalanceResponse *ret = grpc_lb_v1_InitialLoadBalanceResponse_new(arena);
   return (ret && upb_decode(buf, size, ret, &grpc_lb_v1_InitialLoadBalanceResponse_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE grpc_lb_v1_InitialLoadBalanceResponse *grpc_lb_v1_InitialLoadBalanceResponse_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  grpc_lb_v1_InitialLoadBalanceResponse *ret = grpc_lb_v1_InitialLoadBalanceResponse_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &grpc_lb_v1_InitialLoadBalanceResponse_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *grpc_lb_v1_InitialLoadBalanceResponse_serialize(const grpc_lb_v1_InitialLoadBalanceResponse *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &grpc_lb_v1_InitialLoadBalanceResponse_msginit, arena, len);
 }
 
-UPB_INLINE upb_strview grpc_lb_v1_InitialLoadBalanceResponse_load_balancer_delegate(const grpc_lb_v1_InitialLoadBalanceResponse *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(0, 0), upb_strview); }
-UPB_INLINE bool grpc_lb_v1_InitialLoadBalanceResponse_has_client_stats_report_interval(const grpc_lb_v1_InitialLoadBalanceResponse *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(8, 16)); }
-UPB_INLINE const struct google_protobuf_Duration* grpc_lb_v1_InitialLoadBalanceResponse_client_stats_report_interval(const grpc_lb_v1_InitialLoadBalanceResponse *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(8, 16), const struct google_protobuf_Duration*); }
+UPB_INLINE upb_strview grpc_lb_v1_InitialLoadBalanceResponse_load_balancer_delegate(const grpc_lb_v1_InitialLoadBalanceResponse *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(4, 8), upb_strview); }
+UPB_INLINE bool grpc_lb_v1_InitialLoadBalanceResponse_has_client_stats_report_interval(const grpc_lb_v1_InitialLoadBalanceResponse *msg) { return _upb_hasbit(msg, 1); }
+UPB_INLINE const struct google_protobuf_Duration* grpc_lb_v1_InitialLoadBalanceResponse_client_stats_report_interval(const grpc_lb_v1_InitialLoadBalanceResponse *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(12, 24), const struct google_protobuf_Duration*); }
 
 UPB_INLINE void grpc_lb_v1_InitialLoadBalanceResponse_set_load_balancer_delegate(grpc_lb_v1_InitialLoadBalanceResponse *msg, upb_strview value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(0, 0), upb_strview) = value;
+  *UPB_PTR_AT(msg, UPB_SIZE(4, 8), upb_strview) = value;
 }
 UPB_INLINE void grpc_lb_v1_InitialLoadBalanceResponse_set_client_stats_report_interval(grpc_lb_v1_InitialLoadBalanceResponse *msg, struct google_protobuf_Duration* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(8, 16), struct google_protobuf_Duration*) = value;
+  _upb_sethas(msg, 1);
+  *UPB_PTR_AT(msg, UPB_SIZE(12, 24), struct google_protobuf_Duration*) = value;
 }
 UPB_INLINE struct google_protobuf_Duration* grpc_lb_v1_InitialLoadBalanceResponse_mutable_client_stats_report_interval(grpc_lb_v1_InitialLoadBalanceResponse *msg, upb_arena *arena) {
   struct google_protobuf_Duration* sub = (struct google_protobuf_Duration*)grpc_lb_v1_InitialLoadBalanceResponse_client_stats_report_interval(msg);
@@ -318,6 +357,12 @@ UPB_INLINE grpc_lb_v1_ServerList *grpc_lb_v1_ServerList_parse(const char *buf, s
   grpc_lb_v1_ServerList *ret = grpc_lb_v1_ServerList_new(arena);
   return (ret && upb_decode(buf, size, ret, &grpc_lb_v1_ServerList_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE grpc_lb_v1_ServerList *grpc_lb_v1_ServerList_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  grpc_lb_v1_ServerList *ret = grpc_lb_v1_ServerList_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &grpc_lb_v1_ServerList_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *grpc_lb_v1_ServerList_serialize(const grpc_lb_v1_ServerList *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &grpc_lb_v1_ServerList_msginit, arena, len);
 }
@@ -329,12 +374,12 @@ UPB_INLINE grpc_lb_v1_Server** grpc_lb_v1_ServerList_mutable_servers(grpc_lb_v1_
   return (grpc_lb_v1_Server**)_upb_array_mutable_accessor(msg, UPB_SIZE(0, 0), len);
 }
 UPB_INLINE grpc_lb_v1_Server** grpc_lb_v1_ServerList_resize_servers(grpc_lb_v1_ServerList *msg, size_t len, upb_arena *arena) {
-  return (grpc_lb_v1_Server**)_upb_array_resize_accessor(msg, UPB_SIZE(0, 0), len, UPB_TYPE_MESSAGE, arena);
+  return (grpc_lb_v1_Server**)_upb_array_resize_accessor2(msg, UPB_SIZE(0, 0), len, UPB_SIZE(2, 3), arena);
 }
 UPB_INLINE struct grpc_lb_v1_Server* grpc_lb_v1_ServerList_add_servers(grpc_lb_v1_ServerList *msg, upb_arena *arena) {
   struct grpc_lb_v1_Server* sub = (struct grpc_lb_v1_Server*)_upb_msg_new(&grpc_lb_v1_Server_msginit, arena);
-  bool ok = _upb_array_append_accessor(
-      msg, UPB_SIZE(0, 0), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena);
+  bool ok = _upb_array_append_accessor2(
+      msg, UPB_SIZE(0, 0), UPB_SIZE(2, 3), &sub, arena);
   if (!ok) return NULL;
   return sub;
 }
@@ -349,6 +394,12 @@ UPB_INLINE grpc_lb_v1_Server *grpc_lb_v1_Server_parse(const char *buf, size_t si
   grpc_lb_v1_Server *ret = grpc_lb_v1_Server_new(arena);
   return (ret && upb_decode(buf, size, ret, &grpc_lb_v1_Server_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE grpc_lb_v1_Server *grpc_lb_v1_Server_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  grpc_lb_v1_Server *ret = grpc_lb_v1_Server_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &grpc_lb_v1_Server_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *grpc_lb_v1_Server_serialize(const grpc_lb_v1_Server *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &grpc_lb_v1_Server_msginit, arena, len);
 }
@@ -381,6 +432,12 @@ UPB_INLINE grpc_lb_v1_FallbackResponse *grpc_lb_v1_FallbackResponse_parse(const
   grpc_lb_v1_FallbackResponse *ret = grpc_lb_v1_FallbackResponse_new(arena);
   return (ret && upb_decode(buf, size, ret, &grpc_lb_v1_FallbackResponse_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE grpc_lb_v1_FallbackResponse *grpc_lb_v1_FallbackResponse_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  grpc_lb_v1_FallbackResponse *ret = grpc_lb_v1_FallbackResponse_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &grpc_lb_v1_FallbackResponse_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *grpc_lb_v1_FallbackResponse_serialize(const grpc_lb_v1_FallbackResponse *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &grpc_lb_v1_FallbackResponse_msginit, arena, len);
 }
index 81e7746..a4d95cc 100644 (file)
@@ -18,15 +18,15 @@ static const upb_msglayout *const google_security_meshca_v1_MeshCertificateReque
 };
 
 static const upb_msglayout_field google_security_meshca_v1_MeshCertificateRequest__fields[3] = {
-  {1, UPB_SIZE(0, 0), 0, 0, 9, 1},
-  {2, UPB_SIZE(8, 16), 0, 0, 9, 1},
-  {3, UPB_SIZE(16, 32), 0, 0, 11, 1},
+  {1, UPB_SIZE(4, 8), 0, 0, 9, 1},
+  {2, UPB_SIZE(12, 24), 0, 0, 9, 1},
+  {3, UPB_SIZE(20, 40), 1, 0, 11, 1},
 };
 
 const upb_msglayout google_security_meshca_v1_MeshCertificateRequest_msginit = {
   &google_security_meshca_v1_MeshCertificateRequest_submsgs[0],
   &google_security_meshca_v1_MeshCertificateRequest__fields[0],
-  UPB_SIZE(24, 48), 3, false,
+  UPB_SIZE(24, 48), 3, false, 255,
 };
 
 static const upb_msglayout_field google_security_meshca_v1_MeshCertificateResponse__fields[1] = {
@@ -36,7 +36,7 @@ static const upb_msglayout_field google_security_meshca_v1_MeshCertificateRespon
 const upb_msglayout google_security_meshca_v1_MeshCertificateResponse_msginit = {
   NULL,
   &google_security_meshca_v1_MeshCertificateResponse__fields[0],
-  UPB_SIZE(4, 8), 1, false,
+  UPB_SIZE(8, 8), 1, false, 255,
 };
 
 #include "upb/port_undef.inc"
index 8afbaab..f301a02 100644 (file)
@@ -11,6 +11,7 @@
 
 #include "upb/msg.h"
 #include "upb/decode.h"
+#include "upb/decode_fast.h"
 #include "upb/encode.h"
 
 #include "upb/port_def.inc"
@@ -39,23 +40,30 @@ UPB_INLINE google_security_meshca_v1_MeshCertificateRequest *google_security_mes
   google_security_meshca_v1_MeshCertificateRequest *ret = google_security_meshca_v1_MeshCertificateRequest_new(arena);
   return (ret && upb_decode(buf, size, ret, &google_security_meshca_v1_MeshCertificateRequest_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE google_security_meshca_v1_MeshCertificateRequest *google_security_meshca_v1_MeshCertificateRequest_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  google_security_meshca_v1_MeshCertificateRequest *ret = google_security_meshca_v1_MeshCertificateRequest_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &google_security_meshca_v1_MeshCertificateRequest_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *google_security_meshca_v1_MeshCertificateRequest_serialize(const google_security_meshca_v1_MeshCertificateRequest *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &google_security_meshca_v1_MeshCertificateRequest_msginit, arena, len);
 }
 
-UPB_INLINE upb_strview google_security_meshca_v1_MeshCertificateRequest_request_id(const google_security_meshca_v1_MeshCertificateRequest *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(0, 0), upb_strview); }
-UPB_INLINE upb_strview google_security_meshca_v1_MeshCertificateRequest_csr(const google_security_meshca_v1_MeshCertificateRequest *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(8, 16), upb_strview); }
-UPB_INLINE bool google_security_meshca_v1_MeshCertificateRequest_has_validity(const google_security_meshca_v1_MeshCertificateRequest *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(16, 32)); }
-UPB_INLINE const struct google_protobuf_Duration* google_security_meshca_v1_MeshCertificateRequest_validity(const google_security_meshca_v1_MeshCertificateRequest *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(16, 32), const struct google_protobuf_Duration*); }
+UPB_INLINE upb_strview google_security_meshca_v1_MeshCertificateRequest_request_id(const google_security_meshca_v1_MeshCertificateRequest *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(4, 8), upb_strview); }
+UPB_INLINE upb_strview google_security_meshca_v1_MeshCertificateRequest_csr(const google_security_meshca_v1_MeshCertificateRequest *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(12, 24), upb_strview); }
+UPB_INLINE bool google_security_meshca_v1_MeshCertificateRequest_has_validity(const google_security_meshca_v1_MeshCertificateRequest *msg) { return _upb_hasbit(msg, 1); }
+UPB_INLINE const struct google_protobuf_Duration* google_security_meshca_v1_MeshCertificateRequest_validity(const google_security_meshca_v1_MeshCertificateRequest *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(20, 40), const struct google_protobuf_Duration*); }
 
 UPB_INLINE void google_security_meshca_v1_MeshCertificateRequest_set_request_id(google_security_meshca_v1_MeshCertificateRequest *msg, upb_strview value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(0, 0), upb_strview) = value;
+  *UPB_PTR_AT(msg, UPB_SIZE(4, 8), upb_strview) = value;
 }
 UPB_INLINE void google_security_meshca_v1_MeshCertificateRequest_set_csr(google_security_meshca_v1_MeshCertificateRequest *msg, upb_strview value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(8, 16), upb_strview) = value;
+  *UPB_PTR_AT(msg, UPB_SIZE(12, 24), upb_strview) = value;
 }
 UPB_INLINE void google_security_meshca_v1_MeshCertificateRequest_set_validity(google_security_meshca_v1_MeshCertificateRequest *msg, struct google_protobuf_Duration* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(16, 32), struct google_protobuf_Duration*) = value;
+  _upb_sethas(msg, 1);
+  *UPB_PTR_AT(msg, UPB_SIZE(20, 40), struct google_protobuf_Duration*) = value;
 }
 UPB_INLINE struct google_protobuf_Duration* google_security_meshca_v1_MeshCertificateRequest_mutable_validity(google_security_meshca_v1_MeshCertificateRequest *msg, upb_arena *arena) {
   struct google_protobuf_Duration* sub = (struct google_protobuf_Duration*)google_security_meshca_v1_MeshCertificateRequest_validity(msg);
@@ -77,6 +85,12 @@ UPB_INLINE google_security_meshca_v1_MeshCertificateResponse *google_security_me
   google_security_meshca_v1_MeshCertificateResponse *ret = google_security_meshca_v1_MeshCertificateResponse_new(arena);
   return (ret && upb_decode(buf, size, ret, &google_security_meshca_v1_MeshCertificateResponse_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE google_security_meshca_v1_MeshCertificateResponse *google_security_meshca_v1_MeshCertificateResponse_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  google_security_meshca_v1_MeshCertificateResponse *ret = google_security_meshca_v1_MeshCertificateResponse_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &google_security_meshca_v1_MeshCertificateResponse_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *google_security_meshca_v1_MeshCertificateResponse_serialize(const google_security_meshca_v1_MeshCertificateResponse *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &google_security_meshca_v1_MeshCertificateResponse_msginit, arena, len);
 }
@@ -87,10 +101,10 @@ UPB_INLINE upb_strview* google_security_meshca_v1_MeshCertificateResponse_mutabl
   return (upb_strview*)_upb_array_mutable_accessor(msg, UPB_SIZE(0, 0), len);
 }
 UPB_INLINE upb_strview* google_security_meshca_v1_MeshCertificateResponse_resize_cert_chain(google_security_meshca_v1_MeshCertificateResponse *msg, size_t len, upb_arena *arena) {
-  return (upb_strview*)_upb_array_resize_accessor(msg, UPB_SIZE(0, 0), len, UPB_TYPE_STRING, arena);
+  return (upb_strview*)_upb_array_resize_accessor2(msg, UPB_SIZE(0, 0), len, UPB_SIZE(3, 4), arena);
 }
 UPB_INLINE bool google_security_meshca_v1_MeshCertificateResponse_add_cert_chain(google_security_meshca_v1_MeshCertificateResponse *msg, upb_strview val, upb_arena *arena) {
-  return _upb_array_append_accessor(msg, UPB_SIZE(0, 0), UPB_SIZE(8, 16), UPB_TYPE_STRING, &val,
+  return _upb_array_append_accessor2(msg, UPB_SIZE(0, 0), UPB_SIZE(3, 4), &val,
       arena);
 }
 
index fcf32a6..5f5f1ed 100644 (file)
@@ -20,7 +20,7 @@ static const upb_msglayout_field udpa_annotations_MigrateAnnotation__fields[1] =
 const upb_msglayout udpa_annotations_MigrateAnnotation_msginit = {
   NULL,
   &udpa_annotations_MigrateAnnotation__fields[0],
-  UPB_SIZE(8, 16), 1, false,
+  UPB_SIZE(8, 16), 1, false, 255,
 };
 
 static const upb_msglayout_field udpa_annotations_FieldMigrateAnnotation__fields[2] = {
@@ -31,7 +31,7 @@ static const upb_msglayout_field udpa_annotations_FieldMigrateAnnotation__fields
 const upb_msglayout udpa_annotations_FieldMigrateAnnotation_msginit = {
   NULL,
   &udpa_annotations_FieldMigrateAnnotation__fields[0],
-  UPB_SIZE(16, 32), 2, false,
+  UPB_SIZE(16, 32), 2, false, 255,
 };
 
 static const upb_msglayout_field udpa_annotations_FileMigrateAnnotation__fields[1] = {
@@ -41,7 +41,7 @@ static const upb_msglayout_field udpa_annotations_FileMigrateAnnotation__fields[
 const upb_msglayout udpa_annotations_FileMigrateAnnotation_msginit = {
   NULL,
   &udpa_annotations_FileMigrateAnnotation__fields[0],
-  UPB_SIZE(8, 16), 1, false,
+  UPB_SIZE(8, 16), 1, false, 255,
 };
 
 #include "upb/port_undef.inc"
index d6a3d0c..8d55a77 100644 (file)
@@ -11,6 +11,7 @@
 
 #include "upb/msg.h"
 #include "upb/decode.h"
+#include "upb/decode_fast.h"
 #include "upb/encode.h"
 
 #include "upb/port_def.inc"
@@ -40,6 +41,12 @@ UPB_INLINE udpa_annotations_MigrateAnnotation *udpa_annotations_MigrateAnnotatio
   udpa_annotations_MigrateAnnotation *ret = udpa_annotations_MigrateAnnotation_new(arena);
   return (ret && upb_decode(buf, size, ret, &udpa_annotations_MigrateAnnotation_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE udpa_annotations_MigrateAnnotation *udpa_annotations_MigrateAnnotation_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  udpa_annotations_MigrateAnnotation *ret = udpa_annotations_MigrateAnnotation_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &udpa_annotations_MigrateAnnotation_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *udpa_annotations_MigrateAnnotation_serialize(const udpa_annotations_MigrateAnnotation *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &udpa_annotations_MigrateAnnotation_msginit, arena, len);
 }
@@ -60,6 +67,12 @@ UPB_INLINE udpa_annotations_FieldMigrateAnnotation *udpa_annotations_FieldMigrat
   udpa_annotations_FieldMigrateAnnotation *ret = udpa_annotations_FieldMigrateAnnotation_new(arena);
   return (ret && upb_decode(buf, size, ret, &udpa_annotations_FieldMigrateAnnotation_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE udpa_annotations_FieldMigrateAnnotation *udpa_annotations_FieldMigrateAnnotation_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  udpa_annotations_FieldMigrateAnnotation *ret = udpa_annotations_FieldMigrateAnnotation_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &udpa_annotations_FieldMigrateAnnotation_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *udpa_annotations_FieldMigrateAnnotation_serialize(const udpa_annotations_FieldMigrateAnnotation *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &udpa_annotations_FieldMigrateAnnotation_msginit, arena, len);
 }
@@ -84,6 +97,12 @@ UPB_INLINE udpa_annotations_FileMigrateAnnotation *udpa_annotations_FileMigrateA
   udpa_annotations_FileMigrateAnnotation *ret = udpa_annotations_FileMigrateAnnotation_new(arena);
   return (ret && upb_decode(buf, size, ret, &udpa_annotations_FileMigrateAnnotation_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE udpa_annotations_FileMigrateAnnotation *udpa_annotations_FileMigrateAnnotation_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  udpa_annotations_FileMigrateAnnotation *ret = udpa_annotations_FileMigrateAnnotation_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &udpa_annotations_FileMigrateAnnotation_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *udpa_annotations_FileMigrateAnnotation_serialize(const udpa_annotations_FileMigrateAnnotation *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &udpa_annotations_FileMigrateAnnotation_msginit, arena, len);
 }
index ebba91c..d135d4f 100644 (file)
@@ -24,7 +24,7 @@ static const upb_msglayout_field udpa_annotations_FieldSecurityAnnotation__field
 const upb_msglayout udpa_annotations_FieldSecurityAnnotation_msginit = {
   NULL,
   &udpa_annotations_FieldSecurityAnnotation__fields[0],
-  UPB_SIZE(2, 2), 2, false,
+  UPB_SIZE(8, 8), 2, false, 255,
 };
 
 #include "upb/port_undef.inc"
index 89115fa..415ba04 100644 (file)
@@ -11,6 +11,7 @@
 
 #include "upb/msg.h"
 #include "upb/decode.h"
+#include "upb/decode_fast.h"
 #include "upb/encode.h"
 
 #include "upb/port_def.inc"
@@ -34,6 +35,12 @@ UPB_INLINE udpa_annotations_FieldSecurityAnnotation *udpa_annotations_FieldSecur
   udpa_annotations_FieldSecurityAnnotation *ret = udpa_annotations_FieldSecurityAnnotation_new(arena);
   return (ret && upb_decode(buf, size, ret, &udpa_annotations_FieldSecurityAnnotation_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE udpa_annotations_FieldSecurityAnnotation *udpa_annotations_FieldSecurityAnnotation_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  udpa_annotations_FieldSecurityAnnotation *ret = udpa_annotations_FieldSecurityAnnotation_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &udpa_annotations_FieldSecurityAnnotation_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *udpa_annotations_FieldSecurityAnnotation_serialize(const udpa_annotations_FieldSecurityAnnotation *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &udpa_annotations_FieldSecurityAnnotation_msginit, arena, len);
 }
index e676115..69f2a86 100644 (file)
@@ -11,6 +11,7 @@
 
 #include "upb/msg.h"
 #include "upb/decode.h"
+#include "upb/decode_fast.h"
 #include "upb/encode.h"
 
 #include "upb/port_def.inc"
index 05cb76c..16b0181 100644 (file)
 #include "upb/port_def.inc"
 
 static const upb_msglayout_field udpa_annotations_StatusAnnotation__fields[2] = {
-  {1, UPB_SIZE(8, 8), 0, 0, 8, 1},
+  {1, UPB_SIZE(4, 4), 0, 0, 8, 1},
   {2, UPB_SIZE(0, 0), 0, 0, 14, 1},
 };
 
 const upb_msglayout udpa_annotations_StatusAnnotation_msginit = {
   NULL,
   &udpa_annotations_StatusAnnotation__fields[0],
-  UPB_SIZE(16, 16), 2, false,
+  UPB_SIZE(8, 8), 2, false, 255,
 };
 
 #include "upb/port_undef.inc"
index b6599e9..a55570d 100644 (file)
@@ -11,6 +11,7 @@
 
 #include "upb/msg.h"
 #include "upb/decode.h"
+#include "upb/decode_fast.h"
 #include "upb/encode.h"
 
 #include "upb/port_def.inc"
@@ -41,15 +42,21 @@ UPB_INLINE udpa_annotations_StatusAnnotation *udpa_annotations_StatusAnnotation_
   udpa_annotations_StatusAnnotation *ret = udpa_annotations_StatusAnnotation_new(arena);
   return (ret && upb_decode(buf, size, ret, &udpa_annotations_StatusAnnotation_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE udpa_annotations_StatusAnnotation *udpa_annotations_StatusAnnotation_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  udpa_annotations_StatusAnnotation *ret = udpa_annotations_StatusAnnotation_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &udpa_annotations_StatusAnnotation_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *udpa_annotations_StatusAnnotation_serialize(const udpa_annotations_StatusAnnotation *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &udpa_annotations_StatusAnnotation_msginit, arena, len);
 }
 
-UPB_INLINE bool udpa_annotations_StatusAnnotation_work_in_progress(const udpa_annotations_StatusAnnotation *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(8, 8), bool); }
+UPB_INLINE bool udpa_annotations_StatusAnnotation_work_in_progress(const udpa_annotations_StatusAnnotation *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(4, 4), bool); }
 UPB_INLINE int32_t udpa_annotations_StatusAnnotation_package_version_status(const udpa_annotations_StatusAnnotation *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(0, 0), int32_t); }
 
 UPB_INLINE void udpa_annotations_StatusAnnotation_set_work_in_progress(udpa_annotations_StatusAnnotation *msg, bool value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(8, 8), bool) = value;
+  *UPB_PTR_AT(msg, UPB_SIZE(4, 4), bool) = value;
 }
 UPB_INLINE void udpa_annotations_StatusAnnotation_set_package_version_status(udpa_annotations_StatusAnnotation *msg, int32_t value) {
   *UPB_PTR_AT(msg, UPB_SIZE(0, 0), int32_t) = value;
index 017d26e..253afc8 100644 (file)
@@ -20,7 +20,7 @@ static const upb_msglayout_field udpa_annotations_VersioningAnnotation__fields[1
 const upb_msglayout udpa_annotations_VersioningAnnotation_msginit = {
   NULL,
   &udpa_annotations_VersioningAnnotation__fields[0],
-  UPB_SIZE(8, 16), 1, false,
+  UPB_SIZE(8, 16), 1, false, 255,
 };
 
 #include "upb/port_undef.inc"
index 5341663..e39f8c3 100644 (file)
@@ -11,6 +11,7 @@
 
 #include "upb/msg.h"
 #include "upb/decode.h"
+#include "upb/decode_fast.h"
 #include "upb/encode.h"
 
 #include "upb/port_def.inc"
@@ -34,6 +35,12 @@ UPB_INLINE udpa_annotations_VersioningAnnotation *udpa_annotations_VersioningAnn
   udpa_annotations_VersioningAnnotation *ret = udpa_annotations_VersioningAnnotation_new(arena);
   return (ret && upb_decode(buf, size, ret, &udpa_annotations_VersioningAnnotation_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE udpa_annotations_VersioningAnnotation *udpa_annotations_VersioningAnnotation_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  udpa_annotations_VersioningAnnotation *ret = udpa_annotations_VersioningAnnotation_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &udpa_annotations_VersioningAnnotation_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *udpa_annotations_VersioningAnnotation_serialize(const udpa_annotations_VersioningAnnotation *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &udpa_annotations_VersioningAnnotation_msginit, arena, len);
 }
index d93320d..a8a3877 100644 (file)
@@ -21,7 +21,7 @@ static const upb_msglayout_field udpa_core_v1_Authority__fields[1] = {
 const upb_msglayout udpa_core_v1_Authority_msginit = {
   NULL,
   &udpa_core_v1_Authority__fields[0],
-  UPB_SIZE(8, 16), 1, false,
+  UPB_SIZE(8, 16), 1, false, 255,
 };
 
 #include "upb/port_undef.inc"
index b464edd..cc7fc1b 100644 (file)
@@ -11,6 +11,7 @@
 
 #include "upb/msg.h"
 #include "upb/decode.h"
+#include "upb/decode_fast.h"
 #include "upb/encode.h"
 
 #include "upb/port_def.inc"
@@ -34,6 +35,12 @@ UPB_INLINE udpa_core_v1_Authority *udpa_core_v1_Authority_parse(const char *buf,
   udpa_core_v1_Authority *ret = udpa_core_v1_Authority_new(arena);
   return (ret && upb_decode(buf, size, ret, &udpa_core_v1_Authority_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE udpa_core_v1_Authority *udpa_core_v1_Authority_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  udpa_core_v1_Authority *ret = udpa_core_v1_Authority_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &udpa_core_v1_Authority_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *udpa_core_v1_Authority_serialize(const udpa_core_v1_Authority *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &udpa_core_v1_Authority_msginit, arena, len);
 }
index f0e763e..f6ba895 100644 (file)
@@ -29,7 +29,7 @@ static const upb_msglayout_field udpa_core_v1_CollectionEntry__fields[2] = {
 const upb_msglayout udpa_core_v1_CollectionEntry_msginit = {
   &udpa_core_v1_CollectionEntry_submsgs[0],
   &udpa_core_v1_CollectionEntry__fields[0],
-  UPB_SIZE(8, 16), 2, false,
+  UPB_SIZE(8, 16), 2, false, 255,
 };
 
 static const upb_msglayout *const udpa_core_v1_CollectionEntry_InlineEntry_submsgs[1] = {
@@ -37,15 +37,15 @@ static const upb_msglayout *const udpa_core_v1_CollectionEntry_InlineEntry_subms
 };
 
 static const upb_msglayout_field udpa_core_v1_CollectionEntry_InlineEntry__fields[3] = {
-  {1, UPB_SIZE(0, 0), 0, 0, 9, 1},
-  {2, UPB_SIZE(8, 16), 0, 0, 9, 1},
-  {3, UPB_SIZE(16, 32), 0, 0, 11, 1},
+  {1, UPB_SIZE(4, 8), 0, 0, 9, 1},
+  {2, UPB_SIZE(12, 24), 0, 0, 9, 1},
+  {3, UPB_SIZE(20, 40), 1, 0, 11, 1},
 };
 
 const upb_msglayout udpa_core_v1_CollectionEntry_InlineEntry_msginit = {
   &udpa_core_v1_CollectionEntry_InlineEntry_submsgs[0],
   &udpa_core_v1_CollectionEntry_InlineEntry__fields[0],
-  UPB_SIZE(24, 48), 3, false,
+  UPB_SIZE(24, 48), 3, false, 255,
 };
 
 #include "upb/port_undef.inc"
index c4d4cda..bf76af4 100644 (file)
@@ -11,6 +11,7 @@
 
 #include "upb/msg.h"
 #include "upb/decode.h"
+#include "upb/decode_fast.h"
 #include "upb/encode.h"
 
 #include "upb/port_def.inc"
@@ -41,6 +42,12 @@ UPB_INLINE udpa_core_v1_CollectionEntry *udpa_core_v1_CollectionEntry_parse(cons
   udpa_core_v1_CollectionEntry *ret = udpa_core_v1_CollectionEntry_new(arena);
   return (ret && upb_decode(buf, size, ret, &udpa_core_v1_CollectionEntry_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE udpa_core_v1_CollectionEntry *udpa_core_v1_CollectionEntry_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  udpa_core_v1_CollectionEntry *ret = udpa_core_v1_CollectionEntry_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &udpa_core_v1_CollectionEntry_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *udpa_core_v1_CollectionEntry_serialize(const udpa_core_v1_CollectionEntry *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &udpa_core_v1_CollectionEntry_msginit, arena, len);
 }
@@ -92,23 +99,30 @@ UPB_INLINE udpa_core_v1_CollectionEntry_InlineEntry *udpa_core_v1_CollectionEntr
   udpa_core_v1_CollectionEntry_InlineEntry *ret = udpa_core_v1_CollectionEntry_InlineEntry_new(arena);
   return (ret && upb_decode(buf, size, ret, &udpa_core_v1_CollectionEntry_InlineEntry_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE udpa_core_v1_CollectionEntry_InlineEntry *udpa_core_v1_CollectionEntry_InlineEntry_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  udpa_core_v1_CollectionEntry_InlineEntry *ret = udpa_core_v1_CollectionEntry_InlineEntry_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &udpa_core_v1_CollectionEntry_InlineEntry_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *udpa_core_v1_CollectionEntry_InlineEntry_serialize(const udpa_core_v1_CollectionEntry_InlineEntry *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &udpa_core_v1_CollectionEntry_InlineEntry_msginit, arena, len);
 }
 
-UPB_INLINE upb_strview udpa_core_v1_CollectionEntry_InlineEntry_name(const udpa_core_v1_CollectionEntry_InlineEntry *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(0, 0), upb_strview); }
-UPB_INLINE upb_strview udpa_core_v1_CollectionEntry_InlineEntry_version(const udpa_core_v1_CollectionEntry_InlineEntry *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(8, 16), upb_strview); }
-UPB_INLINE bool udpa_core_v1_CollectionEntry_InlineEntry_has_resource(const udpa_core_v1_CollectionEntry_InlineEntry *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(16, 32)); }
-UPB_INLINE const struct google_protobuf_Any* udpa_core_v1_CollectionEntry_InlineEntry_resource(const udpa_core_v1_CollectionEntry_InlineEntry *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(16, 32), const struct google_protobuf_Any*); }
+UPB_INLINE upb_strview udpa_core_v1_CollectionEntry_InlineEntry_name(const udpa_core_v1_CollectionEntry_InlineEntry *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(4, 8), upb_strview); }
+UPB_INLINE upb_strview udpa_core_v1_CollectionEntry_InlineEntry_version(const udpa_core_v1_CollectionEntry_InlineEntry *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(12, 24), upb_strview); }
+UPB_INLINE bool udpa_core_v1_CollectionEntry_InlineEntry_has_resource(const udpa_core_v1_CollectionEntry_InlineEntry *msg) { return _upb_hasbit(msg, 1); }
+UPB_INLINE const struct google_protobuf_Any* udpa_core_v1_CollectionEntry_InlineEntry_resource(const udpa_core_v1_CollectionEntry_InlineEntry *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(20, 40), const struct google_protobuf_Any*); }
 
 UPB_INLINE void udpa_core_v1_CollectionEntry_InlineEntry_set_name(udpa_core_v1_CollectionEntry_InlineEntry *msg, upb_strview value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(0, 0), upb_strview) = value;
+  *UPB_PTR_AT(msg, UPB_SIZE(4, 8), upb_strview) = value;
 }
 UPB_INLINE void udpa_core_v1_CollectionEntry_InlineEntry_set_version(udpa_core_v1_CollectionEntry_InlineEntry *msg, upb_strview value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(8, 16), upb_strview) = value;
+  *UPB_PTR_AT(msg, UPB_SIZE(12, 24), upb_strview) = value;
 }
 UPB_INLINE void udpa_core_v1_CollectionEntry_InlineEntry_set_resource(udpa_core_v1_CollectionEntry_InlineEntry *msg, struct google_protobuf_Any* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(16, 32), struct google_protobuf_Any*) = value;
+  _upb_sethas(msg, 1);
+  *UPB_PTR_AT(msg, UPB_SIZE(20, 40), struct google_protobuf_Any*) = value;
 }
 UPB_INLINE struct google_protobuf_Any* udpa_core_v1_CollectionEntry_InlineEntry_mutable_resource(udpa_core_v1_CollectionEntry_InlineEntry *msg, upb_arena *arena) {
   struct google_protobuf_Any* sub = (struct google_protobuf_Any*)udpa_core_v1_CollectionEntry_InlineEntry_resource(msg);
index 8ec1e45..fae1ad0 100644 (file)
@@ -24,7 +24,7 @@ static const upb_msglayout_field udpa_core_v1_ContextParams__fields[1] = {
 const upb_msglayout udpa_core_v1_ContextParams_msginit = {
   &udpa_core_v1_ContextParams_submsgs[0],
   &udpa_core_v1_ContextParams__fields[0],
-  UPB_SIZE(4, 8), 1, false,
+  UPB_SIZE(8, 8), 1, false, 255,
 };
 
 static const upb_msglayout_field udpa_core_v1_ContextParams_ParamsEntry__fields[2] = {
@@ -35,7 +35,7 @@ static const upb_msglayout_field udpa_core_v1_ContextParams_ParamsEntry__fields[
 const upb_msglayout udpa_core_v1_ContextParams_ParamsEntry_msginit = {
   NULL,
   &udpa_core_v1_ContextParams_ParamsEntry__fields[0],
-  UPB_SIZE(16, 32), 2, false,
+  UPB_SIZE(16, 32), 2, false, 255,
 };
 
 #include "upb/port_undef.inc"
index cc16b62..2d62de9 100644 (file)
@@ -11,6 +11,7 @@
 
 #include "upb/msg.h"
 #include "upb/decode.h"
+#include "upb/decode_fast.h"
 #include "upb/encode.h"
 
 #include "upb/port_def.inc"
@@ -37,6 +38,12 @@ UPB_INLINE udpa_core_v1_ContextParams *udpa_core_v1_ContextParams_parse(const ch
   udpa_core_v1_ContextParams *ret = udpa_core_v1_ContextParams_new(arena);
   return (ret && upb_decode(buf, size, ret, &udpa_core_v1_ContextParams_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE udpa_core_v1_ContextParams *udpa_core_v1_ContextParams_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  udpa_core_v1_ContextParams *ret = udpa_core_v1_ContextParams_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &udpa_core_v1_ContextParams_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *udpa_core_v1_ContextParams_serialize(const udpa_core_v1_ContextParams *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &udpa_core_v1_ContextParams_msginit, arena, len);
 }
index f7d100e..86d2cf4 100644 (file)
@@ -21,15 +21,15 @@ static const upb_msglayout *const udpa_core_v1_Resource_submsgs[2] = {
 };
 
 static const upb_msglayout_field udpa_core_v1_Resource__fields[3] = {
-  {1, UPB_SIZE(8, 16), 0, 1, 11, 1},
-  {2, UPB_SIZE(0, 0), 0, 0, 9, 1},
-  {3, UPB_SIZE(12, 24), 0, 0, 11, 1},
+  {1, UPB_SIZE(12, 24), 1, 1, 11, 1},
+  {2, UPB_SIZE(4, 8), 0, 0, 9, 1},
+  {3, UPB_SIZE(16, 32), 2, 0, 11, 1},
 };
 
 const upb_msglayout udpa_core_v1_Resource_msginit = {
   &udpa_core_v1_Resource_submsgs[0],
   &udpa_core_v1_Resource__fields[0],
-  UPB_SIZE(16, 32), 3, false,
+  UPB_SIZE(24, 48), 3, false, 255,
 };
 
 #include "upb/port_undef.inc"
index d7ff6fe..cff8937 100644 (file)
@@ -11,6 +11,7 @@
 
 #include "upb/msg.h"
 #include "upb/decode.h"
+#include "upb/decode_fast.h"
 #include "upb/encode.h"
 
 #include "upb/port_def.inc"
@@ -38,18 +39,25 @@ UPB_INLINE udpa_core_v1_Resource *udpa_core_v1_Resource_parse(const char *buf, s
   udpa_core_v1_Resource *ret = udpa_core_v1_Resource_new(arena);
   return (ret && upb_decode(buf, size, ret, &udpa_core_v1_Resource_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE udpa_core_v1_Resource *udpa_core_v1_Resource_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  udpa_core_v1_Resource *ret = udpa_core_v1_Resource_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &udpa_core_v1_Resource_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *udpa_core_v1_Resource_serialize(const udpa_core_v1_Resource *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &udpa_core_v1_Resource_msginit, arena, len);
 }
 
-UPB_INLINE bool udpa_core_v1_Resource_has_name(const udpa_core_v1_Resource *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(8, 16)); }
-UPB_INLINE const struct udpa_core_v1_ResourceName* udpa_core_v1_Resource_name(const udpa_core_v1_Resource *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(8, 16), const struct udpa_core_v1_ResourceName*); }
-UPB_INLINE upb_strview udpa_core_v1_Resource_version(const udpa_core_v1_Resource *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(0, 0), upb_strview); }
-UPB_INLINE bool udpa_core_v1_Resource_has_resource(const udpa_core_v1_Resource *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(12, 24)); }
-UPB_INLINE const struct google_protobuf_Any* udpa_core_v1_Resource_resource(const udpa_core_v1_Resource *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(12, 24), const struct google_protobuf_Any*); }
+UPB_INLINE bool udpa_core_v1_Resource_has_name(const udpa_core_v1_Resource *msg) { return _upb_hasbit(msg, 1); }
+UPB_INLINE const struct udpa_core_v1_ResourceName* udpa_core_v1_Resource_name(const udpa_core_v1_Resource *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(12, 24), const struct udpa_core_v1_ResourceName*); }
+UPB_INLINE upb_strview udpa_core_v1_Resource_version(const udpa_core_v1_Resource *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(4, 8), upb_strview); }
+UPB_INLINE bool udpa_core_v1_Resource_has_resource(const udpa_core_v1_Resource *msg) { return _upb_hasbit(msg, 2); }
+UPB_INLINE const struct google_protobuf_Any* udpa_core_v1_Resource_resource(const udpa_core_v1_Resource *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(16, 32), const struct google_protobuf_Any*); }
 
 UPB_INLINE void udpa_core_v1_Resource_set_name(udpa_core_v1_Resource *msg, struct udpa_core_v1_ResourceName* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(8, 16), struct udpa_core_v1_ResourceName*) = value;
+  _upb_sethas(msg, 1);
+  *UPB_PTR_AT(msg, UPB_SIZE(12, 24), struct udpa_core_v1_ResourceName*) = value;
 }
 UPB_INLINE struct udpa_core_v1_ResourceName* udpa_core_v1_Resource_mutable_name(udpa_core_v1_Resource *msg, upb_arena *arena) {
   struct udpa_core_v1_ResourceName* sub = (struct udpa_core_v1_ResourceName*)udpa_core_v1_Resource_name(msg);
@@ -61,10 +69,11 @@ UPB_INLINE struct udpa_core_v1_ResourceName* udpa_core_v1_Resource_mutable_name(
   return sub;
 }
 UPB_INLINE void udpa_core_v1_Resource_set_version(udpa_core_v1_Resource *msg, upb_strview value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(0, 0), upb_strview) = value;
+  *UPB_PTR_AT(msg, UPB_SIZE(4, 8), upb_strview) = value;
 }
 UPB_INLINE void udpa_core_v1_Resource_set_resource(udpa_core_v1_Resource *msg, struct google_protobuf_Any* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(12, 24), struct google_protobuf_Any*) = value;
+  _upb_sethas(msg, 2);
+  *UPB_PTR_AT(msg, UPB_SIZE(16, 32), struct google_protobuf_Any*) = value;
 }
 UPB_INLINE struct google_protobuf_Any* udpa_core_v1_Resource_mutable_resource(udpa_core_v1_Resource *msg, upb_arena *arena) {
   struct google_protobuf_Any* sub = (struct google_protobuf_Any*)udpa_core_v1_Resource_resource(msg);
index e953225..5ceb62e 100644 (file)
@@ -22,17 +22,17 @@ static const upb_msglayout *const udpa_core_v1_ResourceLocator_submsgs[2] = {
 
 static const upb_msglayout_field udpa_core_v1_ResourceLocator__fields[6] = {
   {1, UPB_SIZE(0, 0), 0, 0, 14, 1},
-  {2, UPB_SIZE(24, 40), 0, 0, 9, 3},
-  {3, UPB_SIZE(8, 8), 0, 0, 9, 1},
-  {4, UPB_SIZE(16, 24), 0, 0, 9, 1},
-  {5, UPB_SIZE(32, 56), UPB_SIZE(-37, -65), 0, 11, 1},
-  {6, UPB_SIZE(28, 48), 0, 1, 11, 3},
+  {2, UPB_SIZE(20, 40), 0, 0, 9, 3},
+  {3, UPB_SIZE(4, 8), 0, 0, 9, 1},
+  {4, UPB_SIZE(12, 24), 0, 0, 9, 1},
+  {5, UPB_SIZE(28, 56), UPB_SIZE(-33, -65), 0, 11, 1},
+  {6, UPB_SIZE(24, 48), 0, 1, 11, 3},
 };
 
 const upb_msglayout udpa_core_v1_ResourceLocator_msginit = {
   &udpa_core_v1_ResourceLocator_submsgs[0],
   &udpa_core_v1_ResourceLocator__fields[0],
-  UPB_SIZE(40, 80), 6, false,
+  UPB_SIZE(40, 80), 6, false, 255,
 };
 
 static const upb_msglayout *const udpa_core_v1_ResourceLocator_Directive_submsgs[1] = {
@@ -47,7 +47,7 @@ static const upb_msglayout_field udpa_core_v1_ResourceLocator_Directive__fields[
 const upb_msglayout udpa_core_v1_ResourceLocator_Directive_msginit = {
   &udpa_core_v1_ResourceLocator_Directive_submsgs[0],
   &udpa_core_v1_ResourceLocator_Directive__fields[0],
-  UPB_SIZE(16, 32), 2, false,
+  UPB_SIZE(16, 32), 2, false, 255,
 };
 
 #include "upb/port_undef.inc"
index f485f70..ff52c58 100644 (file)
@@ -11,6 +11,7 @@
 
 #include "upb/msg.h"
 #include "upb/decode.h"
+#include "upb/decode_fast.h"
 #include "upb/encode.h"
 
 #include "upb/port_def.inc"
@@ -45,6 +46,12 @@ UPB_INLINE udpa_core_v1_ResourceLocator *udpa_core_v1_ResourceLocator_parse(cons
   udpa_core_v1_ResourceLocator *ret = udpa_core_v1_ResourceLocator_new(arena);
   return (ret && upb_decode(buf, size, ret, &udpa_core_v1_ResourceLocator_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE udpa_core_v1_ResourceLocator *udpa_core_v1_ResourceLocator_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  udpa_core_v1_ResourceLocator *ret = udpa_core_v1_ResourceLocator_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &udpa_core_v1_ResourceLocator_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *udpa_core_v1_ResourceLocator_serialize(const udpa_core_v1_ResourceLocator *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &udpa_core_v1_ResourceLocator_msginit, arena, len);
 }
@@ -53,38 +60,38 @@ typedef enum {
   udpa_core_v1_ResourceLocator_context_param_specifier_exact_context = 5,
   udpa_core_v1_ResourceLocator_context_param_specifier_NOT_SET = 0
 } udpa_core_v1_ResourceLocator_context_param_specifier_oneofcases;
-UPB_INLINE udpa_core_v1_ResourceLocator_context_param_specifier_oneofcases udpa_core_v1_ResourceLocator_context_param_specifier_case(const udpa_core_v1_ResourceLocator* msg) { return (udpa_core_v1_ResourceLocator_context_param_specifier_oneofcases)*UPB_PTR_AT(msg, UPB_SIZE(36, 64), int32_t); }
+UPB_INLINE udpa_core_v1_ResourceLocator_context_param_specifier_oneofcases udpa_core_v1_ResourceLocator_context_param_specifier_case(const udpa_core_v1_ResourceLocator* msg) { return (udpa_core_v1_ResourceLocator_context_param_specifier_oneofcases)*UPB_PTR_AT(msg, UPB_SIZE(32, 64), int32_t); }
 
 UPB_INLINE int32_t udpa_core_v1_ResourceLocator_scheme(const udpa_core_v1_ResourceLocator *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(0, 0), int32_t); }
-UPB_INLINE upb_strview const* udpa_core_v1_ResourceLocator_id(const udpa_core_v1_ResourceLocator *msg, size_t *len) { return (upb_strview const*)_upb_array_accessor(msg, UPB_SIZE(24, 40), len); }
-UPB_INLINE upb_strview udpa_core_v1_ResourceLocator_authority(const udpa_core_v1_ResourceLocator *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(8, 8), upb_strview); }
-UPB_INLINE upb_strview udpa_core_v1_ResourceLocator_resource_type(const udpa_core_v1_ResourceLocator *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(16, 24), upb_strview); }
-UPB_INLINE bool udpa_core_v1_ResourceLocator_has_exact_context(const udpa_core_v1_ResourceLocator *msg) { return _upb_getoneofcase(msg, UPB_SIZE(36, 64)) == 5; }
-UPB_INLINE const struct udpa_core_v1_ContextParams* udpa_core_v1_ResourceLocator_exact_context(const udpa_core_v1_ResourceLocator *msg) { return UPB_READ_ONEOF(msg, const struct udpa_core_v1_ContextParams*, UPB_SIZE(32, 56), UPB_SIZE(36, 64), 5, NULL); }
-UPB_INLINE bool udpa_core_v1_ResourceLocator_has_directives(const udpa_core_v1_ResourceLocator *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(28, 48)); }
-UPB_INLINE const udpa_core_v1_ResourceLocator_Directive* const* udpa_core_v1_ResourceLocator_directives(const udpa_core_v1_ResourceLocator *msg, size_t *len) { return (const udpa_core_v1_ResourceLocator_Directive* const*)_upb_array_accessor(msg, UPB_SIZE(28, 48), len); }
+UPB_INLINE upb_strview const* udpa_core_v1_ResourceLocator_id(const udpa_core_v1_ResourceLocator *msg, size_t *len) { return (upb_strview const*)_upb_array_accessor(msg, UPB_SIZE(20, 40), len); }
+UPB_INLINE upb_strview udpa_core_v1_ResourceLocator_authority(const udpa_core_v1_ResourceLocator *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(4, 8), upb_strview); }
+UPB_INLINE upb_strview udpa_core_v1_ResourceLocator_resource_type(const udpa_core_v1_ResourceLocator *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(12, 24), upb_strview); }
+UPB_INLINE bool udpa_core_v1_ResourceLocator_has_exact_context(const udpa_core_v1_ResourceLocator *msg) { return _upb_getoneofcase(msg, UPB_SIZE(32, 64)) == 5; }
+UPB_INLINE const struct udpa_core_v1_ContextParams* udpa_core_v1_ResourceLocator_exact_context(const udpa_core_v1_ResourceLocator *msg) { return UPB_READ_ONEOF(msg, const struct udpa_core_v1_ContextParams*, UPB_SIZE(28, 56), UPB_SIZE(32, 64), 5, NULL); }
+UPB_INLINE bool udpa_core_v1_ResourceLocator_has_directives(const udpa_core_v1_ResourceLocator *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(24, 48)); }
+UPB_INLINE const udpa_core_v1_ResourceLocator_Directive* const* udpa_core_v1_ResourceLocator_directives(const udpa_core_v1_ResourceLocator *msg, size_t *len) { return (const udpa_core_v1_ResourceLocator_Directive* const*)_upb_array_accessor(msg, UPB_SIZE(24, 48), len); }
 
 UPB_INLINE void udpa_core_v1_ResourceLocator_set_scheme(udpa_core_v1_ResourceLocator *msg, int32_t value) {
   *UPB_PTR_AT(msg, UPB_SIZE(0, 0), int32_t) = value;
 }
 UPB_INLINE upb_strview* udpa_core_v1_ResourceLocator_mutable_id(udpa_core_v1_ResourceLocator *msg, size_t *len) {
-  return (upb_strview*)_upb_array_mutable_accessor(msg, UPB_SIZE(24, 40), len);
+  return (upb_strview*)_upb_array_mutable_accessor(msg, UPB_SIZE(20, 40), len);
 }
 UPB_INLINE upb_strview* udpa_core_v1_ResourceLocator_resize_id(udpa_core_v1_ResourceLocator *msg, size_t len, upb_arena *arena) {
-  return (upb_strview*)_upb_array_resize_accessor(msg, UPB_SIZE(24, 40), len, UPB_TYPE_STRING, arena);
+  return (upb_strview*)_upb_array_resize_accessor2(msg, UPB_SIZE(20, 40), len, UPB_SIZE(3, 4), arena);
 }
 UPB_INLINE bool udpa_core_v1_ResourceLocator_add_id(udpa_core_v1_ResourceLocator *msg, upb_strview val, upb_arena *arena) {
-  return _upb_array_append_accessor(msg, UPB_SIZE(24, 40), UPB_SIZE(8, 16), UPB_TYPE_STRING, &val,
+  return _upb_array_append_accessor2(msg, UPB_SIZE(20, 40), UPB_SIZE(3, 4), &val,
       arena);
 }
 UPB_INLINE void udpa_core_v1_ResourceLocator_set_authority(udpa_core_v1_ResourceLocator *msg, upb_strview value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(8, 8), upb_strview) = value;
+  *UPB_PTR_AT(msg, UPB_SIZE(4, 8), upb_strview) = value;
 }
 UPB_INLINE void udpa_core_v1_ResourceLocator_set_resource_type(udpa_core_v1_ResourceLocator *msg, upb_strview value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(16, 24), upb_strview) = value;
+  *UPB_PTR_AT(msg, UPB_SIZE(12, 24), upb_strview) = value;
 }
 UPB_INLINE void udpa_core_v1_ResourceLocator_set_exact_context(udpa_core_v1_ResourceLocator *msg, struct udpa_core_v1_ContextParams* value) {
-  UPB_WRITE_ONEOF(msg, struct udpa_core_v1_ContextParams*, UPB_SIZE(32, 56), value, UPB_SIZE(36, 64), 5);
+  UPB_WRITE_ONEOF(msg, struct udpa_core_v1_ContextParams*, UPB_SIZE(28, 56), value, UPB_SIZE(32, 64), 5);
 }
 UPB_INLINE struct udpa_core_v1_ContextParams* udpa_core_v1_ResourceLocator_mutable_exact_context(udpa_core_v1_ResourceLocator *msg, upb_arena *arena) {
   struct udpa_core_v1_ContextParams* sub = (struct udpa_core_v1_ContextParams*)udpa_core_v1_ResourceLocator_exact_context(msg);
@@ -96,15 +103,15 @@ UPB_INLINE struct udpa_core_v1_ContextParams* udpa_core_v1_ResourceLocator_mutab
   return sub;
 }
 UPB_INLINE udpa_core_v1_ResourceLocator_Directive** udpa_core_v1_ResourceLocator_mutable_directives(udpa_core_v1_ResourceLocator *msg, size_t *len) {
-  return (udpa_core_v1_ResourceLocator_Directive**)_upb_array_mutable_accessor(msg, UPB_SIZE(28, 48), len);
+  return (udpa_core_v1_ResourceLocator_Directive**)_upb_array_mutable_accessor(msg, UPB_SIZE(24, 48), len);
 }
 UPB_INLINE udpa_core_v1_ResourceLocator_Directive** udpa_core_v1_ResourceLocator_resize_directives(udpa_core_v1_ResourceLocator *msg, size_t len, upb_arena *arena) {
-  return (udpa_core_v1_ResourceLocator_Directive**)_upb_array_resize_accessor(msg, UPB_SIZE(28, 48), len, UPB_TYPE_MESSAGE, arena);
+  return (udpa_core_v1_ResourceLocator_Directive**)_upb_array_resize_accessor2(msg, UPB_SIZE(24, 48), len, UPB_SIZE(2, 3), arena);
 }
 UPB_INLINE struct udpa_core_v1_ResourceLocator_Directive* udpa_core_v1_ResourceLocator_add_directives(udpa_core_v1_ResourceLocator *msg, upb_arena *arena) {
   struct udpa_core_v1_ResourceLocator_Directive* sub = (struct udpa_core_v1_ResourceLocator_Directive*)_upb_msg_new(&udpa_core_v1_ResourceLocator_Directive_msginit, arena);
-  bool ok = _upb_array_append_accessor(
-      msg, UPB_SIZE(28, 48), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena);
+  bool ok = _upb_array_append_accessor2(
+      msg, UPB_SIZE(24, 48), UPB_SIZE(2, 3), &sub, arena);
   if (!ok) return NULL;
   return sub;
 }
@@ -119,6 +126,12 @@ UPB_INLINE udpa_core_v1_ResourceLocator_Directive *udpa_core_v1_ResourceLocator_
   udpa_core_v1_ResourceLocator_Directive *ret = udpa_core_v1_ResourceLocator_Directive_new(arena);
   return (ret && upb_decode(buf, size, ret, &udpa_core_v1_ResourceLocator_Directive_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE udpa_core_v1_ResourceLocator_Directive *udpa_core_v1_ResourceLocator_Directive_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  udpa_core_v1_ResourceLocator_Directive *ret = udpa_core_v1_ResourceLocator_Directive_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &udpa_core_v1_ResourceLocator_Directive_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *udpa_core_v1_ResourceLocator_Directive_serialize(const udpa_core_v1_ResourceLocator_Directive *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &udpa_core_v1_ResourceLocator_Directive_msginit, arena, len);
 }
index 095399d..4bc48b4 100644 (file)
@@ -20,16 +20,16 @@ static const upb_msglayout *const udpa_core_v1_ResourceName_submsgs[1] = {
 };
 
 static const upb_msglayout_field udpa_core_v1_ResourceName__fields[4] = {
-  {1, UPB_SIZE(20, 40), 0, 0, 9, 3},
-  {2, UPB_SIZE(0, 0), 0, 0, 9, 1},
-  {3, UPB_SIZE(8, 16), 0, 0, 9, 1},
-  {4, UPB_SIZE(16, 32), 0, 0, 11, 1},
+  {1, UPB_SIZE(24, 48), 0, 0, 9, 3},
+  {2, UPB_SIZE(4, 8), 0, 0, 9, 1},
+  {3, UPB_SIZE(12, 24), 0, 0, 9, 1},
+  {4, UPB_SIZE(20, 40), 1, 0, 11, 1},
 };
 
 const upb_msglayout udpa_core_v1_ResourceName_msginit = {
   &udpa_core_v1_ResourceName_submsgs[0],
   &udpa_core_v1_ResourceName__fields[0],
-  UPB_SIZE(24, 48), 4, false,
+  UPB_SIZE(32, 64), 4, false, 255,
 };
 
 #include "upb/port_undef.inc"
index 40d8073..f631a2c 100644 (file)
@@ -11,6 +11,7 @@
 
 #include "upb/msg.h"
 #include "upb/decode.h"
+#include "upb/decode_fast.h"
 #include "upb/encode.h"
 
 #include "upb/port_def.inc"
@@ -36,34 +37,41 @@ UPB_INLINE udpa_core_v1_ResourceName *udpa_core_v1_ResourceName_parse(const char
   udpa_core_v1_ResourceName *ret = udpa_core_v1_ResourceName_new(arena);
   return (ret && upb_decode(buf, size, ret, &udpa_core_v1_ResourceName_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE udpa_core_v1_ResourceName *udpa_core_v1_ResourceName_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  udpa_core_v1_ResourceName *ret = udpa_core_v1_ResourceName_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &udpa_core_v1_ResourceName_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *udpa_core_v1_ResourceName_serialize(const udpa_core_v1_ResourceName *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &udpa_core_v1_ResourceName_msginit, arena, len);
 }
 
-UPB_INLINE upb_strview const* udpa_core_v1_ResourceName_id(const udpa_core_v1_ResourceName *msg, size_t *len) { return (upb_strview const*)_upb_array_accessor(msg, UPB_SIZE(20, 40), len); }
-UPB_INLINE upb_strview udpa_core_v1_ResourceName_authority(const udpa_core_v1_ResourceName *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(0, 0), upb_strview); }
-UPB_INLINE upb_strview udpa_core_v1_ResourceName_resource_type(const udpa_core_v1_ResourceName *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(8, 16), upb_strview); }
-UPB_INLINE bool udpa_core_v1_ResourceName_has_context(const udpa_core_v1_ResourceName *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(16, 32)); }
-UPB_INLINE const struct udpa_core_v1_ContextParams* udpa_core_v1_ResourceName_context(const udpa_core_v1_ResourceName *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(16, 32), const struct udpa_core_v1_ContextParams*); }
+UPB_INLINE upb_strview const* udpa_core_v1_ResourceName_id(const udpa_core_v1_ResourceName *msg, size_t *len) { return (upb_strview const*)_upb_array_accessor(msg, UPB_SIZE(24, 48), len); }
+UPB_INLINE upb_strview udpa_core_v1_ResourceName_authority(const udpa_core_v1_ResourceName *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(4, 8), upb_strview); }
+UPB_INLINE upb_strview udpa_core_v1_ResourceName_resource_type(const udpa_core_v1_ResourceName *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(12, 24), upb_strview); }
+UPB_INLINE bool udpa_core_v1_ResourceName_has_context(const udpa_core_v1_ResourceName *msg) { return _upb_hasbit(msg, 1); }
+UPB_INLINE const struct udpa_core_v1_ContextParams* udpa_core_v1_ResourceName_context(const udpa_core_v1_ResourceName *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(20, 40), const struct udpa_core_v1_ContextParams*); }
 
 UPB_INLINE upb_strview* udpa_core_v1_ResourceName_mutable_id(udpa_core_v1_ResourceName *msg, size_t *len) {
-  return (upb_strview*)_upb_array_mutable_accessor(msg, UPB_SIZE(20, 40), len);
+  return (upb_strview*)_upb_array_mutable_accessor(msg, UPB_SIZE(24, 48), len);
 }
 UPB_INLINE upb_strview* udpa_core_v1_ResourceName_resize_id(udpa_core_v1_ResourceName *msg, size_t len, upb_arena *arena) {
-  return (upb_strview*)_upb_array_resize_accessor(msg, UPB_SIZE(20, 40), len, UPB_TYPE_STRING, arena);
+  return (upb_strview*)_upb_array_resize_accessor2(msg, UPB_SIZE(24, 48), len, UPB_SIZE(3, 4), arena);
 }
 UPB_INLINE bool udpa_core_v1_ResourceName_add_id(udpa_core_v1_ResourceName *msg, upb_strview val, upb_arena *arena) {
-  return _upb_array_append_accessor(msg, UPB_SIZE(20, 40), UPB_SIZE(8, 16), UPB_TYPE_STRING, &val,
+  return _upb_array_append_accessor2(msg, UPB_SIZE(24, 48), UPB_SIZE(3, 4), &val,
       arena);
 }
 UPB_INLINE void udpa_core_v1_ResourceName_set_authority(udpa_core_v1_ResourceName *msg, upb_strview value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(0, 0), upb_strview) = value;
+  *UPB_PTR_AT(msg, UPB_SIZE(4, 8), upb_strview) = value;
 }
 UPB_INLINE void udpa_core_v1_ResourceName_set_resource_type(udpa_core_v1_ResourceName *msg, upb_strview value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(8, 16), upb_strview) = value;
+  *UPB_PTR_AT(msg, UPB_SIZE(12, 24), upb_strview) = value;
 }
 UPB_INLINE void udpa_core_v1_ResourceName_set_context(udpa_core_v1_ResourceName *msg, struct udpa_core_v1_ContextParams* value) {
-  *UPB_PTR_AT(msg, UPB_SIZE(16, 32), struct udpa_core_v1_ContextParams*) = value;
+  _upb_sethas(msg, 1);
+  *UPB_PTR_AT(msg, UPB_SIZE(20, 40), struct udpa_core_v1_ContextParams*) = value;
 }
 UPB_INLINE struct udpa_core_v1_ContextParams* udpa_core_v1_ResourceName_mutable_context(udpa_core_v1_ResourceName *msg, upb_arena *arena) {
   struct udpa_core_v1_ContextParams* sub = (struct udpa_core_v1_ContextParams*)udpa_core_v1_ResourceName_context(msg);
index aa9918f..e5069b7 100644 (file)
@@ -29,7 +29,7 @@ static const upb_msglayout_field udpa_data_orca_v1_OrcaLoadReport__fields[5] = {
 const upb_msglayout udpa_data_orca_v1_OrcaLoadReport_msginit = {
   &udpa_data_orca_v1_OrcaLoadReport_submsgs[0],
   &udpa_data_orca_v1_OrcaLoadReport__fields[0],
-  UPB_SIZE(32, 40), 5, false,
+  UPB_SIZE(32, 40), 5, false, 255,
 };
 
 static const upb_msglayout_field udpa_data_orca_v1_OrcaLoadReport_RequestCostEntry__fields[2] = {
@@ -40,7 +40,7 @@ static const upb_msglayout_field udpa_data_orca_v1_OrcaLoadReport_RequestCostEnt
 const upb_msglayout udpa_data_orca_v1_OrcaLoadReport_RequestCostEntry_msginit = {
   NULL,
   &udpa_data_orca_v1_OrcaLoadReport_RequestCostEntry__fields[0],
-  UPB_SIZE(16, 32), 2, false,
+  UPB_SIZE(16, 32), 2, false, 255,
 };
 
 static const upb_msglayout_field udpa_data_orca_v1_OrcaLoadReport_UtilizationEntry__fields[2] = {
@@ -51,7 +51,7 @@ static const upb_msglayout_field udpa_data_orca_v1_OrcaLoadReport_UtilizationEnt
 const upb_msglayout udpa_data_orca_v1_OrcaLoadReport_UtilizationEntry_msginit = {
   NULL,
   &udpa_data_orca_v1_OrcaLoadReport_UtilizationEntry__fields[0],
-  UPB_SIZE(16, 32), 2, false,
+  UPB_SIZE(16, 32), 2, false, 255,
 };
 
 #include "upb/port_undef.inc"
index 5c63aef..e5923cc 100644 (file)
@@ -11,6 +11,7 @@
 
 #include "upb/msg.h"
 #include "upb/decode.h"
+#include "upb/decode_fast.h"
 #include "upb/encode.h"
 
 #include "upb/port_def.inc"
@@ -40,6 +41,12 @@ UPB_INLINE udpa_data_orca_v1_OrcaLoadReport *udpa_data_orca_v1_OrcaLoadReport_pa
   udpa_data_orca_v1_OrcaLoadReport *ret = udpa_data_orca_v1_OrcaLoadReport_new(arena);
   return (ret && upb_decode(buf, size, ret, &udpa_data_orca_v1_OrcaLoadReport_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE udpa_data_orca_v1_OrcaLoadReport *udpa_data_orca_v1_OrcaLoadReport_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  udpa_data_orca_v1_OrcaLoadReport *ret = udpa_data_orca_v1_OrcaLoadReport_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &udpa_data_orca_v1_OrcaLoadReport_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *udpa_data_orca_v1_OrcaLoadReport_serialize(const udpa_data_orca_v1_OrcaLoadReport *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &udpa_data_orca_v1_OrcaLoadReport_msginit, arena, len);
 }
index 63c3243..ec2888e 100644 (file)
@@ -68,7 +68,7 @@ static const upb_msglayout_field validate_FieldRules__fields[22] = {
 const upb_msglayout validate_FieldRules_msginit = {
   &validate_FieldRules_submsgs[0],
   &validate_FieldRules__fields[0],
-  UPB_SIZE(16, 32), 22, false,
+  UPB_SIZE(16, 32), 22, false, 255,
 };
 
 static const upb_msglayout_field validate_FloatRules__fields[7] = {
@@ -84,7 +84,7 @@ static const upb_msglayout_field validate_FloatRules__fields[7] = {
 const upb_msglayout validate_FloatRules_msginit = {
   NULL,
   &validate_FloatRules__fields[0],
-  UPB_SIZE(32, 40), 7, false,
+  UPB_SIZE(32, 40), 7, false, 255,
 };
 
 static const upb_msglayout_field validate_DoubleRules__fields[7] = {
@@ -100,7 +100,7 @@ static const upb_msglayout_field validate_DoubleRules__fields[7] = {
 const upb_msglayout validate_DoubleRules_msginit = {
   NULL,
   &validate_DoubleRules__fields[0],
-  UPB_SIZE(56, 64), 7, false,
+  UPB_SIZE(56, 64), 7, false, 255,
 };
 
 static const upb_msglayout_field validate_Int32Rules__fields[7] = {
@@ -116,7 +116,7 @@ static const upb_msglayout_field validate_Int32Rules__fields[7] = {
 const upb_msglayout validate_Int32Rules_msginit = {
   NULL,
   &validate_Int32Rules__fields[0],
-  UPB_SIZE(32, 40), 7, false,
+  UPB_SIZE(32, 40), 7, false, 255,
 };
 
 static const upb_msglayout_field validate_Int64Rules__fields[7] = {
@@ -132,7 +132,7 @@ static const upb_msglayout_field validate_Int64Rules__fields[7] = {
 const upb_msglayout validate_Int64Rules_msginit = {
   NULL,
   &validate_Int64Rules__fields[0],
-  UPB_SIZE(56, 64), 7, false,
+  UPB_SIZE(56, 64), 7, false, 255,
 };
 
 static const upb_msglayout_field validate_UInt32Rules__fields[7] = {
@@ -148,7 +148,7 @@ static const upb_msglayout_field validate_UInt32Rules__fields[7] = {
 const upb_msglayout validate_UInt32Rules_msginit = {
   NULL,
   &validate_UInt32Rules__fields[0],
-  UPB_SIZE(32, 40), 7, false,
+  UPB_SIZE(32, 40), 7, false, 255,
 };
 
 static const upb_msglayout_field validate_UInt64Rules__fields[7] = {
@@ -164,7 +164,7 @@ static const upb_msglayout_field validate_UInt64Rules__fields[7] = {
 const upb_msglayout validate_UInt64Rules_msginit = {
   NULL,
   &validate_UInt64Rules__fields[0],
-  UPB_SIZE(56, 64), 7, false,
+  UPB_SIZE(56, 64), 7, false, 255,
 };
 
 static const upb_msglayout_field validate_SInt32Rules__fields[7] = {
@@ -180,7 +180,7 @@ static const upb_msglayout_field validate_SInt32Rules__fields[7] = {
 const upb_msglayout validate_SInt32Rules_msginit = {
   NULL,
   &validate_SInt32Rules__fields[0],
-  UPB_SIZE(32, 40), 7, false,
+  UPB_SIZE(32, 40), 7, false, 255,
 };
 
 static const upb_msglayout_field validate_SInt64Rules__fields[7] = {
@@ -196,7 +196,7 @@ static const upb_msglayout_field validate_SInt64Rules__fields[7] = {
 const upb_msglayout validate_SInt64Rules_msginit = {
   NULL,
   &validate_SInt64Rules__fields[0],
-  UPB_SIZE(56, 64), 7, false,
+  UPB_SIZE(56, 64), 7, false, 255,
 };
 
 static const upb_msglayout_field validate_Fixed32Rules__fields[7] = {
@@ -212,7 +212,7 @@ static const upb_msglayout_field validate_Fixed32Rules__fields[7] = {
 const upb_msglayout validate_Fixed32Rules_msginit = {
   NULL,
   &validate_Fixed32Rules__fields[0],
-  UPB_SIZE(32, 40), 7, false,
+  UPB_SIZE(32, 40), 7, false, 255,
 };
 
 static const upb_msglayout_field validate_Fixed64Rules__fields[7] = {
@@ -228,7 +228,7 @@ static const upb_msglayout_field validate_Fixed64Rules__fields[7] = {
 const upb_msglayout validate_Fixed64Rules_msginit = {
   NULL,
   &validate_Fixed64Rules__fields[0],
-  UPB_SIZE(56, 64), 7, false,
+  UPB_SIZE(56, 64), 7, false, 255,
 };
 
 static const upb_msglayout_field validate_SFixed32Rules__fields[7] = {
@@ -244,7 +244,7 @@ static const upb_msglayout_field validate_SFixed32Rules__fields[7] = {
 const upb_msglayout validate_SFixed32Rules_msginit = {
   NULL,
   &validate_SFixed32Rules__fields[0],
-  UPB_SIZE(32, 40), 7, false,
+  UPB_SIZE(32, 40), 7, false, 255,
 };
 
 static const upb_msglayout_field validate_SFixed64Rules__fields[7] = {
@@ -260,7 +260,7 @@ static const upb_msglayout_field validate_SFixed64Rules__fields[7] = {
 const upb_msglayout validate_SFixed64Rules_msginit = {
   NULL,
   &validate_SFixed64Rules__fields[0],
-  UPB_SIZE(56, 64), 7, false,
+  UPB_SIZE(56, 64), 7, false, 255,
 };
 
 static const upb_msglayout_field validate_BoolRules__fields[1] = {
@@ -270,63 +270,63 @@ static const upb_msglayout_field validate_BoolRules__fields[1] = {
 const upb_msglayout validate_BoolRules_msginit = {
   NULL,
   &validate_BoolRules__fields[0],
-  UPB_SIZE(2, 2), 1, false,
+  UPB_SIZE(8, 8), 1, false, 255,
 };
 
 static const upb_msglayout_field validate_StringRules__fields[25] = {
-  {1, UPB_SIZE(60, 64), 8, 0, 12, 1},
-  {2, UPB_SIZE(8, 8), 1, 0, 4, 1},
-  {3, UPB_SIZE(16, 16), 2, 0, 4, 1},
-  {4, UPB_SIZE(24, 24), 3, 0, 4, 1},
-  {5, UPB_SIZE(32, 32), 4, 0, 4, 1},
-  {6, UPB_SIZE(68, 80), 9, 0, 12, 1},
-  {7, UPB_SIZE(76, 96), 10, 0, 12, 1},
-  {8, UPB_SIZE(84, 112), 11, 0, 12, 1},
-  {9, UPB_SIZE(92, 128), 12, 0, 12, 1},
+  {1, UPB_SIZE(60, 64), 1, 0, 12, 1},
+  {2, UPB_SIZE(8, 8), 2, 0, 4, 1},
+  {3, UPB_SIZE(16, 16), 3, 0, 4, 1},
+  {4, UPB_SIZE(24, 24), 4, 0, 4, 1},
+  {5, UPB_SIZE(32, 32), 5, 0, 4, 1},
+  {6, UPB_SIZE(68, 80), 6, 0, 12, 1},
+  {7, UPB_SIZE(76, 96), 7, 0, 12, 1},
+  {8, UPB_SIZE(84, 112), 8, 0, 12, 1},
+  {9, UPB_SIZE(92, 128), 9, 0, 12, 1},
   {10, UPB_SIZE(108, 160), 0, 0, 12, 3},
   {11, UPB_SIZE(112, 168), 0, 0, 12, 3},
-  {12, UPB_SIZE(120, 176), UPB_SIZE(-129, -185), 0, 8, 1},
-  {13, UPB_SIZE(120, 176), UPB_SIZE(-129, -185), 0, 8, 1},
-  {14, UPB_SIZE(120, 176), UPB_SIZE(-129, -185), 0, 8, 1},
-  {15, UPB_SIZE(120, 176), UPB_SIZE(-129, -185), 0, 8, 1},
-  {16, UPB_SIZE(120, 176), UPB_SIZE(-129, -185), 0, 8, 1},
-  {17, UPB_SIZE(120, 176), UPB_SIZE(-129, -185), 0, 8, 1},
-  {18, UPB_SIZE(120, 176), UPB_SIZE(-129, -185), 0, 8, 1},
-  {19, UPB_SIZE(40, 40), 5, 0, 4, 1},
-  {20, UPB_SIZE(48, 48), 6, 0, 4, 1},
-  {21, UPB_SIZE(120, 176), UPB_SIZE(-129, -185), 0, 8, 1},
-  {22, UPB_SIZE(120, 176), UPB_SIZE(-129, -185), 0, 8, 1},
-  {23, UPB_SIZE(100, 144), 13, 0, 12, 1},
-  {24, UPB_SIZE(120, 176), UPB_SIZE(-129, -185), 0, 14, 1},
-  {25, UPB_SIZE(56, 56), 7, 0, 8, 1},
+  {12, UPB_SIZE(116, 176), UPB_SIZE(-121, -181), 0, 8, 1},
+  {13, UPB_SIZE(116, 176), UPB_SIZE(-121, -181), 0, 8, 1},
+  {14, UPB_SIZE(116, 176), UPB_SIZE(-121, -181), 0, 8, 1},
+  {15, UPB_SIZE(116, 176), UPB_SIZE(-121, -181), 0, 8, 1},
+  {16, UPB_SIZE(116, 176), UPB_SIZE(-121, -181), 0, 8, 1},
+  {17, UPB_SIZE(116, 176), UPB_SIZE(-121, -181), 0, 8, 1},
+  {18, UPB_SIZE(116, 176), UPB_SIZE(-121, -181), 0, 8, 1},
+  {19, UPB_SIZE(40, 40), 10, 0, 4, 1},
+  {20, UPB_SIZE(48, 48), 11, 0, 4, 1},
+  {21, UPB_SIZE(116, 176), UPB_SIZE(-121, -181), 0, 8, 1},
+  {22, UPB_SIZE(116, 176), UPB_SIZE(-121, -181), 0, 8, 1},
+  {23, UPB_SIZE(100, 144), 12, 0, 12, 1},
+  {24, UPB_SIZE(116, 176), UPB_SIZE(-121, -181), 0, 14, 1},
+  {25, UPB_SIZE(56, 56), 13, 0, 8, 1},
 };
 
 const upb_msglayout validate_StringRules_msginit = {
   NULL,
   &validate_StringRules__fields[0],
-  UPB_SIZE(136, 192), 25, false,
+  UPB_SIZE(128, 192), 25, false, 255,
 };
 
 static const upb_msglayout_field validate_BytesRules__fields[13] = {
-  {1, UPB_SIZE(32, 32), 4, 0, 12, 1},
-  {2, UPB_SIZE(8, 8), 1, 0, 4, 1},
-  {3, UPB_SIZE(16, 16), 2, 0, 4, 1},
-  {4, UPB_SIZE(40, 48), 5, 0, 12, 1},
-  {5, UPB_SIZE(48, 64), 6, 0, 12, 1},
-  {6, UPB_SIZE(56, 80), 7, 0, 12, 1},
-  {7, UPB_SIZE(64, 96), 8, 0, 12, 1},
+  {1, UPB_SIZE(32, 32), 1, 0, 12, 1},
+  {2, UPB_SIZE(8, 8), 2, 0, 4, 1},
+  {3, UPB_SIZE(16, 16), 3, 0, 4, 1},
+  {4, UPB_SIZE(40, 48), 4, 0, 12, 1},
+  {5, UPB_SIZE(48, 64), 5, 0, 12, 1},
+  {6, UPB_SIZE(56, 80), 6, 0, 12, 1},
+  {7, UPB_SIZE(64, 96), 7, 0, 12, 1},
   {8, UPB_SIZE(72, 112), 0, 0, 12, 3},
   {9, UPB_SIZE(76, 120), 0, 0, 12, 3},
   {10, UPB_SIZE(80, 128), UPB_SIZE(-85, -133), 0, 8, 1},
   {11, UPB_SIZE(80, 128), UPB_SIZE(-85, -133), 0, 8, 1},
   {12, UPB_SIZE(80, 128), UPB_SIZE(-85, -133), 0, 8, 1},
-  {13, UPB_SIZE(24, 24), 3, 0, 4, 1},
+  {13, UPB_SIZE(24, 24), 8, 0, 4, 1},
 };
 
 const upb_msglayout validate_BytesRules_msginit = {
   NULL,
   &validate_BytesRules__fields[0],
-  UPB_SIZE(88, 144), 13, false,
+  UPB_SIZE(88, 144), 13, false, 255,
 };
 
 static const upb_msglayout_field validate_EnumRules__fields[4] = {
@@ -339,7 +339,7 @@ static const upb_msglayout_field validate_EnumRules__fields[4] = {
 const upb_msglayout validate_EnumRules_msginit = {
   NULL,
   &validate_EnumRules__fields[0],
-  UPB_SIZE(20, 32), 4, false,
+  UPB_SIZE(24, 32), 4, false, 255,
 };
 
 static const upb_msglayout_field validate_MessageRules__fields[2] = {
@@ -350,7 +350,7 @@ static const upb_msglayout_field validate_MessageRules__fields[2] = {
 const upb_msglayout validate_MessageRules_msginit = {
   NULL,
   &validate_MessageRules__fields[0],
-  UPB_SIZE(3, 3), 2, false,
+  UPB_SIZE(8, 8), 2, false, 255,
 };
 
 static const upb_msglayout *const validate_RepeatedRules_submsgs[1] = {
@@ -367,10 +367,10 @@ static const upb_msglayout_field validate_RepeatedRules__fields[4] = {
 const upb_msglayout validate_RepeatedRules_msginit = {
   &validate_RepeatedRules_submsgs[0],
   &validate_RepeatedRules__fields[0],
-  UPB_SIZE(32, 40), 4, false,
+  UPB_SIZE(32, 40), 4, false, 255,
 };
 
-static const upb_msglayout *const validate_MapRules_submsgs[2] = {
+static const upb_msglayout *const validate_MapRules_submsgs[1] = {
   &validate_FieldRules_msginit,
 };
 
@@ -385,7 +385,7 @@ static const upb_msglayout_field validate_MapRules__fields[5] = {
 const upb_msglayout validate_MapRules_msginit = {
   &validate_MapRules_submsgs[0],
   &validate_MapRules__fields[0],
-  UPB_SIZE(40, 48), 5, false,
+  UPB_SIZE(40, 48), 5, false, 255,
 };
 
 static const upb_msglayout_field validate_AnyRules__fields[3] = {
@@ -397,10 +397,10 @@ static const upb_msglayout_field validate_AnyRules__fields[3] = {
 const upb_msglayout validate_AnyRules_msginit = {
   NULL,
   &validate_AnyRules__fields[0],
-  UPB_SIZE(12, 24), 3, false,
+  UPB_SIZE(16, 24), 3, false, 255,
 };
 
-static const upb_msglayout *const validate_DurationRules_submsgs[7] = {
+static const upb_msglayout *const validate_DurationRules_submsgs[1] = {
   &google_protobuf_Duration_msginit,
 };
 
@@ -418,30 +418,30 @@ static const upb_msglayout_field validate_DurationRules__fields[8] = {
 const upb_msglayout validate_DurationRules_msginit = {
   &validate_DurationRules_submsgs[0],
   &validate_DurationRules__fields[0],
-  UPB_SIZE(32, 64), 8, false,
+  UPB_SIZE(32, 64), 8, false, 255,
 };
 
-static const upb_msglayout *const validate_TimestampRules_submsgs[6] = {
+static const upb_msglayout *const validate_TimestampRules_submsgs[2] = {
   &google_protobuf_Duration_msginit,
   &google_protobuf_Timestamp_msginit,
 };
 
 static const upb_msglayout_field validate_TimestampRules__fields[9] = {
   {1, UPB_SIZE(2, 2), 1, 0, 8, 1},
-  {2, UPB_SIZE(8, 8), 4, 1, 11, 1},
-  {3, UPB_SIZE(12, 16), 5, 1, 11, 1},
-  {4, UPB_SIZE(16, 24), 6, 1, 11, 1},
-  {5, UPB_SIZE(20, 32), 7, 1, 11, 1},
-  {6, UPB_SIZE(24, 40), 8, 1, 11, 1},
-  {7, UPB_SIZE(3, 3), 2, 0, 8, 1},
-  {8, UPB_SIZE(4, 4), 3, 0, 8, 1},
+  {2, UPB_SIZE(8, 8), 2, 1, 11, 1},
+  {3, UPB_SIZE(12, 16), 3, 1, 11, 1},
+  {4, UPB_SIZE(16, 24), 4, 1, 11, 1},
+  {5, UPB_SIZE(20, 32), 5, 1, 11, 1},
+  {6, UPB_SIZE(24, 40), 6, 1, 11, 1},
+  {7, UPB_SIZE(3, 3), 7, 0, 8, 1},
+  {8, UPB_SIZE(4, 4), 8, 0, 8, 1},
   {9, UPB_SIZE(28, 48), 9, 0, 11, 1},
 };
 
 const upb_msglayout validate_TimestampRules_msginit = {
   &validate_TimestampRules_submsgs[0],
   &validate_TimestampRules__fields[0],
-  UPB_SIZE(32, 56), 9, false,
+  UPB_SIZE(32, 56), 9, false, 255,
 };
 
 #include "upb/port_undef.inc"
index c29b4ec..dcde0a9 100644 (file)
@@ -11,6 +11,7 @@
 
 #include "upb/msg.h"
 #include "upb/decode.h"
+#include "upb/decode_fast.h"
 #include "upb/encode.h"
 
 #include "upb/port_def.inc"
@@ -110,6 +111,12 @@ UPB_INLINE validate_FieldRules *validate_FieldRules_parse(const char *buf, size_
   validate_FieldRules *ret = validate_FieldRules_new(arena);
   return (ret && upb_decode(buf, size, ret, &validate_FieldRules_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE validate_FieldRules *validate_FieldRules_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  validate_FieldRules *ret = validate_FieldRules_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &validate_FieldRules_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *validate_FieldRules_serialize(const validate_FieldRules *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &validate_FieldRules_msginit, arena, len);
 }
@@ -461,6 +468,12 @@ UPB_INLINE validate_FloatRules *validate_FloatRules_parse(const char *buf, size_
   validate_FloatRules *ret = validate_FloatRules_new(arena);
   return (ret && upb_decode(buf, size, ret, &validate_FloatRules_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE validate_FloatRules *validate_FloatRules_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  validate_FloatRules *ret = validate_FloatRules_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &validate_FloatRules_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *validate_FloatRules_serialize(const validate_FloatRules *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &validate_FloatRules_msginit, arena, len);
 }
@@ -502,20 +515,20 @@ UPB_INLINE float* validate_FloatRules_mutable_in(validate_FloatRules *msg, size_
   return (float*)_upb_array_mutable_accessor(msg, UPB_SIZE(24, 24), len);
 }
 UPB_INLINE float* validate_FloatRules_resize_in(validate_FloatRules *msg, size_t len, upb_arena *arena) {
-  return (float*)_upb_array_resize_accessor(msg, UPB_SIZE(24, 24), len, UPB_TYPE_FLOAT, arena);
+  return (float*)_upb_array_resize_accessor2(msg, UPB_SIZE(24, 24), len, 2, arena);
 }
 UPB_INLINE bool validate_FloatRules_add_in(validate_FloatRules *msg, float val, upb_arena *arena) {
-  return _upb_array_append_accessor(msg, UPB_SIZE(24, 24), UPB_SIZE(4, 4), UPB_TYPE_FLOAT, &val,
+  return _upb_array_append_accessor2(msg, UPB_SIZE(24, 24), 2, &val,
       arena);
 }
 UPB_INLINE float* validate_FloatRules_mutable_not_in(validate_FloatRules *msg, size_t *len) {
   return (float*)_upb_array_mutable_accessor(msg, UPB_SIZE(28, 32), len);
 }
 UPB_INLINE float* validate_FloatRules_resize_not_in(validate_FloatRules *msg, size_t len, upb_arena *arena) {
-  return (float*)_upb_array_resize_accessor(msg, UPB_SIZE(28, 32), len, UPB_TYPE_FLOAT, arena);
+  return (float*)_upb_array_resize_accessor2(msg, UPB_SIZE(28, 32), len, 2, arena);
 }
 UPB_INLINE bool validate_FloatRules_add_not_in(validate_FloatRules *msg, float val, upb_arena *arena) {
-  return _upb_array_append_accessor(msg, UPB_SIZE(28, 32), UPB_SIZE(4, 4), UPB_TYPE_FLOAT, &val,
+  return _upb_array_append_accessor2(msg, UPB_SIZE(28, 32), 2, &val,
       arena);
 }
 
@@ -529,6 +542,12 @@ UPB_INLINE validate_DoubleRules *validate_DoubleRules_parse(const char *buf, siz
   validate_DoubleRules *ret = validate_DoubleRules_new(arena);
   return (ret && upb_decode(buf, size, ret, &validate_DoubleRules_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE validate_DoubleRules *validate_DoubleRules_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  validate_DoubleRules *ret = validate_DoubleRules_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &validate_DoubleRules_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *validate_DoubleRules_serialize(const validate_DoubleRules *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &validate_DoubleRules_msginit, arena, len);
 }
@@ -570,20 +589,20 @@ UPB_INLINE double* validate_DoubleRules_mutable_in(validate_DoubleRules *msg, si
   return (double*)_upb_array_mutable_accessor(msg, UPB_SIZE(48, 48), len);
 }
 UPB_INLINE double* validate_DoubleRules_resize_in(validate_DoubleRules *msg, size_t len, upb_arena *arena) {
-  return (double*)_upb_array_resize_accessor(msg, UPB_SIZE(48, 48), len, UPB_TYPE_DOUBLE, arena);
+  return (double*)_upb_array_resize_accessor2(msg, UPB_SIZE(48, 48), len, 3, arena);
 }
 UPB_INLINE bool validate_DoubleRules_add_in(validate_DoubleRules *msg, double val, upb_arena *arena) {
-  return _upb_array_append_accessor(msg, UPB_SIZE(48, 48), UPB_SIZE(8, 8), UPB_TYPE_DOUBLE, &val,
+  return _upb_array_append_accessor2(msg, UPB_SIZE(48, 48), 3, &val,
       arena);
 }
 UPB_INLINE double* validate_DoubleRules_mutable_not_in(validate_DoubleRules *msg, size_t *len) {
   return (double*)_upb_array_mutable_accessor(msg, UPB_SIZE(52, 56), len);
 }
 UPB_INLINE double* validate_DoubleRules_resize_not_in(validate_DoubleRules *msg, size_t len, upb_arena *arena) {
-  return (double*)_upb_array_resize_accessor(msg, UPB_SIZE(52, 56), len, UPB_TYPE_DOUBLE, arena);
+  return (double*)_upb_array_resize_accessor2(msg, UPB_SIZE(52, 56), len, 3, arena);
 }
 UPB_INLINE bool validate_DoubleRules_add_not_in(validate_DoubleRules *msg, double val, upb_arena *arena) {
-  return _upb_array_append_accessor(msg, UPB_SIZE(52, 56), UPB_SIZE(8, 8), UPB_TYPE_DOUBLE, &val,
+  return _upb_array_append_accessor2(msg, UPB_SIZE(52, 56), 3, &val,
       arena);
 }
 
@@ -597,6 +616,12 @@ UPB_INLINE validate_Int32Rules *validate_Int32Rules_parse(const char *buf, size_
   validate_Int32Rules *ret = validate_Int32Rules_new(arena);
   return (ret && upb_decode(buf, size, ret, &validate_Int32Rules_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE validate_Int32Rules *validate_Int32Rules_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  validate_Int32Rules *ret = validate_Int32Rules_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &validate_Int32Rules_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *validate_Int32Rules_serialize(const validate_Int32Rules *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &validate_Int32Rules_msginit, arena, len);
 }
@@ -638,20 +663,20 @@ UPB_INLINE int32_t* validate_Int32Rules_mutable_in(validate_Int32Rules *msg, siz
   return (int32_t*)_upb_array_mutable_accessor(msg, UPB_SIZE(24, 24), len);
 }
 UPB_INLINE int32_t* validate_Int32Rules_resize_in(validate_Int32Rules *msg, size_t len, upb_arena *arena) {
-  return (int32_t*)_upb_array_resize_accessor(msg, UPB_SIZE(24, 24), len, UPB_TYPE_INT32, arena);
+  return (int32_t*)_upb_array_resize_accessor2(msg, UPB_SIZE(24, 24), len, 2, arena);
 }
 UPB_INLINE bool validate_Int32Rules_add_in(validate_Int32Rules *msg, int32_t val, upb_arena *arena) {
-  return _upb_array_append_accessor(msg, UPB_SIZE(24, 24), UPB_SIZE(4, 4), UPB_TYPE_INT32, &val,
+  return _upb_array_append_accessor2(msg, UPB_SIZE(24, 24), 2, &val,
       arena);
 }
 UPB_INLINE int32_t* validate_Int32Rules_mutable_not_in(validate_Int32Rules *msg, size_t *len) {
   return (int32_t*)_upb_array_mutable_accessor(msg, UPB_SIZE(28, 32), len);
 }
 UPB_INLINE int32_t* validate_Int32Rules_resize_not_in(validate_Int32Rules *msg, size_t len, upb_arena *arena) {
-  return (int32_t*)_upb_array_resize_accessor(msg, UPB_SIZE(28, 32), len, UPB_TYPE_INT32, arena);
+  return (int32_t*)_upb_array_resize_accessor2(msg, UPB_SIZE(28, 32), len, 2, arena);
 }
 UPB_INLINE bool validate_Int32Rules_add_not_in(validate_Int32Rules *msg, int32_t val, upb_arena *arena) {
-  return _upb_array_append_accessor(msg, UPB_SIZE(28, 32), UPB_SIZE(4, 4), UPB_TYPE_INT32, &val,
+  return _upb_array_append_accessor2(msg, UPB_SIZE(28, 32), 2, &val,
       arena);
 }
 
@@ -665,6 +690,12 @@ UPB_INLINE validate_Int64Rules *validate_Int64Rules_parse(const char *buf, size_
   validate_Int64Rules *ret = validate_Int64Rules_new(arena);
   return (ret && upb_decode(buf, size, ret, &validate_Int64Rules_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE validate_Int64Rules *validate_Int64Rules_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  validate_Int64Rules *ret = validate_Int64Rules_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &validate_Int64Rules_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *validate_Int64Rules_serialize(const validate_Int64Rules *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &validate_Int64Rules_msginit, arena, len);
 }
@@ -706,20 +737,20 @@ UPB_INLINE int64_t* validate_Int64Rules_mutable_in(validate_Int64Rules *msg, siz
   return (int64_t*)_upb_array_mutable_accessor(msg, UPB_SIZE(48, 48), len);
 }
 UPB_INLINE int64_t* validate_Int64Rules_resize_in(validate_Int64Rules *msg, size_t len, upb_arena *arena) {
-  return (int64_t*)_upb_array_resize_accessor(msg, UPB_SIZE(48, 48), len, UPB_TYPE_INT64, arena);
+  return (int64_t*)_upb_array_resize_accessor2(msg, UPB_SIZE(48, 48), len, 3, arena);
 }
 UPB_INLINE bool validate_Int64Rules_add_in(validate_Int64Rules *msg, int64_t val, upb_arena *arena) {
-  return _upb_array_append_accessor(msg, UPB_SIZE(48, 48), UPB_SIZE(8, 8), UPB_TYPE_INT64, &val,
+  return _upb_array_append_accessor2(msg, UPB_SIZE(48, 48), 3, &val,
       arena);
 }
 UPB_INLINE int64_t* validate_Int64Rules_mutable_not_in(validate_Int64Rules *msg, size_t *len) {
   return (int64_t*)_upb_array_mutable_accessor(msg, UPB_SIZE(52, 56), len);
 }
 UPB_INLINE int64_t* validate_Int64Rules_resize_not_in(validate_Int64Rules *msg, size_t len, upb_arena *arena) {
-  return (int64_t*)_upb_array_resize_accessor(msg, UPB_SIZE(52, 56), len, UPB_TYPE_INT64, arena);
+  return (int64_t*)_upb_array_resize_accessor2(msg, UPB_SIZE(52, 56), len, 3, arena);
 }
 UPB_INLINE bool validate_Int64Rules_add_not_in(validate_Int64Rules *msg, int64_t val, upb_arena *arena) {
-  return _upb_array_append_accessor(msg, UPB_SIZE(52, 56), UPB_SIZE(8, 8), UPB_TYPE_INT64, &val,
+  return _upb_array_append_accessor2(msg, UPB_SIZE(52, 56), 3, &val,
       arena);
 }
 
@@ -733,6 +764,12 @@ UPB_INLINE validate_UInt32Rules *validate_UInt32Rules_parse(const char *buf, siz
   validate_UInt32Rules *ret = validate_UInt32Rules_new(arena);
   return (ret && upb_decode(buf, size, ret, &validate_UInt32Rules_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE validate_UInt32Rules *validate_UInt32Rules_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  validate_UInt32Rules *ret = validate_UInt32Rules_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &validate_UInt32Rules_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *validate_UInt32Rules_serialize(const validate_UInt32Rules *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &validate_UInt32Rules_msginit, arena, len);
 }
@@ -774,20 +811,20 @@ UPB_INLINE uint32_t* validate_UInt32Rules_mutable_in(validate_UInt32Rules *msg,
   return (uint32_t*)_upb_array_mutable_accessor(msg, UPB_SIZE(24, 24), len);
 }
 UPB_INLINE uint32_t* validate_UInt32Rules_resize_in(validate_UInt32Rules *msg, size_t len, upb_arena *arena) {
-  return (uint32_t*)_upb_array_resize_accessor(msg, UPB_SIZE(24, 24), len, UPB_TYPE_UINT32, arena);
+  return (uint32_t*)_upb_array_resize_accessor2(msg, UPB_SIZE(24, 24), len, 2, arena);
 }
 UPB_INLINE bool validate_UInt32Rules_add_in(validate_UInt32Rules *msg, uint32_t val, upb_arena *arena) {
-  return _upb_array_append_accessor(msg, UPB_SIZE(24, 24), UPB_SIZE(4, 4), UPB_TYPE_UINT32, &val,
+  return _upb_array_append_accessor2(msg, UPB_SIZE(24, 24), 2, &val,
       arena);
 }
 UPB_INLINE uint32_t* validate_UInt32Rules_mutable_not_in(validate_UInt32Rules *msg, size_t *len) {
   return (uint32_t*)_upb_array_mutable_accessor(msg, UPB_SIZE(28, 32), len);
 }
 UPB_INLINE uint32_t* validate_UInt32Rules_resize_not_in(validate_UInt32Rules *msg, size_t len, upb_arena *arena) {
-  return (uint32_t*)_upb_array_resize_accessor(msg, UPB_SIZE(28, 32), len, UPB_TYPE_UINT32, arena);
+  return (uint32_t*)_upb_array_resize_accessor2(msg, UPB_SIZE(28, 32), len, 2, arena);
 }
 UPB_INLINE bool validate_UInt32Rules_add_not_in(validate_UInt32Rules *msg, uint32_t val, upb_arena *arena) {
-  return _upb_array_append_accessor(msg, UPB_SIZE(28, 32), UPB_SIZE(4, 4), UPB_TYPE_UINT32, &val,
+  return _upb_array_append_accessor2(msg, UPB_SIZE(28, 32), 2, &val,
       arena);
 }
 
@@ -801,6 +838,12 @@ UPB_INLINE validate_UInt64Rules *validate_UInt64Rules_parse(const char *buf, siz
   validate_UInt64Rules *ret = validate_UInt64Rules_new(arena);
   return (ret && upb_decode(buf, size, ret, &validate_UInt64Rules_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE validate_UInt64Rules *validate_UInt64Rules_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  validate_UInt64Rules *ret = validate_UInt64Rules_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &validate_UInt64Rules_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *validate_UInt64Rules_serialize(const validate_UInt64Rules *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &validate_UInt64Rules_msginit, arena, len);
 }
@@ -842,20 +885,20 @@ UPB_INLINE uint64_t* validate_UInt64Rules_mutable_in(validate_UInt64Rules *msg,
   return (uint64_t*)_upb_array_mutable_accessor(msg, UPB_SIZE(48, 48), len);
 }
 UPB_INLINE uint64_t* validate_UInt64Rules_resize_in(validate_UInt64Rules *msg, size_t len, upb_arena *arena) {
-  return (uint64_t*)_upb_array_resize_accessor(msg, UPB_SIZE(48, 48), len, UPB_TYPE_UINT64, arena);
+  return (uint64_t*)_upb_array_resize_accessor2(msg, UPB_SIZE(48, 48), len, 3, arena);
 }
 UPB_INLINE bool validate_UInt64Rules_add_in(validate_UInt64Rules *msg, uint64_t val, upb_arena *arena) {
-  return _upb_array_append_accessor(msg, UPB_SIZE(48, 48), UPB_SIZE(8, 8), UPB_TYPE_UINT64, &val,
+  return _upb_array_append_accessor2(msg, UPB_SIZE(48, 48), 3, &val,
       arena);
 }
 UPB_INLINE uint64_t* validate_UInt64Rules_mutable_not_in(validate_UInt64Rules *msg, size_t *len) {
   return (uint64_t*)_upb_array_mutable_accessor(msg, UPB_SIZE(52, 56), len);
 }
 UPB_INLINE uint64_t* validate_UInt64Rules_resize_not_in(validate_UInt64Rules *msg, size_t len, upb_arena *arena) {
-  return (uint64_t*)_upb_array_resize_accessor(msg, UPB_SIZE(52, 56), len, UPB_TYPE_UINT64, arena);
+  return (uint64_t*)_upb_array_resize_accessor2(msg, UPB_SIZE(52, 56), len, 3, arena);
 }
 UPB_INLINE bool validate_UInt64Rules_add_not_in(validate_UInt64Rules *msg, uint64_t val, upb_arena *arena) {
-  return _upb_array_append_accessor(msg, UPB_SIZE(52, 56), UPB_SIZE(8, 8), UPB_TYPE_UINT64, &val,
+  return _upb_array_append_accessor2(msg, UPB_SIZE(52, 56), 3, &val,
       arena);
 }
 
@@ -869,6 +912,12 @@ UPB_INLINE validate_SInt32Rules *validate_SInt32Rules_parse(const char *buf, siz
   validate_SInt32Rules *ret = validate_SInt32Rules_new(arena);
   return (ret && upb_decode(buf, size, ret, &validate_SInt32Rules_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE validate_SInt32Rules *validate_SInt32Rules_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  validate_SInt32Rules *ret = validate_SInt32Rules_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &validate_SInt32Rules_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *validate_SInt32Rules_serialize(const validate_SInt32Rules *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &validate_SInt32Rules_msginit, arena, len);
 }
@@ -910,20 +959,20 @@ UPB_INLINE int32_t* validate_SInt32Rules_mutable_in(validate_SInt32Rules *msg, s
   return (int32_t*)_upb_array_mutable_accessor(msg, UPB_SIZE(24, 24), len);
 }
 UPB_INLINE int32_t* validate_SInt32Rules_resize_in(validate_SInt32Rules *msg, size_t len, upb_arena *arena) {
-  return (int32_t*)_upb_array_resize_accessor(msg, UPB_SIZE(24, 24), len, UPB_TYPE_INT32, arena);
+  return (int32_t*)_upb_array_resize_accessor2(msg, UPB_SIZE(24, 24), len, 2, arena);
 }
 UPB_INLINE bool validate_SInt32Rules_add_in(validate_SInt32Rules *msg, int32_t val, upb_arena *arena) {
-  return _upb_array_append_accessor(msg, UPB_SIZE(24, 24), UPB_SIZE(4, 4), UPB_TYPE_INT32, &val,
+  return _upb_array_append_accessor2(msg, UPB_SIZE(24, 24), 2, &val,
       arena);
 }
 UPB_INLINE int32_t* validate_SInt32Rules_mutable_not_in(validate_SInt32Rules *msg, size_t *len) {
   return (int32_t*)_upb_array_mutable_accessor(msg, UPB_SIZE(28, 32), len);
 }
 UPB_INLINE int32_t* validate_SInt32Rules_resize_not_in(validate_SInt32Rules *msg, size_t len, upb_arena *arena) {
-  return (int32_t*)_upb_array_resize_accessor(msg, UPB_SIZE(28, 32), len, UPB_TYPE_INT32, arena);
+  return (int32_t*)_upb_array_resize_accessor2(msg, UPB_SIZE(28, 32), len, 2, arena);
 }
 UPB_INLINE bool validate_SInt32Rules_add_not_in(validate_SInt32Rules *msg, int32_t val, upb_arena *arena) {
-  return _upb_array_append_accessor(msg, UPB_SIZE(28, 32), UPB_SIZE(4, 4), UPB_TYPE_INT32, &val,
+  return _upb_array_append_accessor2(msg, UPB_SIZE(28, 32), 2, &val,
       arena);
 }
 
@@ -937,6 +986,12 @@ UPB_INLINE validate_SInt64Rules *validate_SInt64Rules_parse(const char *buf, siz
   validate_SInt64Rules *ret = validate_SInt64Rules_new(arena);
   return (ret && upb_decode(buf, size, ret, &validate_SInt64Rules_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE validate_SInt64Rules *validate_SInt64Rules_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  validate_SInt64Rules *ret = validate_SInt64Rules_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &validate_SInt64Rules_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *validate_SInt64Rules_serialize(const validate_SInt64Rules *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &validate_SInt64Rules_msginit, arena, len);
 }
@@ -978,20 +1033,20 @@ UPB_INLINE int64_t* validate_SInt64Rules_mutable_in(validate_SInt64Rules *msg, s
   return (int64_t*)_upb_array_mutable_accessor(msg, UPB_SIZE(48, 48), len);
 }
 UPB_INLINE int64_t* validate_SInt64Rules_resize_in(validate_SInt64Rules *msg, size_t len, upb_arena *arena) {
-  return (int64_t*)_upb_array_resize_accessor(msg, UPB_SIZE(48, 48), len, UPB_TYPE_INT64, arena);
+  return (int64_t*)_upb_array_resize_accessor2(msg, UPB_SIZE(48, 48), len, 3, arena);
 }
 UPB_INLINE bool validate_SInt64Rules_add_in(validate_SInt64Rules *msg, int64_t val, upb_arena *arena) {
-  return _upb_array_append_accessor(msg, UPB_SIZE(48, 48), UPB_SIZE(8, 8), UPB_TYPE_INT64, &val,
+  return _upb_array_append_accessor2(msg, UPB_SIZE(48, 48), 3, &val,
       arena);
 }
 UPB_INLINE int64_t* validate_SInt64Rules_mutable_not_in(validate_SInt64Rules *msg, size_t *len) {
   return (int64_t*)_upb_array_mutable_accessor(msg, UPB_SIZE(52, 56), len);
 }
 UPB_INLINE int64_t* validate_SInt64Rules_resize_not_in(validate_SInt64Rules *msg, size_t len, upb_arena *arena) {
-  return (int64_t*)_upb_array_resize_accessor(msg, UPB_SIZE(52, 56), len, UPB_TYPE_INT64, arena);
+  return (int64_t*)_upb_array_resize_accessor2(msg, UPB_SIZE(52, 56), len, 3, arena);
 }
 UPB_INLINE bool validate_SInt64Rules_add_not_in(validate_SInt64Rules *msg, int64_t val, upb_arena *arena) {
-  return _upb_array_append_accessor(msg, UPB_SIZE(52, 56), UPB_SIZE(8, 8), UPB_TYPE_INT64, &val,
+  return _upb_array_append_accessor2(msg, UPB_SIZE(52, 56), 3, &val,
       arena);
 }
 
@@ -1005,6 +1060,12 @@ UPB_INLINE validate_Fixed32Rules *validate_Fixed32Rules_parse(const char *buf, s
   validate_Fixed32Rules *ret = validate_Fixed32Rules_new(arena);
   return (ret && upb_decode(buf, size, ret, &validate_Fixed32Rules_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE validate_Fixed32Rules *validate_Fixed32Rules_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  validate_Fixed32Rules *ret = validate_Fixed32Rules_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &validate_Fixed32Rules_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *validate_Fixed32Rules_serialize(const validate_Fixed32Rules *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &validate_Fixed32Rules_msginit, arena, len);
 }
@@ -1046,20 +1107,20 @@ UPB_INLINE uint32_t* validate_Fixed32Rules_mutable_in(validate_Fixed32Rules *msg
   return (uint32_t*)_upb_array_mutable_accessor(msg, UPB_SIZE(24, 24), len);
 }
 UPB_INLINE uint32_t* validate_Fixed32Rules_resize_in(validate_Fixed32Rules *msg, size_t len, upb_arena *arena) {
-  return (uint32_t*)_upb_array_resize_accessor(msg, UPB_SIZE(24, 24), len, UPB_TYPE_UINT32, arena);
+  return (uint32_t*)_upb_array_resize_accessor2(msg, UPB_SIZE(24, 24), len, 2, arena);
 }
 UPB_INLINE bool validate_Fixed32Rules_add_in(validate_Fixed32Rules *msg, uint32_t val, upb_arena *arena) {
-  return _upb_array_append_accessor(msg, UPB_SIZE(24, 24), UPB_SIZE(4, 4), UPB_TYPE_UINT32, &val,
+  return _upb_array_append_accessor2(msg, UPB_SIZE(24, 24), 2, &val,
       arena);
 }
 UPB_INLINE uint32_t* validate_Fixed32Rules_mutable_not_in(validate_Fixed32Rules *msg, size_t *len) {
   return (uint32_t*)_upb_array_mutable_accessor(msg, UPB_SIZE(28, 32), len);
 }
 UPB_INLINE uint32_t* validate_Fixed32Rules_resize_not_in(validate_Fixed32Rules *msg, size_t len, upb_arena *arena) {
-  return (uint32_t*)_upb_array_resize_accessor(msg, UPB_SIZE(28, 32), len, UPB_TYPE_UINT32, arena);
+  return (uint32_t*)_upb_array_resize_accessor2(msg, UPB_SIZE(28, 32), len, 2, arena);
 }
 UPB_INLINE bool validate_Fixed32Rules_add_not_in(validate_Fixed32Rules *msg, uint32_t val, upb_arena *arena) {
-  return _upb_array_append_accessor(msg, UPB_SIZE(28, 32), UPB_SIZE(4, 4), UPB_TYPE_UINT32, &val,
+  return _upb_array_append_accessor2(msg, UPB_SIZE(28, 32), 2, &val,
       arena);
 }
 
@@ -1073,6 +1134,12 @@ UPB_INLINE validate_Fixed64Rules *validate_Fixed64Rules_parse(const char *buf, s
   validate_Fixed64Rules *ret = validate_Fixed64Rules_new(arena);
   return (ret && upb_decode(buf, size, ret, &validate_Fixed64Rules_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE validate_Fixed64Rules *validate_Fixed64Rules_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  validate_Fixed64Rules *ret = validate_Fixed64Rules_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &validate_Fixed64Rules_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *validate_Fixed64Rules_serialize(const validate_Fixed64Rules *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &validate_Fixed64Rules_msginit, arena, len);
 }
@@ -1114,20 +1181,20 @@ UPB_INLINE uint64_t* validate_Fixed64Rules_mutable_in(validate_Fixed64Rules *msg
   return (uint64_t*)_upb_array_mutable_accessor(msg, UPB_SIZE(48, 48), len);
 }
 UPB_INLINE uint64_t* validate_Fixed64Rules_resize_in(validate_Fixed64Rules *msg, size_t len, upb_arena *arena) {
-  return (uint64_t*)_upb_array_resize_accessor(msg, UPB_SIZE(48, 48), len, UPB_TYPE_UINT64, arena);
+  return (uint64_t*)_upb_array_resize_accessor2(msg, UPB_SIZE(48, 48), len, 3, arena);
 }
 UPB_INLINE bool validate_Fixed64Rules_add_in(validate_Fixed64Rules *msg, uint64_t val, upb_arena *arena) {
-  return _upb_array_append_accessor(msg, UPB_SIZE(48, 48), UPB_SIZE(8, 8), UPB_TYPE_UINT64, &val,
+  return _upb_array_append_accessor2(msg, UPB_SIZE(48, 48), 3, &val,
       arena);
 }
 UPB_INLINE uint64_t* validate_Fixed64Rules_mutable_not_in(validate_Fixed64Rules *msg, size_t *len) {
   return (uint64_t*)_upb_array_mutable_accessor(msg, UPB_SIZE(52, 56), len);
 }
 UPB_INLINE uint64_t* validate_Fixed64Rules_resize_not_in(validate_Fixed64Rules *msg, size_t len, upb_arena *arena) {
-  return (uint64_t*)_upb_array_resize_accessor(msg, UPB_SIZE(52, 56), len, UPB_TYPE_UINT64, arena);
+  return (uint64_t*)_upb_array_resize_accessor2(msg, UPB_SIZE(52, 56), len, 3, arena);
 }
 UPB_INLINE bool validate_Fixed64Rules_add_not_in(validate_Fixed64Rules *msg, uint64_t val, upb_arena *arena) {
-  return _upb_array_append_accessor(msg, UPB_SIZE(52, 56), UPB_SIZE(8, 8), UPB_TYPE_UINT64, &val,
+  return _upb_array_append_accessor2(msg, UPB_SIZE(52, 56), 3, &val,
       arena);
 }
 
@@ -1141,6 +1208,12 @@ UPB_INLINE validate_SFixed32Rules *validate_SFixed32Rules_parse(const char *buf,
   validate_SFixed32Rules *ret = validate_SFixed32Rules_new(arena);
   return (ret && upb_decode(buf, size, ret, &validate_SFixed32Rules_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE validate_SFixed32Rules *validate_SFixed32Rules_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  validate_SFixed32Rules *ret = validate_SFixed32Rules_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &validate_SFixed32Rules_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *validate_SFixed32Rules_serialize(const validate_SFixed32Rules *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &validate_SFixed32Rules_msginit, arena, len);
 }
@@ -1182,20 +1255,20 @@ UPB_INLINE int32_t* validate_SFixed32Rules_mutable_in(validate_SFixed32Rules *ms
   return (int32_t*)_upb_array_mutable_accessor(msg, UPB_SIZE(24, 24), len);
 }
 UPB_INLINE int32_t* validate_SFixed32Rules_resize_in(validate_SFixed32Rules *msg, size_t len, upb_arena *arena) {
-  return (int32_t*)_upb_array_resize_accessor(msg, UPB_SIZE(24, 24), len, UPB_TYPE_INT32, arena);
+  return (int32_t*)_upb_array_resize_accessor2(msg, UPB_SIZE(24, 24), len, 2, arena);
 }
 UPB_INLINE bool validate_SFixed32Rules_add_in(validate_SFixed32Rules *msg, int32_t val, upb_arena *arena) {
-  return _upb_array_append_accessor(msg, UPB_SIZE(24, 24), UPB_SIZE(4, 4), UPB_TYPE_INT32, &val,
+  return _upb_array_append_accessor2(msg, UPB_SIZE(24, 24), 2, &val,
       arena);
 }
 UPB_INLINE int32_t* validate_SFixed32Rules_mutable_not_in(validate_SFixed32Rules *msg, size_t *len) {
   return (int32_t*)_upb_array_mutable_accessor(msg, UPB_SIZE(28, 32), len);
 }
 UPB_INLINE int32_t* validate_SFixed32Rules_resize_not_in(validate_SFixed32Rules *msg, size_t len, upb_arena *arena) {
-  return (int32_t*)_upb_array_resize_accessor(msg, UPB_SIZE(28, 32), len, UPB_TYPE_INT32, arena);
+  return (int32_t*)_upb_array_resize_accessor2(msg, UPB_SIZE(28, 32), len, 2, arena);
 }
 UPB_INLINE bool validate_SFixed32Rules_add_not_in(validate_SFixed32Rules *msg, int32_t val, upb_arena *arena) {
-  return _upb_array_append_accessor(msg, UPB_SIZE(28, 32), UPB_SIZE(4, 4), UPB_TYPE_INT32, &val,
+  return _upb_array_append_accessor2(msg, UPB_SIZE(28, 32), 2, &val,
       arena);
 }
 
@@ -1209,6 +1282,12 @@ UPB_INLINE validate_SFixed64Rules *validate_SFixed64Rules_parse(const char *buf,
   validate_SFixed64Rules *ret = validate_SFixed64Rules_new(arena);
   return (ret && upb_decode(buf, size, ret, &validate_SFixed64Rules_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE validate_SFixed64Rules *validate_SFixed64Rules_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  validate_SFixed64Rules *ret = validate_SFixed64Rules_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &validate_SFixed64Rules_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *validate_SFixed64Rules_serialize(const validate_SFixed64Rules *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &validate_SFixed64Rules_msginit, arena, len);
 }
@@ -1250,20 +1329,20 @@ UPB_INLINE int64_t* validate_SFixed64Rules_mutable_in(validate_SFixed64Rules *ms
   return (int64_t*)_upb_array_mutable_accessor(msg, UPB_SIZE(48, 48), len);
 }
 UPB_INLINE int64_t* validate_SFixed64Rules_resize_in(validate_SFixed64Rules *msg, size_t len, upb_arena *arena) {
-  return (int64_t*)_upb_array_resize_accessor(msg, UPB_SIZE(48, 48), len, UPB_TYPE_INT64, arena);
+  return (int64_t*)_upb_array_resize_accessor2(msg, UPB_SIZE(48, 48), len, 3, arena);
 }
 UPB_INLINE bool validate_SFixed64Rules_add_in(validate_SFixed64Rules *msg, int64_t val, upb_arena *arena) {
-  return _upb_array_append_accessor(msg, UPB_SIZE(48, 48), UPB_SIZE(8, 8), UPB_TYPE_INT64, &val,
+  return _upb_array_append_accessor2(msg, UPB_SIZE(48, 48), 3, &val,
       arena);
 }
 UPB_INLINE int64_t* validate_SFixed64Rules_mutable_not_in(validate_SFixed64Rules *msg, size_t *len) {
   return (int64_t*)_upb_array_mutable_accessor(msg, UPB_SIZE(52, 56), len);
 }
 UPB_INLINE int64_t* validate_SFixed64Rules_resize_not_in(validate_SFixed64Rules *msg, size_t len, upb_arena *arena) {
-  return (int64_t*)_upb_array_resize_accessor(msg, UPB_SIZE(52, 56), len, UPB_TYPE_INT64, arena);
+  return (int64_t*)_upb_array_resize_accessor2(msg, UPB_SIZE(52, 56), len, 3, arena);
 }
 UPB_INLINE bool validate_SFixed64Rules_add_not_in(validate_SFixed64Rules *msg, int64_t val, upb_arena *arena) {
-  return _upb_array_append_accessor(msg, UPB_SIZE(52, 56), UPB_SIZE(8, 8), UPB_TYPE_INT64, &val,
+  return _upb_array_append_accessor2(msg, UPB_SIZE(52, 56), 3, &val,
       arena);
 }
 
@@ -1277,6 +1356,12 @@ UPB_INLINE validate_BoolRules *validate_BoolRules_parse(const char *buf, size_t
   validate_BoolRules *ret = validate_BoolRules_new(arena);
   return (ret && upb_decode(buf, size, ret, &validate_BoolRules_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE validate_BoolRules *validate_BoolRules_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  validate_BoolRules *ret = validate_BoolRules_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &validate_BoolRules_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *validate_BoolRules_serialize(const validate_BoolRules *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &validate_BoolRules_msginit, arena, len);
 }
@@ -1299,6 +1384,12 @@ UPB_INLINE validate_StringRules *validate_StringRules_parse(const char *buf, siz
   validate_StringRules *ret = validate_StringRules_new(arena);
   return (ret && upb_decode(buf, size, ret, &validate_StringRules_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE validate_StringRules *validate_StringRules_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  validate_StringRules *ret = validate_StringRules_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &validate_StringRules_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *validate_StringRules_serialize(const validate_StringRules *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &validate_StringRules_msginit, arena, len);
 }
@@ -1316,157 +1407,157 @@ typedef enum {
   validate_StringRules_well_known_well_known_regex = 24,
   validate_StringRules_well_known_NOT_SET = 0
 } validate_StringRules_well_known_oneofcases;
-UPB_INLINE validate_StringRules_well_known_oneofcases validate_StringRules_well_known_case(const validate_StringRules* msg) { return (validate_StringRules_well_known_oneofcases)*UPB_PTR_AT(msg, UPB_SIZE(128, 184), int32_t); }
+UPB_INLINE validate_StringRules_well_known_oneofcases validate_StringRules_well_known_case(const validate_StringRules* msg) { return (validate_StringRules_well_known_oneofcases)*UPB_PTR_AT(msg, UPB_SIZE(120, 180), int32_t); }
 
-UPB_INLINE bool validate_StringRules_has_const(const validate_StringRules *msg) { return _upb_hasbit(msg, 8); }
+UPB_INLINE bool validate_StringRules_has_const(const validate_StringRules *msg) { return _upb_hasbit(msg, 1); }
 UPB_INLINE upb_strview validate_StringRules_const(const validate_StringRules *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(60, 64), upb_strview); }
-UPB_INLINE bool validate_StringRules_has_min_len(const validate_StringRules *msg) { return _upb_hasbit(msg, 1); }
+UPB_INLINE bool validate_StringRules_has_min_len(const validate_StringRules *msg) { return _upb_hasbit(msg, 2); }
 UPB_INLINE uint64_t validate_StringRules_min_len(const validate_StringRules *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(8, 8), uint64_t); }
-UPB_INLINE bool validate_StringRules_has_max_len(const validate_StringRules *msg) { return _upb_hasbit(msg, 2); }
+UPB_INLINE bool validate_StringRules_has_max_len(const validate_StringRules *msg) { return _upb_hasbit(msg, 3); }
 UPB_INLINE uint64_t validate_StringRules_max_len(const validate_StringRules *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(16, 16), uint64_t); }
-UPB_INLINE bool validate_StringRules_has_min_bytes(const validate_StringRules *msg) { return _upb_hasbit(msg, 3); }
+UPB_INLINE bool validate_StringRules_has_min_bytes(const validate_StringRules *msg) { return _upb_hasbit(msg, 4); }
 UPB_INLINE uint64_t validate_StringRules_min_bytes(const validate_StringRules *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(24, 24), uint64_t); }
-UPB_INLINE bool validate_StringRules_has_max_bytes(const validate_StringRules *msg) { return _upb_hasbit(msg, 4); }
+UPB_INLINE bool validate_StringRules_has_max_bytes(const validate_StringRules *msg) { return _upb_hasbit(msg, 5); }
 UPB_INLINE uint64_t validate_StringRules_max_bytes(const validate_StringRules *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(32, 32), uint64_t); }
-UPB_INLINE bool validate_StringRules_has_pattern(const validate_StringRules *msg) { return _upb_hasbit(msg, 9); }
+UPB_INLINE bool validate_StringRules_has_pattern(const validate_StringRules *msg) { return _upb_hasbit(msg, 6); }
 UPB_INLINE upb_strview validate_StringRules_pattern(const validate_StringRules *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(68, 80), upb_strview); }
-UPB_INLINE bool validate_StringRules_has_prefix(const validate_StringRules *msg) { return _upb_hasbit(msg, 10); }
+UPB_INLINE bool validate_StringRules_has_prefix(const validate_StringRules *msg) { return _upb_hasbit(msg, 7); }
 UPB_INLINE upb_strview validate_StringRules_prefix(const validate_StringRules *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(76, 96), upb_strview); }
-UPB_INLINE bool validate_StringRules_has_suffix(const validate_StringRules *msg) { return _upb_hasbit(msg, 11); }
+UPB_INLINE bool validate_StringRules_has_suffix(const validate_StringRules *msg) { return _upb_hasbit(msg, 8); }
 UPB_INLINE upb_strview validate_StringRules_suffix(const validate_StringRules *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(84, 112), upb_strview); }
-UPB_INLINE bool validate_StringRules_has_contains(const validate_StringRules *msg) { return _upb_hasbit(msg, 12); }
+UPB_INLINE bool validate_StringRules_has_contains(const validate_StringRules *msg) { return _upb_hasbit(msg, 9); }
 UPB_INLINE upb_strview validate_StringRules_contains(const validate_StringRules *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(92, 128), upb_strview); }
 UPB_INLINE upb_strview const* validate_StringRules_in(const validate_StringRules *msg, size_t *len) { return (upb_strview const*)_upb_array_accessor(msg, UPB_SIZE(108, 160), len); }
 UPB_INLINE upb_strview const* validate_StringRules_not_in(const validate_StringRules *msg, size_t *len) { return (upb_strview const*)_upb_array_accessor(msg, UPB_SIZE(112, 168), len); }
-UPB_INLINE bool validate_StringRules_has_email(const validate_StringRules *msg) { return _upb_getoneofcase(msg, UPB_SIZE(128, 184)) == 12; }
-UPB_INLINE bool validate_StringRules_email(const validate_StringRules *msg) { return UPB_READ_ONEOF(msg, bool, UPB_SIZE(120, 176), UPB_SIZE(128, 184), 12, false); }
-UPB_INLINE bool validate_StringRules_has_hostname(const validate_StringRules *msg) { return _upb_getoneofcase(msg, UPB_SIZE(128, 184)) == 13; }
-UPB_INLINE bool validate_StringRules_hostname(const validate_StringRules *msg) { return UPB_READ_ONEOF(msg, bool, UPB_SIZE(120, 176), UPB_SIZE(128, 184), 13, false); }
-UPB_INLINE bool validate_StringRules_has_ip(const validate_StringRules *msg) { return _upb_getoneofcase(msg, UPB_SIZE(128, 184)) == 14; }
-UPB_INLINE bool validate_StringRules_ip(const validate_StringRules *msg) { return UPB_READ_ONEOF(msg, bool, UPB_SIZE(120, 176), UPB_SIZE(128, 184), 14, false); }
-UPB_INLINE bool validate_StringRules_has_ipv4(const validate_StringRules *msg) { return _upb_getoneofcase(msg, UPB_SIZE(128, 184)) == 15; }
-UPB_INLINE bool validate_StringRules_ipv4(const validate_StringRules *msg) { return UPB_READ_ONEOF(msg, bool, UPB_SIZE(120, 176), UPB_SIZE(128, 184), 15, false); }
-UPB_INLINE bool validate_StringRules_has_ipv6(const validate_StringRules *msg) { return _upb_getoneofcase(msg, UPB_SIZE(128, 184)) == 16; }
-UPB_INLINE bool validate_StringRules_ipv6(const validate_StringRules *msg) { return UPB_READ_ONEOF(msg, bool, UPB_SIZE(120, 176), UPB_SIZE(128, 184), 16, false); }
-UPB_INLINE bool validate_StringRules_has_uri(const validate_StringRules *msg) { return _upb_getoneofcase(msg, UPB_SIZE(128, 184)) == 17; }
-UPB_INLINE bool validate_StringRules_uri(const validate_StringRules *msg) { return UPB_READ_ONEOF(msg, bool, UPB_SIZE(120, 176), UPB_SIZE(128, 184), 17, false); }
-UPB_INLINE bool validate_StringRules_has_uri_ref(const validate_StringRules *msg) { return _upb_getoneofcase(msg, UPB_SIZE(128, 184)) == 18; }
-UPB_INLINE bool validate_StringRules_uri_ref(const validate_StringRules *msg) { return UPB_READ_ONEOF(msg, bool, UPB_SIZE(120, 176), UPB_SIZE(128, 184), 18, false); }
-UPB_INLINE bool validate_StringRules_has_len(const validate_StringRules *msg) { return _upb_hasbit(msg, 5); }
+UPB_INLINE bool validate_StringRules_has_email(const validate_StringRules *msg) { return _upb_getoneofcase(msg, UPB_SIZE(120, 180)) == 12; }
+UPB_INLINE bool validate_StringRules_email(const validate_StringRules *msg) { return UPB_READ_ONEOF(msg, bool, UPB_SIZE(116, 176), UPB_SIZE(120, 180), 12, false); }
+UPB_INLINE bool validate_StringRules_has_hostname(const validate_StringRules *msg) { return _upb_getoneofcase(msg, UPB_SIZE(120, 180)) == 13; }
+UPB_INLINE bool validate_StringRules_hostname(const validate_StringRules *msg) { return UPB_READ_ONEOF(msg, bool, UPB_SIZE(116, 176), UPB_SIZE(120, 180), 13, false); }
+UPB_INLINE bool validate_StringRules_has_ip(const validate_StringRules *msg) { return _upb_getoneofcase(msg, UPB_SIZE(120, 180)) == 14; }
+UPB_INLINE bool validate_StringRules_ip(const validate_StringRules *msg) { return UPB_READ_ONEOF(msg, bool, UPB_SIZE(116, 176), UPB_SIZE(120, 180), 14, false); }
+UPB_INLINE bool validate_StringRules_has_ipv4(const validate_StringRules *msg) { return _upb_getoneofcase(msg, UPB_SIZE(120, 180)) == 15; }
+UPB_INLINE bool validate_StringRules_ipv4(const validate_StringRules *msg) { return UPB_READ_ONEOF(msg, bool, UPB_SIZE(116, 176), UPB_SIZE(120, 180), 15, false); }
+UPB_INLINE bool validate_StringRules_has_ipv6(const validate_StringRules *msg) { return _upb_getoneofcase(msg, UPB_SIZE(120, 180)) == 16; }
+UPB_INLINE bool validate_StringRules_ipv6(const validate_StringRules *msg) { return UPB_READ_ONEOF(msg, bool, UPB_SIZE(116, 176), UPB_SIZE(120, 180), 16, false); }
+UPB_INLINE bool validate_StringRules_has_uri(const validate_StringRules *msg) { return _upb_getoneofcase(msg, UPB_SIZE(120, 180)) == 17; }
+UPB_INLINE bool validate_StringRules_uri(const validate_StringRules *msg) { return UPB_READ_ONEOF(msg, bool, UPB_SIZE(116, 176), UPB_SIZE(120, 180), 17, false); }
+UPB_INLINE bool validate_StringRules_has_uri_ref(const validate_StringRules *msg) { return _upb_getoneofcase(msg, UPB_SIZE(120, 180)) == 18; }
+UPB_INLINE bool validate_StringRules_uri_ref(const validate_StringRules *msg) { return UPB_READ_ONEOF(msg, bool, UPB_SIZE(116, 176), UPB_SIZE(120, 180), 18, false); }
+UPB_INLINE bool validate_StringRules_has_len(const validate_StringRules *msg) { return _upb_hasbit(msg, 10); }
 UPB_INLINE uint64_t validate_StringRules_len(const validate_StringRules *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(40, 40), uint64_t); }
-UPB_INLINE bool validate_StringRules_has_len_bytes(const validate_StringRules *msg) { return _upb_hasbit(msg, 6); }
+UPB_INLINE bool validate_StringRules_has_len_bytes(const validate_StringRules *msg) { return _upb_hasbit(msg, 11); }
 UPB_INLINE uint64_t validate_StringRules_len_bytes(const validate_StringRules *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(48, 48), uint64_t); }
-UPB_INLINE bool validate_StringRules_has_address(const validate_StringRules *msg) { return _upb_getoneofcase(msg, UPB_SIZE(128, 184)) == 21; }
-UPB_INLINE bool validate_StringRules_address(const validate_StringRules *msg) { return UPB_READ_ONEOF(msg, bool, UPB_SIZE(120, 176), UPB_SIZE(128, 184), 21, false); }
-UPB_INLINE bool validate_StringRules_has_uuid(const validate_StringRules *msg) { return _upb_getoneofcase(msg, UPB_SIZE(128, 184)) == 22; }
-UPB_INLINE bool validate_StringRules_uuid(const validate_StringRules *msg) { return UPB_READ_ONEOF(msg, bool, UPB_SIZE(120, 176), UPB_SIZE(128, 184), 22, false); }
-UPB_INLINE bool validate_StringRules_has_not_contains(const validate_StringRules *msg) { return _upb_hasbit(msg, 13); }
+UPB_INLINE bool validate_StringRules_has_address(const validate_StringRules *msg) { return _upb_getoneofcase(msg, UPB_SIZE(120, 180)) == 21; }
+UPB_INLINE bool validate_StringRules_address(const validate_StringRules *msg) { return UPB_READ_ONEOF(msg, bool, UPB_SIZE(116, 176), UPB_SIZE(120, 180), 21, false); }
+UPB_INLINE bool validate_StringRules_has_uuid(const validate_StringRules *msg) { return _upb_getoneofcase(msg, UPB_SIZE(120, 180)) == 22; }
+UPB_INLINE bool validate_StringRules_uuid(const validate_StringRules *msg) { return UPB_READ_ONEOF(msg, bool, UPB_SIZE(116, 176), UPB_SIZE(120, 180), 22, false); }
+UPB_INLINE bool validate_StringRules_has_not_contains(const validate_StringRules *msg) { return _upb_hasbit(msg, 12); }
 UPB_INLINE upb_strview validate_StringRules_not_contains(const validate_StringRules *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(100, 144), upb_strview); }
-UPB_INLINE bool validate_StringRules_has_well_known_regex(const validate_StringRules *msg) { return _upb_getoneofcase(msg, UPB_SIZE(128, 184)) == 24; }
-UPB_INLINE int32_t validate_StringRules_well_known_regex(const validate_StringRules *msg) { return UPB_READ_ONEOF(msg, int32_t, UPB_SIZE(120, 176), UPB_SIZE(128, 184), 24, 0); }
-UPB_INLINE bool validate_StringRules_has_strict(const validate_StringRules *msg) { return _upb_hasbit(msg, 7); }
+UPB_INLINE bool validate_StringRules_has_well_known_regex(const validate_StringRules *msg) { return _upb_getoneofcase(msg, UPB_SIZE(120, 180)) == 24; }
+UPB_INLINE int32_t validate_StringRules_well_known_regex(const validate_StringRules *msg) { return UPB_READ_ONEOF(msg, int32_t, UPB_SIZE(116, 176), UPB_SIZE(120, 180), 24, 0); }
+UPB_INLINE bool validate_StringRules_has_strict(const validate_StringRules *msg) { return _upb_hasbit(msg, 13); }
 UPB_INLINE bool validate_StringRules_strict(const validate_StringRules *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(56, 56), bool); }
 
 UPB_INLINE void validate_StringRules_set_const(validate_StringRules *msg, upb_strview value) {
-  _upb_sethas(msg, 8);
+  _upb_sethas(msg, 1);
   *UPB_PTR_AT(msg, UPB_SIZE(60, 64), upb_strview) = value;
 }
 UPB_INLINE void validate_StringRules_set_min_len(validate_StringRules *msg, uint64_t value) {
-  _upb_sethas(msg, 1);
+  _upb_sethas(msg, 2);
   *UPB_PTR_AT(msg, UPB_SIZE(8, 8), uint64_t) = value;
 }
 UPB_INLINE void validate_StringRules_set_max_len(validate_StringRules *msg, uint64_t value) {
-  _upb_sethas(msg, 2);
+  _upb_sethas(msg, 3);
   *UPB_PTR_AT(msg, UPB_SIZE(16, 16), uint64_t) = value;
 }
 UPB_INLINE void validate_StringRules_set_min_bytes(validate_StringRules *msg, uint64_t value) {
-  _upb_sethas(msg, 3);
+  _upb_sethas(msg, 4);
   *UPB_PTR_AT(msg, UPB_SIZE(24, 24), uint64_t) = value;
 }
 UPB_INLINE void validate_StringRules_set_max_bytes(validate_StringRules *msg, uint64_t value) {
-  _upb_sethas(msg, 4);
+  _upb_sethas(msg, 5);
   *UPB_PTR_AT(msg, UPB_SIZE(32, 32), uint64_t) = value;
 }
 UPB_INLINE void validate_StringRules_set_pattern(validate_StringRules *msg, upb_strview value) {
-  _upb_sethas(msg, 9);
+  _upb_sethas(msg, 6);
   *UPB_PTR_AT(msg, UPB_SIZE(68, 80), upb_strview) = value;
 }
 UPB_INLINE void validate_StringRules_set_prefix(validate_StringRules *msg, upb_strview value) {
-  _upb_sethas(msg, 10);
+  _upb_sethas(msg, 7);
   *UPB_PTR_AT(msg, UPB_SIZE(76, 96), upb_strview) = value;
 }
 UPB_INLINE void validate_StringRules_set_suffix(validate_StringRules *msg, upb_strview value) {
-  _upb_sethas(msg, 11);
+  _upb_sethas(msg, 8);
   *UPB_PTR_AT(msg, UPB_SIZE(84, 112), upb_strview) = value;
 }
 UPB_INLINE void validate_StringRules_set_contains(validate_StringRules *msg, upb_strview value) {
-  _upb_sethas(msg, 12);
+  _upb_sethas(msg, 9);
   *UPB_PTR_AT(msg, UPB_SIZE(92, 128), upb_strview) = value;
 }
 UPB_INLINE upb_strview* validate_StringRules_mutable_in(validate_StringRules *msg, size_t *len) {
   return (upb_strview*)_upb_array_mutable_accessor(msg, UPB_SIZE(108, 160), len);
 }
 UPB_INLINE upb_strview* validate_StringRules_resize_in(validate_StringRules *msg, size_t len, upb_arena *arena) {
-  return (upb_strview*)_upb_array_resize_accessor(msg, UPB_SIZE(108, 160), len, UPB_TYPE_STRING, arena);
+  return (upb_strview*)_upb_array_resize_accessor2(msg, UPB_SIZE(108, 160), len, UPB_SIZE(3, 4), arena);
 }
 UPB_INLINE bool validate_StringRules_add_in(validate_StringRules *msg, upb_strview val, upb_arena *arena) {
-  return _upb_array_append_accessor(msg, UPB_SIZE(108, 160), UPB_SIZE(8, 16), UPB_TYPE_STRING, &val,
+  return _upb_array_append_accessor2(msg, UPB_SIZE(108, 160), UPB_SIZE(3, 4), &val,
       arena);
 }
 UPB_INLINE upb_strview* validate_StringRules_mutable_not_in(validate_StringRules *msg, size_t *len) {
   return (upb_strview*)_upb_array_mutable_accessor(msg, UPB_SIZE(112, 168), len);
 }
 UPB_INLINE upb_strview* validate_StringRules_resize_not_in(validate_StringRules *msg, size_t len, upb_arena *arena) {
-  return (upb_strview*)_upb_array_resize_accessor(msg, UPB_SIZE(112, 168), len, UPB_TYPE_STRING, arena);
+  return (upb_strview*)_upb_array_resize_accessor2(msg, UPB_SIZE(112, 168), len, UPB_SIZE(3, 4), arena);
 }
 UPB_INLINE bool validate_StringRules_add_not_in(validate_StringRules *msg, upb_strview val, upb_arena *arena) {
-  return _upb_array_append_accessor(msg, UPB_SIZE(112, 168), UPB_SIZE(8, 16), UPB_TYPE_STRING, &val,
+  return _upb_array_append_accessor2(msg, UPB_SIZE(112, 168), UPB_SIZE(3, 4), &val,
       arena);
 }
 UPB_INLINE void validate_StringRules_set_email(validate_StringRules *msg, bool value) {
-  UPB_WRITE_ONEOF(msg, bool, UPB_SIZE(120, 176), value, UPB_SIZE(128, 184), 12);
+  UPB_WRITE_ONEOF(msg, bool, UPB_SIZE(116, 176), value, UPB_SIZE(120, 180), 12);
 }
 UPB_INLINE void validate_StringRules_set_hostname(validate_StringRules *msg, bool value) {
-  UPB_WRITE_ONEOF(msg, bool, UPB_SIZE(120, 176), value, UPB_SIZE(128, 184), 13);
+  UPB_WRITE_ONEOF(msg, bool, UPB_SIZE(116, 176), value, UPB_SIZE(120, 180), 13);
 }
 UPB_INLINE void validate_StringRules_set_ip(validate_StringRules *msg, bool value) {
-  UPB_WRITE_ONEOF(msg, bool, UPB_SIZE(120, 176), value, UPB_SIZE(128, 184), 14);
+  UPB_WRITE_ONEOF(msg, bool, UPB_SIZE(116, 176), value, UPB_SIZE(120, 180), 14);
 }
 UPB_INLINE void validate_StringRules_set_ipv4(validate_StringRules *msg, bool value) {
-  UPB_WRITE_ONEOF(msg, bool, UPB_SIZE(120, 176), value, UPB_SIZE(128, 184), 15);
+  UPB_WRITE_ONEOF(msg, bool, UPB_SIZE(116, 176), value, UPB_SIZE(120, 180), 15);
 }
 UPB_INLINE void validate_StringRules_set_ipv6(validate_StringRules *msg, bool value) {
-  UPB_WRITE_ONEOF(msg, bool, UPB_SIZE(120, 176), value, UPB_SIZE(128, 184), 16);
+  UPB_WRITE_ONEOF(msg, bool, UPB_SIZE(116, 176), value, UPB_SIZE(120, 180), 16);
 }
 UPB_INLINE void validate_StringRules_set_uri(validate_StringRules *msg, bool value) {
-  UPB_WRITE_ONEOF(msg, bool, UPB_SIZE(120, 176), value, UPB_SIZE(128, 184), 17);
+  UPB_WRITE_ONEOF(msg, bool, UPB_SIZE(116, 176), value, UPB_SIZE(120, 180), 17);
 }
 UPB_INLINE void validate_StringRules_set_uri_ref(validate_StringRules *msg, bool value) {
-  UPB_WRITE_ONEOF(msg, bool, UPB_SIZE(120, 176), value, UPB_SIZE(128, 184), 18);
+  UPB_WRITE_ONEOF(msg, bool, UPB_SIZE(116, 176), value, UPB_SIZE(120, 180), 18);
 }
 UPB_INLINE void validate_StringRules_set_len(validate_StringRules *msg, uint64_t value) {
-  _upb_sethas(msg, 5);
+  _upb_sethas(msg, 10);
   *UPB_PTR_AT(msg, UPB_SIZE(40, 40), uint64_t) = value;
 }
 UPB_INLINE void validate_StringRules_set_len_bytes(validate_StringRules *msg, uint64_t value) {
-  _upb_sethas(msg, 6);
+  _upb_sethas(msg, 11);
   *UPB_PTR_AT(msg, UPB_SIZE(48, 48), uint64_t) = value;
 }
 UPB_INLINE void validate_StringRules_set_address(validate_StringRules *msg, bool value) {
-  UPB_WRITE_ONEOF(msg, bool, UPB_SIZE(120, 176), value, UPB_SIZE(128, 184), 21);
+  UPB_WRITE_ONEOF(msg, bool, UPB_SIZE(116, 176), value, UPB_SIZE(120, 180), 21);
 }
 UPB_INLINE void validate_StringRules_set_uuid(validate_StringRules *msg, bool value) {
-  UPB_WRITE_ONEOF(msg, bool, UPB_SIZE(120, 176), value, UPB_SIZE(128, 184), 22);
+  UPB_WRITE_ONEOF(msg, bool, UPB_SIZE(116, 176), value, UPB_SIZE(120, 180), 22);
 }
 UPB_INLINE void validate_StringRules_set_not_contains(validate_StringRules *msg, upb_strview value) {
-  _upb_sethas(msg, 13);
+  _upb_sethas(msg, 12);
   *UPB_PTR_AT(msg, UPB_SIZE(100, 144), upb_strview) = value;
 }
 UPB_INLINE void validate_StringRules_set_well_known_regex(validate_StringRules *msg, int32_t value) {
-  UPB_WRITE_ONEOF(msg, int32_t, UPB_SIZE(120, 176), value, UPB_SIZE(128, 184), 24);
+  UPB_WRITE_ONEOF(msg, int32_t, UPB_SIZE(116, 176), value, UPB_SIZE(120, 180), 24);
 }
 UPB_INLINE void validate_StringRules_set_strict(validate_StringRules *msg, bool value) {
-  _upb_sethas(msg, 7);
+  _upb_sethas(msg, 13);
   *UPB_PTR_AT(msg, UPB_SIZE(56, 56), bool) = value;
 }
 
@@ -1480,6 +1571,12 @@ UPB_INLINE validate_BytesRules *validate_BytesRules_parse(const char *buf, size_
   validate_BytesRules *ret = validate_BytesRules_new(arena);
   return (ret && upb_decode(buf, size, ret, &validate_BytesRules_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE validate_BytesRules *validate_BytesRules_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  validate_BytesRules *ret = validate_BytesRules_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &validate_BytesRules_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *validate_BytesRules_serialize(const validate_BytesRules *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &validate_BytesRules_msginit, arena, len);
 }
@@ -1492,19 +1589,19 @@ typedef enum {
 } validate_BytesRules_well_known_oneofcases;
 UPB_INLINE validate_BytesRules_well_known_oneofcases validate_BytesRules_well_known_case(const validate_BytesRules* msg) { return (validate_BytesRules_well_known_oneofcases)*UPB_PTR_AT(msg, UPB_SIZE(84, 132), int32_t); }
 
-UPB_INLINE bool validate_BytesRules_has_const(const validate_BytesRules *msg) { return _upb_hasbit(msg, 4); }
+UPB_INLINE bool validate_BytesRules_has_const(const validate_BytesRules *msg) { return _upb_hasbit(msg, 1); }
 UPB_INLINE upb_strview validate_BytesRules_const(const validate_BytesRules *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(32, 32), upb_strview); }
-UPB_INLINE bool validate_BytesRules_has_min_len(const validate_BytesRules *msg) { return _upb_hasbit(msg, 1); }
+UPB_INLINE bool validate_BytesRules_has_min_len(const validate_BytesRules *msg) { return _upb_hasbit(msg, 2); }
 UPB_INLINE uint64_t validate_BytesRules_min_len(const validate_BytesRules *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(8, 8), uint64_t); }
-UPB_INLINE bool validate_BytesRules_has_max_len(const validate_BytesRules *msg) { return _upb_hasbit(msg, 2); }
+UPB_INLINE bool validate_BytesRules_has_max_len(const validate_BytesRules *msg) { return _upb_hasbit(msg, 3); }
 UPB_INLINE uint64_t validate_BytesRules_max_len(const validate_BytesRules *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(16, 16), uint64_t); }
-UPB_INLINE bool validate_BytesRules_has_pattern(const validate_BytesRules *msg) { return _upb_hasbit(msg, 5); }
+UPB_INLINE bool validate_BytesRules_has_pattern(const validate_BytesRules *msg) { return _upb_hasbit(msg, 4); }
 UPB_INLINE upb_strview validate_BytesRules_pattern(const validate_BytesRules *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(40, 48), upb_strview); }
-UPB_INLINE bool validate_BytesRules_has_prefix(const validate_BytesRules *msg) { return _upb_hasbit(msg, 6); }
+UPB_INLINE bool validate_BytesRules_has_prefix(const validate_BytesRules *msg) { return _upb_hasbit(msg, 5); }
 UPB_INLINE upb_strview validate_BytesRules_prefix(const validate_BytesRules *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(48, 64), upb_strview); }
-UPB_INLINE bool validate_BytesRules_has_suffix(const validate_BytesRules *msg) { return _upb_hasbit(msg, 7); }
+UPB_INLINE bool validate_BytesRules_has_suffix(const validate_BytesRules *msg) { return _upb_hasbit(msg, 6); }
 UPB_INLINE upb_strview validate_BytesRules_suffix(const validate_BytesRules *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(56, 80), upb_strview); }
-UPB_INLINE bool validate_BytesRules_has_contains(const validate_BytesRules *msg) { return _upb_hasbit(msg, 8); }
+UPB_INLINE bool validate_BytesRules_has_contains(const validate_BytesRules *msg) { return _upb_hasbit(msg, 7); }
 UPB_INLINE upb_strview validate_BytesRules_contains(const validate_BytesRules *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(64, 96), upb_strview); }
 UPB_INLINE upb_strview const* validate_BytesRules_in(const validate_BytesRules *msg, size_t *len) { return (upb_strview const*)_upb_array_accessor(msg, UPB_SIZE(72, 112), len); }
 UPB_INLINE upb_strview const* validate_BytesRules_not_in(const validate_BytesRules *msg, size_t *len) { return (upb_strview const*)_upb_array_accessor(msg, UPB_SIZE(76, 120), len); }
@@ -1514,55 +1611,55 @@ UPB_INLINE bool validate_BytesRules_has_ipv4(const validate_BytesRules *msg) { r
 UPB_INLINE bool validate_BytesRules_ipv4(const validate_BytesRules *msg) { return UPB_READ_ONEOF(msg, bool, UPB_SIZE(80, 128), UPB_SIZE(84, 132), 11, false); }
 UPB_INLINE bool validate_BytesRules_has_ipv6(const validate_BytesRules *msg) { return _upb_getoneofcase(msg, UPB_SIZE(84, 132)) == 12; }
 UPB_INLINE bool validate_BytesRules_ipv6(const validate_BytesRules *msg) { return UPB_READ_ONEOF(msg, bool, UPB_SIZE(80, 128), UPB_SIZE(84, 132), 12, false); }
-UPB_INLINE bool validate_BytesRules_has_len(const validate_BytesRules *msg) { return _upb_hasbit(msg, 3); }
+UPB_INLINE bool validate_BytesRules_has_len(const validate_BytesRules *msg) { return _upb_hasbit(msg, 8); }
 UPB_INLINE uint64_t validate_BytesRules_len(const validate_BytesRules *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(24, 24), uint64_t); }
 
 UPB_INLINE void validate_BytesRules_set_const(validate_BytesRules *msg, upb_strview value) {
-  _upb_sethas(msg, 4);
+  _upb_sethas(msg, 1);
   *UPB_PTR_AT(msg, UPB_SIZE(32, 32), upb_strview) = value;
 }
 UPB_INLINE void validate_BytesRules_set_min_len(validate_BytesRules *msg, uint64_t value) {
-  _upb_sethas(msg, 1);
+  _upb_sethas(msg, 2);
   *UPB_PTR_AT(msg, UPB_SIZE(8, 8), uint64_t) = value;
 }
 UPB_INLINE void validate_BytesRules_set_max_len(validate_BytesRules *msg, uint64_t value) {
-  _upb_sethas(msg, 2);
+  _upb_sethas(msg, 3);
   *UPB_PTR_AT(msg, UPB_SIZE(16, 16), uint64_t) = value;
 }
 UPB_INLINE void validate_BytesRules_set_pattern(validate_BytesRules *msg, upb_strview value) {
-  _upb_sethas(msg, 5);
+  _upb_sethas(msg, 4);
   *UPB_PTR_AT(msg, UPB_SIZE(40, 48), upb_strview) = value;
 }
 UPB_INLINE void validate_BytesRules_set_prefix(validate_BytesRules *msg, upb_strview value) {
-  _upb_sethas(msg, 6);
+  _upb_sethas(msg, 5);
   *UPB_PTR_AT(msg, UPB_SIZE(48, 64), upb_strview) = value;
 }
 UPB_INLINE void validate_BytesRules_set_suffix(validate_BytesRules *msg, upb_strview value) {
-  _upb_sethas(msg, 7);
+  _upb_sethas(msg, 6);
   *UPB_PTR_AT(msg, UPB_SIZE(56, 80), upb_strview) = value;
 }
 UPB_INLINE void validate_BytesRules_set_contains(validate_BytesRules *msg, upb_strview value) {
-  _upb_sethas(msg, 8);
+  _upb_sethas(msg, 7);
   *UPB_PTR_AT(msg, UPB_SIZE(64, 96), upb_strview) = value;
 }
 UPB_INLINE upb_strview* validate_BytesRules_mutable_in(validate_BytesRules *msg, size_t *len) {
   return (upb_strview*)_upb_array_mutable_accessor(msg, UPB_SIZE(72, 112), len);
 }
 UPB_INLINE upb_strview* validate_BytesRules_resize_in(validate_BytesRules *msg, size_t len, upb_arena *arena) {
-  return (upb_strview*)_upb_array_resize_accessor(msg, UPB_SIZE(72, 112), len, UPB_TYPE_STRING, arena);
+  return (upb_strview*)_upb_array_resize_accessor2(msg, UPB_SIZE(72, 112), len, UPB_SIZE(3, 4), arena);
 }
 UPB_INLINE bool validate_BytesRules_add_in(validate_BytesRules *msg, upb_strview val, upb_arena *arena) {
-  return _upb_array_append_accessor(msg, UPB_SIZE(72, 112), UPB_SIZE(8, 16), UPB_TYPE_STRING, &val,
+  return _upb_array_append_accessor2(msg, UPB_SIZE(72, 112), UPB_SIZE(3, 4), &val,
       arena);
 }
 UPB_INLINE upb_strview* validate_BytesRules_mutable_not_in(validate_BytesRules *msg, size_t *len) {
   return (upb_strview*)_upb_array_mutable_accessor(msg, UPB_SIZE(76, 120), len);
 }
 UPB_INLINE upb_strview* validate_BytesRules_resize_not_in(validate_BytesRules *msg, size_t len, upb_arena *arena) {
-  return (upb_strview*)_upb_array_resize_accessor(msg, UPB_SIZE(76, 120), len, UPB_TYPE_STRING, arena);
+  return (upb_strview*)_upb_array_resize_accessor2(msg, UPB_SIZE(76, 120), len, UPB_SIZE(3, 4), arena);
 }
 UPB_INLINE bool validate_BytesRules_add_not_in(validate_BytesRules *msg, upb_strview val, upb_arena *arena) {
-  return _upb_array_append_accessor(msg, UPB_SIZE(76, 120), UPB_SIZE(8, 16), UPB_TYPE_STRING, &val,
+  return _upb_array_append_accessor2(msg, UPB_SIZE(76, 120), UPB_SIZE(3, 4), &val,
       arena);
 }
 UPB_INLINE void validate_BytesRules_set_ip(validate_BytesRules *msg, bool value) {
@@ -1575,7 +1672,7 @@ UPB_INLINE void validate_BytesRules_set_ipv6(validate_BytesRules *msg, bool valu
   UPB_WRITE_ONEOF(msg, bool, UPB_SIZE(80, 128), value, UPB_SIZE(84, 132), 12);
 }
 UPB_INLINE void validate_BytesRules_set_len(validate_BytesRules *msg, uint64_t value) {
-  _upb_sethas(msg, 3);
+  _upb_sethas(msg, 8);
   *UPB_PTR_AT(msg, UPB_SIZE(24, 24), uint64_t) = value;
 }
 
@@ -1589,6 +1686,12 @@ UPB_INLINE validate_EnumRules *validate_EnumRules_parse(const char *buf, size_t
   validate_EnumRules *ret = validate_EnumRules_new(arena);
   return (ret && upb_decode(buf, size, ret, &validate_EnumRules_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE validate_EnumRules *validate_EnumRules_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  validate_EnumRules *ret = validate_EnumRules_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &validate_EnumRules_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *validate_EnumRules_serialize(const validate_EnumRules *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &validate_EnumRules_msginit, arena, len);
 }
@@ -1612,20 +1715,20 @@ UPB_INLINE int32_t* validate_EnumRules_mutable_in(validate_EnumRules *msg, size_
   return (int32_t*)_upb_array_mutable_accessor(msg, UPB_SIZE(12, 16), len);
 }
 UPB_INLINE int32_t* validate_EnumRules_resize_in(validate_EnumRules *msg, size_t len, upb_arena *arena) {
-  return (int32_t*)_upb_array_resize_accessor(msg, UPB_SIZE(12, 16), len, UPB_TYPE_INT32, arena);
+  return (int32_t*)_upb_array_resize_accessor2(msg, UPB_SIZE(12, 16), len, 2, arena);
 }
 UPB_INLINE bool validate_EnumRules_add_in(validate_EnumRules *msg, int32_t val, upb_arena *arena) {
-  return _upb_array_append_accessor(msg, UPB_SIZE(12, 16), UPB_SIZE(4, 4), UPB_TYPE_INT32, &val,
+  return _upb_array_append_accessor2(msg, UPB_SIZE(12, 16), 2, &val,
       arena);
 }
 UPB_INLINE int32_t* validate_EnumRules_mutable_not_in(validate_EnumRules *msg, size_t *len) {
   return (int32_t*)_upb_array_mutable_accessor(msg, UPB_SIZE(16, 24), len);
 }
 UPB_INLINE int32_t* validate_EnumRules_resize_not_in(validate_EnumRules *msg, size_t len, upb_arena *arena) {
-  return (int32_t*)_upb_array_resize_accessor(msg, UPB_SIZE(16, 24), len, UPB_TYPE_INT32, arena);
+  return (int32_t*)_upb_array_resize_accessor2(msg, UPB_SIZE(16, 24), len, 2, arena);
 }
 UPB_INLINE bool validate_EnumRules_add_not_in(validate_EnumRules *msg, int32_t val, upb_arena *arena) {
-  return _upb_array_append_accessor(msg, UPB_SIZE(16, 24), UPB_SIZE(4, 4), UPB_TYPE_INT32, &val,
+  return _upb_array_append_accessor2(msg, UPB_SIZE(16, 24), 2, &val,
       arena);
 }
 
@@ -1639,6 +1742,12 @@ UPB_INLINE validate_MessageRules *validate_MessageRules_parse(const char *buf, s
   validate_MessageRules *ret = validate_MessageRules_new(arena);
   return (ret && upb_decode(buf, size, ret, &validate_MessageRules_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE validate_MessageRules *validate_MessageRules_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  validate_MessageRules *ret = validate_MessageRules_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &validate_MessageRules_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *validate_MessageRules_serialize(const validate_MessageRules *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &validate_MessageRules_msginit, arena, len);
 }
@@ -1667,6 +1776,12 @@ UPB_INLINE validate_RepeatedRules *validate_RepeatedRules_parse(const char *buf,
   validate_RepeatedRules *ret = validate_RepeatedRules_new(arena);
   return (ret && upb_decode(buf, size, ret, &validate_RepeatedRules_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE validate_RepeatedRules *validate_RepeatedRules_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  validate_RepeatedRules *ret = validate_RepeatedRules_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &validate_RepeatedRules_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *validate_RepeatedRules_serialize(const validate_RepeatedRules *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &validate_RepeatedRules_msginit, arena, len);
 }
@@ -1716,6 +1831,12 @@ UPB_INLINE validate_MapRules *validate_MapRules_parse(const char *buf, size_t si
   validate_MapRules *ret = validate_MapRules_new(arena);
   return (ret && upb_decode(buf, size, ret, &validate_MapRules_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE validate_MapRules *validate_MapRules_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  validate_MapRules *ret = validate_MapRules_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &validate_MapRules_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *validate_MapRules_serialize(const validate_MapRules *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &validate_MapRules_msginit, arena, len);
 }
@@ -1780,6 +1901,12 @@ UPB_INLINE validate_AnyRules *validate_AnyRules_parse(const char *buf, size_t si
   validate_AnyRules *ret = validate_AnyRules_new(arena);
   return (ret && upb_decode(buf, size, ret, &validate_AnyRules_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE validate_AnyRules *validate_AnyRules_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  validate_AnyRules *ret = validate_AnyRules_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &validate_AnyRules_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *validate_AnyRules_serialize(const validate_AnyRules *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &validate_AnyRules_msginit, arena, len);
 }
@@ -1797,20 +1924,20 @@ UPB_INLINE upb_strview* validate_AnyRules_mutable_in(validate_AnyRules *msg, siz
   return (upb_strview*)_upb_array_mutable_accessor(msg, UPB_SIZE(4, 8), len);
 }
 UPB_INLINE upb_strview* validate_AnyRules_resize_in(validate_AnyRules *msg, size_t len, upb_arena *arena) {
-  return (upb_strview*)_upb_array_resize_accessor(msg, UPB_SIZE(4, 8), len, UPB_TYPE_STRING, arena);
+  return (upb_strview*)_upb_array_resize_accessor2(msg, UPB_SIZE(4, 8), len, UPB_SIZE(3, 4), arena);
 }
 UPB_INLINE bool validate_AnyRules_add_in(validate_AnyRules *msg, upb_strview val, upb_arena *arena) {
-  return _upb_array_append_accessor(msg, UPB_SIZE(4, 8), UPB_SIZE(8, 16), UPB_TYPE_STRING, &val,
+  return _upb_array_append_accessor2(msg, UPB_SIZE(4, 8), UPB_SIZE(3, 4), &val,
       arena);
 }
 UPB_INLINE upb_strview* validate_AnyRules_mutable_not_in(validate_AnyRules *msg, size_t *len) {
   return (upb_strview*)_upb_array_mutable_accessor(msg, UPB_SIZE(8, 16), len);
 }
 UPB_INLINE upb_strview* validate_AnyRules_resize_not_in(validate_AnyRules *msg, size_t len, upb_arena *arena) {
-  return (upb_strview*)_upb_array_resize_accessor(msg, UPB_SIZE(8, 16), len, UPB_TYPE_STRING, arena);
+  return (upb_strview*)_upb_array_resize_accessor2(msg, UPB_SIZE(8, 16), len, UPB_SIZE(3, 4), arena);
 }
 UPB_INLINE bool validate_AnyRules_add_not_in(validate_AnyRules *msg, upb_strview val, upb_arena *arena) {
-  return _upb_array_append_accessor(msg, UPB_SIZE(8, 16), UPB_SIZE(8, 16), UPB_TYPE_STRING, &val,
+  return _upb_array_append_accessor2(msg, UPB_SIZE(8, 16), UPB_SIZE(3, 4), &val,
       arena);
 }
 
@@ -1824,6 +1951,12 @@ UPB_INLINE validate_DurationRules *validate_DurationRules_parse(const char *buf,
   validate_DurationRules *ret = validate_DurationRules_new(arena);
   return (ret && upb_decode(buf, size, ret, &validate_DurationRules_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE validate_DurationRules *validate_DurationRules_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  validate_DurationRules *ret = validate_DurationRules_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &validate_DurationRules_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *validate_DurationRules_serialize(const validate_DurationRules *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &validate_DurationRules_msginit, arena, len);
 }
@@ -1918,12 +2051,12 @@ UPB_INLINE struct google_protobuf_Duration** validate_DurationRules_mutable_in(v
   return (struct google_protobuf_Duration**)_upb_array_mutable_accessor(msg, UPB_SIZE(24, 48), len);
 }
 UPB_INLINE struct google_protobuf_Duration** validate_DurationRules_resize_in(validate_DurationRules *msg, size_t len, upb_arena *arena) {
-  return (struct google_protobuf_Duration**)_upb_array_resize_accessor(msg, UPB_SIZE(24, 48), len, UPB_TYPE_MESSAGE, arena);
+  return (struct google_protobuf_Duration**)_upb_array_resize_accessor2(msg, UPB_SIZE(24, 48), len, UPB_SIZE(2, 3), arena);
 }
 UPB_INLINE struct google_protobuf_Duration* validate_DurationRules_add_in(validate_DurationRules *msg, upb_arena *arena) {
   struct google_protobuf_Duration* sub = (struct google_protobuf_Duration*)_upb_msg_new(&google_protobuf_Duration_msginit, arena);
-  bool ok = _upb_array_append_accessor(
-      msg, UPB_SIZE(24, 48), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena);
+  bool ok = _upb_array_append_accessor2(
+      msg, UPB_SIZE(24, 48), UPB_SIZE(2, 3), &sub, arena);
   if (!ok) return NULL;
   return sub;
 }
@@ -1931,12 +2064,12 @@ UPB_INLINE struct google_protobuf_Duration** validate_DurationRules_mutable_not_
   return (struct google_protobuf_Duration**)_upb_array_mutable_accessor(msg, UPB_SIZE(28, 56), len);
 }
 UPB_INLINE struct google_protobuf_Duration** validate_DurationRules_resize_not_in(validate_DurationRules *msg, size_t len, upb_arena *arena) {
-  return (struct google_protobuf_Duration**)_upb_array_resize_accessor(msg, UPB_SIZE(28, 56), len, UPB_TYPE_MESSAGE, arena);
+  return (struct google_protobuf_Duration**)_upb_array_resize_accessor2(msg, UPB_SIZE(28, 56), len, UPB_SIZE(2, 3), arena);
 }
 UPB_INLINE struct google_protobuf_Duration* validate_DurationRules_add_not_in(validate_DurationRules *msg, upb_arena *arena) {
   struct google_protobuf_Duration* sub = (struct google_protobuf_Duration*)_upb_msg_new(&google_protobuf_Duration_msginit, arena);
-  bool ok = _upb_array_append_accessor(
-      msg, UPB_SIZE(28, 56), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena);
+  bool ok = _upb_array_append_accessor2(
+      msg, UPB_SIZE(28, 56), UPB_SIZE(2, 3), &sub, arena);
   if (!ok) return NULL;
   return sub;
 }
@@ -1951,25 +2084,31 @@ UPB_INLINE validate_TimestampRules *validate_TimestampRules_parse(const char *bu
   validate_TimestampRules *ret = validate_TimestampRules_new(arena);
   return (ret && upb_decode(buf, size, ret, &validate_TimestampRules_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE validate_TimestampRules *validate_TimestampRules_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  validate_TimestampRules *ret = validate_TimestampRules_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &validate_TimestampRules_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *validate_TimestampRules_serialize(const validate_TimestampRules *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &validate_TimestampRules_msginit, arena, len);
 }
 
 UPB_INLINE bool validate_TimestampRules_has_required(const validate_TimestampRules *msg) { return _upb_hasbit(msg, 1); }
 UPB_INLINE bool validate_TimestampRules_required(const validate_TimestampRules *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(2, 2), bool); }
-UPB_INLINE bool validate_TimestampRules_has_const(const validate_TimestampRules *msg) { return _upb_hasbit(msg, 4); }
+UPB_INLINE bool validate_TimestampRules_has_const(const validate_TimestampRules *msg) { return _upb_hasbit(msg, 2); }
 UPB_INLINE const struct google_protobuf_Timestamp* validate_TimestampRules_const(const validate_TimestampRules *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(8, 8), const struct google_protobuf_Timestamp*); }
-UPB_INLINE bool validate_TimestampRules_has_lt(const validate_TimestampRules *msg) { return _upb_hasbit(msg, 5); }
+UPB_INLINE bool validate_TimestampRules_has_lt(const validate_TimestampRules *msg) { return _upb_hasbit(msg, 3); }
 UPB_INLINE const struct google_protobuf_Timestamp* validate_TimestampRules_lt(const validate_TimestampRules *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(12, 16), const struct google_protobuf_Timestamp*); }
-UPB_INLINE bool validate_TimestampRules_has_lte(const validate_TimestampRules *msg) { return _upb_hasbit(msg, 6); }
+UPB_INLINE bool validate_TimestampRules_has_lte(const validate_TimestampRules *msg) { return _upb_hasbit(msg, 4); }
 UPB_INLINE const struct google_protobuf_Timestamp* validate_TimestampRules_lte(const validate_TimestampRules *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(16, 24), const struct google_protobuf_Timestamp*); }
-UPB_INLINE bool validate_TimestampRules_has_gt(const validate_TimestampRules *msg) { return _upb_hasbit(msg, 7); }
+UPB_INLINE bool validate_TimestampRules_has_gt(const validate_TimestampRules *msg) { return _upb_hasbit(msg, 5); }
 UPB_INLINE const struct google_protobuf_Timestamp* validate_TimestampRules_gt(const validate_TimestampRules *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(20, 32), const struct google_protobuf_Timestamp*); }
-UPB_INLINE bool validate_TimestampRules_has_gte(const validate_TimestampRules *msg) { return _upb_hasbit(msg, 8); }
+UPB_INLINE bool validate_TimestampRules_has_gte(const validate_TimestampRules *msg) { return _upb_hasbit(msg, 6); }
 UPB_INLINE const struct google_protobuf_Timestamp* validate_TimestampRules_gte(const validate_TimestampRules *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(24, 40), const struct google_protobuf_Timestamp*); }
-UPB_INLINE bool validate_TimestampRules_has_lt_now(const validate_TimestampRules *msg) { return _upb_hasbit(msg, 2); }
+UPB_INLINE bool validate_TimestampRules_has_lt_now(const validate_TimestampRules *msg) { return _upb_hasbit(msg, 7); }
 UPB_INLINE bool validate_TimestampRules_lt_now(const validate_TimestampRules *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(3, 3), bool); }
-UPB_INLINE bool validate_TimestampRules_has_gt_now(const validate_TimestampRules *msg) { return _upb_hasbit(msg, 3); }
+UPB_INLINE bool validate_TimestampRules_has_gt_now(const validate_TimestampRules *msg) { return _upb_hasbit(msg, 8); }
 UPB_INLINE bool validate_TimestampRules_gt_now(const validate_TimestampRules *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(4, 4), bool); }
 UPB_INLINE bool validate_TimestampRules_has_within(const validate_TimestampRules *msg) { return _upb_hasbit(msg, 9); }
 UPB_INLINE const struct google_protobuf_Duration* validate_TimestampRules_within(const validate_TimestampRules *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(28, 48), const struct google_protobuf_Duration*); }
@@ -1979,7 +2118,7 @@ UPB_INLINE void validate_TimestampRules_set_required(validate_TimestampRules *ms
   *UPB_PTR_AT(msg, UPB_SIZE(2, 2), bool) = value;
 }
 UPB_INLINE void validate_TimestampRules_set_const(validate_TimestampRules *msg, struct google_protobuf_Timestamp* value) {
-  _upb_sethas(msg, 4);
+  _upb_sethas(msg, 2);
   *UPB_PTR_AT(msg, UPB_SIZE(8, 8), struct google_protobuf_Timestamp*) = value;
 }
 UPB_INLINE struct google_protobuf_Timestamp* validate_TimestampRules_mutable_const(validate_TimestampRules *msg, upb_arena *arena) {
@@ -1992,7 +2131,7 @@ UPB_INLINE struct google_protobuf_Timestamp* validate_TimestampRules_mutable_con
   return sub;
 }
 UPB_INLINE void validate_TimestampRules_set_lt(validate_TimestampRules *msg, struct google_protobuf_Timestamp* value) {
-  _upb_sethas(msg, 5);
+  _upb_sethas(msg, 3);
   *UPB_PTR_AT(msg, UPB_SIZE(12, 16), struct google_protobuf_Timestamp*) = value;
 }
 UPB_INLINE struct google_protobuf_Timestamp* validate_TimestampRules_mutable_lt(validate_TimestampRules *msg, upb_arena *arena) {
@@ -2005,7 +2144,7 @@ UPB_INLINE struct google_protobuf_Timestamp* validate_TimestampRules_mutable_lt(
   return sub;
 }
 UPB_INLINE void validate_TimestampRules_set_lte(validate_TimestampRules *msg, struct google_protobuf_Timestamp* value) {
-  _upb_sethas(msg, 6);
+  _upb_sethas(msg, 4);
   *UPB_PTR_AT(msg, UPB_SIZE(16, 24), struct google_protobuf_Timestamp*) = value;
 }
 UPB_INLINE struct google_protobuf_Timestamp* validate_TimestampRules_mutable_lte(validate_TimestampRules *msg, upb_arena *arena) {
@@ -2018,7 +2157,7 @@ UPB_INLINE struct google_protobuf_Timestamp* validate_TimestampRules_mutable_lte
   return sub;
 }
 UPB_INLINE void validate_TimestampRules_set_gt(validate_TimestampRules *msg, struct google_protobuf_Timestamp* value) {
-  _upb_sethas(msg, 7);
+  _upb_sethas(msg, 5);
   *UPB_PTR_AT(msg, UPB_SIZE(20, 32), struct google_protobuf_Timestamp*) = value;
 }
 UPB_INLINE struct google_protobuf_Timestamp* validate_TimestampRules_mutable_gt(validate_TimestampRules *msg, upb_arena *arena) {
@@ -2031,7 +2170,7 @@ UPB_INLINE struct google_protobuf_Timestamp* validate_TimestampRules_mutable_gt(
   return sub;
 }
 UPB_INLINE void validate_TimestampRules_set_gte(validate_TimestampRules *msg, struct google_protobuf_Timestamp* value) {
-  _upb_sethas(msg, 8);
+  _upb_sethas(msg, 6);
   *UPB_PTR_AT(msg, UPB_SIZE(24, 40), struct google_protobuf_Timestamp*) = value;
 }
 UPB_INLINE struct google_protobuf_Timestamp* validate_TimestampRules_mutable_gte(validate_TimestampRules *msg, upb_arena *arena) {
@@ -2044,11 +2183,11 @@ UPB_INLINE struct google_protobuf_Timestamp* validate_TimestampRules_mutable_gte
   return sub;
 }
 UPB_INLINE void validate_TimestampRules_set_lt_now(validate_TimestampRules *msg, bool value) {
-  _upb_sethas(msg, 2);
+  _upb_sethas(msg, 7);
   *UPB_PTR_AT(msg, UPB_SIZE(3, 3), bool) = value;
 }
 UPB_INLINE void validate_TimestampRules_set_gt_now(validate_TimestampRules *msg, bool value) {
-  _upb_sethas(msg, 3);
+  _upb_sethas(msg, 8);
   *UPB_PTR_AT(msg, UPB_SIZE(4, 4), bool) = value;
 }
 UPB_INLINE void validate_TimestampRules_set_within(validate_TimestampRules *msg, struct google_protobuf_Duration* value) {
index 60b1db3..7db3483 100644 (file)
@@ -15,15 +15,16 @@ static const upb_msglayout *layouts[1] = {
   &google_protobuf_Any_msginit,
 };
 
-static const char descriptor[221] = {'\n', '\031', 'g', 'o', 'o', 'g', 'l', 'e', '/', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '/', 'a', 'n', 'y', '.', 'p', 'r', 'o', 
+static const char descriptor[228] = {'\n', '\031', 'g', 'o', 'o', 'g', 'l', 'e', '/', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '/', 'a', 'n', 'y', '.', 'p', 'r', 'o', 
 't', 'o', '\022', '\017', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '\"', '6', '\n', '\003', 'A', 'n', 
 'y', '\022', '\031', '\n', '\010', 't', 'y', 'p', 'e', '_', 'u', 'r', 'l', '\030', '\001', ' ', '\001', '(', '\t', 'R', '\007', 't', 'y', 'p', 'e', 
 'U', 'r', 'l', '\022', '\024', '\n', '\005', 'v', 'a', 'l', 'u', 'e', '\030', '\002', ' ', '\001', '(', '\014', 'R', '\005', 'v', 'a', 'l', 'u', 'e', 
-'B', 'o', '\n', '\023', 'c', 'o', 'm', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', 'B', '\010', 
-'A', 'n', 'y', 'P', 'r', 'o', 't', 'o', 'P', '\001', 'Z', '%', 'g', 'i', 't', 'h', 'u', 'b', '.', 'c', 'o', 'm', '/', 'g', 'o', 
-'l', 'a', 'n', 'g', '/', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '/', 'p', 't', 'y', 'p', 'e', 's', '/', 'a', 'n', 'y', '\242', 
-'\002', '\003', 'G', 'P', 'B', '\252', '\002', '\036', 'G', 'o', 'o', 'g', 'l', 'e', '.', 'P', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'W', 
-'e', 'l', 'l', 'K', 'n', 'o', 'w', 'n', 'T', 'y', 'p', 'e', 's', 'b', '\006', 'p', 'r', 'o', 't', 'o', '3', 
+'B', 'v', '\n', '\023', 'c', 'o', 'm', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', 'B', '\010', 
+'A', 'n', 'y', 'P', 'r', 'o', 't', 'o', 'P', '\001', 'Z', ',', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'g', 'o', 'l', 'a', 'n', 'g', 
+'.', 'o', 'r', 'g', '/', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '/', 't', 'y', 'p', 'e', 's', '/', 'k', 'n', 'o', 'w', 'n', 
+'/', 'a', 'n', 'y', 'p', 'b', '\242', '\002', '\003', 'G', 'P', 'B', '\252', '\002', '\036', 'G', 'o', 'o', 'g', 'l', 'e', '.', 'P', 'r', 'o', 
+'t', 'o', 'b', 'u', 'f', '.', 'W', 'e', 'l', 'l', 'K', 'n', 'o', 'w', 'n', 'T', 'y', 'p', 'e', 's', 'b', '\006', 'p', 'r', 'o', 
+'t', 'o', '3', 
 };
 
 static upb_def_init *deps[1] = {
@@ -34,5 +35,5 @@ upb_def_init google_protobuf_any_proto_upbdefinit = {
   deps,
   layouts,
   "google/protobuf/any.proto",
-  UPB_STRVIEW_INIT(descriptor, 221)
+  UPB_STRVIEW_INIT(descriptor, 228)
 };
index 719f087..9026d56 100644 (file)
@@ -67,7 +67,7 @@ static const upb_msglayout *layouts[27] = {
   &google_protobuf_GeneratedCodeInfo_Annotation_msginit,
 };
 
-static const char descriptor[7619] = {'\n', ' ', 'g', 'o', 'o', 'g', 'l', 'e', '/', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '/', 'd', 'e', 's', 'c', 'r', 'i', 'p', 
+static const char descriptor[7601] = {'\n', ' ', 'g', 'o', 'o', 'g', 'l', 'e', '/', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '/', 'd', 'e', 's', 'c', 'r', 'i', 'p', 
 't', 'o', 'r', '.', 'p', 'r', 'o', 't', 'o', '\022', '\017', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 
 'f', '\"', 'M', '\n', '\021', 'F', 'i', 'l', 'e', 'D', 'e', 's', 'c', 'r', 'i', 'p', 't', 'o', 'r', 'S', 'e', 't', '\022', '8', '\n', 
 '\004', 'f', 'i', 'l', 'e', '\030', '\001', ' ', '\003', '(', '\013', '2', '$', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 
@@ -365,13 +365,13 @@ static const char descriptor[7619] = {'\n', ' ', 'g', 'o', 'o', 'g', 'l', 'e', '
 'n', '\022', '\026', '\n', '\004', 'p', 'a', 't', 'h', '\030', '\001', ' ', '\003', '(', '\005', 'B', '\002', '\020', '\001', 'R', '\004', 'p', 'a', 't', 'h', 
 '\022', '\037', '\n', '\013', 's', 'o', 'u', 'r', 'c', 'e', '_', 'f', 'i', 'l', 'e', '\030', '\002', ' ', '\001', '(', '\t', 'R', '\n', 's', 'o', 
 'u', 'r', 'c', 'e', 'F', 'i', 'l', 'e', '\022', '\024', '\n', '\005', 'b', 'e', 'g', 'i', 'n', '\030', '\003', ' ', '\001', '(', '\005', 'R', '\005', 
-'b', 'e', 'g', 'i', 'n', '\022', '\020', '\n', '\003', 'e', 'n', 'd', '\030', '\004', ' ', '\001', '(', '\005', 'R', '\003', 'e', 'n', 'd', 'B', '\217', 
-'\001', '\n', '\023', 'c', 'o', 'm', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', 'B', '\020', 'D', 
-'e', 's', 'c', 'r', 'i', 'p', 't', 'o', 'r', 'P', 'r', 'o', 't', 'o', 's', 'H', '\001', 'Z', '>', 'g', 'i', 't', 'h', 'u', 'b', 
-'.', 'c', 'o', 'm', '/', 'g', 'o', 'l', 'a', 'n', 'g', '/', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '/', 'p', 'r', 'o', 't', 
-'o', 'c', '-', 'g', 'e', 'n', '-', 'g', 'o', '/', 'd', 'e', 's', 'c', 'r', 'i', 'p', 't', 'o', 'r', ';', 'd', 'e', 's', 'c', 
-'r', 'i', 'p', 't', 'o', 'r', '\370', '\001', '\001', '\242', '\002', '\003', 'G', 'P', 'B', '\252', '\002', '\032', 'G', 'o', 'o', 'g', 'l', 'e', '.', 
-'P', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'R', 'e', 'f', 'l', 'e', 'c', 't', 'i', 'o', 'n', 
+'b', 'e', 'g', 'i', 'n', '\022', '\020', '\n', '\003', 'e', 'n', 'd', '\030', '\004', ' ', '\001', '(', '\005', 'R', '\003', 'e', 'n', 'd', 'B', '~', 
+'\n', '\023', 'c', 'o', 'm', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', 'B', '\020', 'D', 'e', 
+'s', 'c', 'r', 'i', 'p', 't', 'o', 'r', 'P', 'r', 'o', 't', 'o', 's', 'H', '\001', 'Z', '-', 'g', 'o', 'o', 'g', 'l', 'e', '.', 
+'g', 'o', 'l', 'a', 'n', 'g', '.', 'o', 'r', 'g', '/', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '/', 't', 'y', 'p', 'e', 's', 
+'/', 'd', 'e', 's', 'c', 'r', 'i', 'p', 't', 'o', 'r', 'p', 'b', '\370', '\001', '\001', '\242', '\002', '\003', 'G', 'P', 'B', '\252', '\002', '\032', 
+'G', 'o', 'o', 'g', 'l', 'e', '.', 'P', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'R', 'e', 'f', 'l', 'e', 'c', 't', 'i', 'o', 
+'n', 
 };
 
 static upb_def_init *deps[1] = {
@@ -382,5 +382,5 @@ upb_def_init google_protobuf_descriptor_proto_upbdefinit = {
   deps,
   layouts,
   "google/protobuf/descriptor.proto",
-  UPB_STRVIEW_INIT(descriptor, 7619)
+  UPB_STRVIEW_INIT(descriptor, 7601)
 };
index 566745d..4cfdc75 100644 (file)
@@ -15,16 +15,17 @@ static const upb_msglayout *layouts[1] = {
   &google_protobuf_Duration_msginit,
 };
 
-static const char descriptor[243] = {'\n', '\036', 'g', 'o', 'o', 'g', 'l', 'e', '/', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '/', 'd', 'u', 'r', 'a', 't', 'i', 'o', 
+static const char descriptor[251] = {'\n', '\036', 'g', 'o', 'o', 'g', 'l', 'e', '/', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '/', 'd', 'u', 'r', 'a', 't', 'i', 'o', 
 'n', '.', 'p', 'r', 'o', 't', 'o', '\022', '\017', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '\"', 
 ':', '\n', '\010', 'D', 'u', 'r', 'a', 't', 'i', 'o', 'n', '\022', '\030', '\n', '\007', 's', 'e', 'c', 'o', 'n', 'd', 's', '\030', '\001', ' ', 
 '\001', '(', '\003', 'R', '\007', 's', 'e', 'c', 'o', 'n', 'd', 's', '\022', '\024', '\n', '\005', 'n', 'a', 'n', 'o', 's', '\030', '\002', ' ', '\001', 
-'(', '\005', 'R', '\005', 'n', 'a', 'n', 'o', 's', 'B', '|', '\n', '\023', 'c', 'o', 'm', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 
-'r', 'o', 't', 'o', 'b', 'u', 'f', 'B', '\r', 'D', 'u', 'r', 'a', 't', 'i', 'o', 'n', 'P', 'r', 'o', 't', 'o', 'P', '\001', 'Z', 
-'*', 'g', 'i', 't', 'h', 'u', 'b', '.', 'c', 'o', 'm', '/', 'g', 'o', 'l', 'a', 'n', 'g', '/', 'p', 'r', 'o', 't', 'o', 'b', 
-'u', 'f', '/', 'p', 't', 'y', 'p', 'e', 's', '/', 'd', 'u', 'r', 'a', 't', 'i', 'o', 'n', '\370', '\001', '\001', '\242', '\002', '\003', 'G', 
-'P', 'B', '\252', '\002', '\036', 'G', 'o', 'o', 'g', 'l', 'e', '.', 'P', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'W', 'e', 'l', 'l', 
-'K', 'n', 'o', 'w', 'n', 'T', 'y', 'p', 'e', 's', 'b', '\006', 'p', 'r', 'o', 't', 'o', '3', 
+'(', '\005', 'R', '\005', 'n', 'a', 'n', 'o', 's', 'B', '\203', '\001', '\n', '\023', 'c', 'o', 'm', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 
+'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', 'B', '\r', 'D', 'u', 'r', 'a', 't', 'i', 'o', 'n', 'P', 'r', 'o', 't', 'o', 'P', '\001', 
+'Z', '1', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'g', 'o', 'l', 'a', 'n', 'g', '.', 'o', 'r', 'g', '/', 'p', 'r', 'o', 't', 'o', 
+'b', 'u', 'f', '/', 't', 'y', 'p', 'e', 's', '/', 'k', 'n', 'o', 'w', 'n', '/', 'd', 'u', 'r', 'a', 't', 'i', 'o', 'n', 'p', 
+'b', '\370', '\001', '\001', '\242', '\002', '\003', 'G', 'P', 'B', '\252', '\002', '\036', 'G', 'o', 'o', 'g', 'l', 'e', '.', 'P', 'r', 'o', 't', 'o', 
+'b', 'u', 'f', '.', 'W', 'e', 'l', 'l', 'K', 'n', 'o', 'w', 'n', 'T', 'y', 'p', 'e', 's', 'b', '\006', 'p', 'r', 'o', 't', 'o', 
+'3', 
 };
 
 static upb_def_init *deps[1] = {
@@ -35,5 +36,5 @@ upb_def_init google_protobuf_duration_proto_upbdefinit = {
   deps,
   layouts,
   "google/protobuf/duration.proto",
-  UPB_STRVIEW_INIT(descriptor, 243)
+  UPB_STRVIEW_INIT(descriptor, 251)
 };
index a7ae127..8f974d9 100644 (file)
@@ -15,14 +15,14 @@ static const upb_msglayout *layouts[1] = {
   &google_protobuf_Empty_msginit,
 };
 
-static const char descriptor[183] = {'\n', '\033', 'g', 'o', 'o', 'g', 'l', 'e', '/', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '/', 'e', 'm', 'p', 't', 'y', '.', 'p', 
+static const char descriptor[190] = {'\n', '\033', 'g', 'o', 'o', 'g', 'l', 'e', '/', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '/', 'e', 'm', 'p', 't', 'y', '.', 'p', 
 'r', 'o', 't', 'o', '\022', '\017', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '\"', '\007', '\n', '\005', 
-'E', 'm', 'p', 't', 'y', 'B', 'v', '\n', '\023', 'c', 'o', 'm', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 
-'b', 'u', 'f', 'B', '\n', 'E', 'm', 'p', 't', 'y', 'P', 'r', 'o', 't', 'o', 'P', '\001', 'Z', '\'', 'g', 'i', 't', 'h', 'u', 'b', 
-'.', 'c', 'o', 'm', '/', 'g', 'o', 'l', 'a', 'n', 'g', '/', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '/', 'p', 't', 'y', 'p', 
-'e', 's', '/', 'e', 'm', 'p', 't', 'y', '\370', '\001', '\001', '\242', '\002', '\003', 'G', 'P', 'B', '\252', '\002', '\036', 'G', 'o', 'o', 'g', 'l', 
-'e', '.', 'P', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'W', 'e', 'l', 'l', 'K', 'n', 'o', 'w', 'n', 'T', 'y', 'p', 'e', 's', 
-'b', '\006', 'p', 'r', 'o', 't', 'o', '3', 
+'E', 'm', 'p', 't', 'y', 'B', '}', '\n', '\023', 'c', 'o', 'm', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 
+'b', 'u', 'f', 'B', '\n', 'E', 'm', 'p', 't', 'y', 'P', 'r', 'o', 't', 'o', 'P', '\001', 'Z', '.', 'g', 'o', 'o', 'g', 'l', 'e', 
+'.', 'g', 'o', 'l', 'a', 'n', 'g', '.', 'o', 'r', 'g', '/', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '/', 't', 'y', 'p', 'e', 
+'s', '/', 'k', 'n', 'o', 'w', 'n', '/', 'e', 'm', 'p', 't', 'y', 'p', 'b', '\370', '\001', '\001', '\242', '\002', '\003', 'G', 'P', 'B', '\252', 
+'\002', '\036', 'G', 'o', 'o', 'g', 'l', 'e', '.', 'P', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'W', 'e', 'l', 'l', 'K', 'n', 'o', 
+'w', 'n', 'T', 'y', 'p', 'e', 's', 'b', '\006', 'p', 'r', 'o', 't', 'o', '3', 
 };
 
 static upb_def_init *deps[1] = {
@@ -33,5 +33,5 @@ upb_def_init google_protobuf_empty_proto_upbdefinit = {
   deps,
   layouts,
   "google/protobuf/empty.proto",
-  UPB_STRVIEW_INIT(descriptor, 183)
+  UPB_STRVIEW_INIT(descriptor, 190)
 };
index fa9fa2a..6f2f13c 100644 (file)
@@ -21,7 +21,7 @@ static const upb_msglayout *layouts[4] = {
   &google_protobuf_ListValue_msginit,
 };
 
-static const char descriptor[741] = {'\n', '\034', 'g', 'o', 'o', 'g', 'l', 'e', '/', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '/', 's', 't', 'r', 'u', 'c', 't', '.', 
+static const char descriptor[738] = {'\n', '\034', 'g', 'o', 'o', 'g', 'l', 'e', '/', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '/', 's', 't', 'r', 'u', 'c', 't', '.', 
 'p', 'r', 'o', 't', 'o', '\022', '\017', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '\"', '\230', '\001', 
 '\n', '\006', 'S', 't', 'r', 'u', 'c', 't', '\022', ';', '\n', '\006', 'f', 'i', 'e', 'l', 'd', 's', '\030', '\001', ' ', '\003', '(', '\013', '2', 
 '#', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'S', 't', 'r', 'u', 'c', 't', '.', 
@@ -45,12 +45,12 @@ static const char descriptor[741] = {'\n', '\034', 'g', 'o', 'o', 'g', 'l', 'e',
 '.', '\n', '\006', 'v', 'a', 'l', 'u', 'e', 's', '\030', '\001', ' ', '\003', '(', '\013', '2', '\026', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 
 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'V', 'a', 'l', 'u', 'e', 'R', '\006', 'v', 'a', 'l', 'u', 'e', 's', '*', '\033', '\n', 
 '\t', 'N', 'u', 'l', 'l', 'V', 'a', 'l', 'u', 'e', '\022', '\016', '\n', '\n', 'N', 'U', 'L', 'L', '_', 'V', 'A', 'L', 'U', 'E', '\020', 
-'\000', 'B', '\201', '\001', '\n', '\023', 'c', 'o', 'm', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', 
-'B', '\013', 'S', 't', 'r', 'u', 'c', 't', 'P', 'r', 'o', 't', 'o', 'P', '\001', 'Z', '1', 'g', 'i', 't', 'h', 'u', 'b', '.', 'c', 
-'o', 'm', '/', 'g', 'o', 'l', 'a', 'n', 'g', '/', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '/', 'p', 't', 'y', 'p', 'e', 's', 
-'/', 's', 't', 'r', 'u', 'c', 't', ';', 's', 't', 'r', 'u', 'c', 't', 'p', 'b', '\370', '\001', '\001', '\242', '\002', '\003', 'G', 'P', 'B', 
-'\252', '\002', '\036', 'G', 'o', 'o', 'g', 'l', 'e', '.', 'P', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'W', 'e', 'l', 'l', 'K', 'n', 
-'o', 'w', 'n', 'T', 'y', 'p', 'e', 's', 'b', '\006', 'p', 'r', 'o', 't', 'o', '3', 
+'\000', 'B', '\177', '\n', '\023', 'c', 'o', 'm', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', 'B', 
+'\013', 'S', 't', 'r', 'u', 'c', 't', 'P', 'r', 'o', 't', 'o', 'P', '\001', 'Z', '/', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'g', 'o', 
+'l', 'a', 'n', 'g', '.', 'o', 'r', 'g', '/', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '/', 't', 'y', 'p', 'e', 's', '/', 'k', 
+'n', 'o', 'w', 'n', '/', 's', 't', 'r', 'u', 'c', 't', 'p', 'b', '\370', '\001', '\001', '\242', '\002', '\003', 'G', 'P', 'B', '\252', '\002', '\036', 
+'G', 'o', 'o', 'g', 'l', 'e', '.', 'P', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'W', 'e', 'l', 'l', 'K', 'n', 'o', 'w', 'n', 
+'T', 'y', 'p', 'e', 's', 'b', '\006', 'p', 'r', 'o', 't', 'o', '3', 
 };
 
 static upb_def_init *deps[1] = {
@@ -61,5 +61,5 @@ upb_def_init google_protobuf_struct_proto_upbdefinit = {
   deps,
   layouts,
   "google/protobuf/struct.proto",
-  UPB_STRVIEW_INIT(descriptor, 741)
+  UPB_STRVIEW_INIT(descriptor, 738)
 };
index beb80cd..bc2f7af 100644 (file)
@@ -15,16 +15,17 @@ static const upb_msglayout *layouts[1] = {
   &google_protobuf_Timestamp_msginit,
 };
 
-static const char descriptor[247] = {'\n', '\037', 'g', 'o', 'o', 'g', 'l', 'e', '/', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '/', 't', 'i', 'm', 'e', 's', 't', 'a', 
+static const char descriptor[255] = {'\n', '\037', 'g', 'o', 'o', 'g', 'l', 'e', '/', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '/', 't', 'i', 'm', 'e', 's', 't', 'a', 
 'm', 'p', '.', 'p', 'r', 'o', 't', 'o', '\022', '\017', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', 
 '\"', ';', '\n', '\t', 'T', 'i', 'm', 'e', 's', 't', 'a', 'm', 'p', '\022', '\030', '\n', '\007', 's', 'e', 'c', 'o', 'n', 'd', 's', '\030', 
 '\001', ' ', '\001', '(', '\003', 'R', '\007', 's', 'e', 'c', 'o', 'n', 'd', 's', '\022', '\024', '\n', '\005', 'n', 'a', 'n', 'o', 's', '\030', '\002', 
-' ', '\001', '(', '\005', 'R', '\005', 'n', 'a', 'n', 'o', 's', 'B', '~', '\n', '\023', 'c', 'o', 'm', '.', 'g', 'o', 'o', 'g', 'l', 'e', 
-'.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', 'B', '\016', 'T', 'i', 'm', 'e', 's', 't', 'a', 'm', 'p', 'P', 'r', 'o', 't', 'o', 
-'P', '\001', 'Z', '+', 'g', 'i', 't', 'h', 'u', 'b', '.', 'c', 'o', 'm', '/', 'g', 'o', 'l', 'a', 'n', 'g', '/', 'p', 'r', 'o', 
-'t', 'o', 'b', 'u', 'f', '/', 'p', 't', 'y', 'p', 'e', 's', '/', 't', 'i', 'm', 'e', 's', 't', 'a', 'm', 'p', '\370', '\001', '\001', 
-'\242', '\002', '\003', 'G', 'P', 'B', '\252', '\002', '\036', 'G', 'o', 'o', 'g', 'l', 'e', '.', 'P', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 
-'W', 'e', 'l', 'l', 'K', 'n', 'o', 'w', 'n', 'T', 'y', 'p', 'e', 's', 'b', '\006', 'p', 'r', 'o', 't', 'o', '3', 
+' ', '\001', '(', '\005', 'R', '\005', 'n', 'a', 'n', 'o', 's', 'B', '\205', '\001', '\n', '\023', 'c', 'o', 'm', '.', 'g', 'o', 'o', 'g', 'l', 
+'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', 'B', '\016', 'T', 'i', 'm', 'e', 's', 't', 'a', 'm', 'p', 'P', 'r', 'o', 't', 
+'o', 'P', '\001', 'Z', '2', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'g', 'o', 'l', 'a', 'n', 'g', '.', 'o', 'r', 'g', '/', 'p', 'r', 
+'o', 't', 'o', 'b', 'u', 'f', '/', 't', 'y', 'p', 'e', 's', '/', 'k', 'n', 'o', 'w', 'n', '/', 't', 'i', 'm', 'e', 's', 't', 
+'a', 'm', 'p', 'p', 'b', '\370', '\001', '\001', '\242', '\002', '\003', 'G', 'P', 'B', '\252', '\002', '\036', 'G', 'o', 'o', 'g', 'l', 'e', '.', 'P', 
+'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'W', 'e', 'l', 'l', 'K', 'n', 'o', 'w', 'n', 'T', 'y', 'p', 'e', 's', 'b', '\006', 'p', 
+'r', 'o', 't', 'o', '3', 
 };
 
 static upb_def_init *deps[1] = {
@@ -35,5 +36,5 @@ upb_def_init google_protobuf_timestamp_proto_upbdefinit = {
   deps,
   layouts,
   "google/protobuf/timestamp.proto",
-  UPB_STRVIEW_INIT(descriptor, 247)
+  UPB_STRVIEW_INIT(descriptor, 255)
 };
index 547ea12..59a598a 100644 (file)
@@ -31,7 +31,7 @@ static const upb_msglayout *layouts[9] = {
   &google_protobuf_BytesValue_msginit,
 };
 
-static const char descriptor[510] = {'\n', '\036', 'g', 'o', 'o', 'g', 'l', 'e', '/', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '/', 'w', 'r', 'a', 'p', 'p', 'e', 'r', 
+static const char descriptor[518] = {'\n', '\036', 'g', 'o', 'o', 'g', 'l', 'e', '/', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '/', 'w', 'r', 'a', 'p', 'p', 'e', 'r', 
 's', '.', 'p', 'r', 'o', 't', 'o', '\022', '\017', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '\"', 
 '#', '\n', '\013', 'D', 'o', 'u', 'b', 'l', 'e', 'V', 'a', 'l', 'u', 'e', '\022', '\024', '\n', '\005', 'v', 'a', 'l', 'u', 'e', '\030', '\001', 
 ' ', '\001', '(', '\001', 'R', '\005', 'v', 'a', 'l', 'u', 'e', '\"', '\"', '\n', '\n', 'F', 'l', 'o', 'a', 't', 'V', 'a', 'l', 'u', 'e', 
@@ -46,12 +46,12 @@ static const char descriptor[510] = {'\n', '\036', 'g', 'o', 'o', 'g', 'l', 'e',
 'l', 'u', 'e', '\"', '#', '\n', '\013', 'S', 't', 'r', 'i', 'n', 'g', 'V', 'a', 'l', 'u', 'e', '\022', '\024', '\n', '\005', 'v', 'a', 'l', 
 'u', 'e', '\030', '\001', ' ', '\001', '(', '\t', 'R', '\005', 'v', 'a', 'l', 'u', 'e', '\"', '\"', '\n', '\n', 'B', 'y', 't', 'e', 's', 'V', 
 'a', 'l', 'u', 'e', '\022', '\024', '\n', '\005', 'v', 'a', 'l', 'u', 'e', '\030', '\001', ' ', '\001', '(', '\014', 'R', '\005', 'v', 'a', 'l', 'u', 
-'e', 'B', '|', '\n', '\023', 'c', 'o', 'm', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', 'B', 
-'\r', 'W', 'r', 'a', 'p', 'p', 'e', 'r', 's', 'P', 'r', 'o', 't', 'o', 'P', '\001', 'Z', '*', 'g', 'i', 't', 'h', 'u', 'b', '.', 
-'c', 'o', 'm', '/', 'g', 'o', 'l', 'a', 'n', 'g', '/', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '/', 'p', 't', 'y', 'p', 'e', 
-'s', '/', 'w', 'r', 'a', 'p', 'p', 'e', 'r', 's', '\370', '\001', '\001', '\242', '\002', '\003', 'G', 'P', 'B', '\252', '\002', '\036', 'G', 'o', 'o', 
-'g', 'l', 'e', '.', 'P', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'W', 'e', 'l', 'l', 'K', 'n', 'o', 'w', 'n', 'T', 'y', 'p', 
-'e', 's', 'b', '\006', 'p', 'r', 'o', 't', 'o', '3', 
+'e', 'B', '\203', '\001', '\n', '\023', 'c', 'o', 'm', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', 
+'B', '\r', 'W', 'r', 'a', 'p', 'p', 'e', 'r', 's', 'P', 'r', 'o', 't', 'o', 'P', '\001', 'Z', '1', 'g', 'o', 'o', 'g', 'l', 'e', 
+'.', 'g', 'o', 'l', 'a', 'n', 'g', '.', 'o', 'r', 'g', '/', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '/', 't', 'y', 'p', 'e', 
+'s', '/', 'k', 'n', 'o', 'w', 'n', '/', 'w', 'r', 'a', 'p', 'p', 'e', 'r', 's', 'p', 'b', '\370', '\001', '\001', '\242', '\002', '\003', 'G', 
+'P', 'B', '\252', '\002', '\036', 'G', 'o', 'o', 'g', 'l', 'e', '.', 'P', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'W', 'e', 'l', 'l', 
+'K', 'n', 'o', 'w', 'n', 'T', 'y', 'p', 'e', 's', 'b', '\006', 'p', 'r', 'o', 't', 'o', '3', 
 };
 
 static upb_def_init *deps[1] = {
@@ -62,5 +62,5 @@ upb_def_init google_protobuf_wrappers_proto_upbdefinit = {
   deps,
   layouts,
   "google/protobuf/wrappers.proto",
-  UPB_STRVIEW_INIT(descriptor, 510)
+  UPB_STRVIEW_INIT(descriptor, 518)
 };
index dedb2bb..dd66b97 100644 (file)
@@ -36,13 +36,16 @@ CertificateProviderStore::CreateOrGetCertificateProvider(
   MutexLock lock(&mu_);
   auto it = certificate_providers_map_.find(key);
   if (it == certificate_providers_map_.end()) {
-    it = certificate_providers_map_.insert({key, nullptr}).first;
+    result = CreateCertificateProviderLocked(key);
+    if (result != nullptr) {
+      certificate_providers_map_.insert({result->key(), result.get()});
+    }
   } else {
     result = it->second->RefIfNonZero();
-  }
-  if (result == nullptr) {
-    result = CreateCertificateProviderLocked(key);
-    it->second = result.get();
+    if (result == nullptr) {
+      result = CreateCertificateProviderLocked(key);
+      it->second = result.get();
+    }
   }
   return result;
 }
@@ -66,8 +69,8 @@ CertificateProviderStore::CreateCertificateProviderLocked(
     return nullptr;
   }
   return MakeRefCounted<CertificateProviderWrapper>(
-      factory->CreateCertificateProvider(plugin_config_it->second.config), this,
-      plugin_config_it->first);
+      factory->CreateCertificateProvider(plugin_config_it->second.config),
+      Ref(), plugin_config_it->first);
 }
 
 void CertificateProviderStore::ReleaseCertificateProvider(
index ef22d36..0954bc5 100644 (file)
 #include "absl/strings/string_view.h"
 
 #include "src/core/ext/xds/certificate_provider_factory.h"
+#include "src/core/lib/gprpp/orphanable.h"
 #include "src/core/lib/gprpp/ref_counted_ptr.h"
 #include "src/core/lib/gprpp/sync.h"
 #include "src/core/lib/security/credentials/tls/grpc_tls_certificate_provider.h"
 
 namespace grpc_core {
 
-// Map for xDS based grpc_tls_certificate_provider instances. The store should
-// outlive the refs taken via `CreateOrGetCertificateProvider()`.
-class CertificateProviderStore {
+// Map for xDS based grpc_tls_certificate_provider instances.
+class CertificateProviderStore
+    : public InternallyRefCounted<CertificateProviderStore> {
  public:
   struct PluginDefinition {
     std::string plugin_name;
@@ -44,7 +45,7 @@ class CertificateProviderStore {
   // Maps plugin instance (opaque) name to plugin defition.
   typedef std::map<std::string, PluginDefinition> PluginDefinitionMap;
 
-  CertificateProviderStore(PluginDefinitionMap plugin_config_map)
+  explicit CertificateProviderStore(PluginDefinitionMap plugin_config_map)
       : plugin_config_map_(std::move(plugin_config_map)) {}
 
   // If a certificate provider corresponding to the instance name \a key is
@@ -55,6 +56,8 @@ class CertificateProviderStore {
   RefCountedPtr<grpc_tls_certificate_provider> CreateOrGetCertificateProvider(
       absl::string_view key);
 
+  void Orphan() override { Unref(); }
+
  private:
   // A thin wrapper around `grpc_tls_certificate_provider` which allows removing
   // the entry from the CertificateProviderStore when the refcount reaches zero.
@@ -62,9 +65,9 @@ class CertificateProviderStore {
    public:
     CertificateProviderWrapper(
         RefCountedPtr<grpc_tls_certificate_provider> certificate_provider,
-        CertificateProviderStore* store, absl::string_view key)
+        RefCountedPtr<CertificateProviderStore> store, absl::string_view key)
         : certificate_provider_(std::move(certificate_provider)),
-          store_(store),
+          store_(std::move(store)),
           key_(key) {}
 
     ~CertificateProviderWrapper() override {
@@ -80,9 +83,11 @@ class CertificateProviderStore {
       return certificate_provider_->interested_parties();
     }
 
+    absl::string_view key() const { return key_; }
+
    private:
     RefCountedPtr<grpc_tls_certificate_provider> certificate_provider_;
-    CertificateProviderStore* store_;
+    RefCountedPtr<CertificateProviderStore> store_;
     absl::string_view key_;
   };
 
index fab8dac..a5250eb 100644 (file)
@@ -23,6 +23,7 @@
 #include "absl/strings/str_format.h"
 #include "absl/strings/str_join.h"
 
+#include "src/core/ext/xds/certificate_provider_registry.h"
 #include "src/core/lib/json/json_util.h"
 
 namespace grpc_core {
@@ -116,4 +117,28 @@ FileWatcherCertificateProviderFactory::CreateCertificateProviderConfig(
                                                               error);
 }
 
+RefCountedPtr<grpc_tls_certificate_provider>
+FileWatcherCertificateProviderFactory::CreateCertificateProvider(
+    RefCountedPtr<CertificateProviderFactory::Config> config) {
+  if (config->name() != name()) {
+    gpr_log(GPR_ERROR, "Wrong config type Actual:%s vs Expected:%s",
+            config->name(), name());
+    return nullptr;
+  }
+  auto* file_watcher_config =
+      static_cast<FileWatcherCertificateProviderFactory::Config*>(config.get());
+  return MakeRefCounted<FileWatcherCertificateProvider>(
+      file_watcher_config->private_key_file(),
+      file_watcher_config->identity_cert_file(),
+      file_watcher_config->root_cert_file(),
+      file_watcher_config->refresh_interval_ms() / GPR_MS_PER_SEC);
+}
+
+void FileWatcherCertificateProviderInit() {
+  CertificateProviderRegistry::RegisterCertificateProviderFactory(
+      absl::make_unique<FileWatcherCertificateProviderFactory>());
+}
+
+void FileWatcherCertificateProviderShutdown() {}
+
 }  // namespace grpc_core
index 96b61e1..c570062 100644 (file)
@@ -61,10 +61,7 @@ class FileWatcherCertificateProviderFactory
                                   grpc_error** error) override;
 
   RefCountedPtr<grpc_tls_certificate_provider> CreateCertificateProvider(
-      RefCountedPtr<CertificateProviderFactory::Config> config) override {
-    // TODO(yashykt) : To be implemented
-    return nullptr;
-  }
+      RefCountedPtr<CertificateProviderFactory::Config> config) override;
 };
 
 }  // namespace grpc_core
index 8ec9dfe..e9403c2 100644 (file)
@@ -429,38 +429,207 @@ XdsApi::RdsUpdate::VirtualHost* XdsApi::RdsUpdate::FindVirtualHostForDomain(
 // XdsApi::StringMatcher
 //
 
+XdsApi::StringMatcher::StringMatcher(StringMatcherType type,
+                                     const std::string& matcher,
+                                     bool ignore_case)
+    : type_(type), ignore_case_(ignore_case) {
+  if (type_ == StringMatcherType::SAFE_REGEX) {
+    regex_matcher_ = absl::make_unique<RE2>(matcher);
+  } else {
+    string_matcher_ = matcher;
+  }
+}
+
 XdsApi::StringMatcher::StringMatcher(const StringMatcher& other)
-    : type(other.type) {
-  switch (type) {
+    : type_(other.type_), ignore_case_(other.ignore_case_) {
+  switch (type_) {
     case StringMatcherType::SAFE_REGEX:
-      regex_match = absl::make_unique<RE2>(other.regex_match->pattern());
+      regex_matcher_ = absl::make_unique<RE2>(other.regex_matcher_->pattern());
       break;
     default:
-      string_matcher = other.string_matcher;
+      string_matcher_ = other.string_matcher_;
   }
 }
 
 XdsApi::StringMatcher& XdsApi::StringMatcher::operator=(
     const StringMatcher& other) {
-  type = other.type;
-  switch (type) {
+  type_ = other.type_;
+  switch (type_) {
     case StringMatcherType::SAFE_REGEX:
-      regex_match = absl::make_unique<RE2>(other.regex_match->pattern());
+      regex_matcher_ = absl::make_unique<RE2>(other.regex_matcher_->pattern());
       break;
     default:
-      string_matcher = other.string_matcher;
+      string_matcher_ = other.string_matcher_;
   }
+  ignore_case_ = other.ignore_case_;
   return *this;
 }
 
 bool XdsApi::StringMatcher::operator==(const StringMatcher& other) const {
-  if (type != other.type) return false;
-  switch (type) {
+  if (type_ != other.type_ || ignore_case_ != other.ignore_case_) return false;
+  switch (type_) {
     case StringMatcherType::SAFE_REGEX:
-      return regex_match->pattern() != other.regex_match->pattern();
+      return regex_matcher_->pattern() == other.regex_matcher_->pattern();
     default:
-      return string_matcher != other.string_matcher;
+      return string_matcher_ == other.string_matcher_;
+  }
+}
+
+bool XdsApi::StringMatcher::Match(absl::string_view value) const {
+  switch (type_) {
+    case XdsApi::StringMatcher::StringMatcherType::EXACT:
+      return ignore_case_ ? absl::EqualsIgnoreCase(value, string_matcher_)
+                          : value == string_matcher_;
+    case XdsApi::StringMatcher::StringMatcherType::PREFIX:
+      return ignore_case_ ? absl::StartsWithIgnoreCase(value, string_matcher_)
+                          : absl::StartsWith(value, string_matcher_);
+    case XdsApi::StringMatcher::StringMatcherType::SUFFIX:
+      return ignore_case_ ? absl::EndsWithIgnoreCase(value, string_matcher_)
+                          : absl::EndsWith(value, string_matcher_);
+    case XdsApi::StringMatcher::StringMatcherType::CONTAINS:
+      return ignore_case_
+                 ? absl::StrContains(absl::AsciiStrToLower(value),
+                                     absl::AsciiStrToLower(string_matcher_))
+                 : absl::StrContains(value, string_matcher_);
+    case XdsApi::StringMatcher::StringMatcherType::SAFE_REGEX:
+      // ignore_case_ is ignored for SAFE_REGEX
+      return RE2::FullMatch(std::string(value), *regex_matcher_);
+    default:
+      return false;
+  }
+}
+
+std::string XdsApi::StringMatcher::ToString() const {
+  switch (type_) {
+    case StringMatcherType::EXACT:
+      return absl::StrFormat("StringMatcher{exact=%s%s}", string_matcher_,
+                             ignore_case_ ? ", ignore_case" : "");
+    case StringMatcherType::PREFIX:
+      return absl::StrFormat("StringMatcher{prefix=%s%s}", string_matcher_,
+                             ignore_case_ ? ", ignore_case" : "");
+    case StringMatcherType::SUFFIX:
+      return absl::StrFormat("StringMatcher{suffix=%s%s}", string_matcher_,
+                             ignore_case_ ? ", ignore_case" : "");
+    case StringMatcherType::CONTAINS:
+      return absl::StrFormat("StringMatcher{contains=%s%s}", string_matcher_,
+                             ignore_case_ ? ", ignore_case" : "");
+    case StringMatcherType::SAFE_REGEX:
+      return absl::StrFormat("StringMatcher{safe_regex=%s}",
+                             regex_matcher_->pattern());
+    default:
+      return "";
+  }
+}
+
+//
+// XdsApi::CommonTlsContext::CertificateValidationContext
+//
+
+std::string XdsApi::CommonTlsContext::CertificateValidationContext::ToString()
+    const {
+  std::vector<std::string> contents;
+  for (const auto& match : match_subject_alt_names) {
+    contents.push_back(match.ToString());
+  }
+  return absl::StrFormat("{match_subject_alt_names=[%s]}",
+                         absl::StrJoin(contents, ", "));
+}
+
+bool XdsApi::CommonTlsContext::CertificateValidationContext::Empty() const {
+  return match_subject_alt_names.empty();
+}
+
+//
+// XdsApi::CommonTlsContext::CertificateValidationContext
+//
+
+std::string XdsApi::CommonTlsContext::CertificateProviderInstance::ToString()
+    const {
+  absl::InlinedVector<std::string, 2> contents;
+  if (!instance_name.empty()) {
+    contents.push_back(absl::StrFormat("instance_name=%s", instance_name));
+  }
+  if (!certificate_name.empty()) {
+    contents.push_back(
+        absl::StrFormat("certificate_name=%s", certificate_name));
+  }
+  return absl::StrCat("{", absl::StrJoin(contents, ", "), "}");
+}
+
+bool XdsApi::CommonTlsContext::CertificateProviderInstance::Empty() const {
+  return instance_name.empty() && certificate_name.empty();
+}
+
+//
+// XdsApi::CommonTlsContext::CombinedCertificateValidationContext
+//
+
+std::string
+XdsApi::CommonTlsContext::CombinedCertificateValidationContext::ToString()
+    const {
+  absl::InlinedVector<std::string, 2> contents;
+  if (!default_validation_context.Empty()) {
+    contents.push_back(absl::StrFormat("default_validation_context=%s",
+                                       default_validation_context.ToString()));
+  }
+  if (!validation_context_certificate_provider_instance.Empty()) {
+    contents.push_back(absl::StrFormat(
+        "validation_context_certificate_provider_instance=%s",
+        validation_context_certificate_provider_instance.ToString()));
+  }
+  return absl::StrCat("{", absl::StrJoin(contents, ", "), "}");
+}
+
+bool XdsApi::CommonTlsContext::CombinedCertificateValidationContext::Empty()
+    const {
+  return default_validation_context.Empty() &&
+         validation_context_certificate_provider_instance.Empty();
+}
+
+//
+// XdsApi::CommonTlsContext
+//
+
+std::string XdsApi::CommonTlsContext::ToString() const {
+  absl::InlinedVector<std::string, 2> contents;
+  if (!tls_certificate_certificate_provider_instance.Empty()) {
+    contents.push_back(absl::StrFormat(
+        "tls_certificate_certificate_provider_instance=%s",
+        tls_certificate_certificate_provider_instance.ToString()));
+  }
+  if (!combined_validation_context.Empty()) {
+    contents.push_back(absl::StrFormat("combined_validation_context=%s",
+                                       combined_validation_context.ToString()));
+  }
+  return absl::StrCat("{", absl::StrJoin(contents, ", "), "}");
+}
+
+bool XdsApi::CommonTlsContext::Empty() const {
+  return tls_certificate_certificate_provider_instance.Empty() &&
+         combined_validation_context.Empty();
+}
+
+//
+// XdsApi::CdsUpdate
+//
+
+std::string XdsApi::CdsUpdate::ToString() const {
+  absl::InlinedVector<std::string, 4> contents;
+  if (!eds_service_name.empty()) {
+    contents.push_back(
+        absl::StrFormat("eds_service_name=%s", eds_service_name));
   }
+  if (!common_tls_context.Empty()) {
+    contents.push_back(absl::StrFormat("common_tls_context=%s",
+                                       common_tls_context.ToString()));
+  }
+  if (lrs_load_reporting_server_name.has_value()) {
+    contents.push_back(absl::StrFormat("lrs_load_reporting_server_name=%s",
+                                       lrs_load_reporting_server_name.value()));
+  }
+  contents.push_back(
+      absl::StrFormat("max_concurrent_requests=%d", max_concurrent_requests));
+  return absl::StrCat("{", absl::StrJoin(contents, ", "), "}");
 }
 
 //
@@ -1136,6 +1305,7 @@ grpc_error* RouteActionParse(const envoy_config_route_v3_Route* route_msg,
             "RouteAction weighted_cluster cluster missing weight");
       }
       cluster.weight = google_protobuf_UInt32Value_value(weight);
+      if (cluster.weight == 0) continue;
       sum_of_weights += cluster.weight;
       route->weighted_clusters.emplace_back(std::move(cluster));
     }
@@ -1442,47 +1612,59 @@ grpc_error* CommonTlsContextParse(
           envoy_extensions_transport_sockets_tls_v3_CertificateValidationContext_match_subject_alt_names(
               default_validation_context, &len);
       for (size_t i = 0; i < len; ++i) {
-        XdsApi::StringMatcher matcher;
+        XdsApi::StringMatcher::StringMatcherType type;
+        std::string matcher;
         if (envoy_type_matcher_v3_StringMatcher_has_exact(
                 subject_alt_names_matchers[i])) {
-          matcher.type = XdsApi::StringMatcher::StringMatcherType::EXACT;
-          matcher.string_matcher =
+          type = XdsApi::StringMatcher::StringMatcherType::EXACT;
+          matcher =
               UpbStringToStdString(envoy_type_matcher_v3_StringMatcher_exact(
                   subject_alt_names_matchers[i]));
         } else if (envoy_type_matcher_v3_StringMatcher_has_prefix(
                        subject_alt_names_matchers[i])) {
-          matcher.type = XdsApi::StringMatcher::StringMatcherType::PREFIX;
-          matcher.string_matcher =
+          type = XdsApi::StringMatcher::StringMatcherType::PREFIX;
+          matcher =
               UpbStringToStdString(envoy_type_matcher_v3_StringMatcher_prefix(
                   subject_alt_names_matchers[i]));
         } else if (envoy_type_matcher_v3_StringMatcher_has_suffix(
                        subject_alt_names_matchers[i])) {
-          matcher.type = XdsApi::StringMatcher::StringMatcherType::SUFFIX;
-          matcher.string_matcher =
+          type = XdsApi::StringMatcher::StringMatcherType::SUFFIX;
+          matcher =
               UpbStringToStdString(envoy_type_matcher_v3_StringMatcher_suffix(
                   subject_alt_names_matchers[i]));
+        } else if (envoy_type_matcher_v3_StringMatcher_has_contains(
+                       subject_alt_names_matchers[i])) {
+          type = XdsApi::StringMatcher::StringMatcherType::CONTAINS;
+          matcher =
+              UpbStringToStdString(envoy_type_matcher_v3_StringMatcher_contains(
+                  subject_alt_names_matchers[i]));
         } else if (envoy_type_matcher_v3_StringMatcher_has_safe_regex(
                        subject_alt_names_matchers[i])) {
-          matcher.type = XdsApi::StringMatcher::StringMatcherType::SAFE_REGEX;
+          type = XdsApi::StringMatcher::StringMatcherType::SAFE_REGEX;
           auto* regex_matcher = envoy_type_matcher_v3_StringMatcher_safe_regex(
               subject_alt_names_matchers[i]);
-          std::unique_ptr<RE2> regex =
-              absl::make_unique<RE2>(UpbStringToStdString(
-                  envoy_type_matcher_v3_RegexMatcher_regex(regex_matcher)));
-          if (!regex->ok()) {
-            return GRPC_ERROR_CREATE_FROM_STATIC_STRING(
-                "Invalid regex string specified in string matcher.");
-          }
-          matcher.regex_match = std::move(regex);
+          matcher = UpbStringToStdString(
+              envoy_type_matcher_v3_RegexMatcher_regex(regex_matcher));
         } else {
           return GRPC_ERROR_CREATE_FROM_STATIC_STRING(
               "Invalid StringMatcher specified");
         }
-        matcher.ignore_case = envoy_type_matcher_v3_StringMatcher_ignore_case(
+        bool ignore_case = envoy_type_matcher_v3_StringMatcher_ignore_case(
             subject_alt_names_matchers[i]);
+        XdsApi::StringMatcher string_matcher(type, matcher, ignore_case);
+        if (type == XdsApi::StringMatcher::StringMatcherType::SAFE_REGEX) {
+          if (!string_matcher.regex_matcher()->ok()) {
+            return GRPC_ERROR_CREATE_FROM_STATIC_STRING(
+                "Invalid regex string specified in string matcher.");
+          }
+          if (ignore_case) {
+            return GRPC_ERROR_CREATE_FROM_STATIC_STRING(
+                "StringMatcher: ignore_case has no effect for SAFE_REGEX.");
+          }
+        }
         common_tls_context->combined_validation_context
-            .default_validation_context.match_subject_alt_names.emplace_back(
-                matcher);
+            .default_validation_context.match_subject_alt_names.push_back(
+                std::move(string_matcher));
       }
     }
     auto* validation_context_certificate_provider_instance =
@@ -1608,6 +1790,13 @@ grpc_error* CdsResponseParse(
               if (error != GRPC_ERROR_NONE) return error;
             }
           }
+          if (cds_update.common_tls_context.combined_validation_context
+                  .validation_context_certificate_provider_instance
+                  .instance_name.empty()) {
+            return GRPC_ERROR_CREATE_FROM_STATIC_STRING(
+                "TLS configuration provided but no "
+                "validation_context_certificate_provider_instance found.");
+          }
         }
       }
     }
index 885dd2c..f2a6707 100644 (file)
@@ -175,23 +175,40 @@ class XdsApi {
     VirtualHost* FindVirtualHostForDomain(const std::string& domain);
   };
 
-  struct StringMatcher {
+  class StringMatcher {
+   public:
     enum class StringMatcherType {
-      EXACT,       // value stored in string_matcher_field
-      PREFIX,      // value stored in string_matcher_field
-      SUFFIX,      // value stored in string_matcher_field
-      SAFE_REGEX,  // use regex_match field
-      CONTAINS,    // value stored in string_matcher_field
+      EXACT,       // value stored in string_matcher_ field
+      PREFIX,      // value stored in string_matcher_ field
+      SUFFIX,      // value stored in string_matcher_ field
+      SAFE_REGEX,  // pattern stored in regex_matcher_ field
+      CONTAINS,    // value stored in string_matcher_ field
     };
-    StringMatcherType type;
-    std::string string_matcher;
-    std::unique_ptr<RE2> regex_match;
-    bool ignore_case;
 
     StringMatcher() = default;
     StringMatcher(const StringMatcher& other);
+    StringMatcher(StringMatcherType type, const std::string& matcher,
+                  bool ignore_case = false);
     StringMatcher& operator=(const StringMatcher& other);
     bool operator==(const StringMatcher& other) const;
+
+    bool Match(absl::string_view value) const;
+
+    std::string ToString() const;
+
+    StringMatcherType type() const { return type_; }
+
+    // Valid for EXACT, PREFIX, SUFFIX and CONTAINS
+    const std::string& string_matcher() const { return string_matcher_; }
+
+    // Valid for SAFE_REGEX
+    RE2* regex_matcher() const { return regex_matcher_.get(); }
+
+   private:
+    StringMatcherType type_ = StringMatcherType::EXACT;
+    std::string string_matcher_;
+    std::unique_ptr<RE2> regex_matcher_;
+    bool ignore_case_ = false;
   };
 
   struct CommonTlsContext {
@@ -201,6 +218,9 @@ class XdsApi {
       bool operator==(const CertificateValidationContext& other) const {
         return match_subject_alt_names == other.match_subject_alt_names;
       }
+
+      std::string ToString() const;
+      bool Empty() const;
     };
 
     struct CertificateProviderInstance {
@@ -211,6 +231,9 @@ class XdsApi {
         return instance_name == other.instance_name &&
                certificate_name == other.certificate_name;
       }
+
+      std::string ToString() const;
+      bool Empty() const;
     };
 
     struct CombinedCertificateValidationContext {
@@ -223,6 +246,9 @@ class XdsApi {
                validation_context_certificate_provider_instance ==
                    other.validation_context_certificate_provider_instance;
       }
+
+      std::string ToString() const;
+      bool Empty() const;
     };
 
     CertificateProviderInstance tls_certificate_certificate_provider_instance;
@@ -233,6 +259,9 @@ class XdsApi {
                  other.tls_certificate_certificate_provider_instance &&
              combined_validation_context == other.combined_validation_context;
     }
+
+    std::string ToString() const;
+    bool Empty() const;
   };
 
   // TODO(roth): When we can use absl::variant<>, consider using that
@@ -280,6 +309,8 @@ class XdsApi {
                  other.lrs_load_reporting_server_name &&
              max_concurrent_requests == other.max_concurrent_requests;
     }
+
+    std::string ToString() const;
   };
 
   using CdsUpdateMap = std::map<std::string /*cluster_name*/, CdsUpdate>;
index 8a3393d..969d5d5 100644 (file)
@@ -29,7 +29,6 @@
 #include <grpc/slice.h>
 
 #include "src/core/ext/xds/certificate_provider_store.h"
-#include "src/core/lib/gprpp/map.h"
 #include "src/core/lib/gprpp/memory.h"
 #include "src/core/lib/gprpp/ref_counted_ptr.h"
 #include "src/core/lib/iomgr/error.h"
index e6ad4dd..f285b6d 100644 (file)
 
 #include <grpc/support/port_platform.h>
 
+#include "src/core/ext/xds/xds_certificate_provider.h"
+
 #include "absl/functional/bind_front.h"
 #include "absl/strings/str_cat.h"
 
-#include "src/core/ext/xds/xds_certificate_provider.h"
+#include "src/core/lib/gpr/useful.h"
 
 namespace grpc_core {
 
@@ -100,20 +102,30 @@ XdsCertificateProvider::XdsCertificateProvider(
     absl::string_view root_cert_name,
     RefCountedPtr<grpc_tls_certificate_distributor> root_cert_distributor,
     absl::string_view identity_cert_name,
-    RefCountedPtr<grpc_tls_certificate_distributor> identity_cert_distributor)
+    RefCountedPtr<grpc_tls_certificate_distributor> identity_cert_distributor,
+    std::vector<XdsApi::StringMatcher> san_matchers)
     : root_cert_name_(root_cert_name),
       identity_cert_name_(identity_cert_name),
       root_cert_distributor_(std::move(root_cert_distributor)),
       identity_cert_distributor_(std::move(identity_cert_distributor)),
+      san_matchers_(std::move(san_matchers)),
       distributor_(MakeRefCounted<grpc_tls_certificate_distributor>()) {
   distributor_->SetWatchStatusCallback(
       absl::bind_front(&XdsCertificateProvider::WatchStatusCallback, this));
 }
 
+XdsCertificateProvider::~XdsCertificateProvider() {
+  distributor_->SetWatchStatusCallback(nullptr);
+}
+
 void XdsCertificateProvider::UpdateRootCertNameAndDistributor(
     absl::string_view root_cert_name,
     RefCountedPtr<grpc_tls_certificate_distributor> root_cert_distributor) {
   MutexLock lock(&mu_);
+  if (root_cert_name_ == root_cert_name &&
+      root_cert_distributor_ == root_cert_distributor) {
+    return;
+  }
   root_cert_name_ = std::string(root_cert_name);
   if (watching_root_certs_) {
     // The root certificates are being watched. Swap out the watcher.
@@ -139,6 +151,10 @@ void XdsCertificateProvider::UpdateIdentityCertNameAndDistributor(
     absl::string_view identity_cert_name,
     RefCountedPtr<grpc_tls_certificate_distributor> identity_cert_distributor) {
   MutexLock lock(&mu_);
+  if (identity_cert_name_ == identity_cert_name &&
+      identity_cert_distributor_ == identity_cert_distributor) {
+    return;
+  }
   identity_cert_name_ = std::string(identity_cert_name);
   if (watching_identity_certs_) {
     // The identity certificates are being watched. Swap out the watcher.
@@ -160,6 +176,12 @@ void XdsCertificateProvider::UpdateIdentityCertNameAndDistributor(
   identity_cert_distributor_ = std::move(identity_cert_distributor);
 }
 
+void XdsCertificateProvider::UpdateSubjectAlternativeNameMatchers(
+    std::vector<XdsApi::StringMatcher> matchers) {
+  MutexLock lock(&san_matchers_mu_);
+  san_matchers_ = std::move(matchers);
+}
+
 void XdsCertificateProvider::WatchStatusCallback(std::string cert_name,
                                                  bool root_being_watched,
                                                  bool identity_being_watched) {
@@ -237,4 +259,41 @@ void XdsCertificateProvider::UpdateIdentityCertWatcher(
       std::move(watcher), absl::nullopt, identity_cert_name_);
 }
 
+namespace {
+
+void* XdsCertificateProviderArgCopy(void* p) {
+  XdsCertificateProvider* xds_certificate_provider =
+      static_cast<XdsCertificateProvider*>(p);
+  return xds_certificate_provider->Ref().release();
+}
+
+void XdsCertificateProviderArgDestroy(void* p) {
+  XdsCertificateProvider* xds_certificate_provider =
+      static_cast<XdsCertificateProvider*>(p);
+  xds_certificate_provider->Unref();
+}
+
+int XdsCertificateProviderArgCmp(void* p, void* q) { return GPR_ICMP(p, q); }
+
+const grpc_arg_pointer_vtable kChannelArgVtable = {
+    XdsCertificateProviderArgCopy, XdsCertificateProviderArgDestroy,
+    XdsCertificateProviderArgCmp};
+
+}  // namespace
+
+grpc_arg XdsCertificateProvider::MakeChannelArg() const {
+  return grpc_channel_arg_pointer_create(
+      const_cast<char*>(GRPC_ARG_XDS_CERTIFICATE_PROVIDER),
+      const_cast<XdsCertificateProvider*>(this), &kChannelArgVtable);
+}
+
+RefCountedPtr<XdsCertificateProvider>
+XdsCertificateProvider::GetFromChannelArgs(const grpc_channel_args* args) {
+  XdsCertificateProvider* xds_certificate_provider =
+      grpc_channel_args_find_pointer<XdsCertificateProvider>(
+          args, GRPC_ARG_XDS_CERTIFICATE_PROVIDER);
+  return xds_certificate_provider != nullptr ? xds_certificate_provider->Ref()
+                                             : nullptr;
+}
+
 }  // namespace grpc_core
index caf0e5c..4d13423 100644 (file)
 
 #include <grpc/support/port_platform.h>
 
+#include "src/core/ext/xds/xds_api.h"
 #include "src/core/lib/security/credentials/tls/grpc_tls_certificate_provider.h"
 
+#define GRPC_ARG_XDS_CERTIFICATE_PROVIDER \
+  "grpc.internal.xds_certificate_provider"
+
 namespace grpc_core {
 
 class XdsCertificateProvider : public grpc_tls_certificate_provider {
@@ -31,8 +35,10 @@ class XdsCertificateProvider : public grpc_tls_certificate_provider {
       absl::string_view root_cert_name,
       RefCountedPtr<grpc_tls_certificate_distributor> root_cert_distributor,
       absl::string_view identity_cert_name,
-      RefCountedPtr<grpc_tls_certificate_distributor>
-          identity_cert_distributor);
+      RefCountedPtr<grpc_tls_certificate_distributor> identity_cert_distributor,
+      std::vector<XdsApi::StringMatcher> san_matchers);
+
+  ~XdsCertificateProvider() override;
 
   void UpdateRootCertNameAndDistributor(
       absl::string_view root_cert_name,
@@ -41,12 +47,34 @@ class XdsCertificateProvider : public grpc_tls_certificate_provider {
       absl::string_view identity_cert_name,
       RefCountedPtr<grpc_tls_certificate_distributor>
           identity_cert_distributor);
+  void UpdateSubjectAlternativeNameMatchers(
+      std::vector<XdsApi::StringMatcher> matchers);
 
   grpc_core::RefCountedPtr<grpc_tls_certificate_distributor> distributor()
       const override {
     return distributor_;
   }
 
+  bool ProvidesRootCerts() {
+    MutexLock lock(&mu_);
+    return root_cert_distributor_ != nullptr;
+  }
+
+  bool ProvidesIdentityCerts() {
+    MutexLock lock(&mu_);
+    return identity_cert_distributor_ != nullptr;
+  }
+
+  std::vector<XdsApi::StringMatcher> subject_alternative_name_matchers() {
+    MutexLock lock(&san_matchers_mu_);
+    return san_matchers_;
+  }
+
+  grpc_arg MakeChannelArg() const;
+
+  static RefCountedPtr<XdsCertificateProvider> GetFromChannelArgs(
+      const grpc_channel_args* args);
+
  private:
   void WatchStatusCallback(std::string cert_name, bool root_being_watched,
                            bool identity_being_watched);
@@ -56,12 +84,22 @@ class XdsCertificateProvider : public grpc_tls_certificate_provider {
       grpc_tls_certificate_distributor* identity_cert_distributor);
 
   Mutex mu_;
+  // Use a separate mutex for san_matchers_ to avoid deadlocks since
+  // san_matchers_ needs to be accessed when a handshake is being done and we
+  // run into a possible deadlock scenario if using the same mutex. The mutex
+  // deadlock cycle is formed as -
+  // WatchStatusCallback() -> SetKeyMaterials() ->
+  // TlsChannelSecurityConnector::TlsChannelCertificateWatcher::OnCertificatesChanged()
+  // -> HandshakeManager::Add() -> SecurityHandshaker::DoHandshake() ->
+  // subject_alternative_names_matchers()
+  Mutex san_matchers_mu_;
   bool watching_root_certs_ = false;
   bool watching_identity_certs_ = false;
   std::string root_cert_name_;
   std::string identity_cert_name_;
   RefCountedPtr<grpc_tls_certificate_distributor> root_cert_distributor_;
   RefCountedPtr<grpc_tls_certificate_distributor> identity_cert_distributor_;
+  std::vector<XdsApi::StringMatcher> san_matchers_;
   RefCountedPtr<grpc_tls_certificate_distributor> distributor_;
   grpc_tls_certificate_distributor::TlsCertificatesWatcherInterface*
       root_cert_watcher_ = nullptr;
index 979ebd7..b31bbbd 100644 (file)
@@ -42,7 +42,6 @@
 #include "src/core/lib/channel/channel_args.h"
 #include "src/core/lib/channel/channel_stack.h"
 #include "src/core/lib/gpr/string.h"
-#include "src/core/lib/gprpp/map.h"
 #include "src/core/lib/gprpp/memory.h"
 #include "src/core/lib/gprpp/orphanable.h"
 #include "src/core/lib/gprpp/ref_counted_ptr.h"
@@ -66,6 +65,7 @@
 namespace grpc_core {
 
 TraceFlag grpc_xds_client_trace(false, "xds_client");
+TraceFlag grpc_xds_client_refcount_trace(false, "xds_client_refcount");
 
 namespace {
 
@@ -460,8 +460,9 @@ grpc_channel* CreateXdsChannel(const XdsBootstrap::XdsServer& server) {
 XdsClient::ChannelState::ChannelState(WeakRefCountedPtr<XdsClient> xds_client,
                                       const XdsBootstrap::XdsServer& server)
     : InternallyRefCounted<ChannelState>(
-          GRPC_TRACE_FLAG_ENABLED(grpc_xds_client_trace) ? "ChannelState"
-                                                         : nullptr),
+          GRPC_TRACE_FLAG_ENABLED(grpc_xds_client_refcount_trace)
+              ? "ChannelState"
+              : nullptr),
       xds_client_(std::move(xds_client)),
       server_(server) {
   if (GRPC_TRACE_FLAG_ENABLED(grpc_xds_client_trace)) {
@@ -668,8 +669,9 @@ void XdsClient::ChannelState::RetryableCall<T>::OnRetryTimerLocked(
 XdsClient::ChannelState::AdsCallState::AdsCallState(
     RefCountedPtr<RetryableCall<AdsCallState>> parent)
     : InternallyRefCounted<AdsCallState>(
-          GRPC_TRACE_FLAG_ENABLED(grpc_xds_client_trace) ? "AdsCallState"
-                                                         : nullptr),
+          GRPC_TRACE_FLAG_ENABLED(grpc_xds_client_refcount_trace)
+              ? "AdsCallState"
+              : nullptr),
       parent_(std::move(parent)) {
   // Init the ADS call. Note that the call will progress every time there's
   // activity in xds_client()->interested_parties_, which is comprised of
@@ -707,8 +709,8 @@ XdsClient::ChannelState::AdsCallState::AdsCallState(
               GRPC_INITIAL_METADATA_WAIT_FOR_READY_EXPLICITLY_SET;
   op->reserved = nullptr;
   op++;
-  call_error = grpc_call_start_batch_and_execute(call_, ops, (size_t)(op - ops),
-                                                 nullptr);
+  call_error = grpc_call_start_batch_and_execute(
+      call_, ops, static_cast<size_t>(op - ops), nullptr);
   GPR_ASSERT(GRPC_CALL_OK == call_error);
   // Op: send request message.
   GRPC_CLOSURE_INIT(&on_request_sent_, OnRequestSent, this,
@@ -742,8 +744,8 @@ XdsClient::ChannelState::AdsCallState::AdsCallState(
   Ref(DEBUG_LOCATION, "ADS+OnResponseReceivedLocked").release();
   GRPC_CLOSURE_INIT(&on_response_received_, OnResponseReceived, this,
                     grpc_schedule_on_exec_ctx);
-  call_error = grpc_call_start_batch_and_execute(call_, ops, (size_t)(op - ops),
-                                                 &on_response_received_);
+  call_error = grpc_call_start_batch_and_execute(
+      call_, ops, static_cast<size_t>(op - ops), &on_response_received_);
   GPR_ASSERT(GRPC_CALL_OK == call_error);
   // Op: recv server status.
   op = ops;
@@ -759,8 +761,8 @@ XdsClient::ChannelState::AdsCallState::AdsCallState(
   // unreffed.
   GRPC_CLOSURE_INIT(&on_status_received_, OnStatusReceived, this,
                     grpc_schedule_on_exec_ctx);
-  call_error = grpc_call_start_batch_and_execute(call_, ops, (size_t)(op - ops),
-                                                 &on_status_received_);
+  call_error = grpc_call_start_batch_and_execute(
+      call_, ops, static_cast<size_t>(op - ops), &on_status_received_);
   GPR_ASSERT(GRPC_CALL_OK == call_error);
 }
 
@@ -1005,13 +1007,8 @@ void XdsClient::ChannelState::AdsCallState::AcceptCdsUpdate(
     auto& state = cds_state.subscribed_resources[cluster_name];
     if (state != nullptr) state->Finish();
     if (GRPC_TRACE_FLAG_ENABLED(grpc_xds_client_trace)) {
-      gpr_log(GPR_INFO,
-              "[xds_client %p] cluster=%s: eds_service_name=%s, "
-              "lrs_load_reporting_server_name=%s",
-              xds_client(), cluster_name, cds_update.eds_service_name.c_str(),
-              cds_update.lrs_load_reporting_server_name.has_value()
-                  ? cds_update.lrs_load_reporting_server_name.value().c_str()
-                  : "(N/A)");
+      gpr_log(GPR_INFO, "[xds_client %p] cluster=%s: %s", xds_client(),
+              cluster_name, cds_update.ToString().c_str());
     }
     // Record the EDS resource names seen.
     eds_resource_names_seen.insert(cds_update.eds_service_name.empty()
@@ -1425,8 +1422,9 @@ bool XdsClient::ChannelState::LrsCallState::Reporter::OnReportDoneLocked(
 XdsClient::ChannelState::LrsCallState::LrsCallState(
     RefCountedPtr<RetryableCall<LrsCallState>> parent)
     : InternallyRefCounted<LrsCallState>(
-          GRPC_TRACE_FLAG_ENABLED(grpc_xds_client_trace) ? "LrsCallState"
-                                                         : nullptr),
+          GRPC_TRACE_FLAG_ENABLED(grpc_xds_client_refcount_trace)
+              ? "LrsCallState"
+              : nullptr),
       parent_(std::move(parent)) {
   // Init the LRS call. Note that the call will progress every time there's
   // activity in xds_client()->interested_parties_, which is comprised of
@@ -1479,8 +1477,8 @@ XdsClient::ChannelState::LrsCallState::LrsCallState(
   Ref(DEBUG_LOCATION, "LRS+OnInitialRequestSentLocked").release();
   GRPC_CLOSURE_INIT(&on_initial_request_sent_, OnInitialRequestSent, this,
                     grpc_schedule_on_exec_ctx);
-  call_error = grpc_call_start_batch_and_execute(call_, ops, (size_t)(op - ops),
-                                                 &on_initial_request_sent_);
+  call_error = grpc_call_start_batch_and_execute(
+      call_, ops, static_cast<size_t>(op - ops), &on_initial_request_sent_);
   GPR_ASSERT(GRPC_CALL_OK == call_error);
   // Op: recv initial metadata.
   op = ops;
@@ -1499,8 +1497,8 @@ XdsClient::ChannelState::LrsCallState::LrsCallState(
   Ref(DEBUG_LOCATION, "LRS+OnResponseReceivedLocked").release();
   GRPC_CLOSURE_INIT(&on_response_received_, OnResponseReceived, this,
                     grpc_schedule_on_exec_ctx);
-  call_error = grpc_call_start_batch_and_execute(call_, ops, (size_t)(op - ops),
-                                                 &on_response_received_);
+  call_error = grpc_call_start_batch_and_execute(
+      call_, ops, static_cast<size_t>(op - ops), &on_response_received_);
   GPR_ASSERT(GRPC_CALL_OK == call_error);
   // Op: recv server status.
   op = ops;
@@ -1516,8 +1514,8 @@ XdsClient::ChannelState::LrsCallState::LrsCallState(
   // unreffed.
   GRPC_CLOSURE_INIT(&on_status_received_, OnStatusReceived, this,
                     grpc_schedule_on_exec_ctx);
-  call_error = grpc_call_start_batch_and_execute(call_, ops, (size_t)(op - ops),
-                                                 &on_status_received_);
+  call_error = grpc_call_start_batch_and_execute(
+      call_, ops, static_cast<size_t>(op - ops), &on_status_received_);
   GPR_ASSERT(GRPC_CALL_OK == call_error);
 }
 
@@ -1737,13 +1735,17 @@ grpc_millis GetRequestTimeout() {
 }  // namespace
 
 XdsClient::XdsClient(grpc_error** error)
-    : DualRefCounted<XdsClient>(GRPC_TRACE_FLAG_ENABLED(grpc_xds_client_trace)
-                                    ? "XdsClient"
-                                    : nullptr),
+    : DualRefCounted<XdsClient>(
+          GRPC_TRACE_FLAG_ENABLED(grpc_xds_client_refcount_trace) ? "XdsClient"
+                                                                  : nullptr),
       request_timeout_(GetRequestTimeout()),
       interested_parties_(grpc_pollset_set_create()),
       bootstrap_(
           XdsBootstrap::ReadFromFile(this, &grpc_xds_client_trace, error)),
+      certificate_provider_store_(MakeOrphanable<CertificateProviderStore>(
+          bootstrap_ == nullptr
+              ? CertificateProviderStore::PluginDefinitionMap()
+              : bootstrap_->certificate_providers())),
       api_(this, &grpc_xds_client_trace,
            bootstrap_ == nullptr ? nullptr : bootstrap_->node()) {
   if (GRPC_TRACE_FLAG_ENABLED(grpc_xds_client_trace)) {
index 49ec9dc..f1c6467 100644 (file)
@@ -30,7 +30,6 @@
 #include "src/core/ext/xds/xds_client_stats.h"
 #include "src/core/lib/channel/channelz.h"
 #include "src/core/lib/gprpp/dual_ref_counted.h"
-#include "src/core/lib/gprpp/map.h"
 #include "src/core/lib/gprpp/memory.h"
 #include "src/core/lib/gprpp/orphanable.h"
 #include "src/core/lib/gprpp/ref_counted.h"
@@ -40,6 +39,7 @@
 namespace grpc_core {
 
 extern TraceFlag grpc_xds_client_trace;
+extern TraceFlag grpc_xds_client_refcount_trace;
 
 class XdsClient : public DualRefCounted<XdsClient> {
  public:
@@ -88,6 +88,10 @@ class XdsClient : public DualRefCounted<XdsClient> {
   explicit XdsClient(grpc_error** error);
   ~XdsClient() override;
 
+  CertificateProviderStore& certificate_provider_store() {
+    return *certificate_provider_store_;
+  }
+
   grpc_pollset_set* interested_parties() const { return interested_parties_; }
 
   // TODO(roth): When we add federation, there will be multiple channels
@@ -292,6 +296,7 @@ class XdsClient : public DualRefCounted<XdsClient> {
   const grpc_millis request_timeout_;
   grpc_pollset_set* interested_parties_;
   std::unique_ptr<XdsBootstrap> bootstrap_;
+  OrphanablePtr<CertificateProviderStore> certificate_provider_store_;
   XdsApi api_;
 
   Mutex mu_;
index 72cae4d..de401a7 100644 (file)
@@ -45,7 +45,7 @@ XdsClusterDropStats::XdsClusterDropStats(RefCountedPtr<XdsClient> xds_client,
                                          absl::string_view lrs_server_name,
                                          absl::string_view cluster_name,
                                          absl::string_view eds_service_name)
-    : RefCounted(GRPC_TRACE_FLAG_ENABLED(grpc_xds_client_trace)
+    : RefCounted(GRPC_TRACE_FLAG_ENABLED(grpc_xds_client_refcount_trace)
                      ? "XdsClusterDropStats"
                      : nullptr),
       xds_client_(std::move(xds_client)),
@@ -98,7 +98,7 @@ XdsClusterLocalityStats::XdsClusterLocalityStats(
     RefCountedPtr<XdsClient> xds_client, absl::string_view lrs_server_name,
     absl::string_view cluster_name, absl::string_view eds_service_name,
     RefCountedPtr<XdsLocalityName> name)
-    : RefCounted(GRPC_TRACE_FLAG_ENABLED(grpc_xds_client_trace)
+    : RefCounted(GRPC_TRACE_FLAG_ENABLED(grpc_xds_client_refcount_trace)
                      ? "XdsClusterLocalityStats"
                      : nullptr),
       xds_client_(std::move(xds_client)),
diff --git a/src/core/ext/xds/xds_server_config_fetcher.cc b/src/core/ext/xds/xds_server_config_fetcher.cc
new file mode 100644 (file)
index 0000000..5c5e8ee
--- /dev/null
@@ -0,0 +1,131 @@
+//
+//
+// 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>
+
+#include "src/core/ext/xds/xds_client.h"
+#include "src/core/lib/surface/api_trace.h"
+#include "src/core/lib/surface/server.h"
+
+namespace grpc_core {
+namespace {
+
+class XdsServerConfigFetcher : public grpc_server_config_fetcher {
+ public:
+  explicit XdsServerConfigFetcher(RefCountedPtr<XdsClient> xds_client)
+      : xds_client_(std::move(xds_client)) {
+    GPR_ASSERT(xds_client_ != nullptr);
+  }
+
+  void StartWatch(std::string listening_address,
+                  std::unique_ptr<grpc_server_config_fetcher::WatcherInterface>
+                      watcher) override {
+    grpc_server_config_fetcher::WatcherInterface* watcher_ptr = watcher.get();
+    auto listener_watcher =
+        absl::make_unique<ListenerWatcher>(std::move(watcher));
+    auto* listener_watcher_ptr = listener_watcher.get();
+    // TODO(yashykt): Get the resource name id from bootstrap
+    xds_client_->WatchListenerData(
+        absl::StrCat("grpc/server?xds.resource.listening_address=",
+                     listening_address),
+        std::move(listener_watcher));
+    MutexLock lock(&mu_);
+    auto& watcher_state = watchers_[watcher_ptr];
+    watcher_state.listening_address = listening_address;
+    watcher_state.listener_watcher = listener_watcher_ptr;
+  }
+
+  void CancelWatch(
+      grpc_server_config_fetcher::WatcherInterface* watcher) override {
+    MutexLock lock(&mu_);
+    auto it = watchers_.find(watcher);
+    if (it != watchers_.end()) {
+      // Cancel the watch on the listener before erasing
+      xds_client_->CancelListenerDataWatch(it->second.listening_address,
+                                           it->second.listener_watcher,
+                                           false /* delay_unsubscription */);
+      watchers_.erase(it);
+    }
+  }
+
+  // Return the interested parties from the xds client so that it can be polled.
+  grpc_pollset_set* interested_parties() override {
+    return xds_client_->interested_parties();
+  }
+
+ private:
+  class ListenerWatcher : public XdsClient::ListenerWatcherInterface {
+   public:
+    explicit ListenerWatcher(
+        std::unique_ptr<grpc_server_config_fetcher::WatcherInterface>
+            server_config_watcher)
+        : server_config_watcher_(std::move(server_config_watcher)) {}
+
+    void OnListenerChanged(XdsApi::LdsUpdate listener) override {
+      // TODO(yashykt): Construct channel args according to received update
+      server_config_watcher_->UpdateConfig(nullptr);
+    }
+
+    void OnError(grpc_error* error) override {
+      gpr_log(GPR_ERROR, "ListenerWatcher:%p XdsClient reports error: %s", this,
+              grpc_error_string(error));
+      GRPC_ERROR_UNREF(error);
+      // TODO(yashykt): We might want to bubble this error to the application.
+    }
+
+    void OnResourceDoesNotExist() override {
+      gpr_log(GPR_ERROR,
+              "ListenerWatcher:%p XdsClient reports requested listener does "
+              "not exist",
+              this);
+      // TODO(yashykt): We might want to bubble this error to the application.
+    }
+
+   private:
+    std::unique_ptr<grpc_server_config_fetcher::WatcherInterface>
+        server_config_watcher_;
+  };
+
+  struct WatcherState {
+    std::string listening_address;
+    ListenerWatcher* listener_watcher = nullptr;
+  };
+
+  RefCountedPtr<XdsClient> xds_client_;
+  Mutex mu_;
+  std::map<grpc_server_config_fetcher::WatcherInterface*, WatcherState>
+      watchers_;
+};
+
+}  // namespace
+}  // namespace grpc_core
+
+grpc_server_config_fetcher* grpc_server_config_fetcher_xds_create() {
+  grpc_core::ApplicationCallbackExecCtx callback_exec_ctx;
+  grpc_core::ExecCtx exec_ctx;
+  GRPC_API_TRACE("grpc_server_config_fetcher_xds_create()", 0, ());
+  grpc_error* error = GRPC_ERROR_NONE;
+  grpc_core::RefCountedPtr<grpc_core::XdsClient> xds_client =
+      grpc_core::XdsClient::GetOrCreate(&error);
+  if (error != GRPC_ERROR_NONE) {
+    gpr_log(GPR_ERROR, "Failed to create xds client: %s",
+            grpc_error_string(error));
+    return nullptr;
+  }
+  return new grpc_core::XdsServerConfigFetcher(std::move(xds_client));
+}
index a89bf92..a383e5a 100644 (file)
@@ -178,21 +178,21 @@ static int cmp_key_stable(const void* ap, const void* bp) {
   return c;
 }
 
-grpc_channel_args* grpc_channel_args_normalize(const grpc_channel_args* a) {
+grpc_channel_args* grpc_channel_args_normalize(const grpc_channel_args* src) {
   grpc_arg** args =
-      static_cast<grpc_arg**>(gpr_malloc(sizeof(grpc_arg*) * a->num_args));
-  for (size_t i = 0; i < a->num_args; i++) {
-    args[i] = &a->args[i];
+      static_cast<grpc_arg**>(gpr_malloc(sizeof(grpc_arg*) * src->num_args));
+  for (size_t i = 0; i < src->num_args; i++) {
+    args[i] = &src->args[i];
   }
-  if (a->num_args > 1) {
-    qsort(args, a->num_args, sizeof(grpc_arg*), cmp_key_stable);
+  if (src->num_args > 1) {
+    qsort(args, src->num_args, sizeof(grpc_arg*), cmp_key_stable);
   }
 
   grpc_channel_args* b =
       static_cast<grpc_channel_args*>(gpr_malloc(sizeof(grpc_channel_args)));
-  b->num_args = a->num_args;
+  b->num_args = src->num_args;
   b->args = static_cast<grpc_arg*>(gpr_malloc(sizeof(grpc_arg) * b->num_args));
-  for (size_t i = 0; i < a->num_args; i++) {
+  for (size_t i = 0; i < src->num_args; i++) {
     b->args[i] = copy_arg(args[i]);
   }
 
index c26e301..126abc7 100644 (file)
@@ -41,7 +41,7 @@ class BaseNode;
 // https://github.com/grpc/proposal/blob/master/A14-channelz.md
 class ChannelTrace {
  public:
-  ChannelTrace(size_t max_event_memory);
+  explicit ChannelTrace(size_t max_event_memory);
   ~ChannelTrace();
 
   enum Severity {
index cfd8abf..188203c 100644 (file)
@@ -20,6 +20,8 @@
 
 #include "src/core/lib/channel/channelz.h"
 
+#include "absl/strings/strip.h"
+
 #include <grpc/grpc.h>
 #include <grpc/support/alloc.h>
 #include <grpc/support/log.h>
@@ -114,21 +116,21 @@ void CallCountingHelper::CollectData(CounterData* out) {
   }
 }
 
-void CallCountingHelper::PopulateCallCounts(Json::Object* object) {
+void CallCountingHelper::PopulateCallCounts(Json::Object* json) {
   CounterData data;
   CollectData(&data);
   if (data.calls_started != 0) {
-    (*object)["callsStarted"] = std::to_string(data.calls_started);
+    (*json)["callsStarted"] = std::to_string(data.calls_started);
     gpr_timespec ts = gpr_convert_clock_type(
         gpr_cycle_counter_to_time(data.last_call_started_cycle),
         GPR_CLOCK_REALTIME);
-    (*object)["lastCallStartedTimestamp"] = gpr_format_timespec(ts);
+    (*json)["lastCallStartedTimestamp"] = gpr_format_timespec(ts);
   }
   if (data.calls_succeeded != 0) {
-    (*object)["callsSucceeded"] = std::to_string(data.calls_succeeded);
+    (*json)["callsSucceeded"] = std::to_string(data.calls_succeeded);
   }
   if (data.calls_failed) {
-    (*object)["callsFailed"] = std::to_string(data.calls_failed);
+    (*json)["callsFailed"] = std::to_string(data.calls_failed);
   }
 }
 
@@ -344,14 +346,12 @@ void PopulateSocketAddressJson(Json::Object* json, const char* name,
                                const char* addr_str) {
   if (addr_str == nullptr) return;
   Json::Object data;
-  grpc_uri* uri = grpc_uri_parse(addr_str, true);
-  if ((uri != nullptr) && ((strcmp(uri->scheme, "ipv4") == 0) ||
-                           (strcmp(uri->scheme, "ipv6") == 0))) {
-    const char* host_port = uri->path;
-    if (*host_port == '/') ++host_port;
+  absl::StatusOr<URI> uri = URI::Parse(addr_str);
+  if (uri.ok() && (uri->scheme() == "ipv4" || uri->scheme() == "ipv6")) {
     std::string host;
     std::string port;
-    GPR_ASSERT(SplitHostPort(host_port, &host, &port));
+    GPR_ASSERT(
+        SplitHostPort(absl::StripPrefix(uri->path(), "/"), &host, &port));
     int port_num = -1;
     if (!port.empty()) {
       port_num = atoi(port.data());
@@ -362,16 +362,15 @@ void PopulateSocketAddressJson(Json::Object* json, const char* name,
         {"ip_address", b64_host},
     };
     gpr_free(b64_host);
-  } else if (uri != nullptr && strcmp(uri->scheme, "unix") == 0) {
+  } else if (uri.ok() && uri->scheme() == "unix") {
     data["uds_address"] = Json::Object{
-        {"filename", uri->path},
+        {"filename", uri->path()},
     };
   } else {
     data["other_address"] = Json::Object{
         {"name", addr_str},
     };
   }
-  grpc_uri_destroy(uri);
   (*json)[name] = std::move(data);
 }
 
index f39ad49..3c55873 100644 (file)
@@ -32,7 +32,6 @@
 #include "src/core/lib/gpr/time_precise.h"
 #include "src/core/lib/gprpp/atomic.h"
 #include "src/core/lib/gprpp/manual_constructor.h"
-#include "src/core/lib/gprpp/map.h"
 #include "src/core/lib/gprpp/ref_counted.h"
 #include "src/core/lib/gprpp/ref_counted_ptr.h"
 #include "src/core/lib/gprpp/sync.h"
index 0691126..8fcb7d8 100644 (file)
@@ -28,7 +28,6 @@
 
 #include "src/core/lib/channel/channel_trace.h"
 #include "src/core/lib/channel/channelz.h"
-#include "src/core/lib/gprpp/map.h"
 #include "src/core/lib/gprpp/sync.h"
 
 namespace grpc_core {
index 461a21d..8d1d45e 100644 (file)
@@ -256,7 +256,7 @@ void HandshakeManager::DoHandshake(grpc_endpoint* endpoint,
 void grpc_handshake_manager_add(grpc_handshake_manager* mgr,
                                 grpc_handshaker* handshaker) {
   // This is a transition method to aid the API change for handshakers.
-  using namespace grpc_core;
-  RefCountedPtr<Handshaker> refd_hs(static_cast<Handshaker*>(handshaker));
+  grpc_core::RefCountedPtr<grpc_core::Handshaker> refd_hs(
+      static_cast<grpc_core::Handshaker*>(handshaker));
   mgr->Add(refd_hs);
 }
index 6bbda64..03e1a88 100644 (file)
@@ -55,7 +55,7 @@ grpc_channel_args* grpc_channel_args_set_channel_default_compression_algorithm(
   GPR_ASSERT(algorithm < GRPC_COMPRESS_ALGORITHMS_COUNT);
   grpc_arg tmp;
   tmp.type = GRPC_ARG_INTEGER;
-  tmp.key = (char*)GRPC_COMPRESSION_CHANNEL_DEFAULT_ALGORITHM;
+  tmp.key = const_cast<char*>(GRPC_COMPRESSION_CHANNEL_DEFAULT_ALGORITHM);
   tmp.value.integer = algorithm;
   return grpc_channel_args_copy_and_add(a, &tmp, 1);
 }
@@ -108,7 +108,8 @@ grpc_channel_args* grpc_channel_args_compression_algorithm_set_state(
     /* create a new arg */
     grpc_arg tmp;
     tmp.type = GRPC_ARG_INTEGER;
-    tmp.key = (char*)GRPC_COMPRESSION_CHANNEL_ENABLED_ALGORITHMS_BITSET;
+    tmp.key =
+        const_cast<char*>(GRPC_COMPRESSION_CHANNEL_ENABLED_ALGORITHMS_BITSET);
     /* all enabled by default */
     tmp.value.integer = (1u << GRPC_COMPRESS_ALGORITHMS_COUNT) - 1;
     if (state != 0) {
index 3d82886..8829b09 100644 (file)
@@ -61,10 +61,10 @@ void grpc_stats_diff(const grpc_stats_data* b, const grpc_stats_data* a,
 std::string grpc_stats_data_as_json(const grpc_stats_data* data);
 int grpc_stats_histo_find_bucket_slow(int value, const int* table,
                                       int table_size);
-double grpc_stats_histo_percentile(const grpc_stats_data* data,
+double grpc_stats_histo_percentile(const grpc_stats_data* stats,
                                    grpc_stats_histograms histogram,
                                    double percentile);
-size_t grpc_stats_histo_count(const grpc_stats_data* data,
+size_t grpc_stats_histo_count(const grpc_stats_data* stats,
                               grpc_stats_histograms histogram);
 
 #endif
index 1f3861f..c1356c4 100644 (file)
@@ -397,43 +397,43 @@ typedef enum {
   GRPC_STATS_INC_COUNTER(GRPC_STATS_COUNTER_CQ_EV_QUEUE_TRANSIENT_POP_FAILURES)
 #define GRPC_STATS_INC_CALL_INITIAL_SIZE(value) \
   grpc_stats_inc_call_initial_size((int)(value))
-void grpc_stats_inc_call_initial_size(int x);
+void grpc_stats_inc_call_initial_size(int value);
 #define GRPC_STATS_INC_POLL_EVENTS_RETURNED(value) \
   grpc_stats_inc_poll_events_returned((int)(value))
-void grpc_stats_inc_poll_events_returned(int x);
+void grpc_stats_inc_poll_events_returned(int value);
 #define GRPC_STATS_INC_TCP_WRITE_SIZE(value) \
   grpc_stats_inc_tcp_write_size((int)(value))
-void grpc_stats_inc_tcp_write_size(int x);
+void grpc_stats_inc_tcp_write_size(int value);
 #define GRPC_STATS_INC_TCP_WRITE_IOV_SIZE(value) \
   grpc_stats_inc_tcp_write_iov_size((int)(value))
-void grpc_stats_inc_tcp_write_iov_size(int x);
+void grpc_stats_inc_tcp_write_iov_size(int value);
 #define GRPC_STATS_INC_TCP_READ_SIZE(value) \
   grpc_stats_inc_tcp_read_size((int)(value))
-void grpc_stats_inc_tcp_read_size(int x);
+void grpc_stats_inc_tcp_read_size(int value);
 #define GRPC_STATS_INC_TCP_READ_OFFER(value) \
   grpc_stats_inc_tcp_read_offer((int)(value))
-void grpc_stats_inc_tcp_read_offer(int x);
+void grpc_stats_inc_tcp_read_offer(int value);
 #define GRPC_STATS_INC_TCP_READ_OFFER_IOV_SIZE(value) \
   grpc_stats_inc_tcp_read_offer_iov_size((int)(value))
-void grpc_stats_inc_tcp_read_offer_iov_size(int x);
+void grpc_stats_inc_tcp_read_offer_iov_size(int value);
 #define GRPC_STATS_INC_HTTP2_SEND_MESSAGE_SIZE(value) \
   grpc_stats_inc_http2_send_message_size((int)(value))
-void grpc_stats_inc_http2_send_message_size(int x);
+void grpc_stats_inc_http2_send_message_size(int value);
 #define GRPC_STATS_INC_HTTP2_SEND_INITIAL_METADATA_PER_WRITE(value) \
   grpc_stats_inc_http2_send_initial_metadata_per_write((int)(value))
-void grpc_stats_inc_http2_send_initial_metadata_per_write(int x);
+void grpc_stats_inc_http2_send_initial_metadata_per_write(int value);
 #define GRPC_STATS_INC_HTTP2_SEND_MESSAGE_PER_WRITE(value) \
   grpc_stats_inc_http2_send_message_per_write((int)(value))
-void grpc_stats_inc_http2_send_message_per_write(int x);
+void grpc_stats_inc_http2_send_message_per_write(int value);
 #define GRPC_STATS_INC_HTTP2_SEND_TRAILING_METADATA_PER_WRITE(value) \
   grpc_stats_inc_http2_send_trailing_metadata_per_write((int)(value))
-void grpc_stats_inc_http2_send_trailing_metadata_per_write(int x);
+void grpc_stats_inc_http2_send_trailing_metadata_per_write(int value);
 #define GRPC_STATS_INC_HTTP2_SEND_FLOWCTL_PER_WRITE(value) \
   grpc_stats_inc_http2_send_flowctl_per_write((int)(value))
-void grpc_stats_inc_http2_send_flowctl_per_write(int x);
+void grpc_stats_inc_http2_send_flowctl_per_write(int value);
 #define GRPC_STATS_INC_SERVER_CQS_CHECKED(value) \
   grpc_stats_inc_server_cqs_checked((int)(value))
-void grpc_stats_inc_server_cqs_checked(int x);
+void grpc_stats_inc_server_cqs_checked(int value);
 #else
 #define GRPC_STATS_INC_CLIENT_CALLS_CREATED()
 #define GRPC_STATS_INC_SERVER_CALLS_CREATED()
index 8c7345b..5bfdc8d 100644 (file)
@@ -66,9 +66,10 @@ void* gpr_malloc_aligned(size_t size, size_t alignment) {
   GPR_ASSERT(((alignment - 1) & alignment) == 0);  // Must be power of 2.
   size_t extra = alignment - 1 + sizeof(void*);
   void* p = gpr_malloc(size + extra);
-  void** ret = (void**)(((uintptr_t)p + extra) & ~(alignment - 1));
+  void** ret = reinterpret_cast<void**>(
+      (reinterpret_cast<uintptr_t>(p) + extra) & ~(alignment - 1));
   ret[-1] = p;
-  return (void*)ret;
+  return ret;
 }
 
 void gpr_free_aligned(void* ptr) { gpr_free((static_cast<void**>(ptr))[-1]); }
index 8a229b2..9a5a54f 100644 (file)
 
 GPR_GLOBAL_CONFIG_DEFINE_STRING(grpc_verbosity, "ERROR",
                                 "Default gRPC logging verbosity")
+GPR_GLOBAL_CONFIG_DEFINE_STRING(grpc_stacktrace_minloglevel, "",
+                                "Messages logged at the same or higher level "
+                                "than this will print stacktrace")
+
+static constexpr gpr_atm GPR_LOG_SEVERITY_UNSET = GPR_LOG_SEVERITY_ERROR + 10;
+static constexpr gpr_atm GPR_LOG_SEVERITY_NONE = GPR_LOG_SEVERITY_ERROR + 11;
 
 void gpr_default_log(gpr_log_func_args* args);
-static gpr_atm g_log_func = (gpr_atm)gpr_default_log;
-static gpr_atm g_min_severity_to_print = GPR_LOG_VERBOSITY_UNSET;
+static gpr_atm g_log_func = reinterpret_cast<gpr_atm>(gpr_default_log);
+static gpr_atm g_min_severity_to_print = GPR_LOG_SEVERITY_UNSET;
+static gpr_atm g_min_severity_to_print_stacktrace = GPR_LOG_SEVERITY_UNSET;
 
 const char* gpr_log_severity_string(gpr_log_severity severity) {
   switch (severity) {
@@ -54,6 +61,13 @@ int gpr_should_log(gpr_log_severity severity) {
              : 0;
 }
 
+int gpr_should_log_stacktrace(gpr_log_severity severity) {
+  return static_cast<gpr_atm>(severity) >=
+                 gpr_atm_no_barrier_load(&g_min_severity_to_print_stacktrace)
+             ? 1
+             : 0;
+}
+
 void gpr_log_message(const char* file, int line, gpr_log_severity severity,
                      const char* message) {
   if (gpr_should_log(severity) == 0) {
@@ -66,7 +80,7 @@ void gpr_log_message(const char* file, int line, gpr_log_severity severity,
   lfargs.line = line;
   lfargs.severity = severity;
   lfargs.message = message;
-  ((gpr_log_func)gpr_atm_no_barrier_load(&g_log_func))(&lfargs);
+  reinterpret_cast<gpr_log_func>(gpr_atm_no_barrier_load(&g_log_func))(&lfargs);
 }
 
 void gpr_set_log_verbosity(gpr_log_severity min_severity_to_print) {
@@ -74,23 +88,46 @@ void gpr_set_log_verbosity(gpr_log_severity min_severity_to_print) {
                            (gpr_atm)min_severity_to_print);
 }
 
-void gpr_log_verbosity_init() {
-  grpc_core::UniquePtr<char> verbosity = GPR_GLOBAL_CONFIG_GET(grpc_verbosity);
-
-  gpr_atm min_severity_to_print = GPR_LOG_SEVERITY_ERROR;
-  if (strlen(verbosity.get()) > 0) {
-    if (gpr_stricmp(verbosity.get(), "DEBUG") == 0) {
-      min_severity_to_print = static_cast<gpr_atm>(GPR_LOG_SEVERITY_DEBUG);
-    } else if (gpr_stricmp(verbosity.get(), "INFO") == 0) {
-      min_severity_to_print = static_cast<gpr_atm>(GPR_LOG_SEVERITY_INFO);
-    } else if (gpr_stricmp(verbosity.get(), "ERROR") == 0) {
-      min_severity_to_print = static_cast<gpr_atm>(GPR_LOG_SEVERITY_ERROR);
-    }
+static gpr_atm parse_log_severity(const char* str, gpr_atm error_value) {
+  if (gpr_stricmp(str, "DEBUG") == 0) {
+    return GPR_LOG_SEVERITY_DEBUG;
+  } else if (gpr_stricmp(str, "INFO") == 0) {
+    return GPR_LOG_SEVERITY_INFO;
+  } else if (gpr_stricmp(str, "ERROR") == 0) {
+    return GPR_LOG_SEVERITY_ERROR;
+  } else if (gpr_stricmp(str, "NONE") == 0) {
+    return GPR_LOG_SEVERITY_NONE;
+  } else {
+    return error_value;
   }
+}
+
+void gpr_log_verbosity_init() {
+  // init verbosity when it hasn't been set
   if ((gpr_atm_no_barrier_load(&g_min_severity_to_print)) ==
-      GPR_LOG_VERBOSITY_UNSET) {
+      GPR_LOG_SEVERITY_UNSET) {
+    grpc_core::UniquePtr<char> verbosity =
+        GPR_GLOBAL_CONFIG_GET(grpc_verbosity);
+    gpr_atm min_severity_to_print = GPR_LOG_SEVERITY_ERROR;
+    if (strlen(verbosity.get()) > 0) {
+      min_severity_to_print =
+          parse_log_severity(verbosity.get(), min_severity_to_print);
+    }
     gpr_atm_no_barrier_store(&g_min_severity_to_print, min_severity_to_print);
   }
+  // init stacktrace_minloglevel when it hasn't been set
+  if ((gpr_atm_no_barrier_load(&g_min_severity_to_print_stacktrace)) ==
+      GPR_LOG_SEVERITY_UNSET) {
+    grpc_core::UniquePtr<char> stacktrace_minloglevel =
+        GPR_GLOBAL_CONFIG_GET(grpc_stacktrace_minloglevel);
+    gpr_atm min_severity_to_print_stacktrace = GPR_LOG_SEVERITY_NONE;
+    if (strlen(stacktrace_minloglevel.get()) > 0) {
+      min_severity_to_print_stacktrace = parse_log_severity(
+          stacktrace_minloglevel.get(), min_severity_to_print_stacktrace);
+    }
+    gpr_atm_no_barrier_store(&g_min_severity_to_print_stacktrace,
+                             min_severity_to_print_stacktrace);
+  }
 }
 
 void gpr_set_log_function(gpr_log_func f) {
index 3d1f4dd..6f64faa 100644 (file)
@@ -44,6 +44,8 @@
 #include "absl/strings/str_format.h"
 #include "src/core/lib/gprpp/examine_stack.h"
 
+int gpr_should_log_stacktrace(gpr_log_severity severity);
+
 static long sys_gettid(void) { return syscall(__NR_gettid); }
 
 void gpr_log(const char* file, int line, gpr_log_severity severity,
@@ -95,7 +97,7 @@ void gpr_default_log(gpr_log_func_args* args) {
       time_buffer, now.tv_nsec, tid, display_file, args->line);
 
   absl::optional<std::string> stack_trace =
-      args->severity >= GPR_LOG_SEVERITY_ERROR
+      gpr_should_log_stacktrace(args->severity)
           ? grpc_core::GetCurrentStackTrace()
           : absl::nullopt;
   if (stack_trace) {
index de293ce..4bd6117 100644 (file)
@@ -34,6 +34,8 @@
 #include "absl/strings/str_format.h"
 #include "src/core/lib/gprpp/examine_stack.h"
 
+int gpr_should_log_stacktrace(gpr_log_severity severity);
+
 static intptr_t sys_gettid(void) { return (intptr_t)pthread_self(); }
 
 void gpr_log(const char* file, int line, gpr_log_severity severity,
@@ -91,7 +93,7 @@ void gpr_default_log(gpr_log_func_args* args) {
       time_buffer, (int)(now.tv_nsec), sys_gettid(), display_file, args->line);
 
   absl::optional<std::string> stack_trace =
-      args->severity >= GPR_LOG_SEVERITY_ERROR
+      gpr_should_log_stacktrace(args->severity)
           ? grpc_core::GetCurrentStackTrace()
           : absl::nullopt;
   if (stack_trace) {
index bed202f..472121b 100644 (file)
@@ -33,6 +33,8 @@
 #include "src/core/lib/gpr/string_windows.h"
 #include "src/core/lib/gprpp/examine_stack.h"
 
+int gpr_should_log_stacktrace(gpr_log_severity severity);
+
 void gpr_log(const char* file, int line, gpr_log_severity severity,
              const char* format, ...) {
   /* Avoid message construction if gpr_log_message won't log */
@@ -94,7 +96,7 @@ void gpr_default_log(gpr_log_func_args* args) {
   }
 
   absl::optional<std::string> stack_trace =
-      args->severity >= GPR_LOG_SEVERITY_ERROR
+      gpr_should_log_stacktrace(args->severity)
           ? grpc_core::GetCurrentStackTrace()
           : absl::nullopt;
   if (stack_trace) {
index a9c0e62..4a19f45 100644 (file)
@@ -23,8 +23,9 @@
 
 #include <grpc/support/atm.h>
 
-/* Simple spinlock. No backoff strategy, gpr_spinlock_lock is almost always
-   a concurrency code smell. */
+// Simple spinlock. No backoff strategy, gpr_spinlock_lock is almost always
+// a concurrency code smell. Code must _never_ block while holding a spinlock
+// as this could lead to a deadlock under a cooperative multithreading model.
 struct gpr_spinlock {
   gpr_atm atm;
 };
@@ -38,6 +39,13 @@ struct gpr_spinlock {
 
 #define gpr_spinlock_trylock(lock) (gpr_atm_acq_cas(&(lock)->atm, 0, 1))
 #define gpr_spinlock_unlock(lock) (gpr_atm_rel_store(&(lock)->atm, 0))
+// Although the following code spins without any library or system calls, it
+// still functions under cooperative multithreading. The principle is that
+// the lock holder can't block, so it will be scheduled onto its system thread
+// for the entire critical section. By the time another thread attempts a lock,
+// it will either get it immediately or will be scheduled onto another system
+// thread that is different from the current lockholder. There is no chance of
+// waiting for a lockholder scheduled to the same system thread.
 #define gpr_spinlock_lock(lock) \
   do {                          \
   } while (!gpr_spinlock_trylock((lock)))
index 61b0419..cbafdfc 100644 (file)
@@ -55,7 +55,7 @@ char* gpr_strdup(const char* src) {
 std::string gpr_format_timespec(gpr_timespec tm) {
   char time_buffer[35];
   char ns_buffer[11];  // '.' + 9 digits of precision
-  struct tm* tm_info = localtime((const time_t*)&tm.tv_sec);
+  struct tm* tm_info = localtime(reinterpret_cast<time_t*>(&tm.tv_sec));
   strftime(time_buffer, sizeof(time_buffer), "%Y-%m-%dT%H:%M:%S", tm_info);
   snprintf(ns_buffer, 11, ".%09d", tm.tv_nsec);
   // This loop trims off trailing zeros by inserting a null character that the
@@ -119,7 +119,8 @@ static void asciidump(dump_out* out, const char* buf, size_t len) {
     dump_out_append(out, '\'');
   }
   for (cur = beg; cur != end; ++cur) {
-    dump_out_append(out, (isprint(*cur) ? *(char*)cur : '.'));
+    dump_out_append(
+        out, (isprint(*cur) ? *reinterpret_cast<const char*>(cur) : '.'));
   }
   if (!out_was_empty) {
     dump_out_append(out, '\'');
@@ -172,45 +173,45 @@ void gpr_reverse_bytes(char* str, int len) {
   }
 }
 
-int gpr_ltoa(long value, char* string) {
+int gpr_ltoa(long value, char* output) {
   long sign;
   int i = 0;
 
   if (value == 0) {
-    string[0] = '0';
-    string[1] = 0;
+    output[0] = '0';
+    output[1] = 0;
     return 1;
   }
 
   sign = value < 0 ? -1 : 1;
   while (value) {
-    string[i++] = static_cast<char>('0' + sign * (value % 10));
+    output[i++] = static_cast<char>('0' + sign * (value % 10));
     value /= 10;
   }
-  if (sign < 0) string[i++] = '-';
-  gpr_reverse_bytes(string, i);
-  string[i] = 0;
+  if (sign < 0) output[i++] = '-';
+  gpr_reverse_bytes(output, i);
+  output[i] = 0;
   return i;
 }
 
-int int64_ttoa(int64_t value, char* string) {
+int int64_ttoa(int64_t value, char* output) {
   int64_t sign;
   int i = 0;
 
   if (value == 0) {
-    string[0] = '0';
-    string[1] = 0;
+    output[0] = '0';
+    output[1] = 0;
     return 1;
   }
 
   sign = value < 0 ? -1 : 1;
   while (value) {
-    string[i++] = static_cast<char>('0' + sign * (value % 10));
+    output[i++] = static_cast<char>('0' + sign * (value % 10));
     value /= 10;
   }
-  if (sign < 0) string[i++] = '-';
-  gpr_reverse_bytes(string, i);
-  string[i] = 0;
+  if (sign < 0) output[i++] = '-';
+  gpr_reverse_bytes(output, i);
+  output[i] = 0;
   return i;
 }
 
@@ -311,7 +312,7 @@ void gpr_string_split(const char* input, const char* sep, char*** strs,
 
 void* gpr_memrchr(const void* s, int c, size_t n) {
   if (s == nullptr) return nullptr;
-  char* b = (char*)s;
+  char* b = const_cast<char*>(reinterpret_cast<const char*>(s));
   size_t i;
   for (i = 0; i < n; i++) {
     if (b[n - i - 1] == c) {
@@ -321,19 +322,19 @@ void* gpr_memrchr(const void* s, int c, size_t n) {
   return nullptr;
 }
 
-bool gpr_parse_bool_value(const char* s, bool* dst) {
+bool gpr_parse_bool_value(const char* value, bool* dst) {
   const char* kTrue[] = {"1", "t", "true", "y", "yes"};
   const char* kFalse[] = {"0", "f", "false", "n", "no"};
   static_assert(sizeof(kTrue) == sizeof(kFalse), "true_false_equal");
 
-  if (s == nullptr) {
+  if (value == nullptr) {
     return false;
   }
   for (size_t i = 0; i < GPR_ARRAY_SIZE(kTrue); ++i) {
-    if (gpr_stricmp(s, kTrue[i]) == 0) {
+    if (gpr_stricmp(value, kTrue[i]) == 0) {
       *dst = true;
       return true;
-    } else if (gpr_stricmp(s, kFalse[i]) == 0) {
+    } else if (gpr_stricmp(value, kFalse[i]) == 0) {
       *dst = false;
       return true;
     }
index 801f66c..8695331 100644 (file)
@@ -45,8 +45,7 @@ char* gpr_dump_return_len(const char* buf, size_t len, uint32_t flags,
 
 /* Parses an array of bytes into an integer (base 10). Returns 1 on success,
    0 on failure. */
-int gpr_parse_bytes_to_uint32(const char* data, size_t length,
-                              uint32_t* result);
+int gpr_parse_bytes_to_uint32(const char* buf, size_t len, uint32_t* result);
 
 /* Minimum buffer size for calling ltoa */
 #define GPR_LTOA_MIN_BUFSIZE (3 * sizeof(long))
@@ -77,15 +76,15 @@ void gpr_reverse_bytes(char* str, int len);
 char* gpr_leftpad(const char* str, char flag, size_t length);
 
 /* Join a set of strings, returning the resulting string.
-   Total combined length (excluding null terminator) is returned in total_length
+   Total combined length (excluding null terminator) is returned in final_length
    if it is non-null. */
-char* gpr_strjoin(const char** strs, size_t nstrs, size_t* total_length);
+char* gpr_strjoin(const char** strs, size_t nstrs, size_t* final_length);
 
 /* Join a set of strings using a separator, returning the resulting string.
-   Total combined length (excluding null terminator) is returned in total_length
+   Total combined length (excluding null terminator) is returned in final_length
    if it is non-null. */
 char* gpr_strjoin_sep(const char** strs, size_t nstrs, const char* sep,
-                      size_t* total_length);
+                      size_t* final_length);
 
 void gpr_string_split(const char* input, const char* sep, char*** strs,
                       size_t* nstrs);
index 2f18fc5..36c35da 100644 (file)
@@ -48,7 +48,7 @@ static void event_initialize(void) {
 
 /* Hash ev into an element of sync_array[]. */
 static struct sync_array_s* hash(gpr_event* ev) {
-  return &sync_array[((uintptr_t)ev) % event_sync_partitions];
+  return &sync_array[reinterpret_cast<uintptr_t>(ev) % event_sync_partitions];
 }
 
 void gpr_event_init(gpr_event* ev) {
@@ -67,16 +67,16 @@ void gpr_event_set(gpr_event* ev, void* value) {
 }
 
 void* gpr_event_get(gpr_event* ev) {
-  return (void*)gpr_atm_acq_load(&ev->state);
+  return reinterpret_cast<void*>(gpr_atm_acq_load(&ev->state));
 }
 
 void* gpr_event_wait(gpr_event* ev, gpr_timespec abs_deadline) {
-  void* result = (void*)gpr_atm_acq_load(&ev->state);
+  void* result = reinterpret_cast<void*>(gpr_atm_acq_load(&ev->state));
   if (result == nullptr) {
     struct sync_array_s* s = hash(ev);
     gpr_mu_lock(&s->mu);
     do {
-      result = (void*)gpr_atm_acq_load(&ev->state);
+      result = reinterpret_cast<void*>(gpr_atm_acq_load(&ev->state));
     } while (result == nullptr && !gpr_cv_wait(&s->cv, &s->mu, abs_deadline));
     gpr_mu_unlock(&s->mu);
   }
index db5a7f6..14df70d 100644 (file)
@@ -107,28 +107,28 @@ static gpr_timespec to_seconds_from_above_second_time(int64_t time_in_units,
   return out;
 }
 
-gpr_timespec gpr_time_from_nanos(int64_t ns, gpr_clock_type type) {
-  return to_seconds_from_sub_second_time(ns, GPR_NS_PER_SEC, type);
+gpr_timespec gpr_time_from_nanos(int64_t ns, gpr_clock_type clock_type) {
+  return to_seconds_from_sub_second_time(ns, GPR_NS_PER_SEC, clock_type);
 }
 
-gpr_timespec gpr_time_from_micros(int64_t us, gpr_clock_type type) {
-  return to_seconds_from_sub_second_time(us, GPR_US_PER_SEC, type);
+gpr_timespec gpr_time_from_micros(int64_t us, gpr_clock_type clock_type) {
+  return to_seconds_from_sub_second_time(us, GPR_US_PER_SEC, clock_type);
 }
 
-gpr_timespec gpr_time_from_millis(int64_t ms, gpr_clock_type type) {
-  return to_seconds_from_sub_second_time(ms, GPR_MS_PER_SEC, type);
+gpr_timespec gpr_time_from_millis(int64_t ms, gpr_clock_type clock_type) {
+  return to_seconds_from_sub_second_time(ms, GPR_MS_PER_SEC, clock_type);
 }
 
-gpr_timespec gpr_time_from_seconds(int64_t s, gpr_clock_type type) {
-  return to_seconds_from_sub_second_time(s, 1, type);
+gpr_timespec gpr_time_from_seconds(int64_t s, gpr_clock_type clock_type) {
+  return to_seconds_from_sub_second_time(s, 1, clock_type);
 }
 
-gpr_timespec gpr_time_from_minutes(int64_t m, gpr_clock_type type) {
-  return to_seconds_from_above_second_time(m, 60, type);
+gpr_timespec gpr_time_from_minutes(int64_t m, gpr_clock_type clock_type) {
+  return to_seconds_from_above_second_time(m, 60, clock_type);
 }
 
-gpr_timespec gpr_time_from_hours(int64_t h, gpr_clock_type type) {
-  return to_seconds_from_above_second_time(h, 3600, type);
+gpr_timespec gpr_time_from_hours(int64_t h, gpr_clock_type clock_type) {
+  return to_seconds_from_above_second_time(h, 3600, clock_type);
 }
 
 gpr_timespec gpr_time_add(gpr_timespec a, gpr_timespec b) {
index 67c91d9..baca5a7 100644 (file)
@@ -96,7 +96,8 @@ class Arena {
   //   where we wish to create an arena and then perform an immediate
   //   allocation.
   explicit Arena(size_t initial_size, size_t initial_alloc = 0)
-      : total_used_(initial_alloc), initial_zone_size_(initial_size) {}
+      : total_used_(GPR_ROUND_UP_TO_ALIGNMENT_SIZE(initial_alloc)),
+        initial_zone_size_(initial_size) {}
 
   ~Arena();
 
@@ -105,7 +106,7 @@ class Arena {
   // Keep track of the total used size. We use this in our call sizing
   // hysteresis.
   Atomic<size_t> total_used_;
-  size_t initial_zone_size_;
+  const size_t initial_zone_size_;
   gpr_spinlock arena_growth_spinlock_ = GPR_SPINLOCK_STATIC_INITIALIZER;
   // If the initial arena allocation wasn't enough, we allocate additional zones
   // in a reverse linked list. Each additional zone consists of (1) a pointer to
diff --git a/src/core/lib/gprpp/map.h b/src/core/lib/gprpp/map.h
deleted file mode 100644 (file)
index 47fcddd..0000000
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- *
- * Copyright 2017 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_CORE_LIB_GPRPP_MAP_H
-#define GRPC_CORE_LIB_GPRPP_MAP_H
-
-#include <grpc/support/port_platform.h>
-
-#include <string.h>
-
-#include <map>
-
-#include "absl/strings/string_view.h"
-
-#include "src/core/lib/gprpp/memory.h"
-
-namespace grpc_core {
-
-struct StringLess {
-  bool operator()(const char* a, const char* b) const {
-    return strcmp(a, b) < 0;
-  }
-  bool operator()(const grpc_core::UniquePtr<char>& a,
-                  const grpc_core::UniquePtr<char>& b) const {
-    return strcmp(a.get(), b.get()) < 0;
-  }
-  bool operator()(const absl::string_view& a,
-                  const absl::string_view& b) const {
-    const size_t min_size = std::min(a.size(), b.size());
-    int c = strncmp(a.data(), b.data(), min_size);
-    if (c != 0) return c < 0;
-    return a.size() < b.size();
-  }
-};
-
-}  // namespace grpc_core
-
-#endif /* GRPC_CORE_LIB_GPRPP_MAP_H */
index bb5e180..64f3f8f 100644 (file)
@@ -221,12 +221,12 @@ class Delete;
 template <typename T>
 class Delete<T, true> {
  public:
-  Delete(T* t) { delete t; }
+  explicit Delete(T* t) { delete t; }
 };
 template <typename T>
 class Delete<T, false> {
  public:
-  Delete(T* t) {}
+  explicit Delete(T* t) {}
 };
 }  // namespace internal
 
index 62fb39f..fd3bfbd 100644 (file)
@@ -35,10 +35,12 @@ template <typename T>
 class RefCountedPtr {
  public:
   RefCountedPtr() {}
+  // NOLINTNEXTLINE(google-explicit-constructor)
   RefCountedPtr(std::nullptr_t) {}
 
   // If value is non-null, we take ownership of a ref to it.
   template <typename Y>
+  // NOLINTNEXTLINE(google-explicit-constructor)
   RefCountedPtr(Y* value) : value_(value) {}
 
   // Move ctors.
@@ -47,6 +49,7 @@ class RefCountedPtr {
     other.value_ = nullptr;
   }
   template <typename Y>
+  // NOLINTNEXTLINE(google-explicit-constructor)
   RefCountedPtr(RefCountedPtr<Y>&& other) noexcept {
     value_ = static_cast<T*>(other.value_);
     other.value_ = nullptr;
@@ -71,6 +74,7 @@ class RefCountedPtr {
     value_ = other.value_;
   }
   template <typename Y>
+  // NOLINTNEXTLINE(google-explicit-constructor)
   RefCountedPtr(const RefCountedPtr<Y>& other) {
     static_assert(std::has_virtual_destructor<T>::value,
                   "T does not have a virtual dtor");
@@ -181,11 +185,13 @@ template <typename T>
 class WeakRefCountedPtr {
  public:
   WeakRefCountedPtr() {}
+  // NOLINTNEXTLINE(google-explicit-constructor)
   WeakRefCountedPtr(std::nullptr_t) {}
 
   // If value is non-null, we take ownership of a ref to it.
   template <typename Y>
-  explicit WeakRefCountedPtr(Y* value) {
+  // NOLINTNEXTLINE(google-explicit-constructor)
+  WeakRefCountedPtr(Y* value) {
     value_ = value;
   }
 
@@ -195,6 +201,7 @@ class WeakRefCountedPtr {
     other.value_ = nullptr;
   }
   template <typename Y>
+  // NOLINTNEXTLINE(google-explicit-constructor)
   WeakRefCountedPtr(WeakRefCountedPtr<Y>&& other) noexcept {
     value_ = static_cast<T*>(other.value_);
     other.value_ = nullptr;
@@ -219,6 +226,7 @@ class WeakRefCountedPtr {
     value_ = other.value_;
   }
   template <typename Y>
+  // NOLINTNEXTLINE(google-explicit-constructor)
   WeakRefCountedPtr(const WeakRefCountedPtr<Y>& other) {
     static_assert(std::has_virtual_destructor<T>::value,
                   "T does not have a virtual dtor");
index b441ae4..c3449bd 100644 (file)
@@ -199,6 +199,11 @@ Thread::Thread(const char* thd_name, void (*thd_body)(void* arg), void* arg,
 }  // namespace grpc_core
 
 // The following is in the external namespace as it is exposed as C89 API
-gpr_thd_id gpr_thd_currentid(void) { return (gpr_thd_id)pthread_self(); }
+gpr_thd_id gpr_thd_currentid(void) {
+  // Use C-style casting because Linux and OSX have different definitions
+  // of pthread_t so that a single C++ cast doesn't handle it.
+  // NOLINTNEXTLINE(google-readability-casting)
+  return (gpr_thd_id)pthread_self();
+}
 
 #endif /* GPR_POSIX_SYNC */
index bd3b7a3..fb90afd 100644 (file)
@@ -171,6 +171,8 @@ Thread::Thread(const char* thd_name, void (*thd_body)(void* arg), void* arg,
 
 }  // namespace grpc_core
 
-gpr_thd_id gpr_thd_currentid(void) { return (gpr_thd_id)g_thd_info; }
+gpr_thd_id gpr_thd_currentid(void) {
+  return reinterpret_cast<gpr_thd_id>(g_thd_info);
+}
 
 #endif /* GPR_WINDOWS */
index bf93552..8d024dd 100644 (file)
@@ -209,7 +209,7 @@ static void next_address(internal_request* req, grpc_error* error) {
   GRPC_CLOSURE_INIT(&req->connected, on_connected, req,
                     grpc_schedule_on_exec_ctx);
   grpc_arg arg = grpc_channel_arg_pointer_create(
-      (char*)GRPC_ARG_RESOURCE_QUOTA, req->resource_quota,
+      const_cast<char*>(GRPC_ARG_RESOURCE_QUOTA), req->resource_quota,
       grpc_resource_quota_arg_vtable());
   grpc_channel_args args = {1, &arg};
   grpc_tcp_client_connect(&req->connected, &req->ep, req->context->pollset_set,
index 16a160c..b61bb06 100644 (file)
@@ -83,8 +83,7 @@ void grpc_httpcli_get(grpc_httpcli_context* context,
                       grpc_polling_entity* pollent,
                       grpc_resource_quota* resource_quota,
                       const grpc_httpcli_request* request, grpc_millis deadline,
-                      grpc_closure* on_complete,
-                      grpc_httpcli_response* response);
+                      grpc_closure* on_done, grpc_httpcli_response* response);
 
 /* Asynchronously perform a HTTP POST.
    'context' specifies the http context under which to do the post
@@ -105,7 +104,7 @@ void grpc_httpcli_post(grpc_httpcli_context* context,
                        grpc_resource_quota* resource_quota,
                        const grpc_httpcli_request* request,
                        const char* body_bytes, size_t body_size,
-                       grpc_millis deadline, grpc_closure* on_complete,
+                       grpc_millis deadline, grpc_closure* on_done,
                        grpc_httpcli_response* response);
 
 /* override functions return 1 if they handled the request, 0 otherwise */
index 966a8fb..15aea33 100644 (file)
@@ -43,7 +43,7 @@
 class grpc_httpcli_ssl_channel_security_connector final
     : public grpc_channel_security_connector {
  public:
-  grpc_httpcli_ssl_channel_security_connector(char* secure_peer_name)
+  explicit grpc_httpcli_ssl_channel_security_connector(char* secure_peer_name)
       : grpc_channel_security_connector(
             /*url_scheme=*/nullptr,
             /*channel_creds=*/nullptr,
index b95a942..3a0b2be 100644 (file)
@@ -281,8 +281,7 @@ static grpc_error* addbyte_body(grpc_http_parser* parser, uint8_t byte) {
 
   if (*body_length == parser->body_capacity) {
     parser->body_capacity = GPR_MAX(8, parser->body_capacity * 3 / 2);
-    *body =
-        static_cast<char*>(gpr_realloc((void*)*body, parser->body_capacity));
+    *body = static_cast<char*>(gpr_realloc(*body, parser->body_capacity));
   }
   (*body)[*body_length] = static_cast<char>(byte);
   (*body_length)++;
index ed0ae17..043b3bb 100644 (file)
@@ -34,13 +34,14 @@ namespace {
 
 grpc_error* DecodeCancelStateError(gpr_atm cancel_state) {
   if (cancel_state & 1) {
-    return (grpc_error*)(cancel_state & ~static_cast<gpr_atm>(1));
+    return reinterpret_cast<grpc_error*>(cancel_state &
+                                         ~static_cast<gpr_atm>(1));
   }
   return GRPC_ERROR_NONE;
 }
 
 gpr_atm EncodeCancelStateError(grpc_error* error) {
-  return static_cast<gpr_atm>(1) | (gpr_atm)error;
+  return static_cast<gpr_atm>(1) | reinterpret_cast<gpr_atm>(error);
 }
 
 }  // namespace
@@ -203,7 +204,8 @@ void CallCombiner::SetNotifyOnCancel(grpc_closure* closure) {
       ExecCtx::Run(DEBUG_LOCATION, closure, GRPC_ERROR_REF(original_error));
       break;
     } else {
-      if (gpr_atm_full_cas(&cancel_state_, original_state, (gpr_atm)closure)) {
+      if (gpr_atm_full_cas(&cancel_state_, original_state,
+                           reinterpret_cast<gpr_atm>(closure))) {
         if (GRPC_TRACE_FLAG_ENABLED(grpc_call_combiner_trace)) {
           gpr_log(GPR_INFO, "call_combiner=%p: setting notify_on_cancel=%p",
                   this, closure);
@@ -212,7 +214,7 @@ void CallCombiner::SetNotifyOnCancel(grpc_closure* closure) {
         // closure with GRPC_ERROR_NONE.  This allows callers to clean
         // up any resources they may be holding for the callback.
         if (original_state != 0) {
-          closure = (grpc_closure*)original_state;
+          closure = reinterpret_cast<grpc_closure*>(original_state);
           if (GRPC_TRACE_FLAG_ENABLED(grpc_call_combiner_trace)) {
             gpr_log(GPR_INFO,
                     "call_combiner=%p: scheduling old cancel callback=%p", this,
@@ -239,7 +241,8 @@ void CallCombiner::Cancel(grpc_error* error) {
     if (gpr_atm_full_cas(&cancel_state_, original_state,
                          EncodeCancelStateError(error))) {
       if (original_state != 0) {
-        grpc_closure* notify_on_cancel = (grpc_closure*)original_state;
+        grpc_closure* notify_on_cancel =
+            reinterpret_cast<grpc_closure*>(original_state);
         if (GRPC_TRACE_FLAG_ENABLED(grpc_call_combiner_trace)) {
           gpr_log(GPR_INFO,
                   "call_combiner=%p: scheduling notify_on_cancel callback=%p",
index 4b85766..aa5a2ea 100644 (file)
@@ -146,7 +146,8 @@ static void combiner_exec(grpc_core::Combiner* lock, grpc_closure* cl,
     // offload for one or two actions, and that's fine
     gpr_atm initiator =
         gpr_atm_no_barrier_load(&lock->initiating_exec_ctx_or_null);
-    if (initiator != 0 && initiator != (gpr_atm)grpc_core::ExecCtx::Get()) {
+    if (initiator != 0 &&
+        initiator != reinterpret_cast<gpr_atm>(grpc_core::ExecCtx::Get())) {
       gpr_atm_no_barrier_store(&lock->initiating_exec_ctx_or_null, 0);
     }
   }
index 009e4ce..b6e6086 100644 (file)
@@ -99,7 +99,7 @@ void grpc_endpoint_add_to_pollset_set(grpc_endpoint* ep,
 void grpc_endpoint_delete_from_pollset_set(grpc_endpoint* ep,
                                            grpc_pollset_set* pollset_set);
 
-grpc_resource_user* grpc_endpoint_get_resource_user(grpc_endpoint* endpoint);
+grpc_resource_user* grpc_endpoint_get_resource_user(grpc_endpoint* ep);
 
 bool grpc_endpoint_can_track_err(grpc_endpoint* ep);
 
index b57c10c..0910145 100644 (file)
@@ -166,7 +166,8 @@ static void error_destroy(grpc_error* err) {
   GPR_ASSERT(!grpc_error_is_special(err));
   unref_errs(err);
   unref_strs(err);
-  gpr_free((void*)gpr_atm_acq_load(&err->atomics.error_string));
+  gpr_free(
+      reinterpret_cast<void*>(gpr_atm_acq_load(&err->atomics.error_string)));
   gpr_free(err);
 }
 
@@ -237,10 +238,10 @@ static void internal_set_str(grpc_error** err, grpc_error_strs which,
   if (slot == UINT8_MAX) {
     slot = get_placement(err, sizeof(value));
     if (slot == UINT8_MAX) {
-      const char* str = grpc_slice_to_c_string(value);
+      char* str = grpc_slice_to_c_string(value);
       gpr_log(GPR_ERROR, "Error %p is full, dropping string {\"%s\":\"%s\"}",
               *err, error_str_name(which), str);
-      gpr_free((void*)str);
+      gpr_free(str);
       return;
     }
   } else {
@@ -258,10 +259,10 @@ static void internal_set_time(grpc_error** err, grpc_error_times which,
   if (slot == UINT8_MAX) {
     slot = get_placement(err, sizeof(value));
     if (slot == UINT8_MAX) {
-      const char* time_str = fmt_time(value);
+      char* time_str = fmt_time(value);
       gpr_log(GPR_ERROR, "Error %p is full, dropping \"%s\":\"%s\"}", *err,
               error_time_name(which), time_str);
-      gpr_free((void*)time_str);
+      gpr_free(time_str);
       return;
     }
   }
@@ -426,7 +427,8 @@ static grpc_error* copy_error_and_unref(grpc_error* in) {
     // bulk memcpy of the rest of the struct.
     // NOLINTNEXTLINE(bugprone-sizeof-expression)
     size_t skip = sizeof(&out->atomics);
-    memcpy((void*)((uintptr_t)out + skip), (void*)((uintptr_t)in + skip),
+    memcpy(reinterpret_cast<void*>(reinterpret_cast<uintptr_t>(out) + skip),
+           reinterpret_cast<void*>(reinterpret_cast<uintptr_t>(in) + skip),
            sizeof(*in) + (in->arena_size * sizeof(intptr_t)) - skip);
     // manually set the atomics and the new capacity
     gpr_atm_no_barrier_store(&out->atomics.error_string, 0);
@@ -632,8 +634,8 @@ static char* fmt_str(const grpc_slice& slice) {
   char* s = nullptr;
   size_t sz = 0;
   size_t cap = 0;
-  append_esc_str((const uint8_t*)GRPC_SLICE_START_PTR(slice),
-                 GRPC_SLICE_LENGTH(slice), &s, &sz, &cap);
+  append_esc_str(GRPC_SLICE_START_PTR(slice), GRPC_SLICE_LENGTH(slice), &s, &sz,
+                 &cap);
   append_chr(0, &s, &sz, &cap);
   return s;
 }
@@ -744,7 +746,8 @@ const char* grpc_error_string(grpc_error* err) {
   if (err == GRPC_ERROR_OOM) return oom_error_string;
   if (err == GRPC_ERROR_CANCELLED) return cancelled_error_string;
 
-  void* p = (void*)gpr_atm_acq_load(&err->atomics.error_string);
+  void* p =
+      reinterpret_cast<void*>(gpr_atm_acq_load(&err->atomics.error_string));
   if (p != nullptr) {
     return static_cast<const char*>(p);
   }
@@ -763,9 +766,10 @@ const char* grpc_error_string(grpc_error* err) {
 
   char* out = finish_kvs(&kvs);
 
-  if (!gpr_atm_rel_cas(&err->atomics.error_string, 0, (gpr_atm)out)) {
+  if (!gpr_atm_rel_cas(&err->atomics.error_string, 0,
+                       reinterpret_cast<gpr_atm>(out))) {
     gpr_free(out);
-    out = (char*)gpr_atm_acq_load(&err->atomics.error_string);
+    out = reinterpret_cast<char*>(gpr_atm_acq_load(&err->atomics.error_string));
   }
 
   return out;
index 7b0cbd6..33c233b 100644 (file)
@@ -22,7 +22,7 @@
 #include <grpc/support/port_platform.h>
 
 #include <inttypes.h>
-#include <stdbool.h>  // TODO, do we need this?
+#include <stdbool.h>  // TODO(unknown): , do we need this?
 
 #include <grpc/support/sync.h>
 #include "src/core/lib/iomgr/error.h"
index 5114d1c..8a1013d 100644 (file)
@@ -618,7 +618,7 @@ static grpc_error* pollset_kick_all(grpc_pollset* pollset) {
       worker = worker->next;
     } while (worker != pollset->root_worker);
   }
-  // TODO: sreek.  Check if we need to set 'kicked_without_poller' to true here
+  // TODO(sreek): Check if we need to set 'kicked_without_poller' to true here
   // in the else case
   return error;
 }
@@ -803,7 +803,8 @@ static bool begin_worker(grpc_pollset* pollset, grpc_pollset_worker* worker,
           neighborhood->active_root = pollset->next = pollset->prev = pollset;
           /* Make this the designated poller if there isn't one already */
           if (worker->state == UNKICKED &&
-              gpr_atm_no_barrier_cas(&g_active_poller, 0, (gpr_atm)worker)) {
+              gpr_atm_no_barrier_cas(&g_active_poller, 0,
+                                     reinterpret_cast<gpr_atm>(worker))) {
             SET_KICK_STATE(worker, DESIGNATED_POLLER);
           }
         } else {
@@ -885,8 +886,9 @@ static bool check_neighborhood_for_available_poller(
       do {
         switch (inspect_worker->state) {
           case UNKICKED:
-            if (gpr_atm_no_barrier_cas(&g_active_poller, 0,
-                                       (gpr_atm)inspect_worker)) {
+            if (gpr_atm_no_barrier_cas(
+                    &g_active_poller, 0,
+                    reinterpret_cast<gpr_atm>(inspect_worker))) {
               if (GRPC_TRACE_FLAG_ENABLED(grpc_polling_trace)) {
                 gpr_log(GPR_INFO, " .. choose next poller to be %p",
                         inspect_worker);
@@ -944,7 +946,8 @@ static void end_worker(grpc_pollset* pollset, grpc_pollset_worker* worker,
   SET_KICK_STATE(worker, KICKED);
   grpc_closure_list_move(&worker->schedule_on_end_work,
                          grpc_core::ExecCtx::Get()->closure_list());
-  if (gpr_atm_no_barrier_load(&g_active_poller) == (gpr_atm)worker) {
+  if (gpr_atm_no_barrier_load(&g_active_poller) ==
+      reinterpret_cast<gpr_atm>(worker)) {
     if (worker->next != worker && worker->next->state == UNKICKED) {
       if (GRPC_TRACE_FLAG_ENABLED(grpc_polling_trace)) {
         gpr_log(GPR_INFO, " .. choose next poller to be peer %p", worker);
@@ -1071,8 +1074,9 @@ static grpc_error* pollset_kick(grpc_pollset* pollset,
     std::vector<std::string> log;
     log.push_back(absl::StrFormat(
         "PS:%p KICK:%p curps=%p curworker=%p root=%p", pollset, specific_worker,
-        (void*)gpr_tls_get(&g_current_thread_pollset),
-        (void*)gpr_tls_get(&g_current_thread_worker), pollset->root_worker));
+        reinterpret_cast<void*>(gpr_tls_get(&g_current_thread_pollset)),
+        reinterpret_cast<void*>(gpr_tls_get(&g_current_thread_worker)),
+        pollset->root_worker));
     if (pollset->root_worker != nullptr) {
       log.push_back(absl::StrFormat(
           " {kick_state=%s next=%p {kick_state=%s}}",
@@ -1088,7 +1092,8 @@ static grpc_error* pollset_kick(grpc_pollset* pollset,
   }
 
   if (specific_worker == nullptr) {
-    if (gpr_tls_get(&g_current_thread_pollset) != (intptr_t)pollset) {
+    if (gpr_tls_get(&g_current_thread_pollset) !=
+        reinterpret_cast<intptr_t>(pollset)) {
       grpc_pollset_worker* root_worker = pollset->root_worker;
       if (root_worker == nullptr) {
         GRPC_STATS_INC_POLLSET_KICKED_WITHOUT_POLLER();
@@ -1115,8 +1120,9 @@ static grpc_error* pollset_kick(grpc_pollset* pollset,
         goto done;
       } else if (root_worker == next_worker &&  // only try and wake up a poller
                                                 // if there is no next worker
-                 root_worker == (grpc_pollset_worker*)gpr_atm_no_barrier_load(
-                                    &g_active_poller)) {
+                 root_worker ==
+                     reinterpret_cast<grpc_pollset_worker*>(
+                         gpr_atm_no_barrier_load(&g_active_poller))) {
         GRPC_STATS_INC_POLLSET_KICK_WAKEUP_FD();
         if (GRPC_TRACE_FLAG_ENABLED(grpc_polling_trace)) {
           gpr_log(GPR_INFO, " .. kicked %p", root_worker);
@@ -1180,7 +1186,7 @@ static grpc_error* pollset_kick(grpc_pollset* pollset,
     }
     goto done;
   } else if (gpr_tls_get(&g_current_thread_worker) ==
-             (intptr_t)specific_worker) {
+             reinterpret_cast<intptr_t>(specific_worker)) {
     GRPC_STATS_INC_POLLSET_KICK_OWN_THREAD();
     if (GRPC_TRACE_FLAG_ENABLED(grpc_polling_trace)) {
       gpr_log(GPR_INFO, " .. mark %p kicked", specific_worker);
@@ -1188,7 +1194,8 @@ static grpc_error* pollset_kick(grpc_pollset* pollset,
     SET_KICK_STATE(specific_worker, KICKED);
     goto done;
   } else if (specific_worker ==
-             (grpc_pollset_worker*)gpr_atm_no_barrier_load(&g_active_poller)) {
+             reinterpret_cast<grpc_pollset_worker*>(
+                 gpr_atm_no_barrier_load(&g_active_poller))) {
     GRPC_STATS_INC_POLLSET_KICK_WAKEUP_FD();
     if (GRPC_TRACE_FLAG_ENABLED(grpc_polling_trace)) {
       gpr_log(GPR_INFO, " .. kick active poller");
@@ -1223,7 +1230,7 @@ static void pollset_add_fd(grpc_pollset* /*pollset*/, grpc_fd* /*fd*/) {}
  */
 
 static grpc_pollset_set* pollset_set_create(void) {
-  return (grpc_pollset_set*)(static_cast<intptr_t>(0xdeafbeef));
+  return reinterpret_cast<grpc_pollset_set*>(static_cast<intptr_t>(0xdeafbeef));
 }
 
 static void pollset_set_destroy(grpc_pollset_set* /*pss*/) {}
index d3392f3..acd095a 100644 (file)
@@ -577,7 +577,8 @@ static grpc_error* pollable_create(pollable_type type, pollable** p) {
   }
   struct epoll_event ev;
   ev.events = static_cast<uint32_t>(EPOLLIN | EPOLLET);
-  ev.data.ptr = (void*)(1 | (intptr_t) & (*p)->wakeup);
+  ev.data.ptr =
+      reinterpret_cast<void*>(1 | reinterpret_cast<intptr_t>(&(*p)->wakeup));
   if (epoll_ctl(epfd, EPOLL_CTL_ADD, (*p)->wakeup.read_fd, &ev) != 0) {
     err = GRPC_OS_ERROR(errno, "epoll_ctl");
     GRPC_FD_TRACE(
@@ -692,7 +693,8 @@ static grpc_error* kick_one_worker(grpc_pollset_worker* specific_worker) {
     GRPC_STATS_INC_POLLSET_KICKED_AGAIN();
     return GRPC_ERROR_NONE;
   }
-  if (gpr_tls_get(&g_current_thread_worker) == (intptr_t)specific_worker) {
+  if (gpr_tls_get(&g_current_thread_worker) ==
+      reinterpret_cast<intptr_t>(specific_worker)) {
     if (GRPC_TRACE_FLAG_ENABLED(grpc_polling_trace)) {
       gpr_log(GPR_INFO, "PS:%p kicked_specific_but_awake", p);
     }
@@ -729,13 +731,14 @@ static grpc_error* pollset_kick(grpc_pollset* pollset,
   GRPC_STATS_INC_POLLSET_KICK();
   if (GRPC_TRACE_FLAG_ENABLED(grpc_polling_trace)) {
     gpr_log(GPR_INFO,
-            "PS:%p kick %p tls_pollset=%p tls_worker=%p pollset.root_worker=%p",
-            pollset, specific_worker,
-            (void*)gpr_tls_get(&g_current_thread_pollset),
-            (void*)gpr_tls_get(&g_current_thread_worker), pollset->root_worker);
+            "PS:%p kick %p tls_pollset=%" PRIxPTR " tls_worker=%" PRIxPTR
+            " pollset.root_worker=%p",
+            pollset, specific_worker, gpr_tls_get(&g_current_thread_pollset),
+            gpr_tls_get(&g_current_thread_worker), pollset->root_worker);
   }
   if (specific_worker == nullptr) {
-    if (gpr_tls_get(&g_current_thread_pollset) != (intptr_t)pollset) {
+    if (gpr_tls_get(&g_current_thread_pollset) !=
+        reinterpret_cast<intptr_t>(pollset)) {
       if (pollset->root_worker == nullptr) {
         if (GRPC_TRACE_FLAG_ENABLED(grpc_polling_trace)) {
           gpr_log(GPR_INFO, "PS:%p kicked_any_without_poller", pollset);
@@ -881,15 +884,16 @@ static grpc_error* pollable_process_events(grpc_pollset* pollset,
     int n = pollable_obj->event_cursor++;
     struct epoll_event* ev = &pollable_obj->events[n];
     void* data_ptr = ev->data.ptr;
-    if (1 & (intptr_t)data_ptr) {
+    if (1 & reinterpret_cast<intptr_t>(data_ptr)) {
       if (GRPC_TRACE_FLAG_ENABLED(grpc_polling_trace)) {
         gpr_log(GPR_INFO, "PS:%p got pollset_wakeup %p", pollset, data_ptr);
       }
-      append_error(&error,
-                   grpc_wakeup_fd_consume_wakeup(
-                       (grpc_wakeup_fd*)((~static_cast<intptr_t>(1)) &
-                                         (intptr_t)data_ptr)),
-                   err_desc);
+      append_error(
+          &error,
+          grpc_wakeup_fd_consume_wakeup(reinterpret_cast<grpc_wakeup_fd*>(
+              ~static_cast<intptr_t>(1) &
+              reinterpret_cast<intptr_t>(data_ptr))),
+          err_desc);
     } else {
       grpc_fd* fd =
           reinterpret_cast<grpc_fd*>(reinterpret_cast<intptr_t>(data_ptr) & ~2);
index a6b9446..e58d1d3 100644 (file)
@@ -148,12 +148,12 @@ static gpr_mu fork_fd_list_mu;
    MUST NOT be called with a pollset lock taken */
 static uint32_t fd_begin_poll(grpc_fd* fd, grpc_pollset* pollset,
                               grpc_pollset_worker* worker, uint32_t read_mask,
-                              uint32_t write_mask, grpc_fd_watcher* rec);
+                              uint32_t write_mask, grpc_fd_watcher* watcher);
 /* Complete polling previously started with fd_begin_poll
    MUST NOT be called with a pollset lock taken
    if got_read or got_write are 1, also does the become_{readable,writable} as
    appropriate. */
-static void fd_end_poll(grpc_fd_watcher* rec, int got_read, int got_write);
+static void fd_end_poll(grpc_fd_watcher* watcher, int got_read, int got_write);
 
 /* Return 1 if this fd is orphaned, 0 otherwise */
 static bool fd_is_orphaned(grpc_fd* fd);
@@ -775,7 +775,7 @@ static grpc_error* pollset_kick_ext(grpc_pollset* p,
       }
       p->kicked_without_pollers = true;
     } else if (gpr_tls_get(&g_current_thread_worker) !=
-               (intptr_t)specific_worker) {
+               reinterpret_cast<intptr_t>(specific_worker)) {
       GPR_TIMER_MARK("different_thread_worker", 0);
       if ((flags & GRPC_POLLSET_REEVALUATE_POLLING_ON_WAKEUP) != 0) {
         specific_worker->reevaluate_polling_on_wakeup = true;
@@ -792,18 +792,20 @@ static grpc_error* pollset_kick_ext(grpc_pollset* p,
       kick_append_error(&error,
                         grpc_wakeup_fd_wakeup(&specific_worker->wakeup_fd->fd));
     }
-  } else if (gpr_tls_get(&g_current_thread_poller) != (intptr_t)p) {
+  } else if (gpr_tls_get(&g_current_thread_poller) !=
+             reinterpret_cast<intptr_t>(p)) {
     GPR_ASSERT((flags & GRPC_POLLSET_REEVALUATE_POLLING_ON_WAKEUP) == 0);
     GPR_TIMER_MARK("kick_anonymous", 0);
     specific_worker = pop_front_worker(p);
     if (specific_worker != nullptr) {
-      if (gpr_tls_get(&g_current_thread_worker) == (intptr_t)specific_worker) {
+      if (gpr_tls_get(&g_current_thread_worker) ==
+          reinterpret_cast<intptr_t>(specific_worker)) {
         GPR_TIMER_MARK("kick_anonymous_not_self", 0);
         push_back_worker(p, specific_worker);
         specific_worker = pop_front_worker(p);
         if ((flags & GRPC_POLLSET_CAN_KICK_SELF) == 0 &&
             gpr_tls_get(&g_current_thread_worker) ==
-                (intptr_t)specific_worker) {
+                reinterpret_cast<intptr_t>(specific_worker)) {
           push_back_worker(p, specific_worker);
           specific_worker = nullptr;
         }
@@ -987,7 +989,7 @@ static grpc_error* pollset_work(grpc_pollset* pollset,
         void* buf = gpr_malloc(pfd_size + watch_size);
         pfds = static_cast<struct pollfd*>(buf);
         watchers = static_cast<grpc_fd_watcher*>(
-            (void*)(static_cast<char*>(buf) + pfd_size));
+            static_cast<void*>((static_cast<char*>(buf) + pfd_size)));
       }
 
       fd_count = 0;
index 6b4e184..c993133 100644 (file)
@@ -58,8 +58,8 @@ typedef struct grpc_combiner grpc_combiner;
 #define GRPC_APP_CALLBACK_EXEC_CTX_FLAG_IS_INTERNAL_THREAD 1
 
 gpr_timespec grpc_millis_to_timespec(grpc_millis millis, gpr_clock_type clock);
-grpc_millis grpc_timespec_to_millis_round_down(gpr_timespec timespec);
-grpc_millis grpc_timespec_to_millis_round_up(gpr_timespec timespec);
+grpc_millis grpc_timespec_to_millis_round_down(gpr_timespec ts);
+grpc_millis grpc_timespec_to_millis_round_up(gpr_timespec ts);
 grpc_millis grpc_cycle_counter_to_millis_round_down(gpr_cycle_counter cycles);
 grpc_millis grpc_cycle_counter_to_millis_round_up(gpr_cycle_counter cycles);
 
@@ -113,7 +113,7 @@ class ExecCtx {
   }
 
   /** Parameterised Constructor */
-  ExecCtx(uintptr_t fl) : flags_(fl) {
+  explicit ExecCtx(uintptr_t fl) : flags_(fl) {
     if (!(GRPC_EXEC_CTX_FLAG_IS_INTERNAL_THREAD & flags_)) {
       grpc_core::Fork::IncExecCtxCount();
     }
@@ -308,7 +308,9 @@ class ApplicationCallbackExecCtx {
   ApplicationCallbackExecCtx() { Set(this, flags_); }
 
   /** Parameterised Constructor */
-  ApplicationCallbackExecCtx(uintptr_t fl) : flags_(fl) { Set(this, flags_); }
+  explicit ApplicationCallbackExecCtx(uintptr_t fl) : flags_(fl) {
+    Set(this, flags_);
+  }
 
   ~ApplicationCallbackExecCtx() {
     if (reinterpret_cast<ApplicationCallbackExecCtx*>(
index 9f92c9f..b1d21bc 100644 (file)
@@ -283,7 +283,8 @@ void Executor::Enqueue(grpc_closure* closure, grpc_error* error,
       return;
     }
 
-    ThreadState* ts = (ThreadState*)gpr_tls_get(&g_this_thread_state);
+    ThreadState* ts =
+        reinterpret_cast<ThreadState*>(gpr_tls_get(&g_this_thread_state));
     if (ts == nullptr) {
       ts = &thd_state_[GPR_HASH_POINTER(grpc_core::ExecCtx::Get(),
                                         cur_thread_count)];
index 7133700..7a5d16b 100644 (file)
@@ -54,7 +54,7 @@ enum class ExecutorJobType {
 
 class Executor {
  public:
-  Executor(const char* executor_name);
+  explicit Executor(const char* executor_name);
 
   void Init();
 
index 5f8a968..66218b5 100644 (file)
@@ -99,7 +99,7 @@ class ThreadPool : public ThreadPoolInterface {
   // Creates a thread pool with size of "num_threads", with default thread name
   // "ThreadPoolWorker" and all thread options set to default. If the given size
   // is 0 or less, there will be 1 worker thread created inside pool.
-  ThreadPool(int num_threads);
+  explicit ThreadPool(int num_threads);
 
   // Same as ThreadPool(int num_threads) constructor, except
   // that it also sets "thd_name" as the name of all threads in the thread pool.
index 802e3bd..02646db 100644 (file)
@@ -59,7 +59,7 @@ void grpc_iomgr_init() {
   gpr_cv_init(&g_rcv);
   grpc_core::Executor::InitAll();
   g_root_object.next = g_root_object.prev = &g_root_object;
-  g_root_object.name = (char*)"root";
+  g_root_object.name = const_cast<char*>("root");
   grpc_iomgr_platform_init();
   grpc_timer_list_init();
   grpc_core::grpc_errqueue_init();
index 1cb2b5d..d7f8175 100644 (file)
@@ -30,6 +30,6 @@
 /* Loads the content of a file into a slice. add_null_terminator will add
    a NULL terminator if non-zero. */
 grpc_error* grpc_load_file(const char* filename, int add_null_terminator,
-                           grpc_slice* slice);
+                           grpc_slice* output);
 
 #endif /* GRPC_CORE_LIB_IOMGR_LOAD_FILE_H */
index 4b28af4..b3fd8e0 100644 (file)
@@ -96,8 +96,9 @@ void LockfreeEvent::NotifyOn(grpc_closure* closure) {
      * referencing it. */
     gpr_atm curr = gpr_atm_acq_load(&state_);
     if (GRPC_TRACE_FLAG_ENABLED(grpc_polling_trace)) {
-      gpr_log(GPR_DEBUG, "LockfreeEvent::NotifyOn: %p curr=%p closure=%p", this,
-              (void*)curr, closure);
+      gpr_log(GPR_DEBUG,
+              "LockfreeEvent::NotifyOn: %p curr=%" PRIxPTR " closure=%p", this,
+              curr, closure);
     }
     switch (curr) {
       case kClosureNotReady: {
@@ -108,7 +109,8 @@ void LockfreeEvent::NotifyOn(grpc_closure* closure) {
 
            The release itself pairs with the acquire half of a set_ready full
            barrier. */
-        if (gpr_atm_rel_cas(&state_, kClosureNotReady, (gpr_atm)closure)) {
+        if (gpr_atm_rel_cas(&state_, kClosureNotReady,
+                            reinterpret_cast<gpr_atm>(closure))) {
           return; /* Successful. Return */
         }
 
@@ -137,7 +139,8 @@ void LockfreeEvent::NotifyOn(grpc_closure* closure) {
            contains a pointer to the shutdown-error). If the fd is shutdown,
            schedule the closure with the shutdown error */
         if ((curr & kShutdownBit) > 0) {
-          grpc_error* shutdown_err = (grpc_error*)(curr & ~kShutdownBit);
+          grpc_error* shutdown_err =
+              reinterpret_cast<grpc_error*>(curr & ~kShutdownBit);
           ExecCtx::Run(DEBUG_LOCATION, closure,
                        GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING(
                            "FD Shutdown", &shutdown_err, 1));
@@ -156,14 +159,15 @@ void LockfreeEvent::NotifyOn(grpc_closure* closure) {
   GPR_UNREACHABLE_CODE(return );
 }
 
-bool LockfreeEvent::SetShutdown(grpc_error* shutdown_err) {
-  gpr_atm new_state = (gpr_atm)shutdown_err | kShutdownBit;
+bool LockfreeEvent::SetShutdown(grpc_error* shutdown_error) {
+  gpr_atm new_state = reinterpret_cast<gpr_atm>(shutdown_error) | kShutdownBit;
 
   while (true) {
     gpr_atm curr = gpr_atm_no_barrier_load(&state_);
     if (GRPC_TRACE_FLAG_ENABLED(grpc_polling_trace)) {
-      gpr_log(GPR_DEBUG, "LockfreeEvent::SetShutdown: %p curr=%p err=%s",
-              &state_, (void*)curr, grpc_error_string(shutdown_err));
+      gpr_log(GPR_DEBUG,
+              "LockfreeEvent::SetShutdown: %p curr=%" PRIxPTR " err=%s",
+              &state_, curr, grpc_error_string(shutdown_error));
     }
     switch (curr) {
       case kClosureReady:
@@ -180,7 +184,7 @@ bool LockfreeEvent::SetShutdown(grpc_error* shutdown_err) {
 
         /* If fd is already shutdown, we are done */
         if ((curr & kShutdownBit) > 0) {
-          GRPC_ERROR_UNREF(shutdown_err);
+          GRPC_ERROR_UNREF(shutdown_error);
           return false;
         }
 
@@ -190,9 +194,9 @@ bool LockfreeEvent::SetShutdown(grpc_error* shutdown_err) {
            happens-after on that edge), and a release to pair with anything
            loading the shutdown state. */
         if (gpr_atm_full_cas(&state_, curr, new_state)) {
-          ExecCtx::Run(DEBUG_LOCATION, (grpc_closure*)curr,
+          ExecCtx::Run(DEBUG_LOCATION, reinterpret_cast<grpc_closure*>(curr),
                        GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING(
-                           "FD Shutdown", &shutdown_err, 1));
+                           "FD Shutdown", &shutdown_error, 1));
           return true;
         }
 
@@ -211,8 +215,8 @@ void LockfreeEvent::SetReady() {
     gpr_atm curr = gpr_atm_no_barrier_load(&state_);
 
     if (GRPC_TRACE_FLAG_ENABLED(grpc_polling_trace)) {
-      gpr_log(GPR_DEBUG, "LockfreeEvent::SetReady: %p curr=%p", &state_,
-              (void*)curr);
+      gpr_log(GPR_DEBUG, "LockfreeEvent::SetReady: %p curr=%" PRIxPTR, &state_,
+              curr);
     }
 
     switch (curr) {
@@ -240,7 +244,8 @@ void LockfreeEvent::SetReady() {
            spurious set_ready; release pairs with this or the acquire in
            notify_on (or set_shutdown) */
         else if (gpr_atm_full_cas(&state_, curr, kClosureNotReady)) {
-          ExecCtx::Run(DEBUG_LOCATION, (grpc_closure*)curr, GRPC_ERROR_NONE);
+          ExecCtx::Run(DEBUG_LOCATION, reinterpret_cast<grpc_closure*>(curr),
+                       GRPC_ERROR_NONE);
           return;
         }
         /* else the state changed again (only possible by either a racing
index d6a6c22..f7e8554 100644 (file)
@@ -55,8 +55,8 @@ class LockfreeEvent {
   void NotifyOn(grpc_closure* closure);
 
   // Sets the shutdown state. If a closure had been provided by NotifyOn and has
-  // not yet been scheduled, it will be scheduled with \a error.
-  bool SetShutdown(grpc_error* error);
+  // not yet been scheduled, it will be scheduled with \a shutdown_error.
+  bool SetShutdown(grpc_error* shutdown_error);
 
   // Signals that the event has been received.
   void SetReady();
index 9e8f785..9afac74 100644 (file)
 
 #include <grpc/support/port_platform.h>
 
-#include "absl/strings/str_cat.h"
-
-#include "src/core/lib/iomgr/grpc_if_nametoindex.h"
 #include "src/core/lib/iomgr/parse_address.h"
-#include "src/core/lib/iomgr/sockaddr.h"
-#include "src/core/lib/iomgr/socket_utils.h"
 
 #include <stdio.h>
 #include <string.h>
 #ifdef GRPC_HAVE_UNIX_SOCKET
 #include <sys/un.h>
 #endif
+#ifdef GRPC_POSIX_SOCKET
+#include <errno.h>
+#include <net/if.h>
+#endif
+
+#include "absl/strings/str_cat.h"
+#include "absl/strings/strip.h"
 
 #include <grpc/support/alloc.h>
 #include <grpc/support/log.h>
 
 #include "src/core/lib/gpr/string.h"
 #include "src/core/lib/gprpp/host_port.h"
-
-#ifdef GRPC_POSIX_SOCKET
-#include <errno.h>
-#include <net/if.h>
-#endif
+#include "src/core/lib/iomgr/grpc_if_nametoindex.h"
+#include "src/core/lib/iomgr/sockaddr.h"
+#include "src/core/lib/iomgr/socket_utils.h"
 
 #ifdef GRPC_HAVE_UNIX_SOCKET
 
-bool grpc_parse_unix(const grpc_uri* uri,
+bool grpc_parse_unix(const grpc_core::URI& uri,
                      grpc_resolved_address* resolved_addr) {
-  if (strcmp("unix", uri->scheme) != 0) {
-    gpr_log(GPR_ERROR, "Expected 'unix' scheme, got '%s'", uri->scheme);
+  if (uri.scheme() != "unix") {
+    gpr_log(GPR_ERROR, "Expected 'unix' scheme, got '%s'",
+            uri.scheme().c_str());
     return false;
   }
-  grpc_error* error = grpc_core::UnixSockaddrPopulate(uri->path, resolved_addr);
+  grpc_error* error =
+      grpc_core::UnixSockaddrPopulate(uri.path(), resolved_addr);
   if (error != GRPC_ERROR_NONE) {
     gpr_log(GPR_ERROR, "%s", grpc_error_string(error));
     GRPC_ERROR_UNREF(error);
@@ -60,15 +62,15 @@ bool grpc_parse_unix(const grpc_uri* uri,
   return true;
 }
 
-bool grpc_parse_unix_abstract(const grpc_uri* uri,
+bool grpc_parse_unix_abstract(const grpc_core::URI& uri,
                               grpc_resolved_address* resolved_addr) {
-  if (strcmp("unix-abstract", uri->scheme) != 0) {
+  if (uri.scheme() != "unix-abstract") {
     gpr_log(GPR_ERROR, "Expected 'unix-abstract' scheme, got '%s'",
-            uri->scheme);
+            uri.scheme().c_str());
     return false;
   }
   grpc_error* error =
-      grpc_core::UnixAbstractSockaddrPopulate(uri->path, resolved_addr);
+      grpc_core::UnixAbstractSockaddrPopulate(uri.path(), resolved_addr);
   if (error != GRPC_ERROR_NONE) {
     gpr_log(GPR_ERROR, "%s", grpc_error_string(error));
     GRPC_ERROR_UNREF(error);
@@ -120,12 +122,12 @@ grpc_error* UnixAbstractSockaddrPopulate(absl::string_view path,
 
 #else  /* GRPC_HAVE_UNIX_SOCKET */
 
-bool grpc_parse_unix(const grpc_uri* uri,
+bool grpc_parse_unix(const grpc_core::URI& uri,
                      grpc_resolved_address* resolved_addr) {
   abort();
 }
 
-bool grpc_parse_unix_abstract(const grpc_uri* uri,
+bool grpc_parse_unix_abstract(const grpc_core::URI& uri,
                               grpc_resolved_address* resolved_addr) {
   abort();
 }
@@ -145,15 +147,16 @@ grpc_error* UnixAbstractSockaddrPopulate(absl::string_view path,
 }  // namespace grpc_core
 #endif /* GRPC_HAVE_UNIX_SOCKET */
 
-bool grpc_parse_ipv4_hostport(const char* hostport, grpc_resolved_address* addr,
-                              bool log_errors) {
+bool grpc_parse_ipv4_hostport(absl::string_view hostport,
+                              grpc_resolved_address* addr, bool log_errors) {
   bool success = false;
   // Split host and port.
   std::string host;
   std::string port;
   if (!grpc_core::SplitHostPort(hostport, &host, &port)) {
     if (log_errors) {
-      gpr_log(GPR_ERROR, "Failed gpr_split_host_port(%s, ...)", hostport);
+      gpr_log(GPR_ERROR, "Failed gpr_split_host_port(%s, ...)",
+              std::string(hostport).c_str());
     }
     return false;
   }
@@ -185,27 +188,27 @@ done:
   return success;
 }
 
-bool grpc_parse_ipv4(const grpc_uri* uri,
+bool grpc_parse_ipv4(const grpc_core::URI& uri,
                      grpc_resolved_address* resolved_addr) {
-  if (strcmp("ipv4", uri->scheme) != 0) {
-    gpr_log(GPR_ERROR, "Expected 'ipv4' scheme, got '%s'", uri->scheme);
+  if (uri.scheme() != "ipv4") {
+    gpr_log(GPR_ERROR, "Expected 'ipv4' scheme, got '%s'",
+            uri.scheme().c_str());
     return false;
   }
-  const char* host_port = uri->path;
-  if (*host_port == '/') ++host_port;
-  return grpc_parse_ipv4_hostport(host_port, resolved_addr,
-                                  true /* log_errors */);
+  return grpc_parse_ipv4_hostport(absl::StripPrefix(uri.path(), "/"),
+                                  resolved_addr, true /* log_errors */);
 }
 
-bool grpc_parse_ipv6_hostport(const char* hostport, grpc_resolved_address* addr,
-                              bool log_errors) {
+bool grpc_parse_ipv6_hostport(absl::string_view hostport,
+                              grpc_resolved_address* addr, bool log_errors) {
   bool success = false;
   // Split host and port.
   std::string host;
   std::string port;
   if (!grpc_core::SplitHostPort(hostport, &host, &port)) {
     if (log_errors) {
-      gpr_log(GPR_ERROR, "Failed gpr_split_host_port(%s, ...)", hostport);
+      gpr_log(GPR_ERROR, "Failed gpr_split_host_port(%s, ...)",
+              std::string(hostport).c_str());
     }
     return false;
   }
@@ -280,29 +283,32 @@ done:
   return success;
 }
 
-bool grpc_parse_ipv6(const grpc_uri* uri,
+bool grpc_parse_ipv6(const grpc_core::URI& uri,
                      grpc_resolved_address* resolved_addr) {
-  if (strcmp("ipv6", uri->scheme) != 0) {
-    gpr_log(GPR_ERROR, "Expected 'ipv6' scheme, got '%s'", uri->scheme);
+  if (uri.scheme() != "ipv6") {
+    gpr_log(GPR_ERROR, "Expected 'ipv6' scheme, got '%s'",
+            uri.scheme().c_str());
     return false;
   }
-  const char* host_port = uri->path;
-  if (*host_port == '/') ++host_port;
-  return grpc_parse_ipv6_hostport(host_port, resolved_addr,
-                                  true /* log_errors */);
+  return grpc_parse_ipv6_hostport(absl::StripPrefix(uri.path(), "/"),
+                                  resolved_addr, true /* log_errors */);
 }
 
-bool grpc_parse_uri(const grpc_uri* uri, grpc_resolved_address* resolved_addr) {
-  if (strcmp("unix", uri->scheme) == 0) {
+bool grpc_parse_uri(const grpc_core::URI& uri,
+                    grpc_resolved_address* resolved_addr) {
+  if (uri.scheme() == "unix") {
     return grpc_parse_unix(uri, resolved_addr);
-  } else if (strcmp("unix-abstract", uri->scheme) == 0) {
+  }
+  if (uri.scheme() == "unix-abstract") {
     return grpc_parse_unix_abstract(uri, resolved_addr);
-  } else if (strcmp("ipv4", uri->scheme) == 0) {
+  }
+  if (uri.scheme() == "ipv4") {
     return grpc_parse_ipv4(uri, resolved_addr);
-  } else if (strcmp("ipv6", uri->scheme) == 0) {
+  }
+  if (uri.scheme() == "ipv6") {
     return grpc_parse_ipv6(uri, resolved_addr);
   }
-  gpr_log(GPR_ERROR, "Can't parse scheme '%s'", uri->scheme);
+  gpr_log(GPR_ERROR, "Can't parse scheme '%s'", uri.scheme().c_str());
   return false;
 }
 
index 29c8321..870afef 100644 (file)
 
 /** Populate \a resolved_addr from \a uri, whose path is expected to contain a
  * unix socket path. Returns true upon success. */
-bool grpc_parse_unix(const grpc_uri* uri, grpc_resolved_address* resolved_addr);
+bool grpc_parse_unix(const grpc_core::URI& uri,
+                     grpc_resolved_address* resolved_addr);
 
 /** Populate \a resolved_addr from \a uri, whose path is expected to contain a
  * unix socket path in the abstract namespace. Returns true upon success. */
-bool grpc_parse_unix_abstract(const grpc_uri* uri,
+bool grpc_parse_unix_abstract(const grpc_core::URI& uri,
                               grpc_resolved_address* resolved_addr);
 
 /** Populate \a resolved_addr from \a uri, whose path is expected to contain an
  * IPv4 host:port pair. Returns true upon success. */
-bool grpc_parse_ipv4(const grpc_uri* uri, grpc_resolved_address* resolved_addr);
+bool grpc_parse_ipv4(const grpc_core::URI& uri,
+                     grpc_resolved_address* resolved_addr);
 
 /** Populate \a resolved_addr from \a uri, whose path is expected to contain an
  * IPv6 host:port pair. Returns true upon success. */
-bool grpc_parse_ipv6(const grpc_uri* uri, grpc_resolved_address* resolved_addr);
+bool grpc_parse_ipv6(const grpc_core::URI& uri,
+                     grpc_resolved_address* resolved_addr);
 
 /** Populate \a resolved_addr from \a uri. Returns true upon success. */
-bool grpc_parse_uri(const grpc_uri* uri, grpc_resolved_address* resolved_addr);
+bool grpc_parse_uri(const grpc_core::URI& uri,
+                    grpc_resolved_address* resolved_addr);
 
 /** Parse bare IPv4 or IPv6 "IP:port" strings. */
-bool grpc_parse_ipv4_hostport(const char* hostport, grpc_resolved_address* addr,
-                              bool log_errors);
-bool grpc_parse_ipv6_hostport(const char* hostport, grpc_resolved_address* addr,
-                              bool log_errors);
+bool grpc_parse_ipv4_hostport(absl::string_view hostport,
+                              grpc_resolved_address* addr, bool log_errors);
+bool grpc_parse_ipv6_hostport(absl::string_view hostport,
+                              grpc_resolved_address* addr, bool log_errors);
 
 /* Converts named or numeric port to a uint16 suitable for use in a sockaddr. */
 uint16_t grpc_strhtons(const char* port);
index 3c0e05d..0bd0ecc 100644 (file)
@@ -36,7 +36,7 @@ class LibuvEventManager {
   class Options {
    public:
     Options();
-    Options(int num_workers);
+    explicit Options(int num_workers);
 
     int num_workers() const { return num_workers_; }
     void set_num_workers(int num) { num_workers_ = num; }
index 2c1df60..0cc9089 100644 (file)
@@ -23,7 +23,7 @@
 #include "src/core/lib/iomgr/pollset_set.h"
 
 static grpc_pollset_set* pollset_set_create(void) {
-  return (grpc_pollset_set*)((intptr_t)0xdeafbeef);
+  return reinterpret_cast<grpc_pollset_set*>(static_cast<intptr_t>(0xdeafbeef));
 }
 
 static void pollset_set_destroy(grpc_pollset_set* /*pollset_set*/) {}
index a8c2fe4..05d72a5 100644 (file)
@@ -36,7 +36,7 @@ inline grpc_error* grpc_socket_error(char* error) {
 }
 
 inline char* grpc_slice_buffer_start(grpc_slice_buffer* buffer, int i) {
-  return (char*)GRPC_SLICE_START_PTR(buffer->slices[i]);
+  return reinterpret_cast<char*>(GRPC_SLICE_START_PTR(buffer->slices[i]));
 }
 
 inline int grpc_slice_buffer_length(grpc_slice_buffer* buffer, int i) {
index f2a4676..7479836 100644 (file)
@@ -35,11 +35,11 @@ void grpc_resolve_address(const char* addr, const char* default_port,
       addr, default_port, interested_parties, on_done, addresses);
 }
 
-void grpc_resolved_addresses_destroy(grpc_resolved_addresses* addrs) {
-  if (addrs != nullptr) {
-    gpr_free(addrs->addrs);
+void grpc_resolved_addresses_destroy(grpc_resolved_addresses* addresses) {
+  if (addresses != nullptr) {
+    gpr_free(addresses->addrs);
   }
-  gpr_free(addrs);
+  gpr_free(addresses);
 }
 
 grpc_error* grpc_blocking_resolve_address(const char* name,
index dbe84e3..464cccd 100644 (file)
@@ -659,8 +659,8 @@ grpc_resource_quota* grpc_resource_quota_create(const char* name) {
   if (name != nullptr) {
     resource_quota->name = name;
   } else {
-    resource_quota->name =
-        absl::StrCat("anonymous_pool_", (intptr_t)resource_quota);
+    resource_quota->name = absl::StrCat(
+        "anonymous_pool_", reinterpret_cast<intptr_t>(resource_quota));
   }
   GRPC_CLOSURE_INIT(&resource_quota->rq_step_closure, rq_step, resource_quota,
                     nullptr);
@@ -807,8 +807,8 @@ grpc_resource_user* grpc_resource_user_create(
   if (name != nullptr) {
     resource_user->name = name;
   } else {
-    resource_user->name =
-        absl::StrCat("anonymous_resource_user_", (intptr_t)resource_user);
+    resource_user->name = absl::StrCat(
+        "anonymous_resource_user_", reinterpret_cast<intptr_t>(resource_user));
   }
   return resource_user;
 }
index 2856be4..6d90c13 100644 (file)
@@ -201,8 +201,8 @@ std::string grpc_sockaddr_to_string(const grpc_resolved_address* resolved_addr,
 void grpc_string_to_sockaddr(grpc_resolved_address* out, const char* addr,
                              int port) {
   memset(out, 0, sizeof(grpc_resolved_address));
-  grpc_sockaddr_in6* addr6 = (grpc_sockaddr_in6*)out->addr;
-  grpc_sockaddr_in* addr4 = (grpc_sockaddr_in*)out->addr;
+  grpc_sockaddr_in6* addr6 = reinterpret_cast<grpc_sockaddr_in6*>(out->addr);
+  grpc_sockaddr_in* addr4 = reinterpret_cast<grpc_sockaddr_in*>(out->addr);
   if (grpc_inet_pton(GRPC_AF_INET6, addr, &addr6->sin6_addr) == 1) {
     addr6->sin6_family = GRPC_AF_INET6;
     out->len = sizeof(grpc_sockaddr_in6);
@@ -260,9 +260,11 @@ int grpc_sockaddr_get_port(const grpc_resolved_address* resolved_addr) {
       reinterpret_cast<const grpc_sockaddr*>(resolved_addr->addr);
   switch (addr->sa_family) {
     case GRPC_AF_INET:
-      return grpc_ntohs(((grpc_sockaddr_in*)addr)->sin_port);
+      return grpc_ntohs(
+          (reinterpret_cast<const grpc_sockaddr_in*>(addr))->sin_port);
     case GRPC_AF_INET6:
-      return grpc_ntohs(((grpc_sockaddr_in6*)addr)->sin6_port);
+      return grpc_ntohs(
+          (reinterpret_cast<const grpc_sockaddr_in6*>(addr))->sin6_port);
     default:
       if (grpc_is_unix_socket(resolved_addr)) {
         return 1;
@@ -273,19 +275,17 @@ int grpc_sockaddr_get_port(const grpc_resolved_address* resolved_addr) {
   }
 }
 
-int grpc_sockaddr_set_port(const grpc_resolved_address* resolved_addr,
-                           int port) {
-  const grpc_sockaddr* addr =
-      reinterpret_cast<const grpc_sockaddr*>(resolved_addr->addr);
+int grpc_sockaddr_set_port(grpc_resolved_address* resolved_addr, int port) {
+  grpc_sockaddr* addr = reinterpret_cast<grpc_sockaddr*>(resolved_addr->addr);
   switch (addr->sa_family) {
     case GRPC_AF_INET:
       GPR_ASSERT(port >= 0 && port < 65536);
-      ((grpc_sockaddr_in*)addr)->sin_port =
+      (reinterpret_cast<grpc_sockaddr_in*>(addr))->sin_port =
           grpc_htons(static_cast<uint16_t>(port));
       return 1;
     case GRPC_AF_INET6:
       GPR_ASSERT(port >= 0 && port < 65536);
-      ((grpc_sockaddr_in6*)addr)->sin6_port =
+      (reinterpret_cast<grpc_sockaddr_in6*>(addr))->sin6_port =
           grpc_htons(static_cast<uint16_t>(port));
       return 1;
     default:
index 051c275..ba91e56 100644 (file)
@@ -56,7 +56,7 @@ void grpc_sockaddr_make_wildcard6(int port, grpc_resolved_address* wild_out);
 int grpc_sockaddr_get_port(const grpc_resolved_address* addr);
 
 /* Set IP port number of a sockaddr */
-int grpc_sockaddr_set_port(const grpc_resolved_address* addr, int port);
+int grpc_sockaddr_set_port(grpc_resolved_address* addr, int port);
 
 // Converts a sockaddr into a newly-allocated human-readable string.
 //
index 5713776..8d1bd71 100644 (file)
@@ -87,8 +87,9 @@ static const grpc_arg_pointer_vtable socket_factory_arg_vtable = {
     socket_factory_arg_copy, socket_factory_arg_destroy, socket_factory_cmp};
 
 grpc_arg grpc_socket_factory_to_arg(grpc_socket_factory* factory) {
-  return grpc_channel_arg_pointer_create((char*)GRPC_ARG_SOCKET_FACTORY,
-                                         factory, &socket_factory_arg_vtable);
+  return grpc_channel_arg_pointer_create(
+      const_cast<char*>(GRPC_ARG_SOCKET_FACTORY), factory,
+      &socket_factory_arg_vtable);
 }
 
 #endif
index a448c9f..918754a 100644 (file)
@@ -78,6 +78,7 @@ static const grpc_arg_pointer_vtable socket_mutator_arg_vtable = {
     socket_mutator_arg_copy, socket_mutator_arg_destroy, socket_mutator_cmp};
 
 grpc_arg grpc_socket_mutator_to_arg(grpc_socket_mutator* mutator) {
-  return grpc_channel_arg_pointer_create((char*)GRPC_ARG_SOCKET_MUTATOR,
-                                         mutator, &socket_mutator_arg_vtable);
+  return grpc_channel_arg_pointer_create(
+      const_cast<char*>(GRPC_ARG_SOCKET_MUTATOR), mutator,
+      &socket_mutator_arg_vtable);
 }
index 6c0ba40..3441a63 100644 (file)
 
 grpc_tcp_client_vtable* grpc_tcp_client_impl;
 
-void grpc_tcp_client_connect(grpc_closure* closure, grpc_endpoint** ep,
+void grpc_tcp_client_connect(grpc_closure* on_connect, grpc_endpoint** endpoint,
                              grpc_pollset_set* interested_parties,
                              const grpc_channel_args* channel_args,
                              const grpc_resolved_address* addr,
                              grpc_millis deadline) {
-  grpc_tcp_client_impl->connect(closure, ep, interested_parties, channel_args,
-                                addr, deadline);
+  grpc_tcp_client_impl->connect(on_connect, endpoint, interested_parties,
+                                channel_args, addr, deadline);
 }
 
 void grpc_set_tcp_client_impl(grpc_tcp_client_vtable* impl) {
index 5e8a3a1..046380c 100644 (file)
@@ -61,7 +61,7 @@ static void custom_close_callback(grpc_custom_socket* /*socket*/) {}
 
 static void on_alarm(void* acp, grpc_error* error) {
   int done;
-  grpc_custom_socket* socket = (grpc_custom_socket*)acp;
+  grpc_custom_socket* socket = static_cast<grpc_custom_socket*>(acp);
   grpc_custom_tcp_connect* connect = socket->connector;
   if (GRPC_TRACE_FLAG_ENABLED(grpc_tcp_trace)) {
     const char* str = grpc_error_string(error);
@@ -124,13 +124,14 @@ static void tcp_connect(grpc_closure* closure, grpc_endpoint** ep,
     for (size_t i = 0; i < channel_args->num_args; i++) {
       if (0 == strcmp(channel_args->args[i].key, GRPC_ARG_RESOURCE_QUOTA)) {
         grpc_resource_quota_unref_internal(resource_quota);
-        resource_quota = grpc_resource_quota_ref_internal(
-            (grpc_resource_quota*)channel_args->args[i].value.pointer.p);
+        resource_quota =
+            grpc_resource_quota_ref_internal(static_cast<grpc_resource_quota*>(
+                channel_args->args[i].value.pointer.p));
       }
     }
   }
   grpc_custom_socket* socket =
-      (grpc_custom_socket*)gpr_malloc(sizeof(grpc_custom_socket));
+      static_cast<grpc_custom_socket*>(gpr_malloc(sizeof(grpc_custom_socket)));
   socket->refs = 2;
   grpc_custom_socket_vtable->init(socket, GRPC_AF_UNSPEC);
   grpc_custom_tcp_connect* connect = new grpc_custom_tcp_connect();
@@ -153,8 +154,8 @@ static void tcp_connect(grpc_closure* closure, grpc_endpoint** ep,
                     grpc_schedule_on_exec_ctx);
   grpc_timer_init(&connect->alarm, deadline, &connect->on_alarm);
   grpc_custom_socket_vtable->connect(
-      socket, (const grpc_sockaddr*)resolved_addr->addr, resolved_addr->len,
-      custom_connect_callback);
+      socket, reinterpret_cast<const grpc_sockaddr*>(resolved_addr->addr),
+      resolved_addr->len, custom_connect_callback);
 }
 
 grpc_tcp_client_vtable custom_tcp_client_vtable = {tcp_connect};
index 06763f6..0f45c75 100644 (file)
@@ -73,7 +73,8 @@ struct custom_tcp_endpoint {
   std::string local_address;
 };
 static void tcp_free(grpc_custom_socket* s) {
-  custom_tcp_endpoint* tcp = (custom_tcp_endpoint*)s->endpoint;
+  custom_tcp_endpoint* tcp =
+      reinterpret_cast<custom_tcp_endpoint*>(s->endpoint);
   grpc_resource_user_unref(tcp->resource_user);
   delete tcp;
   s->refs--;
@@ -149,18 +150,19 @@ static void custom_read_callback(grpc_custom_socket* socket, size_t nread,
   grpc_core::ApplicationCallbackExecCtx callback_exec_ctx;
   grpc_core::ExecCtx exec_ctx;
   grpc_slice_buffer garbage;
-  custom_tcp_endpoint* tcp = (custom_tcp_endpoint*)socket->endpoint;
+  custom_tcp_endpoint* tcp =
+      reinterpret_cast<custom_tcp_endpoint*>(socket->endpoint);
   if (error == GRPC_ERROR_NONE && nread == 0) {
     error = GRPC_ERROR_CREATE_FROM_STATIC_STRING("EOF");
   }
   if (error == GRPC_ERROR_NONE) {
     // Successful read
-    if ((size_t)nread < tcp->read_slices->length) {
+    if (nread < tcp->read_slices->length) {
       /* TODO(murgatroid99): Instead of discarding the unused part of the read
        * buffer, reuse it as the next read buffer. */
       grpc_slice_buffer_init(&garbage);
-      grpc_slice_buffer_trim_end(
-          tcp->read_slices, tcp->read_slices->length - (size_t)nread, &garbage);
+      grpc_slice_buffer_trim_end(tcp->read_slices,
+                                 tcp->read_slices->length - nread, &garbage);
       grpc_slice_buffer_reset_and_unref_internal(&garbage);
     }
   } else {
@@ -170,7 +172,7 @@ static void custom_read_callback(grpc_custom_socket* socket, size_t nread,
 }
 
 static void tcp_read_allocation_done(void* tcpp, grpc_error* error) {
-  custom_tcp_endpoint* tcp = (custom_tcp_endpoint*)tcpp;
+  custom_tcp_endpoint* tcp = static_cast<custom_tcp_endpoint*>(tcpp);
   if (GRPC_TRACE_FLAG_ENABLED(grpc_tcp_trace)) {
     gpr_log(GPR_INFO, "TCP:%p read_allocation_done: %s", tcp->socket,
             grpc_error_string(error));
@@ -179,7 +181,8 @@ static void tcp_read_allocation_done(void* tcpp, grpc_error* error) {
     /* Before calling read, we allocate a buffer with exactly one slice
      * to tcp->read_slices and wait for the callback indicating that the
      * allocation was successful. So slices[0] should always exist here */
-    char* buffer = (char*)GRPC_SLICE_START_PTR(tcp->read_slices->slices[0]);
+    char* buffer = reinterpret_cast<char*>(
+        GRPC_SLICE_START_PTR(tcp->read_slices->slices[0]));
     size_t len = GRPC_SLICE_LENGTH(tcp->read_slices->slices[0]);
     grpc_custom_socket_vtable->read(tcp->socket, buffer, len,
                                     custom_read_callback);
@@ -195,7 +198,7 @@ static void tcp_read_allocation_done(void* tcpp, grpc_error* error) {
 
 static void endpoint_read(grpc_endpoint* ep, grpc_slice_buffer* read_slices,
                           grpc_closure* cb, bool /*urgent*/) {
-  custom_tcp_endpoint* tcp = (custom_tcp_endpoint*)ep;
+  custom_tcp_endpoint* tcp = reinterpret_cast<custom_tcp_endpoint*>(ep);
   GRPC_CUSTOM_IOMGR_ASSERT_SAME_THREAD();
   GPR_ASSERT(tcp->read_cb == nullptr);
   tcp->read_cb = cb;
@@ -213,7 +216,8 @@ static void custom_write_callback(grpc_custom_socket* socket,
                                   grpc_error* error) {
   grpc_core::ApplicationCallbackExecCtx callback_exec_ctx;
   grpc_core::ExecCtx exec_ctx;
-  custom_tcp_endpoint* tcp = (custom_tcp_endpoint*)socket->endpoint;
+  custom_tcp_endpoint* tcp =
+      reinterpret_cast<custom_tcp_endpoint*>(socket->endpoint);
   grpc_closure* cb = tcp->write_cb;
   tcp->write_cb = nullptr;
   if (GRPC_TRACE_FLAG_ENABLED(grpc_tcp_trace)) {
@@ -226,7 +230,7 @@ static void custom_write_callback(grpc_custom_socket* socket,
 
 static void endpoint_write(grpc_endpoint* ep, grpc_slice_buffer* write_slices,
                            grpc_closure* cb, void* /*arg*/) {
-  custom_tcp_endpoint* tcp = (custom_tcp_endpoint*)ep;
+  custom_tcp_endpoint* tcp = reinterpret_cast<custom_tcp_endpoint*>(ep);
   GRPC_CUSTOM_IOMGR_ASSERT_SAME_THREAD();
 
   if (GRPC_TRACE_FLAG_ENABLED(grpc_tcp_trace)) {
@@ -284,7 +288,7 @@ static void endpoint_delete_from_pollset_set(grpc_endpoint* ep,
 }
 
 static void endpoint_shutdown(grpc_endpoint* ep, grpc_error* why) {
-  custom_tcp_endpoint* tcp = (custom_tcp_endpoint*)ep;
+  custom_tcp_endpoint* tcp = reinterpret_cast<custom_tcp_endpoint*>(ep);
   if (!tcp->shutting_down) {
     if (GRPC_TRACE_FLAG_ENABLED(grpc_tcp_trace)) {
       const char* str = grpc_error_string(why);
@@ -309,28 +313,29 @@ static void custom_close_callback(grpc_custom_socket* socket) {
   } else if (socket->endpoint) {
     grpc_core::ApplicationCallbackExecCtx callback_exec_ctx;
     grpc_core::ExecCtx exec_ctx;
-    custom_tcp_endpoint* tcp = (custom_tcp_endpoint*)socket->endpoint;
+    custom_tcp_endpoint* tcp =
+        reinterpret_cast<custom_tcp_endpoint*>(socket->endpoint);
     TCP_UNREF(tcp, "destroy");
   }
 }
 
 static void endpoint_destroy(grpc_endpoint* ep) {
-  custom_tcp_endpoint* tcp = (custom_tcp_endpoint*)ep;
+  custom_tcp_endpoint* tcp = reinterpret_cast<custom_tcp_endpoint*>(ep);
   grpc_custom_socket_vtable->close(tcp->socket, custom_close_callback);
 }
 
 static absl::string_view endpoint_get_peer(grpc_endpoint* ep) {
-  custom_tcp_endpoint* tcp = (custom_tcp_endpoint*)ep;
+  custom_tcp_endpoint* tcp = reinterpret_cast<custom_tcp_endpoint*>(ep);
   return tcp->peer_string;
 }
 
 static absl::string_view endpoint_get_local_address(grpc_endpoint* ep) {
-  custom_tcp_endpoint* tcp = (custom_tcp_endpoint*)ep;
+  custom_tcp_endpoint* tcp = reinterpret_cast<custom_tcp_endpoint*>(ep);
   return tcp->local_address;
 }
 
 static grpc_resource_user* endpoint_get_resource_user(grpc_endpoint* ep) {
-  custom_tcp_endpoint* tcp = (custom_tcp_endpoint*)ep;
+  custom_tcp_endpoint* tcp = reinterpret_cast<custom_tcp_endpoint*>(ep);
   return tcp->resource_user;
 }
 
@@ -362,7 +367,7 @@ grpc_endpoint* custom_tcp_endpoint_create(grpc_custom_socket* socket,
     gpr_log(GPR_INFO, "Creating TCP endpoint %p", socket);
   }
   socket->refs++;
-  socket->endpoint = (grpc_endpoint*)tcp;
+  socket->endpoint = reinterpret_cast<grpc_endpoint*>(tcp);
   tcp->socket = socket;
   tcp->base.vtable = &vtable;
   gpr_ref_init(&tcp->refcount, 1);
index b968ef9..7813e04 100644 (file)
@@ -181,8 +181,9 @@ class TcpZerocopySendCtx {
   static constexpr int kDefaultMaxSends = 4;
   static constexpr size_t kDefaultSendBytesThreshold = 16 * 1024;  // 16KB
 
-  TcpZerocopySendCtx(int max_sends = kDefaultMaxSends,
-                     size_t send_bytes_threshold = kDefaultSendBytesThreshold)
+  explicit TcpZerocopySendCtx(
+      int max_sends = kDefaultMaxSends,
+      size_t send_bytes_threshold = kDefaultSendBytesThreshold)
       : max_sends_(max_sends),
         free_send_records_size_(max_sends),
         threshold_bytes_(send_bytes_threshold) {
@@ -465,7 +466,8 @@ static void run_poller(void* bp, grpc_error* /*error_ignored*/) {
   if (gpr_atm_no_barrier_load(&g_uncovered_notifications_pending) == 1 &&
       gpr_atm_full_cas(&g_uncovered_notifications_pending, 1, 0)) {
     gpr_mu_lock(p->pollset_mu);
-    bool cas_ok = gpr_atm_full_cas(&g_backup_poller, (gpr_atm)p, 0);
+    bool cas_ok =
+        gpr_atm_full_cas(&g_backup_poller, reinterpret_cast<gpr_atm>(p), 0);
     if (GRPC_TRACE_FLAG_ENABLED(grpc_tcp_trace)) {
       gpr_log(GPR_INFO, "BACKUP_POLLER:%p done cas_ok=%d", p, cas_ok);
     }
@@ -487,7 +489,8 @@ static void run_poller(void* bp, grpc_error* /*error_ignored*/) {
 }
 
 static void drop_uncovered(grpc_tcp* /*tcp*/) {
-  backup_poller* p = (backup_poller*)gpr_atm_acq_load(&g_backup_poller);
+  backup_poller* p =
+      reinterpret_cast<backup_poller*>(gpr_atm_acq_load(&g_backup_poller));
   gpr_atm old_count =
       gpr_atm_full_fetch_add(&g_uncovered_notifications_pending, -1);
   if (GRPC_TRACE_FLAG_ENABLED(grpc_tcp_trace)) {
@@ -526,8 +529,8 @@ static void cover_self(grpc_tcp* tcp) {
         GRPC_ERROR_NONE, grpc_core::ExecutorType::DEFAULT,
         grpc_core::ExecutorJobType::LONG);
   } else {
-    while ((p = (backup_poller*)gpr_atm_acq_load(&g_backup_poller)) ==
-           nullptr) {
+    while ((p = reinterpret_cast<backup_poller*>(
+                gpr_atm_acq_load(&g_backup_poller))) == nullptr) {
       // spin waiting for backup poller
     }
   }
index 85f859b..18d7494 100644 (file)
@@ -83,7 +83,8 @@ struct grpc_tcp_server {
 static grpc_error* tcp_server_create(grpc_closure* shutdown_complete,
                                      const grpc_channel_args* args,
                                      grpc_tcp_server** server) {
-  grpc_tcp_server* s = (grpc_tcp_server*)gpr_malloc(sizeof(grpc_tcp_server));
+  grpc_tcp_server* s =
+      static_cast<grpc_tcp_server*>(gpr_malloc(sizeof(grpc_tcp_server)));
   // Let the implementation decide if so_reuseport can be enabled or not.
   s->so_reuseport = true;
   s->resource_quota = grpc_resource_quota_create(nullptr);
@@ -95,7 +96,7 @@ static grpc_error* tcp_server_create(grpc_closure* shutdown_complete,
       if (args->args[i].type == GRPC_ARG_POINTER) {
         grpc_resource_quota_unref_internal(s->resource_quota);
         s->resource_quota = grpc_resource_quota_ref_internal(
-            (grpc_resource_quota*)args->args[i].value.pointer.p);
+            static_cast<grpc_resource_quota*>(args->args[i].value.pointer.p));
       } else {
         grpc_resource_quota_unref_internal(s->resource_quota);
         gpr_free(s);
@@ -163,12 +164,12 @@ static void custom_close_callback(grpc_custom_socket* socket) {
   }
 }
 
-void grpc_custom_close_server_callback(grpc_tcp_listener* sp) {
-  if (sp) {
+void grpc_custom_close_server_callback(grpc_tcp_listener* listener) {
+  if (listener) {
     grpc_core::ExecCtx exec_ctx;
-    sp->server->open_ports--;
-    if (sp->server->open_ports == 0 && sp->server->shutdown) {
-      finish_shutdown(sp->server);
+    listener->server->open_ports--;
+    if (listener->server->open_ports == 0 && listener->server->shutdown) {
+      finish_shutdown(listener->server);
     }
   }
 }
@@ -213,7 +214,7 @@ static void tcp_server_unref(grpc_tcp_server* s) {
 
 static void finish_accept(grpc_tcp_listener* sp, grpc_custom_socket* socket) {
   grpc_tcp_server_acceptor* acceptor =
-      (grpc_tcp_server_acceptor*)gpr_malloc(sizeof(*acceptor));
+      static_cast<grpc_tcp_server_acceptor*>(gpr_malloc(sizeof(*acceptor)));
   grpc_endpoint* ep = nullptr;
   grpc_resolved_address peer_name;
   std::string peer_name_string;
@@ -222,7 +223,8 @@ static void finish_accept(grpc_tcp_listener* sp, grpc_custom_socket* socket) {
   memset(&peer_name, 0, sizeof(grpc_resolved_address));
   peer_name.len = GRPC_MAX_SOCKADDR_SIZE;
   err = grpc_custom_socket_vtable->getpeername(
-      socket, (grpc_sockaddr*)&peer_name.addr, (int*)&peer_name.len);
+      socket, reinterpret_cast<grpc_sockaddr*>(&peer_name.addr),
+      reinterpret_cast<int*>(&peer_name.len));
   if (err == GRPC_ERROR_NONE) {
     peer_name_string = grpc_sockaddr_to_uri(&peer_name);
   } else {
@@ -262,8 +264,8 @@ static void custom_accept_callback(grpc_custom_socket* socket,
   }
   finish_accept(sp, client);
   if (!sp->closed) {
-    grpc_custom_socket* new_socket =
-        (grpc_custom_socket*)gpr_malloc(sizeof(grpc_custom_socket));
+    grpc_custom_socket* new_socket = static_cast<grpc_custom_socket*>(
+        gpr_malloc(sizeof(grpc_custom_socket)));
     new_socket->endpoint = nullptr;
     new_socket->listener = nullptr;
     new_socket->connector = nullptr;
@@ -290,8 +292,9 @@ static grpc_error* add_socket_to_server(grpc_tcp_server* s,
     flags |= GRPC_CUSTOM_SOCKET_OPT_SO_REUSEPORT;
   }
 
-  error = grpc_custom_socket_vtable->bind(socket, (grpc_sockaddr*)addr->addr,
-                                          addr->len, flags);
+  error = grpc_custom_socket_vtable->bind(
+      socket, reinterpret_cast<grpc_sockaddr*>(const_cast<char*>(addr->addr)),
+      addr->len, flags);
   if (error != GRPC_ERROR_NONE) {
     return error;
   }
@@ -303,7 +306,8 @@ static grpc_error* add_socket_to_server(grpc_tcp_server* s,
 
   sockname_temp.len = GRPC_MAX_SOCKADDR_SIZE;
   error = grpc_custom_socket_vtable->getsockname(
-      socket, (grpc_sockaddr*)&sockname_temp.addr, (int*)&sockname_temp.len);
+      socket, reinterpret_cast<grpc_sockaddr*>(&sockname_temp.addr),
+      reinterpret_cast<int*>(&sockname_temp.len));
   if (error != GRPC_ERROR_NONE) {
     return error;
   }
@@ -312,7 +316,7 @@ static grpc_error* add_socket_to_server(grpc_tcp_server* s,
 
   GPR_ASSERT(port >= 0);
   GPR_ASSERT(!s->on_accept_cb && "must add ports before starting server");
-  sp = (grpc_tcp_listener*)gpr_zalloc(sizeof(grpc_tcp_listener));
+  sp = static_cast<grpc_tcp_listener*>(gpr_zalloc(sizeof(grpc_tcp_listener)));
   sp->next = nullptr;
   if (s->head == nullptr) {
     s->head = sp;
@@ -358,12 +362,13 @@ static grpc_error* tcp_server_add_port(grpc_tcp_server* s,
       socket = sp->socket;
       sockname_temp.len = GRPC_MAX_SOCKADDR_SIZE;
       if (nullptr == grpc_custom_socket_vtable->getsockname(
-                         socket, (grpc_sockaddr*)&sockname_temp.addr,
-                         (int*)&sockname_temp.len)) {
+                         socket,
+                         reinterpret_cast<grpc_sockaddr*>(&sockname_temp.addr),
+                         reinterpret_cast<int*>(&sockname_temp.len))) {
         *port = grpc_sockaddr_get_port(&sockname_temp);
         if (*port > 0) {
-          allocated_addr =
-              (grpc_resolved_address*)gpr_malloc(sizeof(grpc_resolved_address));
+          allocated_addr = static_cast<grpc_resolved_address*>(
+              gpr_malloc(sizeof(grpc_resolved_address)));
           memcpy(allocated_addr, addr, sizeof(grpc_resolved_address));
           grpc_sockaddr_set_port(allocated_addr, *port);
           addr = allocated_addr;
@@ -391,7 +396,8 @@ static grpc_error* tcp_server_add_port(grpc_tcp_server* s,
   }
 
   family = grpc_sockaddr_get_family(addr);
-  socket = (grpc_custom_socket*)gpr_malloc(sizeof(grpc_custom_socket));
+  socket =
+      static_cast<grpc_custom_socket*>(gpr_malloc(sizeof(grpc_custom_socket)));
   socket->refs = 1;
   socket->endpoint = nullptr;
   socket->listener = nullptr;
@@ -430,8 +436,8 @@ static void tcp_server_start(grpc_tcp_server* server,
   server->on_accept_cb = on_accept_cb;
   server->on_accept_cb_arg = cb_arg;
   for (sp = server->head; sp; sp = sp->next) {
-    grpc_custom_socket* new_socket =
-        (grpc_custom_socket*)gpr_malloc(sizeof(grpc_custom_socket));
+    grpc_custom_socket* new_socket = static_cast<grpc_custom_socket*>(
+        gpr_malloc(sizeof(grpc_custom_socket)));
     new_socket->endpoint = nullptr;
     new_socket->listener = nullptr;
     new_socket->connector = nullptr;
index 4d0e4e9..867359a 100644 (file)
@@ -57,16 +57,16 @@ static void timer_init(grpc_timer* timer, grpc_millis deadline,
   timer->pending = true;
   timer->closure = closure;
   grpc_custom_timer* timer_wrapper =
-      (grpc_custom_timer*)gpr_malloc(sizeof(grpc_custom_timer));
+      static_cast<grpc_custom_timer*>(gpr_malloc(sizeof(grpc_custom_timer)));
   timer_wrapper->timeout_ms = timeout;
-  timer->custom_timer = (void*)timer_wrapper;
+  timer->custom_timer = timer_wrapper;
   timer_wrapper->original = timer;
   custom_timer_impl->start(timer_wrapper);
 }
 
 static void timer_cancel(grpc_timer* timer) {
   GRPC_CUSTOM_IOMGR_ASSERT_SAME_THREAD();
-  grpc_custom_timer* tw = (grpc_custom_timer*)timer->custom_timer;
+  grpc_custom_timer* tw = static_cast<grpc_custom_timer*>(timer->custom_timer);
   if (timer->pending) {
     timer->pending = false;
     grpc_core::ExecCtx::Run(DEBUG_LOCATION, timer->closure,
index d21b3aa..153fb1d 100644 (file)
@@ -432,7 +432,7 @@ static void timer_init(grpc_timer* timer, grpc_millis deadline,
       note_deadline_change(shard);
       if (shard->shard_queue_index == 0 && deadline < old_min_deadline) {
 #if GPR_ARCH_64
-        // TODO: sreek - Using c-style cast here. static_cast<> gives an error
+        // TODO(sreek): Using c-style cast here. static_cast<> gives an error
         // (on mac platforms complaining that gpr_atm* is (long *) while
         // (&g_shared_mutables.min_timer) is a (long long *). The cast should be
         // safe since we know that both are pointer types and 64-bit wide.
@@ -586,7 +586,7 @@ static grpc_timer_check_result run_some_expired_timers(grpc_millis now,
   grpc_timer_check_result result = GRPC_TIMERS_NOT_CHECKED;
 
 #if GPR_ARCH_64
-  // TODO: sreek - Using c-style cast here. static_cast<> gives an error (on
+  // TODO(sreek): Using c-style cast here. static_cast<> gives an error (on
   // mac platforms complaining that gpr_atm* is (long *) while
   // (&g_shared_mutables.min_timer) is a (long long *). The cast should be
   // safe since we know that both are pointer types and 64-bit wide
@@ -651,7 +651,7 @@ static grpc_timer_check_result run_some_expired_timers(grpc_millis now,
     }
 
 #if GPR_ARCH_64
-    // TODO: sreek - Using c-style cast here. static_cast<> gives an error (on
+    // TODO(sreek): Using c-style cast here. static_cast<> gives an error (on
     // mac platforms complaining that gpr_atm* is (long *) while
     // (&g_shared_mutables.min_timer) is a (long long *). The cast should be
     // safe since we know that both are pointer types and 64-bit wide
index 96d502c..e234727 100644 (file)
@@ -342,8 +342,8 @@ void grpc_timer_manager_shutdown(void) {
   gpr_cv_destroy(&g_cv_shutdown);
 }
 
-void grpc_timer_manager_set_threading(bool threaded) {
-  if (threaded) {
+void grpc_timer_manager_set_threading(bool enabled) {
+  if (enabled) {
     start_threads();
   } else {
     stop_threads();
index 6490c8d..c2eacc5 100644 (file)
@@ -570,8 +570,7 @@ static int add_socket_to_server(grpc_udp_server* s, int fd,
   return port;
 }
 
-int grpc_udp_server_add_port(grpc_udp_server* s,
-                             const grpc_resolved_address* addr,
+int grpc_udp_server_add_port(grpc_udp_server* s, grpc_resolved_address* addr,
                              int rcv_buf_size, int snd_buf_size,
                              GrpcUdpHandlerFactory* handler_factory,
                              size_t num_listeners) {
index 6cda332..ba7acbb 100644 (file)
@@ -93,8 +93,7 @@ int grpc_udp_server_get_fd(grpc_udp_server* s, unsigned port_index);
 
 /* TODO(ctiller): deprecate this, and make grpc_udp_server_add_ports to handle
                   all of the multiple socket port matching logic in one place */
-int grpc_udp_server_add_port(grpc_udp_server* s,
-                             const grpc_resolved_address* addr,
+int grpc_udp_server_add_port(grpc_udp_server* s, grpc_resolved_address* addr,
                              int rcv_buf_size, int snd_buf_size,
                              GrpcUdpHandlerFactory* handler_factory,
                              size_t num_listeners);
index 4ebd325..034aa91 100644 (file)
@@ -42,24 +42,24 @@ void grpc_create_socketpair_if_unix(int sv[2]) {
   GPR_ASSERT(socketpair(AF_UNIX, SOCK_STREAM, 0, sv) == 0);
 }
 
-grpc_error* grpc_resolve_unix_domain_address(const char* name,
-                                             grpc_resolved_addresses** addrs) {
-  *addrs = static_cast<grpc_resolved_addresses*>(
+grpc_error* grpc_resolve_unix_domain_address(
+    const char* name, grpc_resolved_addresses** addresses) {
+  *addresses = static_cast<grpc_resolved_addresses*>(
       gpr_malloc(sizeof(grpc_resolved_addresses)));
-  (*addrs)->naddrs = 1;
-  (*addrs)->addrs = static_cast<grpc_resolved_address*>(
+  (*addresses)->naddrs = 1;
+  (*addresses)->addrs = static_cast<grpc_resolved_address*>(
       gpr_malloc(sizeof(grpc_resolved_address)));
-  return grpc_core::UnixSockaddrPopulate(name, (*addrs)->addrs);
+  return grpc_core::UnixSockaddrPopulate(name, (*addresses)->addrs);
 }
 
 grpc_error* grpc_resolve_unix_abstract_domain_address(
-    const absl::string_view name, grpc_resolved_addresses** addrs) {
-  *addrs = static_cast<grpc_resolved_addresses*>(
+    const absl::string_view name, grpc_resolved_addresses** addresses) {
+  *addresses = static_cast<grpc_resolved_addresses*>(
       gpr_malloc(sizeof(grpc_resolved_addresses)));
-  (*addrs)->naddrs = 1;
-  (*addrs)->addrs = static_cast<grpc_resolved_address*>(
+  (*addresses)->naddrs = 1;
+  (*addresses)->addrs = static_cast<grpc_resolved_address*>(
       gpr_malloc(sizeof(grpc_resolved_address)));
-  return grpc_core::UnixAbstractSockaddrPopulate(name, (*addrs)->addrs);
+  return grpc_core::UnixAbstractSockaddrPopulate(name, (*addresses)->addrs);
 }
 
 int grpc_is_unix_socket(const grpc_resolved_address* resolved_addr) {
@@ -96,16 +96,15 @@ std::string grpc_sockaddr_to_uri_unix_if_possible(
   if (addr->sa_family != AF_UNIX) {
     return "";
   }
-  if (((struct sockaddr_un*)addr)->sun_path[0] == '\0' &&
-      ((struct sockaddr_un*)addr)->sun_path[1] != '\0') {
-    const struct sockaddr_un* un =
-        reinterpret_cast<const struct sockaddr_un*>(resolved_addr->addr);
+  const auto* unix_addr = reinterpret_cast<const struct sockaddr_un*>(addr);
+  if (unix_addr->sun_path[0] == '\0' && unix_addr->sun_path[1] != '\0') {
     return absl::StrCat(
         "unix-abstract:",
-        absl::string_view(un->sun_path + 1,
-                          resolved_addr->len - sizeof(un->sun_family) - 1));
+        absl::string_view(
+            unix_addr->sun_path + 1,
+            resolved_addr->len - sizeof(unix_addr->sun_family) - 1));
   }
-  return absl::StrCat("unix:", ((struct sockaddr_un*)addr)->sun_path);
+  return absl::StrCat("unix:", unix_addr->sun_path);
 }
 
 #endif
index 4916fe2..9b3e0be 100644 (file)
@@ -76,6 +76,7 @@ class Json {
 
   // Construct from copying a string.
   // If is_number is true, the type will be NUMBER instead of STRING.
+  // NOLINTNEXTLINE(google-explicit-constructor)
   Json(const std::string& string, bool is_number = false)
       : type_(is_number ? Type::NUMBER : Type::STRING), string_value_(string) {}
   Json& operator=(const std::string& string) {
@@ -85,12 +86,14 @@ class Json {
   }
 
   // Same thing for C-style strings, both const and mutable.
+  // NOLINTNEXTLINE(google-explicit-constructor)
   Json(const char* string, bool is_number = false)
       : Json(std::string(string), is_number) {}
   Json& operator=(const char* string) {
     *this = std::string(string);
     return *this;
   }
+  // NOLINTNEXTLINE(google-explicit-constructor)
   Json(char* string, bool is_number = false)
       : Json(std::string(string), is_number) {}
   Json& operator=(char* string) {
@@ -99,6 +102,7 @@ class Json {
   }
 
   // Construct by moving a string.
+  // NOLINTNEXTLINE(google-explicit-constructor)
   Json(std::string&& string)
       : type_(Type::STRING), string_value_(std::move(string)) {}
   Json& operator=(std::string&& string) {
@@ -108,6 +112,7 @@ class Json {
   }
 
   // Construct from bool.
+  // NOLINTNEXTLINE(google-explicit-constructor)
   Json(bool b) : type_(b ? Type::JSON_TRUE : Type::JSON_FALSE) {}
   Json& operator=(bool b) {
     type_ = b ? Type::JSON_TRUE : Type::JSON_FALSE;
@@ -116,6 +121,7 @@ class Json {
 
   // Construct from any numeric type.
   template <typename NumericType>
+  // NOLINTNEXTLINE(google-explicit-constructor)
   Json(NumericType number)
       : type_(Type::NUMBER), string_value_(std::to_string(number)) {}
   template <typename NumericType>
@@ -126,6 +132,7 @@ class Json {
   }
 
   // Construct by copying object.
+  // NOLINTNEXTLINE(google-explicit-constructor)
   Json(const Object& object) : type_(Type::OBJECT), object_value_(object) {}
   Json& operator=(const Object& object) {
     type_ = Type::OBJECT;
@@ -134,6 +141,7 @@ class Json {
   }
 
   // Construct by moving object.
+  // NOLINTNEXTLINE(google-explicit-constructor)
   Json(Object&& object)
       : type_(Type::OBJECT), object_value_(std::move(object)) {}
   Json& operator=(Object&& object) {
@@ -143,6 +151,7 @@ class Json {
   }
 
   // Construct by copying array.
+  // NOLINTNEXTLINE(google-explicit-constructor)
   Json(const Array& array) : type_(Type::ARRAY), array_value_(array) {}
   Json& operator=(const Array& array) {
     type_ = Type::ARRAY;
@@ -151,6 +160,7 @@ class Json {
   }
 
   // Construct by moving array.
+  // NOLINTNEXTLINE(google-explicit-constructor)
   Json(Array&& array) : type_(Type::ARRAY), array_value_(std::move(array)) {}
   Json& operator=(Array&& array) {
     type_ = Type::ARRAY;
index 68f6cb8..6eaf106 100644 (file)
@@ -87,14 +87,12 @@ int EvaluateArgs::GetLocalPort() const {
   if (endpoint_ == nullptr) {
     return 0;
   }
-  grpc_uri* uri = grpc_uri_parse(
-      std::string(grpc_endpoint_get_local_address(endpoint_)).c_str(), true);
+  absl::StatusOr<URI> uri =
+      URI::Parse(grpc_endpoint_get_local_address(endpoint_));
   grpc_resolved_address resolved_addr;
-  if (uri == nullptr || !grpc_parse_uri(uri, &resolved_addr)) {
-    grpc_uri_destroy(uri);
+  if (!uri.ok() || !grpc_parse_uri(*uri, &resolved_addr)) {
     return 0;
   }
-  grpc_uri_destroy(uri);
   return grpc_sockaddr_get_port(&resolved_addr);
 }
 
@@ -113,14 +111,11 @@ int EvaluateArgs::GetPeerPort() const {
   if (endpoint_ == nullptr) {
     return 0;
   }
-  grpc_uri* uri = grpc_uri_parse(
-      std::string(grpc_endpoint_get_peer(endpoint_)).c_str(), true);
+  absl::StatusOr<URI> uri = URI::Parse(grpc_endpoint_get_peer(endpoint_));
   grpc_resolved_address resolved_addr;
-  if (uri == nullptr || !grpc_parse_uri(uri, &resolved_addr)) {
-    grpc_uri_destroy(uri);
+  if (!uri.ok() || !grpc_parse_uri(*uri, &resolved_addr)) {
     return 0;
   }
-  grpc_uri_destroy(uri);
   return grpc_sockaddr_get_port(&resolved_addr);
 }
 
index e258f72..14e25bc 100644 (file)
@@ -46,7 +46,7 @@ class EvaluateArgs {
   absl::string_view GetSpiffeId() const;
   absl::string_view GetCertServerName() const;
 
-  // TODO: Add a getter function for source.principal
+  // TODO(unknown): Add a getter function for source.principal
 
  private:
   grpc_metadata_batch* metadata_;
index ef60165..d760d82 100644 (file)
@@ -294,9 +294,10 @@ static const grpc_arg_pointer_vtable auth_context_pointer_vtable = {
     auth_context_pointer_arg_copy, auth_context_pointer_arg_destroy,
     auth_context_pointer_cmp};
 
-grpc_arg grpc_auth_context_to_arg(grpc_auth_context* p) {
-  return grpc_channel_arg_pointer_create((char*)GRPC_AUTH_CONTEXT_ARG, p,
-                                         &auth_context_pointer_vtable);
+grpc_arg grpc_auth_context_to_arg(grpc_auth_context* c) {
+  return grpc_channel_arg_pointer_create(
+      const_cast<char*>(GRPC_AUTH_CONTEXT_ARG), c,
+      &auth_context_pointer_vtable);
 }
 
 grpc_auth_context* grpc_auth_context_from_arg(const grpc_arg* arg) {
index 9c98d7a..f3370a3 100644 (file)
@@ -57,7 +57,7 @@ namespace internal {
 char* read_bios_file(const char* bios_file) {
   FILE* fp = fopen(bios_file, "r");
   if (!fp) {
-    gpr_log(GPR_ERROR, "BIOS data file cannot be opened.");
+    gpr_log(GPR_INFO, "BIOS data file does not exist or cannot be opened.");
     return nullptr;
   }
   char buf[kBiosDataBufferSize + 1];
index 309ace8..d2f4c9c 100644 (file)
@@ -67,9 +67,9 @@ static const grpc_arg_pointer_vtable credentials_pointer_vtable = {
 
 grpc_arg grpc_channel_credentials_to_arg(
     grpc_channel_credentials* credentials) {
-  return grpc_channel_arg_pointer_create((char*)GRPC_ARG_CHANNEL_CREDENTIALS,
-                                         credentials,
-                                         &credentials_pointer_vtable);
+  return grpc_channel_arg_pointer_create(
+      const_cast<char*>(GRPC_ARG_CHANNEL_CREDENTIALS), credentials,
+      &credentials_pointer_vtable);
 }
 
 grpc_channel_credentials* grpc_channel_credentials_from_arg(
@@ -134,9 +134,9 @@ static const grpc_arg_pointer_vtable cred_ptr_vtable = {
     server_credentials_pointer_arg_copy, server_credentials_pointer_arg_destroy,
     server_credentials_pointer_cmp};
 
-grpc_arg grpc_server_credentials_to_arg(grpc_server_credentials* p) {
-  return grpc_channel_arg_pointer_create((char*)GRPC_SERVER_CREDENTIALS_ARG, p,
-                                         &cred_ptr_vtable);
+grpc_arg grpc_server_credentials_to_arg(grpc_server_credentials* c) {
+  return grpc_channel_arg_pointer_create(
+      const_cast<char*>(GRPC_SERVER_CREDENTIALS_ARG), c, &cred_ptr_vtable);
 }
 
 grpc_server_credentials* grpc_server_credentials_from_arg(const grpc_arg* arg) {
diff --git a/src/core/lib/security/credentials/external/aws_external_account_credentials.cc b/src/core/lib/security/credentials/external/aws_external_account_credentials.cc
new file mode 100644 (file)
index 0000000..e9d60ea
--- /dev/null
@@ -0,0 +1,413 @@
+//
+// 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>
+
+#include "src/core/lib/security/credentials/external/aws_external_account_credentials.h"
+
+#include "absl/strings/str_format.h"
+#include "absl/strings/str_join.h"
+#include "absl/strings/str_replace.h"
+
+#include "src/core/lib/gpr/env.h"
+
+namespace grpc_core {
+
+namespace {
+
+const char* kExpectedEnvironmentId = "aws1";
+
+const char* kRegionEnvVar = "AWS_REGION";
+const char* kAccessKeyIdEnvVar = "AWS_ACCESS_KEY_ID";
+const char* kSecretAccessKeyEnvVar = "AWS_SECRET_ACCESS_KEY";
+const char* kSessionTokenEnvVar = "AWS_SESSION_TOKEN";
+
+std::string UrlEncode(const absl::string_view& s) {
+  const char* hex = "0123456789ABCDEF";
+  std::string result;
+  result.reserve(s.length());
+  for (auto c : s) {
+    if ((c >= '0' && c <= '9') || (c >= 'A' && c <= 'Z') ||
+        (c >= 'a' && c <= 'z') || c == '-' || c == '_' || c == '!' ||
+        c == '\'' || c == '(' || c == ')' || c == '*' || c == '~' || c == '.') {
+      result.push_back(c);
+    } else {
+      result.push_back('%');
+      result.push_back(hex[static_cast<unsigned char>(c) >> 4]);
+      result.push_back(hex[static_cast<unsigned char>(c) & 15]);
+    }
+  }
+  return result;
+}
+
+}  // namespace
+
+RefCountedPtr<AwsExternalAccountCredentials>
+AwsExternalAccountCredentials::Create(Options options,
+                                      std::vector<std::string> scopes,
+                                      grpc_error** error) {
+  auto creds = MakeRefCounted<AwsExternalAccountCredentials>(
+      std::move(options), std::move(scopes), error);
+  if (*error == GRPC_ERROR_NONE) {
+    return creds;
+  } else {
+    return nullptr;
+  }
+}
+
+AwsExternalAccountCredentials::AwsExternalAccountCredentials(
+    Options options, std::vector<std::string> scopes, grpc_error** error)
+    : ExternalAccountCredentials(options, std::move(scopes)) {
+  audience_ = options.audience;
+  auto it = options.credential_source.object_value().find("environment_id");
+  if (it == options.credential_source.object_value().end()) {
+    *error = GRPC_ERROR_CREATE_FROM_STATIC_STRING(
+        "environment_id field not present.");
+    return;
+  }
+  if (it->second.type() != Json::Type::STRING) {
+    *error = GRPC_ERROR_CREATE_FROM_STATIC_STRING(
+        "environment_id field must be a string.");
+    return;
+  }
+  if (it->second.string_value() != kExpectedEnvironmentId) {
+    *error =
+        GRPC_ERROR_CREATE_FROM_STATIC_STRING("environment_id does not match.");
+    return;
+  }
+  it = options.credential_source.object_value().find("region_url");
+  if (it == options.credential_source.object_value().end()) {
+    *error =
+        GRPC_ERROR_CREATE_FROM_STATIC_STRING("region_url field not present.");
+    return;
+  }
+  if (it->second.type() != Json::Type::STRING) {
+    *error = GRPC_ERROR_CREATE_FROM_STATIC_STRING(
+        "region_url field must be a string.");
+    return;
+  }
+  region_url_ = it->second.string_value();
+  it = options.credential_source.object_value().find("url");
+  if (it != options.credential_source.object_value().end() &&
+      it->second.type() == Json::Type::STRING) {
+    url_ = it->second.string_value();
+  }
+  it = options.credential_source.object_value().find(
+      "regional_cred_verification_url");
+  if (it == options.credential_source.object_value().end()) {
+    *error = GRPC_ERROR_CREATE_FROM_STATIC_STRING(
+        "regional_cred_verification_url field not present.");
+    return;
+  }
+  if (it->second.type() != Json::Type::STRING) {
+    *error = GRPC_ERROR_CREATE_FROM_STATIC_STRING(
+        "regional_cred_verification_url field must be a string.");
+    return;
+  }
+  regional_cred_verification_url_ = it->second.string_value();
+}
+
+void AwsExternalAccountCredentials::RetrieveSubjectToken(
+    HTTPRequestContext* ctx, const Options& options,
+    std::function<void(std::string, grpc_error*)> cb) {
+  if (ctx == nullptr) {
+    FinishRetrieveSubjectToken(
+        "",
+        GRPC_ERROR_CREATE_FROM_STATIC_STRING(
+            "Missing HTTPRequestContext to start subject token retrieval."));
+    return;
+  }
+  ctx_ = ctx;
+  cb_ = cb;
+  if (signer_ != nullptr) {
+    BuildSubjectToken();
+  } else {
+    RetrieveRegion();
+  }
+}
+
+void AwsExternalAccountCredentials::RetrieveRegion() {
+  UniquePtr<char> region_from_env(gpr_getenv(kRegionEnvVar));
+  if (region_from_env != nullptr) {
+    region_ = std::string(region_from_env.get());
+    if (url_.empty()) {
+      RetrieveSigningKeys();
+    } else {
+      RetrieveRoleName();
+    }
+    return;
+  }
+  absl::StatusOr<URI> uri = URI::Parse(region_url_);
+  if (!uri.ok()) {
+    FinishRetrieveSubjectToken("", GRPC_ERROR_CREATE_FROM_COPIED_STRING(
+                                       absl::StrFormat("Invalid region url. %s",
+                                                       uri.status().ToString())
+                                           .c_str()));
+    return;
+  }
+  grpc_httpcli_request request;
+  memset(&request, 0, sizeof(grpc_httpcli_request));
+  request.host = const_cast<char*>(uri->authority().c_str());
+  request.http.path = gpr_strdup(uri->path().c_str());
+  request.handshaker =
+      uri->scheme() == "https" ? &grpc_httpcli_ssl : &grpc_httpcli_plaintext;
+  grpc_resource_quota* resource_quota =
+      grpc_resource_quota_create("external_account_credentials");
+  grpc_http_response_destroy(&ctx_->response);
+  ctx_->response = {};
+  GRPC_CLOSURE_INIT(&ctx_->closure, OnRetrieveRegion, this, nullptr);
+  grpc_httpcli_get(ctx_->httpcli_context, ctx_->pollent, resource_quota,
+                   &request, ctx_->deadline, &ctx_->closure, &ctx_->response);
+  grpc_resource_quota_unref_internal(resource_quota);
+  grpc_http_request_destroy(&request.http);
+}
+
+void AwsExternalAccountCredentials::OnRetrieveRegion(void* arg,
+                                                     grpc_error* error) {
+  AwsExternalAccountCredentials* self =
+      static_cast<AwsExternalAccountCredentials*>(arg);
+  self->OnRetrieveRegionInternal(GRPC_ERROR_REF(error));
+}
+
+void AwsExternalAccountCredentials::OnRetrieveRegionInternal(
+    grpc_error* error) {
+  if (error != GRPC_ERROR_NONE) {
+    FinishRetrieveSubjectToken("", error);
+    return;
+  }
+  // Remove the last letter of availability zone to get pure region
+  absl::string_view response_body(ctx_->response.body,
+                                  ctx_->response.body_length);
+  region_ = std::string(response_body.substr(0, response_body.size() - 1));
+  if (url_.empty()) {
+    RetrieveSigningKeys();
+  } else {
+    RetrieveRoleName();
+  }
+}
+
+void AwsExternalAccountCredentials::RetrieveRoleName() {
+  absl::StatusOr<URI> uri = URI::Parse(url_);
+  if (!uri.ok()) {
+    FinishRetrieveSubjectToken(
+        "", GRPC_ERROR_CREATE_FROM_COPIED_STRING(
+                absl::StrFormat("Invalid url: %s.", uri.status().ToString())
+                    .c_str()));
+    return;
+  }
+  grpc_httpcli_request request;
+  memset(&request, 0, sizeof(grpc_httpcli_request));
+  request.host = const_cast<char*>(uri->authority().c_str());
+  request.http.path = gpr_strdup(uri->path().c_str());
+  request.handshaker =
+      uri->scheme() == "https" ? &grpc_httpcli_ssl : &grpc_httpcli_plaintext;
+  grpc_resource_quota* resource_quota =
+      grpc_resource_quota_create("external_account_credentials");
+  grpc_http_response_destroy(&ctx_->response);
+  ctx_->response = {};
+  GRPC_CLOSURE_INIT(&ctx_->closure, OnRetrieveRoleName, this, nullptr);
+  grpc_httpcli_get(ctx_->httpcli_context, ctx_->pollent, resource_quota,
+                   &request, ctx_->deadline, &ctx_->closure, &ctx_->response);
+  grpc_resource_quota_unref_internal(resource_quota);
+  grpc_http_request_destroy(&request.http);
+}
+
+void AwsExternalAccountCredentials::OnRetrieveRoleName(void* arg,
+                                                       grpc_error* error) {
+  AwsExternalAccountCredentials* self =
+      static_cast<AwsExternalAccountCredentials*>(arg);
+  self->OnRetrieveRoleNameInternal(GRPC_ERROR_REF(error));
+}
+
+void AwsExternalAccountCredentials::OnRetrieveRoleNameInternal(
+    grpc_error* error) {
+  if (error != GRPC_ERROR_NONE) {
+    FinishRetrieveSubjectToken("", error);
+    return;
+  }
+  role_name_ = std::string(ctx_->response.body, ctx_->response.body_length);
+  RetrieveSigningKeys();
+}
+
+void AwsExternalAccountCredentials::RetrieveSigningKeys() {
+  UniquePtr<char> access_key_id_from_env(gpr_getenv(kAccessKeyIdEnvVar));
+  UniquePtr<char> secret_access_key_from_env(
+      gpr_getenv(kSecretAccessKeyEnvVar));
+  UniquePtr<char> token_from_env(gpr_getenv(kSessionTokenEnvVar));
+  if (access_key_id_from_env != nullptr &&
+      secret_access_key_from_env != nullptr && token_from_env != nullptr) {
+    access_key_id_ = std::string(access_key_id_from_env.get());
+    secret_access_key_ = std::string(secret_access_key_from_env.get());
+    token_ = std::string(token_from_env.get());
+    BuildSubjectToken();
+    return;
+  }
+  if (role_name_.empty()) {
+    FinishRetrieveSubjectToken(
+        "", GRPC_ERROR_CREATE_FROM_STATIC_STRING(
+                "Missing role name when retrieving signing keys."));
+    return;
+  }
+  std::string url_with_role_name = absl::StrCat(url_, "/", role_name_);
+  absl::StatusOr<URI> uri = URI::Parse(url_with_role_name);
+  if (!uri.ok()) {
+    FinishRetrieveSubjectToken(
+        "", GRPC_ERROR_CREATE_FROM_COPIED_STRING(
+                absl::StrFormat("Invalid url with role name: %s.",
+                                uri.status().ToString())
+                    .c_str()));
+    return;
+  }
+  grpc_httpcli_request request;
+  memset(&request, 0, sizeof(grpc_httpcli_request));
+  request.host = const_cast<char*>(uri->authority().c_str());
+  request.http.path = gpr_strdup(uri->path().c_str());
+  request.handshaker =
+      uri->scheme() == "https" ? &grpc_httpcli_ssl : &grpc_httpcli_plaintext;
+  grpc_resource_quota* resource_quota =
+      grpc_resource_quota_create("external_account_credentials");
+  grpc_http_response_destroy(&ctx_->response);
+  ctx_->response = {};
+  GRPC_CLOSURE_INIT(&ctx_->closure, OnRetrieveSigningKeys, this, nullptr);
+  grpc_httpcli_get(ctx_->httpcli_context, ctx_->pollent, resource_quota,
+                   &request, ctx_->deadline, &ctx_->closure, &ctx_->response);
+  grpc_resource_quota_unref_internal(resource_quota);
+  grpc_http_request_destroy(&request.http);
+}
+
+void AwsExternalAccountCredentials::OnRetrieveSigningKeys(void* arg,
+                                                          grpc_error* error) {
+  AwsExternalAccountCredentials* self =
+      static_cast<AwsExternalAccountCredentials*>(arg);
+  self->OnRetrieveSigningKeysInternal(GRPC_ERROR_REF(error));
+}
+
+void AwsExternalAccountCredentials::OnRetrieveSigningKeysInternal(
+    grpc_error* error) {
+  if (error != GRPC_ERROR_NONE) {
+    FinishRetrieveSubjectToken("", error);
+    return;
+  }
+  absl::string_view response_body(ctx_->response.body,
+                                  ctx_->response.body_length);
+  Json json = Json::Parse(response_body, &error);
+  if (error != GRPC_ERROR_NONE || json.type() != Json::Type::OBJECT) {
+    FinishRetrieveSubjectToken(
+        "", GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING(
+                "Invalid retrieve signing keys response.", &error, 1));
+    GRPC_ERROR_UNREF(error);
+    return;
+  }
+  auto it = json.object_value().find("AccessKeyId");
+  if (it != json.object_value().end() &&
+      it->second.type() == Json::Type::STRING) {
+    access_key_id_ = it->second.string_value();
+  } else {
+    FinishRetrieveSubjectToken(
+        "", GRPC_ERROR_CREATE_FROM_COPIED_STRING(
+                absl::StrFormat("Missing or invalid AccessKeyId in %s.",
+                                response_body)
+                    .c_str()));
+    return;
+  }
+  it = json.object_value().find("SecretAccessKey");
+  if (it != json.object_value().end() &&
+      it->second.type() == Json::Type::STRING) {
+    secret_access_key_ = it->second.string_value();
+  } else {
+    FinishRetrieveSubjectToken(
+        "", GRPC_ERROR_CREATE_FROM_COPIED_STRING(
+                absl::StrFormat("Missing or invalid SecretAccessKey in %s.",
+                                response_body)
+                    .c_str()));
+    return;
+  }
+  it = json.object_value().find("Token");
+  if (it != json.object_value().end() &&
+      it->second.type() == Json::Type::STRING) {
+    token_ = it->second.string_value();
+  } else {
+    FinishRetrieveSubjectToken(
+        "",
+        GRPC_ERROR_CREATE_FROM_COPIED_STRING(
+            absl::StrFormat("Missing or invalid Token in %s.", response_body)
+                .c_str()));
+    return;
+  }
+  BuildSubjectToken();
+}
+
+void AwsExternalAccountCredentials::BuildSubjectToken() {
+  grpc_error* error = GRPC_ERROR_NONE;
+  if (signer_ == nullptr) {
+    cred_verification_url_ = absl::StrReplaceAll(
+        regional_cred_verification_url_, {{"{region}", region_}});
+    signer_ = absl::make_unique<AwsRequestSigner>(
+        access_key_id_, secret_access_key_, token_, "POST",
+        cred_verification_url_, region_, "",
+        std::map<std::string, std::string>(), &error);
+    if (error != GRPC_ERROR_NONE) {
+      FinishRetrieveSubjectToken(
+          "", GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING(
+                  "Creating aws request signer failed.", &error, 1));
+      GRPC_ERROR_UNREF(error);
+      return;
+    }
+  }
+  auto signed_headers = signer_->GetSignedRequestHeaders();
+  if (error != GRPC_ERROR_NONE) {
+    FinishRetrieveSubjectToken("",
+                               GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING(
+                                   "Invalid getting signed request"
+                                   "headers.",
+                                   &error, 1));
+    GRPC_ERROR_UNREF(error);
+    return;
+  }
+  // Construct subject token
+  Json::Array headers;
+  headers.push_back(Json(
+      {{"key", "Authorization"}, {"value", signed_headers["Authorization"]}}));
+  headers.push_back(Json({{"key", "host"}, {"value", signed_headers["host"]}}));
+  headers.push_back(
+      Json({{"key", "x-amz-date"}, {"value", signed_headers["x-amz-date"]}}));
+  headers.push_back(Json({{"key", "x-amz-security-token"},
+                          {"value", signed_headers["x-amz-security-token"]}}));
+  headers.push_back(
+      Json({{"key", "x-goog-cloud-target-resource"}, {"value", audience_}}));
+  Json::Object object{{"url", Json(cred_verification_url_)},
+                      {"method", Json("POST")},
+                      {"headers", Json(headers)}};
+  Json subject_token_json(object);
+  std::string subject_token = UrlEncode(subject_token_json.Dump());
+  FinishRetrieveSubjectToken(subject_token, GRPC_ERROR_NONE);
+}
+
+void AwsExternalAccountCredentials::FinishRetrieveSubjectToken(
+    std::string subject_token, grpc_error* error) {
+  // Reset context
+  ctx_ = nullptr;
+  // Move object state into local variables.
+  auto cb = cb_;
+  cb_ = nullptr;
+  // Invoke the callback.
+  if (error != GRPC_ERROR_NONE) {
+    cb("", error);
+  } else {
+    cb(subject_token, GRPC_ERROR_NONE);
+  }
+}
+
+}  // namespace grpc_core
diff --git a/src/core/lib/security/credentials/external/aws_external_account_credentials.h b/src/core/lib/security/credentials/external/aws_external_account_credentials.h
new file mode 100644 (file)
index 0000000..edb7e82
--- /dev/null
@@ -0,0 +1,80 @@
+//
+// 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_CORE_LIB_SECURITY_CREDENTIALS_EXTERNAL_AWS_EXTERNAL_ACCOUNT_CREDENTIALS_H
+#define GRPC_CORE_LIB_SECURITY_CREDENTIALS_EXTERNAL_AWS_EXTERNAL_ACCOUNT_CREDENTIALS_H
+
+#include <grpc/support/port_platform.h>
+
+#include "src/core/lib/security/credentials/external/external_account_credentials.h"
+
+#include "src/core/lib/security/credentials/external/aws_request_signer.h"
+
+namespace grpc_core {
+
+class AwsExternalAccountCredentials final : public ExternalAccountCredentials {
+ public:
+  static RefCountedPtr<AwsExternalAccountCredentials> Create(
+      Options options, std::vector<std::string> scopes, grpc_error** error);
+
+  AwsExternalAccountCredentials(Options options,
+                                std::vector<std::string> scopes,
+                                grpc_error** error);
+
+ private:
+  void RetrieveSubjectToken(
+      HTTPRequestContext* ctx, const Options& options,
+      std::function<void(std::string, grpc_error*)> cb) override;
+
+  void RetrieveRegion();
+  static void OnRetrieveRegion(void* arg, grpc_error* error);
+  void OnRetrieveRegionInternal(grpc_error* error);
+
+  void RetrieveRoleName();
+  static void OnRetrieveRoleName(void* arg, grpc_error* error);
+  void OnRetrieveRoleNameInternal(grpc_error* error);
+
+  void RetrieveSigningKeys();
+  static void OnRetrieveSigningKeys(void* arg, grpc_error* error);
+  void OnRetrieveSigningKeysInternal(grpc_error* error);
+
+  void BuildSubjectToken();
+  void FinishRetrieveSubjectToken(std::string subject_token, grpc_error* error);
+
+  std::string audience_;
+
+  // Fields of credential source
+  std::string region_url_;
+  std::string url_;
+  std::string regional_cred_verification_url_;
+
+  // Information required by request signer
+  std::string region_;
+  std::string role_name_;
+  std::string access_key_id_;
+  std::string secret_access_key_;
+  std::string token_;
+
+  std::unique_ptr<AwsRequestSigner> signer_;
+  std::string cred_verification_url_;
+
+  HTTPRequestContext* ctx_ = nullptr;
+  std::function<void(std::string, grpc_error*)> cb_ = nullptr;
+};
+
+}  // namespace grpc_core
+
+#endif  // GRPC_CORE_LIB_SECURITY_CREDENTIALS_EXTERNAL_AWS_EXTERNAL_ACCOUNT_CREDENTIALS_H
index d4c80e6..af8531e 100644 (file)
@@ -55,7 +55,8 @@ std::string HMAC(const std::string& key, const std::string& msg) {
   unsigned int len;
   unsigned char digest[EVP_MAX_MD_SIZE];
   HMAC(EVP_sha256(), key.c_str(), key.length(),
-       (const unsigned char*)msg.c_str(), msg.length(), digest, &len);
+       reinterpret_cast<const unsigned char*>(msg.c_str()), msg.length(),
+       digest, &len);
   return std::string(digest, digest + len);
 }
 
@@ -94,15 +95,14 @@ AwsRequestSigner::AwsRequestSigner(
     static_request_date_ =
         absl::FormatTime(kXAmzDateFormat, request_date, absl::UTCTimeZone());
   }
-  url_ = grpc_uri_parse(url, false);
-  if (url_ == nullptr) {
+  absl::StatusOr<URI> tmp_url = URI::Parse(url);
+  if (!tmp_url.ok()) {
     *error = GRPC_ERROR_CREATE_FROM_STATIC_STRING("Invalid Aws request url.");
     return;
   }
+  url_ = tmp_url.value();
 }
 
-AwsRequestSigner::~AwsRequestSigner() { grpc_uri_destroy(url_); }
-
 std::map<std::string, std::string> AwsRequestSigner::GetSignedRequestHeaders() {
   std::string request_date_full;
   if (!static_request_date_.empty()) {
@@ -123,15 +123,20 @@ std::map<std::string, std::string> AwsRequestSigner::GetSignedRequestHeaders() {
   canonical_request_vector.emplace_back(method_);
   canonical_request_vector.emplace_back("\n");
   // 2. CanonicalURI
-
-  canonical_request_vector.emplace_back(*url_->path == '\0' ? "/" : url_->path);
+  canonical_request_vector.emplace_back(
+      url_.path().empty() ? "/" : absl::string_view(url_.path()));
   canonical_request_vector.emplace_back("\n");
   // 3. CanonicalQueryString
-  canonical_request_vector.emplace_back(url_->query);
+  std::vector<std::string> query_vector;
+  for (const URI::QueryParam& query_kv : url_.query_parameter_pairs()) {
+    query_vector.emplace_back(absl::StrCat(query_kv.key, "=", query_kv.value));
+  }
+  std::string query = absl::StrJoin(query_vector, "&");
+  canonical_request_vector.emplace_back(query);
   canonical_request_vector.emplace_back("\n");
   // 4. CanonicalHeaders
   if (request_headers_.empty()) {
-    request_headers_.insert({"host", url_->authority});
+    request_headers_.insert({"host", url_.authority()});
     if (!token_.empty()) {
       request_headers_.insert({"x-amz-security-token", token_});
     }
@@ -176,7 +181,7 @@ std::map<std::string, std::string> AwsRequestSigner::GetSignedRequestHeaders() {
   string_to_sign_vector.emplace_back("\n");
   // 3. CredentialScope
   std::pair<absl::string_view, absl::string_view> host_parts =
-      absl::StrSplit(url_->authority, absl::MaxSplits('.', 1));
+      absl::StrSplit(url_.authority(), absl::MaxSplits('.', 1));
   std::string service_name(host_parts.first);
   std::string credential_scope = absl::StrFormat(
       "%s/%s/%s/aws4_request", request_date_short, region_, service_name);
index a4823e0..62e112c 100644 (file)
@@ -46,7 +46,6 @@ class AwsRequestSigner {
                    std::string region, std::string request_payload,
                    std::map<std::string, std::string> additional_headers,
                    grpc_error** error);
-  ~AwsRequestSigner();
 
   // This method triggers the signing process then returns the headers of the
   // signed request as a map. In case there is an error, the input `error`
@@ -59,7 +58,7 @@ class AwsRequestSigner {
   std::string secret_access_key_;
   std::string token_;
   std::string method_;
-  grpc_uri* url_ = nullptr;
+  URI url_;
   std::string region_;
   std::string request_payload_;
   std::map<std::string, std::string> additional_headers_;
index 599b718..127a5f3 100644 (file)
@@ -19,6 +19,7 @@
 
 #include "absl/strings/str_format.h"
 #include "absl/strings/str_join.h"
+#include "absl/strings/str_split.h"
 #include "absl/time/clock.h"
 #include "absl/time/time.h"
 
 #include "src/core/lib/security/util/json_util.h"
 #include "src/core/lib/slice/b64.h"
 
+#include "src/core/lib/security/credentials/external/aws_external_account_credentials.h"
+#include "src/core/lib/security/credentials/external/file_external_account_credentials.h"
+#include "src/core/lib/security/credentials/external/url_external_account_credentials.h"
+
 #define EXTERNAL_ACCOUNT_CREDENTIALS_GRANT_TYPE \
   "urn:ietf:params:oauth:grant-type:token-exchange"
 #define EXTERNAL_ACCOUNT_CREDENTIALS_REQUESTED_TOKEN_TYPE \
 
 namespace grpc_core {
 
+namespace {
+
+std::string UrlEncode(const absl::string_view& s) {
+  const char* hex = "0123456789ABCDEF";
+  std::string result;
+  result.reserve(s.length());
+  for (auto c : s) {
+    if ((c >= '0' && c <= '9') || (c >= 'A' && c <= 'Z') ||
+        (c >= 'a' && c <= 'z') || c == '-' || c == '_' || c == '!' ||
+        c == '\'' || c == '(' || c == ')' || c == '*' || c == '~' || c == '.') {
+      result.push_back(c);
+    } else {
+      result.push_back('%');
+      result.push_back(hex[static_cast<unsigned char>(c) >> 4]);
+      result.push_back(hex[static_cast<unsigned char>(c) & 15]);
+    }
+  }
+  return result;
+}
+
+}  // namespace
+
+RefCountedPtr<ExternalAccountCredentials> ExternalAccountCredentials::Create(
+    const Json& json, std::vector<std::string> scopes, grpc_error** error) {
+  GPR_ASSERT(*error == GRPC_ERROR_NONE);
+  Options options;
+  options.type = GRPC_AUTH_JSON_TYPE_INVALID;
+  if (json.type() != Json::Type::OBJECT) {
+    *error = GRPC_ERROR_CREATE_FROM_STATIC_STRING(
+        "Invalid json to construct credentials options.");
+    return nullptr;
+  }
+  auto it = json.object_value().find("type");
+  if (it == json.object_value().end()) {
+    *error = GRPC_ERROR_CREATE_FROM_STATIC_STRING("type field not present.");
+    return nullptr;
+  }
+  if (it->second.type() != Json::Type::STRING) {
+    *error =
+        GRPC_ERROR_CREATE_FROM_STATIC_STRING("type field must be a string.");
+    return nullptr;
+  }
+  if (it->second.string_value() != GRPC_AUTH_JSON_TYPE_EXTERNAL_ACCOUNT) {
+    *error =
+        GRPC_ERROR_CREATE_FROM_STATIC_STRING("Invalid credentials json type.");
+    return nullptr;
+  }
+  options.type = GRPC_AUTH_JSON_TYPE_EXTERNAL_ACCOUNT;
+  it = json.object_value().find("audience");
+  if (it == json.object_value().end()) {
+    *error =
+        GRPC_ERROR_CREATE_FROM_STATIC_STRING("audience field not present.");
+    return nullptr;
+  }
+  if (it->second.type() != Json::Type::STRING) {
+    *error = GRPC_ERROR_CREATE_FROM_STATIC_STRING(
+        "audience field must be a string.");
+    return nullptr;
+  }
+  options.audience = it->second.string_value();
+  it = json.object_value().find("subject_token_type");
+  if (it == json.object_value().end()) {
+    *error = GRPC_ERROR_CREATE_FROM_STATIC_STRING(
+        "subject_token_type field not present.");
+    return nullptr;
+  }
+  if (it->second.type() != Json::Type::STRING) {
+    *error = GRPC_ERROR_CREATE_FROM_STATIC_STRING(
+        "subject_token_type field must be a string.");
+    return nullptr;
+  }
+  options.subject_token_type = it->second.string_value();
+  it = json.object_value().find("service_account_impersonation_url");
+  if (it != json.object_value().end()) {
+    options.service_account_impersonation_url = it->second.string_value();
+  }
+  it = json.object_value().find("token_url");
+  if (it == json.object_value().end()) {
+    *error =
+        GRPC_ERROR_CREATE_FROM_STATIC_STRING("token_url field not present.");
+    return nullptr;
+  }
+  if (it->second.type() != Json::Type::STRING) {
+    *error = GRPC_ERROR_CREATE_FROM_STATIC_STRING(
+        "token_url field must be a string.");
+    return nullptr;
+  }
+  options.token_url = it->second.string_value();
+  it = json.object_value().find("token_info_url");
+  if (it != json.object_value().end()) {
+    options.token_info_url = it->second.string_value();
+  }
+  it = json.object_value().find("credential_source");
+  if (it == json.object_value().end()) {
+    *error = GRPC_ERROR_CREATE_FROM_STATIC_STRING(
+        "credential_source field not present.");
+    return nullptr;
+  }
+  options.credential_source = it->second;
+  it = json.object_value().find("quota_project_id");
+  if (it != json.object_value().end()) {
+    options.quota_project_id = it->second.string_value();
+  }
+  it = json.object_value().find("client_id");
+  if (it != json.object_value().end()) {
+    options.client_id = it->second.string_value();
+  }
+  it = json.object_value().find("client_secret");
+  if (it != json.object_value().end()) {
+    options.client_secret = it->second.string_value();
+  }
+  RefCountedPtr<ExternalAccountCredentials> creds;
+  if (options.credential_source.object_value().find("environment_id") !=
+      options.credential_source.object_value().end()) {
+    creds = MakeRefCounted<AwsExternalAccountCredentials>(
+        std::move(options), std::move(scopes), error);
+  } else if (options.credential_source.object_value().find("file") !=
+             options.credential_source.object_value().end()) {
+    creds = MakeRefCounted<FileExternalAccountCredentials>(
+        std::move(options), std::move(scopes), error);
+  } else if (options.credential_source.object_value().find("url") !=
+             options.credential_source.object_value().end()) {
+    creds = MakeRefCounted<UrlExternalAccountCredentials>(
+        std::move(options), std::move(scopes), error);
+  } else {
+    *error = GRPC_ERROR_CREATE_FROM_STATIC_STRING(
+        "Invalid options credential source to create "
+        "ExternalAccountCredentials.");
+  }
+  if (*error == GRPC_ERROR_NONE) {
+    return creds;
+  } else {
+    return nullptr;
+  }
+}
+
 ExternalAccountCredentials::ExternalAccountCredentials(
-    ExternalAccountCredentialsOptions options, std::vector<std::string> scopes)
+    Options options, std::vector<std::string> scopes)
     : options_(std::move(options)) {
   if (scopes.empty()) {
     scopes.push_back(GOOGLE_CLOUD_PLATFORM_DEFAULT_SCOPE);
@@ -89,16 +230,18 @@ void ExternalAccountCredentials::OnRetrieveSubjectTokenInternal(
 
 void ExternalAccountCredentials::ExchangeToken(
     absl::string_view subject_token) {
-  grpc_uri* uri = grpc_uri_parse(options_.token_url, false);
-  if (uri == nullptr) {
+  absl::StatusOr<URI> uri = URI::Parse(options_.token_url);
+  if (!uri.ok()) {
     FinishTokenFetch(GRPC_ERROR_CREATE_FROM_COPIED_STRING(
-        absl::StrFormat("Invalid token url: %s.", options_.token_url).c_str()));
+        absl::StrFormat("Invalid token url: %s. Error: %s", options_.token_url,
+                        uri.status().ToString())
+            .c_str()));
     return;
   }
   grpc_httpcli_request request;
   memset(&request, 0, sizeof(grpc_httpcli_request));
-  request.host = const_cast<char*>(uri->authority);
-  request.http.path = gpr_strdup(uri->path);
+  request.host = const_cast<char*>(uri->authority().c_str());
+  request.http.path = gpr_strdup(uri->path().c_str());
   grpc_http_header* headers = nullptr;
   if (!options_.client_id.empty() && !options_.client_secret.empty()) {
     request.http.hdr_count = 2;
@@ -122,25 +265,28 @@ void ExternalAccountCredentials::ExchangeToken(
     headers[0].value = gpr_strdup("application/x-www-form-urlencoded");
   }
   request.http.hdrs = headers;
-  request.handshaker = (strcmp(uri->scheme, "https") == 0)
-                           ? &grpc_httpcli_ssl
-                           : &grpc_httpcli_plaintext;
+  request.handshaker =
+      uri->scheme() == "https" ? &grpc_httpcli_ssl : &grpc_httpcli_plaintext;
   std::vector<std::string> body_parts;
-  body_parts.push_back(absl::StrFormat("%s=%s", "audience", options_.audience));
+  body_parts.push_back(absl::StrFormat("%s=%s", "audience",
+                                       UrlEncode(options_.audience).c_str()));
   body_parts.push_back(absl::StrFormat(
-      "%s=%s", "grant_type", EXTERNAL_ACCOUNT_CREDENTIALS_GRANT_TYPE));
-  body_parts.push_back(
-      absl::StrFormat("%s=%s", "requested_token_type",
-                      EXTERNAL_ACCOUNT_CREDENTIALS_REQUESTED_TOKEN_TYPE));
-  body_parts.push_back(absl::StrFormat("%s=%s", "subject_token_type",
-                                       options_.subject_token_type));
+      "%s=%s", "grant_type",
+      UrlEncode(EXTERNAL_ACCOUNT_CREDENTIALS_GRANT_TYPE).c_str()));
+  body_parts.push_back(absl::StrFormat(
+      "%s=%s", "requested_token_type",
+      UrlEncode(EXTERNAL_ACCOUNT_CREDENTIALS_REQUESTED_TOKEN_TYPE).c_str()));
   body_parts.push_back(
-      absl::StrFormat("%s=%s", "subject_token", subject_token));
+      absl::StrFormat("%s=%s", "subject_token_type",
+                      UrlEncode(options_.subject_token_type).c_str()));
+  body_parts.push_back(absl::StrFormat("%s=%s", "subject_token",
+                                       UrlEncode(subject_token).c_str()));
   std::string scope = GOOGLE_CLOUD_PLATFORM_DEFAULT_SCOPE;
   if (options_.service_account_impersonation_url.empty()) {
     scope = absl::StrJoin(scopes_, " ");
   }
-  body_parts.push_back(absl::StrFormat("%s=%s", "scope", scope));
+  body_parts.push_back(
+      absl::StrFormat("%s=%s", "scope", UrlEncode(scope).c_str()));
   std::string body = absl::StrJoin(body_parts, "&");
   grpc_resource_quota* resource_quota =
       grpc_resource_quota_create("external_account_credentials");
@@ -152,7 +298,6 @@ void ExternalAccountCredentials::ExchangeToken(
                     &ctx_->closure, &ctx_->response);
   grpc_resource_quota_unref_internal(resource_quota);
   grpc_http_request_destroy(&request.http);
-  grpc_uri_destroy(uri);
 }
 
 void ExternalAccountCredentials::OnExchangeToken(void* arg, grpc_error* error) {
@@ -167,7 +312,16 @@ void ExternalAccountCredentials::OnExchangeTokenInternal(grpc_error* error) {
   } else {
     if (options_.service_account_impersonation_url.empty()) {
       metadata_req_->response = ctx_->response;
-      metadata_req_->response.body = gpr_strdup(ctx_->response.body);
+      metadata_req_->response.body = gpr_strdup(
+          std::string(ctx_->response.body, ctx_->response.body_length).c_str());
+      metadata_req_->response.hdrs = static_cast<grpc_http_header*>(
+          gpr_malloc(sizeof(grpc_http_header) * ctx_->response.hdr_count));
+      for (int i = 0; i < ctx_->response.hdr_count; i++) {
+        metadata_req_->response.hdrs[i].key =
+            gpr_strdup(ctx_->response.hdrs[i].key);
+        metadata_req_->response.hdrs[i].value =
+            gpr_strdup(ctx_->response.hdrs[i].value);
+      }
       FinishTokenFetch(GRPC_ERROR_NONE);
     } else {
       ImpersenateServiceAccount();
@@ -195,19 +349,20 @@ void ExternalAccountCredentials::ImpersenateServiceAccount() {
     return;
   }
   std::string access_token = it->second.string_value();
-  grpc_uri* uri =
-      grpc_uri_parse(options_.service_account_impersonation_url, false);
-  if (uri == nullptr) {
+  absl::StatusOr<URI> uri =
+      URI::Parse(options_.service_account_impersonation_url);
+  if (!uri.ok()) {
     FinishTokenFetch(GRPC_ERROR_CREATE_FROM_COPIED_STRING(
-        absl::StrFormat("Invalid service account impersonation url: %s.",
-                        options_.service_account_impersonation_url)
+        absl::StrFormat(
+            "Invalid service account impersonation url: %s. Error: %s",
+            options_.service_account_impersonation_url, uri.status().ToString())
             .c_str()));
     return;
   }
   grpc_httpcli_request request;
   memset(&request, 0, sizeof(grpc_httpcli_request));
-  request.host = const_cast<char*>(uri->authority);
-  request.http.path = gpr_strdup(uri->path);
+  request.host = const_cast<char*>(uri->authority().c_str());
+  request.http.path = gpr_strdup(uri->path().c_str());
   request.http.hdr_count = 2;
   grpc_http_header* headers = static_cast<grpc_http_header*>(
       gpr_malloc(sizeof(grpc_http_header) * request.http.hdr_count));
@@ -217,9 +372,8 @@ void ExternalAccountCredentials::ImpersenateServiceAccount() {
   headers[1].key = gpr_strdup("Authorization");
   headers[1].value = gpr_strdup(str.c_str());
   request.http.hdrs = headers;
-  request.handshaker = (strcmp(uri->scheme, "https") == 0)
-                           ? &grpc_httpcli_ssl
-                           : &grpc_httpcli_plaintext;
+  request.handshaker =
+      uri->scheme() == "https" ? &grpc_httpcli_ssl : &grpc_httpcli_plaintext;
   std::string scope = absl::StrJoin(scopes_, " ");
   std::string body = absl::StrFormat("%s=%s", "scope", scope);
   grpc_resource_quota* resource_quota =
@@ -232,7 +386,6 @@ void ExternalAccountCredentials::ImpersenateServiceAccount() {
                     &ctx_->closure, &ctx_->response);
   grpc_resource_quota_unref_internal(resource_quota);
   grpc_http_request_destroy(&request.http);
-  grpc_uri_destroy(uri);
 }
 
 void ExternalAccountCredentials::OnImpersenateServiceAccount(
@@ -288,6 +441,14 @@ void ExternalAccountCredentials::OnImpersenateServiceAccountInternal(
   metadata_req_->response = ctx_->response;
   metadata_req_->response.body = gpr_strdup(body.c_str());
   metadata_req_->response.body_length = body.length();
+  metadata_req_->response.hdrs = static_cast<grpc_http_header*>(
+      gpr_malloc(sizeof(grpc_http_header) * ctx_->response.hdr_count));
+  for (int i = 0; i < ctx_->response.hdr_count; i++) {
+    metadata_req_->response.hdrs[i].key =
+        gpr_strdup(ctx_->response.hdrs[i].key);
+    metadata_req_->response.hdrs[i].value =
+        gpr_strdup(ctx_->response.hdrs[i].value);
+  }
   FinishTokenFetch(GRPC_ERROR_NONE);
 }
 
@@ -309,3 +470,28 @@ void ExternalAccountCredentials::FinishTokenFetch(grpc_error* error) {
 }
 
 }  // namespace grpc_core
+
+grpc_call_credentials* grpc_external_account_credentials_create(
+    const char* json_string, const char* scopes_string) {
+  grpc_error* error = GRPC_ERROR_NONE;
+  grpc_core::Json json = grpc_core::Json::Parse(json_string, &error);
+  if (error != GRPC_ERROR_NONE) {
+    gpr_log(GPR_ERROR,
+            "External account credentials creation failed. Error: %s.",
+            grpc_error_string(error));
+    GRPC_ERROR_UNREF(error);
+    return nullptr;
+  }
+  std::vector<std::string> scopes = absl::StrSplit(scopes_string, ',');
+  auto creds = grpc_core::ExternalAccountCredentials::Create(
+                   json, std::move(scopes), &error)
+                   .release();
+  if (error != GRPC_ERROR_NONE) {
+    gpr_log(GPR_ERROR,
+            "External account credentials creation failed. Error: %s.",
+            grpc_error_string(error));
+    GRPC_ERROR_UNREF(error);
+    return nullptr;
+  }
+  return creds;
+}
index 04f09d4..0da7786 100644 (file)
@@ -35,7 +35,7 @@ class ExternalAccountCredentials
     : public grpc_oauth2_token_fetcher_credentials {
  public:
   // External account credentials json interface.
-  struct ExternalAccountCredentialsOptions {
+  struct Options {
     std::string type;
     std::string audience;
     std::string subject_token_type;
@@ -48,8 +48,10 @@ class ExternalAccountCredentials
     std::string client_secret;
   };
 
-  ExternalAccountCredentials(ExternalAccountCredentialsOptions options,
-                             std::vector<std::string> scopes);
+  static RefCountedPtr<ExternalAccountCredentials> Create(
+      const Json& json, std::vector<std::string> scopes, grpc_error** error);
+
+  ExternalAccountCredentials(Options options, std::vector<std::string> scopes);
   ~ExternalAccountCredentials() override;
   std::string debug_string() override;
 
@@ -81,7 +83,7 @@ class ExternalAccountCredentials
   // the callback function (cb) to pass the subject token (or error)
   // back.
   virtual void RetrieveSubjectToken(
-      HTTPRequestContext* ctx, const ExternalAccountCredentialsOptions& options,
+      HTTPRequestContext* ctx, const Options& options,
       std::function<void(std::string, grpc_error*)> cb) = 0;
 
  private:
@@ -105,7 +107,7 @@ class ExternalAccountCredentials
 
   void FinishTokenFetch(grpc_error* error);
 
-  ExternalAccountCredentialsOptions options_;
+  Options options_;
   std::vector<std::string> scopes_;
 
   HTTPRequestContext* ctx_ = nullptr;
index f2724f0..730c095 100644 (file)
@@ -26,9 +26,9 @@
 namespace grpc_core {
 
 RefCountedPtr<FileExternalAccountCredentials>
-FileExternalAccountCredentials::Create(
-    ExternalAccountCredentialsOptions options, std::vector<std::string> scopes,
-    grpc_error** error) {
+FileExternalAccountCredentials::Create(Options options,
+                                       std::vector<std::string> scopes,
+                                       grpc_error** error) {
   auto creds = MakeRefCounted<FileExternalAccountCredentials>(
       std::move(options), std::move(scopes), error);
   if (*error == GRPC_ERROR_NONE) {
@@ -39,8 +39,7 @@ FileExternalAccountCredentials::Create(
 }
 
 FileExternalAccountCredentials::FileExternalAccountCredentials(
-    ExternalAccountCredentialsOptions options, std::vector<std::string> scopes,
-    grpc_error** error)
+    Options options, std::vector<std::string> scopes, grpc_error** error)
     : ExternalAccountCredentials(options, std::move(scopes)) {
   auto it = options.credential_source.object_value().find("file");
   if (it == options.credential_source.object_value().end()) {
@@ -92,7 +91,7 @@ FileExternalAccountCredentials::FileExternalAccountCredentials(
 }
 
 void FileExternalAccountCredentials::RetrieveSubjectToken(
-    HTTPRequestContext* ctx, const ExternalAccountCredentialsOptions& options,
+    HTTPRequestContext* ctx, const Options& options,
     std::function<void(std::string, grpc_error*)> cb) {
   struct SliceWrapper {
     ~SliceWrapper() { grpc_slice_unref_internal(slice); }
index 49b4d31..7df5b6b 100644 (file)
@@ -26,16 +26,15 @@ namespace grpc_core {
 class FileExternalAccountCredentials final : public ExternalAccountCredentials {
  public:
   static RefCountedPtr<FileExternalAccountCredentials> Create(
-      ExternalAccountCredentialsOptions options,
-      std::vector<std::string> scopes, grpc_error** error);
+      Options options, std::vector<std::string> scopes, grpc_error** error);
 
-  FileExternalAccountCredentials(ExternalAccountCredentialsOptions options,
+  FileExternalAccountCredentials(Options options,
                                  std::vector<std::string> scopes,
                                  grpc_error** error);
 
  private:
   void RetrieveSubjectToken(
-      HTTPRequestContext* ctx, const ExternalAccountCredentialsOptions& options,
+      HTTPRequestContext* ctx, const Options& options,
       std::function<void(std::string, grpc_error*)> cb) override;
 
   // Fields of credential source
index 43029e0..85d09be 100644 (file)
 
 #include "src/core/lib/security/credentials/external/url_external_account_credentials.h"
 
+#include "absl/strings/str_cat.h"
 #include "absl/strings/str_format.h"
+#include "absl/strings/str_split.h"
 
 namespace grpc_core {
 
 RefCountedPtr<UrlExternalAccountCredentials>
-UrlExternalAccountCredentials::Create(ExternalAccountCredentialsOptions options,
+UrlExternalAccountCredentials::Create(Options options,
                                       std::vector<std::string> scopes,
                                       grpc_error** error) {
   auto creds = MakeRefCounted<UrlExternalAccountCredentials>(
@@ -35,8 +37,7 @@ UrlExternalAccountCredentials::Create(ExternalAccountCredentialsOptions options,
 }
 
 UrlExternalAccountCredentials::UrlExternalAccountCredentials(
-    ExternalAccountCredentialsOptions options, std::vector<std::string> scopes,
-    grpc_error** error)
+    Options options, std::vector<std::string> scopes, grpc_error** error)
     : ExternalAccountCredentials(options, std::move(scopes)) {
   auto it = options.credential_source.object_value().find("url");
   if (it == options.credential_source.object_value().end()) {
@@ -48,13 +49,19 @@ UrlExternalAccountCredentials::UrlExternalAccountCredentials(
         GRPC_ERROR_CREATE_FROM_STATIC_STRING("url field must be a string.");
     return;
   }
-  grpc_uri* url = grpc_uri_parse(it->second.string_value(), false);
-  if (url == nullptr) {
-    *error =
-        GRPC_ERROR_CREATE_FROM_STATIC_STRING("Invalid credential source url.");
+  absl::StatusOr<URI> tmp_url = URI::Parse(it->second.string_value());
+  if (!tmp_url.ok()) {
+    *error = GRPC_ERROR_CREATE_FROM_COPIED_STRING(
+        absl::StrFormat("Invalid credential source url. Error: %s",
+                        tmp_url.status().ToString())
+            .c_str());
     return;
   }
-  url_ = url;
+  url_ = *tmp_url;
+  // The url must follow the format of <scheme>://<authority>/<path>
+  std::vector<absl::string_view> v =
+      absl::StrSplit(it->second.string_value(), absl::MaxSplits('/', 3));
+  url_full_path_ = absl::StrCat("/", v[3]);
   it = options.credential_source.object_value().find("headers");
   if (it != options.credential_source.object_value().end()) {
     if (it->second.type() != Json::Type::OBJECT) {
@@ -104,12 +111,8 @@ UrlExternalAccountCredentials::UrlExternalAccountCredentials(
   }
 }
 
-UrlExternalAccountCredentials::~UrlExternalAccountCredentials() {
-  grpc_uri_destroy(url_);
-}
-
 void UrlExternalAccountCredentials::RetrieveSubjectToken(
-    HTTPRequestContext* ctx, const ExternalAccountCredentialsOptions& options,
+    HTTPRequestContext* ctx, const Options& options,
     std::function<void(std::string, grpc_error*)> cb) {
   if (ctx == nullptr) {
     FinishRetrieveSubjectToken(
@@ -122,8 +125,8 @@ void UrlExternalAccountCredentials::RetrieveSubjectToken(
   cb_ = cb;
   grpc_httpcli_request request;
   memset(&request, 0, sizeof(grpc_httpcli_request));
-  request.host = const_cast<char*>(url_->authority);
-  request.http.path = gpr_strdup(url_->path);
+  request.host = const_cast<char*>(url_.authority().c_str());
+  request.http.path = gpr_strdup(url_full_path_.c_str());
   grpc_http_header* headers = nullptr;
   request.http.hdr_count = headers_.size();
   headers = static_cast<grpc_http_header*>(
@@ -135,9 +138,8 @@ void UrlExternalAccountCredentials::RetrieveSubjectToken(
     ++i;
   }
   request.http.hdrs = headers;
-  request.handshaker = (strcmp(url_->scheme, "https") == 0)
-                           ? &grpc_httpcli_ssl
-                           : &grpc_httpcli_plaintext;
+  request.handshaker =
+      url_.scheme() == "https" ? &grpc_httpcli_ssl : &grpc_httpcli_plaintext;
   grpc_resource_quota* resource_quota =
       grpc_resource_quota_create("external_account_credentials");
   grpc_http_response_destroy(&ctx_->response);
index 8383ab5..4e37c57 100644 (file)
@@ -26,17 +26,15 @@ namespace grpc_core {
 class UrlExternalAccountCredentials final : public ExternalAccountCredentials {
  public:
   static RefCountedPtr<UrlExternalAccountCredentials> Create(
-      ExternalAccountCredentialsOptions options,
-      std::vector<std::string> scopes, grpc_error** error);
+      Options options, std::vector<std::string> scopes, grpc_error** error);
 
-  UrlExternalAccountCredentials(ExternalAccountCredentialsOptions options,
+  UrlExternalAccountCredentials(Options options,
                                 std::vector<std::string> scopes,
                                 grpc_error** error);
-  ~UrlExternalAccountCredentials() override;
 
  private:
   void RetrieveSubjectToken(
-      HTTPRequestContext* ctx, const ExternalAccountCredentialsOptions& options,
+      HTTPRequestContext* ctx, const Options& options,
       std::function<void(std::string, grpc_error*)> cb) override;
 
   static void OnRetrieveSubjectToken(void* arg, grpc_error* error);
@@ -45,7 +43,8 @@ class UrlExternalAccountCredentials final : public ExternalAccountCredentials {
   void FinishRetrieveSubjectToken(std::string subject_token, grpc_error* error);
 
   // Fields of credential source
-  grpc_uri* url_ = nullptr;
+  URI url_;
+  std::string url_full_path_;
   std::map<std::string, std::string> headers_;
   std::string format_type_;
   std::string format_subject_token_field_name_;
index 8fd0493..eef636d 100644 (file)
@@ -76,7 +76,8 @@ grpc_fake_transport_security_server_credentials_create() {
 
 grpc_arg grpc_fake_transport_expected_targets_arg(char* expected_targets) {
   return grpc_channel_arg_string_create(
-      (char*)GRPC_ARG_FAKE_SECURITY_EXPECTED_TARGETS, expected_targets);
+      const_cast<char*>(GRPC_ARG_FAKE_SECURITY_EXPECTED_TARGETS),
+      expected_targets);
 }
 
 const char* grpc_fake_transport_get_expected_targets(
index 9162bad..d1de87d 100644 (file)
@@ -27,6 +27,7 @@
 #include <grpc/support/sync.h>
 
 #include "src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.h"
+#include "src/core/ext/filters/client_channel/lb_policy/xds/xds_channel_args.h"
 #include "src/core/lib/channel/channel_args.h"
 #include "src/core/lib/gpr/env.h"
 #include "src/core/lib/gpr/string.h"
@@ -37,6 +38,7 @@
 #include "src/core/lib/iomgr/polling_entity.h"
 #include "src/core/lib/security/credentials/alts/alts_credentials.h"
 #include "src/core/lib/security/credentials/alts/check_gcp_environment.h"
+#include "src/core/lib/security/credentials/external/external_account_credentials.h"
 #include "src/core/lib/security/credentials/google_default/google_default_credentials.h"
 #include "src/core/lib/security/credentials/jwt/jwt_credentials.h"
 #include "src/core/lib/security/credentials/oauth2/oauth2_credentials.h"
@@ -80,21 +82,22 @@ grpc_google_default_channel_credentials::create_security_connector(
     grpc_core::RefCountedPtr<grpc_call_credentials> call_creds,
     const char* target, const grpc_channel_args* args,
     grpc_channel_args** new_args) {
-  bool is_grpclb_load_balancer = grpc_channel_arg_get_bool(
-      grpc_channel_args_find(args, GRPC_ARG_ADDRESS_IS_GRPCLB_LOAD_BALANCER),
-      false);
-  bool is_backend_from_grpclb_load_balancer = grpc_channel_arg_get_bool(
-      grpc_channel_args_find(
-          args, GRPC_ARG_ADDRESS_IS_BACKEND_FROM_GRPCLB_LOAD_BALANCER),
-      false);
-  bool use_alts =
-      is_grpclb_load_balancer || is_backend_from_grpclb_load_balancer;
+  const bool is_grpclb_load_balancer = grpc_channel_args_find_bool(
+      args, GRPC_ARG_ADDRESS_IS_GRPCLB_LOAD_BALANCER, false);
+  const bool is_backend_from_grpclb_load_balancer = grpc_channel_args_find_bool(
+      args, GRPC_ARG_ADDRESS_IS_BACKEND_FROM_GRPCLB_LOAD_BALANCER, false);
+  const char* xds_cluster =
+      grpc_channel_args_find_string(args, GRPC_ARG_XDS_CLUSTER_NAME);
+  const bool is_xds_non_cfe_cluster =
+      xds_cluster != nullptr && strcmp(xds_cluster, "google_cfe") != 0;
+  const bool use_alts = is_grpclb_load_balancer ||
+                        is_backend_from_grpclb_load_balancer ||
+                        is_xds_non_cfe_cluster;
   /* Return failure if ALTS is selected but not running on GCE. */
   if (use_alts && alts_creds_ == nullptr) {
     gpr_log(GPR_ERROR, "ALTS is selected, but not running on GCE.");
     return nullptr;
   }
-
   grpc_core::RefCountedPtr<grpc_channel_security_connector> sc =
       use_alts ? alts_creds_->create_security_connector(call_creds, target,
                                                         args, new_args)
@@ -175,8 +178,8 @@ static int is_metadata_server_reachable() {
   detector.is_done = 0;
   detector.success = 0;
   memset(&request, 0, sizeof(grpc_httpcli_request));
-  request.host = (char*)GRPC_COMPUTE_ENGINE_DETECTION_HOST;
-  request.http.path = (char*)"/";
+  request.host = const_cast<char*>(GRPC_COMPUTE_ENGINE_DETECTION_HOST);
+  request.http.path = const_cast<char*>("/");
   grpc_httpcli_context_init(&context);
   grpc_resource_quota* resource_quota =
       grpc_resource_quota_create("google_default_credentials");
@@ -267,6 +270,9 @@ static grpc_error* create_default_creds_from_path(
     goto end;
   }
 
+  /* Finally try an external account credentials.*/
+  result = grpc_core::ExternalAccountCredentials::Create(json, {}, &error);
+
 end:
   GPR_ASSERT((result == nullptr) + (error == GRPC_ERROR_NONE) == 1);
   grpc_slice_unref_internal(creds_data);
index 820fc47..01c1ad7 100644 (file)
@@ -30,12 +30,10 @@ constexpr char kCredentialsTypeInsecure[] = "insecure";
 
 class InsecureCredentials final : public grpc_channel_credentials {
  public:
-  explicit InsecureCredentials()
-      : grpc_channel_credentials(kCredentialsTypeInsecure) {}
+  InsecureCredentials() : grpc_channel_credentials(kCredentialsTypeInsecure) {}
 
-  grpc_core::RefCountedPtr<grpc_channel_security_connector>
-  create_security_connector(
-      grpc_core::RefCountedPtr<grpc_call_credentials> call_creds,
+  RefCountedPtr<grpc_channel_security_connector> create_security_connector(
+      RefCountedPtr<grpc_call_credentials> call_creds,
       const char* /* target_name */, const grpc_channel_args* /* args */,
       grpc_channel_args** /* new_args */) override {
     return MakeRefCounted<InsecureChannelSecurityConnector>(
@@ -43,9 +41,24 @@ class InsecureCredentials final : public grpc_channel_credentials {
   }
 };
 
+class InsecureServerCredentials final : public grpc_server_credentials {
+ public:
+  InsecureServerCredentials()
+      : grpc_server_credentials(kCredentialsTypeInsecure) {}
+
+  RefCountedPtr<grpc_server_security_connector> create_security_connector()
+      override {
+    return MakeRefCounted<InsecureServerSecurityConnector>(Ref());
+  }
+};
+
 }  // namespace
 }  // namespace grpc_core
 
 grpc_channel_credentials* grpc_insecure_credentials_create() {
   return new grpc_core::InsecureCredentials();
 }
+
+grpc_server_credentials* grpc_insecure_server_credentials_create() {
+  return new grpc_core::InsecureServerCredentials();
+}
index 3b61742..8f5a94f 100644 (file)
@@ -112,7 +112,7 @@ grpc_auth_json_key grpc_auth_json_key_create_from_json(const Json& json) {
     goto end;
   }
   result.private_key =
-      PEM_read_bio_RSAPrivateKey(bio, nullptr, nullptr, (void*)"");
+      PEM_read_bio_RSAPrivateKey(bio, nullptr, nullptr, const_cast<char*>(""));
   if (result.private_key == nullptr) {
     gpr_log(GPR_ERROR, "Could not deserialize private key.");
     goto end;
index a6ed657..ec3aed8 100644 (file)
@@ -696,7 +696,7 @@ static void on_openid_config_retrieved(void* user_data, grpc_error* /*error*/) {
   req.host = gpr_strdup(jwks_uri);
   req.http.path = const_cast<char*>(strchr(jwks_uri, '/'));
   if (req.http.path == nullptr) {
-    req.http.path = (char*)"";
+    req.http.path = const_cast<char*>("");
   } else {
     *(req.host + (req.http.path - jwks_uri)) = '\0';
   }
@@ -757,8 +757,8 @@ const char* grpc_jwt_issuer_email_domain(const char* issuer) {
   if (dot == nullptr || dot == email_domain) return email_domain;
   GPR_ASSERT(dot > email_domain);
   /* There may be a subdomain, we just want the domain. */
-  dot = static_cast<const char*>(gpr_memrchr(
-      (void*)email_domain, '.', static_cast<size_t>(dot - email_domain)));
+  dot = static_cast<const char*>(
+      gpr_memrchr(email_domain, '.', static_cast<size_t>(dot - email_domain)));
   if (dot == nullptr) return email_domain;
   return dot + 1;
 }
index 8e1ec57..bbd2cb5 100644 (file)
@@ -386,8 +386,9 @@ class grpc_compute_engine_token_fetcher_credentials
                                const_cast<char*>("Google")};
     grpc_httpcli_request request;
     memset(&request, 0, sizeof(grpc_httpcli_request));
-    request.host = (char*)GRPC_COMPUTE_ENGINE_METADATA_HOST;
-    request.http.path = (char*)GRPC_COMPUTE_ENGINE_METADATA_TOKEN_PATH;
+    request.host = const_cast<char*>(GRPC_COMPUTE_ENGINE_METADATA_HOST);
+    request.http.path =
+        const_cast<char*>(GRPC_COMPUTE_ENGINE_METADATA_TOKEN_PATH);
     request.http.hdr_count = 1;
     request.http.hdrs = &header;
     /* TODO(ctiller): Carry the resource_quota in ctx and share it with the host
@@ -445,8 +446,8 @@ void grpc_google_refresh_token_credentials::fetch_oauth2(
       GRPC_REFRESH_TOKEN_POST_BODY_FORMAT_STRING, refresh_token_.client_id,
       refresh_token_.client_secret, refresh_token_.refresh_token);
   memset(&request, 0, sizeof(grpc_httpcli_request));
-  request.host = (char*)GRPC_GOOGLE_OAUTH2_SERVICE_HOST;
-  request.http.path = (char*)GRPC_GOOGLE_OAUTH2_SERVICE_TOKEN_PATH;
+  request.host = const_cast<char*>(GRPC_GOOGLE_OAUTH2_SERVICE_HOST);
+  request.http.path = const_cast<char*>(GRPC_GOOGLE_OAUTH2_SERVICE_TOKEN_PATH);
   request.http.hdr_count = 1;
   request.http.hdrs = &header;
   request.handshaker = &grpc_httpcli_ssl;
@@ -537,9 +538,9 @@ grpc_error* LoadTokenFile(const char* path, gpr_slice* token) {
 class StsTokenFetcherCredentials
     : public grpc_oauth2_token_fetcher_credentials {
  public:
-  StsTokenFetcherCredentials(grpc_uri* sts_url,  // Ownership transferred.
+  StsTokenFetcherCredentials(URI sts_url,
                              const grpc_sts_credentials_options* options)
-      : sts_url_(sts_url),
+      : sts_url_(std::move(sts_url)),
         resource_(gpr_strdup(options->resource)),
         audience_(gpr_strdup(options->audience)),
         scope_(gpr_strdup(options->scope)),
@@ -549,12 +550,10 @@ class StsTokenFetcherCredentials
         actor_token_path_(gpr_strdup(options->actor_token_path)),
         actor_token_type_(gpr_strdup(options->actor_token_type)) {}
 
-  ~StsTokenFetcherCredentials() override { grpc_uri_destroy(sts_url_); }
-
   std::string debug_string() override {
     return absl::StrFormat(
-        "StsTokenFetcherCredentials{Path:%s,Authority:%s,%s}", sts_url_->path,
-        sts_url_->authority,
+        "StsTokenFetcherCredentials{Path:%s,Authority:%s,%s}", sts_url_.path(),
+        sts_url_.authority(),
         grpc_oauth2_token_fetcher_credentials::debug_string());
   }
 
@@ -577,11 +576,11 @@ class StsTokenFetcherCredentials
         const_cast<char*>("application/x-www-form-urlencoded")};
     grpc_httpcli_request request;
     memset(&request, 0, sizeof(grpc_httpcli_request));
-    request.host = (char*)sts_url_->authority;
-    request.http.path = (char*)sts_url_->path;
+    request.host = const_cast<char*>(sts_url_.authority().c_str());
+    request.http.path = const_cast<char*>(sts_url_.path().c_str());
     request.http.hdr_count = 1;
     request.http.hdrs = &header;
-    request.handshaker = (strcmp(sts_url_->scheme, "https") == 0)
+    request.handshaker = (sts_url_.scheme() == "https")
                              ? &grpc_httpcli_ssl
                              : &grpc_httpcli_plaintext;
     /* TODO(ctiller): Carry the resource_quota in ctx and share it with the host
@@ -641,7 +640,7 @@ class StsTokenFetcherCredentials
     return cleanup();
   }
 
-  grpc_uri* sts_url_;
+  URI sts_url_;
   grpc_closure http_post_cb_closure_;
   grpc_core::UniquePtr<char> resource_;
   grpc_core::UniquePtr<char> audience_;
@@ -655,26 +654,21 @@ class StsTokenFetcherCredentials
 
 }  // namespace
 
-grpc_error* ValidateStsCredentialsOptions(
-    const grpc_sts_credentials_options* options, grpc_uri** sts_url_out) {
-  struct GrpcUriDeleter {
-    void operator()(grpc_uri* uri) { grpc_uri_destroy(uri); }
-  };
-  *sts_url_out = nullptr;
+absl::StatusOr<URI> ValidateStsCredentialsOptions(
+    const grpc_sts_credentials_options* options) {
   absl::InlinedVector<grpc_error*, 3> error_list;
-  std::unique_ptr<grpc_uri, GrpcUriDeleter> sts_url(
-      options->token_exchange_service_uri != nullptr
-          ? grpc_uri_parse(options->token_exchange_service_uri, false)
-          : nullptr);
-  if (sts_url == nullptr) {
+  absl::StatusOr<URI> sts_url =
+      URI::Parse(options->token_exchange_service_uri == nullptr
+                     ? ""
+                     : options->token_exchange_service_uri);
+  if (!sts_url.ok()) {
+    error_list.push_back(GRPC_ERROR_CREATE_FROM_COPIED_STRING(
+        absl::StrFormat("Invalid or missing STS endpoint URL. Error: %s",
+                        sts_url.status().ToString())
+            .c_str()));
+  } else if (sts_url->scheme() != "https" && sts_url->scheme() != "http") {
     error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING(
-        "Invalid or missing STS endpoint URL"));
-  } else {
-    if (strcmp(sts_url->scheme, "https") != 0 &&
-        strcmp(sts_url->scheme, "http") != 0) {
-      error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING(
-          "Invalid URI scheme, must be https to http."));
-    }
+        "Invalid URI scheme, must be https to http."));
   }
   if (options->subject_token_path == nullptr ||
       strlen(options->subject_token_path) == 0) {
@@ -687,12 +681,13 @@ grpc_error* ValidateStsCredentialsOptions(
         "subject_token_type needs to be specified"));
   }
   if (error_list.empty()) {
-    *sts_url_out = sts_url.release();
-    return GRPC_ERROR_NONE;
-  } else {
-    return GRPC_ERROR_CREATE_FROM_VECTOR("Invalid STS Credentials Options",
-                                         &error_list);
+    return sts_url;
   }
+  auto grpc_error_vec = GRPC_ERROR_CREATE_FROM_VECTOR(
+      "Invalid STS Credentials Options", &error_list);
+  auto retval = absl::InvalidArgumentError(grpc_error_string(grpc_error_vec));
+  GRPC_ERROR_UNREF(grpc_error_vec);
+  return retval;
 }
 
 }  // namespace grpc_core
@@ -700,17 +695,15 @@ grpc_error* ValidateStsCredentialsOptions(
 grpc_call_credentials* grpc_sts_credentials_create(
     const grpc_sts_credentials_options* options, void* reserved) {
   GPR_ASSERT(reserved == nullptr);
-  grpc_uri* sts_url;
-  grpc_error* error =
-      grpc_core::ValidateStsCredentialsOptions(options, &sts_url);
-  if (error != GRPC_ERROR_NONE) {
+  absl::StatusOr<grpc_core::URI> sts_url =
+      grpc_core::ValidateStsCredentialsOptions(options);
+  if (!sts_url.ok()) {
     gpr_log(GPR_ERROR, "STS Credentials creation failed. Error: %s.",
-            grpc_error_string(error));
-    GRPC_ERROR_UNREF(error);
+            sts_url.status().ToString().c_str());
     return nullptr;
   }
   return grpc_core::MakeRefCounted<grpc_core::StsTokenFetcherCredentials>(
-             sts_url, options)
+             std::move(*sts_url), options)
       .release();
 }
 
index 2a9b37e..2642919 100644 (file)
@@ -107,7 +107,8 @@ class grpc_oauth2_token_fetcher_credentials : public grpc_call_credentials {
 class grpc_google_refresh_token_credentials final
     : public grpc_oauth2_token_fetcher_credentials {
  public:
-  grpc_google_refresh_token_credentials(grpc_auth_refresh_token refresh_token);
+  explicit grpc_google_refresh_token_credentials(
+      grpc_auth_refresh_token refresh_token);
   ~grpc_google_refresh_token_credentials() override;
 
   const grpc_auth_refresh_token& refresh_token() const {
@@ -130,7 +131,7 @@ class grpc_google_refresh_token_credentials final
 // Access token credentials.
 class grpc_access_token_credentials final : public grpc_call_credentials {
  public:
-  grpc_access_token_credentials(const char* access_token);
+  explicit grpc_access_token_credentials(const char* access_token);
   ~grpc_access_token_credentials() override;
 
   bool get_request_metadata(grpc_polling_entity* pollent,
@@ -164,8 +165,8 @@ namespace grpc_core {
 // Exposed for testing only. This function validates the options, ensuring that
 // the required fields are set, and outputs the parsed URL of the STS token
 // exchanged service.
-grpc_error* ValidateStsCredentialsOptions(
-    const grpc_sts_credentials_options* options, grpc_uri** sts_url);
+absl::StatusOr<URI> ValidateStsCredentialsOptions(
+    const grpc_sts_credentials_options* options);
 }  // namespace grpc_core
 
 #endif /* GRPC_CORE_LIB_SECURITY_CREDENTIALS_OAUTH2_OAUTH2_CREDENTIALS_H */
index 9cb8b81..a5b01cd 100644 (file)
@@ -224,7 +224,7 @@ bool grpc_plugin_credentials::get_request_metadata(
       grpc_slice_unref_internal(creds_md[i].key);
       grpc_slice_unref_internal(creds_md[i].value);
     }
-    gpr_free((void*)error_details);
+    gpr_free(const_cast<char*>(error_details));
     gpr_free(request);
   }
   return retval;
index 3bb7790..e2a1ad0 100644 (file)
@@ -38,8 +38,8 @@ void grpc_tsi_ssl_pem_key_cert_pairs_destroy(tsi_ssl_pem_key_cert_pair* kp,
                                              size_t num_key_cert_pairs) {
   if (kp == nullptr) return;
   for (size_t i = 0; i < num_key_cert_pairs; i++) {
-    gpr_free((void*)kp[i].private_key);
-    gpr_free((void*)kp[i].cert_chain);
+    gpr_free(const_cast<char*>(kp[i].private_key));
+    gpr_free(const_cast<char*>(kp[i].cert_chain));
   }
   gpr_free(kp);
 }
@@ -87,7 +87,7 @@ grpc_ssl_credentials::create_security_connector(
     return sc;
   }
   grpc_arg new_arg = grpc_channel_arg_string_create(
-      (char*)GRPC_ARG_HTTP2_SCHEME, (char*)"https");
+      const_cast<char*>(GRPC_ARG_HTTP2_SCHEME), const_cast<char*>("https"));
   *new_args = grpc_channel_args_copy_and_add(args, &new_arg, 1);
   return sc;
 }
@@ -262,8 +262,8 @@ void grpc_ssl_server_certificate_config_destroy(
     grpc_ssl_server_certificate_config* config) {
   if (config == nullptr) return;
   for (size_t i = 0; i < config->num_key_cert_pairs; i++) {
-    gpr_free((void*)config->pem_key_cert_pairs[i].private_key);
-    gpr_free((void*)config->pem_key_cert_pairs[i].cert_chain);
+    gpr_free(const_cast<char*>(config->pem_key_cert_pairs[i].private_key));
+    gpr_free(const_cast<char*>(config->pem_key_cert_pairs[i].cert_chain));
   }
   gpr_free(config->pem_key_cert_pairs);
   gpr_free(config->pem_root_certs);
index 4c90813..0c5af81 100644 (file)
@@ -64,7 +64,7 @@ struct grpc_ssl_server_certificate_config_fetcher {
 
 class grpc_ssl_server_credentials final : public grpc_server_credentials {
  public:
-  grpc_ssl_server_credentials(
+  explicit grpc_ssl_server_credentials(
       const grpc_ssl_server_credentials_options& options);
   ~grpc_ssl_server_credentials() override;
 
index 2aee165..179df8d 100644 (file)
@@ -337,12 +337,7 @@ void grpc_tls_identity_pairs_add_pair(grpc_tls_identity_pairs* pairs,
   GPR_ASSERT(pairs != nullptr);
   GPR_ASSERT(private_key != nullptr);
   GPR_ASSERT(cert_chain != nullptr);
-  grpc_ssl_pem_key_cert_pair* ssl_pair =
-      static_cast<grpc_ssl_pem_key_cert_pair*>(
-          gpr_malloc(sizeof(grpc_ssl_pem_key_cert_pair)));
-  ssl_pair->private_key = gpr_strdup(private_key);
-  ssl_pair->cert_chain = gpr_strdup(cert_chain);
-  pairs->pem_key_cert_pairs.emplace_back(ssl_pair);
+  pairs->pem_key_cert_pairs.emplace_back(private_key, cert_chain);
 }
 
 void grpc_tls_identity_pairs_destroy(grpc_tls_identity_pairs* pairs) {
index 35451e7..9ce9443 100644 (file)
@@ -72,12 +72,7 @@ struct grpc_tls_certificate_distributor
                          grpc_error* identity_cert_error) = 0;
   };
 
-  // Sets the key materials based on their certificate name. Note that we are
-  // not doing any copies for pem_root_certs and pem_key_cert_pairs. For
-  // pem_root_certs, the original string contents need to outlive the
-  // distributor; for pem_key_cert_pairs, internally it is taking two
-  // unique_ptr(s) to the credential string, so the ownership is actually
-  // transferred.
+  // Sets the key materials based on their certificate name.
   //
   // @param cert_name The name of the certificates being updated.
   // @param pem_root_certs The content of root certificates.
index 80ea4ea..2dae03c 100644 (file)
@@ -22,6 +22,8 @@
 #include <grpc/support/log.h>
 #include <grpc/support/string_util.h>
 
+#include "src/core/lib/gprpp/stat.h"
+#include "src/core/lib/slice/slice_internal.h"
 #include "src/core/lib/surface/api_trace.h"
 
 namespace grpc_core {
@@ -35,20 +37,329 @@ StaticDataCertificateProvider::StaticDataCertificateProvider(
   distributor_->SetWatchStatusCallback([this](std::string cert_name,
                                               bool root_being_watched,
                                               bool identity_being_watched) {
-    if (!root_being_watched && !identity_being_watched) return;
+    grpc_core::MutexLock lock(&mu_);
     absl::optional<std::string> root_certificate;
     absl::optional<grpc_core::PemKeyCertPairList> pem_key_cert_pairs;
-    if (root_being_watched) {
+    StaticDataCertificateProvider::WatcherInfo& info = watcher_info_[cert_name];
+    if (!info.root_being_watched && root_being_watched &&
+        !root_certificate_.empty()) {
       root_certificate = root_certificate_;
     }
-    if (identity_being_watched) {
+    info.root_being_watched = root_being_watched;
+    if (!info.identity_being_watched && identity_being_watched &&
+        !pem_key_cert_pairs_.empty()) {
       pem_key_cert_pairs = pem_key_cert_pairs_;
     }
-    distributor_->SetKeyMaterials(cert_name, std::move(root_certificate),
-                                  std::move(pem_key_cert_pairs));
+    info.identity_being_watched = identity_being_watched;
+    if (!info.root_being_watched && !info.identity_being_watched) {
+      watcher_info_.erase(cert_name);
+    }
+    const bool root_has_update = root_certificate.has_value();
+    const bool identity_has_update = pem_key_cert_pairs.has_value();
+    if (root_has_update || identity_has_update) {
+      distributor_->SetKeyMaterials(cert_name, std::move(root_certificate),
+                                    std::move(pem_key_cert_pairs));
+    }
+    grpc_error* root_cert_error = GRPC_ERROR_NONE;
+    grpc_error* identity_cert_error = GRPC_ERROR_NONE;
+    if (root_being_watched && !root_has_update) {
+      root_cert_error = GRPC_ERROR_CREATE_FROM_STATIC_STRING(
+          "Unable to get latest root certificates.");
+    }
+    if (identity_being_watched && !identity_has_update) {
+      identity_cert_error = GRPC_ERROR_CREATE_FROM_STATIC_STRING(
+          "Unable to get latest identity certificates.");
+    }
+    if (root_cert_error != GRPC_ERROR_NONE ||
+        identity_cert_error != GRPC_ERROR_NONE) {
+      distributor_->SetErrorForCert(cert_name, root_cert_error,
+                                    identity_cert_error);
+    }
+  });
+}
+
+StaticDataCertificateProvider::~StaticDataCertificateProvider() {
+  // Reset distributor's callback to make sure the callback won't be invoked
+  // again after this object(provider) is destroyed.
+  distributor_->SetWatchStatusCallback(nullptr);
+}
+
+namespace {
+
+gpr_timespec TimeoutSecondsToDeadline(int64_t seconds) {
+  return gpr_time_add(gpr_now(GPR_CLOCK_MONOTONIC),
+                      gpr_time_from_seconds(seconds, GPR_TIMESPAN));
+}
+
+}  // namespace
+
+FileWatcherCertificateProvider::FileWatcherCertificateProvider(
+    std::string private_key_path, std::string identity_certificate_path,
+    std::string root_cert_path, unsigned int refresh_interval_sec)
+    : private_key_path_(std::move(private_key_path)),
+      identity_certificate_path_(std::move(identity_certificate_path)),
+      root_cert_path_(std::move(root_cert_path)),
+      refresh_interval_sec_(refresh_interval_sec),
+      distributor_(MakeRefCounted<grpc_tls_certificate_distributor>()) {
+  // Private key and identity cert files must be both set or both unset.
+  GPR_ASSERT(private_key_path_.empty() == identity_certificate_path_.empty());
+  // Must be watching either root or identity certs.
+  GPR_ASSERT(!private_key_path_.empty() || !root_cert_path_.empty());
+  gpr_event_init(&shutdown_event_);
+  ForceUpdate();
+  auto thread_lambda = [](void* arg) {
+    FileWatcherCertificateProvider* provider =
+        static_cast<FileWatcherCertificateProvider*>(arg);
+    GPR_ASSERT(provider != nullptr);
+    while (true) {
+      void* value = gpr_event_wait(
+          &provider->shutdown_event_,
+          TimeoutSecondsToDeadline(provider->refresh_interval_sec_));
+      if (value != nullptr) {
+        return;
+      };
+      provider->ForceUpdate();
+    }
+  };
+  refresh_thread_ = grpc_core::Thread(
+      "FileWatcherCertificateProvider_refreshing_thread", thread_lambda, this);
+  refresh_thread_.Start();
+  distributor_->SetWatchStatusCallback([this](std::string cert_name,
+                                              bool root_being_watched,
+                                              bool identity_being_watched) {
+    grpc_core::MutexLock lock(&mu_);
+    absl::optional<std::string> root_certificate;
+    absl::optional<grpc_core::PemKeyCertPairList> pem_key_cert_pairs;
+    FileWatcherCertificateProvider::WatcherInfo& info =
+        watcher_info_[cert_name];
+    if (!info.root_being_watched && root_being_watched &&
+        !root_certificate_.empty()) {
+      root_certificate = root_certificate_;
+    }
+    info.root_being_watched = root_being_watched;
+    if (!info.identity_being_watched && identity_being_watched &&
+        !pem_key_cert_pairs_.empty()) {
+      pem_key_cert_pairs = pem_key_cert_pairs_;
+    }
+    info.identity_being_watched = identity_being_watched;
+    if (!info.root_being_watched && !info.identity_being_watched) {
+      watcher_info_.erase(cert_name);
+    }
+    ExecCtx exec_ctx;
+    if (root_certificate.has_value() || pem_key_cert_pairs.has_value()) {
+      distributor_->SetKeyMaterials(cert_name, root_certificate,
+                                    pem_key_cert_pairs);
+    }
+    grpc_error* root_cert_error = GRPC_ERROR_NONE;
+    grpc_error* identity_cert_error = GRPC_ERROR_NONE;
+    if (root_being_watched && !root_certificate.has_value()) {
+      root_cert_error = GRPC_ERROR_CREATE_FROM_STATIC_STRING(
+          "Unable to get latest root certificates.");
+    }
+    if (identity_being_watched && !pem_key_cert_pairs.has_value()) {
+      identity_cert_error = GRPC_ERROR_CREATE_FROM_STATIC_STRING(
+          "Unable to get latest identity certificates.");
+    }
+    if (root_cert_error != GRPC_ERROR_NONE ||
+        identity_cert_error != GRPC_ERROR_NONE) {
+      distributor_->SetErrorForCert(cert_name, root_cert_error,
+                                    identity_cert_error);
+    }
   });
 }
 
+FileWatcherCertificateProvider::~FileWatcherCertificateProvider() {
+  // Reset distributor's callback to make sure the callback won't be invoked
+  // again after this object(provider) is destroyed.
+  distributor_->SetWatchStatusCallback(nullptr);
+  gpr_event_set(&shutdown_event_, reinterpret_cast<void*>(1));
+  refresh_thread_.Join();
+}
+
+void FileWatcherCertificateProvider::ForceUpdate() {
+  absl::optional<std::string> root_certificate;
+  absl::optional<grpc_core::PemKeyCertPairList> pem_key_cert_pairs;
+  if (!root_cert_path_.empty()) {
+    root_certificate = ReadRootCertificatesFromFile(root_cert_path_);
+  }
+  if (!private_key_path_.empty()) {
+    pem_key_cert_pairs = ReadIdentityKeyCertPairFromFiles(
+        private_key_path_, identity_certificate_path_);
+  }
+  grpc_core::MutexLock lock(&mu_);
+  const bool root_cert_changed =
+      (!root_certificate.has_value() && !root_certificate_.empty()) ||
+      (root_certificate.has_value() && root_certificate_ != *root_certificate);
+  if (root_cert_changed) {
+    if (root_certificate.has_value()) {
+      root_certificate_ = std::move(*root_certificate);
+    } else {
+      root_certificate_ = "";
+    }
+  }
+  const bool identity_cert_changed =
+      (!pem_key_cert_pairs.has_value() && !pem_key_cert_pairs_.empty()) ||
+      (pem_key_cert_pairs.has_value() &&
+       pem_key_cert_pairs_ != *pem_key_cert_pairs);
+  if (identity_cert_changed) {
+    if (pem_key_cert_pairs.has_value()) {
+      pem_key_cert_pairs_ = std::move(*pem_key_cert_pairs);
+    } else {
+      pem_key_cert_pairs_ = {};
+    }
+  }
+  if (root_cert_changed || identity_cert_changed) {
+    ExecCtx exec_ctx;
+    grpc_error* root_cert_error = GRPC_ERROR_CREATE_FROM_STATIC_STRING(
+        "Unable to get latest root certificates.");
+    grpc_error* identity_cert_error = GRPC_ERROR_CREATE_FROM_STATIC_STRING(
+        "Unable to get latest identity certificates.");
+    for (const auto& p : watcher_info_) {
+      const std::string& cert_name = p.first;
+      const WatcherInfo& info = p.second;
+      absl::optional<std::string> root_to_report;
+      absl::optional<grpc_core::PemKeyCertPairList> identity_to_report;
+      // Set key materials to the distributor if their contents changed.
+      if (info.root_being_watched && !root_certificate_.empty() &&
+          root_cert_changed) {
+        root_to_report = root_certificate_;
+      }
+      if (info.identity_being_watched && !pem_key_cert_pairs_.empty() &&
+          identity_cert_changed) {
+        identity_to_report = pem_key_cert_pairs_;
+      }
+      if (root_to_report.has_value() || identity_to_report.has_value()) {
+        distributor_->SetKeyMaterials(cert_name, std::move(root_to_report),
+                                      std::move(identity_to_report));
+      }
+      // Report errors to the distributor if the contents are empty.
+      const bool report_root_error =
+          info.root_being_watched && root_certificate_.empty();
+      const bool report_identity_error =
+          info.identity_being_watched && pem_key_cert_pairs_.empty();
+      if (report_root_error || report_identity_error) {
+        distributor_->SetErrorForCert(
+            cert_name,
+            report_root_error ? GRPC_ERROR_REF(root_cert_error)
+                              : GRPC_ERROR_NONE,
+            report_identity_error ? GRPC_ERROR_REF(identity_cert_error)
+                                  : GRPC_ERROR_NONE);
+      }
+    }
+    GRPC_ERROR_UNREF(root_cert_error);
+    GRPC_ERROR_UNREF(identity_cert_error);
+  }
+}
+
+absl::optional<std::string>
+FileWatcherCertificateProvider::ReadRootCertificatesFromFile(
+    const std::string& root_cert_full_path) {
+  // Read the root file.
+  grpc_slice root_slice = grpc_empty_slice();
+  grpc_error* root_error =
+      grpc_load_file(root_cert_full_path.c_str(), 0, &root_slice);
+  if (root_error != GRPC_ERROR_NONE) {
+    gpr_log(GPR_ERROR, "Reading file %s failed: %s",
+            root_cert_full_path.c_str(), grpc_error_string(root_error));
+    GRPC_ERROR_UNREF(root_error);
+    return absl::nullopt;
+  }
+  std::string root_cert(StringViewFromSlice(root_slice));
+  grpc_slice_unref_internal(root_slice);
+  return root_cert;
+}
+
+namespace {
+
+// This helper function gets the last-modified time of |filename|. When failed,
+// it logs the error and returns 0.
+time_t GetModificationTime(const char* filename) {
+  time_t ts = 0;
+  absl::Status status = grpc_core::GetFileModificationTime(filename, &ts);
+  return ts;
+}
+
+}  // namespace
+
+absl::optional<PemKeyCertPairList>
+FileWatcherCertificateProvider::ReadIdentityKeyCertPairFromFiles(
+    const std::string& private_key_path,
+    const std::string& identity_certificate_path) {
+  struct SliceWrapper {
+    grpc_slice slice = grpc_empty_slice();
+    ~SliceWrapper() { grpc_slice_unref_internal(slice); }
+  };
+  const int kNumRetryAttempts = 3;
+  for (int i = 0; i < kNumRetryAttempts; ++i) {
+    // TODO(ZhenLian): replace the timestamp approach with key-match approach
+    //  once the latter is implemented.
+    // Checking the last modification of identity files before reading.
+    time_t identity_key_ts_before =
+        GetModificationTime(private_key_path.c_str());
+    if (identity_key_ts_before == 0) {
+      gpr_log(
+          GPR_ERROR,
+          "Failed to get the file's modification time of %s. Start retrying...",
+          private_key_path.c_str());
+      continue;
+    }
+    time_t identity_cert_ts_before =
+        GetModificationTime(identity_certificate_path.c_str());
+    if (identity_cert_ts_before == 0) {
+      gpr_log(
+          GPR_ERROR,
+          "Failed to get the file's modification time of %s. Start retrying...",
+          identity_certificate_path.c_str());
+      continue;
+    }
+    // Read the identity files.
+    SliceWrapper key_slice, cert_slice;
+    grpc_error* key_error =
+        grpc_load_file(private_key_path.c_str(), 0, &key_slice.slice);
+    if (key_error != GRPC_ERROR_NONE) {
+      gpr_log(GPR_ERROR, "Reading file %s failed: %s. Start retrying...",
+              private_key_path.c_str(), grpc_error_string(key_error));
+      GRPC_ERROR_UNREF(key_error);
+      continue;
+    }
+    grpc_error* cert_error =
+        grpc_load_file(identity_certificate_path.c_str(), 0, &cert_slice.slice);
+    if (cert_error != GRPC_ERROR_NONE) {
+      gpr_log(GPR_ERROR, "Reading file %s failed: %s. Start retrying...",
+              identity_certificate_path.c_str(), grpc_error_string(cert_error));
+      GRPC_ERROR_UNREF(cert_error);
+      continue;
+    }
+    std::string private_key(StringViewFromSlice(key_slice.slice));
+    std::string cert_chain(StringViewFromSlice(cert_slice.slice));
+    PemKeyCertPairList identity_pairs;
+    identity_pairs.emplace_back(private_key, cert_chain);
+    // Checking the last modification of identity files before reading.
+    time_t identity_key_ts_after =
+        GetModificationTime(private_key_path.c_str());
+    if (identity_key_ts_before != identity_key_ts_after) {
+      gpr_log(GPR_ERROR,
+              "Last modified time before and after reading %s is not the same. "
+              "Start retrying...",
+              private_key_path.c_str());
+      continue;
+    }
+    time_t identity_cert_ts_after =
+        GetModificationTime(identity_certificate_path.c_str());
+    if (identity_cert_ts_before != identity_cert_ts_after) {
+      gpr_log(GPR_ERROR,
+              "Last modified time before and after reading %s is not the same. "
+              "Start retrying...",
+              identity_certificate_path.c_str());
+      continue;
+    }
+    return identity_pairs;
+  }
+  gpr_log(GPR_ERROR,
+          "All retry attempts failed. Will try again after the next interval.");
+  return absl::nullopt;
+}
+
 }  // namespace grpc_core
 
 /** -- Wrapper APIs declared in grpc_security.h -- **/
@@ -69,6 +380,16 @@ grpc_tls_certificate_provider* grpc_tls_certificate_provider_static_data_create(
       std::move(root_cert_core), std::move(identity_pairs_core));
 }
 
+grpc_tls_certificate_provider*
+grpc_tls_certificate_provider_file_watcher_create(
+    const char* private_key_path, const char* identity_certificate_path,
+    const char* root_cert_path, unsigned int refresh_interval_sec) {
+  return new grpc_core::FileWatcherCertificateProvider(
+      private_key_path == nullptr ? "" : private_key_path,
+      identity_certificate_path == nullptr ? "" : identity_certificate_path,
+      root_cert_path == nullptr ? "" : root_cert_path, refresh_interval_sec);
+}
+
 void grpc_tls_certificate_provider_release(
     grpc_tls_certificate_provider* provider) {
   GRPC_API_TRACE("grpc_tls_certificate_provider_release(provider=%p)", 1,
index dae6fd2..414718d 100644 (file)
@@ -26,6 +26,8 @@
 
 #include "src/core/lib/gprpp/ref_counted.h"
 #include "src/core/lib/gprpp/ref_counted_ptr.h"
+#include "src/core/lib/gprpp/thd.h"
+#include "src/core/lib/iomgr/load_file.h"
 #include "src/core/lib/iomgr/pollset_set.h"
 #include "src/core/lib/security/credentials/tls/grpc_tls_certificate_distributor.h"
 #include "src/core/lib/security/security_connector/ssl_utils.h"
@@ -59,14 +61,76 @@ class StaticDataCertificateProvider final
       std::string root_certificate,
       grpc_core::PemKeyCertPairList pem_key_cert_pairs);
 
+  ~StaticDataCertificateProvider() override;
+
+  RefCountedPtr<grpc_tls_certificate_distributor> distributor() const override {
+    return distributor_;
+  }
+
+ private:
+  struct WatcherInfo {
+    bool root_being_watched = false;
+    bool identity_being_watched = false;
+  };
+  RefCountedPtr<grpc_tls_certificate_distributor> distributor_;
+  std::string root_certificate_;
+  grpc_core::PemKeyCertPairList pem_key_cert_pairs_;
+  // Guards members below.
+  grpc_core::Mutex mu_;
+  // Stores each cert_name we get from the distributor callback and its watcher
+  // information.
+  std::map<std::string, WatcherInfo> watcher_info_;
+};
+
+// A provider class that will watch the credential changes on the file system.
+class FileWatcherCertificateProvider final
+    : public grpc_tls_certificate_provider {
+ public:
+  FileWatcherCertificateProvider(std::string private_key_path,
+                                 std::string identity_certificate_path,
+                                 std::string root_cert_path,
+                                 unsigned int refresh_interval_sec);
+
+  ~FileWatcherCertificateProvider() override;
+
   RefCountedPtr<grpc_tls_certificate_distributor> distributor() const override {
     return distributor_;
   }
 
  private:
+  struct WatcherInfo {
+    bool root_being_watched = false;
+    bool identity_being_watched = false;
+  };
+  // Force an update from the file system regardless of the interval.
+  void ForceUpdate();
+  // Read the root certificates from files and update the distributor.
+  absl::optional<std::string> ReadRootCertificatesFromFile(
+      const std::string& root_cert_full_path);
+  // Read the root certificates from files and update the distributor.
+  absl::optional<PemKeyCertPairList> ReadIdentityKeyCertPairFromFiles(
+      const std::string& private_key_path,
+      const std::string& identity_certificate_path);
+
+  // Information that is used by the refreshing thread.
+  std::string private_key_path_;
+  std::string identity_certificate_path_;
+  std::string root_cert_path_;
+  unsigned int refresh_interval_sec_ = 0;
+
   RefCountedPtr<grpc_tls_certificate_distributor> distributor_;
+  grpc_core::Thread refresh_thread_;
+  gpr_event shutdown_event_;
+
+  // Guards members below.
+  grpc_core::Mutex mu_;
+  // The most-recent credential data. It will be empty if the most recent read
+  // attempt failed.
   std::string root_certificate_;
   grpc_core::PemKeyCertPairList pem_key_cert_pairs_;
+  // Stores each cert_name we get from the distributor callback and its watcher
+  // information.
+  std::map<std::string, WatcherInfo> watcher_info_;
 };
 
 }  // namespace grpc_core
index 12e462b..cf2b4c6 100644 (file)
@@ -46,7 +46,7 @@ grpc_tls_server_authorization_check_config::
 grpc_tls_server_authorization_check_config::
     ~grpc_tls_server_authorization_check_config() {
   if (destruct_ != nullptr) {
-    destruct_((void*)config_user_data_);
+    destruct_(config_user_data_);
   }
 }
 
index c672384..2aae29b 100644 (file)
@@ -147,7 +147,6 @@ struct grpc_tls_credentials_options
     server_authorization_check_config_ = std::move(config);
   }
   // Sets the provider in the options.
-  // This should only be used by C-core API for Tls*Creds case.
   void set_certificate_provider(
       grpc_core::RefCountedPtr<grpc_tls_certificate_provider> provider) {
     provider_ = std::move(provider);
index f2c4b3b..06887e7 100644 (file)
@@ -92,7 +92,7 @@ TlsCredentials::create_security_connector(
   }
   if (args != nullptr) {
     grpc_arg new_arg = grpc_channel_arg_string_create(
-        (char*)GRPC_ARG_HTTP2_SCHEME, (char*)"https");
+        const_cast<char*>(GRPC_ARG_HTTP2_SCHEME), const_cast<char*>("https"));
     *new_args = grpc_channel_args_copy_and_add(args, &new_arg, 1);
   }
   return sc;
diff --git a/src/core/lib/security/credentials/tls/tls_utils.cc b/src/core/lib/security/credentials/tls/tls_utils.cc
new file mode 100644 (file)
index 0000000..b94c2ee
--- /dev/null
@@ -0,0 +1,91 @@
+//
+//
+// 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>
+
+#include "src/core/lib/security/credentials/tls/tls_utils.h"
+
+#include "absl/strings/ascii.h"
+#include "absl/strings/match.h"
+#include "absl/strings/str_cat.h"
+
+namespace grpc_core {
+
+// Based on
+// https://github.com/grpc/grpc-java/blob/ca12e7a339add0ef48202fb72434b9dc0df41756/xds/src/main/java/io/grpc/xds/internal/sds/trust/SdsX509TrustManager.java#L62
+bool VerifySubjectAlternativeName(absl::string_view subject_alternative_name,
+                                  const std::string& matcher) {
+  if (subject_alternative_name.empty() ||
+      absl::StartsWith(subject_alternative_name, ".")) {
+    // Illegal pattern/domain name
+    return false;
+  }
+  if (matcher.empty() || absl::StartsWith(matcher, ".")) {
+    // Illegal domain name
+    return false;
+  }
+  // Normalize \a subject_alternative_name and \a matcher by turning them into
+  // absolute domain names if they are not yet absolute. This is needed because
+  // server certificates do not normally contain absolute names or patterns, but
+  // they should be treated as absolute. At the same time, any
+  // subject_alternative_name presented to this method should also be treated as
+  // absolute for the purposes of matching to the server certificate.
+  std::string normalized_san =
+      absl::EndsWith(subject_alternative_name, ".")
+          ? std::string(subject_alternative_name)
+          : absl::StrCat(subject_alternative_name, ".");
+  std::string normalized_matcher =
+      absl::EndsWith(matcher, ".") ? matcher : absl::StrCat(matcher, ".");
+  absl::AsciiStrToLower(&normalized_san);
+  absl::AsciiStrToLower(&normalized_matcher);
+  if (!absl::StrContains(normalized_san, "*")) {
+    return normalized_san == normalized_matcher;
+  }
+  // WILDCARD PATTERN RULES:
+  // 1. Asterisk (*) is only permitted in the left-most domain name label and
+  //    must be the only character in that label (i.e., must match the whole
+  //    left-most label). For example, *.example.com is permitted, while
+  //    *a.example.com, a*.example.com, a*b.example.com, a.*.example.com are
+  //    not permitted.
+  // 2. Asterisk (*) cannot match across domain name labels.
+  //    For example, *.example.com matches test.example.com but does not match
+  //    sub.test.example.com.
+  // 3. Wildcard patterns for single-label domain names are not permitted.
+  if (!absl::StartsWith(normalized_san, "*.")) {
+    // Asterisk (*) is only permitted in the left-most domain name label and
+    // must be the only character in that label
+    return false;
+  }
+  if (normalized_san == "*.") {
+    // Wildcard pattern for single-label domain name -- not permitted.
+    return false;
+  }
+  absl::string_view suffix = absl::string_view(normalized_san).substr(1);
+  if (absl::StrContains(suffix, "*")) {
+    // Asterisk (*) is not permitted in the suffix
+    return false;
+  }
+  if (!absl::EndsWith(normalized_matcher, suffix)) return false;
+  int suffix_start_index = normalized_matcher.length() - suffix.length();
+  // Asterisk matching across domain labels is not permitted.
+  return suffix_start_index <= 0 /* should not happen */ ||
+         normalized_matcher.find_last_of('.', suffix_start_index - 1) ==
+             std::string::npos;
+}
+
+}  // namespace grpc_core
diff --git a/src/core/lib/security/credentials/tls/tls_utils.h b/src/core/lib/security/credentials/tls/tls_utils.h
new file mode 100644 (file)
index 0000000..6fe9bb4
--- /dev/null
@@ -0,0 +1,38 @@
+//
+//
+// 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_CORE_LIB_SECURITY_CREDENTIALS_TLS_TLS_UTILS_H
+#define GRPC_CORE_LIB_SECURITY_CREDENTIALS_TLS_TLS_UTILS_H
+
+#include <grpc/support/port_platform.h>
+
+#include <string>
+#include <vector>
+
+#include "absl/strings/string_view.h"
+
+namespace grpc_core {
+
+// Matches \a subject_alternative_name with \a matcher. Returns true if there
+// is a match, false otherwise.
+bool VerifySubjectAlternativeName(absl::string_view subject_alternative_name,
+                                  const std::string& matcher);
+
+}  // namespace grpc_core
+
+#endif  // GRPC_CORE_LIB_SECURITY_CREDENTIALS_TLS_TLS_UTILS_H
index 682d49b..9e00f70 100644 (file)
 
 #include "src/core/lib/security/credentials/xds/xds_credentials.h"
 
+#include "src/core/ext/xds/xds_certificate_provider.h"
+#include "src/core/lib/security/credentials/tls/grpc_tls_credentials_options.h"
+#include "src/core/lib/security/credentials/tls/tls_credentials.h"
+#include "src/core/lib/security/credentials/tls/tls_utils.h"
+#include "src/core/lib/uri/uri_parser.h"
+
 namespace grpc_core {
 
-constexpr const char XdsCredentials::kCredentialsTypeXds[];
+const char kCredentialsTypeXds[] = "Xds";
+
+namespace {
+
+bool XdsVerifySubjectAlternativeNames(
+    const char* const* subject_alternative_names,
+    size_t subject_alternative_names_size,
+    const std::vector<XdsApi::StringMatcher>& matchers) {
+  if (matchers.empty()) return true;
+  for (size_t i = 0; i < subject_alternative_names_size; ++i) {
+    for (const auto& matcher : matchers) {
+      if (matcher.type() == XdsApi::StringMatcher::StringMatcherType::EXACT) {
+        // For EXACT match, use DNS rules for verifying SANs
+        // TODO(zhenlian): Right now, the SSL layer does not save the type of
+        // the SAN, so we are doing a DNS style verification for all SANs when
+        // the type is EXACT. When we expose the SAN type, change this to only
+        // do this verification when the SAN type is DNS and match type is
+        // EXACT. For all other cases, we should use matcher.Match().
+        if (VerifySubjectAlternativeName(subject_alternative_names[i],
+                                         matcher.string_matcher())) {
+          return true;
+        }
+      } else {
+        if (matcher.Match(subject_alternative_names[i])) {
+          return true;
+        }
+      }
+    }
+  }
+  return false;
+}
+
+int ServerAuthCheckSchedule(void* config_user_data,
+                            grpc_tls_server_authorization_check_arg* arg) {
+  XdsCertificateProvider* xds_certificate_provider =
+      static_cast<XdsCertificateProvider*>(config_user_data);
+  if (XdsVerifySubjectAlternativeNames(
+          arg->subject_alternative_names, arg->subject_alternative_names_size,
+          xds_certificate_provider->subject_alternative_name_matchers())) {
+    arg->success = 1;
+    arg->status = GRPC_STATUS_OK;
+  } else {
+    arg->success = 0;
+    arg->status = GRPC_STATUS_UNAUTHENTICATED;
+    if (arg->error_details) {
+      arg->error_details->set_error_details(
+          "SANs from certificate did not match SANs from xDS control plane");
+    }
+  }
+
+  return 0; /* synchronous check */
+}
+
+void ServerAuthCheckDestroy(void* config_user_data) {
+  XdsCertificateProvider* xds_certificate_provider =
+      static_cast<XdsCertificateProvider*>(config_user_data);
+  xds_certificate_provider->Unref();
+}
+
+}  // namespace
+
+bool TestOnlyXdsVerifySubjectAlternativeNames(
+    const char* const* subject_alternative_names,
+    size_t subject_alternative_names_size,
+    const std::vector<XdsApi::StringMatcher>& matchers) {
+  return XdsVerifySubjectAlternativeNames(
+      subject_alternative_names, subject_alternative_names_size, matchers);
+}
+
+//
+// XdsCredentials
+//
 
-grpc_core::RefCountedPtr<grpc_channel_security_connector>
+RefCountedPtr<grpc_channel_security_connector>
 XdsCredentials::create_security_connector(
-    grpc_core::RefCountedPtr<grpc_call_credentials> call_creds,
-    const char* target_name, const grpc_channel_args* args,
-    grpc_channel_args** new_args) {
-  /* TODO(yashkt) : To be filled */
-  if (fallback_credentials_ != nullptr) {
-    return fallback_credentials_->create_security_connector(
-        std::move(call_creds), target_name, args, new_args);
+    RefCountedPtr<grpc_call_credentials> call_creds, const char* target_name,
+    const grpc_channel_args* args, grpc_channel_args** new_args) {
+  auto xds_certificate_provider =
+      XdsCertificateProvider::GetFromChannelArgs(args);
+  // TODO(yashykt): This arg will no longer need to be added after b/173119596
+  // is fixed.
+  grpc_arg override_arg = grpc_channel_arg_string_create(
+      const_cast<char*>(GRPC_SSL_TARGET_NAME_OVERRIDE_ARG),
+      const_cast<char*>(target_name));
+  const char* override_arg_name = GRPC_SSL_TARGET_NAME_OVERRIDE_ARG;
+  const grpc_channel_args* temp_args = args;
+  if (grpc_channel_args_find(args, override_arg_name) == nullptr) {
+    temp_args = grpc_channel_args_copy_and_add_and_remove(
+        args, &override_arg_name, 1, &override_arg, 1);
   }
-  return nullptr;
+  RefCountedPtr<grpc_channel_security_connector> security_connector;
+  if (xds_certificate_provider != nullptr) {
+    auto tls_credentials_options =
+        MakeRefCounted<grpc_tls_credentials_options>();
+    tls_credentials_options->set_certificate_provider(xds_certificate_provider);
+    if (xds_certificate_provider->ProvidesRootCerts()) {
+      tls_credentials_options->set_watch_root_cert(true);
+    }
+    if (xds_certificate_provider->ProvidesIdentityCerts()) {
+      tls_credentials_options->set_watch_identity_pair(true);
+    }
+    tls_credentials_options->set_server_verification_option(
+        GRPC_TLS_SKIP_HOSTNAME_VERIFICATION);
+    tls_credentials_options->set_server_authorization_check_config(
+        MakeRefCounted<grpc_tls_server_authorization_check_config>(
+            xds_certificate_provider->Ref().release(), ServerAuthCheckSchedule,
+            nullptr, ServerAuthCheckDestroy));
+    auto tls_credentials =
+        MakeRefCounted<TlsCredentials>(std::move(tls_credentials_options));
+    security_connector = tls_credentials->create_security_connector(
+        std::move(call_creds), target_name, temp_args, new_args);
+  } else {
+    GPR_ASSERT(fallback_credentials_ != nullptr);
+    security_connector = fallback_credentials_->create_security_connector(
+        std::move(call_creds), target_name, temp_args, new_args);
+  }
+  if (temp_args != args) {
+    grpc_channel_args_destroy(temp_args);
+  }
+  return security_connector;
+}
+
+//
+// XdsServerCredentials
+//
+
+RefCountedPtr<grpc_server_security_connector>
+XdsServerCredentials::create_security_connector() {
+  // TODO(yashkt): Fill this
+  return fallback_credentials_->create_security_connector();
 }
 
 }  // namespace grpc_core
 
 grpc_channel_credentials* grpc_xds_credentials_create(
     grpc_channel_credentials* fallback_credentials) {
+  GPR_ASSERT(fallback_credentials != nullptr);
   return new grpc_core::XdsCredentials(fallback_credentials->Ref());
 }
+
+grpc_server_credentials* grpc_xds_server_credentials_create(
+    grpc_server_credentials* fallback_credentials) {
+  GPR_ASSERT(fallback_credentials != nullptr);
+  return new grpc_core::XdsServerCredentials(fallback_credentials->Ref());
+}
index 51576de..e12608c 100644 (file)
 
 #include <grpc/grpc_security.h>
 
+#include "src/core/ext/xds/xds_api.h"
 #include "src/core/lib/security/credentials/credentials.h"
 
 namespace grpc_core {
 
+extern const char kCredentialsTypeXds[];
+
 class XdsCredentials final : public grpc_channel_credentials {
  public:
-  static constexpr const char kCredentialsTypeXds[] = "Xds";
-
   explicit XdsCredentials(
-      grpc_core::RefCountedPtr<grpc_channel_credentials> fallback_credentials)
+      RefCountedPtr<grpc_channel_credentials> fallback_credentials)
       : grpc_channel_credentials(kCredentialsTypeXds),
         fallback_credentials_(std::move(fallback_credentials)) {}
 
-  grpc_core::RefCountedPtr<grpc_channel_security_connector>
-  create_security_connector(
-      grpc_core::RefCountedPtr<grpc_call_credentials> call_creds,
-      const char* target_name, const grpc_channel_args* args,
-      grpc_channel_args** new_args) override;
+  RefCountedPtr<grpc_channel_security_connector> create_security_connector(
+      RefCountedPtr<grpc_call_credentials> call_creds, const char* target_name,
+      const grpc_channel_args* args, grpc_channel_args** new_args) override;
+
+ private:
+  RefCountedPtr<grpc_channel_credentials> fallback_credentials_;
+};
+
+class XdsServerCredentials final : public grpc_server_credentials {
+ public:
+  explicit XdsServerCredentials(
+      RefCountedPtr<grpc_server_credentials> fallback_credentials)
+      : grpc_server_credentials(kCredentialsTypeXds),
+        fallback_credentials_(std::move(fallback_credentials)) {}
+
+  RefCountedPtr<grpc_server_security_connector> create_security_connector()
+      override;
 
  private:
-  grpc_core::RefCountedPtr<grpc_channel_credentials> fallback_credentials_;
+  RefCountedPtr<grpc_server_credentials> fallback_credentials_;
 };
 
+bool TestOnlyXdsVerifySubjectAlternativeNames(
+    const char* const* subject_alternative_names,
+    size_t subject_alternative_names_size,
+    const std::vector<XdsApi::StringMatcher>& matchers);
+
 }  // namespace grpc_core
 
 #endif /* GRPC_CORE_LIB_SECURITY_CREDENTIALS_XDS_XDS_CREDENTIALS_H */
index 47c357f..64c39e6 100644 (file)
@@ -134,7 +134,7 @@ class grpc_alts_channel_security_connector final
 class grpc_alts_server_security_connector final
     : public grpc_server_security_connector {
  public:
-  grpc_alts_server_security_connector(
+  explicit grpc_alts_server_security_connector(
       grpc_core::RefCountedPtr<grpc_server_credentials> server_creds)
       : grpc_server_security_connector(GRPC_ALTS_URL_SCHEME,
                                        std::move(server_creds)) {}
index 0e3b1e8..fdf750f 100644 (file)
@@ -275,7 +275,7 @@ void grpc_fake_channel_security_connector::check_peer(
 class grpc_fake_server_security_connector
     : public grpc_server_security_connector {
  public:
-  grpc_fake_server_security_connector(
+  explicit grpc_fake_server_security_connector(
       grpc_core::RefCountedPtr<grpc_server_credentials> server_creds)
       : grpc_server_security_connector(GRPC_FAKE_SECURITY_URL_SCHEME,
                                        std::move(server_creds)) {}
index a621ff9..4cb7d21 100644 (file)
@@ -28,6 +28,26 @@ namespace grpc_core {
 
 const char kInsecureTransportSecurityType[] = "insecure";
 
+namespace {
+
+RefCountedPtr<grpc_auth_context> MakeAuthContext() {
+  auto ctx = MakeRefCounted<grpc_auth_context>(nullptr);
+  grpc_auth_context_add_cstring_property(
+      ctx.get(), GRPC_TRANSPORT_SECURITY_TYPE_PROPERTY_NAME,
+      kInsecureTransportSecurityType);
+  const char* security_level = tsi_security_level_to_string(TSI_SECURITY_NONE);
+  grpc_auth_context_add_property(ctx.get(),
+                                 GRPC_TRANSPORT_SECURITY_LEVEL_PROPERTY_NAME,
+                                 security_level, strlen(security_level));
+  return ctx;
+}
+
+}  // namespace
+
+RefCountedPtr<grpc_auth_context> TestOnlyMakeInsecureAuthContext() {
+  return MakeAuthContext();
+}
+
 // check_call_host and cancel_check_call_host are no-ops since we want to
 // provide an insecure channel.
 bool InsecureChannelSecurityConnector::check_call_host(
@@ -70,19 +90,32 @@ int InsecureChannelSecurityConnector::cmp(
       static_cast<const grpc_channel_security_connector*>(other_sc));
 }
 
-RefCountedPtr<grpc_auth_context>
-InsecureChannelSecurityConnector::MakeAuthContext() {
-  auto ctx = MakeRefCounted<grpc_auth_context>(nullptr);
-  grpc_auth_context_add_cstring_property(
-      ctx.get(), GRPC_TRANSPORT_SECURITY_TYPE_PROPERTY_NAME,
-      kInsecureTransportSecurityType);
-  GPR_ASSERT(grpc_auth_context_set_peer_identity_property_name(
-                 ctx.get(), GRPC_TRANSPORT_SECURITY_TYPE_PROPERTY_NAME) == 1);
-  const char* security_level = tsi_security_level_to_string(TSI_SECURITY_NONE);
-  grpc_auth_context_add_property(ctx.get(),
-                                 GRPC_TRANSPORT_SECURITY_LEVEL_PROPERTY_NAME,
-                                 security_level, strlen(security_level));
-  return ctx;
+// add_handshakers should have been a no-op but we need to add a minimalist
+// security handshaker so that check_peer is invoked and an auth_context is
+// created with the security level of TSI_SECURITY_NONE.
+void InsecureServerSecurityConnector::add_handshakers(
+    const grpc_channel_args* args, grpc_pollset_set* /* interested_parties */,
+    grpc_core::HandshakeManager* handshake_manager) {
+  tsi_handshaker* handshaker = nullptr;
+  // Re-use local_tsi_handshaker_create as a minimalist handshaker.
+  GPR_ASSERT(tsi_local_handshaker_create(false /* is_client */, &handshaker) ==
+             TSI_OK);
+  handshake_manager->Add(SecurityHandshakerCreate(handshaker, this, args));
+}
+
+void InsecureServerSecurityConnector::check_peer(
+    tsi_peer peer, grpc_endpoint* ep,
+    grpc_core::RefCountedPtr<grpc_auth_context>* auth_context,
+    grpc_closure* on_peer_checked) {
+  *auth_context = MakeAuthContext();
+  tsi_peer_destruct(&peer);
+  ExecCtx::Run(DEBUG_LOCATION, on_peer_checked, GRPC_ERROR_NONE);
+}
+
+int InsecureServerSecurityConnector::cmp(
+    const grpc_security_connector* other) const {
+  return server_security_connector_cmp(
+      static_cast<const grpc_server_security_connector*>(other));
 }
 
 }  // namespace grpc_core
index 5dd640c..7d0f79e 100644 (file)
@@ -29,6 +29,12 @@ namespace grpc_core {
 
 extern const char kInsecureTransportSecurityType[];
 
+// Exposed for testing purposes only.
+// Create an auth context which is necessary to pass the santiy check in
+// client_auth_filter that verifies if the peer's auth context is obtained
+// during handshakes.
+RefCountedPtr<grpc_auth_context> TestOnlyMakeInsecureAuthContext();
+
 class InsecureChannelSecurityConnector
     : public grpc_channel_security_connector {
  public:
@@ -55,13 +61,24 @@ class InsecureChannelSecurityConnector
                   grpc_closure* on_peer_checked) override;
 
   int cmp(const grpc_security_connector* other_sc) const override;
+};
+
+class InsecureServerSecurityConnector : public grpc_server_security_connector {
+ public:
+  explicit InsecureServerSecurityConnector(
+      grpc_core::RefCountedPtr<grpc_server_credentials> server_creds)
+      : grpc_server_security_connector(nullptr /* url_scheme */,
+                                       std::move(server_creds)) {}
+
+  void add_handshakers(const grpc_channel_args* args,
+                       grpc_pollset_set* /* interested_parties */,
+                       grpc_core::HandshakeManager* handshake_manager) override;
+
+  void check_peer(tsi_peer peer, grpc_endpoint* ep,
+                  grpc_core::RefCountedPtr<grpc_auth_context>* auth_context,
+                  grpc_closure* on_peer_checked) override;
 
-  // Exposed for testing purposes only.
-  // Create an auth context which is necessary to pass the santiy check in
-  // client_auth_filter that verifies if the peer's auth context is obtained
-  // during handshakes. The auth context is only checked for its existence and
-  // not actually used.
-  static RefCountedPtr<grpc_auth_context> MakeAuthContext();
+  int cmp(const grpc_security_connector* other) const override;
 };
 
 }  // namespace grpc_core
index 3313fd0..2cec0db 100644 (file)
@@ -206,7 +206,7 @@ class grpc_local_channel_security_connector final
 class grpc_local_server_security_connector final
     : public grpc_server_security_connector {
  public:
-  grpc_local_server_security_connector(
+  explicit grpc_local_server_security_connector(
       grpc_core::RefCountedPtr<grpc_server_credentials> server_creds)
       : grpc_server_security_connector(nullptr, std::move(server_creds)) {}
   ~grpc_local_server_security_connector() override = default;
index b3825fe..822fe15 100644 (file)
@@ -104,8 +104,9 @@ static const grpc_arg_pointer_vtable connector_arg_vtable = {
     connector_arg_copy, connector_arg_destroy, connector_cmp};
 
 grpc_arg grpc_security_connector_to_arg(grpc_security_connector* sc) {
-  return grpc_channel_arg_pointer_create((char*)GRPC_ARG_SECURITY_CONNECTOR, sc,
-                                         &connector_arg_vtable);
+  return grpc_channel_arg_pointer_create(
+      const_cast<char*>(GRPC_ARG_SECURITY_CONNECTOR), sc,
+      &connector_arg_vtable);
 }
 
 grpc_security_connector* grpc_security_connector_from_arg(const grpc_arg* arg) {
index 7d4574e..ee5672b 100644 (file)
@@ -111,7 +111,7 @@ class grpc_ssl_channel_security_connector final
     const tsi_result result =
         tsi_create_ssl_client_handshaker_factory_with_options(
             &options, &client_handshaker_factory_);
-    gpr_free((void*)options.alpn_protocols);
+    gpr_free(options.alpn_protocols);
     if (result != TSI_OK) {
       gpr_log(GPR_ERROR, "Handshaker factory creation failed with %s.",
               tsi_result_to_string(result));
@@ -206,7 +206,7 @@ class grpc_ssl_channel_security_connector final
 class grpc_ssl_server_security_connector
     : public grpc_server_security_connector {
  public:
-  grpc_ssl_server_security_connector(
+  explicit grpc_ssl_server_security_connector(
       grpc_core::RefCountedPtr<grpc_server_credentials> server_creds)
       : grpc_server_security_connector(GRPC_SSL_URL_SCHEME,
                                        std::move(server_creds)) {}
@@ -258,7 +258,7 @@ class grpc_ssl_server_security_connector
       const tsi_result result =
           tsi_create_ssl_server_handshaker_factory_with_options(
               &options, &server_handshaker_factory_);
-      gpr_free((void*)alpn_protocol_strings);
+      gpr_free(alpn_protocol_strings);
       if (result != TSI_OK) {
         gpr_log(GPR_ERROR, "Handshaker factory creation failed with %s.",
                 tsi_result_to_string(result));
@@ -368,7 +368,7 @@ class grpc_ssl_server_security_connector
     grpc_tsi_ssl_pem_key_cert_pairs_destroy(
         const_cast<tsi_ssl_pem_key_cert_pair*>(options.pem_key_cert_pairs),
         options.num_key_cert_pairs);
-    gpr_free((void*)alpn_protocol_strings);
+    gpr_free(alpn_protocol_strings);
 
     if (result != TSI_OK) {
       gpr_log(GPR_ERROR, "Handshaker factory creation failed with %s.",
index 1761c34..f1797d5 100644 (file)
@@ -427,7 +427,7 @@ grpc_security_status grpc_ssl_tsi_client_handshaker_factory_init(
   const tsi_result result =
       tsi_create_ssl_client_handshaker_factory_with_options(&options,
                                                             handshaker_factory);
-  gpr_free((void*)options.alpn_protocols);
+  gpr_free(options.alpn_protocols);
   if (result != TSI_OK) {
     gpr_log(GPR_ERROR, "Handshaker factory creation failed with %s.",
             tsi_result_to_string(result));
@@ -459,7 +459,7 @@ grpc_security_status grpc_ssl_tsi_server_handshaker_factory_init(
   const tsi_result result =
       tsi_create_ssl_server_handshaker_factory_with_options(&options,
                                                             handshaker_factory);
-  gpr_free((void*)alpn_protocol_strings);
+  gpr_free(alpn_protocol_strings);
   if (result != TSI_OK) {
     gpr_log(GPR_ERROR, "Handshaker factory creation failed with %s.",
             tsi_result_to_string(result));
index d54cdee..562a08c 100644 (file)
@@ -145,13 +145,8 @@ class DefaultSslRootStore {
 
 class PemKeyCertPair {
  public:
-  // Construct from the C struct.  We steal its members and then immediately
-  // free it.
-  explicit PemKeyCertPair(grpc_ssl_pem_key_cert_pair* pair)
-      : private_key_(const_cast<char*>(pair->private_key)),
-        cert_chain_(const_cast<char*>(pair->cert_chain)) {
-    gpr_free(pair);
-  }
+  PemKeyCertPair(absl::string_view private_key, absl::string_view cert_chain)
+      : private_key_(private_key), cert_chain_(cert_chain) {}
 
   // Movable.
   PemKeyCertPair(PemKeyCertPair&& other) noexcept {
@@ -166,30 +161,28 @@ class PemKeyCertPair {
 
   // Copyable.
   PemKeyCertPair(const PemKeyCertPair& other)
-      : private_key_(gpr_strdup(other.private_key())),
-        cert_chain_(gpr_strdup(other.cert_chain())) {}
+      : private_key_(other.private_key()), cert_chain_(other.cert_chain()) {}
   PemKeyCertPair& operator=(const PemKeyCertPair& other) {
-    private_key_ = grpc_core::UniquePtr<char>(gpr_strdup(other.private_key()));
-    cert_chain_ = grpc_core::UniquePtr<char>(gpr_strdup(other.cert_chain()));
+    private_key_ = other.private_key();
+    cert_chain_ = other.cert_chain();
     return *this;
   }
 
   bool operator==(const PemKeyCertPair& other) const {
-    return std::strcmp(this->private_key(), other.private_key()) == 0 &&
-           std::strcmp(this->cert_chain(), other.cert_chain()) == 0;
+    return this->private_key() == other.private_key() &&
+           this->cert_chain() == other.cert_chain();
   }
 
-  char* private_key() const { return private_key_.get(); }
-  char* cert_chain() const { return cert_chain_.get(); }
+  const std::string& private_key() const { return private_key_; }
+  const std::string& cert_chain() const { return cert_chain_; }
 
  private:
-  grpc_core::UniquePtr<char> private_key_;
-  grpc_core::UniquePtr<char> cert_chain_;
+  std::string private_key_;
+  std::string cert_chain_;
 };
 
 typedef absl::InlinedVector<grpc_core::PemKeyCertPair, 1> PemKeyCertPairList;
 
 }  // namespace grpc_core
 
-#endif /* GRPC_CORE_LIB_SECURITY_SECURITY_CONNECTOR_SSL_UTILS_H \
-        */
+#endif  // GRPC_CORE_LIB_SECURITY_SECURITY_CONNECTOR_SSL_UTILS_H
index 05f50b4..a198bb5 100644 (file)
@@ -55,10 +55,12 @@ tsi_ssl_pem_key_cert_pair* ConvertToTsiPemKeyCertPair(
         gpr_zalloc(num_key_cert_pairs * sizeof(tsi_ssl_pem_key_cert_pair)));
   }
   for (size_t i = 0; i < num_key_cert_pairs; i++) {
-    GPR_ASSERT(cert_pair_list[i].private_key() != nullptr);
-    GPR_ASSERT(cert_pair_list[i].cert_chain() != nullptr);
-    tsi_pairs[i].cert_chain = gpr_strdup(cert_pair_list[i].cert_chain());
-    tsi_pairs[i].private_key = gpr_strdup(cert_pair_list[i].private_key());
+    GPR_ASSERT(!cert_pair_list[i].private_key().empty());
+    GPR_ASSERT(!cert_pair_list[i].cert_chain().empty());
+    tsi_pairs[i].cert_chain =
+        gpr_strdup(cert_pair_list[i].cert_chain().c_str());
+    tsi_pairs[i].private_key =
+        gpr_strdup(cert_pair_list[i].private_key().c_str());
   }
   return tsi_pairs;
 }
@@ -68,12 +70,12 @@ tsi_ssl_pem_key_cert_pair* ConvertToTsiPemKeyCertPair(
 // -------------------channel security connector-------------------
 grpc_core::RefCountedPtr<grpc_channel_security_connector>
 TlsChannelSecurityConnector::CreateTlsChannelSecurityConnector(
-    grpc_core::RefCountedPtr<grpc_channel_credentials> ch_creds,
+    grpc_core::RefCountedPtr<grpc_channel_credentials> channel_creds,
     grpc_core::RefCountedPtr<grpc_tls_credentials_options> options,
     grpc_core::RefCountedPtr<grpc_call_credentials> request_metadata_creds,
     const char* target_name, const char* overridden_target_name,
     tsi_ssl_session_cache* ssl_session_cache) {
-  if (ch_creds == nullptr) {
+  if (channel_creds == nullptr) {
     gpr_log(GPR_ERROR,
             "channel_creds is nullptr in "
             "TlsChannelSecurityConnectorCreate()");
@@ -93,19 +95,20 @@ TlsChannelSecurityConnector::CreateTlsChannelSecurityConnector(
   }
   grpc_core::RefCountedPtr<TlsChannelSecurityConnector> c =
       grpc_core::MakeRefCounted<TlsChannelSecurityConnector>(
-          std::move(ch_creds), std::move(options),
+          std::move(channel_creds), std::move(options),
           std::move(request_metadata_creds), target_name,
           overridden_target_name, ssl_session_cache);
   return c;
 }
 
 TlsChannelSecurityConnector::TlsChannelSecurityConnector(
-    grpc_core::RefCountedPtr<grpc_channel_credentials> ch_creds,
+    grpc_core::RefCountedPtr<grpc_channel_credentials> channel_creds,
     grpc_core::RefCountedPtr<grpc_tls_credentials_options> options,
     grpc_core::RefCountedPtr<grpc_call_credentials> request_metadata_creds,
     const char* target_name, const char* overridden_target_name,
     tsi_ssl_session_cache* ssl_session_cache)
-    : grpc_channel_security_connector(GRPC_SSL_URL_SCHEME, std::move(ch_creds),
+    : grpc_channel_security_connector(GRPC_SSL_URL_SCHEME,
+                                      std::move(channel_creds),
                                       std::move(request_metadata_creds)),
       options_(std::move(options)),
       overridden_target_name_(
@@ -240,6 +243,39 @@ void TlsChannelSecurityConnector::check_peer(
                 : check_arg_->peer_cert_full_chain;
         gpr_free(peer_pem_chain);
       }
+      // TODO(zhenlian) - This should be cleaned up as part of the custom
+      // verification changes. Fill in the subject alternative names
+      std::vector<char*> subject_alternative_names;
+      for (size_t i = 0; i < peer.property_count; i++) {
+        const tsi_peer_property* prop = &peer.properties[i];
+        if (strcmp(prop->name,
+                   TSI_X509_SUBJECT_ALTERNATIVE_NAME_PEER_PROPERTY) == 0) {
+          char* san = new char[prop->value.length + 1];
+          memcpy(san, prop->value.data, prop->value.length);
+          san[prop->value.length] = '\0';
+          subject_alternative_names.emplace_back(san);
+        }
+      }
+      if (check_arg_->subject_alternative_names != nullptr) {
+        for (size_t i = 0; i < check_arg_->subject_alternative_names_size;
+             ++i) {
+          delete[] check_arg_->subject_alternative_names[i];
+        }
+        delete[] check_arg_->subject_alternative_names;
+      }
+      check_arg_->subject_alternative_names_size =
+          subject_alternative_names.size();
+      if (subject_alternative_names.empty()) {
+        check_arg_->subject_alternative_names = nullptr;
+      } else {
+        check_arg_->subject_alternative_names =
+            new char*[check_arg_->subject_alternative_names_size];
+        for (size_t i = 0; i < check_arg_->subject_alternative_names_size;
+             ++i) {
+          check_arg_->subject_alternative_names[i] =
+              subject_alternative_names[i];
+        }
+      }
       int callback_status = config->Schedule(check_arg_);
       /* Server authorization check is handled asynchronously. */
       if (callback_status) {
@@ -406,6 +442,11 @@ TlsChannelSecurityConnector::ServerAuthorizationCheckArgCreate(
     void* user_data) {
   grpc_tls_server_authorization_check_arg* arg =
       new grpc_tls_server_authorization_check_arg();
+  arg->target_name = nullptr;
+  arg->peer_cert = nullptr;
+  arg->peer_cert_full_chain = nullptr;
+  arg->subject_alternative_names = nullptr;
+  arg->subject_alternative_names_size = 0;
   arg->error_details = new grpc_tls_error_details();
   arg->cb = ServerAuthorizationCheckDone;
   arg->cb_user_data = user_data;
@@ -418,9 +459,13 @@ void TlsChannelSecurityConnector::ServerAuthorizationCheckArgDestroy(
   if (arg == nullptr) {
     return;
   }
-  gpr_free((void*)arg->target_name);
-  gpr_free((void*)arg->peer_cert);
-  if (arg->peer_cert_full_chain) gpr_free((void*)arg->peer_cert_full_chain);
+  gpr_free(const_cast<char*>(arg->target_name));
+  gpr_free(const_cast<char*>(arg->peer_cert));
+  gpr_free(const_cast<char*>(arg->peer_cert_full_chain));
+  for (size_t i = 0; i < arg->subject_alternative_names_size; ++i) {
+    delete[] arg->subject_alternative_names[i];
+  }
+  delete[] arg->subject_alternative_names;
   delete arg->error_details;
   if (arg->destroy_context != nullptr) {
     arg->destroy_context(arg->context);
index d915959..453c531 100644 (file)
@@ -74,13 +74,12 @@ class TlsChannelSecurityConnector final
     return client_handshaker_factory_;
   };
 
-  const absl::optional<absl::string_view>& RootCertsForTesting() {
+  absl::optional<absl::string_view> RootCertsForTesting() {
     grpc_core::MutexLock lock(&mu_);
     return pem_root_certs_;
   }
 
-  const absl::optional<grpc_core::PemKeyCertPairList>&
-  KeyCertPairListForTesting() {
+  absl::optional<grpc_core::PemKeyCertPairList> KeyCertPairListForTesting() {
     grpc_core::MutexLock lock(&mu_);
     return pem_key_cert_pair_list_;
   }
index f42aaea..7ab4d7b 100644 (file)
@@ -443,10 +443,10 @@ static const grpc_endpoint_vtable vtable = {endpoint_read,
 grpc_endpoint* grpc_secure_endpoint_create(
     struct tsi_frame_protector* protector,
     struct tsi_zero_copy_grpc_protector* zero_copy_protector,
-    grpc_endpoint* transport, grpc_slice* leftover_slices,
+    grpc_endpoint* to_wrap, grpc_slice* leftover_slices,
     size_t leftover_nslices) {
   secure_endpoint* ep =
-      new secure_endpoint(&vtable, protector, zero_copy_protector, transport,
+      new secure_endpoint(&vtable, protector, zero_copy_protector, to_wrap,
                           leftover_slices, leftover_nslices);
   return &ep->base;
 }
index 5563d5b..e7b9885 100644 (file)
@@ -241,8 +241,8 @@ void SecurityHandshaker::OnPeerCheckedInner(grpc_error* error) {
       handshaker_result_, &unused_bytes, &unused_bytes_size);
   // Create secure endpoint.
   if (unused_bytes_size > 0) {
-    grpc_slice slice =
-        grpc_slice_from_copied_buffer((char*)unused_bytes, unused_bytes_size);
+    grpc_slice slice = grpc_slice_from_copied_buffer(
+        reinterpret_cast<const char*>(unused_bytes), unused_bytes_size);
     args_->endpoint = grpc_secure_endpoint_create(
         protector, zero_copy_protector, args_->endpoint, &slice, 1);
     grpc_slice_unref_internal(slice);
index bfde30b..6e03f48 100644 (file)
@@ -273,17 +273,16 @@ grpc_core::ManagedMemorySlice::ManagedMemorySlice(const char* string)
     : grpc_core::ManagedMemorySlice::ManagedMemorySlice(string,
                                                         strlen(string)) {}
 
-grpc_core::ManagedMemorySlice::ManagedMemorySlice(const char* string,
-                                                  size_t len) {
+grpc_core::ManagedMemorySlice::ManagedMemorySlice(const char* buf, size_t len) {
   GPR_TIMER_SCOPE("grpc_slice_intern", 0);
-  const uint32_t hash = gpr_murmur_hash3(string, len, g_hash_seed);
+  const uint32_t hash = gpr_murmur_hash3(buf, len, g_hash_seed);
   const StaticMetadataSlice* static_slice =
-      MatchStaticSlice(hash, std::pair<const char*, size_t>(string, len));
+      MatchStaticSlice(hash, std::pair<const char*, size_t>(buf, len));
   if (static_slice) {
     *this = *static_slice;
   } else {
     *this = grpc_core::InternedSlice(FindOrCreateInternedSlice(
-        hash, std::pair<const char*, size_t>(string, len)));
+        hash, std::pair<const char*, size_t>(buf, len)));
   }
 }
 
index 0ff8e58..1cbe32b 100644 (file)
@@ -176,7 +176,7 @@ namespace grpc_core {
 struct StaticSliceRefcount {
   static grpc_slice_refcount kStaticSubRefcount;
 
-  StaticSliceRefcount(uint32_t index)
+  explicit StaticSliceRefcount(uint32_t index)
       : base(&kStaticSubRefcount, grpc_slice_refcount::Type::STATIC),
         index(index) {}
 
@@ -310,7 +310,7 @@ inline bool grpc_slice_static_interned_equal(const grpc_slice& a,
 
 void grpc_slice_intern_init(void);
 void grpc_slice_intern_shutdown(void);
-void grpc_test_only_set_slice_hash_seed(uint32_t key);
+void grpc_test_only_set_slice_hash_seed(uint32_t seed);
 // if slice matches a static slice, returns the static slice
 // otherwise returns the passed in slice (without reffing it)
 // used for surface boundaries where we might receive an un-interned static
index ebbe27c..d749d39 100644 (file)
@@ -124,7 +124,7 @@ struct parent_call {
 };
 
 struct child_call {
-  child_call(grpc_call* parent) : parent(parent) {}
+  explicit child_call(grpc_call* parent) : parent(parent) {}
   grpc_call* parent;
   /** siblings: children of the same parent form a list, and this list is
      protected under
@@ -284,7 +284,8 @@ grpc_core::TraceFlag grpc_compression_trace(false, "compression");
 #define CALL_FROM_TOP_ELEM(top_elem) \
   CALL_FROM_CALL_STACK(grpc_call_stack_from_top_element(top_elem))
 
-static void execute_batch(grpc_call* call, grpc_transport_stream_op_batch* op,
+static void execute_batch(grpc_call* call,
+                          grpc_transport_stream_op_batch* batch,
                           grpc_closure* start_batch_closure);
 
 static void cancel_with_status(grpc_call* c, grpc_status_code status,
@@ -309,20 +310,24 @@ void* grpc_call_arena_alloc(grpc_call* call, size_t size) {
 }
 
 static parent_call* get_or_create_parent_call(grpc_call* call) {
-  parent_call* p = (parent_call*)gpr_atm_acq_load(&call->parent_call_atm);
+  parent_call* p =
+      reinterpret_cast<parent_call*>(gpr_atm_acq_load(&call->parent_call_atm));
   if (p == nullptr) {
     p = call->arena->New<parent_call>();
-    if (!gpr_atm_rel_cas(&call->parent_call_atm, (gpr_atm) nullptr,
-                         (gpr_atm)p)) {
+    if (!gpr_atm_rel_cas(&call->parent_call_atm,
+                         reinterpret_cast<gpr_atm>(nullptr),
+                         reinterpret_cast<gpr_atm>(p))) {
       p->~parent_call();
-      p = (parent_call*)gpr_atm_acq_load(&call->parent_call_atm);
+      p = reinterpret_cast<parent_call*>(
+          gpr_atm_acq_load(&call->parent_call_atm));
     }
   }
   return p;
 }
 
 static parent_call* get_parent_call(grpc_call* call) {
-  return (parent_call*)gpr_atm_acq_load(&call->parent_call_atm);
+  return reinterpret_cast<parent_call*>(
+      gpr_atm_acq_load(&call->parent_call_atm));
 }
 
 size_t grpc_call_get_initial_size_estimate() {
@@ -648,15 +653,16 @@ static void execute_batch(grpc_call* call,
 }
 
 char* grpc_call_get_peer(grpc_call* call) {
-  char* peer_string = (char*)gpr_atm_acq_load(&call->peer_string);
+  char* peer_string =
+      reinterpret_cast<char*>(gpr_atm_acq_load(&call->peer_string));
   if (peer_string != nullptr) return gpr_strdup(peer_string);
   peer_string = grpc_channel_get_target(call->channel);
   if (peer_string != nullptr) return peer_string;
   return gpr_strdup("unknown");
 }
 
-grpc_call* grpc_call_from_top_element(grpc_call_element* elem) {
-  return CALL_FROM_TOP_ELEM(elem);
+grpc_call* grpc_call_from_top_element(grpc_call_element* surface_element) {
+  return CALL_FROM_TOP_ELEM(surface_element);
 }
 
 /*******************************************************************************
@@ -827,8 +833,8 @@ static void set_encodings_accepted_by_peer(grpc_call* /*call*/,
   accepted_user_data =
       grpc_mdelem_get_user_data(mdel, destroy_encodings_accepted_by_peer);
   if (accepted_user_data != nullptr) {
-    *encodings_accepted_by_peer =
-        static_cast<uint32_t>(((uintptr_t)accepted_user_data) - 1);
+    *encodings_accepted_by_peer = static_cast<uint32_t>(
+        reinterpret_cast<uintptr_t>(accepted_user_data) - 1);
     return;
   }
 
@@ -868,7 +874,8 @@ static void set_encodings_accepted_by_peer(grpc_call* /*call*/,
 
   grpc_mdelem_set_user_data(
       mdel, destroy_encodings_accepted_by_peer,
-      (void*)((static_cast<uintptr_t>(*encodings_accepted_by_peer)) + 1));
+      reinterpret_cast<void*>(
+          static_cast<uintptr_t>(*encodings_accepted_by_peer) + 1));
 }
 
 uint32_t grpc_call_test_only_get_encodings_accepted_by_peer(grpc_call* call) {
@@ -882,8 +889,8 @@ grpc_call_test_only_get_incoming_stream_encodings(grpc_call* call) {
   return call->incoming_stream_compression_algorithm;
 }
 
-static grpc_linked_mdelem* linked_from_md(const grpc_metadata* md) {
-  return (grpc_linked_mdelem*)&md->internal_data;
+static grpc_linked_mdelem* linked_from_md(grpc_metadata* md) {
+  return reinterpret_cast<grpc_linked_mdelem*>(&md->internal_data);
 }
 
 static grpc_metadata* get_md_elem(grpc_metadata* metadata,
@@ -906,8 +913,7 @@ static int prepare_application_metadata(grpc_call* call, int count,
   grpc_metadata_batch* batch =
       &call->metadata_batch[0 /* is_receiving */][is_trailing];
   for (i = 0; i < total_count; i++) {
-    const grpc_metadata* md =
-        get_md_elem(metadata, additional_metadata, i, count);
+    grpc_metadata* md = get_md_elem(metadata, additional_metadata, i, count);
     grpc_linked_mdelem* l = linked_from_md(md);
     GPR_ASSERT(sizeof(grpc_linked_mdelem) == sizeof(md->internal_data));
     if (!GRPC_LOG_IF_ERROR("validate_metadata",
@@ -926,8 +932,7 @@ static int prepare_application_metadata(grpc_call* call, int count,
   }
   if (i != total_count) {
     for (int j = 0; j < i; j++) {
-      const grpc_metadata* md =
-          get_md_elem(metadata, additional_metadata, j, count);
+      grpc_metadata* md = get_md_elem(metadata, additional_metadata, j, count);
       grpc_linked_mdelem* l = linked_from_md(md);
       GRPC_MDELEM_UNREF(l->md);
     }
@@ -1229,9 +1234,10 @@ static void post_batch_completion(batch_control* bctl) {
   if (bctl->completion_data.notify_tag.is_closure) {
     /* unrefs error */
     bctl->call = nullptr;
-    grpc_core::Closure::Run(DEBUG_LOCATION,
-                            (grpc_closure*)bctl->completion_data.notify_tag.tag,
-                            error);
+    grpc_core::Closure::Run(
+        DEBUG_LOCATION,
+        static_cast<grpc_closure*>(bctl->completion_data.notify_tag.tag),
+        error);
     GRPC_CALL_INTERNAL_UNREF(call, "completion");
   } else {
     /* unrefs error */
@@ -1355,7 +1361,8 @@ static void receiving_stream_ready(void* bctlp, grpc_error* error) {
    * object with rel_cas, and will not use it after the cas. Its corresponding
    * acq_load is in receiving_initial_metadata_ready() */
   if (error != GRPC_ERROR_NONE || call->receiving_stream == nullptr ||
-      !gpr_atm_rel_cas(&call->recv_state, RECV_NONE, (gpr_atm)bctlp)) {
+      !gpr_atm_rel_cas(&call->recv_state, RECV_NONE,
+                       reinterpret_cast<gpr_atm>(bctlp))) {
     process_data_after_md(bctl);
   }
 }
@@ -1569,7 +1576,8 @@ static grpc_call_error call_start_batch(grpc_call* call, const grpc_op* ops,
                      static_cast<grpc_cq_completion*>(
                          gpr_malloc(sizeof(grpc_cq_completion))));
     } else {
-      grpc_core::Closure::Run(DEBUG_LOCATION, (grpc_closure*)notify_tag,
+      grpc_core::Closure::Run(DEBUG_LOCATION,
+                              static_cast<grpc_closure*>(notify_tag),
                               GRPC_ERROR_NONE);
     }
     error = GRPC_CALL_OK;
index 55e9e34..29c184c 100644 (file)
 #include "src/core/lib/slice/slice_internal.h"
 #include "src/core/lib/surface/api_trace.h"
 
-void grpc_call_details_init(grpc_call_details* cd) {
-  GRPC_API_TRACE("grpc_call_details_init(cd=%p)", 1, (cd));
-  cd->method = grpc_empty_slice();
-  cd->host = grpc_empty_slice();
+void grpc_call_details_init(grpc_call_details* details) {
+  GRPC_API_TRACE("grpc_call_details_init(details=%p)", 1, (details));
+  details->method = grpc_empty_slice();
+  details->host = grpc_empty_slice();
 }
 
-void grpc_call_details_destroy(grpc_call_details* cd) {
-  GRPC_API_TRACE("grpc_call_details_destroy(cd=%p)", 1, (cd));
+void grpc_call_details_destroy(grpc_call_details* details) {
+  GRPC_API_TRACE("grpc_call_details_destroy(details=%p)", 1, (details));
   grpc_core::ExecCtx exec_ctx;
-  grpc_slice_unref_internal(cd->method);
-  grpc_slice_unref_internal(cd->host);
+  grpc_slice_unref_internal(details->method);
+  grpc_slice_unref_internal(details->host);
 }
index 2d57668..d68f43f 100644 (file)
@@ -58,7 +58,7 @@ static void destroy_channel(void* arg, grpc_error* error);
 
 grpc_channel* grpc_channel_create_with_builder(
     grpc_channel_stack_builder* builder,
-    grpc_channel_stack_type channel_stack_type) {
+    grpc_channel_stack_type channel_stack_type, grpc_error** error) {
   char* target = gpr_strdup(grpc_channel_stack_builder_get_target(builder));
   grpc_channel_args* args = grpc_channel_args_copy(
       grpc_channel_stack_builder_get_channel_arguments(builder));
@@ -70,16 +70,21 @@ grpc_channel* grpc_channel_create_with_builder(
   } else {
     GRPC_STATS_INC_CLIENT_CHANNELS_CREATED();
   }
-  grpc_error* error = grpc_channel_stack_builder_finish(
+  grpc_error* builder_error = grpc_channel_stack_builder_finish(
       builder, sizeof(grpc_channel), 1, destroy_channel, nullptr,
       reinterpret_cast<void**>(&channel));
-  if (error != GRPC_ERROR_NONE) {
+  if (builder_error != GRPC_ERROR_NONE) {
     gpr_log(GPR_ERROR, "channel stack builder failed: %s",
-            grpc_error_string(error));
-    GRPC_ERROR_UNREF(error);
+            grpc_error_string(builder_error));
+    GPR_ASSERT(channel == nullptr);
+    if (error != nullptr) {
+      *error = builder_error;
+    } else {
+      GRPC_ERROR_UNREF(builder_error);
+    }
     gpr_free(target);
     grpc_channel_args_destroy(args);
-    return channel;
+    return nullptr;
   }
   channel->target = target;
   channel->resource_user = resource_user;
@@ -219,7 +224,8 @@ grpc_channel* grpc_channel_create(const char* target,
                                   const grpc_channel_args* input_args,
                                   grpc_channel_stack_type channel_stack_type,
                                   grpc_transport* optional_transport,
-                                  grpc_resource_user* resource_user) {
+                                  grpc_resource_user* resource_user,
+                                  grpc_error** error) {
   // We need to make sure that grpc_shutdown() does not shut things down
   // until after the channel is destroyed.  However, the channel may not
   // actually be destroyed by the time grpc_channel_destroy() returns,
@@ -268,7 +274,7 @@ grpc_channel* grpc_channel_create(const char* target,
     CreateChannelzNode(builder);
   }
   grpc_channel* channel =
-      grpc_channel_create_with_builder(builder, channel_stack_type);
+      grpc_channel_create_with_builder(builder, channel_stack_type, error);
   if (channel == nullptr) {
     grpc_shutdown();  // Since we won't call destroy_channel().
   }
@@ -372,14 +378,14 @@ static grpc_call* grpc_channel_create_call_internal(
 grpc_call* grpc_channel_create_call(grpc_channel* channel,
                                     grpc_call* parent_call,
                                     uint32_t propagation_mask,
-                                    grpc_completion_queue* cq,
+                                    grpc_completion_queue* completion_queue,
                                     grpc_slice method, const grpc_slice* host,
                                     gpr_timespec deadline, void* reserved) {
   GPR_ASSERT(!reserved);
   grpc_core::ApplicationCallbackExecCtx callback_exec_ctx;
   grpc_core::ExecCtx exec_ctx;
   grpc_call* call = grpc_channel_create_call_internal(
-      channel, parent_call, propagation_mask, cq, nullptr,
+      channel, parent_call, propagation_mask, completion_queue, nullptr,
       grpc_mdelem_create(GRPC_MDSTR_PATH, method, nullptr),
       host != nullptr ? grpc_mdelem_create(GRPC_MDSTR_AUTHORITY, *host, nullptr)
                       : GRPC_MDNULL,
index 028c8ae..659bc8e 100644 (file)
@@ -34,7 +34,8 @@ grpc_channel* grpc_channel_create(const char* target,
                                   const grpc_channel_args* args,
                                   grpc_channel_stack_type channel_stack_type,
                                   grpc_transport* optional_transport,
-                                  grpc_resource_user* resource_user = nullptr);
+                                  grpc_resource_user* resource_user = nullptr,
+                                  grpc_error** error = nullptr);
 
 /** The same as grpc_channel_destroy, but doesn't create an ExecCtx, and so
  * is safe to use from within core. */
@@ -42,7 +43,7 @@ void grpc_channel_destroy_internal(grpc_channel* channel);
 
 grpc_channel* grpc_channel_create_with_builder(
     grpc_channel_stack_builder* builder,
-    grpc_channel_stack_type channel_stack_type);
+    grpc_channel_stack_type channel_stack_type, grpc_error** error = nullptr);
 
 /** Create a call given a grpc_channel, in order to call \a method.
     Progress is tied to activity on \a pollset_set. The returned call object is
index 62eb1c3..17f6c90 100644 (file)
@@ -87,7 +87,7 @@ void grpc_channel_init_shutdown(void) {
   for (int i = 0; i < GRPC_NUM_CHANNEL_STACK_TYPES; i++) {
     gpr_free(g_slots[i].slots);
     g_slots[i].slots =
-        static_cast<stage_slot*>((void*)static_cast<uintptr_t>(0xdeadbeef));
+        static_cast<stage_slot*>(reinterpret_cast<void*>(0xdeadbeef));
   }
 }
 
index 5af4838..02ac506 100644 (file)
@@ -310,7 +310,7 @@ struct cq_pluck_data {
 };
 
 struct cq_callback_data {
-  cq_callback_data(
+  explicit cq_callback_data(
       grpc_experimental_completion_queue_functor* shutdown_callback)
       : shutdown_callback(shutdown_callback) {}
 
@@ -439,7 +439,7 @@ grpc_core::TraceFlag grpc_cq_pluck_trace(false, "queue_pluck");
     }                                                    \
   } while (0)
 
-static void on_pollset_shutdown_done(void* cq, grpc_error* error);
+static void on_pollset_shutdown_done(void* arg, grpc_error* error);
 
 void grpc_cq_global_init() {
   gpr_tls_init(&g_cached_event);
@@ -447,7 +447,8 @@ void grpc_cq_global_init() {
 }
 
 void grpc_completion_queue_thread_local_cache_init(grpc_completion_queue* cq) {
-  if ((grpc_completion_queue*)gpr_tls_get(&g_cached_cq) == nullptr) {
+  if (reinterpret_cast<grpc_completion_queue*>(gpr_tls_get(&g_cached_cq)) ==
+      nullptr) {
     gpr_tls_set(&g_cached_event, (intptr_t)0);
     gpr_tls_set(&g_cached_cq, (intptr_t)cq);
   }
@@ -456,10 +457,10 @@ void grpc_completion_queue_thread_local_cache_init(grpc_completion_queue* cq) {
 int grpc_completion_queue_thread_local_cache_flush(grpc_completion_queue* cq,
                                                    void** tag, int* ok) {
   grpc_cq_completion* storage =
-      (grpc_cq_completion*)gpr_tls_get(&g_cached_event);
+      reinterpret_cast<grpc_cq_completion*>(gpr_tls_get(&g_cached_event));
   int ret = 0;
-  if (storage != nullptr &&
-      (grpc_completion_queue*)gpr_tls_get(&g_cached_cq) == cq) {
+  if (storage != nullptr && reinterpret_cast<grpc_completion_queue*>(
+                                gpr_tls_get(&g_cached_cq)) == cq) {
     *tag = storage->tag;
     grpc_core::ExecCtx exec_ctx;
     *ok = (storage->next & static_cast<uintptr_t>(1)) == 1;
@@ -717,8 +718,10 @@ static void cq_end_op_for_next(
 
   cq_check_tag(cq, tag, true); /* Used in debug builds only */
 
-  if ((grpc_completion_queue*)gpr_tls_get(&g_cached_cq) == cq &&
-      (grpc_cq_completion*)gpr_tls_get(&g_cached_event) == nullptr) {
+  if (reinterpret_cast<grpc_completion_queue*>(gpr_tls_get(&g_cached_cq)) ==
+          cq &&
+      reinterpret_cast<grpc_cq_completion*>(gpr_tls_get(&g_cached_event)) ==
+          nullptr) {
     gpr_tls_set(&g_cached_event, (intptr_t)storage);
   } else {
     /* Add the completion to the queue */
@@ -793,8 +796,8 @@ static void cq_end_op_for_pluck(
   storage->tag = tag;
   storage->done = done;
   storage->done_arg = done_arg;
-  storage->next =
-      ((uintptr_t)&cqd->completed_head) | (static_cast<uintptr_t>(is_success));
+  storage->next = reinterpret_cast<uintptr_t>(&cqd->completed_head) |
+                  static_cast<uintptr_t>(is_success);
 
   gpr_mu_lock(cq->mu);
   cq_check_tag(cq, tag, false); /* Used in debug builds only */
@@ -802,7 +805,7 @@ static void cq_end_op_for_pluck(
   /* Add to the list of completions */
   cqd->things_queued_ever.FetchAdd(1, grpc_core::MemoryOrder::RELAXED);
   cqd->completed_tail->next =
-      ((uintptr_t)storage) | (1u & cqd->completed_tail->next);
+      reinterpret_cast<uintptr_t>(storage) | (1u & cqd->completed_tail->next);
   cqd->completed_tail = storage;
 
   if (cqd->pending_events.FetchSub(1, grpc_core::MemoryOrder::ACQ_REL) == 1) {
@@ -910,7 +913,8 @@ struct cq_is_finished_arg {
 };
 class ExecCtxNext : public grpc_core::ExecCtx {
  public:
-  ExecCtxNext(void* arg) : ExecCtx(0), check_ready_to_finish_arg_(arg) {}
+  explicit ExecCtxNext(void* arg)
+      : ExecCtx(0), check_ready_to_finish_arg_(arg) {}
 
   bool CheckReadyToFinish() override {
     cq_is_finished_arg* a =
@@ -1158,7 +1162,8 @@ static void del_plucker(grpc_completion_queue* cq, void* tag,
 
 class ExecCtxPluck : public grpc_core::ExecCtx {
  public:
-  ExecCtxPluck(void* arg) : ExecCtx(0), check_ready_to_finish_arg_(arg) {}
+  explicit ExecCtxPluck(void* arg)
+      : ExecCtx(0), check_ready_to_finish_arg_(arg) {}
 
   bool CheckReadyToFinish() override {
     cq_is_finished_arg* a =
@@ -1176,8 +1181,8 @@ class ExecCtxPluck : public grpc_core::ExecCtx {
           cqd->things_queued_ever.Load(grpc_core::MemoryOrder::RELAXED);
       grpc_cq_completion* c;
       grpc_cq_completion* prev = &cqd->completed_head;
-      while ((c = (grpc_cq_completion*)(prev->next &
-                                        ~static_cast<uintptr_t>(1))) !=
+      while ((c = reinterpret_cast<grpc_cq_completion*>(
+                  prev->next & ~static_cast<uintptr_t>(1))) !=
              &cqd->completed_head) {
         if (c->tag == a->tag) {
           prev->next = (prev->next & static_cast<uintptr_t>(1)) |
@@ -1248,9 +1253,9 @@ static grpc_event cq_pluck(grpc_completion_queue* cq, void* tag,
       break;
     }
     prev = &cqd->completed_head;
-    while (
-        (c = (grpc_cq_completion*)(prev->next & ~static_cast<uintptr_t>(1))) !=
-        &cqd->completed_head) {
+    while ((c = reinterpret_cast<grpc_cq_completion*>(
+                prev->next & ~static_cast<uintptr_t>(1))) !=
+           &cqd->completed_head) {
       if (c->tag == tag) {
         prev->next = (prev->next & static_cast<uintptr_t>(1)) |
                      (c->next & ~static_cast<uintptr_t>(1));
index 4a114be..59116d4 100644 (file)
@@ -51,19 +51,19 @@ typedef struct grpc_cq_completion {
 } grpc_cq_completion;
 
 #ifndef NDEBUG
-void grpc_cq_internal_ref(grpc_completion_queue* cc, const char* reason,
+void grpc_cq_internal_ref(grpc_completion_queue* cq, const char* reason,
                           const char* file, int line);
-void grpc_cq_internal_unref(grpc_completion_queue* cc, const char* reason,
+void grpc_cq_internal_unref(grpc_completion_queue* cq, const char* reason,
                             const char* file, int line);
-#define GRPC_CQ_INTERNAL_REF(cc, reason) \
-  grpc_cq_internal_ref(cc, reason, __FILE__, __LINE__)
-#define GRPC_CQ_INTERNAL_UNREF(cc, reason) \
-  grpc_cq_internal_unref(cc, reason, __FILE__, __LINE__)
+#define GRPC_CQ_INTERNAL_REF(cq, reason) \
+  grpc_cq_internal_ref(cq, reason, __FILE__, __LINE__)
+#define GRPC_CQ_INTERNAL_UNREF(cq, reason) \
+  grpc_cq_internal_unref(cq, reason, __FILE__, __LINE__)
 #else
-void grpc_cq_internal_ref(grpc_completion_queue* cc);
-void grpc_cq_internal_unref(grpc_completion_queue* cc);
-#define GRPC_CQ_INTERNAL_REF(cc, reason) grpc_cq_internal_ref(cc)
-#define GRPC_CQ_INTERNAL_UNREF(cc, reason) grpc_cq_internal_unref(cc)
+void grpc_cq_internal_ref(grpc_completion_queue* cq);
+void grpc_cq_internal_unref(grpc_completion_queue* cq);
+#define GRPC_CQ_INTERNAL_REF(cq, reason) grpc_cq_internal_ref(cq)
+#define GRPC_CQ_INTERNAL_UNREF(cq, reason) grpc_cq_internal_unref(cq)
 #endif
 
 /* Initializes global variables used by completion queues */
@@ -73,22 +73,22 @@ void grpc_cq_global_init();
    shutdown until a corrensponding grpc_cq_end_* call is made.
    \a tag is currently used only in debug builds. Return true on success, and
    false if completion_queue has been shutdown. */
-bool grpc_cq_begin_op(grpc_completion_queue* cc, void* tag);
+bool grpc_cq_begin_op(grpc_completion_queue* cq, void* tag);
 
 /* Queue a GRPC_OP_COMPLETED operation; tag must correspond to the tag passed to
    grpc_cq_begin_op */
-void grpc_cq_end_op(grpc_completion_queue* cc, void* tag, grpc_error* error,
+void grpc_cq_end_op(grpc_completion_queue* cq, void* tag, grpc_error* error,
                     void (*done)(void* done_arg, grpc_cq_completion* storage),
                     void* done_arg, grpc_cq_completion* storage,
                     bool internal = false);
 
-grpc_pollset* grpc_cq_pollset(grpc_completion_queue* cc);
+grpc_pollset* grpc_cq_pollset(grpc_completion_queue* cq);
 
-bool grpc_cq_can_listen(grpc_completion_queue* cc);
+bool grpc_cq_can_listen(grpc_completion_queue* cq);
 
-grpc_cq_completion_type grpc_get_cq_completion_type(grpc_completion_queue* cc);
+grpc_cq_completion_type grpc_get_cq_completion_type(grpc_completion_queue* cq);
 
-int grpc_get_cq_poll_num(grpc_completion_queue* cc);
+int grpc_get_cq_poll_num(grpc_completion_queue* cq);
 
 grpc_completion_queue* grpc_completion_queue_create_internal(
     grpc_cq_completion_type completion_type, grpc_cq_polling_type polling_type,
index ff5b074..0b2151b 100644 (file)
@@ -101,11 +101,12 @@ static void register_builtin_channel_init() {
   grpc_channel_init_register_stage(GRPC_SERVER_CHANNEL,
                                    GRPC_CHANNEL_INIT_BUILTIN_PRIORITY,
                                    grpc_add_connected_filter, nullptr);
-  grpc_channel_init_register_stage(GRPC_CLIENT_LAME_CHANNEL,
-                                   GRPC_CHANNEL_INIT_BUILTIN_PRIORITY,
-                                   append_filter, (void*)&grpc_lame_filter);
-  grpc_channel_init_register_stage(GRPC_SERVER_CHANNEL, INT_MAX, prepend_filter,
-                                   (void*)&grpc_core::Server::kServerTopFilter);
+  grpc_channel_init_register_stage(
+      GRPC_CLIENT_LAME_CHANNEL, GRPC_CHANNEL_INIT_BUILTIN_PRIORITY,
+      append_filter, const_cast<grpc_channel_filter*>(&grpc_lame_filter));
+  grpc_channel_init_register_stage(
+      GRPC_SERVER_CHANNEL, INT_MAX, prepend_filter,
+      const_cast<grpc_channel_filter*>(&grpc_core::Server::kServerTopFilter));
 }
 
 typedef struct grpc_plugin {
index 2b3bc64..7b86d50 100644 (file)
 
 #include <grpc/support/port_platform.h>
 
+#include <grpc/support/log.h>
+
 #include "src/core/lib/surface/init.h"
 
 void grpc_security_pre_init(void) {}
 
 void grpc_register_security_filters(void) {}
 
-void grpc_security_init(void) {}
+void grpc_security_init(void) {
+  gpr_log(GPR_DEBUG,
+          "Using insecure gRPC build. Security handshakers will not be invoked "
+          "even if secure credentials are used.");
+}
index a9f5c9c..d32cc28 100644 (file)
@@ -39,59 +39,25 @@ namespace grpc_core {
 
 namespace {
 
-struct CallData {
-  CallCombiner* call_combiner;
-  grpc_linked_mdelem status;
-  grpc_linked_mdelem details;
-  Atomic<bool> filled_metadata;
-};
-
 struct ChannelData {
   ChannelData() : state_tracker("lame_channel", GRPC_CHANNEL_SHUTDOWN) {}
+  ~ChannelData() { GRPC_ERROR_UNREF(error); }
 
-  grpc_status_code error_code;
-  const char* error_message;
+  grpc_error* error = GRPC_ERROR_NONE;
   Mutex mu;
   ConnectivityStateTracker state_tracker;
 };
 
-static void fill_metadata(grpc_call_element* elem, grpc_metadata_batch* mdb) {
-  CallData* calld = static_cast<CallData*>(elem->call_data);
-  bool expected = false;
-  if (!calld->filled_metadata.CompareExchangeStrong(
-          &expected, true, MemoryOrder::RELAXED, MemoryOrder::RELAXED)) {
-    return;
-  }
-  ChannelData* chand = static_cast<ChannelData*>(elem->channel_data);
-  char tmp[GPR_LTOA_MIN_BUFSIZE];
-  gpr_ltoa(chand->error_code, tmp);
-  calld->status.md = grpc_mdelem_from_slices(
-      GRPC_MDSTR_GRPC_STATUS, grpc_core::UnmanagedMemorySlice(tmp));
-  calld->details.md = grpc_mdelem_from_slices(
-      GRPC_MDSTR_GRPC_MESSAGE,
-      grpc_core::UnmanagedMemorySlice(chand->error_message));
-  calld->status.prev = calld->details.next = nullptr;
-  calld->status.next = &calld->details;
-  calld->details.prev = &calld->status;
-  mdb->list.head = &calld->status;
-  mdb->list.tail = &calld->details;
-  mdb->list.count = 2;
-  mdb->deadline = GRPC_MILLIS_INF_FUTURE;
-}
+struct CallData {
+  CallCombiner* call_combiner;
+};
 
 static void lame_start_transport_stream_op_batch(
     grpc_call_element* elem, grpc_transport_stream_op_batch* op) {
   CallData* calld = static_cast<CallData*>(elem->call_data);
-  if (op->recv_initial_metadata) {
-    fill_metadata(elem,
-                  op->payload->recv_initial_metadata.recv_initial_metadata);
-  } else if (op->recv_trailing_metadata) {
-    fill_metadata(elem,
-                  op->payload->recv_trailing_metadata.recv_trailing_metadata);
-  }
+  ChannelData* chand = static_cast<ChannelData*>(elem->channel_data);
   grpc_transport_stream_op_batch_finish_with_failure(
-      op, GRPC_ERROR_CREATE_FROM_STATIC_STRING("lame client channel"),
-      calld->call_combiner);
+      op, GRPC_ERROR_REF(chand->error), calld->call_combiner);
 }
 
 static void lame_get_channel_info(grpc_channel_element* /*elem*/,
@@ -152,6 +118,12 @@ static void lame_destroy_channel_elem(grpc_channel_element* elem) {
 
 }  // namespace
 
+void SetLameFilterError(grpc_channel_element* elem, grpc_error* error) {
+  GPR_ASSERT(elem->filter == &grpc_lame_filter);
+  auto chand = static_cast<grpc_core::ChannelData*>(elem->channel_data);
+  chand->error = error;
+}
+
 }  // namespace grpc_core
 
 const grpc_channel_filter grpc_lame_filter = {
@@ -182,10 +154,12 @@ grpc_channel* grpc_lame_client_channel_create(const char* target,
       "grpc_lame_client_channel_create(target=%s, error_code=%d, "
       "error_message=%s)",
       3, (target, (int)error_code, error_message));
-  GPR_ASSERT(elem->filter == &grpc_lame_filter);
-  auto chand = static_cast<grpc_core::ChannelData*>(elem->channel_data);
-  chand->error_code = error_code;
-  chand->error_message = error_message;
-
+  grpc_core::SetLameFilterError(
+      elem, grpc_error_set_str(
+                grpc_error_set_int(
+                    GRPC_ERROR_CREATE_FROM_STATIC_STRING("lame client channel"),
+                    GRPC_ERROR_INT_GRPC_STATUS, error_code),
+                GRPC_ERROR_STR_GRPC_MESSAGE,
+                grpc_slice_from_static_string(error_message)));
   return channel;
 }
index aefa67c..8fd3f4e 100644 (file)
@@ -25,4 +25,8 @@
 
 extern const grpc_channel_filter grpc_lame_filter;
 
+namespace grpc_core {
+void SetLameFilterError(grpc_channel_element* elem, grpc_error* error);
+}  // namespace grpc_core
+
 #endif /* GRPC_CORE_LIB_SURFACE_LAME_CLIENT_H */
index 8872022..852c93d 100644 (file)
@@ -538,6 +538,14 @@ Server::Server(const grpc_channel_args* args)
 
 Server::~Server() {
   grpc_channel_args_destroy(channel_args_);
+  // Remove the cq pollsets from the config_fetcher.
+  if (started_ && config_fetcher_ != nullptr &&
+      config_fetcher_->interested_parties() != nullptr) {
+    for (grpc_pollset* pollset : pollsets_) {
+      grpc_pollset_set_del_pollset(config_fetcher_->interested_parties(),
+                                   pollset);
+    }
+  }
   for (size_t i = 0; i < cqs_.size(); i++) {
     GRPC_CQ_INTERNAL_UNREF(cqs_[i], "server");
   }
@@ -571,6 +579,16 @@ void Server::Start() {
     MutexLock lock(&mu_global_);
     starting_ = true;
   }
+  // Register the interested parties from the config fetcher to the cq pollsets
+  // before starting listeners so that config fetcher is being polled when the
+  // listeners start watch the fetcher.
+  if (config_fetcher_ != nullptr &&
+      config_fetcher_->interested_parties() != nullptr) {
+    for (grpc_pollset* pollset : pollsets_) {
+      grpc_pollset_set_add_pollset(config_fetcher_->interested_parties(),
+                                   pollset);
+    }
+  }
   for (auto& listener : listeners_) {
     listener.listener->Start(this, &pollsets_);
   }
@@ -579,14 +597,18 @@ void Server::Start() {
   starting_cv_.Signal();
 }
 
-void Server::SetupTransport(
+grpc_error* Server::SetupTransport(
     grpc_transport* transport, grpc_pollset* accepting_pollset,
     const grpc_channel_args* args,
     const RefCountedPtr<grpc_core::channelz::SocketNode>& socket_node,
     grpc_resource_user* resource_user) {
   // Create channel.
+  grpc_error* error = GRPC_ERROR_NONE;
   grpc_channel* channel = grpc_channel_create(
-      nullptr, args, GRPC_SERVER_CHANNEL, transport, resource_user);
+      nullptr, args, GRPC_SERVER_CHANNEL, transport, resource_user, &error);
+  if (channel == nullptr) {
+    return error;
+  }
   ChannelData* chand = static_cast<ChannelData*>(
       grpc_channel_stack_element(grpc_channel_get_channel_stack(channel), 0)
           ->channel_data);
@@ -607,6 +629,7 @@ void Server::SetupTransport(
   }
   // Initialize chand.
   chand->InitTransport(Ref(), channel, cq_idx, transport, channelz_socket_uuid);
+  return GRPC_ERROR_NONE;
 }
 
 bool Server::HasOpenConnections() {
@@ -1115,8 +1138,8 @@ void Server::ChannelData::AcceptStream(void* arg, grpc_transport* /*transport*/,
   calld->Start(elem);
 }
 
-void Server::ChannelData::FinishDestroy(void* cd, grpc_error* /*error*/) {
-  auto* chand = static_cast<Server::ChannelData*>(cd);
+void Server::ChannelData::FinishDestroy(void* arg, grpc_error* /*error*/) {
+  auto* chand = static_cast<Server::ChannelData*>(arg);
   Server* server = chand->server_.get();
   GRPC_CHANNEL_INTERNAL_UNREF(chand->channel_, "server");
   server->Unref();
@@ -1355,8 +1378,8 @@ void Server::CallData::StartTransportStreamOpBatchImpl(
   grpc_call_next_op(elem, batch);
 }
 
-void Server::CallData::RecvInitialMetadataReady(void* ptr, grpc_error* error) {
-  grpc_call_element* elem = static_cast<grpc_call_element*>(ptr);
+void Server::CallData::RecvInitialMetadataReady(void* arg, grpc_error* error) {
+  grpc_call_element* elem = static_cast<grpc_call_element*>(arg);
   CallData* calld = static_cast<CallData*>(elem->call_data);
   grpc_millis op_deadline;
   if (error == GRPC_ERROR_NONE) {
@@ -1398,9 +1421,8 @@ void Server::CallData::RecvInitialMetadataReady(void* ptr, grpc_error* error) {
   Closure::Run(DEBUG_LOCATION, closure, error);
 }
 
-void Server::CallData::RecvTrailingMetadataReady(void* user_data,
-                                                 grpc_error* error) {
-  grpc_call_element* elem = static_cast<grpc_call_element*>(user_data);
+void Server::CallData::RecvTrailingMetadataReady(void* arg, grpc_error* error) {
+  grpc_call_element* elem = static_cast<grpc_call_element*>(arg);
   CallData* calld = static_cast<CallData*>(elem->call_data);
   if (calld->original_recv_initial_metadata_ready_ != nullptr) {
     calld->recv_trailing_metadata_error_ = GRPC_ERROR_REF(error);
@@ -1535,23 +1557,45 @@ grpc_call_error grpc_server_request_call(
 }
 
 grpc_call_error grpc_server_request_registered_call(
-    grpc_server* server, void* rmp, grpc_call** call, gpr_timespec* deadline,
-    grpc_metadata_array* request_metadata, grpc_byte_buffer** optional_payload,
+    grpc_server* server, void* registered_method, grpc_call** call,
+    gpr_timespec* deadline, grpc_metadata_array* request_metadata,
+    grpc_byte_buffer** optional_payload,
     grpc_completion_queue* cq_bound_to_call,
     grpc_completion_queue* cq_for_notification, void* tag_new) {
   grpc_core::ApplicationCallbackExecCtx callback_exec_ctx;
   grpc_core::ExecCtx exec_ctx;
   GRPC_STATS_INC_SERVER_REQUESTED_CALLS();
-  auto* rm = static_cast<grpc_core::Server::RegisteredMethod*>(rmp);
+  auto* rm =
+      static_cast<grpc_core::Server::RegisteredMethod*>(registered_method);
   GRPC_API_TRACE(
       "grpc_server_request_registered_call("
-      "server=%p, rmp=%p, call=%p, deadline=%p, request_metadata=%p, "
+      "server=%p, registered_method=%p, call=%p, deadline=%p, "
+      "request_metadata=%p, "
       "optional_payload=%p, cq_bound_to_call=%p, cq_for_notification=%p, "
       "tag=%p)",
       9,
-      (server, rmp, call, deadline, request_metadata, optional_payload,
-       cq_bound_to_call, cq_for_notification, tag_new));
+      (server, registered_method, call, deadline, request_metadata,
+       optional_payload, cq_bound_to_call, cq_for_notification, tag_new));
   return server->core_server->RequestRegisteredCall(
       rm, call, deadline, request_metadata, optional_payload, cq_bound_to_call,
       cq_for_notification, tag_new);
 }
+
+void grpc_server_set_config_fetcher(
+    grpc_server* server, grpc_server_config_fetcher* server_config_fetcher) {
+  grpc_core::ApplicationCallbackExecCtx callback_exec_ctx;
+  grpc_core::ExecCtx exec_ctx;
+  GRPC_API_TRACE("grpc_server_set_config_fetcher(server=%p, config_fetcher=%p)",
+                 2, (server, server_config_fetcher));
+  server->core_server->set_config_fetcher(
+      std::unique_ptr<grpc_server_config_fetcher>(server_config_fetcher));
+}
+
+void grpc_server_config_fetcher_destroy(
+    grpc_server_config_fetcher* server_config_fetcher) {
+  grpc_core::ApplicationCallbackExecCtx callback_exec_ctx;
+  grpc_core::ExecCtx exec_ctx;
+  GRPC_API_TRACE("grpc_server_config_fetcher_destroy(config_fetcher=%p)", 1,
+                 (server_config_fetcher));
+  delete server_config_fetcher;
+}
index af8ddab..06bdd4d 100644 (file)
@@ -103,6 +103,15 @@ class Server : public InternallyRefCounted<Server> {
   // result is valid for the lifetime of the server.
   const std::vector<grpc_pollset*>& pollsets() const { return pollsets_; }
 
+  grpc_server_config_fetcher* config_fetcher() const {
+    return config_fetcher_.get();
+  }
+
+  void set_config_fetcher(
+      std::unique_ptr<grpc_server_config_fetcher> config_fetcher) {
+    config_fetcher_ = std::move(config_fetcher);
+  }
+
   bool HasOpenConnections();
 
   // Adds a listener to the server.  When the server starts, it will call
@@ -115,11 +124,11 @@ class Server : public InternallyRefCounted<Server> {
 
   // Sets up a transport.  Creates a channel stack and binds the transport to
   // the server.  Called from the listener when a new connection is accepted.
-  void SetupTransport(grpc_transport* transport,
-                      grpc_pollset* accepting_pollset,
-                      const grpc_channel_args* args,
-                      const RefCountedPtr<channelz::SocketNode>& socket_node,
-                      grpc_resource_user* resource_user = nullptr);
+  grpc_error* SetupTransport(
+      grpc_transport* transport, grpc_pollset* accepting_pollset,
+      const grpc_channel_args* args,
+      const RefCountedPtr<channelz::SocketNode>& socket_node,
+      grpc_resource_user* resource_user = nullptr);
 
   void RegisterCompletionQueue(grpc_completion_queue* cq);
 
@@ -350,6 +359,7 @@ class Server : public InternallyRefCounted<Server> {
   grpc_channel_args* const channel_args_;
   grpc_resource_user* default_resource_user_ = nullptr;
   RefCountedPtr<channelz::ServerNode> channelz_node_;
+  std::unique_ptr<grpc_server_config_fetcher> config_fetcher_;
 
   std::vector<grpc_completion_queue*> cqs_;
   std::vector<grpc_pollset*> pollsets_;
@@ -394,4 +404,26 @@ struct grpc_server {
   grpc_core::OrphanablePtr<grpc_core::Server> core_server;
 };
 
+// TODO(roth): Eventually, will need a way to modify configuration even after
+// a connection is established (e.g., to change things like L7 rate
+// limiting, RBAC, and fault injection configs).  One possible option
+// would be to do something like ServiceConfig and ConfigSelector, but
+// that might add unnecessary per-call overhead.  Need to consider other
+// approaches here.
+struct grpc_server_config_fetcher {
+ public:
+  class WatcherInterface {
+   public:
+    virtual ~WatcherInterface() = default;
+    virtual void UpdateConfig(grpc_channel_args* args) = 0;
+  };
+
+  virtual ~grpc_server_config_fetcher() = default;
+
+  virtual void StartWatch(std::string listening_address,
+                          std::unique_ptr<WatcherInterface> watcher) = 0;
+  virtual void CancelWatch(WatcherInterface* watcher) = 0;
+  virtual grpc_pollset_set* interested_parties() = 0;
+};
+
 #endif /* GRPC_CORE_LIB_SURFACE_SERVER_H */
index d356efd..03cb2ec 100644 (file)
@@ -25,4 +25,4 @@
 
 const char* grpc_version_string(void) { return "14.0.0"; }
 
-const char* grpc_g_stands_for(void) { return "gauntlet"; }
+const char* grpc_g_stands_for(void) { return "gecko"; }
index 8c13320..6685072 100644 (file)
@@ -16,6 +16,8 @@
 
 #include <grpc/support/port_platform.h>
 
+#include "absl/strings/string_view.h"
+
 #include "src/core/lib/channel/channel_args.h"
 
 // Channel arg key for the authority override.
 
 namespace grpc_core {
 
-/// Returns a channel argument containing \a authority.
 grpc_arg CreateAuthorityOverrideChannelArg(const char* authority) {
   return grpc_channel_arg_string_create(
       const_cast<char*>(GRPC_ARG_AUTHORITY_OVERRIDE),
       const_cast<char*>(authority));
 }
 
-/// Returns the authority override from \a args or nullptr.
-const char* FindAuthorityOverrideInArgs(const grpc_channel_args* args) {
-  return grpc_channel_args_find_string(args, GRPC_ARG_AUTHORITY_OVERRIDE);
+absl::string_view FindAuthorityOverrideInArgs(const grpc_channel_args* args) {
+  const char* found =
+      grpc_channel_args_find_string(args, GRPC_ARG_AUTHORITY_OVERRIDE);
+  return found == nullptr ? "" : found;
 }
 
 }  // namespace grpc_core
index 0cbf27e..7af6526 100644 (file)
@@ -19,6 +19,8 @@
 
 #include <grpc/support/port_platform.h>
 
+#include "absl/strings/string_view.h"
+
 #include <grpc/grpc.h>
 
 namespace grpc_core {
@@ -26,8 +28,9 @@ namespace grpc_core {
 /// Returns a channel argument containing \a authority.
 grpc_arg CreateAuthorityOverrideChannelArg(const char* authority);
 
-/// Returns the authority override from \a args or nullptr.
-const char* FindAuthorityOverrideInArgs(const grpc_channel_args* args);
+/// Returns the authority override from \a args or the empty string. The return
+/// value is a string_view into the `args` data structure.
+absl::string_view FindAuthorityOverrideInArgs(const grpc_channel_args* args);
 
 }  // namespace grpc_core
 
index cad34c2..3417311 100644 (file)
 
 #include <grpc/support/port_platform.h>
 
+#include <map>
+#include <memory>
+
 #include "absl/status/status.h"
 
 #include <grpc/grpc.h>
 
 #include "src/core/lib/debug/trace.h"
 #include "src/core/lib/gprpp/atomic.h"
-#include "src/core/lib/gprpp/map.h"
 #include "src/core/lib/gprpp/orphanable.h"
 #include "src/core/lib/iomgr/closure.h"
 #include "src/core/lib/iomgr/exec_ctx.h"
@@ -95,9 +97,9 @@ class AsyncConnectivityStateWatcherInterface
 // to be called).
 class ConnectivityStateTracker {
  public:
-  ConnectivityStateTracker(const char* name,
-                           grpc_connectivity_state state = GRPC_CHANNEL_IDLE,
-                           const absl::Status& status = absl::Status())
+  explicit ConnectivityStateTracker(
+      const char* name, grpc_connectivity_state state = GRPC_CHANNEL_IDLE,
+      const absl::Status& status = absl::Status())
       : name_(name), state_(state), status_(status) {}
 
   ~ConnectivityStateTracker();
index e9b1a8f..c61320d 100644 (file)
@@ -36,7 +36,7 @@
 /// NULL.
 void grpc_error_get_status(grpc_error* error, grpc_millis deadline,
                            grpc_status_code* code, grpc_slice* slice,
-                           grpc_http2_error_code* http_status,
+                           grpc_http2_error_code* http_error,
                            const char** error_string);
 
 /// Utility Function to convert a grpc_error * \a error to an absl::Status.
index 3101f48..69864c1 100644 (file)
@@ -73,7 +73,7 @@ void grpc_metadata_batch_remove(grpc_metadata_batch* batch,
 /** Substitute a new mdelem for an old value */
 grpc_error* grpc_metadata_batch_substitute(grpc_metadata_batch* batch,
                                            grpc_linked_mdelem* storage,
-                                           grpc_mdelem new_value);
+                                           grpc_mdelem new_mdelem);
 
 void grpc_metadata_batch_set_value(grpc_linked_mdelem* storage,
                                    const grpc_slice& value);
@@ -172,10 +172,10 @@ grpc_error* grpc_metadata_batch_filter(
     void* user_data, const char* composite_error_string) GRPC_MUST_USE_RESULT;
 
 #ifndef NDEBUG
-void grpc_metadata_batch_assert_ok(grpc_metadata_batch* comd);
+void grpc_metadata_batch_assert_ok(grpc_metadata_batch* batch);
 #else
-#define grpc_metadata_batch_assert_ok(comd) \
-  do {                                      \
+#define grpc_metadata_batch_assert_ok(batch) \
+  do {                                       \
   } while (0)
 #endif
 
index e027c00..483a40f 100644 (file)
@@ -1207,7 +1207,7 @@ static uint32_t elems_phash(uint32_t i) {
   uint32_t y = i / 108;
   uint32_t h = x;
   if (y < GPR_ARRAY_SIZE(elems_r)) {
-    uint32_t delta = (uint32_t)elems_r[y];
+    uint32_t delta = static_cast<uint32_t>(elems_r[y]);
     h += delta;
   }
   return h;
index c83d6b0..1b19307 100644 (file)
@@ -42,14 +42,15 @@ grpc_status_code grpc_get_status_code_from_metadata(grpc_mdelem md) {
   }
   void* user_data = grpc_mdelem_get_user_data(md, destroy_status);
   if (user_data != nullptr) {
-    return static_cast<grpc_status_code>((intptr_t)user_data - STATUS_OFFSET);
+    return static_cast<grpc_status_code>(reinterpret_cast<intptr_t>(user_data) -
+                                         STATUS_OFFSET);
   }
   uint32_t status;
   if (!grpc_parse_slice_to_uint32(GRPC_MDVALUE(md), &status)) {
     status = GRPC_STATUS_UNKNOWN; /* could not parse status code */
   }
-  grpc_mdelem_set_user_data(
-      md, destroy_status, (void*)static_cast<intptr_t>(status + STATUS_OFFSET));
+  grpc_mdelem_set_user_data(md, destroy_status,
+                            reinterpret_cast<void*>(status + STATUS_OFFSET));
   return static_cast<grpc_status_code>(status);
 }
 
index 911f091..4076048 100644 (file)
@@ -411,7 +411,7 @@ void grpc_transport_destroy_stream(grpc_transport* transport,
                                    grpc_closure* then_schedule_closure);
 
 void grpc_transport_stream_op_batch_finish_with_failure(
-    grpc_transport_stream_op_batch* op, grpc_error* error,
+    grpc_transport_stream_op_batch* batch, grpc_error* error,
     grpc_core::CallCombiner* call_combiner);
 
 std::string grpc_transport_stream_op_batch_string(
@@ -450,14 +450,14 @@ void grpc_transport_destroy(grpc_transport* transport);
 /* Get the endpoint used by \a transport */
 grpc_endpoint* grpc_transport_get_endpoint(grpc_transport* transport);
 
-/* Allocate a grpc_transport_op, and preconfigure the on_consumed closure to
-   \a on_consumed and then delete the returned transport op */
-grpc_transport_op* grpc_make_transport_op(grpc_closure* on_consumed);
-/* Allocate a grpc_transport_stream_op_batch, and preconfigure the on_consumed
+/* Allocate a grpc_transport_op, and preconfigure the on_complete closure to
+   \a on_complete and then delete the returned transport op */
+grpc_transport_op* grpc_make_transport_op(grpc_closure* on_complete);
+/* Allocate a grpc_transport_stream_op_batch, and preconfigure the on_complete
    closure
-   to \a on_consumed and then delete the returned transport op */
+   to \a on_complete and then delete the returned transport op */
 grpc_transport_stream_op_batch* grpc_make_transport_stream_op(
-    grpc_closure* on_consumed);
+    grpc_closure* on_complete);
 
 namespace grpc_core {
 // This is the key to be used for loading/storing keepalive_throttling in the
index 28a76d9..ea10330 100644 (file)
 
 #include <string.h>
 
+#include <map>
 #include <string>
 
+#include "absl/strings/escaping.h"
 #include "absl/strings/str_format.h"
+#include "absl/strings/str_split.h"
 
-#include <grpc/slice_buffer.h>
-#include <grpc/support/alloc.h>
 #include <grpc/support/log.h>
 
 #include "src/core/lib/gpr/string.h"
-#include "src/core/lib/slice/percent_encoding.h"
-#include "src/core/lib/slice/slice_internal.h"
-#include "src/core/lib/slice/slice_string_helpers.h"
 
-/** a size_t default value... maps to all 1's */
-#define NOT_SET (~(size_t)0)
+namespace grpc_core {
+namespace {
 
-static grpc_uri* bad_uri(absl::string_view uri_text, size_t pos,
-                         const char* section, bool suppress_errors) {
-  if (!suppress_errors) {
-    std::string line_prefix = absl::StrFormat("bad uri.%s: '", section);
-    gpr_log(GPR_ERROR, "%s%s'", line_prefix.c_str(),
-            std::string(uri_text).c_str());
-    size_t pfx_len = line_prefix.size() + pos;
-    gpr_log(GPR_ERROR, "%s^ here", std::string(pfx_len, ' ').c_str());
+// Similar to `grpc_permissive_percent_decode_slice`, this %-decodes all valid
+// triplets, and passes through the rest verbatim.
+std::string PercentDecode(absl::string_view str) {
+  if (str.empty() || !absl::StrContains(str, "%")) {
+    return std::string(str);
+  }
+  std::string out;
+  std::string unescaped;
+  out.reserve(str.size());
+  for (size_t i = 0; i < str.length(); i++) {
+    unescaped = "";
+    if (str[i] != '%') {
+      out += str[i];
+      continue;
+    }
+    if (i + 3 >= str.length() ||
+        !absl::CUnescape(absl::StrCat("\\x", str.substr(i + 1, 2)),
+                         &unescaped) ||
+        unescaped.length() > 1) {
+      out += str[i];
+    } else {
+      out += unescaped[0];
+      i += 2;
+    }
   }
-  return nullptr;
-}
-
-/** Returns a copy of percent decoded \a src[begin, end) */
-static char* decode_and_copy_component(absl::string_view src, size_t begin,
-                                       size_t end) {
-  grpc_slice component =
-      (begin == NOT_SET || end == NOT_SET)
-          ? grpc_empty_slice()
-          : grpc_slice_from_copied_buffer(src.data() + begin, end - begin);
-  grpc_slice decoded_component =
-      grpc_permissive_percent_decode_slice(component);
-  char* out = grpc_dump_slice(decoded_component, GPR_DUMP_ASCII);
-  grpc_slice_unref_internal(component);
-  grpc_slice_unref_internal(decoded_component);
   return out;
 }
 
-static bool valid_hex(char c) {
-  return ((c >= 'a') && (c <= 'f')) || ((c >= 'A') && (c <= 'F')) ||
-         ((c >= '0') && (c <= '9'));
+// Checks if this string is made up of pchars, '/', '?', and '%' exclusively.
+// See https://tools.ietf.org/html/rfc3986#section-3.4
+bool IsPCharString(absl::string_view str) {
+  return (str.find_first_not_of("ABCDEFGHIJKLMNOPQRSTUVWXYZ"
+                                "abcdefghijklmnopqrstuvwxyz"
+                                "0123456789"
+                                "?/:@\\-._~!$&'()*+,;=%") ==
+          absl::string_view::npos);
 }
 
-/** Returns how many chars to advance if \a uri_text[i] begins a valid \a pchar
- * production. If \a uri_text[i] introduces an invalid \a pchar (such as percent
- * sign not followed by two hex digits), NOT_SET is returned. */
-static size_t parse_pchar(absl::string_view uri_text, size_t i) {
-  /* pchar = unreserved / pct-encoded / sub-delims / ":" / "@"
-   * unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~"
-   * pct-encoded = "%" HEXDIG HEXDIG
-   * sub-delims = "!" / "$" / "&" / "'" / "(" / ")"
-   / "*" / "+" / "," / ";" / "=" */
-  char c = uri_text[i];
-  switch (c) {
-    default:
-      if (((c >= 'a') && (c <= 'z')) || ((c >= 'A') && (c <= 'Z')) ||
-          ((c >= '0') && (c <= '9'))) {
-        return 1;
-      }
-      break;
-    case ':':
-    case '@':
-    case '-':
-    case '.':
-    case '_':
-    case '~':
-    case '!':
-    case '$':
-    case '&':
-    case '\'':
-    case '(':
-    case ')':
-    case '*':
-    case '+':
-    case ',':
-    case ';':
-    case '=':
-      return 1;
-    case '%': /* pct-encoded */
-      if (uri_text.size() > i + 2 && valid_hex(uri_text[i + 1]) &&
-          valid_hex(uri_text[i + 2])) {
-        return 2;
-      }
-      return NOT_SET;
-  }
-  return 0;
+absl::Status MakeInvalidURIStatus(absl::string_view part_name,
+                                  absl::string_view uri,
+                                  absl::string_view extra) {
+  return absl::InvalidArgumentError(absl::StrFormat(
+      "Could not parse '%s' from uri '%s'. %s", part_name, uri, extra));
 }
-
-/* *( pchar / "?" / "/" ) */
-static int parse_fragment_or_query(absl::string_view uri_text, size_t* i) {
-  while (uri_text.size() > *i) {
-    const size_t advance = parse_pchar(uri_text, *i); /* pchar */
-    switch (advance) {
-      case 0: /* uri_text[i] isn't in pchar */
-        /* maybe it's ? or / */
-        if (uri_text[*i] == '?' || uri_text[*i] == '/') {
-          (*i)++;
-          break;
-        } else {
-          return 1;
-        }
-        GPR_UNREACHABLE_CODE(return 0);
-      default:
-        (*i) += advance;
-        break;
-      case NOT_SET: /* uri_text[i] introduces an invalid URI */
-        return 0;
-    }
+}  // namespace
+
+absl::StatusOr<URI> URI::Parse(absl::string_view uri_text) {
+  absl::StatusOr<std::string> decoded;
+  absl::string_view remaining = uri_text;
+  // parse scheme
+  size_t idx = remaining.find(':');
+  if (idx == remaining.npos || idx == 0) {
+    return MakeInvalidURIStatus("scheme", uri_text, "Scheme not found.");
   }
-  /* *i is the first uri_text position past the \a query production, maybe \0 */
-  return 1;
-}
-
-static void parse_query_parts(grpc_uri* uri) {
-  static const char* QUERY_PARTS_SEPARATOR = "&";
-  static const char* QUERY_PARTS_VALUE_SEPARATOR = "=";
-  GPR_ASSERT(uri->query != nullptr);
-  if (uri->query[0] == '\0') {
-    uri->query_parts = nullptr;
-    uri->query_parts_values = nullptr;
-    uri->num_query_parts = 0;
-    return;
+  std::string scheme(remaining.substr(0, idx));
+  if (scheme.find_first_not_of("ABCDEFGHIJKLMNOPQRSTUVWXYZ"
+                               "abcdefghijklmnopqrstuvwxyz"
+                               "0123456789+-.") != std::string::npos) {
+    return MakeInvalidURIStatus("scheme", uri_text,
+                                "Scheme contains invalid characters.");
   }
-
-  gpr_string_split(uri->query, QUERY_PARTS_SEPARATOR, &uri->query_parts,
-                   &uri->num_query_parts);
-  uri->query_parts_values =
-      static_cast<char**>(gpr_malloc(uri->num_query_parts * sizeof(char**)));
-  for (size_t i = 0; i < uri->num_query_parts; i++) {
-    char** query_param_parts;
-    size_t num_query_param_parts;
-    char* full = uri->query_parts[i];
-    gpr_string_split(full, QUERY_PARTS_VALUE_SEPARATOR, &query_param_parts,
-                     &num_query_param_parts);
-    GPR_ASSERT(num_query_param_parts > 0);
-    uri->query_parts[i] = query_param_parts[0];
-    if (num_query_param_parts > 1) {
-      /* TODO(dgq): only the first value after the separator is considered.
-       * Perhaps all chars after the first separator for the query part should
-       * be included, even if they include the separator. */
-      uri->query_parts_values[i] = query_param_parts[1];
-    } else {
-      uri->query_parts_values[i] = nullptr;
-    }
-    for (size_t j = 2; j < num_query_param_parts; j++) {
-      gpr_free(query_param_parts[j]);
-    }
-    gpr_free(query_param_parts);
-    gpr_free(full);
+  if (!isalpha(scheme[0])) {
+    return MakeInvalidURIStatus(
+        "scheme", uri_text,
+        "Scheme must begin with an alpha character [A-Za-z].");
   }
-}
-
-grpc_uri* grpc_uri_parse(absl::string_view uri_text, bool suppress_errors) {
-  grpc_uri* uri;
-  size_t scheme_begin = 0;
-  size_t scheme_end = NOT_SET;
-  size_t authority_begin = NOT_SET;
-  size_t authority_end = NOT_SET;
-  size_t path_begin = NOT_SET;
-  size_t path_end = NOT_SET;
-  size_t query_begin = NOT_SET;
-  size_t query_end = NOT_SET;
-  size_t fragment_begin = NOT_SET;
-  size_t fragment_end = NOT_SET;
-  size_t i;
-
-  for (i = scheme_begin; i < uri_text.size(); ++i) {
-    if (uri_text[i] == ':') {
-      scheme_end = i;
-      break;
-    }
-    if (uri_text[i] >= 'a' && uri_text[i] <= 'z') continue;
-    if (uri_text[i] >= 'A' && uri_text[i] <= 'Z') continue;
-    if (i != scheme_begin) {
-      if (uri_text[i] >= '0' && uri_text[i] <= '9') continue;
-      if (uri_text[i] == '+') continue;
-      if (uri_text[i] == '-') continue;
-      if (uri_text[i] == '.') continue;
-    }
-    break;
+  remaining.remove_prefix(scheme.length() + 1);
+  // parse authority
+  std::string authority;
+  if (absl::StartsWith(remaining, "//")) {
+    remaining.remove_prefix(2);
+    authority =
+        PercentDecode(remaining.substr(0, remaining.find_first_of("/?#")));
+    remaining.remove_prefix(authority.length());
   }
-  if (scheme_end == NOT_SET) {
-    return bad_uri(uri_text, i, "scheme", suppress_errors);
+  // parse path
+  std::string path;
+  if (!remaining.empty()) {
+    path = PercentDecode(remaining.substr(0, remaining.find_first_of("?#")));
+    remaining.remove_prefix(path.length());
   }
-
-  if (uri_text.size() > scheme_end + 2 && uri_text[scheme_end + 1] == '/' &&
-      uri_text[scheme_end + 2] == '/') {
-    authority_begin = scheme_end + 3;
-    for (i = authority_begin; uri_text.size() > i && authority_end == NOT_SET;
-         i++) {
-      if (uri_text[i] == '/' || uri_text[i] == '?' || uri_text[i] == '#') {
-        authority_end = i;
-      }
+  // parse query
+  std::vector<QueryParam> query_param_pairs;
+  if (!remaining.empty() && remaining[0] == '?') {
+    remaining.remove_prefix(1);
+    absl::string_view tmp_query = remaining.substr(0, remaining.find('#'));
+    if (tmp_query.empty()) {
+      return MakeInvalidURIStatus("query", uri_text, "Invalid query string.");
     }
-    if (authority_end == NOT_SET && uri_text.size() == i) {
-      authority_end = i;
+    if (!IsPCharString(tmp_query)) {
+      return MakeInvalidURIStatus("query string", uri_text,
+                                  "Query string contains invalid characters.");
     }
-    if (authority_end == NOT_SET) {
-      return bad_uri(uri_text, i, "authority", suppress_errors);
+    for (absl::string_view query_param : absl::StrSplit(tmp_query, '&')) {
+      const std::pair<absl::string_view, absl::string_view> possible_kv =
+          absl::StrSplit(query_param, absl::MaxSplits('=', 1));
+      if (possible_kv.first.empty()) continue;
+      query_param_pairs.push_back({PercentDecode(possible_kv.first),
+                                   PercentDecode(possible_kv.second)});
     }
-    /* TODO(ctiller): parse the authority correctly */
-    path_begin = authority_end;
-  } else {
-    path_begin = scheme_end + 1;
+    remaining.remove_prefix(tmp_query.length());
   }
-
-  for (i = path_begin; i < uri_text.size(); ++i) {
-    if (uri_text[i] == '?' || uri_text[i] == '#') {
-      path_end = i;
-      break;
+  std::string fragment;
+  if (!remaining.empty() && remaining[0] == '#') {
+    remaining.remove_prefix(1);
+    if (!IsPCharString(remaining)) {
+      return MakeInvalidURIStatus("fragment", uri_text,
+                                  "Fragment contains invalid characters.");
     }
+    fragment = PercentDecode(remaining);
   }
-  if (path_end == NOT_SET && uri_text.size() == i) {
-    path_end = i;
-  }
-  if (path_end == NOT_SET) {
-    return bad_uri(uri_text, i, "path", suppress_errors);
-  }
+  return URI(std::move(scheme), std::move(authority), std::move(path),
+             std::move(query_param_pairs), std::move(fragment));
+}
 
-  if (uri_text.size() > i && uri_text[i] == '?') {
-    query_begin = ++i;
-    if (!parse_fragment_or_query(uri_text, &i)) {
-      return bad_uri(uri_text, i, "query", suppress_errors);
-    } else if (uri_text.size() > i && uri_text[i] != '#') {
-      /* We must be at the end or at the beginning of a fragment */
-      return bad_uri(uri_text, i, "query", suppress_errors);
-    }
-    query_end = i;
-  }
-  if (uri_text.size() > i && uri_text[i] == '#') {
-    fragment_begin = ++i;
-    if (!parse_fragment_or_query(uri_text, &i)) {
-      return bad_uri(uri_text, i - fragment_end, "fragment", suppress_errors);
-    } else if (uri_text.size() > i) {
-      /* We must be at the end */
-      return bad_uri(uri_text, i, "fragment", suppress_errors);
-    }
-    fragment_end = i;
+URI::URI(std::string scheme, std::string authority, std::string path,
+         std::vector<QueryParam> query_parameter_pairs, std::string fragment)
+    : scheme_(std::move(scheme)),
+      authority_(std::move(authority)),
+      path_(std::move(path)),
+      query_parameter_pairs_(std::move(query_parameter_pairs)),
+      fragment_(std::move(fragment)) {
+  for (const auto& kv : query_parameter_pairs_) {
+    query_parameter_map_[kv.key] = kv.value;
   }
-
-  uri = static_cast<grpc_uri*>(gpr_zalloc(sizeof(*uri)));
-  uri->scheme = decode_and_copy_component(uri_text, scheme_begin, scheme_end);
-  uri->authority =
-      decode_and_copy_component(uri_text, authority_begin, authority_end);
-  uri->path = decode_and_copy_component(uri_text, path_begin, path_end);
-  uri->query = decode_and_copy_component(uri_text, query_begin, query_end);
-  uri->fragment =
-      decode_and_copy_component(uri_text, fragment_begin, fragment_end);
-  parse_query_parts(uri);
-
-  return uri;
 }
 
-const char* grpc_uri_get_query_arg(const grpc_uri* uri, const char* key) {
-  GPR_ASSERT(key != nullptr);
-  if (key[0] == '\0') return nullptr;
-
-  for (size_t i = 0; i < uri->num_query_parts; ++i) {
-    if (0 == strcmp(key, uri->query_parts[i])) {
-      return uri->query_parts_values[i];
-    }
+URI::URI(const URI& other)
+    : scheme_(other.scheme_),
+      authority_(other.authority_),
+      path_(other.path_),
+      query_parameter_pairs_(other.query_parameter_pairs_),
+      fragment_(other.fragment_) {
+  for (const auto& kv : query_parameter_pairs_) {
+    query_parameter_map_[kv.key] = kv.value;
   }
-  return nullptr;
 }
 
-void grpc_uri_destroy(grpc_uri* uri) {
-  if (!uri) return;
-  gpr_free(uri->scheme);
-  gpr_free(uri->authority);
-  gpr_free(uri->path);
-  gpr_free(uri->query);
-  for (size_t i = 0; i < uri->num_query_parts; ++i) {
-    gpr_free(uri->query_parts[i]);
-    gpr_free(uri->query_parts_values[i]);
+URI& URI::operator=(const URI& other) {
+  if (this == &other) {
+    return *this;
+  }
+  scheme_ = other.scheme_;
+  authority_ = other.authority_;
+  path_ = other.path_;
+  query_parameter_pairs_ = other.query_parameter_pairs_;
+  fragment_ = other.fragment_;
+  for (const auto& kv : query_parameter_pairs_) {
+    query_parameter_map_[kv.key] = kv.value;
   }
-  gpr_free(uri->query_parts);
-  gpr_free(uri->query_parts_values);
-  gpr_free(uri->fragment);
-  gpr_free(uri);
+  return *this;
 }
+}  // namespace grpc_core
index e000afc..dcd7e12 100644 (file)
 
 #include <grpc/support/port_platform.h>
 
+#include <stddef.h>
+
+#include <map>
+#include <string>
+#include <vector>
+
+#include "absl/status/statusor.h"
 #include "absl/strings/string_view.h"
 
-#include <stddef.h>
+namespace grpc_core {
 
-struct grpc_uri {
-  char* scheme;
-  char* authority;
-  char* path;
-  char* query;
-  /** Query substrings separated by '&' */
-  char** query_parts;
-  /** Number of elements in \a query_parts and \a query_parts_values */
-  size_t num_query_parts;
-  /** Split each query part by '='. NULL if not present. */
-  char** query_parts_values;
-  char* fragment;
-};
-/** parse a uri, return NULL on failure */
-grpc_uri* grpc_uri_parse(absl::string_view uri_text, bool suppress_errors);
+class URI {
+ public:
+  struct QueryParam {
+    std::string key;
+    std::string value;
+    bool operator==(const QueryParam& other) const {
+      return key == other.key && value == other.value;
+    }
+  };
+
+  // Creates an instance of GrpcURI by parsing an rfc3986 URI string. Returns
+  // an IllegalArgumentError on failure.
+  static absl::StatusOr<URI> Parse(absl::string_view uri_text);
+  // Explicit construction by individual URI components
+  URI(std::string scheme, std::string authority, std::string path,
+      std::vector<QueryParam> query_parameter_pairs, std::string fragment_);
+  URI() = default;
+  // Copy construction and assignment
+  URI(const URI& other);
+  URI& operator=(const URI& other);
+  // Move construction and assignment
+  URI(URI&&) = default;
+  URI& operator=(URI&&) = default;
 
-/** return the part of a query string after the '=' in "?key=xxx&...", or NULL
- * if key is not present */
-const char* grpc_uri_get_query_arg(const grpc_uri* uri, const char* key);
+  const std::string& scheme() const { return scheme_; }
+  const std::string& authority() const { return authority_; }
+  const std::string& path() const { return path_; }
+  // Stores the *last* value appearing for each repeated key in the query
+  // string. If you need to capture repeated query parameters, use
+  // `query_parameter_pairs`.
+  const std::map<absl::string_view, absl::string_view>& query_parameter_map()
+      const {
+    return query_parameter_map_;
+  }
+  // A vector of key:value query parameter pairs, kept in order of appearance
+  // within the URI search string. Repeated keys are represented as separate
+  // key:value elements.
+  const std::vector<QueryParam>& query_parameter_pairs() const {
+    return query_parameter_pairs_;
+  }
+  const std::string& fragment() const { return fragment_; }
 
-/** destroy a uri */
-void grpc_uri_destroy(grpc_uri* uri);
+ private:
+  std::string scheme_;
+  std::string authority_;
+  std::string path_;
+  std::map<absl::string_view, absl::string_view> query_parameter_map_;
+  std::vector<QueryParam> query_parameter_pairs_;
+  std::string fragment_;
+};
+}  // namespace grpc_core
 
 #endif /* GRPC_CORE_LIB_URI_URI_PARSER_H */
index 5581523..ae3993a 100644 (file)
@@ -68,12 +68,16 @@ void XdsClientGlobalShutdown();
 }  // namespace grpc_core
 void grpc_certificate_provider_registry_init(void);
 void grpc_certificate_provider_registry_shutdown(void);
+namespace grpc_core {
+void FileWatcherCertificateProviderInit();
+void FileWatcherCertificateProviderShutdown();
+}  // namespace grpc_core
 void grpc_lb_policy_cds_init(void);
 void grpc_lb_policy_cds_shutdown(void);
-void grpc_lb_policy_eds_init(void);
-void grpc_lb_policy_eds_shutdown(void);
 void grpc_lb_policy_xds_cluster_impl_init(void);
 void grpc_lb_policy_xds_cluster_impl_shutdown(void);
+void grpc_lb_policy_xds_cluster_resolver_init(void);
+void grpc_lb_policy_xds_cluster_resolver_shutdown(void);
 void grpc_lb_policy_xds_cluster_manager_init(void);
 void grpc_lb_policy_xds_cluster_manager_shutdown(void);
 void grpc_resolver_xds_init(void);
@@ -126,12 +130,14 @@ void grpc_register_built_in_plugins(void) {
                        grpc_core::XdsClientGlobalShutdown);
   grpc_register_plugin(grpc_certificate_provider_registry_init,
                        grpc_certificate_provider_registry_shutdown);
+  grpc_register_plugin(grpc_core::FileWatcherCertificateProviderInit,
+                       grpc_core::FileWatcherCertificateProviderShutdown);
   grpc_register_plugin(grpc_lb_policy_cds_init,
                        grpc_lb_policy_cds_shutdown);
-  grpc_register_plugin(grpc_lb_policy_eds_init,
-                       grpc_lb_policy_eds_shutdown);
   grpc_register_plugin(grpc_lb_policy_xds_cluster_impl_init,
                        grpc_lb_policy_xds_cluster_impl_shutdown);
+  grpc_register_plugin(grpc_lb_policy_xds_cluster_resolver_init,
+                       grpc_lb_policy_xds_cluster_resolver_shutdown);
   grpc_register_plugin(grpc_lb_policy_xds_cluster_manager_init,
                        grpc_lb_policy_xds_cluster_manager_shutdown);
   grpc_register_plugin(grpc_resolver_xds_init,
index 6236591..d4de9cd 100644 (file)
@@ -43,8 +43,9 @@ grpc_status_code gsec_aead_crypter_encrypt(
     char** error_details) {
   if (crypter != nullptr && crypter->vtable != nullptr &&
       crypter->vtable->encrypt_iovec != nullptr) {
-    struct iovec aad_vec = {(void*)aad, aad_length};
-    struct iovec plaintext_vec = {(void*)plaintext, plaintext_length};
+    struct iovec aad_vec = {const_cast<uint8_t*>(aad), aad_length};
+    struct iovec plaintext_vec = {const_cast<uint8_t*>(plaintext),
+                                  plaintext_length};
     struct iovec ciphertext_vec = {ciphertext_and_tag,
                                    ciphertext_and_tag_length};
     return crypter->vtable->encrypt_iovec(
@@ -81,8 +82,8 @@ grpc_status_code gsec_aead_crypter_decrypt(
     size_t plaintext_length, size_t* bytes_written, char** error_details) {
   if (crypter != nullptr && crypter->vtable != nullptr &&
       crypter->vtable->decrypt_iovec != nullptr) {
-    struct iovec aad_vec = {(void*)aad, aad_length};
-    struct iovec ciphertext_vec = {(void*)ciphertext_and_tag,
+    struct iovec aad_vec = {const_cast<uint8_t*>(aad), aad_length};
+    struct iovec ciphertext_vec = {const_cast<uint8_t*>(ciphertext_and_tag),
                                    ciphertext_and_tag_length};
     struct iovec plaintext_vec = {plaintext, plaintext_length};
     return crypter->vtable->decrypt_iovec(
index d3fda63..aa90bbc 100644 (file)
 
 /* Use little endian to interpret a string of bytes as uint32_t. */
 static uint32_t load_32_le(const unsigned char* buffer) {
-  return (((uint32_t)buffer[3]) << 24) | (((uint32_t)buffer[2]) << 16) |
-         (((uint32_t)buffer[1]) << 8) | ((uint32_t)buffer[0]);
+  return (static_cast<uint32_t>(buffer[3]) << 24) |
+         (static_cast<uint32_t>(buffer[2]) << 16) |
+         (static_cast<uint32_t>(buffer[1]) << 8) |
+         static_cast<uint32_t>(buffer[0]);
 }
 
 /* Store uint32_t as a string of little endian bytes. */
 static void store_32_le(uint32_t value, unsigned char* buffer) {
-  buffer[3] = (unsigned char)(value >> 24) & 0xFF;
-  buffer[2] = (unsigned char)(value >> 16) & 0xFF;
-  buffer[1] = (unsigned char)(value >> 8) & 0xFF;
-  buffer[0] = (unsigned char)(value)&0xFF;
+  buffer[3] = static_cast<unsigned char>(value >> 24) & 0xFF;
+  buffer[2] = static_cast<unsigned char>(value >> 16) & 0xFF;
+  buffer[1] = static_cast<unsigned char>(value >> 8) & 0xFF;
+  buffer[0] = static_cast<unsigned char>(value) & 0xFF;
 }
 
 /* Frame writer implementation. */
index e2f04f7..845b23f 100644 (file)
@@ -279,7 +279,7 @@ void alts_handshaker_client_handle_response(alts_handshaker_client* c,
   if (code != GRPC_STATUS_OK) {
     upb_strview details = grpc_gcp_HandshakerStatus_details(resp_status);
     if (details.size > 0) {
-      char* error_details = (char*)gpr_zalloc(details.size + 1);
+      char* error_details = static_cast<char*>(gpr_zalloc(details.size + 1));
       memcpy(error_details, details.data, details.size);
       gpr_log(GPR_ERROR, "Error from handshaker service:%s", error_details);
       gpr_free(error_details);
index e7cd3cd..19f41fe 100644 (file)
@@ -253,8 +253,8 @@ static const tsi_handshaker_result_vtable result_vtable = {
 
 tsi_result alts_tsi_handshaker_result_create(grpc_gcp_HandshakerResp* resp,
                                              bool is_client,
-                                             tsi_handshaker_result** self) {
-  if (self == nullptr || resp == nullptr) {
+                                             tsi_handshaker_result** result) {
+  if (result == nullptr || resp == nullptr) {
     gpr_log(GPR_ERROR, "Invalid arguments to create_handshaker_result()");
     return TSI_INVALID_ARGUMENT;
   }
@@ -305,19 +305,19 @@ tsi_result alts_tsi_handshaker_result_create(grpc_gcp_HandshakerResp* resp,
       grpc_gcp_Identity_service_account(local_identity);
   // We don't check if local service account is empty here
   // because local identity could be empty in certain situations.
-  alts_tsi_handshaker_result* result =
-      static_cast<alts_tsi_handshaker_result*>(gpr_zalloc(sizeof(*result)));
-  result->key_data =
+  alts_tsi_handshaker_result* sresult =
+      static_cast<alts_tsi_handshaker_result*>(gpr_zalloc(sizeof(*sresult)));
+  sresult->key_data =
       static_cast<char*>(gpr_zalloc(kAltsAes128GcmRekeyKeyLength));
-  memcpy(result->key_data, key_data.data, kAltsAes128GcmRekeyKeyLength);
-  result->peer_identity =
+  memcpy(sresult->key_data, key_data.data, kAltsAes128GcmRekeyKeyLength);
+  sresult->peer_identity =
       static_cast<char*>(gpr_zalloc(peer_service_account.size + 1));
-  memcpy(result->peer_identity, peer_service_account.data,
+  memcpy(sresult->peer_identity, peer_service_account.data,
          peer_service_account.size);
-  result->max_frame_size = grpc_gcp_HandshakerResult_max_frame_size(hresult);
+  sresult->max_frame_size = grpc_gcp_HandshakerResult_max_frame_size(hresult);
   upb::Arena rpc_versions_arena;
   bool serialized = grpc_gcp_rpc_protocol_versions_encode(
-      peer_rpc_version, rpc_versions_arena.ptr(), &result->rpc_versions);
+      peer_rpc_version, rpc_versions_arena.ptr(), &sresult->rpc_versions);
   if (!serialized) {
     gpr_log(GPR_ERROR, "Failed to serialize peer's RPC protocol versions.");
     return TSI_FAILED_PRECONDITION;
@@ -363,11 +363,11 @@ tsi_result alts_tsi_handshaker_result_create(grpc_gcp_HandshakerResp* resp,
     gpr_log(GPR_ERROR, "Failed to serialize peer's ALTS context.");
     return TSI_FAILED_PRECONDITION;
   }
-  result->serialized_context =
+  sresult->serialized_context =
       grpc_slice_from_copied_buffer(serialized_ctx, serialized_ctx_length);
-  result->is_client = is_client;
-  result->base.vtable = &result_vtable;
-  *self = &result->base;
+  sresult->is_client = is_client;
+  sresult->base.vtable = &result_vtable;
+  *result = &sresult->base;
   return TSI_OK;
 }
 
@@ -652,21 +652,21 @@ tsi_result alts_tsi_handshaker_create(
   return TSI_OK;
 }
 
-void alts_tsi_handshaker_result_set_unused_bytes(tsi_handshaker_result* self,
+void alts_tsi_handshaker_result_set_unused_bytes(tsi_handshaker_result* result,
                                                  grpc_slice* recv_bytes,
                                                  size_t bytes_consumed) {
-  GPR_ASSERT(recv_bytes != nullptr && self != nullptr);
+  GPR_ASSERT(recv_bytes != nullptr && result != nullptr);
   if (GRPC_SLICE_LENGTH(*recv_bytes) == bytes_consumed) {
     return;
   }
-  alts_tsi_handshaker_result* result =
-      reinterpret_cast<alts_tsi_handshaker_result*>(self);
-  result->unused_bytes_size = GRPC_SLICE_LENGTH(*recv_bytes) - bytes_consumed;
-  result->unused_bytes =
-      static_cast<unsigned char*>(gpr_zalloc(result->unused_bytes_size));
-  memcpy(result->unused_bytes,
+  alts_tsi_handshaker_result* sresult =
+      reinterpret_cast<alts_tsi_handshaker_result*>(result);
+  sresult->unused_bytes_size = GRPC_SLICE_LENGTH(*recv_bytes) - bytes_consumed;
+  sresult->unused_bytes =
+      static_cast<unsigned char*>(gpr_zalloc(sresult->unused_bytes_size));
+  memcpy(sresult->unused_bytes,
          GRPC_SLICE_START_PTR(*recv_bytes) + bytes_consumed,
-         result->unused_bytes_size);
+         sresult->unused_bytes_size);
 }
 
 namespace grpc_core {
index 6a548e5..26c18a4 100644 (file)
@@ -56,16 +56,18 @@ static void maybe_append_error_msg(const char* appendix, char** dst) {
 
 /* Use little endian to interpret a string of bytes as uint32_t.  */
 static uint32_t load_32_le(const unsigned char* buffer) {
-  return (((uint32_t)buffer[3]) << 24) | (((uint32_t)buffer[2]) << 16) |
-         (((uint32_t)buffer[1]) << 8) | ((uint32_t)buffer[0]);
+  return (static_cast<uint32_t>(buffer[3]) << 24) |
+         (static_cast<uint32_t>(buffer[2]) << 16) |
+         (static_cast<uint32_t>(buffer[1]) << 8) |
+         static_cast<uint32_t>(buffer[0]);
 }
 
 /* Store uint32_t as a string of little endian bytes.  */
 static void store_32_le(uint32_t value, unsigned char* buffer) {
-  buffer[3] = (unsigned char)(value >> 24) & 0xFF;
-  buffer[2] = (unsigned char)(value >> 16) & 0xFF;
-  buffer[1] = (unsigned char)(value >> 8) & 0xFF;
-  buffer[0] = (unsigned char)(value)&0xFF;
+  buffer[3] = static_cast<unsigned char>(value >> 24) & 0xFF;
+  buffer[2] = static_cast<unsigned char>(value >> 16) & 0xFF;
+  buffer[1] = static_cast<unsigned char>(value >> 8) & 0xFF;
+  buffer[0] = static_cast<unsigned char>(value) & 0xFF;
 }
 
 /* Ensures header and tag iovec have sufficient length.  */
index 0cdf974..e0ce641 100644 (file)
@@ -87,10 +87,10 @@ static bool read_frame_size(const grpc_slice_buffer* sb,
   }
   GPR_ASSERT(remaining == 0);
   /* Gets little-endian frame size.  */
-  uint32_t frame_size = (((uint32_t)frame_size_buffer[3]) << 24) |
-                        (((uint32_t)frame_size_buffer[2]) << 16) |
-                        (((uint32_t)frame_size_buffer[1]) << 8) |
-                        ((uint32_t)frame_size_buffer[0]);
+  uint32_t frame_size = (static_cast<uint32_t>(frame_size_buffer[3]) << 24) |
+                        (static_cast<uint32_t>(frame_size_buffer[2]) << 16) |
+                        (static_cast<uint32_t>(frame_size_buffer[1]) << 8) |
+                        static_cast<uint32_t>(frame_size_buffer[0]);
   if (frame_size > kMaxFrameLength) {
     gpr_log(GPR_ERROR, "Frame size is larger than maximum frame size");
     return false;
index 0675654..0b256a1 100644 (file)
@@ -524,7 +524,8 @@ static tsi_result fake_handshaker_result_create_frame_protector(
 static tsi_result fake_handshaker_result_get_unused_bytes(
     const tsi_handshaker_result* self, const unsigned char** bytes,
     size_t* bytes_size) {
-  fake_handshaker_result* result = (fake_handshaker_result*)self;
+  fake_handshaker_result* result = reinterpret_cast<fake_handshaker_result*>(
+      const_cast<tsi_handshaker_result*>(self));
   *bytes_size = result->unused_bytes_size;
   *bytes = result->unused_bytes;
   return TSI_OK;
@@ -581,8 +582,9 @@ static tsi_result fake_handshaker_get_bytes_to_send_to_peer(
         static_cast<tsi_fake_handshake_message>(impl->next_message_to_send + 2);
     const char* msg_string =
         tsi_fake_handshake_message_to_string(impl->next_message_to_send);
-    result = tsi_fake_frame_set_data((unsigned char*)msg_string,
-                                     strlen(msg_string), &impl->outgoing_frame);
+    result = tsi_fake_frame_set_data(
+        reinterpret_cast<unsigned char*>(const_cast<char*>(msg_string)),
+        strlen(msg_string), &impl->outgoing_frame);
     if (result != TSI_OK) return result;
     if (next_message_to_send > TSI_FAKE_HANDSHAKE_MESSAGE_MAX) {
       next_message_to_send = TSI_FAKE_HANDSHAKE_MESSAGE_MAX;
index 612ecff..dcfff00 100644 (file)
@@ -32,7 +32,7 @@ namespace {
 
 class BoringSslCachedSession : public SslCachedSession {
  public:
-  BoringSslCachedSession(SslSessionPtr session)
+  explicit BoringSslCachedSession(SslSessionPtr session)
       : session_(std::move(session)) {}
 
   SslSessionPtr CopySession() const override {
index ad9f570..7f8749c 100644 (file)
@@ -141,7 +141,7 @@ struct tsi_ssl_frame_protector {
 static gpr_once g_init_openssl_once = GPR_ONCE_INIT;
 static int g_ssl_ctx_ex_factory_index = -1;
 static const unsigned char kSslSessionIdContext[] = {'g', 'r', 'p', 'c'};
-#ifndef OPENSSL_IS_BORINGSSL
+#if !defined(OPENSSL_IS_BORINGSSL) && !defined(OPENSSL_NO_ENGINE)
 static const char kSslEnginePrefix[] = "engine:";
 #endif
 
@@ -340,8 +340,7 @@ static tsi_result add_pem_certificate(X509* cert, tsi_peer_property* property) {
     return TSI_INTERNAL_ERROR;
   }
   tsi_result result = tsi_construct_string_peer_property(
-      TSI_X509_PEM_CERT_PROPERTY, (const char*)contents,
-      static_cast<size_t>(len), property);
+      TSI_X509_PEM_CERT_PROPERTY, contents, static_cast<size_t>(len), property);
   BIO_free(bio);
   return result;
 }
@@ -554,12 +553,12 @@ static tsi_result ssl_ctx_use_certificate_chain(SSL_CTX* context,
   X509* certificate = nullptr;
   BIO* pem;
   GPR_ASSERT(pem_cert_chain_size <= INT_MAX);
-  pem = BIO_new_mem_buf((void*)pem_cert_chain,
-                        static_cast<int>(pem_cert_chain_size));
+  pem = BIO_new_mem_buf(pem_cert_chain, static_cast<int>(pem_cert_chain_size));
   if (pem == nullptr) return TSI_OUT_OF_RESOURCES;
 
   do {
-    certificate = PEM_read_bio_X509_AUX(pem, nullptr, nullptr, (void*)"");
+    certificate =
+        PEM_read_bio_X509_AUX(pem, nullptr, nullptr, const_cast<char*>(""));
     if (certificate == nullptr) {
       result = TSI_INVALID_ARGUMENT;
       break;
@@ -570,7 +569,7 @@ static tsi_result ssl_ctx_use_certificate_chain(SSL_CTX* context,
     }
     while (true) {
       X509* certificate_authority =
-          PEM_read_bio_X509(pem, nullptr, nullptr, (void*)"");
+          PEM_read_bio_X509(pem, nullptr, nullptr, const_cast<char*>(""));
       if (certificate_authority == nullptr) {
         ERR_clear_error();
         break; /* Done reading. */
@@ -592,7 +591,7 @@ static tsi_result ssl_ctx_use_certificate_chain(SSL_CTX* context,
   return result;
 }
 
-#ifndef OPENSSL_IS_BORINGSSL
+#if !defined(OPENSSL_IS_BORINGSSL) && !defined(OPENSSL_NO_ENGINE)
 static tsi_result ssl_ctx_use_engine_private_key(SSL_CTX* context,
                                                  const char* pem_key,
                                                  size_t pem_key_size) {
@@ -665,7 +664,7 @@ static tsi_result ssl_ctx_use_engine_private_key(SSL_CTX* context,
   if (engine_name != nullptr) gpr_free(engine_name);
   return result;
 }
-#endif /* OPENSSL_IS_BORINGSSL */
+#endif /* !defined(OPENSSL_IS_BORINGSSL) && !defined(OPENSSL_NO_ENGINE) */
 
 static tsi_result ssl_ctx_use_pem_private_key(SSL_CTX* context,
                                               const char* pem_key,
@@ -674,10 +673,11 @@ static tsi_result ssl_ctx_use_pem_private_key(SSL_CTX* context,
   EVP_PKEY* private_key = nullptr;
   BIO* pem;
   GPR_ASSERT(pem_key_size <= INT_MAX);
-  pem = BIO_new_mem_buf((void*)pem_key, static_cast<int>(pem_key_size));
+  pem = BIO_new_mem_buf(pem_key, static_cast<int>(pem_key_size));
   if (pem == nullptr) return TSI_OUT_OF_RESOURCES;
   do {
-    private_key = PEM_read_bio_PrivateKey(pem, nullptr, nullptr, (void*)"");
+    private_key =
+        PEM_read_bio_PrivateKey(pem, nullptr, nullptr, const_cast<char*>(""));
     if (private_key == nullptr) {
       result = TSI_INVALID_ARGUMENT;
       break;
@@ -696,11 +696,11 @@ static tsi_result ssl_ctx_use_pem_private_key(SSL_CTX* context,
 static tsi_result ssl_ctx_use_private_key(SSL_CTX* context, const char* pem_key,
                                           size_t pem_key_size) {
 // BoringSSL does not have ENGINE support
-#ifndef OPENSSL_IS_BORINGSSL
+#if !defined(OPENSSL_IS_BORINGSSL) && !defined(OPENSSL_NO_ENGINE)
   if (strncmp(pem_key, kSslEnginePrefix, strlen(kSslEnginePrefix)) == 0) {
     return ssl_ctx_use_engine_private_key(context, pem_key, pem_key_size);
   } else
-#endif /* OPENSSL_IS_BORINGSSL */
+#endif /* !defined(OPENSSL_IS_BORINGSSL) && !defined(OPENSSL_NO_ENGINE) */
   {
     return ssl_ctx_use_pem_private_key(context, pem_key, pem_key_size);
   }
@@ -718,7 +718,7 @@ static tsi_result x509_store_load_certs(X509_STORE* cert_store,
   X509_NAME* root_name = nullptr;
   BIO* pem;
   GPR_ASSERT(pem_roots_size <= INT_MAX);
-  pem = BIO_new_mem_buf((void*)pem_roots, static_cast<int>(pem_roots_size));
+  pem = BIO_new_mem_buf(pem_roots, static_cast<int>(pem_roots_size));
   if (cert_store == nullptr) return TSI_INVALID_ARGUMENT;
   if (pem == nullptr) return TSI_OUT_OF_RESOURCES;
   if (root_names != nullptr) {
@@ -727,7 +727,7 @@ static tsi_result x509_store_load_certs(X509_STORE* cert_store,
   }
 
   while (true) {
-    root = PEM_read_bio_X509_AUX(pem, nullptr, nullptr, (void*)"");
+    root = PEM_read_bio_X509_AUX(pem, nullptr, nullptr, const_cast<char*>(""));
     if (root == nullptr) {
       ERR_clear_error();
       break; /* We're at the end of stream. */
@@ -837,10 +837,10 @@ tsi_result tsi_ssl_extract_x509_subject_names_from_pem_cert(
   tsi_result result = TSI_OK;
   X509* cert = nullptr;
   BIO* pem;
-  pem = BIO_new_mem_buf((void*)pem_cert, static_cast<int>(strlen(pem_cert)));
+  pem = BIO_new_mem_buf(pem_cert, static_cast<int>(strlen(pem_cert)));
   if (pem == nullptr) return TSI_OUT_OF_RESOURCES;
 
-  cert = PEM_read_bio_X509(pem, nullptr, nullptr, (void*)"");
+  cert = PEM_read_bio_X509(pem, nullptr, nullptr, const_cast<char*>(""));
   if (cert == nullptr) {
     gpr_log(GPR_ERROR, "Invalid certificate");
     result = TSI_INVALID_ARGUMENT;
@@ -910,12 +910,18 @@ static tsi_result tsi_set_min_and_max_tls_versions(
     return TSI_INVALID_ARGUMENT;
   }
 #if OPENSSL_VERSION_NUMBER >= 0x10100000
-  // Set the min TLS version of the SSL context.
+  // Set the min TLS version of the SSL context if using OpenSSL version
+  // >= 1.1.0. This OpenSSL version is required because the
+  // |SSL_CTX_set_min_proto_version| and |SSL_CTX_set_max_proto_version| APIs
+  // only exist in this version range.
   switch (min_tls_version) {
     case tsi_tls_version::TSI_TLS1_2:
       SSL_CTX_set_min_proto_version(ssl_context, TLS1_2_VERSION);
       break;
 #if defined(TLS1_3_VERSION)
+    // If the library does not support TLS 1.3 and the caller requests a minimum
+    // of TLS 1.3, then return an error because the caller's request cannot be
+    // satisfied.
     case tsi_tls_version::TSI_TLS1_3:
       SSL_CTX_set_min_proto_version(ssl_context, TLS1_3_VERSION);
       break;
@@ -924,16 +930,21 @@ static tsi_result tsi_set_min_and_max_tls_versions(
       gpr_log(GPR_INFO, "TLS version is not supported.");
       return TSI_FAILED_PRECONDITION;
   }
+
   // Set the max TLS version of the SSL context.
   switch (max_tls_version) {
     case tsi_tls_version::TSI_TLS1_2:
       SSL_CTX_set_max_proto_version(ssl_context, TLS1_2_VERSION);
       break;
-#if defined(TLS1_3_VERSION)
     case tsi_tls_version::TSI_TLS1_3:
+#if defined(TLS1_3_VERSION)
       SSL_CTX_set_max_proto_version(ssl_context, TLS1_3_VERSION);
-      break;
+#else
+      // If the library does not support TLS 1.3, then set the max TLS version
+      // to TLS 1.2 instead.
+      SSL_CTX_set_max_proto_version(ssl_context, TLS1_2_VERSION);
 #endif
+      break;
     default:
       gpr_log(GPR_INFO, "TLS version is not supported.");
       return TSI_FAILED_PRECONDITION;
@@ -1150,11 +1161,11 @@ static const tsi_frame_protector_vtable frame_protector_vtable = {
 /* --- tsi_server_handshaker_factory methods implementation. --- */
 
 static void tsi_ssl_handshaker_factory_destroy(
-    tsi_ssl_handshaker_factory* self) {
-  if (self == nullptr) return;
+    tsi_ssl_handshaker_factory* factory) {
+  if (factory == nullptr) return;
 
-  if (self->vtable != nullptr && self->vtable->destroy != nullptr) {
-    self->vtable->destroy(self);
+  if (factory->vtable != nullptr && factory->vtable->destroy != nullptr) {
+    factory->vtable->destroy(factory);
   }
   /* Note, we don't free(self) here because this object is always directly
    * embedded in another object. If tsi_ssl_handshaker_factory_init allocates
@@ -1162,17 +1173,18 @@ static void tsi_ssl_handshaker_factory_destroy(
 }
 
 static tsi_ssl_handshaker_factory* tsi_ssl_handshaker_factory_ref(
-    tsi_ssl_handshaker_factory* self) {
-  if (self == nullptr) return nullptr;
-  gpr_refn(&self->refcount, 1);
-  return self;
+    tsi_ssl_handshaker_factory* factory) {
+  if (factory == nullptr) return nullptr;
+  gpr_refn(&factory->refcount, 1);
+  return factory;
 }
 
-static void tsi_ssl_handshaker_factory_unref(tsi_ssl_handshaker_factory* self) {
-  if (self == nullptr) return;
+static void tsi_ssl_handshaker_factory_unref(
+    tsi_ssl_handshaker_factory* factory) {
+  if (factory == nullptr) return;
 
-  if (gpr_unref(&self->refcount)) {
-    tsi_ssl_handshaker_factory_destroy(self);
+  if (gpr_unref(&factory->refcount)) {
+    tsi_ssl_handshaker_factory_destroy(factory);
   }
 }
 
@@ -1206,8 +1218,8 @@ tsi_result tsi_ssl_get_cert_chain_contents(STACK_OF(X509) * peer_chain,
     return TSI_INTERNAL_ERROR;
   }
   tsi_result result = tsi_construct_string_peer_property(
-      TSI_X509_PEM_CERT_CHAIN_PROPERTY, (const char*)contents,
-      static_cast<size_t>(len), property);
+      TSI_X509_PEM_CERT_CHAIN_PROPERTY, contents, static_cast<size_t>(len),
+      property);
   BIO_free(bio);
   return result;
 }
@@ -1682,16 +1694,17 @@ static int select_protocol_list(const unsigned char** out,
 /* --- tsi_ssl_client_handshaker_factory methods implementation. --- */
 
 tsi_result tsi_ssl_client_handshaker_factory_create_handshaker(
-    tsi_ssl_client_handshaker_factory* self, const char* server_name_indication,
-    tsi_handshaker** handshaker) {
-  return create_tsi_ssl_handshaker(self->ssl_context, 1, server_name_indication,
-                                   &self->base, handshaker);
+    tsi_ssl_client_handshaker_factory* factory,
+    const char* server_name_indication, tsi_handshaker** handshaker) {
+  return create_tsi_ssl_handshaker(factory->ssl_context, 1,
+                                   server_name_indication, &factory->base,
+                                   handshaker);
 }
 
 void tsi_ssl_client_handshaker_factory_unref(
-    tsi_ssl_client_handshaker_factory* self) {
-  if (self == nullptr) return;
-  tsi_ssl_handshaker_factory_unref(&self->base);
+    tsi_ssl_client_handshaker_factory* factory) {
+  if (factory == nullptr) return;
+  tsi_ssl_handshaker_factory_unref(&factory->base);
 }
 
 static void tsi_ssl_client_handshaker_factory_destroy(
@@ -1710,7 +1723,7 @@ static int client_handshaker_factory_npn_callback(
     const unsigned char* in, unsigned int inlen, void* arg) {
   tsi_ssl_client_handshaker_factory* factory =
       static_cast<tsi_ssl_client_handshaker_factory*>(arg);
-  return select_protocol_list((const unsigned char**)out, outlen,
+  return select_protocol_list(const_cast<const unsigned char**>(out), outlen,
                               factory->alpn_protocol_list,
                               factory->alpn_protocol_list_length, in, inlen);
 }
@@ -1718,18 +1731,18 @@ static int client_handshaker_factory_npn_callback(
 /* --- tsi_ssl_server_handshaker_factory methods implementation. --- */
 
 tsi_result tsi_ssl_server_handshaker_factory_create_handshaker(
-    tsi_ssl_server_handshaker_factory* self, tsi_handshaker** handshaker) {
-  if (self->ssl_context_count == 0) return TSI_INVALID_ARGUMENT;
+    tsi_ssl_server_handshaker_factory* factory, tsi_handshaker** handshaker) {
+  if (factory->ssl_context_count == 0) return TSI_INVALID_ARGUMENT;
   /* Create the handshaker with the first context. We will switch if needed
      because of SNI in ssl_server_handshaker_factory_servername_callback.  */
-  return create_tsi_ssl_handshaker(self->ssl_contexts[0], 0, nullptr,
-                                   &self->base, handshaker);
+  return create_tsi_ssl_handshaker(factory->ssl_contexts[0], 0, nullptr,
+                                   &factory->base, handshaker);
 }
 
 void tsi_ssl_server_handshaker_factory_unref(
-    tsi_ssl_server_handshaker_factory* self) {
-  if (self == nullptr) return;
-  tsi_ssl_handshaker_factory_unref(&self->base);
+    tsi_ssl_server_handshaker_factory* factory) {
+  if (factory == nullptr) return;
+  tsi_ssl_handshaker_factory_unref(&factory->base);
 }
 
 static void tsi_ssl_server_handshaker_factory_destroy(
index e57ef88..f25e067 100644 (file)
@@ -184,7 +184,7 @@ tsi_result tsi_create_ssl_client_handshaker_factory_with_options(
     tsi_ssl_client_handshaker_factory** factory);
 
 /* Creates a client handshaker.
-  - self is the factory from which the handshaker will be created.
+  - factory is the factory from which the handshaker will be created.
   - server_name_indication indicates the name of the server the client is
     trying to connect to which will be relayed to the server using the SNI
     extension.
@@ -193,8 +193,8 @@ tsi_result tsi_create_ssl_client_handshaker_factory_with_options(
   - This method returns TSI_OK on success or TSI_INVALID_PARAMETER in the case
     where a parameter is invalid.  */
 tsi_result tsi_ssl_client_handshaker_factory_create_handshaker(
-    tsi_ssl_client_handshaker_factory* self, const char* server_name_indication,
-    tsi_handshaker** handshaker);
+    tsi_ssl_client_handshaker_factory* factory,
+    const char* server_name_indication, tsi_handshaker** handshaker);
 
 /* Decrements reference count of the handshaker factory. Handshaker factory will
  * be destroyed once no references exist. */
@@ -315,18 +315,18 @@ tsi_result tsi_create_ssl_server_handshaker_factory_with_options(
     tsi_ssl_server_handshaker_factory** factory);
 
 /* Creates a server handshaker.
-  - self is the factory from which the handshaker will be created.
+  - factory is the factory from which the handshaker will be created.
   - handshaker is the address of the handshaker pointer to be created.
 
   - This method returns TSI_OK on success or TSI_INVALID_PARAMETER in the case
     where a parameter is invalid.  */
 tsi_result tsi_ssl_server_handshaker_factory_create_handshaker(
-    tsi_ssl_server_handshaker_factory* self, tsi_handshaker** handshaker);
+    tsi_ssl_server_handshaker_factory* factory, tsi_handshaker** handshaker);
 
 /* Decrements reference count of the handshaker factory. Handshaker factory will
  * be destroyed once no references exist. */
 void tsi_ssl_server_handshaker_factory_unref(
-    tsi_ssl_server_handshaker_factory* self);
+    tsi_ssl_server_handshaker_factory* factory);
 
 /* Util that checks that an ssl peer matches a specific name.
    Still TODO(jboeuf):
index ee9b60e..cc0b769 100644 (file)
@@ -36,6 +36,32 @@ common name which is set to testclient.
 $ openssl x509 -req -CA ca.pem -CAkey ca.key -CAcreateserial -in client.csr \
   -out client.pem -days 3650
 
+client1 is issued by CA:
+-----------------------
+
+$ openssl genrsa -out client1.key.rsa 2048
+$ openssl pkcs8 -topk8 -in client1.key.rsa -out client1.key -nocrypt
+$ openssl req -new -key client1.key -out client1.csr
+
+When prompted for certificate information, everything is default except the
+common name which is set to testclient1.
+
+$ openssl x509 -req -CA ca.pem -CAkey ca.key -CAcreateserial -in client1.csr \
+  -out client1.pem -days 3650
+
+client2 is issued by CA:
+-----------------------
+
+$ openssl genrsa -out client2.key.rsa 2048
+$ openssl pkcs8 -topk8 -in client2.key.rsa -out client2.key -nocrypt
+$ openssl req -new -key client2.key -out client2.csr
+
+When prompted for certificate information, everything is default except the
+common name which is set to testclient2.
+
+$ openssl x509 -req -CA ca.pem -CAkey ca.key -CAcreateserial -in client2.csr \
+  -out client2.pem -days 3650
+
 server0 is issued by CA:
 ------------------------
 
@@ -62,7 +88,8 @@ common name which is set to *.test.google.com.
 $ openssl x509 -req -CA ca.pem -CAkey ca.key -CAcreateserial -in server1.csr \
   -out server1.pem -extensions req_ext -extfile server1-openssl.cnf -days 3650
 
-multi-domain is a self-signed certificate having multiple subject alternative names:
+multi-domain is a self-signed certificate having multiple subject alternative
+names:
 ----------------------------------------------------------------------------
 
 $ openssl genrsa -out multi-domain.key.rsa 2048
@@ -81,7 +108,7 @@ $ rm ca.srl
 Sync up with other repositories
 ===============================
 
-Copies of these keys (except for multi-domain) exist in multiple locations across all the grpc repos
+Copies of these keys exist in multiple locations across all the grpc repos
 (e.g., see the following partial list). You need to be careful when updating
 the keys.
 
@@ -97,3 +124,10 @@ src/python/grpcio_tests/tests/interop/credentials/
 src/python/grpcio_tests/tests/unit/credentials/
 src/ruby/spec/testdata/
 test/core/end2end/data/
+
+The following keys/certs are not distributed through multiple grpc repos yet,
+since they are only used in grpc core tests:
+
+multi-domain.*
+client1.*
+client2.*
diff --git a/src/core/tsi/test_creds/client1.key b/src/core/tsi/test_creds/client1.key
new file mode 100644 (file)
index 0000000..c37df79
--- /dev/null
@@ -0,0 +1,28 @@
+-----BEGIN PRIVATE KEY-----
+MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQD0d1XmFuS1iwBQ
+wzGnGhA/ovsFp5jTF0v+aJptNKcwQzlMCkbpBtkVB2SFcsgWew0qtQH57E4iS8pe
+gdW5JO6Jgl04aFuVDU2gKYRUB2pXQYObw9GZ6k8SyvDWfZIpTj+qCQ25zQ1/CzgD
+b9FKPBPXaIuW8eiYZJwPoOlhBX+RxAfKt79/Ilj2V9JnWi5wH6kRKbfZYg/usKT/
+lfHtlxZ8TdORqVFncnMxoxPTEwLwbqYaUyW6x3kqoFjixdYDuEkOIVoHs/+SBp1H
+fRKpfnyErQkd3YcjQm0JgjqCG4+hFNb2HfEUfCSeeWHhAD/S4r1s3sepCm71/huU
+GmO7IV2VAgMBAAECggEARy/o55OLDgJoGRx9/Pbt/FntVvwy2GVUT8UOEvbeKIOq
+z6W+eGTyGdmJQALomQNEFkeXR7u0FPCVAWg1YDCM9aXsl1xsLr8s95KfYgi2wqnl
+NRqUkolUdVh7QTpXsYeDqnPwd0Zqw6/0o6uP+ln8PSHIZDAVVysU9sgYrZP4Te2B
+0l5lmmBp8wRtKjZqhQPPuEhW3UETYRWK0QK3siVsnQJrH4k7Sys7AEnMP5NWewBC
+R79DQL7eHPX19H/7vBY2cAI8e51yhcT2b+tK6oMn/Xg/sHelVs/uRmShSxwo0eya
+Du9oXbV1h3DoIRP2rC1aXQ67sMJQvQvINV8jRgIHkQKBgQD9Mo2XrCWK9W+qFc67
+9MeKX8LG0pz7ORJnx7sORYfsIbfhD5/u22K9RuaHrPoLcjTNXKvQHR54fGJFevaL
+h7X+MrXYxtgCIOQeebdHgkb//Px4VqUOoTOz3YfZ754M6S2x2Nf/eqvTSd1hjxKa
+L4FHVe65/7ENmLiFTbmTMFNTtwKBgQD3LAq2b3q8CTEhF9CaFrSCHnyvKtQYtGzg
+JE2ZfX5qAz6JlM/hOiVprRLEk/5g88519Q+odoPwzOFDSeWAhD7/tPA/OtLkqaSc
+reB6Gytu//yVKyPJ0eIDFKbWMWeDEObSwZtEwUf78wcABm5SMuoKC3C2y/woOke3
+a3bb9LUREwKBgHU5YICmPMN3Gnm+mvY+P9v6tezjOba+F51gxWO4IVPb0Iwsdbla
+bP6Awt5x4VpHR9cEXq99q8vQmpbcdSTocgP8amCwvvVNURAi/g3nbQO7lxAH3WdG
+ju9pUyo9XAlSM8uxP1+S5dZuzkYKvWwRLmNej6YhkVFgMZ3V/GL+7rVFAoGAaQ0Q
+6ITs9yo49UW35SWtRnhKqfBcALv+Yi1LxeauacRDOhpDWAhsikOC7IWx4eb9Yujq
+5MCqRxfszbqEjmCmnet7CISpyYHIcsb71ynhBeZKpeOV7FsF4iVO205YHj56vCyJ
+H2m+fHjICtyw2sLE8cv29dowq7BJds130PhqVH0CgYA3rlDMoCZiSKARwJr0/D6d
+B3ez0ZpxKbIHHB7e+T5PFll607I+F+S6IpPfKab3CZQiG/5H/7WFXda1t+rkdayM
+QKYvAk8Z8DdDDtdF6GygQq6kq5L54H8w+hcAhPA/AFvGM+59HBOkXlbF1ONmrH2D
+btxOGV07JxZEj0IlBMYIaA==
+-----END PRIVATE KEY-----
diff --git a/src/core/tsi/test_creds/client1.pem b/src/core/tsi/test_creds/client1.pem
new file mode 100644 (file)
index 0000000..c616b31
--- /dev/null
@@ -0,0 +1,20 @@
+-----BEGIN CERTIFICATE-----
+MIIDODCCAiACFDrXOoJ6yF2DsFledztcRyjY+3BcMA0GCSqGSIb3DQEBCwUAMFYx
+CzAJBgNVBAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRl
+cm5ldCBXaWRnaXRzIFB0eSBMdGQxDzANBgNVBAMMBnRlc3RjYTAeFw0yMDEyMDEy
+MzE2MTFaFw0zMDExMjkyMzE2MTFaMFsxCzAJBgNVBAYTAkFVMRMwEQYDVQQIDApT
+b21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGQxFDAS
+BgNVBAMMC3Rlc3RjbGllbnQxMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC
+AQEA9HdV5hbktYsAUMMxpxoQP6L7BaeY0xdL/miabTSnMEM5TApG6QbZFQdkhXLI
+FnsNKrUB+exOIkvKXoHVuSTuiYJdOGhblQ1NoCmEVAdqV0GDm8PRmepPEsrw1n2S
+KU4/qgkNuc0Nfws4A2/RSjwT12iLlvHomGScD6DpYQV/kcQHyre/fyJY9lfSZ1ou
+cB+pESm32WIP7rCk/5Xx7ZcWfE3TkalRZ3JzMaMT0xMC8G6mGlMlusd5KqBY4sXW
+A7hJDiFaB7P/kgadR30SqX58hK0JHd2HI0JtCYI6ghuPoRTW9h3xFHwknnlh4QA/
+0uK9bN7HqQpu9f4blBpjuyFdlQIDAQABMA0GCSqGSIb3DQEBCwUAA4IBAQAbJTrl
+e8OAQJMrB9utPrCemvV2xC3aK/jtKLOrJ/7n6Atf7Zd5cymfbK2XAGWUiUePvF06
+MlN5AJpN4ujQOB0y+UYS8y/58VGCC9UJnQLo5UATE8w5cAIq5j91vuW9roE/UU4x
+jSZ5kjKOPjOpAjbKM5Dp4WVff9/veve+gA+nXA8Xv7Hn0vCLcjdRpFPEfvgp66qP
+E+tpeRWOu6fggxtTlAK68HMkQqKpb6R+obMePzxiAAgGiy4o6RvsHLA0iuViqHuE
+mu8cmPbEvWxwzTthkZEj2ekdLKecFN4ub4suZyAF85mz2SI7D0p4C8M46VIhWq6i
+bBfU/DCPHpZpcVIl
+-----END CERTIFICATE-----
diff --git a/src/core/tsi/test_creds/client2.key b/src/core/tsi/test_creds/client2.key
new file mode 100644 (file)
index 0000000..613c47a
--- /dev/null
@@ -0,0 +1,28 @@
+-----BEGIN PRIVATE KEY-----
+MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQClO55XKwBIEnTa
+KeclFa6l3Bc3G4lMdDa+JdCi3x+5KYlBN9NJth5z7Pj6Nrv/bpm4g69qhVV2sIjJ
+4XeEeObLY+0cadU58hdPXlhWHoMJst5uU+DkV0yjPwvLkmhsRj0RPicV+2qV6Scq
+zQDqXMMx8jyhhExkZBeOz1xCGR4Abo1zdpNfusZJ3GsFGQwqxwdK/l4dIkyLqtxp
+IS+vSsYeAMyuVZJHD61u7YiZasREyrFqkkSyDPGeCR3k6+4ajwfz1rVMITP5EZJ2
+pUdvdRgke7Okpwanf8og9LF5AaJz53yuUBVz40O/3whI7J4e+D3i5V5JGftLl0/V
+xJDdHrU1AgMBAAECggEATQ701Wo0g2g4HtaT+fOWs7tlCEpLSeCY9yzjlFHClbQN
+UuEaJLJOmXnW07pbCtEl16tyT5dHOEc0RBJmjt1jpU9A8ZNZ4eBJhrZVNDSeoBNP
+MNzlcRhVoXxxn8rz8CsBp9z4lYPfPXKy1X8uAh6o2c5DAICWr+sOIYgLWrgkCcbF
+QxP5cRs53nFwImnOJka7sxgUvQNW74Zto3WByCQ3QkFDQEOMEFPP2v5J0AiZTuIC
+nFfB1/O2YByKOUjhA+7ZYX/3qSXRrC7VW4kaMl1fVABccUCWhPdc9u+xz+m2fWnQ
+ZZXeTbgNbhykldz6J6JmKnDtIdj5WfdNTdLSDGgasQKBgQDTBwW/y7NT0r+IJEOF
+hbxN2XtB+i2VDVoeS0TYpJFMZfufXkBc331jyQid/8yusPjYW31n5vHYopDydsde
+NGAdCfjtBFawVGPYvbTgXSrB5n120merdHQ6TFmp7QhjHU5ds7N8ihh1OQfkBw/6
+UUaHVn3sBAKOLYbcCvGin7FuFwKBgQDIcjFmajYPHQ+yom8zn1bCvfgJ1aEXsP6m
+PxHeP4JeBjaD1ukuq+LUGCgViDWCO8c/j1AcnrNihh2oP7brY+xEqpm6IfQI79KZ
+kp++ybm4w6yvuYNnWR9yXJc0LTrTu4IOMuDpbPBFT9gGDLZYYc7yT8U55NGC3ry7
+tv0lZKQykwKBgQCjUf8IFj3etO+ZDP/Y+cznr1aulFHs1p2VbomE5bCyIQehqs9D
+UZB4xuDNb2jZFoww3nXrERjBoeduT7Ey3nQ4ZTxrK31wEJAJ8aBoOJLb6GfXqzWi
+w4kkiWynj5R7KPY6nNZfn30YVCAgQbsC7x4Xpj/khqH3qZKDAFFMnC001wKBgCTA
+Sy5r6t16hpZKEfl1DYNHMWMcOB0P5qC0j6IgItb6bKRfkwFronsgsri/8I+gRjfx
+Hs8gieNWk7l1dSRTfc5ZOTZXY1cAIazmpUNl2Rd3SQIvEVixjoJ5V3/Jiy+nAYF4
+8qPZxXPv37u8OPKbfEYROigTPBayoAgK1P82JKThAoGAJQ7aR+ItRUSOyD/ofZKB
+wQeYSVnv+UQg6gTh4GWf91D4WYgBVCGWhPJ8zMRZfcy1/TplJC917MVnkLP7k91D
+paxsSdRDVkSATGTX3bOTw2P9CbNFpRUIdz++7hmbhZjT/DBvtFYiRuaylGAuAdH7
+YzdO4ZLBuBW7jbDc7a2RHNg=
+-----END PRIVATE KEY-----
diff --git a/src/core/tsi/test_creds/client2.pem b/src/core/tsi/test_creds/client2.pem
new file mode 100644 (file)
index 0000000..0565b1b
--- /dev/null
@@ -0,0 +1,20 @@
+-----BEGIN CERTIFICATE-----
+MIIDODCCAiACFBjjQkCIdrl6SU6uUtepyES0xVV2MA0GCSqGSIb3DQEBCwUAMFYx
+CzAJBgNVBAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRl
+cm5ldCBXaWRnaXRzIFB0eSBMdGQxDzANBgNVBAMMBnRlc3RjYTAeFw0yMDEyMDIw
+MTExNDNaFw0zMDExMzAwMTExNDNaMFsxCzAJBgNVBAYTAkFVMRMwEQYDVQQIDApT
+b21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGQxFDAS
+BgNVBAMMC3Rlc3RjbGllbnQyMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC
+AQEApTueVysASBJ02innJRWupdwXNxuJTHQ2viXQot8fuSmJQTfTSbYec+z4+ja7
+/26ZuIOvaoVVdrCIyeF3hHjmy2PtHGnVOfIXT15YVh6DCbLeblPg5FdMoz8Ly5Jo
+bEY9ET4nFftqleknKs0A6lzDMfI8oYRMZGQXjs9cQhkeAG6Nc3aTX7rGSdxrBRkM
+KscHSv5eHSJMi6rcaSEvr0rGHgDMrlWSRw+tbu2ImWrERMqxapJEsgzxngkd5Ovu
+Go8H89a1TCEz+RGSdqVHb3UYJHuzpKcGp3/KIPSxeQGic+d8rlAVc+NDv98ISOye
+Hvg94uVeSRn7S5dP1cSQ3R61NQIDAQABMA0GCSqGSIb3DQEBCwUAA4IBAQB4WZlD
+CgvMA/LD3wJAG2v53IuG8rJ2R0QG3dKbN6hCKsqVfJpF51L55RB+ABn7FT3CAfqJ
+w8IvisQ4vlr6dqxkGS7MPTou2H2LU6PARWPgqJnwRAB5gvjecHzDjKqhHlsQQXBw
+PHFt54EcyWtX2xgQmP5acjCj8o03gC3+tWtaAQgM6CExgXB4PgeUGIgTH5c016aZ
+YzxJgZS4UDfgA8+YVmzWNsGvgbITKu84hU2dqLCLoIqJPzwSikUVNS7Bo07o0hgH
+NNSDLaMNpaMC51dDiHbtER8hPp9elhSWOZRPXgEGbvQCFOt/Wz79Mw2dnpbBXVdb
+ANSsdO2Qu7snGMXr
+-----END CERTIFICATE-----
index 262db0d..dd62189 100644 (file)
@@ -194,7 +194,7 @@ tsi_result tsi_handshaker_extract_peer(tsi_handshaker* self, tsi_peer* peer) {
 }
 
 tsi_result tsi_handshaker_create_frame_protector(
-    tsi_handshaker* self, size_t* max_protected_frame_size,
+    tsi_handshaker* self, size_t* max_output_protected_frame_size,
     tsi_frame_protector** protector) {
   tsi_result result;
   if (self == nullptr || self->vtable == nullptr || protector == nullptr) {
@@ -204,8 +204,8 @@ tsi_result tsi_handshaker_create_frame_protector(
   if (self->handshake_shutdown) return TSI_HANDSHAKE_SHUTDOWN;
   if (tsi_handshaker_get_result(self) != TSI_OK) return TSI_FAILED_PRECONDITION;
   if (self->vtable->create_frame_protector == nullptr) return TSI_UNIMPLEMENTED;
-  result = self->vtable->create_frame_protector(self, max_protected_frame_size,
-                                                protector);
+  result = self->vtable->create_frame_protector(
+      self, max_output_protected_frame_size, protector);
   if (result == TSI_OK) {
     self->frame_protector_created = true;
   }
@@ -252,14 +252,14 @@ tsi_result tsi_handshaker_result_extract_peer(const tsi_handshaker_result* self,
 }
 
 tsi_result tsi_handshaker_result_create_frame_protector(
-    const tsi_handshaker_result* self, size_t* max_protected_frame_size,
+    const tsi_handshaker_result* self, size_t* max_output_protected_frame_size,
     tsi_frame_protector** protector) {
   if (self == nullptr || self->vtable == nullptr || protector == nullptr) {
     return TSI_INVALID_ARGUMENT;
   }
   if (self->vtable->create_frame_protector == nullptr) return TSI_UNIMPLEMENTED;
-  return self->vtable->create_frame_protector(self, max_protected_frame_size,
-                                              protector);
+  return self->vtable->create_frame_protector(
+      self, max_output_protected_frame_size, protector);
 }
 
 tsi_result tsi_handshaker_result_get_unused_bytes(
index 4608f40..50becca 100644 (file)
@@ -247,7 +247,7 @@ tsi_result tsi_handshaker_result_create_frame_protector(
    consequence, the caller must not free the bytes.  */
 tsi_result tsi_handshaker_result_get_unused_bytes(
     const tsi_handshaker_result* self, const unsigned char** bytes,
-    size_t* byte_size);
+    size_t* bytes_size);
 
 /* This method releases the tsi_handshaker_handshaker object. After this method
    is called, no other method can be called on the object.  */
index 299e535..16168b1 100644 (file)
@@ -1,6 +1,6 @@
 Pod::Spec.new do |s|
   s.name     = 'Protobuf-C++'
-  s.version  = '3.13.0'
+  s.version  = '3.14.0'
   s.summary  = 'Protocol Buffers v3 runtime library for C++.'
   s.homepage = 'https://github.com/google/protobuf'
   s.license  = '3-Clause BSD License'
index 967a0a4..134f4db 100755 (executable)
@@ -25,10 +25,10 @@ To add gRPC as a dependency in bazel:
       ],
       strip_prefix = "grpc-YOUR_GRPC_COMMIT_SHA",
   )
-
   load("@com_github_grpc_grpc//bazel:grpc_deps.bzl", "grpc_deps")
-
   grpc_deps()
+  load("@com_github_grpc_grpc//bazel:grpc_extra_deps.bzl", "grpc_extra_deps")
+  grpc_extra_deps()
   ```
 
 ## CMake
index af2841c..4facd2b 100644 (file)
@@ -28,6 +28,8 @@
 #include <grpcpp/impl/grpc_library.h>
 #include <grpcpp/support/channel_arguments.h>
 
+#include "absl/strings/str_join.h"
+
 // TODO(yashykt): We shouldn't be including "src/core" headers.
 #include "src/core/lib/gpr/env.h"
 #include "src/core/lib/iomgr/error.h"
@@ -107,6 +109,17 @@ std::shared_ptr<ChannelCredentials> GoogleDefaultCredentials() {
       grpc_google_default_credentials_create(nullptr));
 }
 
+namespace experimental {
+
+std::shared_ptr<CallCredentials> ExternalAccountCredentials(
+    const grpc::string& json_string, const std::vector<grpc::string>& scopes) {
+  grpc::GrpcLibraryCodegen init;  // To call grpc_init().
+  return WrapCallCredentials(grpc_external_account_credentials_create(
+      json_string.c_str(), absl::StrJoin(scopes, ",").c_str()));
+}
+
+}  // namespace experimental
+
 // Builds SSL Credentials given SSL specific options
 std::shared_ptr<ChannelCredentials> SslCredentials(
     const SslCredentialsOptions& options) {
index ff9aa61..63b4883 100644 (file)
@@ -23,6 +23,7 @@ namespace experimental {
 
 std::shared_ptr<ChannelCredentials> XdsCredentials(
     const std::shared_ptr<ChannelCredentials>& fallback_creds) {
+  GPR_ASSERT(fallback_creds != nullptr);
   if (fallback_creds->IsInsecure()) {
     grpc_channel_credentials* insecure_creds =
         grpc_insecure_credentials_create();
index 8df6c7b..ab56d60 100644 (file)
@@ -87,7 +87,7 @@ void ChannelFilterPluginInit() {
   for (size_t i = 0; i < channel_filters->size(); ++i) {
     FilterRecord& filter = (*channel_filters)[i];
     grpc_channel_init_register_stage(filter.stack_type, filter.priority,
-                                     MaybeAddFilter, (void*)&filter);
+                                     MaybeAddFilter, &filter);
   }
 }
 
index 3550e28..2deea5f 100644 (file)
@@ -41,5 +41,19 @@ StaticDataCertificateProvider::~StaticDataCertificateProvider() {
   grpc_tls_certificate_provider_release(c_provider_);
 };
 
+FileWatcherCertificateProvider::FileWatcherCertificateProvider(
+    const std::string& private_key_path,
+    const std::string& identity_certificate_path,
+    const std::string& root_cert_path, unsigned int refresh_interval_sec) {
+  c_provider_ = grpc_tls_certificate_provider_file_watcher_create(
+      private_key_path.c_str(), identity_certificate_path.c_str(),
+      root_cert_path.c_str(), refresh_interval_sec);
+  GPR_ASSERT(c_provider_ != nullptr);
+};
+
+FileWatcherCertificateProvider::~FileWatcherCertificateProvider() {
+  grpc_tls_certificate_provider_release(c_provider_);
+};
+
 }  // namespace experimental
 }  // namespace grpc
index e12f0fc..64da15a 100644 (file)
@@ -22,5 +22,5 @@
 #include <grpcpp/grpcpp.h>
 
 namespace grpc {
-std::string Version() { return "1.34.1"; }
+std::string Version() { return "1.35.0"; }
 }  // namespace grpc
index 289ef2b..3d90921 100644 (file)
@@ -106,7 +106,7 @@ void CensusClientCallData::StartTransportStreamOpBatch(
               GRPC_BATCH_GRPC_TRACE_BIN));
     }
     grpc_slice tags = grpc_empty_slice();
-    // TODO: Add in tagging serialization.
+    // TODO(unknown): Add in tagging serialization.
     size_t encoded_tags_len = StatsContextSerialize(kMaxTagsLen, &tags);
     if (encoded_tags_len > 0) {
       GRPC_LOG_IF_ERROR(
@@ -176,7 +176,7 @@ void CensusClientCallData::Destroy(grpc_call_element* elem,
       tags);
   grpc_slice_unref_internal(path_);
   if (final_info->final_status != GRPC_STATUS_OK) {
-    // TODO: Map grpc_status_code to trace::StatusCode.
+    // TODO(unknown): Map grpc_status_code to trace::StatusCode.
     context_.Span().SetStatus(opencensus::trace::StatusCode::UNKNOWN,
                               StatusCodeToString(final_info->final_status));
   }
index b5fd167..2deeedf 100644 (file)
@@ -78,7 +78,7 @@ size_t TraceContextSerialize(const ::opencensus::trace::SpanContext& context,
 }
 
 size_t StatsContextSerialize(size_t max_tags_len, grpc_slice* tags) {
-  // TODO: Add implementation. Waiting on stats tagging to be added.
+  // TODO(unknown): Add implementation. Waiting on stats tagging to be added.
   return 0;
 }
 
index ffffa60..b897dfc 100644 (file)
@@ -31,7 +31,7 @@
 
 namespace grpc {
 
-// TODO: Rename to GrpcTraceContextV0.
+// TODO(unknown): Rename to GrpcTraceContextV0.
 struct GrpcTraceContext {
   GrpcTraceContext() {}
 
@@ -48,7 +48,7 @@ struct GrpcTraceContext {
         ::opencensus::trace::TraceOptions(trace_options));
   }
 
-  // TODO: For performance:
+  // TODO(unknown): For performance:
   // uint8_t version;
   // uint8_t trace_id_field_id;
   uint8_t trace_id[::opencensus::trace::TraceId::kSize];
@@ -78,7 +78,7 @@ class TraceContextEncoding {
       return kEncodeDecodeFailure;
     }
     uint8_t version = buf[kVersionIdOffset];
-    // TODO: Support other versions later. Only support version 0 for
+    // TODO(unknown): Support other versions later. Only support version 0 for
     // now.
     if (version != kVersionId) {
       return kEncodeDecodeFailure;
@@ -123,7 +123,7 @@ class TraceContextEncoding {
   // in a GrpcTraceContext struct.  If it does not recognize the field ID it
   // will return 0, otherwise it returns the number of bytes read.
   static size_t ParseField(absl::string_view buf, GrpcTraceContext* tc) {
-    // TODO: Add support for multi-byte field IDs.
+    // TODO(unknown): Add support for multi-byte field IDs.
     if (buf.empty()) {
       return 0;
     }
@@ -200,7 +200,7 @@ class TraceContextEncoding {
   TraceContextEncoding operator=(TraceContextEncoding&&) = delete;
 };
 
-// TODO: This may not be needed. Check to see if opencensus requires
+// TODO(unknown): This may not be needed. Check to see if opencensus requires
 // a trailing server response.
 // RpcServerStatsEncoding encapsulates the logic for encoding and decoding of
 // rpc server stats messages. Rpc server stats consists of a uint64_t time
index 29ecef0..336465a 100644 (file)
@@ -109,14 +109,14 @@ Status ProtoServerReflection::ListService(ServerContext* /*context*/,
 }
 
 Status ProtoServerReflection::GetFileByName(
-    ServerContext* /*context*/, const std::string& filename,
+    ServerContext* /*context*/, const std::string& file_name,
     ServerReflectionResponse* response) {
   if (descriptor_pool_ == nullptr) {
     return Status::CANCELLED;
   }
 
   const protobuf::FileDescriptor* file_desc =
-      descriptor_pool_->FindFileByName(filename);
+      descriptor_pool_->FindFileByName(file_name);
   if (file_desc == nullptr) {
     return Status(StatusCode::NOT_FOUND, "File not found.");
   }
index 3bc7b67..954aaff 100644 (file)
@@ -41,7 +41,7 @@ class DynamicThreadPool final : public ThreadPoolInterface {
  private:
   class DynamicThread {
    public:
-    DynamicThread(DynamicThreadPool* pool);
+    explicit DynamicThread(DynamicThreadPool* pool);
     ~DynamicThread();
 
    private:
index 04e5435..4c1cec0 100644 (file)
@@ -33,6 +33,9 @@ class InsecureServerCredentialsImpl final : public ServerCredentials {
     (void)processor;
     GPR_ASSERT(0);  // Should not be called on InsecureServerCredentials.
   }
+
+ private:
+  bool IsInsecure() const override { return true; }
 };
 }  // namespace
 
index 25a46ed..4f52a87 100644 (file)
@@ -55,18 +55,18 @@ void AuthMetadataProcessorAyncWrapper::Process(
 }
 
 void AuthMetadataProcessorAyncWrapper::InvokeProcessor(
-    grpc_auth_context* ctx, const grpc_metadata* md, size_t num_md,
+    grpc_auth_context* context, const grpc_metadata* md, size_t num_md,
     grpc_process_auth_metadata_done_cb cb, void* user_data) {
   AuthMetadataProcessor::InputMetadata metadata;
   for (size_t i = 0; i < num_md; i++) {
     metadata.insert(std::make_pair(StringRefFromSlice(&md[i].key),
                                    StringRefFromSlice(&md[i].value)));
   }
-  SecureAuthContext context(ctx);
+  SecureAuthContext ctx(context);
   AuthMetadataProcessor::OutputMetadata consumed_metadata;
   AuthMetadataProcessor::OutputMetadata response_metadata;
 
-  Status status = processor_->Process(metadata, &context, &consumed_metadata,
+  Status status = processor_->Process(metadata, &ctx, &consumed_metadata,
                                       &response_metadata);
 
   std::vector<grpc_metadata> consumed_md;
index 407d707..730abdb 100644 (file)
@@ -40,7 +40,7 @@ class AuthMetadataProcessorAyncWrapper final {
                       const grpc_metadata* md, size_t num_md,
                       grpc_process_auth_metadata_done_cb cb, void* user_data);
 
-  AuthMetadataProcessorAyncWrapper(
+  explicit AuthMetadataProcessorAyncWrapper(
       const std::shared_ptr<AuthMetadataProcessor>& processor)
       : processor_(processor) {
     if (processor && processor->IsBlocking()) {
@@ -69,7 +69,11 @@ class SecureServerCredentials final : public ServerCredentials {
   void SetAuthMetadataProcessor(
       const std::shared_ptr<grpc::AuthMetadataProcessor>& processor) override;
 
+  grpc_server_credentials* c_creds() { return creds_; }
+
  private:
+  SecureServerCredentials* AsSecureServerCredentials() override { return this; }
+
   grpc_server_credentials* creds_;
   std::unique_ptr<grpc::AuthMetadataProcessorAyncWrapper> processor_;
 };
index c374cf9..dc38125 100644 (file)
@@ -83,9 +83,9 @@ ServerBuilder& ServerBuilder::RegisterService(Service* service) {
   return *this;
 }
 
-ServerBuilder& ServerBuilder::RegisterService(const std::string& addr,
+ServerBuilder& ServerBuilder::RegisterService(const std::string& host,
                                               Service* service) {
-  services_.emplace_back(new NamedService(addr, service));
+  services_.emplace_back(new NamedService(host, service));
   return *this;
 }
 
@@ -95,7 +95,7 @@ ServerBuilder& ServerBuilder::RegisterAsyncGenericService(
     gpr_log(GPR_ERROR,
             "Adding multiple generic services is unsupported for now. "
             "Dropping the service %p",
-            (void*)service);
+            service);
   } else {
     generic_service_ = service;
   }
@@ -122,7 +122,7 @@ ServerBuilder& ServerBuilder::experimental_type::RegisterCallbackGenericService(
     gpr_log(GPR_ERROR,
             "Adding multiple generic services is unsupported for now. "
             "Dropping the service %p",
-            (void*)service);
+            service);
   } else {
     builder_->callback_generic_service_ = service;
   }
@@ -331,7 +331,7 @@ std::unique_ptr<grpc::Server> ServerBuilder::BuildAndStart() {
   std::unique_ptr<grpc::Server> server(new grpc::Server(
       &args, sync_server_cqs, sync_server_settings_.min_pollers,
       sync_server_settings_.max_pollers, sync_server_settings_.cq_timeout_msec,
-      std::move(acceptors_), resource_quota_,
+      std::move(acceptors_), server_config_fetcher_, resource_quota_,
       std::move(interceptor_creators_)));
 
   ServerInitializer* initializer = server->initializer();
index dca828d..2b5486a 100644 (file)
@@ -315,7 +315,7 @@ class Server::UnimplementedAsyncResponse final
           grpc::internal::CallOpSendInitialMetadata,
           grpc::internal::CallOpServerSendStatus> {
  public:
-  UnimplementedAsyncResponse(UnimplementedAsyncRequest* request);
+  explicit UnimplementedAsyncResponse(UnimplementedAsyncRequest* request);
   ~UnimplementedAsyncResponse() override { delete request_; }
 
   bool FinalizeResult(void** tag, bool* status) override {
@@ -592,7 +592,7 @@ class Server::CallbackRequest final
 
   class CallbackCallTag : public grpc_experimental_completion_queue_functor {
    public:
-    CallbackCallTag(Server::CallbackRequest<ServerContextType>* req)
+    explicit CallbackCallTag(Server::CallbackRequest<ServerContextType>* req)
         : req_(req) {
       functor_run = &CallbackCallTag::StaticRun;
       // Set inlineable to true since this callback is internally-controlled
@@ -877,6 +877,7 @@ Server::Server(
     int min_pollers, int max_pollers, int sync_cq_timeout_msec,
     std::vector<std::shared_ptr<grpc::internal::ExternalConnectionAcceptorImpl>>
         acceptors,
+    grpc_server_config_fetcher* server_config_fetcher,
     grpc_resource_quota* server_rq,
     std::vector<
         std::unique_ptr<grpc::experimental::ServerInterceptorFactoryInterface>>
@@ -940,6 +941,7 @@ Server::Server(
     }
   }
   server_ = grpc_server_create(&channel_args, nullptr);
+  grpc_server_set_config_fetcher(server_, server_config_fetcher);
 }
 
 Server::~Server() {
@@ -1009,7 +1011,7 @@ static grpc_server_register_method_payload_handling PayloadHandlingForMethod(
   GPR_UNREACHABLE_CODE(return GRPC_SRM_PAYLOAD_NONE;);
 }
 
-bool Server::RegisterService(const std::string* host, grpc::Service* service) {
+bool Server::RegisterService(const std::string* addr, grpc::Service* service) {
   bool has_async_methods = service->has_async_methods();
   if (has_async_methods) {
     GPR_ASSERT(service->server_ == nullptr &&
@@ -1025,7 +1027,7 @@ bool Server::RegisterService(const std::string* host, grpc::Service* service) {
     }
 
     void* method_registration_tag = grpc_server_register_method(
-        server_, method->name(), host ? host->c_str() : nullptr,
+        server_, method->name(), addr ? addr->c_str() : nullptr,
         PayloadHandlingForMethod(method.get()), 0);
     if (method_registration_tag == nullptr) {
       gpr_log(GPR_DEBUG, "Attempt to register %s multiple times",
index f3cb004..cb9cf43 100644 (file)
@@ -121,8 +121,9 @@ class ServerContextBase::CompletionOp final
   void ContinueFinalizeResultAfterInterception() override {
     done_intercepting_ = true;
     if (!has_tag_) {
-      /* We don't have a tag to return. */
+      // We don't have a tag to return.
       Unref();
+      // Unref can delete this, so do not access anything from this afterward.
       return;
     }
     /* Start a dummy op so that we can return the tag */
@@ -174,33 +175,41 @@ void ServerContextBase::CompletionOp::FillOps(internal::Call* call) {
 }
 
 bool ServerContextBase::CompletionOp::FinalizeResult(void** tag, bool* status) {
-  // Decide whether to call the cancel callback within the lock
-  bool call_cancel;
+  // Decide whether to do the unref or call the cancel callback within the lock
+  bool do_unref = false;
+  bool has_tag = false;
+  bool call_cancel = false;
 
   {
     grpc_core::MutexLock lock(&mu_);
     if (done_intercepting_) {
       // We are done intercepting.
-      bool has_tag = has_tag_;
+      has_tag = has_tag_;
       if (has_tag) {
         *tag = tag_;
       }
-      Unref();
-      return has_tag;
-    }
-    finalized_ = true;
+      // Release the lock before unreffing as Unref may delete this object
+      do_unref = true;
+    } else {
+      finalized_ = true;
+
+      // If for some reason the incoming status is false, mark that as a
+      // cancellation.
+      // TODO(vjpai): does this ever happen?
+      if (!*status) {
+        cancelled_ = 1;
+      }
 
-    // If for some reason the incoming status is false, mark that as a
-    // cancellation.
-    // TODO(vjpai): does this ever happen?
-    if (!*status) {
-      cancelled_ = 1;
+      call_cancel = (cancelled_ != 0);
+      // Release the lock since we may call a callback and interceptors.
     }
-
-    call_cancel = (cancelled_ != 0);
-    // Release the lock since we may call a callback and interceptors.
   }
 
+  if (do_unref) {
+    Unref();
+    // Unref can delete this, so do not access anything from this afterward.
+    return has_tag;
+  }
   if (call_cancel && callback_controller_ != nullptr) {
     callback_controller_->MaybeCallOnCancel();
   }
@@ -214,6 +223,7 @@ bool ServerContextBase::CompletionOp::FinalizeResult(void** tag, bool* status) {
       *tag = tag_;
     }
     Unref();
+    // Unref can delete this, so do not access anything from this afterward.
     return has_tag;
   }
   // There are interceptors to be run. Return false for now.
@@ -240,6 +250,7 @@ void ServerContextBase::BindDeadlineAndMetadata(gpr_timespec deadline,
 ServerContextBase::~ServerContextBase() {
   if (completion_op_) {
     completion_op_->Unref();
+    // Unref can delete completion_op_, so do not access it afterward.
   }
   if (rpc_info_) {
     rpc_info_->Unref();
diff --git a/src/cpp/server/xds_server_credentials.cc b/src/cpp/server/xds_server_credentials.cc
new file mode 100644 (file)
index 0000000..b543f3f
--- /dev/null
@@ -0,0 +1,41 @@
+//
+//
+// 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 "src/cpp/server/secure_server_credentials.h"
+
+namespace grpc {
+namespace experimental {
+
+std::shared_ptr<ServerCredentials> XdsServerCredentials(
+    const std::shared_ptr<ServerCredentials>& fallback_credentials) {
+  GPR_ASSERT(fallback_credentials != nullptr);
+  if (fallback_credentials->IsInsecure()) {
+    grpc_server_credentials* insecure_creds =
+        grpc_insecure_server_credentials_create();
+    auto xds_creds = std::make_shared<SecureServerCredentials>(
+        grpc_xds_server_credentials_create(insecure_creds));
+    grpc_server_credentials_release(insecure_creds);
+    return xds_creds;
+  }
+  return std::make_shared<SecureServerCredentials>(
+      grpc_xds_server_credentials_create(
+          fallback_credentials->AsSecureServerCredentials()->c_creds()));
+}
+
+}  // namespace experimental
+}  // namespace grpc
index 43f1fd5..aae2417 100644 (file)
@@ -119,7 +119,7 @@ class ThreadManager {
   // not be called (and the need for this WorkerThread class is eliminated)
   class WorkerThread {
    public:
-    WorkerThread(ThreadManager* thd_mgr);
+    explicit WorkerThread(ThreadManager* thd_mgr);
     ~WorkerThread();
 
     bool created() const { return created_; }
index 8986fd1..88d047a 100644 (file)
@@ -33,11 +33,11 @@ namespace Grpc.Core
         /// <summary>
         /// Current <c>AssemblyFileVersion</c> of gRPC C# assemblies
         /// </summary>
-        public const string CurrentAssemblyFileVersion = "2.34.1.0";
+        public const string CurrentAssemblyFileVersion = "2.35.0.0";
 
         /// <summary>
         /// Current version of gRPC C#
         /// </summary>
-        public const string CurrentVersion = "2.34.1";
+        public const string CurrentVersion = "2.35.0";
     }
 }
index 083dbb2..9fe22e9 100644 (file)
@@ -69,11 +69,32 @@ namespace Grpc.Testing {
             "IAEoCRINCgV2YWx1ZRgCIAEoBToCOAEaMQoPUnBjc0J5UGVlckVudHJ5EgsK",
             "A2tleRgBIAEoCRINCgV2YWx1ZRgCIAEoBToCOAEaZwoRUnBjc0J5TWV0aG9k",
             "RW50cnkSCwoDa2V5GAEgASgJEkEKBXZhbHVlGAIgASgLMjIuZ3JwYy50ZXN0",
-            "aW5nLkxvYWRCYWxhbmNlclN0YXRzUmVzcG9uc2UuUnBjc0J5UGVlcjoCOAEq",
-            "HwoLUGF5bG9hZFR5cGUSEAoMQ09NUFJFU1NBQkxFEAAqbwoPR3JwY2xiUm91",
-            "dGVUeXBlEh0KGUdSUENMQl9ST1VURV9UWVBFX1VOS05PV04QABIeChpHUlBD",
-            "TEJfUk9VVEVfVFlQRV9GQUxMQkFDSxABEh0KGUdSUENMQl9ST1VURV9UWVBF",
-            "X0JBQ0tFTkQQAmIGcHJvdG8z"));
+            "aW5nLkxvYWRCYWxhbmNlclN0YXRzUmVzcG9uc2UuUnBjc0J5UGVlcjoCOAEi",
+            "JQojTG9hZEJhbGFuY2VyQWNjdW11bGF0ZWRTdGF0c1JlcXVlc3QiwgQKJExv",
+            "YWRCYWxhbmNlckFjY3VtdWxhdGVkU3RhdHNSZXNwb25zZRJyChpudW1fcnBj",
+            "c19zdGFydGVkX2J5X21ldGhvZBgBIAMoCzJOLmdycGMudGVzdGluZy5Mb2Fk",
+            "QmFsYW5jZXJBY2N1bXVsYXRlZFN0YXRzUmVzcG9uc2UuTnVtUnBjc1N0YXJ0",
+            "ZWRCeU1ldGhvZEVudHJ5EnYKHG51bV9ycGNzX3N1Y2NlZWRlZF9ieV9tZXRo",
+            "b2QYAiADKAsyUC5ncnBjLnRlc3RpbmcuTG9hZEJhbGFuY2VyQWNjdW11bGF0",
+            "ZWRTdGF0c1Jlc3BvbnNlLk51bVJwY3NTdWNjZWVkZWRCeU1ldGhvZEVudHJ5",
+            "EnAKGW51bV9ycGNzX2ZhaWxlZF9ieV9tZXRob2QYAyADKAsyTS5ncnBjLnRl",
+            "c3RpbmcuTG9hZEJhbGFuY2VyQWNjdW11bGF0ZWRTdGF0c1Jlc3BvbnNlLk51",
+            "bVJwY3NGYWlsZWRCeU1ldGhvZEVudHJ5Gj0KG051bVJwY3NTdGFydGVkQnlN",
+            "ZXRob2RFbnRyeRILCgNrZXkYASABKAkSDQoFdmFsdWUYAiABKAU6AjgBGj8K",
+            "HU51bVJwY3NTdWNjZWVkZWRCeU1ldGhvZEVudHJ5EgsKA2tleRgBIAEoCRIN",
+            "CgV2YWx1ZRgCIAEoBToCOAEaPAoaTnVtUnBjc0ZhaWxlZEJ5TWV0aG9kRW50",
+            "cnkSCwoDa2V5GAEgASgJEg0KBXZhbHVlGAIgASgFOgI4ASKlAgoWQ2xpZW50",
+            "Q29uZmlndXJlUmVxdWVzdBI7CgV0eXBlcxgBIAMoDjIsLmdycGMudGVzdGlu",
+            "Zy5DbGllbnRDb25maWd1cmVSZXF1ZXN0LlJwY1R5cGUSPwoIbWV0YWRhdGEY",
+            "AiADKAsyLS5ncnBjLnRlc3RpbmcuQ2xpZW50Q29uZmlndXJlUmVxdWVzdC5N",
+            "ZXRhZGF0YRpiCghNZXRhZGF0YRI6CgR0eXBlGAEgASgOMiwuZ3JwYy50ZXN0",
+            "aW5nLkNsaWVudENvbmZpZ3VyZVJlcXVlc3QuUnBjVHlwZRILCgNrZXkYAiAB",
+            "KAkSDQoFdmFsdWUYAyABKAkiKQoHUnBjVHlwZRIOCgpFTVBUWV9DQUxMEAAS",
+            "DgoKVU5BUllfQ0FMTBABIhkKF0NsaWVudENvbmZpZ3VyZVJlc3BvbnNlKh8K",
+            "C1BheWxvYWRUeXBlEhAKDENPTVBSRVNTQUJMRRAAKm8KD0dycGNsYlJvdXRl",
+            "VHlwZRIdChlHUlBDTEJfUk9VVEVfVFlQRV9VTktOT1dOEAASHgoaR1JQQ0xC",
+            "X1JPVVRFX1RZUEVfRkFMTEJBQ0sQARIdChlHUlBDTEJfUk9VVEVfVFlQRV9C",
+            "QUNLRU5EEAJiBnByb3RvMw=="));
       descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData,
           new pbr::FileDescriptor[] { },
           new pbr::GeneratedClrTypeInfo(new[] {typeof(global::Grpc.Testing.PayloadType), typeof(global::Grpc.Testing.GrpclbRouteType), }, null, new pbr::GeneratedClrTypeInfo[] {
@@ -91,7 +112,11 @@ namespace Grpc.Testing {
             new pbr::GeneratedClrTypeInfo(typeof(global::Grpc.Testing.ReconnectInfo), global::Grpc.Testing.ReconnectInfo.Parser, new[]{ "Passed", "BackoffMs" }, null, null, null, null),
             new pbr::GeneratedClrTypeInfo(typeof(global::Grpc.Testing.LoadBalancerStatsRequest), global::Grpc.Testing.LoadBalancerStatsRequest.Parser, new[]{ "NumRpcs", "TimeoutSec" }, null, null, null, null),
             new pbr::GeneratedClrTypeInfo(typeof(global::Grpc.Testing.LoadBalancerStatsResponse), global::Grpc.Testing.LoadBalancerStatsResponse.Parser, new[]{ "RpcsByPeer", "NumFailures", "RpcsByMethod" }, null, null, null, new pbr::GeneratedClrTypeInfo[] { new pbr::GeneratedClrTypeInfo(typeof(global::Grpc.Testing.LoadBalancerStatsResponse.Types.RpcsByPeer), global::Grpc.Testing.LoadBalancerStatsResponse.Types.RpcsByPeer.Parser, new[]{ "RpcsByPeer_" }, null, null, null, new pbr::GeneratedClrTypeInfo[] { null, }),
-            null, null, })
+            null, null, }),
+            new pbr::GeneratedClrTypeInfo(typeof(global::Grpc.Testing.LoadBalancerAccumulatedStatsRequest), global::Grpc.Testing.LoadBalancerAccumulatedStatsRequest.Parser, null, null, null, null, null),
+            new pbr::GeneratedClrTypeInfo(typeof(global::Grpc.Testing.LoadBalancerAccumulatedStatsResponse), global::Grpc.Testing.LoadBalancerAccumulatedStatsResponse.Parser, new[]{ "NumRpcsStartedByMethod", "NumRpcsSucceededByMethod", "NumRpcsFailedByMethod" }, null, null, null, new pbr::GeneratedClrTypeInfo[] { null, null, null, }),
+            new pbr::GeneratedClrTypeInfo(typeof(global::Grpc.Testing.ClientConfigureRequest), global::Grpc.Testing.ClientConfigureRequest.Parser, new[]{ "Types_", "Metadata" }, null, new[]{ typeof(global::Grpc.Testing.ClientConfigureRequest.Types.RpcType) }, null, new pbr::GeneratedClrTypeInfo[] { new pbr::GeneratedClrTypeInfo(typeof(global::Grpc.Testing.ClientConfigureRequest.Types.Metadata), global::Grpc.Testing.ClientConfigureRequest.Types.Metadata.Parser, new[]{ "Type", "Key", "Value" }, null, null, null, null)}),
+            new pbr::GeneratedClrTypeInfo(typeof(global::Grpc.Testing.ClientConfigureResponse), global::Grpc.Testing.ClientConfigureResponse.Parser, null, null, null, null, null)
           }));
     }
     #endregion
@@ -3866,6 +3891,966 @@ namespace Grpc.Testing {
 
   }
 
+  /// <summary>
+  /// Request for retrieving a test client's accumulated stats.
+  /// </summary>
+  public sealed partial class LoadBalancerAccumulatedStatsRequest : pb::IMessage<LoadBalancerAccumulatedStatsRequest>
+  #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
+      , pb::IBufferMessage
+  #endif
+  {
+    private static readonly pb::MessageParser<LoadBalancerAccumulatedStatsRequest> _parser = new pb::MessageParser<LoadBalancerAccumulatedStatsRequest>(() => new LoadBalancerAccumulatedStatsRequest());
+    private pb::UnknownFieldSet _unknownFields;
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public static pb::MessageParser<LoadBalancerAccumulatedStatsRequest> Parser { get { return _parser; } }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public static pbr::MessageDescriptor Descriptor {
+      get { return global::Grpc.Testing.MessagesReflection.Descriptor.MessageTypes[14]; }
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    pbr::MessageDescriptor pb::IMessage.Descriptor {
+      get { return Descriptor; }
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public LoadBalancerAccumulatedStatsRequest() {
+      OnConstruction();
+    }
+
+    partial void OnConstruction();
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public LoadBalancerAccumulatedStatsRequest(LoadBalancerAccumulatedStatsRequest other) : this() {
+      _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields);
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public LoadBalancerAccumulatedStatsRequest Clone() {
+      return new LoadBalancerAccumulatedStatsRequest(this);
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public override bool Equals(object other) {
+      return Equals(other as LoadBalancerAccumulatedStatsRequest);
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public bool Equals(LoadBalancerAccumulatedStatsRequest other) {
+      if (ReferenceEquals(other, null)) {
+        return false;
+      }
+      if (ReferenceEquals(other, this)) {
+        return true;
+      }
+      return Equals(_unknownFields, other._unknownFields);
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public override int GetHashCode() {
+      int hash = 1;
+      if (_unknownFields != null) {
+        hash ^= _unknownFields.GetHashCode();
+      }
+      return hash;
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public override string ToString() {
+      return pb::JsonFormatter.ToDiagnosticString(this);
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public void WriteTo(pb::CodedOutputStream output) {
+    #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
+      output.WriteRawMessage(this);
+    #else
+      if (_unknownFields != null) {
+        _unknownFields.WriteTo(output);
+      }
+    #endif
+    }
+
+    #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) {
+      if (_unknownFields != null) {
+        _unknownFields.WriteTo(ref output);
+      }
+    }
+    #endif
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public int CalculateSize() {
+      int size = 0;
+      if (_unknownFields != null) {
+        size += _unknownFields.CalculateSize();
+      }
+      return size;
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public void MergeFrom(LoadBalancerAccumulatedStatsRequest other) {
+      if (other == null) {
+        return;
+      }
+      _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields);
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public void MergeFrom(pb::CodedInputStream input) {
+    #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
+      input.ReadRawMessage(this);
+    #else
+      uint tag;
+      while ((tag = input.ReadTag()) != 0) {
+        switch(tag) {
+          default:
+            _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
+            break;
+        }
+      }
+    #endif
+    }
+
+    #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) {
+      uint tag;
+      while ((tag = input.ReadTag()) != 0) {
+        switch(tag) {
+          default:
+            _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input);
+            break;
+        }
+      }
+    }
+    #endif
+
+  }
+
+  /// <summary>
+  /// Accumulated stats for RPCs sent by a test client.
+  /// </summary>
+  public sealed partial class LoadBalancerAccumulatedStatsResponse : pb::IMessage<LoadBalancerAccumulatedStatsResponse>
+  #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
+      , pb::IBufferMessage
+  #endif
+  {
+    private static readonly pb::MessageParser<LoadBalancerAccumulatedStatsResponse> _parser = new pb::MessageParser<LoadBalancerAccumulatedStatsResponse>(() => new LoadBalancerAccumulatedStatsResponse());
+    private pb::UnknownFieldSet _unknownFields;
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public static pb::MessageParser<LoadBalancerAccumulatedStatsResponse> Parser { get { return _parser; } }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public static pbr::MessageDescriptor Descriptor {
+      get { return global::Grpc.Testing.MessagesReflection.Descriptor.MessageTypes[15]; }
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    pbr::MessageDescriptor pb::IMessage.Descriptor {
+      get { return Descriptor; }
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public LoadBalancerAccumulatedStatsResponse() {
+      OnConstruction();
+    }
+
+    partial void OnConstruction();
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public LoadBalancerAccumulatedStatsResponse(LoadBalancerAccumulatedStatsResponse other) : this() {
+      numRpcsStartedByMethod_ = other.numRpcsStartedByMethod_.Clone();
+      numRpcsSucceededByMethod_ = other.numRpcsSucceededByMethod_.Clone();
+      numRpcsFailedByMethod_ = other.numRpcsFailedByMethod_.Clone();
+      _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields);
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public LoadBalancerAccumulatedStatsResponse Clone() {
+      return new LoadBalancerAccumulatedStatsResponse(this);
+    }
+
+    /// <summary>Field number for the "num_rpcs_started_by_method" field.</summary>
+    public const int NumRpcsStartedByMethodFieldNumber = 1;
+    private static readonly pbc::MapField<string, int>.Codec _map_numRpcsStartedByMethod_codec
+        = new pbc::MapField<string, int>.Codec(pb::FieldCodec.ForString(10, ""), pb::FieldCodec.ForInt32(16, 0), 10);
+    private readonly pbc::MapField<string, int> numRpcsStartedByMethod_ = new pbc::MapField<string, int>();
+    /// <summary>
+    /// The total number of RPCs have ever issued for each type.
+    /// </summary>
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public pbc::MapField<string, int> NumRpcsStartedByMethod {
+      get { return numRpcsStartedByMethod_; }
+    }
+
+    /// <summary>Field number for the "num_rpcs_succeeded_by_method" field.</summary>
+    public const int NumRpcsSucceededByMethodFieldNumber = 2;
+    private static readonly pbc::MapField<string, int>.Codec _map_numRpcsSucceededByMethod_codec
+        = new pbc::MapField<string, int>.Codec(pb::FieldCodec.ForString(10, ""), pb::FieldCodec.ForInt32(16, 0), 18);
+    private readonly pbc::MapField<string, int> numRpcsSucceededByMethod_ = new pbc::MapField<string, int>();
+    /// <summary>
+    /// The total number of RPCs have ever completed successfully for each type.
+    /// </summary>
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public pbc::MapField<string, int> NumRpcsSucceededByMethod {
+      get { return numRpcsSucceededByMethod_; }
+    }
+
+    /// <summary>Field number for the "num_rpcs_failed_by_method" field.</summary>
+    public const int NumRpcsFailedByMethodFieldNumber = 3;
+    private static readonly pbc::MapField<string, int>.Codec _map_numRpcsFailedByMethod_codec
+        = new pbc::MapField<string, int>.Codec(pb::FieldCodec.ForString(10, ""), pb::FieldCodec.ForInt32(16, 0), 26);
+    private readonly pbc::MapField<string, int> numRpcsFailedByMethod_ = new pbc::MapField<string, int>();
+    /// <summary>
+    /// The total number of RPCs have ever failed for each type.
+    /// </summary>
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public pbc::MapField<string, int> NumRpcsFailedByMethod {
+      get { return numRpcsFailedByMethod_; }
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public override bool Equals(object other) {
+      return Equals(other as LoadBalancerAccumulatedStatsResponse);
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public bool Equals(LoadBalancerAccumulatedStatsResponse other) {
+      if (ReferenceEquals(other, null)) {
+        return false;
+      }
+      if (ReferenceEquals(other, this)) {
+        return true;
+      }
+      if (!NumRpcsStartedByMethod.Equals(other.NumRpcsStartedByMethod)) return false;
+      if (!NumRpcsSucceededByMethod.Equals(other.NumRpcsSucceededByMethod)) return false;
+      if (!NumRpcsFailedByMethod.Equals(other.NumRpcsFailedByMethod)) return false;
+      return Equals(_unknownFields, other._unknownFields);
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public override int GetHashCode() {
+      int hash = 1;
+      hash ^= NumRpcsStartedByMethod.GetHashCode();
+      hash ^= NumRpcsSucceededByMethod.GetHashCode();
+      hash ^= NumRpcsFailedByMethod.GetHashCode();
+      if (_unknownFields != null) {
+        hash ^= _unknownFields.GetHashCode();
+      }
+      return hash;
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public override string ToString() {
+      return pb::JsonFormatter.ToDiagnosticString(this);
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public void WriteTo(pb::CodedOutputStream output) {
+    #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
+      output.WriteRawMessage(this);
+    #else
+      numRpcsStartedByMethod_.WriteTo(output, _map_numRpcsStartedByMethod_codec);
+      numRpcsSucceededByMethod_.WriteTo(output, _map_numRpcsSucceededByMethod_codec);
+      numRpcsFailedByMethod_.WriteTo(output, _map_numRpcsFailedByMethod_codec);
+      if (_unknownFields != null) {
+        _unknownFields.WriteTo(output);
+      }
+    #endif
+    }
+
+    #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) {
+      numRpcsStartedByMethod_.WriteTo(ref output, _map_numRpcsStartedByMethod_codec);
+      numRpcsSucceededByMethod_.WriteTo(ref output, _map_numRpcsSucceededByMethod_codec);
+      numRpcsFailedByMethod_.WriteTo(ref output, _map_numRpcsFailedByMethod_codec);
+      if (_unknownFields != null) {
+        _unknownFields.WriteTo(ref output);
+      }
+    }
+    #endif
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public int CalculateSize() {
+      int size = 0;
+      size += numRpcsStartedByMethod_.CalculateSize(_map_numRpcsStartedByMethod_codec);
+      size += numRpcsSucceededByMethod_.CalculateSize(_map_numRpcsSucceededByMethod_codec);
+      size += numRpcsFailedByMethod_.CalculateSize(_map_numRpcsFailedByMethod_codec);
+      if (_unknownFields != null) {
+        size += _unknownFields.CalculateSize();
+      }
+      return size;
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public void MergeFrom(LoadBalancerAccumulatedStatsResponse other) {
+      if (other == null) {
+        return;
+      }
+      numRpcsStartedByMethod_.Add(other.numRpcsStartedByMethod_);
+      numRpcsSucceededByMethod_.Add(other.numRpcsSucceededByMethod_);
+      numRpcsFailedByMethod_.Add(other.numRpcsFailedByMethod_);
+      _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields);
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public void MergeFrom(pb::CodedInputStream input) {
+    #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
+      input.ReadRawMessage(this);
+    #else
+      uint tag;
+      while ((tag = input.ReadTag()) != 0) {
+        switch(tag) {
+          default:
+            _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
+            break;
+          case 10: {
+            numRpcsStartedByMethod_.AddEntriesFrom(input, _map_numRpcsStartedByMethod_codec);
+            break;
+          }
+          case 18: {
+            numRpcsSucceededByMethod_.AddEntriesFrom(input, _map_numRpcsSucceededByMethod_codec);
+            break;
+          }
+          case 26: {
+            numRpcsFailedByMethod_.AddEntriesFrom(input, _map_numRpcsFailedByMethod_codec);
+            break;
+          }
+        }
+      }
+    #endif
+    }
+
+    #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) {
+      uint tag;
+      while ((tag = input.ReadTag()) != 0) {
+        switch(tag) {
+          default:
+            _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input);
+            break;
+          case 10: {
+            numRpcsStartedByMethod_.AddEntriesFrom(ref input, _map_numRpcsStartedByMethod_codec);
+            break;
+          }
+          case 18: {
+            numRpcsSucceededByMethod_.AddEntriesFrom(ref input, _map_numRpcsSucceededByMethod_codec);
+            break;
+          }
+          case 26: {
+            numRpcsFailedByMethod_.AddEntriesFrom(ref input, _map_numRpcsFailedByMethod_codec);
+            break;
+          }
+        }
+      }
+    }
+    #endif
+
+  }
+
+  /// <summary>
+  /// Configurations for a test client.
+  /// </summary>
+  public sealed partial class ClientConfigureRequest : pb::IMessage<ClientConfigureRequest>
+  #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
+      , pb::IBufferMessage
+  #endif
+  {
+    private static readonly pb::MessageParser<ClientConfigureRequest> _parser = new pb::MessageParser<ClientConfigureRequest>(() => new ClientConfigureRequest());
+    private pb::UnknownFieldSet _unknownFields;
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public static pb::MessageParser<ClientConfigureRequest> Parser { get { return _parser; } }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public static pbr::MessageDescriptor Descriptor {
+      get { return global::Grpc.Testing.MessagesReflection.Descriptor.MessageTypes[16]; }
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    pbr::MessageDescriptor pb::IMessage.Descriptor {
+      get { return Descriptor; }
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public ClientConfigureRequest() {
+      OnConstruction();
+    }
+
+    partial void OnConstruction();
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public ClientConfigureRequest(ClientConfigureRequest other) : this() {
+      types_ = other.types_.Clone();
+      metadata_ = other.metadata_.Clone();
+      _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields);
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public ClientConfigureRequest Clone() {
+      return new ClientConfigureRequest(this);
+    }
+
+    /// <summary>Field number for the "types" field.</summary>
+    public const int Types_FieldNumber = 1;
+    private static readonly pb::FieldCodec<global::Grpc.Testing.ClientConfigureRequest.Types.RpcType> _repeated_types_codec
+        = pb::FieldCodec.ForEnum(10, x => (int) x, x => (global::Grpc.Testing.ClientConfigureRequest.Types.RpcType) x);
+    private readonly pbc::RepeatedField<global::Grpc.Testing.ClientConfigureRequest.Types.RpcType> types_ = new pbc::RepeatedField<global::Grpc.Testing.ClientConfigureRequest.Types.RpcType>();
+    /// <summary>
+    /// The types of RPCs the client sends.
+    /// </summary>
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public pbc::RepeatedField<global::Grpc.Testing.ClientConfigureRequest.Types.RpcType> Types_ {
+      get { return types_; }
+    }
+
+    /// <summary>Field number for the "metadata" field.</summary>
+    public const int MetadataFieldNumber = 2;
+    private static readonly pb::FieldCodec<global::Grpc.Testing.ClientConfigureRequest.Types.Metadata> _repeated_metadata_codec
+        = pb::FieldCodec.ForMessage(18, global::Grpc.Testing.ClientConfigureRequest.Types.Metadata.Parser);
+    private readonly pbc::RepeatedField<global::Grpc.Testing.ClientConfigureRequest.Types.Metadata> metadata_ = new pbc::RepeatedField<global::Grpc.Testing.ClientConfigureRequest.Types.Metadata>();
+    /// <summary>
+    /// The collection of custom metadata to be attached to RPCs sent by the client.
+    /// </summary>
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public pbc::RepeatedField<global::Grpc.Testing.ClientConfigureRequest.Types.Metadata> Metadata {
+      get { return metadata_; }
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public override bool Equals(object other) {
+      return Equals(other as ClientConfigureRequest);
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public bool Equals(ClientConfigureRequest other) {
+      if (ReferenceEquals(other, null)) {
+        return false;
+      }
+      if (ReferenceEquals(other, this)) {
+        return true;
+      }
+      if(!types_.Equals(other.types_)) return false;
+      if(!metadata_.Equals(other.metadata_)) return false;
+      return Equals(_unknownFields, other._unknownFields);
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public override int GetHashCode() {
+      int hash = 1;
+      hash ^= types_.GetHashCode();
+      hash ^= metadata_.GetHashCode();
+      if (_unknownFields != null) {
+        hash ^= _unknownFields.GetHashCode();
+      }
+      return hash;
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public override string ToString() {
+      return pb::JsonFormatter.ToDiagnosticString(this);
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public void WriteTo(pb::CodedOutputStream output) {
+    #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
+      output.WriteRawMessage(this);
+    #else
+      types_.WriteTo(output, _repeated_types_codec);
+      metadata_.WriteTo(output, _repeated_metadata_codec);
+      if (_unknownFields != null) {
+        _unknownFields.WriteTo(output);
+      }
+    #endif
+    }
+
+    #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) {
+      types_.WriteTo(ref output, _repeated_types_codec);
+      metadata_.WriteTo(ref output, _repeated_metadata_codec);
+      if (_unknownFields != null) {
+        _unknownFields.WriteTo(ref output);
+      }
+    }
+    #endif
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public int CalculateSize() {
+      int size = 0;
+      size += types_.CalculateSize(_repeated_types_codec);
+      size += metadata_.CalculateSize(_repeated_metadata_codec);
+      if (_unknownFields != null) {
+        size += _unknownFields.CalculateSize();
+      }
+      return size;
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public void MergeFrom(ClientConfigureRequest other) {
+      if (other == null) {
+        return;
+      }
+      types_.Add(other.types_);
+      metadata_.Add(other.metadata_);
+      _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields);
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public void MergeFrom(pb::CodedInputStream input) {
+    #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
+      input.ReadRawMessage(this);
+    #else
+      uint tag;
+      while ((tag = input.ReadTag()) != 0) {
+        switch(tag) {
+          default:
+            _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
+            break;
+          case 10:
+          case 8: {
+            types_.AddEntriesFrom(input, _repeated_types_codec);
+            break;
+          }
+          case 18: {
+            metadata_.AddEntriesFrom(input, _repeated_metadata_codec);
+            break;
+          }
+        }
+      }
+    #endif
+    }
+
+    #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) {
+      uint tag;
+      while ((tag = input.ReadTag()) != 0) {
+        switch(tag) {
+          default:
+            _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input);
+            break;
+          case 10:
+          case 8: {
+            types_.AddEntriesFrom(ref input, _repeated_types_codec);
+            break;
+          }
+          case 18: {
+            metadata_.AddEntriesFrom(ref input, _repeated_metadata_codec);
+            break;
+          }
+        }
+      }
+    }
+    #endif
+
+    #region Nested types
+    /// <summary>Container for nested types declared in the ClientConfigureRequest message type.</summary>
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public static partial class Types {
+      /// <summary>
+      /// Type of RPCs to send.
+      /// </summary>
+      public enum RpcType {
+        [pbr::OriginalName("EMPTY_CALL")] EmptyCall = 0,
+        [pbr::OriginalName("UNARY_CALL")] UnaryCall = 1,
+      }
+
+      /// <summary>
+      /// Metadata to be attached for the given type of RPCs.
+      /// </summary>
+      public sealed partial class Metadata : pb::IMessage<Metadata>
+      #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
+          , pb::IBufferMessage
+      #endif
+      {
+        private static readonly pb::MessageParser<Metadata> _parser = new pb::MessageParser<Metadata>(() => new Metadata());
+        private pb::UnknownFieldSet _unknownFields;
+        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+        public static pb::MessageParser<Metadata> Parser { get { return _parser; } }
+
+        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+        public static pbr::MessageDescriptor Descriptor {
+          get { return global::Grpc.Testing.ClientConfigureRequest.Descriptor.NestedTypes[0]; }
+        }
+
+        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+        pbr::MessageDescriptor pb::IMessage.Descriptor {
+          get { return Descriptor; }
+        }
+
+        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+        public Metadata() {
+          OnConstruction();
+        }
+
+        partial void OnConstruction();
+
+        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+        public Metadata(Metadata other) : this() {
+          type_ = other.type_;
+          key_ = other.key_;
+          value_ = other.value_;
+          _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields);
+        }
+
+        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+        public Metadata Clone() {
+          return new Metadata(this);
+        }
+
+        /// <summary>Field number for the "type" field.</summary>
+        public const int TypeFieldNumber = 1;
+        private global::Grpc.Testing.ClientConfigureRequest.Types.RpcType type_ = global::Grpc.Testing.ClientConfigureRequest.Types.RpcType.EmptyCall;
+        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+        public global::Grpc.Testing.ClientConfigureRequest.Types.RpcType Type {
+          get { return type_; }
+          set {
+            type_ = value;
+          }
+        }
+
+        /// <summary>Field number for the "key" field.</summary>
+        public const int KeyFieldNumber = 2;
+        private string key_ = "";
+        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+        public string Key {
+          get { return key_; }
+          set {
+            key_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
+          }
+        }
+
+        /// <summary>Field number for the "value" field.</summary>
+        public const int ValueFieldNumber = 3;
+        private string value_ = "";
+        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+        public string Value {
+          get { return value_; }
+          set {
+            value_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
+          }
+        }
+
+        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+        public override bool Equals(object other) {
+          return Equals(other as Metadata);
+        }
+
+        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+        public bool Equals(Metadata other) {
+          if (ReferenceEquals(other, null)) {
+            return false;
+          }
+          if (ReferenceEquals(other, this)) {
+            return true;
+          }
+          if (Type != other.Type) return false;
+          if (Key != other.Key) return false;
+          if (Value != other.Value) return false;
+          return Equals(_unknownFields, other._unknownFields);
+        }
+
+        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+        public override int GetHashCode() {
+          int hash = 1;
+          if (Type != global::Grpc.Testing.ClientConfigureRequest.Types.RpcType.EmptyCall) hash ^= Type.GetHashCode();
+          if (Key.Length != 0) hash ^= Key.GetHashCode();
+          if (Value.Length != 0) hash ^= Value.GetHashCode();
+          if (_unknownFields != null) {
+            hash ^= _unknownFields.GetHashCode();
+          }
+          return hash;
+        }
+
+        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+        public override string ToString() {
+          return pb::JsonFormatter.ToDiagnosticString(this);
+        }
+
+        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+        public void WriteTo(pb::CodedOutputStream output) {
+        #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
+          output.WriteRawMessage(this);
+        #else
+          if (Type != global::Grpc.Testing.ClientConfigureRequest.Types.RpcType.EmptyCall) {
+            output.WriteRawTag(8);
+            output.WriteEnum((int) Type);
+          }
+          if (Key.Length != 0) {
+            output.WriteRawTag(18);
+            output.WriteString(Key);
+          }
+          if (Value.Length != 0) {
+            output.WriteRawTag(26);
+            output.WriteString(Value);
+          }
+          if (_unknownFields != null) {
+            _unknownFields.WriteTo(output);
+          }
+        #endif
+        }
+
+        #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
+        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+        void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) {
+          if (Type != global::Grpc.Testing.ClientConfigureRequest.Types.RpcType.EmptyCall) {
+            output.WriteRawTag(8);
+            output.WriteEnum((int) Type);
+          }
+          if (Key.Length != 0) {
+            output.WriteRawTag(18);
+            output.WriteString(Key);
+          }
+          if (Value.Length != 0) {
+            output.WriteRawTag(26);
+            output.WriteString(Value);
+          }
+          if (_unknownFields != null) {
+            _unknownFields.WriteTo(ref output);
+          }
+        }
+        #endif
+
+        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+        public int CalculateSize() {
+          int size = 0;
+          if (Type != global::Grpc.Testing.ClientConfigureRequest.Types.RpcType.EmptyCall) {
+            size += 1 + pb::CodedOutputStream.ComputeEnumSize((int) Type);
+          }
+          if (Key.Length != 0) {
+            size += 1 + pb::CodedOutputStream.ComputeStringSize(Key);
+          }
+          if (Value.Length != 0) {
+            size += 1 + pb::CodedOutputStream.ComputeStringSize(Value);
+          }
+          if (_unknownFields != null) {
+            size += _unknownFields.CalculateSize();
+          }
+          return size;
+        }
+
+        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+        public void MergeFrom(Metadata other) {
+          if (other == null) {
+            return;
+          }
+          if (other.Type != global::Grpc.Testing.ClientConfigureRequest.Types.RpcType.EmptyCall) {
+            Type = other.Type;
+          }
+          if (other.Key.Length != 0) {
+            Key = other.Key;
+          }
+          if (other.Value.Length != 0) {
+            Value = other.Value;
+          }
+          _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields);
+        }
+
+        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+        public void MergeFrom(pb::CodedInputStream input) {
+        #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
+          input.ReadRawMessage(this);
+        #else
+          uint tag;
+          while ((tag = input.ReadTag()) != 0) {
+            switch(tag) {
+              default:
+                _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
+                break;
+              case 8: {
+                Type = (global::Grpc.Testing.ClientConfigureRequest.Types.RpcType) input.ReadEnum();
+                break;
+              }
+              case 18: {
+                Key = input.ReadString();
+                break;
+              }
+              case 26: {
+                Value = input.ReadString();
+                break;
+              }
+            }
+          }
+        #endif
+        }
+
+        #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
+        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+        void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) {
+          uint tag;
+          while ((tag = input.ReadTag()) != 0) {
+            switch(tag) {
+              default:
+                _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input);
+                break;
+              case 8: {
+                Type = (global::Grpc.Testing.ClientConfigureRequest.Types.RpcType) input.ReadEnum();
+                break;
+              }
+              case 18: {
+                Key = input.ReadString();
+                break;
+              }
+              case 26: {
+                Value = input.ReadString();
+                break;
+              }
+            }
+          }
+        }
+        #endif
+
+      }
+
+    }
+    #endregion
+
+  }
+
+  /// <summary>
+  /// Response for updating a test client's configuration.
+  /// </summary>
+  public sealed partial class ClientConfigureResponse : pb::IMessage<ClientConfigureResponse>
+  #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
+      , pb::IBufferMessage
+  #endif
+  {
+    private static readonly pb::MessageParser<ClientConfigureResponse> _parser = new pb::MessageParser<ClientConfigureResponse>(() => new ClientConfigureResponse());
+    private pb::UnknownFieldSet _unknownFields;
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public static pb::MessageParser<ClientConfigureResponse> Parser { get { return _parser; } }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public static pbr::MessageDescriptor Descriptor {
+      get { return global::Grpc.Testing.MessagesReflection.Descriptor.MessageTypes[17]; }
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    pbr::MessageDescriptor pb::IMessage.Descriptor {
+      get { return Descriptor; }
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public ClientConfigureResponse() {
+      OnConstruction();
+    }
+
+    partial void OnConstruction();
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public ClientConfigureResponse(ClientConfigureResponse other) : this() {
+      _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields);
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public ClientConfigureResponse Clone() {
+      return new ClientConfigureResponse(this);
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public override bool Equals(object other) {
+      return Equals(other as ClientConfigureResponse);
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public bool Equals(ClientConfigureResponse other) {
+      if (ReferenceEquals(other, null)) {
+        return false;
+      }
+      if (ReferenceEquals(other, this)) {
+        return true;
+      }
+      return Equals(_unknownFields, other._unknownFields);
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public override int GetHashCode() {
+      int hash = 1;
+      if (_unknownFields != null) {
+        hash ^= _unknownFields.GetHashCode();
+      }
+      return hash;
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public override string ToString() {
+      return pb::JsonFormatter.ToDiagnosticString(this);
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public void WriteTo(pb::CodedOutputStream output) {
+    #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
+      output.WriteRawMessage(this);
+    #else
+      if (_unknownFields != null) {
+        _unknownFields.WriteTo(output);
+      }
+    #endif
+    }
+
+    #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) {
+      if (_unknownFields != null) {
+        _unknownFields.WriteTo(ref output);
+      }
+    }
+    #endif
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public int CalculateSize() {
+      int size = 0;
+      if (_unknownFields != null) {
+        size += _unknownFields.CalculateSize();
+      }
+      return size;
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public void MergeFrom(ClientConfigureResponse other) {
+      if (other == null) {
+        return;
+      }
+      _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields);
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public void MergeFrom(pb::CodedInputStream input) {
+    #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
+      input.ReadRawMessage(this);
+    #else
+      uint tag;
+      while ((tag = input.ReadTag()) != 0) {
+        switch(tag) {
+          default:
+            _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
+            break;
+        }
+      }
+    #endif
+    }
+
+    #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) {
+      uint tag;
+      while ((tag = input.ReadTag()) != 0) {
+        switch(tag) {
+          default:
+            _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input);
+            break;
+        }
+      }
+    }
+    #endif
+
+  }
+
   #endregion
 
 }
index 8967af6..f82862a 100644 (file)
@@ -47,13 +47,19 @@ namespace Grpc.Testing {
             "bmcuRW1wdHkaEy5ncnBjLnRlc3RpbmcuRW1wdHkyiQEKEFJlY29ubmVjdFNl",
             "cnZpY2USOwoFU3RhcnQSHS5ncnBjLnRlc3RpbmcuUmVjb25uZWN0UGFyYW1z",
             "GhMuZ3JwYy50ZXN0aW5nLkVtcHR5EjgKBFN0b3ASEy5ncnBjLnRlc3Rpbmcu",
-            "RW1wdHkaGy5ncnBjLnRlc3RpbmcuUmVjb25uZWN0SW5mbzJ/ChhMb2FkQmFs",
-            "YW5jZXJTdGF0c1NlcnZpY2USYwoOR2V0Q2xpZW50U3RhdHMSJi5ncnBjLnRl",
-            "c3RpbmcuTG9hZEJhbGFuY2VyU3RhdHNSZXF1ZXN0GicuZ3JwYy50ZXN0aW5n",
-            "LkxvYWRCYWxhbmNlclN0YXRzUmVzcG9uc2UiADKLAQoWWGRzVXBkYXRlSGVh",
-            "bHRoU2VydmljZRI2CgpTZXRTZXJ2aW5nEhMuZ3JwYy50ZXN0aW5nLkVtcHR5",
-            "GhMuZ3JwYy50ZXN0aW5nLkVtcHR5EjkKDVNldE5vdFNlcnZpbmcSEy5ncnBj",
-            "LnRlc3RpbmcuRW1wdHkaEy5ncnBjLnRlc3RpbmcuRW1wdHliBnByb3RvMw=="));
+            "RW1wdHkaGy5ncnBjLnRlc3RpbmcuUmVjb25uZWN0SW5mbzKGAgoYTG9hZEJh",
+            "bGFuY2VyU3RhdHNTZXJ2aWNlEmMKDkdldENsaWVudFN0YXRzEiYuZ3JwYy50",
+            "ZXN0aW5nLkxvYWRCYWxhbmNlclN0YXRzUmVxdWVzdBonLmdycGMudGVzdGlu",
+            "Zy5Mb2FkQmFsYW5jZXJTdGF0c1Jlc3BvbnNlIgAShAEKGUdldENsaWVudEFj",
+            "Y3VtdWxhdGVkU3RhdHMSMS5ncnBjLnRlc3RpbmcuTG9hZEJhbGFuY2VyQWNj",
+            "dW11bGF0ZWRTdGF0c1JlcXVlc3QaMi5ncnBjLnRlc3RpbmcuTG9hZEJhbGFu",
+            "Y2VyQWNjdW11bGF0ZWRTdGF0c1Jlc3BvbnNlIgAyiwEKFlhkc1VwZGF0ZUhl",
+            "YWx0aFNlcnZpY2USNgoKU2V0U2VydmluZxITLmdycGMudGVzdGluZy5FbXB0",
+            "eRoTLmdycGMudGVzdGluZy5FbXB0eRI5Cg1TZXROb3RTZXJ2aW5nEhMuZ3Jw",
+            "Yy50ZXN0aW5nLkVtcHR5GhMuZ3JwYy50ZXN0aW5nLkVtcHR5MnsKH1hkc1Vw",
+            "ZGF0ZUNsaWVudENvbmZpZ3VyZVNlcnZpY2USWAoJQ29uZmlndXJlEiQuZ3Jw",
+            "Yy50ZXN0aW5nLkNsaWVudENvbmZpZ3VyZVJlcXVlc3QaJS5ncnBjLnRlc3Rp",
+            "bmcuQ2xpZW50Q29uZmlndXJlUmVzcG9uc2ViBnByb3RvMw=="));
       descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData,
           new pbr::FileDescriptor[] { global::Grpc.Testing.EmptyReflection.Descriptor, global::Grpc.Testing.MessagesReflection.Descriptor, },
           new pbr::GeneratedClrTypeInfo(null, null, null));
index 168c089..8c1e012 100644 (file)
@@ -947,6 +947,8 @@ namespace Grpc.Testing {
 
     static readonly grpc::Marshaller<global::Grpc.Testing.LoadBalancerStatsRequest> __Marshaller_grpc_testing_LoadBalancerStatsRequest = grpc::Marshallers.Create(__Helper_SerializeMessage, context => __Helper_DeserializeMessage(context, global::Grpc.Testing.LoadBalancerStatsRequest.Parser));
     static readonly grpc::Marshaller<global::Grpc.Testing.LoadBalancerStatsResponse> __Marshaller_grpc_testing_LoadBalancerStatsResponse = grpc::Marshallers.Create(__Helper_SerializeMessage, context => __Helper_DeserializeMessage(context, global::Grpc.Testing.LoadBalancerStatsResponse.Parser));
+    static readonly grpc::Marshaller<global::Grpc.Testing.LoadBalancerAccumulatedStatsRequest> __Marshaller_grpc_testing_LoadBalancerAccumulatedStatsRequest = grpc::Marshallers.Create(__Helper_SerializeMessage, context => __Helper_DeserializeMessage(context, global::Grpc.Testing.LoadBalancerAccumulatedStatsRequest.Parser));
+    static readonly grpc::Marshaller<global::Grpc.Testing.LoadBalancerAccumulatedStatsResponse> __Marshaller_grpc_testing_LoadBalancerAccumulatedStatsResponse = grpc::Marshallers.Create(__Helper_SerializeMessage, context => __Helper_DeserializeMessage(context, global::Grpc.Testing.LoadBalancerAccumulatedStatsResponse.Parser));
 
     static readonly grpc::Method<global::Grpc.Testing.LoadBalancerStatsRequest, global::Grpc.Testing.LoadBalancerStatsResponse> __Method_GetClientStats = new grpc::Method<global::Grpc.Testing.LoadBalancerStatsRequest, global::Grpc.Testing.LoadBalancerStatsResponse>(
         grpc::MethodType.Unary,
@@ -955,6 +957,13 @@ namespace Grpc.Testing {
         __Marshaller_grpc_testing_LoadBalancerStatsRequest,
         __Marshaller_grpc_testing_LoadBalancerStatsResponse);
 
+    static readonly grpc::Method<global::Grpc.Testing.LoadBalancerAccumulatedStatsRequest, global::Grpc.Testing.LoadBalancerAccumulatedStatsResponse> __Method_GetClientAccumulatedStats = new grpc::Method<global::Grpc.Testing.LoadBalancerAccumulatedStatsRequest, global::Grpc.Testing.LoadBalancerAccumulatedStatsResponse>(
+        grpc::MethodType.Unary,
+        __ServiceName,
+        "GetClientAccumulatedStats",
+        __Marshaller_grpc_testing_LoadBalancerAccumulatedStatsRequest,
+        __Marshaller_grpc_testing_LoadBalancerAccumulatedStatsResponse);
+
     /// <summary>Service descriptor</summary>
     public static global::Google.Protobuf.Reflection.ServiceDescriptor Descriptor
     {
@@ -976,6 +985,17 @@ namespace Grpc.Testing {
         throw new grpc::RpcException(new grpc::Status(grpc::StatusCode.Unimplemented, ""));
       }
 
+      /// <summary>
+      /// Gets the accumulated stats for RPCs sent by a test client.
+      /// </summary>
+      /// <param name="request">The request received from the client.</param>
+      /// <param name="context">The context of the server-side call handler being invoked.</param>
+      /// <returns>The response to send back to the client (wrapped by a task).</returns>
+      public virtual global::System.Threading.Tasks.Task<global::Grpc.Testing.LoadBalancerAccumulatedStatsResponse> GetClientAccumulatedStats(global::Grpc.Testing.LoadBalancerAccumulatedStatsRequest request, grpc::ServerCallContext context)
+      {
+        throw new grpc::RpcException(new grpc::Status(grpc::StatusCode.Unimplemented, ""));
+      }
+
     }
 
     /// <summary>Client for LoadBalancerStatsService</summary>
@@ -1045,6 +1065,50 @@ namespace Grpc.Testing {
       {
         return CallInvoker.AsyncUnaryCall(__Method_GetClientStats, null, options, request);
       }
+      /// <summary>
+      /// Gets the accumulated stats for RPCs sent by a test client.
+      /// </summary>
+      /// <param name="request">The request to send to the server.</param>
+      /// <param name="headers">The initial metadata to send with the call. This parameter is optional.</param>
+      /// <param name="deadline">An optional deadline for the call. The call will be cancelled if deadline is hit.</param>
+      /// <param name="cancellationToken">An optional token for canceling the call.</param>
+      /// <returns>The response received from the server.</returns>
+      public virtual global::Grpc.Testing.LoadBalancerAccumulatedStatsResponse GetClientAccumulatedStats(global::Grpc.Testing.LoadBalancerAccumulatedStatsRequest request, grpc::Metadata headers = null, global::System.DateTime? deadline = null, global::System.Threading.CancellationToken cancellationToken = default(global::System.Threading.CancellationToken))
+      {
+        return GetClientAccumulatedStats(request, new grpc::CallOptions(headers, deadline, cancellationToken));
+      }
+      /// <summary>
+      /// Gets the accumulated stats for RPCs sent by a test client.
+      /// </summary>
+      /// <param name="request">The request to send to the server.</param>
+      /// <param name="options">The options for the call.</param>
+      /// <returns>The response received from the server.</returns>
+      public virtual global::Grpc.Testing.LoadBalancerAccumulatedStatsResponse GetClientAccumulatedStats(global::Grpc.Testing.LoadBalancerAccumulatedStatsRequest request, grpc::CallOptions options)
+      {
+        return CallInvoker.BlockingUnaryCall(__Method_GetClientAccumulatedStats, null, options, request);
+      }
+      /// <summary>
+      /// Gets the accumulated stats for RPCs sent by a test client.
+      /// </summary>
+      /// <param name="request">The request to send to the server.</param>
+      /// <param name="headers">The initial metadata to send with the call. This parameter is optional.</param>
+      /// <param name="deadline">An optional deadline for the call. The call will be cancelled if deadline is hit.</param>
+      /// <param name="cancellationToken">An optional token for canceling the call.</param>
+      /// <returns>The call object.</returns>
+      public virtual grpc::AsyncUnaryCall<global::Grpc.Testing.LoadBalancerAccumulatedStatsResponse> GetClientAccumulatedStatsAsync(global::Grpc.Testing.LoadBalancerAccumulatedStatsRequest request, grpc::Metadata headers = null, global::System.DateTime? deadline = null, global::System.Threading.CancellationToken cancellationToken = default(global::System.Threading.CancellationToken))
+      {
+        return GetClientAccumulatedStatsAsync(request, new grpc::CallOptions(headers, deadline, cancellationToken));
+      }
+      /// <summary>
+      /// Gets the accumulated stats for RPCs sent by a test client.
+      /// </summary>
+      /// <param name="request">The request to send to the server.</param>
+      /// <param name="options">The options for the call.</param>
+      /// <returns>The call object.</returns>
+      public virtual grpc::AsyncUnaryCall<global::Grpc.Testing.LoadBalancerAccumulatedStatsResponse> GetClientAccumulatedStatsAsync(global::Grpc.Testing.LoadBalancerAccumulatedStatsRequest request, grpc::CallOptions options)
+      {
+        return CallInvoker.AsyncUnaryCall(__Method_GetClientAccumulatedStats, null, options, request);
+      }
       /// <summary>Creates a new instance of client from given <c>ClientBaseConfiguration</c>.</summary>
       protected override LoadBalancerStatsServiceClient NewInstance(ClientBaseConfiguration configuration)
       {
@@ -1057,7 +1121,8 @@ namespace Grpc.Testing {
     public static grpc::ServerServiceDefinition BindService(LoadBalancerStatsServiceBase serviceImpl)
     {
       return grpc::ServerServiceDefinition.CreateBuilder()
-          .AddMethod(__Method_GetClientStats, serviceImpl.GetClientStats).Build();
+          .AddMethod(__Method_GetClientStats, serviceImpl.GetClientStats)
+          .AddMethod(__Method_GetClientAccumulatedStats, serviceImpl.GetClientAccumulatedStats).Build();
     }
 
     /// <summary>Register service method with a service binder with or without implementation. Useful when customizing the  service binding logic.
@@ -1067,6 +1132,7 @@ namespace Grpc.Testing {
     public static void BindService(grpc::ServiceBinderBase serviceBinder, LoadBalancerStatsServiceBase serviceImpl)
     {
       serviceBinder.AddMethod(__Method_GetClientStats, serviceImpl == null ? null : new grpc::UnaryServerMethod<global::Grpc.Testing.LoadBalancerStatsRequest, global::Grpc.Testing.LoadBalancerStatsResponse>(serviceImpl.GetClientStats));
+      serviceBinder.AddMethod(__Method_GetClientAccumulatedStats, serviceImpl == null ? null : new grpc::UnaryServerMethod<global::Grpc.Testing.LoadBalancerAccumulatedStatsRequest, global::Grpc.Testing.LoadBalancerAccumulatedStatsResponse>(serviceImpl.GetClientAccumulatedStats));
     }
 
   }
@@ -1227,5 +1293,167 @@ namespace Grpc.Testing {
     }
 
   }
+  /// <summary>
+  /// A service to dynamically update the configuration of an xDS test client.
+  /// </summary>
+  public static partial class XdsUpdateClientConfigureService
+  {
+    static readonly string __ServiceName = "grpc.testing.XdsUpdateClientConfigureService";
+
+    static void __Helper_SerializeMessage(global::Google.Protobuf.IMessage message, grpc::SerializationContext context)
+    {
+      #if !GRPC_DISABLE_PROTOBUF_BUFFER_SERIALIZATION
+      if (message is global::Google.Protobuf.IBufferMessage)
+      {
+        context.SetPayloadLength(message.CalculateSize());
+        global::Google.Protobuf.MessageExtensions.WriteTo(message, context.GetBufferWriter());
+        context.Complete();
+        return;
+      }
+      #endif
+      context.Complete(global::Google.Protobuf.MessageExtensions.ToByteArray(message));
+    }
+
+    static class __Helper_MessageCache<T>
+    {
+      public static readonly bool IsBufferMessage = global::System.Reflection.IntrospectionExtensions.GetTypeInfo(typeof(global::Google.Protobuf.IBufferMessage)).IsAssignableFrom(typeof(T));
+    }
+
+    static T __Helper_DeserializeMessage<T>(grpc::DeserializationContext context, global::Google.Protobuf.MessageParser<T> parser) where T : global::Google.Protobuf.IMessage<T>
+    {
+      #if !GRPC_DISABLE_PROTOBUF_BUFFER_SERIALIZATION
+      if (__Helper_MessageCache<T>.IsBufferMessage)
+      {
+        return parser.ParseFrom(context.PayloadAsReadOnlySequence());
+      }
+      #endif
+      return parser.ParseFrom(context.PayloadAsNewBuffer());
+    }
+
+    static readonly grpc::Marshaller<global::Grpc.Testing.ClientConfigureRequest> __Marshaller_grpc_testing_ClientConfigureRequest = grpc::Marshallers.Create(__Helper_SerializeMessage, context => __Helper_DeserializeMessage(context, global::Grpc.Testing.ClientConfigureRequest.Parser));
+    static readonly grpc::Marshaller<global::Grpc.Testing.ClientConfigureResponse> __Marshaller_grpc_testing_ClientConfigureResponse = grpc::Marshallers.Create(__Helper_SerializeMessage, context => __Helper_DeserializeMessage(context, global::Grpc.Testing.ClientConfigureResponse.Parser));
+
+    static readonly grpc::Method<global::Grpc.Testing.ClientConfigureRequest, global::Grpc.Testing.ClientConfigureResponse> __Method_Configure = new grpc::Method<global::Grpc.Testing.ClientConfigureRequest, global::Grpc.Testing.ClientConfigureResponse>(
+        grpc::MethodType.Unary,
+        __ServiceName,
+        "Configure",
+        __Marshaller_grpc_testing_ClientConfigureRequest,
+        __Marshaller_grpc_testing_ClientConfigureResponse);
+
+    /// <summary>Service descriptor</summary>
+    public static global::Google.Protobuf.Reflection.ServiceDescriptor Descriptor
+    {
+      get { return global::Grpc.Testing.TestReflection.Descriptor.Services[5]; }
+    }
+
+    /// <summary>Base class for server-side implementations of XdsUpdateClientConfigureService</summary>
+    [grpc::BindServiceMethod(typeof(XdsUpdateClientConfigureService), "BindService")]
+    public abstract partial class XdsUpdateClientConfigureServiceBase
+    {
+      /// <summary>
+      /// Update the tes client's configuration.
+      /// </summary>
+      /// <param name="request">The request received from the client.</param>
+      /// <param name="context">The context of the server-side call handler being invoked.</param>
+      /// <returns>The response to send back to the client (wrapped by a task).</returns>
+      public virtual global::System.Threading.Tasks.Task<global::Grpc.Testing.ClientConfigureResponse> Configure(global::Grpc.Testing.ClientConfigureRequest request, grpc::ServerCallContext context)
+      {
+        throw new grpc::RpcException(new grpc::Status(grpc::StatusCode.Unimplemented, ""));
+      }
+
+    }
+
+    /// <summary>Client for XdsUpdateClientConfigureService</summary>
+    public partial class XdsUpdateClientConfigureServiceClient : grpc::ClientBase<XdsUpdateClientConfigureServiceClient>
+    {
+      /// <summary>Creates a new client for XdsUpdateClientConfigureService</summary>
+      /// <param name="channel">The channel to use to make remote calls.</param>
+      public XdsUpdateClientConfigureServiceClient(grpc::ChannelBase channel) : base(channel)
+      {
+      }
+      /// <summary>Creates a new client for XdsUpdateClientConfigureService that uses a custom <c>CallInvoker</c>.</summary>
+      /// <param name="callInvoker">The callInvoker to use to make remote calls.</param>
+      public XdsUpdateClientConfigureServiceClient(grpc::CallInvoker callInvoker) : base(callInvoker)
+      {
+      }
+      /// <summary>Protected parameterless constructor to allow creation of test doubles.</summary>
+      protected XdsUpdateClientConfigureServiceClient() : base()
+      {
+      }
+      /// <summary>Protected constructor to allow creation of configured clients.</summary>
+      /// <param name="configuration">The client configuration.</param>
+      protected XdsUpdateClientConfigureServiceClient(ClientBaseConfiguration configuration) : base(configuration)
+      {
+      }
+
+      /// <summary>
+      /// Update the tes client's configuration.
+      /// </summary>
+      /// <param name="request">The request to send to the server.</param>
+      /// <param name="headers">The initial metadata to send with the call. This parameter is optional.</param>
+      /// <param name="deadline">An optional deadline for the call. The call will be cancelled if deadline is hit.</param>
+      /// <param name="cancellationToken">An optional token for canceling the call.</param>
+      /// <returns>The response received from the server.</returns>
+      public virtual global::Grpc.Testing.ClientConfigureResponse Configure(global::Grpc.Testing.ClientConfigureRequest request, grpc::Metadata headers = null, global::System.DateTime? deadline = null, global::System.Threading.CancellationToken cancellationToken = default(global::System.Threading.CancellationToken))
+      {
+        return Configure(request, new grpc::CallOptions(headers, deadline, cancellationToken));
+      }
+      /// <summary>
+      /// Update the tes client's configuration.
+      /// </summary>
+      /// <param name="request">The request to send to the server.</param>
+      /// <param name="options">The options for the call.</param>
+      /// <returns>The response received from the server.</returns>
+      public virtual global::Grpc.Testing.ClientConfigureResponse Configure(global::Grpc.Testing.ClientConfigureRequest request, grpc::CallOptions options)
+      {
+        return CallInvoker.BlockingUnaryCall(__Method_Configure, null, options, request);
+      }
+      /// <summary>
+      /// Update the tes client's configuration.
+      /// </summary>
+      /// <param name="request">The request to send to the server.</param>
+      /// <param name="headers">The initial metadata to send with the call. This parameter is optional.</param>
+      /// <param name="deadline">An optional deadline for the call. The call will be cancelled if deadline is hit.</param>
+      /// <param name="cancellationToken">An optional token for canceling the call.</param>
+      /// <returns>The call object.</returns>
+      public virtual grpc::AsyncUnaryCall<global::Grpc.Testing.ClientConfigureResponse> ConfigureAsync(global::Grpc.Testing.ClientConfigureRequest request, grpc::Metadata headers = null, global::System.DateTime? deadline = null, global::System.Threading.CancellationToken cancellationToken = default(global::System.Threading.CancellationToken))
+      {
+        return ConfigureAsync(request, new grpc::CallOptions(headers, deadline, cancellationToken));
+      }
+      /// <summary>
+      /// Update the tes client's configuration.
+      /// </summary>
+      /// <param name="request">The request to send to the server.</param>
+      /// <param name="options">The options for the call.</param>
+      /// <returns>The call object.</returns>
+      public virtual grpc::AsyncUnaryCall<global::Grpc.Testing.ClientConfigureResponse> ConfigureAsync(global::Grpc.Testing.ClientConfigureRequest request, grpc::CallOptions options)
+      {
+        return CallInvoker.AsyncUnaryCall(__Method_Configure, null, options, request);
+      }
+      /// <summary>Creates a new instance of client from given <c>ClientBaseConfiguration</c>.</summary>
+      protected override XdsUpdateClientConfigureServiceClient NewInstance(ClientBaseConfiguration configuration)
+      {
+        return new XdsUpdateClientConfigureServiceClient(configuration);
+      }
+    }
+
+    /// <summary>Creates service definition that can be registered with a server</summary>
+    /// <param name="serviceImpl">An object implementing the server-side handling logic.</param>
+    public static grpc::ServerServiceDefinition BindService(XdsUpdateClientConfigureServiceBase serviceImpl)
+    {
+      return grpc::ServerServiceDefinition.CreateBuilder()
+          .AddMethod(__Method_Configure, serviceImpl.Configure).Build();
+    }
+
+    /// <summary>Register service method with a service binder with or without implementation. Useful when customizing the  service binding logic.
+    /// Note: this method is part of an experimental API that can change or be removed without any prior notice.</summary>
+    /// <param name="serviceBinder">Service methods will be bound by calling <c>AddMethod</c> on this object.</param>
+    /// <param name="serviceImpl">An object implementing the server-side handling logic.</param>
+    public static void BindService(grpc::ServiceBinderBase serviceBinder, XdsUpdateClientConfigureServiceBase serviceImpl)
+    {
+      serviceBinder.AddMethod(__Method_Configure, serviceImpl == null ? null : new grpc::UnaryServerMethod<global::Grpc.Testing.ClientConfigureRequest, global::Grpc.Testing.ClientConfigureResponse>(serviceImpl.Configure));
+    }
+
+  }
 }
 #endregion
index bbe42f6..0a3db2b 100644 (file)
@@ -1,7 +1,7 @@
 <!-- This file is generated -->
 <Project>
   <PropertyGroup>
-    <GrpcCsharpVersion>2.34.1</GrpcCsharpVersion>
-    <GoogleProtobufVersion>3.13.0</GoogleProtobufVersion>
+    <GrpcCsharpVersion>2.35.0</GrpcCsharpVersion>
+    <GoogleProtobufVersion>3.14.0</GoogleProtobufVersion>
   </PropertyGroup>
 </Project>
index 34778bc..7f5fa21 100644 (file)
@@ -42,7 +42,7 @@ Pod::Spec.new do |s|
   # exclamation mark ensures that other "regular" pods will be able to find it as it'll be installed
   # before them.
   s.name     = '!ProtoCompiler-gRPCCppPlugin'
-  v = '1.34.1'
+  v = '1.35.0'
   s.version  = v
   s.summary  = 'The gRPC ProtoC plugin generates C++ files from .proto services.'
   s.description = <<-DESC
@@ -100,7 +100,7 @@ Pod::Spec.new do |s|
   s.preserve_paths = plugin
 
   # Restrict the protoc version to the one supported by this plugin.
-  s.dependency '!ProtoCompiler', '3.13.0'
+  s.dependency '!ProtoCompiler', '3.14.0'
   # For the Protobuf dependency not to complain:
   s.ios.deployment_target = '9.0'
   s.osx.deployment_target = '10.10'
index 4f38e7d..174be70 100644 (file)
@@ -42,7 +42,7 @@ Pod::Spec.new do |s|
   # exclamation mark ensures that other "regular" pods will be able to find it as it'll be installed
   # before them.
   s.name     = '!ProtoCompiler-gRPCPlugin'
-  v = '1.34.1'
+  v = '1.35.0'
   s.version  = v
   s.summary  = 'The gRPC ProtoC plugin generates Objective-C files from .proto services.'
   s.description = <<-DESC
@@ -102,7 +102,7 @@ Pod::Spec.new do |s|
   s.preserve_paths = plugin
 
   # Restrict the protoc version to the one supported by this plugin.
-  s.dependency '!ProtoCompiler', '3.13.0'
+  s.dependency '!ProtoCompiler', '3.14.0'
   # For the Protobuf dependency not to complain:
   s.ios.deployment_target = '9.0'
   s.osx.deployment_target = '10.10'
index 20aa37f..509a463 100644 (file)
@@ -36,7 +36,7 @@ Pod::Spec.new do |s|
   # exclamation mark ensures that other "regular" pods will be able to find it as it'll be installed
   # before them.
   s.name     = '!ProtoCompiler'
-  v = '3.13.0'
+  v = '3.14.0'
   s.version  = v
   s.summary  = 'The Protobuf Compiler (protoc) generates Objective-C files from .proto files'
   s.description = <<-DESC
index 66f34b6..eb3ad28 100644 (file)
@@ -22,4 +22,4 @@
 // instead. This file can be regenerated from the template by running
 // `tools/buildgen/generate_projects.sh`.
 
-#define GRPC_OBJC_VERSION_STRING @"1.34.1"
+#define GRPC_OBJC_VERSION_STRING @"1.35.0"
index f7168ba..7a971fd 100644 (file)
@@ -22,5 +22,5 @@
 // instead. This file can be regenerated from the template by running
 // `tools/buildgen/generate_projects.sh`.
 
-#define GRPC_OBJC_VERSION_STRING @"1.34.1"
+#define GRPC_OBJC_VERSION_STRING @"1.35.0"
 #define GRPC_C_VERSION_STRING @"14.0.0"
index 328ae04..09f6f93 100644 (file)
@@ -2,7 +2,7 @@
   "name": "grpc/grpc-dev",
   "description": "gRPC library for PHP - for Development use only",
   "license": "Apache-2.0",
-  "version": "1.34.1",
+  "version": "1.35.0",
   "require": {
     "php": ">=7.0.0",
     "google/protobuf": "^v3.3.0"
index 67ede05..53422e8 100644 (file)
@@ -21,8 +21,8 @@ ARG MAKEFLAGS=-j8
 
 WORKDIR /tmp
 
-RUN wget https://phar.phpunit.de/phpunit-8.5.8.phar && \
-  mv phpunit-8.5.8.phar /usr/local/bin/phpunit && \
+RUN wget https://phar.phpunit.de/phpunit-8.5.13.phar && \
+  mv phpunit-8.5.13.phar /usr/local/bin/phpunit && \
   chmod +x /usr/local/bin/phpunit
 
 
index 9c5278e..c9fefa7 100644 (file)
@@ -35,8 +35,8 @@ ARG MAKEFLAGS=-j8
 
 WORKDIR /tmp
 
-RUN wget https://phar.phpunit.de/phpunit-8.5.8.phar && \
-  mv phpunit-8.5.8.phar /usr/local/bin/phpunit && \
+RUN wget https://phar.phpunit.de/phpunit-8.5.13.phar && \
+  mv phpunit-8.5.13.phar /usr/local/bin/phpunit && \
   chmod +x /usr/local/bin/phpunit
 
 
index 137724b..605105e 100644 (file)
@@ -23,8 +23,8 @@ ARG MAKEFLAGS=-j8
 
 WORKDIR /tmp
 
-RUN wget https://phar.phpunit.de/phpunit-8.5.8.phar && \
-  mv phpunit-8.5.8.phar /usr/local/bin/phpunit && \
+RUN wget https://phar.phpunit.de/phpunit-8.5.13.phar && \
+  mv phpunit-8.5.13.phar /usr/local/bin/phpunit && \
   chmod +x /usr/local/bin/phpunit
 
 
index bd3acc1..edcd669 100644 (file)
@@ -23,8 +23,8 @@ ARG MAKEFLAGS=-j8
 
 WORKDIR /tmp
 
-RUN wget https://phar.phpunit.de/phpunit-8.5.8.phar && \
-  mv phpunit-8.5.8.phar /usr/local/bin/phpunit && \
+RUN wget https://phar.phpunit.de/phpunit-8.5.13.phar && \
+  mv phpunit-8.5.13.phar /usr/local/bin/phpunit && \
   chmod +x /usr/local/bin/phpunit
 
 
index 5855603..90ca477 100644 (file)
@@ -23,8 +23,8 @@ ARG MAKEFLAGS=-j8
 
 WORKDIR /tmp
 
-RUN wget https://phar.phpunit.de/phpunit-8.5.8.phar && \
-  mv phpunit-8.5.8.phar /usr/local/bin/phpunit && \
+RUN wget https://phar.phpunit.de/phpunit-8.5.13.phar && \
+  mv phpunit-8.5.13.phar /usr/local/bin/phpunit && \
   chmod +x /usr/local/bin/phpunit
 
 
index 1817da1..1218e44 100644 (file)
@@ -23,8 +23,8 @@ ARG MAKEFLAGS=-j8
 
 WORKDIR /tmp
 
-RUN wget https://phar.phpunit.de/phpunit-8.5.8.phar && \
-  mv phpunit-8.5.8.phar /usr/local/bin/phpunit && \
+RUN wget https://phar.phpunit.de/phpunit-8.5.13.phar && \
+  mv phpunit-8.5.13.phar /usr/local/bin/phpunit && \
   chmod +x /usr/local/bin/phpunit
 
 
index f77e3dc..feb1b64 100644 (file)
@@ -23,8 +23,8 @@ RUN apt-get -qq update && apt-get -qq install -y \
 
 WORKDIR /tmp
 
-RUN wget https://phar.phpunit.de/phpunit-8.5.8.phar && \
-  mv phpunit-8.5.8.phar /usr/local/bin/phpunit && \
+RUN wget https://phar.phpunit.de/phpunit-8.5.13.phar && \
+  mv phpunit-8.5.13.phar /usr/local/bin/phpunit && \
   chmod +x /usr/local/bin/phpunit
 
 
index 9889645..4369568 100644 (file)
@@ -23,8 +23,8 @@ ARG MAKEFLAGS=-j8
 
 WORKDIR /tmp
 
-RUN wget https://phar.phpunit.de/phpunit-8.5.8.phar && \
-  mv phpunit-8.5.8.phar /usr/local/bin/phpunit && \
+RUN wget https://phar.phpunit.de/phpunit-8.5.13.phar && \
+  mv phpunit-8.5.13.phar /usr/local/bin/phpunit && \
   chmod +x /usr/local/bin/phpunit
 
 
index 47ab8f6..330c0d5 100644 (file)
@@ -12,7 +12,7 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-FROM php:8.0.0RC3-cli-buster
+FROM php:8.0.0-zts-buster
 
 RUN apt-get -qq update && apt-get -qq install -y \
   autoconf automake git libtool pkg-config \
@@ -29,6 +29,11 @@ RUN apt-get install expect -y && \
   expect -c 'spawn php ./go-pear.phar; expect "or Enter to continue:"; send "\n"; expect "Currently used php.ini"; send "\n"; expect eof' && \
   rm go-pear.phar
 
+RUN wget https://phar.phpunit.de/phpunit-8.5.13.phar && \
+  mv phpunit-8.5.13.phar /usr/local/bin/phpunit && \
+  chmod +x /usr/local/bin/phpunit
+
+
 WORKDIR /github/grpc
 
 COPY . .
@@ -37,4 +42,4 @@ RUN pear package && \
   find . -name grpc-*.tgz | xargs -I{} pecl install {}
 
 
-CMD php -d extension=grpc.so -r '$a = new \Grpc\Channel("dummy", []); echo get_class($a)."\n";'
+CMD ["/github/grpc/src/php/bin/run_tests.sh", "--skip-persistent-channel-tests", "--ignore-valgrind-undef-errors"]
index 360aa68..13c107d 100644 (file)
@@ -171,9 +171,7 @@ void prefork() {
 // Called at post fork
 void php_grpc_clean_persistent_list(TSRMLS_D) {
     zend_hash_clean(&grpc_persistent_list);
-    zend_hash_destroy(&grpc_persistent_list);
     zend_hash_clean(&grpc_target_upper_bound_map);
-    zend_hash_destroy(&grpc_target_upper_bound_map);
 }
 
 void postfork_child() {
index 92efe17..a06eb39 100644 (file)
@@ -20,6 +20,6 @@
 #ifndef VERSION_H
 #define VERSION_H
 
-#define PHP_GRPC_VERSION "1.34.1"
+#define PHP_GRPC_VERSION "1.35.0"
 
 #endif /* VERSION_H */
index 10f0436..c96131a 100644 (file)
Binary files a/src/php/tests/generated_code/GPBMetadata/Math.php and b/src/php/tests/generated_code/GPBMetadata/Math.php differ
index 199ccf4..6ba468e 100644 (file)
Binary files a/src/php/tests/interop/GPBMetadata/Src/Proto/Grpc/Testing/Messages.php and b/src/php/tests/interop/GPBMetadata/Src/Proto/Grpc/Testing/Messages.php differ
index f103e2e..542c18b 100644 (file)
@@ -14,9 +14,12 @@ class PBEmpty
         if (static::$is_initialized == true) {
           return;
         }
-        $pool->internalAddGeneratedFile(hex2bin(
-            "0a4a0a227372632f70726f746f2f677270632f74657374696e672f656d7074792e70726f746f120c677270632e74657374696e67220e0a0c456d7074794d657373616765620670726f746f33"
-        ), true);
+        $pool->internalAddGeneratedFile(
+            '
+J
+"src/proto/grpc/testing/empty.proto\12\fgrpc.testing"\ e
+\fEmptyMessageb\ 6proto3'
+        , true);
 
         static::$is_initialized = true;
     }
index d950b30..00b82e5 100644 (file)
Binary files a/src/php/tests/interop/GPBMetadata/Src/Proto/Grpc/Testing/Test.php and b/src/php/tests/interop/GPBMetadata/Src/Proto/Grpc/Testing/Test.php differ
diff --git a/src/php/tests/interop/Grpc/Testing/ClientConfigureRequest.php b/src/php/tests/interop/Grpc/Testing/ClientConfigureRequest.php
new file mode 100644 (file)
index 0000000..bb2b1ca
--- /dev/null
@@ -0,0 +1,101 @@
+<?php
+# Generated by the protocol buffer compiler.  DO NOT EDIT!
+# source: src/proto/grpc/testing/messages.proto
+
+namespace Grpc\Testing;
+
+use Google\Protobuf\Internal\GPBType;
+use Google\Protobuf\Internal\RepeatedField;
+use Google\Protobuf\Internal\GPBUtil;
+
+/**
+ * Configurations for a test client.
+ *
+ * Generated from protobuf message <code>grpc.testing.ClientConfigureRequest</code>
+ */
+class ClientConfigureRequest extends \Google\Protobuf\Internal\Message
+{
+    /**
+     * The types of RPCs the client sends.
+     *
+     * Generated from protobuf field <code>repeated .grpc.testing.ClientConfigureRequest.RpcType types = 1;</code>
+     */
+    private $types;
+    /**
+     * The collection of custom metadata to be attached to RPCs sent by the client.
+     *
+     * Generated from protobuf field <code>repeated .grpc.testing.ClientConfigureRequest.Metadata metadata = 2;</code>
+     */
+    private $metadata;
+
+    /**
+     * Constructor.
+     *
+     * @param array $data {
+     *     Optional. Data for populating the Message object.
+     *
+     *     @type int[]|\Google\Protobuf\Internal\RepeatedField $types
+     *           The types of RPCs the client sends.
+     *     @type \Grpc\Testing\ClientConfigureRequest\Metadata[]|\Google\Protobuf\Internal\RepeatedField $metadata
+     *           The collection of custom metadata to be attached to RPCs sent by the client.
+     * }
+     */
+    public function __construct($data = NULL) {
+        \GPBMetadata\Src\Proto\Grpc\Testing\Messages::initOnce();
+        parent::__construct($data);
+    }
+
+    /**
+     * The types of RPCs the client sends.
+     *
+     * Generated from protobuf field <code>repeated .grpc.testing.ClientConfigureRequest.RpcType types = 1;</code>
+     * @return \Google\Protobuf\Internal\RepeatedField
+     */
+    public function getTypes()
+    {
+        return $this->types;
+    }
+
+    /**
+     * The types of RPCs the client sends.
+     *
+     * Generated from protobuf field <code>repeated .grpc.testing.ClientConfigureRequest.RpcType types = 1;</code>
+     * @param int[]|\Google\Protobuf\Internal\RepeatedField $var
+     * @return $this
+     */
+    public function setTypes($var)
+    {
+        $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::ENUM, \Grpc\Testing\ClientConfigureRequest\RpcType::class);
+        $this->types = $arr;
+
+        return $this;
+    }
+
+    /**
+     * The collection of custom metadata to be attached to RPCs sent by the client.
+     *
+     * Generated from protobuf field <code>repeated .grpc.testing.ClientConfigureRequest.Metadata metadata = 2;</code>
+     * @return \Google\Protobuf\Internal\RepeatedField
+     */
+    public function getMetadata()
+    {
+        return $this->metadata;
+    }
+
+    /**
+     * The collection of custom metadata to be attached to RPCs sent by the client.
+     *
+     * Generated from protobuf field <code>repeated .grpc.testing.ClientConfigureRequest.Metadata metadata = 2;</code>
+     * @param \Grpc\Testing\ClientConfigureRequest\Metadata[]|\Google\Protobuf\Internal\RepeatedField $var
+     * @return $this
+     */
+    public function setMetadata($var)
+    {
+        $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \Grpc\Testing\ClientConfigureRequest\Metadata::class);
+        $this->metadata = $arr;
+
+        return $this;
+    }
+
+}
+
diff --git a/src/php/tests/interop/Grpc/Testing/ClientConfigureRequest/Metadata.php b/src/php/tests/interop/Grpc/Testing/ClientConfigureRequest/Metadata.php
new file mode 100644 (file)
index 0000000..2f7f63d
--- /dev/null
@@ -0,0 +1,117 @@
+<?php
+# Generated by the protocol buffer compiler.  DO NOT EDIT!
+# source: src/proto/grpc/testing/messages.proto
+
+namespace Grpc\Testing\ClientConfigureRequest;
+
+use Google\Protobuf\Internal\GPBType;
+use Google\Protobuf\Internal\RepeatedField;
+use Google\Protobuf\Internal\GPBUtil;
+
+/**
+ * Metadata to be attached for the given type of RPCs.
+ *
+ * Generated from protobuf message <code>grpc.testing.ClientConfigureRequest.Metadata</code>
+ */
+class Metadata extends \Google\Protobuf\Internal\Message
+{
+    /**
+     * Generated from protobuf field <code>.grpc.testing.ClientConfigureRequest.RpcType type = 1;</code>
+     */
+    protected $type = 0;
+    /**
+     * Generated from protobuf field <code>string key = 2;</code>
+     */
+    protected $key = '';
+    /**
+     * Generated from protobuf field <code>string value = 3;</code>
+     */
+    protected $value = '';
+
+    /**
+     * Constructor.
+     *
+     * @param array $data {
+     *     Optional. Data for populating the Message object.
+     *
+     *     @type int $type
+     *     @type string $key
+     *     @type string $value
+     * }
+     */
+    public function __construct($data = NULL) {
+        \GPBMetadata\Src\Proto\Grpc\Testing\Messages::initOnce();
+        parent::__construct($data);
+    }
+
+    /**
+     * Generated from protobuf field <code>.grpc.testing.ClientConfigureRequest.RpcType type = 1;</code>
+     * @return int
+     */
+    public function getType()
+    {
+        return $this->type;
+    }
+
+    /**
+     * Generated from protobuf field <code>.grpc.testing.ClientConfigureRequest.RpcType type = 1;</code>
+     * @param int $var
+     * @return $this
+     */
+    public function setType($var)
+    {
+        GPBUtil::checkEnum($var, \Grpc\Testing\ClientConfigureRequest\RpcType::class);
+        $this->type = $var;
+
+        return $this;
+    }
+
+    /**
+     * Generated from protobuf field <code>string key = 2;</code>
+     * @return string
+     */
+    public function getKey()
+    {
+        return $this->key;
+    }
+
+    /**
+     * Generated from protobuf field <code>string key = 2;</code>
+     * @param string $var
+     * @return $this
+     */
+    public function setKey($var)
+    {
+        GPBUtil::checkString($var, True);
+        $this->key = $var;
+
+        return $this;
+    }
+
+    /**
+     * Generated from protobuf field <code>string value = 3;</code>
+     * @return string
+     */
+    public function getValue()
+    {
+        return $this->value;
+    }
+
+    /**
+     * Generated from protobuf field <code>string value = 3;</code>
+     * @param string $var
+     * @return $this
+     */
+    public function setValue($var)
+    {
+        GPBUtil::checkString($var, True);
+        $this->value = $var;
+
+        return $this;
+    }
+
+}
+
+// Adding a class alias for backwards compatibility with the previous class name.
+class_alias(Metadata::class, \Grpc\Testing\ClientConfigureRequest_Metadata::class);
+
diff --git a/src/php/tests/interop/Grpc/Testing/ClientConfigureRequest/RpcType.php b/src/php/tests/interop/Grpc/Testing/ClientConfigureRequest/RpcType.php
new file mode 100644 (file)
index 0000000..70bf8a4
--- /dev/null
@@ -0,0 +1,53 @@
+<?php
+# Generated by the protocol buffer compiler.  DO NOT EDIT!
+# source: src/proto/grpc/testing/messages.proto
+
+namespace Grpc\Testing\ClientConfigureRequest;
+
+use UnexpectedValueException;
+
+/**
+ * Type of RPCs to send.
+ *
+ * Protobuf type <code>grpc.testing.ClientConfigureRequest.RpcType</code>
+ */
+class RpcType
+{
+    /**
+     * Generated from protobuf enum <code>EMPTY_CALL = 0;</code>
+     */
+    const EMPTY_CALL = 0;
+    /**
+     * Generated from protobuf enum <code>UNARY_CALL = 1;</code>
+     */
+    const UNARY_CALL = 1;
+
+    private static $valueToName = [
+        self::EMPTY_CALL => 'EMPTY_CALL',
+        self::UNARY_CALL => 'UNARY_CALL',
+    ];
+
+    public static function name($value)
+    {
+        if (!isset(self::$valueToName[$value])) {
+            throw new UnexpectedValueException(sprintf(
+                    'Enum %s has no name defined for value %s', __CLASS__, $value));
+        }
+        return self::$valueToName[$value];
+    }
+
+
+    public static function value($name)
+    {
+        $const = __CLASS__ . '::' . strtoupper($name);
+        if (!defined($const)) {
+            throw new UnexpectedValueException(sprintf(
+                    'Enum %s has no value defined for name %s', __CLASS__, $name));
+        }
+        return constant($const);
+    }
+}
+
+// Adding a class alias for backwards compatibility with the previous class name.
+class_alias(RpcType::class, \Grpc\Testing\ClientConfigureRequest_RpcType::class);
+
diff --git a/src/php/tests/interop/Grpc/Testing/ClientConfigureRequest_Metadata.php b/src/php/tests/interop/Grpc/Testing/ClientConfigureRequest_Metadata.php
new file mode 100644 (file)
index 0000000..543e02a
--- /dev/null
@@ -0,0 +1,16 @@
+<?php
+# Generated by the protocol buffer compiler.  DO NOT EDIT!
+# source: src/proto/grpc/testing/messages.proto
+
+namespace Grpc\Testing;
+
+if (false) {
+    /**
+     * This class is deprecated. Use Grpc\Testing\ClientConfigureRequest\Metadata instead.
+     * @deprecated
+     */
+    class ClientConfigureRequest_Metadata {}
+}
+class_exists(ClientConfigureRequest\Metadata::class);
+@trigger_error('Grpc\Testing\ClientConfigureRequest_Metadata is deprecated and will be removed in the next major release. Use Grpc\Testing\ClientConfigureRequest\Metadata instead', E_USER_DEPRECATED);
+
diff --git a/src/php/tests/interop/Grpc/Testing/ClientConfigureRequest_RpcType.php b/src/php/tests/interop/Grpc/Testing/ClientConfigureRequest_RpcType.php
new file mode 100644 (file)
index 0000000..3df15b6
--- /dev/null
@@ -0,0 +1,16 @@
+<?php
+# Generated by the protocol buffer compiler.  DO NOT EDIT!
+# source: src/proto/grpc/testing/messages.proto
+
+namespace Grpc\Testing;
+
+if (false) {
+    /**
+     * This class is deprecated. Use Grpc\Testing\ClientConfigureRequest\RpcType instead.
+     * @deprecated
+     */
+    class ClientConfigureRequest_RpcType {}
+}
+class_exists(ClientConfigureRequest\RpcType::class);
+@trigger_error('Grpc\Testing\ClientConfigureRequest_RpcType is deprecated and will be removed in the next major release. Use Grpc\Testing\ClientConfigureRequest\RpcType instead', E_USER_DEPRECATED);
+
diff --git a/src/php/tests/interop/Grpc/Testing/ClientConfigureResponse.php b/src/php/tests/interop/Grpc/Testing/ClientConfigureResponse.php
new file mode 100644 (file)
index 0000000..158121b
--- /dev/null
@@ -0,0 +1,33 @@
+<?php
+# Generated by the protocol buffer compiler.  DO NOT EDIT!
+# source: src/proto/grpc/testing/messages.proto
+
+namespace Grpc\Testing;
+
+use Google\Protobuf\Internal\GPBType;
+use Google\Protobuf\Internal\RepeatedField;
+use Google\Protobuf\Internal\GPBUtil;
+
+/**
+ * Response for updating a test client's configuration.
+ *
+ * Generated from protobuf message <code>grpc.testing.ClientConfigureResponse</code>
+ */
+class ClientConfigureResponse extends \Google\Protobuf\Internal\Message
+{
+
+    /**
+     * Constructor.
+     *
+     * @param array $data {
+     *     Optional. Data for populating the Message object.
+     *
+     * }
+     */
+    public function __construct($data = NULL) {
+        \GPBMetadata\Src\Proto\Grpc\Testing\Messages::initOnce();
+        parent::__construct($data);
+    }
+
+}
+
diff --git a/src/php/tests/interop/Grpc/Testing/LoadBalancerAccumulatedStatsRequest.php b/src/php/tests/interop/Grpc/Testing/LoadBalancerAccumulatedStatsRequest.php
new file mode 100644 (file)
index 0000000..23f20eb
--- /dev/null
@@ -0,0 +1,33 @@
+<?php
+# Generated by the protocol buffer compiler.  DO NOT EDIT!
+# source: src/proto/grpc/testing/messages.proto
+
+namespace Grpc\Testing;
+
+use Google\Protobuf\Internal\GPBType;
+use Google\Protobuf\Internal\RepeatedField;
+use Google\Protobuf\Internal\GPBUtil;
+
+/**
+ * Request for retrieving a test client's accumulated stats.
+ *
+ * Generated from protobuf message <code>grpc.testing.LoadBalancerAccumulatedStatsRequest</code>
+ */
+class LoadBalancerAccumulatedStatsRequest extends \Google\Protobuf\Internal\Message
+{
+
+    /**
+     * Constructor.
+     *
+     * @param array $data {
+     *     Optional. Data for populating the Message object.
+     *
+     * }
+     */
+    public function __construct($data = NULL) {
+        \GPBMetadata\Src\Proto\Grpc\Testing\Messages::initOnce();
+        parent::__construct($data);
+    }
+
+}
+
diff --git a/src/php/tests/interop/Grpc/Testing/LoadBalancerAccumulatedStatsResponse.php b/src/php/tests/interop/Grpc/Testing/LoadBalancerAccumulatedStatsResponse.php
new file mode 100644 (file)
index 0000000..ddd2c43
--- /dev/null
@@ -0,0 +1,135 @@
+<?php
+# Generated by the protocol buffer compiler.  DO NOT EDIT!
+# source: src/proto/grpc/testing/messages.proto
+
+namespace Grpc\Testing;
+
+use Google\Protobuf\Internal\GPBType;
+use Google\Protobuf\Internal\RepeatedField;
+use Google\Protobuf\Internal\GPBUtil;
+
+/**
+ * Accumulated stats for RPCs sent by a test client.
+ *
+ * Generated from protobuf message <code>grpc.testing.LoadBalancerAccumulatedStatsResponse</code>
+ */
+class LoadBalancerAccumulatedStatsResponse extends \Google\Protobuf\Internal\Message
+{
+    /**
+     * The total number of RPCs have ever issued for each type.
+     *
+     * Generated from protobuf field <code>map<string, int32> num_rpcs_started_by_method = 1;</code>
+     */
+    private $num_rpcs_started_by_method;
+    /**
+     * The total number of RPCs have ever completed successfully for each type.
+     *
+     * Generated from protobuf field <code>map<string, int32> num_rpcs_succeeded_by_method = 2;</code>
+     */
+    private $num_rpcs_succeeded_by_method;
+    /**
+     * The total number of RPCs have ever failed for each type.
+     *
+     * Generated from protobuf field <code>map<string, int32> num_rpcs_failed_by_method = 3;</code>
+     */
+    private $num_rpcs_failed_by_method;
+
+    /**
+     * Constructor.
+     *
+     * @param array $data {
+     *     Optional. Data for populating the Message object.
+     *
+     *     @type array|\Google\Protobuf\Internal\MapField $num_rpcs_started_by_method
+     *           The total number of RPCs have ever issued for each type.
+     *     @type array|\Google\Protobuf\Internal\MapField $num_rpcs_succeeded_by_method
+     *           The total number of RPCs have ever completed successfully for each type.
+     *     @type array|\Google\Protobuf\Internal\MapField $num_rpcs_failed_by_method
+     *           The total number of RPCs have ever failed for each type.
+     * }
+     */
+    public function __construct($data = NULL) {
+        \GPBMetadata\Src\Proto\Grpc\Testing\Messages::initOnce();
+        parent::__construct($data);
+    }
+
+    /**
+     * The total number of RPCs have ever issued for each type.
+     *
+     * Generated from protobuf field <code>map<string, int32> num_rpcs_started_by_method = 1;</code>
+     * @return \Google\Protobuf\Internal\MapField
+     */
+    public function getNumRpcsStartedByMethod()
+    {
+        return $this->num_rpcs_started_by_method;
+    }
+
+    /**
+     * The total number of RPCs have ever issued for each type.
+     *
+     * Generated from protobuf field <code>map<string, int32> num_rpcs_started_by_method = 1;</code>
+     * @param array|\Google\Protobuf\Internal\MapField $var
+     * @return $this
+     */
+    public function setNumRpcsStartedByMethod($var)
+    {
+        $arr = GPBUtil::checkMapField($var, \Google\Protobuf\Internal\GPBType::STRING, \Google\Protobuf\Internal\GPBType::INT32);
+        $this->num_rpcs_started_by_method = $arr;
+
+        return $this;
+    }
+
+    /**
+     * The total number of RPCs have ever completed successfully for each type.
+     *
+     * Generated from protobuf field <code>map<string, int32> num_rpcs_succeeded_by_method = 2;</code>
+     * @return \Google\Protobuf\Internal\MapField
+     */
+    public function getNumRpcsSucceededByMethod()
+    {
+        return $this->num_rpcs_succeeded_by_method;
+    }
+
+    /**
+     * The total number of RPCs have ever completed successfully for each type.
+     *
+     * Generated from protobuf field <code>map<string, int32> num_rpcs_succeeded_by_method = 2;</code>
+     * @param array|\Google\Protobuf\Internal\MapField $var
+     * @return $this
+     */
+    public function setNumRpcsSucceededByMethod($var)
+    {
+        $arr = GPBUtil::checkMapField($var, \Google\Protobuf\Internal\GPBType::STRING, \Google\Protobuf\Internal\GPBType::INT32);
+        $this->num_rpcs_succeeded_by_method = $arr;
+
+        return $this;
+    }
+
+    /**
+     * The total number of RPCs have ever failed for each type.
+     *
+     * Generated from protobuf field <code>map<string, int32> num_rpcs_failed_by_method = 3;</code>
+     * @return \Google\Protobuf\Internal\MapField
+     */
+    public function getNumRpcsFailedByMethod()
+    {
+        return $this->num_rpcs_failed_by_method;
+    }
+
+    /**
+     * The total number of RPCs have ever failed for each type.
+     *
+     * Generated from protobuf field <code>map<string, int32> num_rpcs_failed_by_method = 3;</code>
+     * @param array|\Google\Protobuf\Internal\MapField $var
+     * @return $this
+     */
+    public function setNumRpcsFailedByMethod($var)
+    {
+        $arr = GPBUtil::checkMapField($var, \Google\Protobuf\Internal\GPBType::STRING, \Google\Protobuf\Internal\GPBType::INT32);
+        $this->num_rpcs_failed_by_method = $arr;
+
+        return $this;
+    }
+
+}
+
index 3b23ff6..f347d76 100644 (file)
@@ -50,4 +50,19 @@ class LoadBalancerStatsServiceClient extends \Grpc\BaseStub {
         $metadata, $options);
     }
 
+    /**
+     * Gets the accumulated stats for RPCs sent by a test client.
+     * @param \Grpc\Testing\LoadBalancerAccumulatedStatsRequest $argument input argument
+     * @param array $metadata metadata
+     * @param array $options call options
+     * @return \Grpc\UnaryCall
+     */
+    public function GetClientAccumulatedStats(\Grpc\Testing\LoadBalancerAccumulatedStatsRequest $argument,
+      $metadata = [], $options = []) {
+        return $this->_simpleRequest('/grpc.testing.LoadBalancerStatsService/GetClientAccumulatedStats',
+        $argument,
+        ['\Grpc\Testing\LoadBalancerAccumulatedStatsResponse', 'decode'],
+        $metadata, $options);
+    }
+
 }
diff --git a/src/php/tests/interop/Grpc/Testing/XdsUpdateClientConfigureServiceClient.php b/src/php/tests/interop/Grpc/Testing/XdsUpdateClientConfigureServiceClient.php
new file mode 100644 (file)
index 0000000..4c650af
--- /dev/null
@@ -0,0 +1,53 @@
+<?php
+// GENERATED CODE -- DO NOT EDIT!
+
+// Original file comments:
+// 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.
+//
+// An integration test service that covers all the method signature permutations
+// of unary/streaming requests/responses.
+//
+namespace Grpc\Testing;
+
+/**
+ * A service to dynamically update the configuration of an xDS test client.
+ */
+class XdsUpdateClientConfigureServiceClient extends \Grpc\BaseStub {
+
+    /**
+     * @param string $hostname hostname
+     * @param array $opts channel options
+     * @param \Grpc\Channel $channel (optional) re-use channel object
+     */
+    public function __construct($hostname, $opts, $channel = null) {
+        parent::__construct($hostname, $opts, $channel);
+    }
+
+    /**
+     * Update the tes client's configuration.
+     * @param \Grpc\Testing\ClientConfigureRequest $argument input argument
+     * @param array $metadata metadata
+     * @param array $options call options
+     * @return \Grpc\UnaryCall
+     */
+    public function Configure(\Grpc\Testing\ClientConfigureRequest $argument,
+      $metadata = [], $options = []) {
+        return $this->_simpleRequest('/grpc.testing.XdsUpdateClientConfigureService/Configure',
+        $argument,
+        ['\Grpc\Testing\ClientConfigureResponse', 'decode'],
+        $metadata, $options);
+    }
+
+}
index a88a268..42bf480 100644 (file)
@@ -138,21 +138,17 @@ class CallCredentialsTest extends \PHPUnit\Framework\TestCase
                           get_class($call_credentials3));
     }
 
-    /**
-     * @expectedException InvalidArgumentException
-     */
     public function testCreateFromPluginInvalidParam()
     {
+        $this->expectException(\InvalidArgumentException::class);
         $call_credentials = Grpc\CallCredentials::createFromPlugin(
             'callbackFunc'
         );
     }
 
-    /**
-     * @expectedException InvalidArgumentException
-     */
     public function testCreateCompositeInvalidParam()
     {
+        $this->expectException(\InvalidArgumentException::class);
         $call_credentials3 = Grpc\CallCredentials::createComposite(
             $this->call_credentials,
             $this->credentials
index 300d805..4663695 100644 (file)
@@ -176,11 +176,13 @@ class CallInvokerTest extends \PHPUnit\Framework\TestCase
     public function testCreateDefaultCallInvoker()
     {
         $call_invoker = new \Grpc\DefaultCallInvoker();
+        $this->assertNotNull($call_invoker);
     }
 
     public function testCreateCallInvoker()
     {
         $call_invoker = new CallInvokerUpdateChannel();
+        $this->assertNotNull($call_invoker);
     }
 
     public function testCallInvokerAccessChannel()
index 4d1be1b..8bb8c1e 100644 (file)
@@ -107,81 +107,65 @@ class CallTest extends \PHPUnit\Framework\TestCase
         $this->assertNull($this->call->cancel());
     }
 
-    /**
-     * @expectedException InvalidArgumentException
-     */
     public function testInvalidStartBatchKey()
     {
+        $this->expectException(\InvalidArgumentException::class);
         $batch = [
             'invalid' => ['key1' => 'value1'],
         ];
         $result = $this->call->startBatch($batch);
     }
 
-    /**
-     * @expectedException InvalidArgumentException
-     */
     public function testInvalidMetadataStrKey()
     {
+        $this->expectException(\InvalidArgumentException::class);
         $batch = [
             Grpc\OP_SEND_INITIAL_METADATA => ['Key' => ['value1', 'value2']],
         ];
         $result = $this->call->startBatch($batch);
     }
 
-    /**
-     * @expectedException InvalidArgumentException
-     */
     public function testInvalidMetadataIntKey()
     {
+        $this->expectException(\InvalidArgumentException::class);
         $batch = [
             Grpc\OP_SEND_INITIAL_METADATA => [1 => ['value1', 'value2']],
         ];
         $result = $this->call->startBatch($batch);
     }
 
-    /**
-     * @expectedException InvalidArgumentException
-     */
     public function testInvalidMetadataInnerValue()
     {
+        $this->expectException(\InvalidArgumentException::class);
         $batch = [
             Grpc\OP_SEND_INITIAL_METADATA => ['key1' => 'value1'],
         ];
         $result = $this->call->startBatch($batch);
     }
 
-    /**
-     * @expectedException InvalidArgumentException
-     */
     public function testInvalidConstuctor()
     {
+        $this->expectException(\InvalidArgumentException::class);
         $this->call = new Grpc\Call();
         $this->assertNull($this->call);
     }
 
-    /**
-     * @expectedException InvalidArgumentException
-     */
     public function testInvalidConstuctor2()
     {
+        $this->expectException(\InvalidArgumentException::class);
         $this->call = new Grpc\Call('hi', 'hi', 'hi');
         $this->assertNull($this->call);
     }
 
-    /**
-     * @expectedException InvalidArgumentException
-     */
     public function testInvalidSetCredentials()
     {
+        $this->expectException(\InvalidArgumentException::class);
         $this->call->setCredentials('hi');
     }
 
-    /**
-     * @expectedException InvalidArgumentException
-     */
     public function testInvalidSetCredentials2()
     {
+        $this->expectException(\InvalidArgumentException::class);
         $this->call->setCredentials([]);
     }
 }
index 73963ce..ed61f3e 100644 (file)
@@ -56,19 +56,15 @@ class ChanellCredentialsTest extends \PHPUnit\Framework\TestCase
         $this->assertTrue(Grpc\ChannelCredentials::isDefaultRootsPemSet());
     }
 
-    /**
-     * @expectedException InvalidArgumentException
-     */
     public function testInvalidCreateSsl()
     {
+        $this->expectException(\InvalidArgumentException::class);
         $channel_credentials = Grpc\ChannelCredentials::createSsl([]);
     }
 
-    /**
-     * @expectedException InvalidArgumentException
-     */
     public function testInvalidCreateComposite()
     {
+        $this->expectException(\InvalidArgumentException::class);
         $channel_credentials = Grpc\ChannelCredentials::createComposite(
             'something', 'something');
     }
index 8ae3945..6c05440 100644 (file)
@@ -39,8 +39,9 @@ class ChannelTest extends \PHPUnit\Framework\TestCase
 
     public function testConstructorCreateSsl()
     {
-        new Grpc\Channel('localhost:50033', 
+        $channel = new Grpc\Channel('localhost:50033', 
             ['credentials' => \Grpc\ChannelCredentials::createSsl()]);
+        $this->assertNotNull($channel);
     }
 
     public function testGetConnectivityState()
@@ -105,67 +106,53 @@ class ChannelTest extends \PHPUnit\Framework\TestCase
         $this->channel->close();
     }
 
-    /**
-     * @expectedException InvalidArgumentException
-     */
     public function testInvalidConstructorWithNull()
     {
+        $this->expectException(\InvalidArgumentException::class);
         $this->channel = new Grpc\Channel();
         $this->assertNull($this->channel);
     }
 
-    /**
-     * @expectedException InvalidArgumentException
-     */
     public function testInvalidConstructorWith()
     {
+        $this->expectException(\InvalidArgumentException::class);
         $this->channel = new Grpc\Channel('localhost:50008', 'invalid');
         $this->assertNull($this->channel);
     }
 
-    /**
-     * @expectedException InvalidArgumentException
-     */
     public function testInvalidCredentials()
     {
+        $this->expectException(\InvalidArgumentException::class);
         $this->channel = new Grpc\Channel('localhost:50009',
             ['credentials' => new Grpc\Timeval(100)]);
     }
 
-    /**
-     * @expectedException InvalidArgumentException
-     */
     public function testInvalidOptionsArray()
     {
+        $this->expectException(\InvalidArgumentException::class);
         $this->channel = new Grpc\Channel('localhost:50010',
             ['abc' => []]);
     }
 
-    /**
-     * @expectedException InvalidArgumentException
-     */
     public function testInvalidGetConnectivityStateWithArray()
     {
+        $this->expectException(\InvalidArgumentException::class);
         $this->channel = new Grpc\Channel('localhost:50011',
             ['credentials' => Grpc\ChannelCredentials::createInsecure()]);
         $this->channel->getConnectivityState([]);
     }
 
-    /**
-     * @expectedException InvalidArgumentException
-     */
     public function testInvalidWatchConnectivityState()
     {
+        $this->expectException(\InvalidArgumentException::class);
         $this->channel = new Grpc\Channel('localhost:50012',
             ['credentials' => Grpc\ChannelCredentials::createInsecure()]);
         $this->channel->watchConnectivityState([]);
     }
 
-    /**
-     * @expectedException InvalidArgumentException
-     */
     public function testInvalidWatchConnectivityState2()
     {
+        $this->expectException(\InvalidArgumentException::class);
         $this->channel = new Grpc\Channel('localhost:50013',
             ['credentials' => Grpc\ChannelCredentials::createInsecure()]);
         $this->channel->watchConnectivityState(1, 'hi');
@@ -409,11 +396,9 @@ class ChannelTest extends \PHPUnit\Framework\TestCase
         $this->assertEquals(GRPC\CHANNEL_IDLE, $state);
     }
 
-    /**
-     * @expectedException RuntimeException
-     */
     public function testPersistentChannelSharedChannelClose2()
     {
+        $this->expectException(\RuntimeException::class);
         // same underlying channel
         $this->channel1 = new Grpc\Channel('localhost:50223', [
             "grpc_target_persist_bound" => 3,
@@ -645,12 +630,9 @@ class ChannelTest extends \PHPUnit\Framework\TestCase
         $this->assertEquals(GRPC\CHANNEL_IDLE, $state);
     }
 
-    /**
-     * @expectedException RuntimeException
-     */
     public function testPersistentChannelForceNewOldChannelClose2()
     {
-
+        $this->expectException(\RuntimeException::class);
         $this->channel1 = new Grpc\Channel('localhost:50230', [
             "grpc_target_persist_bound" => 2,
         ]);
index 08b28e0..700da87 100644 (file)
@@ -188,11 +188,9 @@ class EndToEndTest extends \PHPUnit\Framework\TestCase
         unset($server_call);
     }
 
-    /**
-     * @expectedException InvalidArgumentException
-     */
     public function testInvalidClientMessageArray()
     {
+        $this->expectException(\InvalidArgumentException::class);
         $deadline = Grpc\Timeval::infFuture();
         $req_text = 'client_server_full_request_response';
         $reply_text = 'reply:client_server_full_request_response';
@@ -209,11 +207,9 @@ class EndToEndTest extends \PHPUnit\Framework\TestCase
         ]);
     }
 
-    /**
-     * @expectedException InvalidArgumentException
-     */
     public function testInvalidClientMessageString()
     {
+        $this->expectException(\InvalidArgumentException::class);
         $deadline = Grpc\Timeval::infFuture();
         $req_text = 'client_server_full_request_response';
         $reply_text = 'reply:client_server_full_request_response';
@@ -230,11 +226,9 @@ class EndToEndTest extends \PHPUnit\Framework\TestCase
         ]);
     }
 
-    /**
-     * @expectedException InvalidArgumentException
-     */
     public function testInvalidClientMessageFlags()
     {
+        $this->expectException(\InvalidArgumentException::class);
         $deadline = Grpc\Timeval::infFuture();
         $req_text = 'client_server_full_request_response';
         $reply_text = 'reply:client_server_full_request_response';
@@ -253,11 +247,9 @@ class EndToEndTest extends \PHPUnit\Framework\TestCase
         ]);
     }
 
-    /**
-     * @expectedException InvalidArgumentException
-     */
     public function testInvalidServerStatusMetadata()
     {
+        $this->expectException(\InvalidArgumentException::class);
         $deadline = Grpc\Timeval::infFuture();
         $req_text = 'client_server_full_request_response';
         $reply_text = 'reply:client_server_full_request_response';
@@ -294,11 +286,9 @@ class EndToEndTest extends \PHPUnit\Framework\TestCase
         ]);
     }
 
-    /**
-     * @expectedException InvalidArgumentException
-     */
     public function testInvalidServerStatusCode()
     {
+        $this->expectException(\InvalidArgumentException::class);
         $deadline = Grpc\Timeval::infFuture();
         $req_text = 'client_server_full_request_response';
         $reply_text = 'reply:client_server_full_request_response';
@@ -335,11 +325,9 @@ class EndToEndTest extends \PHPUnit\Framework\TestCase
         ]);
     }
 
-    /**
-     * @expectedException InvalidArgumentException
-     */
     public function testMissingServerStatusCode()
     {
+        $this->expectException(\InvalidArgumentException::class);
         $deadline = Grpc\Timeval::infFuture();
         $req_text = 'client_server_full_request_response';
         $reply_text = 'reply:client_server_full_request_response';
@@ -375,11 +363,9 @@ class EndToEndTest extends \PHPUnit\Framework\TestCase
         ]);
     }
 
-    /**
-     * @expectedException InvalidArgumentException
-     */
     public function testInvalidServerStatusDetails()
     {
+        $this->expectException(\InvalidArgumentException::class);
         $deadline = Grpc\Timeval::infFuture();
         $req_text = 'client_server_full_request_response';
         $reply_text = 'reply:client_server_full_request_response';
@@ -416,11 +402,9 @@ class EndToEndTest extends \PHPUnit\Framework\TestCase
         ]);
     }
 
-    /**
-     * @expectedException InvalidArgumentException
-     */
     public function testMissingServerStatusDetails()
     {
+        $this->expectException(\InvalidArgumentException::class);
         $deadline = Grpc\Timeval::infFuture();
         $req_text = 'client_server_full_request_response';
         $reply_text = 'reply:client_server_full_request_response';
@@ -456,11 +440,9 @@ class EndToEndTest extends \PHPUnit\Framework\TestCase
         ]);
     }
 
-    /**
-     * @expectedException InvalidArgumentException
-     */
     public function testInvalidStartBatchKey()
     {
+        $this->expectException(\InvalidArgumentException::class);
         $deadline = Grpc\Timeval::infFuture();
         $req_text = 'client_server_full_request_response';
         $reply_text = 'reply:client_server_full_request_response';
@@ -475,11 +457,9 @@ class EndToEndTest extends \PHPUnit\Framework\TestCase
         ]);
     }
 
-    /**
-     * @expectedException LogicException
-     */
     public function testInvalidStartBatch()
     {
+        $this->expectException(\LogicException::class);
         $deadline = Grpc\Timeval::infFuture();
         $req_text = 'client_server_full_request_response';
         $reply_text = 'reply:client_server_full_request_response';
@@ -557,29 +537,23 @@ class EndToEndTest extends \PHPUnit\Framework\TestCase
         $this->assertTrue($new_state == Grpc\CHANNEL_IDLE);
     }
 
-    /**
-     * @expectedException InvalidArgumentException
-     */
     public function testGetConnectivityStateInvalidParam()
     {
+        $this->expectException(\InvalidArgumentException::class);
         $this->assertTrue($this->channel->getConnectivityState(
             new Grpc\Timeval()));
     }
 
-    /**
-     * @expectedException InvalidArgumentException
-     */
     public function testWatchConnectivityStateInvalidParam()
     {
+        $this->expectException(\InvalidArgumentException::class);
         $this->assertTrue($this->channel->watchConnectivityState(
             0, 1000));
     }
 
-    /**
-     * @expectedException InvalidArgumentException
-     */
     public function testChannelConstructorInvalidParam()
     {
+        $this->expectException(\InvalidArgumentException::class);
         $this->channel = new Grpc\Channel('localhost:'.$this->port, null);
     }
 
index f10daeb..46c9d61 100644 (file)
@@ -167,13 +167,11 @@ class PersistentListTest extends \PHPUnit\Framework\TestCase
       $this->channel2->close();
   }
 
-  /**
-   * @expectedException RuntimeException
-   * @expectedExceptionMessage startBatch Error. Channel is closed
-   */
   public function testPersistentChannelSharedChannelClose()
   {
-      // same underlying channel
+    $this->expectException(\RuntimeException::class);
+    $this->expectExceptionMessage("startBatch Error. Channel is closed");
+    // same underlying channel
       $this->channel1 = new Grpc\Channel('localhost:10001', [
           "grpc_target_persist_bound" => 2,
       ]);
index b29a6b0..d0d6d25 100644 (file)
@@ -90,65 +90,52 @@ class ServerTest extends \PHPUnit\Framework\TestCase
         return $server_credentials;
     }
 
-    /**
-     * @expectedException InvalidArgumentException
-     */
     public function testInvalidConstructor()
     {
+        $this->expectException(\InvalidArgumentException::class);
         $this->server = new Grpc\Server('invalid_host');
         $this->assertNull($this->server);
     }
 
-    /**
-     * @expectedException InvalidArgumentException
-     */
     public function testInvalidConstructorWithNumKeyOfArray()
     {
+        $this->expectException(\InvalidArgumentException::class);
         $this->server = new Grpc\Server([10 => '127.0.0.1',
                                          20 => '8080', ]);
         $this->assertNull($this->server);
     }
 
-    /**
-     * @expectedException InvalidArgumentException
-     */
     public function testInvalidConstructorWithList()
     {
+        $this->expectException(\InvalidArgumentException::class);
         $this->server = new Grpc\Server(['127.0.0.1', '8080']);
         $this->assertNull($this->server);
     }
-    /**
-     * @expectedException InvalidArgumentException
-     */
+
     public function testInvalidAddHttp2Port()
     {
+        $this->expectException(\InvalidArgumentException::class);
         $this->server = new Grpc\Server([]);
         $port = $this->server->addHttp2Port(['0.0.0.0:0']);
     }
 
-    /**
-     * @expectedException InvalidArgumentException
-     */
     public function testInvalidAddSecureHttp2Port()
     {
+        $this->expectException(\InvalidArgumentException::class);
         $this->server = new Grpc\Server([]);
         $port = $this->server->addSecureHttp2Port(['0.0.0.0:0']);
     }
 
-    /**
-     * @expectedException InvalidArgumentException
-     */
     public function testInvalidAddSecureHttp2Port2()
     {
+        $this->expectException(\InvalidArgumentException::class);
         $this->server = new Grpc\Server();
         $port = $this->server->addSecureHttp2Port('0.0.0.0:0');
     }
 
-    /**
-     * @expectedException InvalidArgumentException
-     */
     public function testInvalidAddSecureHttp2Port3()
     {
+        $this->expectException(\InvalidArgumentException::class);
         $this->server = new Grpc\Server();
         $port = $this->server->addSecureHttp2Port('0.0.0.0:0', 'invalid');
     }
index 1a52508..a046f00 100644 (file)
@@ -185,45 +185,35 @@ class TimevalTest extends \PHPUnit\Framework\TestCase
         $this->assertTrue(($done_microtime - $curr_microtime) > 0.0009);
     }
 
-    /**
-     * @expectedException InvalidArgumentException
-     */
     public function testConstructorInvalidParam()
     {
+        $this->expectException(\InvalidArgumentException::class);
         $delta = new Grpc\Timeval('abc');
     }
 
-    /**
-     * @expectedException InvalidArgumentException
-     */
     public function testAddInvalidParam()
     {
+        $this->expectException(\InvalidArgumentException::class);
         $a = Grpc\Timeval::now();
         $a->add(1000);
     }
 
-    /**
-     * @expectedException InvalidArgumentException
-     */
     public function testSubtractInvalidParam()
     {
+        $this->expectException(\InvalidArgumentException::class);
         $a = Grpc\Timeval::now();
         $a->subtract(1000);
     }
 
-    /**
-     * @expectedException InvalidArgumentException
-     */
     public function testCompareInvalidParam()
     {
+        $this->expectException(\InvalidArgumentException::class);
         $a = Grpc\Timeval::compare(1000, 1100);
     }
 
-    /**
-     * @expectedException InvalidArgumentException
-     */
     public function testSimilarInvalidParam()
     {
+        $this->expectException(\InvalidArgumentException::class);
         $a = Grpc\Timeval::similar(1000, 1100, 1200);
         $this->assertNull($delta);
     }
index 62e2813..1bcfa4b 100644 (file)
@@ -83,6 +83,7 @@ grpc_proto_library(
     ],
     well_known_protos = True,
     deps = [
+        "base_proto",
         "config_source_proto",
     ],
 )
@@ -187,3 +188,25 @@ grpc_proto_library(
         "route_proto",
     ],
 )
+
+grpc_proto_library(
+    name = "string_proto",
+    srcs = [
+        "string.proto",
+    ],
+    well_known_protos = True,
+    deps = [
+        "regex_proto",
+    ],
+)
+
+grpc_proto_library(
+    name = "tls_proto",
+    srcs = [
+        "tls.proto",
+    ],
+    well_known_protos = True,
+    deps = [
+        "string_proto",
+    ],
+)
index acecdda..b5acb09 100644 (file)
@@ -20,6 +20,7 @@ package envoy.config.core.v3;
 
 import "src/proto/grpc/testing/xds/v3/percent.proto";
 
+import "google/protobuf/any.proto";
 import "google/protobuf/struct.proto";
 
 // Identifies location of where either Envoy runs or where upstream hosts run.
@@ -109,3 +110,19 @@ message RuntimeFractionalPercent {
   // Default value if the runtime value's for the numerator/denominator keys are not available.
   type.v3.FractionalPercent default_value = 1;
 }
+
+// Configuration for transport socket in :ref:`listeners <config_listeners>` and
+// :ref:`clusters <envoy_api_msg_config.cluster.v3.Cluster>`. If the configuration is
+// empty, a default transport socket implementation and configuration will be
+// chosen based on the platform and existence of tls_context.
+message TransportSocket {
+  // The name of the transport socket to instantiate. The name must match a supported transport
+  // socket implementation.
+  string name = 1;
+
+  // Implementation specific configuration which depends on the implementation being instantiated.
+  // See the supported transport socket implementations for further documentation.
+  oneof config_type {
+    google.protobuf.Any typed_config = 3;
+  }
+}
index c20d887..c493e86 100644 (file)
@@ -18,6 +18,7 @@ syntax = "proto3";
 
 package envoy.config.cluster.v3;
 
+import "src/proto/grpc/testing/xds/v3/base.proto";
 import "src/proto/grpc/testing/xds/v3/config_source.proto";
 
 import "google/protobuf/wrappers.proto";
@@ -144,6 +145,13 @@ message Cluster {
 
   CircuitBreakers circuit_breakers = 10;
 
+  // Optional custom transport socket implementation to use for upstream connections.
+  // To setup TLS, set a transport socket with name `tls` and
+  // :ref:`UpstreamTlsContexts <envoy_api_msg_extensions.transport_sockets.tls.v3.UpstreamTlsContext>` in the `typed_config`.
+  // If no transport socket configuration is specified, new connections
+  // will be set up with plaintext.
+  core.v3.TransportSocket transport_socket = 24;
+
   // [#not-implemented-hide:]
   // If present, tells the client where to send load reports via LRS. If not present, the
   // client will fall back to a client-side default, which may be either (a) don't send any
diff --git a/src/proto/grpc/testing/xds/v3/string.proto b/src/proto/grpc/testing/xds/v3/string.proto
new file mode 100644 (file)
index 0000000..d7e7730
--- /dev/null
@@ -0,0 +1,64 @@
+// Copyright 2020 The 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.
+
+// Local copy of Envoy xDS proto file, used for testing only.
+
+syntax = "proto3";
+
+package envoy.type.matcher.v3;
+
+import "src/proto/grpc/testing/xds/v3/regex.proto";
+
+message StringMatcher {
+  oneof match_pattern {
+    // The input string must match exactly the string specified here.
+    //
+    // Examples:
+    //
+    // * *abc* only matches the value *abc*.
+    string exact = 1;
+
+    // The input string must have the prefix specified here.
+    // Note: empty prefix is not allowed, please use regex instead.
+    //
+    // Examples:
+    //
+    // * *abc* matches the value *abc.xyz*
+    string prefix = 2;
+
+    // The input string must have the suffix specified here.
+    // Note: empty prefix is not allowed, please use regex instead.
+    //
+    // Examples:
+    //
+    // * *abc* matches the value *xyz.abc*
+    string suffix = 3;
+
+    // The input string must match the regular expression specified here.
+    RegexMatcher safe_regex = 5;
+
+    // The input string must have the substring specified here.
+    // Note: empty contains match is not allowed, please use regex instead.
+    //
+    // Examples:
+    //
+    // * *abc* matches the value *xyz.abc.def*
+    string contains = 7;
+  }
+
+  // If true, indicates the exact/prefix/suffix matching should be case insensitive. This has no
+  // effect for the safe_regex match.
+  // For example, the matcher *data* will match both input string *Data* and *data* if set to true.
+  bool ignore_case = 6;
+}
diff --git a/src/proto/grpc/testing/xds/v3/tls.proto b/src/proto/grpc/testing/xds/v3/tls.proto
new file mode 100644 (file)
index 0000000..47db0a0
--- /dev/null
@@ -0,0 +1,102 @@
+// Copyright 2020 The 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.
+
+// Local copy of Envoy xDS proto file, used for testing only.
+
+syntax = "proto3";
+
+package envoy.extensions.transport_sockets.tls.v3;
+
+import "src/proto/grpc/testing/xds/v3/string.proto";
+
+message CertificateValidationContext {
+  // An optional list of Subject Alternative name matchers. If specified, Envoy will verify that the
+  // Subject Alternative Name of the presented certificate matches one of the specified matchers.
+  //
+  // When a certificate has wildcard DNS SAN entries, to match a specific client, it should be
+  // configured with exact match type in the :ref:`string matcher <envoy_api_msg_type.matcher.v3.StringMatcher>`.
+  // For example if the certificate has "\*.example.com" as DNS SAN entry, to allow only "api.example.com",
+  // it should be configured as shown below.
+  //
+  // .. code-block:: yaml
+  //
+  //  match_subject_alt_names:
+  //    exact: "api.example.com"
+  //
+  // .. attention::
+  //
+  //   Subject Alternative Names are easily spoofable and verifying only them is insecure,
+  //   therefore this option must be used together with :ref:`trusted_ca
+  //   <envoy_api_field_extensions.transport_sockets.tls.v3.CertificateValidationContext.trusted_ca>`.
+  repeated type.matcher.v3.StringMatcher match_subject_alt_names = 9;
+}
+
+message UpstreamTlsContext {
+  // Common TLS context settings.
+  //
+  // .. attention::
+  //
+  //   Server certificate verification is not enabled by default. Configure
+  //   :ref:`trusted_ca<envoy_api_field_extensions.transport_sockets.tls.v3.CertificateValidationContext.trusted_ca>` to enable
+  //   verification.
+  CommonTlsContext common_tls_context = 1;
+}
+
+// TLS context shared by both client and server TLS contexts.
+// [#next-free-field: 14]
+message CommonTlsContext {
+  // Similar to CertificateProvider above, but allows the provider instances to be configured on
+  // the client side instead of being sent from the control plane.
+  message CertificateProviderInstance {
+    // Provider instance name. This name must be defined in the client's configuration (e.g., a
+    // bootstrap file) to correspond to a provider instance (i.e., the same data in the typed_config
+    // field that would be sent in the CertificateProvider message if the config was sent by the
+    // control plane). If not present, defaults to "default".
+    //
+    // Instance names should generally be defined not in terms of the underlying provider
+    // implementation (e.g., "file_watcher") but rather in terms of the function of the
+    // certificates (e.g., "foo_deployment_identity").
+    string instance_name = 1;
+
+    // Opaque name used to specify certificate instances or types. For example, "ROOTCA" to specify
+    // a root-certificate (validation context) or "example.com" to specify a certificate for a
+    // particular domain. Not all provider instances will actually use this field, so the value
+    // defaults to the empty string.
+    string certificate_name = 2;
+  }
+
+  message CombinedCertificateValidationContext {
+    // How to validate peer certificates.
+    CertificateValidationContext default_validation_context = 1;
+
+    // Certificate provider instance for fetching validation context.
+    // Only one of validation_context_sds_secret_config, validation_context_certificate_provider,
+    // or validation_context_certificate_provider_instance may be used.
+    CertificateProviderInstance validation_context_certificate_provider_instance = 4;
+  }
+
+  // Certificate provider instance for fetching TLS certificates.
+  CertificateProviderInstance tls_certificate_certificate_provider_instance = 11;
+
+  oneof validation_context_type {
+    // Combined certificate validation context holds a default CertificateValidationContext
+    // and SDS config. When SDS server returns dynamic CertificateValidationContext, both dynamic
+    // and default CertificateValidationContext are merged into a new CertificateValidationContext
+    // for validation. This merge is done by Message::MergeFrom(), so dynamic
+    // CertificateValidationContext overwrites singular fields in default
+    // CertificateValidationContext, and concatenates repeated fields to default
+    // CertificateValidationContext, and logical OR is applied to boolean fields.
+    CombinedCertificateValidationContext combined_validation_context = 8;
+  }
+}
index 10c024e..2c2a3ff 100644 (file)
@@ -360,7 +360,7 @@ cdef class _AioCall(GrpcCallWrapper):
             self,
             self._loop
         )
-        if received_message:
+        if received_message is not None:
             return received_message
         else:
             return EOF
index 86fc91e..bc25c2e 100644 (file)
@@ -130,6 +130,8 @@ async def _receive_message(GrpcCallWrapper grpc_call_wrapper,
         #
         # Since they all indicates finish, they are better be merged.
         _LOGGER.debug('Failed to receive any message from Core')
+    # NOTE(lidiz) The returned message might be an empty bytes (aka. b'').
+    # Please explicitly check if it is None or falsey string object!
     return receive_op.message()
 
 
index 46a47bd..4651a6b 100644 (file)
@@ -67,6 +67,13 @@ cdef enum AioServerStatus:
     AIO_SERVER_STATUS_STOPPING
 
 
+cdef class _ConcurrentRpcLimiter:
+    cdef int _maximum_concurrent_rpcs
+    cdef int _active_rpcs
+    cdef object _active_rpcs_condition # asyncio.Condition
+    cdef object _loop  # asyncio.EventLoop
+
+
 cdef class AioServer:
     cdef Server _server
     cdef list _generic_handlers
@@ -79,5 +86,6 @@ cdef class AioServer:
     cdef object _crash_exception  # Exception
     cdef tuple _interceptors
     cdef object _thread_pool  # concurrent.futures.ThreadPoolExecutor
+    cdef _ConcurrentRpcLimiter _limiter
 
     cdef thread_pool(self)
index 8c74d3e..73d9fb4 100644 (file)
@@ -781,6 +781,40 @@ cdef CallbackFailureHandler SERVER_SHUTDOWN_FAILURE_HANDLER = CallbackFailureHan
     InternalError)
 
 
+cdef class _ConcurrentRpcLimiter:
+
+    def __cinit__(self, int maximum_concurrent_rpcs, object loop):
+        if maximum_concurrent_rpcs <= 0:
+            raise ValueError("maximum_concurrent_rpcs should be a postive integer")
+        self._maximum_concurrent_rpcs = maximum_concurrent_rpcs
+        self._active_rpcs = 0
+        self._active_rpcs_condition = asyncio.Condition()
+        self._loop = loop
+
+    async def check_before_request_call(self):
+        await self._active_rpcs_condition.acquire()
+        try:
+            predicate = lambda: self._active_rpcs < self._maximum_concurrent_rpcs
+            await self._active_rpcs_condition.wait_for(predicate)
+            self._active_rpcs += 1
+        finally:
+            self._active_rpcs_condition.release()
+
+    async def _decrease_active_rpcs_count_with_lock(self):
+        await self._active_rpcs_condition.acquire()
+        try:
+            self._active_rpcs -= 1
+            self._active_rpcs_condition.notify()
+        finally:
+            self._active_rpcs_condition.release()
+
+    def _decrease_active_rpcs_count(self, unused_future):
+        self._loop.create_task(self._decrease_active_rpcs_count_with_lock())
+
+    def decrease_once_finished(self, object rpc_task):
+        rpc_task.add_done_callback(self._decrease_active_rpcs_count)
+
+
 cdef class AioServer:
 
     def __init__(self, loop, thread_pool, generic_handlers, interceptors,
@@ -815,9 +849,9 @@ cdef class AioServer:
             self._interceptors = ()
 
         self._thread_pool = thread_pool
-
-        if maximum_concurrent_rpcs:
-            raise NotImplementedError()
+        if maximum_concurrent_rpcs is not None:
+            self._limiter = _ConcurrentRpcLimiter(maximum_concurrent_rpcs,
+                                                  loop)
 
     def add_generic_rpc_handlers(self, object generic_rpc_handlers):
         self._generic_handlers.extend(generic_rpc_handlers)
@@ -860,6 +894,9 @@ cdef class AioServer:
             if self._status != AIO_SERVER_STATUS_RUNNING:
                 break
 
+            if self._limiter is not None:
+                await self._limiter.check_before_request_call()
+
             # Accepts new request from Core
             rpc_state = await self._request_call()
 
@@ -874,7 +911,7 @@ cdef class AioServer:
                                    self._loop)
 
             # Fires off a task that listens on the cancellation from client.
-            self._loop.create_task(
+            rpc_task = self._loop.create_task(
                 _schedule_rpc_coro(
                     rpc_coro,
                     rpc_state,
@@ -882,6 +919,9 @@ cdef class AioServer:
                 )
             )
 
+            if self._limiter is not None:
+                self._limiter.decrease_once_finished(rpc_task)
+
     def _serving_task_crash_handler(self, object task):
         """Shutdown the server immediately if unexpectedly exited."""
         if task.cancelled():
index 5bbd2a1..4904688 100644 (file)
@@ -14,4 +14,4 @@
 
 # AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio/grpc/_grpcio_metadata.py.template`!!!
 
-__version__ = """1.34.1"""
+__version__ = """1.35.0"""
index 926c865..0118489 100644 (file)
@@ -169,8 +169,10 @@ class ServicerContext(Generic[RequestType, ResponseType], abc.ABC):
         """
 
     @abc.abstractmethod
-    async def abort(self, code: grpc.StatusCode, details: str,
-                    trailing_metadata: Metadata) -> None:
+    async def abort(self,
+                    code: grpc.StatusCode,
+                    details: str = '',
+                    trailing_metadata: Metadata = tuple()) -> None:
         """Raises an exception to terminate the RPC with a non-OK status.
 
         The code and details passed as arguments will supercede any existing
index f9482c0..b0cac4d 100644 (file)
@@ -24,6 +24,7 @@ CORE_SOURCE_FILES = [
     'src/core/ext/filters/client_channel/client_channel_factory.cc',
     'src/core/ext/filters/client_channel/client_channel_plugin.cc',
     'src/core/ext/filters/client_channel/config_selector.cc',
+    'src/core/ext/filters/client_channel/dynamic_filters.cc',
     'src/core/ext/filters/client_channel/global_subchannel_pool.cc',
     'src/core/ext/filters/client_channel/health/health_check_client.cc',
     'src/core/ext/filters/client_channel/http_connect_handshaker.cc',
@@ -42,20 +43,18 @@ CORE_SOURCE_FILES = [
     'src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc',
     'src/core/ext/filters/client_channel/lb_policy/weighted_target/weighted_target.cc',
     'src/core/ext/filters/client_channel/lb_policy/xds/cds.cc',
-    'src/core/ext/filters/client_channel/lb_policy/xds/eds.cc',
     'src/core/ext/filters/client_channel/lb_policy/xds/xds_cluster_impl.cc',
     'src/core/ext/filters/client_channel/lb_policy/xds/xds_cluster_manager.cc',
+    'src/core/ext/filters/client_channel/lb_policy/xds/xds_cluster_resolver.cc',
     'src/core/ext/filters/client_channel/lb_policy_registry.cc',
     'src/core/ext/filters/client_channel/local_subchannel_pool.cc',
     'src/core/ext/filters/client_channel/proxy_mapper_registry.cc',
     'src/core/ext/filters/client_channel/resolver.cc',
     'src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc',
-    'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.cc',
     'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_libuv.cc',
     'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_posix.cc',
     'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_windows.cc',
     'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc',
-    'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_fallback.cc',
     'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv.cc',
     'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_posix.cc',
     'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc',
@@ -66,7 +65,6 @@ CORE_SOURCE_FILES = [
     'src/core/ext/filters/client_channel/resolver/xds/xds_resolver.cc',
     'src/core/ext/filters/client_channel/resolver_registry.cc',
     'src/core/ext/filters/client_channel/resolver_result_parsing.cc',
-    'src/core/ext/filters/client_channel/resolving_lb_policy.cc',
     'src/core/ext/filters/client_channel/retry_throttle.cc',
     'src/core/ext/filters/client_channel/server_address.cc',
     'src/core/ext/filters/client_channel/service_config.cc',
@@ -289,12 +287,12 @@ CORE_SOURCE_FILES = [
     'src/core/ext/xds/certificate_provider_registry.cc',
     'src/core/ext/xds/certificate_provider_store.cc',
     'src/core/ext/xds/file_watcher_certificate_provider_factory.cc',
-    'src/core/ext/xds/google_mesh_ca_certificate_provider_factory.cc',
     'src/core/ext/xds/xds_api.cc',
     'src/core/ext/xds/xds_bootstrap.cc',
     'src/core/ext/xds/xds_certificate_provider.cc',
     'src/core/ext/xds/xds_client.cc',
     'src/core/ext/xds/xds_client_stats.cc',
+    'src/core/ext/xds/xds_server_config_fetcher.cc',
     'src/core/lib/avl/avl.cc',
     'src/core/lib/backoff/backoff.cc',
     'src/core/lib/channel/channel_args.cc',
@@ -478,6 +476,7 @@ CORE_SOURCE_FILES = [
     'src/core/lib/security/credentials/composite/composite_credentials.cc',
     'src/core/lib/security/credentials/credentials.cc',
     'src/core/lib/security/credentials/credentials_metadata.cc',
+    'src/core/lib/security/credentials/external/aws_external_account_credentials.cc',
     'src/core/lib/security/credentials/external/aws_request_signer.cc',
     'src/core/lib/security/credentials/external/external_account_credentials.cc',
     'src/core/lib/security/credentials/external/file_external_account_credentials.cc',
@@ -498,6 +497,7 @@ CORE_SOURCE_FILES = [
     'src/core/lib/security/credentials/tls/grpc_tls_certificate_provider.cc',
     'src/core/lib/security/credentials/tls/grpc_tls_credentials_options.cc',
     'src/core/lib/security/credentials/tls/tls_credentials.cc',
+    'src/core/lib/security/credentials/tls/tls_utils.cc',
     'src/core/lib/security/credentials/xds/xds_credentials.cc',
     'src/core/lib/security/security_connector/alts/alts_security_connector.cc',
     'src/core/lib/security/security_connector/fake/fake_security_connector.cc',
@@ -610,6 +610,7 @@ CORE_SOURCE_FILES = [
     'third_party/abseil-cpp/absl/numeric/int128.cc',
     'third_party/abseil-cpp/absl/status/status.cc',
     'third_party/abseil-cpp/absl/status/status_payload_printer.cc',
+    'third_party/abseil-cpp/absl/status/statusor.cc',
     'third_party/abseil-cpp/absl/strings/ascii.cc',
     'third_party/abseil-cpp/absl/strings/charconv.cc',
     'third_party/abseil-cpp/absl/strings/cord.cc',
@@ -1002,10 +1003,12 @@ CORE_SOURCE_FILES = [
     'third_party/re2/util/rune.cc',
     'third_party/re2/util/strutil.cc',
     'third_party/upb/upb/decode.c',
+    'third_party/upb/upb/decode_fast.c',
     'third_party/upb/upb/def.c',
     'third_party/upb/upb/encode.c',
+    'third_party/upb/upb/json_decode.c',
+    'third_party/upb/upb/json_encode.c',
     'third_party/upb/upb/msg.c',
-    'third_party/upb/upb/port.c',
     'third_party/upb/upb/reflection.c',
     'third_party/upb/upb/table.c',
     'third_party/upb/upb/text_encode.c',
index 5ceeea6..b31e04f 100644 (file)
@@ -14,4 +14,4 @@
 
 # AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio/grpc_version.py.template`!!!
 
-VERSION = '1.34.1'
+VERSION = '1.35.0'
index f018884..09a4e44 100644 (file)
@@ -14,4 +14,4 @@
 
 # AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio_channelz/grpc_version.py.template`!!!
 
-VERSION = '1.34.1'
+VERSION = '1.35.0'
index 96a3baf..c5235f3 100644 (file)
@@ -14,4 +14,4 @@
 
 # AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio_health_checking/grpc_version.py.template`!!!
 
-VERSION = '1.34.1'
+VERSION = '1.35.0'
index a9c9796..122aa21 100644 (file)
@@ -14,4 +14,4 @@
 
 # AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio_reflection/grpc_version.py.template`!!!
 
-VERSION = '1.34.1'
+VERSION = '1.35.0'
index e0148a9..2e69ef7 100644 (file)
@@ -14,4 +14,4 @@
 
 # AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio_status/grpc_version.py.template`!!!
 
-VERSION = '1.34.1'
+VERSION = '1.35.0'
index 963724f..4730cb9 100644 (file)
@@ -14,4 +14,4 @@
 
 # AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio_testing/grpc_version.py.template`!!!
 
-VERSION = '1.34.1'
+VERSION = '1.35.0'
index 753c98f..689bb12 100644 (file)
@@ -14,4 +14,4 @@
 
 # AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio_tests/grpc_version.py.template`!!!
 
-VERSION = '1.34.1'
+VERSION = '1.35.0'
index 5e5081a..ee137de 100644 (file)
@@ -67,10 +67,13 @@ class TestServiceServicer(test_pb2_grpc.TestServiceServicer):
                 await asyncio.sleep(
                     datetime.timedelta(microseconds=response_parameters.
                                        interval_us).total_seconds())
-            yield messages_pb2.StreamingOutputCallResponse(
-                payload=messages_pb2.Payload(type=request.response_type,
-                                             body=b'\x00' *
-                                             response_parameters.size))
+            if response_parameters.size != 0:
+                yield messages_pb2.StreamingOutputCallResponse(
+                    payload=messages_pb2.Payload(type=request.response_type,
+                                                 body=b'\x00' *
+                                                 response_parameters.size))
+            else:
+                yield messages_pb2.StreamingOutputCallResponse()
 
     # Next methods are extra ones that are registred programatically
     # when the sever is instantiated. They are not being provided by
@@ -96,10 +99,13 @@ class TestServiceServicer(test_pb2_grpc.TestServiceServicer):
                     await asyncio.sleep(
                         datetime.timedelta(microseconds=response_parameters.
                                            interval_us).total_seconds())
-                yield messages_pb2.StreamingOutputCallResponse(
-                    payload=messages_pb2.Payload(type=request.payload.type,
-                                                 body=b'\x00' *
-                                                 response_parameters.size))
+                if response_parameters.size != 0:
+                    yield messages_pb2.StreamingOutputCallResponse(
+                        payload=messages_pb2.Payload(type=request.payload.type,
+                                                     body=b'\x00' *
+                                                     response_parameters.size))
+                else:
+                    yield messages_pb2.StreamingOutputCallResponse()
 
 
 def _create_extra_generic_handler(servicer: TestServiceServicer):
index 1961226..c7d99a2 100644 (file)
@@ -472,6 +472,24 @@ class TestUnaryStreamCall(_MulticallableTestMixin, AioTestBase):
 
         self.assertEqual(grpc.StatusCode.OK, await call.code())
 
+    async def test_empty_responses(self):
+        # Prepares the request
+        request = messages_pb2.StreamingOutputCallRequest()
+        for _ in range(_NUM_STREAM_RESPONSES):
+            request.response_parameters.append(
+                messages_pb2.ResponseParameters())
+
+        # Invokes the actual RPC
+        call = self._stub.StreamingOutputCall(request)
+
+        for _ in range(_NUM_STREAM_RESPONSES):
+            response = await call.read()
+            self.assertIs(type(response),
+                          messages_pb2.StreamingOutputCallResponse)
+            self.assertEqual(b'', response.SerializeToString())
+
+        self.assertEqual(grpc.StatusCode.OK, await call.code())
+
 
 class TestStreamUnaryCall(_MulticallableTestMixin, AioTestBase):
 
@@ -624,6 +642,10 @@ class TestStreamUnaryCall(_MulticallableTestMixin, AioTestBase):
 _STREAM_OUTPUT_REQUEST_ONE_RESPONSE = messages_pb2.StreamingOutputCallRequest()
 _STREAM_OUTPUT_REQUEST_ONE_RESPONSE.response_parameters.append(
     messages_pb2.ResponseParameters(size=_RESPONSE_PAYLOAD_SIZE))
+_STREAM_OUTPUT_REQUEST_ONE_EMPTY_RESPONSE = messages_pb2.StreamingOutputCallRequest(
+)
+_STREAM_OUTPUT_REQUEST_ONE_EMPTY_RESPONSE.response_parameters.append(
+    messages_pb2.ResponseParameters())
 
 
 class TestStreamStreamCall(_MulticallableTestMixin, AioTestBase):
@@ -808,6 +830,15 @@ class TestStreamStreamCall(_MulticallableTestMixin, AioTestBase):
 
         self.assertEqual(await call.code(), grpc.StatusCode.OK)
 
+    async def test_empty_ping_pong(self):
+        call = self._stub.FullDuplexCall()
+        for _ in range(_NUM_STREAM_RESPONSES):
+            await call.write(_STREAM_OUTPUT_REQUEST_ONE_EMPTY_RESPONSE)
+            response = await call.read()
+            self.assertEqual(b'', response.SerializeToString())
+        await call.done_writing()
+        self.assertEqual(await call.code(), grpc.StatusCode.OK)
+
 
 if __name__ == '__main__':
     logging.basicConfig(level=logging.DEBUG)
index 61d1edd..8ba3ce1 100644 (file)
@@ -47,6 +47,7 @@ _REQUEST = b'\x00\x00\x00'
 _RESPONSE = b'\x01\x01\x01'
 _NUM_STREAM_REQUESTS = 3
 _NUM_STREAM_RESPONSES = 5
+_MAXIMUM_CONCURRENT_RPCS = 5
 
 
 class _GenericHandler(grpc.GenericRpcHandler):
@@ -189,7 +190,8 @@ class _GenericHandler(grpc.GenericRpcHandler):
         context.set_code(grpc.StatusCode.INTERNAL)
 
     def service(self, handler_details):
-        self._called.set_result(None)
+        if not self._called.done():
+            self._called.set_result(None)
         return self._routing_table.get(handler_details.method)
 
     async def wait_for_call(self):
@@ -480,6 +482,30 @@ class TestServer(AioTestBase):
         with self.assertRaises(RuntimeError):
             server.add_secure_port(bind_address, server_credentials)
 
+    async def test_maximum_concurrent_rpcs(self):
+        # Build the server with concurrent rpc argument
+        server = aio.server(maximum_concurrent_rpcs=_MAXIMUM_CONCURRENT_RPCS)
+        port = server.add_insecure_port('localhost:0')
+        bind_address = "localhost:%d" % port
+        server.add_generic_rpc_handlers((_GenericHandler(),))
+        await server.start()
+        # Build the channel
+        channel = aio.insecure_channel(bind_address)
+        # Deplete the concurrent quota with 3 times of max RPCs
+        rpcs = []
+        for _ in range(3 * _MAXIMUM_CONCURRENT_RPCS):
+            rpcs.append(channel.unary_unary(_BLOCK_BRIEFLY)(_REQUEST))
+        task = self.loop.create_task(
+            asyncio.wait(rpcs, return_when=asyncio.FIRST_EXCEPTION))
+        # Each batch took test_constants.SHORT_TIMEOUT /2
+        start_time = time.time()
+        await task
+        elapsed_time = time.time() - start_time
+        self.assertGreater(elapsed_time, test_constants.SHORT_TIMEOUT * 3 / 2)
+        # Clean-up
+        await channel.close()
+        await server.stop(0)
+
 
 if __name__ == '__main__':
     logging.basicConfig(level=logging.DEBUG)
index 21277a9..1386938 100644 (file)
@@ -13,6 +13,8 @@
 # limitations under the License.
 
 import argparse
+import collections
+import datetime
 import logging
 import signal
 import threading
@@ -42,8 +44,22 @@ _SUPPORTED_METHODS = (
     "EmptyCall",
 )
 
+_METHOD_CAMEL_TO_CAPS_SNAKE = {
+    "UnaryCall": "UNARY_CALL",
+    "EmptyCall": "EMPTY_CALL",
+}
+
+_METHOD_STR_TO_ENUM = {
+    "UnaryCall": messages_pb2.ClientConfigureRequest.UNARY_CALL,
+    "EmptyCall": messages_pb2.ClientConfigureRequest.EMPTY_CALL,
+}
+
+_METHOD_ENUM_TO_STR = {v: k for k, v in _METHOD_STR_TO_ENUM.items()}
+
 PerMethodMetadataType = Mapping[str, Sequence[Tuple[str, str]]]
 
+_CONFIG_CHANGE_TIMEOUT = datetime.timedelta(milliseconds=500)
+
 
 class _StatsWatcher:
     _start: int
@@ -98,9 +114,12 @@ _stop_event = threading.Event()
 _global_rpc_id: int = 0
 _watchers: Set[_StatsWatcher] = set()
 _global_server = None
+_global_rpcs_started: Mapping[str, int] = collections.defaultdict(int)
+_global_rpcs_succeeded: Mapping[str, int] = collections.defaultdict(int)
+_global_rpcs_failed: Mapping[str, int] = collections.defaultdict(int)
 
 
-def _handle_sigint(sig, frame):
+def _handle_sigint(sig, frame) -> None:
     _stop_event.set()
     _global_server.stop(None)
 
@@ -126,7 +145,25 @@ class _LoadBalancerStatsServicer(test_pb2_grpc.LoadBalancerStatsServiceServicer
         response = watcher.await_rpc_stats_response(request.timeout_sec)
         with _global_lock:
             _watchers.remove(watcher)
-        logger.info("Returning stats response: {}".format(response))
+        logger.info("Returning stats response: %s", response)
+        return response
+
+    def GetClientAccumulatedStats(
+            self, request: messages_pb2.LoadBalancerAccumulatedStatsRequest,
+            context: grpc.ServicerContext
+    ) -> messages_pb2.LoadBalancerAccumulatedStatsResponse:
+        logger.info("Received cumulative stats request.")
+        response = messages_pb2.LoadBalancerAccumulatedStatsResponse()
+        with _global_lock:
+            for method in _SUPPORTED_METHODS:
+                caps_method = _METHOD_CAMEL_TO_CAPS_SNAKE[method]
+                response.num_rpcs_started_by_method[
+                    caps_method] = _global_rpcs_started[method]
+                response.num_rpcs_succeeded_by_method[
+                    caps_method] = _global_rpcs_succeeded[method]
+                response.num_rpcs_failed_by_method[
+                    caps_method] = _global_rpcs_failed[method]
+        logger.info("Returning cumulative stats response.")
         return response
 
 
@@ -153,6 +190,8 @@ def _on_rpc_done(rpc_id: int, future: grpc.Future, method: str,
     exception = future.exception()
     hostname = ""
     if exception is not None:
+        with _global_lock:
+            _global_rpcs_failed[method] += 1
         if exception.code() == grpc.StatusCode.DEADLINE_EXCEEDED:
             logger.error(f"RPC {rpc_id} timed out")
         else:
@@ -166,6 +205,12 @@ def _on_rpc_done(rpc_id: int, future: grpc.Future, method: str,
                 break
         else:
             hostname = response.hostname
+        if future.code() == grpc.StatusCode.OK:
+            with _global_lock:
+                _global_rpcs_succeeded[method] += 1
+        else:
+            with _global_lock:
+                _global_rpcs_failed[method] += 1
         if print_response:
             if future.code() == grpc.StatusCode.OK:
                 logger.info("Successful response.")
@@ -194,24 +239,55 @@ def _cancel_all_rpcs(futures: Mapping[int, Tuple[grpc.Future, str]]) -> None:
         future.cancel()
 
 
-def _run_single_channel(method: str, metadata: Sequence[Tuple[str, str]],
-                        qps: int, server: str, rpc_timeout_sec: int,
-                        print_response: bool):
+class _ChannelConfiguration:
+    """Configuration for a single client channel.
+
+    Instances of this class are meant to be dealt with as PODs. That is,
+    data member should be accessed directly. This class is not thread-safe.
+    When accessing any of its members, the lock member should be held.
+    """
+
+    def __init__(self, method: str, metadata: Sequence[Tuple[str, str]],
+                 qps: int, server: str, rpc_timeout_sec: int,
+                 print_response: bool):
+        # condition is signalled when a change is made to the config.
+        self.condition = threading.Condition()
+
+        self.method = method
+        self.metadata = metadata
+        self.qps = qps
+        self.server = server
+        self.rpc_timeout_sec = rpc_timeout_sec
+        self.print_response = print_response
+
+
+def _run_single_channel(config: _ChannelConfiguration) -> None:
     global _global_rpc_id  # pylint: disable=global-statement
-    duration_per_query = 1.0 / float(qps)
+    with config.condition:
+        server = config.server
     with grpc.insecure_channel(server) as channel:
         stub = test_pb2_grpc.TestServiceStub(channel)
         futures: Dict[int, Tuple[grpc.Future, str]] = {}
         while not _stop_event.is_set():
+            with config.condition:
+                if config.qps == 0:
+                    config.condition.wait(
+                        timeout=_CONFIG_CHANGE_TIMEOUT.total_seconds())
+                    continue
+                else:
+                    duration_per_query = 1.0 / float(config.qps)
             request_id = None
             with _global_lock:
                 request_id = _global_rpc_id
                 _global_rpc_id += 1
+                _global_rpcs_started[config.method] += 1
             start = time.time()
             end = start + duration_per_query
-            _start_rpc(method, metadata, request_id, stub,
-                       float(rpc_timeout_sec), futures)
-            _remove_completed_rpcs(futures, print_response)
+            with config.condition:
+                _start_rpc(config.method, config.metadata, request_id, stub,
+                           float(config.rpc_timeout_sec), futures)
+            with config.condition:
+                _remove_completed_rpcs(futures, config.print_response)
             logger.debug(f"Currently {len(futures)} in-flight RPCs")
             now = time.time()
             while now < end:
@@ -220,30 +296,54 @@ def _run_single_channel(method: str, metadata: Sequence[Tuple[str, str]],
         _cancel_all_rpcs(futures)
 
 
+class _XdsUpdateClientConfigureServicer(
+        test_pb2_grpc.XdsUpdateClientConfigureServiceServicer):
+
+    def __init__(self, per_method_configs: Mapping[str, _ChannelConfiguration],
+                 qps: int):
+        super(_XdsUpdateClientConfigureServicer).__init__()
+        self._per_method_configs = per_method_configs
+        self._qps = qps
+
+    def Configure(self, request: messages_pb2.ClientConfigureRequest,
+                  context: grpc.ServicerContext
+                 ) -> messages_pb2.ClientConfigureResponse:
+        logger.info("Received Configure RPC: %s", request)
+        method_strs = (_METHOD_ENUM_TO_STR[t] for t in request.types)
+        for method in _SUPPORTED_METHODS:
+            method_enum = _METHOD_STR_TO_ENUM[method]
+            if method in method_strs:
+                qps = self._qps
+                metadata = ((md.key, md.value)
+                            for md in request.metadata
+                            if md.type == method_enum)
+            else:
+                qps = 0
+                metadata = ()
+            channel_config = self._per_method_configs[method]
+            with channel_config.condition:
+                channel_config.qps = qps
+                channel_config.metadata = list(metadata)
+                channel_config.condition.notify_all()
+        return messages_pb2.ClientConfigureResponse()
+
+
 class _MethodHandle:
     """An object grouping together threads driving RPCs for a method."""
 
     _channel_threads: List[threading.Thread]
 
-    def __init__(self, method: str, metadata: Sequence[Tuple[str, str]],
-                 num_channels: int, qps: int, server: str, rpc_timeout_sec: int,
-                 print_response: bool):
+    def __init__(self, num_channels: int,
+                 channel_config: _ChannelConfiguration):
         """Creates and starts a group of threads running the indicated method."""
         self._channel_threads = []
         for i in range(num_channels):
             thread = threading.Thread(target=_run_single_channel,
-                                      args=(
-                                          method,
-                                          metadata,
-                                          qps,
-                                          server,
-                                          rpc_timeout_sec,
-                                          print_response,
-                                      ))
+                                      args=(channel_config,))
             thread.start()
             self._channel_threads.append(thread)
 
-    def stop(self):
+    def stop(self) -> None:
         """Joins all threads referenced by the handle."""
         for channel_thread in self._channel_threads:
             channel_thread.join()
@@ -254,15 +354,24 @@ def _run(args: argparse.Namespace, methods: Sequence[str],
     logger.info("Starting python xDS Interop Client.")
     global _global_server  # pylint: disable=global-statement
     method_handles = []
-    for method in methods:
-        method_handles.append(
-            _MethodHandle(method, per_method_metadata.get(method, []),
-                          args.num_channels, args.qps, args.server,
-                          args.rpc_timeout_sec, args.print_response))
+    channel_configs = {}
+    for method in _SUPPORTED_METHODS:
+        if method in methods:
+            qps = args.qps
+        else:
+            qps = 0
+        channel_config = _ChannelConfiguration(
+            method, per_method_metadata.get(method, []), qps, args.server,
+            args.rpc_timeout_sec, args.print_response)
+        channel_configs[method] = channel_config
+        method_handles.append(_MethodHandle(args.num_channels, channel_config))
     _global_server = grpc.server(futures.ThreadPoolExecutor())
     _global_server.add_insecure_port(f"0.0.0.0:{args.stats_port}")
     test_pb2_grpc.add_LoadBalancerStatsServiceServicer_to_server(
         _LoadBalancerStatsServicer(), _global_server)
+    test_pb2_grpc.add_XdsUpdateClientConfigureServiceServicer_to_server(
+        _XdsUpdateClientConfigureServicer(channel_configs, args.qps),
+        _global_server)
     _global_server.start()
     _global_server.wait_for_termination()
     for method_handle in method_handles:
index 043e621..448e726 100644 (file)
@@ -19,12 +19,9 @@ def main
   root_dir = File.join(File.dirname(__FILE__), '..', '..', '..')
   pb_dir = File.join(root_dir, 'src', 'ruby', 'end2end', 'protos')
 
-  fail 'CONFIG env variable unexpectedly unset' unless ENV['CONFIG']
-  bins_sub_dir = ENV['CONFIG']
-  bins_dir = File.join(root_dir, 'bins', bins_sub_dir)
-
+  bins_dir = File.join(root_dir, 'cmake', 'build')
   plugin = File.join(bins_dir, 'grpc_ruby_plugin')
-  protoc = File.join(bins_dir, 'protobuf', 'protoc')
+  protoc = File.join(bins_dir, 'third_party', 'protobuf', 'protoc')
 
   got = nil
 
index c9ca14e..0bdf725 100644 (file)
@@ -29,6 +29,8 @@
 #include <grpc/support/time.h>
 #include <ruby/thread.h>
 
+#include "rb_grpc.h"
+
 typedef struct grpc_rb_event {
   // callback will be called with argument while holding the GVL
   void (*callback)(void*);
index 9024a8e..5d5d3e0 100644 (file)
@@ -80,6 +80,9 @@ grpc_server_register_method_type grpc_server_register_method_import;
 grpc_server_request_registered_call_type grpc_server_request_registered_call_import;
 grpc_server_create_type grpc_server_create_import;
 grpc_server_register_completion_queue_type grpc_server_register_completion_queue_import;
+grpc_server_config_fetcher_xds_create_type grpc_server_config_fetcher_xds_create_import;
+grpc_server_config_fetcher_destroy_type grpc_server_config_fetcher_destroy_import;
+grpc_server_set_config_fetcher_type grpc_server_set_config_fetcher_import;
 grpc_server_add_insecure_http2_port_type grpc_server_add_insecure_http2_port_import;
 grpc_server_start_type grpc_server_start_import;
 grpc_server_shutdown_and_notify_type grpc_server_shutdown_and_notify_import;
@@ -130,6 +133,7 @@ grpc_composite_call_credentials_create_type grpc_composite_call_credentials_crea
 grpc_google_compute_engine_credentials_create_type grpc_google_compute_engine_credentials_create_import;
 grpc_max_auth_token_lifetime_type grpc_max_auth_token_lifetime_import;
 grpc_service_account_jwt_access_credentials_create_type grpc_service_account_jwt_access_credentials_create_import;
+grpc_external_account_credentials_create_type grpc_external_account_credentials_create_import;
 grpc_google_refresh_token_credentials_create_type grpc_google_refresh_token_credentials_create_import;
 grpc_access_token_credentials_create_type grpc_access_token_credentials_create_import;
 grpc_google_iam_credentials_create_type grpc_google_iam_credentials_create_import;
@@ -162,6 +166,7 @@ grpc_tls_identity_pairs_create_type grpc_tls_identity_pairs_create_import;
 grpc_tls_identity_pairs_add_pair_type grpc_tls_identity_pairs_add_pair_import;
 grpc_tls_identity_pairs_destroy_type grpc_tls_identity_pairs_destroy_import;
 grpc_tls_certificate_provider_static_data_create_type grpc_tls_certificate_provider_static_data_create_import;
+grpc_tls_certificate_provider_file_watcher_create_type grpc_tls_certificate_provider_file_watcher_create_import;
 grpc_tls_certificate_provider_release_type grpc_tls_certificate_provider_release_import;
 grpc_tls_credentials_options_create_type grpc_tls_credentials_options_create_import;
 grpc_tls_credentials_options_set_cert_request_type_type grpc_tls_credentials_options_set_cert_request_type_import;
@@ -175,6 +180,7 @@ grpc_tls_credentials_options_set_server_authorization_check_config_type grpc_tls
 grpc_tls_server_authorization_check_config_create_type grpc_tls_server_authorization_check_config_create_import;
 grpc_tls_server_authorization_check_config_release_type grpc_tls_server_authorization_check_config_release_import;
 grpc_xds_credentials_create_type grpc_xds_credentials_create_import;
+grpc_xds_server_credentials_create_type grpc_xds_server_credentials_create_import;
 grpc_raw_byte_buffer_create_type grpc_raw_byte_buffer_create_import;
 grpc_raw_compressed_byte_buffer_create_type grpc_raw_compressed_byte_buffer_create_import;
 grpc_byte_buffer_copy_type grpc_byte_buffer_copy_import;
@@ -358,6 +364,9 @@ void grpc_rb_load_imports(HMODULE library) {
   grpc_server_request_registered_call_import = (grpc_server_request_registered_call_type) GetProcAddress(library, "grpc_server_request_registered_call");
   grpc_server_create_import = (grpc_server_create_type) GetProcAddress(library, "grpc_server_create");
   grpc_server_register_completion_queue_import = (grpc_server_register_completion_queue_type) GetProcAddress(library, "grpc_server_register_completion_queue");
+  grpc_server_config_fetcher_xds_create_import = (grpc_server_config_fetcher_xds_create_type) GetProcAddress(library, "grpc_server_config_fetcher_xds_create");
+  grpc_server_config_fetcher_destroy_import = (grpc_server_config_fetcher_destroy_type) GetProcAddress(library, "grpc_server_config_fetcher_destroy");
+  grpc_server_set_config_fetcher_import = (grpc_server_set_config_fetcher_type) GetProcAddress(library, "grpc_server_set_config_fetcher");
   grpc_server_add_insecure_http2_port_import = (grpc_server_add_insecure_http2_port_type) GetProcAddress(library, "grpc_server_add_insecure_http2_port");
   grpc_server_start_import = (grpc_server_start_type) GetProcAddress(library, "grpc_server_start");
   grpc_server_shutdown_and_notify_import = (grpc_server_shutdown_and_notify_type) GetProcAddress(library, "grpc_server_shutdown_and_notify");
@@ -408,6 +417,7 @@ void grpc_rb_load_imports(HMODULE library) {
   grpc_google_compute_engine_credentials_create_import = (grpc_google_compute_engine_credentials_create_type) GetProcAddress(library, "grpc_google_compute_engine_credentials_create");
   grpc_max_auth_token_lifetime_import = (grpc_max_auth_token_lifetime_type) GetProcAddress(library, "grpc_max_auth_token_lifetime");
   grpc_service_account_jwt_access_credentials_create_import = (grpc_service_account_jwt_access_credentials_create_type) GetProcAddress(library, "grpc_service_account_jwt_access_credentials_create");
+  grpc_external_account_credentials_create_import = (grpc_external_account_credentials_create_type) GetProcAddress(library, "grpc_external_account_credentials_create");
   grpc_google_refresh_token_credentials_create_import = (grpc_google_refresh_token_credentials_create_type) GetProcAddress(library, "grpc_google_refresh_token_credentials_create");
   grpc_access_token_credentials_create_import = (grpc_access_token_credentials_create_type) GetProcAddress(library, "grpc_access_token_credentials_create");
   grpc_google_iam_credentials_create_import = (grpc_google_iam_credentials_create_type) GetProcAddress(library, "grpc_google_iam_credentials_create");
@@ -440,6 +450,7 @@ void grpc_rb_load_imports(HMODULE library) {
   grpc_tls_identity_pairs_add_pair_import = (grpc_tls_identity_pairs_add_pair_type) GetProcAddress(library, "grpc_tls_identity_pairs_add_pair");
   grpc_tls_identity_pairs_destroy_import = (grpc_tls_identity_pairs_destroy_type) GetProcAddress(library, "grpc_tls_identity_pairs_destroy");
   grpc_tls_certificate_provider_static_data_create_import = (grpc_tls_certificate_provider_static_data_create_type) GetProcAddress(library, "grpc_tls_certificate_provider_static_data_create");
+  grpc_tls_certificate_provider_file_watcher_create_import = (grpc_tls_certificate_provider_file_watcher_create_type) GetProcAddress(library, "grpc_tls_certificate_provider_file_watcher_create");
   grpc_tls_certificate_provider_release_import = (grpc_tls_certificate_provider_release_type) GetProcAddress(library, "grpc_tls_certificate_provider_release");
   grpc_tls_credentials_options_create_import = (grpc_tls_credentials_options_create_type) GetProcAddress(library, "grpc_tls_credentials_options_create");
   grpc_tls_credentials_options_set_cert_request_type_import = (grpc_tls_credentials_options_set_cert_request_type_type) GetProcAddress(library, "grpc_tls_credentials_options_set_cert_request_type");
@@ -453,6 +464,7 @@ void grpc_rb_load_imports(HMODULE library) {
   grpc_tls_server_authorization_check_config_create_import = (grpc_tls_server_authorization_check_config_create_type) GetProcAddress(library, "grpc_tls_server_authorization_check_config_create");
   grpc_tls_server_authorization_check_config_release_import = (grpc_tls_server_authorization_check_config_release_type) GetProcAddress(library, "grpc_tls_server_authorization_check_config_release");
   grpc_xds_credentials_create_import = (grpc_xds_credentials_create_type) GetProcAddress(library, "grpc_xds_credentials_create");
+  grpc_xds_server_credentials_create_import = (grpc_xds_server_credentials_create_type) GetProcAddress(library, "grpc_xds_server_credentials_create");
   grpc_raw_byte_buffer_create_import = (grpc_raw_byte_buffer_create_type) GetProcAddress(library, "grpc_raw_byte_buffer_create");
   grpc_raw_compressed_byte_buffer_create_import = (grpc_raw_compressed_byte_buffer_create_type) GetProcAddress(library, "grpc_raw_compressed_byte_buffer_create");
   grpc_byte_buffer_copy_import = (grpc_byte_buffer_copy_type) GetProcAddress(library, "grpc_byte_buffer_copy");
index 1079e42..c526b3a 100644 (file)
@@ -47,7 +47,7 @@ extern grpc_compression_algorithm_is_message_type grpc_compression_algorithm_is_
 typedef int(*grpc_compression_algorithm_is_stream_type)(grpc_compression_algorithm algorithm);
 extern grpc_compression_algorithm_is_stream_type grpc_compression_algorithm_is_stream_import;
 #define grpc_compression_algorithm_is_stream grpc_compression_algorithm_is_stream_import
-typedef int(*grpc_compression_algorithm_parse_type)(grpc_slice value, grpc_compression_algorithm* algorithm);
+typedef int(*grpc_compression_algorithm_parse_type)(grpc_slice name, grpc_compression_algorithm* algorithm);
 extern grpc_compression_algorithm_parse_type grpc_compression_algorithm_parse_import;
 #define grpc_compression_algorithm_parse grpc_compression_algorithm_parse_import
 typedef int(*grpc_compression_algorithm_name_type)(grpc_compression_algorithm algorithm, const char** name);
@@ -215,6 +215,15 @@ extern grpc_server_create_type grpc_server_create_import;
 typedef void(*grpc_server_register_completion_queue_type)(grpc_server* server, grpc_completion_queue* cq, void* reserved);
 extern grpc_server_register_completion_queue_type grpc_server_register_completion_queue_import;
 #define grpc_server_register_completion_queue grpc_server_register_completion_queue_import
+typedef grpc_server_config_fetcher*(*grpc_server_config_fetcher_xds_create_type)();
+extern grpc_server_config_fetcher_xds_create_type grpc_server_config_fetcher_xds_create_import;
+#define grpc_server_config_fetcher_xds_create grpc_server_config_fetcher_xds_create_import
+typedef void(*grpc_server_config_fetcher_destroy_type)(grpc_server_config_fetcher* config_fetcher);
+extern grpc_server_config_fetcher_destroy_type grpc_server_config_fetcher_destroy_import;
+#define grpc_server_config_fetcher_destroy grpc_server_config_fetcher_destroy_import
+typedef void(*grpc_server_set_config_fetcher_type)(grpc_server* server, grpc_server_config_fetcher* config_fetcher);
+extern grpc_server_set_config_fetcher_type grpc_server_set_config_fetcher_import;
+#define grpc_server_set_config_fetcher grpc_server_set_config_fetcher_import
 typedef int(*grpc_server_add_insecure_http2_port_type)(grpc_server* server, const char* addr);
 extern grpc_server_add_insecure_http2_port_type grpc_server_add_insecure_http2_port_import;
 #define grpc_server_add_insecure_http2_port grpc_server_add_insecure_http2_port_import
@@ -365,6 +374,9 @@ extern grpc_max_auth_token_lifetime_type grpc_max_auth_token_lifetime_import;
 typedef grpc_call_credentials*(*grpc_service_account_jwt_access_credentials_create_type)(const char* json_key, gpr_timespec token_lifetime, void* reserved);
 extern grpc_service_account_jwt_access_credentials_create_type grpc_service_account_jwt_access_credentials_create_import;
 #define grpc_service_account_jwt_access_credentials_create grpc_service_account_jwt_access_credentials_create_import
+typedef grpc_call_credentials*(*grpc_external_account_credentials_create_type)(const char* json_string, const char* scopes_string);
+extern grpc_external_account_credentials_create_type grpc_external_account_credentials_create_import;
+#define grpc_external_account_credentials_create grpc_external_account_credentials_create_import
 typedef grpc_call_credentials*(*grpc_google_refresh_token_credentials_create_type)(const char* json_refresh_token, void* reserved);
 extern grpc_google_refresh_token_credentials_create_type grpc_google_refresh_token_credentials_create_import;
 #define grpc_google_refresh_token_credentials_create grpc_google_refresh_token_credentials_create_import
@@ -461,6 +473,9 @@ extern grpc_tls_identity_pairs_destroy_type grpc_tls_identity_pairs_destroy_impo
 typedef grpc_tls_certificate_provider*(*grpc_tls_certificate_provider_static_data_create_type)(const char* root_certificate, grpc_tls_identity_pairs* pem_key_cert_pairs);
 extern grpc_tls_certificate_provider_static_data_create_type grpc_tls_certificate_provider_static_data_create_import;
 #define grpc_tls_certificate_provider_static_data_create grpc_tls_certificate_provider_static_data_create_import
+typedef grpc_tls_certificate_provider*(*grpc_tls_certificate_provider_file_watcher_create_type)(const char* private_key_path, const char* identity_certificate_path, const char* root_cert_path, unsigned int refresh_interval_sec);
+extern grpc_tls_certificate_provider_file_watcher_create_type grpc_tls_certificate_provider_file_watcher_create_import;
+#define grpc_tls_certificate_provider_file_watcher_create grpc_tls_certificate_provider_file_watcher_create_import
 typedef void(*grpc_tls_certificate_provider_release_type)(grpc_tls_certificate_provider* provider);
 extern grpc_tls_certificate_provider_release_type grpc_tls_certificate_provider_release_import;
 #define grpc_tls_certificate_provider_release grpc_tls_certificate_provider_release_import
@@ -500,6 +515,9 @@ extern grpc_tls_server_authorization_check_config_release_type grpc_tls_server_a
 typedef grpc_channel_credentials*(*grpc_xds_credentials_create_type)(grpc_channel_credentials* fallback_credentials);
 extern grpc_xds_credentials_create_type grpc_xds_credentials_create_import;
 #define grpc_xds_credentials_create grpc_xds_credentials_create_import
+typedef grpc_server_credentials*(*grpc_xds_server_credentials_create_type)(grpc_server_credentials* fallback_credentials);
+extern grpc_xds_server_credentials_create_type grpc_xds_server_credentials_create_import;
+#define grpc_xds_server_credentials_create grpc_xds_server_credentials_create_import
 typedef grpc_byte_buffer*(*grpc_raw_byte_buffer_create_type)(grpc_slice* slices, size_t nslices);
 extern grpc_raw_byte_buffer_create_type grpc_raw_byte_buffer_create_import;
 #define grpc_raw_byte_buffer_create grpc_raw_byte_buffer_create_import
@@ -512,7 +530,7 @@ extern grpc_byte_buffer_copy_type grpc_byte_buffer_copy_import;
 typedef size_t(*grpc_byte_buffer_length_type)(grpc_byte_buffer* bb);
 extern grpc_byte_buffer_length_type grpc_byte_buffer_length_import;
 #define grpc_byte_buffer_length grpc_byte_buffer_length_import
-typedef void(*grpc_byte_buffer_destroy_type)(grpc_byte_buffer* byte_buffer);
+typedef void(*grpc_byte_buffer_destroy_type)(grpc_byte_buffer* bb);
 extern grpc_byte_buffer_destroy_type grpc_byte_buffer_destroy_import;
 #define grpc_byte_buffer_destroy grpc_byte_buffer_destroy_import
 typedef int(*grpc_byte_buffer_reader_init_type)(grpc_byte_buffer_reader* reader, grpc_byte_buffer* buffer);
@@ -680,7 +698,7 @@ extern grpc_slice_buffer_swap_type grpc_slice_buffer_swap_import;
 typedef void(*grpc_slice_buffer_move_into_type)(grpc_slice_buffer* src, grpc_slice_buffer* dst);
 extern grpc_slice_buffer_move_into_type grpc_slice_buffer_move_into_import;
 #define grpc_slice_buffer_move_into grpc_slice_buffer_move_into_import
-typedef void(*grpc_slice_buffer_trim_end_type)(grpc_slice_buffer* src, size_t n, grpc_slice_buffer* garbage);
+typedef void(*grpc_slice_buffer_trim_end_type)(grpc_slice_buffer* sb, size_t n, grpc_slice_buffer* garbage);
 extern grpc_slice_buffer_trim_end_type grpc_slice_buffer_trim_end_import;
 #define grpc_slice_buffer_trim_end grpc_slice_buffer_trim_end_import
 typedef void(*grpc_slice_buffer_move_first_type)(grpc_slice_buffer* src, size_t n, grpc_slice_buffer* dst);
@@ -692,10 +710,10 @@ extern grpc_slice_buffer_move_first_no_ref_type grpc_slice_buffer_move_first_no_
 typedef void(*grpc_slice_buffer_move_first_into_buffer_type)(grpc_slice_buffer* src, size_t n, void* dst);
 extern grpc_slice_buffer_move_first_into_buffer_type grpc_slice_buffer_move_first_into_buffer_import;
 #define grpc_slice_buffer_move_first_into_buffer grpc_slice_buffer_move_first_into_buffer_import
-typedef grpc_slice(*grpc_slice_buffer_take_first_type)(grpc_slice_buffer* src);
+typedef grpc_slice(*grpc_slice_buffer_take_first_type)(grpc_slice_buffer* sb);
 extern grpc_slice_buffer_take_first_type grpc_slice_buffer_take_first_import;
 #define grpc_slice_buffer_take_first grpc_slice_buffer_take_first_import
-typedef void(*grpc_slice_buffer_undo_take_first_type)(grpc_slice_buffer* src, grpc_slice slice);
+typedef void(*grpc_slice_buffer_undo_take_first_type)(grpc_slice_buffer* sb, grpc_slice slice);
 extern grpc_slice_buffer_undo_take_first_type grpc_slice_buffer_undo_take_first_import;
 #define grpc_slice_buffer_undo_take_first grpc_slice_buffer_undo_take_first_import
 typedef void*(*gpr_malloc_type)(size_t size);
@@ -761,7 +779,7 @@ extern gpr_cv_signal_type gpr_cv_signal_import;
 typedef void(*gpr_cv_broadcast_type)(gpr_cv* cv);
 extern gpr_cv_broadcast_type gpr_cv_broadcast_import;
 #define gpr_cv_broadcast gpr_cv_broadcast_import
-typedef void(*gpr_once_init_type)(gpr_once* once, void (*init_routine)(void));
+typedef void(*gpr_once_init_type)(gpr_once* once, void (*init_function)(void));
 extern gpr_once_init_type gpr_once_init_import;
 #define gpr_once_init gpr_once_init_import
 typedef void(*gpr_event_init_type)(gpr_event* ev);
@@ -821,7 +839,7 @@ extern gpr_time_init_type gpr_time_init_import;
 typedef gpr_timespec(*gpr_now_type)(gpr_clock_type clock);
 extern gpr_now_type gpr_now_import;
 #define gpr_now gpr_now_import
-typedef gpr_timespec(*gpr_convert_clock_type_type)(gpr_timespec t, gpr_clock_type target_clock);
+typedef gpr_timespec(*gpr_convert_clock_type_type)(gpr_timespec t, gpr_clock_type clock_type);
 extern gpr_convert_clock_type_type gpr_convert_clock_type_import;
 #define gpr_convert_clock_type gpr_convert_clock_type_import
 typedef int(*gpr_time_cmp_type)(gpr_timespec a, gpr_timespec b);
@@ -839,22 +857,22 @@ extern gpr_time_add_type gpr_time_add_import;
 typedef gpr_timespec(*gpr_time_sub_type)(gpr_timespec a, gpr_timespec b);
 extern gpr_time_sub_type gpr_time_sub_import;
 #define gpr_time_sub gpr_time_sub_import
-typedef gpr_timespec(*gpr_time_from_micros_type)(int64_t x, gpr_clock_type clock_type);
+typedef gpr_timespec(*gpr_time_from_micros_type)(int64_t us, gpr_clock_type clock_type);
 extern gpr_time_from_micros_type gpr_time_from_micros_import;
 #define gpr_time_from_micros gpr_time_from_micros_import
-typedef gpr_timespec(*gpr_time_from_nanos_type)(int64_t x, gpr_clock_type clock_type);
+typedef gpr_timespec(*gpr_time_from_nanos_type)(int64_t ns, gpr_clock_type clock_type);
 extern gpr_time_from_nanos_type gpr_time_from_nanos_import;
 #define gpr_time_from_nanos gpr_time_from_nanos_import
-typedef gpr_timespec(*gpr_time_from_millis_type)(int64_t x, gpr_clock_type clock_type);
+typedef gpr_timespec(*gpr_time_from_millis_type)(int64_t ms, gpr_clock_type clock_type);
 extern gpr_time_from_millis_type gpr_time_from_millis_import;
 #define gpr_time_from_millis gpr_time_from_millis_import
-typedef gpr_timespec(*gpr_time_from_seconds_type)(int64_t x, gpr_clock_type clock_type);
+typedef gpr_timespec(*gpr_time_from_seconds_type)(int64_t s, gpr_clock_type clock_type);
 extern gpr_time_from_seconds_type gpr_time_from_seconds_import;
 #define gpr_time_from_seconds gpr_time_from_seconds_import
-typedef gpr_timespec(*gpr_time_from_minutes_type)(int64_t x, gpr_clock_type clock_type);
+typedef gpr_timespec(*gpr_time_from_minutes_type)(int64_t m, gpr_clock_type clock_type);
 extern gpr_time_from_minutes_type gpr_time_from_minutes_import;
 #define gpr_time_from_minutes gpr_time_from_minutes_import
-typedef gpr_timespec(*gpr_time_from_hours_type)(int64_t x, gpr_clock_type clock_type);
+typedef gpr_timespec(*gpr_time_from_hours_type)(int64_t h, gpr_clock_type clock_type);
 extern gpr_time_from_hours_type gpr_time_from_hours_import;
 #define gpr_time_from_hours gpr_time_from_hours_import
 typedef int32_t(*gpr_time_to_millis_type)(gpr_timespec timespec);
index e329dd7..87687aa 100644 (file)
@@ -14,5 +14,5 @@
 
 # GRPC contains the General RPC module.
 module GRPC
-  VERSION = '1.34.1'
+  VERSION = '1.35.0'
 end
index d902ae0..3a44783 100644 (file)
@@ -76,6 +76,28 @@ Google::Protobuf::DescriptorPool.generated_pool.build do
     add_message "grpc.testing.LoadBalancerStatsResponse.RpcsByPeer" do
       map :rpcs_by_peer, :string, :int32, 1
     end
+    add_message "grpc.testing.LoadBalancerAccumulatedStatsRequest" do
+    end
+    add_message "grpc.testing.LoadBalancerAccumulatedStatsResponse" do
+      map :num_rpcs_started_by_method, :string, :int32, 1
+      map :num_rpcs_succeeded_by_method, :string, :int32, 2
+      map :num_rpcs_failed_by_method, :string, :int32, 3
+    end
+    add_message "grpc.testing.ClientConfigureRequest" do
+      repeated :types, :enum, 1, "grpc.testing.ClientConfigureRequest.RpcType"
+      repeated :metadata, :message, 2, "grpc.testing.ClientConfigureRequest.Metadata"
+    end
+    add_message "grpc.testing.ClientConfigureRequest.Metadata" do
+      optional :type, :enum, 1, "grpc.testing.ClientConfigureRequest.RpcType"
+      optional :key, :string, 2
+      optional :value, :string, 3
+    end
+    add_enum "grpc.testing.ClientConfigureRequest.RpcType" do
+      value :EMPTY_CALL, 0
+      value :UNARY_CALL, 1
+    end
+    add_message "grpc.testing.ClientConfigureResponse" do
+    end
     add_enum "grpc.testing.PayloadType" do
       value :COMPRESSABLE, 0
     end
@@ -104,6 +126,12 @@ module Grpc
     LoadBalancerStatsRequest = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("grpc.testing.LoadBalancerStatsRequest").msgclass
     LoadBalancerStatsResponse = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("grpc.testing.LoadBalancerStatsResponse").msgclass
     LoadBalancerStatsResponse::RpcsByPeer = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("grpc.testing.LoadBalancerStatsResponse.RpcsByPeer").msgclass
+    LoadBalancerAccumulatedStatsRequest = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("grpc.testing.LoadBalancerAccumulatedStatsRequest").msgclass
+    LoadBalancerAccumulatedStatsResponse = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("grpc.testing.LoadBalancerAccumulatedStatsResponse").msgclass
+    ClientConfigureRequest = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("grpc.testing.ClientConfigureRequest").msgclass
+    ClientConfigureRequest::Metadata = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("grpc.testing.ClientConfigureRequest.Metadata").msgclass
+    ClientConfigureRequest::RpcType = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("grpc.testing.ClientConfigureRequest.RpcType").enummodule
+    ClientConfigureResponse = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("grpc.testing.ClientConfigureResponse").msgclass
     PayloadType = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("grpc.testing.PayloadType").enummodule
     GrpclbRouteType = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("grpc.testing.GrpclbRouteType").enummodule
   end
index 115acd0..19e6df7 100644 (file)
@@ -110,6 +110,8 @@ module Grpc
 
         # Gets the backend distribution for RPCs sent by a test client.
         rpc :GetClientStats, ::Grpc::Testing::LoadBalancerStatsRequest, ::Grpc::Testing::LoadBalancerStatsResponse
+        # Gets the accumulated stats for RPCs sent by a test client.
+        rpc :GetClientAccumulatedStats, ::Grpc::Testing::LoadBalancerAccumulatedStatsRequest, ::Grpc::Testing::LoadBalancerAccumulatedStatsResponse
       end
 
       Stub = Service.rpc_stub_class
@@ -130,5 +132,21 @@ module Grpc
 
       Stub = Service.rpc_stub_class
     end
+    module XdsUpdateClientConfigureService
+      # A service to dynamically update the configuration of an xDS test client.
+      class Service
+
+        include GRPC::GenericService
+
+        self.marshal_class_method = :encode
+        self.unmarshal_class_method = :decode
+        self.service_name = 'grpc.testing.XdsUpdateClientConfigureService'
+
+        # Update the tes client's configuration.
+        rpc :Configure, ::Grpc::Testing::ClientConfigureRequest, ::Grpc::Testing::ClientConfigureResponse
+      end
+
+      Stub = Service.rpc_stub_class
+    end
   end
 end
index 2f15c5f..2ab24b6 100755 (executable)
@@ -39,11 +39,38 @@ require_relative '../src/proto/grpc/testing/empty_pb'
 require_relative '../src/proto/grpc/testing/messages_pb'
 require_relative '../src/proto/grpc/testing/test_services_pb'
 
+class RpcConfig
+  def init(rpcs_to_send, metadata_to_send)
+    @rpcs_to_send = rpcs_to_send
+    @metadata_to_send = metadata_to_send
+  end
+  def rpcs_to_send
+    @rpcs_to_send
+  end
+  def metadata_to_send
+    @metadata_to_send
+  end
+end
+
+# Some global constant mappings
+$RPC_MAP = {
+  'UnaryCall' => :UNARY_CALL,
+  'EmptyCall' => :EMPTY_CALL,
+}
+
 # Some global variables to be shared by server and client
 $watchers = Array.new
 $watchers_mutex = Mutex.new
 $watchers_cv = ConditionVariable.new
 $shutdown = false
+# These can be configured by the test runner dynamically
+$rpc_config = RpcConfig.new
+$rpc_config.init([:UNARY_CALL], {})
+# These stats are shared across threads
+$accumulated_stats_mu = Mutex.new
+$num_rpcs_started_by_method = {}
+$num_rpcs_succeeded_by_method = {}
+$num_rpcs_failed_by_method = {}
 
 # RubyLogger defines a logger for gRPC based on the standard ruby logger.
 module RubyLogger
@@ -71,6 +98,31 @@ def create_stub(opts)
   )
 end
 
+class ConfigureTarget < Grpc::Testing::XdsUpdateClientConfigureService::Service
+  include Grpc::Testing
+
+  def configure(req, _call)
+    rpcs_to_send = req['types'];
+    metadata_to_send = {}
+    req['metadata'].each do |m|
+      rpc = m.type
+      if !metadata_to_send.key?(rpc)
+        metadata_to_send[rpc] = {}
+      end
+      metadata_key = m.key
+      metadata_value = m.value
+      metadata_to_send[rpc][metadata_key] = metadata_value
+    end
+    GRPC.logger.info("Configuring new rpcs_to_send and metadata_to_send...")
+    GRPC.logger.info(rpcs_to_send)
+    GRPC.logger.info(metadata_to_send)
+    new_rpc_config = RpcConfig.new
+    new_rpc_config.init(rpcs_to_send, metadata_to_send)
+    $rpc_config = new_rpc_config
+    ClientConfigureResponse.new();
+  end
+end
+
 # This implements LoadBalancerStatsService required by the test runner
 class TestTarget < Grpc::Testing::LoadBalancerStatsService::Service
   include Grpc::Testing
@@ -109,10 +161,20 @@ class TestTarget < Grpc::Testing::LoadBalancerStatsService::Service
       num_failures: watcher['no_remote_peer'] + watcher['rpcs_needed']
     );
   end
+
+  def get_client_accumulated_stats(req, _call)
+    $accumulated_stats_mu.synchronize do
+      LoadBalancerAccumulatedStatsResponse.new(
+        num_rpcs_started_by_method: $num_rpcs_started_by_method,
+        num_rpcs_succeeded_by_method: $num_rpcs_succeeded_by_method,
+        num_rpcs_failed_by_method: $num_rpcs_failed_by_method
+      )
+    end
+  end
 end
 
 # execute 1 RPC and return remote hostname
-def execute_rpc(op, fail_on_failed_rpcs)
+def execute_rpc(op, fail_on_failed_rpcs, rpc_stats_key)
   remote_peer = ""
   begin
     op.execute
@@ -120,60 +182,108 @@ def execute_rpc(op, fail_on_failed_rpcs)
       remote_peer = op.metadata['hostname']
     end
   rescue GRPC::BadStatus => e
-    GRPC.logger.info("ruby xds: rpc failed:|#{e.message}|, " \
-                     "this may or may not be expected")
     if fail_on_failed_rpcs
       raise e
     end
   end
+  $accumulated_stats_mu.synchronize do
+    if remote_peer.empty?
+      $num_rpcs_failed_by_method[rpc_stats_key] += 1
+    else
+      $num_rpcs_succeeded_by_method[rpc_stats_key] += 1
+    end
+  end
   remote_peer
 end
 
+def execute_rpc_in_thread(op, rpc_stats_key)
+  Thread.new {
+    begin
+      op.execute
+      # The following should _not_ happen with the current spec
+      # because we are only executing RPCs in a thread if we expect it
+      # to be kept open, or deadline_exceeded, or dropped by the load
+      # balancing policy. These RPCs should not complete successfully.
+      # Doing this for consistency
+      $accumulated_stats_mu.synchronize do
+        $num_rpcs_succeeded_by_method[rpc_stats_key] += 1
+      end
+    rescue GRPC::BadStatus => e
+      # Normal execution arrives here,
+      # either because of deadline_exceeded or "call dropped by load
+      # balancing policy"
+      $accumulated_stats_mu.synchronize do
+        $num_rpcs_failed_by_method[rpc_stats_key] += 1
+      end
+    end
+  }
+end
+
 # send 1 rpc every 1/qps second
-def run_test_loop(stub, target_seconds_between_rpcs, fail_on_failed_rpcs,
-                  rpcs_to_send, metadata_to_send)
+def run_test_loop(stub, target_seconds_between_rpcs, fail_on_failed_rpcs)
   include Grpc::Testing
   simple_req = SimpleRequest.new()
   empty_req = Empty.new()
   target_next_start = Process.clock_gettime(Process::CLOCK_MONOTONIC)
+  # Some RPCs are meant to be "kept open". Since Ruby does not have an
+  # async API, we are executing those RPCs in a thread so that they don't
+  # block.
+  keep_open_threads = Array.new
   while !$shutdown
     now = Process.clock_gettime(Process::CLOCK_MONOTONIC)
     sleep_seconds = target_next_start - now
     if sleep_seconds < 0
       target_next_start = now + target_seconds_between_rpcs
-      GRPC.logger.info(
-        "ruby xds: warning, rpc takes too long to finish. " \
-        "Deficit = %.1fms. " \
-        "If you consistently see this, the qps is too high." \
-        % [(sleep_seconds * 1000).abs().round(1)])
     else
       target_next_start += target_seconds_between_rpcs
       sleep(sleep_seconds)
     end
     deadline = GRPC::Core::TimeConsts::from_relative_time(30) # 30 seconds
     results = {}
-    rpcs_to_send.each do |rpc|
-      metadata = metadata_to_send.key?(rpc) ? metadata_to_send[rpc] : {}
-      if rpc == 'UnaryCall'
+    $rpc_config.rpcs_to_send.each do |rpc|
+      # rpc is in the form of :UNARY_CALL or :EMPTY_CALL here
+      metadata = $rpc_config.metadata_to_send.key?(rpc) ?
+                   $rpc_config.metadata_to_send[rpc] : {}
+      $accumulated_stats_mu.synchronize do
+        $num_rpcs_started_by_method[rpc.to_s] += 1
+        num_started = $num_rpcs_started_by_method[rpc.to_s]
+        if num_started % 100 == 0
+          GRPC.logger.info("Started #{num_started} of #{rpc}")
+        end
+      end
+      if rpc == :UNARY_CALL
         op = stub.unary_call(simple_req,
                              metadata: metadata,
                              deadline: deadline,
                              return_op: true)
-      elsif rpc == 'EmptyCall'
+      elsif rpc == :EMPTY_CALL
         op = stub.empty_call(empty_req,
                              metadata: metadata,
                              deadline: deadline,
                              return_op: true)
       else
-        raise "Unsupported rpc %s" % [rpc]
+        raise "Unsupported rpc #{rpc}"
+      end
+      rpc_stats_key = rpc.to_s
+      if metadata.key?('rpc-behavior') and
+        (metadata['rpc-behavior'] == 'keep-open')
+        num_open_threads = keep_open_threads.size
+        if num_open_threads % 50 == 0
+          GRPC.logger.info("number of keep_open_threads = #{num_open_threads}")
+        end
+        keep_open_threads << execute_rpc_in_thread(op, rpc_stats_key)
+      else
+        results[rpc] = execute_rpc(op, fail_on_failed_rpcs, rpc_stats_key)
       end
-      results[rpc] = execute_rpc(op, fail_on_failed_rpcs)
     end
     $watchers_mutex.synchronize do
       $watchers.each do |watcher|
         # this is counted once when each group of all rpcs_to_send were done
         watcher['rpcs_needed'] -= 1
         results.each do |rpc_name, remote_peer|
+          # These stats expect rpc_name to be in the form of
+          # UnaryCall or EmptyCall, not the underscore-case all-caps form
+          rpc_name = $RPC_MAP.invert()[rpc_name]
           if remote_peer.strip.empty?
             # error is counted per individual RPC
             watcher['no_remote_peer'] += 1
@@ -191,6 +301,7 @@ def run_test_loop(stub, target_seconds_between_rpcs, fail_on_failed_rpcs,
       $watchers_cv.broadcast
     end
   end
+  keep_open_threads.each { |thd| thd.join }
 end
 
 # Args is used to hold the command line info.
@@ -242,18 +353,22 @@ def main
   s = GRPC::RpcServer.new
   s.add_http2_port(host, :this_port_is_insecure)
   s.handle(TestTarget)
+  s.handle(ConfigureTarget)
   server_thread = Thread.new {
     # run the server until the main test runner terminates this process
     s.run_till_terminated_or_interrupted(['TERM'])
   }
 
-  # The client just sends unary rpcs continuously in a regular interval
+  # Initialize stats
+  $RPC_MAP.values.each do |rpc|
+    $num_rpcs_started_by_method[rpc.to_s] = 0
+    $num_rpcs_succeeded_by_method[rpc.to_s] = 0
+    $num_rpcs_failed_by_method[rpc.to_s] = 0
+  end
+
+  # The client just sends rpcs continuously in a regular interval
   stub = create_stub(opts)
   target_seconds_between_rpcs = (1.0 / opts['qps'].to_f)
-  rpcs_to_send = []
-  if opts['rpc']
-    rpcs_to_send = opts['rpc'].split(',')
-  end
   # Convert 'metadata' input in the form of
   #   rpc1:k1:v1,rpc2:k2:v2,rpc1:k3:v3
   # into
@@ -266,11 +381,13 @@ def main
   #       'k2' => 'v2'
   #     },
   #   }
+  rpcs_to_send = []
   metadata_to_send = {}
   if opts['metadata']
     metadata_entries = opts['metadata'].split(',')
     metadata_entries.each do |e|
       (rpc_name, metadata_key, metadata_value) = e.split(':')
+      rpc_name = $RPC_MAP[rpc_name]
       # initialize if we haven't seen this rpc_name yet
       if !metadata_to_send.key?(rpc_name)
         metadata_to_send[rpc_name] = {}
@@ -278,12 +395,20 @@ def main
       metadata_to_send[rpc_name][metadata_key] = metadata_value
     end
   end
+  if opts['rpc']
+    rpcs_to_send = opts['rpc'].split(',')
+  end
+  if rpcs_to_send.size > 0
+    rpcs_to_send.map! { |rpc| $RPC_MAP[rpc] }
+    new_rpc_config = RpcConfig.new
+    new_rpc_config.init(rpcs_to_send, metadata_to_send)
+    $rpc_config = new_rpc_config
+  end
   client_threads = Array.new
   opts['num_channels'].times {
     client_threads << Thread.new {
       run_test_loop(stub, target_seconds_between_rpcs,
-                    opts['fail_on_failed_rpcs'],
-                    rpcs_to_send, metadata_to_send)
+                    opts['fail_on_failed_rpcs'])
     }
   }
 
index d902ae0..3a44783 100644 (file)
@@ -76,6 +76,28 @@ Google::Protobuf::DescriptorPool.generated_pool.build do
     add_message "grpc.testing.LoadBalancerStatsResponse.RpcsByPeer" do
       map :rpcs_by_peer, :string, :int32, 1
     end
+    add_message "grpc.testing.LoadBalancerAccumulatedStatsRequest" do
+    end
+    add_message "grpc.testing.LoadBalancerAccumulatedStatsResponse" do
+      map :num_rpcs_started_by_method, :string, :int32, 1
+      map :num_rpcs_succeeded_by_method, :string, :int32, 2
+      map :num_rpcs_failed_by_method, :string, :int32, 3
+    end
+    add_message "grpc.testing.ClientConfigureRequest" do
+      repeated :types, :enum, 1, "grpc.testing.ClientConfigureRequest.RpcType"
+      repeated :metadata, :message, 2, "grpc.testing.ClientConfigureRequest.Metadata"
+    end
+    add_message "grpc.testing.ClientConfigureRequest.Metadata" do
+      optional :type, :enum, 1, "grpc.testing.ClientConfigureRequest.RpcType"
+      optional :key, :string, 2
+      optional :value, :string, 3
+    end
+    add_enum "grpc.testing.ClientConfigureRequest.RpcType" do
+      value :EMPTY_CALL, 0
+      value :UNARY_CALL, 1
+    end
+    add_message "grpc.testing.ClientConfigureResponse" do
+    end
     add_enum "grpc.testing.PayloadType" do
       value :COMPRESSABLE, 0
     end
@@ -104,6 +126,12 @@ module Grpc
     LoadBalancerStatsRequest = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("grpc.testing.LoadBalancerStatsRequest").msgclass
     LoadBalancerStatsResponse = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("grpc.testing.LoadBalancerStatsResponse").msgclass
     LoadBalancerStatsResponse::RpcsByPeer = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("grpc.testing.LoadBalancerStatsResponse.RpcsByPeer").msgclass
+    LoadBalancerAccumulatedStatsRequest = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("grpc.testing.LoadBalancerAccumulatedStatsRequest").msgclass
+    LoadBalancerAccumulatedStatsResponse = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("grpc.testing.LoadBalancerAccumulatedStatsResponse").msgclass
+    ClientConfigureRequest = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("grpc.testing.ClientConfigureRequest").msgclass
+    ClientConfigureRequest::Metadata = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("grpc.testing.ClientConfigureRequest.Metadata").msgclass
+    ClientConfigureRequest::RpcType = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("grpc.testing.ClientConfigureRequest.RpcType").enummodule
+    ClientConfigureResponse = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("grpc.testing.ClientConfigureResponse").msgclass
     PayloadType = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("grpc.testing.PayloadType").enummodule
     GrpclbRouteType = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("grpc.testing.GrpclbRouteType").enummodule
   end
index f64b4f6..b99cfed 100644 (file)
@@ -71,14 +71,10 @@ describe 'Code Generation Options' do
 end
 
 def with_protos(file_paths)
-  fail 'CONFIG env variable unexpectedly unset' unless ENV['CONFIG']
-  bins_sub_dir = ENV['CONFIG']
-
   pb_dir = File.dirname(__FILE__)
-  bins_dir = File.join('..', '..', '..', '..', '..', 'bins', bins_sub_dir)
-
+  bins_dir = File.join('..', '..', '..', '..', '..', 'cmake', 'build')
   plugin = File.join(bins_dir, 'grpc_ruby_plugin')
-  protoc = File.join(bins_dir, 'protobuf', 'protoc')
+  protoc = File.join(bins_dir, 'third_party', 'protobuf', 'protoc')
 
   # Generate the service from the proto
   Dir.mktmpdir(nil, File.dirname(__FILE__)) do |tmp_dir|
index 28c7970..ce3b428 100644 (file)
@@ -14,6 +14,6 @@
 
 module GRPC
   module Tools
-    VERSION = '1.34.1'
+    VERSION = '1.35.0'
   end
 end
index 3bbc44c..71a4886 100755 (executable)
@@ -29,15 +29,17 @@ try:
         'build': 'all',
         'language': 'c',
         'src': [
+            "third_party/upb/upb/decode_fast.c",
             "third_party/upb/upb/decode.c",
+            "third_party/upb/upb/def.c",
             "third_party/upb/upb/encode.c",
+            "third_party/upb/upb/json_decode.c",
+            "third_party/upb/upb/json_encode.c",
             "third_party/upb/upb/msg.c",
-            "third_party/upb/upb/port.c",
-            "third_party/upb/upb/table.c",
-            "third_party/upb/upb/upb.c",
-            "third_party/upb/upb/def.c",
             "third_party/upb/upb/reflection.c",
+            "third_party/upb/upb/table.c",
             "third_party/upb/upb/text_encode.c",
+            "third_party/upb/upb/upb.c",
             "src/core/ext/upb-generated/google/protobuf/any.upb.c",
             "src/core/ext/upb-generated/google/protobuf/descriptor.upb.c",
             "src/core/ext/upb-generated/google/protobuf/duration.upb.c",
@@ -54,18 +56,24 @@ try:
             "src/core/ext/upbdefs-generated/google/protobuf/wrappers.upbdefs.c",
         ],
         'headers': [
+            "third_party/upb/upb/decode_fast.h",
             "third_party/upb/upb/decode.h",
+            "third_party/upb/upb/decode.int.h",
+            "third_party/upb/upb/def.h",
+            "third_party/upb/upb/def.hpp",
             "third_party/upb/upb/encode.h",
+            "third_party/upb/upb/json_decode.h",
+            "third_party/upb/upb/json_encode.h",
             "third_party/upb/upb/msg.h",
             "third_party/upb/upb/port_def.inc",
             "third_party/upb/upb/port_undef.inc",
+            "third_party/upb/upb/reflection.h",
             "third_party/upb/upb/table.int.h",
+            "third_party/upb/upb/text_encode.h",
             "third_party/upb/upb/upb.h",
             "third_party/upb/upb/upb.hpp",
-            "third_party/upb/upb/def.h",
-            "third_party/upb/upb/def.hpp",
-            "third_party/upb/upb/reflection.h",
-            "third_party/upb/upb/text_encode.h",
+            "third_party/upb/upb/upb.int.h",
+            "third_party/upb/third_party/wyhash/wyhash.h",
             "src/core/ext/upb-generated/google/protobuf/any.upb.h",
             "src/core/ext/upb-generated/google/protobuf/descriptor.upb.h",
             "src/core/ext/upb-generated/google/protobuf/duration.upb.h",
index 50f5d42..fe37dbd 100644 (file)
     def is_absl_lib(target_name):
       return target_name.startswith("absl/");
 
-    proto_re = re.compile('(.*)\\.proto')
-
-    def proto_to_cc(filename):
-      m = proto_re.match(filename)
-      if not m:
-        return filename
-      return '$(GENDIR)/' + m.group(1) + '.pb.cc $(GENDIR)/' + m.group(1) + '.grpc.pb.cc'
-
     sources_that_need_openssl = set()
     sources_that_don_t_need_openssl = set()
 
@@ -65,8 +57,8 @@
     # Currently it is necessary because some dependencies are marked as "build: private" in build.yaml
     # (which itself is correct, as they are not "public" libraries from our perspective and cmake
     # needs to have them marked as such)
-    filtered_libs = [lib for lib in libs if lib.build in ['all', 'protoc'] or lib.name in ['ares', 'boringssl', 're2', 'upb', 'z']]
-    filtered_targets = [tgt for tgt in targets if tgt.build in ['all', 'protoc']]
+    filtered_libs = [lib for lib in libs if (lib.build in ['all'] and lib.language != 'c++') or lib.name in ['ares', 'boringssl', 're2', 'upb', 'z']]
+    filtered_targets = [tgt for tgt in targets if tgt.build in ['all'] and lib.language != 'c++']
   %>
 
   comma := ,
 
   prefix ?= /usr/local
 
-  PROTOC ?= protoc
   DTRACE ?= dtrace
   CONFIG ?= opt
   # Doing X ?= Y is the same as:
   
   LDLIBS_SECURE += $(addprefix -l, $(LIBS_SECURE))
 
-  # Setup protobuf dependency
-  
-  # we only support building protobuf from submodule
-  HAS_SYSTEM_PROTOBUF = false
-  HAS_PROTOC = false
-  HAS_VALID_PROTOC = false
-  ifeq ($(wildcard third_party/protobuf/src/google/protobuf/descriptor.pb.h),)
-  HAS_EMBEDDED_PROTOBUF = false
-  ifneq ($(HAS_VALID_PROTOC),true)
-  NO_PROTOC = true
-  endif
-  else
-  HAS_EMBEDDED_PROTOBUF = true
-  endif
-
-  PROTOC_PLUGINS_DIR = $(BINDIR)/$(CONFIG)
-
-  PROTOC_PLUGINS_ALL =\
-  % for tgt in filtered_targets:
-  % if tgt.build == 'protoc':
-   $(BINDIR)/$(CONFIG)/${tgt.name}\
-  % endif
-  % endfor
-
-  ifeq ($(HAS_EMBEDDED_PROTOBUF),true)
-  PROTOBUF_DEP = $(LIBDIR)/$(CONFIG)/protobuf/libprotobuf.a
-  CPPFLAGS := -Ithird_party/protobuf/src $(CPPFLAGS)
-  LDFLAGS := -L$(LIBDIR)/$(CONFIG)/protobuf $(LDFLAGS)
-  PROTOC = $(BINDIR)/$(CONFIG)/protobuf/protoc
-  PROTOC_PLUGINS = $(PROTOC_PLUGINS_ALL)
-  else
-  NO_PROTOBUF = true
-  endif
-
-  LIBS_PROTOBUF = protobuf
-  LIBS_PROTOC = protoc protobuf
-  HOST_LDLIBS_PROTOC += $(addprefix -l, $(LIBS_PROTOC))
-  LDLIBS_PROTOBUF += $(addprefix -l, $(LIBS_PROTOBUF))
-
   ifeq ($(MAKECMDGOALS),clean)
   NO_DEPS = true
   endif
   .SECONDARY = %.pb.h %.pb.cc
 
   ifeq ($(DEP_MISSING),)
-  all: static shared plugins\
+  all: static shared\
   % for tgt in filtered_targets:
   % if tgt.build == 'all':
    $(BINDIR)/$(CONFIG)/${tgt.name}\
 
   openssl_dep_error: openssl_dep_message git_update stop
 
-  protobuf_dep_error: protobuf_dep_message git_update stop
-
-  protoc_dep_error: protoc_dep_message git_update stop
-
   openssl_dep_message:
        @echo
        @echo "DEPENDENCY ERROR"
        @echo "  make run_dep_checks"
        @echo
 
-  protobuf_dep_message:
-       @echo
-       @echo "DEPENDENCY ERROR"
-       @echo
-       @echo "The target you are trying to run requires protobuf 3.12.0+"
-       @echo "Your system doesn't have it, and neither does the third_party directory."
-       @echo
-       @echo "Please consult BUILDING.md to get more information."
-       @echo
-       @echo "If you need information about why these tests failed, run:"
-       @echo
-       @echo "  make run_dep_checks"
-       @echo
-
-  protoc_dep_message:
-       @echo
-       @echo "DEPENDENCY ERROR"
-       @echo
-       @echo "The target you are trying to run requires protobuf-compiler 3.12.0+"
-       @echo "Your system doesn't have it, and neither does the third_party directory."
-       @echo
-       @echo "Please consult BUILDING.md to get more information."
-       @echo
-       @echo "If you need information about why these tests failed, run:"
-       @echo
-       @echo "  make run_dep_checks"
-       @echo
-
   systemtap_dep_error:
        @echo
        @echo "DEPENDENCY ERROR"
   run_dep_checks:
        @echo "run_dep_checks target has been deprecated."
 
-  third_party/protobuf/configure:
-       $(E) "[AUTOGEN] Preparing protobuf"
-       $(Q)(cd third_party/protobuf ; autoreconf -f -i -Wall,no-obsolete)
-
-  $(LIBDIR)/$(CONFIG)/protobuf/libprotobuf.a: third_party/protobuf/configure
-       $(E) "[MAKE]    Building protobuf"
-       $(Q)mkdir -p $(LIBDIR)/$(CONFIG)/protobuf
-       $(Q)(cd third_party/protobuf ; CC="$(CC)" CXX="$(CXX)" LDFLAGS="$(LDFLAGS_$(CONFIG)) -g $(PROTOBUF_LDFLAGS_EXTRA)" CPPFLAGS="$(PIC_CPPFLAGS) $(CPPFLAGS_$(CONFIG)) -g $(PROTOBUF_CPPFLAGS_EXTRA)" ./configure --disable-shared --enable-static $(PROTOBUF_CONFIG_OPTS))
-       $(Q)$(MAKE) -C third_party/protobuf clean
-       $(Q)$(MAKE) -C third_party/protobuf
-       $(Q)mkdir -p $(BINDIR)/$(CONFIG)/protobuf
-       $(Q)cp third_party/protobuf/src/.libs/libprotoc.a $(LIBDIR)/$(CONFIG)/protobuf
-       $(Q)cp third_party/protobuf/src/.libs/libprotobuf.a $(LIBDIR)/$(CONFIG)/protobuf
-       $(Q)cp third_party/protobuf/src/protoc $(BINDIR)/$(CONFIG)/protobuf
-
   static: static_c static_cxx
 
   static_c: cache.mk \
 
   grpc_csharp_ext: shared_csharp
 
-  plugins: $(PROTOC_PLUGINS)
-
   privatelibs: privatelibs_c privatelibs_cxx
 
   privatelibs_c: \
        $(E) "[MAKE]    Generating $@"
        $(Q) echo "$(CACHE_MK)" | tr , '\n' >$@
 
-  % for p in protos:
-  ifeq ($(NO_PROTOC),true)
-  $(GENDIR)/${p}.pb.cc: protoc_dep_error
-  $(GENDIR)/${p}.grpc.pb.cc: protoc_dep_error
-  else
-  <%
-    pluginflags=""
-  %>
-  % if p in ["src/proto/grpc/testing/compiler_test", "src/proto/grpc/testing/echo"]:
-  <%
-    pluginflags="generate_mock_code=true:"
-  %>
-  % endif
-  $(GENDIR)/${p}.pb.cc: ${p}.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS) ${' '.join('$(GENDIR)/%s.pb.cc' % q for q in proto_deps.get(p, []))}
-       $(E) "[PROTOC]  Generating protobuf CC file from $<"
-       $(Q) mkdir -p `dirname $@`
-       $(Q) $(PROTOC) -Ithird_party/protobuf/src -I. --cpp_out=$(GENDIR) $<
-
-  $(GENDIR)/${p}.grpc.pb.cc: ${p}.proto $(GENDIR)/${p}.pb.cc $(PROTOBUF_DEP) $(PROTOC_PLUGINS) ${' '.join('$(GENDIR)/%s.pb.cc $(GENDIR)/%s.grpc.pb.cc' % (q,q) for q in proto_deps.get(p, []))}
-       $(E) "[GRPC]    Generating gRPC's protobuf service CC file from $<"
-       $(Q) mkdir -p `dirname $@`
-       $(Q) $(PROTOC) -Ithird_party/protobuf/src -I. --grpc_out=${pluginflags}$(GENDIR) --plugin=protoc-gen-grpc=$(PROTOC_PLUGINS_DIR)/grpc_cpp_plugin$(EXECUTABLE_SUFFIX) $<
-  endif
-
-  % endfor
-
   ifeq ($(CONFIG),stapprof)
   src/core/profiling/stap_timers.c: $(GENDIR)/src/core/profiling/stap_probes.h
   ifeq ($(HAS_SYSTEMTAP),true)
   %>
   ${makelib(grpc_abseil_lib)}
 
-  # All of the test targets, and protoc plugins
-
-  % for tgt in filtered_targets:
-  ${maketarget(tgt)}
-  % endfor
-
   <%def name="makelib(lib)">
   # start of build recipe for library "${lib.name}" (generated by makelib(lib) template function)
   LIB${lib.name.upper()}_SRC = \\
 
   % for src in lib.src:
-      ${proto_to_cc(src)} \\
+      ${src} \\
 
   % endfor
 
 
   else
 
-  % if lib.language == 'c++':
-  ifeq ($(NO_PROTOBUF),true)
-
-  # You can't build a C++ library if you don't have protobuf - a bit overreached, but still okay.
-
-  $(LIBDIR)/$(CONFIG)/lib${lib.name}.a: protobuf_dep_error
-
-  % if lib.build == "all":
-  $(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)${lib.name}$(SHARED_VERSION_${lang_to_var[lib.language]}).$(SHARED_EXT_${lang_to_var[lib.language]}): protobuf_dep_error
-  % endif
-
-  else
-  % endif
-
   $(LIBDIR)/$(CONFIG)/lib${lib.name}.a: $(ZLIB_DEP) $(OPENSSL_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(RE2_DEP) $(UPB_DEP) $(GRPC_ABSEIL_DEP) \
   ## The else here corresponds to the if secure earlier.
   % else:
-  % if lib.language == 'c++':
-  ifeq ($(NO_PROTOBUF),true)
-
-  # You can't build a C++ library if you don't have protobuf - a bit overreached, but still okay.
-
-  $(LIBDIR)/$(CONFIG)/lib${lib.name}.a: protobuf_dep_error
-
-  % if lib.build == "all":
-  $(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)${lib.name}$(SHARED_VERSION_${lang_to_var[lib.language]}).$(SHARED_EXT_${lang_to_var[lib.language]}): protobuf_dep_error
-  % endif
-
-  else
-
-  % endif
   $(LIBDIR)/$(CONFIG)/lib${lib.name}.a: \
   % if lib.name not in ['z', 'ares', 'address_sorting', 're2', 'upb', 'grpc_abseil']:
   $(ZLIB_DEP) \
   $(GRPC_ABSEIL_DEP) \
   % endif
   % endif
-  % if lib.language == 'c++':
-   $(PROTOBUF_DEP)\
-  % endif
    $(LIB${lib.name.upper()}_OBJS) \
   % if lib.get('baselib', False):
    $(LIBGPR_OBJS) \
   endif
 
   <%
-
-    if lib.language == 'c++':
-      ld = '$(LDXX)'
-    else:
-      ld = '$(LDXX)'
+    ld = '$(LDXX)'
 
     out_mingbase = '$(LIBDIR)/$(CONFIG)/' + lib.name + '$(SHARED_VERSION_' + lang_to_var[lib.language] + ')'
     out_libbase = '$(LIBDIR)/$(CONFIG)/lib' + lib.name + '$(SHARED_VERSION_' + lang_to_var[lib.language] + ')'
     lib_deps = ' $(ZLIB_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(RE2_DEP) $(UPB_DEP) $(GRPC_ABSEIL_DEP)'
     mingw_libs = ''
     mingw_lib_deps = ' $(ZLIB_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(RE2_DEP) $(UPB_DEP) $(GRPC_ABSEIL_DEP)'
-    if lib.language == 'c++':
-      lib_deps += ' $(PROTOBUF_DEP)'
-      mingw_lib_deps += ' $(PROTOBUF_DEP)'
     if lib.get('deps_linkage', None) == 'static':
       for dep in lib.get('deps', []):
         if is_absl_lib(dep): continue
 
     if security in [True, 'check']:
       for src in lib.src:
-        if not proto_re.match(src):
-          sources_that_need_openssl.add(src)
+        sources_that_need_openssl.add(src)
     else:
       for src in lib.src:
         sources_that_don_t_need_openssl.add(src)
       lib_deps = lib_deps + ' $(OPENSSL_DEP)'
       mingw_lib_deps = mingw_lib_deps + ' $(OPENSSL_DEP)'
 
-    if lib.language == 'c++':
-      common = common + ' $(LDLIBSXX) $(LDLIBS_PROTOBUF)'
-
     ldflags = '$(LDFLAGS)'
     if lib.get('LDFLAGS', None):
       ldflags += ' ' + lib['LDFLAGS']
 
   endif
   % endif
-  % if lib.language == 'c++':
-  ## If the lib was C++, we have to close the Makefile's if that tested
-  ## the presence of protobuf 3.12.0+
-
-  endif
-  % endif
 
   % if lib.get('secure', 'check') == True or lib.get('secure', 'check') == 'check':
   ifneq ($(NO_SECURE),true)
   % if lib.get('secure', 'check') == True or lib.get('secure', 'check') == 'check':
   endif
   % endif
-  % for src in lib.src:
-  % if not proto_re.match(src) and any(proto_re.match(src2) for src2 in lib.src):
-  $(OBJDIR)/$(CONFIG)/${os.path.splitext(src)[0]}.o: ${' '.join(proto_to_cc(src2) for src2 in lib.src if proto_re.match(src2))}
-  % endif
-  % endfor
   # end of build recipe for library "${lib.name}"
   </%def>
 
-  <%def name="maketarget(tgt)"><% has_no_sources = not tgt.src %>
-  # start of build recipe for target "${tgt.name}" (generated by maketarget(tgt) template function)
-  % if not has_no_sources:
-  ${tgt.name.upper()}_SRC = \\
-
-  % for src in tgt.src:
-      ${proto_to_cc(src)} \\
-
-  % endfor
-
-  ${tgt.name.upper()}_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(${tgt.name.upper()}_SRC))))
-  % endif
-  % if tgt.get('secure', 'check') == True or tgt.get('secure', 'check') == 'check':
-  ifeq ($(NO_SECURE),true)
-
-  # You can't build secure targets if you don't have OpenSSL.
-
-  $(BINDIR)/$(CONFIG)/${tgt.name}: openssl_dep_error
-
-  else
-
-  % endif
-
-  % if tgt.boringssl:
-  # boringssl needs an override to ensure that it does not include
-  # system openssl headers regardless of other configuration
-  # we do so here with a target specific variable assignment
-  $(${tgt.name.upper()}_OBJS): CFLAGS := -Ithird_party/boringssl-with-bazel/src/include $(CFLAGS) -Wno-sign-conversion -Wno-conversion -Wno-unused-value $(NO_W_EXTRA_SEMI)
-  $(${tgt.name.upper()}_OBJS): CXXFLAGS := -Ithird_party/boringssl-with-bazel/src/include $(CXXFLAGS)
-  $(${tgt.name.upper()}_OBJS): CPPFLAGS += -DOPENSSL_NO_ASM -D_GNU_SOURCE
-  % else:
-  % endif
-
-  ##
-  ## We're not trying to add a dependency on building zlib and openssl here,
-  ## as it's already done in the libraries. We're assuming that the build
-  ## trickles down, and that a secure target requires a secure version of
-  ## a library.
-  ##
-  ## That simplifies the codegen a bit, but prevents a fully defined Makefile.
-  ## I can live with that.
-  ##
-  % if tgt.build == 'protoc' or tgt.language == 'c++':
-
-  ifeq ($(NO_PROTOBUF),true)
-
-  # You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.12.0+.
-
-  $(BINDIR)/$(CONFIG)/${tgt.name}: protobuf_dep_error
-
-  else
-
-  $(BINDIR)/$(CONFIG)/${tgt.name}: \
-  % if not has_no_sources:
-  $(PROTOBUF_DEP) $(${tgt.name.upper()}_OBJS)\
-  % endif
-  % else:
-  $(BINDIR)/$(CONFIG)/${tgt.name}: \
-  % if not has_no_sources:
-  $(${tgt.name.upper()}_OBJS)\
-  % endif
-  % endif
-  % for dep in tgt.deps:
-  %  if not is_absl_lib(dep):
-   $(LIBDIR)/$(CONFIG)/lib${dep}.a\
-  %  endif
-  % endfor
-
-  % if tgt.language == "c++" or tgt.boringssl or tgt.build == 'fuzzer':
-  ## C++ targets specificies.
-  % if tgt.build == 'protoc':
-       $(E) "[HOSTLD]  Linking $@"
-       $(Q) mkdir -p `dirname $@`
-       $(Q) $(HOST_LDXX) $(HOST_LDFLAGS) \
-  % if not has_no_sources:
-  $(${tgt.name.upper()}_OBJS)\
-  % endif
-  % else:
-       $(E) "[LD]      Linking $@"
-       $(Q) mkdir -p `dirname $@`
-       $(Q) $(LDXX) $(LDFLAGS) \
-  % if not has_no_sources:
-  $(${tgt.name.upper()}_OBJS)\
-  % endif
-  % endif
-  % else:
-  ## C-only targets specificities.
-       $(E) "[LD]      Linking $@"
-       $(Q) mkdir -p `dirname $@`
-       $(Q) $(LDXX) $(LDFLAGS) \
-  % if not has_no_sources:
-  $(${tgt.name.upper()}_OBJS)\
-  % endif
-  % endif
-  % for dep in tgt.deps:
-   $(LIBDIR)/$(CONFIG)/lib${dep}.a\
-  % endfor
-  % if tgt.language == "c++":
-  % if tgt.build == 'protoc':
-   $(HOST_LDLIBSXX) $(HOST_LDLIBS_PROTOC)\
-  % else:
-   $(LDLIBSXX) $(LDLIBS_PROTOBUF)\
-  % endif
-  % endif
-  % if tgt.build == 'protoc':
-   $(HOST_LDLIBS)\
-  % else:
-   $(LDLIBS)\
-  % endif
-  % if tgt.build == 'protoc':
-   $(HOST_LDLIBS_PROTOC)\
-  % elif tgt.get('secure', 'check') == True or tgt.get('secure', 'check') == 'check':
-   $(LDLIBS_SECURE)\
-  % endif
-  % if tgt.build == 'fuzzer':
-   -lFuzzer\
-  % endif
-   -o $(BINDIR)/$(CONFIG)/${tgt.name}
-  % if tgt.build == 'protoc' or tgt.language == 'c++':
-
-  endif
-  % endif
-  % if tgt.get('secure', 'check') == True or tgt.get('secure', 'check') == 'check':
-
-  endif
-  % endif
-
-  % if tgt.get('defaults', None):
-  %  for name, value in defaults.get(tgt.defaults).items():
-  $(${tgt.name.upper()}_OBJS): ${name} += ${value}
-  %  endfor
-  % endif
-  % for src in tgt.src:
-  $(OBJDIR)/$(CONFIG)/${os.path.splitext(src)[0]}.o: \
-  % for dep in tgt.deps:
-   $(LIBDIR)/$(CONFIG)/lib${dep}.a\
-  % endfor
-
-  % if tgt.language == 'c89':
-  % for src in tgt.src:
-  $(OBJDIR)/$(CONFIG)/${os.path.splitext(src)[0]}.o : ${src}
-       $(E) "[C]       Compiling $<"
-       $(Q) mkdir -p `dirname $@`
-       $(Q) $(CC) $(CPPFLAGS) $(CFLAGS) -std=c89 -pedantic -MMD -MF $(addsuffix .dep, $(basename $@)) -c -o $@ $<
-  % endfor
-  % endif
-
-  % endfor
-  % if not has_no_sources:
-  deps_${tgt.name}: $(${tgt.name.upper()}_OBJS:.o=.dep)
-  % endif
-
-  % if not has_no_sources:
-  % if tgt.get('secure', 'check') == True or tgt.get('secure', 'check') == 'check':
-  ifneq ($(NO_SECURE),true)
-  % endif
-  ifneq ($(NO_DEPS),true)
-  -include $(${tgt.name.upper()}_OBJS:.o=.dep)
-  endif
-  % if tgt.get('secure', 'check') == True or tgt.get('secure', 'check') == 'check':
-  endif
-  % endif
-  % endif
-  % for src in tgt.src:
-  % if not proto_re.match(src) and any(proto_re.match(src2) for src2 in tgt.src):
-  $(OBJDIR)/$(CONFIG)/${os.path.splitext(src)[0]}.o: ${' '.join(proto_to_cc(src2) for src2 in tgt.src if proto_re.match(src2))}
-  % endif
-  % endfor
-  # end of build recipe for target "${tgt.name}"
-  </%def>
-
   # TODO(jtattermusch): is there a way to get around this hack?
   ifneq ($(OPENSSL_DEP),)
   # This is to ensure the embedded OpenSSL is built beforehand, properly
index 8d917f5..da3df69 100644 (file)
 
     s.prepare_command = <<-END_OF_COMMAND
       sed -E -i '' 's;#include <openssl/(.*)>;#if COCOAPODS==1\\\n  #include <openssl_grpc/\\1>\\\n#else\\\n  #include <openssl/\\1>\\\n#endif;g' $(find src/core -type f \\( -path '*.h' -or -path '*.cc' \\) -print | xargs grep -H -c '#include <openssl_grpc/' | grep 0$ | cut -d':' -f1)
+      find third_party/upb/ -type f \\( -name '*.h' -or -name '*.hpp' -or -name '*.c' -or -name '*.cc' \\) -print0 | xargs -0 -L1 sed -E -i'.grpc_back' 's;#include "third_party/(.*)";#if COCOAPODS==1\\\n  #include  "third_party/upb/third_party/\\1"\\\n#else\\\n  #include  "third_party/\\1"\\\n#endif;g'
       find src/core/ src/cpp/ third_party/upb/ -type f \\( -name '*.h' -or -name '*.hpp' -or -name '*.c' -or -name '*.cc' \\) -print0 | xargs -0 -L1 sed -E -i'.grpc_back' 's;#include "upb/(.*)";#if COCOAPODS==1\\\n  #include  "third_party/upb/upb/\\1"\\\n#else\\\n  #include  "upb/\\1"\\\n#endif;g'
       find src/core/ src/cpp/ third_party/upb/ -type f -name '*.grpc_back' -print0 | xargs -0 rm
       find src/core/ src/cpp/ third_party/upb/ -type f \\( -name '*.h' -or -name '*.c' -or -name '*.cc' \\) -print0 | xargs -0 -L1 sed -E -i'.grpc_back' 's;#include "(.*).upb.h";#if COCOAPODS==1\\\n  #include  "src/core/ext/upb-generated/\\1.upb.h"\\\n#else\\\n  #include  "\\1.upb.h"\\\n#endif;g'
index 56a082e..81fe0e9 100644 (file)
     # TODO (mxyan): Instead of this hack, add include path "third_party" to C core's include path?
     s.prepare_command = <<-END_OF_COMMAND
       sed -E -i '' 's;#include <openssl/(.*)>;#if COCOAPODS==1\\\n  #include <openssl_grpc/\\1>\\\n#else\\\n  #include <openssl/\\1>\\\n#endif;g' $(find src/core -type f \\( -path '*.h' -or -path '*.cc' \\) -print | xargs grep -H -c '#include <openssl_grpc/' | grep 0$ | cut -d':' -f1)
+      find third_party/upb/ -type f \\( -name '*.h' -or -name '*.hpp' -or -name '*.c' -or -name '*.cc' \\) -print0 | xargs -0 -L1 sed -E -i'.grpc_back' 's;#include "third_party/(.*)";#if COCOAPODS==1\\\n  #include  "third_party/upb/third_party/\\1"\\\n#else\\\n  #include  "third_party/\\1"\\\n#endif;g'
       find src/core/ src/cpp/ third_party/upb/ -type f \\( -name '*.h' -or -name '*.hpp' -or -name '*.c' -or -name '*.cc' \\) -print0 | xargs -0 -L1 sed -E -i'.grpc_back' 's;#include "upb/(.*)";#if COCOAPODS==1\\\n  #include  "third_party/upb/upb/\\1"\\\n#else\\\n  #include  "upb/\\1"\\\n#endif;g'
       find src/core/ src/cpp/ third_party/upb/ -type f -name '*.grpc_back' -print0 | xargs -0 rm
       find src/core/ src/cpp/ third_party/upb/ -type f \\( -name '*.h' -or -name '*.c' -or -name '*.cc' \\) -print0 | xargs -0 -L1 sed -E -i'.grpc_back' 's;#include "(.*).upb.h";#if COCOAPODS==1\\\n  #include  "src/core/ext/upb-generated/\\1.upb.h"\\\n#else\\\n  #include  "\\1.upb.h"\\\n#endif;g'
index c9a5cc7..a5e0801 100644 (file)
@@ -34,7 +34,7 @@
     s.require_paths = %w( src/ruby/lib src/ruby/bin src/ruby/pb )
     s.platform      = Gem::Platform::RUBY
 
-    s.add_dependency 'google-protobuf', '~> 3.13'
+    s.add_dependency 'google-protobuf', '~> ${settings.protobuf_major_minor_version}'
     s.add_dependency 'googleapis-common-protos-types', '~> 1.0'
 
     s.add_development_dependency 'bundler',            '>= 1.9'
index 8c21a9f..ca55dd9 100755 (executable)
@@ -4,6 +4,6 @@
   <Project>
     <PropertyGroup>
       <GrpcCsharpVersion>${settings.csharp_version}</GrpcCsharpVersion>
-      <GoogleProtobufVersion>3.13.0</GoogleProtobufVersion>
+      <GoogleProtobufVersion>${settings.protobuf_version}</GoogleProtobufVersion>
     </PropertyGroup>
   </Project>
index 626e3c8..27aaacf 100644 (file)
     s.preserve_paths = plugin
 
     # Restrict the protoc version to the one supported by this plugin.
-    s.dependency '!ProtoCompiler', '3.13.0'
+    s.dependency '!ProtoCompiler', '${settings.protobuf_version}'
     # For the Protobuf dependency not to complain:
     s.ios.deployment_target = '9.0'
     s.osx.deployment_target = '10.10'
index fec8994..34a244c 100644 (file)
     s.preserve_paths = plugin
 
     # Restrict the protoc version to the one supported by this plugin.
-    s.dependency '!ProtoCompiler', '3.13.0'
+    s.dependency '!ProtoCompiler', '${settings.protobuf_version}'
     # For the Protobuf dependency not to complain:
     s.ios.deployment_target = '9.0'
     s.osx.deployment_target = '10.10'
diff --git a/templates/src/objective-c/!ProtoCompiler.podspec.template b/templates/src/objective-c/!ProtoCompiler.podspec.template
new file mode 100644 (file)
index 0000000..c1ca9da
--- /dev/null
@@ -0,0 +1,135 @@
+%YAML 1.2
+--- |
+  # Proto Compiler CocoaPods podspec
+  
+  # Copyright 2016, Google Inc.
+  # All rights reserved.
+  #
+  # Redistribution and use in source and binary forms, with or without
+  # modification, are permitted provided that the following conditions are
+  # met:
+  #
+  #     * Redistributions of source code must retain the above copyright
+  # notice, this list of conditions and the following disclaimer.
+  #     * Redistributions in binary form must reproduce the above
+  # copyright notice, this list of conditions and the following disclaimer
+  # in the documentation and/or other materials provided with the
+  # distribution.
+  #     * Neither the name of Google Inc. nor the names of its
+  # contributors may be used to endorse or promote products derived from
+  # this software without specific prior written permission.
+  #
+  # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+  # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+  # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+  # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+  # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+  # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+  # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+  # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+  # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+  # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+  # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+  
+  Pod::Spec.new do |s|
+    # This pod is only a utility that will be used by other pods _at install time_ (not at compile
+    # time). Other pods can access it in their `prepare_command` script, under <pods_root>/<pod name>.
+    # Because CocoaPods installs pods in alphabetical order, beginning this pod's name with an
+    # exclamation mark ensures that other "regular" pods will be able to find it as it'll be installed
+    # before them.
+    s.name     = '!ProtoCompiler'
+    v = '${settings.protobuf_version}'
+    s.version  = v
+    s.summary  = 'The Protobuf Compiler (protoc) generates Objective-C files from .proto files'
+    s.description = <<-DESC
+      This podspec only downloads protoc so that local pods generating protos can execute it as part
+      of their prepare_command.
+      The generated code will have a dependency on the Protobuf Objective-C runtime of the same
+      version. The runtime can be obtained as the "Protobuf" pod.
+    DESC
+    s.homepage = 'https://github.com/google/protobuf'
+    s.license  = {
+      :type => 'New BSD',
+      :text => <<-LICENSE
+        This license applies to all parts of Protocol Buffers except the following:
+  
+        - Atomicops support for generic gcc, located in
+          src/google/protobuf/stubs/atomicops_internals_generic_gcc.h.
+          This file is copyrighted by Red Hat Inc.
+  
+        - Atomicops support for AIX/POWER, located in
+          src/google/protobuf/stubs/atomicops_internals_power.h.
+          This file is copyrighted by Bloomberg Finance LP.
+  
+        Copyright 2014, Google Inc.  All rights reserved.
+  
+        Redistribution and use in source and binary forms, with or without
+        modification, are permitted provided that the following conditions are
+        met:
+  
+            * Redistributions of source code must retain the above copyright
+        notice, this list of conditions and the following disclaimer.
+            * Redistributions in binary form must reproduce the above
+        copyright notice, this list of conditions and the following disclaimer
+        in the documentation and/or other materials provided with the
+        distribution.
+            * Neither the name of Google Inc. nor the names of its
+        contributors may be used to endorse or promote products derived from
+        this software without specific prior written permission.
+  
+        THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+        "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+        LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+        A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+        OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+        SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+        LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+        DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+        THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+        (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+        OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+  
+        Code generated by the Protocol Buffer compiler is owned by the owner
+        of the input file used when generating it.  This code is not
+        standalone and requires a support library to be linked with it.  This
+        support library is itself covered by the above license.
+      LICENSE
+    }
+    # "The name and email addresses of the library maintainers, not the Podspec maintainer."
+    s.authors  = { 'The Protocol Buffers contributors' => 'protobuf@googlegroups.com' }
+  
+    repo = 'google/protobuf'
+    file = "protoc-#{v}-osx-x86_64.zip"
+    s.source = {
+      :http => "https://github.com/#{repo}/releases/download/v#{v}/#{file}",
+      # TODO(jcanizales): Add sha1 or sha256
+      # :sha1 => '??',
+    }
+  
+    s.preserve_paths = 'protoc',
+                       'google/**/*.proto' # Well-known protobuf types
+  
+    # Restrict the protobuf runtime version to the one supported by this version of protoc.
+    s.dependency 'Protobuf', '~> 3.0'
+    # For the Protobuf dependency not to complain:
+    s.ios.deployment_target = '9.0'
+    s.osx.deployment_target = '10.10'
+    s.tvos.deployment_target = '10.0'
+    s.watchos.deployment_target = '4.0'
+  
+    # This is only for local development of protoc: If the Podfile brings this pod from a local
+    # directory using `:path`, CocoaPods won't download the zip file and so the compiler won't be
+    # present in this pod's directory. We use that knowledge to check for the existence of the file
+    # and, if absent, build it from the local sources.
+    repo_root = '../..'
+    bazel = "#{repo_root}/tools/bazel"
+    
+    s.prepare_command = <<-CMD
+      if [ ! -f bin/protoc ]; then
+        #{bazel} build @com_google_protobuf//:protoc
+      else
+        mv bin/protoc .
+        mv include/google .
+      fi
+    CMD
+  end
index 8d5e17f..11da1d8 100644 (file)
@@ -1,3 +1,3 @@
-RUN wget https://phar.phpunit.de/phpunit-8.5.8.phar && ${'\\'}
-  mv phpunit-8.5.8.phar /usr/local/bin/phpunit && ${'\\'}
+RUN wget https://phar.phpunit.de/phpunit-8.5.13.phar && ${'\\'}
+  mv phpunit-8.5.13.phar /usr/local/bin/phpunit && ${'\\'}
   chmod +x /usr/local/bin/phpunit
index eb00edb..d8c7ffb 100644 (file)
@@ -14,7 +14,7 @@
   # See the License for the specific language governing permissions and
   # limitations under the License.
 
-  FROM php:8.0.0RC3-cli-buster
+  FROM php:8.0.0-zts-buster
 
   RUN apt-get -qq update && apt-get -qq install -y ${'\\'}
     autoconf automake git libtool pkg-config ${'\\'}
@@ -31,6 +31,8 @@
     expect -c 'spawn php ./go-pear.phar; expect "or Enter to continue:"; send "\n"; expect "Currently used php.ini"; send "\n"; expect eof' && ${'\\'}
     rm go-pear.phar
 
+  <%include file="../download_phpunit.include" />
+
   <%include file="../pecl_ext_build_src.include" />
 
-  CMD php -d extension=grpc.so -r '$a = new \Grpc\Channel("dummy", []); echo get_class($a)."\n";'
+  CMD ["/github/grpc/src/php/bin/run_tests.sh", "--skip-persistent-channel-tests", "--ignore-valgrind-undef-errors"]
index 8be5ba2..4330369 100644 (file)
@@ -39,6 +39,9 @@ argp.add_argument('--dns_resolver_bin_path', default=None, type=str,
                   help=('Path to the DNS health check utility.'))
 argp.add_argument('--tcp_connect_bin_path', default=None, type=str,
                   help=('Path to the TCP health check utility.'))
+argp.add_argument('--extra_args', default='', type=str,
+                  help=('Comma-separate list of command args to '
+                       'plumb through to --test_bin_path'))
 args = argp.parse_args()
 
 def test_runner_log(msg):
@@ -77,9 +80,9 @@ def wait_until_dns_server_is_up(args,
           '--server_host', '127.0.0.1',
           '--server_port', str(args.dns_server_port)]),
           stdout=subprocess.PIPE)
-      dns_resolver_stdout, _ = dns_resolver_subprocess.communicate()
+      dns_resolver_stdout, _ = dns_resolver_subprocess.communicate(str.encode('ascii'))
       if dns_resolver_subprocess.returncode == 0:
-        if '123.123.123.123' in dns_resolver_stdout:
+        if '123.123.123.123'.encode('ascii') in dns_resolver_stdout:
           test_runner_log(('DNS server is up! '
                            'Successfully reached it over UDP and TCP.'))
         return
@@ -131,7 +134,8 @@ current_test_subprocess = subprocess.Popen([\
 
 \
   % endfor
-  '--local_dns_server_address', '127.0.0.1:%d' % args.dns_server_port])\
+  '--local_dns_server_address', '127.0.0.1:%d' % args.dns_server_port
+  ] + args.extra_args.split(','))\
 
 current_test_subprocess.communicate()\
 
index a2f471a..5031353 100644 (file)
@@ -17,3 +17,4 @@
   # AUTO-GENERATED FROM `$REPO_ROOT/templates/tools/distrib/python/grpcio_tools/grpc_version.py.template`!!!
 
   VERSION = '${settings.python_version.pep440()}'
+  PROTOBUF_VERSION = '${settings.protobuf_version}'
index e25791d..8532d6a 100644 (file)
@@ -17,3 +17,4 @@
   # AUTO-GENERATED FROM `$REPO_ROOT/templates/tools/distrib/python/grpcio_tools/grpc_version.py.template`!!!
 
   VERSION = '${settings.python_version.pep440()}'
+  PROTOBUF_VERSION = '${settings.protobuf_version}'
index c94385d..16651c6 100644 (file)
@@ -2,7 +2,7 @@
 # Bazel installation
 
 # Must be in sync with tools/bazel
-ENV BAZEL_VERSION 2.2.0
+ENV BAZEL_VERSION 3.7.1
 
 # The correct bazel version is already preinstalled, no need to use //tools/bazel wrapper.
 ENV DISABLE_BAZEL_WRAPPER 1
index ae9dd12..329be36 100644 (file)
@@ -14,7 +14,7 @@
   # See the License for the specific language governing permissions and
   # limitations under the License.
   
-  <%include file="../../debian_jessie_header.include"/>
+  FROM debian:buster
   
   <%include file="../../apt_get_basic.include"/>
   <%include file="../../python_deps.include"/>
index bcbd08c..496c263 100644 (file)
@@ -2,11 +2,12 @@
 # Ruby dependencies
 
 # Install rvm
-RUN apt-get update && apt-get install -y gnupg2
+RUN apt-get update && apt-get install -y gnupg2 && apt-get clean
 RUN gpg2 --keyserver hkp://pool.sks-keyservers.net --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3 7D2BAF1CF37B13E2069D6956105BD0E739499BDB
 RUN \curl -sSL https://get.rvm.io | bash -s stable
 
 # Install Ruby 2.5
+RUN apt-get update && apt-get install -y procps && apt-get clean
 RUN /bin/bash -l -c "rvm install ruby-2.5"
 RUN /bin/bash -l -c "rvm use --default ruby-2.5"
 RUN /bin/bash -l -c "echo 'gem: --no-document' > ~/.gemrc"
   # See the License for the specific language governing permissions and
   # limitations under the License.
   
-  <%include file="../../debian_jessie_header.include"/>
+  FROM debian:buster
   
   <%include file="../../apt_get_basic.include"/>
   <%include file="../../python_deps.include"/>
   <%include file="../../gcp_api_libraries.include"/>
   <%include file="../../ruby_deps.include"/>
+  <%include file="../../cmake.include"/>
   <%include file="../../run_tests_addons.include"/>
   # Define the default command.
   CMD ["bash"]
index 17c6d04..bba8781 100644 (file)
@@ -31,7 +31,7 @@
         curl ${"\\"}
         shellcheck
   RUN python2 -m pip install simplejson mako virtualenv==16.7.9 lxml
-  RUN python3 -m pip install simplejson mako virtualenv==16.7.9 lxml
+  RUN python3 -m pip install simplejson mako virtualenv==16.7.9 lxml six
 
   # Add buster-backports for more recent clang packages
   RUN echo "deb http://deb.debian.org/debian buster-backports main" | tee /etc/apt/sources.list.d/buster-backports.list
diff --git a/templates/tools/run_tests/generated/lb_interop_test_scenarios.json.template b/templates/tools/run_tests/generated/lb_interop_test_scenarios.json.template
deleted file mode 100644 (file)
index 18d71a7..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-%YAML 1.2
---- |
-  <%!
-  import json
-  %>
-  ${json.dumps(lb_interop_test_scenarios, indent=4, sort_keys=True)}
index 1f36675..000215e 100644 (file)
@@ -53,13 +53,13 @@ static void thd_func(void* arg) {
   if (a->validator != nullptr) {
     a->validator(a->server, a->cq, a->registered_method);
   }
-  gpr_event_set(&a->done_thd, (void*)1);
+  gpr_event_set(&a->done_thd, reinterpret_cast<void*>(1));
 }
 
 /* Sets the done_write event */
 static void set_done_write(void* arg, grpc_error* /*error*/) {
   gpr_event* done_write = static_cast<gpr_event*>(arg);
-  gpr_event_set(done_write, (void*)1);
+  gpr_event_set(done_write, reinterpret_cast<void*>(1));
 }
 
 static void server_setup_transport(void* ts, grpc_transport* transport) {
@@ -72,7 +72,7 @@ static void server_setup_transport(void* ts, grpc_transport* transport) {
 /* Sets the read_done event */
 static void set_read_done(void* arg, grpc_error* /*error*/) {
   gpr_event* read_done = static_cast<gpr_event*>(arg);
-  gpr_event_set(read_done, (void*)1);
+  gpr_event_set(read_done, reinterpret_cast<void*>(1));
 }
 
 /* shutdown client */
@@ -307,7 +307,7 @@ bool rst_stream_client_validator(grpc_slice_buffer* incoming, void* /*arg*/) {
   return success;
 }
 
-static void* tag(intptr_t t) { return (void*)t; }
+static void* tag(intptr_t t) { return reinterpret_cast<void*>(t); }
 
 void server_verifier_request_call(grpc_server* server,
                                   grpc_completion_queue* cq,
index ae19133..1fa1fd2 100644 (file)
@@ -49,7 +49,7 @@
   "\x00\x00\x20\x00\x00\x00\x00\x00\x01" \
   "\x00\x00\x00\x00"
 
-static void* tag(intptr_t t) { return (void*)t; }
+static void* tag(intptr_t t) { return reinterpret_cast<void*>(t); }
 
 static void verifier(grpc_server* server, grpc_completion_queue* cq,
                      void* /*registered_method*/) {
index c856b9b..08d7bb8 100644 (file)
@@ -66,7 +66,7 @@ static const char prefix[] =
     "\x01\x00\x00\x27\x10"
     "";
 
-static void* tag(intptr_t t) { return (void*)t; }
+static void* tag(intptr_t t) { return reinterpret_cast<void*>(t); }
 
 static void verifier(grpc_server* server, grpc_completion_queue* cq,
                      void* registered_method) {
index da0ac28..69e2692 100644 (file)
@@ -38,7 +38,7 @@
   "\x10\x02te\x08trailers"                                    \
   "\x10\x0auser-agent\"bad-client grpc-c/0.12.0.0 (linux)"
 
-static void* tag(intptr_t t) { return (void*)t; }
+static void* tag(intptr_t t) { return reinterpret_cast<void*>(t); }
 
 static void verifier_succeeds(grpc_server* server, grpc_completion_queue* cq,
                               void* registered_method) {
index d1df05d..a4aacc2 100644 (file)
@@ -85,7 +85,7 @@
   "\x10\x0cgrpc-timeout\x02"                                                \
   "5S"
 
-static void* tag(intptr_t t) { return (void*)t; }
+static void* tag(intptr_t t) { return reinterpret_cast<void*>(t); }
 
 static void verifier(grpc_server* server, grpc_completion_queue* cq,
                      void* /*registered_method*/) {
index 05498f3..1c89ee7 100644 (file)
@@ -44,7 +44,7 @@
 #include "src/core/lib/surface/completion_queue.h"
 #include "src/core/lib/surface/server.h"
 
-static void* tag(intptr_t t) { return (void*)t; }
+static void* tag(intptr_t t) { return reinterpret_cast<void*>(t); }
 
 typedef struct test_ctx test_ctx;
 
index e273f20..8fbf52b 100644 (file)
@@ -34,7 +34,7 @@
 #include "test/core/util/subprocess.h"
 #include "test/core/util/test_config.h"
 
-static void* tag(intptr_t t) { return (void*)t; }
+static void* tag(intptr_t t) { return reinterpret_cast<void*>(t); }
 
 static void run_test(const char* target, size_t nops) {
   grpc_channel_credentials* ssl_creds =
@@ -147,7 +147,7 @@ int main(int argc, char** argv) {
   args[1] = const_cast<char*>("--bind");
   std::string joined = grpc_core::JoinHostPort("::", port);
   args[2] = const_cast<char*>(joined.c_str());
-  svr = gpr_subprocess_create(4, (const char**)args);
+  svr = gpr_subprocess_create(4, const_cast<const char**>(args));
   gpr_free(args[0]);
 
   for (i = 3; i <= 4; i++) {
index ebbe2b6..88740a4 100644 (file)
@@ -62,7 +62,8 @@ void bad_ssl_run(grpc_server* server) {
   grpc_server_start(server);
 
   error = grpc_server_request_call(server, &s, &call_details,
-                                   &request_metadata_recv, cq, cq, (void*)1);
+                                   &request_metadata_recv, cq, cq,
+                                   reinterpret_cast<void*>(1));
   GPR_ASSERT(GRPC_CALL_OK == error);
 
   signal(SIGINT, sigint_handler);
index e408e4d..b154ad2 100644 (file)
@@ -111,12 +111,12 @@ static bool add_original_filter(grpc_channel_stack_builder* builder,
 }
 
 static void init_plugin(void) {
-  grpc_channel_init_register_stage(GRPC_CLIENT_CHANNEL, INT_MAX,
-                                   add_original_filter,
-                                   (void*)&original_filter);
-  grpc_channel_init_register_stage(GRPC_CLIENT_CHANNEL, INT_MAX,
-                                   add_replacement_filter,
-                                   (void*)&replacement_filter);
+  grpc_channel_init_register_stage(
+      GRPC_CLIENT_CHANNEL, INT_MAX, add_original_filter,
+      const_cast<grpc_channel_filter*>(&original_filter));
+  grpc_channel_init_register_stage(
+      GRPC_CLIENT_CHANNEL, INT_MAX, add_replacement_filter,
+      const_cast<grpc_channel_filter*>(&replacement_filter));
 }
 
 static void destroy_plugin(void) {}
index 4a7af6a..0ecefed 100644 (file)
@@ -73,8 +73,8 @@ void ValidateChannelTraceData(const Json& json,
   Json::Object object = json.object_value();
   Json& num_events_logged_json = object["numEventsLogged"];
   ASSERT_EQ(num_events_logged_json.type(), Json::Type::STRING);
-  size_t num_events_logged =
-      (size_t)strtol(num_events_logged_json.string_value().c_str(), nullptr, 0);
+  size_t num_events_logged = static_cast<size_t>(
+      strtol(num_events_logged_json.string_value().c_str(), nullptr, 0));
   ASSERT_EQ(num_events_logged, num_events_logged_expected);
   Json& start_time_json = object["creationTimestamp"];
   ASSERT_EQ(start_time_json.type(), Json::Type::STRING);
@@ -102,7 +102,7 @@ void ValidateChannelTrace(ChannelTrace* tracer, size_t num_events_logged) {
 
 class ChannelFixture {
  public:
-  ChannelFixture(int max_tracer_event_memory) {
+  explicit ChannelFixture(int max_tracer_event_memory) {
     grpc_arg client_a = grpc_channel_arg_integer_create(
         const_cast<char*>(GRPC_ARG_MAX_CHANNEL_TRACE_EVENT_MEMORY_PER_NODE),
         max_tracer_event_memory);
index 9fc5dbc..0da9f6f 100644 (file)
@@ -143,7 +143,7 @@ void ValidateGetServers(size_t expected_servers) {
 
 class ChannelFixture {
  public:
-  ChannelFixture(int max_tracer_event_memory = 0) {
+  explicit ChannelFixture(int max_tracer_event_memory = 0) {
     grpc_arg client_a[] = {
         grpc_channel_arg_integer_create(
             const_cast<char*>(GRPC_ARG_MAX_CHANNEL_TRACE_EVENT_MEMORY_PER_NODE),
@@ -200,8 +200,8 @@ void ValidateChildInteger(const Json::Object& object, const std::string& key,
   }
   ASSERT_NE(it, object.end());
   ASSERT_EQ(it->second.type(), Json::Type::STRING);
-  int64_t gotten_number =
-      (int64_t)strtol(it->second.string_value().c_str(), nullptr, 0);
+  int64_t gotten_number = static_cast<int64_t>(
+      strtol(it->second.string_value().c_str(), nullptr, 0));
   EXPECT_EQ(gotten_number, expected);
 }
 
index d052137..08bc8d5 100644 (file)
@@ -95,15 +95,17 @@ static grpc_core::OrphanablePtr<grpc_core::Resolver> create_resolver(
     std::unique_ptr<grpc_core::Resolver::ResultHandler> result_handler) {
   grpc_core::ResolverFactory* factory =
       grpc_core::ResolverRegistry::LookupResolverFactory("dns");
-  grpc_uri* uri = grpc_uri_parse(name, false);
-  GPR_ASSERT(uri);
+  absl::StatusOr<grpc_core::URI> uri = grpc_core::URI::Parse(name);
+  if (!uri.ok()) {
+    gpr_log(GPR_ERROR, "%s", uri.status().ToString().c_str());
+    GPR_ASSERT(uri.ok());
+  }
   grpc_core::ResolverArgs args;
-  args.uri = uri;
+  args.uri = std::move(*uri);
   args.work_serializer = *g_work_serializer;
   args.result_handler = std::move(result_handler);
   grpc_core::OrphanablePtr<grpc_core::Resolver> resolver =
       factory->CreateResolver(std::move(args));
-  grpc_uri_destroy(uri);
   return resolver;
 }
 
@@ -128,7 +130,7 @@ class ResultHandler : public grpc_core::Resolver::ResultHandler {
     GPR_ASSERT(output != nullptr);
     output->result = std::move(result);
     output->error = GRPC_ERROR_NONE;
-    gpr_event_set(&output->ev, (void*)1);
+    gpr_event_set(&output->ev, reinterpret_cast<void*>(1));
   }
 
   void ReturnError(grpc_error* error) override {
@@ -136,7 +138,7 @@ class ResultHandler : public grpc_core::Resolver::ResultHandler {
         reinterpret_cast<ResolverOutput*>(gpr_atm_acq_load(&output_));
     GPR_ASSERT(output != nullptr);
     output->error = error;
-    gpr_event_set(&output->ev, (void*)1);
+    gpr_event_set(&output->ev, reinterpret_cast<void*>(1));
   }
 
  private:
index 2d5e37c..32fb6d5 100644 (file)
@@ -174,7 +174,7 @@ static void poll_pollset_until_request_done(iomgr_args* args) {
     gpr_mu_unlock(args->mu);
     grpc_core::ExecCtx::Get()->Flush();
   }
-  gpr_event_set(&args->ev, (void*)1);
+  gpr_event_set(&args->ev, reinterpret_cast<void*>(1));
 }
 
 struct OnResolutionCallbackArg;
@@ -280,12 +280,16 @@ static void start_test_under_work_serializer(void* arg) {
   res_cb_arg->result_handler = new ResultHandler();
   grpc_core::ResolverFactory* factory =
       grpc_core::ResolverRegistry::LookupResolverFactory("dns");
-  grpc_uri* uri = grpc_uri_parse(res_cb_arg->uri_str, false);
+  absl::StatusOr<grpc_core::URI> uri =
+      grpc_core::URI::Parse(res_cb_arg->uri_str);
   gpr_log(GPR_DEBUG, "test: '%s' should be valid for '%s'", res_cb_arg->uri_str,
           factory->scheme());
-  GPR_ASSERT(uri != nullptr);
+  if (!uri.ok()) {
+    gpr_log(GPR_ERROR, "%s", uri.status().ToString().c_str());
+    GPR_ASSERT(uri.ok());
+  }
   grpc_core::ResolverArgs args;
-  args.uri = uri;
+  args.uri = std::move(*uri);
   args.work_serializer = *g_work_serializer;
   args.result_handler = std::unique_ptr<grpc_core::Resolver::ResultHandler>(
       res_cb_arg->result_handler);
@@ -298,7 +302,6 @@ static void start_test_under_work_serializer(void* arg) {
   args.args = &cooldown_args;
   res_cb_arg->resolver = factory->CreateResolver(std::move(args));
   GPR_ASSERT(res_cb_arg->resolver != nullptr);
-  grpc_uri_destroy(uri);
   // First resolution, would incur in system-level resolution.
   res_cb_arg->result_handler->SetCallback(on_first_resolution, res_cb_arg);
   res_cb_arg->resolver->StartLocked();
index 3b91dc1..6aa6371 100644 (file)
@@ -40,16 +40,18 @@ static void test_succeeds(grpc_core::ResolverFactory* factory,
   gpr_log(GPR_DEBUG, "test: '%s' should be valid for '%s'", string,
           factory->scheme());
   grpc_core::ExecCtx exec_ctx;
-  grpc_uri* uri = grpc_uri_parse(string, false);
-  GPR_ASSERT(uri);
+  absl::StatusOr<grpc_core::URI> uri = grpc_core::URI::Parse(string);
+  if (!uri.ok()) {
+    gpr_log(GPR_ERROR, "%s", uri.status().ToString().c_str());
+    GPR_ASSERT(uri.ok());
+  }
   grpc_core::ResolverArgs args;
-  args.uri = uri;
+  args.uri = std::move(*uri);
   args.work_serializer = *g_work_serializer;
   args.result_handler = absl::make_unique<TestResultHandler>();
   grpc_core::OrphanablePtr<grpc_core::Resolver> resolver =
       factory->CreateResolver(std::move(args));
   GPR_ASSERT(resolver != nullptr);
-  grpc_uri_destroy(uri);
 }
 
 static void test_fails(grpc_core::ResolverFactory* factory,
@@ -57,16 +59,18 @@ static void test_fails(grpc_core::ResolverFactory* factory,
   gpr_log(GPR_DEBUG, "test: '%s' should be invalid for '%s'", string,
           factory->scheme());
   grpc_core::ExecCtx exec_ctx;
-  grpc_uri* uri = grpc_uri_parse(string, false);
-  GPR_ASSERT(uri);
+  absl::StatusOr<grpc_core::URI> uri = grpc_core::URI::Parse(string);
+  if (!uri.ok()) {
+    gpr_log(GPR_ERROR, "%s", uri.status().ToString().c_str());
+    GPR_ASSERT(uri.ok());
+  }
   grpc_core::ResolverArgs args;
-  args.uri = uri;
+  args.uri = std::move(*uri);
   args.work_serializer = *g_work_serializer;
   args.result_handler = absl::make_unique<TestResultHandler>();
   grpc_core::OrphanablePtr<grpc_core::Resolver> resolver =
       factory->CreateResolver(std::move(args));
   GPR_ASSERT(resolver == nullptr);
-  grpc_uri_destroy(uri);
 }
 
 int main(int argc, char** argv) {
index f0316ba..5dde6be 100644 (file)
@@ -54,7 +54,7 @@ class ResultHandler : public grpc_core::Resolver::ResultHandler {
     for (size_t i = 0; i < expected_.addresses.size(); ++i) {
       GPR_ASSERT(actual.addresses[i] == expected_.addresses[i]);
     }
-    gpr_event_set(ev_, (void*)1);
+    gpr_event_set(ev_, reinterpret_cast<void*>(1));
     ev_ = nullptr;
   }
 
@@ -93,14 +93,14 @@ static grpc_core::Resolver::Result create_new_resolver_result() {
   for (size_t i = 0; i < num_addresses; ++i) {
     std::string uri_string = absl::StrFormat("ipv4:127.0.0.1:100%" PRIuPTR,
                                              test_counter * num_addresses + i);
-    grpc_uri* uri = grpc_uri_parse(uri_string.c_str(), true);
+    absl::StatusOr<grpc_core::URI> uri = grpc_core::URI::Parse(uri_string);
+    GPR_ASSERT(uri.ok());
     grpc_resolved_address address;
-    GPR_ASSERT(grpc_parse_uri(uri, &address));
+    GPR_ASSERT(grpc_parse_uri(*uri, &address));
     absl::InlinedVector<grpc_arg, 2> args_to_add;
     result.addresses.emplace_back(
         address.addr, address.len,
         grpc_channel_args_copy_and_add(nullptr, nullptr, 0));
-    grpc_uri_destroy(uri);
   }
   ++test_counter;
   return result;
index ff56963..9dfd883 100644 (file)
@@ -42,16 +42,18 @@ static void test_succeeds(grpc_core::ResolverFactory* factory,
   gpr_log(GPR_DEBUG, "test: '%s' should be valid for '%s'", string,
           factory->scheme());
   grpc_core::ExecCtx exec_ctx;
-  grpc_uri* uri = grpc_uri_parse(string, false);
-  GPR_ASSERT(uri);
+  absl::StatusOr<grpc_core::URI> uri = grpc_core::URI::Parse(string);
+  if (!uri.ok()) {
+    gpr_log(GPR_ERROR, "%s", uri.status().ToString().c_str());
+    GPR_ASSERT(uri.ok());
+  }
   grpc_core::ResolverArgs args;
-  args.uri = uri;
+  args.uri = std::move(*uri);
   args.work_serializer = *g_work_serializer;
   args.result_handler = absl::make_unique<ResultHandler>();
   grpc_core::OrphanablePtr<grpc_core::Resolver> resolver =
       factory->CreateResolver(std::move(args));
   GPR_ASSERT(resolver != nullptr);
-  grpc_uri_destroy(uri);
   resolver->StartLocked();
   /* Flush ExecCtx to avoid stack-use-after-scope on on_res_arg which is
    * accessed in the closure on_resolution_cb */
@@ -63,16 +65,18 @@ static void test_fails(grpc_core::ResolverFactory* factory,
   gpr_log(GPR_DEBUG, "test: '%s' should be invalid for '%s'", string,
           factory->scheme());
   grpc_core::ExecCtx exec_ctx;
-  grpc_uri* uri = grpc_uri_parse(string, false);
-  GPR_ASSERT(uri);
+  absl::StatusOr<grpc_core::URI> uri = grpc_core::URI::Parse(string);
+  if (!uri.ok()) {
+    gpr_log(GPR_ERROR, "%s", uri.status().ToString().c_str());
+    GPR_ASSERT(uri.ok());
+  }
   grpc_core::ResolverArgs args;
-  args.uri = uri;
+  args.uri = std::move(*uri);
   args.work_serializer = *g_work_serializer;
   args.result_handler = absl::make_unique<ResultHandler>();
   grpc_core::OrphanablePtr<grpc_core::Resolver> resolver =
       factory->CreateResolver(std::move(args));
   GPR_ASSERT(resolver == nullptr);
-  grpc_uri_destroy(uri);
 }
 
 int main(int argc, char** argv) {
index 793e86d..1ae8684 100644 (file)
@@ -98,7 +98,7 @@ TEST(ServerRetryThrottleData, Replacement) {
 
 TEST(ServerRetryThrottleMap, Replacement) {
   ServerRetryThrottleMap::Init();
-  const char kServerName[] = "server_name";
+  const std::string kServerName = "server_name";
   // Create old throttle data.
   // Max token count is 4, so threshold for retrying is 2.
   // Token count starts at 4.
index 97749cf..cc170c0 100644 (file)
@@ -38,7 +38,7 @@ namespace testing {
 
 class TestParsedConfig1 : public ServiceConfigParser::ParsedConfig {
  public:
-  TestParsedConfig1(int value) : value_(value) {}
+  explicit TestParsedConfig1(int value) : value_(value) {}
 
   int value() const { return value_; }
 
@@ -518,7 +518,12 @@ TEST_F(ClientChannelParserTest, ValidLoadBalancingConfigXds) {
       "{\n"
       "  \"loadBalancingConfig\":[\n"
       "    { \"does_not_exist\":{} },\n"
-      "    { \"eds_experimental\":{ \"clusterName\": \"foo\" } }\n"
+      "    { \"xds_cluster_resolver_experimental\":{\n"
+      "      \"discoveryMechanisms\": [\n"
+      "      { \"clusterName\": \"foo\",\n"
+      "        \"type\": \"EDS\"\n"
+      "    } ]\n"
+      "    } }\n"
       "  ]\n"
       "}";
   grpc_error* error = GRPC_ERROR_NONE;
@@ -528,7 +533,7 @@ TEST_F(ClientChannelParserTest, ValidLoadBalancingConfigXds) {
       static_cast<grpc_core::internal::ClientChannelGlobalParsedConfig*>(
           svc_cfg->GetGlobalParsedConfig(0));
   auto lb_config = parsed_config->parsed_lb_config();
-  EXPECT_STREQ(lb_config->name(), "eds_experimental");
+  EXPECT_STREQ(lb_config->name(), "xds_cluster_resolver_experimental");
 }
 
 TEST_F(ClientChannelParserTest, UnknownLoadBalancingConfig) {
@@ -601,7 +606,8 @@ TEST_F(ClientChannelParserTest, UnknownLoadBalancingPolicy) {
 }
 
 TEST_F(ClientChannelParserTest, LoadBalancingPolicyXdsNotAllowed) {
-  const char* test_json = "{\"loadBalancingPolicy\":\"eds_experimental\"}";
+  const char* test_json =
+      "{\"loadBalancingPolicy\":\"xds_cluster_resolver_experimental\"}";
   grpc_error* error = GRPC_ERROR_NONE;
   auto svc_cfg = ServiceConfig::Create(nullptr, test_json, &error);
   EXPECT_THAT(grpc_error_string(error),
@@ -609,7 +615,8 @@ TEST_F(ClientChannelParserTest, LoadBalancingPolicyXdsNotAllowed) {
                   "Service config parsing error.*referenced_errors.*"
                   "Global Params.*referenced_errors.*"
                   "Client channel global parser.*referenced_errors.*"
-                  "field:loadBalancingPolicy error:eds_experimental requires "
+                  "field:loadBalancingPolicy "
+                  "error:xds_cluster_resolver_experimental requires "
                   "a config. Please use loadBalancingConfig instead."));
   GRPC_ERROR_UNREF(error);
 }
@@ -984,8 +991,8 @@ TEST_F(ClientChannelParserTest, ValidHealthCheck) {
       static_cast<grpc_core::internal::ClientChannelGlobalParsedConfig*>(
           svc_cfg->GetGlobalParsedConfig(0));
   ASSERT_NE(parsed_config, nullptr);
-  EXPECT_STREQ(parsed_config->health_check_service_name(),
-               "health_check_service_name");
+  EXPECT_EQ(parsed_config->health_check_service_name(),
+            "health_check_service_name");
 }
 
 TEST_F(ClientChannelParserTest, InvalidHealthCheckMultipleEntries) {
index 8cc0b61..cb5427f 100644 (file)
@@ -93,7 +93,7 @@ static grpc_closure on_read;
 static grpc_closure on_writing_settings_frame;
 static grpc_closure on_write;
 
-static void* tag(intptr_t t) { return (void*)t; }
+static void* tag(intptr_t t) { return reinterpret_cast<void*>(t); }
 
 static void done_write(void* /*arg*/, grpc_error* error) {
   GPR_ASSERT(error == GRPC_ERROR_NONE);
@@ -286,7 +286,7 @@ static void actually_poll_server(void* arg) {
     }
     test_tcp_server_poll(pa->server, 1000);
   }
-  gpr_event_set(pa->signal_when_done, (void*)1);
+  gpr_event_set(pa->signal_when_done, reinterpret_cast<void*>(1));
   gpr_free(pa);
 }
 
index 7df6f0e..59d7c69 100644 (file)
@@ -33,7 +33,7 @@
 #include "test/core/util/port.h"
 #include "test/core/util/test_config.h"
 
-static void* tag(intptr_t i) { return (void*)i; }
+static void* tag(intptr_t t) { return reinterpret_cast<void*>(t); }
 
 static void run_test(bool wait_for_ready, bool use_service_config) {
   grpc_channel* chan;
index b8da655..da526ea 100644 (file)
@@ -186,14 +186,17 @@ int byte_buffer_eq_string(grpc_byte_buffer* bb, const char* str) {
   return byte_buffer_eq_slice(bb, grpc_slice_from_copied_string(str));
 }
 
-static bool is_probably_integer(void* p) { return ((uintptr_t)p) < 1000000; }
+static bool is_probably_integer(void* p) {
+  return reinterpret_cast<uintptr_t>(p) < 1000000;
+}
 
 namespace {
 
 std::string ExpectationString(const Expectation& e) {
   std::string out;
   if (is_probably_integer(e.tag)) {
-    out = absl::StrFormat("tag(%" PRIdPTR ") ", (intptr_t)e.tag);
+    out = absl::StrFormat("tag(%" PRIdPTR ") ",
+                          reinterpret_cast<intptr_t>(e.tag));
   } else {
     out = absl::StrFormat("%p ", e.tag);
   }
index 9976919..48bf018 100644 (file)
@@ -62,7 +62,7 @@ void cq_expect_completion_any_status(cq_verifier* v, const char* file, int line,
   cq_expect_completion_any_status(v, __FILE__, __LINE__, tag)
 
 int byte_buffer_eq_slice(grpc_byte_buffer* bb, grpc_slice b);
-int byte_buffer_eq_string(grpc_byte_buffer* byte_buffer, const char* string);
+int byte_buffer_eq_string(grpc_byte_buffer* bb, const char* str);
 int contains_metadata(grpc_metadata_array* array, const char* key,
                       const char* value);
 int contains_metadata_slices(grpc_metadata_array* array, grpc_slice key,
index 63b0dda..2b332dc 100644 (file)
@@ -48,7 +48,7 @@
 
 /* This test exercises IPv4, IPv6, and dualstack sockets in various ways. */
 
-static void* tag(intptr_t i) { return (void*)i; }
+static void* tag(intptr_t t) { return reinterpret_cast<void*>(t); }
 
 static void drain_cq(grpc_completion_queue* cq) {
   grpc_event ev;
index eacb2c6..62ef4bb 100644 (file)
@@ -67,12 +67,12 @@ extern void disappearing_server(grpc_end2end_test_config config);
 extern void disappearing_server_pre_init(void);
 extern void empty_batch(grpc_end2end_test_config config);
 extern void empty_batch_pre_init(void);
-extern void filter_call_init_fails(grpc_end2end_test_config config);
-extern void filter_call_init_fails_pre_init(void);
 extern void filter_causes_close(grpc_end2end_test_config config);
 extern void filter_causes_close_pre_init(void);
 extern void filter_context(grpc_end2end_test_config config);
 extern void filter_context_pre_init(void);
+extern void filter_init_fails(grpc_end2end_test_config config);
+extern void filter_init_fails_pre_init(void);
 extern void filter_latency(grpc_end2end_test_config config);
 extern void filter_latency_pre_init(void);
 extern void filter_status_code(grpc_end2end_test_config config);
@@ -210,9 +210,9 @@ void grpc_end2end_tests_pre_init(void) {
   default_host_pre_init();
   disappearing_server_pre_init();
   empty_batch_pre_init();
-  filter_call_init_fails_pre_init();
   filter_causes_close_pre_init();
   filter_context_pre_init();
+  filter_init_fails_pre_init();
   filter_latency_pre_init();
   filter_status_code_pre_init();
   graceful_server_shutdown_pre_init();
@@ -298,9 +298,9 @@ void grpc_end2end_tests(int argc, char **argv,
     default_host(config);
     disappearing_server(config);
     empty_batch(config);
-    filter_call_init_fails(config);
     filter_causes_close(config);
     filter_context(config);
+    filter_init_fails(config);
     filter_latency(config);
     filter_status_code(config);
     graceful_server_shutdown(config);
@@ -438,10 +438,6 @@ void grpc_end2end_tests(int argc, char **argv,
       empty_batch(config);
       continue;
     }
-    if (0 == strcmp("filter_call_init_fails", argv[i])) {
-      filter_call_init_fails(config);
-      continue;
-    }
     if (0 == strcmp("filter_causes_close", argv[i])) {
       filter_causes_close(config);
       continue;
@@ -450,6 +446,10 @@ void grpc_end2end_tests(int argc, char **argv,
       filter_context(config);
       continue;
     }
+    if (0 == strcmp("filter_init_fails", argv[i])) {
+      filter_init_fails(config);
+      continue;
+    }
     if (0 == strcmp("filter_latency", argv[i])) {
       filter_latency(config);
       continue;
index ec8a55e..0641fc6 100644 (file)
@@ -69,12 +69,12 @@ extern void disappearing_server(grpc_end2end_test_config config);
 extern void disappearing_server_pre_init(void);
 extern void empty_batch(grpc_end2end_test_config config);
 extern void empty_batch_pre_init(void);
-extern void filter_call_init_fails(grpc_end2end_test_config config);
-extern void filter_call_init_fails_pre_init(void);
 extern void filter_causes_close(grpc_end2end_test_config config);
 extern void filter_causes_close_pre_init(void);
 extern void filter_context(grpc_end2end_test_config config);
 extern void filter_context_pre_init(void);
+extern void filter_init_fails(grpc_end2end_test_config config);
+extern void filter_init_fails_pre_init(void);
 extern void filter_latency(grpc_end2end_test_config config);
 extern void filter_latency_pre_init(void);
 extern void filter_status_code(grpc_end2end_test_config config);
@@ -213,9 +213,9 @@ void grpc_end2end_tests_pre_init(void) {
   default_host_pre_init();
   disappearing_server_pre_init();
   empty_batch_pre_init();
-  filter_call_init_fails_pre_init();
   filter_causes_close_pre_init();
   filter_context_pre_init();
+  filter_init_fails_pre_init();
   filter_latency_pre_init();
   filter_status_code_pre_init();
   graceful_server_shutdown_pre_init();
@@ -302,9 +302,9 @@ void grpc_end2end_tests(int argc, char **argv,
     default_host(config);
     disappearing_server(config);
     empty_batch(config);
-    filter_call_init_fails(config);
     filter_causes_close(config);
     filter_context(config);
+    filter_init_fails(config);
     filter_latency(config);
     filter_status_code(config);
     graceful_server_shutdown(config);
@@ -446,10 +446,6 @@ void grpc_end2end_tests(int argc, char **argv,
       empty_batch(config);
       continue;
     }
-    if (0 == strcmp("filter_call_init_fails", argv[i])) {
-      filter_call_init_fails(config);
-      continue;
-    }
     if (0 == strcmp("filter_causes_close", argv[i])) {
       filter_causes_close(config);
       continue;
@@ -458,6 +454,10 @@ void grpc_end2end_tests(int argc, char **argv,
       filter_context(config);
       continue;
     }
+    if (0 == strcmp("filter_init_fails", argv[i])) {
+      filter_init_fails(config);
+      continue;
+    }
     if (0 == strcmp("filter_latency", argv[i])) {
       filter_latency(config);
       continue;
index 6be694c..ea85fe3 100644 (file)
@@ -27,14 +27,18 @@ typedef struct grpc_end2end_test_config grpc_end2end_test_config;
 /* Test feature flags. */
 #define FEATURE_MASK_SUPPORTS_DELAYED_CONNECTION 1
 #define FEATURE_MASK_SUPPORTS_HOSTNAME_VERIFICATION 2
+// Feature mask supports call credentials with a minimum security level of
+// GRPC_PRIVACY_AND_INTEGRITY.
 #define FEATURE_MASK_SUPPORTS_PER_CALL_CREDENTIALS 4
-#define FEATURE_MASK_SUPPORTS_REQUEST_PROXYING 8
-#define FEATURE_MASK_SUPPORTS_CLIENT_CHANNEL 16
-#define FEATURE_MASK_SUPPORTS_AUTHORITY_HEADER 32
-#define FEATURE_MASK_DOES_NOT_SUPPORT_RESOURCE_QUOTA_SERVER 64
-#define FEATURE_MASK_DOES_NOT_SUPPORT_NETWORK_STATUS_CHANGE 128
-#define FEATURE_MASK_SUPPORTS_WORKAROUNDS 256
-#define FEATURE_MASK_DOES_NOT_SUPPORT_SEND_CALL_CREDENTIALS 512
+// Feature mask supports call credentials with a minimum security level of
+// GRPC_SECURTITY_NONE.
+#define FEATURE_MASK_SUPPORTS_PER_CALL_CREDENTIALS_LEVEL_INSECURE 8
+#define FEATURE_MASK_SUPPORTS_REQUEST_PROXYING 16
+#define FEATURE_MASK_SUPPORTS_CLIENT_CHANNEL 32
+#define FEATURE_MASK_SUPPORTS_AUTHORITY_HEADER 64
+#define FEATURE_MASK_DOES_NOT_SUPPORT_RESOURCE_QUOTA_SERVER 128
+#define FEATURE_MASK_DOES_NOT_SUPPORT_NETWORK_STATUS_CHANGE 256
+#define FEATURE_MASK_SUPPORTS_WORKAROUNDS 512
 #define FEATURE_MASK_DOES_NOT_SUPPORT_CLIENT_HANDSHAKE_COMPLETE_FIRST 1024
 
 #define FAIL_AUTH_CHECK_SERVER_ARG_NAME "fail_auth_check"
index 099bf0d..b38e90c 100644 (file)
@@ -130,7 +130,7 @@ static grpc_end2end_test_config configs[] = {
      FEATURE_MASK_SUPPORTS_DELAYED_CONNECTION |
          FEATURE_MASK_SUPPORTS_CLIENT_CHANNEL |
          FEATURE_MASK_SUPPORTS_AUTHORITY_HEADER |
-         FEATURE_MASK_DOES_NOT_SUPPORT_SEND_CALL_CREDENTIALS,
+         FEATURE_MASK_SUPPORTS_PER_CALL_CREDENTIALS_LEVEL_INSECURE,
      nullptr, chttp2_create_fixture_secure_fullstack,
      chttp2_init_client_fake_secure_fullstack,
      chttp2_init_server_fake_secure_fullstack,
diff --git a/test/core/end2end/fixtures/h2_insecure.cc b/test/core/end2end/fixtures/h2_insecure.cc
new file mode 100644 (file)
index 0000000..f6d6d23
--- /dev/null
@@ -0,0 +1,127 @@
+//
+//
+// 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 "test/core/end2end/end2end_tests.h"
+
+#include <string.h>
+
+#include <grpc/grpc_security.h>
+#include <grpc/support/alloc.h>
+#include <grpc/support/log.h>
+
+#include "src/core/lib/channel/channel_args.h"
+#include "src/core/lib/gprpp/host_port.h"
+#include "test/core/util/port.h"
+#include "test/core/util/test_config.h"
+
+namespace {
+
+struct Chttp2InsecureFullstackFixtureData {
+  std::string localaddr;
+};
+
+grpc_end2end_test_fixture Chttp2CreateFixtureInsecureFullstack(
+    grpc_channel_args* /*client_args*/, grpc_channel_args* /*server_args*/) {
+  grpc_end2end_test_fixture f;
+  int port = grpc_pick_unused_port_or_die();
+  Chttp2InsecureFullstackFixtureData* ffd =
+      new Chttp2InsecureFullstackFixtureData();
+  memset(&f, 0, sizeof(f));
+  ffd->localaddr = grpc_core::JoinHostPort("localhost", port);
+  f.fixture_data = ffd;
+  f.cq = grpc_completion_queue_create_for_next(nullptr);
+  f.shutdown_cq = grpc_completion_queue_create_for_pluck(nullptr);
+
+  return f;
+}
+
+void Chttp2InitClientInsecureFullstack(grpc_end2end_test_fixture* f,
+                                       grpc_channel_args* client_args) {
+  Chttp2InsecureFullstackFixtureData* ffd =
+      static_cast<Chttp2InsecureFullstackFixtureData*>(f->fixture_data);
+  grpc_channel_credentials* creds = grpc_insecure_credentials_create();
+  f->client = grpc_secure_channel_create(creds, ffd->localaddr.c_str(),
+                                         client_args, nullptr);
+  grpc_channel_credentials_release(creds);
+  GPR_ASSERT(f->client);
+}
+
+void ProcessAuthFailure(void* state, grpc_auth_context* /*ctx*/,
+                        const grpc_metadata* /*md*/, size_t /*md_count*/,
+                        grpc_process_auth_metadata_done_cb cb,
+                        void* user_data) {
+  GPR_ASSERT(state == nullptr);
+  cb(user_data, nullptr, 0, nullptr, 0, GRPC_STATUS_UNAUTHENTICATED, nullptr);
+}
+
+void Chttp2InitServerInsecureFullstack(grpc_end2end_test_fixture* f,
+                                       grpc_channel_args* server_args) {
+  Chttp2InsecureFullstackFixtureData* ffd =
+      static_cast<Chttp2InsecureFullstackFixtureData*>(f->fixture_data);
+  if (f->server) {
+    grpc_server_destroy(f->server);
+  }
+  f->server = grpc_server_create(server_args, nullptr);
+  grpc_server_register_completion_queue(f->server, f->cq, nullptr);
+  grpc_server_credentials* server_creds =
+      grpc_insecure_server_credentials_create();
+  if (grpc_channel_args_find(server_args, FAIL_AUTH_CHECK_SERVER_ARG_NAME) !=
+      nullptr) {
+    grpc_auth_metadata_processor processor = {ProcessAuthFailure, nullptr,
+                                              nullptr};
+    grpc_server_credentials_set_auth_metadata_processor(server_creds,
+                                                        processor);
+  }
+  GPR_ASSERT(grpc_server_add_secure_http2_port(
+      f->server, ffd->localaddr.c_str(), server_creds));
+  grpc_server_credentials_release(server_creds);
+  grpc_server_start(f->server);
+}
+
+void Chttp2TearDownInsecureFullstack(grpc_end2end_test_fixture* f) {
+  Chttp2InsecureFullstackFixtureData* ffd =
+      static_cast<Chttp2InsecureFullstackFixtureData*>(f->fixture_data);
+  delete ffd;
+}
+
+/* All test configurations */
+grpc_end2end_test_config configs[] = {
+    {"chttp2/insecure_fullstack",
+     FEATURE_MASK_SUPPORTS_DELAYED_CONNECTION |
+         FEATURE_MASK_SUPPORTS_CLIENT_CHANNEL |
+         FEATURE_MASK_SUPPORTS_AUTHORITY_HEADER |
+         FEATURE_MASK_SUPPORTS_PER_CALL_CREDENTIALS_LEVEL_INSECURE,
+     nullptr, Chttp2CreateFixtureInsecureFullstack,
+     Chttp2InitClientInsecureFullstack, Chttp2InitServerInsecureFullstack,
+     Chttp2TearDownInsecureFullstack},
+};
+
+}  // namespace
+
+int main(int argc, char** argv) {
+  size_t i;
+  grpc::testing::TestEnvironment env(argc, argv);
+  grpc_end2end_tests_pre_init();
+  grpc_init();
+  for (i = 0; i < sizeof(configs) / sizeof(*configs); i++) {
+    grpc_end2end_tests(argc, argv, configs[i]);
+  }
+  grpc_shutdown();
+
+  return 0;
+}
index fbecb7e..97fe368 100644 (file)
@@ -52,8 +52,14 @@ static void server_setup_transport(void* ts, grpc_transport* transport) {
   grpc_core::ExecCtx exec_ctx;
   grpc_endpoint_pair* sfd = static_cast<grpc_endpoint_pair*>(f->fixture_data);
   grpc_endpoint_add_to_pollset(sfd->server, grpc_cq_pollset(f->cq));
-  f->server->core_server->SetupTransport(
+  grpc_error* error = f->server->core_server->SetupTransport(
       transport, nullptr, f->server->core_server->channel_args(), nullptr);
+  if (error == GRPC_ERROR_NONE) {
+    grpc_chttp2_transport_start_reading(transport, nullptr, nullptr);
+  } else {
+    GRPC_ERROR_UNREF(error);
+    grpc_transport_destroy(transport);
+  }
 }
 
 typedef struct {
@@ -68,9 +74,24 @@ static void client_setup_transport(void* ts, grpc_transport* transport) {
       const_cast<char*>("test-authority"));
   grpc_channel_args* args =
       grpc_channel_args_copy_and_add(cs->client_args, &authority_arg, 1);
-  cs->f->client = grpc_channel_create("socketpair-target", args,
-                                      GRPC_CLIENT_DIRECT_CHANNEL, transport);
+  grpc_error* error = GRPC_ERROR_NONE;
+  cs->f->client =
+      grpc_channel_create("socketpair-target", args, GRPC_CLIENT_DIRECT_CHANNEL,
+                          transport, nullptr, &error);
   grpc_channel_args_destroy(args);
+  if (cs->f->client != nullptr) {
+    grpc_chttp2_transport_start_reading(transport, nullptr, nullptr);
+  } else {
+    intptr_t integer;
+    grpc_status_code status = GRPC_STATUS_INTERNAL;
+    if (grpc_error_get_int(error, GRPC_ERROR_INT_GRPC_STATUS, &integer)) {
+      status = static_cast<grpc_status_code>(integer);
+    }
+    GRPC_ERROR_UNREF(error);
+    cs->f->client =
+        grpc_lame_client_channel_create(nullptr, status, "lame channel");
+    grpc_transport_destroy(transport);
+  }
 }
 
 static grpc_end2end_test_fixture chttp2_create_fixture_socketpair(
@@ -100,7 +121,6 @@ static void chttp2_init_client_socketpair(grpc_end2end_test_fixture* f,
   transport = grpc_create_chttp2_transport(client_args, sfd->client, true);
   client_setup_transport(&cs, transport);
   GPR_ASSERT(f->client);
-  grpc_chttp2_transport_start_reading(transport, nullptr, nullptr);
 }
 
 static void chttp2_init_server_socketpair(grpc_end2end_test_fixture* f,
@@ -114,7 +134,6 @@ static void chttp2_init_server_socketpair(grpc_end2end_test_fixture* f,
   grpc_server_start(f->server);
   transport = grpc_create_chttp2_transport(server_args, sfd->server, false);
   server_setup_transport(f, transport);
-  grpc_chttp2_transport_start_reading(transport, nullptr, nullptr);
 }
 
 static void chttp2_tear_down_socketpair(grpc_end2end_test_fixture* f) {
index 8ae50a7..d92305a 100644 (file)
@@ -46,8 +46,14 @@ static void server_setup_transport(void* ts, grpc_transport* transport) {
   grpc_core::ExecCtx exec_ctx;
   grpc_endpoint_pair* sfd = static_cast<grpc_endpoint_pair*>(f->fixture_data);
   grpc_endpoint_add_to_pollset(sfd->server, grpc_cq_pollset(f->cq));
-  f->server->core_server->SetupTransport(
+  grpc_error* error = f->server->core_server->SetupTransport(
       transport, nullptr, f->server->core_server->channel_args(), nullptr);
+  if (error == GRPC_ERROR_NONE) {
+    grpc_chttp2_transport_start_reading(transport, nullptr, nullptr);
+  } else {
+    GRPC_ERROR_UNREF(error);
+    grpc_transport_destroy(transport);
+  }
 }
 
 typedef struct {
@@ -63,9 +69,24 @@ static void client_setup_transport(void* ts, grpc_transport* transport) {
       const_cast<char*>("test-authority"));
   grpc_channel_args* args =
       grpc_channel_args_copy_and_add(cs->client_args, &authority_arg, 1);
-  cs->f->client = grpc_channel_create("socketpair-target", args,
-                                      GRPC_CLIENT_DIRECT_CHANNEL, transport);
+  grpc_error* error = GRPC_ERROR_NONE;
+  cs->f->client =
+      grpc_channel_create("socketpair-target", args, GRPC_CLIENT_DIRECT_CHANNEL,
+                          transport, nullptr, &error);
   grpc_channel_args_destroy(args);
+  if (cs->f->client != nullptr) {
+    grpc_chttp2_transport_start_reading(transport, nullptr, nullptr);
+  } else {
+    intptr_t integer;
+    grpc_status_code status = GRPC_STATUS_INTERNAL;
+    if (grpc_error_get_int(error, GRPC_ERROR_INT_GRPC_STATUS, &integer)) {
+      status = static_cast<grpc_status_code>(integer);
+    }
+    GRPC_ERROR_UNREF(error);
+    cs->f->client =
+        grpc_lame_client_channel_create(nullptr, status, "lame channel");
+    grpc_transport_destroy(transport);
+  }
 }
 
 static grpc_end2end_test_fixture chttp2_create_fixture_socketpair(
@@ -95,7 +116,6 @@ static void chttp2_init_client_socketpair(grpc_end2end_test_fixture* f,
   transport = grpc_create_chttp2_transport(client_args, sfd->client, true);
   client_setup_transport(&cs, transport);
   GPR_ASSERT(f->client);
-  grpc_chttp2_transport_start_reading(transport, nullptr, nullptr);
 }
 
 static void chttp2_init_server_socketpair(grpc_end2end_test_fixture* f,
@@ -109,7 +129,6 @@ static void chttp2_init_server_socketpair(grpc_end2end_test_fixture* f,
   grpc_server_start(f->server);
   transport = grpc_create_chttp2_transport(server_args, sfd->server, false);
   server_setup_transport(f, transport);
-  grpc_chttp2_transport_start_reading(transport, nullptr, nullptr);
 }
 
 static void chttp2_tear_down_socketpair(grpc_end2end_test_fixture* f) {
index 1f13711..6b161db 100644 (file)
@@ -46,8 +46,14 @@ static void server_setup_transport(void* ts, grpc_transport* transport) {
   grpc_core::ExecCtx exec_ctx;
   grpc_endpoint_pair* sfd = static_cast<grpc_endpoint_pair*>(f->fixture_data);
   grpc_endpoint_add_to_pollset(sfd->server, grpc_cq_pollset(f->cq));
-  f->server->core_server->SetupTransport(
+  grpc_error* error = f->server->core_server->SetupTransport(
       transport, nullptr, f->server->core_server->channel_args(), nullptr);
+  if (error == GRPC_ERROR_NONE) {
+    grpc_chttp2_transport_start_reading(transport, nullptr, nullptr);
+  } else {
+    GRPC_ERROR_UNREF(error);
+    grpc_transport_destroy(transport);
+  }
 }
 
 typedef struct {
@@ -63,9 +69,24 @@ static void client_setup_transport(void* ts, grpc_transport* transport) {
       const_cast<char*>("test-authority"));
   grpc_channel_args* args =
       grpc_channel_args_copy_and_add(cs->client_args, &authority_arg, 1);
-  cs->f->client = grpc_channel_create("socketpair-target", args,
-                                      GRPC_CLIENT_DIRECT_CHANNEL, transport);
+  grpc_error* error = GRPC_ERROR_NONE;
+  cs->f->client =
+      grpc_channel_create("socketpair-target", args, GRPC_CLIENT_DIRECT_CHANNEL,
+                          transport, nullptr, &error);
   grpc_channel_args_destroy(args);
+  if (cs->f->client != nullptr) {
+    grpc_chttp2_transport_start_reading(transport, nullptr, nullptr);
+  } else {
+    intptr_t integer;
+    grpc_status_code status = GRPC_STATUS_INTERNAL;
+    if (grpc_error_get_int(error, GRPC_ERROR_INT_GRPC_STATUS, &integer)) {
+      status = static_cast<grpc_status_code>(integer);
+    }
+    GRPC_ERROR_UNREF(error);
+    cs->f->client =
+        grpc_lame_client_channel_create(nullptr, status, "lame channel");
+    grpc_transport_destroy(transport);
+  }
 }
 
 static grpc_end2end_test_fixture chttp2_create_fixture_socketpair(
@@ -106,7 +127,6 @@ static void chttp2_init_client_socketpair(grpc_end2end_test_fixture* f,
   transport = grpc_create_chttp2_transport(client_args, sfd->client, true);
   client_setup_transport(&cs, transport);
   GPR_ASSERT(f->client);
-  grpc_chttp2_transport_start_reading(transport, nullptr, nullptr);
 }
 
 static void chttp2_init_server_socketpair(grpc_end2end_test_fixture* f,
@@ -120,7 +140,6 @@ static void chttp2_init_server_socketpair(grpc_end2end_test_fixture* f,
   grpc_server_start(f->server);
   transport = grpc_create_chttp2_transport(server_args, sfd->server, false);
   server_setup_transport(f, transport);
-  grpc_chttp2_transport_start_reading(transport, nullptr, nullptr);
 }
 
 static void chttp2_tear_down_socketpair(grpc_end2end_test_fixture* f) {
index 4689cee..9157e1e 100644 (file)
@@ -39,6 +39,7 @@
 #include "test/core/util/port.h"
 #include "test/core/util/test_config.h"
 
+// For normal TLS connections.
 #define CA_CERT_PATH "src/core/tsi/test_creds/ca.pem"
 #define SERVER_CERT_PATH "src/core/tsi/test_creds/server1.pem"
 #define SERVER_KEY_PATH "src/core/tsi/test_creds/server1.key"
@@ -60,7 +61,7 @@ struct fullstack_secure_fixture_data {
   grpc_tls_certificate_provider* server_provider = nullptr;
 };
 
-static grpc_end2end_test_fixture chttp2_create_fixture_secure_fullstack(
+static grpc_end2end_test_fixture chttp2_create_fixture_static_data(
     grpc_channel_args* /*client_args*/, grpc_channel_args* /*server_args*/,
     grpc_tls_version tls_version) {
   grpc_end2end_test_fixture f;
@@ -101,16 +102,47 @@ static grpc_end2end_test_fixture chttp2_create_fixture_secure_fullstack(
   return f;
 }
 
-static grpc_end2end_test_fixture chttp2_create_fixture_secure_fullstack_tls1_2(
+static grpc_end2end_test_fixture chttp2_create_fixture_cert_watcher(
+    grpc_channel_args* /*client_args*/, grpc_channel_args* /*server_args*/,
+    grpc_tls_version tls_version) {
+  grpc_end2end_test_fixture f;
+  int port = grpc_pick_unused_port_or_die();
+  fullstack_secure_fixture_data* ffd = new fullstack_secure_fixture_data();
+  memset(&f, 0, sizeof(f));
+  ffd->localaddr = grpc_core::JoinHostPort("localhost", port);
+  ffd->tls_version = tls_version;
+  ffd->client_provider = grpc_tls_certificate_provider_file_watcher_create(
+      SERVER_KEY_PATH, SERVER_CERT_PATH, CA_CERT_PATH, 1);
+  ffd->server_provider = grpc_tls_certificate_provider_file_watcher_create(
+      SERVER_KEY_PATH, SERVER_CERT_PATH, CA_CERT_PATH, 1);
+  f.fixture_data = ffd;
+  f.cq = grpc_completion_queue_create_for_next(nullptr);
+  f.shutdown_cq = grpc_completion_queue_create_for_pluck(nullptr);
+  return f;
+}
+
+static grpc_end2end_test_fixture chttp2_create_fixture_static_data_tls1_2(
     grpc_channel_args* client_args, grpc_channel_args* server_args) {
-  return chttp2_create_fixture_secure_fullstack(client_args, server_args,
-                                                grpc_tls_version::TLS1_2);
+  return chttp2_create_fixture_static_data(client_args, server_args,
+                                           grpc_tls_version::TLS1_2);
 }
 
-static grpc_end2end_test_fixture chttp2_create_fixture_secure_fullstack_tls1_3(
+static grpc_end2end_test_fixture chttp2_create_fixture_static_data_tls1_3(
     grpc_channel_args* client_args, grpc_channel_args* server_args) {
-  return chttp2_create_fixture_secure_fullstack(client_args, server_args,
-                                                grpc_tls_version::TLS1_3);
+  return chttp2_create_fixture_static_data(client_args, server_args,
+                                           grpc_tls_version::TLS1_3);
+}
+
+static grpc_end2end_test_fixture chttp2_create_fixture_cert_watcher_tls1_2(
+    grpc_channel_args* client_args, grpc_channel_args* server_args) {
+  return chttp2_create_fixture_cert_watcher(client_args, server_args,
+                                            grpc_tls_version::TLS1_2);
+}
+
+static grpc_end2end_test_fixture chttp2_create_fixture_cert_watcher_tls1_3(
+    grpc_channel_args* client_args, grpc_channel_args* server_args) {
+  return chttp2_create_fixture_cert_watcher(client_args, server_args,
+                                            grpc_tls_version::TLS1_3);
 }
 
 static void process_auth_failure(void* state, grpc_auth_context* /*ctx*/,
@@ -262,21 +294,47 @@ static void chttp2_init_server(grpc_end2end_test_fixture* f,
 }
 
 static grpc_end2end_test_config configs[] = {
-    /* client sync reload async authz + server sync reload. */
+    // client: static data provider + async custom verification
+    // server: static data provider
+    // extra: TLS 1.2
     {"chttp2/simple_ssl_fullstack_tls1_2",
      FEATURE_MASK_SUPPORTS_DELAYED_CONNECTION |
          FEATURE_MASK_SUPPORTS_PER_CALL_CREDENTIALS |
          FEATURE_MASK_SUPPORTS_CLIENT_CHANNEL |
          FEATURE_MASK_SUPPORTS_AUTHORITY_HEADER,
-     "foo.test.google.fr", chttp2_create_fixture_secure_fullstack_tls1_2,
+     "foo.test.google.fr", chttp2_create_fixture_static_data_tls1_2,
      chttp2_init_client, chttp2_init_server, chttp2_tear_down_secure_fullstack},
+    // client: static data provider + async custom verification
+    // server: static data provider
+    // extra: TLS 1.3
     {"chttp2/simple_ssl_fullstack_tls1_3",
      FEATURE_MASK_SUPPORTS_DELAYED_CONNECTION |
          FEATURE_MASK_SUPPORTS_PER_CALL_CREDENTIALS |
          FEATURE_MASK_SUPPORTS_CLIENT_CHANNEL |
          FEATURE_MASK_SUPPORTS_AUTHORITY_HEADER,
-     "foo.test.google.fr", chttp2_create_fixture_secure_fullstack_tls1_3,
+     "foo.test.google.fr", chttp2_create_fixture_static_data_tls1_3,
      chttp2_init_client, chttp2_init_server, chttp2_tear_down_secure_fullstack},
+    // client: certificate watcher provider + async custom verification
+    // server: certificate watcher provider
+    // extra: TLS 1.2
+    {"chttp2/reloading_from_files_ssl_fullstack_tls1_2",
+     FEATURE_MASK_SUPPORTS_DELAYED_CONNECTION |
+         FEATURE_MASK_SUPPORTS_PER_CALL_CREDENTIALS |
+         FEATURE_MASK_SUPPORTS_CLIENT_CHANNEL |
+         FEATURE_MASK_SUPPORTS_AUTHORITY_HEADER,
+     "foo.test.google.fr", chttp2_create_fixture_cert_watcher_tls1_2,
+     chttp2_init_client, chttp2_init_server, chttp2_tear_down_secure_fullstack},
+    // client: certificate watcher provider + async custom verification
+    // server: certificate watcher provider
+    // extra: TLS 1.3
+    {"chttp2/reloading_from_files_ssl_fullstack_tls1_3",
+     FEATURE_MASK_SUPPORTS_DELAYED_CONNECTION |
+         FEATURE_MASK_SUPPORTS_PER_CALL_CREDENTIALS |
+         FEATURE_MASK_SUPPORTS_CLIENT_CHANNEL |
+         FEATURE_MASK_SUPPORTS_AUTHORITY_HEADER,
+     "foo.test.google.fr", chttp2_create_fixture_cert_watcher_tls1_3,
+     chttp2_init_client, chttp2_init_server, chttp2_tear_down_secure_fullstack},
+
 };
 
 int main(int argc, char** argv) {
index 8901ca6..3d55bff 100644 (file)
@@ -33,7 +33,7 @@ bool leak_check = true;
 
 static void discard_write(grpc_slice /*slice*/) {}
 
-static void* tag(int n) { return (void*)static_cast<uintptr_t>(n); }
+static void* tag(intptr_t t) { return reinterpret_cast<void*>(t); }
 
 static void dont_log(gpr_log_func_args* /*args*/) {}
 
index 377a1a9..1f1b40e 100644 (file)
@@ -29,8 +29,7 @@ bool leak_check = true;
 
 static void discard_write(grpc_slice /*slice*/) {}
 
-static void* tag(int n) { return (void*)static_cast<uintptr_t>(n); }
-static int detag(void* p) { return static_cast<int>((uintptr_t)p); }
+static void* tag(intptr_t t) { return reinterpret_cast<void*>(t); }
 
 static void dont_log(gpr_log_func_args* /*args*/) {}
 
@@ -84,12 +83,11 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
         case GRPC_QUEUE_SHUTDOWN:
           break;
         case GRPC_OP_COMPLETE:
-          switch (detag(ev.tag)) {
-            case 1:
-              requested_calls--;
-              // TODO(ctiller): keep reading that call!
-              break;
+          if (ev.tag == tag(1)) {
+            requested_calls--;
+            // TODO(ctiller): keep reading that call!
           }
+          break;
       }
     }
 
index c4191ac..f812e65 100755 (executable)
@@ -70,6 +70,7 @@ END2END_FIXTURES = {
     "h2_full+trace": _fixture_options(tracing = True),
     "h2_full+workarounds": _fixture_options(),
     "h2_http_proxy": _fixture_options(supports_proxy_auth = True),
+    "h2_insecure": _fixture_options(secure = True),
     "h2_oauth2": _fixture_options(),
     "h2_proxy": _fixture_options(includes_proxy = True),
     "h2_sockpair_1byte": _fixture_options(
@@ -236,7 +237,7 @@ END2END_TESTS = {
     "disappearing_server": _test_options(needs_fullstack = True, needs_names = True),
     "empty_batch": _test_options(),
     "filter_causes_close": _test_options(),
-    "filter_call_init_fails": _test_options(),
+    "filter_init_fails": _test_options(),
     "filter_context": _test_options(),
     "graceful_server_shutdown": _test_options(exclude_inproc = True),
     "hpack_size": _test_options(
index 6c76c24..d0ca219 100644 (file)
@@ -44,7 +44,7 @@
 extern grpc_address_resolver_vtable* grpc_resolve_address_impl;
 static grpc_address_resolver_vtable* default_resolver;
 
-static void* tag(intptr_t i) { return (void*)i; }
+static void* tag(intptr_t t) { return reinterpret_cast<void*>(t); }
 
 static gpr_mu g_mu;
 static int g_resolve_port = -1;
index a209d8f..4aeac24 100644 (file)
@@ -44,7 +44,7 @@ namespace grpc {
 namespace testing {
 namespace {
 
-void* tag(intptr_t t) { return (void*)t; }
+void* tag(intptr_t t) { return reinterpret_cast<void*>(t); }
 
 gpr_timespec five_seconds_time() { return grpc_timeout_seconds_to_deadline(5); }
 
index 7c2e961..10ca9fb 100644 (file)
@@ -31,7 +31,7 @@
 #include "test/core/util/port.h"
 #include "test/core/util/test_config.h"
 
-static void* tag(intptr_t i) { return (void*)i; }
+static void* tag(intptr_t t) { return reinterpret_cast<void*>(t); }
 
 struct test_state {
   int is_client;
index f5cf823..e69d92c 100644 (file)
@@ -27,7 +27,7 @@
 #include "test/core/end2end/cq_verifier.h"
 #include "test/core/util/test_config.h"
 
-static void* tag(intptr_t i) { return (void*)i; }
+static void* tag(intptr_t t) { return reinterpret_cast<void*>(t); }
 
 void run_test(bool wait_for_ready) {
   gpr_log(GPR_INFO, "TEST: wait_for_ready=%d", wait_for_ready);
index 01a95e4..18cc6f5 100644 (file)
@@ -27,7 +27,7 @@
 #include <grpc/support/time.h>
 #include "test/core/end2end/cq_verifier.h"
 
-static void* tag(intptr_t t) { return (void*)t; }
+static void* tag(intptr_t t) { return reinterpret_cast<void*>(t); }
 
 static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config,
                                             const char* test_name,
index b6f06a2..33281ab 100644 (file)
@@ -29,7 +29,7 @@
 #include "src/core/lib/gpr/string.h"
 #include "test/core/end2end/cq_verifier.h"
 
-static void* tag(intptr_t t) { return (void*)t; }
+static void* tag(intptr_t t) { return reinterpret_cast<void*>(t); }
 
 static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config,
                                             const char* test_name,
index 12aff71..6d927ee 100644 (file)
@@ -32,7 +32,7 @@
 
 #define MAX_PING_STRIKES 2
 
-static void* tag(intptr_t t) { return (void*)t; }
+static void* tag(intptr_t t) { return reinterpret_cast<void*>(t); }
 
 static void drain_cq(grpc_completion_queue* cq) {
   grpc_event ev;
index cdf5b1e..6bcaac5 100644 (file)
@@ -27,7 +27,7 @@
 #include <grpc/support/time.h>
 #include "test/core/end2end/cq_verifier.h"
 
-static void* tag(intptr_t t) { return (void*)t; }
+static void* tag(intptr_t t) { return reinterpret_cast<void*>(t); }
 
 static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config,
                                             const char* test_name,
index 83802a6..a11c95e 100644 (file)
@@ -35,16 +35,24 @@ static const char iam_token[] = "token";
 static const char iam_selector[] = "selector";
 static const char overridden_iam_token[] = "overridden_token";
 static const char overridden_iam_selector[] = "overridden_selector";
+static const char fake_md_key[] = "fake_key";
+static const char fake_md_value[] = "fake_value";
+static const char overridden_fake_md_key[] = "overridden_fake_key";
+static const char overridden_fake_md_value[] = "overridden_fake_value";
 
 typedef enum { NONE, OVERRIDE, DESTROY, FAIL } override_mode;
 
-static void* tag(intptr_t t) { return (void*)t; }
+static void* tag(intptr_t t) { return reinterpret_cast<void*>(t); }
 
 static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config,
                                             const char* test_name,
+                                            bool use_secure_call_creds,
                                             int fail_server_auth_check) {
   grpc_end2end_test_fixture f;
-  gpr_log(GPR_INFO, "Running test: %s/%s", test_name, config.name);
+  gpr_log(GPR_INFO, "Running test: %s%s/%s", test_name,
+          use_secure_call_creds ? "_with_secure_call_creds"
+                                : "_with_insecure_call_creds",
+          config.name);
   f = config.create_fixture(nullptr, nullptr);
   config.init_client(&f, nullptr);
   if (fail_server_auth_check) {
@@ -122,10 +130,10 @@ static void print_auth_context(int is_client, const grpc_auth_context* ctx) {
 }
 
 static void request_response_with_payload_and_call_creds(
-    const char* test_name, grpc_end2end_test_config config,
-    override_mode mode) {
-  grpc_call* c;
-  grpc_call* s;
+    const char* test_name, grpc_end2end_test_config config, override_mode mode,
+    bool use_secure_call_creds) {
+  grpc_call* c = nullptr;
+  grpc_call* s = nullptr;
   grpc_slice request_payload_slice =
       grpc_slice_from_copied_string("hello world");
   grpc_slice response_payload_slice =
@@ -152,7 +160,7 @@ static void request_response_with_payload_and_call_creds(
   grpc_auth_context* s_auth_context = nullptr;
   grpc_auth_context* c_auth_context = nullptr;
 
-  f = begin_test(config, test_name, 0);
+  f = begin_test(config, test_name, use_secure_call_creds, 0);
   cqv = cq_verifier_create(f.cq);
 
   gpr_timespec deadline = five_seconds_from_now();
@@ -160,7 +168,13 @@ static void request_response_with_payload_and_call_creds(
                                grpc_slice_from_static_string("/foo"), nullptr,
                                deadline, nullptr);
   GPR_ASSERT(c);
-  creds = grpc_google_iam_credentials_create(iam_token, iam_selector, nullptr);
+  if (use_secure_call_creds) {
+    creds =
+        grpc_google_iam_credentials_create(iam_token, iam_selector, nullptr);
+  } else {
+    creds =
+        grpc_md_only_test_credentials_create(fake_md_key, fake_md_value, false);
+  }
   GPR_ASSERT(creds != nullptr);
   GPR_ASSERT(grpc_call_set_credentials(c, creds) == GRPC_CALL_OK);
   switch (mode) {
@@ -168,15 +182,22 @@ static void request_response_with_payload_and_call_creds(
       break;
     case OVERRIDE:
       grpc_call_credentials_release(creds);
-      creds = grpc_google_iam_credentials_create(
-          overridden_iam_token, overridden_iam_selector, nullptr);
+      if (use_secure_call_creds) {
+        creds = grpc_google_iam_credentials_create(
+            overridden_iam_token, overridden_iam_selector, nullptr);
+      } else {
+        creds = grpc_md_only_test_credentials_create(
+            overridden_fake_md_key, overridden_fake_md_value, false);
+      }
       GPR_ASSERT(creds != nullptr);
       GPR_ASSERT(grpc_call_set_credentials(c, creds) == GRPC_CALL_OK);
       break;
     case DESTROY:
-    case FAIL:
       GPR_ASSERT(grpc_call_set_credentials(c, nullptr) == GRPC_CALL_OK);
       break;
+    case FAIL:
+      // Do nothing
+      break;
   }
   grpc_call_credentials_release(creds);
 
@@ -222,111 +243,137 @@ static void request_response_with_payload_and_call_creds(
                                 nullptr);
   GPR_ASSERT(GRPC_CALL_OK == error);
 
-  error =
-      grpc_server_request_call(f.server, &s, &call_details,
-                               &request_metadata_recv, f.cq, f.cq, tag(101));
-  GPR_ASSERT(GRPC_CALL_OK == error);
-  CQ_EXPECT_COMPLETION(cqv, tag(101), 1);
-  cq_verify(cqv);
-  s_auth_context = grpc_call_auth_context(s);
-  GPR_ASSERT(s_auth_context != nullptr);
-  print_auth_context(0, s_auth_context);
-  grpc_auth_context_release(s_auth_context);
-
-  c_auth_context = grpc_call_auth_context(c);
-  GPR_ASSERT(c_auth_context != nullptr);
-  print_auth_context(1, c_auth_context);
-  grpc_auth_context_release(c_auth_context);
-
-  /* Cannot set creds on the server call object. */
-  GPR_ASSERT(grpc_call_set_credentials(s, nullptr) != GRPC_CALL_OK);
-
-  memset(ops, 0, sizeof(ops));
-  op = ops;
-  op->op = GRPC_OP_SEND_INITIAL_METADATA;
-  op->data.send_initial_metadata.count = 0;
-  op->flags = 0;
-  op->reserved = nullptr;
-  op++;
-  op->op = GRPC_OP_RECV_MESSAGE;
-  op->data.recv_message.recv_message = &request_payload_recv;
-  op->flags = 0;
-  op->reserved = nullptr;
-  op++;
-  error = grpc_call_start_batch(s, ops, static_cast<size_t>(op - ops), tag(102),
-                                nullptr);
-  GPR_ASSERT(GRPC_CALL_OK == error);
-
-  CQ_EXPECT_COMPLETION(cqv, tag(102), 1);
-  cq_verify(cqv);
-
-  memset(ops, 0, sizeof(ops));
-  op = ops;
-  op->op = GRPC_OP_RECV_CLOSE_ON_SERVER;
-  op->data.recv_close_on_server.cancelled = &was_cancelled;
-  op->flags = 0;
-  op->reserved = nullptr;
-  op++;
-  op->op = GRPC_OP_SEND_MESSAGE;
-  op->data.send_message.send_message = response_payload;
-  op->flags = 0;
-  op->reserved = nullptr;
-  op++;
-  op->op = GRPC_OP_SEND_STATUS_FROM_SERVER;
-  op->data.send_status_from_server.trailing_metadata_count = 0;
-  op->data.send_status_from_server.status = GRPC_STATUS_OK;
-  grpc_slice status_details = grpc_slice_from_static_string("xyz");
-  op->data.send_status_from_server.status_details = &status_details;
-  op->flags = 0;
-  op->reserved = nullptr;
-  op++;
-  error = grpc_call_start_batch(s, ops, static_cast<size_t>(op - ops), tag(103),
-                                nullptr);
-  GPR_ASSERT(GRPC_CALL_OK == error);
-
-  CQ_EXPECT_COMPLETION(cqv, tag(103), 1);
-  CQ_EXPECT_COMPLETION(cqv, tag(1), 1);
-  cq_verify(cqv);
-
-  GPR_ASSERT(status == GRPC_STATUS_OK);
-  GPR_ASSERT(0 == grpc_slice_str_cmp(details, "xyz"));
-  GPR_ASSERT(0 == grpc_slice_str_cmp(call_details.method, "/foo"));
-  GPR_ASSERT(was_cancelled == 0);
-  GPR_ASSERT(byte_buffer_eq_string(request_payload_recv, "hello world"));
-  GPR_ASSERT(byte_buffer_eq_string(response_payload_recv, "hello you"));
-
-  switch (mode) {
-    case NONE:
-      GPR_ASSERT(contains_metadata(&request_metadata_recv,
-                                   GRPC_IAM_AUTHORIZATION_TOKEN_METADATA_KEY,
-                                   iam_token));
-      GPR_ASSERT(contains_metadata(&request_metadata_recv,
-                                   GRPC_IAM_AUTHORITY_SELECTOR_METADATA_KEY,
-                                   iam_selector));
-      break;
-    case OVERRIDE:
-      GPR_ASSERT(contains_metadata(&request_metadata_recv,
-                                   GRPC_IAM_AUTHORIZATION_TOKEN_METADATA_KEY,
-                                   overridden_iam_token));
-      GPR_ASSERT(contains_metadata(&request_metadata_recv,
-                                   GRPC_IAM_AUTHORITY_SELECTOR_METADATA_KEY,
-                                   overridden_iam_selector));
-      break;
-    case DESTROY:
-    case FAIL:
-      GPR_ASSERT(!contains_metadata(&request_metadata_recv,
-                                    GRPC_IAM_AUTHORIZATION_TOKEN_METADATA_KEY,
-                                    iam_token));
-      GPR_ASSERT(!contains_metadata(&request_metadata_recv,
-                                    GRPC_IAM_AUTHORITY_SELECTOR_METADATA_KEY,
-                                    iam_selector));
-      GPR_ASSERT(!contains_metadata(&request_metadata_recv,
-                                    GRPC_IAM_AUTHORIZATION_TOKEN_METADATA_KEY,
-                                    overridden_iam_token));
-      GPR_ASSERT(!contains_metadata(&request_metadata_recv,
-                                    GRPC_IAM_AUTHORITY_SELECTOR_METADATA_KEY,
-                                    overridden_iam_selector));
-      break;
+  if (mode == FAIL) {
+    // Expect the call to fail since the channel credentials did not satisfy the
+    // minimum security level requirements.
+    CQ_EXPECT_COMPLETION(cqv, tag(1), 1);
+    cq_verify(cqv);
+    GPR_ASSERT(status == GRPC_STATUS_UNAUTHENTICATED);
+  } else {
+    error =
+        grpc_server_request_call(f.server, &s, &call_details,
+                                 &request_metadata_recv, f.cq, f.cq, tag(101));
+    GPR_ASSERT(GRPC_CALL_OK == error);
+    CQ_EXPECT_COMPLETION(cqv, tag(101), 1);
+    cq_verify(cqv);
+    s_auth_context = grpc_call_auth_context(s);
+    GPR_ASSERT(s_auth_context != nullptr);
+    print_auth_context(0, s_auth_context);
+    grpc_auth_context_release(s_auth_context);
+
+    c_auth_context = grpc_call_auth_context(c);
+    GPR_ASSERT(c_auth_context != nullptr);
+    print_auth_context(1, c_auth_context);
+    grpc_auth_context_release(c_auth_context);
+
+    /* Cannot set creds on the server call object. */
+    GPR_ASSERT(grpc_call_set_credentials(s, nullptr) != GRPC_CALL_OK);
+
+    memset(ops, 0, sizeof(ops));
+    op = ops;
+    op->op = GRPC_OP_SEND_INITIAL_METADATA;
+    op->data.send_initial_metadata.count = 0;
+    op->flags = 0;
+    op->reserved = nullptr;
+    op++;
+    op->op = GRPC_OP_RECV_MESSAGE;
+    op->data.recv_message.recv_message = &request_payload_recv;
+    op->flags = 0;
+    op->reserved = nullptr;
+    op++;
+    error = grpc_call_start_batch(s, ops, static_cast<size_t>(op - ops),
+                                  tag(102), nullptr);
+    GPR_ASSERT(GRPC_CALL_OK == error);
+
+    CQ_EXPECT_COMPLETION(cqv, tag(102), 1);
+    cq_verify(cqv);
+
+    memset(ops, 0, sizeof(ops));
+    op = ops;
+    op->op = GRPC_OP_RECV_CLOSE_ON_SERVER;
+    op->data.recv_close_on_server.cancelled = &was_cancelled;
+    op->flags = 0;
+    op->reserved = nullptr;
+    op++;
+    op->op = GRPC_OP_SEND_MESSAGE;
+    op->data.send_message.send_message = response_payload;
+    op->flags = 0;
+    op->reserved = nullptr;
+    op++;
+    op->op = GRPC_OP_SEND_STATUS_FROM_SERVER;
+    op->data.send_status_from_server.trailing_metadata_count = 0;
+    op->data.send_status_from_server.status = GRPC_STATUS_OK;
+    grpc_slice status_details = grpc_slice_from_static_string("xyz");
+    op->data.send_status_from_server.status_details = &status_details;
+    op->flags = 0;
+    op->reserved = nullptr;
+    op++;
+    error = grpc_call_start_batch(s, ops, static_cast<size_t>(op - ops),
+                                  tag(103), nullptr);
+    GPR_ASSERT(GRPC_CALL_OK == error);
+
+    CQ_EXPECT_COMPLETION(cqv, tag(103), 1);
+    CQ_EXPECT_COMPLETION(cqv, tag(1), 1);
+    cq_verify(cqv);
+
+    GPR_ASSERT(status == GRPC_STATUS_OK);
+    GPR_ASSERT(0 == grpc_slice_str_cmp(details, "xyz"));
+    GPR_ASSERT(0 == grpc_slice_str_cmp(call_details.method, "/foo"));
+    GPR_ASSERT(was_cancelled == 0);
+    GPR_ASSERT(byte_buffer_eq_string(request_payload_recv, "hello world"));
+    GPR_ASSERT(byte_buffer_eq_string(response_payload_recv, "hello you"));
+
+    switch (mode) {
+      case NONE:
+        if (use_secure_call_creds) {
+          GPR_ASSERT(contains_metadata(
+              &request_metadata_recv, GRPC_IAM_AUTHORIZATION_TOKEN_METADATA_KEY,
+              iam_token));
+          GPR_ASSERT(contains_metadata(&request_metadata_recv,
+                                       GRPC_IAM_AUTHORITY_SELECTOR_METADATA_KEY,
+                                       iam_selector));
+        } else {
+          GPR_ASSERT(contains_metadata(&request_metadata_recv, fake_md_key,
+                                       fake_md_value));
+        }
+        break;
+      case OVERRIDE:
+        if (use_secure_call_creds) {
+          GPR_ASSERT(contains_metadata(
+              &request_metadata_recv, GRPC_IAM_AUTHORIZATION_TOKEN_METADATA_KEY,
+              overridden_iam_token));
+          GPR_ASSERT(contains_metadata(&request_metadata_recv,
+                                       GRPC_IAM_AUTHORITY_SELECTOR_METADATA_KEY,
+                                       overridden_iam_selector));
+        } else {
+          GPR_ASSERT(contains_metadata(&request_metadata_recv,
+                                       overridden_fake_md_key,
+                                       overridden_fake_md_value));
+        }
+        break;
+      case DESTROY:
+        GPR_ASSERT(!contains_metadata(&request_metadata_recv,
+                                      GRPC_IAM_AUTHORIZATION_TOKEN_METADATA_KEY,
+                                      iam_token));
+        GPR_ASSERT(!contains_metadata(&request_metadata_recv,
+                                      GRPC_IAM_AUTHORITY_SELECTOR_METADATA_KEY,
+                                      iam_selector));
+        GPR_ASSERT(!contains_metadata(&request_metadata_recv,
+                                      GRPC_IAM_AUTHORIZATION_TOKEN_METADATA_KEY,
+                                      overridden_iam_token));
+        GPR_ASSERT(!contains_metadata(&request_metadata_recv,
+                                      GRPC_IAM_AUTHORITY_SELECTOR_METADATA_KEY,
+                                      overridden_iam_selector));
+        GPR_ASSERT(!contains_metadata(&request_metadata_recv, fake_md_key,
+                                      fake_md_value));
+        GPR_ASSERT(!contains_metadata(&request_metadata_recv,
+                                      overridden_fake_md_key,
+                                      overridden_fake_md_value));
+        break;
+      case FAIL:
+        GPR_ASSERT(0);
+    }
+    grpc_call_unref(s);
   }
 
   grpc_slice_unref(details);
@@ -336,7 +383,6 @@ static void request_response_with_payload_and_call_creds(
   grpc_call_details_destroy(&call_details);
 
   grpc_call_unref(c);
-  grpc_call_unref(s);
 
   cq_verifier_destroy(cqv);
 
@@ -350,30 +396,31 @@ static void request_response_with_payload_and_call_creds(
 }
 
 static void test_request_response_with_payload_and_call_creds(
-    grpc_end2end_test_config config) {
+    grpc_end2end_test_config config, bool use_secure_call_creds) {
   request_response_with_payload_and_call_creds(
-      "test_request_response_with_payload_and_call_creds", config, NONE);
+      "test_request_response_with_payload_and_call_creds", config, NONE,
+      use_secure_call_creds);
 }
 
 static void test_request_response_with_payload_and_overridden_call_creds(
-    grpc_end2end_test_config config) {
+    grpc_end2end_test_config config, bool use_secure_call_creds) {
   request_response_with_payload_and_call_creds(
       "test_request_response_with_payload_and_overridden_call_creds", config,
-      OVERRIDE);
+      OVERRIDE, use_secure_call_creds);
 }
 
 static void test_request_response_with_payload_and_deleted_call_creds(
-    grpc_end2end_test_config config) {
+    grpc_end2end_test_config config, bool use_secure_call_creds) {
   request_response_with_payload_and_call_creds(
       "test_request_response_with_payload_and_deleted_call_creds", config,
-      DESTROY);
+      DESTROY, use_secure_call_creds);
 }
 
 static void test_request_response_with_payload_fail_to_send_call_creds(
-    grpc_end2end_test_config config) {
+    grpc_end2end_test_config config, bool use_secure_call_creds) {
   request_response_with_payload_and_call_creds(
       "test_request_response_with_payload_fail_to_send_call_creds", config,
-      FAIL);
+      FAIL, use_secure_call_creds);
 }
 
 static void test_request_with_server_rejecting_client_creds(
@@ -398,7 +445,8 @@ static void test_request_with_server_rejecting_client_creds(
       grpc_raw_byte_buffer_create(&request_payload_slice, 1);
   grpc_call_credentials* creds;
 
-  f = begin_test(config, "test_request_with_server_rejecting_client_creds", 1);
+  f = begin_test(config, "test_request_with_server_rejecting_client_creds",
+                 false, 1);
   cqv = cq_verifier_create(f.cq);
 
   c = grpc_channel_create_call(f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq,
@@ -406,7 +454,8 @@ static void test_request_with_server_rejecting_client_creds(
                                deadline, nullptr);
   GPR_ASSERT(c);
 
-  creds = grpc_google_iam_credentials_create(iam_token, iam_selector, nullptr);
+  creds =
+      grpc_md_only_test_credentials_create(fake_md_key, fake_md_value, false);
   GPR_ASSERT(creds != nullptr);
   GPR_ASSERT(grpc_call_set_credentials(c, creds) == GRPC_CALL_OK);
   grpc_call_credentials_release(creds);
@@ -475,15 +524,29 @@ static void test_request_with_server_rejecting_client_creds(
 }
 
 void call_creds(grpc_end2end_test_config config) {
+  // Test fixtures that support call credentials with a minimum security level
+  // of GRPC_PRIVACY_AND_INTEGRITY
   if (config.feature_mask & FEATURE_MASK_SUPPORTS_PER_CALL_CREDENTIALS) {
-    test_request_response_with_payload_and_call_creds(config);
-    test_request_response_with_payload_and_overridden_call_creds(config);
-    test_request_response_with_payload_and_deleted_call_creds(config);
-    test_request_with_server_rejecting_client_creds(config);
+    test_request_response_with_payload_and_call_creds(config, true);
+    test_request_response_with_payload_and_overridden_call_creds(config, true);
+    test_request_response_with_payload_and_deleted_call_creds(config, true);
   }
+  // Test that fixtures that support call credentials with a minimum security
+  // level of GRPC_SECURITY_NONE cannot send call credentials that require
+  // higher security level
   if (config.feature_mask &
-      FEATURE_MASK_DOES_NOT_SUPPORT_SEND_CALL_CREDENTIALS) {
-    test_request_response_with_payload_fail_to_send_call_creds(config);
+      FEATURE_MASK_SUPPORTS_PER_CALL_CREDENTIALS_LEVEL_INSECURE) {
+    test_request_response_with_payload_fail_to_send_call_creds(config, true);
+  }
+  // Fixtures that support sending call credentials should be able to send call
+  // credentials of security level GRPC_SECURITY_NONE.
+  if (config.feature_mask & FEATURE_MASK_SUPPORTS_PER_CALL_CREDENTIALS ||
+      config.feature_mask &
+          FEATURE_MASK_SUPPORTS_PER_CALL_CREDENTIALS_LEVEL_INSECURE) {
+    test_request_response_with_payload_and_call_creds(config, false);
+    test_request_response_with_payload_and_overridden_call_creds(config, false);
+    test_request_response_with_payload_and_deleted_call_creds(config, false);
+    test_request_with_server_rejecting_client_creds(config);
   }
 }
 
index b5b79fd..2538999 100644 (file)
@@ -31,7 +31,7 @@
 #include "src/core/lib/gpr/string.h"
 #include "test/core/end2end/cq_verifier.h"
 
-static void* tag(intptr_t t) { return (void*)t; }
+static void* tag(intptr_t t) { return reinterpret_cast<void*>(t); }
 
 static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config,
                                             const char* test_name,
index 510bf3c..d80f524 100644 (file)
@@ -34,7 +34,7 @@
 #include "test/core/end2end/cq_verifier.h"
 #include "test/core/end2end/tests/cancel_test_helpers.h"
 
-static void* tag(intptr_t t) { return (void*)t; }
+static void* tag(intptr_t t) { return reinterpret_cast<void*>(t); }
 
 static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config,
                                             const char* test_name,
index 6e93783..5ff9dd0 100644 (file)
@@ -30,7 +30,7 @@
 #include "test/core/end2end/cq_verifier.h"
 #include "test/core/end2end/tests/cancel_test_helpers.h"
 
-static void* tag(intptr_t t) { return (void*)t; }
+static void* tag(intptr_t t) { return reinterpret_cast<void*>(t); }
 
 static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config,
                                             const char* test_name,
index 78009eb..2d58b99 100644 (file)
@@ -31,7 +31,7 @@
 #include "test/core/end2end/cq_verifier.h"
 #include "test/core/end2end/tests/cancel_test_helpers.h"
 
-static void* tag(intptr_t t) { return (void*)t; }
+static void* tag(intptr_t t) { return reinterpret_cast<void*>(t); }
 
 static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config,
                                             const char* test_name,
index 609ac57..ea03dae 100644 (file)
@@ -34,7 +34,7 @@
 #include "test/core/end2end/cq_verifier.h"
 #include "test/core/end2end/tests/cancel_test_helpers.h"
 
-static void* tag(intptr_t t) { return (void*)t; }
+static void* tag(intptr_t t) { return reinterpret_cast<void*>(t); }
 
 static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config,
                                             const char* test_name,
index abb2dbc..f118fff 100644 (file)
@@ -28,7 +28,7 @@
 #include <grpc/support/time.h>
 #include "test/core/end2end/cq_verifier.h"
 
-static void* tag(intptr_t t) { return (void*)t; }
+static void* tag(intptr_t t) { return reinterpret_cast<void*>(t); }
 
 static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config,
                                             const char* test_name,
index 4672e64..4b530f1 100644 (file)
@@ -30,7 +30,7 @@
 #include "test/core/end2end/cq_verifier.h"
 #include "test/core/end2end/tests/cancel_test_helpers.h"
 
-static void* tag(intptr_t t) { return (void*)t; }
+static void* tag(intptr_t t) { return reinterpret_cast<void*>(t); }
 
 static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config,
                                             const char* test_name,
index 2d6ad77..80eb5e0 100644 (file)
@@ -31,7 +31,7 @@
 #include "src/core/lib/gpr/string.h"
 #include "test/core/end2end/cq_verifier.h"
 
-static void* tag(intptr_t t) { return (void*)t; }
+static void* tag(intptr_t t) { return reinterpret_cast<void*>(t); }
 
 static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config,
                                             const char* test_name,
@@ -140,8 +140,8 @@ static void simple_request_body(grpc_end2end_test_config /*config*/,
   GPR_ASSERT(GRPC_CALL_OK == error);
 
   char* dynamic_string = gpr_strdup("xyz");
-  grpc_call_cancel_with_status(c, GRPC_STATUS_UNIMPLEMENTED,
-                               (const char*)dynamic_string, nullptr);
+  grpc_call_cancel_with_status(c, GRPC_STATUS_UNIMPLEMENTED, dynamic_string,
+                               nullptr);
   // The API of \a description allows for it to be a dynamic/non-const
   // string, test this guarantee.
   gpr_free(dynamic_string);
index 1be992d..2061873 100644 (file)
@@ -33,7 +33,7 @@
 #include "src/core/lib/gpr/string.h"
 #include "test/core/end2end/cq_verifier.h"
 
-static void* tag(intptr_t t) { return (void*)t; }
+static void* tag(intptr_t t) { return reinterpret_cast<void*>(t); }
 
 static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config,
                                             const char* test_name,
index e3f8868..f9cfaff 100644 (file)
@@ -27,7 +27,7 @@
 #include <grpc/support/time.h>
 #include "test/core/end2end/cq_verifier.h"
 
-static void* tag(intptr_t t) { return (void*)t; }
+static void* tag(intptr_t t) { return reinterpret_cast<void*>(t); }
 
 static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config,
                                             const char* test_name,
index c703449..05ffb50 100644 (file)
@@ -39,7 +39,7 @@
 #include "src/core/lib/transport/static_metadata.h"
 #include "test/core/end2end/cq_verifier.h"
 
-static void* tag(intptr_t t) { return (void*)t; }
+static void* tag(intptr_t t) { return reinterpret_cast<void*>(t); }
 
 static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config,
                                             const char* test_name,
index 1f589d1..208672e 100644 (file)
@@ -25,7 +25,7 @@
 #include "src/core/lib/gprpp/thd.h"
 #include "test/core/end2end/cq_verifier.h"
 
-static void* tag(intptr_t t) { return (void*)t; }
+static void* tag(intptr_t t) { return reinterpret_cast<void*>(t); }
 
 typedef struct {
   gpr_event started;
@@ -47,7 +47,7 @@ struct CallbackContext {
 static void child_thread(void* arg) {
   child_events* ce = static_cast<child_events*>(arg);
   grpc_event ev;
-  gpr_event_set(&ce->started, (void*)1);
+  gpr_event_set(&ce->started, reinterpret_cast<void*>(1));
   gpr_log(GPR_DEBUG, "verifying");
   ev = grpc_completion_queue_next(ce->cq, gpr_inf_future(GPR_CLOCK_MONOTONIC),
                                   nullptr);
@@ -176,22 +176,22 @@ static void test_connectivity(grpc_end2end_test_config config) {
 
 static void cb_watch_connectivity(
     grpc_experimental_completion_queue_functor* functor, int success) {
-  CallbackContext* cb_ctx = (CallbackContext*)functor;
+  CallbackContext* cb_ctx = reinterpret_cast<CallbackContext*>(functor);
 
   gpr_log(GPR_DEBUG, "cb_watch_connectivity called, verifying");
 
   /* callback must not have errors */
   GPR_ASSERT(success != 0);
 
-  gpr_event_set(&cb_ctx->finished, (void*)1);
+  gpr_event_set(&cb_ctx->finished, reinterpret_cast<void*>(1));
 }
 
 static void cb_shutdown(grpc_experimental_completion_queue_functor* functor,
                         int /*success*/) {
-  CallbackContext* cb_ctx = (CallbackContext*)functor;
+  CallbackContext* cb_ctx = reinterpret_cast<CallbackContext*>(functor);
 
   gpr_log(GPR_DEBUG, "cb_shutdown called, nothing to do");
-  gpr_event_set(&cb_ctx->finished, (void*)1);
+  gpr_event_set(&cb_ctx->finished, reinterpret_cast<void*>(1));
 }
 
 static void test_watch_connectivity_cq_callback(
index ec2baef..3527073 100644 (file)
@@ -29,7 +29,7 @@
 #include "src/core/lib/gpr/string.h"
 #include "test/core/end2end/cq_verifier.h"
 
-static void* tag(intptr_t t) { return (void*)t; }
+static void* tag(intptr_t t) { return reinterpret_cast<void*>(t); }
 
 static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config,
                                             const char* test_name,
index b281d44..e8fa4e4 100644 (file)
@@ -27,7 +27,7 @@
 #include <grpc/support/time.h>
 #include "test/core/end2end/cq_verifier.h"
 
-static void* tag(intptr_t t) { return (void*)t; }
+static void* tag(intptr_t t) { return reinterpret_cast<void*>(t); }
 
 static gpr_timespec n_seconds_from_now(int n) {
   return grpc_timeout_seconds_to_deadline(n);
index 1144ebf..7325616 100644 (file)
@@ -29,7 +29,7 @@
 #include "src/core/lib/gpr/string.h"
 #include "test/core/end2end/cq_verifier.h"
 
-static void* tag(intptr_t t) { return (void*)t; }
+static void* tag(intptr_t t) { return reinterpret_cast<void*>(t); }
 
 static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config,
                                             const char* test_name,
index 7f99b92..fb1af99 100644 (file)
@@ -32,7 +32,7 @@
 
 static bool g_enable_filter = false;
 
-static void* tag(intptr_t t) { return (void*)t; }
+static void* tag(intptr_t t) { return reinterpret_cast<void*>(t); }
 
 static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config,
                                             const char* test_name,
index 0c41874..5b02e06 100644 (file)
@@ -36,7 +36,7 @@ enum { TIMEOUT = 200000 };
 
 static bool g_enable_filter = false;
 
-static void* tag(intptr_t t) { return (void*)t; }
+static void* tag(intptr_t t) { return reinterpret_cast<void*>(t); }
 
 static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config,
                                             const char* test_name,
@@ -295,14 +295,18 @@ static bool maybe_add_filter(grpc_channel_stack_builder* builder, void* arg) {
 }
 
 static void init_plugin(void) {
-  grpc_channel_init_register_stage(GRPC_CLIENT_CHANNEL, INT_MAX,
-                                   maybe_add_filter, (void*)&test_filter);
-  grpc_channel_init_register_stage(GRPC_CLIENT_SUBCHANNEL, INT_MAX,
-                                   maybe_add_filter, (void*)&test_filter);
-  grpc_channel_init_register_stage(GRPC_CLIENT_DIRECT_CHANNEL, INT_MAX,
-                                   maybe_add_filter, (void*)&test_filter);
-  grpc_channel_init_register_stage(GRPC_SERVER_CHANNEL, INT_MAX,
-                                   maybe_add_filter, (void*)&test_filter);
+  grpc_channel_init_register_stage(
+      GRPC_CLIENT_CHANNEL, INT_MAX, maybe_add_filter,
+      const_cast<grpc_channel_filter*>(&test_filter));
+  grpc_channel_init_register_stage(
+      GRPC_CLIENT_SUBCHANNEL, INT_MAX, maybe_add_filter,
+      const_cast<grpc_channel_filter*>(&test_filter));
+  grpc_channel_init_register_stage(
+      GRPC_CLIENT_DIRECT_CHANNEL, INT_MAX, maybe_add_filter,
+      const_cast<grpc_channel_filter*>(&test_filter));
+  grpc_channel_init_register_stage(
+      GRPC_SERVER_CHANNEL, INT_MAX, maybe_add_filter,
+      const_cast<grpc_channel_filter*>(&test_filter));
 }
 
 static void destroy_plugin(void) {}
@@ -36,8 +36,9 @@ enum { TIMEOUT = 200000 };
 static bool g_enable_server_channel_filter = false;
 static bool g_enable_client_channel_filter = false;
 static bool g_enable_client_subchannel_filter = false;
+static bool g_channel_filter_init_failure = false;
 
-static void* tag(intptr_t t) { return (void*)t; }
+static void* tag(intptr_t t) { return reinterpret_cast<void*>(t); }
 
 static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config,
                                             const char* test_name,
@@ -103,7 +104,7 @@ static void test_server_channel_filter(grpc_end2end_test_config config) {
   grpc_byte_buffer* request_payload =
       grpc_raw_byte_buffer_create(&request_payload_slice, 1);
   grpc_end2end_test_fixture f =
-      begin_test(config, "filter_call_init_fails", nullptr, nullptr);
+      begin_test(config, "filter_init_fails", nullptr, nullptr);
   cq_verifier* cqv = cq_verifier_create(f.cq);
   grpc_op ops[6];
   grpc_op* op;
@@ -168,8 +169,17 @@ static void test_server_channel_filter(grpc_end2end_test_config config) {
   CQ_EXPECT_COMPLETION(cqv, tag(1), 1);
   cq_verify(cqv);
 
-  GPR_ASSERT(status == GRPC_STATUS_PERMISSION_DENIED);
-  GPR_ASSERT(0 == grpc_slice_str_cmp(details, "access denied"));
+  if (g_channel_filter_init_failure == true) {
+    // Inproc channel returns invalid_argument and other clients return
+    // unavailable.
+    // Windows with sockpair returns unknown.
+    GPR_ASSERT(status == GRPC_STATUS_UNKNOWN ||
+               status == GRPC_STATUS_UNAVAILABLE ||
+               status == GRPC_STATUS_INVALID_ARGUMENT);
+  } else {
+    GPR_ASSERT(status == GRPC_STATUS_PERMISSION_DENIED);
+    GPR_ASSERT(0 == grpc_slice_str_cmp(details, "access denied"));
+  }
 
   grpc_slice_unref(details);
   grpc_metadata_array_destroy(&initial_metadata_recv);
@@ -198,7 +208,7 @@ static void test_client_channel_filter(grpc_end2end_test_config config) {
       grpc_raw_byte_buffer_create(&request_payload_slice, 1);
   gpr_timespec deadline = five_seconds_from_now();
   grpc_end2end_test_fixture f =
-      begin_test(config, "filter_call_init_fails", nullptr, nullptr);
+      begin_test(config, "filter_init_fails", nullptr, nullptr);
   cq_verifier* cqv = cq_verifier_create(f.cq);
   grpc_op ops[6];
   grpc_op* op;
@@ -257,8 +267,12 @@ static void test_client_channel_filter(grpc_end2end_test_config config) {
   CQ_EXPECT_COMPLETION(cqv, tag(1), 1);
   cq_verify(cqv);
 
-  GPR_ASSERT(status == GRPC_STATUS_PERMISSION_DENIED);
-  GPR_ASSERT(0 == grpc_slice_str_cmp(details, "access denied"));
+  if (g_channel_filter_init_failure) {
+    GPR_ASSERT(status == GRPC_STATUS_INVALID_ARGUMENT);
+  } else {
+    GPR_ASSERT(status == GRPC_STATUS_PERMISSION_DENIED);
+    GPR_ASSERT(0 == grpc_slice_str_cmp(details, "access denied"));
+  }
 
   grpc_slice_unref(details);
   grpc_metadata_array_destroy(&initial_metadata_recv);
@@ -287,7 +301,7 @@ static void test_client_subchannel_filter(grpc_end2end_test_config config) {
       grpc_raw_byte_buffer_create(&request_payload_slice, 1);
   gpr_timespec deadline = five_seconds_from_now();
   grpc_end2end_test_fixture f =
-      begin_test(config, "filter_call_init_fails", nullptr, nullptr);
+      begin_test(config, "filter_init_fails", nullptr, nullptr);
   cq_verifier* cqv = cq_verifier_create(f.cq);
   grpc_op ops[6];
   grpc_op* op;
@@ -347,8 +361,12 @@ static void test_client_subchannel_filter(grpc_end2end_test_config config) {
   CQ_EXPECT_COMPLETION(cqv, tag(1), 1);
   cq_verify(cqv);
 
-  GPR_ASSERT(status == GRPC_STATUS_PERMISSION_DENIED);
-  GPR_ASSERT(0 == grpc_slice_str_cmp(details, "access denied"));
+  if (g_channel_filter_init_failure) {
+    GPR_ASSERT(status == GRPC_STATUS_UNAVAILABLE);
+  } else {
+    GPR_ASSERT(status == GRPC_STATUS_PERMISSION_DENIED);
+    GPR_ASSERT(0 == grpc_slice_str_cmp(details, "access denied"));
+  }
 
   // Reset and create a new call.  (The first call uses a different code
   // path in client_channel.c than subsequent calls on the same channel,
@@ -370,8 +388,12 @@ static void test_client_subchannel_filter(grpc_end2end_test_config config) {
   CQ_EXPECT_COMPLETION(cqv, tag(2), 1);
   cq_verify(cqv);
 
-  GPR_ASSERT(status == GRPC_STATUS_PERMISSION_DENIED);
-  GPR_ASSERT(0 == grpc_slice_str_cmp(details, "access denied"));
+  if (g_channel_filter_init_failure) {
+    GPR_ASSERT(status == GRPC_STATUS_UNAVAILABLE);
+  } else {
+    GPR_ASSERT(status == GRPC_STATUS_PERMISSION_DENIED);
+    GPR_ASSERT(0 == grpc_slice_str_cmp(details, "access denied"));
+  }
 
   grpc_slice_unref(details);
   grpc_metadata_array_destroy(&initial_metadata_recv);
@@ -407,6 +429,11 @@ static void destroy_call_elem(grpc_call_element* /*elem*/,
 
 static grpc_error* init_channel_elem(grpc_channel_element* /*elem*/,
                                      grpc_channel_element_args* /*args*/) {
+  if (g_channel_filter_init_failure) {
+    return grpc_error_set_int(
+        GRPC_ERROR_CREATE_FROM_STATIC_STRING("Test channel filter init error"),
+        GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_INVALID_ARGUMENT);
+  }
   return GRPC_ERROR_NONE;
 }
 
@@ -423,7 +450,7 @@ static const grpc_channel_filter test_filter = {
     init_channel_elem,
     destroy_channel_elem,
     grpc_channel_next_get_info,
-    "filter_call_init_fails"};
+    "filter_init_fails"};
 
 /*******************************************************************************
  * Registration
@@ -499,7 +526,7 @@ static void init_plugin(void) {
 
 static void destroy_plugin(void) {}
 
-void filter_call_init_fails(grpc_end2end_test_config config) {
+static void filter_init_fails_internal(grpc_end2end_test_config config) {
   gpr_log(GPR_INFO, "Testing SERVER_CHANNEL filter.");
   g_enable_server_channel_filter = true;
   test_server_channel_filter(config);
@@ -524,6 +551,14 @@ void filter_call_init_fails(grpc_end2end_test_config config) {
   }
 }
 
-void filter_call_init_fails_pre_init(void) {
+void filter_init_fails(grpc_end2end_test_config config) {
+  filter_init_fails_internal(config);
+  gpr_log(GPR_INFO, "Testing with channel filter init error");
+  g_channel_filter_init_failure = true;
+  filter_init_fails_internal(config);
+  g_channel_filter_init_failure = false;
+}
+
+void filter_init_fails_pre_init(void) {
   grpc_register_plugin(init_plugin, destroy_plugin);
 }
index b0992b1..1a8091e 100644 (file)
@@ -39,7 +39,7 @@ static gpr_mu g_mu;
 static gpr_timespec g_client_latency;
 static gpr_timespec g_server_latency;
 
-static void* tag(intptr_t t) { return (void*)t; }
+static void* tag(intptr_t t) { return reinterpret_cast<void*>(t); }
 
 static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config,
                                             const char* test_name,
@@ -326,15 +326,15 @@ static bool maybe_add_filter(grpc_channel_stack_builder* builder, void* arg) {
 
 static void init_plugin(void) {
   gpr_mu_init(&g_mu);
-  grpc_channel_init_register_stage(GRPC_CLIENT_CHANNEL, INT_MAX,
-                                   maybe_add_filter,
-                                   (void*)&test_client_filter);
-  grpc_channel_init_register_stage(GRPC_CLIENT_DIRECT_CHANNEL, INT_MAX,
-                                   maybe_add_filter,
-                                   (void*)&test_client_filter);
-  grpc_channel_init_register_stage(GRPC_SERVER_CHANNEL, INT_MAX,
-                                   maybe_add_filter,
-                                   (void*)&test_server_filter);
+  grpc_channel_init_register_stage(
+      GRPC_CLIENT_CHANNEL, INT_MAX, maybe_add_filter,
+      const_cast<grpc_channel_filter*>(&test_client_filter));
+  grpc_channel_init_register_stage(
+      GRPC_CLIENT_DIRECT_CHANNEL, INT_MAX, maybe_add_filter,
+      const_cast<grpc_channel_filter*>(&test_client_filter));
+  grpc_channel_init_register_stage(
+      GRPC_SERVER_CHANNEL, INT_MAX, maybe_add_filter,
+      const_cast<grpc_channel_filter*>(&test_server_filter));
 }
 
 static void destroy_plugin(void) { gpr_mu_destroy(&g_mu); }
index 3fc47ac..061166f 100644 (file)
@@ -52,7 +52,7 @@ static gpr_cv g_server_code_cv;
 static grpc_status_code g_client_status_code;
 static grpc_status_code g_server_status_code;
 
-static void* tag(intptr_t t) { return (void*)t; }
+static void* tag(intptr_t t) { return reinterpret_cast<void*>(t); }
 
 static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config,
                                             const char* test_name,
@@ -376,15 +376,15 @@ static void init_plugin(void) {
   g_client_code_recv = false;
   g_server_code_recv = false;
 
-  grpc_channel_init_register_stage(GRPC_CLIENT_CHANNEL, INT_MAX,
-                                   maybe_add_filter,
-                                   (void*)&test_client_filter);
-  grpc_channel_init_register_stage(GRPC_CLIENT_DIRECT_CHANNEL, INT_MAX,
-                                   maybe_add_filter,
-                                   (void*)&test_client_filter);
-  grpc_channel_init_register_stage(GRPC_SERVER_CHANNEL, INT_MAX,
-                                   maybe_add_filter,
-                                   (void*)&test_server_filter);
+  grpc_channel_init_register_stage(
+      GRPC_CLIENT_CHANNEL, INT_MAX, maybe_add_filter,
+      const_cast<grpc_channel_filter*>(&test_client_filter));
+  grpc_channel_init_register_stage(
+      GRPC_CLIENT_DIRECT_CHANNEL, INT_MAX, maybe_add_filter,
+      const_cast<grpc_channel_filter*>(&test_client_filter));
+  grpc_channel_init_register_stage(
+      GRPC_SERVER_CHANNEL, INT_MAX, maybe_add_filter,
+      const_cast<grpc_channel_filter*>(&test_server_filter));
 }
 
 static void destroy_plugin(void) {
index 376b00b..93561bf 100644 (file)
@@ -27,7 +27,7 @@
 #include <grpc/support/time.h>
 #include "test/core/end2end/cq_verifier.h"
 
-static void* tag(intptr_t t) { return (void*)t; }
+static void* tag(intptr_t t) { return reinterpret_cast<void*>(t); }
 
 static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config,
                                             const char* test_name,
index 30ccc83..5500594 100644 (file)
@@ -34,7 +34,7 @@
 #include "src/core/lib/gpr/string.h"
 #include "test/core/end2end/cq_verifier.h"
 
-static void* tag(intptr_t t) { return (void*)t; }
+static void* tag(intptr_t t) { return reinterpret_cast<void*>(t); }
 
 static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config,
                                             const char* test_name,
index 8dfb9eb..a9be014 100644 (file)
@@ -35,7 +35,7 @@
 #include "src/core/lib/gpr/useful.h"
 #include "test/core/end2end/cq_verifier.h"
 
-static void* tag(intptr_t t) { return (void*)t; }
+static void* tag(intptr_t t) { return reinterpret_cast<void*>(t); }
 
 const char* hobbits[][2] = {
     {"Adaldrida", "Brandybuck"}, {"Adamanta", "Took"},
index f91375c..294b94c 100644 (file)
@@ -30,7 +30,7 @@
 #include "src/core/lib/gpr/string.h"
 #include "test/core/end2end/cq_verifier.h"
 
-static void* tag(intptr_t t) { return (void*)t; }
+static void* tag(intptr_t t) { return reinterpret_cast<void*>(t); }
 
 static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config,
                                             const char* test_name,
index 2ac09a3..987125f 100644 (file)
@@ -33,7 +33,7 @@
 #include "src/core/lib/gpr/useful.h"
 #include "test/core/end2end/cq_verifier.h"
 
-static void* tag(intptr_t t) { return (void*)t; }
+static void* tag(intptr_t t) { return reinterpret_cast<void*>(t); }
 
 static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config,
                                             const char* test_name,
index 1750f6f..a1aacd0 100644 (file)
@@ -37,7 +37,7 @@
 #include "src/core/lib/iomgr/ev_posix.h"
 #endif  // GRPC_POSIX_SOCKET
 
-static void* tag(intptr_t t) { return (void*)t; }
+static void* tag(intptr_t t) { return reinterpret_cast<void*>(t); }
 
 static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config,
                                             const char* test_name,
index fb1fe41..07983d8 100644 (file)
@@ -27,7 +27,7 @@
 #include <grpc/support/time.h>
 #include "test/core/end2end/cq_verifier.h"
 
-static void* tag(intptr_t t) { return (void*)t; }
+static void* tag(intptr_t t) { return reinterpret_cast<void*>(t); }
 
 static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config,
                                             const char* test_name,
index 90f2f5a..bd7d7cd 100644 (file)
@@ -27,7 +27,7 @@
 #include <grpc/support/time.h>
 #include "test/core/end2end/cq_verifier.h"
 
-static void* tag(intptr_t t) { return (void*)t; }
+static void* tag(intptr_t t) { return reinterpret_cast<void*>(t); }
 
 static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config,
                                             const char* test_name,
@@ -343,7 +343,7 @@ static void test_max_concurrent_streams(grpc_end2end_test_config config) {
        * both);
        * check this here */
       /* We'll get tag 303 or 403, we want 300, 400 */
-      live_call = (static_cast<int>((intptr_t)ev.tag)) - 1;
+      live_call = (static_cast<int>(reinterpret_cast<intptr_t>(ev.tag))) - 1;
       got_client_start = 1;
     }
   }
index a8979f0..63b8042 100644 (file)
@@ -45,7 +45,7 @@
 /* The grace period for the test to observe the channel shutdown process */
 #define IMMEDIATE_SHUTDOWN_GRACE_TIME_MS 3000
 
-static void* tag(intptr_t t) { return (void*)t; }
+static void* tag(intptr_t t) { return reinterpret_cast<void*>(t); }
 
 static void drain_cq(grpc_completion_queue* cq) {
   grpc_event ev;
index 53701ab..6df32f4 100644 (file)
@@ -32,7 +32,7 @@
 #define MAX_CONNECTION_IDLE_MS 500
 #define MAX_CONNECTION_AGE_MS 9999
 
-static void* tag(intptr_t t) { return (void*)t; }
+static void* tag(intptr_t t) { return reinterpret_cast<void*>(t); }
 
 static void drain_cq(grpc_completion_queue* cq) {
   grpc_event ev;
index 256cc98..ca9f860 100644 (file)
@@ -34,7 +34,7 @@
 
 #include "test/core/end2end/cq_verifier.h"
 
-static void* tag(intptr_t t) { return (void*)t; }
+static void* tag(intptr_t t) { return reinterpret_cast<void*>(t); }
 
 static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config,
                                             const char* test_name,
index 464267c..e975f37 100644 (file)
@@ -30,7 +30,7 @@
 #include "src/core/lib/gpr/string.h"
 #include "test/core/end2end/cq_verifier.h"
 
-static void* tag(intptr_t t) { return (void*)t; }
+static void* tag(intptr_t t) { return reinterpret_cast<void*>(t); }
 
 static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config,
                                             const char* test_name,
index 7affd5b..411ed93 100644 (file)
@@ -31,7 +31,7 @@
 #include "src/core/lib/iomgr/error.h"
 #include "test/core/end2end/cq_verifier.h"
 
-static void* tag(intptr_t t) { return (void*)t; }
+static void* tag(intptr_t t) { return reinterpret_cast<void*>(t); }
 
 static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config,
                                             const char* test_name,
index 8341501..5f32527 100644 (file)
@@ -36,7 +36,7 @@
 
 enum { TIMEOUT = 200000 };
 
-static void* tag(intptr_t t) { return (void*)t; }
+static void* tag(intptr_t t) { return reinterpret_cast<void*>(t); }
 
 void gpr_default_log(gpr_log_func_args* args);
 
@@ -53,10 +53,11 @@ static void test_no_error_log(gpr_log_func_args* args) {
   }
 }
 
-static gpr_atm g_log_func = (gpr_atm)gpr_default_log;
+static gpr_atm g_log_func = reinterpret_cast<gpr_atm>(gpr_default_log);
 
 static void log_dispatcher_func(gpr_log_func_args* args) {
-  gpr_log_func log_func = (gpr_log_func)gpr_atm_no_barrier_load(&g_log_func);
+  gpr_log_func log_func =
+      reinterpret_cast<gpr_log_func>(gpr_atm_no_barrier_load(&g_log_func));
   log_func(args);
 }
 
index 020f842..2c515f1 100644 (file)
@@ -27,7 +27,7 @@
 #include <grpc/support/time.h>
 #include "test/core/end2end/cq_verifier.h"
 
-static void* tag(intptr_t t) { return (void*)t; }
+static void* tag(intptr_t t) { return reinterpret_cast<void*>(t); }
 
 static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config,
                                             const char* test_name,
index 6e2bc16..fab5daf 100644 (file)
@@ -27,7 +27,7 @@
 #include <grpc/support/time.h>
 #include "test/core/end2end/cq_verifier.h"
 
-static void* tag(intptr_t t) { return (void*)t; }
+static void* tag(intptr_t t) { return reinterpret_cast<void*>(t); }
 
 static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config,
                                             const char* test_name,
index 0a97962..28bef18 100644 (file)
@@ -29,7 +29,7 @@
 
 #define PING_NUM 5
 
-static void* tag(intptr_t t) { return (void*)t; }
+static void* tag(intptr_t t) { return reinterpret_cast<void*>(t); }
 
 static void test_ping(grpc_end2end_test_config config,
                       int min_time_between_pings_ms) {
index 30ee0bf..4e030e0 100644 (file)
@@ -27,7 +27,7 @@
 #include <grpc/support/time.h>
 #include "test/core/end2end/cq_verifier.h"
 
-static void* tag(intptr_t t) { return (void*)t; }
+static void* tag(intptr_t t) { return reinterpret_cast<void*>(t); }
 
 static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config,
                                             const char* test_name,
index 3f1443f..3684b27 100644 (file)
@@ -34,7 +34,7 @@
 #include "src/core/lib/gpr/string.h"
 #include "test/core/end2end/cq_verifier.h"
 
-static void* tag(intptr_t t) { return (void*)t; }
+static void* tag(intptr_t t) { return reinterpret_cast<void*>(t); }
 
 static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config,
                                             const char* test_name,
index 6228476..719758e 100644 (file)
@@ -30,7 +30,7 @@
 #include "src/core/lib/gpr/string.h"
 #include "test/core/end2end/cq_verifier.h"
 
-static void* tag(intptr_t t) { return (void*)t; }
+static void* tag(intptr_t t) { return reinterpret_cast<void*>(t); }
 
 static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config,
                                             const char* test_name,
index f3baf37..348e0b6 100644 (file)
@@ -30,7 +30,7 @@
 #include "src/core/lib/transport/byte_stream.h"
 #include "test/core/end2end/cq_verifier.h"
 
-static void* tag(intptr_t t) { return (void*)t; }
+static void* tag(intptr_t t) { return reinterpret_cast<void*>(t); }
 
 static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config,
                                             const char* test_name,
index 37d9481..404c3bf 100644 (file)
@@ -27,7 +27,7 @@
 #include <grpc/support/time.h>
 #include "test/core/end2end/cq_verifier.h"
 
-static void* tag(intptr_t t) { return (void*)t; }
+static void* tag(intptr_t t) { return reinterpret_cast<void*>(t); }
 
 static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config,
                                             const char* test_name,
index df83caa..96c0686 100644 (file)
@@ -28,7 +28,7 @@
 
 #include "test/core/end2end/cq_verifier.h"
 
-static void* tag(intptr_t t) { return (void*)t; }
+static void* tag(intptr_t t) { return reinterpret_cast<void*>(t); }
 
 static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config,
                                             const char* test_name,
@@ -238,7 +238,7 @@ void resource_quota_server(grpc_end2end_test_config config) {
         grpc_completion_queue_next(f.cq, n_seconds_from_now(60), nullptr);
     GPR_ASSERT(ev.type == GRPC_OP_COMPLETE);
 
-    int ev_tag = static_cast<int>((intptr_t)ev.tag);
+    int ev_tag = static_cast<int>(reinterpret_cast<intptr_t>(ev.tag));
     if (ev_tag < CLIENT_BASE_TAG) {
       abort(); /* illegal tag */
     } else if (ev_tag < SERVER_START_BASE_TAG) {
index 243dedc..5e9f8aa 100644 (file)
@@ -37,7 +37,7 @@
 #include "test/core/end2end/cq_verifier.h"
 #include "test/core/end2end/tests/cancel_test_helpers.h"
 
-static void* tag(intptr_t t) { return (void*)t; }
+static void* tag(intptr_t t) { return reinterpret_cast<void*>(t); }
 
 static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config,
                                             const char* test_name,
@@ -182,7 +182,8 @@ static void test_retry(grpc_end2end_test_config config) {
   op->data.recv_status_on_client.status = &status;
   op->data.recv_status_on_client.status_details = &details;
   op++;
-  error = grpc_call_start_batch(c, ops, (size_t)(op - ops), tag(1), nullptr);
+  error = grpc_call_start_batch(c, ops, static_cast<size_t>(op - ops), tag(1),
+                                nullptr);
   GPR_ASSERT(GRPC_CALL_OK == error);
 
   error =
@@ -221,7 +222,8 @@ static void test_retry(grpc_end2end_test_config config) {
   op->op = GRPC_OP_RECV_CLOSE_ON_SERVER;
   op->data.recv_close_on_server.cancelled = &was_cancelled;
   op++;
-  error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(102), nullptr);
+  error = grpc_call_start_batch(s, ops, static_cast<size_t>(op - ops), tag(102),
+                                nullptr);
   GPR_ASSERT(GRPC_CALL_OK == error);
 
   CQ_EXPECT_COMPLETION(cqv, tag(102), true);
@@ -281,7 +283,8 @@ static void test_retry(grpc_end2end_test_config config) {
   op->op = GRPC_OP_RECV_CLOSE_ON_SERVER;
   op->data.recv_close_on_server.cancelled = &was_cancelled;
   op++;
-  error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(202), nullptr);
+  error = grpc_call_start_batch(s, ops, static_cast<size_t>(op - ops), tag(202),
+                                nullptr);
   GPR_ASSERT(GRPC_CALL_OK == error);
 
   CQ_EXPECT_COMPLETION(cqv, tag(202), true);
index 86a8353..261e962 100644 (file)
@@ -40,7 +40,7 @@
 #include "test/core/end2end/cq_verifier.h"
 #include "test/core/end2end/tests/cancel_test_helpers.h"
 
-static void* tag(intptr_t t) { return (void*)t; }
+static void* tag(intptr_t t) { return reinterpret_cast<void*>(t); }
 
 static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config,
                                             const char* test_name,
@@ -186,7 +186,8 @@ static void test_retry_cancellation(grpc_end2end_test_config config,
   op->data.recv_status_on_client.status = &status;
   op->data.recv_status_on_client.status_details = &details;
   op++;
-  error = grpc_call_start_batch(c, ops, (size_t)(op - ops), tag(1), nullptr);
+  error = grpc_call_start_batch(c, ops, static_cast<size_t>(op - ops), tag(1),
+                                nullptr);
   GPR_ASSERT(GRPC_CALL_OK == error);
 
   // Server gets a call and fails with retryable status.
@@ -219,7 +220,8 @@ static void test_retry_cancellation(grpc_end2end_test_config config,
   op->op = GRPC_OP_RECV_CLOSE_ON_SERVER;
   op->data.recv_close_on_server.cancelled = &was_cancelled;
   op++;
-  error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(102), nullptr);
+  error = grpc_call_start_batch(s, ops, static_cast<size_t>(op - ops), tag(102),
+                                nullptr);
   GPR_ASSERT(GRPC_CALL_OK == error);
 
   CQ_EXPECT_COMPLETION(cqv, tag(102), true);
index 340daed..3cdc045 100644 (file)
@@ -37,7 +37,7 @@
 #include "test/core/end2end/cq_verifier.h"
 #include "test/core/end2end/tests/cancel_test_helpers.h"
 
-static void* tag(intptr_t t) { return (void*)t; }
+static void* tag(intptr_t t) { return reinterpret_cast<void*>(t); }
 
 static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config,
                                             const char* test_name,
@@ -186,7 +186,8 @@ static void test_retry_disabled(grpc_end2end_test_config config) {
   op->data.recv_status_on_client.status = &status;
   op->data.recv_status_on_client.status_details = &details;
   op++;
-  error = grpc_call_start_batch(c, ops, (size_t)(op - ops), tag(1), nullptr);
+  error = grpc_call_start_batch(c, ops, static_cast<size_t>(op - ops), tag(1),
+                                nullptr);
   GPR_ASSERT(GRPC_CALL_OK == error);
 
   error =
@@ -218,7 +219,8 @@ static void test_retry_disabled(grpc_end2end_test_config config) {
   op->op = GRPC_OP_RECV_CLOSE_ON_SERVER;
   op->data.recv_close_on_server.cancelled = &was_cancelled;
   op++;
-  error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(102), nullptr);
+  error = grpc_call_start_batch(s, ops, static_cast<size_t>(op - ops), tag(102),
+                                nullptr);
   GPR_ASSERT(GRPC_CALL_OK == error);
 
   CQ_EXPECT_COMPLETION(cqv, tag(102), true);
index 8d2dcc7..4d5f691 100644 (file)
@@ -37,7 +37,7 @@
 #include "test/core/end2end/cq_verifier.h"
 #include "test/core/end2end/tests/cancel_test_helpers.h"
 
-static void* tag(intptr_t t) { return (void*)t; }
+static void* tag(intptr_t t) { return reinterpret_cast<void*>(t); }
 
 static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config,
                                             const char* test_name,
@@ -189,7 +189,8 @@ static void test_retry_exceeds_buffer_size_in_initial_batch(
   op->data.recv_status_on_client.status = &status;
   op->data.recv_status_on_client.status_details = &details;
   op++;
-  error = grpc_call_start_batch(c, ops, (size_t)(op - ops), tag(1), nullptr);
+  error = grpc_call_start_batch(c, ops, static_cast<size_t>(op - ops), tag(1),
+                                nullptr);
   GPR_ASSERT(GRPC_CALL_OK == error);
 
   error =
@@ -221,7 +222,8 @@ static void test_retry_exceeds_buffer_size_in_initial_batch(
   op->op = GRPC_OP_RECV_CLOSE_ON_SERVER;
   op->data.recv_close_on_server.cancelled = &was_cancelled;
   op++;
-  error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(102), nullptr);
+  error = grpc_call_start_batch(s, ops, static_cast<size_t>(op - ops), tag(102),
+                                nullptr);
   GPR_ASSERT(GRPC_CALL_OK == error);
 
   CQ_EXPECT_COMPLETION(cqv, tag(102), true);
index 6a93834..1c99f4c 100644 (file)
@@ -37,7 +37,7 @@
 #include "test/core/end2end/cq_verifier.h"
 #include "test/core/end2end/tests/cancel_test_helpers.h"
 
-static void* tag(intptr_t t) { return (void*)t; }
+static void* tag(intptr_t t) { return reinterpret_cast<void*>(t); }
 
 static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config,
                                             const char* test_name,
@@ -178,7 +178,8 @@ static void test_retry_exceeds_buffer_size_in_subsequent_batch(
   op->op = GRPC_OP_SEND_INITIAL_METADATA;
   op->data.send_initial_metadata.count = 0;
   op++;
-  error = grpc_call_start_batch(c, ops, (size_t)(op - ops), tag(1), nullptr);
+  error = grpc_call_start_batch(c, ops, static_cast<size_t>(op - ops), tag(1),
+                                nullptr);
   GPR_ASSERT(GRPC_CALL_OK == error);
   CQ_EXPECT_COMPLETION(cqv, tag(1), true);
   cq_verify(cqv);
@@ -201,7 +202,8 @@ static void test_retry_exceeds_buffer_size_in_subsequent_batch(
   op->data.recv_status_on_client.status = &status;
   op->data.recv_status_on_client.status_details = &details;
   op++;
-  error = grpc_call_start_batch(c, ops, (size_t)(op - ops), tag(2), nullptr);
+  error = grpc_call_start_batch(c, ops, static_cast<size_t>(op - ops), tag(2),
+                                nullptr);
   GPR_ASSERT(GRPC_CALL_OK == error);
 
   error =
@@ -233,7 +235,8 @@ static void test_retry_exceeds_buffer_size_in_subsequent_batch(
   op->op = GRPC_OP_RECV_CLOSE_ON_SERVER;
   op->data.recv_close_on_server.cancelled = &was_cancelled;
   op++;
-  error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(102), nullptr);
+  error = grpc_call_start_batch(s, ops, static_cast<size_t>(op - ops), tag(102),
+                                nullptr);
   GPR_ASSERT(GRPC_CALL_OK == error);
 
   CQ_EXPECT_COMPLETION(cqv, tag(102), true);
index b8ae4ad..5124713 100644 (file)
@@ -37,7 +37,7 @@
 #include "test/core/end2end/cq_verifier.h"
 #include "test/core/end2end/tests/cancel_test_helpers.h"
 
-static void* tag(intptr_t t) { return (void*)t; }
+static void* tag(intptr_t t) { return reinterpret_cast<void*>(t); }
 
 static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config,
                                             const char* test_name,
@@ -181,7 +181,8 @@ static void test_retry_non_retriable_status(grpc_end2end_test_config config) {
   op->data.recv_status_on_client.status = &status;
   op->data.recv_status_on_client.status_details = &details;
   op++;
-  error = grpc_call_start_batch(c, ops, (size_t)(op - ops), tag(1), nullptr);
+  error = grpc_call_start_batch(c, ops, static_cast<size_t>(op - ops), tag(1),
+                                nullptr);
   GPR_ASSERT(GRPC_CALL_OK == error);
 
   error =
@@ -213,7 +214,8 @@ static void test_retry_non_retriable_status(grpc_end2end_test_config config) {
   op->op = GRPC_OP_RECV_CLOSE_ON_SERVER;
   op->data.recv_close_on_server.cancelled = &was_cancelled;
   op++;
-  error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(102), nullptr);
+  error = grpc_call_start_batch(s, ops, static_cast<size_t>(op - ops), tag(102),
+                                nullptr);
   GPR_ASSERT(GRPC_CALL_OK == error);
 
   CQ_EXPECT_COMPLETION(cqv, tag(102), true);
index c0f35d9..5bdada8 100644 (file)
@@ -37,7 +37,7 @@
 #include "test/core/end2end/cq_verifier.h"
 #include "test/core/end2end/tests/cancel_test_helpers.h"
 
-static void* tag(intptr_t t) { return (void*)t; }
+static void* tag(intptr_t t) { return reinterpret_cast<void*>(t); }
 
 static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config,
                                             const char* test_name,
@@ -179,7 +179,8 @@ test_retry_non_retriable_status_before_recv_trailing_metadata_started(
   op->op = GRPC_OP_RECV_INITIAL_METADATA;
   op->data.recv_initial_metadata.recv_initial_metadata = &initial_metadata_recv;
   op++;
-  error = grpc_call_start_batch(c, ops, (size_t)(op - ops), tag(1), nullptr);
+  error = grpc_call_start_batch(c, ops, static_cast<size_t>(op - ops), tag(1),
+                                nullptr);
   GPR_ASSERT(GRPC_CALL_OK == error);
 
   error =
@@ -211,7 +212,8 @@ test_retry_non_retriable_status_before_recv_trailing_metadata_started(
   op->op = GRPC_OP_RECV_CLOSE_ON_SERVER;
   op->data.recv_close_on_server.cancelled = &was_cancelled;
   op++;
-  error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(102), nullptr);
+  error = grpc_call_start_batch(s, ops, static_cast<size_t>(op - ops), tag(102),
+                                nullptr);
   GPR_ASSERT(GRPC_CALL_OK == error);
 
   CQ_EXPECT_COMPLETION(cqv, tag(102), true);
@@ -225,7 +227,8 @@ test_retry_non_retriable_status_before_recv_trailing_metadata_started(
   op->data.recv_status_on_client.status = &status;
   op->data.recv_status_on_client.status_details = &details;
   op++;
-  error = grpc_call_start_batch(c, ops, (size_t)(op - ops), tag(2), nullptr);
+  error = grpc_call_start_batch(c, ops, static_cast<size_t>(op - ops), tag(2),
+                                nullptr);
   GPR_ASSERT(GRPC_CALL_OK == error);
 
   CQ_EXPECT_COMPLETION(cqv, tag(2), true);
index 6205373..eae84ee 100644 (file)
@@ -37,7 +37,7 @@
 #include "test/core/end2end/cq_verifier.h"
 #include "test/core/end2end/tests/cancel_test_helpers.h"
 
-static void* tag(intptr_t t) { return (void*)t; }
+static void* tag(intptr_t t) { return reinterpret_cast<void*>(t); }
 
 static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config,
                                             const char* test_name,
@@ -182,7 +182,8 @@ static void test_retry_recv_initial_metadata(grpc_end2end_test_config config) {
   op->data.recv_status_on_client.status = &status;
   op->data.recv_status_on_client.status_details = &details;
   op++;
-  error = grpc_call_start_batch(c, ops, (size_t)(op - ops), tag(1), nullptr);
+  error = grpc_call_start_batch(c, ops, static_cast<size_t>(op - ops), tag(1),
+                                nullptr);
   GPR_ASSERT(GRPC_CALL_OK == error);
 
   error =
@@ -208,7 +209,8 @@ static void test_retry_recv_initial_metadata(grpc_end2end_test_config config) {
   op->op = GRPC_OP_SEND_INITIAL_METADATA;
   op->data.send_initial_metadata.count = 0;
   op++;
-  error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(102), nullptr);
+  error = grpc_call_start_batch(s, ops, static_cast<size_t>(op - ops), tag(102),
+                                nullptr);
   GPR_ASSERT(GRPC_CALL_OK == error);
 
   CQ_EXPECT_COMPLETION(cqv, tag(102), true);
@@ -224,7 +226,8 @@ static void test_retry_recv_initial_metadata(grpc_end2end_test_config config) {
   op->op = GRPC_OP_RECV_CLOSE_ON_SERVER;
   op->data.recv_close_on_server.cancelled = &was_cancelled;
   op++;
-  error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(103), nullptr);
+  error = grpc_call_start_batch(s, ops, static_cast<size_t>(op - ops), tag(103),
+                                nullptr);
   GPR_ASSERT(GRPC_CALL_OK == error);
 
   CQ_EXPECT_COMPLETION(cqv, tag(103), true);
index 75be258..f720591 100644 (file)
@@ -37,7 +37,7 @@
 #include "test/core/end2end/cq_verifier.h"
 #include "test/core/end2end/tests/cancel_test_helpers.h"
 
-static void* tag(intptr_t t) { return (void*)t; }
+static void* tag(intptr_t t) { return reinterpret_cast<void*>(t); }
 
 static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config,
                                             const char* test_name,
@@ -182,7 +182,8 @@ static void test_retry_recv_message(grpc_end2end_test_config config) {
   op->data.recv_status_on_client.status = &status;
   op->data.recv_status_on_client.status_details = &details;
   op++;
-  error = grpc_call_start_batch(c, ops, (size_t)(op - ops), tag(1), nullptr);
+  error = grpc_call_start_batch(c, ops, static_cast<size_t>(op - ops), tag(1),
+                                nullptr);
   GPR_ASSERT(GRPC_CALL_OK == error);
 
   error =
@@ -217,7 +218,8 @@ static void test_retry_recv_message(grpc_end2end_test_config config) {
   op->op = GRPC_OP_RECV_CLOSE_ON_SERVER;
   op->data.recv_close_on_server.cancelled = &was_cancelled;
   op++;
-  error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(103), nullptr);
+  error = grpc_call_start_batch(s, ops, static_cast<size_t>(op - ops), tag(103),
+                                nullptr);
   GPR_ASSERT(GRPC_CALL_OK == error);
 
   CQ_EXPECT_COMPLETION(cqv, tag(103), true);
index 221b416..122eb49 100644 (file)
@@ -37,7 +37,7 @@
 #include "test/core/end2end/cq_verifier.h"
 #include "test/core/end2end/tests/cancel_test_helpers.h"
 
-static void* tag(intptr_t t) { return (void*)t; }
+static void* tag(intptr_t t) { return reinterpret_cast<void*>(t); }
 
 static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config,
                                             const char* test_name,
@@ -187,7 +187,8 @@ static void test_retry_server_pushback_delay(grpc_end2end_test_config config) {
   op->data.recv_status_on_client.status = &status;
   op->data.recv_status_on_client.status_details = &details;
   op++;
-  error = grpc_call_start_batch(c, ops, (size_t)(op - ops), tag(1), nullptr);
+  error = grpc_call_start_batch(c, ops, static_cast<size_t>(op - ops), tag(1),
+                                nullptr);
   GPR_ASSERT(GRPC_CALL_OK == error);
 
   error =
@@ -220,7 +221,8 @@ static void test_retry_server_pushback_delay(grpc_end2end_test_config config) {
   op->op = GRPC_OP_RECV_CLOSE_ON_SERVER;
   op->data.recv_close_on_server.cancelled = &was_cancelled;
   op++;
-  error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(102), nullptr);
+  error = grpc_call_start_batch(s, ops, static_cast<size_t>(op - ops), tag(102),
+                                nullptr);
   GPR_ASSERT(GRPC_CALL_OK == error);
 
   CQ_EXPECT_COMPLETION(cqv, tag(102), true);
@@ -274,7 +276,8 @@ static void test_retry_server_pushback_delay(grpc_end2end_test_config config) {
   op->op = GRPC_OP_RECV_CLOSE_ON_SERVER;
   op->data.recv_close_on_server.cancelled = &was_cancelled;
   op++;
-  error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(202), nullptr);
+  error = grpc_call_start_batch(s, ops, static_cast<size_t>(op - ops), tag(202),
+                                nullptr);
   GPR_ASSERT(GRPC_CALL_OK == error);
 
   CQ_EXPECT_COMPLETION(cqv, tag(202), true);
index 28515eb..44a37a4 100644 (file)
@@ -37,7 +37,7 @@
 #include "test/core/end2end/cq_verifier.h"
 #include "test/core/end2end/tests/cancel_test_helpers.h"
 
-static void* tag(intptr_t t) { return (void*)t; }
+static void* tag(intptr_t t) { return reinterpret_cast<void*>(t); }
 
 static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config,
                                             const char* test_name,
@@ -188,7 +188,8 @@ static void test_retry_server_pushback_disabled(
   op->data.recv_status_on_client.status = &status;
   op->data.recv_status_on_client.status_details = &details;
   op++;
-  error = grpc_call_start_batch(c, ops, (size_t)(op - ops), tag(1), nullptr);
+  error = grpc_call_start_batch(c, ops, static_cast<size_t>(op - ops), tag(1),
+                                nullptr);
   GPR_ASSERT(GRPC_CALL_OK == error);
 
   error =
@@ -220,7 +221,8 @@ static void test_retry_server_pushback_disabled(
   op->op = GRPC_OP_RECV_CLOSE_ON_SERVER;
   op->data.recv_close_on_server.cancelled = &was_cancelled;
   op++;
-  error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(102), nullptr);
+  error = grpc_call_start_batch(s, ops, static_cast<size_t>(op - ops), tag(102),
+                                nullptr);
   GPR_ASSERT(GRPC_CALL_OK == error);
 
   CQ_EXPECT_COMPLETION(cqv, tag(102), true);
@@ -262,7 +264,8 @@ static void test_retry_server_pushback_disabled(
   op->op = GRPC_OP_RECV_CLOSE_ON_SERVER;
   op->data.recv_close_on_server.cancelled = &was_cancelled;
   op++;
-  error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(202), nullptr);
+  error = grpc_call_start_batch(s, ops, static_cast<size_t>(op - ops), tag(202),
+                                nullptr);
   GPR_ASSERT(GRPC_CALL_OK == error);
 
   CQ_EXPECT_COMPLETION(cqv, tag(202), true);
index 784014c..2521910 100644 (file)
@@ -40,7 +40,7 @@
 #include "test/core/end2end/cq_verifier.h"
 #include "test/core/end2end/tests/cancel_test_helpers.h"
 
-static void* tag(intptr_t t) { return (void*)t; }
+static void* tag(intptr_t t) { return reinterpret_cast<void*>(t); }
 
 static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config,
                                             const char* test_name,
@@ -200,7 +200,8 @@ static void test_retry_streaming(grpc_end2end_test_config config) {
   op->data.recv_status_on_client.status = &status;
   op->data.recv_status_on_client.status_details = &details;
   op++;
-  error = grpc_call_start_batch(c, ops, (size_t)(op - ops), tag(1), nullptr);
+  error = grpc_call_start_batch(c, ops, static_cast<size_t>(op - ops), tag(1),
+                                nullptr);
   GPR_ASSERT(GRPC_CALL_OK == error);
 
   // Client sends initial metadata and a message.
@@ -212,7 +213,8 @@ static void test_retry_streaming(grpc_end2end_test_config config) {
   op->op = GRPC_OP_SEND_MESSAGE;
   op->data.send_message.send_message = request_payload;
   op++;
-  error = grpc_call_start_batch(c, ops, (size_t)(op - ops), tag(2), nullptr);
+  error = grpc_call_start_batch(c, ops, static_cast<size_t>(op - ops), tag(2),
+                                nullptr);
   GPR_ASSERT(GRPC_CALL_OK == error);
   CQ_EXPECT_COMPLETION(cqv, tag(2), true);
   cq_verify(cqv);
@@ -240,7 +242,8 @@ static void test_retry_streaming(grpc_end2end_test_config config) {
   op->op = GRPC_OP_RECV_MESSAGE;
   op->data.recv_message.recv_message = &request_payload_recv;
   op++;
-  error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(102), nullptr);
+  error = grpc_call_start_batch(s, ops, static_cast<size_t>(op - ops), tag(102),
+                                nullptr);
   GPR_ASSERT(GRPC_CALL_OK == error);
   CQ_EXPECT_COMPLETION(cqv, tag(102), true);
   cq_verify(cqv);
@@ -251,7 +254,8 @@ static void test_retry_streaming(grpc_end2end_test_config config) {
   op->op = GRPC_OP_SEND_MESSAGE;
   op->data.send_message.send_message = request2_payload;
   op++;
-  error = grpc_call_start_batch(c, ops, (size_t)(op - ops), tag(3), nullptr);
+  error = grpc_call_start_batch(c, ops, static_cast<size_t>(op - ops), tag(3),
+                                nullptr);
   GPR_ASSERT(GRPC_CALL_OK == error);
   CQ_EXPECT_COMPLETION(cqv, tag(3), true);
   cq_verify(cqv);
@@ -262,7 +266,8 @@ static void test_retry_streaming(grpc_end2end_test_config config) {
   op->op = GRPC_OP_RECV_MESSAGE;
   op->data.recv_message.recv_message = &request2_payload_recv;
   op++;
-  error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(103), nullptr);
+  error = grpc_call_start_batch(s, ops, static_cast<size_t>(op - ops), tag(103),
+                                nullptr);
   GPR_ASSERT(GRPC_CALL_OK == error);
   CQ_EXPECT_COMPLETION(cqv, tag(103), true);
   cq_verify(cqv);
@@ -281,7 +286,8 @@ static void test_retry_streaming(grpc_end2end_test_config config) {
   op->data.send_status_from_server.status = GRPC_STATUS_ABORTED;
   op->data.send_status_from_server.status_details = &status_details;
   op++;
-  error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(104), nullptr);
+  error = grpc_call_start_batch(s, ops, static_cast<size_t>(op - ops), tag(104),
+                                nullptr);
   GPR_ASSERT(GRPC_CALL_OK == error);
   CQ_EXPECT_COMPLETION(cqv, tag(104), true);
   cq_verify(cqv);
@@ -323,7 +329,8 @@ static void test_retry_streaming(grpc_end2end_test_config config) {
   op->op = GRPC_OP_RECV_MESSAGE;
   op->data.recv_message.recv_message = &request_payload_recv;
   op++;
-  error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(202), nullptr);
+  error = grpc_call_start_batch(s, ops, static_cast<size_t>(op - ops), tag(202),
+                                nullptr);
   GPR_ASSERT(GRPC_CALL_OK == error);
   CQ_EXPECT_COMPLETION(cqv, tag(202), true);
   cq_verify(cqv);
@@ -334,7 +341,8 @@ static void test_retry_streaming(grpc_end2end_test_config config) {
   op->op = GRPC_OP_RECV_MESSAGE;
   op->data.recv_message.recv_message = &request2_payload_recv;
   op++;
-  error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(203), nullptr);
+  error = grpc_call_start_batch(s, ops, static_cast<size_t>(op - ops), tag(203),
+                                nullptr);
   GPR_ASSERT(GRPC_CALL_OK == error);
   CQ_EXPECT_COMPLETION(cqv, tag(203), true);
   cq_verify(cqv);
@@ -347,7 +355,8 @@ static void test_retry_streaming(grpc_end2end_test_config config) {
   op++;
   op->op = GRPC_OP_SEND_CLOSE_FROM_CLIENT;
   op++;
-  error = grpc_call_start_batch(c, ops, (size_t)(op - ops), tag(4), nullptr);
+  error = grpc_call_start_batch(c, ops, static_cast<size_t>(op - ops), tag(4),
+                                nullptr);
   GPR_ASSERT(GRPC_CALL_OK == error);
   CQ_EXPECT_COMPLETION(cqv, tag(4), true);
   cq_verify(cqv);
@@ -358,7 +367,8 @@ static void test_retry_streaming(grpc_end2end_test_config config) {
   op->op = GRPC_OP_RECV_MESSAGE;
   op->data.recv_message.recv_message = &request3_payload_recv;
   op++;
-  error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(204), nullptr);
+  error = grpc_call_start_batch(s, ops, static_cast<size_t>(op - ops), tag(204),
+                                nullptr);
   GPR_ASSERT(GRPC_CALL_OK == error);
   CQ_EXPECT_COMPLETION(cqv, tag(204), true);
   cq_verify(cqv);
@@ -383,7 +393,8 @@ static void test_retry_streaming(grpc_end2end_test_config config) {
   op->data.send_status_from_server.status = GRPC_STATUS_ABORTED;
   op->data.send_status_from_server.status_details = &status_details;
   op++;
-  error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(205), nullptr);
+  error = grpc_call_start_batch(s, ops, static_cast<size_t>(op - ops), tag(205),
+                                nullptr);
   GPR_ASSERT(GRPC_CALL_OK == error);
   CQ_EXPECT_COMPLETION(cqv, tag(205), true);
   CQ_EXPECT_COMPLETION(cqv, tag(1), true);
index 509d56d..de7d7c3 100644 (file)
@@ -37,7 +37,7 @@
 #include "test/core/end2end/cq_verifier.h"
 #include "test/core/end2end/tests/cancel_test_helpers.h"
 
-static void* tag(intptr_t t) { return (void*)t; }
+static void* tag(intptr_t t) { return reinterpret_cast<void*>(t); }
 
 static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config,
                                             const char* test_name,
@@ -177,7 +177,8 @@ static void test_retry_streaming_after_commit(grpc_end2end_test_config config) {
   op->op = GRPC_OP_RECV_MESSAGE;
   op->data.recv_message.recv_message = &response_payload_recv;
   op++;
-  error = grpc_call_start_batch(c, ops, (size_t)(op - ops), tag(2), nullptr);
+  error = grpc_call_start_batch(c, ops, static_cast<size_t>(op - ops), tag(2),
+                                nullptr);
   GPR_ASSERT(GRPC_CALL_OK == error);
 
   // Client sends initial metadata and a message.
@@ -189,7 +190,8 @@ static void test_retry_streaming_after_commit(grpc_end2end_test_config config) {
   op->op = GRPC_OP_SEND_MESSAGE;
   op->data.send_message.send_message = request_payload;
   op++;
-  error = grpc_call_start_batch(c, ops, (size_t)(op - ops), tag(3), nullptr);
+  error = grpc_call_start_batch(c, ops, static_cast<size_t>(op - ops), tag(3),
+                                nullptr);
   GPR_ASSERT(GRPC_CALL_OK == error);
   CQ_EXPECT_COMPLETION(cqv, tag(3), true);
   cq_verify(cqv);
@@ -217,7 +219,8 @@ static void test_retry_streaming_after_commit(grpc_end2end_test_config config) {
   op->op = GRPC_OP_RECV_MESSAGE;
   op->data.recv_message.recv_message = &request_payload_recv;
   op++;
-  error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(102), nullptr);
+  error = grpc_call_start_batch(s, ops, static_cast<size_t>(op - ops), tag(102),
+                                nullptr);
   GPR_ASSERT(GRPC_CALL_OK == error);
   CQ_EXPECT_COMPLETION(cqv, tag(102), true);
   cq_verify(cqv);
@@ -231,7 +234,8 @@ static void test_retry_streaming_after_commit(grpc_end2end_test_config config) {
   op->op = GRPC_OP_SEND_MESSAGE;
   op->data.send_message.send_message = response_payload;
   op++;
-  error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(103), nullptr);
+  error = grpc_call_start_batch(s, ops, static_cast<size_t>(op - ops), tag(103),
+                                nullptr);
   GPR_ASSERT(GRPC_CALL_OK == error);
   CQ_EXPECT_COMPLETION(cqv, tag(103), true);
   // Client receives initial metadata and a message.
@@ -246,7 +250,8 @@ static void test_retry_streaming_after_commit(grpc_end2end_test_config config) {
   op++;
   op->op = GRPC_OP_SEND_CLOSE_FROM_CLIENT;
   op++;
-  error = grpc_call_start_batch(c, ops, (size_t)(op - ops), tag(4), nullptr);
+  error = grpc_call_start_batch(c, ops, static_cast<size_t>(op - ops), tag(4),
+                                nullptr);
   GPR_ASSERT(GRPC_CALL_OK == error);
   CQ_EXPECT_COMPLETION(cqv, tag(4), true);
   cq_verify(cqv);
@@ -257,7 +262,8 @@ static void test_retry_streaming_after_commit(grpc_end2end_test_config config) {
   op->op = GRPC_OP_RECV_MESSAGE;
   op->data.recv_message.recv_message = &request2_payload_recv;
   op++;
-  error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(104), nullptr);
+  error = grpc_call_start_batch(s, ops, static_cast<size_t>(op - ops), tag(104),
+                                nullptr);
   GPR_ASSERT(GRPC_CALL_OK == error);
   CQ_EXPECT_COMPLETION(cqv, tag(104), true);
   cq_verify(cqv);
@@ -278,7 +284,8 @@ static void test_retry_streaming_after_commit(grpc_end2end_test_config config) {
   op->data.send_status_from_server.status = GRPC_STATUS_ABORTED;
   op->data.send_status_from_server.status_details = &status_details;
   op++;
-  error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(105), nullptr);
+  error = grpc_call_start_batch(s, ops, static_cast<size_t>(op - ops), tag(105),
+                                nullptr);
   GPR_ASSERT(GRPC_CALL_OK == error);
   CQ_EXPECT_COMPLETION(cqv, tag(105), true);
   cq_verify(cqv);
@@ -289,7 +296,8 @@ static void test_retry_streaming_after_commit(grpc_end2end_test_config config) {
   op->op = GRPC_OP_RECV_MESSAGE;
   op->data.recv_message.recv_message = &response2_payload_recv;
   op++;
-  error = grpc_call_start_batch(c, ops, (size_t)(op - ops), tag(5), nullptr);
+  error = grpc_call_start_batch(c, ops, static_cast<size_t>(op - ops), tag(5),
+                                nullptr);
   GPR_ASSERT(GRPC_CALL_OK == error);
   CQ_EXPECT_COMPLETION(cqv, tag(5), true);
   cq_verify(cqv);
@@ -302,7 +310,8 @@ static void test_retry_streaming_after_commit(grpc_end2end_test_config config) {
   op->data.recv_status_on_client.status = &status;
   op->data.recv_status_on_client.status_details = &details;
   op++;
-  error = grpc_call_start_batch(c, ops, (size_t)(op - ops), tag(1), nullptr);
+  error = grpc_call_start_batch(c, ops, static_cast<size_t>(op - ops), tag(1),
+                                nullptr);
   GPR_ASSERT(GRPC_CALL_OK == error);
   CQ_EXPECT_COMPLETION(cqv, tag(1), true);
   cq_verify(cqv);
index dbe2ef1..866c948 100644 (file)
@@ -37,7 +37,7 @@
 #include "test/core/end2end/cq_verifier.h"
 #include "test/core/end2end/tests/cancel_test_helpers.h"
 
-static void* tag(intptr_t t) { return (void*)t; }
+static void* tag(intptr_t t) { return reinterpret_cast<void*>(t); }
 
 static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config,
                                             const char* test_name,
@@ -183,7 +183,8 @@ static void test_retry_streaming_succeeds_before_replay_finished(
   op->data.recv_status_on_client.status = &status;
   op->data.recv_status_on_client.status_details = &details;
   op++;
-  error = grpc_call_start_batch(c, ops, (size_t)(op - ops), tag(1), nullptr);
+  error = grpc_call_start_batch(c, ops, static_cast<size_t>(op - ops), tag(1),
+                                nullptr);
   GPR_ASSERT(GRPC_CALL_OK == error);
 
   // Client sends initial metadata and a message.
@@ -195,7 +196,8 @@ static void test_retry_streaming_succeeds_before_replay_finished(
   op->op = GRPC_OP_SEND_MESSAGE;
   op->data.send_message.send_message = request_payload;
   op++;
-  error = grpc_call_start_batch(c, ops, (size_t)(op - ops), tag(2), nullptr);
+  error = grpc_call_start_batch(c, ops, static_cast<size_t>(op - ops), tag(2),
+                                nullptr);
   GPR_ASSERT(GRPC_CALL_OK == error);
   CQ_EXPECT_COMPLETION(cqv, tag(2), true);
   cq_verify(cqv);
@@ -223,7 +225,8 @@ static void test_retry_streaming_succeeds_before_replay_finished(
   op->op = GRPC_OP_RECV_MESSAGE;
   op->data.recv_message.recv_message = &request_payload_recv;
   op++;
-  error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(102), nullptr);
+  error = grpc_call_start_batch(s, ops, static_cast<size_t>(op - ops), tag(102),
+                                nullptr);
   GPR_ASSERT(GRPC_CALL_OK == error);
   CQ_EXPECT_COMPLETION(cqv, tag(102), true);
   cq_verify(cqv);
@@ -234,7 +237,8 @@ static void test_retry_streaming_succeeds_before_replay_finished(
   op->op = GRPC_OP_SEND_MESSAGE;
   op->data.send_message.send_message = request2_payload;
   op++;
-  error = grpc_call_start_batch(c, ops, (size_t)(op - ops), tag(3), nullptr);
+  error = grpc_call_start_batch(c, ops, static_cast<size_t>(op - ops), tag(3),
+                                nullptr);
   GPR_ASSERT(GRPC_CALL_OK == error);
   CQ_EXPECT_COMPLETION(cqv, tag(3), true);
   cq_verify(cqv);
@@ -245,7 +249,8 @@ static void test_retry_streaming_succeeds_before_replay_finished(
   op->op = GRPC_OP_RECV_MESSAGE;
   op->data.recv_message.recv_message = &request2_payload_recv;
   op++;
-  error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(103), nullptr);
+  error = grpc_call_start_batch(s, ops, static_cast<size_t>(op - ops), tag(103),
+                                nullptr);
   GPR_ASSERT(GRPC_CALL_OK == error);
   CQ_EXPECT_COMPLETION(cqv, tag(103), true);
   cq_verify(cqv);
@@ -256,7 +261,8 @@ static void test_retry_streaming_succeeds_before_replay_finished(
   op->op = GRPC_OP_SEND_MESSAGE;
   op->data.send_message.send_message = request3_payload;
   op++;
-  error = grpc_call_start_batch(c, ops, (size_t)(op - ops), tag(4), nullptr);
+  error = grpc_call_start_batch(c, ops, static_cast<size_t>(op - ops), tag(4),
+                                nullptr);
   GPR_ASSERT(GRPC_CALL_OK == error);
   CQ_EXPECT_COMPLETION(cqv, tag(4), true);
   cq_verify(cqv);
@@ -267,7 +273,8 @@ static void test_retry_streaming_succeeds_before_replay_finished(
   op->op = GRPC_OP_RECV_MESSAGE;
   op->data.recv_message.recv_message = &request3_payload_recv;
   op++;
-  error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(104), nullptr);
+  error = grpc_call_start_batch(s, ops, static_cast<size_t>(op - ops), tag(104),
+                                nullptr);
   GPR_ASSERT(GRPC_CALL_OK == error);
   CQ_EXPECT_COMPLETION(cqv, tag(104), true);
   cq_verify(cqv);
@@ -286,7 +293,8 @@ static void test_retry_streaming_succeeds_before_replay_finished(
   op->data.send_status_from_server.status = GRPC_STATUS_ABORTED;
   op->data.send_status_from_server.status_details = &status_details;
   op++;
-  error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(105), nullptr);
+  error = grpc_call_start_batch(s, ops, static_cast<size_t>(op - ops), tag(105),
+                                nullptr);
   GPR_ASSERT(GRPC_CALL_OK == error);
   CQ_EXPECT_COMPLETION(cqv, tag(105), true);
   cq_verify(cqv);
@@ -332,7 +340,8 @@ static void test_retry_streaming_succeeds_before_replay_finished(
   op->op = GRPC_OP_RECV_MESSAGE;
   op->data.recv_message.recv_message = &request_payload_recv;
   op++;
-  error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(202), nullptr);
+  error = grpc_call_start_batch(s, ops, static_cast<size_t>(op - ops), tag(202),
+                                nullptr);
   GPR_ASSERT(GRPC_CALL_OK == error);
   CQ_EXPECT_COMPLETION(cqv, tag(202), true);
   cq_verify(cqv);
@@ -353,7 +362,8 @@ static void test_retry_streaming_succeeds_before_replay_finished(
   op->data.send_status_from_server.status = GRPC_STATUS_ABORTED;
   op->data.send_status_from_server.status_details = &status_details;
   op++;
-  error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(205), nullptr);
+  error = grpc_call_start_batch(s, ops, static_cast<size_t>(op - ops), tag(205),
+                                nullptr);
   GPR_ASSERT(GRPC_CALL_OK == error);
   CQ_EXPECT_COMPLETION(cqv, tag(205), true);
   CQ_EXPECT_COMPLETION(cqv, tag(1), true);
index 61ced01..9fdca88 100644 (file)
@@ -37,7 +37,7 @@
 #include "test/core/end2end/cq_verifier.h"
 #include "test/core/end2end/tests/cancel_test_helpers.h"
 
-static void* tag(intptr_t t) { return (void*)t; }
+static void* tag(intptr_t t) { return reinterpret_cast<void*>(t); }
 
 static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config,
                                             const char* test_name,
@@ -188,7 +188,8 @@ static void test_retry_throttled(grpc_end2end_test_config config) {
   op->data.recv_status_on_client.status = &status;
   op->data.recv_status_on_client.status_details = &details;
   op++;
-  error = grpc_call_start_batch(c, ops, (size_t)(op - ops), tag(1), nullptr);
+  error = grpc_call_start_batch(c, ops, static_cast<size_t>(op - ops), tag(1),
+                                nullptr);
   GPR_ASSERT(GRPC_CALL_OK == error);
 
   error =
@@ -220,7 +221,8 @@ static void test_retry_throttled(grpc_end2end_test_config config) {
   op->op = GRPC_OP_RECV_CLOSE_ON_SERVER;
   op->data.recv_close_on_server.cancelled = &was_cancelled;
   op++;
-  error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(102), nullptr);
+  error = grpc_call_start_batch(s, ops, static_cast<size_t>(op - ops), tag(102),
+                                nullptr);
   GPR_ASSERT(GRPC_CALL_OK == error);
 
   CQ_EXPECT_COMPLETION(cqv, tag(102), true);
index 2094451..2a8301f 100644 (file)
@@ -37,7 +37,7 @@
 #include "test/core/end2end/cq_verifier.h"
 #include "test/core/end2end/tests/cancel_test_helpers.h"
 
-static void* tag(intptr_t t) { return (void*)t; }
+static void* tag(intptr_t t) { return reinterpret_cast<void*>(t); }
 
 static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config,
                                             const char* test_name,
@@ -182,7 +182,8 @@ static void test_retry_too_many_attempts(grpc_end2end_test_config config) {
   op->data.recv_status_on_client.status = &status;
   op->data.recv_status_on_client.status_details = &details;
   op++;
-  error = grpc_call_start_batch(c, ops, (size_t)(op - ops), tag(1), nullptr);
+  error = grpc_call_start_batch(c, ops, static_cast<size_t>(op - ops), tag(1),
+                                nullptr);
   GPR_ASSERT(GRPC_CALL_OK == error);
 
   error =
@@ -214,7 +215,8 @@ static void test_retry_too_many_attempts(grpc_end2end_test_config config) {
   op->op = GRPC_OP_RECV_CLOSE_ON_SERVER;
   op->data.recv_close_on_server.cancelled = &was_cancelled;
   op++;
-  error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(102), nullptr);
+  error = grpc_call_start_batch(s, ops, static_cast<size_t>(op - ops), tag(102),
+                                nullptr);
   GPR_ASSERT(GRPC_CALL_OK == error);
 
   CQ_EXPECT_COMPLETION(cqv, tag(102), true);
@@ -255,7 +257,8 @@ static void test_retry_too_many_attempts(grpc_end2end_test_config config) {
   op->op = GRPC_OP_RECV_CLOSE_ON_SERVER;
   op->data.recv_close_on_server.cancelled = &was_cancelled;
   op++;
-  error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(202), nullptr);
+  error = grpc_call_start_batch(s, ops, static_cast<size_t>(op - ops), tag(202),
+                                nullptr);
   GPR_ASSERT(GRPC_CALL_OK == error);
 
   CQ_EXPECT_COMPLETION(cqv, tag(202), true);
index dc489a4..859fa61 100644 (file)
@@ -29,7 +29,7 @@
 #include "src/core/lib/gpr/string.h"
 #include "test/core/end2end/cq_verifier.h"
 
-static void* tag(intptr_t t) { return (void*)t; }
+static void* tag(intptr_t t) { return reinterpret_cast<void*>(t); }
 
 static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config,
                                             const char* test_name,
index ece86f8..f457e65 100644 (file)
@@ -27,7 +27,7 @@
 #include <grpc/support/time.h>
 #include "test/core/end2end/cq_verifier.h"
 
-static void* tag(intptr_t t) { return (void*)t; }
+static void* tag(intptr_t t) { return reinterpret_cast<void*>(t); }
 
 static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config,
                                             const char* test_name,
index 60b738e..443c3ce 100644 (file)
@@ -27,7 +27,7 @@
 #include <grpc/support/time.h>
 #include "test/core/end2end/cq_verifier.h"
 
-static void* tag(intptr_t t) { return (void*)t; }
+static void* tag(intptr_t t) { return reinterpret_cast<void*>(t); }
 
 static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config,
                                             const char* test_name,
index 55caacb..92f45e5 100644 (file)
@@ -27,7 +27,7 @@
 #include <grpc/support/time.h>
 #include "test/core/end2end/cq_verifier.h"
 
-static void* tag(intptr_t t) { return (void*)t; }
+static void* tag(intptr_t t) { return reinterpret_cast<void*>(t); }
 
 static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config,
                                             const char* test_name,
@@ -77,7 +77,7 @@ static void test_early_server_shutdown_finishes_tags(
   grpc_end2end_test_fixture f = begin_test(
       config, "test_early_server_shutdown_finishes_tags", nullptr, nullptr);
   cq_verifier* cqv = cq_verifier_create(f.cq);
-  grpc_call* s = (grpc_call*)static_cast<uintptr_t>(1);
+  grpc_call* s = reinterpret_cast<grpc_call*>(1);
   grpc_call_details call_details;
   grpc_metadata_array request_metadata_recv;
 
index be6d16e..25a09a7 100644 (file)
@@ -29,7 +29,7 @@
 
 enum { TIMEOUT = 200000 };
 
-static void* tag(intptr_t t) { return (void*)t; }
+static void* tag(intptr_t t) { return reinterpret_cast<void*>(t); }
 
 static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config,
                                             const char* test_name,
index 4b2b7ce..947e397 100644 (file)
@@ -27,7 +27,7 @@
 #include <grpc/support/time.h>
 #include "test/core/end2end/cq_verifier.h"
 
-static void* tag(intptr_t t) { return (void*)t; }
+static void* tag(intptr_t t) { return reinterpret_cast<void*>(t); }
 
 static gpr_timespec n_seconds_from_now(int n) {
   return grpc_timeout_seconds_to_deadline(n);
index 3e476c2..9e1a18b 100644 (file)
@@ -27,7 +27,7 @@
 #include <grpc/support/time.h>
 #include "test/core/end2end/cq_verifier.h"
 
-static void* tag(intptr_t t) { return (void*)t; }
+static void* tag(intptr_t t) { return reinterpret_cast<void*>(t); }
 
 static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config,
                                             const char* test_name,
index afeb43d..c9782a1 100644 (file)
@@ -32,7 +32,7 @@
 #include "src/core/lib/gpr/string.h"
 #include "test/core/end2end/cq_verifier.h"
 
-static void* tag(intptr_t t) { return (void*)t; }
+static void* tag(intptr_t t) { return reinterpret_cast<void*>(t); }
 
 static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config,
                                             const char* test_name,
@@ -228,7 +228,7 @@ static void simple_request_body(grpc_end2end_test_config config,
   GPR_ASSERT(was_cancelled == 0);
 
   grpc_slice_unref(details);
-  gpr_free((void*)error_string);
+  gpr_free(const_cast<char*>(error_string));
   grpc_metadata_array_destroy(&initial_metadata_recv);
   grpc_metadata_array_destroy(&trailing_metadata_recv);
   grpc_metadata_array_destroy(&request_metadata_recv);
index 8fa7af5..3bb481a 100644 (file)
@@ -39,7 +39,7 @@
 #include "src/core/lib/transport/static_metadata.h"
 #include "test/core/end2end/cq_verifier.h"
 
-static void* tag(intptr_t t) { return (void*)t; }
+static void* tag(intptr_t t) { return reinterpret_cast<void*>(t); }
 
 static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config,
                                             const char* test_name,
index b67566e..cf29185 100644 (file)
@@ -31,7 +31,7 @@
 #include "src/core/lib/surface/call.h"
 #include "test/core/end2end/cq_verifier.h"
 
-static void* tag(intptr_t t) { return (void*)t; }
+static void* tag(intptr_t t) { return reinterpret_cast<void*>(t); }
 
 static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config,
                                             const char* test_name,
index 39698bd..36c6cd2 100644 (file)
@@ -32,7 +32,7 @@
 #include "src/core/lib/surface/call.h"
 #include "test/core/end2end/cq_verifier.h"
 
-static void* tag(intptr_t t) { return (void*)t; }
+static void* tag(intptr_t t) { return reinterpret_cast<void*>(t); }
 
 static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config,
                                             const char* test_name,
index 0502bba..df0c778 100644 (file)
@@ -30,7 +30,7 @@
 #include <grpc/support/time.h>
 #include "test/core/end2end/cq_verifier.h"
 
-static void* tag(intptr_t t) { return (void*)t; }
+static void* tag(intptr_t t) { return reinterpret_cast<void*>(t); }
 
 static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config,
                                             const char* test_name,
index 5cf6f2b..1201729 100644 (file)
@@ -27,7 +27,7 @@
 #include <grpc/support/time.h>
 #include "test/core/end2end/cq_verifier.h"
 
-static void* tag(intptr_t t) { return (void*)t; }
+static void* tag(intptr_t t) { return reinterpret_cast<void*>(t); }
 
 static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config,
                                             const char* test_name,
index 5ffb477..69b33eb 100644 (file)
@@ -36,7 +36,7 @@
 #include "src/core/lib/transport/static_metadata.h"
 #include "test/core/end2end/cq_verifier.h"
 
-static void* tag(intptr_t t) { return (void*)t; }
+static void* tag(intptr_t t) { return reinterpret_cast<void*>(t); }
 
 static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config,
                                             const char* test_name,
index 2f7ee9c..2f1b297 100644 (file)
@@ -27,7 +27,7 @@
 #include <grpc/support/time.h>
 #include "test/core/end2end/cq_verifier.h"
 
-static void* tag(intptr_t t) { return (void*)t; }
+static void* tag(intptr_t t) { return reinterpret_cast<void*>(t); }
 
 static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config,
                                             const char* test_name,
index 886d491..55c208f 100644 (file)
@@ -27,7 +27,7 @@
 #include <grpc/support/time.h>
 #include "test/core/end2end/cq_verifier.h"
 
-static void* tag(intptr_t t) { return (void*)t; }
+static void* tag(intptr_t t) { return reinterpret_cast<void*>(t); }
 
 static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config,
                                             const char* test_name,
index 2a7a5ca..c9db195 100644 (file)
@@ -104,7 +104,8 @@ static void init_ping_pong_stream(void) {
   stream_init_ops[1].op = GRPC_OP_RECV_INITIAL_METADATA;
   stream_init_ops[1].data.recv_initial_metadata.recv_initial_metadata =
       &initial_metadata_recv;
-  error = grpc_call_start_batch(call, stream_init_ops, 2, (void*)1, nullptr);
+  error = grpc_call_start_batch(call, stream_init_ops, 2,
+                                reinterpret_cast<void*>(1), nullptr);
   GPR_ASSERT(GRPC_CALL_OK == error);
   grpc_completion_queue_next(cq, gpr_inf_future(GPR_CLOCK_REALTIME), nullptr);
 
@@ -119,7 +120,8 @@ static void init_ping_pong_stream(void) {
 static void step_ping_pong_stream(void) {
   GPR_TIMER_SCOPE("ping_pong", 1);
   grpc_call_error error;
-  error = grpc_call_start_batch(call, stream_step_ops, 2, (void*)1, nullptr);
+  error = grpc_call_start_batch(call, stream_step_ops, 2,
+                                reinterpret_cast<void*>(1), nullptr);
   GPR_ASSERT(GRPC_CALL_OK == error);
   grpc_completion_queue_next(cq, gpr_inf_future(GPR_CLOCK_REALTIME), nullptr);
   grpc_byte_buffer_destroy(response_payload_recv);
index 54ce02d..80b1ebd 100644 (file)
@@ -50,7 +50,7 @@ int main(int /*argc*/, char** argv) {
   std::string joined = grpc_core::JoinHostPort("::", port);
   args[2] = const_cast<char*>(joined.c_str());
   args[3] = const_cast<char*>("--no-secure");
-  svr = gpr_subprocess_create(4, (const char**)args);
+  svr = gpr_subprocess_create(4, const_cast<const char**>(args));
 
   /* start the client */
   command =
@@ -62,7 +62,7 @@ int main(int /*argc*/, char** argv) {
   args[3] = const_cast<char*>("--scenario=ping-pong-stream");
   args[4] = const_cast<char*>("--no-secure");
   args[5] = nullptr;
-  cli = gpr_subprocess_create(6, (const char**)args);
+  cli = gpr_subprocess_create(6, const_cast<const char**>(args));
 
   /* wait for completion */
   printf("waiting for client\n");
index f1c6728..0f0d8fe 100644 (file)
@@ -52,7 +52,7 @@ int main(int /*argc*/, const char** argv) {
   std::string joined = grpc_core::JoinHostPort("::", port);
   args[2] = const_cast<char*>(joined.c_str());
   args[3] = const_cast<char*>("--no-secure");
-  svr = gpr_subprocess_create(4, (const char**)args);
+  svr = gpr_subprocess_create(4, const_cast<const char**>(args));
 
   /* start the client */
   command =
@@ -64,7 +64,7 @@ int main(int /*argc*/, const char** argv) {
   args[3] = const_cast<char*>("--scenario=ping-pong-request");
   args[4] = const_cast<char*>("--no-secure");
   args[5] = nullptr;
-  cli = gpr_subprocess_create(6, (const char**)args);
+  cli = gpr_subprocess_create(6, const_cast<const char**>(args));
 
   /* wait for completion */
   printf("waiting for client\n");
index 4085e28..af9bd55 100644 (file)
@@ -59,7 +59,7 @@ static int was_cancelled = 2;
 static grpc_op unary_ops[6];
 static int got_sigint = 0;
 
-static void* tag(intptr_t t) { return (void*)t; }
+static void* tag(intptr_t t) { return reinterpret_cast<void*>(t); }
 
 typedef enum {
   FLING_SERVER_NEW_REQUEST = 1,
@@ -253,7 +253,7 @@ int main(int argc, char** argv) {
     s = static_cast<call_state*>(ev.tag);
     switch (ev.type) {
       case GRPC_OP_COMPLETE:
-        switch ((intptr_t)s) {
+        switch (reinterpret_cast<intptr_t>(s)) {
           case FLING_SERVER_NEW_REQUEST:
             if (call != nullptr) {
               if (0 == grpc_slice_str_cmp(call_details.method,
index b38b17f..83f3e3c 100644 (file)
@@ -65,6 +65,9 @@ grpc_cc_test(
 grpc_cc_test(
     name = "log_test",
     srcs = ["log_test.cc"],
+    external_deps = [
+        "gtest",
+    ],
     language = "C++",
     uses_polling = False,
     deps = [
index c7aa63a..64bd058 100644 (file)
@@ -106,7 +106,7 @@ static void concurrent_test(void) {
     thds[i].Start();
   }
 
-  gpr_event_set(&args.ev_start, (void*)1);
+  gpr_event_set(&args.ev_start, reinterpret_cast<void*>(1));
 
   for (auto& th : thds) {
     th.Join();
index d7b3a20..2acefda 100644 (file)
  *
  */
 
-#include <grpc/support/log.h>
-
 #include <stdbool.h>
 #include <string.h>
 
+#include <gtest/gtest.h>
+
+#include <grpc/support/log.h>
+
 #include "src/core/lib/gprpp/global_config.h"
 #include "test/core/util/test_config.h"
 
-// Config declaration is supposed to be located at log.h but
-// log.h doesn't include global_config headers because it has to
-// be a strict C so declaration statement gets to be here.
-GPR_GLOBAL_CONFIG_DECLARE_STRING(grpc_verbosity);
-
 static bool log_func_reached = false;
 
 static void test_callback(gpr_log_func_args* args) {
@@ -52,15 +49,16 @@ static void test_should_not_log(gpr_log_func_args* /*args*/) {
   GPR_ASSERT(log_func_reached);                 \
   log_func_reached = false;                     \
   gpr_log(SEVERITY, "hello %d %d %d", 1, 2, 3); \
-  GPR_ASSERT(log_func_reached);
+  GPR_ASSERT(log_func_reached);                 \
+  gpr_set_log_function(nullptr);
 
-#define test_log_function_unreached(SEVERITY) \
-  gpr_set_log_function(test_should_not_log);  \
-  gpr_log_message(SEVERITY, "hello 1 2 3");   \
-  gpr_log(SEVERITY, "hello %d %d %d", 1, 2, 3);
+#define test_log_function_unreached(SEVERITY)   \
+  gpr_set_log_function(test_should_not_log);    \
+  gpr_log_message(SEVERITY, "hello 1 2 3");     \
+  gpr_log(SEVERITY, "hello %d %d %d", 1, 2, 3); \
+  gpr_set_log_function(nullptr);
 
-int main(int argc, char** argv) {
-  grpc::testing::TestEnvironment env(argc, argv);
+TEST(LogTest, Basic) {
   /* test logging at various verbosity levels */
   gpr_log(GPR_DEBUG, "%s", "hello world");
   gpr_log(GPR_INFO, "%s", "hello world");
@@ -71,23 +69,9 @@ int main(int argc, char** argv) {
   gpr_log_message(GPR_INFO, "hello 1 2 3");
   gpr_log(GPR_INFO, "hello %d %d %d", 1, 2, 3);
   gpr_set_log_function(nullptr);
+}
 
-  /* gpr_log_verbosity_init() will be effective only once, and only before
-   * gpr_set_log_verbosity() is called */
-  GPR_GLOBAL_CONFIG_SET(grpc_verbosity, "ERROR");
-  gpr_log_verbosity_init();
-
-  test_log_function_reached(GPR_ERROR);
-  test_log_function_unreached(GPR_INFO);
-  test_log_function_unreached(GPR_DEBUG);
-
-  /* gpr_log_verbosity_init() should not be effective */
-  GPR_GLOBAL_CONFIG_SET(grpc_verbosity, "DEBUG");
-  gpr_log_verbosity_init();
-  test_log_function_reached(GPR_ERROR);
-  test_log_function_unreached(GPR_INFO);
-  test_log_function_unreached(GPR_DEBUG);
-
+TEST(LogTest, LogVerbosity) {
   gpr_set_log_verbosity(GPR_LOG_SEVERITY_DEBUG);
   test_log_function_reached(GPR_ERROR);
   test_log_function_reached(GPR_INFO);
@@ -102,14 +86,11 @@ int main(int argc, char** argv) {
   test_log_function_reached(GPR_ERROR);
   test_log_function_unreached(GPR_INFO);
   test_log_function_unreached(GPR_DEBUG);
+}
 
-  /* gpr_log_verbosity_init() should not be effective */
-  GPR_GLOBAL_CONFIG_SET(grpc_verbosity, "DEBUG");
-  gpr_log_verbosity_init();
-  test_log_function_reached(GPR_ERROR);
-  test_log_function_unreached(GPR_INFO);
-  test_log_function_unreached(GPR_DEBUG);
-
-  /* TODO(ctiller): should we add a GPR_ASSERT failure test here */
-  return 0;
+int main(int argc, char** argv) {
+  grpc::testing::TestEnvironment env(argc, argv);
+  ::testing::InitGoogleTest(&argc, argv);
+  int ret = RUN_ALL_TESTS();
+  return ret;
 }
index fc7216e..ae0025f 100644 (file)
@@ -431,7 +431,7 @@ static void refinc(void* v /*=m*/) {
     }
   }
   if (gpr_unref(&m->thread_refcount)) {
-    gpr_event_set(&m->event, (void*)1);
+    gpr_event_set(&m->event, reinterpret_cast<void*>(1));
   }
   mark_thread_done(m);
 }
index 0f56eea..bc69f77 100644 (file)
@@ -51,7 +51,7 @@ static void test_init() {
 #define CONCURRENT_TEST_THREADS 100
 
 static void sleeping_thd(void* arg) {
-  int64_t sleep_ms = (int64_t)arg;
+  int64_t sleep_ms = reinterpret_cast<int64_t>(arg);
   gpr_sleep_until(gpr_time_add(gpr_now(GPR_CLOCK_REALTIME),
                                gpr_time_from_millis(sleep_ms, GPR_TIMESPAN)));
 }
@@ -74,8 +74,8 @@ static void test_thd_count() {
   for (int i = 0; i < CONCURRENT_TEST_THREADS; i++) {
     intptr_t sleep_time_ms =
         (i * THREAD_DELAY_MS) / (CONCURRENT_TEST_THREADS - 1);
-    thds[i] =
-        grpc_core::Thread("grpc_fork_test", sleeping_thd, (void*)sleep_time_ms);
+    thds[i] = grpc_core::Thread("grpc_fork_test", sleeping_thd,
+                                reinterpret_cast<void*>(sleep_time_ms));
     thds[i].Start();
   }
   grpc_core::Fork::AwaitThreads();
@@ -88,7 +88,7 @@ static void test_thd_count() {
 }
 
 static void exec_ctx_thread(void* arg) {
-  bool* exec_ctx_created = (bool*)arg;
+  bool* exec_ctx_created = static_cast<bool*>(arg);
   grpc_core::Fork::IncExecCtxCount();
   *exec_ctx_created = true;
 }
index 2c1760f..4066794 100644 (file)
@@ -90,7 +90,7 @@ static void test_mt(void) {
   }
   size_t num_done = 0;
   size_t spins = 0;
-  gpr_event_set(&start, (void*)1);
+  gpr_event_set(&start, reinterpret_cast<void*>(1));
   while (num_done != GPR_ARRAY_SIZE(thds)) {
     MultiProducerSingleConsumerQueue::Node* n;
     while ((n = q.Pop()) == nullptr) {
@@ -168,7 +168,7 @@ static void test_mt_multipop(void) {
     pull_thds[i] = grpc_core::Thread("grpc_multipop_pull", pull_thread, &pa);
     pull_thds[i].Start();
   }
-  gpr_event_set(&start, (void*)1);
+  gpr_event_set(&start, reinterpret_cast<void*>(1));
   for (auto& pth : pull_thds) {
     pth.Join();
   }
index af78fcd..86a7d76 100644 (file)
@@ -106,7 +106,8 @@ static int alpn_select_cb(SSL* /*ssl*/, const uint8_t** out, uint8_t* out_len,
   const uint8_t* alpn_preferred = static_cast<const uint8_t*>(arg);
 
   *out = alpn_preferred;
-  *out_len = static_cast<uint8_t>(strlen((char*)alpn_preferred));
+  *out_len = static_cast<uint8_t>(
+      strlen(reinterpret_cast<const char*>(alpn_preferred)));
 
   // Validate that the ALPN list includes "h2" and "grpc-exp", that "grpc-exp"
   // precedes "h2".
index c146850..708b316 100644 (file)
@@ -77,11 +77,10 @@ class ReadAheadHandshakerFactory : public HandshakerFactory {
 }  // namespace grpc_core
 
 int main(int /*argc*/, char* /*argv*/[]) {
-  using namespace grpc_core;
   grpc_init();
-  HandshakerRegistry::RegisterHandshakerFactory(
-      true /* at_start */, HANDSHAKER_SERVER,
-      absl::make_unique<ReadAheadHandshakerFactory>());
+  grpc_core::HandshakerRegistry::RegisterHandshakerFactory(
+      true /* at_start */, grpc_core::HANDSHAKER_SERVER,
+      absl::make_unique<grpc_core::ReadAheadHandshakerFactory>());
   const char* full_alpn_list[] = {"grpc-exp", "h2"};
   GPR_ASSERT(server_ssl_test(full_alpn_list, 2, "grpc-exp"));
   grpc_shutdown();
index 7a78d2d..a227050 100644 (file)
@@ -184,7 +184,8 @@ int main(int argc, char** argv) {
     /* start the server */
     args[1 + arg_shift] = const_cast<char*>("--port");
     gpr_asprintf(&args[2 + arg_shift], "%d", port);
-    server = gpr_subprocess_create(3 + arg_shift, (const char**)args);
+    server =
+        gpr_subprocess_create(3 + arg_shift, const_cast<const char**>(args));
     GPR_ASSERT(server);
     gpr_free(args[0]);
     if (arg_shift) gpr_free(args[1]);
index 5ed2878..542fe55 100644 (file)
@@ -192,7 +192,7 @@ int main(int argc, char** argv) {
   args[1 + arg_shift] = const_cast<char*>("--port");
   gpr_asprintf(&args[2 + arg_shift], "%d", port);
   args[3 + arg_shift] = const_cast<char*>("--ssl");
-  server = gpr_subprocess_create(4 + arg_shift, (const char**)args);
+  server = gpr_subprocess_create(4 + arg_shift, const_cast<const char**>(args));
   GPR_ASSERT(server);
   gpr_free(args[0]);
   if (arg_shift) gpr_free(args[1]);
index ff28f82..55b6d0e 100644 (file)
@@ -373,7 +373,6 @@ grpc_cc_test(
     external_deps = [
         "gtest",
     ],
-    flaky = True,  # TODO(b/162087149)
     language = "C++",
     tags = [
         # TODO(apolcyn): This test is failing on Windows at entry, enable once passing.
index 1554a09..fa0a23d 100644 (file)
@@ -33,7 +33,7 @@ static void test_no_op(void) {
 }
 
 static void set_event_to_true(void* value, grpc_error* /*error*/) {
-  gpr_event_set(static_cast<gpr_event*>(value), (void*)1);
+  gpr_event_set(static_cast<gpr_event*>(value), reinterpret_cast<void*>(1));
 }
 
 static void test_execute_one(void) {
@@ -115,7 +115,7 @@ static void test_execute_many(void) {
 static gpr_event got_in_finally;
 
 static void in_finally(void* /*arg*/, grpc_error* /*error*/) {
-  gpr_event_set(&got_in_finally, (void*)1);
+  gpr_event_set(&got_in_finally, reinterpret_cast<void*>(1));
 }
 
 static void add_finally(void* arg, grpc_error* /*error*/) {
index 93beb66..d63ae78 100644 (file)
@@ -30,7 +30,7 @@ struct WorkItem {
   int index;
   bool done;
 
-  WorkItem(int i) : index(i) { done = false; }
+  explicit WorkItem(int i) : index(i) { done = false; }
 };
 
 // Thread to "produce" items and put items into queue
@@ -77,7 +77,7 @@ class ProducerThread {
 // Thread to pull out items from queue
 class ConsumerThread {
  public:
-  ConsumerThread(grpc_core::InfLenFIFOQueue* queue) : queue_(queue) {
+  explicit ConsumerThread(grpc_core::InfLenFIFOQueue* queue) : queue_(queue) {
     thd_ = grpc_core::Thread(
         "mpmcq_test_consumer_thd",
         [](void* th) { static_cast<ConsumerThread*>(th)->Run(); }, this);
index 1f9db4b..d61ff5d 100644 (file)
 
 static void test_grpc_parse_unix(const char* uri_text, const char* pathname) {
   grpc_core::ExecCtx exec_ctx;
-  grpc_uri* uri = grpc_uri_parse(uri_text, false);
+  absl::StatusOr<grpc_core::URI> uri = grpc_core::URI::Parse(uri_text);
+  if (!uri.ok()) {
+    gpr_log(GPR_ERROR, "%s", uri.status().ToString().c_str());
+    GPR_ASSERT(uri.ok());
+  }
   grpc_resolved_address addr;
 
-  GPR_ASSERT(1 == grpc_parse_uri(uri, &addr));
+  GPR_ASSERT(1 == grpc_parse_uri(*uri, &addr));
   struct sockaddr_un* addr_un =
       reinterpret_cast<struct sockaddr_un*>(addr.addr);
   GPR_ASSERT(AF_UNIX == addr_un->sun_family);
   GPR_ASSERT(0 == strcmp(addr_un->sun_path, pathname));
-
-  grpc_uri_destroy(uri);
 }
 
 static void test_grpc_parse_unix_abstract(const char* uri_text,
                                           const char* pathname) {
   grpc_core::ExecCtx exec_ctx;
-  grpc_uri* uri = grpc_uri_parse(uri_text, false);
+  absl::StatusOr<grpc_core::URI> uri = grpc_core::URI::Parse(uri_text);
+  if (!uri.ok()) {
+    gpr_log(GPR_ERROR, "%s", uri.status().ToString().c_str());
+    GPR_ASSERT(uri.ok());
+  }
   grpc_resolved_address addr;
 
-  GPR_ASSERT(1 == grpc_parse_uri(uri, &addr));
+  GPR_ASSERT(1 == grpc_parse_uri(*uri, &addr));
   struct sockaddr_un* addr_un =
       reinterpret_cast<struct sockaddr_un*>(addr.addr);
   GPR_ASSERT(AF_UNIX == addr_un->sun_family);
   GPR_ASSERT('\0' == addr_un->sun_path[0]);
   GPR_ASSERT(0 == strncmp(addr_un->sun_path + 1, pathname, strlen(pathname)));
-
-  grpc_uri_destroy(uri);
 }
 
 #else /* GRPC_HAVE_UNIX_SOCKET */
@@ -75,29 +79,34 @@ static void test_grpc_parse_unix_abstract(const char* uri_text,
 static void test_grpc_parse_ipv4(const char* uri_text, const char* host,
                                  unsigned short port) {
   grpc_core::ExecCtx exec_ctx;
-  grpc_uri* uri = grpc_uri_parse(uri_text, false);
+  absl::StatusOr<grpc_core::URI> uri = grpc_core::URI::Parse(uri_text);
+  if (!uri.ok()) {
+    gpr_log(GPR_ERROR, "%s", uri.status().ToString().c_str());
+    GPR_ASSERT(uri.ok());
+  }
   grpc_resolved_address addr;
   char ntop_buf[GRPC_INET_ADDRSTRLEN];
 
-  GPR_ASSERT(1 == grpc_parse_ipv4(uri, &addr));
+  GPR_ASSERT(1 == grpc_parse_ipv4(*uri, &addr));
   grpc_sockaddr_in* addr_in = reinterpret_cast<grpc_sockaddr_in*>(addr.addr);
   GPR_ASSERT(GRPC_AF_INET == addr_in->sin_family);
   GPR_ASSERT(nullptr != grpc_inet_ntop(GRPC_AF_INET, &addr_in->sin_addr,
                                        ntop_buf, sizeof(ntop_buf)));
   GPR_ASSERT(0 == strcmp(ntop_buf, host));
   GPR_ASSERT(grpc_ntohs(addr_in->sin_port) == port);
-
-  grpc_uri_destroy(uri);
 }
 
 static void test_grpc_parse_ipv6(const char* uri_text, const char* host,
                                  unsigned short port, uint32_t scope_id) {
   grpc_core::ExecCtx exec_ctx;
-  grpc_uri* uri = grpc_uri_parse(uri_text, false);
+  absl::StatusOr<grpc_core::URI> uri = grpc_core::URI::Parse(uri_text);
+  if (!uri.ok()) {
+    gpr_log(GPR_ERROR, "%s", uri.status().ToString().c_str());
+    GPR_ASSERT(uri.ok());
+  }
   grpc_resolved_address addr;
   char ntop_buf[GRPC_INET6_ADDRSTRLEN];
-
-  GPR_ASSERT(1 == grpc_parse_ipv6(uri, &addr));
+  GPR_ASSERT(1 == grpc_parse_ipv6(*uri, &addr));
   grpc_sockaddr_in6* addr_in6 = reinterpret_cast<grpc_sockaddr_in6*>(addr.addr);
   GPR_ASSERT(GRPC_AF_INET6 == addr_in6->sin6_family);
   GPR_ASSERT(nullptr != grpc_inet_ntop(GRPC_AF_INET6, &addr_in6->sin6_addr,
@@ -105,17 +114,18 @@ static void test_grpc_parse_ipv6(const char* uri_text, const char* host,
   GPR_ASSERT(0 == strcmp(ntop_buf, host));
   GPR_ASSERT(grpc_ntohs(addr_in6->sin6_port) == port);
   GPR_ASSERT(addr_in6->sin6_scope_id == scope_id);
-
-  grpc_uri_destroy(uri);
 }
 
 /* Test parsing invalid ipv6 addresses (valid uri_text but invalid ipv6 addr) */
 static void test_grpc_parse_ipv6_invalid(const char* uri_text) {
   grpc_core::ExecCtx exec_ctx;
-  grpc_uri* uri = grpc_uri_parse(uri_text, false);
+  absl::StatusOr<grpc_core::URI> uri = grpc_core::URI::Parse(uri_text);
+  if (!uri.ok()) {
+    gpr_log(GPR_ERROR, "%s", uri.status().ToString().c_str());
+    GPR_ASSERT(uri.ok());
+  }
   grpc_resolved_address addr;
-  GPR_ASSERT(!grpc_parse_ipv6(uri, &addr));
-  grpc_uri_destroy(uri);
+  GPR_ASSERT(!grpc_parse_ipv6(*uri, &addr));
 }
 
 int main(int argc, char** argv) {
@@ -131,7 +141,7 @@ int main(int argc, char** argv) {
   /* Address length greater than GRPC_INET6_ADDRSTRLEN */
   test_grpc_parse_ipv6_invalid(
       "ipv6:WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW45%"
-      "v6:45%x$1*");
+      "25v6:45%25x$1*");
 
   grpc_shutdown();
 }
index 3b3c3be..e7b9878 100644 (file)
@@ -41,9 +41,13 @@ static void test_grpc_parse_ipv6_parity_with_getaddrinfo(
     const char* target, const struct sockaddr_in6 result_from_getaddrinfo) {
   // Get the sockaddr that gRPC's ipv6 resolver resolves this too.
   grpc_core::ExecCtx exec_ctx;
-  grpc_uri* uri = grpc_uri_parse(target, false);
+  absl::StatusOr<grpc_core::URI> uri = grpc_core::URI::Parse(target);
+  if (!uri.ok()) {
+    gpr_log(GPR_ERROR, "%s", uri.status().ToString().c_str());
+    GPR_ASSERT(uri.ok());
+  }
   grpc_resolved_address addr;
-  GPR_ASSERT(1 == grpc_parse_ipv6(uri, &addr));
+  GPR_ASSERT(1 == grpc_parse_ipv6(*uri, &addr));
   grpc_sockaddr_in6* result_from_grpc_parser =
       reinterpret_cast<grpc_sockaddr_in6*>(addr.addr);
   // Compare the sockaddr returned from gRPC's ipv6 resolver with that returned
@@ -55,16 +59,19 @@ static void test_grpc_parse_ipv6_parity_with_getaddrinfo(
   GPR_ASSERT(result_from_grpc_parser->sin6_scope_id ==
              result_from_getaddrinfo.sin6_scope_id);
   GPR_ASSERT(result_from_grpc_parser->sin6_scope_id != 0);
-  // TODO: compare sin6_flow_info fields? parse_ipv6 zero's this field as is.
-  // Cleanup
-  grpc_uri_destroy(uri);
+  // TODO(unknown): compare sin6_flow_info fields? parse_ipv6 zero's this field
+  // as is. Cleanup
 }
 
 struct sockaddr_in6 resolve_with_gettaddrinfo(const char* uri_text) {
-  grpc_uri* uri = grpc_uri_parse(uri_text, false);
+  absl::StatusOr<grpc_core::URI> uri = grpc_core::URI::Parse(uri_text);
+  if (!uri.ok()) {
+    gpr_log(GPR_ERROR, "%s", uri.status().ToString().c_str());
+    GPR_ASSERT(uri.ok());
+  }
   std::string host;
   std::string port;
-  grpc_core::SplitHostPort(uri->path, &host, &port);
+  grpc_core::SplitHostPort(uri->path(), &host, &port);
   struct addrinfo hints;
   memset(&hints, 0, sizeof(hints));
   hints.ai_family = AF_INET6;
@@ -88,7 +95,6 @@ struct sockaddr_in6 resolve_with_gettaddrinfo(const char* uri_text) {
       *reinterpret_cast<struct sockaddr_in6*>(result->ai_addr);
   // Cleanup
   freeaddrinfo(result);
-  grpc_uri_destroy(uri);
   return out;
 }
 
@@ -101,10 +107,10 @@ int main(int argc, char** argv) {
   // system recognizes, and then use that for the test.
   for (size_t i = 1; i < 65536; i++) {
     if (if_indextoname(i, arbitrary_interface_name) != nullptr) {
-      gpr_log(
-          GPR_DEBUG,
-          "Found interface at index %d named %s. Will use this for the test",
-          (int)i, arbitrary_interface_name);
+      gpr_log(GPR_DEBUG,
+              "Found interface at index %" PRIuPTR
+              " named %s. Will use this for the test",
+              i, arbitrary_interface_name);
       break;
     }
   }
index 8443e9f..82b6de1 100644 (file)
@@ -32,7 +32,8 @@ namespace {
 
 TEST(LibuvEventManager, Allocation) {
   for (int i = 0; i < 10; i++) {
-    LibuvEventManager* em = new LibuvEventManager(i);
+    LibuvEventManager* em =
+        new LibuvEventManager(LibuvEventManager::Options(i));
     gpr_sleep_until(grpc_timeout_milliseconds_to_deadline(1));
     delete em;
   }
@@ -40,7 +41,8 @@ TEST(LibuvEventManager, Allocation) {
 
 TEST(LibuvEventManager, ShutdownRef) {
   for (int i = 0; i < 10; i++) {
-    LibuvEventManager* em = new LibuvEventManager(i);
+    LibuvEventManager* em =
+        new LibuvEventManager(LibuvEventManager::Options(i));
     for (int j = 0; j < i; j++) {
       em->ShutdownRef();
     }
@@ -54,7 +56,8 @@ TEST(LibuvEventManager, ShutdownRef) {
 
 TEST(LibuvEventManager, ShutdownRefAsync) {
   for (int i = 0; i < 10; i++) {
-    LibuvEventManager* em = new LibuvEventManager(i);
+    LibuvEventManager* em =
+        new LibuvEventManager(LibuvEventManager::Options(i));
     for (int j = 0; j < i; j++) {
       em->ShutdownRef();
     }
index 3e6d346..c8bebc7 100644 (file)
@@ -109,7 +109,7 @@ static void actually_poll(void* argsp) {
     gpr_mu_unlock(args->mu);
     grpc_core::ExecCtx::Get()->Flush();
   }
-  gpr_event_set(&args->ev, (void*)1);
+  gpr_event_set(&args->ev, reinterpret_cast<void*>(1));
 }
 
 static void poll_pollset_until_request_done(args_struct* args) {
@@ -158,11 +158,11 @@ static void test_named_and_numeric_scope_ids(void) {
   // system recognizes, and then use that for the test.
   for (size_t i = 1; i < 65536; i++) {
     if (if_indextoname(i, arbitrary_interface_name) != nullptr) {
-      gpr_log(
-          GPR_DEBUG,
-          "Found interface at index %d named %s. Will use this for the test",
-          (int)i, arbitrary_interface_name);
-      interface_index = (int)i;
+      gpr_log(GPR_DEBUG,
+              "Found interface at index %" PRIuPTR
+              " named %s. Will use this for the test",
+              i, arbitrary_interface_name);
+      interface_index = static_cast<int>(i);
       break;
     }
   }
index ca7c914..6249620 100644 (file)
@@ -101,7 +101,7 @@ static void poll_pollset_until_request_done(args_struct* args) {
     gpr_mu_unlock(args->mu);
     grpc_core::ExecCtx::Get()->Flush();
   }
-  gpr_event_set(&args->ev, (void*)1);
+  gpr_event_set(&args->ev, reinterpret_cast<void*>(1));
 }
 
 static void must_succeed(void* argsp, grpc_error* err) {
index d5d86a3..7f516b7 100644 (file)
@@ -45,7 +45,7 @@ static void assert_counter_becomes(int* ctr, int value) {
 }
 
 static void set_event_cb(void* a, grpc_error* /*error*/) {
-  gpr_event_set(static_cast<gpr_event*>(a), (void*)1);
+  gpr_event_set(static_cast<gpr_event*>(a), reinterpret_cast<void*>(1));
 }
 grpc_closure* set_event(gpr_event* ev) {
   return GRPC_CLOSURE_CREATE(set_event_cb, ev, grpc_schedule_on_exec_ctx);
index 85dd39e..c8bb6a8 100644 (file)
@@ -296,15 +296,15 @@ grpc_core::Resolver::Result BuildResolverResponse(
     const std::vector<std::string>& addresses) {
   grpc_core::Resolver::Result result;
   for (const auto& address_str : addresses) {
-    grpc_uri* uri = grpc_uri_parse(address_str.c_str(), true);
-    if (uri == nullptr) {
-      gpr_log(GPR_ERROR, "Failed to parse uri:%s", address_str.c_str());
-      GPR_ASSERT(0);
+    absl::StatusOr<grpc_core::URI> uri = grpc_core::URI::Parse(address_str);
+    if (!uri.ok()) {
+      gpr_log(GPR_ERROR, "Failed to parse. Error: %s",
+              uri.status().ToString().c_str());
+      GPR_ASSERT(uri.ok());
     }
     grpc_resolved_address address;
-    GPR_ASSERT(grpc_parse_uri(uri, &address));
+    GPR_ASSERT(grpc_parse_uri(*uri, &address));
     result.addresses.emplace_back(address.addr, address.len, nullptr);
-    grpc_uri_destroy(uri);
   }
   return result;
 }
index ad6e126..3d995ee 100644 (file)
@@ -89,14 +89,15 @@ static void create_inet_sockets(int sv[2]) {
   GPR_ASSERT(client);
   int ret;
   do {
-    ret = connect(client, (sockaddr*)&addr, sizeof(sockaddr_in));
+    ret = connect(client, reinterpret_cast<sockaddr*>(&addr),
+                  sizeof(sockaddr_in));
   } while (ret == -1 && errno == EINTR);
 
   /* Accept client connection */
   len = sizeof(socklen_t);
   int server;
   do {
-    server = accept(sock, (sockaddr*)&addr, (socklen_t*)&len);
+    server = accept(sock, reinterpret_cast<sockaddr*>(&addr), &len);
   } while (server == -1 && errno == EINTR);
   GPR_ASSERT(server != -1);
 
@@ -388,7 +389,7 @@ void timestamps_verifier(void* arg, grpc_core::Timestamps* ts,
   GPR_ASSERT(ts->sendmsg_time.time.clock_type == GPR_CLOCK_REALTIME);
   GPR_ASSERT(ts->scheduled_time.time.clock_type == GPR_CLOCK_REALTIME);
   GPR_ASSERT(ts->acked_time.time.clock_type == GPR_CLOCK_REALTIME);
-  gpr_atm* done_timestamps = (gpr_atm*)arg;
+  gpr_atm* done_timestamps = static_cast<gpr_atm*>(arg);
   gpr_atm_rel_store(done_timestamps, static_cast<gpr_atm>(1));
 }
 
@@ -447,7 +448,7 @@ static void write_test(size_t num_bytes, size_t slice_size,
   gpr_atm_rel_store(&done_timestamps, static_cast<gpr_atm>(0));
   grpc_endpoint_write(ep, &outgoing, &write_done_closure,
                       grpc_event_engine_can_track_errors() && collect_timestamps
-                          ? (void*)&done_timestamps
+                          ? &done_timestamps
                           : nullptr);
   drain_socket_blocking(sv[0], num_bytes, num_bytes);
   exec_ctx.Flush();
index fa24449..a26926d 100644 (file)
@@ -42,7 +42,7 @@ static const int64_t kMillisIn25Days = 2160000000;
 static const int64_t kHoursIn25Days = 600;
 
 static void cb(void* arg, grpc_error* error) {
-  cb_called[(intptr_t)arg][error == GRPC_ERROR_NONE]++;
+  cb_called[reinterpret_cast<intptr_t>(arg)][error == GRPC_ERROR_NONE]++;
 }
 
 static void add_test(void) {
index fa8ef54..bbc9e3f 100644 (file)
@@ -38,7 +38,8 @@ TEST(WorkSerializerTest, ExecuteOne) {
   grpc_core::WorkSerializer lock;
   gpr_event done;
   gpr_event_init(&done);
-  lock.Run([&done]() { gpr_event_set(&done, (void*)1); }, DEBUG_LOCATION);
+  lock.Run([&done]() { gpr_event_set(&done, reinterpret_cast<void*>(1)); },
+           DEBUG_LOCATION);
   EXPECT_TRUE(gpr_event_wait(&done, grpc_timeout_seconds_to_deadline(5)) !=
               nullptr);
 }
@@ -81,8 +82,9 @@ class TestThread {
       // sleep for a little bit, to test other threads picking up the load
       gpr_sleep_until(grpc_timeout_milliseconds_to_deadline(100));
     }
-    self->lock_->Run([self]() { gpr_event_set(&self->done_, (void*)1); },
-                     DEBUG_LOCATION);
+    self->lock_->Run(
+        [self]() { gpr_event_set(&self->done_, reinterpret_cast<void*>(1)); },
+        DEBUG_LOCATION);
   }
 
   grpc_core::WorkSerializer* lock_ = nullptr;
index e576028..0491cb6 100644 (file)
@@ -318,6 +318,10 @@ grpc_cc_test(
     srcs = ["grpc_tls_credentials_options_test.cc"],
     data = [
         "//src/core/tsi/test_creds:ca.pem",
+        "//src/core/tsi/test_creds:multi-domain.key",
+        "//src/core/tsi/test_creds:multi-domain.pem",
+        "//src/core/tsi/test_creds:server0.key",
+        "//src/core/tsi/test_creds:server0.pem",
         "//src/core/tsi/test_creds:server1.key",
         "//src/core/tsi/test_creds:server1.pem",
     ],
@@ -345,6 +349,28 @@ grpc_cc_test(
 )
 
 grpc_cc_test(
+    name = "grpc_tls_certificate_provider_test",
+    srcs = ["grpc_tls_certificate_provider_test.cc"],
+    data = [
+        "//src/core/tsi/test_creds:ca.pem",
+        "//src/core/tsi/test_creds:multi-domain.key",
+        "//src/core/tsi/test_creds:multi-domain.pem",
+        "//src/core/tsi/test_creds:server0.key",
+        "//src/core/tsi/test_creds:server0.pem",
+        "//src/core/tsi/test_creds:server1.key",
+        "//src/core/tsi/test_creds:server1.pem",
+    ],
+    external_deps = ["gtest"],
+    language = "C++",
+    deps = [
+        "//:gpr",
+        "//:grpc",
+        "//:grpc_secure",
+        "//test/core/util:grpc_test_util",
+    ],
+)
+
+grpc_cc_test(
     name = "insecure_security_connector_test",
     srcs = ["insecure_security_connector_test.cc"],
     external_deps = [
@@ -357,3 +383,17 @@ grpc_cc_test(
         "//test/core/util:grpc_test_util",
     ],
 )
+
+grpc_cc_test(
+    name = "xds_credentials_test",
+    srcs = ["xds_credentials_test.cc"],
+    external_deps = [
+        "gtest",
+    ],
+    deps = [
+        "//:gpr",
+        "//:grpc",
+        "//:grpc_secure",
+        "//test/core/util:grpc_test_util",
+    ],
+)
index bd3b964..6106f6d 100644 (file)
@@ -26,6 +26,7 @@
 
 #include <string>
 
+#include "absl/strings/match.h"
 #include "absl/strings/str_cat.h"
 #include "absl/strings/str_format.h"
 #include "absl/strings/str_replace.h"
@@ -44,6 +45,7 @@
 #include "src/core/lib/http/httpcli.h"
 #include "src/core/lib/iomgr/error.h"
 #include "src/core/lib/security/credentials/composite/composite_credentials.h"
+#include "src/core/lib/security/credentials/external/aws_external_account_credentials.h"
 #include "src/core/lib/security/credentials/external/external_account_credentials.h"
 #include "src/core/lib/security/credentials/external/file_external_account_credentials.h"
 #include "src/core/lib/security/credentials/external/url_external_account_credentials.h"
@@ -155,6 +157,12 @@ static const char
         "\"headers\":{\"Metadata-Flavor\":\"Google\"}}";
 
 static const char
+    valid_url_external_account_creds_options_credential_source_with_qurey_params_format_text
+        [] = "{\"url\":\"https://foo.com:5555/"
+             "path/to/url/creds?p1=v1&p2=v2\","
+             "\"headers\":{\"Metadata-Flavor\":\"Google\"}}";
+
+static const char
     valid_url_external_account_creds_retrieve_subject_token_response_format_text
         [] = "test_subject_token";
 
@@ -174,6 +182,58 @@ static const char
         "{\"url\":\"invalid_credential_source_url\","
         "\"headers\":{\"Metadata-Flavor\":\"Google\"}}";
 
+static const char
+    valid_aws_external_account_creds_retrieve_signing_keys_response[] =
+        "{\"AccessKeyId\":\"test_access_key_id\",\"SecretAccessKey\":"
+        "\"test_secret_access_key\",\"Token\":\"test_token\"}";
+
+static const char valid_aws_external_account_creds_options_credential_source[] =
+    "{\"environment_id\":\"aws1\","
+    "\"region_url\":\"https://foo.com:5555/region_url\","
+    "\"url\":\"https://foo.com:5555/url\","
+    "\"regional_cred_verification_url\":\"https://foo.com:5555/"
+    "regional_cred_verification_url_{region}\"}";
+
+static const char
+    invalid_aws_external_account_creds_options_credential_source_unmatched_environment_id
+        [] = "{\"environment_id\":\"unsupported_aws_version\","
+             "\"region_url\":\"https://foo.com:5555/region_url\","
+             "\"url\":\"https://foo.com:5555/url\","
+             "\"regional_cred_verification_url\":\"https://foo.com:5555/"
+             "regional_cred_verification_url_{region}\"}";
+
+static const char
+    invalid_aws_external_account_creds_options_credential_source_invalid_region_url
+        [] = "{\"environment_id\":\"aws1\","
+             "\"region_url\":\"invalid_region_url\","
+             "\"url\":\"https://foo.com:5555/url\","
+             "\"regional_cred_verification_url\":\"https://foo.com:5555/"
+             "regional_cred_verification_url_{region}\"}";
+
+static const char
+    invalid_aws_external_account_creds_options_credential_source_invalid_url[] =
+        "{\"environment_id\":\"aws1\","
+        "\"region_url\":\"https://foo.com:5555/region_url\","
+        "\"url\":\"invalid_url\","
+        "\"regional_cred_verification_url\":\"https://foo.com:5555/"
+        "regional_cred_verification_url_{region}\"}";
+
+static const char
+    invalid_aws_external_account_creds_options_credential_source_missing_role_name
+        [] = "{\"environment_id\":\"aws1\","
+             "\"region_url\":\"https://foo.com:5555/region_url\","
+             "\"url\":\"https://foo.com:5555/url_no_role_name\","
+             "\"regional_cred_verification_url\":\"https://foo.com:5555/"
+             "regional_cred_verification_url_{region}\"}";
+
+static const char
+    invalid_aws_external_account_creds_options_credential_source_invalid_regional_cred_verification_url
+        [] = "{\"environment_id\":\"aws1\","
+             "\"region_url\":\"https://foo.com:5555/region_url\","
+             "\"url\":\"https://foo.com:5555/url_no_role_name\","
+             "\"regional_cred_verification_url\":\"invalid_regional_cred_"
+             "verification_url\"}";
+
 /*  -- Global state flags. -- */
 
 static bool g_test_is_on_gce = false;
@@ -825,17 +885,14 @@ static void test_valid_sts_creds_options(void) {
       nullptr,                      // actor_token_path
       nullptr                       // actor_token_type
   };
-  grpc_uri* sts_url;
-  grpc_error* error =
-      grpc_core::ValidateStsCredentialsOptions(&valid_options, &sts_url);
-  GPR_ASSERT(error == GRPC_ERROR_NONE);
-  GPR_ASSERT(sts_url != nullptr);
+  absl::StatusOr<grpc_core::URI> sts_url =
+      grpc_core::ValidateStsCredentialsOptions(&valid_options);
+  GPR_ASSERT(sts_url.ok());
   absl::string_view host;
   absl::string_view port;
-  GPR_ASSERT(grpc_core::SplitHostPort(sts_url->authority, &host, &port));
+  GPR_ASSERT(grpc_core::SplitHostPort(sts_url->authority(), &host, &port));
   GPR_ASSERT(host == "foo.com");
   GPR_ASSERT(port == "5555");
-  grpc_uri_destroy(sts_url);
 }
 
 static void test_invalid_sts_creds_options(void) {
@@ -850,12 +907,9 @@ static void test_invalid_sts_creds_options(void) {
       nullptr,                     // actor_token_path
       nullptr                      // actor_token_type
   };
-  grpc_uri* url_should_be_null;
-  grpc_error* error = grpc_core::ValidateStsCredentialsOptions(
-      &invalid_options, &url_should_be_null);
-  GPR_ASSERT(error != GRPC_ERROR_NONE);
-  GRPC_ERROR_UNREF(error);
-  GPR_ASSERT(url_should_be_null == nullptr);
+  absl::StatusOr<grpc_core::URI> url_should_be_invalid =
+      grpc_core::ValidateStsCredentialsOptions(&invalid_options);
+  GPR_ASSERT(!url_should_be_invalid.ok());
 
   invalid_options = {
       test_sts_endpoint_url,        // sts_endpoint_url
@@ -868,11 +922,9 @@ static void test_invalid_sts_creds_options(void) {
       nullptr,                      // actor_token_path
       nullptr                       // actor_token_type
   };
-  error = grpc_core::ValidateStsCredentialsOptions(&invalid_options,
-                                                   &url_should_be_null);
-  GPR_ASSERT(error != GRPC_ERROR_NONE);
-  GRPC_ERROR_UNREF(error);
-  GPR_ASSERT(url_should_be_null == nullptr);
+  url_should_be_invalid =
+      grpc_core::ValidateStsCredentialsOptions(&invalid_options);
+  GPR_ASSERT(!url_should_be_invalid.ok());
 
   invalid_options = {
       nullptr,                      // sts_endpoint_url (Required)
@@ -885,11 +937,9 @@ static void test_invalid_sts_creds_options(void) {
       nullptr,                      // actor_token_path
       nullptr                       // actor_token_type
   };
-  error = grpc_core::ValidateStsCredentialsOptions(&invalid_options,
-                                                   &url_should_be_null);
-  GPR_ASSERT(error != GRPC_ERROR_NONE);
-  GRPC_ERROR_UNREF(error);
-  GPR_ASSERT(url_should_be_null == nullptr);
+  url_should_be_invalid =
+      grpc_core::ValidateStsCredentialsOptions(&invalid_options);
+  GPR_ASSERT(!url_should_be_invalid.ok());
 
   invalid_options = {
       "not_a_valid_uri",            // sts_endpoint_url
@@ -902,11 +952,9 @@ static void test_invalid_sts_creds_options(void) {
       nullptr,                      // actor_token_path
       nullptr                       // actor_token_type
   };
-  error = grpc_core::ValidateStsCredentialsOptions(&invalid_options,
-                                                   &url_should_be_null);
-  GPR_ASSERT(error != GRPC_ERROR_NONE);
-  GRPC_ERROR_UNREF(error);
-  GPR_ASSERT(url_should_be_null == nullptr);
+  url_should_be_invalid =
+      grpc_core::ValidateStsCredentialsOptions(&invalid_options);
+  GPR_ASSERT(!url_should_be_invalid.ok());
 
   invalid_options = {
       "ftp://ftp.is.not.a.valid.scheme/bar",  // sts_endpoint_url
@@ -919,11 +967,21 @@ static void test_invalid_sts_creds_options(void) {
       nullptr,                                // actor_token_path
       nullptr                                 // actor_token_type
   };
-  error = grpc_core::ValidateStsCredentialsOptions(&invalid_options,
-                                                   &url_should_be_null);
-  GPR_ASSERT(error != GRPC_ERROR_NONE);
-  GRPC_ERROR_UNREF(error);
-  GPR_ASSERT(url_should_be_null == nullptr);
+  url_should_be_invalid =
+      grpc_core::ValidateStsCredentialsOptions(&invalid_options);
+  GPR_ASSERT(!url_should_be_invalid.ok());
+}
+
+static void assert_query_parameters(const grpc_core::URI& uri,
+                                    absl::string_view expected_key,
+                                    absl::string_view expected_val) {
+  const auto it = uri.query_parameter_map().find(expected_key);
+  GPR_ASSERT(it != uri.query_parameter_map().end());
+  if (it->second != expected_val) {
+    gpr_log(GPR_ERROR, "%s!=%s", std::string(it->second).c_str(),
+            std::string(expected_val).c_str());
+  }
+  GPR_ASSERT(it->second == expected_val);
 }
 
 static void validate_sts_token_http_request(const grpc_httpcli_request* request,
@@ -935,26 +993,29 @@ static void validate_sts_token_http_request(const grpc_httpcli_request* request,
   GPR_ASSERT(request->handshaker == &grpc_httpcli_ssl);
   std::string get_url_equivalent =
       absl::StrFormat("%s?%s", test_sts_endpoint_url, body);
-  grpc_uri* url = grpc_uri_parse(get_url_equivalent.c_str(), false);
-  GPR_ASSERT(strcmp(grpc_uri_get_query_arg(url, "resource"), "resource") == 0);
-  GPR_ASSERT(strcmp(grpc_uri_get_query_arg(url, "audience"), "audience") == 0);
-  GPR_ASSERT(strcmp(grpc_uri_get_query_arg(url, "scope"), "scope") == 0);
-  GPR_ASSERT(strcmp(grpc_uri_get_query_arg(url, "requested_token_type"),
-                    "requested_token_type") == 0);
-  GPR_ASSERT(strcmp(grpc_uri_get_query_arg(url, "subject_token"),
-                    test_signed_jwt) == 0);
-  GPR_ASSERT(strcmp(grpc_uri_get_query_arg(url, "subject_token_type"),
-                    test_signed_jwt_token_type) == 0);
+  absl::StatusOr<grpc_core::URI> url =
+      grpc_core::URI::Parse(get_url_equivalent);
+  if (!url.ok()) {
+    gpr_log(GPR_ERROR, "%s", url.status().ToString().c_str());
+    GPR_ASSERT(url.ok());
+  }
+  assert_query_parameters(*url, "resource", "resource");
+  assert_query_parameters(*url, "audience", "audience");
+  assert_query_parameters(*url, "scope", "scope");
+  assert_query_parameters(*url, "requested_token_type", "requested_token_type");
+  assert_query_parameters(*url, "subject_token", test_signed_jwt);
+  assert_query_parameters(*url, "subject_token_type",
+                          test_signed_jwt_token_type);
   if (expect_actor_token) {
-    GPR_ASSERT(strcmp(grpc_uri_get_query_arg(url, "actor_token"),
-                      test_signed_jwt2) == 0);
-    GPR_ASSERT(strcmp(grpc_uri_get_query_arg(url, "actor_token_type"),
-                      test_signed_jwt_token_type2) == 0);
+    assert_query_parameters(*url, "actor_token", test_signed_jwt2);
+    assert_query_parameters(*url, "actor_token_type",
+                            test_signed_jwt_token_type2);
   } else {
-    GPR_ASSERT(grpc_uri_get_query_arg(url, "actor_token") == nullptr);
-    GPR_ASSERT(grpc_uri_get_query_arg(url, "actor_token_type") == nullptr);
+    GPR_ASSERT(url->query_parameter_map().find("actor_token") ==
+               url->query_parameter_map().end());
+    GPR_ASSERT(url->query_parameter_map().find("actor_token_type") ==
+               url->query_parameter_map().end());
   }
-  grpc_uri_destroy(url);
 
   // Check the rest of the request.
   GPR_ASSERT(strcmp(request->host, "foo.com:5555") == 0);
@@ -1929,19 +1990,21 @@ static void validate_external_account_creds_token_exchage_request(
   GPR_ASSERT(request->handshaker == &grpc_httpcli_ssl);
   std::string get_url_equivalent =
       absl::StrFormat("%s?%s", "https://foo.com:5555/token", body);
-  grpc_uri* uri = grpc_uri_parse(get_url_equivalent.c_str(), false);
-  GPR_ASSERT(strcmp(grpc_uri_get_query_arg(uri, "audience"), "audience") == 0);
-  GPR_ASSERT(strcmp(grpc_uri_get_query_arg(uri, "grant_type"),
-                    "urn:ietf:params:oauth:grant-type:token-exchange") == 0);
-  GPR_ASSERT(strcmp(grpc_uri_get_query_arg(uri, "requested_token_type"),
-                    "urn:ietf:params:oauth:token-type:access_token") == 0);
-  GPR_ASSERT(strcmp(grpc_uri_get_query_arg(uri, "subject_token"),
-                    "test_subject_token") == 0);
-  GPR_ASSERT(strcmp(grpc_uri_get_query_arg(uri, "subject_token_type"),
-                    "subject_token_type") == 0);
-  GPR_ASSERT(strcmp(grpc_uri_get_query_arg(uri, "scope"),
-                    "https://www.googleapis.com/auth/cloud-platform") == 0);
-  grpc_uri_destroy(uri);
+  absl::StatusOr<grpc_core::URI> uri =
+      grpc_core::URI::Parse(get_url_equivalent);
+  if (!uri.ok()) {
+    gpr_log(GPR_ERROR, "%s", uri.status().ToString().c_str());
+    GPR_ASSERT(uri.ok());
+  }
+  assert_query_parameters(*uri, "audience", "audience");
+  assert_query_parameters(*uri, "grant_type",
+                          "urn:ietf:params:oauth:grant-type:token-exchange");
+  assert_query_parameters(*uri, "requested_token_type",
+                          "urn:ietf:params:oauth:token-type:access_token");
+  assert_query_parameters(*uri, "subject_token", "test_subject_token");
+  assert_query_parameters(*uri, "subject_token_type", "subject_token_type");
+  assert_query_parameters(*uri, "scope",
+                          "https://www.googleapis.com/auth/cloud-platform");
 
   // Check the rest of the request.
   GPR_ASSERT(strcmp(request->host, "foo.com:5555") == 0);
@@ -1956,6 +2019,36 @@ static void validate_external_account_creds_token_exchage_request(
 }
 
 static void
+validate_external_account_creds_token_exchage_request_with_url_encode(
+    const grpc_httpcli_request* request, const char* body, size_t body_size,
+    bool expect_actor_token) {
+  // Check that the body is constructed properly.
+  GPR_ASSERT(body != nullptr);
+  GPR_ASSERT(body_size != 0);
+  GPR_ASSERT(request->handshaker == &grpc_httpcli_ssl);
+  GPR_ASSERT(
+      strcmp(
+          std::string(body, body_size).c_str(),
+          "audience=audience_!%40%23%24&grant_type=urn%3Aietf%3Aparams%3Aoauth%"
+          "3Agrant-type%3Atoken-exchange&requested_token_type=urn%3Aietf%"
+          "3Aparams%3Aoauth%3Atoken-type%3Aaccess_token&subject_token_type="
+          "subject_token_type_!%40%23%24&subject_token=test_subject_token&"
+          "scope=https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fcloud-platform") ==
+      0);
+
+  // Check the rest of the request.
+  GPR_ASSERT(strcmp(request->host, "foo.com:5555") == 0);
+  GPR_ASSERT(strcmp(request->http.path, "/token_url_encode") == 0);
+  GPR_ASSERT(request->http.hdr_count == 2);
+  GPR_ASSERT(strcmp(request->http.hdrs[0].key, "Content-Type") == 0);
+  GPR_ASSERT(strcmp(request->http.hdrs[0].value,
+                    "application/x-www-form-urlencoded") == 0);
+  GPR_ASSERT(strcmp(request->http.hdrs[1].key, "Authorization") == 0);
+  GPR_ASSERT(strcmp(request->http.hdrs[1].value,
+                    "Basic Y2xpZW50X2lkOmNsaWVudF9zZWNyZXQ=") == 0);
+}
+
+static void
 validate_external_account_creds_service_account_impersonation_request(
     const grpc_httpcli_request* request, const char* body, size_t body_size,
     bool expect_actor_token) {
@@ -1964,7 +2057,6 @@ validate_external_account_creds_service_account_impersonation_request(
   GPR_ASSERT(body_size != 0);
   GPR_ASSERT(request->handshaker == &grpc_httpcli_ssl);
   GPR_ASSERT(strcmp(body, "scope=scope_1 scope_2") == 0);
-
   // Check the rest of the request.
   GPR_ASSERT(strcmp(request->host, "foo.com:5555") == 0);
   GPR_ASSERT(strcmp(request->http.path, "/service_account_impersonation") == 0);
@@ -1993,6 +2085,11 @@ static int external_account_creds_httpcli_post_success(
     *response = http_response(
         200,
         valid_external_account_creds_service_account_impersonation_response);
+  } else if (strcmp(request->http.path, "/token_url_encode") == 0) {
+    validate_external_account_creds_token_exchage_request_with_url_encode(
+        request, body, body_size, true);
+    *response = http_response(
+        200, valid_external_account_creds_token_exchange_response);
   }
   grpc_core::ExecCtx::Run(DEBUG_LOCATION, on_done, GRPC_ERROR_NONE);
   return 1;
@@ -2025,6 +2122,11 @@ static int url_external_account_creds_httpcli_get_success(
     *response = http_response(
         200,
         valid_url_external_account_creds_retrieve_subject_token_response_format_text);
+  } else if (strcmp(request->http.path, "/path/to/url/creds?p1=v1&p2=v2") ==
+             0) {
+    *response = http_response(
+        200,
+        valid_url_external_account_creds_retrieve_subject_token_response_format_text);
   } else if (strcmp(request->http.path,
                     "/generate_subject_token_format_json") == 0) {
     *response = http_response(
@@ -2035,19 +2137,82 @@ static int url_external_account_creds_httpcli_get_success(
   return 1;
 }
 
+static void validate_aws_external_account_creds_token_exchage_request(
+    const grpc_httpcli_request* request, const char* body, size_t body_size,
+    bool expect_actor_token) {
+  // Check that the body is constructed properly.
+  GPR_ASSERT(body != nullptr);
+  GPR_ASSERT(body_size != 0);
+  GPR_ASSERT(request->handshaker == &grpc_httpcli_ssl);
+  std::string get_url_equivalent =
+      absl::StrFormat("%s?%s", "https://foo.com:5555/token", body);
+  absl::StatusOr<grpc_core::URI> uri =
+      grpc_core::URI::Parse(get_url_equivalent);
+  GPR_ASSERT(uri.ok());
+  assert_query_parameters(*uri, "audience", "audience");
+  assert_query_parameters(*uri, "grant_type",
+                          "urn:ietf:params:oauth:grant-type:token-exchange");
+  assert_query_parameters(*uri, "requested_token_type",
+                          "urn:ietf:params:oauth:token-type:access_token");
+  assert_query_parameters(*uri, "subject_token_type", "subject_token_type");
+  assert_query_parameters(*uri, "scope",
+                          "https://www.googleapis.com/auth/cloud-platform");
+  // Check the rest of the request.
+  GPR_ASSERT(strcmp(request->host, "foo.com:5555") == 0);
+  GPR_ASSERT(strcmp(request->http.path, "/token") == 0);
+  GPR_ASSERT(request->http.hdr_count == 2);
+  GPR_ASSERT(strcmp(request->http.hdrs[0].key, "Content-Type") == 0);
+  GPR_ASSERT(strcmp(request->http.hdrs[0].value,
+                    "application/x-www-form-urlencoded") == 0);
+  GPR_ASSERT(strcmp(request->http.hdrs[1].key, "Authorization") == 0);
+  GPR_ASSERT(strcmp(request->http.hdrs[1].value,
+                    "Basic Y2xpZW50X2lkOmNsaWVudF9zZWNyZXQ=") == 0);
+}
+
+static int aws_external_account_creds_httpcli_get_success(
+    const grpc_httpcli_request* request, grpc_millis /*deadline*/,
+    grpc_closure* on_done, grpc_httpcli_response* response) {
+  if (strcmp(request->http.path, "/region_url") == 0) {
+    *response = http_response(200, "test_regionz");
+  } else if (strcmp(request->http.path, "/url") == 0) {
+    *response = http_response(200, "test_role_name");
+  } else if (strcmp(request->http.path, "/url_no_role_name") == 0) {
+    *response = http_response(200, "");
+  } else if (strcmp(request->http.path, "/url/test_role_name") == 0) {
+    *response = http_response(
+        200, valid_aws_external_account_creds_retrieve_signing_keys_response);
+  }
+  grpc_core::ExecCtx::Run(DEBUG_LOCATION, on_done, GRPC_ERROR_NONE);
+  return 1;
+}
+
+static int aws_external_account_creds_httpcli_post_success(
+    const grpc_httpcli_request* request, const char* body, size_t body_size,
+    grpc_millis /*deadline*/, grpc_closure* on_done,
+    grpc_httpcli_response* response) {
+  if (strcmp(request->http.path, "/token") == 0) {
+    validate_aws_external_account_creds_token_exchage_request(request, body,
+                                                              body_size, true);
+    *response = http_response(
+        200, valid_external_account_creds_token_exchange_response);
+  }
+  grpc_core::ExecCtx::Run(DEBUG_LOCATION, on_done, GRPC_ERROR_NONE);
+  return 1;
+}
+
 // The subclass of ExternalAccountCredentials for testing.
 // ExternalAccountCredentials is an abstract class so we can't directly test
 // against it.
 class TestExternalAccountCredentials final
     : public grpc_core::ExternalAccountCredentials {
  public:
-  TestExternalAccountCredentials(ExternalAccountCredentialsOptions options,
+  TestExternalAccountCredentials(Options options,
                                  std::vector<std::string> scopes)
       : ExternalAccountCredentials(std::move(options), std::move(scopes)) {}
 
  protected:
   void RetrieveSubjectToken(
-      HTTPRequestContext* ctx, const ExternalAccountCredentialsOptions& options,
+      HTTPRequestContext* ctx, const Options& options,
       std::function<void(std::string, grpc_error*)> cb) override {
     cb("test_subject_token", GRPC_ERROR_NONE);
   }
@@ -2059,7 +2224,7 @@ static void test_external_account_creds_success(void) {
   grpc_auth_metadata_context auth_md_ctx = {test_service_url, test_method,
                                             nullptr, nullptr};
   grpc_core::Json credential_source("");
-  TestExternalAccountCredentials::ExternalAccountCredentialsOptions options = {
+  TestExternalAccountCredentials::Options options = {
       "external_account",                 // type;
       "audience",                         // audience;
       "subject_token_type",               // subject_token_type;
@@ -2091,6 +2256,34 @@ static void test_external_account_creds_success(void) {
   grpc_httpcli_set_override(nullptr, nullptr);
 }
 
+static void test_external_account_creds_success_with_url_encode(void) {
+  expected_md emd[] = {{"authorization", "Bearer token_exchange_access_token"}};
+  grpc_core::ExecCtx exec_ctx;
+  grpc_auth_metadata_context auth_md_ctx = {test_service_url, test_method,
+                                            nullptr, nullptr};
+  grpc_core::Json credential_source("");
+  TestExternalAccountCredentials::Options options = {
+      "external_account",         // type;
+      "audience_!@#$",            // audience;
+      "subject_token_type_!@#$",  // subject_token_type;
+      "",                         // service_account_impersonation_url;
+      "https://foo.com:5555/token_url_encode",  // token_url;
+      "https://foo.com:5555/token_info",        // token_info_url;
+      credential_source,                        // credential_source;
+      "quota_project_id",                       // quota_project_id;
+      "client_id",                              // client_id;
+      "client_secret",                          // client_secret;
+  };
+  TestExternalAccountCredentials creds(options, {});
+  request_metadata_state* state =
+      make_request_metadata_state(GRPC_ERROR_NONE, emd, GPR_ARRAY_SIZE(emd));
+  grpc_httpcli_set_override(httpcli_get_should_not_be_called,
+                            external_account_creds_httpcli_post_success);
+  run_request_metadata_test(&creds, auth_md_ctx, state);
+  grpc_core::ExecCtx::Get()->Flush();
+  grpc_httpcli_set_override(nullptr, nullptr);
+}
+
 static void
 test_external_account_creds_success_with_service_account_impersonation(void) {
   expected_md emd[] = {
@@ -2099,7 +2292,7 @@ test_external_account_creds_success_with_service_account_impersonation(void) {
   grpc_auth_metadata_context auth_md_ctx = {test_service_url, test_method,
                                             nullptr, nullptr};
   grpc_core::Json credential_source("");
-  TestExternalAccountCredentials::ExternalAccountCredentialsOptions options = {
+  TestExternalAccountCredentials::Options options = {
       "external_account",    // type;
       "audience",            // audience;
       "subject_token_type",  // subject_token_type;
@@ -2129,7 +2322,7 @@ static void test_external_account_creds_failure_invalid_token_url(void) {
   grpc_auth_metadata_context auth_md_ctx = {test_service_url, test_method,
                                             nullptr, nullptr};
   grpc_core::Json credential_source("");
-  TestExternalAccountCredentials::ExternalAccountCredentialsOptions options = {
+  TestExternalAccountCredentials::Options options = {
       "external_account",    // type;
       "audience",            // audience;
       "subject_token_type",  // subject_token_type;
@@ -2163,7 +2356,7 @@ test_external_account_creds_failure_invalid_service_account_impersonation_url(
   grpc_auth_metadata_context auth_md_ctx = {test_service_url, test_method,
                                             nullptr, nullptr};
   grpc_core::Json credential_source("");
-  TestExternalAccountCredentials::ExternalAccountCredentialsOptions options = {
+  TestExternalAccountCredentials::Options options = {
       "external_account",                           // type;
       "audience",                                   // audience;
       "subject_token_type",                         // subject_token_type;
@@ -2198,7 +2391,7 @@ test_external_account_creds_failure_token_exchange_response_missing_access_token
   grpc_auth_metadata_context auth_md_ctx = {test_service_url, test_method,
                                             nullptr, nullptr};
   grpc_core::Json credential_source("");
-  TestExternalAccountCredentials::ExternalAccountCredentialsOptions options = {
+  TestExternalAccountCredentials::Options options = {
       "external_account",    // type;
       "audience",            // audience;
       "subject_token_type",  // subject_token_type;
@@ -2238,19 +2431,55 @@ static void test_url_external_account_creds_success_format_text(void) {
       valid_url_external_account_creds_options_credential_source_format_text,
       &error);
   GPR_ASSERT(error == GRPC_ERROR_NONE);
-  grpc_core::ExternalAccountCredentials::ExternalAccountCredentialsOptions
-      options = {
-          "external_account",            // type;
-          "audience",                    // audience;
-          "subject_token_type",          // subject_token_type;
-          "",                            // service_account_impersonation_url;
-          "https://foo.com:5555/token",  // token_url;
-          "https://foo.com:5555/token_info",  // token_info_url;
-          credential_source,                  // credential_source;
-          "quota_project_id",                 // quota_project_id;
-          "client_id",                        // client_id;
-          "client_secret",                    // client_secret;
-      };
+  grpc_core::ExternalAccountCredentials::Options options = {
+      "external_account",                 // type;
+      "audience",                         // audience;
+      "subject_token_type",               // subject_token_type;
+      "",                                 // service_account_impersonation_url;
+      "https://foo.com:5555/token",       // token_url;
+      "https://foo.com:5555/token_info",  // token_info_url;
+      credential_source,                  // credential_source;
+      "quota_project_id",                 // quota_project_id;
+      "client_id",                        // client_id;
+      "client_secret",                    // client_secret;
+  };
+  auto creds =
+      grpc_core::UrlExternalAccountCredentials::Create(options, {}, &error);
+  GPR_ASSERT(creds != nullptr);
+  GPR_ASSERT(error == GRPC_ERROR_NONE);
+  GPR_ASSERT(creds->min_security_level() == GRPC_PRIVACY_AND_INTEGRITY);
+  request_metadata_state* state =
+      make_request_metadata_state(GRPC_ERROR_NONE, emd, GPR_ARRAY_SIZE(emd));
+  grpc_httpcli_set_override(url_external_account_creds_httpcli_get_success,
+                            external_account_creds_httpcli_post_success);
+  run_request_metadata_test(creds.get(), auth_md_ctx, state);
+  grpc_core::ExecCtx::Get()->Flush();
+  grpc_httpcli_set_override(nullptr, nullptr);
+}
+
+static void
+test_url_external_account_creds_success_with_qurey_params_format_text(void) {
+  expected_md emd[] = {{"authorization", "Bearer token_exchange_access_token"}};
+  grpc_core::ExecCtx exec_ctx;
+  grpc_auth_metadata_context auth_md_ctx = {test_service_url, test_method,
+                                            nullptr, nullptr};
+  grpc_error* error = GRPC_ERROR_NONE;
+  grpc_core::Json credential_source = grpc_core::Json::Parse(
+      valid_url_external_account_creds_options_credential_source_with_qurey_params_format_text,
+      &error);
+  GPR_ASSERT(error == GRPC_ERROR_NONE);
+  grpc_core::ExternalAccountCredentials::Options options = {
+      "external_account",                 // type;
+      "audience",                         // audience;
+      "subject_token_type",               // subject_token_type;
+      "",                                 // service_account_impersonation_url;
+      "https://foo.com:5555/token",       // token_url;
+      "https://foo.com:5555/token_info",  // token_info_url;
+      credential_source,                  // credential_source;
+      "quota_project_id",                 // quota_project_id;
+      "client_id",                        // client_id;
+      "client_secret",                    // client_secret;
+  };
   auto creds =
       grpc_core::UrlExternalAccountCredentials::Create(options, {}, &error);
   GPR_ASSERT(creds != nullptr);
@@ -2275,19 +2504,18 @@ static void test_url_external_account_creds_success_format_json(void) {
       valid_url_external_account_creds_options_credential_source_format_json,
       &error);
   GPR_ASSERT(error == GRPC_ERROR_NONE);
-  grpc_core::ExternalAccountCredentials::ExternalAccountCredentialsOptions
-      options = {
-          "external_account",            // type;
-          "audience",                    // audience;
-          "subject_token_type",          // subject_token_type;
-          "",                            // service_account_impersonation_url;
-          "https://foo.com:5555/token",  // token_url;
-          "https://foo.com:5555/token_info",  // token_info_url;
-          credential_source,                  // credential_source;
-          "quota_project_id",                 // quota_project_id;
-          "client_id",                        // client_id;
-          "client_secret",                    // client_secret;
-      };
+  grpc_core::ExternalAccountCredentials::Options options = {
+      "external_account",                 // type;
+      "audience",                         // audience;
+      "subject_token_type",               // subject_token_type;
+      "",                                 // service_account_impersonation_url;
+      "https://foo.com:5555/token",       // token_url;
+      "https://foo.com:5555/token_info",  // token_info_url;
+      credential_source,                  // credential_source;
+      "quota_project_id",                 // quota_project_id;
+      "client_id",                        // client_id;
+      "client_secret",                    // client_secret;
+  };
   auto creds =
       grpc_core::UrlExternalAccountCredentials::Create(options, {}, &error);
   GPR_ASSERT(creds != nullptr);
@@ -2308,28 +2536,27 @@ test_url_external_account_creds_failure_invalid_credential_source_url(void) {
   grpc_core::Json credential_source = grpc_core::Json::Parse(
       invalid_url_external_account_creds_options_credential_source, &error);
   GPR_ASSERT(error == GRPC_ERROR_NONE);
-  grpc_core::ExternalAccountCredentials::ExternalAccountCredentialsOptions
-      options = {
-          "external_account",            // type;
-          "audience",                    // audience;
-          "subject_token_type",          // subject_token_type;
-          "",                            // service_account_impersonation_url;
-          "https://foo.com:5555/token",  // token_url;
-          "https://foo.com:5555/token_info",  // token_info_url;
-          credential_source,                  // credential_source;
-          "quota_project_id",                 // quota_project_id;
-          "client_id",                        // client_id;
-          "client_secret",                    // client_secret;
-      };
+  grpc_core::ExternalAccountCredentials::Options options = {
+      "external_account",                 // type;
+      "audience",                         // audience;
+      "subject_token_type",               // subject_token_type;
+      "",                                 // service_account_impersonation_url;
+      "https://foo.com:5555/token",       // token_url;
+      "https://foo.com:5555/token_info",  // token_info_url;
+      credential_source,                  // credential_source;
+      "quota_project_id",                 // quota_project_id;
+      "client_id",                        // client_id;
+      "client_secret",                    // client_secret;
+  };
   auto creds =
       grpc_core::UrlExternalAccountCredentials::Create(options, {}, &error);
   GPR_ASSERT(creds == nullptr);
-  grpc_slice expected_error_slice =
-      grpc_slice_from_static_string("Invalid credential source url.");
   grpc_slice actual_error_slice;
   GPR_ASSERT(grpc_error_get_str(error, GRPC_ERROR_STR_DESCRIPTION,
                                 &actual_error_slice));
-  GPR_ASSERT(grpc_slice_cmp(expected_error_slice, actual_error_slice) == 0);
+  absl::string_view actual_error =
+      grpc_core::StringViewFromSlice(actual_error_slice);
+  GPR_ASSERT(absl::StartsWith(actual_error, "Invalid credential source url."));
   GRPC_ERROR_UNREF(error);
 }
 
@@ -2346,19 +2573,18 @@ static void test_file_external_account_creds_success_format_text(void) {
           absl::StrReplaceAll(subject_token_path, {{"\\", "\\\\"}})),
       &error);
   GPR_ASSERT(error == GRPC_ERROR_NONE);
-  grpc_core::ExternalAccountCredentials::ExternalAccountCredentialsOptions
-      options = {
-          "external_account",            // type;
-          "audience",                    // audience;
-          "subject_token_type",          // subject_token_type;
-          "",                            // service_account_impersonation_url;
-          "https://foo.com:5555/token",  // token_url;
-          "https://foo.com:5555/token_info",  // token_info_url;
-          credential_source,                  // credential_source;
-          "quota_project_id",                 // quota_project_id;
-          "client_id",                        // client_id;
-          "client_secret",                    // client_secret;
-      };
+  grpc_core::ExternalAccountCredentials::Options options = {
+      "external_account",                 // type;
+      "audience",                         // audience;
+      "subject_token_type",               // subject_token_type;
+      "",                                 // service_account_impersonation_url;
+      "https://foo.com:5555/token",       // token_url;
+      "https://foo.com:5555/token_info",  // token_info_url;
+      credential_source,                  // credential_source;
+      "quota_project_id",                 // quota_project_id;
+      "client_id",                        // client_id;
+      "client_secret",                    // client_secret;
+  };
   auto creds =
       grpc_core::FileExternalAccountCredentials::Create(options, {}, &error);
   GPR_ASSERT(creds != nullptr);
@@ -2396,19 +2622,18 @@ static void test_file_external_account_creds_success_format_json(void) {
           absl::StrReplaceAll(subject_token_path, {{"\\", "\\\\"}})),
       &error);
   GPR_ASSERT(error == GRPC_ERROR_NONE);
-  grpc_core::ExternalAccountCredentials::ExternalAccountCredentialsOptions
-      options = {
-          "external_account",            // type;
-          "audience",                    // audience;
-          "subject_token_type",          // subject_token_type;
-          "",                            // service_account_impersonation_url;
-          "https://foo.com:5555/token",  // token_url;
-          "https://foo.com:5555/token_info",  // token_info_url;
-          credential_source,                  // credential_source;
-          "quota_project_id",                 // quota_project_id;
-          "client_id",                        // client_id;
-          "client_secret",                    // client_secret;
-      };
+  grpc_core::ExternalAccountCredentials::Options options = {
+      "external_account",                 // type;
+      "audience",                         // audience;
+      "subject_token_type",               // subject_token_type;
+      "",                                 // service_account_impersonation_url;
+      "https://foo.com:5555/token",       // token_url;
+      "https://foo.com:5555/token_info",  // token_info_url;
+      credential_source,                  // credential_source;
+      "quota_project_id",                 // quota_project_id;
+      "client_id",                        // client_id;
+      "client_secret",                    // client_secret;
+  };
   auto creds =
       grpc_core::FileExternalAccountCredentials::Create(options, {}, &error);
   GPR_ASSERT(creds != nullptr);
@@ -2433,19 +2658,18 @@ static void test_file_external_account_creds_failure_file_not_found(void) {
   grpc_core::Json credential_source =
       grpc_core::Json::Parse("{\"file\":\"non_exisiting_file\"}", &error);
   GPR_ASSERT(error == GRPC_ERROR_NONE);
-  grpc_core::ExternalAccountCredentials::ExternalAccountCredentialsOptions
-      options = {
-          "external_account",            // type;
-          "audience",                    // audience;
-          "subject_token_type",          // subject_token_type;
-          "",                            // service_account_impersonation_url;
-          "https://foo.com:5555/token",  // token_url;
-          "https://foo.com:5555/token_info",  // token_info_url;
-          credential_source,                  // credential_source;
-          "quota_project_id",                 // quota_project_id;
-          "client_id",                        // client_id;
-          "client_secret",                    // client_secret;
-      };
+  grpc_core::ExternalAccountCredentials::Options options = {
+      "external_account",                 // type;
+      "audience",                         // audience;
+      "subject_token_type",               // subject_token_type;
+      "",                                 // service_account_impersonation_url;
+      "https://foo.com:5555/token",       // token_url;
+      "https://foo.com:5555/token_info",  // token_info_url;
+      credential_source,                  // credential_source;
+      "quota_project_id",                 // quota_project_id;
+      "client_id",                        // client_id;
+      "client_secret",                    // client_secret;
+  };
   auto creds =
       grpc_core::FileExternalAccountCredentials::Create(options, {}, &error);
   GPR_ASSERT(creds != nullptr);
@@ -2483,19 +2707,18 @@ static void test_file_external_account_creds_failure_invalid_json_content(
           absl::StrReplaceAll(subject_token_path, {{"\\", "\\\\"}})),
       &error);
   GPR_ASSERT(error == GRPC_ERROR_NONE);
-  grpc_core::ExternalAccountCredentials::ExternalAccountCredentialsOptions
-      options = {
-          "external_account",            // type;
-          "audience",                    // audience;
-          "subject_token_type",          // subject_token_type;
-          "",                            // service_account_impersonation_url;
-          "https://foo.com:5555/token",  // token_url;
-          "https://foo.com:5555/token_info",  // token_info_url;
-          credential_source,                  // credential_source;
-          "quota_project_id",                 // quota_project_id;
-          "client_id",                        // client_id;
-          "client_secret",                    // client_secret;
-      };
+  grpc_core::ExternalAccountCredentials::Options options = {
+      "external_account",                 // type;
+      "audience",                         // audience;
+      "subject_token_type",               // subject_token_type;
+      "",                                 // service_account_impersonation_url;
+      "https://foo.com:5555/token",       // token_url;
+      "https://foo.com:5555/token_info",  // token_info_url;
+      credential_source,                  // credential_source;
+      "quota_project_id",                 // quota_project_id;
+      "client_id",                        // client_id;
+      "client_secret",                    // client_secret;
+  };
   auto creds =
       grpc_core::FileExternalAccountCredentials::Create(options, {}, &error);
   GPR_ASSERT(creds != nullptr);
@@ -2515,6 +2738,443 @@ static void test_file_external_account_creds_failure_invalid_json_content(
   gpr_free(subject_token_path);
 }
 
+static void test_aws_external_account_creds_success(void) {
+  expected_md emd[] = {{"authorization", "Bearer token_exchange_access_token"}};
+  grpc_core::ExecCtx exec_ctx;
+  grpc_auth_metadata_context auth_md_ctx = {test_service_url, test_method,
+                                            nullptr, nullptr};
+  grpc_error* error = GRPC_ERROR_NONE;
+  grpc_core::Json credential_source = grpc_core::Json::Parse(
+      valid_aws_external_account_creds_options_credential_source, &error);
+  GPR_ASSERT(error == GRPC_ERROR_NONE);
+  grpc_core::ExternalAccountCredentials::Options options = {
+      "external_account",                 // type;
+      "audience",                         // audience;
+      "subject_token_type",               // subject_token_type;
+      "",                                 // service_account_impersonation_url;
+      "https://foo.com:5555/token",       // token_url;
+      "https://foo.com:5555/token_info",  // token_info_url;
+      credential_source,                  // credential_source;
+      "quota_project_id",                 // quota_project_id;
+      "client_id",                        // client_id;
+      "client_secret",                    // client_secret;
+  };
+  auto creds =
+      grpc_core::AwsExternalAccountCredentials::Create(options, {}, &error);
+  GPR_ASSERT(creds != nullptr);
+  GPR_ASSERT(error == GRPC_ERROR_NONE);
+  GPR_ASSERT(creds->min_security_level() == GRPC_PRIVACY_AND_INTEGRITY);
+  request_metadata_state* state =
+      make_request_metadata_state(GRPC_ERROR_NONE, emd, GPR_ARRAY_SIZE(emd));
+  grpc_httpcli_set_override(aws_external_account_creds_httpcli_get_success,
+                            aws_external_account_creds_httpcli_post_success);
+  run_request_metadata_test(creds.get(), auth_md_ctx, state);
+  grpc_core::ExecCtx::Get()->Flush();
+  grpc_httpcli_set_override(nullptr, nullptr);
+}
+
+static void test_aws_external_account_creds_success_path_region_env_keys_url(
+    void) {
+  expected_md emd[] = {{"authorization", "Bearer token_exchange_access_token"}};
+  grpc_core::ExecCtx exec_ctx;
+  grpc_auth_metadata_context auth_md_ctx = {test_service_url, test_method,
+                                            nullptr, nullptr};
+  gpr_setenv("AWS_REGION", "test_regionz");
+  grpc_error* error = GRPC_ERROR_NONE;
+  grpc_core::Json credential_source = grpc_core::Json::Parse(
+      valid_aws_external_account_creds_options_credential_source, &error);
+  GPR_ASSERT(error == GRPC_ERROR_NONE);
+  grpc_core::ExternalAccountCredentials::Options options = {
+      "external_account",                 // type;
+      "audience",                         // audience;
+      "subject_token_type",               // subject_token_type;
+      "",                                 // service_account_impersonation_url;
+      "https://foo.com:5555/token",       // token_url;
+      "https://foo.com:5555/token_info",  // token_info_url;
+      credential_source,                  // credential_source;
+      "quota_project_id",                 // quota_project_id;
+      "client_id",                        // client_id;
+      "client_secret",                    // client_secret;
+  };
+  auto creds =
+      grpc_core::AwsExternalAccountCredentials::Create(options, {}, &error);
+  GPR_ASSERT(creds != nullptr);
+  GPR_ASSERT(error == GRPC_ERROR_NONE);
+  GPR_ASSERT(creds->min_security_level() == GRPC_PRIVACY_AND_INTEGRITY);
+  request_metadata_state* state =
+      make_request_metadata_state(GRPC_ERROR_NONE, emd, GPR_ARRAY_SIZE(emd));
+  grpc_httpcli_set_override(aws_external_account_creds_httpcli_get_success,
+                            aws_external_account_creds_httpcli_post_success);
+  run_request_metadata_test(creds.get(), auth_md_ctx, state);
+  grpc_core::ExecCtx::Get()->Flush();
+  grpc_httpcli_set_override(nullptr, nullptr);
+  gpr_unsetenv("AWS_REGION");
+}
+
+static void test_aws_external_account_creds_success_path_region_url_keys_env(
+    void) {
+  expected_md emd[] = {{"authorization", "Bearer token_exchange_access_token"}};
+  grpc_core::ExecCtx exec_ctx;
+  grpc_auth_metadata_context auth_md_ctx = {test_service_url, test_method,
+                                            nullptr, nullptr};
+  gpr_setenv("AWS_ACCESS_KEY_ID", "test_access_key_id");
+  gpr_setenv("AWS_SECRET_ACCESS_KEY", "test_secret_access_key");
+  gpr_setenv("AWS_SESSION_TOKEN", "test_token");
+  grpc_error* error = GRPC_ERROR_NONE;
+  grpc_core::Json credential_source = grpc_core::Json::Parse(
+      valid_aws_external_account_creds_options_credential_source, &error);
+  GPR_ASSERT(error == GRPC_ERROR_NONE);
+  grpc_core::ExternalAccountCredentials::Options options = {
+      "external_account",                 // type;
+      "audience",                         // audience;
+      "subject_token_type",               // subject_token_type;
+      "",                                 // service_account_impersonation_url;
+      "https://foo.com:5555/token",       // token_url;
+      "https://foo.com:5555/token_info",  // token_info_url;
+      credential_source,                  // credential_source;
+      "quota_project_id",                 // quota_project_id;
+      "client_id",                        // client_id;
+      "client_secret",                    // client_secret;
+  };
+  auto creds =
+      grpc_core::AwsExternalAccountCredentials::Create(options, {}, &error);
+  GPR_ASSERT(creds != nullptr);
+  GPR_ASSERT(error == GRPC_ERROR_NONE);
+  GPR_ASSERT(creds->min_security_level() == GRPC_PRIVACY_AND_INTEGRITY);
+  request_metadata_state* state =
+      make_request_metadata_state(GRPC_ERROR_NONE, emd, GPR_ARRAY_SIZE(emd));
+  grpc_httpcli_set_override(aws_external_account_creds_httpcli_get_success,
+                            aws_external_account_creds_httpcli_post_success);
+  run_request_metadata_test(creds.get(), auth_md_ctx, state);
+  grpc_core::ExecCtx::Get()->Flush();
+  grpc_httpcli_set_override(nullptr, nullptr);
+  gpr_unsetenv("AWS_ACCESS_KEY_ID");
+  gpr_unsetenv("AWS_SECRET_ACCESS_KEY");
+  gpr_unsetenv("AWS_SESSION_TOKEN");
+}
+
+static void test_aws_external_account_creds_success_path_region_env_keys_env(
+    void) {
+  expected_md emd[] = {{"authorization", "Bearer token_exchange_access_token"}};
+  grpc_core::ExecCtx exec_ctx;
+  grpc_auth_metadata_context auth_md_ctx = {test_service_url, test_method,
+                                            nullptr, nullptr};
+  gpr_setenv("AWS_REGION", "test_regionz");
+  gpr_setenv("AWS_ACCESS_KEY_ID", "test_access_key_id");
+  gpr_setenv("AWS_SECRET_ACCESS_KEY", "test_secret_access_key");
+  gpr_setenv("AWS_SESSION_TOKEN", "test_token");
+  grpc_error* error = GRPC_ERROR_NONE;
+  grpc_core::Json credential_source = grpc_core::Json::Parse(
+      valid_aws_external_account_creds_options_credential_source, &error);
+  GPR_ASSERT(error == GRPC_ERROR_NONE);
+  grpc_core::ExternalAccountCredentials::Options options = {
+      "external_account",                 // type;
+      "audience",                         // audience;
+      "subject_token_type",               // subject_token_type;
+      "",                                 // service_account_impersonation_url;
+      "https://foo.com:5555/token",       // token_url;
+      "https://foo.com:5555/token_info",  // token_info_url;
+      credential_source,                  // credential_source;
+      "quota_project_id",                 // quota_project_id;
+      "client_id",                        // client_id;
+      "client_secret",                    // client_secret;
+  };
+  auto creds =
+      grpc_core::AwsExternalAccountCredentials::Create(options, {}, &error);
+  GPR_ASSERT(creds != nullptr);
+  GPR_ASSERT(error == GRPC_ERROR_NONE);
+  GPR_ASSERT(creds->min_security_level() == GRPC_PRIVACY_AND_INTEGRITY);
+  request_metadata_state* state =
+      make_request_metadata_state(GRPC_ERROR_NONE, emd, GPR_ARRAY_SIZE(emd));
+  grpc_httpcli_set_override(aws_external_account_creds_httpcli_get_success,
+                            aws_external_account_creds_httpcli_post_success);
+  run_request_metadata_test(creds.get(), auth_md_ctx, state);
+  grpc_core::ExecCtx::Get()->Flush();
+  grpc_httpcli_set_override(nullptr, nullptr);
+  gpr_unsetenv("AWS_REGION");
+  gpr_unsetenv("AWS_ACCESS_KEY_ID");
+  gpr_unsetenv("AWS_SECRET_ACCESS_KEY");
+  gpr_unsetenv("AWS_SESSION_TOKEN");
+}
+
+static void test_aws_external_account_creds_failure_unmatched_environment_id(
+    void) {
+  grpc_error* error = GRPC_ERROR_NONE;
+  grpc_core::Json credential_source = grpc_core::Json::Parse(
+      invalid_aws_external_account_creds_options_credential_source_unmatched_environment_id,
+      &error);
+  GPR_ASSERT(error == GRPC_ERROR_NONE);
+  grpc_core::ExternalAccountCredentials::Options options = {
+      "external_account",                 // type;
+      "audience",                         // audience;
+      "subject_token_type",               // subject_token_type;
+      "",                                 // service_account_impersonation_url;
+      "https://foo.com:5555/token",       // token_url;
+      "https://foo.com:5555/token_info",  // token_info_url;
+      credential_source,                  // credential_source;
+      "quota_project_id",                 // quota_project_id;
+      "client_id",                        // client_id;
+      "client_secret",                    // client_secret;
+  };
+  auto creds =
+      grpc_core::AwsExternalAccountCredentials::Create(options, {}, &error);
+  GPR_ASSERT(creds == nullptr);
+  grpc_slice expected_error_slice =
+      grpc_slice_from_static_string("environment_id does not match.");
+  grpc_slice actual_error_slice;
+  GPR_ASSERT(grpc_error_get_str(error, GRPC_ERROR_STR_DESCRIPTION,
+                                &actual_error_slice));
+  GPR_ASSERT(grpc_slice_cmp(expected_error_slice, actual_error_slice) == 0);
+  GRPC_ERROR_UNREF(error);
+}
+
+static void test_aws_external_account_creds_failure_invalid_region_url(void) {
+  grpc_core::ExecCtx exec_ctx;
+  grpc_auth_metadata_context auth_md_ctx = {test_service_url, test_method,
+                                            nullptr, nullptr};
+  grpc_error* error = GRPC_ERROR_NONE;
+  grpc_core::Json credential_source = grpc_core::Json::Parse(
+      invalid_aws_external_account_creds_options_credential_source_invalid_region_url,
+      &error);
+  GPR_ASSERT(error == GRPC_ERROR_NONE);
+  grpc_core::ExternalAccountCredentials::Options options = {
+      "external_account",                 // type;
+      "audience",                         // audience;
+      "subject_token_type",               // subject_token_type;
+      "",                                 // service_account_impersonation_url;
+      "https://foo.com:5555/token",       // token_url;
+      "https://foo.com:5555/token_info",  // token_info_url;
+      credential_source,                  // credential_source;
+      "quota_project_id",                 // quota_project_id;
+      "client_id",                        // client_id;
+      "client_secret",                    // client_secret;
+  };
+  auto creds =
+      grpc_core::AwsExternalAccountCredentials::Create(options, {}, &error);
+  GPR_ASSERT(creds != nullptr);
+  GPR_ASSERT(error == GRPC_ERROR_NONE);
+  GPR_ASSERT(creds->min_security_level() == GRPC_PRIVACY_AND_INTEGRITY);
+  error = GRPC_ERROR_CREATE_FROM_STATIC_STRING(
+      "Invalid region url: invalid_region_url.");
+  grpc_error* expected_error = GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING(
+      "Error occurred when fetching oauth2 token.", &error, 1);
+  request_metadata_state* state =
+      make_request_metadata_state(expected_error, nullptr, 0);
+  grpc_httpcli_set_override(aws_external_account_creds_httpcli_get_success,
+                            aws_external_account_creds_httpcli_post_success);
+  run_request_metadata_test(creds.get(), auth_md_ctx, state);
+  grpc_core::ExecCtx::Get()->Flush();
+  grpc_httpcli_set_override(nullptr, nullptr);
+  GRPC_ERROR_UNREF(error);
+}
+
+static void test_aws_external_account_creds_failure_invalid_url(void) {
+  grpc_core::ExecCtx exec_ctx;
+  grpc_auth_metadata_context auth_md_ctx = {test_service_url, test_method,
+                                            nullptr, nullptr};
+  grpc_error* error = GRPC_ERROR_NONE;
+  grpc_core::Json credential_source = grpc_core::Json::Parse(
+      invalid_aws_external_account_creds_options_credential_source_invalid_url,
+      &error);
+  GPR_ASSERT(error == GRPC_ERROR_NONE);
+  grpc_core::ExternalAccountCredentials::Options options = {
+      "external_account",                 // type;
+      "audience",                         // audience;
+      "subject_token_type",               // subject_token_type;
+      "",                                 // service_account_impersonation_url;
+      "https://foo.com:5555/token",       // token_url;
+      "https://foo.com:5555/token_info",  // token_info_url;
+      credential_source,                  // credential_source;
+      "quota_project_id",                 // quota_project_id;
+      "client_id",                        // client_id;
+      "client_secret",                    // client_secret;
+  };
+  auto creds =
+      grpc_core::AwsExternalAccountCredentials::Create(options, {}, &error);
+  GPR_ASSERT(creds != nullptr);
+  GPR_ASSERT(error == GRPC_ERROR_NONE);
+  GPR_ASSERT(creds->min_security_level() == GRPC_PRIVACY_AND_INTEGRITY);
+  error = GRPC_ERROR_CREATE_FROM_STATIC_STRING("Invalid url: invalid_url.");
+  grpc_error* expected_error = GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING(
+      "Error occurred when fetching oauth2 token.", &error, 1);
+  request_metadata_state* state =
+      make_request_metadata_state(expected_error, nullptr, 0);
+  grpc_httpcli_set_override(aws_external_account_creds_httpcli_get_success,
+                            aws_external_account_creds_httpcli_post_success);
+  run_request_metadata_test(creds.get(), auth_md_ctx, state);
+  grpc_core::ExecCtx::Get()->Flush();
+  grpc_httpcli_set_override(nullptr, nullptr);
+  GRPC_ERROR_UNREF(error);
+}
+
+static void test_aws_external_account_creds_failure_missing_role_name(void) {
+  grpc_core::ExecCtx exec_ctx;
+  grpc_auth_metadata_context auth_md_ctx = {test_service_url, test_method,
+                                            nullptr, nullptr};
+  grpc_error* error = GRPC_ERROR_NONE;
+  grpc_core::Json credential_source = grpc_core::Json::Parse(
+      invalid_aws_external_account_creds_options_credential_source_missing_role_name,
+      &error);
+  GPR_ASSERT(error == GRPC_ERROR_NONE);
+  grpc_core::ExternalAccountCredentials::Options options = {
+      "external_account",                 // type;
+      "audience",                         // audience;
+      "subject_token_type",               // subject_token_type;
+      "",                                 // service_account_impersonation_url;
+      "https://foo.com:5555/token",       // token_url;
+      "https://foo.com:5555/token_info",  // token_info_url;
+      credential_source,                  // credential_source;
+      "quota_project_id",                 // quota_project_id;
+      "client_id",                        // client_id;
+      "client_secret",                    // client_secret;
+  };
+  auto creds =
+      grpc_core::AwsExternalAccountCredentials::Create(options, {}, &error);
+  GPR_ASSERT(creds != nullptr);
+  GPR_ASSERT(error == GRPC_ERROR_NONE);
+  GPR_ASSERT(creds->min_security_level() == GRPC_PRIVACY_AND_INTEGRITY);
+  error = GRPC_ERROR_CREATE_FROM_STATIC_STRING(
+      "Missing role name when retrieving signing keys.");
+  grpc_error* expected_error = GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING(
+      "Error occurred when fetching oauth2 token.", &error, 1);
+  request_metadata_state* state =
+      make_request_metadata_state(expected_error, nullptr, 0);
+  grpc_httpcli_set_override(aws_external_account_creds_httpcli_get_success,
+                            aws_external_account_creds_httpcli_post_success);
+  run_request_metadata_test(creds.get(), auth_md_ctx, state);
+  grpc_core::ExecCtx::Get()->Flush();
+  grpc_httpcli_set_override(nullptr, nullptr);
+  GRPC_ERROR_UNREF(error);
+}
+
+static void
+test_aws_external_account_creds_failure_invalid_regional_cred_verification_url(
+    void) {
+  grpc_core::ExecCtx exec_ctx;
+  grpc_auth_metadata_context auth_md_ctx = {test_service_url, test_method,
+                                            nullptr, nullptr};
+  grpc_error* error = GRPC_ERROR_NONE;
+  grpc_core::Json credential_source = grpc_core::Json::Parse(
+      invalid_aws_external_account_creds_options_credential_source_invalid_regional_cred_verification_url,
+      &error);
+  GPR_ASSERT(error == GRPC_ERROR_NONE);
+  grpc_core::ExternalAccountCredentials::Options options = {
+      "external_account",                 // type;
+      "audience",                         // audience;
+      "subject_token_type",               // subject_token_type;
+      "",                                 // service_account_impersonation_url;
+      "https://foo.com:5555/token",       // token_url;
+      "https://foo.com:5555/token_info",  // token_info_url;
+      credential_source,                  // credential_source;
+      "quota_project_id",                 // quota_project_id;
+      "client_id",                        // client_id;
+      "client_secret",                    // client_secret;
+  };
+  auto creds =
+      grpc_core::AwsExternalAccountCredentials::Create(options, {}, &error);
+  GPR_ASSERT(creds != nullptr);
+  GPR_ASSERT(error == GRPC_ERROR_NONE);
+  GPR_ASSERT(creds->min_security_level() == GRPC_PRIVACY_AND_INTEGRITY);
+  error = GRPC_ERROR_CREATE_FROM_STATIC_STRING(
+      "Creating aws request signer failed.");
+  grpc_error* expected_error = GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING(
+      "Error occurred when fetching oauth2 token.", &error, 1);
+  request_metadata_state* state =
+      make_request_metadata_state(expected_error, nullptr, 0);
+  grpc_httpcli_set_override(aws_external_account_creds_httpcli_get_success,
+                            aws_external_account_creds_httpcli_post_success);
+  run_request_metadata_test(creds.get(), auth_md_ctx, state);
+  grpc_core::ExecCtx::Get()->Flush();
+  grpc_httpcli_set_override(nullptr, nullptr);
+  GRPC_ERROR_UNREF(error);
+}
+
+static void test_external_account_credentials_create_success(void) {
+  // url credentials
+  const char* url_options_string =
+      "{\"type\":\"external_account\",\"audience\":\"audience\",\"subject_"
+      "token_type\":\"subject_token_type\",\"service_account_impersonation_"
+      "url\":\"service_account_impersonation_url\",\"token_url\":\"https://"
+      "foo.com:5555/token\",\"token_info_url\":\"https://foo.com:5555/"
+      "token_info\",\"credential_source\":{\"url\":\"https://foo.com:5555/"
+      "generate_subject_token_format_json\",\"headers\":{\"Metadata-Flavor\":"
+      "\"Google\"},\"format\":{\"type\":\"json\",\"subject_token_field_name\":"
+      "\"access_token\"}},\"quota_project_id\":\"quota_"
+      "project_id\",\"client_id\":\"client_id\",\"client_secret\":\"client_"
+      "secret\"}";
+  const char* url_scopes_string = "scope1,scope2";
+  grpc_call_credentials* url_creds = grpc_external_account_credentials_create(
+      url_options_string, url_scopes_string);
+  GPR_ASSERT(url_creds != nullptr);
+  url_creds->Unref();
+  // file credentials
+  const char* file_options_string =
+      "{\"type\":\"external_account\",\"audience\":\"audience\",\"subject_"
+      "token_type\":\"subject_token_type\",\"service_account_impersonation_"
+      "url\":\"service_account_impersonation_url\",\"token_url\":\"https://"
+      "foo.com:5555/token\",\"token_info_url\":\"https://foo.com:5555/"
+      "token_info\",\"credential_source\":{\"file\":\"credentials_file_path\"},"
+      "\"quota_project_id\":\"quota_"
+      "project_id\",\"client_id\":\"client_id\",\"client_secret\":\"client_"
+      "secret\"}";
+  const char* file_scopes_string = "scope1,scope2";
+  grpc_call_credentials* file_creds = grpc_external_account_credentials_create(
+      file_options_string, file_scopes_string);
+  GPR_ASSERT(file_creds != nullptr);
+  file_creds->Unref();
+  // aws credentials
+  const char* aws_options_string =
+      "{\"type\":\"external_account\",\"audience\":\"audience\",\"subject_"
+      "token_type\":\"subject_token_type\",\"service_account_impersonation_"
+      "url\":\"service_account_impersonation_url\",\"token_url\":\"https://"
+      "foo.com:5555/token\",\"token_info_url\":\"https://foo.com:5555/"
+      "token_info\",\"credential_source\":{\"environment_id\":\"aws1\","
+      "\"region_url\":\"https://foo.com:5555/region_url\",\"url\":\"https://"
+      "foo.com:5555/url\",\"regional_cred_verification_url\":\"https://"
+      "foo.com:5555/regional_cred_verification_url_{region}\"},"
+      "\"quota_project_id\":\"quota_"
+      "project_id\",\"client_id\":\"client_id\",\"client_secret\":\"client_"
+      "secret\"}";
+  const char* aws_scopes_string = "scope1,scope2";
+  grpc_call_credentials* aws_creds = grpc_external_account_credentials_create(
+      aws_options_string, aws_scopes_string);
+  GPR_ASSERT(aws_creds != nullptr);
+  aws_creds->Unref();
+}
+
+static void
+test_external_account_credentials_create_failure_invalid_json_format(void) {
+  const char* options_string = "invalid_json";
+  grpc_call_credentials* creds =
+      grpc_external_account_credentials_create(options_string, "");
+  GPR_ASSERT(creds == nullptr);
+}
+
+static void
+test_external_account_credentials_create_failure_invalid_options_format(void) {
+  const char* options_string = "{\"random_key\":\"random_value\"}";
+  grpc_call_credentials* creds =
+      grpc_external_account_credentials_create(options_string, "");
+  GPR_ASSERT(creds == nullptr);
+}
+
+static void
+test_external_account_credentials_create_failure_invalid_options_credential_source(
+    void) {
+  const char* options_string =
+      "{\"type\":\"external_account\",\"audience\":\"audience\",\"subject_"
+      "token_type\":\"subject_token_type\",\"service_account_impersonation_"
+      "url\":\"service_account_impersonation_url\",\"token_url\":\"https://"
+      "foo.com:5555/token\",\"token_info_url\":\"https://foo.com:5555/"
+      "token_info\",\"credential_source\":{\"random_key\":\"random_value\"},"
+      "\"quota_project_id\":\"quota_"
+      "project_id\",\"client_id\":\"client_id\",\"client_secret\":\"client_"
+      "secret\"}";
+  grpc_call_credentials* creds =
+      grpc_external_account_credentials_create(options_string, "");
+  GPR_ASSERT(creds == nullptr);
+}
+
 int main(int argc, char** argv) {
   grpc::testing::TestEnvironment env(argc, argv);
   grpc_init();
@@ -2560,6 +3220,7 @@ int main(int argc, char** argv) {
   test_channel_creds_duplicate_without_call_creds();
   test_auth_metadata_context();
   test_external_account_creds_success();
+  test_external_account_creds_success_with_url_encode();
   test_external_account_creds_success_with_service_account_impersonation();
   test_external_account_creds_failure_invalid_token_url();
   test_external_account_creds_failure_invalid_service_account_impersonation_url();
@@ -2567,10 +3228,24 @@ int main(int argc, char** argv) {
   test_url_external_account_creds_success_format_text();
   test_url_external_account_creds_success_format_json();
   test_url_external_account_creds_failure_invalid_credential_source_url();
+  test_url_external_account_creds_success_with_qurey_params_format_text();
   test_file_external_account_creds_success_format_text();
   test_file_external_account_creds_success_format_json();
   test_file_external_account_creds_failure_file_not_found();
   test_file_external_account_creds_failure_invalid_json_content();
+  test_aws_external_account_creds_success();
+  test_aws_external_account_creds_success_path_region_env_keys_url();
+  test_aws_external_account_creds_success_path_region_url_keys_env();
+  test_aws_external_account_creds_success_path_region_env_keys_env();
+  test_aws_external_account_creds_failure_unmatched_environment_id();
+  test_aws_external_account_creds_failure_invalid_region_url();
+  test_aws_external_account_creds_failure_invalid_url();
+  test_aws_external_account_creds_failure_missing_role_name();
+  test_aws_external_account_creds_failure_invalid_regional_cred_verification_url();
+  test_external_account_credentials_create_success();
+  test_external_account_credentials_create_failure_invalid_json_format();
+  test_external_account_credentials_create_failure_invalid_options_format();
+  test_external_account_credentials_create_failure_invalid_options_credential_source();
   grpc_shutdown();
   return 0;
 }
index 61be71c..9e8efcc 100644 (file)
@@ -29,6 +29,9 @@
 
 #include "src/core/lib/slice/slice_internal.h"
 #include "test/core/util/test_config.h"
+#include "test/core/util/tls_utils.h"
+
+namespace grpc_core {
 
 namespace testing {
 
@@ -53,29 +56,14 @@ class GrpcTlsCertificateDistributorTest : public ::testing::Test {
   // Forward declaration.
   class TlsCertificatesTestWatcher;
 
-  static grpc_core::PemKeyCertPairList MakeCertKeyPairs(const char* private_key,
-                                                        const char* certs) {
-    if (strcmp(private_key, "") == 0 && strcmp(certs, "") == 0) {
-      return {};
-    }
-    grpc_ssl_pem_key_cert_pair* ssl_pair =
-        static_cast<grpc_ssl_pem_key_cert_pair*>(
-            gpr_malloc(sizeof(grpc_ssl_pem_key_cert_pair)));
-    ssl_pair->private_key = gpr_strdup(private_key);
-    ssl_pair->cert_chain = gpr_strdup(certs);
-    grpc_core::PemKeyCertPairList pem_key_cert_pairs;
-    pem_key_cert_pairs.emplace_back(ssl_pair);
-    return pem_key_cert_pairs;
-  }
-
   // CredentialInfo contains the parameters when calling OnCertificatesChanged
   // of a watcher. When OnCertificatesChanged is invoked, we will push a
   // CredentialInfo to the cert_update_queue of state_, and check in each test
   // if the status updates are correct.
   struct CredentialInfo {
     std::string root_certs;
-    grpc_core::PemKeyCertPairList key_cert_pairs;
-    CredentialInfo(std::string root, grpc_core::PemKeyCertPairList key_cert)
+    PemKeyCertPairList key_cert_pairs;
+    CredentialInfo(std::string root, PemKeyCertPairList key_cert)
         : root_certs(std::move(root)), key_cert_pairs(std::move(key_cert)) {}
     bool operator==(const CredentialInfo& other) const {
       return root_certs == other.root_certs &&
@@ -128,12 +116,12 @@ class GrpcTlsCertificateDistributorTest : public ::testing::Test {
 
     void OnCertificatesChanged(
         absl::optional<absl::string_view> root_certs,
-        absl::optional<grpc_core::PemKeyCertPairList> key_cert_pairs) override {
+        absl::optional<PemKeyCertPairList> key_cert_pairs) override {
       std::string updated_root;
       if (root_certs.has_value()) {
         updated_root = std::string(*root_certs);
       }
-      grpc_core::PemKeyCertPairList updated_identity;
+      PemKeyCertPairList updated_identity;
       if (key_cert_pairs.has_value()) {
         updated_identity = std::move(*key_cert_pairs);
       }
@@ -151,8 +139,7 @@ class GrpcTlsCertificateDistributorTest : public ::testing::Test {
         grpc_slice root_error_slice;
         GPR_ASSERT(grpc_error_get_str(
             root_cert_error, GRPC_ERROR_STR_DESCRIPTION, &root_error_slice));
-        root_error_str =
-            std::string(grpc_core::StringViewFromSlice(root_error_slice));
+        root_error_str = std::string(StringViewFromSlice(root_error_slice));
       }
       if (identity_cert_error != GRPC_ERROR_NONE) {
         grpc_slice identity_error_slice;
@@ -160,7 +147,7 @@ class GrpcTlsCertificateDistributorTest : public ::testing::Test {
                                       GRPC_ERROR_STR_DESCRIPTION,
                                       &identity_error_slice));
         identity_error_str =
-            std::string(grpc_core::StringViewFromSlice(identity_error_slice));
+            std::string(StringViewFromSlice(identity_error_slice));
       }
       state_->error_queue.emplace_back(std::move(root_error_str),
                                        std::move(identity_error_str));
@@ -202,7 +189,7 @@ class GrpcTlsCertificateDistributorTest : public ::testing::Test {
 
   WatcherState* MakeWatcher(absl::optional<std::string> root_cert_name,
                             absl::optional<std::string> identity_cert_name) {
-    grpc_core::MutexLock lock(&mu_);
+    MutexLock lock(&mu_);
     watchers_.emplace_back();
     // TlsCertificatesTestWatcher ctor takes a pointer to the WatcherState.
     // It sets WatcherState::watcher to point to itself.
@@ -217,7 +204,7 @@ class GrpcTlsCertificateDistributorTest : public ::testing::Test {
   }
 
   void CancelWatch(WatcherState* state) {
-    grpc_core::MutexLock lock(&mu_);
+    MutexLock lock(&mu_);
     distributor_.CancelTlsCertificatesWatch(state->watcher);
     EXPECT_EQ(state->watcher, nullptr);
   }
@@ -234,7 +221,7 @@ class GrpcTlsCertificateDistributorTest : public ::testing::Test {
   std::list<WatcherState> watchers_;
   std::deque<CallbackStatus> callback_queue_;
   // This is to make watchers_ and callback_queue_ thread-safe.
-  grpc_core::Mutex mu_;
+  Mutex mu_;
 };
 
 TEST_F(GrpcTlsCertificateDistributorTest, BasicCredentialBehaviors) {
@@ -257,21 +244,21 @@ TEST_F(GrpcTlsCertificateDistributorTest, BasicCredentialBehaviors) {
 TEST_F(GrpcTlsCertificateDistributorTest, UpdateCredentialsOnAnySide) {
   WatcherState* watcher_state_1 = MakeWatcher(kCertName1, kCertName1);
   EXPECT_THAT(GetCallbackQueue(),
-              testing::ElementsAre(CallbackStatus(kCertName1, true, true)));
+              ::testing::ElementsAre(CallbackStatus(kCertName1, true, true)));
   // SetKeyMaterials should trigger watcher's OnCertificatesChanged method.
   distributor_.SetKeyMaterials(
       kCertName1, kRootCert1Contents,
       MakeCertKeyPairs(kIdentityCert1PrivateKey, kIdentityCert1Contents));
   EXPECT_THAT(
       watcher_state_1->GetCredentialQueue(),
-      testing::ElementsAre(CredentialInfo(
+      ::testing::ElementsAre(CredentialInfo(
           kRootCert1Contents,
           MakeCertKeyPairs(kIdentityCert1PrivateKey, kIdentityCert1Contents))));
   // Set root certs should trigger watcher's OnCertificatesChanged again.
   distributor_.SetKeyMaterials(kCertName1, kRootCert2Contents, absl::nullopt);
   EXPECT_THAT(
       watcher_state_1->GetCredentialQueue(),
-      testing::ElementsAre(CredentialInfo(
+      ::testing::ElementsAre(CredentialInfo(
           kRootCert2Contents,
           MakeCertKeyPairs(kIdentityCert1PrivateKey, kIdentityCert1Contents))));
   // Set identity certs should trigger watcher's OnCertificatesChanged again.
@@ -280,7 +267,7 @@ TEST_F(GrpcTlsCertificateDistributorTest, UpdateCredentialsOnAnySide) {
       MakeCertKeyPairs(kIdentityCert2PrivateKey, kIdentityCert2Contents));
   EXPECT_THAT(
       watcher_state_1->GetCredentialQueue(),
-      testing::ElementsAre(CredentialInfo(
+      ::testing::ElementsAre(CredentialInfo(
           kRootCert2Contents,
           MakeCertKeyPairs(kIdentityCert2PrivateKey, kIdentityCert2Contents))));
   CancelWatch(watcher_state_1);
@@ -292,12 +279,12 @@ TEST_F(GrpcTlsCertificateDistributorTest, SameIdentityNameDiffRootName) {
       MakeWatcher(kRootCert1Name, kIdentityCert1Name);
   EXPECT_THAT(
       GetCallbackQueue(),
-      testing::ElementsAre(CallbackStatus(kRootCert1Name, true, false),
-                           CallbackStatus(kIdentityCert1Name, false, true)));
+      ::testing::ElementsAre(CallbackStatus(kRootCert1Name, true, false),
+                             CallbackStatus(kIdentityCert1Name, false, true)));
   // Register watcher 2.
   WatcherState* watcher_state_2 =
       MakeWatcher(kRootCert2Name, kIdentityCert1Name);
-  EXPECT_THAT(GetCallbackQueue(), testing::ElementsAre(CallbackStatus(
+  EXPECT_THAT(GetCallbackQueue(), ::testing::ElementsAre(CallbackStatus(
                                       kRootCert2Name, true, false)));
   // Push credential updates to kRootCert1Name and check if the status works as
   // expected.
@@ -305,13 +292,13 @@ TEST_F(GrpcTlsCertificateDistributorTest, SameIdentityNameDiffRootName) {
                                absl::nullopt);
   // Check the updates are delivered to watcher 1.
   EXPECT_THAT(watcher_state_1->GetCredentialQueue(),
-              testing::ElementsAre(CredentialInfo(kRootCert1Contents, {})));
+              ::testing::ElementsAre(CredentialInfo(kRootCert1Contents, {})));
   // Push credential updates to kRootCert2Name.
   distributor_.SetKeyMaterials(kRootCert2Name, kRootCert2Contents,
                                absl::nullopt);
   // Check the updates are delivered to watcher 2.
   EXPECT_THAT(watcher_state_2->GetCredentialQueue(),
-              testing::ElementsAre(CredentialInfo(kRootCert2Contents, {})));
+              ::testing::ElementsAre(CredentialInfo(kRootCert2Contents, {})));
   // Push credential updates to kIdentityCert1Name and check if the status works
   // as expected.
   distributor_.SetKeyMaterials(
@@ -320,24 +307,24 @@ TEST_F(GrpcTlsCertificateDistributorTest, SameIdentityNameDiffRootName) {
   // Check the updates are delivered to watcher 1 and watcher 2.
   EXPECT_THAT(
       watcher_state_1->GetCredentialQueue(),
-      testing::ElementsAre(CredentialInfo(
+      ::testing::ElementsAre(CredentialInfo(
           kRootCert1Contents,
           MakeCertKeyPairs(kIdentityCert1PrivateKey, kIdentityCert1Contents))));
   EXPECT_THAT(
       watcher_state_2->GetCredentialQueue(),
-      testing::ElementsAre(CredentialInfo(
+      ::testing::ElementsAre(CredentialInfo(
           kRootCert2Contents,
           MakeCertKeyPairs(kIdentityCert1PrivateKey, kIdentityCert1Contents))));
   // Cancel watcher 1.
   CancelWatch(watcher_state_1);
-  EXPECT_THAT(GetCallbackQueue(), testing::ElementsAre(CallbackStatus(
+  EXPECT_THAT(GetCallbackQueue(), ::testing::ElementsAre(CallbackStatus(
                                       kRootCert1Name, false, false)));
   // Cancel watcher 2.
   CancelWatch(watcher_state_2);
   EXPECT_THAT(
       GetCallbackQueue(),
-      testing::ElementsAre(CallbackStatus(kRootCert2Name, false, false),
-                           CallbackStatus(kIdentityCert1Name, false, false)));
+      ::testing::ElementsAre(CallbackStatus(kRootCert2Name, false, false),
+                             CallbackStatus(kIdentityCert1Name, false, false)));
 }
 
 TEST_F(GrpcTlsCertificateDistributorTest, SameRootNameDiffIdentityName) {
@@ -346,12 +333,12 @@ TEST_F(GrpcTlsCertificateDistributorTest, SameRootNameDiffIdentityName) {
       MakeWatcher(kRootCert1Name, kIdentityCert1Name);
   EXPECT_THAT(
       GetCallbackQueue(),
-      testing::ElementsAre(CallbackStatus(kRootCert1Name, true, false),
-                           CallbackStatus(kIdentityCert1Name, false, true)));
+      ::testing::ElementsAre(CallbackStatus(kRootCert1Name, true, false),
+                             CallbackStatus(kIdentityCert1Name, false, true)));
   // Register watcher 2.
   WatcherState* watcher_state_2 =
       MakeWatcher(kRootCert1Name, kIdentityCert2Name);
-  EXPECT_THAT(GetCallbackQueue(), testing::ElementsAre(CallbackStatus(
+  EXPECT_THAT(GetCallbackQueue(), ::testing::ElementsAre(CallbackStatus(
                                       kIdentityCert2Name, false, true)));
   // Push credential updates to kRootCert1Name and check if the status works as
   // expected.
@@ -359,10 +346,10 @@ TEST_F(GrpcTlsCertificateDistributorTest, SameRootNameDiffIdentityName) {
                                absl::nullopt);
   // Check the updates are delivered to watcher 1.
   EXPECT_THAT(watcher_state_1->GetCredentialQueue(),
-              testing::ElementsAre(CredentialInfo(kRootCert1Contents, {})));
+              ::testing::ElementsAre(CredentialInfo(kRootCert1Contents, {})));
   // Check the updates are delivered to watcher 2.
   EXPECT_THAT(watcher_state_2->GetCredentialQueue(),
-              testing::ElementsAre(CredentialInfo(kRootCert1Contents, {})));
+              ::testing::ElementsAre(CredentialInfo(kRootCert1Contents, {})));
   // Push credential updates to SetKeyMaterials.
   distributor_.SetKeyMaterials(
       kIdentityCert1Name, absl::nullopt,
@@ -370,7 +357,7 @@ TEST_F(GrpcTlsCertificateDistributorTest, SameRootNameDiffIdentityName) {
   // Check the updates are delivered to watcher 1.
   EXPECT_THAT(
       watcher_state_1->GetCredentialQueue(),
-      testing::ElementsAre(CredentialInfo(
+      ::testing::ElementsAre(CredentialInfo(
           kRootCert1Contents,
           MakeCertKeyPairs(kIdentityCert1PrivateKey, kIdentityCert1Contents))));
   // Push credential updates to kIdentityCert2Name.
@@ -380,19 +367,19 @@ TEST_F(GrpcTlsCertificateDistributorTest, SameRootNameDiffIdentityName) {
   // Check the updates are delivered to watcher 2.
   EXPECT_THAT(
       watcher_state_2->GetCredentialQueue(),
-      testing::ElementsAre(CredentialInfo(
+      ::testing::ElementsAre(CredentialInfo(
           kRootCert1Contents,
           MakeCertKeyPairs(kIdentityCert2PrivateKey, kIdentityCert2Contents))));
   // Cancel watcher 1.
   CancelWatch(watcher_state_1);
-  EXPECT_THAT(GetCallbackQueue(), testing::ElementsAre(CallbackStatus(
+  EXPECT_THAT(GetCallbackQueue(), ::testing::ElementsAre(CallbackStatus(
                                       kIdentityCert1Name, false, false)));
   // Cancel watcher 2.
   CancelWatch(watcher_state_2);
   EXPECT_THAT(
       GetCallbackQueue(),
-      testing::ElementsAre(CallbackStatus(kRootCert1Name, false, false),
-                           CallbackStatus(kIdentityCert2Name, false, false)));
+      ::testing::ElementsAre(CallbackStatus(kRootCert1Name, false, false),
+                             CallbackStatus(kIdentityCert2Name, false, false)));
 }
 
 TEST_F(GrpcTlsCertificateDistributorTest,
@@ -400,7 +387,7 @@ TEST_F(GrpcTlsCertificateDistributorTest,
   // Register watcher 1 watching kCertName1 for both root and identity certs.
   WatcherState* watcher_state_1 = MakeWatcher(kCertName1, kCertName1);
   EXPECT_THAT(GetCallbackQueue(),
-              testing::ElementsAre(CallbackStatus(kCertName1, true, true)));
+              ::testing::ElementsAre(CallbackStatus(kCertName1, true, true)));
   // Push credential updates to kCertName1 and check if the status works as
   // expected.
   distributor_.SetKeyMaterials(
@@ -409,13 +396,13 @@ TEST_F(GrpcTlsCertificateDistributorTest,
   // Check the updates are delivered to watcher 1.
   EXPECT_THAT(
       watcher_state_1->GetCredentialQueue(),
-      testing::ElementsAre(CredentialInfo(
+      ::testing::ElementsAre(CredentialInfo(
           kRootCert1Contents,
           MakeCertKeyPairs(kIdentityCert1PrivateKey, kIdentityCert1Contents))));
   // Cancel watcher 1.
   CancelWatch(watcher_state_1);
   EXPECT_THAT(GetCallbackQueue(),
-              testing::ElementsAre(CallbackStatus(kCertName1, false, false)));
+              ::testing::ElementsAre(CallbackStatus(kCertName1, false, false)));
 }
 
 TEST_F(GrpcTlsCertificateDistributorTest,
@@ -423,11 +410,11 @@ TEST_F(GrpcTlsCertificateDistributorTest,
   // Register watcher 1 watching kCertName1 for root certs.
   WatcherState* watcher_state_1 = MakeWatcher(kCertName1, absl::nullopt);
   EXPECT_THAT(GetCallbackQueue(),
-              testing::ElementsAre(CallbackStatus(kCertName1, true, false)));
+              ::testing::ElementsAre(CallbackStatus(kCertName1, true, false)));
   // Register watcher 2 watching kCertName1 for identity certs.
   WatcherState* watcher_state_2 = MakeWatcher(absl::nullopt, kCertName1);
   EXPECT_THAT(GetCallbackQueue(),
-              testing::ElementsAre(CallbackStatus(kCertName1, true, true)));
+              ::testing::ElementsAre(CallbackStatus(kCertName1, true, true)));
   // Push credential updates to kCertName1 and check if the status works as
   // expected.
   distributor_.SetKeyMaterials(
@@ -435,39 +422,39 @@ TEST_F(GrpcTlsCertificateDistributorTest,
       MakeCertKeyPairs(kIdentityCert1PrivateKey, kIdentityCert1Contents));
   // Check the updates are delivered to watcher 1.
   EXPECT_THAT(watcher_state_1->GetCredentialQueue(),
-              testing::ElementsAre(CredentialInfo(kRootCert1Contents, {})));
+              ::testing::ElementsAre(CredentialInfo(kRootCert1Contents, {})));
   // Check the updates are delivered to watcher 2.
   EXPECT_THAT(watcher_state_2->GetCredentialQueue(),
-              testing::ElementsAre(CredentialInfo(
+              ::testing::ElementsAre(CredentialInfo(
                   "", MakeCertKeyPairs(kIdentityCert1PrivateKey,
                                        kIdentityCert1Contents))));
   // Push root cert updates to kCertName1.
   distributor_.SetKeyMaterials(kCertName1, kRootCert2Contents, absl::nullopt);
   // Check the updates are delivered to watcher 1.
   EXPECT_THAT(watcher_state_1->GetCredentialQueue(),
-              testing::ElementsAre(CredentialInfo(kRootCert2Contents, {})));
+              ::testing::ElementsAre(CredentialInfo(kRootCert2Contents, {})));
   // Check the updates are not delivered to watcher 2.
-  EXPECT_THAT(watcher_state_2->GetCredentialQueue(), testing::ElementsAre());
+  EXPECT_THAT(watcher_state_2->GetCredentialQueue(), ::testing::ElementsAre());
   // Push identity cert updates to kCertName1.
   distributor_.SetKeyMaterials(
       kCertName1, absl::nullopt,
       MakeCertKeyPairs(kIdentityCert2PrivateKey, kIdentityCert2Contents));
   // Check the updates are not delivered to watcher 1.
-  EXPECT_THAT(watcher_state_1->GetCredentialQueue(), testing::ElementsAre());
+  EXPECT_THAT(watcher_state_1->GetCredentialQueue(), ::testing::ElementsAre());
   // Check the updates are delivered to watcher 2.
   EXPECT_THAT(watcher_state_2->GetCredentialQueue(),
-              testing::ElementsAre(CredentialInfo(
+              ::testing::ElementsAre(CredentialInfo(
                   "", MakeCertKeyPairs(kIdentityCert2PrivateKey,
                                        kIdentityCert2Contents))));
   watcher_state_2->cert_update_queue.clear();
   // Cancel watcher 2.
   CancelWatch(watcher_state_2);
   EXPECT_THAT(GetCallbackQueue(),
-              testing::ElementsAre(CallbackStatus(kCertName1, true, false)));
+              ::testing::ElementsAre(CallbackStatus(kCertName1, true, false)));
   // Cancel watcher 1.
   CancelWatch(watcher_state_1);
   EXPECT_THAT(GetCallbackQueue(),
-              testing::ElementsAre(CallbackStatus(kCertName1, false, false)));
+              ::testing::ElementsAre(CallbackStatus(kCertName1, false, false)));
 }
 
 TEST_F(GrpcTlsCertificateDistributorTest,
@@ -475,11 +462,11 @@ TEST_F(GrpcTlsCertificateDistributorTest,
   // Register watcher 1 watching kCertName1 for identity certs.
   WatcherState* watcher_state_1 = MakeWatcher(absl::nullopt, kCertName1);
   EXPECT_THAT(GetCallbackQueue(),
-              testing::ElementsAre(CallbackStatus(kCertName1, false, true)));
+              ::testing::ElementsAre(CallbackStatus(kCertName1, false, true)));
   // Register watcher 2 watching kCertName1 for root certs.
   WatcherState* watcher_state_2 = MakeWatcher(kCertName1, absl::nullopt);
   EXPECT_THAT(GetCallbackQueue(),
-              testing::ElementsAre(CallbackStatus(kCertName1, true, true)));
+              ::testing::ElementsAre(CallbackStatus(kCertName1, true, true)));
   // Push credential updates to kCertName1 and check if the status works as
   // expected.
   distributor_.SetKeyMaterials(
@@ -487,38 +474,38 @@ TEST_F(GrpcTlsCertificateDistributorTest,
       MakeCertKeyPairs(kIdentityCert1PrivateKey, kIdentityCert1Contents));
   // Check the updates are delivered to watcher 1.
   EXPECT_THAT(watcher_state_1->GetCredentialQueue(),
-              testing::ElementsAre(CredentialInfo(
+              ::testing::ElementsAre(CredentialInfo(
                   "", MakeCertKeyPairs(kIdentityCert1PrivateKey,
                                        kIdentityCert1Contents))));
   // Check the updates are delivered to watcher 2.
   EXPECT_THAT(watcher_state_2->GetCredentialQueue(),
-              testing::ElementsAre(CredentialInfo(kRootCert1Contents, {})));
+              ::testing::ElementsAre(CredentialInfo(kRootCert1Contents, {})));
   // Push root cert updates to kCertName1.
   distributor_.SetKeyMaterials(kCertName1, kRootCert2Contents, absl::nullopt);
   // Check the updates are delivered to watcher 2.
   EXPECT_THAT(watcher_state_2->GetCredentialQueue(),
-              testing::ElementsAre(CredentialInfo(kRootCert2Contents, {})));
+              ::testing::ElementsAre(CredentialInfo(kRootCert2Contents, {})));
   // Check the updates are not delivered to watcher 1.
-  EXPECT_THAT(watcher_state_1->GetCredentialQueue(), testing::ElementsAre());
+  EXPECT_THAT(watcher_state_1->GetCredentialQueue(), ::testing::ElementsAre());
   // Push identity cert updates to kCertName1.
   distributor_.SetKeyMaterials(
       kCertName1, absl::nullopt,
       MakeCertKeyPairs(kIdentityCert2PrivateKey, kIdentityCert2Contents));
   // Check the updates are not delivered to watcher 2.
-  EXPECT_THAT(watcher_state_2->GetCredentialQueue(), testing::ElementsAre());
+  EXPECT_THAT(watcher_state_2->GetCredentialQueue(), ::testing::ElementsAre());
   // Check the updates are delivered to watcher 1.
   EXPECT_THAT(watcher_state_1->GetCredentialQueue(),
-              testing::ElementsAre(CredentialInfo(
+              ::testing::ElementsAre(CredentialInfo(
                   "", MakeCertKeyPairs(kIdentityCert2PrivateKey,
                                        kIdentityCert2Contents))));
   // Cancel watcher 2.
   CancelWatch(watcher_state_2);
   EXPECT_THAT(GetCallbackQueue(),
-              testing::ElementsAre(CallbackStatus(kCertName1, false, true)));
+              ::testing::ElementsAre(CallbackStatus(kCertName1, false, true)));
   // Cancel watcher 1.
   CancelWatch(watcher_state_1);
   EXPECT_THAT(GetCallbackQueue(),
-              testing::ElementsAre(CallbackStatus(kCertName1, false, false)));
+              ::testing::ElementsAre(CallbackStatus(kCertName1, false, false)));
 }
 
 TEST_F(GrpcTlsCertificateDistributorTest,
@@ -527,24 +514,24 @@ TEST_F(GrpcTlsCertificateDistributorTest,
   // certs.
   WatcherState* watcher_state_1 = MakeWatcher(kCertName1, kCertName1);
   EXPECT_THAT(GetCallbackQueue(),
-              testing::ElementsAre(CallbackStatus(kCertName1, true, true)));
+              ::testing::ElementsAre(CallbackStatus(kCertName1, true, true)));
   WatcherState* watcher_state_2 = MakeWatcher(kCertName1, kCertName1);
-  EXPECT_THAT(GetCallbackQueue(), testing::ElementsAre());
+  EXPECT_THAT(GetCallbackQueue(), ::testing::ElementsAre());
   // Push credential updates to kCertName1.
   distributor_.SetKeyMaterials(
       kCertName1, kRootCert1Contents,
       MakeCertKeyPairs(kIdentityCert1PrivateKey, kIdentityCert1Contents));
   // Cancel watcher 2.
   CancelWatch(watcher_state_2);
-  EXPECT_THAT(GetCallbackQueue(), testing::ElementsAre());
+  EXPECT_THAT(GetCallbackQueue(), ::testing::ElementsAre());
   // Cancel watcher 1.
   CancelWatch(watcher_state_1);
   EXPECT_THAT(GetCallbackQueue(),
-              testing::ElementsAre(CallbackStatus(kCertName1, false, false)));
+              ::testing::ElementsAre(CallbackStatus(kCertName1, false, false)));
   // Register watcher 3 watching kCertName for root and identity certs.
   WatcherState* watcher_state_3 = MakeWatcher(kCertName1, kCertName1);
   EXPECT_THAT(GetCallbackQueue(),
-              testing::ElementsAre(CallbackStatus(kCertName1, true, true)));
+              ::testing::ElementsAre(CallbackStatus(kCertName1, true, true)));
   // Push credential updates to kCertName1.
   distributor_.SetKeyMaterials(
       kCertName1, kRootCert2Contents,
@@ -552,25 +539,25 @@ TEST_F(GrpcTlsCertificateDistributorTest,
   // Check the updates are delivered to watcher 3.
   EXPECT_THAT(
       watcher_state_3->GetCredentialQueue(),
-      testing::ElementsAre(CredentialInfo(
+      ::testing::ElementsAre(CredentialInfo(
           kRootCert2Contents,
           MakeCertKeyPairs(kIdentityCert2PrivateKey, kIdentityCert2Contents))));
   // Cancel watcher 3.
   CancelWatch(watcher_state_3);
   EXPECT_THAT(GetCallbackQueue(),
-              testing::ElementsAre(CallbackStatus(kCertName1, false, false)));
+              ::testing::ElementsAre(CallbackStatus(kCertName1, false, false)));
 }
 
 TEST_F(GrpcTlsCertificateDistributorTest, ResetCallbackToNull) {
   // Register watcher 1 watching kCertName1 for root and identity certs.
   WatcherState* watcher_state_1 = MakeWatcher(kCertName1, kCertName1);
   EXPECT_THAT(GetCallbackQueue(),
-              testing::ElementsAre(CallbackStatus(kCertName1, true, true)));
+              ::testing::ElementsAre(CallbackStatus(kCertName1, true, true)));
   // Reset callback to nullptr.
   distributor_.SetWatchStatusCallback(nullptr);
   // Cancel watcher 1 shouldn't trigger any callback.
   CancelWatch(watcher_state_1);
-  EXPECT_THAT(GetCallbackQueue(), testing::ElementsAre());
+  EXPECT_THAT(GetCallbackQueue(), ::testing::ElementsAre());
 }
 
 TEST_F(GrpcTlsCertificateDistributorTest, SetKeyMaterialsInCallback) {
@@ -586,7 +573,7 @@ TEST_F(GrpcTlsCertificateDistributorTest, SetKeyMaterialsInCallback) {
     // Check the updates are delivered to watcher 1.
     EXPECT_THAT(
         watcher_state_1->GetCredentialQueue(),
-        testing::ElementsAre(CredentialInfo(
+        ::testing::ElementsAre(CredentialInfo(
             kRootCert1Contents, MakeCertKeyPairs(kIdentityCert1PrivateKey,
                                                  kIdentityCert1Contents))));
     CancelWatch(watcher_state_1);
@@ -621,7 +608,7 @@ TEST_F(GrpcTlsCertificateDistributorTest, WatchACertInfoWithValidCredentials) {
   // watcher 1 should receive the credentials right away.
   EXPECT_THAT(
       watcher_state_1->GetCredentialQueue(),
-      testing::ElementsAre(CredentialInfo(
+      ::testing::ElementsAre(CredentialInfo(
           kRootCert1Contents,
           MakeCertKeyPairs(kIdentityCert1PrivateKey, kIdentityCert1Contents))));
   CancelWatch(watcher_state_1);
@@ -629,13 +616,13 @@ TEST_F(GrpcTlsCertificateDistributorTest, WatchACertInfoWithValidCredentials) {
   WatcherState* watcher_state_2 = MakeWatcher(kRootCert2Name, absl::nullopt);
   // watcher 2 should receive the root credentials right away.
   EXPECT_THAT(watcher_state_2->GetCredentialQueue(),
-              testing::ElementsAre(CredentialInfo(kRootCert2Contents, {})));
+              ::testing::ElementsAre(CredentialInfo(kRootCert2Contents, {})));
   // Register watcher 3.
   WatcherState* watcher_state_3 =
       MakeWatcher(absl::nullopt, kIdentityCert2Name);
   // watcher 3 should received the identity credentials right away.
   EXPECT_THAT(watcher_state_3->GetCredentialQueue(),
-              testing::ElementsAre(CredentialInfo(
+              ::testing::ElementsAre(CredentialInfo(
                   "", MakeCertKeyPairs(kIdentityCert2PrivateKey,
                                        kIdentityCert2Contents))));
   CancelWatch(watcher_state_2);
@@ -652,7 +639,7 @@ TEST_F(GrpcTlsCertificateDistributorTest,
       kCertName1, GRPC_ERROR_CREATE_FROM_STATIC_STRING(kRootErrorMessage),
       GRPC_ERROR_CREATE_FROM_STATIC_STRING(kIdentityErrorMessage));
   EXPECT_THAT(watcher_state_1->GetErrorQueue(),
-              testing::ElementsAre(
+              ::testing::ElementsAre(
                   ErrorInfo(kRootErrorMessage, kIdentityErrorMessage)));
   // Calling SetErrorForCert on root cert name should call OnError
   // on watcher 1 again.
@@ -661,14 +648,14 @@ TEST_F(GrpcTlsCertificateDistributorTest,
       absl::nullopt);
   EXPECT_THAT(
       watcher_state_1->GetErrorQueue(),
-      testing::ElementsAre(ErrorInfo(kErrorMessage, kIdentityErrorMessage)));
+      ::testing::ElementsAre(ErrorInfo(kErrorMessage, kIdentityErrorMessage)));
   // Calling SetErrorForCert on identity cert name should call OnError
   // on watcher 1 again.
   distributor_.SetErrorForCert(
       kCertName1, absl::nullopt,
       GRPC_ERROR_CREATE_FROM_STATIC_STRING(kErrorMessage));
   EXPECT_THAT(watcher_state_1->GetErrorQueue(),
-              testing::ElementsAre(ErrorInfo(kErrorMessage, kErrorMessage)));
+              ::testing::ElementsAre(ErrorInfo(kErrorMessage, kErrorMessage)));
   distributor_.CancelTlsCertificatesWatch(watcher_state_1->watcher);
   EXPECT_EQ(watcher_state_1->watcher, nullptr);
 }
@@ -682,18 +669,18 @@ TEST_F(GrpcTlsCertificateDistributorTest, SetErrorForCertForRootOrIdentity) {
       kCertName1, GRPC_ERROR_CREATE_FROM_STATIC_STRING(kRootErrorMessage),
       absl::nullopt);
   EXPECT_THAT(watcher_state_1->GetErrorQueue(),
-              testing::ElementsAre(ErrorInfo(kRootErrorMessage, "")));
+              ::testing::ElementsAre(ErrorInfo(kRootErrorMessage, "")));
   // Calling SetErrorForCert on identity name should do nothing.
   distributor_.SetErrorForCert(
       kCertName1, absl::nullopt,
       GRPC_ERROR_CREATE_FROM_STATIC_STRING(kIdentityErrorMessage));
-  EXPECT_THAT(watcher_state_1->GetErrorQueue(), testing::ElementsAre());
+  EXPECT_THAT(watcher_state_1->GetErrorQueue(), ::testing::ElementsAre());
   // Calling SetErrorForCert on both names should still get one OnError call.
   distributor_.SetErrorForCert(
       kCertName1, GRPC_ERROR_CREATE_FROM_STATIC_STRING(kRootErrorMessage),
       GRPC_ERROR_CREATE_FROM_STATIC_STRING(kIdentityErrorMessage));
   EXPECT_THAT(watcher_state_1->GetErrorQueue(),
-              testing::ElementsAre(ErrorInfo(kRootErrorMessage, "")));
+              ::testing::ElementsAre(ErrorInfo(kRootErrorMessage, "")));
   CancelWatch(watcher_state_1);
   // Register watcher 2.
   WatcherState* watcher_state_2 = MakeWatcher(absl::nullopt, kCertName1);
@@ -703,18 +690,18 @@ TEST_F(GrpcTlsCertificateDistributorTest, SetErrorForCertForRootOrIdentity) {
       kCertName1, absl::nullopt,
       GRPC_ERROR_CREATE_FROM_STATIC_STRING(kIdentityErrorMessage));
   EXPECT_THAT(watcher_state_2->GetErrorQueue(),
-              testing::ElementsAre(ErrorInfo("", kIdentityErrorMessage)));
+              ::testing::ElementsAre(ErrorInfo("", kIdentityErrorMessage)));
   // Calling SetErrorForCert on root name should do nothing.
   distributor_.SetErrorForCert(
       kCertName1, GRPC_ERROR_CREATE_FROM_STATIC_STRING(kRootErrorMessage),
       absl::nullopt);
-  EXPECT_THAT(watcher_state_2->GetErrorQueue(), testing::ElementsAre());
+  EXPECT_THAT(watcher_state_2->GetErrorQueue(), ::testing::ElementsAre());
   // Calling SetErrorForCert on both names should still get one OnError call.
   distributor_.SetErrorForCert(
       kCertName1, GRPC_ERROR_CREATE_FROM_STATIC_STRING(kRootErrorMessage),
       GRPC_ERROR_CREATE_FROM_STATIC_STRING(kIdentityErrorMessage));
   EXPECT_THAT(watcher_state_2->GetErrorQueue(),
-              testing::ElementsAre(ErrorInfo("", kIdentityErrorMessage)));
+              ::testing::ElementsAre(ErrorInfo("", kIdentityErrorMessage)));
   CancelWatch(watcher_state_2);
 }
 
@@ -728,14 +715,14 @@ TEST_F(GrpcTlsCertificateDistributorTest,
   WatcherState* watcher_state_1 = MakeWatcher(kCertName1, kCertName2);
   // Should trigger OnError call right away since kCertName1 has error.
   EXPECT_THAT(watcher_state_1->GetErrorQueue(),
-              testing::ElementsAre(ErrorInfo(kRootErrorMessage, "")));
+              ::testing::ElementsAre(ErrorInfo(kRootErrorMessage, "")));
   // Calling SetErrorForCert on kCertName2 should trigger OnError with both
   // errors, because kCertName1 also has error.
   distributor_.SetErrorForCert(
       kCertName2, absl::nullopt,
       GRPC_ERROR_CREATE_FROM_STATIC_STRING(kIdentityErrorMessage));
   EXPECT_THAT(watcher_state_1->GetErrorQueue(),
-              testing::ElementsAre(
+              ::testing::ElementsAre(
                   ErrorInfo(kRootErrorMessage, kIdentityErrorMessage)));
   CancelWatch(watcher_state_1);
 }
@@ -750,14 +737,14 @@ TEST_F(GrpcTlsCertificateDistributorTest,
   WatcherState* watcher_state_1 = MakeWatcher(kCertName2, kCertName1);
   // Should trigger OnError call right away since kCertName2 has error.
   EXPECT_THAT(watcher_state_1->GetErrorQueue(),
-              testing::ElementsAre(ErrorInfo("", kIdentityErrorMessage)));
+              ::testing::ElementsAre(ErrorInfo("", kIdentityErrorMessage)));
   // Calling SetErrorForCert on kCertName2 should trigger OnError with both
   // errors, because kCertName1 also has error.
   distributor_.SetErrorForCert(
       kCertName2, GRPC_ERROR_CREATE_FROM_STATIC_STRING(kRootErrorMessage),
       absl::nullopt);
   EXPECT_THAT(watcher_state_1->GetErrorQueue(),
-              testing::ElementsAre(
+              ::testing::ElementsAre(
                   ErrorInfo(kRootErrorMessage, kIdentityErrorMessage)));
   CancelWatch(watcher_state_1);
 }
@@ -767,25 +754,25 @@ TEST_F(GrpcTlsCertificateDistributorTest,
   // Register watcher 1 for kCertName1 as root and kCertName2 as identity.
   WatcherState* watcher_state_1 = MakeWatcher(kCertName1, kCertName2);
   // Should not trigger OnError.
-  EXPECT_THAT(watcher_state_1->GetErrorQueue(), testing::ElementsAre());
+  EXPECT_THAT(watcher_state_1->GetErrorQueue(), ::testing::ElementsAre());
   // Calling SetErrorForCert on kCertName2 should trigger OnError.
   distributor_.SetErrorForCert(
       kCertName2, absl::nullopt,
       GRPC_ERROR_CREATE_FROM_STATIC_STRING(kIdentityErrorMessage));
   EXPECT_THAT(watcher_state_1->GetErrorQueue(),
-              testing::ElementsAre(ErrorInfo("", kIdentityErrorMessage)));
+              ::testing::ElementsAre(ErrorInfo("", kIdentityErrorMessage)));
   CancelWatch(watcher_state_1);
   // Register watcher 2 for kCertName2 as identity and a non-existing name
   // kRootCert1Name as root.
   WatcherState* watcher_state_2 = MakeWatcher(kRootCert1Name, kCertName2);
   // Should not trigger OnError.
-  EXPECT_THAT(watcher_state_2->GetErrorQueue(), testing::ElementsAre());
+  EXPECT_THAT(watcher_state_2->GetErrorQueue(), ::testing::ElementsAre());
   // Calling SetErrorForCert on kCertName2 should trigger OnError.
   distributor_.SetErrorForCert(
       kCertName2, absl::nullopt,
       GRPC_ERROR_CREATE_FROM_STATIC_STRING(kIdentityErrorMessage));
   EXPECT_THAT(watcher_state_2->error_queue,
-              testing::ElementsAre(ErrorInfo("", kIdentityErrorMessage)));
+              ::testing::ElementsAre(ErrorInfo("", kIdentityErrorMessage)));
   CancelWatch(watcher_state_2);
 }
 
@@ -793,25 +780,25 @@ TEST_F(GrpcTlsCertificateDistributorTest,
        SetErrorForRootNameWithPreexistingErrorForIdentityName) {
   WatcherState* watcher_state_1 = MakeWatcher(kCertName2, kCertName1);
   // Should not trigger OnError.
-  EXPECT_THAT(watcher_state_1->GetErrorQueue(), testing::ElementsAre());
+  EXPECT_THAT(watcher_state_1->GetErrorQueue(), ::testing::ElementsAre());
   // Calling SetErrorForCert on kCertName2 should trigger OnError.
   distributor_.SetErrorForCert(
       kCertName2, GRPC_ERROR_CREATE_FROM_STATIC_STRING(kRootErrorMessage),
       absl::nullopt);
   EXPECT_THAT(watcher_state_1->GetErrorQueue(),
-              testing::ElementsAre(ErrorInfo(kRootErrorMessage, "")));
+              ::testing::ElementsAre(ErrorInfo(kRootErrorMessage, "")));
   CancelWatch(watcher_state_1);
   // Register watcher 2 for kCertName2 as root and a non-existing name
   // kIdentityCert1Name as identity.
   WatcherState* watcher_state_2 = MakeWatcher(kCertName2, kIdentityCert1Name);
   // Should not trigger OnError.
-  EXPECT_THAT(watcher_state_2->GetErrorQueue(), testing::ElementsAre());
+  EXPECT_THAT(watcher_state_2->GetErrorQueue(), ::testing::ElementsAre());
   // Calling SetErrorForCert on kCertName2 should trigger OnError.
   distributor_.SetErrorForCert(
       kCertName2, GRPC_ERROR_CREATE_FROM_STATIC_STRING(kRootErrorMessage),
       absl::nullopt);
   EXPECT_THAT(watcher_state_2->GetErrorQueue(),
-              testing::ElementsAre(ErrorInfo(kRootErrorMessage, "")));
+              ::testing::ElementsAre(ErrorInfo(kRootErrorMessage, "")));
   CancelWatch(watcher_state_2);
 }
 
@@ -825,14 +812,14 @@ TEST_F(GrpcTlsCertificateDistributorTest,
       kCertName1, GRPC_ERROR_CREATE_FROM_STATIC_STRING(kRootErrorMessage),
       GRPC_ERROR_CREATE_FROM_STATIC_STRING(kIdentityErrorMessage));
   EXPECT_THAT(watcher_state_1->GetErrorQueue(),
-              testing::ElementsAre(
+              ::testing::ElementsAre(
                   ErrorInfo(kRootErrorMessage, kIdentityErrorMessage)));
   // When watcher 1 is removed, the cert info entry should be removed.
   CancelWatch(watcher_state_1);
   // Register watcher 2 on the same cert name.
   WatcherState* watcher_state_2 = MakeWatcher(kCertName1, kCertName1);
   // Should not trigger OnError call on watcher 2 right away.
-  EXPECT_THAT(watcher_state_2->GetErrorQueue(), testing::ElementsAre());
+  EXPECT_THAT(watcher_state_2->GetErrorQueue(), ::testing::ElementsAre());
   CancelWatch(watcher_state_2);
 }
 
@@ -851,11 +838,11 @@ TEST_F(GrpcTlsCertificateDistributorTest,
   // watcher 1 should receive both the old credentials and the error right away.
   EXPECT_THAT(
       watcher_state_1->GetCredentialQueue(),
-      testing::ElementsAre(CredentialInfo(
+      ::testing::ElementsAre(CredentialInfo(
           kRootCert1Contents,
           MakeCertKeyPairs(kIdentityCert1PrivateKey, kIdentityCert1Contents))));
   EXPECT_THAT(watcher_state_1->GetErrorQueue(),
-              testing::ElementsAre(
+              ::testing::ElementsAre(
                   ErrorInfo(kRootErrorMessage, kIdentityErrorMessage)));
   CancelWatch(watcher_state_1);
 }
@@ -876,10 +863,10 @@ TEST_F(GrpcTlsCertificateDistributorTest,
   // the previous error is wiped out by a successful update.
   EXPECT_THAT(
       watcher_state_1->GetCredentialQueue(),
-      testing::ElementsAre(CredentialInfo(
+      ::testing::ElementsAre(CredentialInfo(
           kRootCert1Contents,
           MakeCertKeyPairs(kIdentityCert1PrivateKey, kIdentityCert1Contents))));
-  EXPECT_THAT(watcher_state_1->GetErrorQueue(), testing::ElementsAre());
+  EXPECT_THAT(watcher_state_1->GetErrorQueue(), ::testing::ElementsAre());
   CancelWatch(watcher_state_1);
 }
 
@@ -893,11 +880,11 @@ TEST_F(GrpcTlsCertificateDistributorTest, WatchCertInfoThenInvokeSetError) {
       MakeWatcher(absl::nullopt, kIdentityCert1Name);
   distributor_.SetError(GRPC_ERROR_CREATE_FROM_STATIC_STRING(kErrorMessage));
   EXPECT_THAT(watcher_state_1->GetErrorQueue(),
-              testing::ElementsAre(ErrorInfo(kErrorMessage, kErrorMessage)));
+              ::testing::ElementsAre(ErrorInfo(kErrorMessage, kErrorMessage)));
   EXPECT_THAT(watcher_state_2->GetErrorQueue(),
-              testing::ElementsAre(ErrorInfo(kErrorMessage, "")));
+              ::testing::ElementsAre(ErrorInfo(kErrorMessage, "")));
   EXPECT_THAT(watcher_state_3->GetErrorQueue(),
-              testing::ElementsAre(ErrorInfo("", kErrorMessage)));
+              ::testing::ElementsAre(ErrorInfo("", kErrorMessage)));
   CancelWatch(watcher_state_1);
   CancelWatch(watcher_state_2);
   CancelWatch(watcher_state_3);
@@ -915,12 +902,12 @@ TEST_F(GrpcTlsCertificateDistributorTest, WatchErroredCertInfoBySetError) {
   // Register watcher 3 watching kCertName1 as root and kCertName2 as identity
   // should not get the error updates.
   WatcherState* watcher_state_3 = MakeWatcher(kCertName1, kCertName2);
-  EXPECT_THAT(watcher_state_3->GetErrorQueue(), testing::ElementsAre());
+  EXPECT_THAT(watcher_state_3->GetErrorQueue(), ::testing::ElementsAre());
   CancelWatch(watcher_state_3);
   // Register watcher 4 watching kCertName2 as root and kCertName1 as identity
   // should not get the error updates.
   WatcherState* watcher_state_4 = MakeWatcher(kCertName2, kCertName1);
-  EXPECT_THAT(watcher_state_4->GetErrorQueue(), testing::ElementsAre());
+  EXPECT_THAT(watcher_state_4->GetErrorQueue(), ::testing::ElementsAre());
   CancelWatch(watcher_state_4);
 }
 
@@ -936,7 +923,7 @@ TEST_F(GrpcTlsCertificateDistributorTest, SetErrorForCertInCallback) {
     WatcherState* watcher_state_1 = MakeWatcher(cert_name, cert_name);
     // Check the errors are delivered to watcher 1.
     EXPECT_THAT(watcher_state_1->GetErrorQueue(),
-                testing::ElementsAre(
+                ::testing::ElementsAre(
                     ErrorInfo(kRootErrorMessage, kIdentityErrorMessage)));
     CancelWatch(watcher_state_1);
   };
@@ -955,6 +942,8 @@ TEST_F(GrpcTlsCertificateDistributorTest, SetErrorForCertInCallback) {
 
 }  // namespace testing
 
+}  // namespace grpc_core
+
 int main(int argc, char** argv) {
   grpc::testing::TestEnvironment env(argc, argv);
   ::testing::InitGoogleTest(&argc, argv);
diff --git a/test/core/security/grpc_tls_certificate_provider_test.cc b/test/core/security/grpc_tls_certificate_provider_test.cc
new file mode 100644 (file)
index 0000000..5055357
--- /dev/null
@@ -0,0 +1,509 @@
+//
+// 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 "src/core/lib/security/credentials/tls/grpc_tls_certificate_provider.h"
+
+#include <gmock/gmock.h>
+
+#include <grpc/support/alloc.h>
+#include <grpc/support/log.h>
+#include <grpc/support/string_util.h>
+#include <gtest/gtest.h>
+
+#include <deque>
+#include <list>
+
+#include "src/core/lib/gpr/tmpfile.h"
+#include "src/core/lib/iomgr/load_file.h"
+#include "src/core/lib/slice/slice_internal.h"
+#include "test/core/util/test_config.h"
+#include "test/core/util/tls_utils.h"
+
+#define CA_CERT_PATH "src/core/tsi/test_creds/ca.pem"
+#define SERVER_CERT_PATH "src/core/tsi/test_creds/server1.pem"
+#define SERVER_KEY_PATH "src/core/tsi/test_creds/server1.key"
+#define CA_CERT_PATH_2 "src/core/tsi/test_creds/multi-domain.pem"
+#define SERVER_CERT_PATH_2 "src/core/tsi/test_creds/server0.pem"
+#define SERVER_KEY_PATH_2 "src/core/tsi/test_creds/server0.key"
+#define INVALID_PATH "invalid/path"
+
+namespace grpc_core {
+
+namespace testing {
+
+constexpr const char* kCertName = "cert_name";
+constexpr const char* kRootError = "Unable to get latest root certificates.";
+constexpr const char* kIdentityError =
+    "Unable to get latest identity certificates.";
+
+class GrpcTlsCertificateProviderTest : public ::testing::Test {
+ protected:
+  // Forward declaration.
+  class TlsCertificatesTestWatcher;
+
+  // CredentialInfo contains the parameters when calling OnCertificatesChanged
+  // of a watcher. When OnCertificatesChanged is invoked, we will push a
+  // CredentialInfo to the cert_update_queue of state_, and check in each test
+  // if the status updates are correct.
+  struct CredentialInfo {
+    std::string root_certs;
+    PemKeyCertPairList key_cert_pairs;
+    CredentialInfo(std::string root, PemKeyCertPairList key_cert)
+        : root_certs(std::move(root)), key_cert_pairs(std::move(key_cert)) {}
+    bool operator==(const CredentialInfo& other) const {
+      return root_certs == other.root_certs &&
+             key_cert_pairs == other.key_cert_pairs;
+    }
+  };
+
+  // ErrorInfo contains the parameters when calling OnError of a watcher. When
+  // OnError is invoked, we will push a ErrorInfo to the error_queue of state_,
+  // and check in each test if the status updates are correct.
+  struct ErrorInfo {
+    std::string root_cert_str;
+    std::string identity_cert_str;
+    ErrorInfo(std::string root, std::string identity)
+        : root_cert_str(std::move(root)),
+          identity_cert_str(std::move(identity)) {}
+    bool operator==(const ErrorInfo& other) const {
+      return root_cert_str == other.root_cert_str &&
+             identity_cert_str == other.identity_cert_str;
+    }
+  };
+
+  struct WatcherState {
+    TlsCertificatesTestWatcher* watcher = nullptr;
+    std::deque<CredentialInfo> cert_update_queue;
+    std::deque<ErrorInfo> error_queue;
+    Mutex mu;
+
+    std::deque<CredentialInfo> GetCredentialQueue() {
+      // We move the data member value so the data member will be re-initiated
+      // with size 0, and ready for the next check.
+      MutexLock lock(&mu);
+      return std::move(cert_update_queue);
+    }
+    std::deque<ErrorInfo> GetErrorQueue() {
+      // We move the data member value so the data member will be re-initiated
+      // with size 0, and ready for the next check.
+      MutexLock lock(&mu);
+      return std::move(error_queue);
+    }
+  };
+
+  class TlsCertificatesTestWatcher : public grpc_tls_certificate_distributor::
+                                         TlsCertificatesWatcherInterface {
+   public:
+    // ctor sets state->watcher to this.
+    explicit TlsCertificatesTestWatcher(WatcherState* state) : state_(state) {
+      state_->watcher = this;
+    }
+
+    // dtor sets state->watcher to nullptr.
+    ~TlsCertificatesTestWatcher() override { state_->watcher = nullptr; }
+
+    void OnCertificatesChanged(
+        absl::optional<absl::string_view> root_certs,
+        absl::optional<PemKeyCertPairList> key_cert_pairs) override {
+      MutexLock lock(&state_->mu);
+      std::string updated_root;
+      if (root_certs.has_value()) {
+        updated_root = std::string(*root_certs);
+      }
+      PemKeyCertPairList updated_identity;
+      if (key_cert_pairs.has_value()) {
+        updated_identity = std::move(*key_cert_pairs);
+      }
+      state_->cert_update_queue.emplace_back(std::move(updated_root),
+                                             std::move(updated_identity));
+    }
+
+    void OnError(grpc_error* root_cert_error,
+                 grpc_error* identity_cert_error) override {
+      MutexLock lock(&state_->mu);
+      GPR_ASSERT(root_cert_error != GRPC_ERROR_NONE ||
+                 identity_cert_error != GRPC_ERROR_NONE);
+      std::string root_error_str;
+      std::string identity_error_str;
+      if (root_cert_error != GRPC_ERROR_NONE) {
+        grpc_slice root_error_slice;
+        GPR_ASSERT(grpc_error_get_str(
+            root_cert_error, GRPC_ERROR_STR_DESCRIPTION, &root_error_slice));
+        root_error_str = std::string(StringViewFromSlice(root_error_slice));
+      }
+      if (identity_cert_error != GRPC_ERROR_NONE) {
+        grpc_slice identity_error_slice;
+        GPR_ASSERT(grpc_error_get_str(identity_cert_error,
+                                      GRPC_ERROR_STR_DESCRIPTION,
+                                      &identity_error_slice));
+        identity_error_str =
+            std::string(StringViewFromSlice(identity_error_slice));
+      }
+      state_->error_queue.emplace_back(std::move(root_error_str),
+                                       std::move(identity_error_str));
+      GRPC_ERROR_UNREF(root_cert_error);
+      GRPC_ERROR_UNREF(identity_cert_error);
+    }
+
+   private:
+    WatcherState* state_;
+  };
+
+  void SetUp() override {
+    root_cert_ = GetFileContents(CA_CERT_PATH);
+    cert_chain_ = GetFileContents(SERVER_CERT_PATH);
+    private_key_ = GetFileContents(SERVER_KEY_PATH);
+    root_cert_2_ = GetFileContents(CA_CERT_PATH_2);
+    cert_chain_2_ = GetFileContents(SERVER_CERT_PATH_2);
+    private_key_2_ = GetFileContents(SERVER_KEY_PATH_2);
+  }
+
+  WatcherState* MakeWatcher(
+      RefCountedPtr<grpc_tls_certificate_distributor> distributor,
+      absl::optional<std::string> root_cert_name,
+      absl::optional<std::string> identity_cert_name) {
+    MutexLock lock(&mu_);
+    distributor_ = distributor;
+    watchers_.emplace_back();
+    // TlsCertificatesTestWatcher ctor takes a pointer to the WatcherState.
+    // It sets WatcherState::watcher to point to itself.
+    // The TlsCertificatesTestWatcher dtor will set WatcherState::watcher back
+    // to nullptr to indicate that it's been destroyed.
+    auto watcher =
+        absl::make_unique<TlsCertificatesTestWatcher>(&watchers_.back());
+    distributor_->WatchTlsCertificates(std::move(watcher),
+                                       std::move(root_cert_name),
+                                       std::move(identity_cert_name));
+    return &watchers_.back();
+  }
+
+  void CancelWatch(WatcherState* state) {
+    MutexLock lock(&mu_);
+    distributor_->CancelTlsCertificatesWatch(state->watcher);
+    EXPECT_EQ(state->watcher, nullptr);
+  }
+
+  std::string root_cert_;
+  std::string private_key_;
+  std::string cert_chain_;
+  std::string root_cert_2_;
+  std::string private_key_2_;
+  std::string cert_chain_2_;
+  RefCountedPtr<grpc_tls_certificate_distributor> distributor_;
+  // Use a std::list<> here to avoid the address invalidation caused by internal
+  // reallocation of std::vector<>.
+  std::list<WatcherState> watchers_;
+  // This is to make watchers_ thread-safe.
+  Mutex mu_;
+};
+
+TEST_F(GrpcTlsCertificateProviderTest, StaticDataCertificateProviderCreation) {
+  StaticDataCertificateProvider provider(
+      root_cert_, MakeCertKeyPairs(private_key_.c_str(), cert_chain_.c_str()));
+  // Watcher watching both root and identity certs.
+  WatcherState* watcher_state_1 =
+      MakeWatcher(provider.distributor(), kCertName, kCertName);
+  EXPECT_THAT(watcher_state_1->GetCredentialQueue(),
+              ::testing::ElementsAre(CredentialInfo(
+                  root_cert_, MakeCertKeyPairs(private_key_.c_str(),
+                                               cert_chain_.c_str()))));
+  CancelWatch(watcher_state_1);
+  // Watcher watching only root certs.
+  WatcherState* watcher_state_2 =
+      MakeWatcher(provider.distributor(), kCertName, absl::nullopt);
+  EXPECT_THAT(watcher_state_2->GetCredentialQueue(),
+              ::testing::ElementsAre(CredentialInfo(root_cert_, {})));
+  CancelWatch(watcher_state_2);
+  // Watcher watching only identity certs.
+  WatcherState* watcher_state_3 =
+      MakeWatcher(provider.distributor(), absl::nullopt, kCertName);
+  EXPECT_THAT(
+      watcher_state_3->GetCredentialQueue(),
+      ::testing::ElementsAre(CredentialInfo(
+          "", MakeCertKeyPairs(private_key_.c_str(), cert_chain_.c_str()))));
+  CancelWatch(watcher_state_3);
+}
+
+TEST_F(GrpcTlsCertificateProviderTest,
+       FileWatcherCertificateProviderWithGoodPaths) {
+  FileWatcherCertificateProvider provider(SERVER_KEY_PATH, SERVER_CERT_PATH,
+                                          CA_CERT_PATH, 1);
+  // Watcher watching both root and identity certs.
+  WatcherState* watcher_state_1 =
+      MakeWatcher(provider.distributor(), kCertName, kCertName);
+  EXPECT_THAT(watcher_state_1->GetCredentialQueue(),
+              ::testing::ElementsAre(CredentialInfo(
+                  root_cert_, MakeCertKeyPairs(private_key_.c_str(),
+                                               cert_chain_.c_str()))));
+  CancelWatch(watcher_state_1);
+  // Watcher watching only root certs.
+  WatcherState* watcher_state_2 =
+      MakeWatcher(provider.distributor(), kCertName, absl::nullopt);
+  EXPECT_THAT(watcher_state_2->GetCredentialQueue(),
+              ::testing::ElementsAre(CredentialInfo(root_cert_, {})));
+  CancelWatch(watcher_state_2);
+  // Watcher watching only identity certs.
+  WatcherState* watcher_state_3 =
+      MakeWatcher(provider.distributor(), absl::nullopt, kCertName);
+  EXPECT_THAT(
+      watcher_state_3->GetCredentialQueue(),
+      ::testing::ElementsAre(CredentialInfo(
+          "", MakeCertKeyPairs(private_key_.c_str(), cert_chain_.c_str()))));
+  CancelWatch(watcher_state_3);
+}
+
+TEST_F(GrpcTlsCertificateProviderTest,
+       FileWatcherCertificateProviderWithBadPaths) {
+  FileWatcherCertificateProvider provider(INVALID_PATH, INVALID_PATH,
+                                          INVALID_PATH, 1);
+  // Watcher watching both root and identity certs.
+  WatcherState* watcher_state_1 =
+      MakeWatcher(provider.distributor(), kCertName, kCertName);
+  EXPECT_THAT(watcher_state_1->GetErrorQueue(),
+              ::testing::ElementsAre(ErrorInfo(kRootError, kIdentityError)));
+  EXPECT_THAT(watcher_state_1->GetCredentialQueue(), ::testing::ElementsAre());
+  CancelWatch(watcher_state_1);
+  // Watcher watching only root certs.
+  WatcherState* watcher_state_2 =
+      MakeWatcher(provider.distributor(), kCertName, absl::nullopt);
+  EXPECT_THAT(watcher_state_2->GetErrorQueue(),
+              ::testing::ElementsAre(ErrorInfo(kRootError, "")));
+  EXPECT_THAT(watcher_state_2->GetCredentialQueue(), ::testing::ElementsAre());
+  CancelWatch(watcher_state_2);
+  // Watcher watching only identity certs.
+  WatcherState* watcher_state_3 =
+      MakeWatcher(provider.distributor(), absl::nullopt, kCertName);
+  EXPECT_THAT(watcher_state_3->GetErrorQueue(),
+              ::testing::ElementsAre(ErrorInfo("", kIdentityError)));
+  EXPECT_THAT(watcher_state_3->GetCredentialQueue(), ::testing::ElementsAre());
+  CancelWatch(watcher_state_3);
+}
+
+// The following tests write credential data to temporary files to test the
+// transition behavior of the provider.
+TEST_F(GrpcTlsCertificateProviderTest,
+       FileWatcherCertificateProviderOnBothCertsRefreshed) {
+  // Create temporary files and copy cert data into them.
+  TmpFile tmp_root_cert(root_cert_);
+  TmpFile tmp_identity_key(private_key_);
+  TmpFile tmp_identity_cert(cert_chain_);
+  // Create FileWatcherCertificateProvider.
+  FileWatcherCertificateProvider provider(tmp_identity_key.name(),
+                                          tmp_identity_cert.name(),
+                                          tmp_root_cert.name(), 1);
+  WatcherState* watcher_state_1 =
+      MakeWatcher(provider.distributor(), kCertName, kCertName);
+  // Expect to see the credential data.
+  EXPECT_THAT(watcher_state_1->GetCredentialQueue(),
+              ::testing::ElementsAre(CredentialInfo(
+                  root_cert_, MakeCertKeyPairs(private_key_.c_str(),
+                                               cert_chain_.c_str()))));
+  // Copy new data to files.
+  // TODO(ZhenLian): right now it is not completely atomic. Use the real atomic
+  // update when the directory renaming is added in gpr.
+  tmp_root_cert.RewriteFile(root_cert_2_);
+  tmp_identity_key.RewriteFile(private_key_2_);
+  tmp_identity_cert.RewriteFile(cert_chain_2_);
+  // Wait 2 seconds for the provider's refresh thread to read the updated files.
+  gpr_sleep_until(gpr_time_add(gpr_now(GPR_CLOCK_MONOTONIC),
+                               gpr_time_from_seconds(2, GPR_TIMESPAN)));
+  // Expect to see the new credential data.
+  EXPECT_THAT(watcher_state_1->GetCredentialQueue(),
+              ::testing::ElementsAre(CredentialInfo(
+                  root_cert_2_, MakeCertKeyPairs(private_key_2_.c_str(),
+                                                 cert_chain_2_.c_str()))));
+  // Clean up.
+  CancelWatch(watcher_state_1);
+}
+
+TEST_F(GrpcTlsCertificateProviderTest,
+       FileWatcherCertificateProviderOnRootCertsRefreshed) {
+  // Create temporary files and copy cert data into them.
+  TmpFile tmp_root_cert(root_cert_);
+  TmpFile tmp_identity_key(private_key_);
+  TmpFile tmp_identity_cert(cert_chain_);
+  // Create FileWatcherCertificateProvider.
+  FileWatcherCertificateProvider provider(tmp_identity_key.name(),
+                                          tmp_identity_cert.name(),
+                                          tmp_root_cert.name(), 1);
+  WatcherState* watcher_state_1 =
+      MakeWatcher(provider.distributor(), kCertName, kCertName);
+  // Expect to see the credential data.
+  EXPECT_THAT(watcher_state_1->GetCredentialQueue(),
+              ::testing::ElementsAre(CredentialInfo(
+                  root_cert_, MakeCertKeyPairs(private_key_.c_str(),
+                                               cert_chain_.c_str()))));
+  // Copy new data to files.
+  // TODO(ZhenLian): right now it is not completely atomic. Use the real atomic
+  // update when the directory renaming is added in gpr.
+  tmp_root_cert.RewriteFile(root_cert_2_);
+  // Wait 2 seconds for the provider's refresh thread to read the updated files.
+  gpr_sleep_until(gpr_time_add(gpr_now(GPR_CLOCK_MONOTONIC),
+                               gpr_time_from_seconds(2, GPR_TIMESPAN)));
+  // Expect to see the new credential data.
+  EXPECT_THAT(watcher_state_1->GetCredentialQueue(),
+              ::testing::ElementsAre(CredentialInfo(
+                  root_cert_2_, MakeCertKeyPairs(private_key_.c_str(),
+                                                 cert_chain_.c_str()))));
+  // Clean up.
+  CancelWatch(watcher_state_1);
+}
+
+TEST_F(GrpcTlsCertificateProviderTest,
+       FileWatcherCertificateProviderOnIdentityCertsRefreshed) {
+  // Create temporary files and copy cert data into them.
+  TmpFile tmp_root_cert(root_cert_);
+  TmpFile tmp_identity_key(private_key_);
+  TmpFile tmp_identity_cert(cert_chain_);
+  // Create FileWatcherCertificateProvider.
+  FileWatcherCertificateProvider provider(tmp_identity_key.name(),
+                                          tmp_identity_cert.name(),
+                                          tmp_root_cert.name(), 1);
+  WatcherState* watcher_state_1 =
+      MakeWatcher(provider.distributor(), kCertName, kCertName);
+  // Expect to see the credential data.
+  EXPECT_THAT(watcher_state_1->GetCredentialQueue(),
+              ::testing::ElementsAre(CredentialInfo(
+                  root_cert_, MakeCertKeyPairs(private_key_.c_str(),
+                                               cert_chain_.c_str()))));
+  // Copy new data to files.
+  // TODO(ZhenLian): right now it is not completely atomic. Use the real atomic
+  // update when the directory renaming is added in gpr.
+  tmp_identity_key.RewriteFile(private_key_2_);
+  tmp_identity_cert.RewriteFile(cert_chain_2_);
+  // Wait 2 seconds for the provider's refresh thread to read the updated files.
+  gpr_sleep_until(gpr_time_add(gpr_now(GPR_CLOCK_MONOTONIC),
+                               gpr_time_from_seconds(2, GPR_TIMESPAN)));
+  // Expect to see the new credential data.
+  EXPECT_THAT(watcher_state_1->GetCredentialQueue(),
+              ::testing::ElementsAre(CredentialInfo(
+                  root_cert_, MakeCertKeyPairs(private_key_2_.c_str(),
+                                               cert_chain_2_.c_str()))));
+  // Clean up.
+  CancelWatch(watcher_state_1);
+}
+
+TEST_F(GrpcTlsCertificateProviderTest,
+       FileWatcherCertificateProviderWithGoodAtFirstThenDeletedBothCerts) {
+  // Create temporary files and copy cert data into it.
+  auto tmp_root_cert = absl::make_unique<TmpFile>(root_cert_);
+  auto tmp_identity_key = absl::make_unique<TmpFile>(private_key_);
+  auto tmp_identity_cert = absl::make_unique<TmpFile>(cert_chain_);
+  // Create FileWatcherCertificateProvider.
+  FileWatcherCertificateProvider provider(tmp_identity_key->name(),
+                                          tmp_identity_cert->name(),
+                                          tmp_root_cert->name(), 1);
+  WatcherState* watcher_state_1 =
+      MakeWatcher(provider.distributor(), kCertName, kCertName);
+  // The initial data is all good, so we expect to have successful credential
+  // updates.
+  EXPECT_THAT(watcher_state_1->GetCredentialQueue(),
+              ::testing::ElementsAre(CredentialInfo(
+                  root_cert_, MakeCertKeyPairs(private_key_.c_str(),
+                                               cert_chain_.c_str()))));
+  // Delete TmpFile objects, which will remove the corresponding files.
+  tmp_root_cert.reset();
+  tmp_identity_key.reset();
+  tmp_identity_cert.reset();
+  // Wait 2 seconds for the provider's refresh thread to read the deleted files.
+  gpr_sleep_until(gpr_time_add(gpr_now(GPR_CLOCK_MONOTONIC),
+                               gpr_time_from_seconds(2, GPR_TIMESPAN)));
+  // Expect to see errors sent to watchers, and no credential updates.
+  // We have no ideas on how many errors we will receive, so we only check once.
+  EXPECT_THAT(watcher_state_1->GetErrorQueue(),
+              ::testing::Contains(ErrorInfo(kRootError, kIdentityError)));
+  EXPECT_THAT(watcher_state_1->GetCredentialQueue(), ::testing::ElementsAre());
+  // Clean up.
+  CancelWatch(watcher_state_1);
+}
+
+TEST_F(GrpcTlsCertificateProviderTest,
+       FileWatcherCertificateProviderWithGoodAtFirstThenDeletedRootCerts) {
+  // Create temporary files and copy cert data into it.
+  auto tmp_root_cert = absl::make_unique<TmpFile>(root_cert_);
+  TmpFile tmp_identity_key(private_key_);
+  TmpFile tmp_identity_cert(cert_chain_);
+  // Create FileWatcherCertificateProvider.
+  FileWatcherCertificateProvider provider(tmp_identity_key.name(),
+                                          tmp_identity_cert.name(),
+                                          tmp_root_cert->name(), 1);
+  WatcherState* watcher_state_1 =
+      MakeWatcher(provider.distributor(), kCertName, kCertName);
+  // The initial data is all good, so we expect to have successful credential
+  // updates.
+  EXPECT_THAT(watcher_state_1->GetCredentialQueue(),
+              ::testing::ElementsAre(CredentialInfo(
+                  root_cert_, MakeCertKeyPairs(private_key_.c_str(),
+                                               cert_chain_.c_str()))));
+  // Delete root TmpFile object, which will remove the corresponding file.
+  tmp_root_cert.reset();
+  // Wait 2 seconds for the provider's refresh thread to read the deleted files.
+  gpr_sleep_until(gpr_time_add(gpr_now(GPR_CLOCK_MONOTONIC),
+                               gpr_time_from_seconds(2, GPR_TIMESPAN)));
+  // Expect to see errors sent to watchers, and no credential updates.
+  // We have no ideas on how many errors we will receive, so we only check once.
+  EXPECT_THAT(watcher_state_1->GetErrorQueue(),
+              ::testing::Contains(ErrorInfo(kRootError, "")));
+  EXPECT_THAT(watcher_state_1->GetCredentialQueue(), ::testing::ElementsAre());
+  // Clean up.
+  CancelWatch(watcher_state_1);
+}
+
+TEST_F(GrpcTlsCertificateProviderTest,
+       FileWatcherCertificateProviderWithGoodAtFirstThenDeletedIdentityCerts) {
+  // Create temporary files and copy cert data into it.
+  TmpFile tmp_root_cert(root_cert_);
+  auto tmp_identity_key = absl::make_unique<TmpFile>(private_key_);
+  auto tmp_identity_cert = absl::make_unique<TmpFile>(cert_chain_);
+  // Create FileWatcherCertificateProvider.
+  FileWatcherCertificateProvider provider(tmp_identity_key->name(),
+                                          tmp_identity_cert->name(),
+                                          tmp_root_cert.name(), 1);
+  WatcherState* watcher_state_1 =
+      MakeWatcher(provider.distributor(), kCertName, kCertName);
+  // The initial data is all good, so we expect to have successful credential
+  // updates.
+  EXPECT_THAT(watcher_state_1->GetCredentialQueue(),
+              ::testing::ElementsAre(CredentialInfo(
+                  root_cert_, MakeCertKeyPairs(private_key_.c_str(),
+                                               cert_chain_.c_str()))));
+  // Delete identity TmpFile objects, which will remove the corresponding files.
+  tmp_identity_key.reset();
+  tmp_identity_cert.reset();
+  // Wait 2 seconds for the provider's refresh thread to read the deleted files.
+  gpr_sleep_until(gpr_time_add(gpr_now(GPR_CLOCK_MONOTONIC),
+                               gpr_time_from_seconds(2, GPR_TIMESPAN)));
+  // Expect to see errors sent to watchers, and no credential updates.
+  // We have no ideas on how many errors we will receive, so we only check once.
+  EXPECT_THAT(watcher_state_1->GetErrorQueue(),
+              ::testing::Contains(ErrorInfo("", kIdentityError)));
+  EXPECT_THAT(watcher_state_1->GetCredentialQueue(), ::testing::ElementsAre());
+  // Clean up.
+  CancelWatch(watcher_state_1);
+}
+
+}  // namespace testing
+
+}  // namespace grpc_core
+
+int main(int argc, char** argv) {
+  grpc::testing::TestEnvironment env(argc, argv);
+  ::testing::InitGoogleTest(&argc, argv);
+  grpc_init();
+  int ret = RUN_ALL_TESTS();
+  grpc_shutdown();
+  return ret;
+}
index dee1d47..5e9a4e3 100644 (file)
 #include <grpc/support/string_util.h>
 #include <gtest/gtest.h>
 
+#include "src/core/lib/gpr/tmpfile.h"
 #include "src/core/lib/iomgr/load_file.h"
+#include "src/core/lib/security/credentials/tls/tls_credentials.h"
+#include "src/core/lib/security/security_connector/tls/tls_security_connector.h"
 #include "test/core/util/test_config.h"
+#include "test/core/util/tls_utils.h"
 
 #define CA_CERT_PATH "src/core/tsi/test_creds/ca.pem"
 #define SERVER_CERT_PATH "src/core/tsi/test_creds/server1.pem"
 #define SERVER_KEY_PATH "src/core/tsi/test_creds/server1.key"
+#define CA_CERT_PATH_2 "src/core/tsi/test_creds/multi-domain.pem"
+#define SERVER_CERT_PATH_2 "src/core/tsi/test_creds/server0.pem"
+#define SERVER_KEY_PATH_2 "src/core/tsi/test_creds/server0.key"
+#define INVALID_PATH "invalid/path"
+
+namespace grpc_core {
 
 namespace testing {
 
-TEST(GrpcTlsCredentialsOptionsTest, ErrorDetails) {
+class GrpcTlsCredentialsOptionsTest : public ::testing::Test {
+ protected:
+  void SetUp() override {
+    root_cert_ = GetFileContents(CA_CERT_PATH);
+    cert_chain_ = GetFileContents(SERVER_CERT_PATH);
+    private_key_ = GetFileContents(SERVER_KEY_PATH);
+    root_cert_2_ = GetFileContents(CA_CERT_PATH_2);
+    cert_chain_2_ = GetFileContents(SERVER_CERT_PATH_2);
+    private_key_2_ = GetFileContents(SERVER_KEY_PATH_2);
+  }
+
+  std::string root_cert_;
+  std::string private_key_;
+  std::string cert_chain_;
+  std::string root_cert_2_;
+  std::string private_key_2_;
+  std::string cert_chain_2_;
+};
+
+TEST_F(GrpcTlsCredentialsOptionsTest, ErrorDetails) {
   grpc_tls_error_details error_details;
   EXPECT_STREQ(error_details.error_details().c_str(), "");
   error_details.set_error_details("test error details");
   EXPECT_STREQ(error_details.error_details().c_str(), "test error details");
 }
 
+// Tests for StaticDataCertificateProvider.
+TEST_F(GrpcTlsCredentialsOptionsTest,
+       ClientOptionsWithStaticDataProviderOnBothCerts) {
+  auto options = MakeRefCounted<grpc_tls_credentials_options>();
+  auto provider = MakeRefCounted<StaticDataCertificateProvider>(
+      root_cert_, MakeCertKeyPairs(private_key_.c_str(), cert_chain_.c_str()));
+  options->set_certificate_provider(std::move(provider));
+  options->set_watch_root_cert(true);
+  options->set_watch_identity_pair(true);
+  options->set_server_verification_option(GRPC_TLS_SERVER_VERIFICATION);
+  auto credentials = MakeRefCounted<TlsCredentials>(options);
+  ASSERT_NE(credentials, nullptr);
+  grpc_channel_args* new_args = nullptr;
+  auto connector = credentials->create_security_connector(
+      nullptr, "random targets", nullptr, &new_args);
+  grpc_channel_args_destroy(new_args);
+  ASSERT_NE(connector, nullptr);
+  TlsChannelSecurityConnector* tls_connector =
+      static_cast<TlsChannelSecurityConnector*>(connector.get());
+  EXPECT_NE(tls_connector->ClientHandshakerFactoryForTesting(), nullptr);
+  EXPECT_TRUE(tls_connector->RootCertsForTesting().has_value());
+  EXPECT_TRUE(tls_connector->KeyCertPairListForTesting().has_value());
+}
+
+TEST_F(GrpcTlsCredentialsOptionsTest,
+       ClientOptionsWithStaticDataProviderOnRootCerts) {
+  auto options = MakeRefCounted<grpc_tls_credentials_options>();
+  auto provider = MakeRefCounted<StaticDataCertificateProvider>(
+      root_cert_, PemKeyCertPairList());
+  options->set_certificate_provider(std::move(provider));
+  options->set_watch_root_cert(true);
+  options->set_server_verification_option(GRPC_TLS_SERVER_VERIFICATION);
+  auto credentials = MakeRefCounted<TlsCredentials>(options);
+  ASSERT_NE(credentials, nullptr);
+  grpc_channel_args* new_args = nullptr;
+  auto connector = credentials->create_security_connector(
+      nullptr, "random targets", nullptr, &new_args);
+  grpc_channel_args_destroy(new_args);
+  ASSERT_NE(connector, nullptr);
+  TlsChannelSecurityConnector* tls_connector =
+      static_cast<TlsChannelSecurityConnector*>(connector.get());
+  EXPECT_NE(tls_connector->ClientHandshakerFactoryForTesting(), nullptr);
+  EXPECT_TRUE(tls_connector->RootCertsForTesting().has_value());
+  EXPECT_FALSE(tls_connector->KeyCertPairListForTesting().has_value());
+}
+
+TEST_F(GrpcTlsCredentialsOptionsTest,
+       ClientOptionsWithStaticDataProviderOnNotProvidedCerts) {
+  auto options = MakeRefCounted<grpc_tls_credentials_options>();
+  auto provider = MakeRefCounted<StaticDataCertificateProvider>(
+      "", MakeCertKeyPairs(private_key_.c_str(), cert_chain_.c_str()));
+  options->set_certificate_provider(std::move(provider));
+  options->set_watch_root_cert(true);
+  options->set_server_verification_option(GRPC_TLS_SERVER_VERIFICATION);
+  auto credentials = MakeRefCounted<TlsCredentials>(options);
+  ASSERT_NE(credentials, nullptr);
+  grpc_channel_args* new_args = nullptr;
+  auto connector = credentials->create_security_connector(
+      nullptr, "random targets", nullptr, &new_args);
+  grpc_channel_args_destroy(new_args);
+  ASSERT_NE(connector, nullptr);
+  TlsChannelSecurityConnector* tls_connector =
+      static_cast<TlsChannelSecurityConnector*>(connector.get());
+  EXPECT_EQ(tls_connector->ClientHandshakerFactoryForTesting(), nullptr);
+}
+
+TEST_F(GrpcTlsCredentialsOptionsTest,
+       ServerOptionsWithStaticDataProviderOnBothCerts) {
+  auto options = MakeRefCounted<grpc_tls_credentials_options>();
+  auto provider = MakeRefCounted<StaticDataCertificateProvider>(
+      root_cert_, MakeCertKeyPairs(private_key_.c_str(), cert_chain_.c_str()));
+  options->set_certificate_provider(std::move(provider));
+  options->set_watch_root_cert(true);
+  options->set_watch_identity_pair(true);
+  options->set_cert_request_type(
+      GRPC_SSL_REQUEST_AND_REQUIRE_CLIENT_CERTIFICATE_AND_VERIFY);
+  auto credentials = MakeRefCounted<TlsServerCredentials>(options);
+  ASSERT_NE(credentials, nullptr);
+  auto connector = credentials->create_security_connector();
+  ASSERT_NE(connector, nullptr);
+  TlsServerSecurityConnector* tls_connector =
+      static_cast<TlsServerSecurityConnector*>(connector.get());
+  EXPECT_NE(tls_connector->ServerHandshakerFactoryForTesting(), nullptr);
+  EXPECT_TRUE(tls_connector->RootCertsForTesting().has_value());
+  EXPECT_TRUE(tls_connector->KeyCertPairListForTesting().has_value());
+}
+
+TEST_F(GrpcTlsCredentialsOptionsTest,
+       ServerOptionsWithStaticDataProviderOnIdentityCerts) {
+  auto options = MakeRefCounted<grpc_tls_credentials_options>();
+  auto provider = MakeRefCounted<StaticDataCertificateProvider>(
+      "", MakeCertKeyPairs(private_key_.c_str(), cert_chain_.c_str()));
+  options->set_certificate_provider(std::move(provider));
+  options->set_watch_identity_pair(true);
+  options->set_cert_request_type(GRPC_SSL_DONT_REQUEST_CLIENT_CERTIFICATE);
+  auto credentials = MakeRefCounted<TlsServerCredentials>(options);
+  ASSERT_NE(credentials, nullptr);
+  auto connector = credentials->create_security_connector();
+  ASSERT_NE(connector, nullptr);
+  TlsServerSecurityConnector* tls_connector =
+      static_cast<TlsServerSecurityConnector*>(connector.get());
+  EXPECT_NE(tls_connector->ServerHandshakerFactoryForTesting(), nullptr);
+  EXPECT_FALSE(tls_connector->RootCertsForTesting().has_value());
+  EXPECT_TRUE(tls_connector->KeyCertPairListForTesting().has_value());
+}
+
+TEST_F(GrpcTlsCredentialsOptionsTest,
+       ServerOptionsWithStaticDataProviderOnNotProvidedCerts) {
+  auto options = MakeRefCounted<grpc_tls_credentials_options>();
+  auto provider = MakeRefCounted<StaticDataCertificateProvider>(
+      root_cert_, PemKeyCertPairList());
+  options->set_certificate_provider(std::move(provider));
+  options->set_watch_identity_pair(true);
+  options->set_cert_request_type(GRPC_SSL_DONT_REQUEST_CLIENT_CERTIFICATE);
+  auto credentials = MakeRefCounted<TlsServerCredentials>(options);
+  ASSERT_NE(credentials, nullptr);
+  auto connector = credentials->create_security_connector();
+  ASSERT_NE(connector, nullptr);
+  TlsServerSecurityConnector* tls_connector =
+      static_cast<TlsServerSecurityConnector*>(connector.get());
+  EXPECT_EQ(tls_connector->ServerHandshakerFactoryForTesting(), nullptr);
+}
+
+//// Tests for FileWatcherCertificateProvider.
+TEST_F(GrpcTlsCredentialsOptionsTest,
+       ClientOptionsWithCertWatcherProviderOnBothCerts) {
+  auto options = MakeRefCounted<grpc_tls_credentials_options>();
+  auto provider = MakeRefCounted<FileWatcherCertificateProvider>(
+      SERVER_KEY_PATH, SERVER_CERT_PATH, CA_CERT_PATH, 1);
+  options->set_certificate_provider(std::move(provider));
+  options->set_watch_root_cert(true);
+  options->set_watch_identity_pair(true);
+  options->set_server_verification_option(GRPC_TLS_SERVER_VERIFICATION);
+  auto credentials = MakeRefCounted<TlsCredentials>(options);
+  ASSERT_NE(credentials, nullptr);
+  grpc_channel_args* new_args = nullptr;
+  auto connector = credentials->create_security_connector(
+      nullptr, "random targets", nullptr, &new_args);
+  grpc_channel_args_destroy(new_args);
+  ASSERT_NE(connector, nullptr);
+  TlsChannelSecurityConnector* tls_connector =
+      static_cast<TlsChannelSecurityConnector*>(connector.get());
+  EXPECT_NE(tls_connector->ClientHandshakerFactoryForTesting(), nullptr);
+  EXPECT_TRUE(tls_connector->RootCertsForTesting().has_value());
+  EXPECT_TRUE(tls_connector->KeyCertPairListForTesting().has_value());
+}
+
+TEST_F(GrpcTlsCredentialsOptionsTest,
+       ClientOptionsWithCertWatcherProviderOnRootCerts) {
+  auto options = MakeRefCounted<grpc_tls_credentials_options>();
+  auto provider =
+      MakeRefCounted<FileWatcherCertificateProvider>("", "", CA_CERT_PATH, 1);
+  options->set_certificate_provider(std::move(provider));
+  options->set_watch_root_cert(true);
+  options->set_server_verification_option(GRPC_TLS_SERVER_VERIFICATION);
+  auto credentials = MakeRefCounted<TlsCredentials>(options);
+  ASSERT_NE(credentials, nullptr);
+  grpc_channel_args* new_args = nullptr;
+  auto connector = credentials->create_security_connector(
+      nullptr, "random targets", nullptr, &new_args);
+  grpc_channel_args_destroy(new_args);
+  ASSERT_NE(connector, nullptr);
+  TlsChannelSecurityConnector* tls_connector =
+      static_cast<TlsChannelSecurityConnector*>(connector.get());
+  EXPECT_NE(tls_connector->ClientHandshakerFactoryForTesting(), nullptr);
+  EXPECT_TRUE(tls_connector->RootCertsForTesting().has_value());
+  EXPECT_FALSE(tls_connector->KeyCertPairListForTesting().has_value());
+}
+
+TEST_F(GrpcTlsCredentialsOptionsTest,
+       ClientOptionsWithCertWatcherProviderOnNotProvidedCerts) {
+  auto options = MakeRefCounted<grpc_tls_credentials_options>();
+  auto provider = MakeRefCounted<FileWatcherCertificateProvider>(
+      SERVER_KEY_PATH, SERVER_CERT_PATH, "", 1);
+  options->set_certificate_provider(std::move(provider));
+  options->set_watch_root_cert(true);
+  options->set_server_verification_option(GRPC_TLS_SERVER_VERIFICATION);
+  auto credentials = MakeRefCounted<TlsCredentials>(options);
+  ASSERT_NE(credentials, nullptr);
+  grpc_channel_args* new_args = nullptr;
+  auto connector = credentials->create_security_connector(
+      nullptr, "random targets", nullptr, &new_args);
+  grpc_channel_args_destroy(new_args);
+  ASSERT_NE(connector, nullptr);
+  TlsChannelSecurityConnector* tls_connector =
+      static_cast<TlsChannelSecurityConnector*>(connector.get());
+  EXPECT_EQ(tls_connector->ClientHandshakerFactoryForTesting(), nullptr);
+}
+
+TEST_F(GrpcTlsCredentialsOptionsTest,
+       ClientOptionsWithCertWatcherProviderOnBadTrustCerts) {
+  auto options = MakeRefCounted<grpc_tls_credentials_options>();
+  auto provider =
+      MakeRefCounted<FileWatcherCertificateProvider>("", "", INVALID_PATH, 1);
+  options->set_certificate_provider(std::move(provider));
+  options->set_watch_root_cert(true);
+  options->set_server_verification_option(GRPC_TLS_SERVER_VERIFICATION);
+  auto credentials = MakeRefCounted<TlsCredentials>(options);
+  ASSERT_NE(credentials, nullptr);
+  grpc_channel_args* new_args = nullptr;
+  auto connector = credentials->create_security_connector(
+      nullptr, "random targets", nullptr, &new_args);
+  grpc_channel_args_destroy(new_args);
+  ASSERT_NE(connector, nullptr);
+  TlsChannelSecurityConnector* tls_connector =
+      static_cast<TlsChannelSecurityConnector*>(connector.get());
+  EXPECT_EQ(tls_connector->ClientHandshakerFactoryForTesting(), nullptr);
+}
+
+TEST_F(GrpcTlsCredentialsOptionsTest,
+       ServerOptionsWithCertWatcherProviderOnBothCerts) {
+  auto options = MakeRefCounted<grpc_tls_credentials_options>();
+  auto provider = MakeRefCounted<FileWatcherCertificateProvider>(
+      SERVER_KEY_PATH, SERVER_CERT_PATH, CA_CERT_PATH, 1);
+  options->set_certificate_provider(std::move(provider));
+  options->set_watch_root_cert(true);
+  options->set_watch_identity_pair(true);
+  options->set_cert_request_type(
+      GRPC_SSL_REQUEST_AND_REQUIRE_CLIENT_CERTIFICATE_AND_VERIFY);
+  auto credentials = MakeRefCounted<TlsServerCredentials>(options);
+  ASSERT_NE(credentials, nullptr);
+  auto connector = credentials->create_security_connector();
+  ASSERT_NE(connector, nullptr);
+  TlsServerSecurityConnector* tls_connector =
+      static_cast<TlsServerSecurityConnector*>(connector.get());
+  EXPECT_NE(tls_connector->ServerHandshakerFactoryForTesting(), nullptr);
+  EXPECT_TRUE(tls_connector->RootCertsForTesting().has_value());
+  EXPECT_TRUE(tls_connector->KeyCertPairListForTesting().has_value());
+}
+
+TEST_F(GrpcTlsCredentialsOptionsTest,
+       ServerOptionsWithCertWatcherProviderOnIdentityCerts) {
+  auto options = MakeRefCounted<grpc_tls_credentials_options>();
+  auto provider = MakeRefCounted<FileWatcherCertificateProvider>(
+      SERVER_KEY_PATH, SERVER_CERT_PATH, "", 1);
+  options->set_certificate_provider(std::move(provider));
+  options->set_watch_identity_pair(true);
+  options->set_cert_request_type(GRPC_SSL_DONT_REQUEST_CLIENT_CERTIFICATE);
+  auto credentials = MakeRefCounted<TlsServerCredentials>(options);
+  ASSERT_NE(credentials, nullptr);
+  auto connector = credentials->create_security_connector();
+  ASSERT_NE(connector, nullptr);
+  TlsServerSecurityConnector* tls_connector =
+      static_cast<TlsServerSecurityConnector*>(connector.get());
+  EXPECT_NE(tls_connector->ServerHandshakerFactoryForTesting(), nullptr);
+  EXPECT_FALSE(tls_connector->RootCertsForTesting().has_value());
+  EXPECT_TRUE(tls_connector->KeyCertPairListForTesting().has_value());
+}
+
+TEST_F(GrpcTlsCredentialsOptionsTest,
+       ServerOptionsWithCertWatcherProviderOnNotProvidedCerts) {
+  auto options = MakeRefCounted<grpc_tls_credentials_options>();
+  auto provider =
+      MakeRefCounted<FileWatcherCertificateProvider>("", "", CA_CERT_PATH, 1);
+  options->set_certificate_provider(std::move(provider));
+  options->set_watch_identity_pair(true);
+  options->set_cert_request_type(GRPC_SSL_DONT_REQUEST_CLIENT_CERTIFICATE);
+  auto credentials = MakeRefCounted<TlsServerCredentials>(options);
+  ASSERT_NE(credentials, nullptr);
+  auto connector = credentials->create_security_connector();
+  ASSERT_NE(connector, nullptr);
+  TlsServerSecurityConnector* tls_connector =
+      static_cast<TlsServerSecurityConnector*>(connector.get());
+  EXPECT_EQ(tls_connector->ServerHandshakerFactoryForTesting(), nullptr);
+}
+
+TEST_F(GrpcTlsCredentialsOptionsTest,
+       ServerOptionsWithCertWatcherProviderOnBadIdentityCerts) {
+  auto options = MakeRefCounted<grpc_tls_credentials_options>();
+  auto provider = MakeRefCounted<FileWatcherCertificateProvider>(
+      INVALID_PATH, INVALID_PATH, "", 1);
+  options->set_certificate_provider(std::move(provider));
+  options->set_watch_identity_pair(true);
+  options->set_cert_request_type(GRPC_SSL_DONT_REQUEST_CLIENT_CERTIFICATE);
+  auto credentials = MakeRefCounted<TlsServerCredentials>(options);
+  ASSERT_NE(credentials, nullptr);
+  auto connector = credentials->create_security_connector();
+  ASSERT_NE(connector, nullptr);
+  TlsServerSecurityConnector* tls_connector =
+      static_cast<TlsServerSecurityConnector*>(connector.get());
+  EXPECT_EQ(tls_connector->ServerHandshakerFactoryForTesting(), nullptr);
+}
+
+// The following tests write credential data to temporary files to test the
+// transition behavior of the provider.
+TEST_F(GrpcTlsCredentialsOptionsTest,
+       ClientOptionsWithCertWatcherProviderOnCertificateRefreshed) {
+  // Create temporary files and copy cert data into them.
+  TmpFile tmp_root_cert(root_cert_);
+  TmpFile tmp_identity_key(private_key_);
+  TmpFile tmp_identity_cert(cert_chain_);
+  // Create ClientOptions using FileWatcherCertificateProvider.
+  auto options = MakeRefCounted<grpc_tls_credentials_options>();
+  auto provider = MakeRefCounted<FileWatcherCertificateProvider>(
+      tmp_identity_key.name(), tmp_identity_cert.name(), tmp_root_cert.name(),
+      1);
+  options->set_certificate_provider(std::move(provider));
+  options->set_watch_root_cert(true);
+  options->set_watch_identity_pair(true);
+  options->set_server_verification_option(GRPC_TLS_SERVER_VERIFICATION);
+  auto credentials = MakeRefCounted<TlsCredentials>(options);
+  ASSERT_NE(credentials, nullptr);
+  grpc_channel_args* new_args = nullptr;
+  auto connector = credentials->create_security_connector(
+      nullptr, "random targets", nullptr, &new_args);
+  grpc_channel_args_destroy(new_args);
+  ASSERT_NE(connector, nullptr);
+  TlsChannelSecurityConnector* tls_connector =
+      static_cast<TlsChannelSecurityConnector*>(connector.get());
+  // Expect to see the credential data.
+  EXPECT_NE(tls_connector->ClientHandshakerFactoryForTesting(), nullptr);
+  ASSERT_TRUE(tls_connector->RootCertsForTesting().has_value());
+  EXPECT_EQ(tls_connector->RootCertsForTesting(), root_cert_);
+  ASSERT_TRUE(tls_connector->KeyCertPairListForTesting().has_value());
+  EXPECT_EQ(tls_connector->KeyCertPairListForTesting(),
+            MakeCertKeyPairs(private_key_.c_str(), cert_chain_.c_str()));
+  // Copy new data to files.
+  // TODO(ZhenLian): right now it is not completely atomic. Use the real atomic
+  // update when the directory renaming is added in gpr.
+  tmp_root_cert.RewriteFile(root_cert_2_);
+  tmp_identity_key.RewriteFile(private_key_2_);
+  tmp_identity_cert.RewriteFile(cert_chain_2_);
+  // Wait 2 seconds for the provider's refresh thread to read the updated files.
+  gpr_sleep_until(gpr_time_add(gpr_now(GPR_CLOCK_MONOTONIC),
+                               gpr_time_from_seconds(2, GPR_TIMESPAN)));
+  // Expect to see new credential data loaded by the security connector.
+  EXPECT_NE(tls_connector->ClientHandshakerFactoryForTesting(), nullptr);
+  ASSERT_TRUE(tls_connector->RootCertsForTesting().has_value());
+  EXPECT_EQ(tls_connector->RootCertsForTesting(), root_cert_2_);
+  ASSERT_TRUE(tls_connector->KeyCertPairListForTesting().has_value());
+  EXPECT_EQ(tls_connector->KeyCertPairListForTesting(),
+            MakeCertKeyPairs(private_key_2_.c_str(), cert_chain_2_.c_str()));
+}
+
+TEST_F(GrpcTlsCredentialsOptionsTest,
+       ClientOptionsWithCertWatcherProviderOnDeletedFiles) {
+  // Create temporary files and copy cert data into it.
+  auto tmp_root_cert = absl::make_unique<TmpFile>(root_cert_);
+  auto tmp_identity_key = absl::make_unique<TmpFile>(private_key_);
+  auto tmp_identity_cert = absl::make_unique<TmpFile>(cert_chain_);
+  // Create ClientOptions using FileWatcherCertificateProvider.
+  auto options = MakeRefCounted<grpc_tls_credentials_options>();
+  auto provider = MakeRefCounted<FileWatcherCertificateProvider>(
+      tmp_identity_key->name(), tmp_identity_cert->name(),
+      tmp_root_cert->name(), 1);
+  options->set_certificate_provider(std::move(provider));
+  options->set_watch_root_cert(true);
+  options->set_watch_identity_pair(true);
+  options->set_server_verification_option(GRPC_TLS_SERVER_VERIFICATION);
+  auto credentials = MakeRefCounted<TlsCredentials>(options);
+  ASSERT_NE(credentials, nullptr);
+  grpc_channel_args* new_args = nullptr;
+  auto connector = credentials->create_security_connector(
+      nullptr, "random targets", nullptr, &new_args);
+  grpc_channel_args_destroy(new_args);
+  ASSERT_NE(connector, nullptr);
+  TlsChannelSecurityConnector* tls_connector =
+      static_cast<TlsChannelSecurityConnector*>(connector.get());
+  // The initial data is all good, so we expect to have successful credential
+  // updates.
+  EXPECT_NE(tls_connector->ClientHandshakerFactoryForTesting(), nullptr);
+  ASSERT_TRUE(tls_connector->RootCertsForTesting().has_value());
+  EXPECT_EQ(tls_connector->RootCertsForTesting(), root_cert_);
+  ASSERT_TRUE(tls_connector->KeyCertPairListForTesting().has_value());
+  EXPECT_EQ(tls_connector->KeyCertPairListForTesting(),
+            MakeCertKeyPairs(private_key_.c_str(), cert_chain_.c_str()));
+  // Delete TmpFile objects, which will remove the corresponding files.
+  tmp_root_cert.reset();
+  tmp_identity_key.reset();
+  tmp_identity_cert.reset();
+  // Wait 2 seconds for the provider's refresh thread to read the deleted files.
+  gpr_sleep_until(gpr_time_add(gpr_now(GPR_CLOCK_MONOTONIC),
+                               gpr_time_from_seconds(2, GPR_TIMESPAN)));
+  // It's a bit hard to test if errors are sent to the security connector,
+  // because the security connector simply logs the error. We will see the err
+  // messages if we open the log.
+  // The old certs should still being used.
+  EXPECT_NE(tls_connector->ClientHandshakerFactoryForTesting(), nullptr);
+  ASSERT_TRUE(tls_connector->RootCertsForTesting().has_value());
+  EXPECT_EQ(tls_connector->RootCertsForTesting(), root_cert_);
+  ASSERT_TRUE(tls_connector->KeyCertPairListForTesting().has_value());
+  EXPECT_EQ(tls_connector->KeyCertPairListForTesting(),
+            MakeCertKeyPairs(private_key_.c_str(), cert_chain_.c_str()));
+}
+
 }  // namespace testing
 
+}  // namespace grpc_core
+
 int main(int argc, char** argv) {
   grpc::testing::TestEnvironment env(argc, argv);
   ::testing::InitGoogleTest(&argc, argv);
index faa1b28..dfdb28b 100644 (file)
@@ -31,9 +31,12 @@ namespace testing {
 namespace {
 
 TEST(InsecureSecurityConnector, MakeAuthContextTest) {
-  auto auth_context = InsecureChannelSecurityConnector::MakeAuthContext();
-  // Verify that peer identity is set
-  auto it = grpc_auth_context_peer_identity(auth_context.get());
+  auto auth_context = TestOnlyMakeInsecureAuthContext();
+  // Verify that peer is not authenticated
+  EXPECT_EQ(auth_context->is_authenticated(), false);
+  // Verify that GRPC_TRANSPORT_SECURITY_TYPE_PROPERTY_NAME is set
+  auto it = grpc_auth_context_find_properties_by_name(
+      auth_context.get(), GRPC_TRANSPORT_SECURITY_TYPE_PROPERTY_NAME);
   const grpc_auth_property* prop = grpc_auth_property_iterator_next(&it);
   ASSERT_NE(prop, nullptr);
   EXPECT_STREQ(prop->name, GRPC_TRANSPORT_SECURITY_TYPE_PROPERTY_NAME);
index a60d874..71178cb 100644 (file)
@@ -382,7 +382,8 @@ static void test_jwt_verifier_google_email_issuer_success(void) {
   grpc_auth_json_key_destruct(&key);
   GPR_ASSERT(jwt != nullptr);
   grpc_jwt_verifier_verify(verifier, nullptr, jwt, expected_audience,
-                           on_verification_success, (void*)expected_user_data);
+                           on_verification_success,
+                           const_cast<char*>(expected_user_data));
   grpc_jwt_verifier_destroy(verifier);
   grpc_core::ExecCtx::Get()->Flush();
   gpr_free(jwt);
@@ -415,7 +416,8 @@ static void test_jwt_verifier_custom_email_issuer_success(void) {
   grpc_auth_json_key_destruct(&key);
   GPR_ASSERT(jwt != nullptr);
   grpc_jwt_verifier_verify(verifier, nullptr, jwt, expected_audience,
-                           on_verification_success, (void*)expected_user_data);
+                           on_verification_success,
+                           const_cast<char*>(expected_user_data));
   grpc_jwt_verifier_destroy(verifier);
   grpc_core::ExecCtx::Get()->Flush();
   gpr_free(jwt);
@@ -462,7 +464,8 @@ static void test_jwt_verifier_url_issuer_success(void) {
   grpc_auth_json_key_destruct(&key);
   GPR_ASSERT(jwt != nullptr);
   grpc_jwt_verifier_verify(verifier, nullptr, jwt, expected_audience,
-                           on_verification_success, (void*)expected_user_data);
+                           on_verification_success,
+                           const_cast<char*>(expected_user_data));
   grpc_jwt_verifier_destroy(verifier);
   grpc_core::ExecCtx::Get()->Flush();
   gpr_free(jwt);
@@ -502,7 +505,7 @@ static void test_jwt_verifier_url_issuer_bad_config(void) {
   GPR_ASSERT(jwt != nullptr);
   grpc_jwt_verifier_verify(verifier, nullptr, jwt, expected_audience,
                            on_verification_key_retrieval_error,
-                           (void*)expected_user_data);
+                           const_cast<char*>(expected_user_data));
   grpc_jwt_verifier_destroy(verifier);
   grpc_core::ExecCtx::Get()->Flush();
   gpr_free(jwt);
@@ -525,7 +528,7 @@ static void test_jwt_verifier_bad_json_key(void) {
   GPR_ASSERT(jwt != nullptr);
   grpc_jwt_verifier_verify(verifier, nullptr, jwt, expected_audience,
                            on_verification_key_retrieval_error,
-                           (void*)expected_user_data);
+                           const_cast<char*>(expected_user_data));
   grpc_jwt_verifier_destroy(verifier);
   grpc_core::ExecCtx::Get()->Flush();
   gpr_free(jwt);
@@ -577,7 +580,7 @@ static void test_jwt_verifier_bad_signature(void) {
   GPR_ASSERT(jwt != nullptr);
   grpc_jwt_verifier_verify(verifier, nullptr, jwt, expected_audience,
                            on_verification_bad_signature,
-                           (void*)expected_user_data);
+                           const_cast<char*>(expected_user_data));
   gpr_free(jwt);
   grpc_jwt_verifier_destroy(verifier);
   grpc_core::ExecCtx::Get()->Flush();
@@ -606,7 +609,7 @@ static void test_jwt_verifier_bad_format(void) {
                             httpcli_post_should_not_be_called);
   grpc_jwt_verifier_verify(verifier, nullptr, "bad jwt", expected_audience,
                            on_verification_bad_format,
-                           (void*)expected_user_data);
+                           const_cast<char*>(expected_user_data));
   grpc_jwt_verifier_destroy(verifier);
   grpc_core::ExecCtx::Get()->Flush();
   grpc_httpcli_set_override(nullptr, nullptr);
index c6b760b..2049832 100644 (file)
@@ -571,8 +571,8 @@ class TestDefaultSslRootStore : public DefaultSslRootStore {
 }  // namespace
 }  // namespace grpc_core
 
-// TODO: Convert this test to C++ test when security_connector implementation
-// is converted to C++.
+// TODO(unknown): Convert this test to C++ test when security_connector
+// implementation is converted to C++.
 static void test_default_ssl_roots(void) {
   const char* roots_for_env_var = "roots for env var";
 
index 63ec2a4..c6f744d 100644 (file)
@@ -75,18 +75,8 @@ class TlsSecurityConnectorTest : public ::testing::Test {
         std::string(grpc_core::StringViewFromSlice(cert_slice_1));
     std::string identity_cert_0 =
         std::string(grpc_core::StringViewFromSlice(cert_slice_0));
-    grpc_ssl_pem_key_cert_pair* ssl_pair_1 =
-        static_cast<grpc_ssl_pem_key_cert_pair*>(
-            gpr_malloc(sizeof(grpc_ssl_pem_key_cert_pair)));
-    ssl_pair_1->private_key = gpr_strdup(identity_key_1.c_str());
-    ssl_pair_1->cert_chain = gpr_strdup(identity_cert_1.c_str());
-    identity_pairs_1_.emplace_back(ssl_pair_1);
-    grpc_ssl_pem_key_cert_pair* ssl_pair_0 =
-        static_cast<grpc_ssl_pem_key_cert_pair*>(
-            gpr_malloc(sizeof(grpc_ssl_pem_key_cert_pair)));
-    ssl_pair_0->private_key = gpr_strdup(identity_key_0.c_str());
-    ssl_pair_0->cert_chain = gpr_strdup(identity_cert_0.c_str());
-    identity_pairs_0_.emplace_back(ssl_pair_0);
+    identity_pairs_1_.emplace_back(identity_key_1, identity_cert_1);
+    identity_pairs_0_.emplace_back(identity_key_0, identity_cert_0);
     grpc_slice_unref(ca_slice_1);
     grpc_slice_unref(ca_slice_0);
     grpc_slice_unref(cert_slice_1);
diff --git a/test/core/security/xds_credentials_test.cc b/test/core/security/xds_credentials_test.cc
new file mode 100644 (file)
index 0000000..373e905
--- /dev/null
@@ -0,0 +1,306 @@
+//
+//
+// 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 "src/core/lib/security/credentials/xds/xds_credentials.h"
+
+#include <gtest/gtest.h>
+
+#include <grpc/grpc.h>
+
+#include "test/core/util/test_config.h"
+
+namespace grpc_core {
+namespace testing {
+
+namespace {
+
+XdsApi::StringMatcher ExactMatcher(const char* string) {
+  return XdsApi::StringMatcher(XdsApi::StringMatcher::StringMatcherType::EXACT,
+                               string);
+}
+
+XdsApi::StringMatcher PrefixMatcher(const char* string,
+                                    bool ignore_case = false) {
+  return XdsApi::StringMatcher(XdsApi::StringMatcher::StringMatcherType::PREFIX,
+                               string, ignore_case);
+}
+
+XdsApi::StringMatcher SuffixMatcher(const char* string,
+                                    bool ignore_case = false) {
+  return XdsApi::StringMatcher(XdsApi::StringMatcher::StringMatcherType::SUFFIX,
+                               string, ignore_case);
+}
+
+XdsApi::StringMatcher ContainsMatcher(const char* string,
+                                      bool ignore_case = false) {
+  return XdsApi::StringMatcher(
+      XdsApi::StringMatcher::StringMatcherType::CONTAINS, string, ignore_case);
+}
+
+XdsApi::StringMatcher SafeRegexMatcher(const char* string) {
+  return XdsApi::StringMatcher(
+      XdsApi::StringMatcher::StringMatcherType::SAFE_REGEX, string);
+}
+
+TEST(XdsSanMatchingTest, EmptySansList) {
+  std::vector<const char*> sans = {};
+  EXPECT_FALSE(TestOnlyXdsVerifySubjectAlternativeNames(
+      sans.data(), sans.size(),
+      {ExactMatcher("a.example.com"), ExactMatcher("b.example.com")}));
+}
+
+TEST(XdsSanMatchingTest, EmptyMatchersList) {
+  std::vector<const char*> sans = {"a.example.com", "foo.example.com"};
+  EXPECT_TRUE(
+      TestOnlyXdsVerifySubjectAlternativeNames(sans.data(), sans.size(), {}));
+}
+
+TEST(XdsSanMatchingTest, ExactMatchIllegalValues) {
+  std::vector<const char*> sans = {".a.example.com"};
+  EXPECT_FALSE(TestOnlyXdsVerifySubjectAlternativeNames(
+      sans.data(), sans.size(),
+      {ExactMatcher(""), ExactMatcher("a.example.com"),
+       ExactMatcher(".a.example.com")}));
+  sans = {""};
+  EXPECT_FALSE(TestOnlyXdsVerifySubjectAlternativeNames(
+      sans.data(), sans.size(),
+      {ExactMatcher(""), ExactMatcher("a.example.com"),
+       ExactMatcher(".a.example.com")}));
+  sans = {"a.example.com"};
+  EXPECT_TRUE(TestOnlyXdsVerifySubjectAlternativeNames(
+      sans.data(), sans.size(),
+      {ExactMatcher(""), ExactMatcher("a.example.com"),
+       ExactMatcher(".a.example.com")}));
+}
+
+TEST(XdsSanMatchingTest, ExactMatchDns) {
+  std::vector<const char*> sans = {"a.example.com"};
+  EXPECT_TRUE(TestOnlyXdsVerifySubjectAlternativeNames(
+      sans.data(), sans.size(), {ExactMatcher("a.example.com")}));
+  EXPECT_FALSE(TestOnlyXdsVerifySubjectAlternativeNames(
+      sans.data(), sans.size(), {ExactMatcher("b.example.com")}));
+  sans = {"b.example.com."};
+  EXPECT_FALSE(TestOnlyXdsVerifySubjectAlternativeNames(
+      sans.data(), sans.size(), {ExactMatcher("a.example.com.")}));
+  EXPECT_TRUE(TestOnlyXdsVerifySubjectAlternativeNames(
+      sans.data(), sans.size(), {ExactMatcher("b.example.com.")}));
+}
+
+TEST(XdsSanMatchingTest, ExactMatchWithFullyQualifiedSan) {
+  std::vector<const char*> sans = {"a.example.com."};
+  EXPECT_TRUE(TestOnlyXdsVerifySubjectAlternativeNames(
+      sans.data(), sans.size(), {ExactMatcher("a.example.com")}));
+  EXPECT_FALSE(TestOnlyXdsVerifySubjectAlternativeNames(
+      sans.data(), sans.size(), {ExactMatcher("b.example.com")}));
+}
+
+TEST(XdsSanMatchingTest, ExactMatchWithFullyQualifiedMatcher) {
+  std::vector<const char*> sans = {"a.example.com"};
+  EXPECT_TRUE(TestOnlyXdsVerifySubjectAlternativeNames(
+      sans.data(), sans.size(), {ExactMatcher("a.example.com.")}));
+  EXPECT_FALSE(TestOnlyXdsVerifySubjectAlternativeNames(
+      sans.data(), sans.size(), {ExactMatcher("b.example.com.")}));
+}
+
+TEST(XdsSanMatchingTest, ExactMatchDnsCaseInsensitive) {
+  std::vector<const char*> sans = {"A.eXaMpLe.CoM"};
+  EXPECT_TRUE(TestOnlyXdsVerifySubjectAlternativeNames(
+      sans.data(), sans.size(), {ExactMatcher("a.example.com")}));
+  EXPECT_TRUE(TestOnlyXdsVerifySubjectAlternativeNames(
+      sans.data(), sans.size(), {ExactMatcher("a.ExAmPlE.cOm")}));
+}
+
+TEST(XdsSanMatchingTest, ExactMatchMultipleSansMultipleMatchers) {
+  std::vector<const char*> sans = {"a.example.com", "foo.example.com",
+                                   "b.example.com"};
+  EXPECT_TRUE(TestOnlyXdsVerifySubjectAlternativeNames(
+      sans.data(), sans.size(),
+      {ExactMatcher("abc.example.com"), ExactMatcher("foo.example.com"),
+       ExactMatcher("xyz.example.com")}));
+}
+
+TEST(XdsSanMatchingTest, ExactMatchWildCard) {
+  std::vector<const char*> sans = {"*.example.com"};
+  EXPECT_TRUE(TestOnlyXdsVerifySubjectAlternativeNames(
+      sans.data(), sans.size(), {ExactMatcher("a.example.com")}));
+  EXPECT_TRUE(TestOnlyXdsVerifySubjectAlternativeNames(
+      sans.data(), sans.size(), {ExactMatcher("fOo.ExAmPlE.cOm")}));
+  EXPECT_TRUE(TestOnlyXdsVerifySubjectAlternativeNames(
+      sans.data(), sans.size(), {ExactMatcher("BaR.eXaMpLe.CoM")}));
+  EXPECT_FALSE(TestOnlyXdsVerifySubjectAlternativeNames(
+      sans.data(), sans.size(), {ExactMatcher(".example.com")}));
+  EXPECT_FALSE(TestOnlyXdsVerifySubjectAlternativeNames(
+      sans.data(), sans.size(), {ExactMatcher("example.com")}));
+  EXPECT_FALSE(TestOnlyXdsVerifySubjectAlternativeNames(
+      sans.data(), sans.size(), {ExactMatcher("foo.bar.com")}));
+}
+
+TEST(XdsSanMatchingTest, ExactMatchWildCardDoesNotMatchSingleLabelDomain) {
+  std::vector<const char*> sans = {"*"};
+  EXPECT_FALSE(TestOnlyXdsVerifySubjectAlternativeNames(
+      sans.data(), sans.size(), {ExactMatcher("abc")}));
+  EXPECT_FALSE(TestOnlyXdsVerifySubjectAlternativeNames(
+      sans.data(), sans.size(), {ExactMatcher("abc.com.")}));
+  EXPECT_FALSE(TestOnlyXdsVerifySubjectAlternativeNames(
+      sans.data(), sans.size(), {ExactMatcher("bar.baz.com")}));
+  sans = {"*."};
+  EXPECT_FALSE(TestOnlyXdsVerifySubjectAlternativeNames(
+      sans.data(), sans.size(), {ExactMatcher("abc")}));
+  EXPECT_FALSE(TestOnlyXdsVerifySubjectAlternativeNames(
+      sans.data(), sans.size(), {ExactMatcher("abc.com.")}));
+  EXPECT_FALSE(TestOnlyXdsVerifySubjectAlternativeNames(
+      sans.data(), sans.size(), {ExactMatcher("bar.baz.com")}));
+}
+
+TEST(XdsSanMatchingTest, ExactMatchAsteriskOnlyPermittedInLeftMostDomainName) {
+  std::vector<const char*> sans = {"*.example.*.com"};
+  EXPECT_FALSE(TestOnlyXdsVerifySubjectAlternativeNames(
+      sans.data(), sans.size(), {ExactMatcher("abc.example.xyz.com")}));
+  sans = {"*.exam*ple.com"};
+  EXPECT_FALSE(TestOnlyXdsVerifySubjectAlternativeNames(
+      sans.data(), sans.size(), {ExactMatcher("abc.example.com")}));
+}
+
+TEST(XdsSanMatchingTest,
+     ExactMatchAsteriskMustBeOnlyCharacterInLeftMostDomainName) {
+  std::vector<const char*> sans = {"*c.example.com"};
+  EXPECT_FALSE(TestOnlyXdsVerifySubjectAlternativeNames(
+      sans.data(), sans.size(), {ExactMatcher("abc.example.com")}));
+}
+
+TEST(XdsSanMatchingTest,
+     ExactMatchAsteriskMatchingAcrossDomainLabelsNotPermitted) {
+  std::vector<const char*> sans = {"*.com"};
+  EXPECT_FALSE(TestOnlyXdsVerifySubjectAlternativeNames(
+      sans.data(), sans.size(), {ExactMatcher("abc.example.com")}));
+  EXPECT_FALSE(TestOnlyXdsVerifySubjectAlternativeNames(
+      sans.data(), sans.size(), {ExactMatcher("foo.bar.baz.com")}));
+  EXPECT_TRUE(TestOnlyXdsVerifySubjectAlternativeNames(
+      sans.data(), sans.size(), {ExactMatcher("abc.com")}));
+}
+
+TEST(XdsSanMatchingTest, PrefixMatch) {
+  std::vector<const char*> sans = {"abc.com"};
+  EXPECT_TRUE(TestOnlyXdsVerifySubjectAlternativeNames(sans.data(), sans.size(),
+                                                       {PrefixMatcher("abc")}));
+  sans = {"AbC.CoM"};
+  EXPECT_FALSE(TestOnlyXdsVerifySubjectAlternativeNames(
+      sans.data(), sans.size(), {PrefixMatcher("abc")}));
+  sans = {"xyz.com"};
+  EXPECT_FALSE(TestOnlyXdsVerifySubjectAlternativeNames(
+      sans.data(), sans.size(), {PrefixMatcher("abc")}));
+}
+
+TEST(XdsSanMatchingTest, PrefixMatchIgnoreCase) {
+  std::vector<const char*> sans = {"aBc.cOm"};
+  EXPECT_TRUE(TestOnlyXdsVerifySubjectAlternativeNames(
+      sans.data(), sans.size(),
+      {PrefixMatcher("AbC", true /* ignore_case */)}));
+  sans = {"abc.com"};
+  EXPECT_TRUE(TestOnlyXdsVerifySubjectAlternativeNames(
+      sans.data(), sans.size(),
+      {PrefixMatcher("AbC", true /* ignore_case */)}));
+  sans = {"xyz.com"};
+  EXPECT_FALSE(TestOnlyXdsVerifySubjectAlternativeNames(
+      sans.data(), sans.size(),
+      {PrefixMatcher("AbC", true /* ignore_case */)}));
+}
+
+TEST(XdsSanMatchingTest, SuffixMatch) {
+  std::vector<const char*> sans = {"abc.com"};
+  EXPECT_TRUE(TestOnlyXdsVerifySubjectAlternativeNames(
+      sans.data(), sans.size(), {SuffixMatcher(".com")}));
+  sans = {"AbC.CoM"};
+  EXPECT_FALSE(TestOnlyXdsVerifySubjectAlternativeNames(
+      sans.data(), sans.size(), {SuffixMatcher(".com")}));
+  sans = {"abc.xyz"};
+  EXPECT_FALSE(TestOnlyXdsVerifySubjectAlternativeNames(
+      sans.data(), sans.size(), {SuffixMatcher(".com")}));
+}
+
+TEST(XdsSanMatchingTest, SuffixMatchIgnoreCase) {
+  std::vector<const char*> sans = {"abc.com"};
+  EXPECT_TRUE(TestOnlyXdsVerifySubjectAlternativeNames(
+      sans.data(), sans.size(),
+      {SuffixMatcher(".CoM", true /* ignore_case */)}));
+  sans = {"AbC.cOm"};
+  EXPECT_TRUE(TestOnlyXdsVerifySubjectAlternativeNames(
+      sans.data(), sans.size(),
+      {SuffixMatcher(".CoM", true /* ignore_case */)}));
+  sans = {"abc.xyz"};
+  EXPECT_FALSE(TestOnlyXdsVerifySubjectAlternativeNames(
+      sans.data(), sans.size(),
+      {SuffixMatcher(".CoM", true /* ignore_case */)}));
+}
+
+TEST(XdsSanMatchingTest, ContainsMatch) {
+  std::vector<const char*> sans = {"abc.com"};
+  EXPECT_TRUE(TestOnlyXdsVerifySubjectAlternativeNames(
+      sans.data(), sans.size(), {ContainsMatcher("abc")}));
+  sans = {"xyz.abc.com"};
+  EXPECT_TRUE(TestOnlyXdsVerifySubjectAlternativeNames(
+      sans.data(), sans.size(), {ContainsMatcher("abc")}));
+  sans = {"foo.AbC.com"};
+  EXPECT_FALSE(TestOnlyXdsVerifySubjectAlternativeNames(
+      sans.data(), sans.size(), {ContainsMatcher("abc")}));
+}
+
+TEST(XdsSanMatchingTest, ContainsMatchIgnoresCase) {
+  std::vector<const char*> sans = {"abc.com"};
+  EXPECT_TRUE(TestOnlyXdsVerifySubjectAlternativeNames(
+      sans.data(), sans.size(),
+      {ContainsMatcher("AbC", true /* ignore_case */)}));
+  sans = {"xyz.abc.com"};
+  EXPECT_TRUE(TestOnlyXdsVerifySubjectAlternativeNames(
+      sans.data(), sans.size(),
+      {ContainsMatcher("AbC", true /* ignore_case */)}));
+  sans = {"foo.aBc.com"};
+  EXPECT_TRUE(TestOnlyXdsVerifySubjectAlternativeNames(
+      sans.data(), sans.size(),
+      {ContainsMatcher("AbC", true /* ignore_case */)}));
+  sans = {"foo.Ab.com"};
+  EXPECT_FALSE(TestOnlyXdsVerifySubjectAlternativeNames(
+      sans.data(), sans.size(),
+      {ContainsMatcher("AbC", true /* ignore_case */)}));
+}
+
+TEST(XdsSanMatchingTest, RegexMatch) {
+  std::vector<const char*> sans = {"abc.example.com"};
+  EXPECT_TRUE(TestOnlyXdsVerifySubjectAlternativeNames(
+      sans.data(), sans.size(), {SafeRegexMatcher("(abc|xyz).example.com")}));
+  sans = {"xyz.example.com"};
+  EXPECT_TRUE(TestOnlyXdsVerifySubjectAlternativeNames(
+      sans.data(), sans.size(), {SafeRegexMatcher("(abc|xyz).example.com")}));
+  sans = {"foo.example.com"};
+  EXPECT_FALSE(TestOnlyXdsVerifySubjectAlternativeNames(
+      sans.data(), sans.size(), {SafeRegexMatcher("(abc|xyz).example.com")}));
+}
+
+}  // namespace
+
+}  // namespace testing
+}  // namespace grpc_core
+
+int main(int argc, char** argv) {
+  ::testing::InitGoogleTest(&argc, argv);
+  grpc::testing::TestEnvironment env(argc, argv);
+  grpc_init();
+  auto result = RUN_ALL_TESTS();
+  grpc_shutdown();
+  return result;
+}
index 39a86cc..f207c0e 100644 (file)
@@ -67,7 +67,6 @@ grpc_cc_test(
 grpc_cc_test(
     name = "concurrent_connectivity_test",
     srcs = ["concurrent_connectivity_test.cc"],
-    flaky = True,  # TODO(b/157516542)
     language = "C++",
     deps = [
         "//:gpr",
index 3d8304b..cbf536f 100644 (file)
@@ -31,7 +31,7 @@
 
 static void* create_test_tag(void) {
   static intptr_t i = 0;
-  return (void*)(++i);
+  return reinterpret_cast<void*>(++i);
 }
 
 /* helper for tests to shutdown correctly and tersely */
@@ -380,7 +380,7 @@ static void test_callback(void) {
   bool got_shutdown = false;
   class ShutdownCallback : public grpc_experimental_completion_queue_functor {
    public:
-    ShutdownCallback(bool* done) : done_(done) {
+    explicit ShutdownCallback(bool* done) : done_(done) {
       functor_run = &ShutdownCallback::Run;
       inlineable = false;
     }
index e68d21b..a466cd2 100644 (file)
@@ -31,7 +31,7 @@
 
 static void* create_test_tag(void) {
   static intptr_t i = 0;
-  return (void*)(++i);
+  return reinterpret_cast<void*>(++i);
 }
 
 /* helper for tests to shutdown correctly and tersely */
@@ -146,7 +146,7 @@ static void producer_thread(void* arg) {
   int i;
 
   gpr_log(GPR_INFO, "producer %d started", opt->id);
-  gpr_event_set(&opt->on_started, (void*)static_cast<intptr_t>(1));
+  gpr_event_set(&opt->on_started, reinterpret_cast<void*>(1));
   GPR_ASSERT(gpr_event_wait(opt->phase1, ten_seconds_time()));
 
   gpr_log(GPR_INFO, "producer %d phase 1", opt->id);
@@ -155,13 +155,13 @@ static void producer_thread(void* arg) {
   }
 
   gpr_log(GPR_INFO, "producer %d phase 1 done", opt->id);
-  gpr_event_set(&opt->on_phase1_done, (void*)static_cast<intptr_t>(1));
+  gpr_event_set(&opt->on_phase1_done, reinterpret_cast<void*>(1));
   GPR_ASSERT(gpr_event_wait(opt->phase2, ten_seconds_time()));
 
   gpr_log(GPR_INFO, "producer %d phase 2", opt->id);
   for (i = 0; i < TEST_THREAD_EVENTS; i++) {
     grpc_core::ExecCtx exec_ctx;
-    grpc_cq_end_op(opt->cc, (void*)static_cast<intptr_t>(1), GRPC_ERROR_NONE,
+    grpc_cq_end_op(opt->cc, reinterpret_cast<void*>(1), GRPC_ERROR_NONE,
                    free_completion, nullptr,
                    static_cast<grpc_cq_completion*>(
                        gpr_malloc(sizeof(grpc_cq_completion))));
@@ -169,7 +169,7 @@ static void producer_thread(void* arg) {
   }
 
   gpr_log(GPR_INFO, "producer %d phase 2 done", opt->id);
-  gpr_event_set(&opt->on_finished, (void*)static_cast<intptr_t>(1));
+  gpr_event_set(&opt->on_finished, reinterpret_cast<void*>(1));
 }
 
 static void consumer_thread(void* arg) {
@@ -177,13 +177,13 @@ static void consumer_thread(void* arg) {
   grpc_event ev;
 
   gpr_log(GPR_INFO, "consumer %d started", opt->id);
-  gpr_event_set(&opt->on_started, (void*)static_cast<intptr_t>(1));
+  gpr_event_set(&opt->on_started, reinterpret_cast<void*>(1));
   GPR_ASSERT(gpr_event_wait(opt->phase1, ten_seconds_time()));
 
   gpr_log(GPR_INFO, "consumer %d phase 1", opt->id);
 
   gpr_log(GPR_INFO, "consumer %d phase 1 done", opt->id);
-  gpr_event_set(&opt->on_phase1_done, (void*)static_cast<intptr_t>(1));
+  gpr_event_set(&opt->on_phase1_done, reinterpret_cast<void*>(1));
   GPR_ASSERT(gpr_event_wait(opt->phase2, ten_seconds_time()));
 
   gpr_log(GPR_INFO, "consumer %d phase 2", opt->id);
@@ -197,7 +197,7 @@ static void consumer_thread(void* arg) {
         break;
       case GRPC_QUEUE_SHUTDOWN:
         gpr_log(GPR_INFO, "consumer %d phase 2 done", opt->id);
-        gpr_event_set(&opt->on_finished, (void*)static_cast<intptr_t>(1));
+        gpr_event_set(&opt->on_finished, reinterpret_cast<void*>(1));
         return;
       case GRPC_QUEUE_TIMEOUT:
         gpr_log(GPR_ERROR, "Invalid timeout received");
@@ -244,7 +244,7 @@ static void test_threading(size_t producers, size_t consumers) {
   /* start phase1: producers will pre-declare all operations they will
      complete */
   gpr_log(GPR_INFO, "start phase 1");
-  gpr_event_set(&phase1, (void*)static_cast<intptr_t>(1));
+  gpr_event_set(&phase1, reinterpret_cast<void*>(1));
 
   gpr_log(GPR_INFO, "wait phase 1");
   for (i = 0; i < producers + consumers; i++) {
@@ -254,7 +254,7 @@ static void test_threading(size_t producers, size_t consumers) {
 
   /* start phase2: operations will complete, and consumers will consume them */
   gpr_log(GPR_INFO, "start phase 2");
-  gpr_event_set(&phase2, (void*)static_cast<intptr_t>(1));
+  gpr_event_set(&phase2, reinterpret_cast<void*>(1));
 
   /* in parallel, we shutdown the completion channel - all events should still
      be consumed */
index b317758..f2edbc8 100644 (file)
@@ -66,8 +66,7 @@
 // it should never take longer that this to shutdown the server
 #define SERVER_SHUTDOWN_TIMEOUT 30000
 
-static void* tag(int n) { return (void*)static_cast<uintptr_t>(n); }
-static int detag(void* p) { return static_cast<int>((uintptr_t)p); }
+static void* tag(int n) { return reinterpret_cast<void*>(n); }
 
 void create_loop_destroy(void* addr) {
   for (int i = 0; i < NUM_OUTER_LOOPS; ++i) {
@@ -113,7 +112,7 @@ void server_thread(void* vargs) {
       grpc_timeout_milliseconds_to_deadline(SERVER_SHUTDOWN_TIMEOUT);
   ev = grpc_completion_queue_next(args->cq, deadline, nullptr);
   GPR_ASSERT(ev.type == GRPC_OP_COMPLETE);
-  GPR_ASSERT(detag(ev.tag) == 0xd1e);
+  GPR_ASSERT(ev.tag == tag(0xd1e));
 }
 
 static void on_connect(void* vargs, grpc_endpoint* tcp,
@@ -148,7 +147,7 @@ void bad_server_thread(void* vargs) {
   args->addr = absl::StrCat("localhost:", port);
 
   grpc_tcp_server_start(s, &args->pollset, on_connect, args);
-  gpr_event_set(&args->ready, (void*)1);
+  gpr_event_set(&args->ready, reinterpret_cast<void*>(1));
 
   gpr_mu_lock(args->mu);
   while (args->stop.load(std::memory_order_acquire) == false) {
index c633354..bac7ee0 100644 (file)
@@ -36,7 +36,7 @@ class Watcher : public grpc_core::ConnectivityStateWatcherInterface {
   }
 };
 
-static void* tag(intptr_t x) { return (void*)x; }
+static void* tag(intptr_t t) { return reinterpret_cast<void*>(t); }
 
 static grpc_closure transport_op_cb;
 
@@ -76,8 +76,10 @@ int main(int argc, char** argv) {
   grpc_metadata_array_init(&initial_metadata_recv);
   grpc_metadata_array_init(&trailing_metadata_recv);
 
-  chan = grpc_lame_client_channel_create(
-      "lampoon:national", GRPC_STATUS_UNKNOWN, "Rpc sent on a lame channel.");
+  const char* error_message = "Rpc sent on a lame channel.";
+  grpc_status_code error_code = GRPC_STATUS_ABORTED;
+  chan = grpc_lame_client_channel_create("lampoon:national", error_code,
+                                         error_message);
   GPR_ASSERT(chan);
 
   test_transport_op(chan);
@@ -136,6 +138,9 @@ int main(int argc, char** argv) {
   GPR_ASSERT(strcmp(peer, "lampoon:national") == 0);
   gpr_free(peer);
 
+  GPR_ASSERT(status == error_code);
+  GPR_ASSERT(grpc_slice_str_cmp(details, error_message) == 0);
+
   grpc_call_unref(call);
   grpc_channel_destroy(chan);
   cq_verifier_destroy(cqv);
index 1b2cce8..2a348da 100644 (file)
@@ -45,8 +45,9 @@ static void channel_idle_start_watch(grpc_channel* channel,
   GPR_ASSERT(grpc_channel_check_connectivity_state(channel, 0) ==
              GRPC_CHANNEL_IDLE);
 
-  grpc_channel_watch_connectivity_state(
-      channel, GRPC_CHANNEL_IDLE, connect_deadline, cq, (void*)(next_tag++));
+  grpc_channel_watch_connectivity_state(channel, GRPC_CHANNEL_IDLE,
+                                        connect_deadline, cq,
+                                        reinterpret_cast<void*>(next_tag++));
   gpr_log(GPR_DEBUG, "number of active connect watchers: %d",
           grpc_channel_num_external_connectivity_watchers(channel));
 }
@@ -136,7 +137,8 @@ static void run_channel_shutdown_before_timeout_test(
              GRPC_CHANNEL_IDLE);
 
   grpc_channel_watch_connectivity_state(channel, GRPC_CHANNEL_IDLE,
-                                        connect_deadline, cq, (void*)1);
+                                        connect_deadline, cq,
+                                        reinterpret_cast<void*>(1));
   grpc_channel_destroy(channel);
 
   grpc_event ev = grpc_completion_queue_next(
index 4b821be..22f89ba 100644 (file)
@@ -126,6 +126,9 @@ int main(int argc, char **argv) {
   printf("%lx", (unsigned long) grpc_server_request_registered_call);
   printf("%lx", (unsigned long) grpc_server_create);
   printf("%lx", (unsigned long) grpc_server_register_completion_queue);
+  printf("%lx", (unsigned long) grpc_server_config_fetcher_xds_create);
+  printf("%lx", (unsigned long) grpc_server_config_fetcher_destroy);
+  printf("%lx", (unsigned long) grpc_server_set_config_fetcher);
   printf("%lx", (unsigned long) grpc_server_add_insecure_http2_port);
   printf("%lx", (unsigned long) grpc_server_start);
   printf("%lx", (unsigned long) grpc_server_shutdown_and_notify);
@@ -174,6 +177,7 @@ int main(int argc, char **argv) {
   printf("%lx", (unsigned long) grpc_google_compute_engine_credentials_create);
   printf("%lx", (unsigned long) grpc_max_auth_token_lifetime);
   printf("%lx", (unsigned long) grpc_service_account_jwt_access_credentials_create);
+  printf("%lx", (unsigned long) grpc_external_account_credentials_create);
   printf("%lx", (unsigned long) grpc_google_refresh_token_credentials_create);
   printf("%lx", (unsigned long) grpc_access_token_credentials_create);
   printf("%lx", (unsigned long) grpc_google_iam_credentials_create);
@@ -206,6 +210,7 @@ int main(int argc, char **argv) {
   printf("%lx", (unsigned long) grpc_tls_identity_pairs_add_pair);
   printf("%lx", (unsigned long) grpc_tls_identity_pairs_destroy);
   printf("%lx", (unsigned long) grpc_tls_certificate_provider_static_data_create);
+  printf("%lx", (unsigned long) grpc_tls_certificate_provider_file_watcher_create);
   printf("%lx", (unsigned long) grpc_tls_certificate_provider_release);
   printf("%lx", (unsigned long) grpc_tls_credentials_options_create);
   printf("%lx", (unsigned long) grpc_tls_credentials_options_set_cert_request_type);
@@ -219,6 +224,7 @@ int main(int argc, char **argv) {
   printf("%lx", (unsigned long) grpc_tls_server_authorization_check_config_create);
   printf("%lx", (unsigned long) grpc_tls_server_authorization_check_config_release);
   printf("%lx", (unsigned long) grpc_xds_credentials_create);
+  printf("%lx", (unsigned long) grpc_xds_server_credentials_create);
   printf("%lx", (unsigned long) grpc_raw_byte_buffer_create);
   printf("%lx", (unsigned long) grpc_raw_compressed_byte_buffer_create);
   printf("%lx", (unsigned long) grpc_byte_buffer_copy);
index 3452c86..fb03732 100644 (file)
@@ -55,13 +55,13 @@ static void test_basic_add_find(uint32_t n) {
   grpc_chttp2_stream_map_init(&map, 8);
   GPR_ASSERT(0 == grpc_chttp2_stream_map_size(&map));
   for (i = 1; i <= n; i++) {
-    grpc_chttp2_stream_map_add(&map, i, (void*)static_cast<uintptr_t>(i));
+    grpc_chttp2_stream_map_add(&map, i, reinterpret_cast<void*>(i));
   }
   GPR_ASSERT(n == grpc_chttp2_stream_map_size(&map));
   GPR_ASSERT(nullptr == grpc_chttp2_stream_map_find(&map, 0));
   GPR_ASSERT(nullptr == grpc_chttp2_stream_map_find(&map, n + 1));
   for (i = 1; i <= n; i++) {
-    got = (uintptr_t)grpc_chttp2_stream_map_find(&map, i);
+    got = reinterpret_cast<uintptr_t>(grpc_chttp2_stream_map_find(&map, i));
     GPR_ASSERT(i == got);
   }
   grpc_chttp2_stream_map_destroy(&map);
@@ -84,7 +84,7 @@ static void check_delete_evens(grpc_chttp2_stream_map* map, uint32_t n) {
   GPR_ASSERT(nullptr == grpc_chttp2_stream_map_find(map, n + 1));
   for (i = 1; i <= n; i++) {
     if (i & 1) {
-      got = (uintptr_t)grpc_chttp2_stream_map_find(map, i);
+      got = reinterpret_cast<uintptr_t>(grpc_chttp2_stream_map_find(map, i));
       GPR_ASSERT(i == got);
     } else {
       GPR_ASSERT(nullptr == grpc_chttp2_stream_map_find(map, i));
@@ -110,7 +110,7 @@ static void test_delete_evens_sweep(uint32_t n) {
 
   grpc_chttp2_stream_map_init(&map, 8);
   for (i = 1; i <= n; i++) {
-    grpc_chttp2_stream_map_add(&map, i, (void*)static_cast<uintptr_t>(i));
+    grpc_chttp2_stream_map_add(&map, i, reinterpret_cast<void*>(i));
   }
   for (i = 1; i <= n; i++) {
     if ((i & 1) == 0) {
@@ -132,7 +132,7 @@ static void test_delete_evens_incremental(uint32_t n) {
 
   grpc_chttp2_stream_map_init(&map, 8);
   for (i = 1; i <= n; i++) {
-    grpc_chttp2_stream_map_add(&map, i, (void*)static_cast<uintptr_t>(i));
+    grpc_chttp2_stream_map_add(&map, i, reinterpret_cast<void*>(i));
     if ((i & 1) == 0) {
       grpc_chttp2_stream_map_delete(&map, i);
     }
@@ -154,7 +154,7 @@ static void test_periodic_compaction(uint32_t n) {
   grpc_chttp2_stream_map_init(&map, 16);
   GPR_ASSERT(map.capacity == 16);
   for (i = 1; i <= n; i++) {
-    grpc_chttp2_stream_map_add(&map, i, (void*)static_cast<uintptr_t>(i));
+    grpc_chttp2_stream_map_add(&map, i, reinterpret_cast<void*>(i));
     if (i > 8) {
       del = i - 8;
       GPR_ASSERT((void*)(uintptr_t)del ==
index 2356bb5..abb3ae5 100644 (file)
@@ -59,7 +59,7 @@
 
 namespace {
 
-void* tag(int i) { return (void*)static_cast<intptr_t>(i); }
+void* tag(intptr_t t) { return reinterpret_cast<void*>(t); }
 
 // Perform a simple RPC where the server cancels the request with
 // grpc_call_cancel_with_status
@@ -249,10 +249,10 @@ grpc_status_code PerformWaitingCall(grpc_channel* channel, grpc_server* server,
 // Shuts down and destroys the server.
 void ServerShutdownAndDestroy(grpc_server* server, grpc_completion_queue* cq) {
   // Shutdown and destroy server
-  grpc_server_shutdown_and_notify(server, cq, (void*)(1000));
+  grpc_server_shutdown_and_notify(server, cq, reinterpret_cast<void*>(1000));
   while (grpc_completion_queue_next(cq, gpr_inf_future(GPR_CLOCK_REALTIME),
                                     nullptr)
-             .tag != (void*)(1000)) {
+             .tag != reinterpret_cast<void*>(1000)) {
   }
   grpc_server_destroy(server);
 }
@@ -273,11 +273,11 @@ void VerifyChannelDisconnected(grpc_channel* channel,
                                grpc_completion_queue* cq) {
   // Verify channel gets disconnected. Use a ping to make sure that clients
   // tries sending/receiving bytes if the channel is connected.
-  grpc_channel_ping(channel, cq, (void*)(2000), nullptr);
+  grpc_channel_ping(channel, cq, reinterpret_cast<void*>(2000), nullptr);
   grpc_event ev = grpc_completion_queue_next(
       cq, grpc_timeout_seconds_to_deadline(5), nullptr);
   GPR_ASSERT(ev.type == GRPC_OP_COMPLETE);
-  GPR_ASSERT(ev.tag == (void*)(2000));
+  GPR_ASSERT(ev.tag == reinterpret_cast<void*>(2000));
   GPR_ASSERT(ev.success == 0);
   GPR_ASSERT(grpc_channel_check_connectivity_state(channel, 0) !=
              GRPC_CHANNEL_READY);
@@ -362,15 +362,15 @@ grpc_core::Resolver::Result BuildResolverResult(
     const std::vector<std::string>& addresses) {
   grpc_core::Resolver::Result result;
   for (const auto& address_str : addresses) {
-    grpc_uri* uri = grpc_uri_parse(address_str.c_str(), true);
-    if (uri == nullptr) {
-      gpr_log(GPR_ERROR, "Failed to parse uri:%s", address_str.c_str());
-      GPR_ASSERT(0);
+    absl::StatusOr<grpc_core::URI> uri = grpc_core::URI::Parse(address_str);
+    if (!uri.ok()) {
+      gpr_log(GPR_ERROR, "Failed to parse uri. Error: %s",
+              uri.status().ToString().c_str());
+      GPR_ASSERT(uri.ok());
     }
     grpc_resolved_address address;
-    GPR_ASSERT(grpc_parse_uri(uri, &address));
+    GPR_ASSERT(grpc_parse_uri(*uri, &address));
     result.addresses.emplace_back(address.addr, address.len, nullptr);
-    grpc_uri_destroy(uri);
   }
   return result;
 }
@@ -707,9 +707,9 @@ TEST(TooManyPings, BdpPingNotSentWithoutReceiveSideActivity) {
   grpc_channel_ping(channel, cq, tag(4), nullptr);
   CQ_EXPECT_COMPLETION(cqv, tag(4), 1);
   cq_verify(cqv, 5);
-  cq_verify_empty_timeout(cqv, 1);
-  ASSERT_NE(grpc_channel_check_connectivity_state(channel, 0),
-            GRPC_CHANNEL_READY);
+  // Give some time for the server to disconnect if it hasn't already.
+  cq_verify_empty_timeout(cqv, 3);
+  VerifyChannelDisconnected(channel, cq);
   cq_verifier_destroy(cqv);
   // shutdown and destroy the client and server
   ServerShutdownAndDestroy(server, cq);
index c682fb8..89c887f 100644 (file)
@@ -42,7 +42,7 @@ void gsec_test_random_array(uint8_t** bytes, size_t length) {
 
 uint32_t gsec_test_bias_random_uint32(uint32_t max_length) {
   uint32_t value;
-  gsec_test_random_bytes((uint8_t*)(&value), sizeof(value));
+  gsec_test_random_bytes(reinterpret_cast<uint8_t*>(&value), sizeof(value));
   return value % max_length;
 }
 
index 1bd7800..9182a22 100644 (file)
@@ -55,9 +55,9 @@ uint32_t gsec_test_bias_random_uint32(uint32_t max_length);
  *
  * - src: a source buffer.
  * - des: a destination buffer.
- * - length: the length of source buffer to be copied from its beginning.
+ * - source_len: the length of source buffer to be copied from its beginning.
  */
-void gsec_test_copy(const uint8_t* src, uint8_t** des, size_t length);
+void gsec_test_copy(const uint8_t* src, uint8_t** des, size_t source_len);
 
 /**
  * This method copies data from a source to a destination buffer, and flips one
index 6780eb7..8bfa530 100644 (file)
@@ -107,7 +107,7 @@ static void frame_n_deframe(frame_handler* handler, unsigned char* payload,
 
 static void frame_handler_test_frame_deframe() {
   unsigned char payload[] = "hello world";
-  size_t payload_length = strlen((char*)payload) + 1;
+  size_t payload_length = strlen(reinterpret_cast<char*>(payload)) + 1;
   frame_handler* handler = create_frame_handler();
   frame_n_deframe(handler, payload, payload_length,
                   frame_length(payload_length), frame_length(payload_length));
index 09e1557..bc2eca1 100644 (file)
@@ -104,7 +104,7 @@ grpc_channel* create_secure_channel_for_test(
 
 class FakeHandshakeServer {
  public:
-  FakeHandshakeServer(bool check_num_concurrent_rpcs) {
+  explicit FakeHandshakeServer(bool check_num_concurrent_rpcs) {
     int port = grpc_pick_unused_port_or_die();
     address_ = grpc_core::JoinHostPort("localhost", port);
     if (check_num_concurrent_rpcs) {
@@ -368,8 +368,9 @@ class FakeTcpServer {
     memset(&addr, 0, sizeof(addr));
     addr.sin6_family = AF_INET6;
     addr.sin6_port = htons(port_);
-    ((char*)&addr.sin6_addr)[15] = 1;
-    if (bind(accept_socket_, (const sockaddr*)&addr, sizeof(addr)) != 0) {
+    (reinterpret_cast<char*>(&addr.sin6_addr))[15] = 1;
+    if (bind(accept_socket_, reinterpret_cast<const sockaddr*>(&addr),
+             sizeof(addr)) != 0) {
       gpr_log(GPR_ERROR, "Failed to bind socket to [::1]:%d : %d", port_,
               errno);
       abort();
@@ -387,7 +388,7 @@ class FakeTcpServer {
     gpr_log(GPR_DEBUG,
             "FakeTcpServer stop and "
             "join server thread");
-    gpr_event_set(&stop_ev_, (void*)1);
+    gpr_event_set(&stop_ev_, reinterpret_cast<void*>(1));
     run_server_loop_thd_->join();
     gpr_log(GPR_DEBUG,
             "FakeTcpServer join server "
index 6105304..a450001 100644 (file)
@@ -366,8 +366,8 @@ static void ssl_test_check_handshaker_peers(tsi_test_fixture* fixture) {
 }
 
 static void ssl_test_pem_key_cert_pair_destroy(tsi_ssl_pem_key_cert_pair kp) {
-  gpr_free((void*)kp.private_key);
-  gpr_free((void*)kp.cert_chain);
+  gpr_free(const_cast<char*>(kp.private_key));
+  gpr_free(const_cast<char*>(kp.cert_chain));
 }
 
 static void ssl_test_destruct(tsi_test_fixture* fixture) {
index 26349db..2975cee 100644 (file)
@@ -197,7 +197,8 @@ void tsi_test_frame_protector_send_message_to_peer(
   uint8_t* message =
       is_client ? config->client_message : config->server_message;
   GPR_ASSERT(message != nullptr);
-  const unsigned char* message_bytes = (const unsigned char*)message;
+  const unsigned char* message_bytes =
+      reinterpret_cast<unsigned char*>(message);
   tsi_result result = TSI_OK;
   /* Do protect and send protected data to peer. */
   while (message_size > 0 && result == TSI_OK) {
@@ -370,10 +371,10 @@ static void do_handshaker_next(handshaker_args* args) {
       args->transferred_data = true;
     }
     /* Peform handshaker next. */
-    result = tsi_handshaker_next(handshaker, args->handshake_buffer, buf_size,
-                                 (const unsigned char**)&bytes_to_send,
-                                 &bytes_to_send_size, &handshaker_result,
-                                 &on_handshake_next_done_wrapper, args);
+    result = tsi_handshaker_next(
+        handshaker, args->handshake_buffer, buf_size,
+        const_cast<const unsigned char**>(&bytes_to_send), &bytes_to_send_size,
+        &handshaker_result, &on_handshake_next_done_wrapper, args);
     if (result != TSI_ASYNC) {
       args->error = on_handshake_next_done(
           result, args, bytes_to_send, bytes_to_send_size, handshaker_result);
index 40ffea9..aaa9b68 100644 (file)
@@ -36,9 +36,9 @@ grpc_fuzzer(
 grpc_cc_test(
     name = "uri_parser_test",
     srcs = ["uri_parser_test.cc"],
+    external_deps = ["gtest"],
     language = "C++",
     deps = [
-        "//:gpr",
         "//:grpc",
         "//test/core/util:grpc_test_util",
     ],
index 9124a31..de6e8df 100644 (file)
@@ -38,11 +38,7 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
 
   {
     grpc_core::ExecCtx exec_ctx;
-    grpc_uri* x;
-    if ((x = grpc_uri_parse(s, true))) {
-      grpc_uri_destroy(x);
-    }
-
+    (void)grpc_core::URI::Parse(s);
     gpr_free(s);
   }
 
index 9659160..ec79a63 100644 (file)
  *
  */
 
+// TODO(hork): rewrite with googletest
+
 #include "src/core/lib/uri/uri_parser.h"
 
-#include <string.h>
+#include "absl/strings/str_join.h"
+#include "absl/strings/str_split.h"
 
+#include <gmock/gmock.h>
 #include <grpc/grpc.h>
 #include <grpc/support/log.h>
+#include <gtest/gtest.h>
 
-#include "src/core/lib/iomgr/exec_ctx.h"
 #include "test/core/util/test_config.h"
 
-static void test_succeeds(const char* uri_text, const char* scheme,
-                          const char* authority, const char* path,
-                          const char* query, const char* fragment) {
-  grpc_core::ExecCtx exec_ctx;
-  grpc_uri* uri = grpc_uri_parse(uri_text, false);
-  GPR_ASSERT(uri);
-  GPR_ASSERT(0 == strcmp(scheme, uri->scheme));
-  GPR_ASSERT(0 == strcmp(authority, uri->authority));
-  GPR_ASSERT(0 == strcmp(path, uri->path));
-  GPR_ASSERT(0 == strcmp(query, uri->query));
-  GPR_ASSERT(0 == strcmp(fragment, uri->fragment));
+using ::testing::ContainerEq;
+using ::testing::Contains;
+using ::testing::ElementsAre;
+using ::testing::Pair;
+
+static void TestSucceeds(
+    absl::string_view uri_text, absl::string_view scheme,
+    absl::string_view authority, absl::string_view path,
+    const std::map<absl::string_view, absl::string_view>& query_param_map,
+    const std::vector<grpc_core::URI::QueryParam>& query_param_pairs,
+    absl::string_view fragment) {
+  absl::StatusOr<grpc_core::URI> uri = grpc_core::URI::Parse(uri_text);
+  ASSERT_TRUE(uri.ok());
+  EXPECT_EQ(scheme, uri->scheme());
+  EXPECT_EQ(authority, uri->authority());
+  EXPECT_EQ(path, uri->path());
+  EXPECT_THAT(uri->query_parameter_map(), ContainerEq(query_param_map));
+  EXPECT_THAT(uri->query_parameter_pairs(), ContainerEq(query_param_pairs));
+  EXPECT_EQ(fragment, uri->fragment());
+}
+
+static void TestFails(absl::string_view uri_text) {
+  absl::StatusOr<grpc_core::URI> uri = grpc_core::URI::Parse(uri_text);
+  ASSERT_FALSE(uri.ok());
+}
+
+TEST(URIParserTest, BasicExamplesAreParsedCorrectly) {
+  TestSucceeds("http://www.google.com", "http", "www.google.com", "", {}, {},
+               "");
+  TestSucceeds("dns:///foo", "dns", "", "/foo", {}, {}, "");
+  TestSucceeds("http://www.google.com:90", "http", "www.google.com:90", "", {},
+               {}, "");
+  TestSucceeds("a192.4-df:foo.coom", "a192.4-df", "", "foo.coom", {}, {}, "");
+  TestSucceeds("a+b:foo.coom", "a+b", "", "foo.coom", {}, {}, "");
+  TestSucceeds("zookeeper://127.0.0.1:2181/foo/bar", "zookeeper",
+               "127.0.0.1:2181", "/foo/bar", {}, {}, "");
+  TestSucceeds("dns:foo.com#fragment-all-the-things", "dns", "", "foo.com", {},
+               {}, "fragment-all-the-things");
+  TestSucceeds("http://localhost:8080/whatzit?mi_casa=su_casa", "http",
+               "localhost:8080", "/whatzit", {{"mi_casa", "su_casa"}},
+               {{"mi_casa", "su_casa"}}, "");
+  TestSucceeds("http://localhost:8080/whatzit?1=2#buckle/my/shoe", "http",
+               "localhost:8080", "/whatzit", {{"1", "2"}}, {{"1", "2"}},
+               "buckle/my/shoe");
+}
+
+TEST(URIParserTest, UncommonValidExamplesAreParsedCorrectly) {
+  TestSucceeds("scheme:path//is/ok", "scheme", "", "path//is/ok", {}, {}, "");
+  TestSucceeds("http:?legit", "http", "", "", {{"legit", ""}}, {{"legit", ""}},
+               "");
+  TestSucceeds("unix:#this-is-ok-too", "unix", "", "", {}, {},
+               "this-is-ok-too");
+  TestSucceeds("http:?legit#twice", "http", "", "", {{"legit", ""}},
+               {{"legit", ""}}, "twice");
+  TestSucceeds("fake:///", "fake", "", "/", {}, {}, "");
+}
 
-  grpc_uri_destroy(uri);
+TEST(URIParserTest, VariousKeyValueAndNonKVQueryParamsAreParsedCorrectly) {
+  TestSucceeds("http://foo/path?a&b=B&c=&#frag", "http", "foo", "/path",
+               {{"c", ""}, {"a", ""}, {"b", "B"}},
+               {{"a", ""}, {"b", "B"}, {"c", ""}}, "frag");
 }
 
-static void test_fails(const char* uri_text) {
-  grpc_core::ExecCtx exec_ctx;
-  GPR_ASSERT(nullptr == grpc_uri_parse(uri_text, 0));
+TEST(URIParserTest, ParserTreatsFirstEqualSignAsKVDelimiterInQueryString) {
+  TestSucceeds(
+      "http://localhost:8080/?too=many=equals&are=present=here#fragged", "http",
+      "localhost:8080", "/", {{"are", "present=here"}, {"too", "many=equals"}},
+      {{"too", "many=equals"}, {"are", "present=here"}}, "fragged");
+  TestSucceeds("http://auth/path?foo=bar=baz&foobar===", "http", "auth",
+               "/path", {{"foo", "bar=baz"}, {"foobar", "=="}},
+               {{"foo", "bar=baz"}, {"foobar", "=="}}, "");
 }
 
-static void test_query_parts() {
+TEST(URIParserTest,
+     RepeatedQueryParamsAreSupportedInOrderedPairsButDeduplicatedInTheMap) {
+  absl::StatusOr<grpc_core::URI> uri =
+      grpc_core::URI::Parse("http://foo/path?a=2&a=1&a=3");
+  ASSERT_TRUE(uri.ok());
+  // The map stores the last found value.
+  ASSERT_THAT(uri->query_parameter_map(), ElementsAre(Pair("a", "3")));
+  // Order matters for query parameter pairs
+  ASSERT_THAT(uri->query_parameter_pairs(),
+              ElementsAre(grpc_core::URI::QueryParam{"a", "2"},
+                          grpc_core::URI::QueryParam{"a", "1"},
+                          grpc_core::URI::QueryParam{"a", "3"}));
+}
+
+TEST(URIParserTest, QueryParamMapRemainsValiditAfterMovingTheURI) {
+  grpc_core::URI uri_copy;
   {
-    grpc_core::ExecCtx exec_ctx;
-    const char* uri_text = "http://foo/path?a&b=B&c=&#frag";
-    grpc_uri* uri = grpc_uri_parse(uri_text, false);
-    GPR_ASSERT(uri);
+    absl::StatusOr<grpc_core::URI> uri =
+        grpc_core::URI::Parse("http://foo/path?a=2&b=1&c=3");
+    ASSERT_TRUE(uri.ok());
+    uri_copy = std::move(*uri);
+  }
+  // ASSERT_EQ(uri_copy.query_parameter_map().find("a")->second, "2");
+  ASSERT_THAT(uri_copy.query_parameter_map(), Contains(Pair("a", "2")));
+}
+
+TEST(URIParserTest, QueryParamMapRemainsValidAfterCopyingTheURI) {
+  // Since the query parameter map points to objects stored in the param pair
+  // vector, this test checks that the param map pointers remain valid after
+  // a copy. Ideally {a,m}san will catch this if there's a problem.
+  // testing copy operator=:
+  grpc_core::URI uri_copy;
+  {
+    absl::StatusOr<grpc_core::URI> del_uri =
+        grpc_core::URI::Parse("http://foo/path?a=2&b=1&c=3");
+    ASSERT_TRUE(del_uri.ok());
+    uri_copy = *del_uri;
+  }
+  ASSERT_THAT(uri_copy.query_parameter_map(), Contains(Pair("a", "2")));
+  grpc_core::URI* del_uri2 = new grpc_core::URI(uri_copy);
+  grpc_core::URI uri_copy2(*del_uri2);
+  delete del_uri2;
+  ASSERT_THAT(uri_copy2.query_parameter_map(), Contains(Pair("a", "2")));
+}
 
-    GPR_ASSERT(0 == strcmp("http", uri->scheme));
-    GPR_ASSERT(0 == strcmp("foo", uri->authority));
-    GPR_ASSERT(0 == strcmp("/path", uri->path));
-    GPR_ASSERT(0 == strcmp("a&b=B&c=&", uri->query));
-    GPR_ASSERT(4 == uri->num_query_parts);
+TEST(URIParserTest, AWSExternalAccountRegressionTest) {
+  TestSucceeds(
+      "https://foo.com:5555/v1/"
+      "token-exchange?subject_token=eyJhbGciO&subject_token_type=urn:ietf:"
+      "params:oauth:token-type:id_token",
+      "https", "foo.com:5555", "/v1/token-exchange",
+      {{"subject_token", "eyJhbGciO"},
+       {"subject_token_type", "urn:ietf:params:oauth:token-type:id_token"}},
+      {{"subject_token", "eyJhbGciO"},
+       {"subject_token_type", "urn:ietf:params:oauth:token-type:id_token"}},
+      "");
+}
 
-    GPR_ASSERT(0 == strcmp("a", uri->query_parts[0]));
-    GPR_ASSERT(nullptr == uri->query_parts_values[0]);
+TEST(URIParserTest, NonKeyValueQueryStringsWork) {
+  TestSucceeds("http://www.google.com?yay-i'm-using-queries", "http",
+               "www.google.com", "", {{"yay-i'm-using-queries", ""}},
+               {{"yay-i'm-using-queries", ""}}, "");
+}
 
-    GPR_ASSERT(0 == strcmp("b", uri->query_parts[1]));
-    GPR_ASSERT(0 == strcmp("B", uri->query_parts_values[1]));
+TEST(URIParserTest, IPV6StringsAreParsedCorrectly) {
+  TestSucceeds("ipv6:[2001:db8::1%252]:12345", "ipv6", "",
+               "[2001:db8::1%2]:12345", {}, {}, "");
+  TestSucceeds("ipv6:[fe80::90%eth1.sky1]:6010", "ipv6", "",
+               "[fe80::90%eth1.sky1]:6010", {}, {}, "");
+}
 
-    GPR_ASSERT(0 == strcmp("c", uri->query_parts[2]));
-    GPR_ASSERT(0 == strcmp("", uri->query_parts_values[2]));
+TEST(URIParserTest, PreviouslyReservedCharactersInUnrelatedURIPartsAreIgnored) {
+  // The '?' and '/' characters are not reserved delimiter characters in the
+  // fragment. See http://go/rfc/3986#section-3.5
+  TestSucceeds("http://foo?bar#lol?", "http", "foo", "", {{"bar", ""}},
+               {{"bar", ""}}, "lol?");
+  TestSucceeds("http://foo?bar#lol?/", "http", "foo", "", {{"bar", ""}},
+               {{"bar", ""}}, "lol?/");
+}
 
-    GPR_ASSERT(0 == strcmp("", uri->query_parts[3]));
-    GPR_ASSERT(nullptr == uri->query_parts_values[3]);
+TEST(URIParserTest, EncodedCharactersInQueryStringAreParsedCorrectly) {
+  TestSucceeds("https://www.google.com/?a=1%26b%3D2&c=3", "https",
+               "www.google.com", "/", {{"c", "3"}, {"a", "1&b=2"}},
+               {{"a", "1&b=2"}, {"c", "3"}}, "");
+}
 
-    GPR_ASSERT(nullptr == grpc_uri_get_query_arg(uri, "a"));
-    GPR_ASSERT(0 == strcmp("B", grpc_uri_get_query_arg(uri, "b")));
-    GPR_ASSERT(0 == strcmp("", grpc_uri_get_query_arg(uri, "c")));
-    GPR_ASSERT(nullptr == grpc_uri_get_query_arg(uri, ""));
+TEST(URIParserTest, InvalidPercentEncodingsArePassedThrough) {
+  TestSucceeds("x:y?%xx", "x", "", "y", {{"%xx", ""}}, {{"%xx", ""}}, "");
+  TestSucceeds("http:?dangling-pct-%0", "http", "", "",
+               {{"dangling-pct-%0", ""}}, {{"dangling-pct-%0", ""}}, "");
+}
 
-    GPR_ASSERT(0 == strcmp("frag", uri->fragment));
+TEST(URIParserTest, NullCharactersInURIStringAreSupported) {
+  // Artificial examples to show that embedded nulls are supported.
+  TestSucceeds(std::string("unix-abstract:\0should-be-ok", 27), "unix-abstract",
+               "", std::string("\0should-be-ok", 13), {}, {}, "");
+}
 
-    grpc_uri_destroy(uri);
-  }
-  {
-    /* test the current behavior of multiple query part values */
-    grpc_core::ExecCtx exec_ctx;
-    const char* uri_text = "http://auth/path?foo=bar=baz&foobar==";
-    grpc_uri* uri = grpc_uri_parse(uri_text, false);
-    GPR_ASSERT(uri);
-
-    GPR_ASSERT(0 == strcmp("http", uri->scheme));
-    GPR_ASSERT(0 == strcmp("auth", uri->authority));
-    GPR_ASSERT(0 == strcmp("/path", uri->path));
-    GPR_ASSERT(0 == strcmp("foo=bar=baz&foobar==", uri->query));
-    GPR_ASSERT(2 == uri->num_query_parts);
-
-    GPR_ASSERT(0 == strcmp("bar", grpc_uri_get_query_arg(uri, "foo")));
-    GPR_ASSERT(0 == strcmp("", grpc_uri_get_query_arg(uri, "foobar")));
-
-    grpc_uri_destroy(uri);
-  }
-  {
-    /* empty query */
-    grpc_core::ExecCtx exec_ctx;
-    const char* uri_text = "http://foo/path";
-    grpc_uri* uri = grpc_uri_parse(uri_text, false);
-    GPR_ASSERT(uri);
-
-    GPR_ASSERT(0 == strcmp("http", uri->scheme));
-    GPR_ASSERT(0 == strcmp("foo", uri->authority));
-    GPR_ASSERT(0 == strcmp("/path", uri->path));
-    GPR_ASSERT(0 == strcmp("", uri->query));
-    GPR_ASSERT(0 == uri->num_query_parts);
-    GPR_ASSERT(nullptr == uri->query_parts);
-    GPR_ASSERT(nullptr == uri->query_parts_values);
-    GPR_ASSERT(0 == strcmp("", uri->fragment));
-
-    grpc_uri_destroy(uri);
-  }
+TEST(URIParserTest, EncodedNullsInURIStringAreSupported) {
+  TestSucceeds("unix-abstract:%00x", "unix-abstract", "", std::string("\0x", 2),
+               {}, {}, "");
+}
+
+TEST(URIParserTest, InvalidURIsResultInFailureStatuses) {
+  TestFails("xyz");
+  TestFails("http://foo?[bar]");
+  TestFails("http://foo?x[bar]");
+  TestFails("http://foo?bar#lol#");
+  TestFails("");
+  TestFails(":no_scheme");
+  TestFails("0invalid_scheme:must_start/with?alpha");
 }
 
 int main(int argc, char** argv) {
+  testing::InitGoogleTest(&argc, argv);
   grpc::testing::TestEnvironment env(argc, argv);
   grpc_init();
-  test_succeeds("http://www.google.com", "http", "www.google.com", "", "", "");
-  test_succeeds("dns:///foo", "dns", "", "/foo", "", "");
-  test_succeeds("http://www.google.com:90", "http", "www.google.com:90", "", "",
-                "");
-  test_succeeds("a192.4-df:foo.coom", "a192.4-df", "", "foo.coom", "", "");
-  test_succeeds("a+b:foo.coom", "a+b", "", "foo.coom", "", "");
-  test_succeeds("zookeeper://127.0.0.1:2181/foo/bar", "zookeeper",
-                "127.0.0.1:2181", "/foo/bar", "", "");
-  test_succeeds("http://www.google.com?yay-i'm-using-queries", "http",
-                "www.google.com", "", "yay-i'm-using-queries", "");
-  test_succeeds("dns:foo.com#fragment-all-the-things", "dns", "", "foo.com", "",
-                "fragment-all-the-things");
-  test_succeeds("http:?legit", "http", "", "", "legit", "");
-  test_succeeds("unix:#this-is-ok-too", "unix", "", "", "", "this-is-ok-too");
-  test_succeeds("http:?legit#twice", "http", "", "", "legit", "twice");
-  test_succeeds("http://foo?bar#lol?", "http", "foo", "", "bar", "lol?");
-  test_succeeds("http://foo?bar#lol?/", "http", "foo", "", "bar", "lol?/");
-  test_succeeds("ipv6:[2001:db8::1%252]:12345", "ipv6", "",
-                "[2001:db8::1%2]:12345", "", "");
-
-  test_fails("xyz");
-  test_fails("http:?dangling-pct-%0");
-  test_fails("http://foo?[bar]");
-  test_fails("http://foo?x[bar]");
-  test_fails("http://foo?bar#lol#");
-
-  test_query_parts();
+  auto result = RUN_ALL_TESTS();
   grpc_shutdown();
-  return 0;
+  return result;
 }
index feaeeab..f4520b8 100644 (file)
@@ -22,19 +22,6 @@ grpc_package(
 )
 
 grpc_cc_library(
-    name = "grpc_debugger_macros",
-    srcs = [
-        "debugger_macros.cc",
-    ],
-    hdrs = [
-        "debugger_macros.h",
-    ],
-    deps = [
-        "//:grpc_common",
-    ],
-)
-
-grpc_cc_library(
     name = "grpc_test_util_base",
     srcs = [
         "cmdline.cc",
@@ -91,7 +78,6 @@ grpc_cc_library(
     ],
     language = "C++",
     deps = [
-        ":grpc_debugger_macros",
         ":stack_tracer",
         "//:gpr",
         "//:grpc_base_c",
@@ -101,8 +87,8 @@ grpc_cc_library(
 
 grpc_cc_library(
     name = "grpc_test_util",
-    srcs = [],
-    hdrs = [],
+    srcs = ["tls_utils.cc"],
+    hdrs = ["tls_utils.h"],
     language = "C++",
     deps = [
         ":grpc_test_util_base",
index c213f84..23e52e6 100644 (file)
@@ -59,7 +59,7 @@ struct gpr_cmdline {
   int survive_failure;
 };
 
-static int normal_state(gpr_cmdline* cl, char* arg);
+static int normal_state(gpr_cmdline* cl, char* str);
 
 gpr_cmdline* gpr_cmdline_create(const char* description) {
   gpr_cmdline* cl = static_cast<gpr_cmdline*>(gpr_zalloc(sizeof(gpr_cmdline)));
index c15e5e3..c1eb5e3 100644 (file)
@@ -30,7 +30,7 @@
 static void test_simple_int(void) {
   int x = 1;
   gpr_cmdline* cl;
-  char* args[] = {(char*)__FILE__, const_cast<char*>("-foo"),
+  char* args[] = {const_cast<char*>(__FILE__), const_cast<char*>("-foo"),
                   const_cast<char*>("3")};
 
   LOG_TEST();
@@ -46,7 +46,7 @@ static void test_simple_int(void) {
 static void test_eq_int(void) {
   int x = 1;
   gpr_cmdline* cl;
-  char* args[] = {(char*)__FILE__, const_cast<char*>("-foo=3")};
+  char* args[] = {const_cast<char*>(__FILE__), const_cast<char*>("-foo=3")};
 
   LOG_TEST();
 
@@ -61,7 +61,7 @@ static void test_eq_int(void) {
 static void test_2dash_int(void) {
   int x = 1;
   gpr_cmdline* cl;
-  char* args[] = {(char*)__FILE__, const_cast<char*>("--foo"),
+  char* args[] = {const_cast<char*>(__FILE__), const_cast<char*>("--foo"),
                   const_cast<char*>("3")};
 
   LOG_TEST();
@@ -77,7 +77,7 @@ static void test_2dash_int(void) {
 static void test_2dash_eq_int(void) {
   int x = 1;
   gpr_cmdline* cl;
-  char* args[] = {(char*)__FILE__, const_cast<char*>("--foo=3")};
+  char* args[] = {const_cast<char*>(__FILE__), const_cast<char*>("--foo=3")};
 
   LOG_TEST();
 
@@ -92,7 +92,7 @@ static void test_2dash_eq_int(void) {
 static void test_simple_string(void) {
   const char* x = nullptr;
   gpr_cmdline* cl;
-  char* args[] = {(char*)__FILE__, const_cast<char*>("-foo"),
+  char* args[] = {const_cast<char*>(__FILE__), const_cast<char*>("-foo"),
                   const_cast<char*>("3")};
 
   LOG_TEST();
@@ -108,7 +108,7 @@ static void test_simple_string(void) {
 static void test_eq_string(void) {
   const char* x = nullptr;
   gpr_cmdline* cl;
-  char* args[] = {(char*)__FILE__, const_cast<char*>("-foo=3")};
+  char* args[] = {const_cast<char*>(__FILE__), const_cast<char*>("-foo=3")};
 
   LOG_TEST();
 
@@ -123,7 +123,7 @@ static void test_eq_string(void) {
 static void test_2dash_string(void) {
   const char* x = nullptr;
   gpr_cmdline* cl;
-  char* args[] = {(char*)__FILE__, const_cast<char*>("--foo"),
+  char* args[] = {const_cast<char*>(__FILE__), const_cast<char*>("--foo"),
                   const_cast<char*>("3")};
 
   LOG_TEST();
@@ -139,7 +139,7 @@ static void test_2dash_string(void) {
 static void test_2dash_eq_string(void) {
   const char* x = nullptr;
   gpr_cmdline* cl;
-  char* args[] = {(char*)__FILE__, const_cast<char*>("--foo=3")};
+  char* args[] = {const_cast<char*>(__FILE__), const_cast<char*>("--foo=3")};
 
   LOG_TEST();
 
@@ -154,7 +154,7 @@ static void test_2dash_eq_string(void) {
 static void test_flag_on(void) {
   int x = 2;
   gpr_cmdline* cl;
-  char* args[] = {(char*)__FILE__, const_cast<char*>("--foo")};
+  char* args[] = {const_cast<char*>(__FILE__), const_cast<char*>("--foo")};
 
   LOG_TEST();
 
@@ -169,7 +169,7 @@ static void test_flag_on(void) {
 static void test_flag_no(void) {
   int x = 2;
   gpr_cmdline* cl;
-  char* args[] = {(char*)__FILE__, const_cast<char*>("--no-foo")};
+  char* args[] = {const_cast<char*>(__FILE__), const_cast<char*>("--no-foo")};
 
   LOG_TEST();
 
@@ -184,7 +184,7 @@ static void test_flag_no(void) {
 static void test_flag_val_1(void) {
   int x = 2;
   gpr_cmdline* cl;
-  char* args[] = {(char*)__FILE__, const_cast<char*>("--foo=1")};
+  char* args[] = {const_cast<char*>(__FILE__), const_cast<char*>("--foo=1")};
 
   LOG_TEST();
 
@@ -199,7 +199,7 @@ static void test_flag_val_1(void) {
 static void test_flag_val_0(void) {
   int x = 2;
   gpr_cmdline* cl;
-  char* args[] = {(char*)__FILE__, const_cast<char*>("--foo=0")};
+  char* args[] = {const_cast<char*>(__FILE__), const_cast<char*>("--foo=0")};
 
   LOG_TEST();
 
@@ -214,7 +214,7 @@ static void test_flag_val_0(void) {
 static void test_flag_val_true(void) {
   int x = 2;
   gpr_cmdline* cl;
-  char* args[] = {(char*)__FILE__, const_cast<char*>("--foo=true")};
+  char* args[] = {const_cast<char*>(__FILE__), const_cast<char*>("--foo=true")};
 
   LOG_TEST();
 
@@ -229,7 +229,8 @@ static void test_flag_val_true(void) {
 static void test_flag_val_false(void) {
   int x = 2;
   gpr_cmdline* cl;
-  char* args[] = {(char*)__FILE__, const_cast<char*>("--foo=false")};
+  char* args[] = {const_cast<char*>(__FILE__),
+                  const_cast<char*>("--foo=false")};
 
   LOG_TEST();
 
@@ -247,7 +248,7 @@ static void test_many(void) {
   int flag = 2;
   gpr_cmdline* cl;
 
-  char* args[] = {(char*)__FILE__, const_cast<char*>("--str"),
+  char* args[] = {const_cast<char*>(__FILE__), const_cast<char*>("--str"),
                   const_cast<char*>("hello"), const_cast<char*>("-x=4"),
                   const_cast<char*>("-no-flag")};
 
@@ -275,7 +276,7 @@ static void extra_arg_cb(void* user_data, const char* arg) {
 static void test_extra(void) {
   gpr_cmdline* cl;
   int count = 0;
-  char* args[] = {(char*)__FILE__, const_cast<char*>("a"),
+  char* args[] = {const_cast<char*>(__FILE__), const_cast<char*>("a"),
                   const_cast<char*>("b"), const_cast<char*>("c")};
 
   LOG_TEST();
@@ -291,7 +292,7 @@ static void test_extra(void) {
 static void test_extra_dashdash(void) {
   gpr_cmdline* cl;
   int count = 0;
-  char* args[] = {(char*)__FILE__, const_cast<char*>("--"),
+  char* args[] = {const_cast<char*>(__FILE__), const_cast<char*>("--"),
                   const_cast<char*>("a"), const_cast<char*>("b"),
                   const_cast<char*>("c")};
 
@@ -341,7 +342,7 @@ static void test_help(void) {
   int x = 0;
   int flag = 2;
 
-  char* help[] = {(char*)__FILE__, const_cast<char*>("-h")};
+  char* help[] = {const_cast<char*>(__FILE__), const_cast<char*>("-h")};
 
   LOG_TEST();
 
@@ -365,7 +366,8 @@ static void test_badargs1(void) {
   int x = 0;
   int flag = 2;
 
-  char* bad_arg_name[] = {(char*)__FILE__, const_cast<char*>("--y")};
+  char* bad_arg_name[] = {const_cast<char*>(__FILE__),
+                          const_cast<char*>("--y")};
 
   LOG_TEST();
 
@@ -390,7 +392,8 @@ static void test_badargs2(void) {
   int x = 0;
   int flag = 2;
 
-  char* bad_int_value[] = {(char*)__FILE__, const_cast<char*>("--x"),
+  char* bad_int_value[] = {const_cast<char*>(__FILE__),
+                           const_cast<char*>("--x"),
                            const_cast<char*>("henry")};
 
   LOG_TEST();
@@ -416,7 +419,8 @@ static void test_badargs3(void) {
   int x = 0;
   int flag = 2;
 
-  char* bad_bool_value[] = {(char*)__FILE__, const_cast<char*>("--flag=henry")};
+  char* bad_bool_value[] = {const_cast<char*>(__FILE__),
+                            const_cast<char*>("--flag=henry")};
 
   LOG_TEST();
 
@@ -441,7 +445,8 @@ static void test_badargs4(void) {
   int x = 0;
   int flag = 2;
 
-  char* bad_bool_value[] = {(char*)__FILE__, const_cast<char*>("--no-str")};
+  char* bad_bool_value[] = {const_cast<char*>(__FILE__),
+                            const_cast<char*>("--no-str")};
 
   LOG_TEST();
 
diff --git a/test/core/util/debugger_macros.cc b/test/core/util/debugger_macros.cc
deleted file mode 100644 (file)
index fde68f3..0000000
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- *
- * Copyright 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.
- *
- */
-
-/*
- * A collection of 'macros' that help navigating the grpc object hierarchy
- * Not intended to be robust for main-line code, often cuts across abstraction
- * boundaries.
- */
-#include <stdio.h>
-
-#include "src/core/ext/filters/client_channel/client_channel.h"
-#include "src/core/ext/transport/chttp2/transport/internal.h"
-#include "src/core/lib/channel/connected_channel.h"
-#include "src/core/lib/surface/call.h"
-
-grpc_stream* grpc_transport_stream_from_call(grpc_call* call) {
-  grpc_call_stack* cs = grpc_call_get_call_stack(call);
-  for (;;) {
-    grpc_call_element* el = grpc_call_stack_element(cs, cs->count - 1);
-    if (el->filter == &grpc_client_channel_filter) {
-      grpc_core::RefCountedPtr<grpc_core::SubchannelCall> scc =
-          grpc_client_channel_get_subchannel_call(el);
-      if (scc == nullptr) {
-        fprintf(stderr, "No subchannel-call");
-        fflush(stderr);
-        return nullptr;
-      }
-      cs = scc->GetCallStack();
-    } else if (el->filter == &grpc_connected_filter) {
-      return grpc_connected_channel_get_stream(el);
-    } else {
-      fprintf(stderr, "Unrecognized filter: %s", el->filter->name);
-      fflush(stderr);
-      return nullptr;
-    }
-  }
-}
-
-grpc_chttp2_stream* grpc_chttp2_stream_from_call(grpc_call* call) {
-  return reinterpret_cast<grpc_chttp2_stream*>(
-      grpc_transport_stream_from_call(call));
-}
index f028ac4..afb2c16 100644 (file)
@@ -124,23 +124,23 @@ int grpc_histogram_merge(grpc_histogram* dst, const grpc_histogram* src) {
   return 1;
 }
 
-void grpc_histogram_merge_contents(grpc_histogram* dst, const uint32_t* data,
-                                   size_t data_count, double min_seen,
-                                   double max_seen, double sum,
+void grpc_histogram_merge_contents(grpc_histogram* histogram,
+                                   const uint32_t* data, size_t data_count,
+                                   double min_seen, double max_seen, double sum,
                                    double sum_of_squares, double count) {
   size_t i;
-  GPR_ASSERT(dst->num_buckets == data_count);
-  dst->sum += sum;
-  dst->sum_of_squares += sum_of_squares;
-  dst->count += count;
-  if (min_seen < dst->min_seen) {
-    dst->min_seen = min_seen;
+  GPR_ASSERT(histogram->num_buckets == data_count);
+  histogram->sum += sum;
+  histogram->sum_of_squares += sum_of_squares;
+  histogram->count += count;
+  if (min_seen < histogram->min_seen) {
+    histogram->min_seen = min_seen;
   }
-  if (max_seen > dst->max_seen) {
-    dst->max_seen = max_seen;
+  if (max_seen > histogram->max_seen) {
+    histogram->max_seen = max_seen;
   }
-  for (i = 0; i < dst->num_buckets; i++) {
-    dst->buckets[i] += data[i];
+  for (i = 0; i < histogram->num_buckets; i++) {
+    histogram->buckets[i] += data[i];
   }
 }
 
@@ -224,7 +224,8 @@ double grpc_histogram_sum_of_squares(grpc_histogram* h) {
   return h->sum_of_squares;
 }
 
-const uint32_t* grpc_histogram_get_contents(grpc_histogram* h, size_t* size) {
-  *size = h->num_buckets;
-  return h->buckets;
+const uint32_t* grpc_histogram_get_contents(grpc_histogram* histogram,
+                                            size_t* count) {
+  *count = histogram->num_buckets;
+  return histogram->buckets;
 }
index 7e495c3..b62613b 100644 (file)
@@ -132,7 +132,8 @@ grpc_endpoint* grpc_mock_endpoint_create(void (*on_write)(grpc_slice slice),
                                          grpc_resource_quota* resource_quota) {
   mock_endpoint* m = static_cast<mock_endpoint*>(gpr_malloc(sizeof(*m)));
   m->base.vtable = &vtable;
-  std::string name = absl::StrFormat("mock_endpoint_%" PRIxPTR, (intptr_t)m);
+  std::string name =
+      absl::StrFormat("mock_endpoint_%" PRIxPTR, reinterpret_cast<intptr_t>(m));
   m->resource_user = grpc_resource_user_create(resource_quota, name.c_str());
   grpc_slice_buffer_init(&m->read_buffer);
   gpr_mu_init(&m->mu);
index 6521d3e..8e58d65 100644 (file)
@@ -23,7 +23,6 @@
 
 grpc_endpoint* grpc_mock_endpoint_create(void (*on_write)(grpc_slice slice),
                                          grpc_resource_quota* resource_quota);
-void grpc_mock_endpoint_put_read(grpc_endpoint* mock_endpoint,
-                                 grpc_slice slice);
+void grpc_mock_endpoint_put_read(grpc_endpoint* ep, grpc_slice slice);
 
 #endif
index e8a8fc5..f856481 100644 (file)
@@ -197,8 +197,8 @@ static void half_init(half* m, passthru_endpoint* parent,
   m->parent = parent;
   grpc_slice_buffer_init(&m->read_buffer);
   m->on_read = nullptr;
-  std::string name = absl::StrFormat("passthru_endpoint_%s_%" PRIxPTR,
-                                     half_name, (intptr_t)parent);
+  std::string name =
+      absl::StrFormat("passthru_endpoint_%s_%p", half_name, parent);
   m->resource_user = grpc_resource_user_create(resource_quota, name.c_str());
 }
 
index 228e5bb..f611ff1 100644 (file)
@@ -97,8 +97,7 @@ std::string GetCurrentStackTrace() {
   void* stack[kNumStackFrames];
   int frame_sizes[kNumStackFrames];
   int depth = absl::GetStackFrames(stack, frame_sizes, kNumStackFrames, 1);
-  DumpStackTrace(stack, frame_sizes, depth, true, DebugWriteToString,
-                 (void*)&result);
+  DumpStackTrace(stack, frame_sizes, depth, true, DebugWriteToString, &result);
   return result;
 }
 
index d44e07b..9fe08bc 100644 (file)
@@ -157,6 +157,7 @@ void grpc_test_init(int argc, char** argv) {
   grpc_core::testing::InitializeStackTracer(argv[0]);
   absl::FailureSignalHandlerOptions options;
   absl::InstallFailureSignalHandler(options);
+  gpr_log_verbosity_init();
   gpr_log(GPR_DEBUG,
           "test slowdown factor: sanitizer=%" PRId64 ", fixture=%" PRId64
           ", poller=%" PRId64 ", total=%" PRId64,
index 8765ea9..549b47b 100644 (file)
@@ -31,7 +31,7 @@ struct test_tcp_server {
   grpc_closure shutdown_complete;
   bool shutdown = false;
   // mu is filled in by grpc_pollset_init and controls the pollset.
-  // TODO: Switch this to a Mutex once pollset_init can provide a Mutex
+  // TODO(unknown): Switch this to a Mutex once pollset_init can provide a Mutex
   gpr_mu* mu;
   std::vector<grpc_pollset*> pollset;
   grpc_tcp_server_cb on_connect;
diff --git a/test/core/util/tls_utils.cc b/test/core/util/tls_utils.cc
new file mode 100644 (file)
index 0000000..e70cdcf
--- /dev/null
@@ -0,0 +1,76 @@
+//
+// 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 "test/core/util/tls_utils.h"
+
+#include "src/core/lib/gpr/tmpfile.h"
+#include "src/core/lib/iomgr/load_file.h"
+#include "src/core/lib/slice/slice_internal.h"
+
+namespace grpc_core {
+
+namespace testing {
+
+TmpFile::TmpFile(absl::string_view credential_data) {
+  name_ = CreateTmpFileAndWriteData(credential_data);
+  GPR_ASSERT(!name_.empty());
+}
+
+TmpFile::~TmpFile() { GPR_ASSERT(remove(name_.c_str()) == 0); }
+
+void TmpFile::RewriteFile(absl::string_view credential_data) {
+  // Create a new file containing new data.
+  std::string new_name = CreateTmpFileAndWriteData(credential_data);
+  GPR_ASSERT(!new_name.empty());
+  // Remove the old file.
+  GPR_ASSERT(remove(name_.c_str()) == 0);
+  // Rename the new file to the original name.
+  GPR_ASSERT(rename(new_name.c_str(), name_.c_str()) == 0);
+}
+
+std::string TmpFile::CreateTmpFileAndWriteData(
+    absl::string_view credential_data) {
+  char* name = nullptr;
+  FILE* file_descriptor = gpr_tmpfile("GrpcTlsCertificateProviderTest", &name);
+  GPR_ASSERT(fwrite(credential_data.data(), 1, credential_data.size(),
+                    file_descriptor) == credential_data.size());
+  GPR_ASSERT(fclose(file_descriptor) == 0);
+  GPR_ASSERT(file_descriptor != nullptr);
+  GPR_ASSERT(name != nullptr);
+  std::string name_to_return = name;
+  gpr_free(name);
+  return name_to_return;
+}
+
+PemKeyCertPairList MakeCertKeyPairs(absl::string_view private_key,
+                                    absl::string_view certs) {
+  if (private_key.empty() && certs.empty()) {
+    return {};
+  }
+  return PemKeyCertPairList{PemKeyCertPair(private_key, certs)};
+}
+
+std::string GetFileContents(const char* path) {
+  grpc_slice slice = grpc_empty_slice();
+  GPR_ASSERT(GRPC_LOG_IF_ERROR("load_file", grpc_load_file(path, 0, &slice)));
+  std::string credential = std::string(StringViewFromSlice(slice));
+  grpc_slice_unref(slice);
+  return credential;
+}
+
+}  // namespace testing
+
+}  // namespace grpc_core
diff --git a/test/core/util/tls_utils.h b/test/core/util/tls_utils.h
new file mode 100644 (file)
index 0000000..4468713
--- /dev/null
@@ -0,0 +1,48 @@
+//
+// 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 "src/core/lib/security/security_connector/ssl_utils.h"
+
+namespace grpc_core {
+
+namespace testing {
+
+class TmpFile {
+ public:
+  // Create a temporary file with |credential_data| written in.
+  explicit TmpFile(absl::string_view credential_data);
+
+  ~TmpFile();
+
+  const std::string& name() { return name_; }
+
+  // Rewrite |credential_data| to the temporary file, in an atomic way.
+  void RewriteFile(absl::string_view credential_data);
+
+ private:
+  std::string CreateTmpFileAndWriteData(absl::string_view credential_data);
+
+  std::string name_;
+};
+
+PemKeyCertPairList MakeCertKeyPairs(absl::string_view private_key,
+                                    absl::string_view certs);
+
+std::string GetFileContents(const char* path);
+
+}  // namespace testing
+
+}  // namespace grpc_core
index ceca797..e12d115 100644 (file)
@@ -64,6 +64,7 @@ grpc_cc_test(
     deps = [
         "//:gpr",
         "//:grpc",
+        "//:grpc_google_mesh_ca_certificate_provider_factory",
         "//test/core/util:grpc_test_util",
     ],
 )
@@ -76,6 +77,7 @@ grpc_cc_test(
     deps = [
         "//:gpr",
         "//:grpc",
+        "//:grpc_secure",
         "//test/core/util:grpc_test_util",
     ],
 )
index 4e31e91..0866ed4 100644 (file)
@@ -109,21 +109,21 @@ TEST_F(CertificateProviderStoreTest, Basic) {
        {"fake1", fake_factory_1->CreateCertificateProviderConfig(Json::Object(),
                                                                  nullptr)}},
   };
-  CertificateProviderStore store(std::move(map));
+  auto store = MakeOrphanable<CertificateProviderStore>(std::move(map));
   // Test for creating certificate providers with known plugin configuration.
-  auto cert_provider_1 = store.CreateOrGetCertificateProvider("fake_plugin_1");
+  auto cert_provider_1 = store->CreateOrGetCertificateProvider("fake_plugin_1");
   ASSERT_NE(cert_provider_1, nullptr);
-  auto cert_provider_3 = store.CreateOrGetCertificateProvider("fake_plugin_3");
+  auto cert_provider_3 = store->CreateOrGetCertificateProvider("fake_plugin_3");
   ASSERT_NE(cert_provider_3, nullptr);
   // Test for creating certificate provider with known plugin configuration but
   // unregistered factory.
-  ASSERT_EQ(store.CreateOrGetCertificateProvider("fake_plugin_2"), nullptr);
+  ASSERT_EQ(store->CreateOrGetCertificateProvider("fake_plugin_2"), nullptr);
   // Test for creating certificate provider with unknown plugin configuration.
-  ASSERT_EQ(store.CreateOrGetCertificateProvider("unknown"), nullptr);
+  ASSERT_EQ(store->CreateOrGetCertificateProvider("unknown"), nullptr);
   // Test for getting previously created certificate providers.
-  ASSERT_EQ(store.CreateOrGetCertificateProvider("fake_plugin_1"),
+  ASSERT_EQ(store->CreateOrGetCertificateProvider("fake_plugin_1"),
             cert_provider_1);
-  ASSERT_EQ(store.CreateOrGetCertificateProvider("fake_plugin_3"),
+  ASSERT_EQ(store->CreateOrGetCertificateProvider("fake_plugin_3"),
             cert_provider_3);
   // Release previously created certificate providers so that the store outlasts
   // the certificate providers.
@@ -139,14 +139,14 @@ TEST_F(CertificateProviderStoreTest, Multithreaded) {
       {"fake_plugin_1",
        {"fake1", fake_factory_1->CreateCertificateProviderConfig(Json::Object(),
                                                                  nullptr)}}};
-  CertificateProviderStore store(std::move(map));
+  auto store = MakeOrphanable<CertificateProviderStore>(std::move(map));
   // Test concurrent `CreateOrGetCertificateProvider()` with the same key.
   std::vector<std::thread> threads;
   threads.reserve(1000);
   for (auto i = 0; i < 1000; i++) {
     threads.emplace_back([&store]() {
       for (auto i = 0; i < 10; ++i) {
-        ASSERT_NE(store.CreateOrGetCertificateProvider("fake_plugin_1"),
+        ASSERT_NE(store->CreateOrGetCertificateProvider("fake_plugin_1"),
                   nullptr);
       }
     });
index 7a7545d..d74bbf0 100644 (file)
@@ -36,7 +36,7 @@ namespace testing {
 
 class TestType {
  public:
-  TestType(bool parse_xds_certificate_providers)
+  explicit TestType(bool parse_xds_certificate_providers)
       : parse_xds_certificate_providers_(parse_xds_certificate_providers) {}
 
   bool parse_xds_certificate_providers() const {
index 25dc7ae..fff1c48 100644 (file)
@@ -21,6 +21,7 @@
 
 #include "src/core/ext/xds/xds_certificate_provider.h"
 #include "test/core/util/test_config.h"
+#include "test/core/util/tls_utils.h"
 
 namespace grpc_core {
 namespace testing {
@@ -35,25 +36,12 @@ constexpr const char* kIdentityCert2 = "identity_cert_2_contents";
 constexpr const char* kRootErrorMessage = "root_error_message";
 constexpr const char* kIdentityErrorMessage = "identity_error_message";
 
-PemKeyCertPairList MakeKeyCertPairs(const char* private_key,
-                                    const char* certs) {
-  if (strcmp(private_key, "") == 0 && strcmp(certs, "") == 0) {
-    return {};
-  }
-  grpc_ssl_pem_key_cert_pair* ssl_pair =
-      static_cast<grpc_ssl_pem_key_cert_pair*>(
-          gpr_malloc(sizeof(grpc_ssl_pem_key_cert_pair)));
-  ssl_pair->private_key = gpr_strdup(private_key);
-  ssl_pair->cert_chain = gpr_strdup(certs);
-  return PemKeyCertPairList{PemKeyCertPair(ssl_pair)};
-}
-
 PemKeyCertPairList MakeKeyCertPairsType1() {
-  return MakeKeyCertPairs(kIdentityCert1PrivateKey, kIdentityCert1);
+  return MakeCertKeyPairs(kIdentityCert1PrivateKey, kIdentityCert1);
 }
 
 PemKeyCertPairList MakeKeyCertPairsType2() {
-  return MakeKeyCertPairs(kIdentityCert2PrivateKey, kIdentityCert2);
+  return MakeCertKeyPairs(kIdentityCert2PrivateKey, kIdentityCert2);
 }
 
 class TestCertificatesWatcher
@@ -118,7 +106,7 @@ TEST(
   auto identity_cert_distributor =
       MakeRefCounted<grpc_tls_certificate_distributor>();
   XdsCertificateProvider provider("root", root_cert_distributor, "identity",
-                                  identity_cert_distributor);
+                                  identity_cert_distributor, {});
   auto* watcher = new TestCertificatesWatcher;
   provider.distributor()->WatchTlsCertificates(
       std::unique_ptr<TestCertificatesWatcher>(watcher), "", "");
@@ -187,7 +175,7 @@ TEST(XdsCertificateProviderTest,
   auto identity_cert_distributor =
       MakeRefCounted<grpc_tls_certificate_distributor>();
   XdsCertificateProvider provider("test", root_cert_distributor, "test",
-                                  identity_cert_distributor);
+                                  identity_cert_distributor, {});
   auto* watcher = new TestCertificatesWatcher;
   provider.distributor()->WatchTlsCertificates(
       std::unique_ptr<TestCertificatesWatcher>(watcher), "", "");
@@ -254,7 +242,8 @@ TEST(XdsCertificateProviderTest,
 TEST(XdsCertificateProviderTest,
      RootCertDistributorSameAsIdentityCertDistributorDifferentCertNames) {
   auto distributor = MakeRefCounted<grpc_tls_certificate_distributor>();
-  XdsCertificateProvider provider("root", distributor, "identity", distributor);
+  XdsCertificateProvider provider("root", distributor, "identity", distributor,
+                                  {});
   auto* watcher = new TestCertificatesWatcher;
   provider.distributor()->WatchTlsCertificates(
       std::unique_ptr<TestCertificatesWatcher>(watcher), "", "");
@@ -317,7 +306,7 @@ TEST(XdsCertificateProviderTest,
 TEST(XdsCertificateProviderTest,
      RootCertDistributorSameAsIdentityCertDistributorSameCertNames) {
   auto distributor = MakeRefCounted<grpc_tls_certificate_distributor>();
-  XdsCertificateProvider provider("", distributor, "", distributor);
+  XdsCertificateProvider provider("", distributor, "", distributor, {});
   auto* watcher = new TestCertificatesWatcher;
   provider.distributor()->WatchTlsCertificates(
       std::unique_ptr<TestCertificatesWatcher>(watcher), "", "");
@@ -380,7 +369,7 @@ TEST(XdsCertificateProviderTest,
 TEST(XdsCertificateProviderTest, SwapOutDistributorsMultipleTimes) {
   auto distributor = MakeRefCounted<grpc_tls_certificate_distributor>();
   distributor->SetKeyMaterials("", kRootCert1, MakeKeyCertPairsType1());
-  XdsCertificateProvider provider("", nullptr, "", nullptr);
+  XdsCertificateProvider provider("", nullptr, "", nullptr, {});
   auto* watcher = new TestCertificatesWatcher;
   provider.distributor()->WatchTlsCertificates(
       std::unique_ptr<TestCertificatesWatcher>(watcher), "", "");
@@ -505,7 +494,7 @@ TEST(XdsCertificateProviderTest, SwapOutDistributorsMultipleTimes) {
 }
 
 TEST(XdsCertificateProviderTest, CertificateNameNotEmpty) {
-  XdsCertificateProvider provider("", nullptr, "", nullptr);
+  XdsCertificateProvider provider("", nullptr, "", nullptr, {});
   auto* watcher = new TestCertificatesWatcher;
   provider.distributor()->WatchTlsCertificates(
       std::unique_ptr<TestCertificatesWatcher>(watcher), "test", "test");
index ce0f6d3..c62c633 100644 (file)
@@ -21,6 +21,11 @@ grpc_package(name = "test/cpp/client")
 grpc_cc_test(
     name = "credentials_test",
     srcs = ["credentials_test.cc"],
+    data = [
+        "//src/core/tsi/test_creds:ca.pem",
+        "//src/core/tsi/test_creds:server1.key",
+        "//src/core/tsi/test_creds:server1.pem",
+    ],
     external_deps = [
         "gtest",
     ],
index 8bbd786..5b61d0e 100644 (file)
@@ -225,16 +225,15 @@ class ClientChannelStressTest {
     grpc_core::ServerAddressList addresses;
     for (const auto& addr : address_data) {
       std::string lb_uri_str = absl::StrCat("ipv4:127.0.0.1:", addr.port);
-      grpc_uri* lb_uri = grpc_uri_parse(lb_uri_str.c_str(), true);
-      GPR_ASSERT(lb_uri != nullptr);
+      absl::StatusOr<grpc_core::URI> lb_uri = grpc_core::URI::Parse(lb_uri_str);
+      GPR_ASSERT(lb_uri.ok());
       grpc_resolved_address address;
-      GPR_ASSERT(grpc_parse_uri(lb_uri, &address));
+      GPR_ASSERT(grpc_parse_uri(*lb_uri, &address));
       grpc_arg arg = grpc_core::CreateAuthorityOverrideChannelArg(
           addr.balancer_name.c_str());
       grpc_channel_args* args =
           grpc_channel_args_copy_and_add(nullptr, &arg, 1);
       addresses.emplace_back(address.addr, address.len, args);
-      grpc_uri_destroy(lb_uri);
     }
     return addresses;
   }
index 0d9eaf0..ddfb3df 100644 (file)
 #include "src/cpp/client/secure_credentials.h"
 #include "src/cpp/common/tls_credentials_options_util.h"
 
+#define CA_CERT_PATH "src/core/tsi/test_creds/ca.pem"
+#define SERVER_CERT_PATH "src/core/tsi/test_creds/server1.pem"
+#define SERVER_KEY_PATH "src/core/tsi/test_creds/server1.key"
+
 namespace {
 
 constexpr const char* kRootCertName = "root_cert_name";
@@ -40,6 +44,7 @@ constexpr const char* kIdentityCertName = "identity_cert_name";
 constexpr const char* kIdentityCertPrivateKey = "identity_private_key";
 constexpr const char* kIdentityCertContents = "identity_cert_contents";
 
+using ::grpc::experimental::FileWatcherCertificateProvider;
 using ::grpc::experimental::StaticDataCertificateProvider;
 using ::grpc::experimental::TlsServerAuthorizationCheckArg;
 using ::grpc::experimental::TlsServerAuthorizationCheckConfig;
@@ -92,6 +97,53 @@ TEST(CredentialsTest, DefaultCredentials) {
   auto creds = GoogleDefaultCredentials();
 }
 
+TEST(CredentialsTest, ExternalAccountCredentials) {
+  // url credentials
+  std::string url_options_string(
+      "{\"type\":\"external_account\",\"audience\":\"audience\",\"subject_"
+      "token_type\":\"subject_token_type\",\"service_account_impersonation_"
+      "url\":\"service_account_impersonation_url\",\"token_url\":\"https://"
+      "foo.com:5555/token\",\"token_info_url\":\"https://foo.com:5555/"
+      "token_info\",\"credential_source\":{\"url\":\"https://foo.com:5555/"
+      "generate_subject_token_format_json\",\"headers\":{\"Metadata-Flavor\":"
+      "\"Google\"},\"format\":{\"type\":\"json\",\"subject_token_field_name\":"
+      "\"access_token\"}},\"quota_project_id\":\"quota_"
+      "project_id\",\"client_id\":\"client_id\",\"client_secret\":\"client_"
+      "secret\"}");
+  auto url_creds = grpc::experimental::ExternalAccountCredentials(
+      url_options_string, {"scope1", "scope2"});
+  EXPECT_TRUE(url_creds != nullptr);
+  // file credentials
+  std::string file_options_string(
+      "{\"type\":\"external_account\",\"audience\":\"audience\",\"subject_"
+      "token_type\":\"subject_token_type\",\"service_account_impersonation_"
+      "url\":\"service_account_impersonation_url\",\"token_url\":\"https://"
+      "foo.com:5555/token\",\"token_info_url\":\"https://foo.com:5555/"
+      "token_info\",\"credential_source\":{\"file\":\"credentials_file_path\"},"
+      "\"quota_project_id\":\"quota_"
+      "project_id\",\"client_id\":\"client_id\",\"client_secret\":\"client_"
+      "secret\"}");
+  auto file_creds = grpc::experimental::ExternalAccountCredentials(
+      file_options_string, {"scope1", "scope2"});
+  EXPECT_TRUE(file_creds != nullptr);
+  // aws credentials
+  std::string aws_options_string(
+      "{\"type\":\"external_account\",\"audience\":\"audience\",\"subject_"
+      "token_type\":\"subject_token_type\",\"service_account_impersonation_"
+      "url\":\"service_account_impersonation_url\",\"token_url\":\"https://"
+      "foo.com:5555/token\",\"token_info_url\":\"https://foo.com:5555/"
+      "token_info\",\"credential_source\":{\"environment_id\":\"aws1\","
+      "\"region_url\":\"https://foo.com:5555/region_url\",\"url\":\"https://"
+      "foo.com:5555/url\",\"regional_cred_verification_url\":\"https://"
+      "foo.com:5555/regional_cred_verification_url_{region}\"},"
+      "\"quota_project_id\":\"quota_"
+      "project_id\",\"client_id\":\"client_id\",\"client_secret\":\"client_"
+      "secret\"}");
+  auto aws_creds = grpc::experimental::ExternalAccountCredentials(
+      aws_options_string, {"scope1", "scope2"});
+  EXPECT_TRUE(aws_creds != nullptr);
+}
+
 TEST(CredentialsTest, StsCredentialsOptionsCppToCore) {
   grpc::experimental::StsCredentialsOptions options;
   options.token_exchange_service_uri = "https://foo.com/exchange";
@@ -407,6 +459,52 @@ TEST(CredentialsTest,
   GPR_ASSERT(channel_credentials.get() != nullptr);
 }
 
+TEST(
+    CredentialsTest,
+    TlsChannelCredentialsWithFileWatcherCertificateProviderLoadingRootAndIdentity) {
+  auto certificate_provider = std::make_shared<FileWatcherCertificateProvider>(
+      SERVER_KEY_PATH, SERVER_CERT_PATH, CA_CERT_PATH, 1);
+  grpc::experimental::TlsChannelCredentialsOptions options(
+      certificate_provider);
+  options.watch_root_certs();
+  options.set_root_cert_name(kRootCertName);
+  options.watch_identity_key_cert_pairs();
+  options.set_identity_cert_name(kIdentityCertName);
+  options.set_server_verification_option(GRPC_TLS_SERVER_VERIFICATION);
+  auto test_server_authorization_check =
+      std::make_shared<TestTlsServerAuthorizationCheck>();
+  auto server_authorization_check_config =
+      std::make_shared<TlsServerAuthorizationCheckConfig>(
+          test_server_authorization_check);
+  options.set_server_authorization_check_config(
+      server_authorization_check_config);
+  auto channel_credentials = grpc::experimental::TlsCredentials(options);
+  GPR_ASSERT(channel_credentials.get() != nullptr);
+}
+
+// ChannelCredentials should always have root credential presented.
+// Otherwise the system root certificates will be loaded, which will cause
+// failure in some tests under MacOS/Windows.
+TEST(CredentialsTest,
+     TlsChannelCredentialsWithFileWatcherCertificateProviderLoadingRootOnly) {
+  auto certificate_provider =
+      std::make_shared<FileWatcherCertificateProvider>(CA_CERT_PATH, 1);
+  grpc::experimental::TlsChannelCredentialsOptions options(
+      certificate_provider);
+  options.watch_root_certs();
+  options.set_root_cert_name(kRootCertName);
+  options.set_server_verification_option(GRPC_TLS_SERVER_VERIFICATION);
+  auto test_server_authorization_check =
+      std::make_shared<TestTlsServerAuthorizationCheck>();
+  auto server_authorization_check_config =
+      std::make_shared<TlsServerAuthorizationCheckConfig>(
+          test_server_authorization_check);
+  options.set_server_authorization_check_config(
+      server_authorization_check_config);
+  auto channel_credentials = grpc::experimental::TlsCredentials(options);
+  GPR_ASSERT(channel_credentials.get() != nullptr);
+}
+
 TEST(CredentialsTest, TlsServerAuthorizationCheckConfigErrorMessages) {
   std::shared_ptr<TlsServerAuthorizationCheckConfig> config(
       new TlsServerAuthorizationCheckConfig(nullptr));
index f8692fb..535a56e 100644 (file)
@@ -60,12 +60,11 @@ void TryConnectAndDestroy() {
   // The precise behavior is dependant on the test runtime environment though,
   // since connect() attempts on this address may unfortunately result in
   // "network unreachable" errors in some test runtime environments.
-  const char* uri_str = "ipv6:[0100::1234]:443";
-  grpc_uri* lb_uri = grpc_uri_parse(uri_str, true);
-  ASSERT_NE(lb_uri, nullptr);
+  absl::StatusOr<grpc_core::URI> lb_uri =
+      grpc_core::URI::Parse("ipv6:[0100::1234]:443");
+  ASSERT_TRUE(lb_uri.ok());
   grpc_resolved_address address;
-  ASSERT_TRUE(grpc_parse_uri(lb_uri, &address));
-  grpc_uri_destroy(lb_uri);
+  ASSERT_TRUE(grpc_parse_uri(*lb_uri, &address));
   grpc_core::ServerAddressList addresses;
   addresses.emplace_back(address.addr, address.len, nullptr);
   grpc_core::Resolver::Result lb_address_result;
index ead9fb1..53050a8 100644 (file)
@@ -48,7 +48,7 @@ class TestSocketMutator : public grpc_socket_mutator {
 //
 
 bool test_mutator_mutate_fd(int fd, grpc_socket_mutator* mutator) {
-  TestSocketMutator* tsm = (TestSocketMutator*)mutator;
+  TestSocketMutator* tsm = reinterpret_cast<TestSocketMutator*>(mutator);
   return tsm->MutateFd(fd);
 }
 
@@ -57,7 +57,7 @@ int test_mutator_compare(grpc_socket_mutator* a, grpc_socket_mutator* b) {
 }
 
 void test_mutator_destroy(grpc_socket_mutator* mutator) {
-  TestSocketMutator* tsm = (TestSocketMutator*)mutator;
+  TestSocketMutator* tsm = reinterpret_cast<TestSocketMutator*>(mutator);
   delete tsm;
 }
 
index d140a35..23a9af5 100644 (file)
@@ -503,6 +503,15 @@ grpc_cc_test(
     name = "xds_end2end_test",
     size = "large",
     srcs = ["xds_end2end_test.cc"],
+    data = [
+        "//src/core/tsi/test_creds:badclient.key",
+        "//src/core/tsi/test_creds:badclient.pem",
+        "//src/core/tsi/test_creds:ca.pem",
+        "//src/core/tsi/test_creds:client.key",
+        "//src/core/tsi/test_creds:client.pem",
+        "//src/core/tsi/test_creds:server1.key",
+        "//src/core/tsi/test_creds:server1.pem",
+    ],
     external_deps = [
         "gtest",
     ],
@@ -534,6 +543,7 @@ grpc_cc_test(
         "//src/proto/grpc/testing/xds/v3:listener_proto",
         "//src/proto/grpc/testing/xds/v3:lrs_proto",
         "//src/proto/grpc/testing/xds/v3:route_proto",
+        "//src/proto/grpc/testing/xds/v3:tls_proto",
         "//test/core/util:grpc_test_util",
         "//test/cpp/util:test_util",
     ],
index 4bb5c1c..f914fdd 100644 (file)
@@ -60,7 +60,7 @@ namespace testing {
 
 namespace {
 
-void* tag(int i) { return (void*)static_cast<intptr_t>(i); }
+void* tag(int t) { return reinterpret_cast<void*>(t); }
 int detag(void* p) { return static_cast<int>(reinterpret_cast<intptr_t>(p)); }
 
 class Verifier {
index a69ee49..a7e3a9f 100644 (file)
@@ -42,7 +42,6 @@
 #include "src/core/lib/gpr/env.h"
 
 #include "src/proto/grpc/testing/echo.grpc.pb.h"
-#include "test/core/util/debugger_macros.h"
 #include "test/core/util/port.h"
 #include "test/core/util/test_config.h"
 #include "test/cpp/end2end/test_service_impl.h"
@@ -145,18 +144,6 @@ class CFStreamTest : public ::testing::TestWithParam<TestScenario> {
     return CreateCustomChannel(server_address.str(), channel_creds, args);
   }
 
-  int GetStreamID(ClientContext& context) {
-    int stream_id = 0;
-    grpc_call* call = context.c_call();
-    if (call) {
-      grpc_chttp2_stream* stream = grpc_chttp2_stream_from_call(call);
-      if (stream) {
-        stream_id = stream->id;
-      }
-    }
-    return stream_id;
-  }
-
   void SendRpc(
       const std::unique_ptr<grpc::testing::EchoTestService::Stub>& stub,
       bool expect_success = false) {
@@ -166,13 +153,11 @@ class CFStreamTest : public ::testing::TestWithParam<TestScenario> {
     request.set_message(msg);
     ClientContext context;
     Status status = stub->Echo(&context, request, response.get());
-    int stream_id = GetStreamID(context);
     if (status.ok()) {
-      gpr_log(GPR_DEBUG, "RPC with stream_id %d succeeded", stream_id);
+      gpr_log(GPR_DEBUG, "RPC with succeeded");
       EXPECT_EQ(msg, response->message());
     } else {
-      gpr_log(GPR_DEBUG, "RPC with stream_id %d failed: %s", stream_id,
-              status.error_message().c_str());
+      gpr_log(GPR_DEBUG, "RPC failed: %s", status.error_message().c_str());
     }
     if (expect_success) {
       EXPECT_TRUE(status.ok());
@@ -392,17 +377,16 @@ TEST_P(CFStreamTest, NetworkFlapRpcsInFlight) {
       ++total_completions;
       GPR_ASSERT(ok);
       AsyncClientCall* call = static_cast<AsyncClientCall*>(got_tag);
-      int stream_id = GetStreamID(call->context);
       if (!call->status.ok()) {
-        gpr_log(GPR_DEBUG, "RPC with stream_id %d failed with error: %s",
-                stream_id, call->status.error_message().c_str());
+        gpr_log(GPR_DEBUG, "RPC failed with error: %s",
+                call->status.error_message().c_str());
         // Bring network up when RPCs start failing
         if (network_down) {
           NetworkUp();
           network_down = false;
         }
       } else {
-        gpr_log(GPR_DEBUG, "RPC with stream_id %d succeeded", stream_id);
+        gpr_log(GPR_DEBUG, "RPC succeeded");
       }
       delete call;
     }
@@ -440,13 +424,12 @@ TEST_P(CFStreamTest, ConcurrentRpc) {
       ++total_completions;
       GPR_ASSERT(ok);
       AsyncClientCall* call = static_cast<AsyncClientCall*>(got_tag);
-      int stream_id = GetStreamID(call->context);
       if (!call->status.ok()) {
-        gpr_log(GPR_DEBUG, "RPC with stream_id %d failed with error: %s",
-                stream_id, call->status.error_message().c_str());
+        gpr_log(GPR_DEBUG, "RPC failed with error: %s",
+                call->status.error_message().c_str());
         // Bring network up when RPCs start failing
       } else {
-        gpr_log(GPR_DEBUG, "RPC with stream_id %d succeeded", stream_id);
+        gpr_log(GPR_DEBUG, "RPC succeeded");
       }
       delete call;
     }
index 04f21ad..8faeb29 100644 (file)
@@ -746,17 +746,30 @@ TEST_F(ChannelzServerTest, GetServerListenSocketsTest) {
                                         &get_server_response);
   EXPECT_TRUE(s.ok()) << "s.error_message() = " << s.error_message();
   EXPECT_EQ(get_server_response.server_size(), 1);
-  EXPECT_EQ(get_server_response.server(0).listen_socket_size(), 1);
+  // The resolver might return one or two addresses depending on the
+  // configuration, one for ipv4 and one for ipv6.
+  int listen_socket_size = get_server_response.server(0).listen_socket_size();
+  EXPECT_TRUE(listen_socket_size == 1 || listen_socket_size == 2);
   GetSocketRequest get_socket_request;
   GetSocketResponse get_socket_response;
   get_socket_request.set_socket_id(
       get_server_response.server(0).listen_socket(0).socket_id());
   EXPECT_TRUE(
       get_server_response.server(0).listen_socket(0).name().find("http"));
-  ClientContext get_socket_context;
-  s = channelz_stub_->GetSocket(&get_socket_context, get_socket_request,
+  ClientContext get_socket_context_1;
+  s = channelz_stub_->GetSocket(&get_socket_context_1, get_socket_request,
                                 &get_socket_response);
   EXPECT_TRUE(s.ok()) << "s.error_message() = " << s.error_message();
+  if (listen_socket_size == 2) {
+    get_socket_request.set_socket_id(
+        get_server_response.server(0).listen_socket(1).socket_id());
+    ClientContext get_socket_context_2;
+    EXPECT_TRUE(
+        get_server_response.server(0).listen_socket(1).name().find("http"));
+    s = channelz_stub_->GetSocket(&get_socket_context_2, get_socket_request,
+                                  &get_socket_response);
+    EXPECT_TRUE(s.ok()) << "s.error_message() = " << s.error_message();
+  }
 }
 
 }  // namespace testing
index bc09353..e38bd71 100644 (file)
@@ -806,7 +806,7 @@ TEST_P(ClientCallbackEnd2endTest, UnaryReactor) {
   ResetStub();
   class UnaryClient : public grpc::experimental::ClientUnaryReactor {
    public:
-    UnaryClient(grpc::testing::EchoTestService::Stub* stub) {
+    explicit UnaryClient(grpc::testing::EchoTestService::Stub* stub) {
       cli_ctx_.AddMetadata("key1", "val1");
       cli_ctx_.AddMetadata("key2", "val2");
       request_.mutable_param()->set_echo_metadata_initially(true);
@@ -1351,7 +1351,7 @@ TEST_P(ClientCallbackEnd2endTest, SimultaneousReadAndWritesDone) {
   class Client : public grpc::experimental::ClientBidiReactor<EchoRequest,
                                                               EchoResponse> {
    public:
-    Client(grpc::testing::EchoTestService::Stub* stub) {
+    explicit Client(grpc::testing::EchoTestService::Stub* stub) {
       request_.set_message("Hello bidi ");
       stub->experimental_async()->BidiStream(&context_, this);
       StartWrite(&request_);
@@ -1434,7 +1434,8 @@ TEST_P(ClientCallbackEnd2endTest,
   class ReadAllIncomingDataClient
       : public grpc::experimental::ClientReadReactor<EchoResponse> {
    public:
-    ReadAllIncomingDataClient(grpc::testing::EchoTestService::Stub* stub) {
+    explicit ReadAllIncomingDataClient(
+        grpc::testing::EchoTestService::Stub* stub) {
       request_.set_message("Hello client ");
       stub->experimental_async()->ResponseStream(&context_, &request_, this);
     }
index 8bc81bf..af45419 100644 (file)
@@ -72,7 +72,7 @@ enum class ChannelType {
 /* Hijacks Echo RPC and fills in the expected values */
 class HijackingInterceptor : public experimental::Interceptor {
  public:
-  HijackingInterceptor(experimental::ClientRpcInfo* info) {
+  explicit HijackingInterceptor(experimental::ClientRpcInfo* info) {
     info_ = info;
     // Make sure it is the right method
     EXPECT_EQ(strcmp("/grpc.testing.EchoTestService/Echo", info->method()), 0);
@@ -178,7 +178,8 @@ class HijackingInterceptorFactory
 
 class HijackingInterceptorMakesAnotherCall : public experimental::Interceptor {
  public:
-  HijackingInterceptorMakesAnotherCall(experimental::ClientRpcInfo* info) {
+  explicit HijackingInterceptorMakesAnotherCall(
+      experimental::ClientRpcInfo* info) {
     info_ = info;
     // Make sure it is the right method
     EXPECT_EQ(strcmp("/grpc.testing.EchoTestService/Echo", info->method()), 0);
@@ -300,7 +301,8 @@ class HijackingInterceptorMakesAnotherCallFactory
 
 class BidiStreamingRpcHijackingInterceptor : public experimental::Interceptor {
  public:
-  BidiStreamingRpcHijackingInterceptor(experimental::ClientRpcInfo* info) {
+  explicit BidiStreamingRpcHijackingInterceptor(
+      experimental::ClientRpcInfo* info) {
     info_ = info;
   }
 
@@ -370,7 +372,8 @@ class BidiStreamingRpcHijackingInterceptor : public experimental::Interceptor {
 class ClientStreamingRpcHijackingInterceptor
     : public experimental::Interceptor {
  public:
-  ClientStreamingRpcHijackingInterceptor(experimental::ClientRpcInfo* info) {
+  explicit ClientStreamingRpcHijackingInterceptor(
+      experimental::ClientRpcInfo* info) {
     info_ = info;
   }
   void Intercept(experimental::InterceptorBatchMethods* methods) override {
@@ -424,7 +427,8 @@ class ClientStreamingRpcHijackingInterceptorFactory
 class ServerStreamingRpcHijackingInterceptor
     : public experimental::Interceptor {
  public:
-  ServerStreamingRpcHijackingInterceptor(experimental::ClientRpcInfo* info) {
+  explicit ServerStreamingRpcHijackingInterceptor(
+      experimental::ClientRpcInfo* info) {
     info_ = info;
     got_failed_message_ = false;
   }
@@ -534,7 +538,7 @@ class BidiStreamingRpcHijackingInterceptorFactory
 // single RPC should be made on the channel before calling the Verify methods.
 class LoggingInterceptor : public experimental::Interceptor {
  public:
-  LoggingInterceptor(experimental::ClientRpcInfo* /*info*/) {
+  explicit LoggingInterceptor(experimental::ClientRpcInfo* /*info*/) {
     pre_send_initial_metadata_ = false;
     pre_send_message_count_ = 0;
     pre_send_close_ = false;
index 7776d8f..644d782 100644 (file)
@@ -199,12 +199,11 @@ class FakeResolverResponseGeneratorWrapper {
           nullptr) {
     grpc_core::Resolver::Result result;
     for (const int& port : ports) {
-      std::string lb_uri_str =
-          absl::StrCat(ipv6_only ? "ipv6:[::1]:" : "ipv4:127.0.0.1:", port);
-      grpc_uri* lb_uri = grpc_uri_parse(lb_uri_str.c_str(), true);
-      GPR_ASSERT(lb_uri != nullptr);
+      absl::StatusOr<grpc_core::URI> lb_uri = grpc_core::URI::Parse(
+          absl::StrCat(ipv6_only ? "ipv6:[::1]:" : "ipv4:127.0.0.1:", port));
+      GPR_ASSERT(lb_uri.ok());
       grpc_resolved_address address;
-      GPR_ASSERT(grpc_parse_uri(lb_uri, &address));
+      GPR_ASSERT(grpc_parse_uri(*lb_uri, &address));
       std::map<const char*,
                std::unique_ptr<grpc_core::ServerAddress::AttributeInterface>>
           attributes;
@@ -213,7 +212,6 @@ class FakeResolverResponseGeneratorWrapper {
       }
       result.addresses.emplace_back(address.addr, address.len,
                                     nullptr /* args */, std::move(attributes));
-      grpc_uri_destroy(lb_uri);
     }
     if (service_config_json != nullptr) {
       result.service_config = grpc_core::ServiceConfig::Create(
@@ -1651,14 +1649,17 @@ TEST_F(ClientLbEnd2endTest, ChannelIdleness) {
   // The initial channel state should be IDLE.
   EXPECT_EQ(channel->GetState(false), GRPC_CHANNEL_IDLE);
   // After sending RPC, channel state should be READY.
+  gpr_log(GPR_INFO, "*** SENDING RPC, CHANNEL SHOULD CONNECT ***");
   response_generator.SetNextResolution(GetServersPorts());
   CheckRpcSendOk(stub, DEBUG_LOCATION);
   EXPECT_EQ(channel->GetState(false), GRPC_CHANNEL_READY);
   // After a period time not using the channel, the channel state should switch
   // to IDLE.
+  gpr_log(GPR_INFO, "*** WAITING FOR CHANNEL TO GO IDLE ***");
   gpr_sleep_until(grpc_timeout_milliseconds_to_deadline(1200));
   EXPECT_EQ(channel->GetState(false), GRPC_CHANNEL_IDLE);
   // Sending a new RPC should awake the IDLE channel.
+  gpr_log(GPR_INFO, "*** SENDING ANOTHER RPC, CHANNEL SHOULD RECONNECT ***");
   response_generator.SetNextResolution(GetServersPorts());
   CheckRpcSendOk(stub, DEBUG_LOCATION);
   EXPECT_EQ(channel->GetState(false), GRPC_CHANNEL_READY);
index 9b371e2..5ff66d8 100644 (file)
@@ -45,7 +45,8 @@ namespace {
 
 class TestChannel : public experimental::DelegatingChannel {
  public:
-  TestChannel(const std::shared_ptr<ChannelInterface>& delegate_channel)
+  explicit TestChannel(
+      const std::shared_ptr<ChannelInterface>& delegate_channel)
       : experimental::DelegatingChannel(delegate_channel) {}
   // Always returns GRPC_CHANNEL_READY
   grpc_connectivity_state GetState(bool /*try_to_connect*/) override {
index e89971e..906d0fa 100644 (file)
@@ -204,7 +204,8 @@ class TestAuthMetadataProcessor : public AuthMetadataProcessor {
  public:
   static const char kGoodGuy[];
 
-  TestAuthMetadataProcessor(bool is_blocking) : is_blocking_(is_blocking) {}
+  explicit TestAuthMetadataProcessor(bool is_blocking)
+      : is_blocking_(is_blocking) {}
 
   std::shared_ptr<CallCredentials> GetCompatibleClientCreds() {
     return grpc::MetadataCredentialsFromPlugin(
@@ -259,7 +260,7 @@ const char TestAuthMetadataProcessor::kIdentityPropName[] = "novel identity";
 
 class Proxy : public ::grpc::testing::EchoTestService::Service {
  public:
-  Proxy(const std::shared_ptr<Channel>& channel)
+  explicit Proxy(const std::shared_ptr<Channel>& channel)
       : stub_(grpc::testing::EchoTestService::NewStub(channel)) {}
 
   Status Echo(ServerContext* server_context, const EchoRequest* request,
@@ -1357,7 +1358,7 @@ TEST_P(End2endTest, RpcMaxMessageSize) {
 void ReaderThreadFunc(ClientReaderWriter<EchoRequest, EchoResponse>* stream,
                       gpr_event* ev) {
   EchoResponse resp;
-  gpr_event_set(ev, (void*)1);
+  gpr_event_set(ev, reinterpret_cast<void*>(1));
   while (stream->Read(&resp)) {
     gpr_log(GPR_INFO, "Read message");
   }
@@ -1857,7 +1858,8 @@ TEST_P(SecureEnd2endTest, SetPerCallCredentials) {
 
 class CredentialsInterceptor : public experimental::Interceptor {
  public:
-  CredentialsInterceptor(experimental::ClientRpcInfo* info) : info_(info) {}
+  explicit CredentialsInterceptor(experimental::ClientRpcInfo* info)
+      : info_(info) {}
 
   void Intercept(experimental::InterceptorBatchMethods* methods) override {
     if (methods->QueryInterceptionHookPoint(
index 6287677..0d8f1d7 100644 (file)
@@ -51,7 +51,7 @@ namespace grpc {
 namespace testing {
 namespace {
 
-void* tag(int i) { return (void*)static_cast<intptr_t>(i); }
+void* tag(int i) { return reinterpret_cast<void*>(i); }
 
 void verify_ok(CompletionQueue* cq, int i, bool expect_ok) {
   bool ok;
index 9b27aa8..805770d 100644 (file)
@@ -43,7 +43,6 @@
 #include "src/core/lib/backoff/backoff.h"
 #include "src/core/lib/gpr/env.h"
 #include "src/proto/grpc/testing/echo.grpc.pb.h"
-#include "test/core/util/debugger_macros.h"
 #include "test/core/util/port.h"
 #include "test/core/util/test_config.h"
 #include "test/cpp/end2end/test_service_impl.h"
@@ -226,19 +225,10 @@ class FlakyNetworkTest : public ::testing::TestWithParam<TestScenario> {
     }
     Status status = stub->Echo(&context, request, response.get());
     auto ok = status.ok();
-    int stream_id = 0;
-    grpc_call* call = context.c_call();
-    if (call) {
-      grpc_chttp2_stream* stream = grpc_chttp2_stream_from_call(call);
-      if (stream) {
-        stream_id = stream->id;
-      }
-    }
     if (ok) {
-      gpr_log(GPR_DEBUG, "RPC with stream_id %d succeeded", stream_id);
+      gpr_log(GPR_DEBUG, "RPC succeeded");
     } else {
-      gpr_log(GPR_DEBUG, "RPC with stream_id %d failed: %s", stream_id,
-              status.error_message().c_str());
+      gpr_log(GPR_DEBUG, "RPC failed: %s", status.error_message().c_str());
     }
     return ok;
   }
index 32aacc4..cff1cf8 100644 (file)
@@ -48,7 +48,7 @@ namespace grpc {
 namespace testing {
 namespace {
 
-void* tag(int i) { return (void*)static_cast<intptr_t>(i); }
+void* tag(int i) { return reinterpret_cast<void*>(i); }
 
 void verify_ok(CompletionQueue* cq, int i, bool expect_ok) {
   bool ok;
index 7858878..a218320 100644 (file)
@@ -540,18 +540,17 @@ class GrpclbEnd2endTest : public ::testing::Test {
       const std::vector<AddressData>& address_data) {
     grpc_core::ServerAddressList addresses;
     for (const auto& addr : address_data) {
-      std::string lb_uri_str = absl::StrCat(
-          ipv6_only_ ? "ipv6:[::1]:" : "ipv4:127.0.0.1:", addr.port);
-      grpc_uri* lb_uri = grpc_uri_parse(lb_uri_str.c_str(), true);
-      GPR_ASSERT(lb_uri != nullptr);
+      absl::StatusOr<grpc_core::URI> lb_uri =
+          grpc_core::URI::Parse(absl::StrCat(
+              ipv6_only_ ? "ipv6:[::1]:" : "ipv4:127.0.0.1:", addr.port));
+      GPR_ASSERT(lb_uri.ok());
       grpc_resolved_address address;
-      GPR_ASSERT(grpc_parse_uri(lb_uri, &address));
+      GPR_ASSERT(grpc_parse_uri(*lb_uri, &address));
       grpc_arg arg = grpc_core::CreateAuthorityOverrideChannelArg(
           addr.balancer_name.c_str());
       grpc_channel_args* args =
           grpc_channel_args_copy_and_add(nullptr, &arg, 1);
       addresses.emplace_back(address.addr, address.len, args);
-      grpc_uri_destroy(lb_uri);
     }
     return addresses;
   }
index 8646b5a..76e1f83 100644 (file)
@@ -49,7 +49,7 @@ using ::grpc::experimental::GenericCallbackServerContext;
 using ::grpc::experimental::ServerGenericBidiReactor;
 #endif
 
-void* tag(int i) { return (void*)static_cast<intptr_t>(i); }
+void* tag(int i) { return reinterpret_cast<void*>(i); }
 
 bool VerifyReturnSuccess(CompletionQueue* cq, int i) {
   void* got_tag;
index 01009cd..0b386b3 100644 (file)
@@ -191,7 +191,7 @@ bool CheckMetadata(const std::multimap<std::string, std::string>& map,
 std::vector<std::unique_ptr<experimental::ClientInterceptorFactoryInterface>>
 CreateDummyClientInterceptors();
 
-inline void* tag(int i) { return (void*)static_cast<intptr_t>(i); }
+inline void* tag(int i) { return reinterpret_cast<void*>(i); }
 inline int detag(void* p) {
   return static_cast<int>(reinterpret_cast<intptr_t>(p));
 }
index 31edffd..d6300ec 100644 (file)
@@ -50,7 +50,7 @@ namespace testing {
 
 namespace {
 
-void* tag(int i) { return (void*)static_cast<intptr_t>(i); }
+void* tag(int i) { return reinterpret_cast<void*>(i); }
 int detag(void* p) { return static_cast<int>(reinterpret_cast<intptr_t>(p)); }
 
 class Verifier {
index 4c90514..4345734 100644 (file)
@@ -47,7 +47,7 @@ namespace {
 
 class LoggingInterceptor : public experimental::Interceptor {
  public:
-  LoggingInterceptor(experimental::ServerRpcInfo* info) {
+  explicit LoggingInterceptor(experimental::ServerRpcInfo* info) {
     info_ = info;
 
     // Check the method name and compare to the type
@@ -150,7 +150,7 @@ class LoggingInterceptorFactory
 // Test if SendMessage function family works as expected for sync/callback apis
 class SyncSendMessageTester : public experimental::Interceptor {
  public:
-  SyncSendMessageTester(experimental::ServerRpcInfo* /*info*/) {}
+  explicit SyncSendMessageTester(experimental::ServerRpcInfo* /*info*/) {}
 
   void Intercept(experimental::InterceptorBatchMethods* methods) override {
     if (methods->QueryInterceptionHookPoint(
@@ -180,7 +180,7 @@ class SyncSendMessageTesterFactory
 // Test if SendMessage function family works as expected for sync/callback apis
 class SyncSendMessageVerifier : public experimental::Interceptor {
  public:
-  SyncSendMessageVerifier(experimental::ServerRpcInfo* /*info*/) {}
+  explicit SyncSendMessageVerifier(experimental::ServerRpcInfo* /*info*/) {}
 
   void Intercept(experimental::InterceptorBatchMethods* methods) override {
     if (methods->QueryInterceptionHookPoint(
index 3855124..07f383a 100644 (file)
@@ -177,13 +177,12 @@ class ServiceConfigEnd2endTest : public ::testing::Test {
     for (const int& port : ports) {
       std::string lb_uri_str =
           absl::StrCat(ipv6_only_ ? "ipv6:[::1]:" : "ipv4:127.0.0.1:", port);
-      grpc_uri* lb_uri = grpc_uri_parse(lb_uri_str.c_str(), true);
-      GPR_ASSERT(lb_uri != nullptr);
+      absl::StatusOr<grpc_core::URI> lb_uri = grpc_core::URI::Parse(lb_uri_str);
+      GPR_ASSERT(lb_uri.ok());
       grpc_resolved_address address;
-      GPR_ASSERT(grpc_parse_uri(lb_uri, &address));
+      GPR_ASSERT(grpc_parse_uri(*lb_uri, &address));
       result.addresses.emplace_back(address.addr, address.len,
                                     nullptr /* args */);
-      grpc_uri_destroy(lb_uri);
     }
     return result;
   }
index 37dfcd4..ed86f8a 100644 (file)
@@ -48,7 +48,7 @@ class TestServiceImpl : public ::grpc::testing::EchoTestService::Service {
 
   Status Echo(ServerContext* context, const EchoRequest* /*request*/,
               EchoResponse* /*response*/) override {
-    gpr_event_set(ev_, (void*)1);
+    gpr_event_set(ev_, reinterpret_cast<void*>(1));
     while (!context->IsCancelled()) {
     }
     return Status::OK;
index eeb93ce..0e7da2e 100644 (file)
@@ -245,7 +245,7 @@ class CommonStressTestAsyncServer : public BaseClass {
       service_.RequestEcho(contexts_[i].srv_ctx.get(),
                            &contexts_[i].recv_request,
                            contexts_[i].response_writer.get(), cq_.get(),
-                           cq_.get(), (void*)static_cast<intptr_t>(i));
+                           cq_.get(), reinterpret_cast<void*>(i));
     }
   }
   struct Context {
@@ -369,8 +369,7 @@ class AsyncClientEnd2endTest : public ::testing::Test {
       request.set_message("Hello: " + std::to_string(i));
       call->response_reader =
           common_.GetStub()->AsyncEcho(&call->context, request, &cq_);
-      call->response_reader->Finish(&call->response, &call->status,
-                                    (void*)call);
+      call->response_reader->Finish(&call->response, &call->status, call);
 
       grpc::internal::MutexLock l(&mu_);
       rpcs_outstanding_++;
index 9f1bc15..1d4efcf 100644 (file)
@@ -97,7 +97,7 @@ namespace {
 // gpr_now() is called with invalid clock_type
 TEST(TimespecTest, GprNowInvalidClockType) {
   // initialize to some junk value
-  gpr_clock_type invalid_clock_type = (gpr_clock_type)32641;
+  gpr_clock_type invalid_clock_type = static_cast<gpr_clock_type>(32641);
   EXPECT_DEATH(gpr_now(invalid_clock_type), ".*");
 }
 
index a5ea1bd..fa9aa4a 100644 (file)
@@ -69,11 +69,52 @@ TEST_P(XdsCredentialsEnd2EndFallbackTest, NoXdsSchemeInTarget) {
   EXPECT_EQ(resp.message(), "Hello");
 }
 
+class XdsServerCredentialsEnd2EndFallbackTest
+    : public ::testing::TestWithParam<const char*> {
+ protected:
+  XdsServerCredentialsEnd2EndFallbackTest() {
+    int port = grpc_pick_unused_port_or_die();
+    // Build a server that is not xDS enabled but uses XdsServerCredentials.
+    ServerBuilder builder;
+    server_address_ = "localhost:" + std::to_string(port);
+    builder.AddListeningPort(
+        server_address_,
+        grpc::experimental::XdsServerCredentials(
+            GetCredentialsProvider()->GetServerCredentials(GetParam())));
+    builder.RegisterService(&service_);
+    server_ = builder.BuildAndStart();
+  }
+
+  std::string server_address_;
+  TestServiceImpl service_;
+  std::unique_ptr<Server> server_;
+};
+
+TEST_P(XdsServerCredentialsEnd2EndFallbackTest, Basic) {
+  ChannelArguments args;
+  auto channel = grpc::CreateCustomChannel(
+      server_address_,
+      GetCredentialsProvider()->GetChannelCredentials(GetParam(), &args), args);
+  auto stub = grpc::testing::EchoTestService::NewStub(channel);
+  ClientContext ctx;
+  EchoRequest req;
+  req.set_message("Hello");
+  EchoResponse resp;
+  Status s = stub->Echo(&ctx, req, &resp);
+  EXPECT_EQ(s.ok(), true);
+  EXPECT_EQ(resp.message(), "Hello");
+}
+
 INSTANTIATE_TEST_SUITE_P(XdsCredentialsEnd2EndFallback,
                          XdsCredentialsEnd2EndFallbackTest,
                          ::testing::ValuesIn(std::vector<const char*>(
                              {kInsecureCredentialsType, kTlsCredentialsType})));
 
+INSTANTIATE_TEST_SUITE_P(XdsServerCredentialsEnd2EndFallback,
+                         XdsServerCredentialsEnd2EndFallbackTest,
+                         ::testing::ValuesIn(std::vector<const char*>(
+                             {kInsecureCredentialsType, kTlsCredentialsType})));
+
 }  // namespace
 }  // namespace testing
 }  // namespace grpc
index 2af66f8..8ce46c5 100644 (file)
 #include "absl/types/optional.h"
 
 #include <grpc/grpc.h>
+#include <grpc/grpc_security.h>
 #include <grpc/support/alloc.h>
 #include <grpc/support/log.h>
 #include <grpc/support/time.h>
 #include <grpcpp/channel.h>
 #include <grpcpp/client_context.h>
 #include <grpcpp/create_channel.h>
+#include <grpcpp/security/tls_certificate_provider.h>
 #include <grpcpp/server.h>
 #include <grpcpp/server_builder.h>
 
 #include "src/core/ext/filters/client_channel/backup_poller.h"
 #include "src/core/ext/filters/client_channel/resolver/fake/fake_resolver.h"
 #include "src/core/ext/filters/client_channel/server_address.h"
+#include "src/core/ext/xds/certificate_provider_registry.h"
 #include "src/core/ext/xds/xds_api.h"
 #include "src/core/ext/xds/xds_channel_args.h"
 #include "src/core/ext/xds/xds_client.h"
 #include "src/core/lib/channel/channel_args.h"
 #include "src/core/lib/gpr/env.h"
 #include "src/core/lib/gpr/tmpfile.h"
-#include "src/core/lib/gprpp/map.h"
 #include "src/core/lib/gprpp/ref_counted_ptr.h"
 #include "src/core/lib/gprpp/sync.h"
+#include "src/core/lib/iomgr/load_file.h"
 #include "src/core/lib/iomgr/parse_address.h"
 #include "src/core/lib/iomgr/sockaddr.h"
 #include "src/core/lib/security/credentials/fake/fake_credentials.h"
@@ -81,6 +84,7 @@
 #include "src/proto/grpc/testing/xds/v3/listener.grpc.pb.h"
 #include "src/proto/grpc/testing/xds/v3/lrs.grpc.pb.h"
 #include "src/proto/grpc/testing/xds/v3/route.grpc.pb.h"
+#include "src/proto/grpc/testing/xds/v3/tls.grpc.pb.h"
 
 namespace grpc {
 namespace testing {
@@ -97,6 +101,8 @@ using ::envoy::config::listener::v3::Listener;
 using ::envoy::config::route::v3::RouteConfiguration;
 using ::envoy::extensions::filters::network::http_connection_manager::v3::
     HttpConnectionManager;
+using ::envoy::extensions::transport_sockets::tls::v3::UpstreamTlsContext;
+using ::envoy::type::matcher::v3::StringMatcher;
 using ::envoy::type::v3::FractionalPercent;
 
 constexpr char kLdsTypeUrl[] =
@@ -131,9 +137,12 @@ constexpr char kDefaultServiceConfig[] =
     "{\n"
     "  \"loadBalancingConfig\":[\n"
     "    { \"does_not_exist\":{} },\n"
-    "    { \"eds_experimental\":{\n"
-    "      \"clusterName\": \"server.example.com\",\n"
-    "      \"lrsLoadReportingServerName\": \"\"\n"
+    "    { \"xds_cluster_resolver_experimental\":{\n"
+    "      \"discoveryMechanisms\": [\n"
+    "      { \"clusterName\": \"server.example.com\",\n"
+    "        \"type\": \"EDS\",\n"
+    "        \"lrsLoadReportingServerName\": \"\"\n"
+    "      } ]\n"
     "    } }\n"
     "  ]\n"
     "}";
@@ -141,8 +150,11 @@ constexpr char kDefaultServiceConfigWithoutLoadReporting[] =
     "{\n"
     "  \"loadBalancingConfig\":[\n"
     "    { \"does_not_exist\":{} },\n"
-    "    { \"eds_experimental\":{\n"
-    "      \"clusterName\": \"server.example.com\"\n"
+    "    { \"xds_cluster_resolver_experimental\":{\n"
+    "      \"discoveryMechanisms\": [\n"
+    "      { \"clusterName\": \"server.example.com\",\n"
+    "        \"type\": \"EDS\"\n"
+    "      } ]\n"
     "    } }\n"
     "  ]\n"
     "}";
@@ -171,6 +183,22 @@ constexpr char kBootstrapFileV3[] =
     "      \"zone\": \"svl\",\n"
     "      \"subzone\": \"mp3\"\n"
     "    }\n"
+    "  },\n"
+    "  \"certificate_providers\": {\n"
+    "    \"fake_plugin1\": {\n"
+    "      \"plugin_name\": \"fake1\"\n"
+    "    },\n"
+    "    \"fake_plugin2\": {\n"
+    "      \"plugin_name\": \"fake2\"\n"
+    "    },\n"
+    "    \"file_plugin\": {\n"
+    "      \"plugin_name\": \"file_watcher\",\n"
+    "      \"config\": {\n"
+    "        \"certificate_file\": \"src/core/tsi/test_creds/client.pem\",\n"
+    "        \"private_key_file\": \"src/core/tsi/test_creds/client.key\",\n"
+    "        \"ca_certificate_file\": \"src/core/tsi/test_creds/ca.pem\"\n"
+    "      }"
+    "    }\n"
     "  }\n"
     "}\n";
 
@@ -199,6 +227,13 @@ constexpr char kBootstrapFileV2[] =
     "    }\n"
     "  }\n"
     "}\n";
+constexpr char kCaCertPath[] = "src/core/tsi/test_creds/ca.pem";
+constexpr char kServerCertPath[] = "src/core/tsi/test_creds/server1.pem";
+constexpr char kServerKeyPath[] = "src/core/tsi/test_creds/server1.key";
+constexpr char kClientCertPath[] = "src/core/tsi/test_creds/client.pem";
+constexpr char kClientKeyPath[] = "src/core/tsi/test_creds/client.key";
+constexpr char kBadClientCertPath[] = "src/core/tsi/test_creds/badclient.pem";
+constexpr char kBadClientKeyPath[] = "src/core/tsi/test_creds/badclient.key";
 
 char* g_bootstrap_file_v3;
 char* g_bootstrap_file_v2;
@@ -268,9 +303,6 @@ class CountedService : public ServiceType {
   size_t response_count_ = 0;
 };
 
-const char g_kCallCredsMdKey[] = "Balancer should not ...";
-const char g_kCallCredsMdValue[] = "... receive me";
-
 template <typename RpcService>
 class BackendServiceImpl
     : public CountedService<TestMultipleServiceImpl<RpcService>> {
@@ -279,19 +311,20 @@ class BackendServiceImpl
 
   Status Echo(ServerContext* context, const EchoRequest* request,
               EchoResponse* response) override {
-    // Backend should receive the call credentials metadata.
-    auto call_credentials_entry =
-        context->client_metadata().find(g_kCallCredsMdKey);
-    EXPECT_NE(call_credentials_entry, context->client_metadata().end());
-    if (call_credentials_entry != context->client_metadata().end()) {
-      EXPECT_EQ(call_credentials_entry->second, g_kCallCredsMdValue);
-    }
+    auto peer_identity = context->auth_context()->GetPeerIdentity();
     CountedService<TestMultipleServiceImpl<RpcService>>::IncreaseRequestCount();
     const auto status =
         TestMultipleServiceImpl<RpcService>::Echo(context, request, response);
     CountedService<
         TestMultipleServiceImpl<RpcService>>::IncreaseResponseCount();
-    AddClient(context->peer());
+    {
+      grpc_core::MutexLock lock(&mu_);
+      clients_.insert(context->peer());
+      last_peer_identity_.clear();
+      for (const auto& entry : peer_identity) {
+        last_peer_identity_.emplace_back(entry.data(), entry.size());
+      }
+    }
     return status;
   }
 
@@ -309,18 +342,19 @@ class BackendServiceImpl
   void Shutdown() {}
 
   std::set<std::string> clients() {
-    grpc_core::MutexLock lock(&clients_mu_);
+    grpc_core::MutexLock lock(&mu_);
     return clients_;
   }
 
- private:
-  void AddClient(const std::string& client) {
-    grpc_core::MutexLock lock(&clients_mu_);
-    clients_.insert(client);
+  const std::vector<std::string>& last_peer_identity() {
+    grpc_core::MutexLock lock(&mu_);
+    return last_peer_identity_;
   }
 
-  grpc_core::Mutex clients_mu_;
+ private:
+  grpc_core::Mutex mu_;
   std::set<std::string> clients_;
+  std::vector<std::string> last_peer_identity_;
 };
 
 class ClientStats {
@@ -330,7 +364,7 @@ class ClientStats {
 
     // Converts from proto message class.
     template <class UpstreamLocalityStats>
-    LocalityStats(const UpstreamLocalityStats& upstream_locality_stats)
+    explicit LocalityStats(const UpstreamLocalityStats& upstream_locality_stats)
         : total_successful_requests(
               upstream_locality_stats.total_successful_requests()),
           total_requests_in_progress(
@@ -670,9 +704,6 @@ class AdsServiceImpl : public std::enable_shared_from_this<AdsServiceImpl> {
       } else {
         parent_->seen_v3_client_ = true;
       }
-      // Balancer shouldn't receive the call credentials metadata.
-      EXPECT_EQ(context->client_metadata().find(g_kCallCredsMdKey),
-                context->client_metadata().end());
       // Take a reference of the AdsServiceImpl object, which will go
       // out of scope when this request handler returns.  This ensures
       // that the parent won't be destroyed until this stream is complete.
@@ -1286,22 +1317,26 @@ class LrsServiceImpl : public std::enable_shared_from_this<LrsServiceImpl> {
 class TestType {
  public:
   TestType(bool use_xds_resolver, bool enable_load_reporting,
-           bool enable_rds_testing = false, bool use_v2 = false)
+           bool enable_rds_testing = false, bool use_v2 = false,
+           bool use_xds_credentials = false)
       : use_xds_resolver_(use_xds_resolver),
         enable_load_reporting_(enable_load_reporting),
         enable_rds_testing_(enable_rds_testing),
-        use_v2_(use_v2) {}
+        use_v2_(use_v2),
+        use_xds_credentials_(use_xds_credentials) {}
 
   bool use_xds_resolver() const { return use_xds_resolver_; }
   bool enable_load_reporting() const { return enable_load_reporting_; }
   bool enable_rds_testing() const { return enable_rds_testing_; }
   bool use_v2() const { return use_v2_; }
+  bool use_xds_credentials() const { return use_xds_credentials_; }
 
   std::string AsString() const {
     std::string retval = (use_xds_resolver_ ? "XdsResolver" : "FakeResolver");
     retval += (use_v2_ ? "V2" : "V3");
     if (enable_load_reporting_) retval += "WithLoadReporting";
     if (enable_rds_testing_) retval += "Rds";
+    if (use_xds_credentials_) retval += "XdsCreds";
     return retval;
   }
 
@@ -1310,8 +1345,158 @@ class TestType {
   const bool enable_load_reporting_;
   const bool enable_rds_testing_;
   const bool use_v2_;
+  const bool use_xds_credentials_;
 };
 
+std::string ReadFile(const char* file_path) {
+  grpc_slice slice;
+  GPR_ASSERT(
+      GRPC_LOG_IF_ERROR("load_file", grpc_load_file(file_path, 0, &slice)));
+  std::string file_contents(grpc_core::StringViewFromSlice(slice));
+  grpc_slice_unref(slice);
+  return file_contents;
+}
+
+grpc_core::PemKeyCertPairList ReadTlsIdentityPair(const char* key_path,
+                                                  const char* cert_path) {
+  return grpc_core::PemKeyCertPairList{
+      grpc_core::PemKeyCertPair(ReadFile(key_path), ReadFile(cert_path))};
+}
+
+// Based on StaticDataCertificateProvider, but provides alternate certificates
+// if the certificate name is not empty.
+class FakeCertificateProvider final : public grpc_tls_certificate_provider {
+ public:
+  struct CertData {
+    std::string root_certificate;
+    grpc_core::PemKeyCertPairList identity_key_cert_pairs;
+  };
+
+  using CertDataMap = std::map<std::string /*cert_name */, CertData>;
+
+  explicit FakeCertificateProvider(CertDataMap cert_data_map)
+      : distributor_(
+            grpc_core::MakeRefCounted<grpc_tls_certificate_distributor>()),
+        cert_data_map_(std::move(cert_data_map)) {
+    distributor_->SetWatchStatusCallback([this](std::string cert_name,
+                                                bool root_being_watched,
+                                                bool identity_being_watched) {
+      if (!root_being_watched && !identity_being_watched) return;
+      auto it = cert_data_map_.find(cert_name);
+      if (it == cert_data_map_.end()) {
+        grpc_error* error = GRPC_ERROR_CREATE_FROM_COPIED_STRING(
+            absl::StrCat("No certificates available for cert_name \"",
+                         cert_name, "\"")
+                .c_str());
+        distributor_->SetErrorForCert(cert_name, GRPC_ERROR_REF(error),
+                                      GRPC_ERROR_REF(error));
+        GRPC_ERROR_UNREF(error);
+      } else {
+        absl::optional<std::string> root_certificate;
+        absl::optional<grpc_core::PemKeyCertPairList> pem_key_cert_pairs;
+        if (root_being_watched) {
+          root_certificate = it->second.root_certificate;
+        }
+        if (identity_being_watched) {
+          pem_key_cert_pairs = it->second.identity_key_cert_pairs;
+        }
+        distributor_->SetKeyMaterials(cert_name, std::move(root_certificate),
+                                      std::move(pem_key_cert_pairs));
+      }
+    });
+  }
+
+  ~FakeCertificateProvider() override {
+    distributor_->SetWatchStatusCallback(nullptr);
+  }
+
+  grpc_core::RefCountedPtr<grpc_tls_certificate_distributor> distributor()
+      const override {
+    return distributor_;
+  }
+
+ private:
+  grpc_core::RefCountedPtr<grpc_tls_certificate_distributor> distributor_;
+  CertDataMap cert_data_map_;
+};
+
+class FakeCertificateProviderFactory
+    : public grpc_core::CertificateProviderFactory {
+ public:
+  class Config : public grpc_core::CertificateProviderFactory::Config {
+   public:
+    explicit Config(const char* name) : name_(name) {}
+
+    const char* name() const override { return name_; }
+
+    std::string ToString() const override { return "{}"; }
+
+   private:
+    const char* name_;
+  };
+
+  FakeCertificateProviderFactory(
+      const char* name, FakeCertificateProvider::CertDataMap** cert_data_map)
+      : name_(name), cert_data_map_(cert_data_map) {
+    GPR_ASSERT(cert_data_map != nullptr);
+  }
+
+  const char* name() const override { return name_; }
+
+  grpc_core::RefCountedPtr<grpc_core::CertificateProviderFactory::Config>
+  CreateCertificateProviderConfig(const grpc_core::Json& config_json,
+                                  grpc_error** error) override {
+    return grpc_core::MakeRefCounted<Config>(name_);
+  }
+
+  grpc_core::RefCountedPtr<grpc_tls_certificate_provider>
+  CreateCertificateProvider(
+      grpc_core::RefCountedPtr<grpc_core::CertificateProviderFactory::Config>
+          config) override {
+    if (*cert_data_map_ == nullptr) return nullptr;
+    return grpc_core::MakeRefCounted<FakeCertificateProvider>(**cert_data_map_);
+  }
+
+ private:
+  const char* name_;
+  FakeCertificateProvider::CertDataMap** cert_data_map_;
+};
+
+// Global variables for each provider.
+FakeCertificateProvider::CertDataMap* g_fake1_cert_data_map = nullptr;
+FakeCertificateProvider::CertDataMap* g_fake2_cert_data_map = nullptr;
+
+int ServerAuthCheckSchedule(void* /* config_user_data */,
+                            grpc_tls_server_authorization_check_arg* arg) {
+  arg->success = 1;
+  arg->status = GRPC_STATUS_OK;
+  return 0; /* synchronous check */
+}
+
+std::shared_ptr<ChannelCredentials> CreateTlsFallbackCredentials() {
+  // TODO(yashykt): Switch to using C++ API once b/173823806 is fixed.
+  grpc_tls_credentials_options* options = grpc_tls_credentials_options_create();
+  grpc_tls_credentials_options_set_server_verification_option(
+      options, GRPC_TLS_SKIP_HOSTNAME_VERIFICATION);
+  grpc_tls_credentials_options_set_certificate_provider(
+      options,
+      grpc_core::MakeRefCounted<grpc_core::StaticDataCertificateProvider>(
+          ReadFile(kCaCertPath),
+          ReadTlsIdentityPair(kServerKeyPath, kServerCertPath))
+          .get());
+  grpc_tls_credentials_options_watch_root_certs(options);
+  grpc_tls_credentials_options_watch_identity_key_cert_pairs(options);
+  grpc_tls_server_authorization_check_config* check_config =
+      grpc_tls_server_authorization_check_config_create(
+          nullptr, ServerAuthCheckSchedule, nullptr, nullptr);
+  grpc_tls_credentials_options_set_server_authorization_check_config(
+      options, check_config);
+  auto channel_creds = std::make_shared<SecureChannelCredentials>(
+      grpc_tls_credentials_create(options));
+  grpc_tls_server_authorization_check_config_release(check_config);
+  return channel_creds;
+}
+
 class XdsEnd2endTest : public ::testing::TestWithParam<TestType> {
  protected:
   XdsEnd2endTest(size_t num_backends, size_t num_balancers,
@@ -1457,18 +1642,12 @@ class XdsEnd2endTest : public ::testing::TestWithParam<TestType> {
     }
     std::string uri = absl::StrCat(
         GetParam().use_xds_resolver() ? "xds" : "fake", ":///", server_name);
-    // TODO(dgq): templatize tests to run everything using both secure and
-    // insecure channel credentials.
-    grpc_channel_credentials* channel_creds =
-        grpc_fake_transport_security_credentials_create();
-    grpc_call_credentials* call_creds = grpc_md_only_test_credentials_create(
-        g_kCallCredsMdKey, g_kCallCredsMdValue, false);
-    std::shared_ptr<ChannelCredentials> creds(
-        new SecureChannelCredentials(grpc_composite_channel_credentials_create(
-            channel_creds, call_creds, nullptr)));
-    call_creds->Unref();
-    channel_creds->Unref();
-    return ::grpc::CreateCustomChannel(uri, creds, args);
+    std::shared_ptr<ChannelCredentials> channel_creds =
+        GetParam().use_xds_credentials()
+            ? experimental::XdsCredentials(CreateTlsFallbackCredentials())
+            : std::make_shared<SecureChannelCredentials>(
+                  grpc_fake_transport_security_credentials_create());
+    return ::grpc::CreateCustomChannel(uri, channel_creds, args);
   }
 
   enum RpcService {
@@ -1630,14 +1809,12 @@ class XdsEnd2endTest : public ::testing::TestWithParam<TestType> {
       const std::vector<int>& ports) {
     grpc_core::ServerAddressList addresses;
     for (int port : ports) {
-      std::string lb_uri_str =
-          absl::StrCat(ipv6_only_ ? "ipv6:[::1]:" : "ipv4:127.0.0.1:", port);
-      grpc_uri* lb_uri = grpc_uri_parse(lb_uri_str.c_str(), true);
-      GPR_ASSERT(lb_uri != nullptr);
+      absl::StatusOr<grpc_core::URI> lb_uri = grpc_core::URI::Parse(
+          absl::StrCat(ipv6_only_ ? "ipv6:[::1]:" : "ipv4:127.0.0.1:", port));
+      GPR_ASSERT(lb_uri.ok());
       grpc_resolved_address address;
-      GPR_ASSERT(grpc_parse_uri(lb_uri, &address));
+      GPR_ASSERT(grpc_parse_uri(*lb_uri, &address));
       addresses.emplace_back(address.addr, address.len, nullptr);
-      grpc_uri_destroy(lb_uri);
     }
     return addresses;
   }
@@ -1901,9 +2078,7 @@ class XdsEnd2endTest : public ::testing::TestWithParam<TestType> {
       std::ostringstream server_address;
       server_address << "localhost:" << port_;
       ServerBuilder builder;
-      std::shared_ptr<ServerCredentials> creds(new SecureServerCredentials(
-          grpc_fake_transport_security_server_credentials_create()));
-      builder.AddListeningPort(server_address.str(), creds);
+      builder.AddListeningPort(server_address.str(), Credentials());
       RegisterAllServices(&builder);
       server_ = builder.BuildAndStart();
       cond->Signal();
@@ -1919,6 +2094,11 @@ class XdsEnd2endTest : public ::testing::TestWithParam<TestType> {
       running_ = false;
     }
 
+    virtual std::shared_ptr<ServerCredentials> Credentials() {
+      return std::make_shared<SecureServerCredentials>(
+          grpc_fake_transport_security_server_credentials_create());
+    }
+
     int port() const { return port_; }
 
    private:
@@ -1949,6 +2129,27 @@ class XdsEnd2endTest : public ::testing::TestWithParam<TestType> {
       return &backend_service2_;
     }
 
+    std::shared_ptr<ServerCredentials> Credentials() override {
+      if (GetParam().use_xds_credentials()) {
+        std::string root_cert = ReadFile(kCaCertPath);
+        std::string identity_cert = ReadFile(kServerCertPath);
+        std::string private_key = ReadFile(kServerKeyPath);
+        std::vector<experimental::IdentityKeyCertPair> identity_key_cert_pairs =
+            {{private_key, identity_cert}};
+        auto certificate_provider =
+            std::make_shared<grpc::experimental::StaticDataCertificateProvider>(
+                root_cert, identity_key_cert_pairs);
+        grpc::experimental::TlsServerCredentialsOptions options(
+            certificate_provider);
+        options.watch_root_certs();
+        options.watch_identity_key_cert_pairs();
+        options.set_cert_request_type(
+            GRPC_SSL_REQUEST_CLIENT_CERTIFICATE_AND_VERIFY);
+        return grpc::experimental::TlsServerCredentials(options);
+      }
+      return ServerThread::Credentials();
+    }
+
    private:
     void RegisterAllServices(ServerBuilder* builder) override {
       builder->RegisterService(&backend_service_);
@@ -2084,9 +2285,10 @@ TEST_P(BasicTest, Vanilla) {
               backends_[i]->backend_service()->request_count());
   }
   // Check LB policy name for the channel.
-  EXPECT_EQ((GetParam().use_xds_resolver() ? "xds_cluster_manager_experimental"
-                                           : "eds_experimental"),
-            channel_->GetLoadBalancingPolicyName());
+  EXPECT_EQ(
+      (GetParam().use_xds_resolver() ? "xds_cluster_manager_experimental"
+                                     : "xds_cluster_resolver_experimental"),
+      channel_->GetLoadBalancingPolicyName());
 }
 
 TEST_P(BasicTest, IgnoresUnhealthyEndpoints) {
@@ -3143,6 +3345,32 @@ TEST_P(LdsRdsTest, RouteActionWeightedTargetHasIncorrectTotalWeightSet) {
             "RouteAction weighted_cluster has incorrect total weight");
 }
 
+TEST_P(LdsRdsTest, RouteActionWeightedClusterHasZeroTotalWeight) {
+  const char* kNewCluster1Name = "new_cluster_1";
+  RouteConfiguration route_config = default_route_config_;
+  auto* route1 = route_config.mutable_virtual_hosts(0)->mutable_routes(0);
+  route1->mutable_match()->set_prefix("/grpc.testing.EchoTest1Service/");
+  auto* weighted_cluster1 =
+      route1->mutable_route()->mutable_weighted_clusters()->add_clusters();
+  weighted_cluster1->set_name(kNewCluster1Name);
+  weighted_cluster1->mutable_weight()->set_value(0);
+  route1->mutable_route()
+      ->mutable_weighted_clusters()
+      ->mutable_total_weight()
+      ->set_value(0);
+  auto* default_route = route_config.mutable_virtual_hosts(0)->add_routes();
+  default_route->mutable_match()->set_prefix("");
+  default_route->mutable_route()->set_cluster(kDefaultClusterName);
+  SetRouteConfiguration(0, route_config);
+  SetNextResolution({});
+  SetNextResolutionForLbChannelAllBalancers();
+  CheckRpcSendFailure();
+  const auto& response_state = RouteConfigurationResponseState(0);
+  EXPECT_EQ(response_state.state, AdsServiceImpl::ResponseState::NACKED);
+  EXPECT_EQ(response_state.error_message,
+            "RouteAction weighted_cluster has no valid clusters specified.");
+}
+
 TEST_P(LdsRdsTest, RouteActionWeightedTargetClusterHasEmptyClusterName) {
   const size_t kWeight75 = 75;
   RouteConfiguration route_config = default_route_config_;
@@ -3657,6 +3885,7 @@ TEST_P(LdsRdsTest, XdsRoutingWeightedCluster) {
   const char* kNewEdsService1Name = "new_eds_service_name_1";
   const char* kNewCluster2Name = "new_cluster_2";
   const char* kNewEdsService2Name = "new_eds_service_name_2";
+  const char* kNotUsedClusterName = "not_used_cluster";
   const size_t kNumEcho1Rpcs = 1000;
   const size_t kNumEchoRpcs = 10;
   const size_t kWeight75 = 75;
@@ -3701,6 +3930,11 @@ TEST_P(LdsRdsTest, XdsRoutingWeightedCluster) {
       route1->mutable_route()->mutable_weighted_clusters()->add_clusters();
   weighted_cluster2->set_name(kNewCluster2Name);
   weighted_cluster2->mutable_weight()->set_value(kWeight25);
+  // Cluster with weight 0 will not be used.
+  auto* weighted_cluster3 =
+      route1->mutable_route()->mutable_weighted_clusters()->add_clusters();
+  weighted_cluster3->set_name(kNotUsedClusterName);
+  weighted_cluster3->mutable_weight()->set_value(0);
   route1->mutable_route()
       ->mutable_weighted_clusters()
       ->mutable_total_weight()
@@ -3723,21 +3957,23 @@ TEST_P(LdsRdsTest, XdsRoutingWeightedCluster) {
   const int weight_25_request_count =
       backends_[2]->backend_service1()->request_count();
   const double kErrorTolerance = 0.2;
-  EXPECT_THAT(weight_75_request_count,
-              ::testing::AllOf(::testing::Ge(kNumEcho1Rpcs * kWeight75 / 100 *
-                                             (1 - kErrorTolerance)),
-                               ::testing::Le(kNumEcho1Rpcs * kWeight75 / 100 *
-                                             (1 + kErrorTolerance))));
-  // TODO: (@donnadionne) Reduce tolerance: increased the tolerance to keep the
+  EXPECT_THAT(
+      weight_75_request_count,
+      ::testing::AllOf(::testing::Ge(static_cast<double>(kNumEcho1Rpcs) *
+                                     kWeight75 / 100 * (1 - kErrorTolerance)),
+                       ::testing::Le(static_cast<double>(kNumEcho1Rpcs) *
+                                     kWeight75 / 100 * (1 + kErrorTolerance))));
+  // TODO(@donnadionne): Reduce tolerance: increased the tolerance to keep the
   // test from flaking while debugging potential root cause.
   const double kErrorToleranceSmallLoad = 0.3;
   gpr_log(GPR_INFO, "target_75 received %d rpcs and target_25 received %d rpcs",
           weight_75_request_count, weight_25_request_count);
   EXPECT_THAT(weight_25_request_count,
-              ::testing::AllOf(::testing::Ge(kNumEcho1Rpcs * kWeight25 / 100 *
-                                             (1 - kErrorToleranceSmallLoad)),
-                               ::testing::Le(kNumEcho1Rpcs * kWeight25 / 100 *
-                                             (1 + kErrorToleranceSmallLoad))));
+              ::testing::AllOf(
+                  ::testing::Ge(static_cast<double>(kNumEcho1Rpcs) * kWeight25 /
+                                100 * (1 - kErrorToleranceSmallLoad)),
+                  ::testing::Le(static_cast<double>(kNumEcho1Rpcs) * kWeight25 /
+                                100 * (1 + kErrorToleranceSmallLoad))));
 }
 
 TEST_P(LdsRdsTest, RouteActionWeightedTargetDefaultRoute) {
@@ -3802,21 +4038,23 @@ TEST_P(LdsRdsTest, RouteActionWeightedTargetDefaultRoute) {
   const int weight_25_request_count =
       backends_[2]->backend_service()->request_count();
   const double kErrorTolerance = 0.2;
-  EXPECT_THAT(weight_75_request_count,
-              ::testing::AllOf(::testing::Ge(kNumEchoRpcs * kWeight75 / 100 *
-                                             (1 - kErrorTolerance)),
-                               ::testing::Le(kNumEchoRpcs * kWeight75 / 100 *
-                                             (1 + kErrorTolerance))));
-  // TODO: (@donnadionne) Reduce tolerance: increased the tolerance to keep the
+  EXPECT_THAT(
+      weight_75_request_count,
+      ::testing::AllOf(::testing::Ge(static_cast<double>(kNumEchoRpcs) *
+                                     kWeight75 / 100 * (1 - kErrorTolerance)),
+                       ::testing::Le(static_cast<double>(kNumEchoRpcs) *
+                                     kWeight75 / 100 * (1 + kErrorTolerance))));
+  // TODO(@donnadionne): Reduce tolerance: increased the tolerance to keep the
   // test from flaking while debugging potential root cause.
   const double kErrorToleranceSmallLoad = 0.3;
   gpr_log(GPR_INFO, "target_75 received %d rpcs and target_25 received %d rpcs",
           weight_75_request_count, weight_25_request_count);
   EXPECT_THAT(weight_25_request_count,
-              ::testing::AllOf(::testing::Ge(kNumEchoRpcs * kWeight25 / 100 *
-                                             (1 - kErrorToleranceSmallLoad)),
-                               ::testing::Le(kNumEchoRpcs * kWeight25 / 100 *
-                                             (1 + kErrorToleranceSmallLoad))));
+              ::testing::AllOf(
+                  ::testing::Ge(static_cast<double>(kNumEchoRpcs) * kWeight25 /
+                                100 * (1 - kErrorToleranceSmallLoad)),
+                  ::testing::Le(static_cast<double>(kNumEchoRpcs) * kWeight25 /
+                                100 * (1 + kErrorToleranceSmallLoad))));
 }
 
 TEST_P(LdsRdsTest, XdsRoutingWeightedClusterUpdateWeights) {
@@ -3906,21 +4144,23 @@ TEST_P(LdsRdsTest, XdsRoutingWeightedClusterUpdateWeights) {
   EXPECT_EQ(0, backends_[3]->backend_service()->request_count());
   EXPECT_EQ(0, backends_[3]->backend_service1()->request_count());
   const double kErrorTolerance = 0.2;
-  EXPECT_THAT(weight_75_request_count,
-              ::testing::AllOf(::testing::Ge(kNumEcho1Rpcs * kWeight75 / 100 *
-                                             (1 - kErrorTolerance)),
-                               ::testing::Le(kNumEcho1Rpcs * kWeight75 / 100 *
-                                             (1 + kErrorTolerance))));
-  // TODO: (@donnadionne) Reduce tolerance: increased the tolerance to keep the
+  EXPECT_THAT(
+      weight_75_request_count,
+      ::testing::AllOf(::testing::Ge(static_cast<double>(kNumEcho1Rpcs) *
+                                     kWeight75 / 100 * (1 - kErrorTolerance)),
+                       ::testing::Le(static_cast<double>(kNumEcho1Rpcs) *
+                                     kWeight75 / 100 * (1 + kErrorTolerance))));
+  // TODO(@donnadionne): Reduce tolerance: increased the tolerance to keep the
   // test from flaking while debugging potential root cause.
   const double kErrorToleranceSmallLoad = 0.3;
   gpr_log(GPR_INFO, "target_75 received %d rpcs and target_25 received %d rpcs",
           weight_75_request_count, weight_25_request_count);
   EXPECT_THAT(weight_25_request_count,
-              ::testing::AllOf(::testing::Ge(kNumEcho1Rpcs * kWeight25 / 100 *
-                                             (1 - kErrorToleranceSmallLoad)),
-                               ::testing::Le(kNumEcho1Rpcs * kWeight25 / 100 *
-                                             (1 + kErrorToleranceSmallLoad))));
+              ::testing::AllOf(
+                  ::testing::Ge(static_cast<double>(kNumEcho1Rpcs) * kWeight25 /
+                                100 * (1 - kErrorToleranceSmallLoad)),
+                  ::testing::Le(static_cast<double>(kNumEcho1Rpcs) * kWeight25 /
+                                100 * (1 + kErrorToleranceSmallLoad))));
   // Change Route Configurations: same clusters different weights.
   weighted_cluster1->mutable_weight()->set_value(kWeight50);
   weighted_cluster2->mutable_weight()->set_value(kWeight50);
@@ -3943,16 +4183,18 @@ TEST_P(LdsRdsTest, XdsRoutingWeightedClusterUpdateWeights) {
       backends_[2]->backend_service1()->request_count();
   EXPECT_EQ(kNumEchoRpcs, backends_[3]->backend_service()->request_count());
   EXPECT_EQ(0, backends_[3]->backend_service1()->request_count());
-  EXPECT_THAT(weight_50_request_count_1,
-              ::testing::AllOf(::testing::Ge(kNumEcho1Rpcs * kWeight50 / 100 *
-                                             (1 - kErrorTolerance)),
-                               ::testing::Le(kNumEcho1Rpcs * kWeight50 / 100 *
-                                             (1 + kErrorTolerance))));
-  EXPECT_THAT(weight_50_request_count_2,
-              ::testing::AllOf(::testing::Ge(kNumEcho1Rpcs * kWeight50 / 100 *
-                                             (1 - kErrorTolerance)),
-                               ::testing::Le(kNumEcho1Rpcs * kWeight50 / 100 *
-                                             (1 + kErrorTolerance))));
+  EXPECT_THAT(
+      weight_50_request_count_1,
+      ::testing::AllOf(::testing::Ge(static_cast<double>(kNumEcho1Rpcs) *
+                                     kWeight50 / 100 * (1 - kErrorTolerance)),
+                       ::testing::Le(static_cast<double>(kNumEcho1Rpcs) *
+                                     kWeight50 / 100 * (1 + kErrorTolerance))));
+  EXPECT_THAT(
+      weight_50_request_count_2,
+      ::testing::AllOf(::testing::Ge(static_cast<double>(kNumEcho1Rpcs) *
+                                     kWeight50 / 100 * (1 - kErrorTolerance)),
+                       ::testing::Le(static_cast<double>(kNumEcho1Rpcs) *
+                                     kWeight50 / 100 * (1 + kErrorTolerance))));
 }
 
 TEST_P(LdsRdsTest, XdsRoutingWeightedClusterUpdateClusters) {
@@ -4041,21 +4283,23 @@ TEST_P(LdsRdsTest, XdsRoutingWeightedClusterUpdateClusters) {
   EXPECT_EQ(0, backends_[3]->backend_service()->request_count());
   EXPECT_EQ(0, backends_[3]->backend_service1()->request_count());
   const double kErrorTolerance = 0.2;
-  EXPECT_THAT(weight_75_request_count,
-              ::testing::AllOf(::testing::Ge(kNumEcho1Rpcs * kWeight75 / 100 *
-                                             (1 - kErrorTolerance)),
-                               ::testing::Le(kNumEcho1Rpcs * kWeight75 / 100 *
-                                             (1 + kErrorTolerance))));
-  // TODO: (@donnadionne) Reduce tolerance: increased the tolerance to keep the
+  EXPECT_THAT(
+      weight_75_request_count,
+      ::testing::AllOf(::testing::Ge(static_cast<double>(kNumEcho1Rpcs) *
+                                     kWeight75 / 100 * (1 - kErrorTolerance)),
+                       ::testing::Le(static_cast<double>(kNumEcho1Rpcs) *
+                                     kWeight75 / 100 * (1 + kErrorTolerance))));
+  // TODO(@donnadionne): Reduce tolerance: increased the tolerance to keep the
   // test from flaking while debugging potential root cause.
   const double kErrorToleranceSmallLoad = 0.3;
   gpr_log(GPR_INFO, "target_75 received %d rpcs and target_25 received %d rpcs",
           weight_75_request_count, weight_25_request_count);
   EXPECT_THAT(weight_25_request_count,
-              ::testing::AllOf(::testing::Ge(kNumEcho1Rpcs * kWeight25 / 100 *
-                                             (1 - kErrorToleranceSmallLoad)),
-                               ::testing::Le(kNumEcho1Rpcs * kWeight25 / 100 *
-                                             (1 + kErrorToleranceSmallLoad))));
+              ::testing::AllOf(
+                  ::testing::Ge(static_cast<double>(kNumEcho1Rpcs) * kWeight25 /
+                                100 * (1 - kErrorToleranceSmallLoad)),
+                  ::testing::Le(static_cast<double>(kNumEcho1Rpcs) * kWeight25 /
+                                100 * (1 + kErrorToleranceSmallLoad))));
   // Change Route Configurations: new set of clusters with different weights.
   weighted_cluster1->mutable_weight()->set_value(kWeight50);
   weighted_cluster2->set_name(kNewCluster2Name);
@@ -4076,16 +4320,18 @@ TEST_P(LdsRdsTest, XdsRoutingWeightedClusterUpdateClusters) {
       backends_[2]->backend_service1()->request_count();
   EXPECT_EQ(0, backends_[3]->backend_service()->request_count());
   EXPECT_EQ(0, backends_[3]->backend_service1()->request_count());
-  EXPECT_THAT(weight_50_request_count_1,
-              ::testing::AllOf(::testing::Ge(kNumEcho1Rpcs * kWeight50 / 100 *
-                                             (1 - kErrorTolerance)),
-                               ::testing::Le(kNumEcho1Rpcs * kWeight50 / 100 *
-                                             (1 + kErrorTolerance))));
-  EXPECT_THAT(weight_50_request_count_2,
-              ::testing::AllOf(::testing::Ge(kNumEcho1Rpcs * kWeight50 / 100 *
-                                             (1 - kErrorTolerance)),
-                               ::testing::Le(kNumEcho1Rpcs * kWeight50 / 100 *
-                                             (1 + kErrorTolerance))));
+  EXPECT_THAT(
+      weight_50_request_count_1,
+      ::testing::AllOf(::testing::Ge(static_cast<double>(kNumEcho1Rpcs) *
+                                     kWeight50 / 100 * (1 - kErrorTolerance)),
+                       ::testing::Le(static_cast<double>(kNumEcho1Rpcs) *
+                                     kWeight50 / 100 * (1 + kErrorTolerance))));
+  EXPECT_THAT(
+      weight_50_request_count_2,
+      ::testing::AllOf(::testing::Ge(static_cast<double>(kNumEcho1Rpcs) *
+                                     kWeight50 / 100 * (1 - kErrorTolerance)),
+                       ::testing::Le(static_cast<double>(kNumEcho1Rpcs) *
+                                     kWeight50 / 100 * (1 + kErrorTolerance))));
   // Change Route Configurations.
   weighted_cluster1->mutable_weight()->set_value(kWeight75);
   weighted_cluster2->set_name(kNewCluster3Name);
@@ -4104,20 +4350,22 @@ TEST_P(LdsRdsTest, XdsRoutingWeightedClusterUpdateClusters) {
   EXPECT_EQ(0, backends_[2]->backend_service1()->request_count());
   EXPECT_EQ(0, backends_[3]->backend_service()->request_count());
   weight_25_request_count = backends_[3]->backend_service1()->request_count();
-  EXPECT_THAT(weight_75_request_count,
-              ::testing::AllOf(::testing::Ge(kNumEcho1Rpcs * kWeight75 / 100 *
-                                             (1 - kErrorTolerance)),
-                               ::testing::Le(kNumEcho1Rpcs * kWeight75 / 100 *
-                                             (1 + kErrorTolerance))));
-  // TODO: (@donnadionne) Reduce tolerance: increased the tolerance to keep the
+  EXPECT_THAT(
+      weight_75_request_count,
+      ::testing::AllOf(::testing::Ge(static_cast<double>(kNumEcho1Rpcs) *
+                                     kWeight75 / 100 * (1 - kErrorTolerance)),
+                       ::testing::Le(static_cast<double>(kNumEcho1Rpcs) *
+                                     kWeight75 / 100 * (1 + kErrorTolerance))));
+  // TODO(@donnadionne): Reduce tolerance: increased the tolerance to keep the
   // test from flaking while debugging potential root cause.
   gpr_log(GPR_INFO, "target_75 received %d rpcs and target_25 received %d rpcs",
           weight_75_request_count, weight_25_request_count);
   EXPECT_THAT(weight_25_request_count,
-              ::testing::AllOf(::testing::Ge(kNumEcho1Rpcs * kWeight25 / 100 *
-                                             (1 - kErrorToleranceSmallLoad)),
-                               ::testing::Le(kNumEcho1Rpcs * kWeight25 / 100 *
-                                             (1 + kErrorToleranceSmallLoad))));
+              ::testing::AllOf(
+                  ::testing::Ge(static_cast<double>(kNumEcho1Rpcs) * kWeight25 /
+                                100 * (1 - kErrorToleranceSmallLoad)),
+                  ::testing::Le(static_cast<double>(kNumEcho1Rpcs) * kWeight25 /
+                                100 * (1 + kErrorToleranceSmallLoad))));
 }
 
 TEST_P(LdsRdsTest, XdsRoutingClusterUpdateClusters) {
@@ -4830,14 +5078,18 @@ TEST_P(LdsRdsTest, XdsRoutingRuntimeFractionMatching) {
   const int matched_backend_count =
       backends_[1]->backend_service()->request_count();
   const double kErrorTolerance = 0.2;
-  EXPECT_THAT(default_backend_count,
-              ::testing::AllOf(
-                  ::testing::Ge(kNumRpcs * 75 / 100 * (1 - kErrorTolerance)),
-                  ::testing::Le(kNumRpcs * 75 / 100 * (1 + kErrorTolerance))));
-  EXPECT_THAT(matched_backend_count,
-              ::testing::AllOf(
-                  ::testing::Ge(kNumRpcs * 25 / 100 * (1 - kErrorTolerance)),
-                  ::testing::Le(kNumRpcs * 25 / 100 * (1 + kErrorTolerance))));
+  EXPECT_THAT(
+      default_backend_count,
+      ::testing::AllOf(::testing::Ge(static_cast<double>(kNumRpcs) * 75 / 100 *
+                                     (1 - kErrorTolerance)),
+                       ::testing::Le(static_cast<double>(kNumRpcs) * 75 / 100 *
+                                     (1 + kErrorTolerance))));
+  EXPECT_THAT(
+      matched_backend_count,
+      ::testing::AllOf(::testing::Ge(static_cast<double>(kNumRpcs) * 25 / 100 *
+                                     (1 - kErrorTolerance)),
+                       ::testing::Le(static_cast<double>(kNumRpcs) * 25 / 100 *
+                                     (1 + kErrorTolerance))));
   const auto& response_state = RouteConfigurationResponseState(0);
   EXPECT_EQ(response_state.state, AdsServiceImpl::ResponseState::ACKED);
 }
@@ -5075,6 +5327,612 @@ TEST_P(CdsTest, WrongLrsServer) {
   EXPECT_EQ(response_state.error_message, "LRS ConfigSource is not self.");
 }
 
+class XdsSecurityTest : public BasicTest {
+ protected:
+  static void SetUpTestCase() {
+    gpr_setenv("GRPC_XDS_EXPERIMENTAL_SECURITY_SUPPORT", "true");
+    BasicTest::SetUpTestCase();
+    grpc_core::CertificateProviderRegistry::RegisterCertificateProviderFactory(
+        absl::make_unique<FakeCertificateProviderFactory>(
+            "fake1", &g_fake1_cert_data_map));
+    grpc_core::CertificateProviderRegistry::RegisterCertificateProviderFactory(
+        absl::make_unique<FakeCertificateProviderFactory>(
+            "fake2", &g_fake2_cert_data_map));
+  }
+
+  static void TearDownTestCase() {
+    BasicTest::TearDownTestCase();
+    gpr_unsetenv("GRPC_XDS_EXPERIMENTAL_SECURITY_SUPPORT");
+  }
+
+  void SetUp() override {
+    BasicTest::SetUp();
+    root_cert_ = ReadFile(kCaCertPath);
+    bad_root_cert_ = ReadFile(kBadClientCertPath);
+    identity_pair_ = ReadTlsIdentityPair(kClientKeyPath, kClientCertPath);
+    // TODO(yashykt): Use different client certs here instead of reusing server
+    // certs after https://github.com/grpc/grpc/pull/24876 is merged
+    fallback_identity_pair_ =
+        ReadTlsIdentityPair(kServerKeyPath, kServerCertPath);
+    bad_identity_pair_ =
+        ReadTlsIdentityPair(kBadClientKeyPath, kBadClientCertPath);
+    server_san_exact_.set_exact("*.test.google.fr");
+    server_san_prefix_.set_prefix("waterzooi.test.google");
+    server_san_suffix_.set_suffix("google.fr");
+    server_san_contains_.set_contains("google");
+    server_san_regex_.mutable_safe_regex()->mutable_google_re2();
+    server_san_regex_.mutable_safe_regex()->set_regex(
+        "(foo|waterzooi).test.google.(fr|be)");
+    bad_san_1_.set_exact("192.168.1.4");
+    bad_san_2_.set_exact("foo.test.google.in");
+    authenticated_identity_ = {"testclient"};
+    fallback_authenticated_identity_ = {"*.test.google.fr",
+                                        "waterzooi.test.google.be",
+                                        "*.test.youtube.com", "192.168.1.3"};
+    AdsServiceImpl::EdsResourceArgs args({
+        {"locality0", GetBackendPorts(0, 1)},
+    });
+    balancers_[0]->ads_service()->SetEdsResource(
+        BuildEdsResource(args, DefaultEdsServiceName()));
+    SetNextResolutionForLbChannelAllBalancers();
+  }
+
+  void TearDown() override {
+    g_fake1_cert_data_map = nullptr;
+    g_fake2_cert_data_map = nullptr;
+    BasicTest::TearDown();
+  }
+
+  // Sends CDS updates with the new security configuration and verifies that
+  // after propagation, this new configuration is used for connections. If \a
+  // identity_instance_name and \a root_instance_name are both empty,
+  // connections are expected to use fallback credentials.
+  void UpdateAndVerifyXdsSecurityConfiguration(
+      absl::string_view root_instance_name,
+      absl::string_view root_certificate_name,
+      absl::string_view identity_instance_name,
+      absl::string_view identity_certificate_name,
+      const std::vector<StringMatcher>& san_matchers,
+      const std::vector<std::string>& expected_authenticated_identity,
+      bool test_expects_failure = false) {
+    auto cluster = default_cluster_;
+    if (!identity_instance_name.empty() || !root_instance_name.empty()) {
+      auto* transport_socket = cluster.mutable_transport_socket();
+      transport_socket->set_name("envoy.transport_sockets.tls");
+      UpstreamTlsContext upstream_tls_context;
+      if (!identity_instance_name.empty()) {
+        upstream_tls_context.mutable_common_tls_context()
+            ->mutable_tls_certificate_certificate_provider_instance()
+            ->set_instance_name(std::string(identity_instance_name));
+        upstream_tls_context.mutable_common_tls_context()
+            ->mutable_tls_certificate_certificate_provider_instance()
+            ->set_certificate_name(std::string(identity_certificate_name));
+      }
+      if (!root_instance_name.empty()) {
+        upstream_tls_context.mutable_common_tls_context()
+            ->mutable_combined_validation_context()
+            ->mutable_validation_context_certificate_provider_instance()
+            ->set_instance_name(std::string(root_instance_name));
+        upstream_tls_context.mutable_common_tls_context()
+            ->mutable_combined_validation_context()
+            ->mutable_validation_context_certificate_provider_instance()
+            ->set_certificate_name(std::string(root_certificate_name));
+      }
+      if (!san_matchers.empty()) {
+        auto* validation_context =
+            upstream_tls_context.mutable_common_tls_context()
+                ->mutable_combined_validation_context()
+                ->mutable_default_validation_context();
+        for (const auto& san_matcher : san_matchers) {
+          *validation_context->add_match_subject_alt_names() = san_matcher;
+        }
+      }
+      transport_socket->mutable_typed_config()->PackFrom(upstream_tls_context);
+    }
+    balancers_[0]->ads_service()->SetCdsResource(cluster);
+    // The updates might take time to have an effect, so use a retry loop.
+    constexpr int kRetryCount = 10;
+    int num_tries = 0;
+    for (; num_tries < kRetryCount; num_tries++) {
+      // Give some time for the updates to propagate.
+      gpr_sleep_until(grpc_timeout_milliseconds_to_deadline(100));
+      ShutdownBackend(0);
+      StartBackend(0);
+      ResetBackendCounters();
+      if (test_expects_failure) {
+        if (!SendRpc().ok()) break;
+      } else {
+        WaitForBackend(0);
+        if (SendRpc().ok() &&
+            backends_[0]->backend_service()->request_count() == 1UL &&
+            backends_[0]->backend_service()->last_peer_identity() ==
+                expected_authenticated_identity) {
+          break;
+        }
+      }
+    }
+    EXPECT_TRUE(num_tries < kRetryCount);
+  }
+
+  std::string root_cert_;
+  std::string bad_root_cert_;
+  grpc_core::PemKeyCertPairList identity_pair_;
+  grpc_core::PemKeyCertPairList fallback_identity_pair_;
+  grpc_core::PemKeyCertPairList bad_identity_pair_;
+  StringMatcher server_san_exact_;
+  StringMatcher server_san_prefix_;
+  StringMatcher server_san_suffix_;
+  StringMatcher server_san_contains_;
+  StringMatcher server_san_regex_;
+  StringMatcher bad_san_1_;
+  StringMatcher bad_san_2_;
+  std::vector<std::string> authenticated_identity_;
+  std::vector<std::string> fallback_authenticated_identity_;
+};
+
+TEST_P(XdsSecurityTest,
+       TLSConfigurationWithoutValidationContextCertificateProviderInstance) {
+  auto cluster = default_cluster_;
+  auto* transport_socket = cluster.mutable_transport_socket();
+  transport_socket->set_name("envoy.transport_sockets.tls");
+  balancers_[0]->ads_service()->SetCdsResource(cluster);
+  CheckRpcSendFailure();
+  const auto& response_state =
+      balancers_[0]->ads_service()->cds_response_state();
+  EXPECT_EQ(response_state.state, AdsServiceImpl::ResponseState::NACKED);
+  EXPECT_EQ(response_state.error_message,
+            "TLS configuration provided but no "
+            "validation_context_certificate_provider_instance found.");
+}
+
+TEST_P(
+    XdsSecurityTest,
+    MatchSubjectAltNamesProvidedWithoutValidationContextCertificateProviderInstance) {
+  auto cluster = default_cluster_;
+  auto* transport_socket = cluster.mutable_transport_socket();
+  transport_socket->set_name("envoy.transport_sockets.tls");
+  UpstreamTlsContext upstream_tls_context;
+  auto* validation_context = upstream_tls_context.mutable_common_tls_context()
+                                 ->mutable_combined_validation_context()
+                                 ->mutable_default_validation_context();
+  *validation_context->add_match_subject_alt_names() = server_san_exact_;
+  transport_socket->mutable_typed_config()->PackFrom(upstream_tls_context);
+  balancers_[0]->ads_service()->SetCdsResource(cluster);
+  CheckRpcSendFailure();
+  const auto& response_state =
+      balancers_[0]->ads_service()->cds_response_state();
+  EXPECT_EQ(response_state.state, AdsServiceImpl::ResponseState::NACKED);
+  EXPECT_EQ(response_state.error_message,
+            "TLS configuration provided but no "
+            "validation_context_certificate_provider_instance found.");
+}
+
+TEST_P(
+    XdsSecurityTest,
+    TlsCertificateCertificateProviderInstanceWithoutValidationContextCertificateProviderInstance) {
+  auto cluster = default_cluster_;
+  auto* transport_socket = cluster.mutable_transport_socket();
+  transport_socket->set_name("envoy.transport_sockets.tls");
+  UpstreamTlsContext upstream_tls_context;
+  upstream_tls_context.mutable_common_tls_context()
+      ->mutable_tls_certificate_certificate_provider_instance()
+      ->set_instance_name(std::string("instance_name"));
+  transport_socket->mutable_typed_config()->PackFrom(upstream_tls_context);
+  balancers_[0]->ads_service()->SetCdsResource(cluster);
+  CheckRpcSendFailure();
+  const auto& response_state =
+      balancers_[0]->ads_service()->cds_response_state();
+  EXPECT_EQ(response_state.state, AdsServiceImpl::ResponseState::NACKED);
+  EXPECT_EQ(response_state.error_message,
+            "TLS configuration provided but no "
+            "validation_context_certificate_provider_instance found.");
+}
+
+TEST_P(XdsSecurityTest, RegexSanMatcherDoesNotAllowIgnoreCase) {
+  auto cluster = default_cluster_;
+  auto* transport_socket = cluster.mutable_transport_socket();
+  transport_socket->set_name("envoy.transport_sockets.tls");
+  UpstreamTlsContext upstream_tls_context;
+  upstream_tls_context.mutable_common_tls_context()
+      ->mutable_combined_validation_context()
+      ->mutable_validation_context_certificate_provider_instance()
+      ->set_instance_name(std::string("fake_plugin1"));
+  auto* validation_context = upstream_tls_context.mutable_common_tls_context()
+                                 ->mutable_combined_validation_context()
+                                 ->mutable_default_validation_context();
+  StringMatcher matcher;
+  matcher.mutable_safe_regex()->mutable_google_re2();
+  matcher.mutable_safe_regex()->set_regex(
+      "(foo|waterzooi).test.google.(fr|be)");
+  matcher.set_ignore_case(true);
+  *validation_context->add_match_subject_alt_names() = matcher;
+  transport_socket->mutable_typed_config()->PackFrom(upstream_tls_context);
+  balancers_[0]->ads_service()->SetCdsResource(cluster);
+  CheckRpcSendFailure();
+  const auto& response_state =
+      balancers_[0]->ads_service()->cds_response_state();
+  EXPECT_EQ(response_state.state, AdsServiceImpl::ResponseState::NACKED);
+  EXPECT_EQ(response_state.error_message,
+            "StringMatcher: ignore_case has no effect for SAFE_REGEX.");
+}
+
+TEST_P(XdsSecurityTest, UnknownRootCertificateProvider) {
+  auto cluster = default_cluster_;
+  auto* transport_socket = cluster.mutable_transport_socket();
+  transport_socket->set_name("envoy.transport_sockets.tls");
+  UpstreamTlsContext upstream_tls_context;
+  upstream_tls_context.mutable_common_tls_context()
+      ->mutable_combined_validation_context()
+      ->mutable_validation_context_certificate_provider_instance()
+      ->set_instance_name("unknown");
+  transport_socket->mutable_typed_config()->PackFrom(upstream_tls_context);
+  balancers_[0]->ads_service()->SetCdsResource(cluster);
+  CheckRpcSendFailure(1, RpcOptions(), StatusCode::UNAVAILABLE);
+}
+
+TEST_P(XdsSecurityTest, UnknownIdentityCertificateProvider) {
+  FakeCertificateProvider::CertDataMap fake1_cert_map = {
+      {"", {root_cert_, identity_pair_}}};
+  g_fake1_cert_data_map = &fake1_cert_map;
+  auto cluster = default_cluster_;
+  auto* transport_socket = cluster.mutable_transport_socket();
+  transport_socket->set_name("envoy.transport_sockets.tls");
+  UpstreamTlsContext upstream_tls_context;
+  upstream_tls_context.mutable_common_tls_context()
+      ->mutable_tls_certificate_certificate_provider_instance()
+      ->set_instance_name("unknown");
+  upstream_tls_context.mutable_common_tls_context()
+      ->mutable_combined_validation_context()
+      ->mutable_validation_context_certificate_provider_instance()
+      ->set_instance_name("fake_plugin1");
+  transport_socket->mutable_typed_config()->PackFrom(upstream_tls_context);
+  balancers_[0]->ads_service()->SetCdsResource(cluster);
+  CheckRpcSendFailure(1, RpcOptions(), StatusCode::UNAVAILABLE);
+  g_fake1_cert_data_map = nullptr;
+}
+
+TEST_P(XdsSecurityTest, TestMtlsConfigurationWithNoSanMatchers) {
+  FakeCertificateProvider::CertDataMap fake1_cert_map = {
+      {"", {root_cert_, identity_pair_}}};
+  g_fake1_cert_data_map = &fake1_cert_map;
+  UpdateAndVerifyXdsSecurityConfiguration("fake_plugin1", "", "fake_plugin1",
+                                          "", {}, authenticated_identity_);
+  g_fake1_cert_data_map = nullptr;
+}
+
+TEST_P(XdsSecurityTest, TestMtlsConfigurationWithExactSanMatcher) {
+  FakeCertificateProvider::CertDataMap fake1_cert_map = {
+      {"", {root_cert_, identity_pair_}}};
+  g_fake1_cert_data_map = &fake1_cert_map;
+  UpdateAndVerifyXdsSecurityConfiguration("fake_plugin1", "", "fake_plugin1",
+                                          "", {server_san_exact_},
+                                          authenticated_identity_);
+  g_fake1_cert_data_map = nullptr;
+}
+
+TEST_P(XdsSecurityTest, TestMtlsConfigurationWithPrefixSanMatcher) {
+  FakeCertificateProvider::CertDataMap fake1_cert_map = {
+      {"", {root_cert_, identity_pair_}}};
+  g_fake1_cert_data_map = &fake1_cert_map;
+  UpdateAndVerifyXdsSecurityConfiguration("fake_plugin1", "", "fake_plugin1",
+                                          "", {server_san_prefix_},
+                                          authenticated_identity_);
+  g_fake1_cert_data_map = nullptr;
+}
+
+TEST_P(XdsSecurityTest, TestMtlsConfigurationWithSuffixSanMatcher) {
+  FakeCertificateProvider::CertDataMap fake1_cert_map = {
+      {"", {root_cert_, identity_pair_}}};
+  g_fake1_cert_data_map = &fake1_cert_map;
+  UpdateAndVerifyXdsSecurityConfiguration("fake_plugin1", "", "fake_plugin1",
+                                          "", {server_san_suffix_},
+                                          authenticated_identity_);
+  g_fake1_cert_data_map = nullptr;
+}
+
+TEST_P(XdsSecurityTest, TestMtlsConfigurationWithContainsSanMatcher) {
+  FakeCertificateProvider::CertDataMap fake1_cert_map = {
+      {"", {root_cert_, identity_pair_}}};
+  g_fake1_cert_data_map = &fake1_cert_map;
+  UpdateAndVerifyXdsSecurityConfiguration("fake_plugin1", "", "fake_plugin1",
+                                          "", {server_san_contains_},
+                                          authenticated_identity_);
+  g_fake1_cert_data_map = nullptr;
+}
+
+TEST_P(XdsSecurityTest, TestMtlsConfigurationWithRegexSanMatcher) {
+  FakeCertificateProvider::CertDataMap fake1_cert_map = {
+      {"", {root_cert_, identity_pair_}}};
+  g_fake1_cert_data_map = &fake1_cert_map;
+  UpdateAndVerifyXdsSecurityConfiguration("fake_plugin1", "", "fake_plugin1",
+                                          "", {server_san_regex_},
+                                          authenticated_identity_);
+  g_fake1_cert_data_map = nullptr;
+}
+
+TEST_P(XdsSecurityTest, TestMtlsConfigurationWithSanMatchersUpdate) {
+  FakeCertificateProvider::CertDataMap fake1_cert_map = {
+      {"", {root_cert_, identity_pair_}}};
+  g_fake1_cert_data_map = &fake1_cert_map;
+  UpdateAndVerifyXdsSecurityConfiguration(
+      "fake_plugin1", "", "fake_plugin1", "",
+      {server_san_exact_, server_san_prefix_}, authenticated_identity_);
+  UpdateAndVerifyXdsSecurityConfiguration("fake_plugin1", "", "fake_plugin1",
+                                          "", {bad_san_1_, bad_san_2_}, {},
+                                          true /* failure */);
+  UpdateAndVerifyXdsSecurityConfiguration(
+      "fake_plugin1", "", "fake_plugin1", "",
+      {server_san_prefix_, server_san_regex_}, authenticated_identity_);
+  g_fake1_cert_data_map = nullptr;
+}
+
+TEST_P(XdsSecurityTest, TestMtlsConfigurationWithRootPluginUpdate) {
+  FakeCertificateProvider::CertDataMap fake1_cert_map = {
+      {"", {root_cert_, identity_pair_}}};
+  g_fake1_cert_data_map = &fake1_cert_map;
+  FakeCertificateProvider::CertDataMap fake2_cert_map = {
+      {"", {bad_root_cert_, bad_identity_pair_}}};
+  g_fake2_cert_data_map = &fake2_cert_map;
+  UpdateAndVerifyXdsSecurityConfiguration("fake_plugin1", "", "fake_plugin1",
+                                          "", {server_san_exact_},
+                                          authenticated_identity_);
+  UpdateAndVerifyXdsSecurityConfiguration("fake_plugin2" /* bad root */, "",
+                                          "fake_plugin1", "", {}, {},
+                                          true /* failure */);
+  UpdateAndVerifyXdsSecurityConfiguration("fake_plugin1", "", "fake_plugin1",
+                                          "", {server_san_exact_},
+                                          authenticated_identity_);
+  g_fake1_cert_data_map = nullptr;
+  g_fake2_cert_data_map = nullptr;
+}
+
+TEST_P(XdsSecurityTest, TestMtlsConfigurationWithIdentityPluginUpdate) {
+  FakeCertificateProvider::CertDataMap fake1_cert_map = {
+      {"", {root_cert_, identity_pair_}}};
+  g_fake1_cert_data_map = &fake1_cert_map;
+  FakeCertificateProvider::CertDataMap fake2_cert_map = {
+      {"", {root_cert_, fallback_identity_pair_}}};
+  g_fake2_cert_data_map = &fake2_cert_map;
+  UpdateAndVerifyXdsSecurityConfiguration("fake_plugin1", "", "fake_plugin1",
+                                          "", {server_san_exact_},
+                                          authenticated_identity_);
+  UpdateAndVerifyXdsSecurityConfiguration("fake_plugin1", "", "fake_plugin2",
+                                          "", {server_san_exact_},
+                                          fallback_authenticated_identity_);
+  g_fake1_cert_data_map = nullptr;
+  g_fake2_cert_data_map = nullptr;
+}
+
+TEST_P(XdsSecurityTest, TestMtlsConfigurationWithBothPluginsUpdated) {
+  FakeCertificateProvider::CertDataMap fake1_cert_map = {
+      {"", {root_cert_, identity_pair_}}};
+  g_fake1_cert_data_map = &fake1_cert_map;
+  FakeCertificateProvider::CertDataMap fake2_cert_map = {
+      {"", {bad_root_cert_, bad_identity_pair_}},
+      {"good", {root_cert_, fallback_identity_pair_}}};
+  g_fake2_cert_data_map = &fake2_cert_map;
+  UpdateAndVerifyXdsSecurityConfiguration("fake_plugin2", "", "fake_plugin2",
+                                          "", {}, {}, true /* failure */);
+  UpdateAndVerifyXdsSecurityConfiguration("fake_plugin1", "", "fake_plugin1",
+                                          "", {server_san_prefix_},
+                                          authenticated_identity_);
+  UpdateAndVerifyXdsSecurityConfiguration(
+      "fake_plugin2", "good", "fake_plugin2", "good", {server_san_prefix_},
+      fallback_authenticated_identity_);
+  g_fake1_cert_data_map = nullptr;
+  g_fake2_cert_data_map = nullptr;
+}
+
+TEST_P(XdsSecurityTest, TestMtlsConfigurationWithRootCertificateNameUpdate) {
+  FakeCertificateProvider::CertDataMap fake1_cert_map = {
+      {"", {root_cert_, identity_pair_}},
+      {"bad", {bad_root_cert_, bad_identity_pair_}}};
+  g_fake1_cert_data_map = &fake1_cert_map;
+  UpdateAndVerifyXdsSecurityConfiguration("fake_plugin1", "", "fake_plugin1",
+                                          "", {server_san_regex_},
+                                          authenticated_identity_);
+  UpdateAndVerifyXdsSecurityConfiguration("fake_plugin1", "bad", "fake_plugin1",
+                                          "", {server_san_regex_}, {},
+                                          true /* failure */);
+  g_fake1_cert_data_map = nullptr;
+}
+
+TEST_P(XdsSecurityTest,
+       TestMtlsConfigurationWithIdentityCertificateNameUpdate) {
+  FakeCertificateProvider::CertDataMap fake1_cert_map = {
+      {"", {root_cert_, identity_pair_}},
+      {"bad", {bad_root_cert_, bad_identity_pair_}}};
+  g_fake1_cert_data_map = &fake1_cert_map;
+  UpdateAndVerifyXdsSecurityConfiguration("fake_plugin1", "", "fake_plugin1",
+                                          "", {server_san_exact_},
+                                          authenticated_identity_);
+  UpdateAndVerifyXdsSecurityConfiguration("fake_plugin1", "", "fake_plugin1",
+                                          "bad", {server_san_exact_}, {},
+                                          true /* failure */);
+  g_fake1_cert_data_map = nullptr;
+}
+
+TEST_P(XdsSecurityTest,
+       TestMtlsConfigurationWithIdentityCertificateNameUpdateGoodCerts) {
+  FakeCertificateProvider::CertDataMap fake1_cert_map = {
+      {"", {root_cert_, identity_pair_}},
+      {"good", {root_cert_, fallback_identity_pair_}}};
+  g_fake1_cert_data_map = &fake1_cert_map;
+  UpdateAndVerifyXdsSecurityConfiguration("fake_plugin1", "", "fake_plugin1",
+                                          "", {server_san_exact_},
+                                          authenticated_identity_);
+  UpdateAndVerifyXdsSecurityConfiguration("fake_plugin1", "", "fake_plugin1",
+                                          "good", {server_san_exact_},
+                                          fallback_authenticated_identity_);
+  g_fake1_cert_data_map = nullptr;
+}
+
+TEST_P(XdsSecurityTest, TestMtlsConfigurationWithBothCertificateNamesUpdated) {
+  FakeCertificateProvider::CertDataMap fake1_cert_map = {
+      {"", {root_cert_, identity_pair_}},
+      {"bad", {bad_root_cert_, bad_identity_pair_}}};
+  g_fake1_cert_data_map = &fake1_cert_map;
+  UpdateAndVerifyXdsSecurityConfiguration("fake_plugin1", "bad", "fake_plugin1",
+                                          "bad", {server_san_prefix_}, {},
+                                          true /* failure */);
+  UpdateAndVerifyXdsSecurityConfiguration("fake_plugin1", "", "fake_plugin1",
+                                          "", {server_san_prefix_},
+                                          authenticated_identity_);
+  g_fake1_cert_data_map = nullptr;
+}
+
+TEST_P(XdsSecurityTest, TestTlsConfigurationWithNoSanMatchers) {
+  FakeCertificateProvider::CertDataMap fake1_cert_map = {
+      {"", {root_cert_, identity_pair_}}};
+  g_fake1_cert_data_map = &fake1_cert_map;
+  UpdateAndVerifyXdsSecurityConfiguration("fake_plugin1", "", "", "", {},
+                                          {} /* unauthenticated */);
+  g_fake1_cert_data_map = nullptr;
+}
+
+TEST_P(XdsSecurityTest, TestTlsConfigurationWithSanMatchers) {
+  FakeCertificateProvider::CertDataMap fake1_cert_map = {
+      {"", {root_cert_, identity_pair_}}};
+  g_fake1_cert_data_map = &fake1_cert_map;
+  UpdateAndVerifyXdsSecurityConfiguration(
+      "fake_plugin1", "", "", "",
+      {server_san_exact_, server_san_prefix_, server_san_regex_},
+      {} /* unauthenticated */);
+  g_fake1_cert_data_map = nullptr;
+}
+
+TEST_P(XdsSecurityTest, TestTlsConfigurationWithSanMatchersUpdate) {
+  FakeCertificateProvider::CertDataMap fake1_cert_map = {
+      {"", {root_cert_, identity_pair_}}};
+  g_fake1_cert_data_map = &fake1_cert_map;
+  UpdateAndVerifyXdsSecurityConfiguration(
+      "fake_plugin1", "", "", "", {server_san_exact_, server_san_prefix_},
+      {} /* unauthenticated */);
+  UpdateAndVerifyXdsSecurityConfiguration(
+      "fake_plugin1", "", "", "", {bad_san_1_, bad_san_2_},
+      {} /* unauthenticated */, true /* failure */);
+  UpdateAndVerifyXdsSecurityConfiguration(
+      "fake_plugin1", "", "", "", {server_san_prefix_, server_san_regex_},
+      {} /* unauthenticated */);
+  g_fake1_cert_data_map = nullptr;
+}
+
+TEST_P(XdsSecurityTest, TestTlsConfigurationWithRootCertificateNameUpdate) {
+  FakeCertificateProvider::CertDataMap fake1_cert_map = {
+      {"", {root_cert_, identity_pair_}},
+      {"bad", {bad_root_cert_, bad_identity_pair_}}};
+  g_fake1_cert_data_map = &fake1_cert_map;
+  UpdateAndVerifyXdsSecurityConfiguration("fake_plugin1", "", "", "",
+                                          {server_san_exact_},
+                                          {} /* unauthenticated */);
+  UpdateAndVerifyXdsSecurityConfiguration("fake_plugin1", "bad", "", "",
+                                          {server_san_exact_}, {},
+                                          true /* failure */);
+  g_fake1_cert_data_map = nullptr;
+}
+
+TEST_P(XdsSecurityTest, TestTlsConfigurationWithRootPluginUpdate) {
+  FakeCertificateProvider::CertDataMap fake1_cert_map = {
+      {"", {root_cert_, identity_pair_}}};
+  g_fake1_cert_data_map = &fake1_cert_map;
+  FakeCertificateProvider::CertDataMap fake2_cert_map = {
+      {"", {bad_root_cert_, bad_identity_pair_}}};
+  g_fake2_cert_data_map = &fake2_cert_map;
+  UpdateAndVerifyXdsSecurityConfiguration("fake_plugin1", "", "", "",
+                                          {server_san_exact_},
+                                          {} /* unauthenticated */);
+  UpdateAndVerifyXdsSecurityConfiguration(
+      "fake_plugin2", "", "", "", {server_san_exact_}, {}, true /* failure */);
+  g_fake1_cert_data_map = nullptr;
+  g_fake2_cert_data_map = nullptr;
+}
+
+TEST_P(XdsSecurityTest, TestFallbackConfiguration) {
+  UpdateAndVerifyXdsSecurityConfiguration("", "", "", "", {},
+                                          fallback_authenticated_identity_);
+  g_fake1_cert_data_map = nullptr;
+}
+
+TEST_P(XdsSecurityTest, TestMtlsToTls) {
+  FakeCertificateProvider::CertDataMap fake1_cert_map = {
+      {"", {root_cert_, identity_pair_}}};
+  g_fake1_cert_data_map = &fake1_cert_map;
+  UpdateAndVerifyXdsSecurityConfiguration("fake_plugin1", "", "fake_plugin1",
+                                          "", {server_san_exact_},
+                                          authenticated_identity_);
+  UpdateAndVerifyXdsSecurityConfiguration("fake_plugin1", "", "", "",
+                                          {server_san_exact_},
+                                          {} /* unauthenticated */);
+  g_fake1_cert_data_map = nullptr;
+}
+
+TEST_P(XdsSecurityTest, TestMtlsToFallback) {
+  FakeCertificateProvider::CertDataMap fake1_cert_map = {
+      {"", {root_cert_, identity_pair_}}};
+  g_fake1_cert_data_map = &fake1_cert_map;
+  UpdateAndVerifyXdsSecurityConfiguration("fake_plugin1", "", "fake_plugin1",
+                                          "", {server_san_exact_},
+                                          authenticated_identity_);
+  UpdateAndVerifyXdsSecurityConfiguration("", "", "", "", {},
+                                          fallback_authenticated_identity_);
+  g_fake1_cert_data_map = nullptr;
+}
+
+TEST_P(XdsSecurityTest, TestTlsToMtls) {
+  FakeCertificateProvider::CertDataMap fake1_cert_map = {
+      {"", {root_cert_, identity_pair_}}};
+  g_fake1_cert_data_map = &fake1_cert_map;
+  UpdateAndVerifyXdsSecurityConfiguration("fake_plugin1", "", "", "",
+                                          {server_san_exact_},
+                                          {} /* unauthenticated */);
+  UpdateAndVerifyXdsSecurityConfiguration("fake_plugin1", "", "fake_plugin1",
+                                          "", {server_san_exact_},
+                                          authenticated_identity_);
+  g_fake1_cert_data_map = nullptr;
+}
+
+TEST_P(XdsSecurityTest, TestTlsToFallback) {
+  FakeCertificateProvider::CertDataMap fake1_cert_map = {
+      {"", {root_cert_, identity_pair_}}};
+  g_fake1_cert_data_map = &fake1_cert_map;
+  UpdateAndVerifyXdsSecurityConfiguration("fake_plugin1", "", "", "",
+                                          {server_san_exact_},
+                                          {} /* unauthenticated */);
+  UpdateAndVerifyXdsSecurityConfiguration("", "", "", "", {},
+                                          fallback_authenticated_identity_);
+  g_fake1_cert_data_map = nullptr;
+}
+
+TEST_P(XdsSecurityTest, TestFallbackToMtls) {
+  FakeCertificateProvider::CertDataMap fake1_cert_map = {
+      {"", {root_cert_, identity_pair_}}};
+  g_fake1_cert_data_map = &fake1_cert_map;
+  UpdateAndVerifyXdsSecurityConfiguration("", "", "", "", {},
+                                          fallback_authenticated_identity_);
+  UpdateAndVerifyXdsSecurityConfiguration("fake_plugin1", "", "fake_plugin1",
+                                          "", {server_san_exact_},
+                                          authenticated_identity_);
+  g_fake1_cert_data_map = nullptr;
+}
+
+TEST_P(XdsSecurityTest, TestFallbackToTls) {
+  FakeCertificateProvider::CertDataMap fake1_cert_map = {
+      {"", {root_cert_, identity_pair_}}};
+  g_fake1_cert_data_map = &fake1_cert_map;
+  UpdateAndVerifyXdsSecurityConfiguration("", "", "", "", {},
+                                          fallback_authenticated_identity_);
+  UpdateAndVerifyXdsSecurityConfiguration("fake_plugin1", "", "", "",
+                                          {server_san_exact_},
+                                          {} /* unauthenticated */);
+  g_fake1_cert_data_map = nullptr;
+}
+
+TEST_P(XdsSecurityTest, TestFileWatcherCertificateProvider) {
+  UpdateAndVerifyXdsSecurityConfiguration("file_plugin", "", "file_plugin", "",
+                                          {server_san_exact_},
+                                          authenticated_identity_);
+}
+
 using EdsTest = BasicTest;
 
 // Tests that EDS client should send a NACK if the EDS update contains
@@ -6358,6 +7216,7 @@ std::string TestTypeName(const ::testing::TestParamInfo<TestType>& info) {
 // - enable_load_reporting
 // - enable_rds_testing = false
 // - use_v2 = false
+// - use_xds_credentials = false
 
 INSTANTIATE_TEST_SUITE_P(XdsTest, BasicTest,
                          ::testing::Values(TestType(false, true),
@@ -6396,6 +7255,15 @@ INSTANTIATE_TEST_SUITE_P(XdsTest, CdsTest,
                                            TestType(true, true)),
                          &TestTypeName);
 
+// CDS depends on XdsResolver.
+// Security depends on v3.
+// Not enabling load reporting or RDS, since those are irrelevant to these
+// tests.
+INSTANTIATE_TEST_SUITE_P(XdsTest, XdsSecurityTest,
+                         ::testing::Values(TestType(true, false, false, false,
+                                                    true)),
+                         &TestTypeName);
+
 // EDS could be tested with or without XdsResolver, but the tests would
 // be the same either way, so we test it only with XdsResolver.
 INSTANTIATE_TEST_SUITE_P(XdsTest, EdsTest,
index 0155cb2..3b98286 100644 (file)
@@ -160,7 +160,7 @@ TEST_F(StatsPluginEnd2EndTest, ErrorCount) {
       client_method_view.GetData().int_data(),
       ::testing::UnorderedElementsAre(::testing::Pair(
           ::testing::ElementsAre(client_method_name_, TEST_TAG_VALUE), 17)));
-  // TODO: Implement server view tagging with custom tags.
+  // TODO(unknown): Implement server view tagging with custom tags.
   EXPECT_THAT(server_method_view.GetData().int_data(),
               ::testing::UnorderedElementsAre(::testing::Pair(
                   ::testing::ElementsAre(server_method_name_), 17)));
@@ -195,7 +195,7 @@ TEST_F(StatsPluginEnd2EndTest, ErrorCount) {
       ::testing::Pair(::testing::ElementsAre("DATA_LOSS", TEST_TAG_VALUE), 1),
   };
 
-  // TODO: Implement server view tagging with custom tags.
+  // TODO(unknown): Implement server view tagging with custom tags.
   auto server_tags = {
       ::testing::Pair(::testing::ElementsAre("OK"), 1),
       ::testing::Pair(::testing::ElementsAre("CANCELLED"), 1),
@@ -359,7 +359,7 @@ TEST_F(StatsPluginEnd2EndTest, CompletedRpcs) {
 }
 
 TEST_F(StatsPluginEnd2EndTest, RequestReceivedMessagesPerRpc) {
-  // TODO: Use streaming RPCs.
+  // TODO(unknown): Use streaming RPCs.
   View client_received_messages_per_rpc_view(
       ClientSentMessagesPerRpcCumulative());
   View client_sent_messages_per_rpc_view(
index adb9d72..2902ab7 100644 (file)
@@ -47,7 +47,7 @@ std::shared_ptr<Channel> CreateChannelForTestCase(
 
 class InteropClientContextInspector {
  public:
-  InteropClientContextInspector(const ::grpc::ClientContext& context)
+  explicit InteropClientContextInspector(const ::grpc::ClientContext& context)
       : context_(context) {}
 
   // Inspector methods, able to peek inside ClientContext, follow.
@@ -68,7 +68,7 @@ class InteropClientContextInspector {
 
 class AdditionalMetadataInterceptor : public experimental::Interceptor {
  public:
-  AdditionalMetadataInterceptor(
+  explicit AdditionalMetadataInterceptor(
       std::multimap<std::string, std::string> additional_metadata)
       : additional_metadata_(std::move(additional_metadata)) {}
 
@@ -91,7 +91,7 @@ class AdditionalMetadataInterceptor : public experimental::Interceptor {
 class AdditionalMetadataInterceptorFactory
     : public experimental::ClientInterceptorFactoryInterface {
  public:
-  AdditionalMetadataInterceptorFactory(
+  explicit AdditionalMetadataInterceptorFactory(
       std::multimap<std::string, std::string> additional_metadata)
       : additional_metadata_(std::move(additional_metadata)) {}
 
index 269d3b3..42728fc 100644 (file)
@@ -44,7 +44,7 @@ class Http2Client {
  private:
   class ServiceStub {
    public:
-    ServiceStub(const std::shared_ptr<Channel>& channel);
+    explicit ServiceStub(const std::shared_ptr<Channel>& channel);
 
     TestService::Stub* Get();
 
index e6b718b..51f66d4 100644 (file)
@@ -149,7 +149,7 @@ class TestServiceImpl : public TestService::Service {
                             const SimpleRequest* /*request*/,
                             SimpleResponse* response) override {
     gpr_timespec ts = gpr_now(GPR_CLOCK_PRECISE);
-    std::string timestamp = std::to_string((long long unsigned)ts.tv_nsec);
+    std::string timestamp = std::to_string(ts.tv_nsec);
     response->mutable_payload()->set_body(timestamp.c_str(), timestamp.size());
     context->AddInitialMetadata("cache-control", "max-age=60, public");
     return Status::OK;
index 237c33c..ee72697 100644 (file)
@@ -37,7 +37,7 @@ std::shared_ptr<ServerCredentials> CreateInteropServerCredentials();
 
 class InteropServerContextInspector {
  public:
-  InteropServerContextInspector(const ::grpc::ServerContext& context);
+  explicit InteropServerContextInspector(const ::grpc::ServerContext& context);
 
   // Inspector methods, able to peek inside ServerContext, follow.
   std::shared_ptr<const AuthContext> GetAuthContext() const;
index eb2ec41..653df91 100644 (file)
@@ -77,7 +77,8 @@ const vector<pair<TestCaseType, std::string>> kTestCaseList = {
 class WeightedRandomTestSelector {
  public:
   // Takes a vector of <test_case, weight> pairs as the input
-  WeightedRandomTestSelector(const vector<pair<TestCaseType, int>>& tests);
+  explicit WeightedRandomTestSelector(
+      const vector<pair<TestCaseType, int>>& tests);
 
   // Returns a weighted-randomly chosen test case based on the test cases and
   // weights passed in the constructor
index 4013ce9..748e9e7 100644 (file)
@@ -24,6 +24,7 @@
 #include <atomic>
 #include <chrono>
 #include <condition_variable>
+#include <deque>
 #include <map>
 #include <mutex>
 #include <set>
 #include <thread>
 #include <vector>
 
+#include "absl/algorithm/container.h"
 #include "absl/flags/flag.h"
 #include "absl/strings/str_split.h"
+#include "src/core/lib/channel/status_util.h"
 #include "src/core/lib/gpr/env.h"
 #include "src/proto/grpc/testing/empty.pb.h"
 #include "src/proto/grpc/testing/messages.pb.h"
@@ -54,6 +57,8 @@ ABSL_FLAG(int32_t, stats_port, 50052,
 ABSL_FLAG(std::string, rpc, "UnaryCall",
           "a comma separated list of rpc methods.");
 ABSL_FLAG(std::string, metadata, "", "metadata to send with the RPC.");
+ABSL_FLAG(std::string, expect_status, "OK",
+          "RPC status for the test RPC to be considered successful");
 
 using grpc::Channel;
 using grpc::ClientAsyncResponseReader;
@@ -63,24 +68,48 @@ using grpc::Server;
 using grpc::ServerBuilder;
 using grpc::ServerContext;
 using grpc::Status;
+using grpc::testing::ClientConfigureRequest;
+using grpc::testing::ClientConfigureRequest_RpcType_Name;
+using grpc::testing::ClientConfigureResponse;
 using grpc::testing::Empty;
+using grpc::testing::LoadBalancerAccumulatedStatsRequest;
+using grpc::testing::LoadBalancerAccumulatedStatsResponse;
 using grpc::testing::LoadBalancerStatsRequest;
 using grpc::testing::LoadBalancerStatsResponse;
 using grpc::testing::LoadBalancerStatsService;
 using grpc::testing::SimpleRequest;
 using grpc::testing::SimpleResponse;
 using grpc::testing::TestService;
+using grpc::testing::XdsUpdateClientConfigureService;
 
 class XdsStatsWatcher;
 
-// Unique ID for each outgoing RPC
-int global_request_id;
-// Stores a set of watchers that should be notified upon outgoing RPC completion
-std::set<XdsStatsWatcher*> watchers;
-// Mutex for global_request_id and watchers
-std::mutex mu;
+struct StatsWatchers {
+  // Unique ID for each outgoing RPC
+  int global_request_id = 0;
+  // Unique ID for each outgoing RPC by RPC method type
+  std::map<int, int> global_request_id_by_type;
+  // Stores a set of watchers that should be notified upon outgoing RPC
+  // completion
+  std::set<XdsStatsWatcher*> watchers;
+  // Global watcher for accumululated stats.
+  XdsStatsWatcher* global_watcher;
+  // Mutex for global_request_id and watchers
+  std::mutex mu;
+};
 // Whether at least one RPC has succeeded, indicating xDS resolution completed.
 std::atomic<bool> one_rpc_succeeded(false);
+// RPC configuration detailing how RPC should be sent.
+struct RpcConfig {
+  ClientConfigureRequest::RpcType type;
+  std::vector<std::pair<std::string, std::string>> metadata;
+};
+struct RpcConfigurationsQueue {
+  // A queue of RPC configurations detailing how RPCs should be sent.
+  std::deque<std::vector<RpcConfig>> rpc_configs_queue;
+  // Mutex for rpc_configs_queue
+  std::mutex mu_rpc_configs_queue;
+};
 
 /** Records the remote peer distribution for a given range of RPCs. */
 class XdsStatsWatcher {
@@ -88,16 +117,25 @@ class XdsStatsWatcher {
   XdsStatsWatcher(int start_id, int end_id)
       : start_id_(start_id), end_id_(end_id), rpcs_needed_(end_id - start_id) {}
 
-  void RpcCompleted(int request_id, const std::string& rpc_method,
+  // Upon the completion of an RPC, we will look at the request_id, the
+  // rpc_type, and the peer the RPC was sent to in order to count
+  // this RPC into the right stats bin.
+  void RpcCompleted(int request_id,
+                    const ClientConfigureRequest::RpcType rpc_type,
                     const std::string& peer) {
-    if (start_id_ <= request_id && request_id < end_id_) {
+    // We count RPCs for global watcher or if the request_id falls into the
+    // watcher's interested range of request ids.
+    if ((start_id_ == 0 && end_id_ == 0) ||
+        (start_id_ <= request_id && request_id < end_id_)) {
       {
-        std::lock_guard<std::mutex> lk(m_);
+        std::lock_guard<std::mutex> lock(m_);
         if (peer.empty()) {
           no_remote_peer_++;
+          ++no_remote_peer_by_type_[rpc_type];
         } else {
+          // RPC is counted into both per-peer bin and per-method-per-peer bin.
           rpcs_by_peer_[peer]++;
-          rpcs_by_method_[rpc_method][peer]++;
+          rpcs_by_type_[rpc_type][peer]++;
         }
         rpcs_needed_--;
       }
@@ -108,18 +146,28 @@ class XdsStatsWatcher {
   void WaitForRpcStatsResponse(LoadBalancerStatsResponse* response,
                                int timeout_sec) {
     {
-      std::unique_lock<std::mutex> lk(m_);
-      cv_.wait_for(lk, std::chrono::seconds(timeout_sec),
+      std::unique_lock<std::mutex> lock(m_);
+      cv_.wait_for(lock, std::chrono::seconds(timeout_sec),
                    [this] { return rpcs_needed_ == 0; });
       response->mutable_rpcs_by_peer()->insert(rpcs_by_peer_.begin(),
                                                rpcs_by_peer_.end());
       auto& response_rpcs_by_method = *response->mutable_rpcs_by_method();
-      for (const auto& rpc_by_method : rpcs_by_method_) {
-        auto& response_rpc_by_method =
-            response_rpcs_by_method[rpc_by_method.first];
+      for (const auto& rpc_by_type : rpcs_by_type_) {
+        std::string method_name;
+        if (rpc_by_type.first == ClientConfigureRequest::EMPTY_CALL) {
+          method_name = "EmptyCall";
+        } else if (rpc_by_type.first == ClientConfigureRequest::UNARY_CALL) {
+          method_name = "UnaryCall";
+        } else {
+          GPR_ASSERT(0);
+        }
+        // TODO(@donnadionne): When the test runner changes to accept EMPTY_CALL
+        // and UNARY_CALL we will just use the name of the enum instead of the
+        // method_name variable.
+        auto& response_rpc_by_method = response_rpcs_by_method[method_name];
         auto& response_rpcs_by_peer =
             *response_rpc_by_method.mutable_rpcs_by_peer();
-        for (const auto& rpc_by_peer : rpc_by_method.second) {
+        for (const auto& rpc_by_peer : rpc_by_type.second) {
           auto& response_rpc_by_peer = response_rpcs_by_peer[rpc_by_peer.first];
           response_rpc_by_peer = rpc_by_peer.second;
         }
@@ -128,48 +176,81 @@ class XdsStatsWatcher {
     }
   }
 
+  void GetCurrentRpcStats(LoadBalancerAccumulatedStatsResponse* response,
+                          StatsWatchers* stats_watchers) {
+    std::unique_lock<std::mutex> lock(m_);
+    auto& response_rpcs_started_by_method =
+        *response->mutable_num_rpcs_started_by_method();
+    auto& response_rpcs_succeeded_by_method =
+        *response->mutable_num_rpcs_succeeded_by_method();
+    auto& response_rpcs_failed_by_method =
+        *response->mutable_num_rpcs_failed_by_method();
+    for (const auto& rpc_by_type : rpcs_by_type_) {
+      auto total_succeeded = 0;
+      for (const auto& rpc_by_peer : rpc_by_type.second) {
+        total_succeeded += rpc_by_peer.second;
+      }
+      response_rpcs_succeeded_by_method[ClientConfigureRequest_RpcType_Name(
+          rpc_by_type.first)] = total_succeeded;
+      response_rpcs_started_by_method[ClientConfigureRequest_RpcType_Name(
+          rpc_by_type.first)] =
+          stats_watchers->global_request_id_by_type[rpc_by_type.first];
+      response_rpcs_failed_by_method[ClientConfigureRequest_RpcType_Name(
+          rpc_by_type.first)] = no_remote_peer_by_type_[rpc_by_type.first];
+    }
+  }
+
  private:
   int start_id_;
   int end_id_;
   int rpcs_needed_;
   int no_remote_peer_ = 0;
+  std::map<int, int> no_remote_peer_by_type_;
   // A map of stats keyed by peer name.
   std::map<std::string, int> rpcs_by_peer_;
   // A two-level map of stats keyed at top level by RPC method and second level
   // by peer name.
-  std::map<std::string, std::map<std::string, int>> rpcs_by_method_;
+  std::map<int, std::map<std::string, int>> rpcs_by_type_;
   std::mutex m_;
   std::condition_variable cv_;
 };
 
 class TestClient {
  public:
-  TestClient(const std::shared_ptr<Channel>& channel)
-      : stub_(TestService::NewStub(channel)) {}
+  TestClient(const std::shared_ptr<Channel>& channel,
+             StatsWatchers* stats_watchers)
+      : stub_(TestService::NewStub(channel)), stats_watchers_(stats_watchers) {}
 
   void AsyncUnaryCall(
       std::vector<std::pair<std::string, std::string>> metadata) {
     SimpleResponse response;
     int saved_request_id;
     {
-      std::lock_guard<std::mutex> lk(mu);
-      saved_request_id = ++global_request_id;
+      std::lock_guard<std::mutex> lock(stats_watchers_->mu);
+      saved_request_id = ++stats_watchers_->global_request_id;
+      ++stats_watchers_
+            ->global_request_id_by_type[ClientConfigureRequest::UNARY_CALL];
     }
     std::chrono::system_clock::time_point deadline =
         std::chrono::system_clock::now() +
         std::chrono::seconds(absl::GetFlag(FLAGS_rpc_timeout_sec));
     AsyncClientCall* call = new AsyncClientCall;
-    call->context.set_deadline(deadline);
     for (const auto& data : metadata) {
       call->context.AddMetadata(data.first, data.second);
+      // TODO(@donnadionne): move deadline to separate proto.
+      if (data.first == "rpc-behavior" && data.second == "keep-open") {
+        deadline =
+            std::chrono::system_clock::now() + std::chrono::seconds(INT_MAX);
+      }
     }
+    call->context.set_deadline(deadline);
     call->saved_request_id = saved_request_id;
-    call->rpc_method = "UnaryCall";
+    call->rpc_type = ClientConfigureRequest::UNARY_CALL;
     call->simple_response_reader = stub_->PrepareAsyncUnaryCall(
         &call->context, SimpleRequest::default_instance(), &cq_);
     call->simple_response_reader->StartCall();
     call->simple_response_reader->Finish(&call->simple_response, &call->status,
-                                         (void*)call);
+                                         call);
   }
 
   void AsyncEmptyCall(
@@ -177,24 +258,31 @@ class TestClient {
     Empty response;
     int saved_request_id;
     {
-      std::lock_guard<std::mutex> lk(mu);
-      saved_request_id = ++global_request_id;
+      std::lock_guard<std::mutex> lock(stats_watchers_->mu);
+      saved_request_id = ++stats_watchers_->global_request_id;
+      ++stats_watchers_
+            ->global_request_id_by_type[ClientConfigureRequest::EMPTY_CALL];
     }
     std::chrono::system_clock::time_point deadline =
         std::chrono::system_clock::now() +
         std::chrono::seconds(absl::GetFlag(FLAGS_rpc_timeout_sec));
     AsyncClientCall* call = new AsyncClientCall;
-    call->context.set_deadline(deadline);
     for (const auto& data : metadata) {
       call->context.AddMetadata(data.first, data.second);
+      // TODO(@donnadionne): move deadline to separate proto.
+      if (data.first == "rpc-behavior" && data.second == "keep-open") {
+        deadline =
+            std::chrono::system_clock::now() + std::chrono::seconds(INT_MAX);
+      }
     }
+    call->context.set_deadline(deadline);
     call->saved_request_id = saved_request_id;
-    call->rpc_method = "EmptyCall";
+    call->rpc_type = ClientConfigureRequest::EMPTY_CALL;
     call->empty_response_reader = stub_->PrepareAsyncEmptyCall(
         &call->context, Empty::default_instance(), &cq_);
     call->empty_response_reader->StartCall();
     call->empty_response_reader->Finish(&call->empty_response, &call->status,
-                                        (void*)call);
+                                        call);
   }
 
   void AsyncCompleteRpc() {
@@ -204,7 +292,7 @@ class TestClient {
       AsyncClientCall* call = static_cast<AsyncClientCall*>(got_tag);
       GPR_ASSERT(ok);
       {
-        std::lock_guard<std::mutex> lk(mu);
+        std::lock_guard<std::mutex> lock(stats_watchers_->mu);
         auto server_initial_metadata = call->context.GetServerInitialMetadata();
         auto metadata_hostname =
             call->context.GetServerInitialMetadata().find("hostname");
@@ -213,13 +301,13 @@ class TestClient {
                 ? std::string(metadata_hostname->second.data(),
                               metadata_hostname->second.length())
                 : call->simple_response.hostname();
-        for (auto watcher : watchers) {
-          watcher->RpcCompleted(call->saved_request_id, call->rpc_method,
+        for (auto watcher : stats_watchers_->watchers) {
+          watcher->RpcCompleted(call->saved_request_id, call->rpc_type,
                                 hostname);
         }
       }
 
-      if (!call->status.ok()) {
+      if (!RpcStatusCheckSuccess(call)) {
         if (absl::GetFlag(FLAGS_print_response) ||
             absl::GetFlag(FLAGS_fail_on_failed_rpc)) {
           std::cout << "RPC failed: " << call->status.error_code() << ": "
@@ -256,18 +344,29 @@ class TestClient {
     ClientContext context;
     Status status;
     int saved_request_id;
-    std::string rpc_method;
+    ClientConfigureRequest::RpcType rpc_type;
     std::unique_ptr<ClientAsyncResponseReader<Empty>> empty_response_reader;
     std::unique_ptr<ClientAsyncResponseReader<SimpleResponse>>
         simple_response_reader;
   };
+  static bool RpcStatusCheckSuccess(AsyncClientCall* call) {
+    // Determine RPC success based on expected status.
+    grpc_status_code code;
+    GPR_ASSERT(grpc_status_code_from_string(
+        absl::GetFlag(FLAGS_expect_status).c_str(), &code));
+    return code == static_cast<grpc_status_code>(call->status.error_code());
+  }
 
   std::unique_ptr<TestService::Stub> stub_;
+  StatsWatchers* stats_watchers_;
   CompletionQueue cq_;
 };
 
 class LoadBalancerStatsServiceImpl : public LoadBalancerStatsService::Service {
  public:
+  explicit LoadBalancerStatsServiceImpl(StatsWatchers* stats_watchers)
+      : stats_watchers_(stats_watchers) {}
+
   Status GetClientStats(ServerContext* context,
                         const LoadBalancerStatsRequest* request,
                         LoadBalancerStatsResponse* response) override {
@@ -275,64 +374,105 @@ class LoadBalancerStatsServiceImpl : public LoadBalancerStatsService::Service {
     int end_id;
     XdsStatsWatcher* watcher;
     {
-      std::lock_guard<std::mutex> lk(mu);
-      start_id = global_request_id + 1;
+      std::lock_guard<std::mutex> lock(stats_watchers_->mu);
+      start_id = stats_watchers_->global_request_id + 1;
       end_id = start_id + request->num_rpcs();
       watcher = new XdsStatsWatcher(start_id, end_id);
-      watchers.insert(watcher);
+      stats_watchers_->watchers.insert(watcher);
     }
     watcher->WaitForRpcStatsResponse(response, request->timeout_sec());
     {
-      std::lock_guard<std::mutex> lk(mu);
-      watchers.erase(watcher);
+      std::lock_guard<std::mutex> lock(stats_watchers_->mu);
+      stats_watchers_->watchers.erase(watcher);
     }
     delete watcher;
     return Status::OK;
   }
+
+  Status GetClientAccumulatedStats(
+      ServerContext* context,
+      const LoadBalancerAccumulatedStatsRequest* request,
+      LoadBalancerAccumulatedStatsResponse* response) override {
+    std::lock_guard<std::mutex> lock(stats_watchers_->mu);
+    stats_watchers_->global_watcher->GetCurrentRpcStats(response,
+                                                        stats_watchers_);
+    return Status::OK;
+  }
+
+ private:
+  StatsWatchers* stats_watchers_;
 };
 
-void RunTestLoop(std::chrono::duration<double> duration_per_query) {
-  std::vector<std::string> rpc_methods =
-      absl::StrSplit(absl::GetFlag(FLAGS_rpc), ',', absl::SkipEmpty());
-  // Store Metadata like
-  // "EmptyCall:key1:value1,UnaryCall:key1:value1,UnaryCall:key2:value2" into a
-  // map where the key is the RPC method and value is a vector of key:value
-  // pairs. {EmptyCall, [{key1,value1}],
-  //  UnaryCall, [{key1,value1}, {key2,value2}]}
-  std::vector<std::string> rpc_metadata =
-      absl::StrSplit(absl::GetFlag(FLAGS_metadata), ',', absl::SkipEmpty());
-  std::map<std::string, std::vector<std::pair<std::string, std::string>>>
-      metadata_map;
-  for (auto& data : rpc_metadata) {
-    std::vector<std::string> metadata =
-        absl::StrSplit(data, ':', absl::SkipEmpty());
-    GPR_ASSERT(metadata.size() == 3);
-    metadata_map[metadata[0]].push_back({metadata[1], metadata[2]});
+class XdsUpdateClientConfigureServiceImpl
+    : public XdsUpdateClientConfigureService::Service {
+ public:
+  explicit XdsUpdateClientConfigureServiceImpl(
+      RpcConfigurationsQueue* rpc_configs_queue)
+      : rpc_configs_queue_(rpc_configs_queue) {}
+
+  Status Configure(ServerContext* context,
+                   const ClientConfigureRequest* request,
+                   ClientConfigureResponse* response) override {
+    std::map<int, std::vector<std::pair<std::string, std::string>>>
+        metadata_map;
+    for (const auto& data : request->metadata()) {
+      metadata_map[data.type()].push_back({data.key(), data.value()});
+    }
+    std::vector<RpcConfig> configs;
+    for (const auto& rpc : request->types()) {
+      RpcConfig config;
+      config.type = static_cast<ClientConfigureRequest::RpcType>(rpc);
+      auto metadata_iter = metadata_map.find(rpc);
+      if (metadata_iter != metadata_map.end()) {
+        config.metadata = metadata_iter->second;
+      }
+      configs.push_back(std::move(config));
+    }
+    {
+      std::lock_guard<std::mutex> lock(
+          rpc_configs_queue_->mu_rpc_configs_queue);
+      rpc_configs_queue_->rpc_configs_queue.emplace_back(std::move(configs));
+    }
+    return Status::OK;
   }
+
+ private:
+  RpcConfigurationsQueue* rpc_configs_queue_;
+};
+
+void RunTestLoop(std::chrono::duration<double> duration_per_query,
+                 StatsWatchers* stats_watchers,
+                 RpcConfigurationsQueue* rpc_configs_queue) {
   TestClient client(grpc::CreateChannel(absl::GetFlag(FLAGS_server),
-                                        grpc::InsecureChannelCredentials()));
+                                        grpc::InsecureChannelCredentials()),
+                    stats_watchers);
   std::chrono::time_point<std::chrono::system_clock> start =
       std::chrono::system_clock::now();
   std::chrono::duration<double> elapsed;
 
   std::thread thread = std::thread(&TestClient::AsyncCompleteRpc, &client);
 
+  std::vector<RpcConfig> configs;
   while (true) {
-    for (const std::string& rpc_method : rpc_methods) {
-      elapsed = std::chrono::system_clock::now() - start;
-      if (elapsed > duration_per_query) {
-        start = std::chrono::system_clock::now();
-        auto metadata_iter = metadata_map.find(rpc_method);
-        if (rpc_method == "EmptyCall") {
-          client.AsyncEmptyCall(
-              metadata_iter != metadata_map.end()
-                  ? metadata_iter->second
-                  : std::vector<std::pair<std::string, std::string>>());
+    {
+      std::lock_guard<std::mutex> lockk(
+          rpc_configs_queue->mu_rpc_configs_queue);
+      if (!rpc_configs_queue->rpc_configs_queue.empty()) {
+        configs = std::move(rpc_configs_queue->rpc_configs_queue.front());
+        rpc_configs_queue->rpc_configs_queue.pop_front();
+      }
+    }
+
+    elapsed = std::chrono::system_clock::now() - start;
+    if (elapsed > duration_per_query) {
+      start = std::chrono::system_clock::now();
+      for (const auto& config : configs) {
+        if (config.type == ClientConfigureRequest::EMPTY_CALL) {
+          client.AsyncEmptyCall(config.metadata);
+        } else if (config.type == ClientConfigureRequest::UNARY_CALL) {
+          client.AsyncUnaryCall(config.metadata);
         } else {
-          client.AsyncUnaryCall(
-              metadata_iter != metadata_map.end()
-                  ? metadata_iter->second
-                  : std::vector<std::pair<std::string, std::string>>());
+          GPR_ASSERT(0);
         }
       }
     }
@@ -340,40 +480,104 @@ void RunTestLoop(std::chrono::duration<double> duration_per_query) {
   thread.join();
 }
 
-void RunServer(const int port) {
+void RunServer(const int port, StatsWatchers* stats_watchers,
+               RpcConfigurationsQueue* rpc_configs_queue) {
   GPR_ASSERT(port != 0);
   std::ostringstream server_address;
   server_address << "0.0.0.0:" << port;
 
-  LoadBalancerStatsServiceImpl service;
+  LoadBalancerStatsServiceImpl stats_service(stats_watchers);
+  XdsUpdateClientConfigureServiceImpl client_config_service(rpc_configs_queue);
 
   ServerBuilder builder;
-  builder.RegisterService(&service);
+  builder.RegisterService(&stats_service);
+  builder.RegisterService(&client_config_service);
   builder.AddListeningPort(server_address.str(),
                            grpc::InsecureServerCredentials());
   std::unique_ptr<Server> server(builder.BuildAndStart());
-  gpr_log(GPR_INFO, "Stats server listening on %s",
-          server_address.str().c_str());
+  gpr_log(GPR_DEBUG, "Server listening on %s", server_address.str().c_str());
 
   server->Wait();
 }
 
+void BuildRpcConfigsFromFlags(RpcConfigurationsQueue* rpc_configs_queue) {
+  // Store Metadata like
+  // "EmptyCall:key1:value1,UnaryCall:key1:value1,UnaryCall:key2:value2" into a
+  // map where the key is the RPC method and value is a vector of key:value
+  // pairs. {EmptyCall, [{key1,value1}],
+  //  UnaryCall, [{key1,value1}, {key2,value2}]}
+  std::vector<std::string> rpc_metadata =
+      absl::StrSplit(absl::GetFlag(FLAGS_metadata), ',', absl::SkipEmpty());
+  std::map<int, std::vector<std::pair<std::string, std::string>>> metadata_map;
+  for (auto& data : rpc_metadata) {
+    std::vector<std::string> metadata =
+        absl::StrSplit(data, ':', absl::SkipEmpty());
+    GPR_ASSERT(metadata.size() == 3);
+    if (metadata[0] == "EmptyCall") {
+      metadata_map[ClientConfigureRequest::EMPTY_CALL].push_back(
+          {metadata[1], metadata[2]});
+    } else if (metadata[0] == "UnaryCall") {
+      metadata_map[ClientConfigureRequest::UNARY_CALL].push_back(
+          {metadata[1], metadata[2]});
+    } else {
+      GPR_ASSERT(0);
+    }
+  }
+  std::vector<RpcConfig> configs;
+  std::vector<std::string> rpc_methods =
+      absl::StrSplit(absl::GetFlag(FLAGS_rpc), ',', absl::SkipEmpty());
+  for (const std::string& rpc_method : rpc_methods) {
+    RpcConfig config;
+    if (rpc_method == "EmptyCall") {
+      config.type = ClientConfigureRequest::EMPTY_CALL;
+    } else if (rpc_method == "UnaryCall") {
+      config.type = ClientConfigureRequest::UNARY_CALL;
+    } else {
+      GPR_ASSERT(0);
+    }
+    auto metadata_iter = metadata_map.find(config.type);
+    if (metadata_iter != metadata_map.end()) {
+      config.metadata = metadata_iter->second;
+    }
+    configs.push_back(std::move(config));
+  }
+  {
+    std::lock_guard<std::mutex> lock(rpc_configs_queue->mu_rpc_configs_queue);
+    rpc_configs_queue->rpc_configs_queue.emplace_back(std::move(configs));
+  }
+}
+
 int main(int argc, char** argv) {
   grpc::testing::TestEnvironment env(argc, argv);
   grpc::testing::InitTest(&argc, &argv, true);
+  // Validate the expect_status flag.
+  grpc_status_code code;
+  GPR_ASSERT(grpc_status_code_from_string(
+      absl::GetFlag(FLAGS_expect_status).c_str(), &code));
+  StatsWatchers stats_watchers;
+  RpcConfigurationsQueue rpc_config_queue;
+
+  {
+    std::lock_guard<std::mutex> lock(stats_watchers.mu);
+    stats_watchers.global_watcher = new XdsStatsWatcher(0, 0);
+    stats_watchers.watchers.insert(stats_watchers.global_watcher);
+  }
+
+  BuildRpcConfigsFromFlags(&rpc_config_queue);
 
   std::chrono::duration<double> duration_per_query =
       std::chrono::nanoseconds(std::chrono::seconds(1)) /
       absl::GetFlag(FLAGS_qps);
 
   std::vector<std::thread> test_threads;
-
   test_threads.reserve(absl::GetFlag(FLAGS_num_channels));
   for (int i = 0; i < absl::GetFlag(FLAGS_num_channels); i++) {
-    test_threads.emplace_back(std::thread(&RunTestLoop, duration_per_query));
+    test_threads.emplace_back(std::thread(&RunTestLoop, duration_per_query,
+                                          &stats_watchers, &rpc_config_queue));
   }
 
-  RunServer(absl::GetFlag(FLAGS_stats_port));
+  RunServer(absl::GetFlag(FLAGS_stats_port), &stats_watchers,
+            &rpc_config_queue);
 
   for (auto it = test_threads.begin(); it != test_threads.end(); it++) {
     it->join();
index fa8f3a7..9955173 100644 (file)
@@ -50,7 +50,7 @@ using grpc::testing::TestService;
 
 class TestServiceImpl : public TestService::Service {
  public:
-  TestServiceImpl(const std::string& i) : hostname_(i) {}
+  explicit TestServiceImpl(const std::string& i) : hostname_(i) {}
 
   Status UnaryCall(ServerContext* context, const SimpleRequest* request,
                    SimpleResponse* response) override {
index 4b11416..e167f40 100644 (file)
@@ -76,7 +76,7 @@ BENCHMARK(BM_Zalloc)
 
 class BaseChannelFixture {
  public:
-  BaseChannelFixture(grpc_channel* channel) : channel_(channel) {}
+  explicit BaseChannelFixture(grpc_channel* channel) : channel_(channel) {}
   ~BaseChannelFixture() { grpc_channel_destroy(channel_); }
 
   grpc_channel* channel() const { return channel_; }
index 6a783d3..3c8822a 100644 (file)
@@ -181,7 +181,7 @@ std::unique_ptr<TestClosure> MakeTestClosure(F f) {
 template <class F>
 grpc_closure* MakeOnceClosure(F f) {
   struct C : public grpc_closure {
-    C(const F& f) : f_(f) {}
+    explicit C(const F& f) : f_(f) {}
     F f_;
     static void Execute(void* arg, grpc_error* error) {
       static_cast<C*>(arg)->f_(error);
@@ -194,7 +194,7 @@ grpc_closure* MakeOnceClosure(F f) {
 
 class Stream {
  public:
-  Stream(Fixture* f) : f_(f) {
+  explicit Stream(Fixture* f) : f_(f) {
     stream_size_ = grpc_transport_stream_size(f->transport());
     stream_ = gpr_malloc(stream_size_);
     arena_ = grpc_core::Arena::Create(4096);
@@ -244,7 +244,7 @@ class Stream {
     grpc_transport_destroy_stream(stream->f_->transport(),
                                   static_cast<grpc_stream*>(stream->stream_),
                                   stream->destroy_closure_);
-    gpr_event_set(&stream->done_, (void*)(1));
+    gpr_event_set(&stream->done_, reinterpret_cast<void*>(1));
   }
 
   Fixture* f_;
@@ -396,7 +396,7 @@ static void BM_TransportEmptyOp(benchmark::State& state) {
   std::unique_ptr<TestClosure> stream_cancel_closure =
       MakeTestClosure([&](grpc_error* error) {
         GPR_ASSERT(error == GRPC_ERROR_NONE);
-        gpr_event_set(stream_cancel_done, (void*)(1));
+        gpr_event_set(stream_cancel_done, reinterpret_cast<void*>(1));
       });
   op.on_complete = stream_cancel_closure.get();
   s->Op(&op);
@@ -444,7 +444,7 @@ static void BM_TransportStreamSend(benchmark::State& state) {
 
   std::unique_ptr<TestClosure> c = MakeTestClosure([&](grpc_error* /*error*/) {
     if (!state.KeepRunning()) {
-      gpr_event_set(bm_done, (void*)(1));
+      gpr_event_set(bm_done, reinterpret_cast<void*>(1));
       return;
     }
     grpc_slice_buffer send_buffer;
@@ -480,7 +480,7 @@ static void BM_TransportStreamSend(benchmark::State& state) {
   std::unique_ptr<TestClosure> stream_cancel_closure =
       MakeTestClosure([&](grpc_error* error) {
         GPR_ASSERT(error == GRPC_ERROR_NONE);
-        gpr_event_set(stream_cancel_done, (void*)(1));
+        gpr_event_set(stream_cancel_done, reinterpret_cast<void*>(1));
       });
   op.on_complete = stream_cancel_closure.get();
   s->Op(&op);
@@ -666,7 +666,7 @@ static void BM_TransportStreamRecv(benchmark::State& state) {
   std::unique_ptr<TestClosure> stream_cancel_closure =
       MakeTestClosure([&](grpc_error* error) {
         GPR_ASSERT(error == GRPC_ERROR_NONE);
-        gpr_event_set(stream_cancel_done, (void*)(1));
+        gpr_event_set(stream_cancel_done, reinterpret_cast<void*>(1));
       });
   op.on_complete = stream_cancel_closure.get();
   s->Op(&op);
index 8ab0450..8ce70c3 100644 (file)
@@ -57,7 +57,7 @@ BENCHMARK(BM_CreateDestroyCpp2);
 static void BM_CreateDestroyCore(benchmark::State& state) {
   TrackCounters track_counters;
   for (auto _ : state) {
-    // TODO: sreek Templatize this benchmark and pass completion type and
+    // TODO(sreek): Templatize this benchmark and pass completion type and
     // polling type as parameters
     grpc_completion_queue_destroy(
         grpc_completion_queue_create_for_next(nullptr));
@@ -103,7 +103,7 @@ BENCHMARK(BM_Pass1Cpp);
 
 static void BM_Pass1Core(benchmark::State& state) {
   TrackCounters track_counters;
-  // TODO: sreek Templatize this benchmark and pass polling_type as a param
+  // TODO(sreek): Templatize this benchmark and pass polling_type as a param
   grpc_completion_queue* cq = grpc_completion_queue_create_for_next(nullptr);
   gpr_timespec deadline = gpr_inf_future(GPR_CLOCK_MONOTONIC);
   for (auto _ : state) {
@@ -122,7 +122,7 @@ BENCHMARK(BM_Pass1Core);
 
 static void BM_Pluck1Core(benchmark::State& state) {
   TrackCounters track_counters;
-  // TODO: sreek Templatize this benchmark and pass polling_type as a param
+  // TODO(sreek): Templatize this benchmark and pass polling_type as a param
   grpc_completion_queue* cq = grpc_completion_queue_create_for_pluck(nullptr);
   gpr_timespec deadline = gpr_inf_future(GPR_CLOCK_MONOTONIC);
   for (auto _ : state) {
@@ -141,7 +141,7 @@ BENCHMARK(BM_Pluck1Core);
 
 static void BM_EmptyCore(benchmark::State& state) {
   TrackCounters track_counters;
-  // TODO: sreek Templatize this benchmark and pass polling_type as a param
+  // TODO(sreek): Templatize this benchmark and pass polling_type as a param
   grpc_completion_queue* cq = grpc_completion_queue_create_for_next(nullptr);
   gpr_timespec deadline = gpr_inf_past(GPR_CLOCK_MONOTONIC);
   for (auto _ : state) {
index b89eafb..f008249 100644 (file)
@@ -78,7 +78,7 @@ static grpc_error* pollset_work(grpc_pollset* ps,
 
   gpr_mu_unlock(&ps->mu);
 
-  void* tag = (void*)static_cast<intptr_t>(10);  // Some random number
+  void* tag = reinterpret_cast<void*>(10);  // Some random number
   GPR_ASSERT(grpc_cq_begin_op(g_cq, tag));
   grpc_cq_end_op(
       g_cq, tag, GRPC_ERROR_NONE, cq_done_cb, nullptr,
index 9fa42b5..de03128 100644 (file)
@@ -112,21 +112,24 @@ class TrickledCHTTP2 : public EndpointPairFixture {
 
   void AddToLabel(std::ostream& out, benchmark::State& state) override {
     out << " writes/iter:"
-        << ((double)stats_->num_writes / (double)state.iterations())
+        << (static_cast<double>(stats_->num_writes) /
+            static_cast<double>(state.iterations()))
         << " cli_transport_stalls/iter:"
-        << ((double)
-                client_stats_.streams_stalled_due_to_transport_flow_control /
-            (double)state.iterations())
+        << (static_cast<double>(
+                client_stats_.streams_stalled_due_to_transport_flow_control) /
+            static_cast<double>(state.iterations()))
         << " cli_stream_stalls/iter:"
-        << ((double)client_stats_.streams_stalled_due_to_stream_flow_control /
-            (double)state.iterations())
+        << (static_cast<double>(
+                client_stats_.streams_stalled_due_to_stream_flow_control) /
+            static_cast<double>(state.iterations()))
         << " svr_transport_stalls/iter:"
-        << ((double)
-                server_stats_.streams_stalled_due_to_transport_flow_control /
-            (double)state.iterations())
+        << (static_cast<double>(
+                server_stats_.streams_stalled_due_to_transport_flow_control) /
+            static_cast<double>(state.iterations()))
         << " svr_stream_stalls/iter:"
-        << ((double)server_stats_.streams_stalled_due_to_stream_flow_control /
-            (double)state.iterations());
+        << (static_cast<double>(
+                server_stats_.streams_stalled_due_to_stream_flow_control) /
+            static_cast<double>(state.iterations()));
   }
 
   void Log(int64_t iteration) GPR_ATTRIBUTE_NO_TSAN {
@@ -194,10 +197,10 @@ class TrickledCHTTP2 : public EndpointPairFixture {
         grpc_trickle_endpoint_trickle(endpoint_pair_.server);
 
     if (update_stats) {
-      UpdateStats((grpc_chttp2_transport*)client_transport_, &client_stats_,
-                  client_backlog);
-      UpdateStats((grpc_chttp2_transport*)server_transport_, &server_stats_,
-                  server_backlog);
+      UpdateStats(reinterpret_cast<grpc_chttp2_transport*>(client_transport_),
+                  &client_stats_, client_backlog);
+      UpdateStats(reinterpret_cast<grpc_chttp2_transport*>(server_transport_),
+                  &server_stats_, server_backlog);
     }
   }
 
@@ -281,7 +284,7 @@ static void BM_PumpStreamServerToClient_Trickle(benchmark::State& state) {
     while (need_tags) {
       TrickleCQNext(fixture.get(), &t, &ok, -1);
       GPR_ASSERT(ok);
-      int i = (int)(intptr_t)t;
+      int i = static_cast<int>(reinterpret_cast<intptr_t>(t));
       GPR_ASSERT(need_tags & (1 << i));
       need_tags &= ~(1 << i);
     }
@@ -327,7 +330,7 @@ static void BM_PumpStreamServerToClient_Trickle(benchmark::State& state) {
         request_rw->Read(&recv_response, tag(0));
         continue;
       }
-      int i = (int)(intptr_t)t;
+      int i = static_cast<int>(reinterpret_cast<intptr_t>(t));
       GPR_ASSERT(need_tags & (1 << i));
       need_tags &= ~(1 << i);
     }
@@ -404,7 +407,7 @@ static void BM_PumpUnbalancedUnary_Trickle(benchmark::State& state) {
       TrickleCQNext(fixture.get(), &t, &ok,
                     in_warmup ? -1 : state.iterations());
       GPR_ASSERT(ok);
-      int tagnum = (int)reinterpret_cast<intptr_t>(t);
+      int tagnum = static_cast<int>(reinterpret_cast<intptr_t>(t));
       GPR_ASSERT(i & (1 << tagnum));
       i -= 1 << tagnum;
     }
index d403f8f..cb6110a 100644 (file)
@@ -37,7 +37,7 @@ namespace testing {
 // the count reaches 0.
 class BlockingCounter {
  public:
-  BlockingCounter(int count) : count_(count) {}
+  explicit BlockingCounter(int count) : count_(count) {}
   void DecrementCount() {
     std::lock_guard<std::mutex> l(mu_);
     count_--;
@@ -130,7 +130,7 @@ BENCHMARK_TEMPLATE(ThreadPoolAddAnother, 2048)
 // A functor class that will delete self on end of running.
 class SuicideFunctorForAdd : public grpc_experimental_completion_queue_functor {
  public:
-  SuicideFunctorForAdd(BlockingCounter* counter) : counter_(counter) {
+  explicit SuicideFunctorForAdd(BlockingCounter* counter) : counter_(counter) {
     functor_run = &SuicideFunctorForAdd::Run;
     inlineable = false;
     internal_next = this;
index 06a1d78..82e05e8 100644 (file)
@@ -52,7 +52,7 @@ auto MakeVector(size_t length, F f) -> std::vector<decltype(f())> {
 class NoOpMutator {
  public:
   template <class ContextType>
-  NoOpMutator(ContextType* /*context*/) {}
+  explicit NoOpMutator(ContextType* /*context*/) {}
 };
 
 template <int length>
@@ -100,7 +100,7 @@ class RandomAsciiMetadata {
 template <class Generator, int kNumKeys>
 class Client_AddMetadata : public NoOpMutator {
  public:
-  Client_AddMetadata(ClientContext* context) : NoOpMutator(context) {
+  explicit Client_AddMetadata(ClientContext* context) : NoOpMutator(context) {
     for (int i = 0; i < kNumKeys; i++) {
       context->AddMetadata(Generator::Key(), Generator::Value());
     }
@@ -110,7 +110,8 @@ class Client_AddMetadata : public NoOpMutator {
 template <class Generator, int kNumKeys>
 class Server_AddInitialMetadata : public NoOpMutator {
  public:
-  Server_AddInitialMetadata(ServerContext* context) : NoOpMutator(context) {
+  explicit Server_AddInitialMetadata(ServerContext* context)
+      : NoOpMutator(context) {
     for (int i = 0; i < kNumKeys; i++) {
       context->AddInitialMetadata(Generator::Key(), Generator::Value());
     }
index 9ba190b..b5e8028 100644 (file)
@@ -111,8 +111,9 @@ class FullstackFixture : public BaseFixture {
 
 class TCP : public FullstackFixture {
  public:
-  TCP(Service* service, const FixtureConfiguration& fixture_configuration =
-                            FixtureConfiguration())
+  explicit TCP(Service* service,
+               const FixtureConfiguration& fixture_configuration =
+                   FixtureConfiguration())
       : FullstackFixture(service, fixture_configuration, MakeAddress(&port_)) {}
 
   ~TCP() override { grpc_recycle_unused_port(port_); }
@@ -130,8 +131,9 @@ class TCP : public FullstackFixture {
 
 class UDS : public FullstackFixture {
  public:
-  UDS(Service* service, const FixtureConfiguration& fixture_configuration =
-                            FixtureConfiguration())
+  explicit UDS(Service* service,
+               const FixtureConfiguration& fixture_configuration =
+                   FixtureConfiguration())
       : FullstackFixture(service, fixture_configuration, MakeAddress(&port_)) {}
 
   ~UDS() override { grpc_recycle_unused_port(port_); }
@@ -150,9 +152,9 @@ class UDS : public FullstackFixture {
 
 class InProcess : public FullstackFixture {
  public:
-  InProcess(Service* service,
-            const FixtureConfiguration& fixture_configuration =
-                FixtureConfiguration())
+  explicit InProcess(Service* service,
+                     const FixtureConfiguration& fixture_configuration =
+                         FixtureConfiguration())
       : FullstackFixture(service, fixture_configuration, "") {}
   ~InProcess() override {}
 };
@@ -241,8 +243,9 @@ class EndpointPairFixture : public BaseFixture {
 
 class SockPair : public EndpointPairFixture {
  public:
-  SockPair(Service* service, const FixtureConfiguration& fixture_configuration =
-                                 FixtureConfiguration())
+  explicit SockPair(Service* service,
+                    const FixtureConfiguration& fixture_configuration =
+                        FixtureConfiguration())
       : EndpointPairFixture(service,
                             grpc_iomgr_create_endpoint_pair("test", nullptr),
                             fixture_configuration) {}
@@ -287,9 +290,9 @@ class InProcessCHTTP2WithExplicitStats : public EndpointPairFixture {
 
 class InProcessCHTTP2 : public InProcessCHTTP2WithExplicitStats {
  public:
-  InProcessCHTTP2(Service* service,
-                  const FixtureConfiguration& fixture_configuration =
-                      FixtureConfiguration())
+  explicit InProcessCHTTP2(Service* service,
+                           const FixtureConfiguration& fixture_configuration =
+                               FixtureConfiguration())
       : InProcessCHTTP2WithExplicitStats(service,
                                          grpc_passthru_endpoint_stats_create(),
                                          fixture_configuration) {}
@@ -313,7 +316,8 @@ class MinStackConfiguration : public FixtureConfiguration {
 template <class Base>
 class MinStackize : public Base {
  public:
-  MinStackize(Service* service) : Base(service, MinStackConfiguration()) {}
+  explicit MinStackize(Service* service)
+      : Base(service, MinStackConfiguration()) {}
 };
 
 typedef MinStackize<TCP> MinTCP;
index db9be84..9ca213c 100644 (file)
@@ -83,7 +83,7 @@ static void BM_StreamingPingPong(benchmark::State& state) {
       while (need_tags) {
         GPR_ASSERT(fixture->cq()->Next(&t, &ok));
         GPR_ASSERT(ok);
-        int i = static_cast<int>((intptr_t)t);
+        int i = static_cast<int>(reinterpret_cast<intptr_t>(t));
         GPR_ASSERT(need_tags & (1 << i));
         need_tags &= ~(1 << i);
       }
@@ -99,7 +99,7 @@ static void BM_StreamingPingPong(benchmark::State& state) {
         while (need_tags) {
           GPR_ASSERT(fixture->cq()->Next(&t, &ok));
           GPR_ASSERT(ok);
-          int i = static_cast<int>((intptr_t)t);
+          int i = static_cast<int>(reinterpret_cast<intptr_t>(t));
 
           // If server recv is complete, start the server send operation
           if (i == 1) {
@@ -122,7 +122,7 @@ static void BM_StreamingPingPong(benchmark::State& state) {
       need_tags = (1 << 0) | (1 << 1) | (1 << 2);
       while (need_tags) {
         GPR_ASSERT(fixture->cq()->Next(&t, &ok));
-        int i = static_cast<int>((intptr_t)t);
+        int i = static_cast<int>(reinterpret_cast<intptr_t>(t));
         GPR_ASSERT(need_tags & (1 << i));
         need_tags &= ~(1 << i);
       }
@@ -175,7 +175,7 @@ static void BM_StreamingPingPongMsgs(benchmark::State& state) {
     while (need_tags) {
       GPR_ASSERT(fixture->cq()->Next(&t, &ok));
       GPR_ASSERT(ok);
-      int i = static_cast<int>((intptr_t)t);
+      int i = static_cast<int>(reinterpret_cast<intptr_t>(t));
       GPR_ASSERT(need_tags & (1 << i));
       need_tags &= ~(1 << i);
     }
@@ -190,7 +190,7 @@ static void BM_StreamingPingPongMsgs(benchmark::State& state) {
       while (need_tags) {
         GPR_ASSERT(fixture->cq()->Next(&t, &ok));
         GPR_ASSERT(ok);
-        int i = static_cast<int>((intptr_t)t);
+        int i = static_cast<int>(reinterpret_cast<intptr_t>(t));
 
         // If server recv is complete, start the server send operation
         if (i == 1) {
@@ -210,7 +210,7 @@ static void BM_StreamingPingPongMsgs(benchmark::State& state) {
     need_tags = (1 << 0) | (1 << 1) | (1 << 2);
     while (need_tags) {
       GPR_ASSERT(fixture->cq()->Next(&t, &ok));
-      int i = static_cast<int>((intptr_t)t);
+      int i = static_cast<int>(reinterpret_cast<intptr_t>(t));
       GPR_ASSERT(need_tags & (1 << i));
       need_tags &= ~(1 << i);
     }
@@ -297,10 +297,10 @@ static void BM_StreamingPingPongWithCoalescingApi(benchmark::State& state) {
           // established). It is necessary when client init metadata is
           // coalesced
           GPR_ASSERT(fixture->cq()->Next(&t, &ok));
-          while (static_cast<int>((intptr_t)t) != 0) {
+          while (static_cast<int>(reinterpret_cast<intptr_t>(t)) != 0) {
             // In some cases tag:2 comes before tag:0 (write tag comes out
             // first), this while loop is to make sure get tag:0.
-            int i = static_cast<int>((intptr_t)t);
+            int i = static_cast<int>(reinterpret_cast<intptr_t>(t));
             GPR_ASSERT(await_tags & (1 << i));
             await_tags &= ~(1 << i);
             GPR_ASSERT(fixture->cq()->Next(&t, &ok));
@@ -317,7 +317,7 @@ static void BM_StreamingPingPongWithCoalescingApi(benchmark::State& state) {
         while (await_tags != 0) {
           GPR_ASSERT(fixture->cq()->Next(&t, &ok));
           GPR_ASSERT(ok);
-          int i = static_cast<int>((intptr_t)t);
+          int i = static_cast<int>(reinterpret_cast<intptr_t>(t));
 
           // If server recv is complete, start the server send operation
           if (i == 3) {
@@ -367,8 +367,8 @@ static void BM_StreamingPingPongWithCoalescingApi(benchmark::State& state) {
         // wait for server call data structure(call_hook, etc.) to be
         // initialized, since initial metadata is corked.
         GPR_ASSERT(fixture->cq()->Next(&t, &ok));
-        while (static_cast<int>((intptr_t)t) != 0) {
-          int i = static_cast<int>((intptr_t)t);
+        while (static_cast<int>(reinterpret_cast<intptr_t>(t)) != 0) {
+          int i = static_cast<int>(reinterpret_cast<intptr_t>(t));
           GPR_ASSERT(expect_tags & (1 << i));
           expect_tags &= ~(1 << i);
           GPR_ASSERT(fixture->cq()->Next(&t, &ok));
@@ -385,7 +385,7 @@ static void BM_StreamingPingPongWithCoalescingApi(benchmark::State& state) {
 
       while (expect_tags) {
         GPR_ASSERT(fixture->cq()->Next(&t, &ok));
-        int i = static_cast<int>((intptr_t)t);
+        int i = static_cast<int>(reinterpret_cast<intptr_t>(t));
         GPR_ASSERT(expect_tags & (1 << i));
         expect_tags &= ~(1 << i);
       }
index cf72710..d05258b 100644 (file)
@@ -62,7 +62,7 @@ static void BM_PumpStreamClientToServer(benchmark::State& state) {
     while (need_tags) {
       GPR_ASSERT(fixture->cq()->Next(&t, &ok));
       GPR_ASSERT(ok);
-      int i = static_cast<int>((intptr_t)t);
+      int i = static_cast<int>(reinterpret_cast<intptr_t>(t));
       GPR_ASSERT(need_tags & (1 << i));
       need_tags &= ~(1 << i);
     }
@@ -85,7 +85,7 @@ static void BM_PumpStreamClientToServer(benchmark::State& state) {
     need_tags = (1 << 0) | (1 << 1);
     while (need_tags) {
       GPR_ASSERT(fixture->cq()->Next(&t, &ok));
-      int i = static_cast<int>((intptr_t)t);
+      int i = static_cast<int>(reinterpret_cast<intptr_t>(t));
       GPR_ASSERT(need_tags & (1 << i));
       need_tags &= ~(1 << i);
     }
@@ -95,7 +95,7 @@ static void BM_PumpStreamClientToServer(benchmark::State& state) {
     need_tags = (1 << 0) | (1 << 1);
     while (need_tags) {
       GPR_ASSERT(fixture->cq()->Next(&t, &ok));
-      int i = static_cast<int>((intptr_t)t);
+      int i = static_cast<int>(reinterpret_cast<intptr_t>(t));
       GPR_ASSERT(need_tags & (1 << i));
       need_tags &= ~(1 << i);
     }
@@ -131,7 +131,7 @@ static void BM_PumpStreamServerToClient(benchmark::State& state) {
     while (need_tags) {
       GPR_ASSERT(fixture->cq()->Next(&t, &ok));
       GPR_ASSERT(ok);
-      int i = static_cast<int>((intptr_t)t);
+      int i = static_cast<int>(reinterpret_cast<intptr_t>(t));
       GPR_ASSERT(need_tags & (1 << i));
       need_tags &= ~(1 << i);
     }
@@ -154,7 +154,7 @@ static void BM_PumpStreamServerToClient(benchmark::State& state) {
     need_tags = (1 << 0) | (1 << 1);
     while (need_tags) {
       GPR_ASSERT(fixture->cq()->Next(&t, &ok));
-      int i = static_cast<int>((intptr_t)t);
+      int i = static_cast<int>(reinterpret_cast<intptr_t>(t));
       GPR_ASSERT(need_tags & (1 << i));
       need_tags &= ~(1 << i);
     }
index dd2dac7..b35c37c 100644 (file)
@@ -38,7 +38,6 @@ grpc_cc_test(
     name = "cancel_ares_query_test",
     srcs = ["cancel_ares_query_test.cc"],
     external_deps = ["gtest"],
-    flaky = True,  # TODO(b/157516105)
     deps = [
         ":dns_test_util",
         "//:gpr",
index 2f89014..edcee21 100644 (file)
@@ -787,7 +787,7 @@ TEST_F(AddressSortingTest, TestSorterKnowsIpv6LoopbackIsAvailable) {
   sockaddr_in6 ipv6_loopback;
   memset(&ipv6_loopback, 0, sizeof(ipv6_loopback));
   ipv6_loopback.sin6_family = AF_INET6;
-  ((char*)&ipv6_loopback.sin6_addr)[15] = 1;
+  (reinterpret_cast<char*>(&ipv6_loopback.sin6_addr))[15] = 1;
   ipv6_loopback.sin6_port = htons(443);
   // Set up the source and destination parameters of
   // address_sorting_get_source_addr
@@ -803,7 +803,7 @@ TEST_F(AddressSortingTest, TestSorterKnowsIpv6LoopbackIsAvailable) {
   // Now also check that the source address was filled in correctly.
   EXPECT_GT(source_for_sort_input_dest.len, 0u);
   sockaddr_in6* source_addr_output =
-      (sockaddr_in6*)source_for_sort_input_dest.addr;
+      reinterpret_cast<sockaddr_in6*>(source_for_sort_input_dest.addr);
   EXPECT_EQ(source_addr_output->sin6_family, AF_INET6);
   char* buf = static_cast<char*>(gpr_zalloc(100));
   EXPECT_NE(inet_ntop(AF_INET6, &source_addr_output->sin6_addr, buf, 100),
index 0163c2e..371e3e5 100644 (file)
@@ -57,7 +57,7 @@
 
 namespace {
 
-void* Tag(intptr_t t) { return (void*)t; }
+void* Tag(intptr_t t) { return reinterpret_cast<void*>(t); }
 
 gpr_timespec FiveSecondsFromNow(void) {
   return grpc_timeout_seconds_to_deadline(5);
@@ -87,7 +87,7 @@ struct ArgsStruct {
 };
 
 void ArgsInit(ArgsStruct* args) {
-  args->pollset = (grpc_pollset*)gpr_zalloc(grpc_pollset_size());
+  args->pollset = static_cast<grpc_pollset*>(gpr_zalloc(grpc_pollset_size()));
   grpc_pollset_init(args->pollset, &args->mu);
   args->pollset_set = grpc_pollset_set_create();
   grpc_pollset_set_add_pollset(args->pollset_set, args->pollset);
@@ -374,7 +374,7 @@ void TestCancelDuringActiveQuery(
   // Teardown
   grpc_channel_args_destroy(client_args);
   grpc_slice_unref(details);
-  gpr_free((void*)error_string);
+  gpr_free(const_cast<char*>(error_string));
   grpc_metadata_array_destroy(&initial_metadata_recv);
   grpc_metadata_array_destroy(&trailing_metadata_recv);
   grpc_metadata_array_destroy(&request_metadata_recv);
index e44ccc2..ca97bf3 100644 (file)
@@ -51,8 +51,9 @@ FakeNonResponsiveDNSServer::FakeNonResponsiveDNSServer(int port) {
   memset(&addr, 0, sizeof(addr));
   addr.sin6_family = AF_INET6;
   addr.sin6_port = htons(port);
-  ((char*)&addr.sin6_addr)[15] = 1;
-  if (bind(udp_socket_, (const sockaddr*)&addr, sizeof(addr)) != 0) {
+  (reinterpret_cast<char*>(&addr.sin6_addr))[15] = 1;
+  if (bind(udp_socket_, reinterpret_cast<const sockaddr*>(&addr),
+           sizeof(addr)) != 0) {
     gpr_log(GPR_DEBUG, "Failed to bind UDP ipv6 socket to [::1]:%d", port);
     abort();
   }
@@ -73,7 +74,8 @@ FakeNonResponsiveDNSServer::FakeNonResponsiveDNSServer(int port) {
     abort();
   }
 #endif
-  if (bind(tcp_socket_, (const sockaddr*)&addr, sizeof(addr)) != 0) {
+  if (bind(tcp_socket_, reinterpret_cast<const sockaddr*>(&addr),
+           sizeof(addr)) != 0) {
     gpr_log(GPR_DEBUG, "Failed to bind TCP ipv6 socket to [::1]:%d", port);
     abort();
   }
index 59d12be..eb27857 100755 (executable)
@@ -65,7 +65,7 @@ def _resolver_test_cases(resolver_component_data):
 def main():
     resolver_component_data = ''
     with open('test/cpp/naming/resolver_test_record_groups.yaml') as f:
-        resolver_component_data = yaml.load(f)
+        resolver_component_data = yaml.load(f, Loader=yaml.FullLoader)
 
     json = {
         'resolver_tests_common_zone_name':
index 77ca6e6..052be9e 100644 (file)
@@ -39,7 +39,6 @@
 #include "src/core/ext/filters/client_channel/client_channel.h"
 #include "src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_balancer_addresses.h"
 #include "src/core/ext/filters/client_channel/resolver.h"
-#include "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.h"
 #include "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h"
 #include "src/core/ext/filters/client_channel/resolver_registry.h"
 #include "src/core/ext/filters/client_channel/server_address.h"
@@ -60,7 +59,7 @@
 #include "test/cpp/util/subprocess.h"
 #include "test/cpp/util/test_config.h"
 
-// TODO: pull in different headers when enabling this
+// TODO(unknown): pull in different headers when enabling this
 // test on windows. Also set BAD_SOCKET_RETURN_VAL
 // to INVALID_SOCKET on windows.
 #ifdef GPR_WINDOWS
@@ -202,7 +201,7 @@ struct ArgsStruct {
 
 void ArgsInit(ArgsStruct* args) {
   gpr_event_init(&args->ev);
-  args->pollset = (grpc_pollset*)gpr_zalloc(grpc_pollset_size());
+  args->pollset = static_cast<grpc_pollset*>(gpr_zalloc(grpc_pollset_size()));
   grpc_pollset_init(args->pollset, &args->mu);
   args->pollset_set = grpc_pollset_set_create();
   grpc_pollset_set_add_pollset(args->pollset_set, args->pollset);
@@ -257,7 +256,7 @@ void PollPollsetUntilRequestDone(ArgsStruct* args) {
                                             NSecondDeadline(1))));
     gpr_mu_unlock(args->mu);
   }
-  gpr_event_set(&args->ev, (void*)1);
+  gpr_event_set(&args->ev, reinterpret_cast<void*>(1));
 }
 
 void CheckServiceConfigResultLocked(const char* service_config_json,
@@ -361,7 +360,7 @@ void OpenAndCloseSocketsStressLoop(int dummy_port, gpr_event* done_ev) {
   memset(&addr, 0, sizeof(addr));
   addr.sin6_family = AF_INET6;
   addr.sin6_port = htons(dummy_port);
-  ((char*)&addr.sin6_addr)[15] = 1;
+  (reinterpret_cast<char*>(&addr.sin6_addr))[15] = 1;
   for (;;) {
     if (gpr_event_get(done_ev)) {
       return;
@@ -541,7 +540,7 @@ void InjectBrokenNameServerList(ares_channel channel) {
           absl::GetFlag(FLAGS_local_dns_server_address).c_str());
   // Put the non-responsive DNS server at the front of c-ares's nameserver list.
   dns_server_addrs[0].family = AF_INET6;
-  ((char*)&dns_server_addrs[0].addr.addr6)[15] = 0x1;
+  (reinterpret_cast<char*>(&dns_server_addrs[0].addr.addr6))[15] = 0x1;
   dns_server_addrs[0].tcp_port = g_fake_non_responsive_dns_server_port;
   dns_server_addrs[0].udp_port = g_fake_non_responsive_dns_server_port;
   dns_server_addrs[0].next = &dns_server_addrs[1];
@@ -550,8 +549,8 @@ void InjectBrokenNameServerList(ares_channel channel) {
   // and will skip over to this healthy DNS server, without causing any DNS
   // resolution errors.
   dns_server_addrs[1].family = AF_INET;
-  ((char*)&dns_server_addrs[1].addr.addr4)[0] = 0x7f;
-  ((char*)&dns_server_addrs[1].addr.addr4)[3] = 0x1;
+  (reinterpret_cast<char*>(&dns_server_addrs[1].addr.addr4))[0] = 0x7f;
+  (reinterpret_cast<char*>(&dns_server_addrs[1].addr.addr4))[3] = 0x1;
   dns_server_addrs[1].tcp_port = atoi(local_dns_server_port.c_str());
   dns_server_addrs[1].udp_port = atoi(local_dns_server_port.c_str());
   dns_server_addrs[1].next = nullptr;
@@ -660,7 +659,7 @@ TEST(ResolverComponentTest, TestResolvesRelevantRecordsWithConcurrentFdStress) {
   // Run the resolver test
   RunResolvesRelevantRecordsTest(ResultHandler::Create);
   // Shutdown and join stress thread
-  gpr_event_set(&done_ev, (void*)1);
+  gpr_event_set(&done_ev, reinterpret_cast<void*>(1));
   socket_stress_thread.join();
 }
 
index bb54453..6a1bff3 100755 (executable)
@@ -39,6 +39,9 @@ argp.add_argument('--dns_resolver_bin_path', default=None, type=str,
                   help=('Path to the DNS health check utility.'))
 argp.add_argument('--tcp_connect_bin_path', default=None, type=str,
                   help=('Path to the TCP health check utility.'))
+argp.add_argument('--extra_args', default='', type=str,
+                  help=('Comma-separate list of command args to '
+                       'plumb through to --test_bin_path'))
 args = argp.parse_args()
 
 def test_runner_log(msg):
@@ -77,9 +80,9 @@ def wait_until_dns_server_is_up(args,
           '--server_host', '127.0.0.1',
           '--server_port', str(args.dns_server_port)]),
           stdout=subprocess.PIPE)
-      dns_resolver_stdout, _ = dns_resolver_subprocess.communicate()
+      dns_resolver_stdout, _ = dns_resolver_subprocess.communicate(str.encode('ascii'))
       if dns_resolver_subprocess.returncode == 0:
-        if '123.123.123.123' in dns_resolver_stdout:
+        if '123.123.123.123'.encode('ascii') in dns_resolver_stdout:
           test_runner_log(('DNS server is up! '
                            'Successfully reached it over UDP and TCP.'))
         return
@@ -130,7 +133,8 @@ current_test_subprocess = subprocess.Popen([
   '--enable_srv_queries', 'True',
   '--enable_txt_queries', 'True',
   '--inject_broken_nameserver_list', 'False',
-  '--local_dns_server_address', '127.0.0.1:%d' % args.dns_server_port])
+  '--local_dns_server_address', '127.0.0.1:%d' % args.dns_server_port
+  ] + args.extra_args.split(','))
 current_test_subprocess.communicate()
 if current_test_subprocess.returncode != 0:
   num_test_failures += 1
@@ -147,7 +151,8 @@ current_test_subprocess = subprocess.Popen([
   '--enable_srv_queries', 'True',
   '--enable_txt_queries', 'True',
   '--inject_broken_nameserver_list', 'False',
-  '--local_dns_server_address', '127.0.0.1:%d' % args.dns_server_port])
+  '--local_dns_server_address', '127.0.0.1:%d' % args.dns_server_port
+  ] + args.extra_args.split(','))
 current_test_subprocess.communicate()
 if current_test_subprocess.returncode != 0:
   num_test_failures += 1
@@ -164,7 +169,8 @@ current_test_subprocess = subprocess.Popen([
   '--enable_srv_queries', 'True',
   '--enable_txt_queries', 'True',
   '--inject_broken_nameserver_list', 'False',
-  '--local_dns_server_address', '127.0.0.1:%d' % args.dns_server_port])
+  '--local_dns_server_address', '127.0.0.1:%d' % args.dns_server_port
+  ] + args.extra_args.split(','))
 current_test_subprocess.communicate()
 if current_test_subprocess.returncode != 0:
   num_test_failures += 1
@@ -181,7 +187,8 @@ current_test_subprocess = subprocess.Popen([
   '--enable_srv_queries', 'True',
   '--enable_txt_queries', 'True',
   '--inject_broken_nameserver_list', 'False',
-  '--local_dns_server_address', '127.0.0.1:%d' % args.dns_server_port])
+  '--local_dns_server_address', '127.0.0.1:%d' % args.dns_server_port
+  ] + args.extra_args.split(','))
 current_test_subprocess.communicate()
 if current_test_subprocess.returncode != 0:
   num_test_failures += 1
@@ -198,7 +205,8 @@ current_test_subprocess = subprocess.Popen([
   '--enable_srv_queries', 'True',
   '--enable_txt_queries', 'True',
   '--inject_broken_nameserver_list', 'False',
-  '--local_dns_server_address', '127.0.0.1:%d' % args.dns_server_port])
+  '--local_dns_server_address', '127.0.0.1:%d' % args.dns_server_port
+  ] + args.extra_args.split(','))
 current_test_subprocess.communicate()
 if current_test_subprocess.returncode != 0:
   num_test_failures += 1
@@ -215,7 +223,8 @@ current_test_subprocess = subprocess.Popen([
   '--enable_srv_queries', 'True',
   '--enable_txt_queries', 'True',
   '--inject_broken_nameserver_list', 'False',
-  '--local_dns_server_address', '127.0.0.1:%d' % args.dns_server_port])
+  '--local_dns_server_address', '127.0.0.1:%d' % args.dns_server_port
+  ] + args.extra_args.split(','))
 current_test_subprocess.communicate()
 if current_test_subprocess.returncode != 0:
   num_test_failures += 1
@@ -232,7 +241,8 @@ current_test_subprocess = subprocess.Popen([
   '--enable_srv_queries', 'True',
   '--enable_txt_queries', 'True',
   '--inject_broken_nameserver_list', 'False',
-  '--local_dns_server_address', '127.0.0.1:%d' % args.dns_server_port])
+  '--local_dns_server_address', '127.0.0.1:%d' % args.dns_server_port
+  ] + args.extra_args.split(','))
 current_test_subprocess.communicate()
 if current_test_subprocess.returncode != 0:
   num_test_failures += 1
@@ -249,7 +259,8 @@ current_test_subprocess = subprocess.Popen([
   '--enable_srv_queries', 'True',
   '--enable_txt_queries', 'True',
   '--inject_broken_nameserver_list', 'False',
-  '--local_dns_server_address', '127.0.0.1:%d' % args.dns_server_port])
+  '--local_dns_server_address', '127.0.0.1:%d' % args.dns_server_port
+  ] + args.extra_args.split(','))
 current_test_subprocess.communicate()
 if current_test_subprocess.returncode != 0:
   num_test_failures += 1
@@ -266,7 +277,8 @@ current_test_subprocess = subprocess.Popen([
   '--enable_srv_queries', 'True',
   '--enable_txt_queries', 'True',
   '--inject_broken_nameserver_list', 'False',
-  '--local_dns_server_address', '127.0.0.1:%d' % args.dns_server_port])
+  '--local_dns_server_address', '127.0.0.1:%d' % args.dns_server_port
+  ] + args.extra_args.split(','))
 current_test_subprocess.communicate()
 if current_test_subprocess.returncode != 0:
   num_test_failures += 1
@@ -283,7 +295,8 @@ current_test_subprocess = subprocess.Popen([
   '--enable_srv_queries', 'True',
   '--enable_txt_queries', 'True',
   '--inject_broken_nameserver_list', 'False',
-  '--local_dns_server_address', '127.0.0.1:%d' % args.dns_server_port])
+  '--local_dns_server_address', '127.0.0.1:%d' % args.dns_server_port
+  ] + args.extra_args.split(','))
 current_test_subprocess.communicate()
 if current_test_subprocess.returncode != 0:
   num_test_failures += 1
@@ -300,7 +313,8 @@ current_test_subprocess = subprocess.Popen([
   '--enable_srv_queries', 'True',
   '--enable_txt_queries', 'True',
   '--inject_broken_nameserver_list', 'False',
-  '--local_dns_server_address', '127.0.0.1:%d' % args.dns_server_port])
+  '--local_dns_server_address', '127.0.0.1:%d' % args.dns_server_port
+  ] + args.extra_args.split(','))
 current_test_subprocess.communicate()
 if current_test_subprocess.returncode != 0:
   num_test_failures += 1
@@ -317,7 +331,8 @@ current_test_subprocess = subprocess.Popen([
   '--enable_srv_queries', 'True',
   '--enable_txt_queries', 'True',
   '--inject_broken_nameserver_list', 'False',
-  '--local_dns_server_address', '127.0.0.1:%d' % args.dns_server_port])
+  '--local_dns_server_address', '127.0.0.1:%d' % args.dns_server_port
+  ] + args.extra_args.split(','))
 current_test_subprocess.communicate()
 if current_test_subprocess.returncode != 0:
   num_test_failures += 1
@@ -334,7 +349,8 @@ current_test_subprocess = subprocess.Popen([
   '--enable_srv_queries', 'True',
   '--enable_txt_queries', 'True',
   '--inject_broken_nameserver_list', 'False',
-  '--local_dns_server_address', '127.0.0.1:%d' % args.dns_server_port])
+  '--local_dns_server_address', '127.0.0.1:%d' % args.dns_server_port
+  ] + args.extra_args.split(','))
 current_test_subprocess.communicate()
 if current_test_subprocess.returncode != 0:
   num_test_failures += 1
@@ -351,7 +367,8 @@ current_test_subprocess = subprocess.Popen([
   '--enable_srv_queries', 'True',
   '--enable_txt_queries', 'True',
   '--inject_broken_nameserver_list', 'False',
-  '--local_dns_server_address', '127.0.0.1:%d' % args.dns_server_port])
+  '--local_dns_server_address', '127.0.0.1:%d' % args.dns_server_port
+  ] + args.extra_args.split(','))
 current_test_subprocess.communicate()
 if current_test_subprocess.returncode != 0:
   num_test_failures += 1
@@ -368,7 +385,8 @@ current_test_subprocess = subprocess.Popen([
   '--enable_srv_queries', 'False',
   '--enable_txt_queries', 'True',
   '--inject_broken_nameserver_list', 'False',
-  '--local_dns_server_address', '127.0.0.1:%d' % args.dns_server_port])
+  '--local_dns_server_address', '127.0.0.1:%d' % args.dns_server_port
+  ] + args.extra_args.split(','))
 current_test_subprocess.communicate()
 if current_test_subprocess.returncode != 0:
   num_test_failures += 1
@@ -385,7 +403,8 @@ current_test_subprocess = subprocess.Popen([
   '--enable_srv_queries', 'False',
   '--enable_txt_queries', 'True',
   '--inject_broken_nameserver_list', 'False',
-  '--local_dns_server_address', '127.0.0.1:%d' % args.dns_server_port])
+  '--local_dns_server_address', '127.0.0.1:%d' % args.dns_server_port
+  ] + args.extra_args.split(','))
 current_test_subprocess.communicate()
 if current_test_subprocess.returncode != 0:
   num_test_failures += 1
@@ -402,7 +421,8 @@ current_test_subprocess = subprocess.Popen([
   '--enable_srv_queries', 'False',
   '--enable_txt_queries', 'True',
   '--inject_broken_nameserver_list', 'False',
-  '--local_dns_server_address', '127.0.0.1:%d' % args.dns_server_port])
+  '--local_dns_server_address', '127.0.0.1:%d' % args.dns_server_port
+  ] + args.extra_args.split(','))
 current_test_subprocess.communicate()
 if current_test_subprocess.returncode != 0:
   num_test_failures += 1
@@ -419,7 +439,8 @@ current_test_subprocess = subprocess.Popen([
   '--enable_srv_queries', 'False',
   '--enable_txt_queries', 'True',
   '--inject_broken_nameserver_list', 'False',
-  '--local_dns_server_address', '127.0.0.1:%d' % args.dns_server_port])
+  '--local_dns_server_address', '127.0.0.1:%d' % args.dns_server_port
+  ] + args.extra_args.split(','))
 current_test_subprocess.communicate()
 if current_test_subprocess.returncode != 0:
   num_test_failures += 1
@@ -436,7 +457,8 @@ current_test_subprocess = subprocess.Popen([
   '--enable_srv_queries', 'False',
   '--enable_txt_queries', 'True',
   '--inject_broken_nameserver_list', 'False',
-  '--local_dns_server_address', '127.0.0.1:%d' % args.dns_server_port])
+  '--local_dns_server_address', '127.0.0.1:%d' % args.dns_server_port
+  ] + args.extra_args.split(','))
 current_test_subprocess.communicate()
 if current_test_subprocess.returncode != 0:
   num_test_failures += 1
@@ -453,7 +475,8 @@ current_test_subprocess = subprocess.Popen([
   '--enable_srv_queries', 'True',
   '--enable_txt_queries', 'False',
   '--inject_broken_nameserver_list', 'False',
-  '--local_dns_server_address', '127.0.0.1:%d' % args.dns_server_port])
+  '--local_dns_server_address', '127.0.0.1:%d' % args.dns_server_port
+  ] + args.extra_args.split(','))
 current_test_subprocess.communicate()
 if current_test_subprocess.returncode != 0:
   num_test_failures += 1
@@ -470,7 +493,8 @@ current_test_subprocess = subprocess.Popen([
   '--enable_srv_queries', 'True',
   '--enable_txt_queries', 'False',
   '--inject_broken_nameserver_list', 'False',
-  '--local_dns_server_address', '127.0.0.1:%d' % args.dns_server_port])
+  '--local_dns_server_address', '127.0.0.1:%d' % args.dns_server_port
+  ] + args.extra_args.split(','))
 current_test_subprocess.communicate()
 if current_test_subprocess.returncode != 0:
   num_test_failures += 1
@@ -487,7 +511,8 @@ current_test_subprocess = subprocess.Popen([
   '--enable_srv_queries', 'True',
   '--enable_txt_queries', 'False',
   '--inject_broken_nameserver_list', 'False',
-  '--local_dns_server_address', '127.0.0.1:%d' % args.dns_server_port])
+  '--local_dns_server_address', '127.0.0.1:%d' % args.dns_server_port
+  ] + args.extra_args.split(','))
 current_test_subprocess.communicate()
 if current_test_subprocess.returncode != 0:
   num_test_failures += 1
@@ -504,7 +529,8 @@ current_test_subprocess = subprocess.Popen([
   '--enable_srv_queries', 'True',
   '--enable_txt_queries', 'True',
   '--inject_broken_nameserver_list', 'False',
-  '--local_dns_server_address', '127.0.0.1:%d' % args.dns_server_port])
+  '--local_dns_server_address', '127.0.0.1:%d' % args.dns_server_port
+  ] + args.extra_args.split(','))
 current_test_subprocess.communicate()
 if current_test_subprocess.returncode != 0:
   num_test_failures += 1
@@ -521,7 +547,8 @@ current_test_subprocess = subprocess.Popen([
   '--enable_srv_queries', 'True',
   '--enable_txt_queries', 'True',
   '--inject_broken_nameserver_list', 'False',
-  '--local_dns_server_address', '127.0.0.1:%d' % args.dns_server_port])
+  '--local_dns_server_address', '127.0.0.1:%d' % args.dns_server_port
+  ] + args.extra_args.split(','))
 current_test_subprocess.communicate()
 if current_test_subprocess.returncode != 0:
   num_test_failures += 1
@@ -538,7 +565,8 @@ current_test_subprocess = subprocess.Popen([
   '--enable_srv_queries', 'True',
   '--enable_txt_queries', 'True',
   '--inject_broken_nameserver_list', 'False',
-  '--local_dns_server_address', '127.0.0.1:%d' % args.dns_server_port])
+  '--local_dns_server_address', '127.0.0.1:%d' % args.dns_server_port
+  ] + args.extra_args.split(','))
 current_test_subprocess.communicate()
 if current_test_subprocess.returncode != 0:
   num_test_failures += 1
@@ -555,7 +583,8 @@ current_test_subprocess = subprocess.Popen([
   '--enable_srv_queries', 'True',
   '--enable_txt_queries', 'True',
   '--inject_broken_nameserver_list', 'False',
-  '--local_dns_server_address', '127.0.0.1:%d' % args.dns_server_port])
+  '--local_dns_server_address', '127.0.0.1:%d' % args.dns_server_port
+  ] + args.extra_args.split(','))
 current_test_subprocess.communicate()
 if current_test_subprocess.returncode != 0:
   num_test_failures += 1
@@ -572,7 +601,8 @@ current_test_subprocess = subprocess.Popen([
   '--enable_srv_queries', 'True',
   '--enable_txt_queries', 'True',
   '--inject_broken_nameserver_list', 'True',
-  '--local_dns_server_address', '127.0.0.1:%d' % args.dns_server_port])
+  '--local_dns_server_address', '127.0.0.1:%d' % args.dns_server_port
+  ] + args.extra_args.split(','))
 current_test_subprocess.communicate()
 if current_test_subprocess.returncode != 0:
   num_test_failures += 1
@@ -589,7 +619,8 @@ current_test_subprocess = subprocess.Popen([
   '--enable_srv_queries', 'True',
   '--enable_txt_queries', 'True',
   '--inject_broken_nameserver_list', 'True',
-  '--local_dns_server_address', '127.0.0.1:%d' % args.dns_server_port])
+  '--local_dns_server_address', '127.0.0.1:%d' % args.dns_server_port
+  ] + args.extra_args.split(','))
 current_test_subprocess.communicate()
 if current_test_subprocess.returncode != 0:
   num_test_failures += 1
@@ -606,7 +637,8 @@ current_test_subprocess = subprocess.Popen([
   '--enable_srv_queries', 'True',
   '--enable_txt_queries', 'True',
   '--inject_broken_nameserver_list', 'False',
-  '--local_dns_server_address', '127.0.0.1:%d' % args.dns_server_port])
+  '--local_dns_server_address', '127.0.0.1:%d' % args.dns_server_port
+  ] + args.extra_args.split(','))
 current_test_subprocess.communicate()
 if current_test_subprocess.returncode != 0:
   num_test_failures += 1
index 258a731..2ae8da9 100644 (file)
@@ -56,48 +56,11 @@ ABSL_FLAG(std::string, grpc_test_directory_relative_to_test_srcdir,
           "Directory of the <repo-root>/test directory relative to bazel's "
           "TEST_SRCDIR environment variable");
 
-using grpc::SubProcess;
-
-static volatile sig_atomic_t abort_wait_for_child = 0;
-
-static void sighandler(int /*sig*/) { abort_wait_for_child = 1; }
-
-static void register_sighandler() {
-  struct sigaction act;
-  memset(&act, 0, sizeof(act));
-  act.sa_handler = sighandler;
-  sigaction(SIGINT, &act, nullptr);
-  sigaction(SIGTERM, &act, nullptr);
-}
+ABSL_FLAG(std::string, extra_args, "",
+          "Comma-separated list of opaque command args to plumb through to "
+          "the binary pointed at by --test_bin_name");
 
-namespace {
-
-const int kTestTimeoutSeconds = 60 * 2;
-
-void RunSigHandlingThread(SubProcess* test_driver, gpr_mu* test_driver_mu,
-                          gpr_cv* test_driver_cv, int* test_driver_done) {
-  gpr_timespec overall_deadline =
-      gpr_time_add(gpr_now(GPR_CLOCK_MONOTONIC),
-                   gpr_time_from_seconds(kTestTimeoutSeconds, GPR_TIMESPAN));
-  while (true) {
-    gpr_timespec now = gpr_now(GPR_CLOCK_MONOTONIC);
-    if (gpr_time_cmp(now, overall_deadline) > 0 || abort_wait_for_child) break;
-    gpr_mu_lock(test_driver_mu);
-    if (*test_driver_done) {
-      gpr_mu_unlock(test_driver_mu);
-      return;
-    }
-    gpr_timespec wait_deadline = gpr_time_add(
-        gpr_now(GPR_CLOCK_MONOTONIC), gpr_time_from_seconds(1, GPR_TIMESPAN));
-    gpr_cv_wait(test_driver_cv, test_driver_mu, wait_deadline);
-    gpr_mu_unlock(test_driver_mu);
-  }
-  gpr_log(GPR_DEBUG,
-          "Test timeout reached or received signal. Interrupting test driver "
-          "child process.");
-  test_driver->Interrupt();
-}
-}  // namespace
+using grpc::SubProcess;
 
 namespace grpc {
 
@@ -117,16 +80,13 @@ void InvokeResolverComponentTestsRunner(
        "--records_config_path=" + records_config_path,
        "--dns_server_port=" + std::to_string(dns_server_port),
        "--dns_resolver_bin_path=" + dns_resolver_bin_path,
-       "--tcp_connect_bin_path=" + tcp_connect_bin_path});
+       "--tcp_connect_bin_path=" + tcp_connect_bin_path,
+       "--extra_args=" + absl::GetFlag(FLAGS_extra_args)});
   gpr_mu test_driver_mu;
   gpr_mu_init(&test_driver_mu);
   gpr_cv test_driver_cv;
   gpr_cv_init(&test_driver_cv);
   int test_driver_done = 0;
-  register_sighandler();
-  std::thread sig_handling_thread(RunSigHandlingThread, test_driver,
-                                  &test_driver_mu, &test_driver_cv,
-                                  &test_driver_done);
   int status = test_driver->Join();
   if (WIFEXITED(status)) {
     if (WEXITSTATUS(status)) {
@@ -150,7 +110,6 @@ void InvokeResolverComponentTestsRunner(
   test_driver_done = 1;
   gpr_cv_signal(&test_driver_cv);
   gpr_mu_unlock(&test_driver_mu);
-  sig_handling_thread.join();
   delete test_driver;
   gpr_mu_destroy(&test_driver_mu);
   gpr_cv_destroy(&test_driver_cv);
index 6b13e68..d70751f 100755 (executable)
@@ -53,6 +53,7 @@ def start_local_dns_server(args):
     all_records = {}
 
     def _push_record(name, r):
+        name = name.encode('ascii')
         print('pushing record: |%s|' % name)
         if all_records.get(name) is not None:
             all_records[name].append(r)
@@ -60,6 +61,7 @@ def start_local_dns_server(args):
         all_records[name] = [r]
 
     def _maybe_split_up_txt_data(name, txt_data, r_ttl):
+        txt_data = txt_data.encode('ascii')
         start = 0
         txt_data_list = []
         while len(txt_data[start:]) > 0:
@@ -93,8 +95,8 @@ def start_local_dns_server(args):
                     p = int(p)
                     w = int(w)
                     port = int(port)
-                    target_full_name = '%s.%s' % (target, common_zone_name)
-                    r_data = '%s %s %s %s' % (p, w, port, target_full_name)
+                    target_full_name = (
+                        '%s.%s' % (target, common_zone_name)).encode('ascii')
                     _push_record(
                         record_full_name,
                         dns.Record_SRV(p, w, port, target_full_name, ttl=r_ttl))
@@ -107,9 +109,9 @@ def start_local_dns_server(args):
     # Server health check record
     _push_record(_SERVER_HEALTH_CHECK_RECORD_NAME,
                  dns.Record_A(_SERVER_HEALTH_CHECK_RECORD_DATA, ttl=0))
-    soa_record = dns.Record_SOA(mname=common_zone_name)
+    soa_record = dns.Record_SOA(mname=common_zone_name.encode('ascii'))
     test_domain_com = NoFileAuthority(
-        soa=(common_zone_name, soa_record),
+        soa=(common_zone_name.encode('ascii'), soa_record),
         records=all_records,
     )
     server = twisted.names.server.DNSServerFactory(
index e5a8ef2..5cb4d9d 100644 (file)
@@ -411,7 +411,7 @@ class Client {
   void MaybeStartRequests() {
     if (!started_requests_) {
       started_requests_ = true;
-      gpr_event_set(&start_requests_, (void*)1);
+      gpr_event_set(&start_requests_, reinterpret_cast<void*>(1));
     }
   }
 
@@ -566,11 +566,11 @@ class ClientImpl : public Client {
       create_stub_;
 };
 
-std::unique_ptr<Client> CreateSynchronousClient(const ClientConfig& args);
-std::unique_ptr<Client> CreateAsyncClient(const ClientConfig& args);
-std::unique_ptr<Client> CreateCallbackClient(const ClientConfig& args);
+std::unique_ptr<Client> CreateSynchronousClient(const ClientConfig& config);
+std::unique_ptr<Client> CreateAsyncClient(const ClientConfig& config);
+std::unique_ptr<Client> CreateCallbackClient(const ClientConfig& config);
 std::unique_ptr<Client> CreateGenericAsyncStreamingClient(
-    const ClientConfig& args);
+    const ClientConfig& config);
 
 }  // namespace testing
 }  // namespace grpc
index 28f73f7..2dec82a 100644 (file)
@@ -955,8 +955,8 @@ std::unique_ptr<Client> CreateAsyncClient(const ClientConfig& config) {
   }
 }
 std::unique_ptr<Client> CreateGenericAsyncStreamingClient(
-    const ClientConfig& args) {
-  return std::unique_ptr<Client>(new GenericAsyncStreamingClient(args));
+    const ClientConfig& config) {
+  return std::unique_ptr<Client>(new GenericAsyncStreamingClient(config));
 }
 
 }  // namespace testing
index bc8fdb5..d0d3d4c 100644 (file)
@@ -45,7 +45,7 @@ namespace testing {
  * Maintains context info per RPC
  */
 struct CallbackClientRpcContext {
-  CallbackClientRpcContext(BenchmarkService::Stub* stub)
+  explicit CallbackClientRpcContext(BenchmarkService::Stub* stub)
       : alarm_(nullptr), stub_(stub) {}
 
   ~CallbackClientRpcContext() {}
@@ -64,7 +64,7 @@ static std::unique_ptr<BenchmarkService::Stub> BenchmarkStubCreator(
 class CallbackClient
     : public ClientImpl<BenchmarkService::Stub, SimpleRequest> {
  public:
-  CallbackClient(const ClientConfig& config)
+  explicit CallbackClient(const ClientConfig& config)
       : ClientImpl<BenchmarkService::Stub, SimpleRequest>(
             config, BenchmarkStubCreator) {
     num_threads_ = NumThreads(config);
@@ -144,7 +144,8 @@ class CallbackClient
 
 class CallbackUnaryClient final : public CallbackClient {
  public:
-  CallbackUnaryClient(const ClientConfig& config) : CallbackClient(config) {
+  explicit CallbackUnaryClient(const ClientConfig& config)
+      : CallbackClient(config) {
     for (int ch = 0; ch < config.client_channels(); ch++) {
       for (int i = 0; i < config.outstanding_rpcs_per_channel(); i++) {
         ctx_.emplace_back(
@@ -214,7 +215,7 @@ class CallbackUnaryClient final : public CallbackClient {
 
 class CallbackStreamingClient : public CallbackClient {
  public:
-  CallbackStreamingClient(const ClientConfig& config)
+  explicit CallbackStreamingClient(const ClientConfig& config)
       : CallbackClient(config),
         messages_per_stream_(config.messages_per_stream()) {
     for (int ch = 0; ch < config.client_channels(); ch++) {
@@ -244,7 +245,7 @@ class CallbackStreamingClient : public CallbackClient {
 
 class CallbackStreamingPingPongClient : public CallbackStreamingClient {
  public:
-  CallbackStreamingPingPongClient(const ClientConfig& config)
+  explicit CallbackStreamingPingPongClient(const ClientConfig& config)
       : CallbackStreamingClient(config) {}
   ~CallbackStreamingPingPongClient() override {}
 };
@@ -342,7 +343,7 @@ class CallbackStreamingPingPongReactor final
 class CallbackStreamingPingPongClientImpl final
     : public CallbackStreamingPingPongClient {
  public:
-  CallbackStreamingPingPongClientImpl(const ClientConfig& config)
+  explicit CallbackStreamingPingPongClientImpl(const ClientConfig& config)
       : CallbackStreamingPingPongClient(config) {
     for (size_t i = 0; i < total_outstanding_rpcs_; i++) {
       reactor_.emplace_back(
index f042a03..72fff1a 100644 (file)
@@ -50,7 +50,7 @@ static std::unique_ptr<BenchmarkService::Stub> BenchmarkStubCreator(
 class SynchronousClient
     : public ClientImpl<BenchmarkService::Stub, SimpleRequest> {
  public:
-  SynchronousClient(const ClientConfig& config)
+  explicit SynchronousClient(const ClientConfig& config)
       : ClientImpl<BenchmarkService::Stub, SimpleRequest>(
             config, BenchmarkStubCreator) {
     num_threads_ =
@@ -111,7 +111,7 @@ class SynchronousClient
 
 class SynchronousUnaryClient final : public SynchronousClient {
  public:
-  SynchronousUnaryClient(const ClientConfig& config)
+  explicit SynchronousUnaryClient(const ClientConfig& config)
       : SynchronousClient(config) {
     StartThreads(num_threads_);
   }
@@ -143,7 +143,7 @@ class SynchronousUnaryClient final : public SynchronousClient {
 template <class StreamType>
 class SynchronousStreamingClient : public SynchronousClient {
  public:
-  SynchronousStreamingClient(const ClientConfig& config)
+  explicit SynchronousStreamingClient(const ClientConfig& config)
       : SynchronousClient(config),
         context_(num_threads_),
         stream_(num_threads_),
@@ -219,7 +219,7 @@ class SynchronousStreamingPingPongClient final
     : public SynchronousStreamingClient<
           grpc::ClientReaderWriter<SimpleRequest, SimpleResponse>> {
  public:
-  SynchronousStreamingPingPongClient(const ClientConfig& config)
+  explicit SynchronousStreamingPingPongClient(const ClientConfig& config)
       : SynchronousStreamingClient(config) {}
   ~SynchronousStreamingPingPongClient() override {
     CleanupAllStreams(
@@ -276,7 +276,7 @@ class SynchronousStreamingPingPongClient final
 class SynchronousStreamingFromClientClient final
     : public SynchronousStreamingClient<grpc::ClientWriter<SimpleRequest>> {
  public:
-  SynchronousStreamingFromClientClient(const ClientConfig& config)
+  explicit SynchronousStreamingFromClientClient(const ClientConfig& config)
       : SynchronousStreamingClient(config), last_issue_(num_threads_) {}
   ~SynchronousStreamingFromClientClient() override {
     CleanupAllStreams(
@@ -329,7 +329,7 @@ class SynchronousStreamingFromClientClient final
 class SynchronousStreamingFromServerClient final
     : public SynchronousStreamingClient<grpc::ClientReader<SimpleResponse>> {
  public:
-  SynchronousStreamingFromServerClient(const ClientConfig& config)
+  explicit SynchronousStreamingFromServerClient(const ClientConfig& config)
       : SynchronousStreamingClient(config), last_recv_(num_threads_) {}
   ~SynchronousStreamingFromServerClient() override {}
 
@@ -375,7 +375,7 @@ class SynchronousStreamingBothWaysClient final
     : public SynchronousStreamingClient<
           grpc::ClientReaderWriter<SimpleRequest, SimpleResponse>> {
  public:
-  SynchronousStreamingBothWaysClient(const ClientConfig& config)
+  explicit SynchronousStreamingBothWaysClient(const ClientConfig& config)
       : SynchronousStreamingClient(config) {}
   ~SynchronousStreamingBothWaysClient() override {
     CleanupAllStreams(
index 55c1984..e0057d1 100644 (file)
@@ -27,7 +27,7 @@ namespace testing {
 
 class Histogram {
  public:
-  // TODO: look into making histogram params not hardcoded for C++
+  // TODO(unknown): look into making histogram params not hardcoded for C++
   Histogram()
       : impl_(grpc_histogram_create(default_resolution(),
                                     default_max_possible())) {}
index 387813d..8777f17 100644 (file)
@@ -20,8 +20,6 @@
 
 #include <string>
 
-#include <google/protobuf/util/json_util.h>
-#include <google/protobuf/util/type_resolver_util.h>
 #include <grpc/support/log.h>
 
 namespace grpc {
@@ -29,17 +27,16 @@ namespace testing {
 
 void ParseJson(const std::string& json, const std::string& type,
                GRPC_CUSTOM_MESSAGE* msg) {
-  std::unique_ptr<google::protobuf::util::TypeResolver> type_resolver(
-      google::protobuf::util::NewTypeResolverForDescriptorPool(
-          "type.googleapis.com",
-          google::protobuf::DescriptorPool::generated_pool()));
+  std::unique_ptr<protobuf::json::TypeResolver> type_resolver(
+      protobuf::json::NewTypeResolverForDescriptorPool(
+          "type.googleapis.com", protobuf::DescriptorPool::generated_pool()));
   std::string binary;
   auto status = JsonToBinaryString(
       type_resolver.get(), "type.googleapis.com/" + type, json, &binary);
   if (!status.ok()) {
     std::string errmsg(status.error_message());
     gpr_log(GPR_ERROR, "Failed to convert json to binary: errcode=%d msg=%s",
-            status.error_code(), errmsg.c_str());
+            status.code(), errmsg.c_str());
     gpr_log(GPR_ERROR, "JSON: %s", json.c_str());
     abort();
   }
@@ -48,10 +45,9 @@ void ParseJson(const std::string& json, const std::string& type,
 
 std::string SerializeJson(const GRPC_CUSTOM_MESSAGE& msg,
                           const std::string& type) {
-  std::unique_ptr<google::protobuf::util::TypeResolver> type_resolver(
-      google::protobuf::util::NewTypeResolverForDescriptorPool(
-          "type.googleapis.com",
-          google::protobuf::DescriptorPool::generated_pool()));
+  std::unique_ptr<protobuf::json::TypeResolver> type_resolver(
+      protobuf::json::NewTypeResolverForDescriptorPool(
+          "type.googleapis.com", protobuf::DescriptorPool::generated_pool()));
   std::string binary;
   std::string json_string;
   msg.SerializeToString(&binary);
index 15a6f34..2084eb1 100644 (file)
@@ -59,6 +59,8 @@ def qps_json_driver_batch():
                 "qps_json_driver",
                 "no_mac",
             ],
+            # TODO(b/156975956): address OOMing benchmark tests
+            flaky = True,
         )
 
 def json_run_localhost_batch():
@@ -85,4 +87,6 @@ def json_run_localhost_batch():
                 "no_windows",
                 "no_mac",
             ],
+            # TODO(b/156975956): address OOMing benchmark tests
+            flaky = True,
         )
index 54a1b20..99c0e34 100644 (file)
@@ -157,7 +157,7 @@ class WorkerServiceImpl final : public WorkerService::Service {
   // Protect against multiple clients using this worker at once.
   class InstanceGuard {
    public:
-    InstanceGuard(WorkerServiceImpl* impl)
+    explicit InstanceGuard(WorkerServiceImpl* impl)
         : impl_(impl), acquired_(impl->TryAcquireInstance()) {}
     ~InstanceGuard() {
       if (acquired_) {
index b00b0a3..d85dea4 100644 (file)
@@ -37,7 +37,7 @@ namespace testing {
 class Reporter {
  public:
   /** Construct a reporter with the given \a name. */
-  Reporter(const string& name) : name_(name) {}
+  explicit Reporter(const string& name) : name_(name) {}
 
   virtual ~Reporter() {}
 
@@ -94,7 +94,7 @@ class CompositeReporter : public Reporter {
 /** Reporter to gpr_log(GPR_INFO). */
 class GprLogReporter : public Reporter {
  public:
-  GprLogReporter(const string& name) : Reporter(name) {}
+  explicit GprLogReporter(const string& name) : Reporter(name) {}
 
  private:
   void ReportQPS(const ScenarioResult& result) override;
index c2ccd8a..cb1972a 100644 (file)
@@ -63,6 +63,11 @@ grpc_cc_test(
 grpc_cc_test(
     name = "credentials_test",
     srcs = ["credentials_test.cc"],
+    data = [
+        "//src/core/tsi/test_creds:ca.pem",
+        "//src/core/tsi/test_creds:server1.key",
+        "//src/core/tsi/test_creds:server1.pem",
+    ],
     external_deps = [
         "gtest",
     ],
index 8e7fc17..3c8dcf7 100644 (file)
 #include "test/core/util/port.h"
 #include "test/core/util/test_config.h"
 
+#define CA_CERT_PATH "src/core/tsi/test_creds/ca.pem"
+#define SERVER_CERT_PATH "src/core/tsi/test_creds/server1.pem"
+#define SERVER_KEY_PATH "src/core/tsi/test_creds/server1.key"
+
 namespace {
 
 constexpr const char* kRootCertName = "root_cert_name";
@@ -35,6 +39,7 @@ constexpr const char* kIdentityCertName = "identity_cert_name";
 constexpr const char* kIdentityCertPrivateKey = "identity_private_key";
 constexpr const char* kIdentityCertContents = "identity_cert_contents";
 
+using ::grpc::experimental::FileWatcherCertificateProvider;
 using ::grpc::experimental::StaticDataCertificateProvider;
 
 }  // namespace
@@ -86,6 +91,38 @@ TEST(CredentialsTest,
   GPR_ASSERT(server_credentials.get() != nullptr);
 }
 
+TEST(
+    CredentialsTest,
+    TlsServerCredentialsWithFileWatcherCertificateProviderLoadingRootAndIdentity) {
+  auto certificate_provider = std::make_shared<FileWatcherCertificateProvider>(
+      SERVER_KEY_PATH, SERVER_CERT_PATH, CA_CERT_PATH, 1);
+  grpc::experimental::TlsServerCredentialsOptions options(certificate_provider);
+  options.watch_root_certs();
+  options.set_root_cert_name(kRootCertName);
+  options.watch_identity_key_cert_pairs();
+  options.set_identity_cert_name(kIdentityCertName);
+  options.set_cert_request_type(
+      GRPC_SSL_REQUEST_AND_REQUIRE_CLIENT_CERTIFICATE_AND_VERIFY);
+  auto server_credentials = grpc::experimental::TlsServerCredentials(options);
+  GPR_ASSERT(server_credentials.get() != nullptr);
+}
+
+// ServerCredentials should always have identity credential presented.
+// Otherwise gRPC stack will fail.
+TEST(
+    CredentialsTest,
+    TlsServerCredentialsWithFileWatcherCertificateProviderLoadingIdentityOnly) {
+  auto certificate_provider = std::make_shared<FileWatcherCertificateProvider>(
+      SERVER_KEY_PATH, SERVER_CERT_PATH, 1);
+  grpc::experimental::TlsServerCredentialsOptions options(certificate_provider);
+  options.watch_identity_key_cert_pairs();
+  options.set_identity_cert_name(kIdentityCertName);
+  options.set_cert_request_type(
+      GRPC_SSL_REQUEST_AND_REQUIRE_CLIENT_CERTIFICATE_AND_VERIFY);
+  auto server_credentials = grpc::experimental::TlsServerCredentials(options);
+  GPR_ASSERT(server_credentials.get() != nullptr);
+}
+
 }  // namespace
 }  // namespace testing
 }  // namespace grpc
index c7d4382..b0bedeb 100644 (file)
@@ -64,7 +64,7 @@ bool mock_socket_mutator_mutate_fd(int /*fd*/, grpc_socket_mutator* m) {
 
 int mock_socket_mutator_compare(grpc_socket_mutator* a,
                                 grpc_socket_mutator* b) {
-  return (uintptr_t)a - (uintptr_t)b;
+  return reinterpret_cast<uintptr_t>(a) - reinterpret_cast<uintptr_t>(b);
 }
 
 void mock_socket_mutator_destroy(grpc_socket_mutator* m) {
@@ -74,7 +74,8 @@ void mock_socket_mutator_destroy(grpc_socket_mutator* m) {
 
 class MockSocketMutatorServerBuilderOption : public grpc::ServerBuilderOption {
  public:
-  MockSocketMutatorServerBuilderOption(MockSocketMutator* mock_socket_mutator)
+  explicit MockSocketMutatorServerBuilderOption(
+      MockSocketMutator* mock_socket_mutator)
       : mock_socket_mutator_(mock_socket_mutator) {}
 
   void UpdateArguments(ChannelArguments* args) override {
index 4b30de3..eaff051 100644 (file)
@@ -65,7 +65,7 @@ TEST(ServerRequestCallTest, ShortDeadlineDoesNotCauseOkayFalse) {
         std::lock_guard<std::mutex> lock(mu);
         if (!shutting_down) {
           service.RequestEcho(&ctx, &req, &responder, cq.get(), cq.get(),
-                              (void*)1);
+                              reinterpret_cast<void*>(1));
         }
       }
 
@@ -106,7 +106,8 @@ TEST(ServerRequestCallTest, ShortDeadlineDoesNotCauseOkayFalse) {
           continue;
         }
         gpr_log(GPR_INFO, "Finishing request %d", n);
-        responder.Finish(response, grpc::Status::OK, (void*)2);
+        responder.Finish(response, grpc::Status::OK,
+                         reinterpret_cast<void*>(2));
         if (!cq->Next(&tag, &ok)) {
           break;
         }
@@ -137,7 +138,7 @@ TEST(ServerRequestCallTest, ShortDeadlineDoesNotCauseOkayFalse) {
     ctx.set_deadline(std::chrono::system_clock::now() +
                      std::chrono::milliseconds(1));
     grpc::Status status = stub->Echo(&ctx, request, &response);
-    EXPECT_EQ(DEADLINE_EXCEEDED, status.error_code());
+    EXPECT_EQ(StatusCode::DEADLINE_EXCEEDED, status.error_code());
     gpr_log(GPR_INFO, "Success.");
   }
   gpr_log(GPR_INFO, "Done sending RPCs.");
index efd01e7..89d82c6 100644 (file)
@@ -155,8 +155,8 @@ TEST(ChannelzSamplerTest, SimpleTest) {
     GPR_ASSERT(0);
   }
   delete test_driver;
-  gpr_event_set(&done_ev1, (void*)1);
-  gpr_event_set(&done_ev2, (void*)1);
+  gpr_event_set(&done_ev1, reinterpret_cast<void*>(1));
+  gpr_event_set(&done_ev2, reinterpret_cast<void*>(1));
   client_thread_1.join();
   client_thread_2.join();
 }
index 30f3c1d..34def7a 100644 (file)
@@ -32,7 +32,7 @@
 namespace grpc {
 namespace testing {
 namespace {
-void* tag(int i) { return (void*)static_cast<intptr_t>(i); }
+void* tag(intptr_t t) { return reinterpret_cast<void*>(t); }
 }  // namespace
 
 Status CliCall::Call(const std::shared_ptr<grpc::Channel>& channel,
index 4541919..a1b275a 100644 (file)
@@ -88,7 +88,7 @@ int main(int argc, char** argv) {
   grpc::testing::InitTest(&argc, &argv, true);
 
   return grpc::testing::GrpcToolMainLib(
-      argc, (const char**)argv, grpc::testing::CliCredentials(),
+      argc, const_cast<const char**>(argv), grpc::testing::CliCredentials(),
       std::bind(SimplePrint, absl::GetFlag(FLAGS_outfile),
                 std::placeholders::_1));
 }
index 0ad20eb..0c73135 100644 (file)
@@ -280,7 +280,7 @@ void Usage(const std::string& msg) {
 }
 
 const Command* FindCommand(const std::string& name) {
-  for (int i = 0; i < (int)ArraySize(ops); i++) {
+  for (int i = 0; i < static_cast<int>(ArraySize(ops)); i++) {
     if (name == ops[i].command) {
       return &ops[i];
     }
index bf4eeaf..7cd2751 100644 (file)
@@ -133,7 +133,7 @@ const int kServerDefaultResponseStreamsToSend = 3;
 
 class TestCliCredentials final : public grpc::testing::CliCredentials {
  public:
-  TestCliCredentials(bool secure = false) : secure_(secure) {}
+  explicit TestCliCredentials(bool secure = false) : secure_(secure) {}
   std::shared_ptr<grpc::ChannelCredentials> GetChannelCredentials()
       const override {
     if (!secure_) {
index 0fe56d4..d75de16 100644 (file)
@@ -29,7 +29,7 @@ namespace grpc {
 
 class SubProcess {
  public:
-  SubProcess(const std::vector<std::string>& args);
+  explicit SubProcess(const std::vector<std::string>& args);
   ~SubProcess();
 
   int Join();
index 646875b..272d239 100644 (file)
@@ -11,4 +11,5 @@ exports_files([
     "enum34.BUILD",
     "futures.BUILD",
     "libuv.BUILD",
+    "protobuf.patch",
 ])
index 616030b..7939021 100644 (file)
@@ -11,6 +11,16 @@ config_setting(
 )
 
 config_setting(
+    name = "darwin_arm64",
+    values = {"cpu": "darwin_arm64"},
+)
+
+config_setting(
+    name = "darwin_arm64e",
+    values = {"cpu": "darwin_arm64e"},
+)
+
+config_setting(
     name = "windows",
     values = {"cpu": "x64_windows"},
 )
@@ -99,6 +109,8 @@ copy_file(
         ":watchos_arm64_32": "@com_github_grpc_grpc//third_party/cares:config_darwin/ares_config.h",
         ":darwin": "@com_github_grpc_grpc//third_party/cares:config_darwin/ares_config.h",
         ":darwin_x86_64": "@com_github_grpc_grpc//third_party/cares:config_darwin/ares_config.h",
+        ":darwin_arm64": "@com_github_grpc_grpc//third_party/cares:config_darwin/ares_config.h",
+        ":darwin_arm64e": "@com_github_grpc_grpc//third_party/cares:config_darwin/ares_config.h",
         ":windows": "@com_github_grpc_grpc//third_party/cares:config_windows/ares_config.h",
         ":android": "@com_github_grpc_grpc//third_party/cares:config_android/ares_config.h",
         "//conditions:default": "@com_github_grpc_grpc//third_party/cares:config_linux/ares_config.h",
diff --git a/third_party/protobuf.patch b/third_party/protobuf.patch
new file mode 100644 (file)
index 0000000..0b302e4
--- /dev/null
@@ -0,0 +1,14 @@
+diff --git a/python/google/protobuf/__init__.py b/python/google/protobuf/__init__.py
+index 97ac28028..8b7585d9d 100644
+--- a/python/google/protobuf/__init__.py
++++ b/python/google/protobuf/__init__.py
+@@ -31,3 +31,9 @@
+ # Copyright 2007 Google Inc. All Rights Reserved.
+
+ __version__ = '3.14.0'
++
++if __name__ != '__main__':
++  try:
++    __import__('pkg_resources').declare_namespace(__name__)
++  except ImportError:
++    __path__ = __import__('pkgutil').extend_path(__path__, __name__)
diff --git a/third_party/rake-compiler-dock/README.md b/third_party/rake-compiler-dock/README.md
deleted file mode 100644 (file)
index d003c7a..0000000
+++ /dev/null
@@ -1,46 +0,0 @@
-rake-compiler-dock for gRPC
-===================================
-
-This has customized docker images for Ruby based on
-[rake-compiler-dock](https://github.com/rake-compiler/rake-compiler-dock).
-gRPC needs four docker images to build Ruby artifacts;
-
-- rake_x64-linux: Linux / 32bit
-- rake_x86_64-linux: Linux / 64bit
-- rake_x86-mingw32: Windows / 32bit
-- rake_x64-mingw32: Windows / 64bit
-
-### Customization
-
-#### Linux
-
-The linux docker images of `rake-compiler-dock` are based on Ubuntu, which is enough for
-most cases but it becomes hard to keep it compataible for some conservative Linux distrubitions
-such as CentOS 6 because Ubuntu uses more modern libraries than them.
-As a result, generated artifacts sometimes cannot run on CentOS 6 due to missing dependencies. 
-This can be easily addressed by using CentOS 6 based docker images such as 
-[dockcross manylinux2010](https://github.com/dockcross/dockcross), which was invented
-to handle the very same problem of Python. By using the same solution, 
-Ruby can have the simple way of building more portable artifacts.
-This idea is summarized in
-[rake-compiler-dock#33](https://github.com/rake-compiler/rake-compiler-dock/issues/33).
-
-These two new docker images; `rake_x64-linux` and `rake_x86_64-linux` are based on 
-[Dockerfile.mri.erb](https://github.com/rake-compiler/rake-compiler-dock/blob/master/Dockerfile.mri.erb)
-with following customizations;
-
-- Changing the base image from `ubuntu:16.04` to `dockcross/manylinux2010`
-- Removing rvm account due to the complexity of having the same thing on `manylinux2010`
-  (mainly due to the limit of `gosu` handling groups)
-- Removing cross compiling setup for x86 because `manylinux2010-x86` already did it. 
-  (like cross compilers for x86 and mk_i686)
-- Removing glibc hack because `manylinux2010` doesn't needit.
-- Adding `patchelf_gem.sh` to trim the unnecessary dependency of `libcrypt.so.2`. 
-  Without this, artifacts for Ruby 2.3 to 2.5 happens to have a `libcrypt.so.2` link although
-  it doesn't have any external symbols from it.
-
-#### Windows
-
-Windows docker images are almost identical to `rake-compiler-dock` but with some exception;
-
-- Renaming `gettimeofday` to `rb_gettimeofday` in `win32.h`
diff --git a/third_party/rake-compiler-dock/build/patchelf_gem.sh b/third_party/rake-compiler-dock/build/patchelf_gem.sh
deleted file mode 100755 (executable)
index 8ce70ae..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-#/bin/bash
-set -ex
-
-if [ -z $1 ] ; then
-  echo "Gem file needed!" && exit 1;
-fi
-
-GEM=$1
-GEM_FILENAME=$(basename -- "$GEM")
-GEM_NAME="${GEM_FILENAME%.gem}"
-
-# Extract all files onto a temporary directory
-TMPDIR=$(mktemp -d -t gem-XXXXXXXXXX)
-gem unpack $GEM --target=$TMPDIR
-gem spec $GEM --ruby > ${TMPDIR}/${GEM_NAME}/${GEM_NAME}.gemspec
-
-# Run patchelf to all so files to strip out unnecessary libcrypt.so.2 dependency
-find $TMPDIR/${GEM_NAME} -name "*.so" \
-    -printf '%p\n' \
-    -exec patchelf --remove-needed libcrypt.so.2 {} \;
-
-# Rebuild the gem again with modified so files
-pushd $TMPDIR/${GEM_NAME}
-gem build ${GEM_NAME}.gemspec
-popd
-
-# Keep the new result
-mv $TMPDIR/${GEM_NAME}/${GEM_NAME}.gem $GEM
-
-rm -rf $TMPDIR
diff --git a/third_party/rake-compiler-dock/build/patches/ruby-2.5.7/no_sendfile.patch b/third_party/rake-compiler-dock/build/patches/ruby-2.5.7/no_sendfile.patch
deleted file mode 100644 (file)
index 77f7600..0000000
+++ /dev/null
@@ -1,24 +0,0 @@
-diff --git a/configure b/configure
-index ebe3d8c..a336b73 100755
---- a/configure
-+++ b/configure
-@@ -18943,7 +18943,6 @@ do :
-   ac_fn_c_check_func "$LINENO" "sendfile" "ac_cv_func_sendfile"
- if test "x$ac_cv_func_sendfile" = xyes; then :
-   cat >>confdefs.h <<_ACEOF
--#define HAVE_SENDFILE 1
- _ACEOF
-
- fi
-diff --git a/io.c b/io.c
-index 82c5940538..a8d3661ec8 100644
---- a/io.c
-+++ b/io.c
-@@ -10721,7 +10721,6 @@ nogvl_copy_stream_wait_write(struct copy_stream_struct *stp)
- }
-
- #if defined HAVE_COPY_FILE_RANGE || (defined __linux__ && defined __NR_copy_file_range)
--#  define USE_COPY_FILE_RANGE
- #endif
-
- #ifdef USE_COPY_FILE_RANGE
diff --git a/third_party/rake-compiler-dock/build/patches/ruby-2.7.0/no_sendfile.patch b/third_party/rake-compiler-dock/build/patches/ruby-2.7.0/no_sendfile.patch
deleted file mode 100644 (file)
index 77f7600..0000000
+++ /dev/null
@@ -1,24 +0,0 @@
-diff --git a/configure b/configure
-index ebe3d8c..a336b73 100755
---- a/configure
-+++ b/configure
-@@ -18943,7 +18943,6 @@ do :
-   ac_fn_c_check_func "$LINENO" "sendfile" "ac_cv_func_sendfile"
- if test "x$ac_cv_func_sendfile" = xyes; then :
-   cat >>confdefs.h <<_ACEOF
--#define HAVE_SENDFILE 1
- _ACEOF
-
- fi
-diff --git a/io.c b/io.c
-index 82c5940538..a8d3661ec8 100644
---- a/io.c
-+++ b/io.c
-@@ -10721,7 +10721,6 @@ nogvl_copy_stream_wait_write(struct copy_stream_struct *stp)
- }
-
- #if defined HAVE_COPY_FILE_RANGE || (defined __linux__ && defined __NR_copy_file_range)
--#  define USE_COPY_FILE_RANGE
- #endif
-
- #ifdef USE_COPY_FILE_RANGE
diff --git a/third_party/rake-compiler-dock/build/patches2/hoe-3.20.0/0001-Load-encrypted-private-key-using-ENV-GEM_PRIVATE_KEY.patch b/third_party/rake-compiler-dock/build/patches2/hoe-3.20.0/0001-Load-encrypted-private-key-using-ENV-GEM_PRIVATE_KEY.patch
deleted file mode 100644 (file)
index 45a1724..0000000
+++ /dev/null
@@ -1,32 +0,0 @@
-From ecc5669223457ceaba6bd94c2947ae99ddfa8f10 Mon Sep 17 00:00:00 2001
-From: Lars Kanis <lars@greiz-reinsdorf.de>
-Date: Fri, 27 Dec 2019 15:57:07 +0100
-Subject: [PATCH] Load encrypted private key using
- ENV['GEM_PRIVATE_KEY_PASSPHRASE'] as passphrase.
-
-This way the password can be avoided to be entered several times when building multiple gems.
-It also allows parallel builds which are incompatible to interactive password prompts.
-
-The same feature has been implemented in rubygems:
-  https://github.com/rubygems/rubygems/commit/c1a114396fcec124d3feabf74708b4bdec02eac3
----
- lib/hoe/signing.rb | 3 ++-
- 1 file changed, 2 insertions(+), 1 deletion(-)
-
-diff --git a/lib/hoe/signing.rb b/lib/hoe/signing.rb
-index 4833c55..11c8c2f 100644
---- a/lib/hoe/signing.rb
-+++ b/lib/hoe/signing.rb
-@@ -70,7 +70,8 @@ module Hoe::Signing
-     end
-
-     if signing_key and cert_chain then
--      spec.signing_key = OpenSSL::PKey::RSA.new File.read signing_key
-+      passphrase = ENV['GEM_PRIVATE_KEY_PASSPHRASE']
-+      spec.signing_key = OpenSSL::PKey::RSA.new(File.read(signing_key), passphrase)
-       spec.cert_chain = cert_chain
-     end
-   end
---
-2.20.1
-
diff --git a/third_party/rake-compiler-dock/build/patches2/rake-compiler-1.1.0/0001-Fix-determining-of-ruby-versions-in-rake-native-gem.patch b/third_party/rake-compiler-dock/build/patches2/rake-compiler-1.1.0/0001-Fix-determining-of-ruby-versions-in-rake-native-gem.patch
deleted file mode 100644 (file)
index eff68a9..0000000
+++ /dev/null
@@ -1,44 +0,0 @@
-From 365843bfe0bfc3f1c1b11e81e24ac7b6c7942bdf Mon Sep 17 00:00:00 2001
-From: Lars Kanis <lars@greiz-reinsdorf.de>
-Date: Fri, 27 Dec 2019 18:18:59 +0100
-Subject: [PATCH] Fix determining of ruby versions in "rake native gem"
-
-"rake native gem" without "cross" didn't set the ruby version constraint.
-Instead it failed with NoMethodError like so:
-
-/ffi $ rake native gem
-no configuration section for specified version of Ruby (rbconfig-i386-mingw32-2.6.3)
-no configuration section for specified version of Ruby (rbconfig-x64-mingw32-2.6.3)
-install -c build/x86_64-linux/ffi_c/2.6.3/ffi_c.so lib/ffi_c.so
-cp build/x86_64-linux/ffi_c/2.6.3/ffi_c.so build/x86_64-linux/stage/lib/ffi_c.so
-rake aborted!
-NoMethodError: undefined method `split' for nil:NilClass
-/home/lars/.rvm/gems/ruby-2.6.3/gems/rake-compiler-1.0.9/lib/rake/extensiontask.rb:515:in `ruby_api_version'
-/home/lars/.rvm/gems/ruby-2.6.3/gems/rake-compiler-1.0.9/lib/rake/extensiontask.rb:262:in `block in define_native_tasks'
-/home/lars/.rvm/gems/ruby-2.6.3/gems/rake-12.3.3/exe/rake:27:in `<top (required)>'
-/home/lars/.rvm/gems/ruby-2.6.3/bin/ruby_executable_hooks:24:in `eval'
-/home/lars/.rvm/gems/ruby-2.6.3/bin/ruby_executable_hooks:24:in `<main>'
-Tasks: TOP => native => native:x86_64-linux => native:ffi:x86_64-linux
-(See full trace by running task with --trace)
----
- lib/rake/extensiontask.rb | 4 ++++
- 1 file changed, 4 insertions(+)
-
-diff --git a/lib/rake/extensiontask.rb b/lib/rake/extensiontask.rb
-index d85b1a3..cb1ea12 100644
---- a/lib/rake/extensiontask.rb
-+++ b/lib/rake/extensiontask.rb
-@@ -242,6 +242,10 @@ Java extension should be preferred.
-       # lib_path
-       lib_path = lib_dir
-
-+      # Update compiled platform/version combinations
-+      ruby_versions = (@ruby_versions_per_platform[platf] ||= [])
-+      ruby_versions << ruby_ver
-+
-       # create 'native:gem_name' and chain it to 'native' task
-       unless Rake::Task.task_defined?("native:#{@gem_spec.name}:#{platf}")
-         task "native:#{@gem_spec.name}:#{platf}" do |t|
---
-2.20.1
-
diff --git a/third_party/rake-compiler-dock/build/patches2/rake-compiler-1.1.0/0001-cross-ruby-remove-needless-Makefile.in-preparation.patch b/third_party/rake-compiler-dock/build/patches2/rake-compiler-1.1.0/0001-cross-ruby-remove-needless-Makefile.in-preparation.patch
deleted file mode 100644 (file)
index 3f2d97e..0000000
+++ /dev/null
@@ -1,64 +0,0 @@
-From d76da276ba556bdefdddcc775b7f7907b8e1273e Mon Sep 17 00:00:00 2001
-From: Sutou Kouhei <kou@clear-code.com>
-Date: Wed, 25 Dec 2019 06:28:56 +0900
-Subject: [PATCH 1/5] cross-ruby: remove needless Makefile.in preparation
-
-ALT_SEPARATOR doesn't exist in Makefile.in since Ruby 1.9.2:
-https://github.com/ruby/ruby/commit/7c7690045870396816624bf57775eb29e6a478fd
----
- tasks/bin/cross-ruby.rake | 32 +-------------------------------
- 1 file changed, 1 insertion(+), 31 deletions(-)
-
-diff --git a/tasks/bin/cross-ruby.rake b/tasks/bin/cross-ruby.rake
-index 37dd220..c9b0bbb 100644
---- a/tasks/bin/cross-ruby.rake
-+++ b/tasks/bin/cross-ruby.rake
-@@ -96,36 +96,6 @@ file source_dir => ["#{USER_HOME}/sources/#{source_file}"] do |t|
-   end
- end
--# backup makefile.in
--if RUBY_CC_VERSION >= "ruby-2.7.0"
--  makefile_in = "#{source_dir}/template/Makefile.in"
--else
--  makefile_in = "#{source_dir}/Makefile.in"
--end
--makefile_in_bak = "#{makefile_in}.bak"
--file makefile_in_bak => [source_dir] do |t|
--  cp makefile_in, makefile_in_bak
--end
--
--# correct the makefiles
--file makefile_in => [makefile_in_bak] do |t|
--  content = File.open(makefile_in_bak, 'rb') { |f| f.read }
--
--  out = ""
--
--  content.each_line do |line|
--    if line =~ /^\s*ALT_SEPARATOR =/
--      out << "\t\t    ALT_SEPARATOR = \"\\\\\\\\\"; \\\n"
--    else
--      out << line
--    end
--  end
--
--  when_writing("Patching Makefile.in") {
--    File.open(makefile_in, 'wb') { |f| f.write(out) }
--  }
--end
--
- task :mingw32 do
-   unless MINGW_HOST then
-     warn "You need to install mingw32 cross compile functionality to be able to continue."
-@@ -135,7 +105,7 @@ task :mingw32 do
- end
- # generate the makefile in a clean build location
--file "#{build_dir}/Makefile" => [build_dir, makefile_in] do |t|
-+file "#{build_dir}/Makefile" => [build_dir, source_dir] do |t|
-   options = [
-     "--host=#{MINGW_HOST}",
--- 
-2.20.1
-
diff --git a/third_party/rake-compiler-dock/build/patches2/rake-compiler-1.1.0/0002-Extend-mingw-search-pattern-to-find-x86_64-gcc.patch b/third_party/rake-compiler-dock/build/patches2/rake-compiler-1.1.0/0002-Extend-mingw-search-pattern-to-find-x86_64-gcc.patch
deleted file mode 100644 (file)
index 12ece02..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-From 07b1a4909fa59324d309bb8a46867cacba97cafd Mon Sep 17 00:00:00 2001
-From: Lars Kanis <lars@greiz-reinsdorf.de>
-Date: Thu, 26 Dec 2019 18:31:25 +0100
-Subject: [PATCH] Extend mingw search pattern to find x86_64 gcc
-
-The previous pattern only recognized 32 bit compiler versions.
----
- lib/rake/extensioncompiler.rb | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/lib/rake/extensioncompiler.rb b/lib/rake/extensioncompiler.rb
-index b3d336b..75f4694 100644
---- a/lib/rake/extensioncompiler.rb
-+++ b/lib/rake/extensioncompiler.rb
-@@ -37,7 +37,7 @@ module Rake
-       paths = ENV['PATH'].split(File::PATH_SEPARATOR)
-       # the pattern to look into (captures *nix and windows executables)
--      pattern = "{mingw32-,i?86*mingw*}gcc{,.*}"
-+      pattern = "{mingw32-,i?86*mingw*,x86*mingw*}gcc{,.*}"
-       @mingw_gcc_executable = paths.find do |path|
-         # cleanup paths before globbing
--- 
-2.20.1
-
diff --git a/third_party/rake-compiler-dock/build/patches2/rake-compiler-1.1.0/0002-Strip-cross-built-shared-library-files-while-linking.patch b/third_party/rake-compiler-dock/build/patches2/rake-compiler-1.1.0/0002-Strip-cross-built-shared-library-files-while-linking.patch
deleted file mode 100644 (file)
index 9d02166..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-From 13e33405d4e51a52402e1e37e7e2df7f1f32892d Mon Sep 17 00:00:00 2001
-From: Lars Kanis <lars@greiz-reinsdorf.de>
-Date: Thu, 26 Dec 2019 19:18:02 +0100
-Subject: [PATCH 2/2] Strip cross built shared library files while linking
-
-The .so files of extensions are often stripped after compilation per task in a Rakefile.
-However this can be omitted, if the cross ruby version is built with stripping enabled.
-Stripping the files a second time doesn't make a difference then.
----
- tasks/bin/cross-ruby.rake | 3 ++-
- 1 file changed, 2 insertions(+), 1 deletion(-)
-
-diff --git a/tasks/bin/cross-ruby.rake b/tasks/bin/cross-ruby.rake
-index 2a73be7..a9eb16b 100644
---- a/tasks/bin/cross-ruby.rake
-+++ b/tasks/bin/cross-ruby.rake
-@@ -115,7 +115,8 @@ file "#{build_dir}/Makefile" => [build_dir, source_dir] do |t|
-     "--build=#{RUBY_BUILD}",
-     '--enable-shared',
-     '--disable-install-doc',
--    '--with-ext='
-+    '--with-ext=',
-+    'LDFLAGS=-pipe -s',
-   ]
-   # Force Winsock2 for Ruby 1.8, 1.9 defaults to it
--- 
-2.20.1
-
diff --git a/third_party/rake-compiler-dock/build/patches2/rake-compiler-1.1.0/0003-Allow-building-of-cross-rubies-in-parallel.patch b/third_party/rake-compiler-dock/build/patches2/rake-compiler-1.1.0/0003-Allow-building-of-cross-rubies-in-parallel.patch
deleted file mode 100644 (file)
index d715324..0000000
+++ /dev/null
@@ -1,214 +0,0 @@
-From 01fd7364bdcb37ac8709ffa48388b5cbe6478211 Mon Sep 17 00:00:00 2001
-From: Lars Kanis <lars@greiz-reinsdorf.de>
-Date: Fri, 10 Jan 2020 23:57:18 +0100
-Subject: [PATCH] Allow building of cross rubies in parallel
-
-Rubies can be build like so:
-  rake-compiler cross-ruby VERSION=2.7.0:2.6.0 HOST=x86_64-w64-mingw32:i686-w64-mingw32
-
-This builds the cross product of all ":" separated ruby and host versions.
-To force sequential builds add option "-j1".
----
- tasks/bin/cross-ruby.rake | 161 +++++++++++++++++++-------------------
- 1 file changed, 80 insertions(+), 81 deletions(-)
-
-diff --git a/tasks/bin/cross-ruby.rake b/tasks/bin/cross-ruby.rake
-index 278541c..8b88025 100644
---- a/tasks/bin/cross-ruby.rake
-+++ b/tasks/bin/cross-ruby.rake
-@@ -41,106 +41,105 @@ end
- require 'rake/extensioncompiler'
- MAKE = ENV['MAKE'] || %w[gmake make].find { |c| system("#{c} -v > /dev/null 2>&1") }
--USER_HOME = File.expand_path("~/.rake-compiler")
--RUBY_CC_VERSION = "ruby-" << ENV.fetch("VERSION", "1.8.7-p371")
-+USER_HOME = File.realpath(File.expand_path("~/.rake-compiler"))
- RUBY_SOURCE = ENV['SOURCE']
- RUBY_BUILD = RbConfig::CONFIG["host"]
--# grab the major "1.8" or "1.9" part of the version number
--MAJOR = RUBY_CC_VERSION.match(/.*-(\d.\d).\d/)[1]
--
--# Use Rake::ExtensionCompiler helpers to find the proper host
--MINGW_HOST = ENV['HOST'] || Rake::ExtensionCompiler.mingw_host
--MINGW_TARGET = MINGW_HOST.gsub('msvc', '')
--
- # Unset any possible variable that might affect compilation
- ["CC", "CXX", "CPPFLAGS", "LDFLAGS", "RUBYOPT"].each do |var|
-   ENV.delete(var)
- end
--source_dir = "#{USER_HOME}/sources/#{RUBY_CC_VERSION}"
--build_dir = "#{USER_HOME}/builds/#{MINGW_HOST}/#{RUBY_CC_VERSION}"
--
--# define a location where sources will be stored
--directory source_dir
--directory build_dir
--
--# clean intermediate files and folders
--CLEAN.include(source_dir)
--CLEAN.include(build_dir)
--
--# remove the final products and sources
--CLOBBER.include("#{USER_HOME}/sources")
--CLOBBER.include("#{USER_HOME}/builds")
--CLOBBER.include("#{USER_HOME}/ruby/#{MINGW_HOST}/#{RUBY_CC_VERSION}")
--CLOBBER.include("#{USER_HOME}/config.yml")
-+RUBY_CC_VERSIONS = ENV.fetch("VERSION", "1.8.7-p371")
-+RUBY_CC_VERSIONS.split(":").each do |ruby_cc_version|
-+  ruby_cc_version = "ruby-" + ruby_cc_version
-+  # grab the major "1.8" or "1.9" part of the version number
-+  major = ruby_cc_version.match(/.*-(\d.\d).\d/)[1]
-+
-+  # define a location where sources will be stored
-+  source_dir = "#{USER_HOME}/sources/#{ruby_cc_version}"
-+  directory source_dir
-+  # clean intermediate files and folders
-+  CLEAN.include(source_dir)
-+
-+  # remove the final products and sources
-+  CLOBBER.include("#{USER_HOME}/sources")
-+  CLOBBER.include("#{USER_HOME}/builds")
-+  CLOBBER.include("#{USER_HOME}/config.yml")
-+
-+  # Extract the sources
-+  source_file = RUBY_SOURCE ? RUBY_SOURCE.split('/').last : "#{ruby_cc_version}.tar.bz2"
-+  file source_dir => ["#{USER_HOME}/sources/#{source_file}"] do |t|
-+    t.prerequisites.each { |f| sh "tar xf #{File.basename(f)}", chdir: File.dirname(t.name) }
-+  end
--# ruby source file should be stored there
--file "#{USER_HOME}/sources/#{RUBY_CC_VERSION}.tar.bz2" => ["#{USER_HOME}/sources"] do |t|
--  # download the source file using wget or curl
--  chdir File.dirname(t.name) do
-+  # ruby source file should be stored there
-+  file "#{USER_HOME}/sources/#{ruby_cc_version}.tar.bz2" => ["#{USER_HOME}/sources"] do |t|
-+    # download the source file using wget or curl
-     if RUBY_SOURCE
-       url = RUBY_SOURCE
-     else
--      url = "http://cache.ruby-lang.org/pub/ruby/#{MAJOR}/#{File.basename(t.name)}"
-+      url = "http://cache.ruby-lang.org/pub/ruby/#{major}/#{File.basename(t.name)}"
-     end
--    sh "wget #{url} || curl -O #{url}"
-+    sh "wget #{url} || curl -O #{url}", chdir: File.dirname(t.name)
-   end
--end
--
--# Extract the sources
--source_file = RUBY_SOURCE ? RUBY_SOURCE.split('/').last : "#{RUBY_CC_VERSION}.tar.bz2"
--file source_dir => ["#{USER_HOME}/sources/#{source_file}"] do |t|
--  chdir File.dirname(t.name) do
--    t.prerequisites.each { |f| sh "tar xf #{File.basename(f)}" }
--  end
--end
--task :mingw32 do
--  unless MINGW_HOST then
--    warn "You need to install mingw32 cross compile functionality to be able to continue."
--    warn "Please refer to your distribution/package manager documentation about installation."
--    fail
--  end
--end
-+  # Create tasks for each host out of the ":" separated hosts list in the HOST variable.
-+  # These tasks are processed in parallel as dependencies to the "install" task.
-+  mingw_hosts = ENV['HOST'] || Rake::ExtensionCompiler.mingw_host
-+  mingw_hosts.split(":").each do |mingw_host|
-+
-+    # Use Rake::ExtensionCompiler helpers to find the proper host
-+    mingw_target = mingw_host.gsub('msvc', '')
-+
-+    # define a location where built files for each host will be stored
-+    build_dir = "#{USER_HOME}/builds/#{mingw_host}/#{ruby_cc_version}"
-+    directory build_dir
-+    install_dir = "#{USER_HOME}/ruby/#{mingw_host}/#{ruby_cc_version}"
-+
-+    # clean intermediate files and folders
-+    CLEAN.include(build_dir)
-+    CLOBBER.include(install_dir)
-+
-+    task :mingw32 do
-+      unless mingw_host then
-+        warn "You need to install mingw32 cross compile functionality to be able to continue."
-+        warn "Please refer to your distribution/package manager documentation about installation."
-+        fail
-+      end
-+    end
--# generate the makefile in a clean build location
--file "#{build_dir}/Makefile" => [build_dir, source_dir] do |t|
--
--  options = [
--    "--host=#{MINGW_HOST}",
--    "--target=#{MINGW_TARGET}",
--    "--build=#{RUBY_BUILD}",
--    '--enable-shared',
--    '--disable-install-doc',
--    '--with-ext=',
--    'LDFLAGS=-pipe -s',
--  ]
--
--  # Force Winsock2 for Ruby 1.8, 1.9 defaults to it
--  options << "--with-winsock2" if MAJOR == "1.8"
--
--  chdir File.dirname(t.name) do
--    prefix = File.expand_path("../../../ruby/#{MINGW_HOST}/#{RUBY_CC_VERSION}")
--    options << "--prefix=#{prefix}"
--    sh File.expand_path("../../../sources/#{RUBY_CC_VERSION}/configure"), *options
--  end
--end
-+    # generate the makefile in a clean build location
-+    file "#{build_dir}/Makefile" => [build_dir, source_dir] do |t|
-+
-+      options = [
-+        "--host=#{mingw_host}",
-+        "--target=#{mingw_target}",
-+        "--build=#{RUBY_BUILD}",
-+        '--enable-shared',
-+        '--disable-install-doc',
-+        '--with-ext=',
-+        'LDFLAGS=-pipe -s',
-+      ]
-+
-+      # Force Winsock2 for Ruby 1.8, 1.9 defaults to it
-+      options << "--with-winsock2" if major == "1.8"
-+      options << "--prefix=#{install_dir}"
-+      sh File.expand_path("#{USER_HOME}/sources/#{ruby_cc_version}/configure"), *options, chdir: File.dirname(t.name)
-+    end
--# make
--file "#{build_dir}/ruby.exe" => ["#{build_dir}/Makefile"] do |t|
--  chdir File.dirname(t.prerequisites.first) do
--    sh MAKE
--  end
--end
-+    # make
-+    file "#{build_dir}/ruby.exe" => ["#{build_dir}/Makefile"] do |t|
-+      sh MAKE, chdir: File.dirname(t.prerequisites.first)
-+    end
--# make install
--file "#{USER_HOME}/ruby/#{MINGW_HOST}/#{RUBY_CC_VERSION}/bin/ruby.exe" => ["#{build_dir}/ruby.exe"] do |t|
--  chdir File.dirname(t.prerequisites.first) do
--    sh "#{MAKE} install"
-+    # make install
-+    file "#{USER_HOME}/ruby/#{mingw_host}/#{ruby_cc_version}/bin/ruby.exe" => ["#{build_dir}/ruby.exe"] do |t|
-+      sh "#{MAKE} install", chdir: File.dirname(t.prerequisites.first)
-+    end
-+    multitask :install => ["#{USER_HOME}/ruby/#{mingw_host}/#{ruby_cc_version}/bin/ruby.exe"]
-   end
- end
--task :install => ["#{USER_HOME}/ruby/#{MINGW_HOST}/#{RUBY_CC_VERSION}/bin/ruby.exe"]
- desc "Update rake-compiler list of installed Ruby versions"
- task 'update-config' do
-@@ -187,5 +186,5 @@ task :default do
-   Rake.application.display_tasks_and_comments
- end
--desc "Build #{RUBY_CC_VERSION} suitable for cross-platform development."
-+desc "Build rubies suitable for cross-platform development."
- task 'cross-ruby' => [:mingw32, :install, 'update-config']
--- 
-2.20.1
-
diff --git a/third_party/rake-compiler-dock/build/patches2/rake-compiler-1.1.0/0004-Enable-build-of-static-libruby.patch b/third_party/rake-compiler-dock/build/patches2/rake-compiler-1.1.0/0004-Enable-build-of-static-libruby.patch
deleted file mode 100644 (file)
index 3d3a9f8..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-From 0b929b7027eb592c0971a400184f1dfa5a0bce7c Mon Sep 17 00:00:00 2001
-From: Lars Kanis <lars@greiz-reinsdorf.de>
-Date: Thu, 26 Dec 2019 19:13:48 +0100
-Subject: [PATCH 1/2] Enable build of static libruby
-
-This is used in rake-compiler-dock for linux targets.
-The static libruby is postprocessed in a special way.
-See rake-compiler-dock's Dockerfile.
----
- tasks/bin/cross-ruby.rake | 2 ++
- 1 file changed, 2 insertions(+)
-
-diff --git a/tasks/bin/cross-ruby.rake b/tasks/bin/cross-ruby.rake
-index c9b0bbb..2a73be7 100644
---- a/tasks/bin/cross-ruby.rake
-+++ b/tasks/bin/cross-ruby.rake
-@@ -108,6 +108,8 @@ end
-     file "#{build_dir}/Makefile" => [build_dir, source_dir] do |t|
-
-       options = [
-+        '--enable-static',
-+        '--enable-install-static-library',
-         "--host=#{mingw_host}",
-         "--target=#{mingw_target}",
-         "--build=#{RUBY_BUILD}",
---
-2.20.1
-
diff --git a/third_party/rake-compiler-dock/build/patches2/ruby-2.7.0/ruby2_keywords.patch b/third_party/rake-compiler-dock/build/patches2/ruby-2.7.0/ruby2_keywords.patch
deleted file mode 100644 (file)
index 5f20d37..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-diff --git a/template/fake.rb.in b/template/fake.rb.in
-index f1da719ecb..e0b649fb28 100644
---- a/template/fake.rb.in
-+++ b/template/fake.rb.in
-@@ -27,6 +27,10 @@ case "$0" in /*) r=-r"$0";; *) r=-r"./$0";; esac
- exec $ruby "$r" "$@"
- =end
- =baseruby
-+<% if RUBY_VERSION < "2.7" %>
-+def ruby2_keywords(*)
-+end
-+<% end %>
- class Object
-   remove_const :CROSS_COMPILING if defined?(CROSS_COMPILING)
-   CROSS_COMPILING = RUBY_PLATFORM
diff --git a/third_party/rake-compiler-dock/build/sigfw.c b/third_party/rake-compiler-dock/build/sigfw.c
deleted file mode 100644 (file)
index 7c1be61..0000000
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * This program handles SIGINT and forwards it to another process.
- * It is intended to be run as PID 1.
- *
- * Docker starts processes with "docker run" as PID 1.
- * On Linux, the default signal handler for PID 1 ignores any signals.
- * Therefore Ctrl-C aka SIGINT is ignored per default.
- */
-
-#include <unistd.h>
-#include <stdio.h>
-#include <signal.h>
-#include <sys/types.h>
-#include <sys/wait.h>
-
-int pid = 0;
-
-void
-handle_sigint (int signum)
-{
-  if(pid)
-    kill(pid, SIGINT);
-}
-
-int main(int argc, char *argv[]){
-  struct sigaction new_action;
-  int status = -1;
-
-  /* Set up the structure to specify the new action. */
-  new_action.sa_handler = handle_sigint;
-  sigemptyset (&new_action.sa_mask);
-  new_action.sa_flags = 0;
-
-  sigaction (SIGINT, &new_action, (void*)0);
-
-  pid = fork();
-  if(pid){
-    wait(&status);
-    return WEXITSTATUS(status);
-  }else{
-    status = execvp(argv[1], &argv[1]);
-    perror("exec");
-    return status;
-  }
-}
diff --git a/third_party/rake-compiler-dock/push_testing_images.sh b/third_party/rake-compiler-dock/push_testing_images.sh
deleted file mode 100755 (executable)
index a64241c..0000000
+++ /dev/null
@@ -1,47 +0,0 @@
-#!/bin/bash
-# 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.
-#
-# Builds selected testing docker images and pushes them to dockerhub.
-# Useful for testing environments where it's impractical (or impossible)
-# to rely on docker images being cached locally after they've been built
-# for the first time (which might be costly especially for some images).
-# NOTE: gRPC docker images intended to be used by end users are NOT
-# pushed using this script (they're built automatically by dockerhub).
-# This script is only for "internal" images we use when testing gRPC.  
-
-set -ex
-
-cd $(dirname $0)
-
-DOCKERHUB_ORGANIZATION=grpctesting
-
-for NAME in rake_x86_64-linux rake_x86-linux rake_x64-mingw32 rake_x86-mingw32
-do
-  # Generate image name based on Dockerfile checksum. That works well as long
-  # as can count on dockerfiles being written in a way that changing the logical 
-  # contents of the docker image always changes the SHA (e.g. using "ADD file" 
-  # cmd in the dockerfile in not ok as contents of the added file will not be
-  # reflected in the SHA).
-  DOCKER_IMAGE_NAME=${NAME}_$(sha1sum ${NAME}/Dockerfile | cut -f1 -d\ )
-
-  # skip the image if it already exists in the repo 
-  curl --silent -f -lSL https://registry.hub.docker.com/v2/repositories/${DOCKERHUB_ORGANIZATION}/${DOCKER_IMAGE_NAME}/tags/latest > /dev/null \
-      && continue
-
-  docker build -t ${DOCKERHUB_ORGANIZATION}/${DOCKER_IMAGE_NAME} -f ${NAME}/Dockerfile .
-      
-  # "docker login" needs to be run in advance
-  docker push ${DOCKERHUB_ORGANIZATION}/${DOCKER_IMAGE_NAME}
-done
index 2a949d0..6663771 100644 (file)
@@ -1,3 +1,3 @@
-FROM larskanis/rake-compiler-dock-mri-x64-mingw32:1.0.0
+FROM larskanis/rake-compiler-dock-mri-x64-mingw32:1.1.0
 
 RUN find / -name win32.h | while read f ; do sed -i 's/gettimeofday/rb_gettimeofday/' $f ; done
index 447762a..50aaae2 100644 (file)
@@ -1,91 +1 @@
-FROM dockcross/manylinux2010-x86
-
-# Docker file for building gRPC manylinux-based Ruby artifacts.
-# Updated: 2020-07-03
-
-# install packages which rvm will require
-RUN yum install -y autoconf gcc-c++ libtool readline-devel ruby sqlite-devel openssl-devel xz
-
-# install rvm, RVM 1.26.0+ has signed releases, source rvm for usage outside of package scripts
-RUN gpg --keyserver hkp://pool.sks-keyservers.net --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3 7D2BAF1CF37B13E2069D6956105BD0E739499BDB && \
-    (curl -L http://get.rvm.io | sudo bash)
-RUN echo "source /etc/profile.d/rvm.sh" >> /etc/rubybashrc
-RUN bash -c " \
-        source /etc/rubybashrc && \
-        rvm cleanup all "
-
-# Import patch files for ruby and gems
-COPY build/patches /work/patches/
-ENV BASH_ENV /etc/rubybashrc
-
-# install rubies and fix permissions on
-RUN bash -c " \
-    export CFLAGS='-s -O3 -fno-fast-math -fPIC' && \
-    for v in 2.5.7 ; do \
-        rvm install \$v --patch \$(echo /work/patches/ruby-\$v/* | tr ' ' ','); \
-    done && \
-    rvm cleanup all && \
-    find /usr/local/rvm -type d -print0 | sudo xargs -0 chmod g+sw "
-
-# Install rake-compiler and typical gems in all Rubies
-# do not generate documentation for gems
-RUN echo "gem: --no-ri --no-rdoc" >> ~/.gemrc && \
-    bash -c " \
-        rvm all do gem update --system --no-document && \
-        rvm all do gem install --no-document bundler 'bundler:~>1.16' rake-compiler:1.1.0 hoe:3.20.0 mini_portile rubygems-tasks mini_portile2 && \
-        find /usr/local/rvm -type d -print0 | sudo xargs -0 chmod g+sw "
-
-# Install rake-compiler's cross rubies in global dir instead of /root
-RUN mkdir -p /usr/local/rake-compiler && \
-    ln -s /usr/local/rake-compiler ~/.rake-compiler
-
-RUN bash -c " \
-        rvm alias create default 2.5.7 && \
-        rvm use default "
-
-# Patch rake-compiler and hoe package
-COPY build/patches2 /work/patches/
-RUN cd /usr/local/rvm/gems/ruby-2.5.7/gems/rake-compiler-1.1.0 && \
-    ( git apply /work/patches/rake-compiler-1.1.0/*.patch || true )
-RUN cd /usr/local/rvm/gems/ruby-2.5.7/gems/hoe-3.20.0 && \
-    ( git apply /work/patches/hoe-3.20.0/*.patch || true )
-
-# Patch ruby-2.7.0 for cross build
-RUN curl -SL http://cache.ruby-lang.org/pub/ruby/2.7/ruby-2.7.0.tar.xz | tar -xJC /root/ && \
-    cd /root/ruby-2.7.0 && \
-    git apply /work/patches/ruby-2.7.0/*.patch && \
-    cd .. && \
-    mkdir -p /usr/local/rake-compiler/sources/ && \
-    tar cjf /usr/local/rake-compiler/sources/ruby-2.7.0.tar.bz2 ruby-2.7.0 && \
-    rm -rf /root/ruby-2.7.0
-
-ENV XRUBIES 2.7.0:2.6.0:2.5.0:2.4.0:2.3.0:2.2.2
-
-# Build all xruby versions in parallel
-# Then cleanup all build artifacts
-RUN bash -c " \
-    export CFLAGS='-s -O1 -fno-omit-frame-pointer -fno-fast-math' && \
-    export MAKE='make V=0' && \
-    rake-compiler cross-ruby VERSION=$XRUBIES HOST=x86-linux-gnu && \
-    rm -rf ~/.rake-compiler/builds ~/.rake-compiler/sources && \
-    find /usr/local/rvm -type d -print0 | sudo xargs -0 chmod g+sw "
-
-# Avoid linking against libruby shared object.
-# See also https://github.com/rake-compiler/rake-compiler-dock/issues/13
-RUN find /usr/local/rake-compiler/ruby/*linux*/ -name libruby.so | xargs rm
-RUN find /usr/local/rake-compiler/ruby/*linux*/ -name libruby-static.a | while read f ; do cp $f `echo $f | sed s/-static//` ; done
-RUN find /usr/local/rake-compiler/ruby/*linux*/ -name libruby.a | while read f ; do ar t $f | xargs ar d $f ; done
-RUN find /usr/local/rake-compiler/ruby/*linux*/ -name mkmf.rb | while read f ; do sed -i ':a;N;$!ba;s/TRY_LINK = [^\n]*\n[^\n]*\n[^\n]*LOCAL_LIBS)/& -lruby-static/' $f ; done
-
-# Fix paths in rake-compiler/config.yml and add rvm and mingw-tools to the global bashrc
-RUN sed -i -- "s:/root/.rake-compiler:/usr/local/rake-compiler:g" /usr/local/rake-compiler/config.yml && \
-    echo "source /etc/profile.d/rvm.sh" >> /etc/bash.bashrc
-
-# Install SIGINT forwarder
-COPY build/sigfw.c /root/
-RUN gcc $HOME/sigfw.c -o /usr/local/bin/sigfw
-
-# Install patchelf_gem.sh
-COPY build/patchelf_gem.sh /usr/local/bin/patchelf_gem.sh
-
-ENV RUBY_CC_VERSION 2.7.0:2.6.0:2.5.0:2.4.0:2.3.0:2.2.2
+FROM larskanis/rake-compiler-dock-mri-x86-linux:1.1.0
index d78d967..6a2880a 100644 (file)
@@ -1,3 +1,3 @@
-FROM larskanis/rake-compiler-dock-mri-x86-mingw32:1.0.0
+FROM larskanis/rake-compiler-dock-mri-x86-mingw32:1.1.0
 
 RUN find / -name win32.h | while read f ; do sed -i 's/gettimeofday/rb_gettimeofday/' $f ; done
index 4f22415..ede37a2 100644 (file)
@@ -1,91 +1 @@
-FROM dockcross/manylinux2010-x64
-
-# Docker file for building gRPC manylinux-based Ruby artifacts.
-# Updated: 2020-07-03
-
-# install packages which rvm will require
-RUN yum install -y autoconf gcc-c++ libtool readline-devel ruby sqlite-devel openssl-devel xz
-
-# install rvm, RVM 1.26.0+ has signed releases, source rvm for usage outside of package scripts
-RUN gpg --keyserver hkp://pool.sks-keyservers.net --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3 7D2BAF1CF37B13E2069D6956105BD0E739499BDB && \
-    (curl -L http://get.rvm.io | sudo bash)
-RUN echo "source /etc/profile.d/rvm.sh" >> /etc/rubybashrc
-RUN bash -c " \
-        source /etc/rubybashrc && \
-        rvm cleanup all "
-
-# Import patch files for ruby and gems
-COPY build/patches /work/patches/
-ENV BASH_ENV /etc/rubybashrc
-
-# install rubies and fix permissions on
-RUN bash -c " \
-    export CFLAGS='-s -O3 -fno-fast-math -fPIC' && \
-    for v in 2.5.7 ; do \
-        rvm install \$v --patch \$(echo /work/patches/ruby-\$v/* | tr ' ' ','); \
-    done && \
-    rvm cleanup all && \
-    find /usr/local/rvm -type d -print0 | sudo xargs -0 chmod g+sw "
-
-# Install rake-compiler and typical gems in all Rubies
-# do not generate documentation for gems
-RUN echo "gem: --no-ri --no-rdoc" >> ~/.gemrc && \
-    bash -c " \
-        rvm all do gem update --system --no-document && \
-        rvm all do gem install --no-document bundler 'bundler:~>1.16' rake-compiler:1.1.0 hoe:3.20.0 mini_portile rubygems-tasks mini_portile2 && \
-        find /usr/local/rvm -type d -print0 | sudo xargs -0 chmod g+sw "
-
-# Install rake-compiler's cross rubies in global dir instead of /root
-RUN mkdir -p /usr/local/rake-compiler && \
-    ln -s /usr/local/rake-compiler ~/.rake-compiler
-
-RUN bash -c " \
-        rvm alias create default 2.5.7 && \
-        rvm use default "
-
-# Patch rake-compiler and hoe package
-COPY build/patches2 /work/patches/
-RUN cd /usr/local/rvm/gems/ruby-2.5.7/gems/rake-compiler-1.1.0 && \
-    ( git apply /work/patches/rake-compiler-1.1.0/*.patch || true )
-RUN cd /usr/local/rvm/gems/ruby-2.5.7/gems/hoe-3.20.0 && \
-    ( git apply /work/patches/hoe-3.20.0/*.patch || true )
-
-# Patch ruby-2.7.0 for cross build
-RUN curl -SL http://cache.ruby-lang.org/pub/ruby/2.7/ruby-2.7.0.tar.xz | tar -xJC /root/ && \
-    cd /root/ruby-2.7.0 && \
-    git apply /work/patches/ruby-2.7.0/*.patch && \
-    cd .. && \
-    mkdir -p /usr/local/rake-compiler/sources/ && \
-    tar cjf /usr/local/rake-compiler/sources/ruby-2.7.0.tar.bz2 ruby-2.7.0 && \
-    rm -rf /root/ruby-2.7.0
-
-ENV XRUBIES 2.7.0:2.6.0:2.5.0:2.4.0:2.3.0:2.2.2
-
-# Build all xruby versions in parallel
-# Then cleanup all build artifacts
-RUN bash -c " \
-    export CFLAGS='-s -O1 -fno-omit-frame-pointer -fno-fast-math' && \
-    export MAKE='make V=0' && \
-    rake-compiler cross-ruby VERSION=$XRUBIES HOST=x86_64-linux-gnu && \
-    rm -rf ~/.rake-compiler/builds ~/.rake-compiler/sources && \
-    find /usr/local/rvm -type d -print0 | sudo xargs -0 chmod g+sw "
-
-# Avoid linking against libruby shared object.
-# See also https://github.com/rake-compiler/rake-compiler-dock/issues/13
-RUN find /usr/local/rake-compiler/ruby/*linux*/ -name libruby.so | xargs rm
-RUN find /usr/local/rake-compiler/ruby/*linux*/ -name libruby-static.a | while read f ; do cp $f `echo $f | sed s/-static//` ; done
-RUN find /usr/local/rake-compiler/ruby/*linux*/ -name libruby.a | while read f ; do ar t $f | xargs ar d $f ; done
-RUN find /usr/local/rake-compiler/ruby/*linux*/ -name mkmf.rb | while read f ; do sed -i ':a;N;$!ba;s/TRY_LINK = [^\n]*\n[^\n]*\n[^\n]*LOCAL_LIBS)/& -lruby-static/' $f ; done
-
-# Fix paths in rake-compiler/config.yml and add rvm and mingw-tools to the global bashrc
-RUN sed -i -- "s:/root/.rake-compiler:/usr/local/rake-compiler:g" /usr/local/rake-compiler/config.yml && \
-    echo "source /etc/profile.d/rvm.sh" >> /etc/bash.bashrc
-
-# Install SIGINT forwarder
-COPY build/sigfw.c /root/
-RUN gcc $HOME/sigfw.c -o /usr/local/bin/sigfw
-
-# Install patchelf_gem.sh
-COPY build/patchelf_gem.sh /usr/local/bin/patchelf_gem.sh
-
-ENV RUBY_CC_VERSION 2.7.0:2.6.0:2.5.0:2.4.0:2.3.0:2.2.2
+FROM larskanis/rake-compiler-dock-mri-x86_64-linux:1.1.0
diff --git a/third_party/upb/.bazelrc b/third_party/upb/.bazelrc
new file mode 100644 (file)
index 0000000..7b9da71
--- /dev/null
@@ -0,0 +1,22 @@
+# Use our custom-configured c++ toolchain.
+
+build:m32 --copt=-m32 --linkopt=-m32
+build:asan --copt=-fsanitize=address --linkopt=-fsanitize=address
+build:valgrind --run_under='valgrind --leak-check=full --error-exitcode=1'
+
+build:ubsan --copt=-fsanitize=undefined --linkopt=-fsanitize=undefined --action_env=UBSAN_OPTIONS=halt_on_error=1:print_stacktrace=1
+# Workaround for the fact that Bazel links with $CC, not $CXX
+# https://github.com/bazelbuild/bazel/issues/11122#issuecomment-613746748
+build:ubsan --copt=-fno-sanitize=function --copt=-fno-sanitize=vptr
+
+build:Werror --copt=-Werror
+build:Werror --per_file_copt=json/parser@-Wno-error
+build:Werror --per_file_copt=com_google_protobuf@-Wno-error
+
+# GCC's -fanalyzer, a deeper static analysis than normal warnings.
+build:analyzer --copt=-fanalyzer --copt=-Werror
+build:analyzer --per_file_copt=json/parser@-fno-analyzer
+build:analyzer --per_file_copt=com_google_protobuf@-fno-analyzer
+build:analyzer --per_file_copt=com_github_google_benchmark@-fno-analyzer
+
+build:asan-fuzzer --copt=-fsanitize=address,fuzzer --linkopt=-fsanitize=address,fuzzer --define fuzz=true
diff --git a/third_party/upb/BUILD b/third_party/upb/BUILD
new file mode 100644 (file)
index 0000000..2e13326
--- /dev/null
@@ -0,0 +1,410 @@
+load(
+    "//bazel:build_defs.bzl",
+    "UPB_DEFAULT_COPTS",
+    "upb_amalgamation",  # copybara:strip_for_google3
+)
+load(
+    "//bazel:upb_proto_library.bzl",
+    "upb_fasttable_enabled",
+    "upb_proto_library",
+    "upb_proto_library_copts",
+    "upb_proto_reflection_library",
+)
+
+# copybara:strip_for_google3_begin
+load(
+    "@rules_proto//proto:defs.bzl",
+    "proto_library",
+)
+
+# copybara:strip_end
+
+licenses(["notice"])  # BSD (Google-authored w/ possible external contributions)
+
+exports_files([
+    "LICENSE",
+    "build_defs",
+])
+
+config_setting(
+    name = "windows",
+    constraint_values = ["@bazel_tools//platforms:windows"],
+)
+
+upb_fasttable_enabled(
+    name = "fasttable_enabled",
+    build_setting_default = False,
+    visibility = ["//visibility:public"],
+)
+
+config_setting(
+    name = "fasttable_enabled_setting",
+    flag_values = {"//:fasttable_enabled": "true"},
+)
+
+upb_proto_library_copts(
+    name = "upb_proto_library_copts__for_generated_code_only_do_not_use",
+    copts = UPB_DEFAULT_COPTS,
+    visibility = ["//visibility:public"],
+)
+
+# Public C/C++ libraries #######################################################
+
+cc_library(
+    name = "port",
+    copts = UPB_DEFAULT_COPTS,
+    textual_hdrs = [
+        "upb/port_def.inc",
+        "upb/port_undef.inc",
+    ],
+    visibility = ["//tests:__pkg__"],
+)
+
+cc_library(
+    name = "upb",
+    srcs = [
+        "upb/decode.c",
+        "upb/decode.int.h",
+        "upb/encode.c",
+        "upb/msg.c",
+        "upb/msg.h",
+        "upb/table.c",
+        "upb/table.int.h",
+        "upb/upb.c",
+        "upb/upb.int.h",
+    ],
+    hdrs = [
+        "upb/decode.h",
+        "upb/encode.h",
+        "upb/upb.h",
+        "upb/upb.hpp",
+    ],
+    copts = UPB_DEFAULT_COPTS,
+    visibility = ["//visibility:public"],
+    deps = [
+        ":fastdecode",
+        ":port",
+        "//third_party/wyhash",
+    ],
+)
+
+cc_library(
+    name = "fastdecode",
+    srcs = [
+        "upb/decode.int.h",
+        "upb/decode_fast.c",
+        "upb/decode_fast.h",
+        "upb/msg.h",
+        "upb/upb.int.h",
+    ],
+    copts = UPB_DEFAULT_COPTS,
+    deps = [
+        ":port",
+        ":table",
+    ],
+)
+
+# Common support routines used by generated code.  This library has no
+# implementation, but depends on :upb and exposes a few more hdrs.
+#
+# This is public only because we have no way of visibility-limiting it to
+# upb_proto_library() only.  This interface is not stable and by using it you
+# give up any backward compatibility guarantees.
+cc_library(
+    name = "generated_code_support__only_for_generated_code_do_not_use__i_give_permission_to_break_me",
+    hdrs = [
+        "upb/decode_fast.h",
+        "upb/msg.h",
+        "upb/port_def.inc",
+        "upb/port_undef.inc",
+    ],
+    copts = UPB_DEFAULT_COPTS,
+    visibility = ["//visibility:public"],
+    deps = [
+        ":table",
+        ":upb",
+    ],
+)
+
+upb_proto_library(
+    name = "descriptor_upb_proto",
+    visibility = ["//visibility:public"],
+    deps = ["@com_google_protobuf//:descriptor_proto"],
+)
+
+upb_proto_reflection_library(
+    name = "descriptor_upb_proto_reflection",
+    visibility = ["//visibility:public"],
+    deps = ["@com_google_protobuf//:descriptor_proto"],
+)
+
+cc_library(
+    name = "reflection",
+    srcs = [
+        "upb/def.c",
+        "upb/msg.h",
+        "upb/reflection.c",
+    ],
+    hdrs = [
+        "upb/def.h",
+        "upb/def.hpp",
+        "upb/reflection.h",
+    ],
+    copts = UPB_DEFAULT_COPTS,
+    visibility = ["//visibility:public"],
+    deps = [
+        ":descriptor_upb_proto",
+        ":port",
+        ":table",
+        ":upb",
+    ],
+)
+
+cc_library(
+    name = "textformat",
+    srcs = [
+        "upb/text_encode.c",
+    ],
+    hdrs = [
+        "upb/text_encode.h",
+    ],
+    copts = UPB_DEFAULT_COPTS,
+    visibility = ["//visibility:public"],
+    deps = [
+        ":port",
+        ":reflection",
+    ],
+)
+
+cc_library(
+    name = "json",
+    srcs = [
+        "upb/json_decode.c",
+        "upb/json_encode.c",
+    ],
+    hdrs = [
+        "upb/json_decode.h",
+        "upb/json_encode.h",
+    ],
+    copts = UPB_DEFAULT_COPTS,
+    visibility = ["//visibility:public"],
+    deps = [
+        ":port",
+        ":reflection",
+        ":upb",
+    ],
+)
+
+# Internal C/C++ libraries #####################################################
+
+cc_library(
+    name = "table",
+    hdrs = [
+        "upb/table.int.h",
+        "upb/upb.h",
+    ],
+    visibility = ["//tests:__pkg__"],
+    deps = [
+        ":port",
+    ],
+)
+
+# Legacy C/C++ Libraries (not recommended for new code) ########################
+
+cc_library(
+    name = "handlers",
+    srcs = [
+        "upb/handlers.c",
+        "upb/handlers-inl.h",
+        "upb/sink.c",
+    ],
+    hdrs = [
+        "upb/handlers.h",
+        "upb/sink.h",
+    ],
+    copts = UPB_DEFAULT_COPTS,
+    visibility = ["//tests:__pkg__"],
+    deps = [
+        ":port",
+        ":reflection",
+        ":table",
+        ":upb",
+    ],
+)
+
+cc_library(
+    name = "upb_pb",
+    srcs = [
+        "upb/pb/compile_decoder.c",
+        "upb/pb/decoder.c",
+        "upb/pb/decoder.int.h",
+        "upb/pb/encoder.c",
+        "upb/pb/textprinter.c",
+        "upb/pb/varint.c",
+        "upb/pb/varint.int.h",
+    ],
+    hdrs = [
+        "upb/pb/decoder.h",
+        "upb/pb/encoder.h",
+        "upb/pb/textprinter.h",
+    ],
+    copts = UPB_DEFAULT_COPTS,
+    visibility = ["//tests:__pkg__"],
+    deps = [
+        ":descriptor_upb_proto",
+        ":handlers",
+        ":port",
+        ":reflection",
+        ":table",
+        ":upb",
+    ],
+)
+
+# copybara:strip_for_google3_begin
+cc_library(
+    name = "upb_json",
+    srcs = [
+        "upb/json/parser.c",
+        "upb/json/printer.c",
+    ],
+    hdrs = [
+        "upb/json/parser.h",
+        "upb/json/printer.h",
+    ],
+    copts = UPB_DEFAULT_COPTS,
+    visibility = ["//tests:__pkg__"],
+    deps = [
+        ":upb",
+        ":upb_pb",
+    ],
+)
+
+genrule(
+    name = "generate_json_ragel",
+    srcs = ["//:upb/json/parser.rl"],
+    outs = ["upb/json/parser.c"],
+    cmd = "$(location @ragel//:ragelc) -C -o upb/json/parser.c $< && mv upb/json/parser.c $@",
+    tools = ["@ragel//:ragelc"],
+    visibility = ["//cmake:__pkg__"],
+)
+
+# Amalgamation #################################################################
+
+py_binary(
+    name = "amalgamate",
+    srcs = ["tools/amalgamate.py"],
+)
+
+upb_amalgamation(
+    name = "gen_amalgamation",
+    outs = [
+        "upb.c",
+        "upb.h",
+    ],
+    amalgamator = ":amalgamate",
+    libs = [
+        ":upb",
+        ":fastdecode",
+        ":descriptor_upb_proto",
+        ":reflection",
+        ":handlers",
+        ":port",
+        ":upb_pb",
+        ":upb_json",
+    ],
+)
+
+cc_library(
+    name = "amalgamation",
+    srcs = ["upb.c"],
+    hdrs = ["upb.h"],
+    copts = UPB_DEFAULT_COPTS,
+    deps = ["//third_party/wyhash"],
+)
+
+upb_amalgamation(
+    name = "gen_php_amalgamation",
+    outs = [
+        "php-upb.c",
+        "php-upb.h",
+    ],
+    amalgamator = ":amalgamate",
+    libs = [
+        ":upb",
+        ":fastdecode",
+        ":descriptor_upb_proto",
+        ":descriptor_upb_proto_reflection",
+        ":reflection",
+        ":port",
+        ":json",
+    ],
+    prefix = "php-",
+)
+
+cc_library(
+    name = "php_amalgamation",
+    srcs = ["php-upb.c"],
+    hdrs = ["php-upb.h"],
+    copts = UPB_DEFAULT_COPTS,
+    deps = ["//third_party/wyhash"],
+)
+
+upb_amalgamation(
+    name = "gen_ruby_amalgamation",
+    outs = [
+        "ruby-upb.c",
+        "ruby-upb.h",
+    ],
+    amalgamator = ":amalgamate",
+    libs = [
+        ":upb",
+        ":fastdecode",
+        ":descriptor_upb_proto",
+        ":reflection",
+        ":port",
+        ":json",
+    ],
+    prefix = "ruby-",
+)
+
+cc_library(
+    name = "ruby_amalgamation",
+    srcs = ["ruby-upb.c"],
+    hdrs = ["ruby-upb.h"],
+    copts = UPB_DEFAULT_COPTS,
+    deps = ["//third_party/wyhash"],
+)
+
+exports_files(
+    [
+        "upb/json/parser.rl",
+        "BUILD",
+        "WORKSPACE",
+    ],
+    visibility = ["//cmake:__pkg__"],
+)
+
+exports_files(
+    [
+        "third_party/lunit/console.lua",
+        "third_party/lunit/lunit.lua",
+    ],
+    visibility = ["//tests/bindings/lua:__pkg__"],
+)
+
+filegroup(
+    name = "cmake_files",
+    srcs = glob([
+        "upb/json/parser.c",
+        "CMakeLists.txt",
+        "generated_for_cmake/**/*",
+        "google/**/*",
+        "upbc/**/*",
+        "upb/**/*",
+        "tests/**/*",
+        "third_party/**/*",
+    ]),
+    visibility = ["//cmake:__pkg__"],
+)
+
+# copybara:strip_end
index 8e365a1..870ebf7 100644 (file)
@@ -1,6 +1,7 @@
 workspace(name = "upb")
 
 load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
+load("@bazel_tools//tools/build_defs/repo:git.bzl", "new_git_repository")
 load("//bazel:workspace_deps.bzl", "upb_deps")
 
 upb_deps()
@@ -37,3 +38,11 @@ http_archive(
     strip_prefix = "benchmark-16703ff83c1ae6d53e5155df3bb3ab0bc96083be",
     urls = ["https://github.com/google/benchmark/archive/16703ff83c1ae6d53e5155df3bb3ab0bc96083be.zip"],
 )
+
+new_git_repository(
+    name = "com_google_googleapis",
+    remote = "https://github.com/googleapis/googleapis.git",
+    branch = "master",
+    build_file = "//benchmarks:BUILD.googleapis",
+    patch_cmds = ["find google -type f -name BUILD.bazel -delete"],
+)
index 121ae27..ae41577 100644 (file)
@@ -2,6 +2,36 @@
 
 load(":upb_proto_library.bzl", "GeneratedSrcsInfo")
 
+UPB_DEFAULT_CPPOPTS = select({
+    "//:windows": [],
+    "//conditions:default": [
+        # copybara:strip_for_google3_begin
+        "-Wextra",
+        # "-Wshorten-64-to-32",  # not in GCC (and my Kokoro images doesn't have Clang)
+        "-Werror",
+        "-Wno-long-long",
+        # copybara:strip_end
+    ],
+})
+
+UPB_DEFAULT_COPTS = select({
+    "//:windows": [],
+    "//:fasttable_enabled_setting": ["-std=gnu99", "-DUPB_ENABLE_FASTTABLE"],
+    "//conditions:default": [
+        # copybara:strip_for_google3_begin
+        "-std=c99",
+        "-pedantic",
+        "-Werror=pedantic",
+        "-Wall",
+        "-Wstrict-prototypes",
+        # GCC (at least) emits spurious warnings for this that cannot be fixed
+        # without introducing redundant initialization (with runtime cost):
+        #   https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80635
+        #"-Wno-maybe-uninitialized",
+        # copybara:strip_end
+    ],
+})
+
 def _librule(name):
     return name + "_lib"
 
@@ -58,50 +88,6 @@ def make_shell_script(name, contents, out):
         cmd = "(cat <<'HEREDOC'\n%s\nHEREDOC\n) > $@" % contents,
     )
 
-def generated_file_staleness_test(name, outs, generated_pattern):
-    """Tests that checked-in file(s) match the contents of generated file(s).
-
-    The resulting test will verify that all output files exist and have the
-    correct contents.  If the test fails, it can be invoked with --fix to
-    bring the checked-in files up to date.
-
-    Args:
-      name: Name of the rule.
-      outs: the checked-in files that are copied from generated files.
-      generated_pattern: the pattern for transforming each "out" file into a
-        generated file.  For example, if generated_pattern="generated/%s" then
-        a file foo.txt will look for generated file generated/foo.txt.
-    """
-
-    script_name = name + ".py"
-    script_src = "//:tools/staleness_test.py"
-
-    # Filter out non-existing rules so Blaze doesn't error out before we even
-    # run the test.
-    existing_outs = native.glob(include = outs)
-
-    # The file list contains a few extra bits of information at the end.
-    # These get unpacked by the Config class in staleness_test_lib.py.
-    file_list = outs + [generated_pattern, native.package_name() or ".", name]
-
-    native.genrule(
-        name = name + "_makescript",
-        outs = [script_name],
-        srcs = [script_src],
-        testonly = 1,
-        cmd = "cat $(location " + script_src + ") > $@; " +
-              "sed -i.bak -e 's|INSERT_FILE_LIST_HERE|" + "\\\n  ".join(file_list) + "|' $@",
-    )
-
-    native.py_test(
-        name = name,
-        srcs = [script_name],
-        data = existing_outs + [generated_pattern % file for file in outs],
-        deps = [
-            "//:staleness_test_lib",
-        ],
-    )
-
 # upb_amalgamation() rule, with file_list aspect.
 
 SrcList = provider(
@@ -156,7 +142,3 @@ upb_amalgamation = rule(
     },
     implementation = _upb_amalgamation,
 )
-
-def licenses(*args):
-    # No-op (for Google-internal usage).
-    pass
index 7be0b59..113c71f 100644 (file)
@@ -4,7 +4,6 @@ package(
 
 cc_library(
     name = "liblua_headers",
-    defines = ["LUA_USE_LINUX"],
     hdrs = [
         "src/lauxlib.h",
         "src/lua.h",
@@ -12,6 +11,7 @@ cc_library(
         "src/luaconf.h",
         "src/lualib.h",
     ],
+    defines = ["LUA_USE_LINUX"],
     includes = ["src"],
 )
 
@@ -72,7 +72,6 @@ cc_library(
         "src/lzio.c",
         "src/lzio.h",
     ],
-    defines = ["LUA_USE_LINUX"],
     hdrs = [
         "src/lauxlib.h",
         "src/lua.h",
@@ -80,6 +79,7 @@ cc_library(
         "src/luaconf.h",
         "src/lualib.h",
     ],
+    defines = ["LUA_USE_LINUX"],
     includes = ["src"],
     linkopts = [
         "-lm",
@@ -92,11 +92,11 @@ cc_binary(
     srcs = [
         "src/lua.c",
     ],
-    deps = [
-        ":liblua",
-    ],
     linkopts = [
         "-lreadline",
         "-rdynamic",
     ],
+    deps = [
+        ":liblua",
+    ],
 )
index 5e3b249..5916bea 100644 (file)
@@ -1,4 +1,3 @@
-
 package(
     default_visibility = ["//visibility:public"],
 )
@@ -158,7 +157,10 @@ cc_binary(
         "aapl/avlimelkey.h",
         "aapl/avltree.h",
     ],
-    includes = ["ragel", "aapl"],
+    includes = [
+        "aapl",
+        "ragel",
+    ],
 )
 
 config_h_contents = """
index d324948..155d18d 100644 (file)
@@ -9,7 +9,7 @@ load("@rules_proto//proto:defs.bzl", "ProtoInfo")  # copybara:strip_for_google3
 
 # Generic support code #########################################################
 
-_is_bazel = not hasattr(native, "genmpm")
+_is_bazel = True  # copybara:replace_for_google3 _is_bazel = False
 
 def _get_real_short_path(file):
     # For some reason, files from other archives have short paths that look like:
@@ -21,23 +21,17 @@ def _get_real_short_path(file):
 
     # Sometimes it has another few prefixes like:
     #   _virtual_imports/any_proto/google/protobuf/any.proto
+    #   benchmarks/_virtual_imports/100_msgs_proto/benchmarks/100_msgs.proto
     # We want just google/protobuf/any.proto.
-    if short_path.startswith("_virtual_imports"):
-        short_path = short_path.split("/", 2)[-1]
+    virtual_imports = "_virtual_imports/"
+    if virtual_imports in short_path:
+        short_path = short_path.split(virtual_imports)[1].split("/", 1)[1]
     return short_path
 
 def _get_real_root(file):
     real_short_path = _get_real_short_path(file)
     return file.path[:-len(real_short_path) - 1]
 
-def _get_real_roots(files):
-    roots = {}
-    for file in files:
-        real_root = _get_real_root(file)
-        if real_root:
-            roots[real_root] = True
-    return roots.keys()
-
 def _generate_output_file(ctx, src, extension):
     real_short_path = _get_real_short_path(src)
     real_short_path = paths.relativize(real_short_path, ctx.label.package)
@@ -52,7 +46,7 @@ def _filter_none(elems):
             out.append(elem)
     return out
 
-def _cc_library_func(ctx, name, hdrs, srcs, dep_ccinfos):
+def _cc_library_func(ctx, name, hdrs, srcs, copts, dep_ccinfos):
     """Like cc_library(), but callable from rules.
 
     Args:
@@ -88,6 +82,7 @@ def _cc_library_func(ctx, name, hdrs, srcs, dep_ccinfos):
         name = name,
         srcs = srcs,
         public_hdrs = hdrs,
+        user_compile_flags = copts,
         compilation_contexts = compilation_contexts,
         **blaze_only_args
     )
@@ -106,6 +101,44 @@ def _cc_library_func(ctx, name, hdrs, srcs, dep_ccinfos):
         linking_context = linking_context,
     )
 
+# Build setting for whether fasttable code generation is enabled ###############
+
+_FastTableEnabled = provider(
+    fields = {
+        "enabled": "whether fasttable is enabled",
+    },
+)
+
+def fasttable_enabled_impl(ctx):
+    raw_setting = ctx.build_setting_value
+
+    if raw_setting:
+        # TODO(haberman): check that the target CPU supports fasttable.
+        pass
+
+    return _FastTableEnabled(enabled = raw_setting)
+
+upb_fasttable_enabled = rule(
+    implementation = fasttable_enabled_impl,
+    build_setting = config.bool(flag = True),
+)
+
+# Dummy rule to expose select() copts to aspects  ##############################
+
+_UpbProtoLibraryCopts = provider(
+    fields = {
+        "copts": "copts for upb_proto_library()",
+    },
+)
+
+def upb_proto_library_copts_impl(ctx):
+    return _UpbProtoLibraryCopts(copts = ctx.attr.copts)
+
+upb_proto_library_copts = rule(
+    implementation = upb_proto_library_copts_impl,
+    attrs = {"copts": attr.string_list(default = [])},
+)
+
 # upb_proto_library / upb_proto_reflection_library shared code #################
 
 GeneratedSrcsInfo = provider(
@@ -120,24 +153,29 @@ _UpbDefsWrappedCcInfo = provider(fields = ["cc_info"])
 _WrappedGeneratedSrcsInfo = provider(fields = ["srcs"])
 _WrappedDefsGeneratedSrcsInfo = provider(fields = ["srcs"])
 
-def _compile_upb_protos(ctx, proto_info, proto_sources, ext):
+def _compile_upb_protos(ctx, generator, proto_info, proto_sources):
     if len(proto_sources) == 0:
         return GeneratedSrcsInfo(srcs = [], hdrs = [])
 
+    ext = "." + generator
+    tool = getattr(ctx.executable, "_gen_" + generator)
     srcs = [_generate_output_file(ctx, name, ext + ".c") for name in proto_sources]
     hdrs = [_generate_output_file(ctx, name, ext + ".h") for name in proto_sources]
     transitive_sets = proto_info.transitive_descriptor_sets.to_list()
+    fasttable_enabled = (hasattr(ctx.attr, "_fasttable_enabled") and
+                         ctx.attr._fasttable_enabled[_FastTableEnabled].enabled)
+    codegen_params = "fasttable:" if fasttable_enabled else ""
     ctx.actions.run(
         inputs = depset(
             direct = [proto_info.direct_descriptor_set],
             transitive = [proto_info.transitive_descriptor_sets],
         ),
-        tools = [ctx.executable._upbc],
+        tools = [tool],
         outputs = srcs + hdrs,
         executable = ctx.executable._protoc,
         arguments = [
-                        "--upb_out=" + _get_real_root(srcs[0]),
-                        "--plugin=protoc-gen-upb=" + ctx.executable._upbc.path,
+                        "--" + generator + "_out=" + codegen_params + _get_real_root(srcs[0]),
+                        "--plugin=protoc-gen-" + generator + "=" + tool.path,
                         "--descriptor_set_in=" + ctx.configuration.host_path_separator.join([f.path for f in transitive_sets]),
                     ] +
                     [_get_real_short_path(file) for file in proto_sources],
@@ -166,10 +204,7 @@ def _upb_proto_rule_impl(ctx):
         fail("proto_library rule must generate _UpbWrappedCcInfo or " +
              "_UpbDefsWrappedCcInfo (aspect should have handled this).")
 
-    if type(cc_info.linking_context.libraries_to_link) == "list":
-        lib = cc_info.linking_context.libraries_to_link[0]
-    else:
-        lib = cc_info.linking_context.libraries_to_link.to_list()[0]
+    lib = cc_info.linking_context.linker_inputs.to_list()[0].libraries[0]
     files = _filter_none([
         lib.static_library,
         lib.pic_static_library,
@@ -181,33 +216,32 @@ def _upb_proto_rule_impl(ctx):
         cc_info,
     ]
 
-def _upb_proto_aspect_impl(target, ctx, cc_provider, file_provider):
+def _upb_proto_aspect_impl(target, ctx, generator, cc_provider, file_provider):
     proto_info = target[ProtoInfo]
-    files = _compile_upb_protos(ctx, proto_info, proto_info.direct_sources, ctx.attr._ext)
-    deps = ctx.rule.attr.deps + ctx.attr._upb
-    if cc_provider == _UpbDefsWrappedCcInfo:
-        deps += ctx.attr._upb_reflection
+    files = _compile_upb_protos(ctx, generator, proto_info, proto_info.direct_sources)
+    deps = ctx.rule.attr.deps + getattr(ctx.attr, "_" + generator)
     dep_ccinfos = [dep[CcInfo] for dep in deps if CcInfo in dep]
     dep_ccinfos += [dep[_UpbWrappedCcInfo].cc_info for dep in deps if _UpbWrappedCcInfo in dep]
     dep_ccinfos += [dep[_UpbDefsWrappedCcInfo].cc_info for dep in deps if _UpbDefsWrappedCcInfo in dep]
-    if cc_provider == _UpbDefsWrappedCcInfo:
+    if generator == "upbdefs":
         if _UpbWrappedCcInfo not in target:
             fail("Target should have _UpbDefsWrappedCcInfo provider")
         dep_ccinfos += [target[_UpbWrappedCcInfo].cc_info]
     cc_info = _cc_library_func(
         ctx = ctx,
-        name = ctx.rule.attr.name + ctx.attr._ext,
+        name = ctx.rule.attr.name + "." + generator,
         hdrs = files.hdrs,
         srcs = files.srcs,
+        copts = ctx.attr._copts[_UpbProtoLibraryCopts].copts,
         dep_ccinfos = dep_ccinfos,
     )
     return [cc_provider(cc_info = cc_info), file_provider(srcs = files)]
 
 def _upb_proto_library_aspect_impl(target, ctx):
-    return _upb_proto_aspect_impl(target, ctx, _UpbWrappedCcInfo, _WrappedGeneratedSrcsInfo)
+    return _upb_proto_aspect_impl(target, ctx, "upb", _UpbWrappedCcInfo, _WrappedGeneratedSrcsInfo)
 
 def _upb_proto_reflection_library_aspect_impl(target, ctx):
-    return _upb_proto_aspect_impl(target, ctx, _UpbDefsWrappedCcInfo, _WrappedDefsGeneratedSrcsInfo)
+    return _upb_proto_aspect_impl(target, ctx, "upbdefs", _UpbDefsWrappedCcInfo, _WrappedDefsGeneratedSrcsInfo)
 
 def _maybe_add(d):
     if not _is_bazel:
@@ -222,10 +256,13 @@ def _maybe_add(d):
 
 _upb_proto_library_aspect = aspect(
     attrs = _maybe_add({
-        "_upbc": attr.label(
+        "_copts": attr.label(
+            default = "//:upb_proto_library_copts__for_generated_code_only_do_not_use",
+        ),
+        "_gen_upb": attr.label(
             executable = True,
             cfg = "host",
-            default = "//:protoc-gen-upb",
+            default = "//upbc:protoc-gen-upb",
         ),
         "_protoc": attr.label(
             executable = True,
@@ -239,7 +276,7 @@ _upb_proto_library_aspect = aspect(
             "//:generated_code_support__only_for_generated_code_do_not_use__i_give_permission_to_break_me",
             "//:upb",
         ]),
-        "_ext": attr.string(default = ".upb"),
+        "_fasttable_enabled": attr.label(default = "//:fasttable_enabled"),
     }),
     implementation = _upb_proto_library_aspect_impl,
     provides = [
@@ -249,6 +286,7 @@ _upb_proto_library_aspect = aspect(
     attr_aspects = ["deps"],
     fragments = ["cpp"],
     toolchains = ["@bazel_tools//tools/cpp:toolchain_type"],
+    incompatible_use_toolchain_transition = True,
 )
 
 upb_proto_library = rule(
@@ -267,10 +305,13 @@ upb_proto_library = rule(
 
 _upb_proto_reflection_library_aspect = aspect(
     attrs = _maybe_add({
-        "_upbc": attr.label(
+        "_copts": attr.label(
+            default = "//:upb_proto_library_copts__for_generated_code_only_do_not_use",
+        ),
+        "_gen_upbdefs": attr.label(
             executable = True,
             cfg = "host",
-            default = "//:protoc-gen-upb",
+            default = "//upbc:protoc-gen-upbdefs",
         ),
         "_protoc": attr.label(
             executable = True,
@@ -280,21 +321,12 @@ _upb_proto_reflection_library_aspect = aspect(
         "_cc_toolchain": attr.label(
             default = "@bazel_tools//tools/cpp:current_cc_toolchain",
         ),
-        # For unknown reasons, this gets overwritten.
-        "_upb": attr.label_list(
-            default = [
-                "//:generated_code_support__only_for_generated_code_do_not_use__i_give_permission_to_break_me",
-                "//:upb",
-                "//:reflection",
-            ],
-        ),
-        "_upb_reflection": attr.label_list(
+        "_upbdefs": attr.label_list(
             default = [
                 "//:upb",
                 "//:reflection",
             ],
         ),
-        "_ext": attr.string(default = ".upbdefs"),
     }),
     implementation = _upb_proto_reflection_library_aspect_impl,
     provides = [
@@ -308,6 +340,7 @@ _upb_proto_reflection_library_aspect = aspect(
     attr_aspects = ["deps"],
     fragments = ["cpp"],
     toolchains = ["@bazel_tools//tools/cpp:toolchain_type"],
+    incompatible_use_toolchain_transition = True,
 )
 
 upb_proto_reflection_library = rule(
index 16f3d4a..c724d7c 100644 (file)
@@ -8,14 +8,14 @@ def upb_deps():
         name = "com_google_absl",
         commit = "df3ea785d8c30a9503321a3d35ee7d35808f190d",  # LTS 2020-02-25
         remote = "https://github.com/abseil/abseil-cpp.git",
-        shallow_since = "1583355457 -0500"
+        shallow_since = "1583355457 -0500",
     )
 
     maybe(
         git_repository,
         name = "com_google_protobuf",
         remote = "https://github.com/protocolbuffers/protobuf.git",
-        commit = "5f5efe50c5bef20042645b51a697f58b0704ac89",  # Need to use Git until proto3 optional is released
+        commit = "c8f76331abf682c289fa79f05b2ee39cc7bf5a48",  # Need to use Git until proto3 optional is released
     )
 
     maybe(
diff --git a/third_party/upb/benchmark.py b/third_party/upb/benchmark.py
deleted file mode 100755 (executable)
index 9c59674..0000000
+++ /dev/null
@@ -1,32 +0,0 @@
-#!/usr/bin/env python3
-
-import json
-import subprocess
-import re
-
-def Run(cmd):
-  subprocess.check_call(cmd, shell=True)
-
-def RunAgainstBranch(branch, outfile, runs=12):
-  tmpfile = "/tmp/bench-output.json"
-  Run("rm -rf {}".format(tmpfile))
-  Run("git checkout {}".format(branch))
-  Run("bazel build -c opt :benchmark")
-
-  Run("./bazel-bin/benchmark --benchmark_out_format=json --benchmark_out={} --benchmark_repetitions={}".format(tmpfile, runs))
-
-  with open(tmpfile) as f:
-    bench_json = json.load(f)
-
-  with open(outfile, "w") as f:
-    for run in bench_json["benchmarks"]:
-      name = re.sub(r'^BM_', 'Benchmark', run["name"])
-      if name.endswith("_mean") or name.endswith("_median") or name.endswith("_stddev"):
-        continue
-      values = (name, run["iterations"], run["cpu_time"])
-      print("{} {} {} ns/op".format(*values), file=f)
-
-RunAgainstBranch("master", "/tmp/old.txt")
-RunAgainstBranch("decoder", "/tmp/new.txt")
-
-Run("~/go/bin/benchstat /tmp/old.txt /tmp/new.txt")
diff --git a/third_party/upb/benchmarks/BUILD b/third_party/upb/benchmarks/BUILD
new file mode 100644 (file)
index 0000000..2ab830f
--- /dev/null
@@ -0,0 +1,218 @@
+load(
+    "//bazel:upb_proto_library.bzl",
+    "upb_proto_library",
+    "upb_proto_reflection_library",
+)
+load(
+    ":build_defs.bzl",
+    "tmpl_cc_binary",
+    "cc_optimizefor_proto_library",
+    "expand_suffixes",
+    "proto_library",
+)
+
+licenses(["notice"])
+
+proto_library(
+    name = "descriptor_proto",
+    srcs = ["descriptor.proto"],
+)
+
+upb_proto_library(
+    name = "benchmark_descriptor_upb_proto",
+    deps = [":descriptor_proto"],
+)
+
+upb_proto_reflection_library(
+    name = "benchmark_descriptor_upb_proto_reflection",
+    deps = [":descriptor_proto"],
+)
+
+upb_proto_reflection_library(
+    name = "ads_upb_proto_reflection",
+    deps = ["@com_google_googleapis//:ads_proto"],
+)
+
+cc_proto_library(
+    name = "benchmark_descriptor_cc_proto",
+    deps = [":descriptor_proto"],
+)
+
+proto_library(
+    name = "benchmark_descriptor_sv_proto",
+    srcs = ["descriptor_sv.proto"],
+)
+
+cc_proto_library(
+    name = "benchmark_descriptor_sv_cc_proto",
+    deps = [":benchmark_descriptor_sv_proto"],
+)
+
+cc_binary(
+    name = "benchmark",
+    testonly = 1,
+    srcs = ["benchmark.cc"],
+    deps = [
+        ":ads_upb_proto_reflection",
+        ":benchmark_descriptor_cc_proto",
+        ":benchmark_descriptor_sv_cc_proto",
+        ":benchmark_descriptor_upb_proto",
+        ":benchmark_descriptor_upb_proto_reflection",
+        "//:descriptor_upb_proto",
+        "//:reflection",
+        "@com_github_google_benchmark//:benchmark_main",
+        "@com_google_absl//absl/container:flat_hash_set",
+        "@com_google_protobuf//:protobuf",
+    ],
+)
+
+# Size benchmarks.
+
+SIZE_BENCHMARKS = {
+    "empty": "Empty",
+    "descriptor": "FileDescriptorSet",
+    "100_msgs": "Message100",
+    "200_msgs": "Message200",
+    "100_fields": "Message",
+    "200_fields": "Message",
+}
+
+py_binary(
+    name = "gen_synthetic_protos",
+    srcs = ["gen_synthetic_protos.py"],
+    python_version = "PY3",
+)
+
+py_binary(
+    name = "gen_upb_binary_c",
+    srcs = ["gen_upb_binary_c.py"],
+    python_version = "PY3",
+)
+
+py_binary(
+    name = "gen_protobuf_binary_cc",
+    srcs = ["gen_protobuf_binary_cc.py"],
+    python_version = "PY3",
+)
+
+genrule(
+    name = "do_gen_synthetic_protos",
+    tools = [":gen_synthetic_protos"],
+    outs = [
+        "100_msgs.proto",
+        "200_msgs.proto",
+        "100_fields.proto",
+        "200_fields.proto",
+    ],
+    cmd = "$(execpath :gen_synthetic_protos) $(RULEDIR)",
+)
+
+proto_library(
+    name = "100_msgs_proto",
+    srcs = ["100_msgs.proto"],
+)
+
+proto_library(
+    name = "200_msgs_proto",
+    srcs = ["200_msgs.proto"],
+)
+
+proto_library(
+    name = "100_fields_proto",
+    srcs = ["100_fields.proto"],
+)
+
+proto_library(
+    name = "200_fields_proto",
+    srcs = ["200_fields.proto"],
+)
+
+proto_library(
+    name = "empty_proto",
+    srcs = ["empty.proto"],
+)
+
+[(
+upb_proto_library(
+    name = k + "_upb_proto",
+    deps = [":" + k + "_proto"],
+),
+cc_proto_library(
+    name = k + "_cc_proto",
+    deps = [":" + k + "_proto"],
+),
+tmpl_cc_binary(
+    name = k + "_upb_binary",
+    testonly = 1,
+    gen = ":gen_upb_binary_c",
+    args = [
+        package_name() + "/" + k + ".upb.h",
+        "upb_benchmark_" + v,
+    ],
+    deps = [
+        ":" + k + "_upb_proto",
+    ],
+),
+tmpl_cc_binary(
+    name = k + "_protobuf_binary",
+    testonly = 1,
+    gen = ":gen_protobuf_binary_cc",
+    args = [
+        package_name() + "/" + k + ".pb.h",
+        "upb_benchmark::" + v,
+    ],
+    deps = [
+        ":" + k + "_cc_proto",
+    ],
+),
+cc_optimizefor_proto_library(
+    srcs = [k + ".proto"],
+    outs = [k + "_lite.proto"],
+    name = k + "_cc_lite_proto",
+    optimize_for = "LITE_RUNTIME",
+),
+tmpl_cc_binary(
+    name = k + "_lite_protobuf_binary",
+    testonly = 1,
+    gen = ":gen_protobuf_binary_cc",
+    args = [
+        package_name() + "/" + k + "_lite.pb.h",
+        "upb_benchmark::" + v,
+    ],
+    deps = [
+        ":" + k + "_cc_lite_proto",
+    ],
+),
+cc_optimizefor_proto_library(
+    srcs = [k + ".proto"],
+    outs = [k + "_codesize.proto"],
+    name = k + "_cc_codesize_proto",
+    optimize_for = "CODE_SIZE",
+),
+tmpl_cc_binary(
+    name = k + "_codesize_protobuf_binary",
+    testonly = 1,
+    gen = ":gen_protobuf_binary_cc",
+    args = [
+        package_name() + "/" + k + "_codesize.pb.h",
+        "upb_benchmark::" + v,
+    ],
+    deps = [
+        ":" + k + "_cc_codesize_proto",
+    ],
+)
+) for k, v in SIZE_BENCHMARKS.items()]
+
+genrule(
+    testonly = 1,
+    name = "size_data",
+    srcs = expand_suffixes(
+        SIZE_BENCHMARKS.keys(),
+        suffixes = ["_upb_binary", "_protobuf_binary", "_lite_protobuf_binary", "_codesize_protobuf_binary"],
+    ),
+    outs = ["size_data.txt"],
+    # We want --format=GNU which counts rodata with data, not text.
+    cmd = "size $$($$OSTYPE == 'linux-gnu' ? '--format=GNU -d' : '') $(SRCS) > $@",
+    # "size" sometimes isn't available remotely.
+    local = 1,
+)
diff --git a/third_party/upb/benchmarks/BUILD.googleapis b/third_party/upb/benchmarks/BUILD.googleapis
new file mode 100644 (file)
index 0000000..904bdec
--- /dev/null
@@ -0,0 +1,29 @@
+load(
+    "@rules_proto//proto:defs.bzl",
+    "proto_library",
+)
+
+proto_library(
+    name = "ads_proto",
+    srcs = glob([
+        "google/ads/googleads/v5/**/*.proto",
+        "google/api/**/*.proto",
+        "google/rpc/**/*.proto",
+        "google/longrunning/**/*.proto",
+        "google/logging/**/*.proto",
+    ]),
+    #srcs = ["google/ads/googleads/v5/services/google_ads_service.proto"],
+    visibility = ["//visibility:public"],
+    deps = [
+        "@com_google_protobuf//:any_proto",
+        "@com_google_protobuf//:api_proto",
+        "@com_google_protobuf//:descriptor_proto",
+        "@com_google_protobuf//:duration_proto",
+        "@com_google_protobuf//:empty_proto",
+        "@com_google_protobuf//:field_mask_proto",
+        "@com_google_protobuf//:struct_proto",
+        "@com_google_protobuf//:timestamp_proto",
+        "@com_google_protobuf//:type_proto",
+        "@com_google_protobuf//:wrappers_proto",
+    ],
+)
diff --git a/third_party/upb/benchmarks/benchmark.cc b/third_party/upb/benchmarks/benchmark.cc
new file mode 100644 (file)
index 0000000..7f4765a
--- /dev/null
@@ -0,0 +1,258 @@
+
+#include <benchmark/benchmark.h>
+#include <string.h>
+
+#include "absl/container/flat_hash_set.h"
+#include "benchmarks/descriptor.pb.h"
+#include "benchmarks/descriptor.upb.h"
+#include "benchmarks/descriptor.upbdefs.h"
+#include "benchmarks/descriptor_sv.pb.h"
+#include "google/ads/googleads/v5/services/google_ads_service.upbdefs.h"
+#include "google/protobuf/descriptor.pb.h"
+#include "upb/def.hpp"
+
+upb_strview descriptor = benchmarks_descriptor_proto_upbdefinit.descriptor;
+namespace protobuf = ::google::protobuf;
+
+/* A buffer big enough to parse descriptor.proto without going to heap. */
+char buf[65535];
+
+void CollectFileDescriptors(const upb_def_init* file,
+                            std::vector<upb_strview>& serialized_files,
+                            absl::flat_hash_set<const upb_def_init*>& seen) {
+  if (!seen.insert(file).second) return;
+  for (upb_def_init **deps = file->deps; *deps; deps++) {
+    CollectFileDescriptors(*deps, serialized_files, seen);
+  }
+  serialized_files.push_back(file->descriptor);
+}
+
+static void BM_ArenaOneAlloc(benchmark::State& state) {
+  for (auto _ : state) {
+    upb_arena* arena = upb_arena_new();
+    upb_arena_malloc(arena, 1);
+    upb_arena_free(arena);
+  }
+}
+BENCHMARK(BM_ArenaOneAlloc);
+
+static void BM_ArenaInitialBlockOneAlloc(benchmark::State& state) {
+  for (auto _ : state) {
+    upb_arena* arena = upb_arena_init(buf, sizeof(buf), NULL);
+    upb_arena_malloc(arena, 1);
+    upb_arena_free(arena);
+  }
+}
+BENCHMARK(BM_ArenaInitialBlockOneAlloc);
+
+static void BM_LoadDescriptor_Upb(benchmark::State& state) {
+  size_t bytes_per_iter = 0;
+  for (auto _ : state) {
+    upb::SymbolTable symtab;
+    upb_benchmark_DescriptorProto_getmsgdef(symtab.ptr());
+    bytes_per_iter = _upb_symtab_bytesloaded(symtab.ptr());
+  }
+  state.SetBytesProcessed(state.iterations() * bytes_per_iter);
+}
+BENCHMARK(BM_LoadDescriptor_Upb);
+
+static void BM_LoadAdsDescriptor_Upb(benchmark::State& state) {
+  size_t bytes_per_iter = 0;
+  for (auto _ : state) {
+    upb::SymbolTable symtab;
+    google_ads_googleads_v5_services_SearchGoogleAdsRequest_getmsgdef(
+        symtab.ptr());
+    bytes_per_iter = _upb_symtab_bytesloaded(symtab.ptr());
+  }
+  state.SetBytesProcessed(state.iterations() * bytes_per_iter);
+}
+BENCHMARK(BM_LoadAdsDescriptor_Upb);
+
+static void BM_LoadDescriptor_Proto2(benchmark::State& state) {
+  for (auto _ : state) {
+    protobuf::Arena arena;
+    protobuf::StringPiece input(descriptor.data,descriptor.size);
+    auto proto = protobuf::Arena::CreateMessage<protobuf::FileDescriptorProto>(
+        &arena);
+    protobuf::DescriptorPool pool;
+    bool ok = proto->ParseFrom<protobuf::MessageLite::kMergePartial>(input) &&
+              pool.BuildFile(*proto) != nullptr;
+    if (!ok) {
+      printf("Failed to add file.\n");
+      exit(1);
+    }
+  }
+  state.SetBytesProcessed(state.iterations() * descriptor.size);
+}
+BENCHMARK(BM_LoadDescriptor_Proto2);
+
+static void BM_LoadAdsDescriptor_Proto2(benchmark::State& state) {
+  extern upb_def_init google_ads_googleads_v5_services_google_ads_service_proto_upbdefinit;
+  std::vector<upb_strview> serialized_files;
+  absl::flat_hash_set<const upb_def_init*> seen_files;
+  CollectFileDescriptors(
+      &google_ads_googleads_v5_services_google_ads_service_proto_upbdefinit,
+      serialized_files, seen_files);
+  size_t bytes_per_iter = 0;
+  for (auto _ : state) {
+    bytes_per_iter = 0;
+    protobuf::Arena arena;
+    protobuf::DescriptorPool pool;
+    for (auto file : serialized_files) {
+      protobuf::StringPiece input(file.data, file.size);
+      auto proto = protobuf::Arena::CreateMessage<protobuf::FileDescriptorProto>(
+          &arena);
+      bool ok = proto->ParseFrom<protobuf::MessageLite::kMergePartial>(input) &&
+                pool.BuildFile(*proto) != nullptr;
+      if (!ok) {
+        printf("Failed to add file.\n");
+        exit(1);
+      }
+      bytes_per_iter += input.size();
+    }
+  }
+  state.SetBytesProcessed(state.iterations() * bytes_per_iter);
+}
+BENCHMARK(BM_LoadAdsDescriptor_Proto2);
+
+enum CopyStrings {
+  Copy,
+  Alias,
+};
+
+enum ArenaMode {
+  NoArena,
+  UseArena,
+  InitBlock,
+};
+
+template <ArenaMode AMode, CopyStrings Copy>
+static void BM_Parse_Upb_FileDesc(benchmark::State& state) {
+  size_t bytes = 0;
+  for (auto _ : state) {
+    upb_arena *arena;
+    if (AMode == InitBlock) {
+      arena = upb_arena_init(buf, sizeof(buf), NULL);
+    } else {
+      arena = upb_arena_new();
+    }
+    upb_benchmark_FileDescriptorProto* set =
+        upb_benchmark_FileDescriptorProto_parse_ex(
+            descriptor.data, descriptor.size, arena,
+            Copy == Alias ? UPB_DECODE_ALIAS : 0);
+    if (!set) {
+      printf("Failed to parse.\n");
+      exit(1);
+    }
+    bytes += descriptor.size;
+    upb_arena_free(arena);
+  }
+  state.SetBytesProcessed(state.iterations() * descriptor.size);
+}
+BENCHMARK_TEMPLATE(BM_Parse_Upb_FileDesc, UseArena, Copy);
+BENCHMARK_TEMPLATE(BM_Parse_Upb_FileDesc, UseArena, Alias);
+BENCHMARK_TEMPLATE(BM_Parse_Upb_FileDesc, InitBlock, Copy);
+BENCHMARK_TEMPLATE(BM_Parse_Upb_FileDesc, InitBlock, Alias);
+
+template <ArenaMode AMode, class P>
+struct Proto2Factory;
+
+template<class P>
+struct Proto2Factory<NoArena, P> {
+ public:
+  P* GetProto() { return &proto_; }
+
+ private:
+  P proto_;
+};
+
+template <class P>
+struct Proto2Factory<UseArena, P> {
+ public:
+  P* GetProto() { return protobuf::Arena::CreateMessage<P>(&arena_); }
+
+ private:
+  protobuf::Arena arena_;
+};
+
+template <class P>
+struct Proto2Factory<InitBlock, P> {
+ public:
+  Proto2Factory() : arena_(GetOptions()) {}
+  P* GetProto() { return protobuf::Arena::CreateMessage<P>(&arena_); }
+
+ private:
+  protobuf::ArenaOptions GetOptions() {
+    protobuf::ArenaOptions opts;
+    opts.initial_block = buf;
+    opts.initial_block_size = sizeof(buf);
+    return opts;
+  }
+
+  protobuf::Arena arena_;
+};
+
+using FileDesc = ::upb_benchmark::FileDescriptorProto;
+using FileDescSV = ::upb_benchmark::sv::FileDescriptorProto;
+
+template <class P, ArenaMode AMode, CopyStrings kCopy>
+void BM_Parse_Proto2(benchmark::State& state) {
+  size_t bytes = 0;
+  constexpr protobuf::MessageLite::ParseFlags kParseFlags =
+      kCopy == Copy
+          ? protobuf::MessageLite::ParseFlags::kMergePartial
+          : protobuf::MessageLite::ParseFlags::kMergePartialWithAliasing;
+  for (auto _ : state) {
+    Proto2Factory<AMode, P> proto_factory;
+    auto proto = proto_factory.GetProto();
+    protobuf::StringPiece input(descriptor.data,descriptor.size);
+    bool ok = proto->template ParseFrom<kParseFlags>(input);
+    if (!ok) {
+      printf("Failed to parse.\n");
+      exit(1);
+    }
+    bytes += descriptor.size;
+  }
+  state.SetBytesProcessed(state.iterations() * descriptor.size);
+}
+BENCHMARK_TEMPLATE(BM_Parse_Proto2, FileDesc, NoArena, Copy);
+BENCHMARK_TEMPLATE(BM_Parse_Proto2, FileDesc, UseArena, Copy);
+BENCHMARK_TEMPLATE(BM_Parse_Proto2, FileDesc, InitBlock, Copy);
+BENCHMARK_TEMPLATE(BM_Parse_Proto2, FileDescSV, InitBlock, Alias);
+
+static void BM_SerializeDescriptor_Proto2(benchmark::State& state) {
+  size_t bytes = 0;
+  upb_benchmark::FileDescriptorProto proto;
+  proto.ParseFromArray(descriptor.data, descriptor.size);
+  for (auto _ : state) {
+    proto.SerializePartialToArray(buf, sizeof(buf));
+    bytes += descriptor.size;
+  }
+  state.SetBytesProcessed(state.iterations() * descriptor.size);
+}
+BENCHMARK(BM_SerializeDescriptor_Proto2);
+
+static void BM_SerializeDescriptor_Upb(benchmark::State& state) {
+  int64_t total = 0;
+  upb_arena* arena = upb_arena_new();
+  upb_benchmark_FileDescriptorProto* set =
+      upb_benchmark_FileDescriptorProto_parse(descriptor.data, descriptor.size,
+                                              arena);
+  if (!set) {
+    printf("Failed to parse.\n");
+    exit(1);
+  }
+  for (auto _ : state) {
+    upb_arena* enc_arena = upb_arena_init(buf, sizeof(buf), NULL);
+    size_t size;
+    char* data =
+        upb_benchmark_FileDescriptorProto_serialize(set, enc_arena, &size);
+    if (!data) {
+      printf("Failed to serialize.\n");
+      exit(1);
+    }
+    total += size;
+  }
+  state.SetBytesProcessed(total);
+}
+BENCHMARK(BM_SerializeDescriptor_Upb);
diff --git a/third_party/upb/benchmarks/build_defs.bzl b/third_party/upb/benchmarks/build_defs.bzl
new file mode 100644 (file)
index 0000000..ff534fb
--- /dev/null
@@ -0,0 +1,63 @@
+
+# copybara:insert_for_google3_begin
+# load("//tools/build_defs/proto/cpp:cc_proto_library.bzl", _cc_proto_library="cc_proto_library")
+# copybara:insert_end
+
+# copybara:strip_for_google3_begin
+_cc_proto_library = native.cc_proto_library
+# copybara:strip_end
+
+def proto_library(**kwargs):
+    native.proto_library(
+        # copybara:insert_for_google3_begin
+        # cc_api_version = 2,
+        # copybara:insert_end
+        **kwargs,
+    )
+
+def tmpl_cc_binary(name, gen, args, replacements = [], **kwargs):
+    srcs = [name + ".cc"]
+    native.genrule(
+        name = name + "_gen_srcs",
+        tools = [gen],
+        outs = srcs,
+        cmd = "$(location " + gen + ") " + " ".join(args) + " > $@",
+    )
+
+    native.cc_binary(
+        # copybara:insert_for_google3_begin
+        # malloc="//base:system_malloc",
+        # features = ["-static_linking_mode"],
+        # copybara:insert_end
+        name = name,
+        srcs = srcs,
+        **kwargs,
+    )
+
+def cc_optimizefor_proto_library(name, srcs, outs, optimize_for):
+    if len(srcs) != 1:
+        fail("Currently srcs must have exactly 1 element")
+
+    native.genrule(
+        name = name + "_gen_proto",
+        srcs = srcs,
+        outs = outs,
+        cmd = "cp $< $@ && chmod a+w $@ && echo 'option optimize_for = " + optimize_for + ";' >> $@",
+    )
+
+    proto_library(
+        name = name + "_proto",
+        srcs = outs,
+    )
+
+    _cc_proto_library(
+        name = name,
+        deps = [":" + name + "_proto"],
+    )
+
+def expand_suffixes(vals, suffixes):
+    ret = []
+    for val in vals:
+        for suffix in suffixes:
+            ret.append(val + suffix)
+    return ret
diff --git a/third_party/upb/benchmarks/compare.py b/third_party/upb/benchmarks/compare.py
new file mode 100755 (executable)
index 0000000..8d62d94
--- /dev/null
@@ -0,0 +1,89 @@
+#!/usr/bin/env python3
+"""Benchmarks the current working directory against a given baseline.
+
+This script benchmarks both size and speed. Sample output:
+"""
+
+import contextlib
+import json
+import os
+import re
+import subprocess
+import sys
+import tempfile
+
+@contextlib.contextmanager
+def GitWorktree(commit):
+  tmpdir = tempfile.mkdtemp()
+  subprocess.run(['git', 'worktree', 'add', '-q', '-d', tmpdir, commit], check=True)
+  cwd = os.getcwd()
+  os.chdir(tmpdir)
+  try:
+    yield tmpdir
+  finally:
+    os.chdir(cwd)
+    subprocess.run(['git', 'worktree', 'remove', tmpdir], check=True)
+
+def Run(cmd):
+  subprocess.check_call(cmd, shell=True)
+
+def Benchmark(outbase, bench_cpu=True, runs=12, fasttable=False):
+  tmpfile = "/tmp/bench-output.json"
+  Run("rm -rf {}".format(tmpfile))
+  #Run("CC=clang bazel test ...")
+  if fasttable:
+    extra_args = " --//:fasttable_enabled=true"
+  else:
+    extra_args = ""
+
+  if bench_cpu:
+    Run("CC=clang bazel build -c opt --copt=-march=native benchmarks:benchmark" + extra_args)
+    Run("./bazel-bin/benchmarks/benchmark --benchmark_out_format=json --benchmark_out={} --benchmark_repetitions={}".format(tmpfile, runs))
+    with open(tmpfile) as f:
+      bench_json = json.load(f)
+
+    # Translate into the format expected by benchstat.
+    with open(outbase + ".txt", "w") as f:
+      for run in bench_json["benchmarks"]:
+        name = run["name"]
+        name = name.replace(" ", "")
+        name = re.sub(r'^BM_', 'Benchmark', name)
+        if name.endswith("_mean") or name.endswith("_median") or name.endswith("_stddev"):
+          continue
+        values = (name, run["iterations"], run["cpu_time"])
+        print("{} {} {} ns/op".format(*values), file=f)
+
+  Run("CC=clang bazel build -c opt --copt=-g tests:conformance_upb" + extra_args)
+  Run("cp -f bazel-bin/tests/conformance_upb {}.bin".format(outbase))
+
+
+baseline = "master"
+bench_cpu = False
+fasttable = False
+
+if len(sys.argv) > 1:
+  baseline = sys.argv[1]
+
+  # Quickly verify that the baseline exists.
+  with GitWorktree(baseline):
+    pass
+
+# Benchmark our current directory first, since it's more likely to be broken.
+Benchmark("/tmp/new", bench_cpu, fasttable=fasttable)
+
+# Benchmark the baseline.
+with GitWorktree(baseline):
+  Benchmark("/tmp/old", bench_cpu, fasttable=fasttable)
+
+print()
+print()
+
+if bench_cpu:
+  Run("~/go/bin/benchstat /tmp/old.txt /tmp/new.txt")
+
+print()
+print()
+
+Run("objcopy --strip-debug /tmp/old.bin /tmp/old.bin.stripped")
+Run("objcopy --strip-debug /tmp/new.bin /tmp/new.bin.stripped")
+Run("~/code/bloaty/bloaty /tmp/new.bin.stripped -- /tmp/old.bin.stripped --debug-file=/tmp/old.bin --debug-file=/tmp/new.bin -d compileunits,symbols")
diff --git a/third_party/upb/benchmarks/descriptor.proto b/third_party/upb/benchmarks/descriptor.proto
new file mode 100644 (file)
index 0000000..b69b27f
--- /dev/null
@@ -0,0 +1,905 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+//  Based on original Protocol Buffers design by
+//  Sanjay Ghemawat, Jeff Dean, and others.
+//
+// The messages in this file describe the definitions found in .proto files.
+// A valid .proto file can be translated directly to a FileDescriptorProto
+// without any other information (e.g. without reading its imports).
+
+
+syntax = "proto2";
+
+package upb_benchmark;
+
+option go_package = "google.golang.org/protobuf/types/descriptorpb";
+option java_package = "com.google.protobuf";
+option java_outer_classname = "DescriptorProtos";
+option csharp_namespace = "Google.Protobuf.Reflection";
+option objc_class_prefix = "GPB";
+option cc_enable_arenas = true;
+
+// The protocol compiler can output a FileDescriptorSet containing the .proto
+// files it parses.
+message FileDescriptorSet {
+  repeated FileDescriptorProto file = 1;
+}
+
+// Describes a complete .proto file.
+message FileDescriptorProto {
+  optional string name = 1;     // file name, relative to root of source tree
+  optional string package = 2;  // e.g. "foo", "foo.bar", etc.
+
+  // Names of files imported by this file.
+  repeated string dependency = 3;
+  // Indexes of the public imported files in the dependency list above.
+  repeated int32 public_dependency = 10;
+  // Indexes of the weak imported files in the dependency list.
+  // For Google-internal migration only. Do not use.
+  repeated int32 weak_dependency = 11;
+
+  // All top-level definitions in this file.
+  repeated DescriptorProto message_type = 4;
+  repeated EnumDescriptorProto enum_type = 5;
+  repeated ServiceDescriptorProto service = 6;
+  repeated FieldDescriptorProto extension = 7;
+
+  optional FileOptions options = 8;
+
+  // This field contains optional information about the original source code.
+  // You may safely remove this entire field without harming runtime
+  // functionality of the descriptors -- the information is needed only by
+  // development tools.
+  optional SourceCodeInfo source_code_info = 9;
+
+  // The syntax of the proto file.
+  // The supported values are "proto2" and "proto3".
+  optional string syntax = 12;
+}
+
+// Describes a message type.
+message DescriptorProto {
+  optional string name = 1;
+
+  repeated FieldDescriptorProto field = 2;
+  repeated FieldDescriptorProto extension = 6;
+
+  repeated DescriptorProto nested_type = 3;
+  repeated EnumDescriptorProto enum_type = 4;
+
+  message ExtensionRange {
+    optional int32 start = 1;  // Inclusive.
+    optional int32 end = 2;    // Exclusive.
+
+    optional ExtensionRangeOptions options = 3;
+  }
+  repeated ExtensionRange extension_range = 5;
+
+  repeated OneofDescriptorProto oneof_decl = 8;
+
+  optional MessageOptions options = 7;
+
+  // Range of reserved tag numbers. Reserved tag numbers may not be used by
+  // fields or extension ranges in the same message. Reserved ranges may
+  // not overlap.
+  message ReservedRange {
+    optional int32 start = 1;  // Inclusive.
+    optional int32 end = 2;    // Exclusive.
+  }
+  repeated ReservedRange reserved_range = 9;
+  // Reserved field names, which may not be used by fields in the same message.
+  // A given name may only be reserved once.
+  repeated string reserved_name = 10;
+}
+
+message ExtensionRangeOptions {
+  // The parser stores options it doesn't recognize here. See above.
+  repeated UninterpretedOption uninterpreted_option = 999;
+
+
+  // Clients can define custom options in extensions of this message. See above.
+  extensions 1000 to max;
+}
+
+// Describes a field within a message.
+message FieldDescriptorProto {
+  enum Type {
+    // 0 is reserved for errors.
+    // Order is weird for historical reasons.
+    TYPE_DOUBLE = 1;
+    TYPE_FLOAT = 2;
+    // Not ZigZag encoded.  Negative numbers take 10 bytes.  Use TYPE_SINT64 if
+    // negative values are likely.
+    TYPE_INT64 = 3;
+    TYPE_UINT64 = 4;
+    // Not ZigZag encoded.  Negative numbers take 10 bytes.  Use TYPE_SINT32 if
+    // negative values are likely.
+    TYPE_INT32 = 5;
+    TYPE_FIXED64 = 6;
+    TYPE_FIXED32 = 7;
+    TYPE_BOOL = 8;
+    TYPE_STRING = 9;
+    // Tag-delimited aggregate.
+    // Group type is deprecated and not supported in proto3. However, Proto3
+    // implementations should still be able to parse the group wire format and
+    // treat group fields as unknown fields.
+    TYPE_GROUP = 10;
+    TYPE_MESSAGE = 11;  // Length-delimited aggregate.
+
+    // New in version 2.
+    TYPE_BYTES = 12;
+    TYPE_UINT32 = 13;
+    TYPE_ENUM = 14;
+    TYPE_SFIXED32 = 15;
+    TYPE_SFIXED64 = 16;
+    TYPE_SINT32 = 17;  // Uses ZigZag encoding.
+    TYPE_SINT64 = 18;  // Uses ZigZag encoding.
+  }
+
+  enum Label {
+    // 0 is reserved for errors
+    LABEL_OPTIONAL = 1;
+    LABEL_REQUIRED = 2;
+    LABEL_REPEATED = 3;
+  }
+
+  optional string name = 1;
+  optional int32 number = 3;
+  optional Label label = 4;
+
+  // If type_name is set, this need not be set.  If both this and type_name
+  // are set, this must be one of TYPE_ENUM, TYPE_MESSAGE or TYPE_GROUP.
+  optional Type type = 5;
+
+  // For message and enum types, this is the name of the type.  If the name
+  // starts with a '.', it is fully-qualified.  Otherwise, C++-like scoping
+  // rules are used to find the type (i.e. first the nested types within this
+  // message are searched, then within the parent, on up to the root
+  // namespace).
+  optional string type_name = 6;
+
+  // For extensions, this is the name of the type being extended.  It is
+  // resolved in the same manner as type_name.
+  optional string extendee = 2;
+
+  // For numeric types, contains the original text representation of the value.
+  // For booleans, "true" or "false".
+  // For strings, contains the default text contents (not escaped in any way).
+  // For bytes, contains the C escaped value.  All bytes >= 128 are escaped.
+  // TODO(kenton):  Base-64 encode?
+  optional string default_value = 7;
+
+  // If set, gives the index of a oneof in the containing type's oneof_decl
+  // list.  This field is a member of that oneof.
+  optional int32 oneof_index = 9;
+
+  // JSON name of this field. The value is set by protocol compiler. If the
+  // user has set a "json_name" option on this field, that option's value
+  // will be used. Otherwise, it's deduced from the field's name by converting
+  // it to camelCase.
+  optional string json_name = 10;
+
+  optional FieldOptions options = 8;
+
+  // If true, this is a proto3 "optional". When a proto3 field is optional, it
+  // tracks presence regardless of field type.
+  //
+  // When proto3_optional is true, this field must be belong to a oneof to
+  // signal to old proto3 clients that presence is tracked for this field. This
+  // oneof is known as a "synthetic" oneof, and this field must be its sole
+  // member (each proto3 optional field gets its own synthetic oneof). Synthetic
+  // oneofs exist in the descriptor only, and do not generate any API. Synthetic
+  // oneofs must be ordered after all "real" oneofs.
+  //
+  // For message fields, proto3_optional doesn't create any semantic change,
+  // since non-repeated message fields always track presence. However it still
+  // indicates the semantic detail of whether the user wrote "optional" or not.
+  // This can be useful for round-tripping the .proto file. For consistency we
+  // give message fields a synthetic oneof also, even though it is not required
+  // to track presence. This is especially important because the parser can't
+  // tell if a field is a message or an enum, so it must always create a
+  // synthetic oneof.
+  //
+  // Proto2 optional fields do not set this flag, because they already indicate
+  // optional with `LABEL_OPTIONAL`.
+  optional bool proto3_optional = 17;
+}
+
+// Describes a oneof.
+message OneofDescriptorProto {
+  optional string name = 1;
+  optional OneofOptions options = 2;
+}
+
+// Describes an enum type.
+message EnumDescriptorProto {
+  optional string name = 1;
+
+  repeated EnumValueDescriptorProto value = 2;
+
+  optional EnumOptions options = 3;
+
+  // Range of reserved numeric values. Reserved values may not be used by
+  // entries in the same enum. Reserved ranges may not overlap.
+  //
+  // Note that this is distinct from DescriptorProto.ReservedRange in that it
+  // is inclusive such that it can appropriately represent the entire int32
+  // domain.
+  message EnumReservedRange {
+    optional int32 start = 1;  // Inclusive.
+    optional int32 end = 2;    // Inclusive.
+  }
+
+  // Range of reserved numeric values. Reserved numeric values may not be used
+  // by enum values in the same enum declaration. Reserved ranges may not
+  // overlap.
+  repeated EnumReservedRange reserved_range = 4;
+
+  // Reserved enum value names, which may not be reused. A given name may only
+  // be reserved once.
+  repeated string reserved_name = 5;
+}
+
+// Describes a value within an enum.
+message EnumValueDescriptorProto {
+  optional string name = 1;
+  optional int32 number = 2;
+
+  optional EnumValueOptions options = 3;
+}
+
+// Describes a service.
+message ServiceDescriptorProto {
+  optional string name = 1;
+  repeated MethodDescriptorProto method = 2;
+
+  optional ServiceOptions options = 3;
+}
+
+// Describes a method of a service.
+message MethodDescriptorProto {
+  optional string name = 1;
+
+  // Input and output type names.  These are resolved in the same way as
+  // FieldDescriptorProto.type_name, but must refer to a message type.
+  optional string input_type = 2;
+  optional string output_type = 3;
+
+  optional MethodOptions options = 4;
+
+  // Identifies if client streams multiple client messages
+  optional bool client_streaming = 5 [default = false];
+  // Identifies if server streams multiple server messages
+  optional bool server_streaming = 6 [default = false];
+}
+
+
+// ===================================================================
+// Options
+
+// Each of the definitions above may have "options" attached.  These are
+// just annotations which may cause code to be generated slightly differently
+// or may contain hints for code that manipulates protocol messages.
+//
+// Clients may define custom options as extensions of the *Options messages.
+// These extensions may not yet be known at parsing time, so the parser cannot
+// store the values in them.  Instead it stores them in a field in the *Options
+// message called uninterpreted_option. This field must have the same name
+// across all *Options messages. We then use this field to populate the
+// extensions when we build a descriptor, at which point all protos have been
+// parsed and so all extensions are known.
+//
+// Extension numbers for custom options may be chosen as follows:
+// * For options which will only be used within a single application or
+//   organization, or for experimental options, use field numbers 50000
+//   through 99999.  It is up to you to ensure that you do not use the
+//   same number for multiple options.
+// * For options which will be published and used publicly by multiple
+//   independent entities, e-mail protobuf-global-extension-registry@google.com
+//   to reserve extension numbers. Simply provide your project name (e.g.
+//   Objective-C plugin) and your project website (if available) -- there's no
+//   need to explain how you intend to use them. Usually you only need one
+//   extension number. You can declare multiple options with only one extension
+//   number by putting them in a sub-message. See the Custom Options section of
+//   the docs for examples:
+//   https://developers.google.com/protocol-buffers/docs/proto#options
+//   If this turns out to be popular, a web service will be set up
+//   to automatically assign option numbers.
+
+message FileOptions {
+
+  // Sets the Java package where classes generated from this .proto will be
+  // placed.  By default, the proto package is used, but this is often
+  // inappropriate because proto packages do not normally start with backwards
+  // domain names.
+  optional string java_package = 1;
+
+
+  // If set, all the classes from the .proto file are wrapped in a single
+  // outer class with the given name.  This applies to both Proto1
+  // (equivalent to the old "--one_java_file" option) and Proto2 (where
+  // a .proto always translates to a single class, but you may want to
+  // explicitly choose the class name).
+  optional string java_outer_classname = 8;
+
+  // If set true, then the Java code generator will generate a separate .java
+  // file for each top-level message, enum, and service defined in the .proto
+  // file.  Thus, these types will *not* be nested inside the outer class
+  // named by java_outer_classname.  However, the outer class will still be
+  // generated to contain the file's getDescriptor() method as well as any
+  // top-level extensions defined in the file.
+  optional bool java_multiple_files = 10 [default = false];
+
+  // This option does nothing.
+  optional bool java_generate_equals_and_hash = 20 [deprecated=true];
+
+  // If set true, then the Java2 code generator will generate code that
+  // throws an exception whenever an attempt is made to assign a non-UTF-8
+  // byte sequence to a string field.
+  // Message reflection will do the same.
+  // However, an extension field still accepts non-UTF-8 byte sequences.
+  // This option has no effect on when used with the lite runtime.
+  optional bool java_string_check_utf8 = 27 [default = false];
+
+
+  // Generated classes can be optimized for speed or code size.
+  enum OptimizeMode {
+    SPEED = 1;         // Generate complete code for parsing, serialization,
+                       // etc.
+    CODE_SIZE = 2;     // Use ReflectionOps to implement these methods.
+    LITE_RUNTIME = 3;  // Generate code using MessageLite and the lite runtime.
+  }
+  optional OptimizeMode optimize_for = 9 [default = SPEED];
+
+  // Sets the Go package where structs generated from this .proto will be
+  // placed. If omitted, the Go package will be derived from the following:
+  //   - The basename of the package import path, if provided.
+  //   - Otherwise, the package statement in the .proto file, if present.
+  //   - Otherwise, the basename of the .proto file, without extension.
+  optional string go_package = 11;
+
+
+
+
+  // Should generic services be generated in each language?  "Generic" services
+  // are not specific to any particular RPC system.  They are generated by the
+  // main code generators in each language (without additional plugins).
+  // Generic services were the only kind of service generation supported by
+  // early versions of google.protobuf.
+  //
+  // Generic services are now considered deprecated in favor of using plugins
+  // that generate code specific to your particular RPC system.  Therefore,
+  // these default to false.  Old code which depends on generic services should
+  // explicitly set them to true.
+  optional bool cc_generic_services = 16 [default = false];
+  optional bool java_generic_services = 17 [default = false];
+  optional bool py_generic_services = 18 [default = false];
+  optional bool php_generic_services = 42 [default = false];
+
+  // Is this file deprecated?
+  // Depending on the target platform, this can emit Deprecated annotations
+  // for everything in the file, or it will be completely ignored; in the very
+  // least, this is a formalization for deprecating files.
+  optional bool deprecated = 23 [default = false];
+
+  // Enables the use of arenas for the proto messages in this file. This applies
+  // only to generated classes for C++.
+  optional bool cc_enable_arenas = 31 [default = true];
+
+
+  // Sets the objective c class prefix which is prepended to all objective c
+  // generated classes from this .proto. There is no default.
+  optional string objc_class_prefix = 36;
+
+  // Namespace for generated classes; defaults to the package.
+  optional string csharp_namespace = 37;
+
+  // By default Swift generators will take the proto package and CamelCase it
+  // replacing '.' with underscore and use that to prefix the types/symbols
+  // defined. When this options is provided, they will use this value instead
+  // to prefix the types/symbols defined.
+  optional string swift_prefix = 39;
+
+  // Sets the php class prefix which is prepended to all php generated classes
+  // from this .proto. Default is empty.
+  optional string php_class_prefix = 40;
+
+  // Use this option to change the namespace of php generated classes. Default
+  // is empty. When this option is empty, the package name will be used for
+  // determining the namespace.
+  optional string php_namespace = 41;
+
+  // Use this option to change the namespace of php generated metadata classes.
+  // Default is empty. When this option is empty, the proto file name will be
+  // used for determining the namespace.
+  optional string php_metadata_namespace = 44;
+
+  // Use this option to change the package of ruby generated classes. Default
+  // is empty. When this option is not set, the package name will be used for
+  // determining the ruby package.
+  optional string ruby_package = 45;
+
+
+  // The parser stores options it doesn't recognize here.
+  // See the documentation for the "Options" section above.
+  repeated UninterpretedOption uninterpreted_option = 999;
+
+  // Clients can define custom options in extensions of this message.
+  // See the documentation for the "Options" section above.
+  extensions 1000 to max;
+
+  reserved 38;
+}
+
+message MessageOptions {
+  // Set true to use the old proto1 MessageSet wire format for extensions.
+  // This is provided for backwards-compatibility with the MessageSet wire
+  // format.  You should not use this for any other reason:  It's less
+  // efficient, has fewer features, and is more complicated.
+  //
+  // The message must be defined exactly as follows:
+  //   message Foo {
+  //     option message_set_wire_format = true;
+  //     extensions 4 to max;
+  //   }
+  // Note that the message cannot have any defined fields; MessageSets only
+  // have extensions.
+  //
+  // All extensions of your type must be singular messages; e.g. they cannot
+  // be int32s, enums, or repeated messages.
+  //
+  // Because this is an option, the above two restrictions are not enforced by
+  // the protocol compiler.
+  optional bool message_set_wire_format = 1 [default = false];
+
+  // Disables the generation of the standard "descriptor()" accessor, which can
+  // conflict with a field of the same name.  This is meant to make migration
+  // from proto1 easier; new code should avoid fields named "descriptor".
+  optional bool no_standard_descriptor_accessor = 2 [default = false];
+
+  // Is this message deprecated?
+  // Depending on the target platform, this can emit Deprecated annotations
+  // for the message, or it will be completely ignored; in the very least,
+  // this is a formalization for deprecating messages.
+  optional bool deprecated = 3 [default = false];
+
+  // Whether the message is an automatically generated map entry type for the
+  // maps field.
+  //
+  // For maps fields:
+  //     map<KeyType, ValueType> map_field = 1;
+  // The parsed descriptor looks like:
+  //     message MapFieldEntry {
+  //         option map_entry = true;
+  //         optional KeyType key = 1;
+  //         optional ValueType value = 2;
+  //     }
+  //     repeated MapFieldEntry map_field = 1;
+  //
+  // Implementations may choose not to generate the map_entry=true message, but
+  // use a native map in the target language to hold the keys and values.
+  // The reflection APIs in such implementations still need to work as
+  // if the field is a repeated message field.
+  //
+  // NOTE: Do not set the option in .proto files. Always use the maps syntax
+  // instead. The option should only be implicitly set by the proto compiler
+  // parser.
+  optional bool map_entry = 7;
+
+  reserved 8;  // javalite_serializable
+  reserved 9;  // javanano_as_lite
+
+
+  // The parser stores options it doesn't recognize here. See above.
+  repeated UninterpretedOption uninterpreted_option = 999;
+
+  // Clients can define custom options in extensions of this message. See above.
+  extensions 1000 to max;
+}
+
+message FieldOptions {
+  // The ctype option instructs the C++ code generator to use a different
+  // representation of the field than it normally would.  See the specific
+  // options below.  This option is not yet implemented in the open source
+  // release -- sorry, we'll try to include it in a future version!
+  optional CType ctype = 1 [default = STRING];
+  enum CType {
+    // Default mode.
+    STRING = 0;
+
+    CORD = 1;
+
+    STRING_PIECE = 2;
+  }
+  // The packed option can be enabled for repeated primitive fields to enable
+  // a more efficient representation on the wire. Rather than repeatedly
+  // writing the tag and type for each element, the entire array is encoded as
+  // a single length-delimited blob. In proto3, only explicit setting it to
+  // false will avoid using packed encoding.
+  optional bool packed = 2;
+
+  // The jstype option determines the JavaScript type used for values of the
+  // field.  The option is permitted only for 64 bit integral and fixed types
+  // (int64, uint64, sint64, fixed64, sfixed64).  A field with jstype JS_STRING
+  // is represented as JavaScript string, which avoids loss of precision that
+  // can happen when a large value is converted to a floating point JavaScript.
+  // Specifying JS_NUMBER for the jstype causes the generated JavaScript code to
+  // use the JavaScript "number" type.  The behavior of the default option
+  // JS_NORMAL is implementation dependent.
+  //
+  // This option is an enum to permit additional types to be added, e.g.
+  // goog.math.Integer.
+  optional JSType jstype = 6 [default = JS_NORMAL];
+  enum JSType {
+    // Use the default type.
+    JS_NORMAL = 0;
+
+    // Use JavaScript strings.
+    JS_STRING = 1;
+
+    // Use JavaScript numbers.
+    JS_NUMBER = 2;
+  }
+
+  // Should this field be parsed lazily?  Lazy applies only to message-type
+  // fields.  It means that when the outer message is initially parsed, the
+  // inner message's contents will not be parsed but instead stored in encoded
+  // form.  The inner message will actually be parsed when it is first accessed.
+  //
+  // This is only a hint.  Implementations are free to choose whether to use
+  // eager or lazy parsing regardless of the value of this option.  However,
+  // setting this option true suggests that the protocol author believes that
+  // using lazy parsing on this field is worth the additional bookkeeping
+  // overhead typically needed to implement it.
+  //
+  // This option does not affect the public interface of any generated code;
+  // all method signatures remain the same.  Furthermore, thread-safety of the
+  // interface is not affected by this option; const methods remain safe to
+  // call from multiple threads concurrently, while non-const methods continue
+  // to require exclusive access.
+  //
+  //
+  // Note that implementations may choose not to check required fields within
+  // a lazy sub-message.  That is, calling IsInitialized() on the outer message
+  // may return true even if the inner message has missing required fields.
+  // This is necessary because otherwise the inner message would have to be
+  // parsed in order to perform the check, defeating the purpose of lazy
+  // parsing.  An implementation which chooses not to check required fields
+  // must be consistent about it.  That is, for any particular sub-message, the
+  // implementation must either *always* check its required fields, or *never*
+  // check its required fields, regardless of whether or not the message has
+  // been parsed.
+  optional bool lazy = 5 [default = false];
+
+  // Is this field deprecated?
+  // Depending on the target platform, this can emit Deprecated annotations
+  // for accessors, or it will be completely ignored; in the very least, this
+  // is a formalization for deprecating fields.
+  optional bool deprecated = 3 [default = false];
+
+  // For Google-internal migration only. Do not use.
+  optional bool weak = 10 [default = false];
+
+
+  // The parser stores options it doesn't recognize here. See above.
+  repeated UninterpretedOption uninterpreted_option = 999;
+
+  // Clients can define custom options in extensions of this message. See above.
+  extensions 1000 to max;
+
+  reserved 4;  // removed jtype
+}
+
+message OneofOptions {
+  // The parser stores options it doesn't recognize here. See above.
+  repeated UninterpretedOption uninterpreted_option = 999;
+
+  // Clients can define custom options in extensions of this message. See above.
+  extensions 1000 to max;
+}
+
+message EnumOptions {
+
+  // Set this option to true to allow mapping different tag names to the same
+  // value.
+  optional bool allow_alias = 2;
+
+  // Is this enum deprecated?
+  // Depending on the target platform, this can emit Deprecated annotations
+  // for the enum, or it will be completely ignored; in the very least, this
+  // is a formalization for deprecating enums.
+  optional bool deprecated = 3 [default = false];
+
+  reserved 5;  // javanano_as_lite
+
+  // The parser stores options it doesn't recognize here. See above.
+  repeated UninterpretedOption uninterpreted_option = 999;
+
+  // Clients can define custom options in extensions of this message. See above.
+  extensions 1000 to max;
+}
+
+message EnumValueOptions {
+  // Is this enum value deprecated?
+  // Depending on the target platform, this can emit Deprecated annotations
+  // for the enum value, or it will be completely ignored; in the very least,
+  // this is a formalization for deprecating enum values.
+  optional bool deprecated = 1 [default = false];
+
+  // The parser stores options it doesn't recognize here. See above.
+  repeated UninterpretedOption uninterpreted_option = 999;
+
+  // Clients can define custom options in extensions of this message. See above.
+  extensions 1000 to max;
+}
+
+message ServiceOptions {
+
+  // Note:  Field numbers 1 through 32 are reserved for Google's internal RPC
+  //   framework.  We apologize for hoarding these numbers to ourselves, but
+  //   we were already using them long before we decided to release Protocol
+  //   Buffers.
+
+  // Is this service deprecated?
+  // Depending on the target platform, this can emit Deprecated annotations
+  // for the service, or it will be completely ignored; in the very least,
+  // this is a formalization for deprecating services.
+  optional bool deprecated = 33 [default = false];
+
+  // The parser stores options it doesn't recognize here. See above.
+  repeated UninterpretedOption uninterpreted_option = 999;
+
+  // Clients can define custom options in extensions of this message. See above.
+  extensions 1000 to max;
+}
+
+message MethodOptions {
+
+  // Note:  Field numbers 1 through 32 are reserved for Google's internal RPC
+  //   framework.  We apologize for hoarding these numbers to ourselves, but
+  //   we were already using them long before we decided to release Protocol
+  //   Buffers.
+
+  // Is this method deprecated?
+  // Depending on the target platform, this can emit Deprecated annotations
+  // for the method, or it will be completely ignored; in the very least,
+  // this is a formalization for deprecating methods.
+  optional bool deprecated = 33 [default = false];
+
+  // Is this method side-effect-free (or safe in HTTP parlance), or idempotent,
+  // or neither? HTTP based RPC implementation may choose GET verb for safe
+  // methods, and PUT verb for idempotent methods instead of the default POST.
+  enum IdempotencyLevel {
+    IDEMPOTENCY_UNKNOWN = 0;
+    NO_SIDE_EFFECTS = 1;  // implies idempotent
+    IDEMPOTENT = 2;       // idempotent, but may have side effects
+  }
+  optional IdempotencyLevel idempotency_level = 34
+      [default = IDEMPOTENCY_UNKNOWN];
+
+  // The parser stores options it doesn't recognize here. See above.
+  repeated UninterpretedOption uninterpreted_option = 999;
+
+  // Clients can define custom options in extensions of this message. See above.
+  extensions 1000 to max;
+}
+
+
+// A message representing a option the parser does not recognize. This only
+// appears in options protos created by the compiler::Parser class.
+// DescriptorPool resolves these when building Descriptor objects. Therefore,
+// options protos in descriptor objects (e.g. returned by Descriptor::options(),
+// or produced by Descriptor::CopyTo()) will never have UninterpretedOptions
+// in them.
+message UninterpretedOption {
+  // The name of the uninterpreted option.  Each string represents a segment in
+  // a dot-separated name.  is_extension is true iff a segment represents an
+  // extension (denoted with parentheses in options specs in .proto files).
+  // E.g.,{ ["foo", false], ["bar.baz", true], ["qux", false] } represents
+  // "foo.(bar.baz).qux".
+  message NamePart {
+    optional string name_part = 1;
+    optional bool is_extension = 2;
+  }
+  repeated NamePart name = 2;
+
+  // The value of the uninterpreted option, in whatever type the tokenizer
+  // identified it as during parsing. Exactly one of these should be set.
+  optional string identifier_value = 3;
+  optional uint64 positive_int_value = 4;
+  optional int64 negative_int_value = 5;
+  optional double double_value = 6;
+  optional bytes string_value = 7;
+  optional string aggregate_value = 8;
+}
+
+// ===================================================================
+// Optional source code info
+
+// Encapsulates information about the original source file from which a
+// FileDescriptorProto was generated.
+message SourceCodeInfo {
+  // A Location identifies a piece of source code in a .proto file which
+  // corresponds to a particular definition.  This information is intended
+  // to be useful to IDEs, code indexers, documentation generators, and similar
+  // tools.
+  //
+  // For example, say we have a file like:
+  //   message Foo {
+  //     optional string foo = 1;
+  //   }
+  // Let's look at just the field definition:
+  //   optional string foo = 1;
+  //   ^       ^^     ^^  ^  ^^^
+  //   a       bc     de  f  ghi
+  // We have the following locations:
+  //   span   path               represents
+  //   [a,i)  [ 4, 0, 2, 0 ]     The whole field definition.
+  //   [a,b)  [ 4, 0, 2, 0, 4 ]  The label (optional).
+  //   [c,d)  [ 4, 0, 2, 0, 5 ]  The type (string).
+  //   [e,f)  [ 4, 0, 2, 0, 1 ]  The name (foo).
+  //   [g,h)  [ 4, 0, 2, 0, 3 ]  The number (1).
+  //
+  // Notes:
+  // - A location may refer to a repeated field itself (i.e. not to any
+  //   particular index within it).  This is used whenever a set of elements are
+  //   logically enclosed in a single code segment.  For example, an entire
+  //   extend block (possibly containing multiple extension definitions) will
+  //   have an outer location whose path refers to the "extensions" repeated
+  //   field without an index.
+  // - Multiple locations may have the same path.  This happens when a single
+  //   logical declaration is spread out across multiple places.  The most
+  //   obvious example is the "extend" block again -- there may be multiple
+  //   extend blocks in the same scope, each of which will have the same path.
+  // - A location's span is not always a subset of its parent's span.  For
+  //   example, the "extendee" of an extension declaration appears at the
+  //   beginning of the "extend" block and is shared by all extensions within
+  //   the block.
+  // - Just because a location's span is a subset of some other location's span
+  //   does not mean that it is a descendant.  For example, a "group" defines
+  //   both a type and a field in a single declaration.  Thus, the locations
+  //   corresponding to the type and field and their components will overlap.
+  // - Code which tries to interpret locations should probably be designed to
+  //   ignore those that it doesn't understand, as more types of locations could
+  //   be recorded in the future.
+  repeated Location location = 1;
+  message Location {
+    // Identifies which part of the FileDescriptorProto was defined at this
+    // location.
+    //
+    // Each element is a field number or an index.  They form a path from
+    // the root FileDescriptorProto to the place where the definition.  For
+    // example, this path:
+    //   [ 4, 3, 2, 7, 1 ]
+    // refers to:
+    //   file.message_type(3)  // 4, 3
+    //       .field(7)         // 2, 7
+    //       .name()           // 1
+    // This is because FileDescriptorProto.message_type has field number 4:
+    //   repeated DescriptorProto message_type = 4;
+    // and DescriptorProto.field has field number 2:
+    //   repeated FieldDescriptorProto field = 2;
+    // and FieldDescriptorProto.name has field number 1:
+    //   optional string name = 1;
+    //
+    // Thus, the above path gives the location of a field name.  If we removed
+    // the last element:
+    //   [ 4, 3, 2, 7 ]
+    // this path refers to the whole field declaration (from the beginning
+    // of the label to the terminating semicolon).
+    repeated int32 path = 1 [packed = true];
+
+    // Always has exactly three or four elements: start line, start column,
+    // end line (optional, otherwise assumed same as start line), end column.
+    // These are packed into a single field for efficiency.  Note that line
+    // and column numbers are zero-based -- typically you will want to add
+    // 1 to each before displaying to a user.
+    repeated int32 span = 2 [packed = true];
+
+    // If this SourceCodeInfo represents a complete declaration, these are any
+    // comments appearing before and after the declaration which appear to be
+    // attached to the declaration.
+    //
+    // A series of line comments appearing on consecutive lines, with no other
+    // tokens appearing on those lines, will be treated as a single comment.
+    //
+    // leading_detached_comments will keep paragraphs of comments that appear
+    // before (but not connected to) the current element. Each paragraph,
+    // separated by empty lines, will be one comment element in the repeated
+    // field.
+    //
+    // Only the comment content is provided; comment markers (e.g. //) are
+    // stripped out.  For block comments, leading whitespace and an asterisk
+    // will be stripped from the beginning of each line other than the first.
+    // Newlines are included in the output.
+    //
+    // Examples:
+    //
+    //   optional int32 foo = 1;  // Comment attached to foo.
+    //   // Comment attached to bar.
+    //   optional int32 bar = 2;
+    //
+    //   optional string baz = 3;
+    //   // Comment attached to baz.
+    //   // Another line attached to baz.
+    //
+    //   // Comment attached to qux.
+    //   //
+    //   // Another line attached to qux.
+    //   optional double qux = 4;
+    //
+    //   // Detached comment for corge. This is not leading or trailing comments
+    //   // to qux or corge because there are blank lines separating it from
+    //   // both.
+    //
+    //   // Detached comment for corge paragraph 2.
+    //
+    //   optional string corge = 5;
+    //   /* Block comment attached
+    //    * to corge.  Leading asterisks
+    //    * will be removed. */
+    //   /* Block comment attached to
+    //    * grault. */
+    //   optional int32 grault = 6;
+    //
+    //   // ignored detached comments.
+    optional string leading_comments = 3;
+    optional string trailing_comments = 4;
+    repeated string leading_detached_comments = 6;
+  }
+}
+
+// Describes the relationship between generated code and its original source
+// file. A GeneratedCodeInfo message is associated with only one generated
+// source file, but may contain references to different source .proto files.
+message GeneratedCodeInfo {
+  // An Annotation connects some span of text in generated code to an element
+  // of its generating .proto file.
+  repeated Annotation annotation = 1;
+  message Annotation {
+    // Identifies the element in the original source .proto file. This field
+    // is formatted the same as SourceCodeInfo.Location.path.
+    repeated int32 path = 1 [packed = true];
+
+    // Identifies the filesystem path to the original source .proto.
+    optional string source_file = 2;
+
+    // Identifies the starting offset in bytes in the generated code
+    // that relates to the identified object.
+    optional int32 begin = 3;
+
+    // Identifies the ending offset in bytes in the generated code that
+    // relates to the identified offset. The end offset should be one past
+    // the last relevant byte (so the length of the text = end - begin).
+    optional int32 end = 4;
+  }
+}
diff --git a/third_party/upb/benchmarks/descriptor_sv.proto b/third_party/upb/benchmarks/descriptor_sv.proto
new file mode 100644 (file)
index 0000000..8ca0888
--- /dev/null
@@ -0,0 +1,890 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+//  Based on original Protocol Buffers design by
+//  Sanjay Ghemawat, Jeff Dean, and others.
+//
+// The messages in this file describe the definitions found in .proto files.
+// A valid .proto file can be translated directly to a FileDescriptorProto
+// without any other information (e.g. without reading its imports).
+
+syntax = "proto2";
+
+package upb_benchmark.sv;
+
+option go_package = "google.golang.org/protobuf/types/descriptorpb";
+option java_package = "com.google.protobuf";
+option java_outer_classname = "DescriptorProtos";
+option csharp_namespace = "Google.Protobuf.Reflection";
+option objc_class_prefix = "GPB";
+option cc_enable_arenas = true;
+
+// The protocol compiler can output a FileDescriptorSet containing the .proto
+// files it parses.
+message FileDescriptorSet {
+  repeated FileDescriptorProto file = 1;
+}
+
+// Describes a complete .proto file.
+message FileDescriptorProto {
+  optional string name = 1
+      [ctype = STRING_PIECE];  // file name, relative to root of source tree
+  optional string package = 2
+      [ctype = STRING_PIECE];  // e.g. "foo", "foo.bar", etc.
+
+  // Names of files imported by this file.
+  repeated string dependency = 3 [ctype = STRING_PIECE];
+  // Indexes of the public imported files in the dependency list above.
+  repeated int32 public_dependency = 10;
+  // Indexes of the weak imported files in the dependency list.
+  // For Google-internal migration only. Do not use.
+  repeated int32 weak_dependency = 11;
+
+  // All top-level definitions in this file.
+  repeated DescriptorProto message_type = 4;
+  repeated EnumDescriptorProto enum_type = 5;
+  repeated ServiceDescriptorProto service = 6;
+  repeated FieldDescriptorProto extension = 7;
+
+  optional FileOptions options = 8;
+
+  // This field contains optional information about the original source code.
+  // You may safely remove this entire field without harming runtime
+  // functionality of the descriptors -- the information is needed only by
+  // development tools.
+  optional SourceCodeInfo source_code_info = 9;
+
+  // The syntax of the proto file.
+  // The supported values are "proto2" and "proto3".
+  optional string syntax = 12 [ctype = STRING_PIECE];
+}
+
+// Describes a message type.
+message DescriptorProto {
+  optional string name = 1 [ctype = STRING_PIECE];
+
+  repeated FieldDescriptorProto field = 2;
+  repeated FieldDescriptorProto extension = 6;
+
+  repeated DescriptorProto nested_type = 3;
+  repeated EnumDescriptorProto enum_type = 4;
+
+  message ExtensionRange {
+    optional int32 start = 1;  // Inclusive.
+    optional int32 end = 2;    // Exclusive.
+
+    optional ExtensionRangeOptions options = 3;
+  }
+  repeated ExtensionRange extension_range = 5;
+
+  repeated OneofDescriptorProto oneof_decl = 8;
+
+  optional MessageOptions options = 7;
+
+  // Range of reserved tag numbers. Reserved tag numbers may not be used by
+  // fields or extension ranges in the same message. Reserved ranges may
+  // not overlap.
+  message ReservedRange {
+    optional int32 start = 1;  // Inclusive.
+    optional int32 end = 2;    // Exclusive.
+  }
+  repeated ReservedRange reserved_range = 9;
+  // Reserved field names, which may not be used by fields in the same message.
+  // A given name may only be reserved once.
+  repeated string reserved_name = 10 [ctype = STRING_PIECE];
+}
+
+message ExtensionRangeOptions {
+  // The parser stores options it doesn't recognize here. See above.
+  repeated UninterpretedOption uninterpreted_option = 999;
+
+  // Clients can define custom options in extensions of this message. See above.
+  extensions 1000 to max;
+}
+
+// Describes a field within a message.
+message FieldDescriptorProto {
+  enum Type {
+    // 0 is reserved for errors.
+    // Order is weird for historical reasons.
+    TYPE_DOUBLE = 1;
+    TYPE_FLOAT = 2;
+    // Not ZigZag encoded.  Negative numbers take 10 bytes.  Use TYPE_SINT64 if
+    // negative values are likely.
+    TYPE_INT64 = 3;
+    TYPE_UINT64 = 4;
+    // Not ZigZag encoded.  Negative numbers take 10 bytes.  Use TYPE_SINT32 if
+    // negative values are likely.
+    TYPE_INT32 = 5;
+    TYPE_FIXED64 = 6;
+    TYPE_FIXED32 = 7;
+    TYPE_BOOL = 8;
+    TYPE_STRING = 9;
+    // Tag-delimited aggregate.
+    // Group type is deprecated and not supported in proto3. However, Proto3
+    // implementations should still be able to parse the group wire format and
+    // treat group fields as unknown fields.
+    TYPE_GROUP = 10;
+    TYPE_MESSAGE = 11;  // Length-delimited aggregate.
+
+    // New in version 2.
+    TYPE_BYTES = 12;
+    TYPE_UINT32 = 13;
+    TYPE_ENUM = 14;
+    TYPE_SFIXED32 = 15;
+    TYPE_SFIXED64 = 16;
+    TYPE_SINT32 = 17;  // Uses ZigZag encoding.
+    TYPE_SINT64 = 18;  // Uses ZigZag encoding.
+  }
+
+  enum Label {
+    // 0 is reserved for errors
+    LABEL_OPTIONAL = 1;
+    LABEL_REQUIRED = 2;
+    LABEL_REPEATED = 3;
+  }
+
+  optional string name = 1 [ctype = STRING_PIECE];
+  optional int32 number = 3;
+  optional Label label = 4;
+
+  // If type_name is set, this need not be set.  If both this and type_name
+  // are set, this must be one of TYPE_ENUM, TYPE_MESSAGE or TYPE_GROUP.
+  optional Type type = 5;
+
+  // For message and enum types, this is the name of the type.  If the name
+  // starts with a '.', it is fully-qualified.  Otherwise, C++-like scoping
+  // rules are used to find the type (i.e. first the nested types within this
+  // message are searched, then within the parent, on up to the root
+  // namespace).
+  optional string type_name = 6 [ctype = STRING_PIECE];
+
+  // For extensions, this is the name of the type being extended.  It is
+  // resolved in the same manner as type_name.
+  optional string extendee = 2 [ctype = STRING_PIECE];
+
+  // For numeric types, contains the original text representation of the value.
+  // For booleans, "true" or "false".
+  // For strings, contains the default text contents (not escaped in any way).
+  // For bytes, contains the C escaped value.  All bytes >= 128 are escaped.
+  // TODO(kenton):  Base-64 encode?
+  optional string default_value = 7 [ctype = STRING_PIECE];
+
+  // If set, gives the index of a oneof in the containing type's oneof_decl
+  // list.  This field is a member of that oneof.
+  optional int32 oneof_index = 9;
+
+  // JSON name of this field. The value is set by protocol compiler. If the
+  // user has set a "json_name" option on this field, that option's value
+  // will be used. Otherwise, it's deduced from the field's name by converting
+  // it to camelCase.
+  optional string json_name = 10 [ctype = STRING_PIECE];
+
+  optional FieldOptions options = 8;
+
+  // If true, this is a proto3 "optional". When a proto3 field is optional, it
+  // tracks presence regardless of field type.
+  //
+  // When proto3_optional is true, this field must be belong to a oneof to
+  // signal to old proto3 clients that presence is tracked for this field. This
+  // oneof is known as a "synthetic" oneof, and this field must be its sole
+  // member (each proto3 optional field gets its own synthetic oneof). Synthetic
+  // oneofs exist in the descriptor only, and do not generate any API. Synthetic
+  // oneofs must be ordered after all "real" oneofs.
+  //
+  // For message fields, proto3_optional doesn't create any semantic change,
+  // since non-repeated message fields always track presence. However it still
+  // indicates the semantic detail of whether the user wrote "optional" or not.
+  // This can be useful for round-tripping the .proto file. For consistency we
+  // give message fields a synthetic oneof also, even though it is not required
+  // to track presence. This is especially important because the parser can't
+  // tell if a field is a message or an enum, so it must always create a
+  // synthetic oneof.
+  //
+  // Proto2 optional fields do not set this flag, because they already indicate
+  // optional with `LABEL_OPTIONAL`.
+  optional bool proto3_optional = 17;
+}
+
+// Describes a oneof.
+message OneofDescriptorProto {
+  optional string name = 1 [ctype = STRING_PIECE];
+  optional OneofOptions options = 2;
+}
+
+// Describes an enum type.
+message EnumDescriptorProto {
+  optional string name = 1 [ctype = STRING_PIECE];
+
+  repeated EnumValueDescriptorProto value = 2;
+
+  optional EnumOptions options = 3;
+
+  // Range of reserved numeric values. Reserved values may not be used by
+  // entries in the same enum. Reserved ranges may not overlap.
+  //
+  // Note that this is distinct from DescriptorProto.ReservedRange in that it
+  // is inclusive such that it can appropriately represent the entire int32
+  // domain.
+  message EnumReservedRange {
+    optional int32 start = 1;  // Inclusive.
+    optional int32 end = 2;    // Inclusive.
+  }
+
+  // Range of reserved numeric values. Reserved numeric values may not be used
+  // by enum values in the same enum declaration. Reserved ranges may not
+  // overlap.
+  repeated EnumReservedRange reserved_range = 4;
+
+  // Reserved enum value names, which may not be reused. A given name may only
+  // be reserved once.
+  repeated string reserved_name = 5 [ctype = STRING_PIECE];
+}
+
+// Describes a value within an enum.
+message EnumValueDescriptorProto {
+  optional string name = 1 [ctype = STRING_PIECE];
+  optional int32 number = 2;
+
+  optional EnumValueOptions options = 3;
+}
+
+// Describes a service.
+message ServiceDescriptorProto {
+  optional string name = 1 [ctype = STRING_PIECE];
+  repeated MethodDescriptorProto method = 2;
+
+  optional ServiceOptions options = 3;
+}
+
+// Describes a method of a service.
+message MethodDescriptorProto {
+  optional string name = 1 [ctype = STRING_PIECE];
+
+  // Input and output type names.  These are resolved in the same way as
+  // FieldDescriptorProto.type_name, but must refer to a message type.
+  optional string input_type = 2 [ctype = STRING_PIECE];
+  optional string output_type = 3 [ctype = STRING_PIECE];
+
+  optional MethodOptions options = 4;
+
+  // Identifies if client streams multiple client messages
+  optional bool client_streaming = 5 [default = false];
+  // Identifies if server streams multiple server messages
+  optional bool server_streaming = 6 [default = false];
+}
+
+// ===================================================================
+// Options
+
+// Each of the definitions above may have "options" attached.  These are
+// just annotations which may cause code to be generated slightly differently
+// or may contain hints for code that manipulates protocol messages.
+//
+// Clients may define custom options as extensions of the *Options messages.
+// These extensions may not yet be known at parsing time, so the parser cannot
+// store the values in them.  Instead it stores them in a field in the *Options
+// message called uninterpreted_option. This field must have the same name
+// across all *Options messages. We then use this field to populate the
+// extensions when we build a descriptor, at which point all protos have been
+// parsed and so all extensions are known.
+//
+// Extension numbers for custom options may be chosen as follows:
+// * For options which will only be used within a single application or
+//   organization, or for experimental options, use field numbers 50000
+//   through 99999.  It is up to you to ensure that you do not use the
+//   same number for multiple options.
+// * For options which will be published and used publicly by multiple
+//   independent entities, e-mail protobuf-global-extension-registry@google.com
+//   to reserve extension numbers. Simply provide your project name (e.g.
+//   Objective-C plugin) and your project website (if available) -- there's no
+//   need to explain how you intend to use them. Usually you only need one
+//   extension number. You can declare multiple options with only one extension
+//   number by putting them in a sub-message. See the Custom Options section of
+//   the docs for examples:
+//   https://developers.google.com/protocol-buffers/docs/proto#options
+//   If this turns out to be popular, a web service will be set up
+//   to automatically assign option numbers.
+
+message FileOptions {
+  // Sets the Java package where classes generated from this .proto will be
+  // placed.  By default, the proto package is used, but this is often
+  // inappropriate because proto packages do not normally start with backwards
+  // domain names.
+  optional string java_package = 1 [ctype = STRING_PIECE];
+
+  // If set, all the classes from the .proto file are wrapped in a single
+  // outer class with the given name.  This applies to both Proto1
+  // (equivalent to the old "--one_java_file" option) and Proto2 (where
+  // a .proto always translates to a single class, but you may want to
+  // explicitly choose the class name).
+  optional string java_outer_classname = 8 [ctype = STRING_PIECE];
+
+  // If set true, then the Java code generator will generate a separate .java
+  // file for each top-level message, enum, and service defined in the .proto
+  // file.  Thus, these types will *not* be nested inside the outer class
+  // named by java_outer_classname.  However, the outer class will still be
+  // generated to contain the file's getDescriptor() method as well as any
+  // top-level extensions defined in the file.
+  optional bool java_multiple_files = 10 [default = false];
+
+  // This option does nothing.
+  optional bool java_generate_equals_and_hash = 20 [deprecated = true];
+
+  // If set true, then the Java2 code generator will generate code that
+  // throws an exception whenever an attempt is made to assign a non-UTF-8
+  // byte sequence to a string field.
+  // Message reflection will do the same.
+  // However, an extension field still accepts non-UTF-8 byte sequences.
+  // This option has no effect on when used with the lite runtime.
+  optional bool java_string_check_utf8 = 27 [default = false];
+
+  // Generated classes can be optimized for speed or code size.
+  enum OptimizeMode {
+    SPEED = 1;         // Generate complete code for parsing, serialization,
+                       // etc.
+    CODE_SIZE = 2;     // Use ReflectionOps to implement these methods.
+    LITE_RUNTIME = 3;  // Generate code using MessageLite and the lite runtime.
+  }
+  optional OptimizeMode optimize_for = 9 [default = SPEED];
+
+  // Sets the Go package where structs generated from this .proto will be
+  // placed. If omitted, the Go package will be derived from the following:
+  //   - The basename of the package import path, if provided.
+  //   - Otherwise, the package statement in the .proto file, if present.
+  //   - Otherwise, the basename of the .proto file, without extension.
+  optional string go_package = 11 [ctype = STRING_PIECE];
+
+  // Should generic services be generated in each language?  "Generic" services
+  // are not specific to any particular RPC system.  They are generated by the
+  // main code generators in each language (without additional plugins).
+  // Generic services were the only kind of service generation supported by
+  // early versions of google.protobuf.
+  //
+  // Generic services are now considered deprecated in favor of using plugins
+  // that generate code specific to your particular RPC system.  Therefore,
+  // these default to false.  Old code which depends on generic services should
+  // explicitly set them to true.
+  optional bool cc_generic_services = 16 [default = false];
+  optional bool java_generic_services = 17 [default = false];
+  optional bool py_generic_services = 18 [default = false];
+  optional bool php_generic_services = 42 [default = false];
+
+  // Is this file deprecated?
+  // Depending on the target platform, this can emit Deprecated annotations
+  // for everything in the file, or it will be completely ignored; in the very
+  // least, this is a formalization for deprecating files.
+  optional bool deprecated = 23 [default = false];
+
+  // Enables the use of arenas for the proto messages in this file. This applies
+  // only to generated classes for C++.
+  optional bool cc_enable_arenas = 31 [default = true];
+
+  // Sets the objective c class prefix which is prepended to all objective c
+  // generated classes from this .proto. There is no default.
+  optional string objc_class_prefix = 36 [ctype = STRING_PIECE];
+
+  // Namespace for generated classes; defaults to the package.
+  optional string csharp_namespace = 37 [ctype = STRING_PIECE];
+
+  // By default Swift generators will take the proto package and CamelCase it
+  // replacing '.' with underscore and use that to prefix the types/symbols
+  // defined. When this options is provided, they will use this value instead
+  // to prefix the types/symbols defined.
+  optional string swift_prefix = 39 [ctype = STRING_PIECE];
+
+  // Sets the php class prefix which is prepended to all php generated classes
+  // from this .proto. Default is empty.
+  optional string php_class_prefix = 40 [ctype = STRING_PIECE];
+
+  // Use this option to change the namespace of php generated classes. Default
+  // is empty. When this option is empty, the package name will be used for
+  // determining the namespace.
+  optional string php_namespace = 41 [ctype = STRING_PIECE];
+
+  // Use this option to change the namespace of php generated metadata classes.
+  // Default is empty. When this option is empty, the proto file name will be
+  // used for determining the namespace.
+  optional string php_metadata_namespace = 44 [ctype = STRING_PIECE];
+
+  // Use this option to change the package of ruby generated classes. Default
+  // is empty. When this option is not set, the package name will be used for
+  // determining the ruby package.
+  optional string ruby_package = 45 [ctype = STRING_PIECE];
+
+  // The parser stores options it doesn't recognize here.
+  // See the documentation for the "Options" section above.
+  repeated UninterpretedOption uninterpreted_option = 999;
+
+  // Clients can define custom options in extensions of this message.
+  // See the documentation for the "Options" section above.
+  extensions 1000 to max;
+
+  reserved 38;
+}
+
+message MessageOptions {
+  // Set true to use the old proto1 MessageSet wire format for extensions.
+  // This is provided for backwards-compatibility with the MessageSet wire
+  // format.  You should not use this for any other reason:  It's less
+  // efficient, has fewer features, and is more complicated.
+  //
+  // The message must be defined exactly as follows:
+  //   message Foo {
+  //     option message_set_wire_format = true;
+  //     extensions 4 to max;
+  //   }
+  // Note that the message cannot have any defined fields; MessageSets only
+  // have extensions.
+  //
+  // All extensions of your type must be singular messages; e.g. they cannot
+  // be int32s, enums, or repeated messages.
+  //
+  // Because this is an option, the above two restrictions are not enforced by
+  // the protocol compiler.
+  optional bool message_set_wire_format = 1 [default = false];
+
+  // Disables the generation of the standard "descriptor()" accessor, which can
+  // conflict with a field of the same name.  This is meant to make migration
+  // from proto1 easier; new code should avoid fields named "descriptor".
+  optional bool no_standard_descriptor_accessor = 2 [default = false];
+
+  // Is this message deprecated?
+  // Depending on the target platform, this can emit Deprecated annotations
+  // for the message, or it will be completely ignored; in the very least,
+  // this is a formalization for deprecating messages.
+  optional bool deprecated = 3 [default = false];
+
+  // Whether the message is an automatically generated map entry type for the
+  // maps field.
+  //
+  // For maps fields:
+  //     map<KeyType, ValueType> map_field = 1;
+  // The parsed descriptor looks like:
+  //     message MapFieldEntry {
+  //         option map_entry = true;
+  //         optional KeyType key = 1;
+  //         optional ValueType value = 2;
+  //     }
+  //     repeated MapFieldEntry map_field = 1;
+  //
+  // Implementations may choose not to generate the map_entry=true message, but
+  // use a native map in the target language to hold the keys and values.
+  // The reflection APIs in such implementations still need to work as
+  // if the field is a repeated message field.
+  //
+  // NOTE: Do not set the option in .proto files. Always use the maps syntax
+  // instead. The option should only be implicitly set by the proto compiler
+  // parser.
+  optional bool map_entry = 7;
+
+  reserved 8;  // javalite_serializable
+  reserved 9;  // javanano_as_lite
+
+  // The parser stores options it doesn't recognize here. See above.
+  repeated UninterpretedOption uninterpreted_option = 999;
+
+  // Clients can define custom options in extensions of this message. See above.
+  extensions 1000 to max;
+}
+
+message FieldOptions {
+  // The ctype option instructs the C++ code generator to use a different
+  // representation of the field than it normally would.  See the specific
+  // options below.  This option is not yet implemented in the open source
+  // release -- sorry, we'll try to include it in a future version!
+  optional CType ctype = 1 [default = STRING];
+  enum CType {
+    // Default mode.
+    STRING = 0;
+
+    CORD = 1;
+
+    STRING_PIECE = 2;
+  }
+  // The packed option can be enabled for repeated primitive fields to enable
+  // a more efficient representation on the wire. Rather than repeatedly
+  // writing the tag and type for each element, the entire array is encoded as
+  // a single length-delimited blob. In proto3, only explicit setting it to
+  // false will avoid using packed encoding.
+  optional bool packed = 2;
+
+  // The jstype option determines the JavaScript type used for values of the
+  // field.  The option is permitted only for 64 bit integral and fixed types
+  // (int64, uint64, sint64, fixed64, sfixed64).  A field with jstype JS_STRING
+  // is represented as JavaScript string, which avoids loss of precision that
+  // can happen when a large value is converted to a floating point JavaScript.
+  // Specifying JS_NUMBER for the jstype causes the generated JavaScript code to
+  // use the JavaScript "number" type.  The behavior of the default option
+  // JS_NORMAL is implementation dependent.
+  //
+  // This option is an enum to permit additional types to be added, e.g.
+  // goog.math.Integer.
+  optional JSType jstype = 6 [default = JS_NORMAL];
+  enum JSType {
+    // Use the default type.
+    JS_NORMAL = 0;
+
+    // Use JavaScript strings.
+    JS_STRING = 1;
+
+    // Use JavaScript numbers.
+    JS_NUMBER = 2;
+  }
+
+  // Should this field be parsed lazily?  Lazy applies only to message-type
+  // fields.  It means that when the outer message is initially parsed, the
+  // inner message's contents will not be parsed but instead stored in encoded
+  // form.  The inner message will actually be parsed when it is first accessed.
+  //
+  // This is only a hint.  Implementations are free to choose whether to use
+  // eager or lazy parsing regardless of the value of this option.  However,
+  // setting this option true suggests that the protocol author believes that
+  // using lazy parsing on this field is worth the additional bookkeeping
+  // overhead typically needed to implement it.
+  //
+  // This option does not affect the public interface of any generated code;
+  // all method signatures remain the same.  Furthermore, thread-safety of the
+  // interface is not affected by this option; const methods remain safe to
+  // call from multiple threads concurrently, while non-const methods continue
+  // to require exclusive access.
+  //
+  //
+  // Note that implementations may choose not to check required fields within
+  // a lazy sub-message.  That is, calling IsInitialized() on the outer message
+  // may return true even if the inner message has missing required fields.
+  // This is necessary because otherwise the inner message would have to be
+  // parsed in order to perform the check, defeating the purpose of lazy
+  // parsing.  An implementation which chooses not to check required fields
+  // must be consistent about it.  That is, for any particular sub-message, the
+  // implementation must either *always* check its required fields, or *never*
+  // check its required fields, regardless of whether or not the message has
+  // been parsed.
+  optional bool lazy = 5 [default = false];
+
+  // Is this field deprecated?
+  // Depending on the target platform, this can emit Deprecated annotations
+  // for accessors, or it will be completely ignored; in the very least, this
+  // is a formalization for deprecating fields.
+  optional bool deprecated = 3 [default = false];
+
+  // For Google-internal migration only. Do not use.
+  optional bool weak = 10 [default = false];
+
+  // The parser stores options it doesn't recognize here. See above.
+  repeated UninterpretedOption uninterpreted_option = 999;
+
+  // Clients can define custom options in extensions of this message. See above.
+  extensions 1000 to max;
+
+  reserved 4;  // removed jtype
+}
+
+message OneofOptions {
+  // The parser stores options it doesn't recognize here. See above.
+  repeated UninterpretedOption uninterpreted_option = 999;
+
+  // Clients can define custom options in extensions of this message. See above.
+  extensions 1000 to max;
+}
+
+message EnumOptions {
+  // Set this option to true to allow mapping different tag names to the same
+  // value.
+  optional bool allow_alias = 2;
+
+  // Is this enum deprecated?
+  // Depending on the target platform, this can emit Deprecated annotations
+  // for the enum, or it will be completely ignored; in the very least, this
+  // is a formalization for deprecating enums.
+  optional bool deprecated = 3 [default = false];
+
+  reserved 5;  // javanano_as_lite
+
+  // The parser stores options it doesn't recognize here. See above.
+  repeated UninterpretedOption uninterpreted_option = 999;
+
+  // Clients can define custom options in extensions of this message. See above.
+  extensions 1000 to max;
+}
+
+message EnumValueOptions {
+  // Is this enum value deprecated?
+  // Depending on the target platform, this can emit Deprecated annotations
+  // for the enum value, or it will be completely ignored; in the very least,
+  // this is a formalization for deprecating enum values.
+  optional bool deprecated = 1 [default = false];
+
+  // The parser stores options it doesn't recognize here. See above.
+  repeated UninterpretedOption uninterpreted_option = 999;
+
+  // Clients can define custom options in extensions of this message. See above.
+  extensions 1000 to max;
+}
+
+message ServiceOptions {
+  // Note:  Field numbers 1 through 32 are reserved for Google's internal RPC
+  //   framework.  We apologize for hoarding these numbers to ourselves, but
+  //   we were already using them long before we decided to release Protocol
+  //   Buffers.
+
+  // Is this service deprecated?
+  // Depending on the target platform, this can emit Deprecated annotations
+  // for the service, or it will be completely ignored; in the very least,
+  // this is a formalization for deprecating services.
+  optional bool deprecated = 33 [default = false];
+
+  // The parser stores options it doesn't recognize here. See above.
+  repeated UninterpretedOption uninterpreted_option = 999;
+
+  // Clients can define custom options in extensions of this message. See above.
+  extensions 1000 to max;
+}
+
+message MethodOptions {
+  // Note:  Field numbers 1 through 32 are reserved for Google's internal RPC
+  //   framework.  We apologize for hoarding these numbers to ourselves, but
+  //   we were already using them long before we decided to release Protocol
+  //   Buffers.
+
+  // Is this method deprecated?
+  // Depending on the target platform, this can emit Deprecated annotations
+  // for the method, or it will be completely ignored; in the very least,
+  // this is a formalization for deprecating methods.
+  optional bool deprecated = 33 [default = false];
+
+  // Is this method side-effect-free (or safe in HTTP parlance), or idempotent,
+  // or neither? HTTP based RPC implementation may choose GET verb for safe
+  // methods, and PUT verb for idempotent methods instead of the default POST.
+  enum IdempotencyLevel {
+    IDEMPOTENCY_UNKNOWN = 0;
+    NO_SIDE_EFFECTS = 1;  // implies idempotent
+    IDEMPOTENT = 2;       // idempotent, but may have side effects
+  }
+  optional IdempotencyLevel idempotency_level = 34
+      [default = IDEMPOTENCY_UNKNOWN];
+
+  // The parser stores options it doesn't recognize here. See above.
+  repeated UninterpretedOption uninterpreted_option = 999;
+
+  // Clients can define custom options in extensions of this message. See above.
+  extensions 1000 to max;
+}
+
+// A message representing a option the parser does not recognize. This only
+// appears in options protos created by the compiler::Parser class.
+// DescriptorPool resolves these when building Descriptor objects. Therefore,
+// options protos in descriptor objects (e.g. returned by Descriptor::options(),
+// or produced by Descriptor::CopyTo()) will never have UninterpretedOptions
+// in them.
+message UninterpretedOption {
+  // The name of the uninterpreted option.  Each string represents a segment in
+  // a dot-separated name.  is_extension is true iff a segment represents an
+  // extension (denoted with parentheses in options specs in .proto files).
+  // E.g.,{ ["foo", false], ["bar.baz", true], ["qux", false] } represents
+  // "foo.(bar.baz).qux".
+  message NamePart {
+    optional string name_part = 1 [ctype = STRING_PIECE];
+    optional bool is_extension = 2;
+  }
+  repeated NamePart name = 2;
+
+  // The value of the uninterpreted option, in whatever type the tokenizer
+  // identified it as during parsing. Exactly one of these should be set.
+  optional string identifier_value = 3 [ctype = STRING_PIECE];
+  optional uint64 positive_int_value = 4;
+  optional int64 negative_int_value = 5;
+  optional double double_value = 6;
+  optional bytes string_value = 7;
+  optional string aggregate_value = 8 [ctype = STRING_PIECE];
+}
+
+// ===================================================================
+// Optional source code info
+
+// Encapsulates information about the original source file from which a
+// FileDescriptorProto was generated.
+message SourceCodeInfo {
+  // A Location identifies a piece of source code in a .proto file which
+  // corresponds to a particular definition.  This information is intended
+  // to be useful to IDEs, code indexers, documentation generators, and similar
+  // tools.
+  //
+  // For example, say we have a file like:
+  //   message Foo {
+  //     optional string foo = 1 [ctype = STRING_PIECE];
+  //   }
+  // Let's look at just the field definition:
+  //   optional string foo = 1 [ctype = STRING_PIECE];
+  //   ^       ^^     ^^  ^  ^^^
+  //   a       bc     de  f  ghi
+  // We have the following locations:
+  //   span   path               represents
+  //   [a,i)  [ 4, 0, 2, 0 ]     The whole field definition.
+  //   [a,b)  [ 4, 0, 2, 0, 4 ]  The label (optional).
+  //   [c,d)  [ 4, 0, 2, 0, 5 ]  The type (string).
+  //   [e,f)  [ 4, 0, 2, 0, 1 ]  The name (foo).
+  //   [g,h)  [ 4, 0, 2, 0, 3 ]  The number (1).
+  //
+  // Notes:
+  // - A location may refer to a repeated field itself (i.e. not to any
+  //   particular index within it).  This is used whenever a set of elements are
+  //   logically enclosed in a single code segment.  For example, an entire
+  //   extend block (possibly containing multiple extension definitions) will
+  //   have an outer location whose path refers to the "extensions" repeated
+  //   field without an index.
+  // - Multiple locations may have the same path.  This happens when a single
+  //   logical declaration is spread out across multiple places.  The most
+  //   obvious example is the "extend" block again -- there may be multiple
+  //   extend blocks in the same scope, each of which will have the same path.
+  // - A location's span is not always a subset of its parent's span.  For
+  //   example, the "extendee" of an extension declaration appears at the
+  //   beginning of the "extend" block and is shared by all extensions within
+  //   the block.
+  // - Just because a location's span is a subset of some other location's span
+  //   does not mean that it is a descendant.  For example, a "group" defines
+  //   both a type and a field in a single declaration.  Thus, the locations
+  //   corresponding to the type and field and their components will overlap.
+  // - Code which tries to interpret locations should probably be designed to
+  //   ignore those that it doesn't understand, as more types of locations could
+  //   be recorded in the future.
+  repeated Location location = 1;
+  message Location {
+    // Identifies which part of the FileDescriptorProto was defined at this
+    // location.
+    //
+    // Each element is a field number or an index.  They form a path from
+    // the root FileDescriptorProto to the place where the definition.  For
+    // example, this path:
+    //   [ 4, 3, 2, 7, 1 ]
+    // refers to:
+    //   file.message_type(3)  // 4, 3
+    //       .field(7)         // 2, 7
+    //       .name()           // 1
+    // This is because FileDescriptorProto.message_type has field number 4:
+    //   repeated DescriptorProto message_type = 4;
+    // and DescriptorProto.field has field number 2:
+    //   repeated FieldDescriptorProto field = 2;
+    // and FieldDescriptorProto.name has field number 1:
+    //   optional string name = 1 [ctype = STRING_PIECE];
+    //
+    // Thus, the above path gives the location of a field name.  If we removed
+    // the last element:
+    //   [ 4, 3, 2, 7 ]
+    // this path refers to the whole field declaration (from the beginning
+    // of the label to the terminating semicolon).
+    repeated int32 path = 1 [packed = true];
+
+    // Always has exactly three or four elements: start line, start column,
+    // end line (optional, otherwise assumed same as start line), end column.
+    // These are packed into a single field for efficiency.  Note that line
+    // and column numbers are zero-based -- typically you will want to add
+    // 1 to each before displaying to a user.
+    repeated int32 span = 2 [packed = true];
+
+    // If this SourceCodeInfo represents a complete declaration, these are any
+    // comments appearing before and after the declaration which appear to be
+    // attached to the declaration.
+    //
+    // A series of line comments appearing on consecutive lines, with no other
+    // tokens appearing on those lines, will be treated as a single comment.
+    //
+    // leading_detached_comments will keep paragraphs of comments that appear
+    // before (but not connected to) the current element. Each paragraph,
+    // separated by empty lines, will be one comment element in the repeated
+    // field.
+    //
+    // Only the comment content is provided; comment markers (e.g. //) are
+    // stripped out.  For block comments, leading whitespace and an asterisk
+    // will be stripped from the beginning of each line other than the first.
+    // Newlines are included in the output.
+    //
+    // Examples:
+    //
+    //   optional int32 foo = 1;  // Comment attached to foo.
+    //   // Comment attached to bar.
+    //   optional int32 bar = 2;
+    //
+    //   optional string baz = 3 [ctype = STRING_PIECE];
+    //   // Comment attached to baz.
+    //   // Another line attached to baz.
+    //
+    //   // Comment attached to qux.
+    //   //
+    //   // Another line attached to qux.
+    //   optional double qux = 4;
+    //
+    //   // Detached comment for corge. This is not leading or trailing comments
+    //   // to qux or corge because there are blank lines separating it from
+    //   // both.
+    //
+    //   // Detached comment for corge paragraph 2.
+    //
+    //   optional string corge = 5 [ctype = STRING_PIECE];
+    //   /* Block comment attached
+    //    * to corge.  Leading asterisks
+    //    * will be removed. */
+    //   /* Block comment attached to
+    //    * grault. */
+    //   optional int32 grault = 6;
+    //
+    //   // ignored detached comments.
+    optional string leading_comments = 3 [ctype = STRING_PIECE];
+    optional string trailing_comments = 4 [ctype = STRING_PIECE];
+    repeated string leading_detached_comments = 6 [ctype = STRING_PIECE];
+  }
+}
+
+// Describes the relationship between generated code and its original source
+// file. A GeneratedCodeInfo message is associated with only one generated
+// source file, but may contain references to different source .proto files.
+message GeneratedCodeInfo {
+  // An Annotation connects some span of text in generated code to an element
+  // of its generating .proto file.
+  repeated Annotation annotation = 1;
+  message Annotation {
+    // Identifies the element in the original source .proto file. This field
+    // is formatted the same as SourceCodeInfo.Location.path.
+    repeated int32 path = 1 [packed = true];
+
+    // Identifies the filesystem path to the original source .proto.
+    optional string source_file = 2 [ctype = STRING_PIECE];
+
+    // Identifies the starting offset in bytes in the generated code
+    // that relates to the identified object.
+    optional int32 begin = 3;
+
+    // Identifies the ending offset in bytes in the generated code that
+    // relates to the identified offset. The end offset should be one past
+    // the last relevant byte (so the length of the text = end - begin).
+    optional int32 end = 4;
+  }
+}
diff --git a/third_party/upb/benchmarks/empty.proto b/third_party/upb/benchmarks/empty.proto
new file mode 100644 (file)
index 0000000..bcccaf9
--- /dev/null
@@ -0,0 +1,6 @@
+
+syntax = "proto3";
+
+package upb_benchmark;
+
+message Empty {}
diff --git a/third_party/upb/benchmarks/gen_protobuf_binary_cc.py b/third_party/upb/benchmarks/gen_protobuf_binary_cc.py
new file mode 100644 (file)
index 0000000..787e391
--- /dev/null
@@ -0,0 +1,38 @@
+
+import sys
+import re
+
+include = sys.argv[1]
+msg_basename = sys.argv[2]
+count = 1
+
+m = re.search(r'(.*\D)(\d+)$', sys.argv[2])
+if m:
+  msg_basename = m.group(1)
+  count = int(m.group(2))
+
+print('''
+#include "{include}"
+
+char buf[1];
+
+int main() {{
+'''.format(include=include))
+
+def RefMessage(name):
+  print('''
+  {{
+    {name} proto;
+    proto.ParseFromArray(buf, 0);
+    proto.SerializePartialToArray(&buf[0], 0);
+  }}
+  '''.format(name=name))
+
+RefMessage(msg_basename)
+
+for i in range(2, count + 1):
+  RefMessage(msg_basename + str(i))
+
+print('''
+  return 0;
+}''')
diff --git a/third_party/upb/benchmarks/gen_synthetic_protos.py b/third_party/upb/benchmarks/gen_synthetic_protos.py
new file mode 100644 (file)
index 0000000..a95deff
--- /dev/null
@@ -0,0 +1,92 @@
+
+import sys
+import random
+
+base = sys.argv[1]
+
+field_freqs = [
+    (('bool', 'optional'), 8.321),
+    (('bool', 'repeated'), 0.033),
+    (('bytes', 'optional'), 0.809),
+    (('bytes', 'repeated'), 0.065),
+    (('double', 'optional'), 2.845),
+    (('double', 'repeated'), 0.143),
+    (('fixed32', 'optional'), 0.084),
+    (('fixed32', 'repeated'), 0.012),
+    (('fixed64', 'optional'), 0.204),
+    (('fixed64', 'repeated'), 0.027),
+    (('float', 'optional'), 2.355),
+    (('float', 'repeated'), 0.132),
+    (('int32', 'optional'), 6.717),
+    (('int32', 'repeated'), 0.366),
+    (('int64', 'optional'), 9.678),
+    (('int64', 'repeated'), 0.425),
+    (('sfixed32', 'optional'), 0.018),
+    (('sfixed32', 'repeated'), 0.005),
+    (('sfixed64', 'optional'), 0.022),
+    (('sfixed64', 'repeated'), 0.005),
+    (('sint32', 'optional'), 0.026),
+    (('sint32', 'repeated'), 0.009),
+    (('sint64', 'optional'), 0.018),
+    (('sint64', 'repeated'), 0.006),
+    (('string', 'optional'), 25.461),
+    (('string', 'repeated'), 2.606),
+    (('Enum', 'optional'), 6.16),
+    (('Enum', 'repeated'), 0.576),
+    (('Message', 'optional'), 22.472),
+    (('Message', 'repeated'), 7.766),
+    (('uint32', 'optional'), 1.289),
+    (('uint32', 'repeated'), 0.051),
+    (('uint64', 'optional'), 1.044),
+    (('uint64', 'repeated'), 0.079),
+]
+
+population = [item[0] for item in field_freqs]
+weights = [item[1] for item in field_freqs]
+
+def choices(k):
+  if sys.version_info >= (3, 6):
+    return random.choices(population=population, weights=weights, k=k)
+  else:
+    print("WARNING: old Python version, field types are not properly weighted!")
+    return [random.choice(population) for _ in range(k)]
+
+with open(base + "/100_msgs.proto", "w") as f:
+  f.write('syntax = "proto3";\n')
+  f.write('package upb_benchmark;\n')
+  f.write('message Message {}\n')
+  for i in range(2, 101):
+    f.write('message Message{i} {{}}\n'.format(i=i))
+
+with open(base + "/200_msgs.proto", "w") as f:
+  f.write('syntax = "proto3";\n')
+  f.write('package upb_benchmark;\n')
+  f.write('message Message {}\n')
+  for i in range(2, 501):
+    f.write('message Message{i} {{}}\n'.format(i=i))
+
+with open(base + "/100_fields.proto", "w") as f:
+  f.write('syntax = "proto2";\n')
+  f.write('package upb_benchmark;\n')
+  f.write('enum Enum { ZERO = 0; }\n')
+  f.write('message Message {\n')
+  i = 1
+  random.seed(a=0, version=2)
+  for field in choices(100):
+    field_type, label = field
+    f.write('  {label} {field_type} field{i} = {i};\n'.format(i=i, label=label, field_type=field_type))
+    i += 1
+  f.write('}\n')
+
+with open(base + "/200_fields.proto", "w") as f:
+  f.write('syntax = "proto2";\n')
+  f.write('package upb_benchmark;\n')
+  f.write('enum Enum { ZERO = 0; }\n')
+  f.write('message Message {\n')
+  i = 1
+  random.seed(a=0, version=2)
+  for field in choices(200):
+    field_type, label = field
+    f.write('  {label} {field_type} field{i} = {i};\n'.format(i=i, label=label,field_type=field_type))
+    i += 1
+  f.write('}\n')
diff --git a/third_party/upb/benchmarks/gen_upb_binary_c.py b/third_party/upb/benchmarks/gen_upb_binary_c.py
new file mode 100644 (file)
index 0000000..4df8fd7
--- /dev/null
@@ -0,0 +1,39 @@
+
+import sys
+import re
+
+include = sys.argv[1]
+msg_basename = sys.argv[2]
+count = 1
+
+m = re.search(r'(.*\D)(\d+)$', sys.argv[2])
+if m:
+  msg_basename = m.group(1)
+  count = int(m.group(2))
+
+print('''
+#include "{include}"
+
+char buf[1];
+
+int main() {{
+  upb_arena *arena = upb_arena_new();
+  size_t size;
+'''.format(include=include))
+
+def RefMessage(name):
+  print('''
+  {{
+    {name} *proto = {name}_parse(buf, 1, arena);
+    {name}_serialize(proto, arena, &size);
+  }}
+  '''.format(name=name))
+
+RefMessage(msg_basename)
+
+for i in range(2, count + 1):
+  RefMessage(msg_basename + str(i))
+
+print('''
+  return 0;
+}''')
diff --git a/third_party/upb/cmake/BUILD b/third_party/upb/cmake/BUILD
new file mode 100644 (file)
index 0000000..53fbd07
--- /dev/null
@@ -0,0 +1,91 @@
+load(
+    ":build_defs.bzl",
+    "generated_file_staleness_test",
+)
+load(
+    "//bazel:build_defs.bzl",
+    "make_shell_script",
+)
+
+licenses(["notice"])
+
+exports_files(["staleness_test.py"])
+
+py_library(
+    name = "staleness_test_lib",
+    testonly = 1,
+    srcs = ["staleness_test_lib.py"],
+)
+
+py_binary(
+    name = "make_cmakelists",
+    srcs = ["make_cmakelists.py"],
+)
+
+genrule(
+    name = "gen_cmakelists",
+    srcs = [
+        "//:BUILD",
+        "//:WORKSPACE",
+        "//:cmake_files",
+        "//third_party/wyhash:cmake_files",
+        ":cmake_files",
+    ],
+    outs = ["generated-in/CMakeLists.txt"],
+    cmd = "$(location :make_cmakelists) $@",
+    tools = [":make_cmakelists"],
+)
+
+genrule(
+    name = "copy_json_ragel",
+    srcs = ["//:upb/json/parser.c"],
+    outs = ["generated-in/upb/json/parser.c"],
+    cmd = "cp $< $@",
+)
+
+genrule(
+    name = "copy_protos",
+    srcs = ["//:descriptor_upb_proto"],
+    outs = [
+        "generated-in/google/protobuf/descriptor.upb.c",
+        "generated-in/google/protobuf/descriptor.upb.h",
+    ],
+    cmd = "cp $(SRCS) $(@D)/generated-in/google/protobuf",
+)
+
+generated_file_staleness_test(
+    name = "test_generated_files",
+    outs = [
+        "CMakeLists.txt",
+        "google/protobuf/descriptor.upb.c",
+        "google/protobuf/descriptor.upb.h",
+        "upb/json/parser.c",
+    ],
+    generated_pattern = "generated-in/%s",
+)
+
+# Test the CMake build #########################################################
+
+filegroup(
+    name = "cmake_files",
+    srcs = glob([
+        "**/*",
+    ]),
+)
+
+make_shell_script(
+    name = "gen_run_cmake_build",
+    out = "run_cmake_build.sh",
+    contents = "find . && mkdir build && cd build && cmake ../cmake && make -j8 && make test",
+)
+
+sh_test(
+    name = "cmake_build",
+    srcs = ["run_cmake_build.sh"],
+    data = [
+        ":cmake_files",
+        "//:cmake_files",
+        "//third_party/wyhash:cmake_files",
+    ],
+    deps = ["@bazel_tools//tools/bash/runfiles"],
+)
similarity index 69%
rename from third_party/upb/CMakeLists.txt
rename to third_party/upb/cmake/CMakeLists.txt
index 4dd6454..d4cbcc9 100644 (file)
@@ -12,6 +12,7 @@ cmake_minimum_required (VERSION 3.0)
 cmake_policy(SET CMP0048 NEW)
 
 project(upb)
+set(CMAKE_C_STANDARD 99)
 
 
 # Prevent CMake from setting -rdynamic on Linux (!!).
@@ -48,8 +49,8 @@ if(UPB_ENABLE_UBSAN)
   set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -fsanitize=address")
 endif()
 
-include_directories(.)
-include_directories(generated_for_cmake)
+include_directories(..)
+include_directories(../cmake)
 include_directories(${CMAKE_CURRENT_BINARY_DIR})
 
 if(APPLE)
@@ -60,79 +61,90 @@ endif()
 
 enable_testing()
 
-add_library(port
-  upb/port.c)
+add_library(port INTERFACE)
 add_library(upb
-  upb/decode.c
-  upb/encode.c
-  upb/msg.c
-  upb/msg.h
-  upb/table.c
-  upb/table.int.h
-  upb/upb.c
-  upb/decode.h
-  upb/encode.h
-  upb/upb.h
-  upb/upb.hpp)
+  ../upb/decode.c
+  ../upb/decode.int.h
+  ../upb/encode.c
+  ../upb/msg.c
+  ../upb/msg.h
+  ../upb/table.c
+  ../upb/table.int.h
+  ../upb/upb.c
+  ../upb/upb.int.h
+  ../upb/decode.h
+  ../upb/encode.h
+  ../upb/upb.h
+  ../upb/upb.hpp)
 target_link_libraries(upb
-  port)
+  fastdecode
+  port
+  /third_party/wyhash)
+add_library(fastdecode
+  ../upb/decode.int.h
+  ../upb/decode_fast.c
+  ../upb/decode_fast.h
+  ../upb/msg.h
+  ../upb/upb.int.h)
+target_link_libraries(fastdecode
+  port
+  table)
 add_library(generated_code_support__only_for_generated_code_do_not_use__i_give_permission_to_break_me INTERFACE)
 target_link_libraries(generated_code_support__only_for_generated_code_do_not_use__i_give_permission_to_break_me INTERFACE
   table
   upb)
 add_library(reflection
-  upb/def.c
-  upb/msg.h
-  upb/reflection.c
-  upb/def.h
-  upb/def.hpp
-  upb/reflection.h)
+  ../upb/def.c
+  ../upb/msg.h
+  ../upb/reflection.c
+  ../upb/def.h
+  ../upb/def.hpp
+  ../upb/reflection.h)
 target_link_libraries(reflection
   descriptor_upb_proto
   port
   table
   upb)
 add_library(textformat
-  upb/text_encode.c
-  upb/text_encode.h)
+  ../upb/text_encode.c
+  ../upb/text_encode.h)
 target_link_libraries(textformat
   port
   reflection)
 add_library(json
-  upb/json_decode.c
-  upb/json_encode.c
-  upb/json_decode.h
-  upb/json_encode.h)
+  ../upb/json_decode.c
+  ../upb/json_encode.c
+  ../upb/json_decode.h
+  ../upb/json_encode.h)
 target_link_libraries(json
   port
   reflection
   upb)
 add_library(table INTERFACE)
 target_link_libraries(table INTERFACE
-  port
-  upb)
+  port)
 add_library(handlers
-  upb/handlers.c
-  upb/handlers-inl.h
-  upb/sink.c
-  upb/handlers.h
-  upb/sink.h)
+  ../upb/handlers.c
+  ../upb/handlers-inl.h
+  ../upb/sink.c
+  ../upb/handlers.h
+  ../upb/sink.h)
 target_link_libraries(handlers
   port
   reflection
   table
   upb)
 add_library(upb_pb
-  upb/pb/compile_decoder.c
-  upb/pb/decoder.c
-  upb/pb/decoder.int.h
-  upb/pb/encoder.c
-  upb/pb/textprinter.c
-  upb/pb/varint.c
-  upb/pb/varint.int.h
-  upb/pb/decoder.h
-  upb/pb/encoder.h
-  upb/pb/textprinter.h)
+  ../upb/pb/compile_decoder.c
+  ../upb/pb/decoder.c
+  ../upb/pb/decoder.int.h
+  ../upb/pb/encoder.c
+  ../upb/pb/textprinter.c
+  ../upb/pb/varint.c
+  ../upb/pb/varint.int.h
+  ../upb/pb/decoder.h
+  ../upb/pb/encoder.h
+  ../upb/pb/textprinter.h)
 target_link_libraries(upb_pb
   descriptor_upb_proto
   handlers
@@ -141,26 +153,13 @@ target_link_libraries(upb_pb
   table
   upb)
 add_library(upb_json
-  generated_for_cmake/upb/json/parser.c
-  upb/json/printer.c
-  upb/json/parser.h
-  upb/json/printer.h)
+  ../cmake/upb/json/parser.c
+  ../upb/json/printer.c
+  ../upb/json/parser.h
+  ../upb/json/printer.h)
 target_link_libraries(upb_json
   upb
   upb_pb)
-add_library(upb_cc_bindings INTERFACE)
-target_link_libraries(upb_cc_bindings INTERFACE
-  descriptor_upb_proto
-  handlers
-  port
-  upb)
-add_library(upb_test
-  tests/testmain.cc
-  tests/test_util.h
-  tests/upb_test.h)
-target_link_libraries(upb_test
-  handlers
-  port
-  upb)
+add_library(wyhash INTERFACE)
 
 
diff --git a/third_party/upb/cmake/README.md b/third_party/upb/cmake/README.md
new file mode 100644 (file)
index 0000000..211a054
--- /dev/null
@@ -0,0 +1,23 @@
+
+# upb CMake build (EXPERIMENTAL)
+
+upb's CMake support is experimental. The core library builds successfully
+under CMake, and this is verified by the Bazel tests in this directory.
+However there is no support for building the upb compiler or for generating
+.upb.c/upb.h files. This means upb's CMake support is incomplete at best,
+unless your application is intended to be purely reflective.
+
+If you find this CMake setup useful in its current state, please consider
+filing an issue so we know. If you have suggestions for how it could be
+more useful (and particularly if you can contribute some code for it)
+please feel free to file an issue for that too. Do keep in mind that upb
+does not currently provide any ABI stability, so we want to avoid providing
+a shared library.
+
+The CMakeLists.txt is generated from the Bazel BUILD files using the Python
+scripts in this directory. We want to avoid having two separate sources of
+truth that both need to be updated when a file is added or removed.
+
+This directory also contains some generated files that would be created
+on the fly during a Bazel build. These are automaticaly kept in sync by
+the Bazel test `//cmake:test_generated_files`.
diff --git a/third_party/upb/cmake/build_defs.bzl b/third_party/upb/cmake/build_defs.bzl
new file mode 100644 (file)
index 0000000..34b4537
--- /dev/null
@@ -0,0 +1,43 @@
+def generated_file_staleness_test(name, outs, generated_pattern):
+    """Tests that checked-in file(s) match the contents of generated file(s).
+
+    The resulting test will verify that all output files exist and have the
+    correct contents.  If the test fails, it can be invoked with --fix to
+    bring the checked-in files up to date.
+
+    Args:
+      name: Name of the rule.
+      outs: the checked-in files that are copied from generated files.
+      generated_pattern: the pattern for transforming each "out" file into a
+        generated file.  For example, if generated_pattern="generated/%s" then
+        a file foo.txt will look for generated file generated/foo.txt.
+    """
+
+    script_name = name + ".py"
+    script_src = ":staleness_test.py"
+
+    # Filter out non-existing rules so Blaze doesn't error out before we even
+    # run the test.
+    existing_outs = native.glob(include = outs)
+
+    # The file list contains a few extra bits of information at the end.
+    # These get unpacked by the Config class in staleness_test_lib.py.
+    file_list = outs + [generated_pattern, native.package_name() or ".", name]
+
+    native.genrule(
+        name = name + "_makescript",
+        outs = [script_name],
+        srcs = [script_src],
+        testonly = 1,
+        cmd = "cat $(location " + script_src + ") > $@; " +
+              "sed -i.bak -e 's|INSERT_FILE_LIST_HERE|" + "\\\n  ".join(file_list) + "|' $@",
+    )
+
+    native.py_test(
+        name = name,
+        srcs = [script_name],
+        data = existing_outs + [generated_pattern % file for file in outs],
+        deps = [
+            ":staleness_test_lib",
+        ],
+    )
@@ -23,7 +23,7 @@ static const upb_msglayout_field google_protobuf_FileDescriptorSet__fields[1] =
 const upb_msglayout google_protobuf_FileDescriptorSet_msginit = {
   &google_protobuf_FileDescriptorSet_submsgs[0],
   &google_protobuf_FileDescriptorSet__fields[0],
-  UPB_SIZE(4, 8), 1, false,
+  UPB_SIZE(8, 8), 1, false, 255,
 };
 
 static const upb_msglayout *const google_protobuf_FileDescriptorProto_submsgs[6] = {
@@ -43,20 +43,20 @@ static const upb_msglayout_field google_protobuf_FileDescriptorProto__fields[12]
   {5, UPB_SIZE(44, 88), 0, 1, 11, 3},
   {6, UPB_SIZE(48, 96), 0, 4, 11, 3},
   {7, UPB_SIZE(52, 104), 0, 2, 11, 3},
-  {8, UPB_SIZE(28, 56), 4, 3, 11, 1},
-  {9, UPB_SIZE(32, 64), 5, 5, 11, 1},
+  {8, UPB_SIZE(28, 56), 3, 3, 11, 1},
+  {9, UPB_SIZE(32, 64), 4, 5, 11, 1},
   {10, UPB_SIZE(56, 112), 0, 0, 5, 3},
   {11, UPB_SIZE(60, 120), 0, 0, 5, 3},
-  {12, UPB_SIZE(20, 40), 3, 0, 12, 1},
+  {12, UPB_SIZE(20, 40), 5, 0, 12, 1},
 };
 
 const upb_msglayout google_protobuf_FileDescriptorProto_msginit = {
   &google_protobuf_FileDescriptorProto_submsgs[0],
   &google_protobuf_FileDescriptorProto__fields[0],
-  UPB_SIZE(64, 128), 12, false,
+  UPB_SIZE(64, 128), 12, false, 255,
 };
 
-static const upb_msglayout *const google_protobuf_DescriptorProto_submsgs[8] = {
+static const upb_msglayout *const google_protobuf_DescriptorProto_submsgs[7] = {
   &google_protobuf_DescriptorProto_msginit,
   &google_protobuf_DescriptorProto_ExtensionRange_msginit,
   &google_protobuf_DescriptorProto_ReservedRange_msginit,
@@ -82,7 +82,7 @@ static const upb_msglayout_field google_protobuf_DescriptorProto__fields[10] = {
 const upb_msglayout google_protobuf_DescriptorProto_msginit = {
   &google_protobuf_DescriptorProto_submsgs[0],
   &google_protobuf_DescriptorProto__fields[0],
-  UPB_SIZE(48, 96), 10, false,
+  UPB_SIZE(48, 96), 10, false, 255,
 };
 
 static const upb_msglayout *const google_protobuf_DescriptorProto_ExtensionRange_submsgs[1] = {
@@ -98,7 +98,7 @@ static const upb_msglayout_field google_protobuf_DescriptorProto_ExtensionRange_
 const upb_msglayout google_protobuf_DescriptorProto_ExtensionRange_msginit = {
   &google_protobuf_DescriptorProto_ExtensionRange_submsgs[0],
   &google_protobuf_DescriptorProto_ExtensionRange__fields[0],
-  UPB_SIZE(16, 24), 3, false,
+  UPB_SIZE(16, 24), 3, false, 255,
 };
 
 static const upb_msglayout_field google_protobuf_DescriptorProto_ReservedRange__fields[2] = {
@@ -109,7 +109,7 @@ static const upb_msglayout_field google_protobuf_DescriptorProto_ReservedRange__
 const upb_msglayout google_protobuf_DescriptorProto_ReservedRange_msginit = {
   NULL,
   &google_protobuf_DescriptorProto_ReservedRange__fields[0],
-  UPB_SIZE(12, 12), 2, false,
+  UPB_SIZE(16, 16), 2, false, 255,
 };
 
 static const upb_msglayout *const google_protobuf_ExtensionRangeOptions_submsgs[1] = {
@@ -123,7 +123,7 @@ static const upb_msglayout_field google_protobuf_ExtensionRangeOptions__fields[1
 const upb_msglayout google_protobuf_ExtensionRangeOptions_msginit = {
   &google_protobuf_ExtensionRangeOptions_submsgs[0],
   &google_protobuf_ExtensionRangeOptions__fields[0],
-  UPB_SIZE(4, 8), 1, false,
+  UPB_SIZE(8, 8), 1, false, 255,
 };
 
 static const upb_msglayout *const google_protobuf_FieldDescriptorProto_submsgs[1] = {
@@ -131,23 +131,23 @@ static const upb_msglayout *const google_protobuf_FieldDescriptorProto_submsgs[1
 };
 
 static const upb_msglayout_field google_protobuf_FieldDescriptorProto__fields[11] = {
-  {1, UPB_SIZE(36, 40), 6, 0, 12, 1},
-  {2, UPB_SIZE(44, 56), 7, 0, 12, 1},
-  {3, UPB_SIZE(24, 24), 3, 0, 5, 1},
-  {4, UPB_SIZE(8, 8), 1, 0, 14, 1},
-  {5, UPB_SIZE(16, 16), 2, 0, 14, 1},
-  {6, UPB_SIZE(52, 72), 8, 0, 12, 1},
-  {7, UPB_SIZE(60, 88), 9, 0, 12, 1},
-  {8, UPB_SIZE(76, 120), 11, 0, 11, 1},
-  {9, UPB_SIZE(28, 28), 4, 0, 5, 1},
-  {10, UPB_SIZE(68, 104), 10, 0, 12, 1},
-  {17, UPB_SIZE(32, 32), 5, 0, 8, 1},
+  {1, UPB_SIZE(24, 24), 1, 0, 12, 1},
+  {2, UPB_SIZE(32, 40), 2, 0, 12, 1},
+  {3, UPB_SIZE(12, 12), 3, 0, 5, 1},
+  {4, UPB_SIZE(4, 4), 4, 0, 14, 1},
+  {5, UPB_SIZE(8, 8), 5, 0, 14, 1},
+  {6, UPB_SIZE(40, 56), 6, 0, 12, 1},
+  {7, UPB_SIZE(48, 72), 7, 0, 12, 1},
+  {8, UPB_SIZE(64, 104), 8, 0, 11, 1},
+  {9, UPB_SIZE(16, 16), 9, 0, 5, 1},
+  {10, UPB_SIZE(56, 88), 10, 0, 12, 1},
+  {17, UPB_SIZE(20, 20), 11, 0, 8, 1},
 };
 
 const upb_msglayout google_protobuf_FieldDescriptorProto_msginit = {
   &google_protobuf_FieldDescriptorProto_submsgs[0],
   &google_protobuf_FieldDescriptorProto__fields[0],
-  UPB_SIZE(80, 128), 11, false,
+  UPB_SIZE(72, 112), 11, false, 255,
 };
 
 static const upb_msglayout *const google_protobuf_OneofDescriptorProto_submsgs[1] = {
@@ -162,7 +162,7 @@ static const upb_msglayout_field google_protobuf_OneofDescriptorProto__fields[2]
 const upb_msglayout google_protobuf_OneofDescriptorProto_msginit = {
   &google_protobuf_OneofDescriptorProto_submsgs[0],
   &google_protobuf_OneofDescriptorProto__fields[0],
-  UPB_SIZE(16, 32), 2, false,
+  UPB_SIZE(16, 32), 2, false, 255,
 };
 
 static const upb_msglayout *const google_protobuf_EnumDescriptorProto_submsgs[3] = {
@@ -182,7 +182,7 @@ static const upb_msglayout_field google_protobuf_EnumDescriptorProto__fields[5]
 const upb_msglayout google_protobuf_EnumDescriptorProto_msginit = {
   &google_protobuf_EnumDescriptorProto_submsgs[0],
   &google_protobuf_EnumDescriptorProto__fields[0],
-  UPB_SIZE(32, 64), 5, false,
+  UPB_SIZE(32, 64), 5, false, 255,
 };
 
 static const upb_msglayout_field google_protobuf_EnumDescriptorProto_EnumReservedRange__fields[2] = {
@@ -193,7 +193,7 @@ static const upb_msglayout_field google_protobuf_EnumDescriptorProto_EnumReserve
 const upb_msglayout google_protobuf_EnumDescriptorProto_EnumReservedRange_msginit = {
   NULL,
   &google_protobuf_EnumDescriptorProto_EnumReservedRange__fields[0],
-  UPB_SIZE(12, 12), 2, false,
+  UPB_SIZE(16, 16), 2, false, 255,
 };
 
 static const upb_msglayout *const google_protobuf_EnumValueDescriptorProto_submsgs[1] = {
@@ -201,15 +201,15 @@ static const upb_msglayout *const google_protobuf_EnumValueDescriptorProto_subms
 };
 
 static const upb_msglayout_field google_protobuf_EnumValueDescriptorProto__fields[3] = {
-  {1, UPB_SIZE(8, 8), 2, 0, 12, 1},
-  {2, UPB_SIZE(4, 4), 1, 0, 5, 1},
+  {1, UPB_SIZE(8, 8), 1, 0, 12, 1},
+  {2, UPB_SIZE(4, 4), 2, 0, 5, 1},
   {3, UPB_SIZE(16, 24), 3, 0, 11, 1},
 };
 
 const upb_msglayout google_protobuf_EnumValueDescriptorProto_msginit = {
   &google_protobuf_EnumValueDescriptorProto_submsgs[0],
   &google_protobuf_EnumValueDescriptorProto__fields[0],
-  UPB_SIZE(24, 32), 3, false,
+  UPB_SIZE(24, 32), 3, false, 255,
 };
 
 static const upb_msglayout *const google_protobuf_ServiceDescriptorProto_submsgs[2] = {
@@ -226,7 +226,7 @@ static const upb_msglayout_field google_protobuf_ServiceDescriptorProto__fields[
 const upb_msglayout google_protobuf_ServiceDescriptorProto_msginit = {
   &google_protobuf_ServiceDescriptorProto_submsgs[0],
   &google_protobuf_ServiceDescriptorProto__fields[0],
-  UPB_SIZE(24, 48), 3, false,
+  UPB_SIZE(24, 48), 3, false, 255,
 };
 
 static const upb_msglayout *const google_protobuf_MethodDescriptorProto_submsgs[1] = {
@@ -234,18 +234,18 @@ static const upb_msglayout *const google_protobuf_MethodDescriptorProto_submsgs[
 };
 
 static const upb_msglayout_field google_protobuf_MethodDescriptorProto__fields[6] = {
-  {1, UPB_SIZE(4, 8), 3, 0, 12, 1},
-  {2, UPB_SIZE(12, 24), 4, 0, 12, 1},
-  {3, UPB_SIZE(20, 40), 5, 0, 12, 1},
-  {4, UPB_SIZE(28, 56), 6, 0, 11, 1},
-  {5, UPB_SIZE(1, 1), 1, 0, 8, 1},
-  {6, UPB_SIZE(2, 2), 2, 0, 8, 1},
+  {1, UPB_SIZE(4, 8), 1, 0, 12, 1},
+  {2, UPB_SIZE(12, 24), 2, 0, 12, 1},
+  {3, UPB_SIZE(20, 40), 3, 0, 12, 1},
+  {4, UPB_SIZE(28, 56), 4, 0, 11, 1},
+  {5, UPB_SIZE(1, 1), 5, 0, 8, 1},
+  {6, UPB_SIZE(2, 2), 6, 0, 8, 1},
 };
 
 const upb_msglayout google_protobuf_MethodDescriptorProto_msginit = {
   &google_protobuf_MethodDescriptorProto_submsgs[0],
   &google_protobuf_MethodDescriptorProto__fields[0],
-  UPB_SIZE(32, 64), 6, false,
+  UPB_SIZE(32, 64), 6, false, 255,
 };
 
 static const upb_msglayout *const google_protobuf_FileOptions_submsgs[1] = {
@@ -253,33 +253,33 @@ static const upb_msglayout *const google_protobuf_FileOptions_submsgs[1] = {
 };
 
 static const upb_msglayout_field google_protobuf_FileOptions__fields[21] = {
-  {1, UPB_SIZE(28, 32), 11, 0, 12, 1},
-  {8, UPB_SIZE(36, 48), 12, 0, 12, 1},
-  {9, UPB_SIZE(8, 8), 1, 0, 14, 1},
-  {10, UPB_SIZE(16, 16), 2, 0, 8, 1},
-  {11, UPB_SIZE(44, 64), 13, 0, 12, 1},
-  {16, UPB_SIZE(17, 17), 3, 0, 8, 1},
-  {17, UPB_SIZE(18, 18), 4, 0, 8, 1},
-  {18, UPB_SIZE(19, 19), 5, 0, 8, 1},
-  {20, UPB_SIZE(20, 20), 6, 0, 8, 1},
-  {23, UPB_SIZE(21, 21), 7, 0, 8, 1},
-  {27, UPB_SIZE(22, 22), 8, 0, 8, 1},
-  {31, UPB_SIZE(23, 23), 9, 0, 8, 1},
-  {36, UPB_SIZE(52, 80), 14, 0, 12, 1},
-  {37, UPB_SIZE(60, 96), 15, 0, 12, 1},
-  {39, UPB_SIZE(68, 112), 16, 0, 12, 1},
-  {40, UPB_SIZE(76, 128), 17, 0, 12, 1},
-  {41, UPB_SIZE(84, 144), 18, 0, 12, 1},
-  {42, UPB_SIZE(24, 24), 10, 0, 8, 1},
-  {44, UPB_SIZE(92, 160), 19, 0, 12, 1},
-  {45, UPB_SIZE(100, 176), 20, 0, 12, 1},
-  {999, UPB_SIZE(108, 192), 0, 0, 11, 3},
+  {1, UPB_SIZE(20, 24), 1, 0, 12, 1},
+  {8, UPB_SIZE(28, 40), 2, 0, 12, 1},
+  {9, UPB_SIZE(4, 4), 3, 0, 14, 1},
+  {10, UPB_SIZE(8, 8), 4, 0, 8, 1},
+  {11, UPB_SIZE(36, 56), 5, 0, 12, 1},
+  {16, UPB_SIZE(9, 9), 6, 0, 8, 1},
+  {17, UPB_SIZE(10, 10), 7, 0, 8, 1},
+  {18, UPB_SIZE(11, 11), 8, 0, 8, 1},
+  {20, UPB_SIZE(12, 12), 9, 0, 8, 1},
+  {23, UPB_SIZE(13, 13), 10, 0, 8, 1},
+  {27, UPB_SIZE(14, 14), 11, 0, 8, 1},
+  {31, UPB_SIZE(15, 15), 12, 0, 8, 1},
+  {36, UPB_SIZE(44, 72), 13, 0, 12, 1},
+  {37, UPB_SIZE(52, 88), 14, 0, 12, 1},
+  {39, UPB_SIZE(60, 104), 15, 0, 12, 1},
+  {40, UPB_SIZE(68, 120), 16, 0, 12, 1},
+  {41, UPB_SIZE(76, 136), 17, 0, 12, 1},
+  {42, UPB_SIZE(16, 16), 18, 0, 8, 1},
+  {44, UPB_SIZE(84, 152), 19, 0, 12, 1},
+  {45, UPB_SIZE(92, 168), 20, 0, 12, 1},
+  {999, UPB_SIZE(100, 184), 0, 0, 11, 3},
 };
 
 const upb_msglayout google_protobuf_FileOptions_msginit = {
   &google_protobuf_FileOptions_submsgs[0],
   &google_protobuf_FileOptions__fields[0],
-  UPB_SIZE(112, 208), 21, false,
+  UPB_SIZE(104, 192), 21, false, 255,
 };
 
 static const upb_msglayout *const google_protobuf_MessageOptions_submsgs[1] = {
@@ -297,7 +297,7 @@ static const upb_msglayout_field google_protobuf_MessageOptions__fields[5] = {
 const upb_msglayout google_protobuf_MessageOptions_msginit = {
   &google_protobuf_MessageOptions_submsgs[0],
   &google_protobuf_MessageOptions__fields[0],
-  UPB_SIZE(12, 16), 5, false,
+  UPB_SIZE(16, 16), 5, false, 255,
 };
 
 static const upb_msglayout *const google_protobuf_FieldOptions_submsgs[1] = {
@@ -305,19 +305,19 @@ static const upb_msglayout *const google_protobuf_FieldOptions_submsgs[1] = {
 };
 
 static const upb_msglayout_field google_protobuf_FieldOptions__fields[7] = {
-  {1, UPB_SIZE(8, 8), 1, 0, 14, 1},
-  {2, UPB_SIZE(24, 24), 3, 0, 8, 1},
-  {3, UPB_SIZE(25, 25), 4, 0, 8, 1},
-  {5, UPB_SIZE(26, 26), 5, 0, 8, 1},
-  {6, UPB_SIZE(16, 16), 2, 0, 14, 1},
-  {10, UPB_SIZE(27, 27), 6, 0, 8, 1},
-  {999, UPB_SIZE(28, 32), 0, 0, 11, 3},
+  {1, UPB_SIZE(4, 4), 1, 0, 14, 1},
+  {2, UPB_SIZE(12, 12), 2, 0, 8, 1},
+  {3, UPB_SIZE(13, 13), 3, 0, 8, 1},
+  {5, UPB_SIZE(14, 14), 4, 0, 8, 1},
+  {6, UPB_SIZE(8, 8), 5, 0, 14, 1},
+  {10, UPB_SIZE(15, 15), 6, 0, 8, 1},
+  {999, UPB_SIZE(16, 16), 0, 0, 11, 3},
 };
 
 const upb_msglayout google_protobuf_FieldOptions_msginit = {
   &google_protobuf_FieldOptions_submsgs[0],
   &google_protobuf_FieldOptions__fields[0],
-  UPB_SIZE(32, 40), 7, false,
+  UPB_SIZE(24, 24), 7, false, 255,
 };
 
 static const upb_msglayout *const google_protobuf_OneofOptions_submsgs[1] = {
@@ -331,7 +331,7 @@ static const upb_msglayout_field google_protobuf_OneofOptions__fields[1] = {
 const upb_msglayout google_protobuf_OneofOptions_msginit = {
   &google_protobuf_OneofOptions_submsgs[0],
   &google_protobuf_OneofOptions__fields[0],
-  UPB_SIZE(4, 8), 1, false,
+  UPB_SIZE(8, 8), 1, false, 255,
 };
 
 static const upb_msglayout *const google_protobuf_EnumOptions_submsgs[1] = {
@@ -347,7 +347,7 @@ static const upb_msglayout_field google_protobuf_EnumOptions__fields[3] = {
 const upb_msglayout google_protobuf_EnumOptions_msginit = {
   &google_protobuf_EnumOptions_submsgs[0],
   &google_protobuf_EnumOptions__fields[0],
-  UPB_SIZE(8, 16), 3, false,
+  UPB_SIZE(8, 16), 3, false, 255,
 };
 
 static const upb_msglayout *const google_protobuf_EnumValueOptions_submsgs[1] = {
@@ -362,7 +362,7 @@ static const upb_msglayout_field google_protobuf_EnumValueOptions__fields[2] = {
 const upb_msglayout google_protobuf_EnumValueOptions_msginit = {
   &google_protobuf_EnumValueOptions_submsgs[0],
   &google_protobuf_EnumValueOptions__fields[0],
-  UPB_SIZE(8, 16), 2, false,
+  UPB_SIZE(8, 16), 2, false, 255,
 };
 
 static const upb_msglayout *const google_protobuf_ServiceOptions_submsgs[1] = {
@@ -377,7 +377,7 @@ static const upb_msglayout_field google_protobuf_ServiceOptions__fields[2] = {
 const upb_msglayout google_protobuf_ServiceOptions_msginit = {
   &google_protobuf_ServiceOptions_submsgs[0],
   &google_protobuf_ServiceOptions__fields[0],
-  UPB_SIZE(8, 16), 2, false,
+  UPB_SIZE(8, 16), 2, false, 255,
 };
 
 static const upb_msglayout *const google_protobuf_MethodOptions_submsgs[1] = {
@@ -385,15 +385,15 @@ static const upb_msglayout *const google_protobuf_MethodOptions_submsgs[1] = {
 };
 
 static const upb_msglayout_field google_protobuf_MethodOptions__fields[3] = {
-  {33, UPB_SIZE(16, 16), 2, 0, 8, 1},
-  {34, UPB_SIZE(8, 8), 1, 0, 14, 1},
-  {999, UPB_SIZE(20, 24), 0, 0, 11, 3},
+  {33, UPB_SIZE(8, 8), 1, 0, 8, 1},
+  {34, UPB_SIZE(4, 4), 2, 0, 14, 1},
+  {999, UPB_SIZE(12, 16), 0, 0, 11, 3},
 };
 
 const upb_msglayout google_protobuf_MethodOptions_msginit = {
   &google_protobuf_MethodOptions_submsgs[0],
   &google_protobuf_MethodOptions__fields[0],
-  UPB_SIZE(24, 32), 3, false,
+  UPB_SIZE(16, 24), 3, false, 255,
 };
 
 static const upb_msglayout *const google_protobuf_UninterpretedOption_submsgs[1] = {
@@ -402,10 +402,10 @@ static const upb_msglayout *const google_protobuf_UninterpretedOption_submsgs[1]
 
 static const upb_msglayout_field google_protobuf_UninterpretedOption__fields[7] = {
   {2, UPB_SIZE(56, 80), 0, 0, 11, 3},
-  {3, UPB_SIZE(32, 32), 4, 0, 12, 1},
-  {4, UPB_SIZE(8, 8), 1, 0, 4, 1},
-  {5, UPB_SIZE(16, 16), 2, 0, 3, 1},
-  {6, UPB_SIZE(24, 24), 3, 0, 1, 1},
+  {3, UPB_SIZE(32, 32), 1, 0, 12, 1},
+  {4, UPB_SIZE(8, 8), 2, 0, 4, 1},
+  {5, UPB_SIZE(16, 16), 3, 0, 3, 1},
+  {6, UPB_SIZE(24, 24), 4, 0, 1, 1},
   {7, UPB_SIZE(40, 48), 5, 0, 12, 1},
   {8, UPB_SIZE(48, 64), 6, 0, 12, 1},
 };
@@ -413,18 +413,18 @@ static const upb_msglayout_field google_protobuf_UninterpretedOption__fields[7]
 const upb_msglayout google_protobuf_UninterpretedOption_msginit = {
   &google_protobuf_UninterpretedOption_submsgs[0],
   &google_protobuf_UninterpretedOption__fields[0],
-  UPB_SIZE(64, 96), 7, false,
+  UPB_SIZE(64, 96), 7, false, 255,
 };
 
 static const upb_msglayout_field google_protobuf_UninterpretedOption_NamePart__fields[2] = {
-  {1, UPB_SIZE(4, 8), 2, 0, 12, 2},
-  {2, UPB_SIZE(1, 1), 1, 0, 8, 2},
+  {1, UPB_SIZE(4, 8), 1, 0, 12, 2},
+  {2, UPB_SIZE(1, 1), 2, 0, 8, 2},
 };
 
 const upb_msglayout google_protobuf_UninterpretedOption_NamePart_msginit = {
   NULL,
   &google_protobuf_UninterpretedOption_NamePart__fields[0],
-  UPB_SIZE(16, 32), 2, false,
+  UPB_SIZE(16, 32), 2, false, 255,
 };
 
 static const upb_msglayout *const google_protobuf_SourceCodeInfo_submsgs[1] = {
@@ -438,7 +438,7 @@ static const upb_msglayout_field google_protobuf_SourceCodeInfo__fields[1] = {
 const upb_msglayout google_protobuf_SourceCodeInfo_msginit = {
   &google_protobuf_SourceCodeInfo_submsgs[0],
   &google_protobuf_SourceCodeInfo__fields[0],
-  UPB_SIZE(4, 8), 1, false,
+  UPB_SIZE(8, 8), 1, false, 255,
 };
 
 static const upb_msglayout_field google_protobuf_SourceCodeInfo_Location__fields[5] = {
@@ -452,7 +452,7 @@ static const upb_msglayout_field google_protobuf_SourceCodeInfo_Location__fields
 const upb_msglayout google_protobuf_SourceCodeInfo_Location_msginit = {
   NULL,
   &google_protobuf_SourceCodeInfo_Location__fields[0],
-  UPB_SIZE(32, 64), 5, false,
+  UPB_SIZE(32, 64), 5, false, 255,
 };
 
 static const upb_msglayout *const google_protobuf_GeneratedCodeInfo_submsgs[1] = {
@@ -466,20 +466,20 @@ static const upb_msglayout_field google_protobuf_GeneratedCodeInfo__fields[1] =
 const upb_msglayout google_protobuf_GeneratedCodeInfo_msginit = {
   &google_protobuf_GeneratedCodeInfo_submsgs[0],
   &google_protobuf_GeneratedCodeInfo__fields[0],
-  UPB_SIZE(4, 8), 1, false,
+  UPB_SIZE(8, 8), 1, false, 255,
 };
 
 static const upb_msglayout_field google_protobuf_GeneratedCodeInfo_Annotation__fields[4] = {
   {1, UPB_SIZE(20, 32), 0, 0, 5, _UPB_LABEL_PACKED},
-  {2, UPB_SIZE(12, 16), 3, 0, 12, 1},
-  {3, UPB_SIZE(4, 4), 1, 0, 5, 1},
-  {4, UPB_SIZE(8, 8), 2, 0, 5, 1},
+  {2, UPB_SIZE(12, 16), 1, 0, 12, 1},
+  {3, UPB_SIZE(4, 4), 2, 0, 5, 1},
+  {4, UPB_SIZE(8, 8), 3, 0, 5, 1},
 };
 
 const upb_msglayout google_protobuf_GeneratedCodeInfo_Annotation_msginit = {
   NULL,
   &google_protobuf_GeneratedCodeInfo_Annotation__fields[0],
-  UPB_SIZE(24, 48), 4, false,
+  UPB_SIZE(24, 48), 4, false, 255,
 };
 
 #include "upb/port_undef.inc"
@@ -11,6 +11,7 @@
 
 #include "upb/msg.h"
 #include "upb/decode.h"
+#include "upb/decode_fast.h"
 #include "upb/encode.h"
 
 #include "upb/port_def.inc"
@@ -163,6 +164,12 @@ UPB_INLINE google_protobuf_FileDescriptorSet *google_protobuf_FileDescriptorSet_
   google_protobuf_FileDescriptorSet *ret = google_protobuf_FileDescriptorSet_new(arena);
   return (ret && upb_decode(buf, size, ret, &google_protobuf_FileDescriptorSet_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE google_protobuf_FileDescriptorSet *google_protobuf_FileDescriptorSet_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  google_protobuf_FileDescriptorSet *ret = google_protobuf_FileDescriptorSet_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &google_protobuf_FileDescriptorSet_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *google_protobuf_FileDescriptorSet_serialize(const google_protobuf_FileDescriptorSet *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &google_protobuf_FileDescriptorSet_msginit, arena, len);
 }
@@ -174,12 +181,12 @@ UPB_INLINE google_protobuf_FileDescriptorProto** google_protobuf_FileDescriptorS
   return (google_protobuf_FileDescriptorProto**)_upb_array_mutable_accessor(msg, UPB_SIZE(0, 0), len);
 }
 UPB_INLINE google_protobuf_FileDescriptorProto** google_protobuf_FileDescriptorSet_resize_file(google_protobuf_FileDescriptorSet *msg, size_t len, upb_arena *arena) {
-  return (google_protobuf_FileDescriptorProto**)_upb_array_resize_accessor(msg, UPB_SIZE(0, 0), len, UPB_TYPE_MESSAGE, arena);
+  return (google_protobuf_FileDescriptorProto**)_upb_array_resize_accessor2(msg, UPB_SIZE(0, 0), len, UPB_SIZE(2, 3), arena);
 }
 UPB_INLINE struct google_protobuf_FileDescriptorProto* google_protobuf_FileDescriptorSet_add_file(google_protobuf_FileDescriptorSet *msg, upb_arena *arena) {
   struct google_protobuf_FileDescriptorProto* sub = (struct google_protobuf_FileDescriptorProto*)_upb_msg_new(&google_protobuf_FileDescriptorProto_msginit, arena);
-  bool ok = _upb_array_append_accessor(
-      msg, UPB_SIZE(0, 0), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena);
+  bool ok = _upb_array_append_accessor2(
+      msg, UPB_SIZE(0, 0), UPB_SIZE(2, 3), &sub, arena);
   if (!ok) return NULL;
   return sub;
 }
@@ -194,6 +201,12 @@ UPB_INLINE google_protobuf_FileDescriptorProto *google_protobuf_FileDescriptorPr
   google_protobuf_FileDescriptorProto *ret = google_protobuf_FileDescriptorProto_new(arena);
   return (ret && upb_decode(buf, size, ret, &google_protobuf_FileDescriptorProto_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE google_protobuf_FileDescriptorProto *google_protobuf_FileDescriptorProto_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  google_protobuf_FileDescriptorProto *ret = google_protobuf_FileDescriptorProto_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &google_protobuf_FileDescriptorProto_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *google_protobuf_FileDescriptorProto_serialize(const google_protobuf_FileDescriptorProto *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &google_protobuf_FileDescriptorProto_msginit, arena, len);
 }
@@ -211,13 +224,13 @@ UPB_INLINE bool google_protobuf_FileDescriptorProto_has_service(const google_pro
 UPB_INLINE const google_protobuf_ServiceDescriptorProto* const* google_protobuf_FileDescriptorProto_service(const google_protobuf_FileDescriptorProto *msg, size_t *len) { return (const google_protobuf_ServiceDescriptorProto* const*)_upb_array_accessor(msg, UPB_SIZE(48, 96), len); }
 UPB_INLINE bool google_protobuf_FileDescriptorProto_has_extension(const google_protobuf_FileDescriptorProto *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(52, 104)); }
 UPB_INLINE const google_protobuf_FieldDescriptorProto* const* google_protobuf_FileDescriptorProto_extension(const google_protobuf_FileDescriptorProto *msg, size_t *len) { return (const google_protobuf_FieldDescriptorProto* const*)_upb_array_accessor(msg, UPB_SIZE(52, 104), len); }
-UPB_INLINE bool google_protobuf_FileDescriptorProto_has_options(const google_protobuf_FileDescriptorProto *msg) { return _upb_hasbit(msg, 4); }
+UPB_INLINE bool google_protobuf_FileDescriptorProto_has_options(const google_protobuf_FileDescriptorProto *msg) { return _upb_hasbit(msg, 3); }
 UPB_INLINE const google_protobuf_FileOptions* google_protobuf_FileDescriptorProto_options(const google_protobuf_FileDescriptorProto *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(28, 56), const google_protobuf_FileOptions*); }
-UPB_INLINE bool google_protobuf_FileDescriptorProto_has_source_code_info(const google_protobuf_FileDescriptorProto *msg) { return _upb_hasbit(msg, 5); }
+UPB_INLINE bool google_protobuf_FileDescriptorProto_has_source_code_info(const google_protobuf_FileDescriptorProto *msg) { return _upb_hasbit(msg, 4); }
 UPB_INLINE const google_protobuf_SourceCodeInfo* google_protobuf_FileDescriptorProto_source_code_info(const google_protobuf_FileDescriptorProto *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(32, 64), const google_protobuf_SourceCodeInfo*); }
 UPB_INLINE int32_t const* google_protobuf_FileDescriptorProto_public_dependency(const google_protobuf_FileDescriptorProto *msg, size_t *len) { return (int32_t const*)_upb_array_accessor(msg, UPB_SIZE(56, 112), len); }
 UPB_INLINE int32_t const* google_protobuf_FileDescriptorProto_weak_dependency(const google_protobuf_FileDescriptorProto *msg, size_t *len) { return (int32_t const*)_upb_array_accessor(msg, UPB_SIZE(60, 120), len); }
-UPB_INLINE bool google_protobuf_FileDescriptorProto_has_syntax(const google_protobuf_FileDescriptorProto *msg) { return _upb_hasbit(msg, 3); }
+UPB_INLINE bool google_protobuf_FileDescriptorProto_has_syntax(const google_protobuf_FileDescriptorProto *msg) { return _upb_hasbit(msg, 5); }
 UPB_INLINE upb_strview google_protobuf_FileDescriptorProto_syntax(const google_protobuf_FileDescriptorProto *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(20, 40), upb_strview); }
 
 UPB_INLINE void google_protobuf_FileDescriptorProto_set_name(google_protobuf_FileDescriptorProto *msg, upb_strview value) {
@@ -232,22 +245,22 @@ UPB_INLINE upb_strview* google_protobuf_FileDescriptorProto_mutable_dependency(g
   return (upb_strview*)_upb_array_mutable_accessor(msg, UPB_SIZE(36, 72), len);
 }
 UPB_INLINE upb_strview* google_protobuf_FileDescriptorProto_resize_dependency(google_protobuf_FileDescriptorProto *msg, size_t len, upb_arena *arena) {
-  return (upb_strview*)_upb_array_resize_accessor(msg, UPB_SIZE(36, 72), len, UPB_TYPE_STRING, arena);
+  return (upb_strview*)_upb_array_resize_accessor2(msg, UPB_SIZE(36, 72), len, UPB_SIZE(3, 4), arena);
 }
 UPB_INLINE bool google_protobuf_FileDescriptorProto_add_dependency(google_protobuf_FileDescriptorProto *msg, upb_strview val, upb_arena *arena) {
-  return _upb_array_append_accessor(msg, UPB_SIZE(36, 72), UPB_SIZE(8, 16), UPB_TYPE_STRING, &val,
+  return _upb_array_append_accessor2(msg, UPB_SIZE(36, 72), UPB_SIZE(3, 4), &val,
       arena);
 }
 UPB_INLINE google_protobuf_DescriptorProto** google_protobuf_FileDescriptorProto_mutable_message_type(google_protobuf_FileDescriptorProto *msg, size_t *len) {
   return (google_protobuf_DescriptorProto**)_upb_array_mutable_accessor(msg, UPB_SIZE(40, 80), len);
 }
 UPB_INLINE google_protobuf_DescriptorProto** google_protobuf_FileDescriptorProto_resize_message_type(google_protobuf_FileDescriptorProto *msg, size_t len, upb_arena *arena) {
-  return (google_protobuf_DescriptorProto**)_upb_array_resize_accessor(msg, UPB_SIZE(40, 80), len, UPB_TYPE_MESSAGE, arena);
+  return (google_protobuf_DescriptorProto**)_upb_array_resize_accessor2(msg, UPB_SIZE(40, 80), len, UPB_SIZE(2, 3), arena);
 }
 UPB_INLINE struct google_protobuf_DescriptorProto* google_protobuf_FileDescriptorProto_add_message_type(google_protobuf_FileDescriptorProto *msg, upb_arena *arena) {
   struct google_protobuf_DescriptorProto* sub = (struct google_protobuf_DescriptorProto*)_upb_msg_new(&google_protobuf_DescriptorProto_msginit, arena);
-  bool ok = _upb_array_append_accessor(
-      msg, UPB_SIZE(40, 80), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena);
+  bool ok = _upb_array_append_accessor2(
+      msg, UPB_SIZE(40, 80), UPB_SIZE(2, 3), &sub, arena);
   if (!ok) return NULL;
   return sub;
 }
@@ -255,12 +268,12 @@ UPB_INLINE google_protobuf_EnumDescriptorProto** google_protobuf_FileDescriptorP
   return (google_protobuf_EnumDescriptorProto**)_upb_array_mutable_accessor(msg, UPB_SIZE(44, 88), len);
 }
 UPB_INLINE google_protobuf_EnumDescriptorProto** google_protobuf_FileDescriptorProto_resize_enum_type(google_protobuf_FileDescriptorProto *msg, size_t len, upb_arena *arena) {
-  return (google_protobuf_EnumDescriptorProto**)_upb_array_resize_accessor(msg, UPB_SIZE(44, 88), len, UPB_TYPE_MESSAGE, arena);
+  return (google_protobuf_EnumDescriptorProto**)_upb_array_resize_accessor2(msg, UPB_SIZE(44, 88), len, UPB_SIZE(2, 3), arena);
 }
 UPB_INLINE struct google_protobuf_EnumDescriptorProto* google_protobuf_FileDescriptorProto_add_enum_type(google_protobuf_FileDescriptorProto *msg, upb_arena *arena) {
   struct google_protobuf_EnumDescriptorProto* sub = (struct google_protobuf_EnumDescriptorProto*)_upb_msg_new(&google_protobuf_EnumDescriptorProto_msginit, arena);
-  bool ok = _upb_array_append_accessor(
-      msg, UPB_SIZE(44, 88), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena);
+  bool ok = _upb_array_append_accessor2(
+      msg, UPB_SIZE(44, 88), UPB_SIZE(2, 3), &sub, arena);
   if (!ok) return NULL;
   return sub;
 }
@@ -268,12 +281,12 @@ UPB_INLINE google_protobuf_ServiceDescriptorProto** google_protobuf_FileDescript
   return (google_protobuf_ServiceDescriptorProto**)_upb_array_mutable_accessor(msg, UPB_SIZE(48, 96), len);
 }
 UPB_INLINE google_protobuf_ServiceDescriptorProto** google_protobuf_FileDescriptorProto_resize_service(google_protobuf_FileDescriptorProto *msg, size_t len, upb_arena *arena) {
-  return (google_protobuf_ServiceDescriptorProto**)_upb_array_resize_accessor(msg, UPB_SIZE(48, 96), len, UPB_TYPE_MESSAGE, arena);
+  return (google_protobuf_ServiceDescriptorProto**)_upb_array_resize_accessor2(msg, UPB_SIZE(48, 96), len, UPB_SIZE(2, 3), arena);
 }
 UPB_INLINE struct google_protobuf_ServiceDescriptorProto* google_protobuf_FileDescriptorProto_add_service(google_protobuf_FileDescriptorProto *msg, upb_arena *arena) {
   struct google_protobuf_ServiceDescriptorProto* sub = (struct google_protobuf_ServiceDescriptorProto*)_upb_msg_new(&google_protobuf_ServiceDescriptorProto_msginit, arena);
-  bool ok = _upb_array_append_accessor(
-      msg, UPB_SIZE(48, 96), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena);
+  bool ok = _upb_array_append_accessor2(
+      msg, UPB_SIZE(48, 96), UPB_SIZE(2, 3), &sub, arena);
   if (!ok) return NULL;
   return sub;
 }
@@ -281,17 +294,17 @@ UPB_INLINE google_protobuf_FieldDescriptorProto** google_protobuf_FileDescriptor
   return (google_protobuf_FieldDescriptorProto**)_upb_array_mutable_accessor(msg, UPB_SIZE(52, 104), len);
 }
 UPB_INLINE google_protobuf_FieldDescriptorProto** google_protobuf_FileDescriptorProto_resize_extension(google_protobuf_FileDescriptorProto *msg, size_t len, upb_arena *arena) {
-  return (google_protobuf_FieldDescriptorProto**)_upb_array_resize_accessor(msg, UPB_SIZE(52, 104), len, UPB_TYPE_MESSAGE, arena);
+  return (google_protobuf_FieldDescriptorProto**)_upb_array_resize_accessor2(msg, UPB_SIZE(52, 104), len, UPB_SIZE(2, 3), arena);
 }
 UPB_INLINE struct google_protobuf_FieldDescriptorProto* google_protobuf_FileDescriptorProto_add_extension(google_protobuf_FileDescriptorProto *msg, upb_arena *arena) {
   struct google_protobuf_FieldDescriptorProto* sub = (struct google_protobuf_FieldDescriptorProto*)_upb_msg_new(&google_protobuf_FieldDescriptorProto_msginit, arena);
-  bool ok = _upb_array_append_accessor(
-      msg, UPB_SIZE(52, 104), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena);
+  bool ok = _upb_array_append_accessor2(
+      msg, UPB_SIZE(52, 104), UPB_SIZE(2, 3), &sub, arena);
   if (!ok) return NULL;
   return sub;
 }
 UPB_INLINE void google_protobuf_FileDescriptorProto_set_options(google_protobuf_FileDescriptorProto *msg, google_protobuf_FileOptions* value) {
-  _upb_sethas(msg, 4);
+  _upb_sethas(msg, 3);
   *UPB_PTR_AT(msg, UPB_SIZE(28, 56), google_protobuf_FileOptions*) = value;
 }
 UPB_INLINE struct google_protobuf_FileOptions* google_protobuf_FileDescriptorProto_mutable_options(google_protobuf_FileDescriptorProto *msg, upb_arena *arena) {
@@ -304,7 +317,7 @@ UPB_INLINE struct google_protobuf_FileOptions* google_protobuf_FileDescriptorPro
   return sub;
 }
 UPB_INLINE void google_protobuf_FileDescriptorProto_set_source_code_info(google_protobuf_FileDescriptorProto *msg, google_protobuf_SourceCodeInfo* value) {
-  _upb_sethas(msg, 5);
+  _upb_sethas(msg, 4);
   *UPB_PTR_AT(msg, UPB_SIZE(32, 64), google_protobuf_SourceCodeInfo*) = value;
 }
 UPB_INLINE struct google_protobuf_SourceCodeInfo* google_protobuf_FileDescriptorProto_mutable_source_code_info(google_protobuf_FileDescriptorProto *msg, upb_arena *arena) {
@@ -320,24 +333,24 @@ UPB_INLINE int32_t* google_protobuf_FileDescriptorProto_mutable_public_dependenc
   return (int32_t*)_upb_array_mutable_accessor(msg, UPB_SIZE(56, 112), len);
 }
 UPB_INLINE int32_t* google_protobuf_FileDescriptorProto_resize_public_dependency(google_protobuf_FileDescriptorProto *msg, size_t len, upb_arena *arena) {
-  return (int32_t*)_upb_array_resize_accessor(msg, UPB_SIZE(56, 112), len, UPB_TYPE_INT32, arena);
+  return (int32_t*)_upb_array_resize_accessor2(msg, UPB_SIZE(56, 112), len, 2, arena);
 }
 UPB_INLINE bool google_protobuf_FileDescriptorProto_add_public_dependency(google_protobuf_FileDescriptorProto *msg, int32_t val, upb_arena *arena) {
-  return _upb_array_append_accessor(msg, UPB_SIZE(56, 112), UPB_SIZE(4, 4), UPB_TYPE_INT32, &val,
+  return _upb_array_append_accessor2(msg, UPB_SIZE(56, 112), 2, &val,
       arena);
 }
 UPB_INLINE int32_t* google_protobuf_FileDescriptorProto_mutable_weak_dependency(google_protobuf_FileDescriptorProto *msg, size_t *len) {
   return (int32_t*)_upb_array_mutable_accessor(msg, UPB_SIZE(60, 120), len);
 }
 UPB_INLINE int32_t* google_protobuf_FileDescriptorProto_resize_weak_dependency(google_protobuf_FileDescriptorProto *msg, size_t len, upb_arena *arena) {
-  return (int32_t*)_upb_array_resize_accessor(msg, UPB_SIZE(60, 120), len, UPB_TYPE_INT32, arena);
+  return (int32_t*)_upb_array_resize_accessor2(msg, UPB_SIZE(60, 120), len, 2, arena);
 }
 UPB_INLINE bool google_protobuf_FileDescriptorProto_add_weak_dependency(google_protobuf_FileDescriptorProto *msg, int32_t val, upb_arena *arena) {
-  return _upb_array_append_accessor(msg, UPB_SIZE(60, 120), UPB_SIZE(4, 4), UPB_TYPE_INT32, &val,
+  return _upb_array_append_accessor2(msg, UPB_SIZE(60, 120), 2, &val,
       arena);
 }
 UPB_INLINE void google_protobuf_FileDescriptorProto_set_syntax(google_protobuf_FileDescriptorProto *msg, upb_strview value) {
-  _upb_sethas(msg, 3);
+  _upb_sethas(msg, 5);
   *UPB_PTR_AT(msg, UPB_SIZE(20, 40), upb_strview) = value;
 }
 
@@ -351,6 +364,12 @@ UPB_INLINE google_protobuf_DescriptorProto *google_protobuf_DescriptorProto_pars
   google_protobuf_DescriptorProto *ret = google_protobuf_DescriptorProto_new(arena);
   return (ret && upb_decode(buf, size, ret, &google_protobuf_DescriptorProto_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE google_protobuf_DescriptorProto *google_protobuf_DescriptorProto_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  google_protobuf_DescriptorProto *ret = google_protobuf_DescriptorProto_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &google_protobuf_DescriptorProto_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *google_protobuf_DescriptorProto_serialize(const google_protobuf_DescriptorProto *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &google_protobuf_DescriptorProto_msginit, arena, len);
 }
@@ -383,12 +402,12 @@ UPB_INLINE google_protobuf_FieldDescriptorProto** google_protobuf_DescriptorProt
   return (google_protobuf_FieldDescriptorProto**)_upb_array_mutable_accessor(msg, UPB_SIZE(16, 32), len);
 }
 UPB_INLINE google_protobuf_FieldDescriptorProto** google_protobuf_DescriptorProto_resize_field(google_protobuf_DescriptorProto *msg, size_t len, upb_arena *arena) {
-  return (google_protobuf_FieldDescriptorProto**)_upb_array_resize_accessor(msg, UPB_SIZE(16, 32), len, UPB_TYPE_MESSAGE, arena);
+  return (google_protobuf_FieldDescriptorProto**)_upb_array_resize_accessor2(msg, UPB_SIZE(16, 32), len, UPB_SIZE(2, 3), arena);
 }
 UPB_INLINE struct google_protobuf_FieldDescriptorProto* google_protobuf_DescriptorProto_add_field(google_protobuf_DescriptorProto *msg, upb_arena *arena) {
   struct google_protobuf_FieldDescriptorProto* sub = (struct google_protobuf_FieldDescriptorProto*)_upb_msg_new(&google_protobuf_FieldDescriptorProto_msginit, arena);
-  bool ok = _upb_array_append_accessor(
-      msg, UPB_SIZE(16, 32), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena);
+  bool ok = _upb_array_append_accessor2(
+      msg, UPB_SIZE(16, 32), UPB_SIZE(2, 3), &sub, arena);
   if (!ok) return NULL;
   return sub;
 }
@@ -396,12 +415,12 @@ UPB_INLINE google_protobuf_DescriptorProto** google_protobuf_DescriptorProto_mut
   return (google_protobuf_DescriptorProto**)_upb_array_mutable_accessor(msg, UPB_SIZE(20, 40), len);
 }
 UPB_INLINE google_protobuf_DescriptorProto** google_protobuf_DescriptorProto_resize_nested_type(google_protobuf_DescriptorProto *msg, size_t len, upb_arena *arena) {
-  return (google_protobuf_DescriptorProto**)_upb_array_resize_accessor(msg, UPB_SIZE(20, 40), len, UPB_TYPE_MESSAGE, arena);
+  return (google_protobuf_DescriptorProto**)_upb_array_resize_accessor2(msg, UPB_SIZE(20, 40), len, UPB_SIZE(2, 3), arena);
 }
 UPB_INLINE struct google_protobuf_DescriptorProto* google_protobuf_DescriptorProto_add_nested_type(google_protobuf_DescriptorProto *msg, upb_arena *arena) {
   struct google_protobuf_DescriptorProto* sub = (struct google_protobuf_DescriptorProto*)_upb_msg_new(&google_protobuf_DescriptorProto_msginit, arena);
-  bool ok = _upb_array_append_accessor(
-      msg, UPB_SIZE(20, 40), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena);
+  bool ok = _upb_array_append_accessor2(
+      msg, UPB_SIZE(20, 40), UPB_SIZE(2, 3), &sub, arena);
   if (!ok) return NULL;
   return sub;
 }
@@ -409,12 +428,12 @@ UPB_INLINE google_protobuf_EnumDescriptorProto** google_protobuf_DescriptorProto
   return (google_protobuf_EnumDescriptorProto**)_upb_array_mutable_accessor(msg, UPB_SIZE(24, 48), len);
 }
 UPB_INLINE google_protobuf_EnumDescriptorProto** google_protobuf_DescriptorProto_resize_enum_type(google_protobuf_DescriptorProto *msg, size_t len, upb_arena *arena) {
-  return (google_protobuf_EnumDescriptorProto**)_upb_array_resize_accessor(msg, UPB_SIZE(24, 48), len, UPB_TYPE_MESSAGE, arena);
+  return (google_protobuf_EnumDescriptorProto**)_upb_array_resize_accessor2(msg, UPB_SIZE(24, 48), len, UPB_SIZE(2, 3), arena);
 }
 UPB_INLINE struct google_protobuf_EnumDescriptorProto* google_protobuf_DescriptorProto_add_enum_type(google_protobuf_DescriptorProto *msg, upb_arena *arena) {
   struct google_protobuf_EnumDescriptorProto* sub = (struct google_protobuf_EnumDescriptorProto*)_upb_msg_new(&google_protobuf_EnumDescriptorProto_msginit, arena);
-  bool ok = _upb_array_append_accessor(
-      msg, UPB_SIZE(24, 48), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena);
+  bool ok = _upb_array_append_accessor2(
+      msg, UPB_SIZE(24, 48), UPB_SIZE(2, 3), &sub, arena);
   if (!ok) return NULL;
   return sub;
 }
@@ -422,12 +441,12 @@ UPB_INLINE google_protobuf_DescriptorProto_ExtensionRange** google_protobuf_Desc
   return (google_protobuf_DescriptorProto_ExtensionRange**)_upb_array_mutable_accessor(msg, UPB_SIZE(28, 56), len);
 }
 UPB_INLINE google_protobuf_DescriptorProto_ExtensionRange** google_protobuf_DescriptorProto_resize_extension_range(google_protobuf_DescriptorProto *msg, size_t len, upb_arena *arena) {
-  return (google_protobuf_DescriptorProto_ExtensionRange**)_upb_array_resize_accessor(msg, UPB_SIZE(28, 56), len, UPB_TYPE_MESSAGE, arena);
+  return (google_protobuf_DescriptorProto_ExtensionRange**)_upb_array_resize_accessor2(msg, UPB_SIZE(28, 56), len, UPB_SIZE(2, 3), arena);
 }
 UPB_INLINE struct google_protobuf_DescriptorProto_ExtensionRange* google_protobuf_DescriptorProto_add_extension_range(google_protobuf_DescriptorProto *msg, upb_arena *arena) {
   struct google_protobuf_DescriptorProto_ExtensionRange* sub = (struct google_protobuf_DescriptorProto_ExtensionRange*)_upb_msg_new(&google_protobuf_DescriptorProto_ExtensionRange_msginit, arena);
-  bool ok = _upb_array_append_accessor(
-      msg, UPB_SIZE(28, 56), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena);
+  bool ok = _upb_array_append_accessor2(
+      msg, UPB_SIZE(28, 56), UPB_SIZE(2, 3), &sub, arena);
   if (!ok) return NULL;
   return sub;
 }
@@ -435,12 +454,12 @@ UPB_INLINE google_protobuf_FieldDescriptorProto** google_protobuf_DescriptorProt
   return (google_protobuf_FieldDescriptorProto**)_upb_array_mutable_accessor(msg, UPB_SIZE(32, 64), len);
 }
 UPB_INLINE google_protobuf_FieldDescriptorProto** google_protobuf_DescriptorProto_resize_extension(google_protobuf_DescriptorProto *msg, size_t len, upb_arena *arena) {
-  return (google_protobuf_FieldDescriptorProto**)_upb_array_resize_accessor(msg, UPB_SIZE(32, 64), len, UPB_TYPE_MESSAGE, arena);
+  return (google_protobuf_FieldDescriptorProto**)_upb_array_resize_accessor2(msg, UPB_SIZE(32, 64), len, UPB_SIZE(2, 3), arena);
 }
 UPB_INLINE struct google_protobuf_FieldDescriptorProto* google_protobuf_DescriptorProto_add_extension(google_protobuf_DescriptorProto *msg, upb_arena *arena) {
   struct google_protobuf_FieldDescriptorProto* sub = (struct google_protobuf_FieldDescriptorProto*)_upb_msg_new(&google_protobuf_FieldDescriptorProto_msginit, arena);
-  bool ok = _upb_array_append_accessor(
-      msg, UPB_SIZE(32, 64), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena);
+  bool ok = _upb_array_append_accessor2(
+      msg, UPB_SIZE(32, 64), UPB_SIZE(2, 3), &sub, arena);
   if (!ok) return NULL;
   return sub;
 }
@@ -461,12 +480,12 @@ UPB_INLINE google_protobuf_OneofDescriptorProto** google_protobuf_DescriptorProt
   return (google_protobuf_OneofDescriptorProto**)_upb_array_mutable_accessor(msg, UPB_SIZE(36, 72), len);
 }
 UPB_INLINE google_protobuf_OneofDescriptorProto** google_protobuf_DescriptorProto_resize_oneof_decl(google_protobuf_DescriptorProto *msg, size_t len, upb_arena *arena) {
-  return (google_protobuf_OneofDescriptorProto**)_upb_array_resize_accessor(msg, UPB_SIZE(36, 72), len, UPB_TYPE_MESSAGE, arena);
+  return (google_protobuf_OneofDescriptorProto**)_upb_array_resize_accessor2(msg, UPB_SIZE(36, 72), len, UPB_SIZE(2, 3), arena);
 }
 UPB_INLINE struct google_protobuf_OneofDescriptorProto* google_protobuf_DescriptorProto_add_oneof_decl(google_protobuf_DescriptorProto *msg, upb_arena *arena) {
   struct google_protobuf_OneofDescriptorProto* sub = (struct google_protobuf_OneofDescriptorProto*)_upb_msg_new(&google_protobuf_OneofDescriptorProto_msginit, arena);
-  bool ok = _upb_array_append_accessor(
-      msg, UPB_SIZE(36, 72), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena);
+  bool ok = _upb_array_append_accessor2(
+      msg, UPB_SIZE(36, 72), UPB_SIZE(2, 3), &sub, arena);
   if (!ok) return NULL;
   return sub;
 }
@@ -474,12 +493,12 @@ UPB_INLINE google_protobuf_DescriptorProto_ReservedRange** google_protobuf_Descr
   return (google_protobuf_DescriptorProto_ReservedRange**)_upb_array_mutable_accessor(msg, UPB_SIZE(40, 80), len);
 }
 UPB_INLINE google_protobuf_DescriptorProto_ReservedRange** google_protobuf_DescriptorProto_resize_reserved_range(google_protobuf_DescriptorProto *msg, size_t len, upb_arena *arena) {
-  return (google_protobuf_DescriptorProto_ReservedRange**)_upb_array_resize_accessor(msg, UPB_SIZE(40, 80), len, UPB_TYPE_MESSAGE, arena);
+  return (google_protobuf_DescriptorProto_ReservedRange**)_upb_array_resize_accessor2(msg, UPB_SIZE(40, 80), len, UPB_SIZE(2, 3), arena);
 }
 UPB_INLINE struct google_protobuf_DescriptorProto_ReservedRange* google_protobuf_DescriptorProto_add_reserved_range(google_protobuf_DescriptorProto *msg, upb_arena *arena) {
   struct google_protobuf_DescriptorProto_ReservedRange* sub = (struct google_protobuf_DescriptorProto_ReservedRange*)_upb_msg_new(&google_protobuf_DescriptorProto_ReservedRange_msginit, arena);
-  bool ok = _upb_array_append_accessor(
-      msg, UPB_SIZE(40, 80), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena);
+  bool ok = _upb_array_append_accessor2(
+      msg, UPB_SIZE(40, 80), UPB_SIZE(2, 3), &sub, arena);
   if (!ok) return NULL;
   return sub;
 }
@@ -487,10 +506,10 @@ UPB_INLINE upb_strview* google_protobuf_DescriptorProto_mutable_reserved_name(go
   return (upb_strview*)_upb_array_mutable_accessor(msg, UPB_SIZE(44, 88), len);
 }
 UPB_INLINE upb_strview* google_protobuf_DescriptorProto_resize_reserved_name(google_protobuf_DescriptorProto *msg, size_t len, upb_arena *arena) {
-  return (upb_strview*)_upb_array_resize_accessor(msg, UPB_SIZE(44, 88), len, UPB_TYPE_STRING, arena);
+  return (upb_strview*)_upb_array_resize_accessor2(msg, UPB_SIZE(44, 88), len, UPB_SIZE(3, 4), arena);
 }
 UPB_INLINE bool google_protobuf_DescriptorProto_add_reserved_name(google_protobuf_DescriptorProto *msg, upb_strview val, upb_arena *arena) {
-  return _upb_array_append_accessor(msg, UPB_SIZE(44, 88), UPB_SIZE(8, 16), UPB_TYPE_STRING, &val,
+  return _upb_array_append_accessor2(msg, UPB_SIZE(44, 88), UPB_SIZE(3, 4), &val,
       arena);
 }
 
@@ -504,6 +523,12 @@ UPB_INLINE google_protobuf_DescriptorProto_ExtensionRange *google_protobuf_Descr
   google_protobuf_DescriptorProto_ExtensionRange *ret = google_protobuf_DescriptorProto_ExtensionRange_new(arena);
   return (ret && upb_decode(buf, size, ret, &google_protobuf_DescriptorProto_ExtensionRange_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE google_protobuf_DescriptorProto_ExtensionRange *google_protobuf_DescriptorProto_ExtensionRange_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  google_protobuf_DescriptorProto_ExtensionRange *ret = google_protobuf_DescriptorProto_ExtensionRange_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &google_protobuf_DescriptorProto_ExtensionRange_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *google_protobuf_DescriptorProto_ExtensionRange_serialize(const google_protobuf_DescriptorProto_ExtensionRange *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &google_protobuf_DescriptorProto_ExtensionRange_msginit, arena, len);
 }
@@ -547,6 +572,12 @@ UPB_INLINE google_protobuf_DescriptorProto_ReservedRange *google_protobuf_Descri
   google_protobuf_DescriptorProto_ReservedRange *ret = google_protobuf_DescriptorProto_ReservedRange_new(arena);
   return (ret && upb_decode(buf, size, ret, &google_protobuf_DescriptorProto_ReservedRange_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE google_protobuf_DescriptorProto_ReservedRange *google_protobuf_DescriptorProto_ReservedRange_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  google_protobuf_DescriptorProto_ReservedRange *ret = google_protobuf_DescriptorProto_ReservedRange_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &google_protobuf_DescriptorProto_ReservedRange_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *google_protobuf_DescriptorProto_ReservedRange_serialize(const google_protobuf_DescriptorProto_ReservedRange *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &google_protobuf_DescriptorProto_ReservedRange_msginit, arena, len);
 }
@@ -575,6 +606,12 @@ UPB_INLINE google_protobuf_ExtensionRangeOptions *google_protobuf_ExtensionRange
   google_protobuf_ExtensionRangeOptions *ret = google_protobuf_ExtensionRangeOptions_new(arena);
   return (ret && upb_decode(buf, size, ret, &google_protobuf_ExtensionRangeOptions_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE google_protobuf_ExtensionRangeOptions *google_protobuf_ExtensionRangeOptions_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  google_protobuf_ExtensionRangeOptions *ret = google_protobuf_ExtensionRangeOptions_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &google_protobuf_ExtensionRangeOptions_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *google_protobuf_ExtensionRangeOptions_serialize(const google_protobuf_ExtensionRangeOptions *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &google_protobuf_ExtensionRangeOptions_msginit, arena, len);
 }
@@ -586,12 +623,12 @@ UPB_INLINE google_protobuf_UninterpretedOption** google_protobuf_ExtensionRangeO
   return (google_protobuf_UninterpretedOption**)_upb_array_mutable_accessor(msg, UPB_SIZE(0, 0), len);
 }
 UPB_INLINE google_protobuf_UninterpretedOption** google_protobuf_ExtensionRangeOptions_resize_uninterpreted_option(google_protobuf_ExtensionRangeOptions *msg, size_t len, upb_arena *arena) {
-  return (google_protobuf_UninterpretedOption**)_upb_array_resize_accessor(msg, UPB_SIZE(0, 0), len, UPB_TYPE_MESSAGE, arena);
+  return (google_protobuf_UninterpretedOption**)_upb_array_resize_accessor2(msg, UPB_SIZE(0, 0), len, UPB_SIZE(2, 3), arena);
 }
 UPB_INLINE struct google_protobuf_UninterpretedOption* google_protobuf_ExtensionRangeOptions_add_uninterpreted_option(google_protobuf_ExtensionRangeOptions *msg, upb_arena *arena) {
   struct google_protobuf_UninterpretedOption* sub = (struct google_protobuf_UninterpretedOption*)_upb_msg_new(&google_protobuf_UninterpretedOption_msginit, arena);
-  bool ok = _upb_array_append_accessor(
-      msg, UPB_SIZE(0, 0), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena);
+  bool ok = _upb_array_append_accessor2(
+      msg, UPB_SIZE(0, 0), UPB_SIZE(2, 3), &sub, arena);
   if (!ok) return NULL;
   return sub;
 }
@@ -606,64 +643,70 @@ UPB_INLINE google_protobuf_FieldDescriptorProto *google_protobuf_FieldDescriptor
   google_protobuf_FieldDescriptorProto *ret = google_protobuf_FieldDescriptorProto_new(arena);
   return (ret && upb_decode(buf, size, ret, &google_protobuf_FieldDescriptorProto_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE google_protobuf_FieldDescriptorProto *google_protobuf_FieldDescriptorProto_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  google_protobuf_FieldDescriptorProto *ret = google_protobuf_FieldDescriptorProto_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &google_protobuf_FieldDescriptorProto_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *google_protobuf_FieldDescriptorProto_serialize(const google_protobuf_FieldDescriptorProto *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &google_protobuf_FieldDescriptorProto_msginit, arena, len);
 }
 
-UPB_INLINE bool google_protobuf_FieldDescriptorProto_has_name(const google_protobuf_FieldDescriptorProto *msg) { return _upb_hasbit(msg, 6); }
-UPB_INLINE upb_strview google_protobuf_FieldDescriptorProto_name(const google_protobuf_FieldDescriptorProto *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(36, 40), upb_strview); }
-UPB_INLINE bool google_protobuf_FieldDescriptorProto_has_extendee(const google_protobuf_FieldDescriptorProto *msg) { return _upb_hasbit(msg, 7); }
-UPB_INLINE upb_strview google_protobuf_FieldDescriptorProto_extendee(const google_protobuf_FieldDescriptorProto *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(44, 56), upb_strview); }
+UPB_INLINE bool google_protobuf_FieldDescriptorProto_has_name(const google_protobuf_FieldDescriptorProto *msg) { return _upb_hasbit(msg, 1); }
+UPB_INLINE upb_strview google_protobuf_FieldDescriptorProto_name(const google_protobuf_FieldDescriptorProto *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(24, 24), upb_strview); }
+UPB_INLINE bool google_protobuf_FieldDescriptorProto_has_extendee(const google_protobuf_FieldDescriptorProto *msg) { return _upb_hasbit(msg, 2); }
+UPB_INLINE upb_strview google_protobuf_FieldDescriptorProto_extendee(const google_protobuf_FieldDescriptorProto *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(32, 40), upb_strview); }
 UPB_INLINE bool google_protobuf_FieldDescriptorProto_has_number(const google_protobuf_FieldDescriptorProto *msg) { return _upb_hasbit(msg, 3); }
-UPB_INLINE int32_t google_protobuf_FieldDescriptorProto_number(const google_protobuf_FieldDescriptorProto *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(24, 24), int32_t); }
-UPB_INLINE bool google_protobuf_FieldDescriptorProto_has_label(const google_protobuf_FieldDescriptorProto *msg) { return _upb_hasbit(msg, 1); }
-UPB_INLINE int32_t google_protobuf_FieldDescriptorProto_label(const google_protobuf_FieldDescriptorProto *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(8, 8), int32_t); }
-UPB_INLINE bool google_protobuf_FieldDescriptorProto_has_type(const google_protobuf_FieldDescriptorProto *msg) { return _upb_hasbit(msg, 2); }
-UPB_INLINE int32_t google_protobuf_FieldDescriptorProto_type(const google_protobuf_FieldDescriptorProto *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(16, 16), int32_t); }
-UPB_INLINE bool google_protobuf_FieldDescriptorProto_has_type_name(const google_protobuf_FieldDescriptorProto *msg) { return _upb_hasbit(msg, 8); }
-UPB_INLINE upb_strview google_protobuf_FieldDescriptorProto_type_name(const google_protobuf_FieldDescriptorProto *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(52, 72), upb_strview); }
-UPB_INLINE bool google_protobuf_FieldDescriptorProto_has_default_value(const google_protobuf_FieldDescriptorProto *msg) { return _upb_hasbit(msg, 9); }
-UPB_INLINE upb_strview google_protobuf_FieldDescriptorProto_default_value(const google_protobuf_FieldDescriptorProto *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(60, 88), upb_strview); }
-UPB_INLINE bool google_protobuf_FieldDescriptorProto_has_options(const google_protobuf_FieldDescriptorProto *msg) { return _upb_hasbit(msg, 11); }
-UPB_INLINE const google_protobuf_FieldOptions* google_protobuf_FieldDescriptorProto_options(const google_protobuf_FieldDescriptorProto *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(76, 120), const google_protobuf_FieldOptions*); }
-UPB_INLINE bool google_protobuf_FieldDescriptorProto_has_oneof_index(const google_protobuf_FieldDescriptorProto *msg) { return _upb_hasbit(msg, 4); }
-UPB_INLINE int32_t google_protobuf_FieldDescriptorProto_oneof_index(const google_protobuf_FieldDescriptorProto *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(28, 28), int32_t); }
+UPB_INLINE int32_t google_protobuf_FieldDescriptorProto_number(const google_protobuf_FieldDescriptorProto *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(12, 12), int32_t); }
+UPB_INLINE bool google_protobuf_FieldDescriptorProto_has_label(const google_protobuf_FieldDescriptorProto *msg) { return _upb_hasbit(msg, 4); }
+UPB_INLINE int32_t google_protobuf_FieldDescriptorProto_label(const google_protobuf_FieldDescriptorProto *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(4, 4), int32_t); }
+UPB_INLINE bool google_protobuf_FieldDescriptorProto_has_type(const google_protobuf_FieldDescriptorProto *msg) { return _upb_hasbit(msg, 5); }
+UPB_INLINE int32_t google_protobuf_FieldDescriptorProto_type(const google_protobuf_FieldDescriptorProto *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(8, 8), int32_t); }
+UPB_INLINE bool google_protobuf_FieldDescriptorProto_has_type_name(const google_protobuf_FieldDescriptorProto *msg) { return _upb_hasbit(msg, 6); }
+UPB_INLINE upb_strview google_protobuf_FieldDescriptorProto_type_name(const google_protobuf_FieldDescriptorProto *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(40, 56), upb_strview); }
+UPB_INLINE bool google_protobuf_FieldDescriptorProto_has_default_value(const google_protobuf_FieldDescriptorProto *msg) { return _upb_hasbit(msg, 7); }
+UPB_INLINE upb_strview google_protobuf_FieldDescriptorProto_default_value(const google_protobuf_FieldDescriptorProto *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(48, 72), upb_strview); }
+UPB_INLINE bool google_protobuf_FieldDescriptorProto_has_options(const google_protobuf_FieldDescriptorProto *msg) { return _upb_hasbit(msg, 8); }
+UPB_INLINE const google_protobuf_FieldOptions* google_protobuf_FieldDescriptorProto_options(const google_protobuf_FieldDescriptorProto *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(64, 104), const google_protobuf_FieldOptions*); }
+UPB_INLINE bool google_protobuf_FieldDescriptorProto_has_oneof_index(const google_protobuf_FieldDescriptorProto *msg) { return _upb_hasbit(msg, 9); }
+UPB_INLINE int32_t google_protobuf_FieldDescriptorProto_oneof_index(const google_protobuf_FieldDescriptorProto *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(16, 16), int32_t); }
 UPB_INLINE bool google_protobuf_FieldDescriptorProto_has_json_name(const google_protobuf_FieldDescriptorProto *msg) { return _upb_hasbit(msg, 10); }
-UPB_INLINE upb_strview google_protobuf_FieldDescriptorProto_json_name(const google_protobuf_FieldDescriptorProto *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(68, 104), upb_strview); }
-UPB_INLINE bool google_protobuf_FieldDescriptorProto_has_proto3_optional(const google_protobuf_FieldDescriptorProto *msg) { return _upb_hasbit(msg, 5); }
-UPB_INLINE bool google_protobuf_FieldDescriptorProto_proto3_optional(const google_protobuf_FieldDescriptorProto *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(32, 32), bool); }
+UPB_INLINE upb_strview google_protobuf_FieldDescriptorProto_json_name(const google_protobuf_FieldDescriptorProto *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(56, 88), upb_strview); }
+UPB_INLINE bool google_protobuf_FieldDescriptorProto_has_proto3_optional(const google_protobuf_FieldDescriptorProto *msg) { return _upb_hasbit(msg, 11); }
+UPB_INLINE bool google_protobuf_FieldDescriptorProto_proto3_optional(const google_protobuf_FieldDescriptorProto *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(20, 20), bool); }
 
 UPB_INLINE void google_protobuf_FieldDescriptorProto_set_name(google_protobuf_FieldDescriptorProto *msg, upb_strview value) {
-  _upb_sethas(msg, 6);
-  *UPB_PTR_AT(msg, UPB_SIZE(36, 40), upb_strview) = value;
+  _upb_sethas(msg, 1);
+  *UPB_PTR_AT(msg, UPB_SIZE(24, 24), upb_strview) = value;
 }
 UPB_INLINE void google_protobuf_FieldDescriptorProto_set_extendee(google_protobuf_FieldDescriptorProto *msg, upb_strview value) {
-  _upb_sethas(msg, 7);
-  *UPB_PTR_AT(msg, UPB_SIZE(44, 56), upb_strview) = value;
+  _upb_sethas(msg, 2);
+  *UPB_PTR_AT(msg, UPB_SIZE(32, 40), upb_strview) = value;
 }
 UPB_INLINE void google_protobuf_FieldDescriptorProto_set_number(google_protobuf_FieldDescriptorProto *msg, int32_t value) {
   _upb_sethas(msg, 3);
-  *UPB_PTR_AT(msg, UPB_SIZE(24, 24), int32_t) = value;
+  *UPB_PTR_AT(msg, UPB_SIZE(12, 12), int32_t) = value;
 }
 UPB_INLINE void google_protobuf_FieldDescriptorProto_set_label(google_protobuf_FieldDescriptorProto *msg, int32_t value) {
-  _upb_sethas(msg, 1);
-  *UPB_PTR_AT(msg, UPB_SIZE(8, 8), int32_t) = value;
+  _upb_sethas(msg, 4);
+  *UPB_PTR_AT(msg, UPB_SIZE(4, 4), int32_t) = value;
 }
 UPB_INLINE void google_protobuf_FieldDescriptorProto_set_type(google_protobuf_FieldDescriptorProto *msg, int32_t value) {
-  _upb_sethas(msg, 2);
-  *UPB_PTR_AT(msg, UPB_SIZE(16, 16), int32_t) = value;
+  _upb_sethas(msg, 5);
+  *UPB_PTR_AT(msg, UPB_SIZE(8, 8), int32_t) = value;
 }
 UPB_INLINE void google_protobuf_FieldDescriptorProto_set_type_name(google_protobuf_FieldDescriptorProto *msg, upb_strview value) {
-  _upb_sethas(msg, 8);
-  *UPB_PTR_AT(msg, UPB_SIZE(52, 72), upb_strview) = value;
+  _upb_sethas(msg, 6);
+  *UPB_PTR_AT(msg, UPB_SIZE(40, 56), upb_strview) = value;
 }
 UPB_INLINE void google_protobuf_FieldDescriptorProto_set_default_value(google_protobuf_FieldDescriptorProto *msg, upb_strview value) {
-  _upb_sethas(msg, 9);
-  *UPB_PTR_AT(msg, UPB_SIZE(60, 88), upb_strview) = value;
+  _upb_sethas(msg, 7);
+  *UPB_PTR_AT(msg, UPB_SIZE(48, 72), upb_strview) = value;
 }
 UPB_INLINE void google_protobuf_FieldDescriptorProto_set_options(google_protobuf_FieldDescriptorProto *msg, google_protobuf_FieldOptions* value) {
-  _upb_sethas(msg, 11);
-  *UPB_PTR_AT(msg, UPB_SIZE(76, 120), google_protobuf_FieldOptions*) = value;
+  _upb_sethas(msg, 8);
+  *UPB_PTR_AT(msg, UPB_SIZE(64, 104), google_protobuf_FieldOptions*) = value;
 }
 UPB_INLINE struct google_protobuf_FieldOptions* google_protobuf_FieldDescriptorProto_mutable_options(google_protobuf_FieldDescriptorProto *msg, upb_arena *arena) {
   struct google_protobuf_FieldOptions* sub = (struct google_protobuf_FieldOptions*)google_protobuf_FieldDescriptorProto_options(msg);
@@ -675,16 +718,16 @@ UPB_INLINE struct google_protobuf_FieldOptions* google_protobuf_FieldDescriptorP
   return sub;
 }
 UPB_INLINE void google_protobuf_FieldDescriptorProto_set_oneof_index(google_protobuf_FieldDescriptorProto *msg, int32_t value) {
-  _upb_sethas(msg, 4);
-  *UPB_PTR_AT(msg, UPB_SIZE(28, 28), int32_t) = value;
+  _upb_sethas(msg, 9);
+  *UPB_PTR_AT(msg, UPB_SIZE(16, 16), int32_t) = value;
 }
 UPB_INLINE void google_protobuf_FieldDescriptorProto_set_json_name(google_protobuf_FieldDescriptorProto *msg, upb_strview value) {
   _upb_sethas(msg, 10);
-  *UPB_PTR_AT(msg, UPB_SIZE(68, 104), upb_strview) = value;
+  *UPB_PTR_AT(msg, UPB_SIZE(56, 88), upb_strview) = value;
 }
 UPB_INLINE void google_protobuf_FieldDescriptorProto_set_proto3_optional(google_protobuf_FieldDescriptorProto *msg, bool value) {
-  _upb_sethas(msg, 5);
-  *UPB_PTR_AT(msg, UPB_SIZE(32, 32), bool) = value;
+  _upb_sethas(msg, 11);
+  *UPB_PTR_AT(msg, UPB_SIZE(20, 20), bool) = value;
 }
 
 /* google.protobuf.OneofDescriptorProto */
@@ -697,6 +740,12 @@ UPB_INLINE google_protobuf_OneofDescriptorProto *google_protobuf_OneofDescriptor
   google_protobuf_OneofDescriptorProto *ret = google_protobuf_OneofDescriptorProto_new(arena);
   return (ret && upb_decode(buf, size, ret, &google_protobuf_OneofDescriptorProto_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE google_protobuf_OneofDescriptorProto *google_protobuf_OneofDescriptorProto_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  google_protobuf_OneofDescriptorProto *ret = google_protobuf_OneofDescriptorProto_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &google_protobuf_OneofDescriptorProto_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *google_protobuf_OneofDescriptorProto_serialize(const google_protobuf_OneofDescriptorProto *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &google_protobuf_OneofDescriptorProto_msginit, arena, len);
 }
@@ -734,6 +783,12 @@ UPB_INLINE google_protobuf_EnumDescriptorProto *google_protobuf_EnumDescriptorPr
   google_protobuf_EnumDescriptorProto *ret = google_protobuf_EnumDescriptorProto_new(arena);
   return (ret && upb_decode(buf, size, ret, &google_protobuf_EnumDescriptorProto_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE google_protobuf_EnumDescriptorProto *google_protobuf_EnumDescriptorProto_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  google_protobuf_EnumDescriptorProto *ret = google_protobuf_EnumDescriptorProto_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &google_protobuf_EnumDescriptorProto_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *google_protobuf_EnumDescriptorProto_serialize(const google_protobuf_EnumDescriptorProto *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &google_protobuf_EnumDescriptorProto_msginit, arena, len);
 }
@@ -756,12 +811,12 @@ UPB_INLINE google_protobuf_EnumValueDescriptorProto** google_protobuf_EnumDescri
   return (google_protobuf_EnumValueDescriptorProto**)_upb_array_mutable_accessor(msg, UPB_SIZE(16, 32), len);
 }
 UPB_INLINE google_protobuf_EnumValueDescriptorProto** google_protobuf_EnumDescriptorProto_resize_value(google_protobuf_EnumDescriptorProto *msg, size_t len, upb_arena *arena) {
-  return (google_protobuf_EnumValueDescriptorProto**)_upb_array_resize_accessor(msg, UPB_SIZE(16, 32), len, UPB_TYPE_MESSAGE, arena);
+  return (google_protobuf_EnumValueDescriptorProto**)_upb_array_resize_accessor2(msg, UPB_SIZE(16, 32), len, UPB_SIZE(2, 3), arena);
 }
 UPB_INLINE struct google_protobuf_EnumValueDescriptorProto* google_protobuf_EnumDescriptorProto_add_value(google_protobuf_EnumDescriptorProto *msg, upb_arena *arena) {
   struct google_protobuf_EnumValueDescriptorProto* sub = (struct google_protobuf_EnumValueDescriptorProto*)_upb_msg_new(&google_protobuf_EnumValueDescriptorProto_msginit, arena);
-  bool ok = _upb_array_append_accessor(
-      msg, UPB_SIZE(16, 32), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena);
+  bool ok = _upb_array_append_accessor2(
+      msg, UPB_SIZE(16, 32), UPB_SIZE(2, 3), &sub, arena);
   if (!ok) return NULL;
   return sub;
 }
@@ -782,12 +837,12 @@ UPB_INLINE google_protobuf_EnumDescriptorProto_EnumReservedRange** google_protob
   return (google_protobuf_EnumDescriptorProto_EnumReservedRange**)_upb_array_mutable_accessor(msg, UPB_SIZE(20, 40), len);
 }
 UPB_INLINE google_protobuf_EnumDescriptorProto_EnumReservedRange** google_protobuf_EnumDescriptorProto_resize_reserved_range(google_protobuf_EnumDescriptorProto *msg, size_t len, upb_arena *arena) {
-  return (google_protobuf_EnumDescriptorProto_EnumReservedRange**)_upb_array_resize_accessor(msg, UPB_SIZE(20, 40), len, UPB_TYPE_MESSAGE, arena);
+  return (google_protobuf_EnumDescriptorProto_EnumReservedRange**)_upb_array_resize_accessor2(msg, UPB_SIZE(20, 40), len, UPB_SIZE(2, 3), arena);
 }
 UPB_INLINE struct google_protobuf_EnumDescriptorProto_EnumReservedRange* google_protobuf_EnumDescriptorProto_add_reserved_range(google_protobuf_EnumDescriptorProto *msg, upb_arena *arena) {
   struct google_protobuf_EnumDescriptorProto_EnumReservedRange* sub = (struct google_protobuf_EnumDescriptorProto_EnumReservedRange*)_upb_msg_new(&google_protobuf_EnumDescriptorProto_EnumReservedRange_msginit, arena);
-  bool ok = _upb_array_append_accessor(
-      msg, UPB_SIZE(20, 40), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena);
+  bool ok = _upb_array_append_accessor2(
+      msg, UPB_SIZE(20, 40), UPB_SIZE(2, 3), &sub, arena);
   if (!ok) return NULL;
   return sub;
 }
@@ -795,10 +850,10 @@ UPB_INLINE upb_strview* google_protobuf_EnumDescriptorProto_mutable_reserved_nam
   return (upb_strview*)_upb_array_mutable_accessor(msg, UPB_SIZE(24, 48), len);
 }
 UPB_INLINE upb_strview* google_protobuf_EnumDescriptorProto_resize_reserved_name(google_protobuf_EnumDescriptorProto *msg, size_t len, upb_arena *arena) {
-  return (upb_strview*)_upb_array_resize_accessor(msg, UPB_SIZE(24, 48), len, UPB_TYPE_STRING, arena);
+  return (upb_strview*)_upb_array_resize_accessor2(msg, UPB_SIZE(24, 48), len, UPB_SIZE(3, 4), arena);
 }
 UPB_INLINE bool google_protobuf_EnumDescriptorProto_add_reserved_name(google_protobuf_EnumDescriptorProto *msg, upb_strview val, upb_arena *arena) {
-  return _upb_array_append_accessor(msg, UPB_SIZE(24, 48), UPB_SIZE(8, 16), UPB_TYPE_STRING, &val,
+  return _upb_array_append_accessor2(msg, UPB_SIZE(24, 48), UPB_SIZE(3, 4), &val,
       arena);
 }
 
@@ -812,6 +867,12 @@ UPB_INLINE google_protobuf_EnumDescriptorProto_EnumReservedRange *google_protobu
   google_protobuf_EnumDescriptorProto_EnumReservedRange *ret = google_protobuf_EnumDescriptorProto_EnumReservedRange_new(arena);
   return (ret && upb_decode(buf, size, ret, &google_protobuf_EnumDescriptorProto_EnumReservedRange_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE google_protobuf_EnumDescriptorProto_EnumReservedRange *google_protobuf_EnumDescriptorProto_EnumReservedRange_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  google_protobuf_EnumDescriptorProto_EnumReservedRange *ret = google_protobuf_EnumDescriptorProto_EnumReservedRange_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &google_protobuf_EnumDescriptorProto_EnumReservedRange_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *google_protobuf_EnumDescriptorProto_EnumReservedRange_serialize(const google_protobuf_EnumDescriptorProto_EnumReservedRange *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &google_protobuf_EnumDescriptorProto_EnumReservedRange_msginit, arena, len);
 }
@@ -840,23 +901,29 @@ UPB_INLINE google_protobuf_EnumValueDescriptorProto *google_protobuf_EnumValueDe
   google_protobuf_EnumValueDescriptorProto *ret = google_protobuf_EnumValueDescriptorProto_new(arena);
   return (ret && upb_decode(buf, size, ret, &google_protobuf_EnumValueDescriptorProto_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE google_protobuf_EnumValueDescriptorProto *google_protobuf_EnumValueDescriptorProto_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  google_protobuf_EnumValueDescriptorProto *ret = google_protobuf_EnumValueDescriptorProto_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &google_protobuf_EnumValueDescriptorProto_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *google_protobuf_EnumValueDescriptorProto_serialize(const google_protobuf_EnumValueDescriptorProto *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &google_protobuf_EnumValueDescriptorProto_msginit, arena, len);
 }
 
-UPB_INLINE bool google_protobuf_EnumValueDescriptorProto_has_name(const google_protobuf_EnumValueDescriptorProto *msg) { return _upb_hasbit(msg, 2); }
+UPB_INLINE bool google_protobuf_EnumValueDescriptorProto_has_name(const google_protobuf_EnumValueDescriptorProto *msg) { return _upb_hasbit(msg, 1); }
 UPB_INLINE upb_strview google_protobuf_EnumValueDescriptorProto_name(const google_protobuf_EnumValueDescriptorProto *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(8, 8), upb_strview); }
-UPB_INLINE bool google_protobuf_EnumValueDescriptorProto_has_number(const google_protobuf_EnumValueDescriptorProto *msg) { return _upb_hasbit(msg, 1); }
+UPB_INLINE bool google_protobuf_EnumValueDescriptorProto_has_number(const google_protobuf_EnumValueDescriptorProto *msg) { return _upb_hasbit(msg, 2); }
 UPB_INLINE int32_t google_protobuf_EnumValueDescriptorProto_number(const google_protobuf_EnumValueDescriptorProto *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(4, 4), int32_t); }
 UPB_INLINE bool google_protobuf_EnumValueDescriptorProto_has_options(const google_protobuf_EnumValueDescriptorProto *msg) { return _upb_hasbit(msg, 3); }
 UPB_INLINE const google_protobuf_EnumValueOptions* google_protobuf_EnumValueDescriptorProto_options(const google_protobuf_EnumValueDescriptorProto *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(16, 24), const google_protobuf_EnumValueOptions*); }
 
 UPB_INLINE void google_protobuf_EnumValueDescriptorProto_set_name(google_protobuf_EnumValueDescriptorProto *msg, upb_strview value) {
-  _upb_sethas(msg, 2);
+  _upb_sethas(msg, 1);
   *UPB_PTR_AT(msg, UPB_SIZE(8, 8), upb_strview) = value;
 }
 UPB_INLINE void google_protobuf_EnumValueDescriptorProto_set_number(google_protobuf_EnumValueDescriptorProto *msg, int32_t value) {
-  _upb_sethas(msg, 1);
+  _upb_sethas(msg, 2);
   *UPB_PTR_AT(msg, UPB_SIZE(4, 4), int32_t) = value;
 }
 UPB_INLINE void google_protobuf_EnumValueDescriptorProto_set_options(google_protobuf_EnumValueDescriptorProto *msg, google_protobuf_EnumValueOptions* value) {
@@ -883,6 +950,12 @@ UPB_INLINE google_protobuf_ServiceDescriptorProto *google_protobuf_ServiceDescri
   google_protobuf_ServiceDescriptorProto *ret = google_protobuf_ServiceDescriptorProto_new(arena);
   return (ret && upb_decode(buf, size, ret, &google_protobuf_ServiceDescriptorProto_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE google_protobuf_ServiceDescriptorProto *google_protobuf_ServiceDescriptorProto_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  google_protobuf_ServiceDescriptorProto *ret = google_protobuf_ServiceDescriptorProto_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &google_protobuf_ServiceDescriptorProto_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *google_protobuf_ServiceDescriptorProto_serialize(const google_protobuf_ServiceDescriptorProto *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &google_protobuf_ServiceDescriptorProto_msginit, arena, len);
 }
@@ -902,12 +975,12 @@ UPB_INLINE google_protobuf_MethodDescriptorProto** google_protobuf_ServiceDescri
   return (google_protobuf_MethodDescriptorProto**)_upb_array_mutable_accessor(msg, UPB_SIZE(16, 32), len);
 }
 UPB_INLINE google_protobuf_MethodDescriptorProto** google_protobuf_ServiceDescriptorProto_resize_method(google_protobuf_ServiceDescriptorProto *msg, size_t len, upb_arena *arena) {
-  return (google_protobuf_MethodDescriptorProto**)_upb_array_resize_accessor(msg, UPB_SIZE(16, 32), len, UPB_TYPE_MESSAGE, arena);
+  return (google_protobuf_MethodDescriptorProto**)_upb_array_resize_accessor2(msg, UPB_SIZE(16, 32), len, UPB_SIZE(2, 3), arena);
 }
 UPB_INLINE struct google_protobuf_MethodDescriptorProto* google_protobuf_ServiceDescriptorProto_add_method(google_protobuf_ServiceDescriptorProto *msg, upb_arena *arena) {
   struct google_protobuf_MethodDescriptorProto* sub = (struct google_protobuf_MethodDescriptorProto*)_upb_msg_new(&google_protobuf_MethodDescriptorProto_msginit, arena);
-  bool ok = _upb_array_append_accessor(
-      msg, UPB_SIZE(16, 32), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena);
+  bool ok = _upb_array_append_accessor2(
+      msg, UPB_SIZE(16, 32), UPB_SIZE(2, 3), &sub, arena);
   if (!ok) return NULL;
   return sub;
 }
@@ -935,37 +1008,43 @@ UPB_INLINE google_protobuf_MethodDescriptorProto *google_protobuf_MethodDescript
   google_protobuf_MethodDescriptorProto *ret = google_protobuf_MethodDescriptorProto_new(arena);
   return (ret && upb_decode(buf, size, ret, &google_protobuf_MethodDescriptorProto_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE google_protobuf_MethodDescriptorProto *google_protobuf_MethodDescriptorProto_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  google_protobuf_MethodDescriptorProto *ret = google_protobuf_MethodDescriptorProto_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &google_protobuf_MethodDescriptorProto_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *google_protobuf_MethodDescriptorProto_serialize(const google_protobuf_MethodDescriptorProto *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &google_protobuf_MethodDescriptorProto_msginit, arena, len);
 }
 
-UPB_INLINE bool google_protobuf_MethodDescriptorProto_has_name(const google_protobuf_MethodDescriptorProto *msg) { return _upb_hasbit(msg, 3); }
+UPB_INLINE bool google_protobuf_MethodDescriptorProto_has_name(const google_protobuf_MethodDescriptorProto *msg) { return _upb_hasbit(msg, 1); }
 UPB_INLINE upb_strview google_protobuf_MethodDescriptorProto_name(const google_protobuf_MethodDescriptorProto *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(4, 8), upb_strview); }
-UPB_INLINE bool google_protobuf_MethodDescriptorProto_has_input_type(const google_protobuf_MethodDescriptorProto *msg) { return _upb_hasbit(msg, 4); }
+UPB_INLINE bool google_protobuf_MethodDescriptorProto_has_input_type(const google_protobuf_MethodDescriptorProto *msg) { return _upb_hasbit(msg, 2); }
 UPB_INLINE upb_strview google_protobuf_MethodDescriptorProto_input_type(const google_protobuf_MethodDescriptorProto *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(12, 24), upb_strview); }
-UPB_INLINE bool google_protobuf_MethodDescriptorProto_has_output_type(const google_protobuf_MethodDescriptorProto *msg) { return _upb_hasbit(msg, 5); }
+UPB_INLINE bool google_protobuf_MethodDescriptorProto_has_output_type(const google_protobuf_MethodDescriptorProto *msg) { return _upb_hasbit(msg, 3); }
 UPB_INLINE upb_strview google_protobuf_MethodDescriptorProto_output_type(const google_protobuf_MethodDescriptorProto *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(20, 40), upb_strview); }
-UPB_INLINE bool google_protobuf_MethodDescriptorProto_has_options(const google_protobuf_MethodDescriptorProto *msg) { return _upb_hasbit(msg, 6); }
+UPB_INLINE bool google_protobuf_MethodDescriptorProto_has_options(const google_protobuf_MethodDescriptorProto *msg) { return _upb_hasbit(msg, 4); }
 UPB_INLINE const google_protobuf_MethodOptions* google_protobuf_MethodDescriptorProto_options(const google_protobuf_MethodDescriptorProto *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(28, 56), const google_protobuf_MethodOptions*); }
-UPB_INLINE bool google_protobuf_MethodDescriptorProto_has_client_streaming(const google_protobuf_MethodDescriptorProto *msg) { return _upb_hasbit(msg, 1); }
+UPB_INLINE bool google_protobuf_MethodDescriptorProto_has_client_streaming(const google_protobuf_MethodDescriptorProto *msg) { return _upb_hasbit(msg, 5); }
 UPB_INLINE bool google_protobuf_MethodDescriptorProto_client_streaming(const google_protobuf_MethodDescriptorProto *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(1, 1), bool); }
-UPB_INLINE bool google_protobuf_MethodDescriptorProto_has_server_streaming(const google_protobuf_MethodDescriptorProto *msg) { return _upb_hasbit(msg, 2); }
+UPB_INLINE bool google_protobuf_MethodDescriptorProto_has_server_streaming(const google_protobuf_MethodDescriptorProto *msg) { return _upb_hasbit(msg, 6); }
 UPB_INLINE bool google_protobuf_MethodDescriptorProto_server_streaming(const google_protobuf_MethodDescriptorProto *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(2, 2), bool); }
 
 UPB_INLINE void google_protobuf_MethodDescriptorProto_set_name(google_protobuf_MethodDescriptorProto *msg, upb_strview value) {
-  _upb_sethas(msg, 3);
+  _upb_sethas(msg, 1);
   *UPB_PTR_AT(msg, UPB_SIZE(4, 8), upb_strview) = value;
 }
 UPB_INLINE void google_protobuf_MethodDescriptorProto_set_input_type(google_protobuf_MethodDescriptorProto *msg, upb_strview value) {
-  _upb_sethas(msg, 4);
+  _upb_sethas(msg, 2);
   *UPB_PTR_AT(msg, UPB_SIZE(12, 24), upb_strview) = value;
 }
 UPB_INLINE void google_protobuf_MethodDescriptorProto_set_output_type(google_protobuf_MethodDescriptorProto *msg, upb_strview value) {
-  _upb_sethas(msg, 5);
+  _upb_sethas(msg, 3);
   *UPB_PTR_AT(msg, UPB_SIZE(20, 40), upb_strview) = value;
 }
 UPB_INLINE void google_protobuf_MethodDescriptorProto_set_options(google_protobuf_MethodDescriptorProto *msg, google_protobuf_MethodOptions* value) {
-  _upb_sethas(msg, 6);
+  _upb_sethas(msg, 4);
   *UPB_PTR_AT(msg, UPB_SIZE(28, 56), google_protobuf_MethodOptions*) = value;
 }
 UPB_INLINE struct google_protobuf_MethodOptions* google_protobuf_MethodDescriptorProto_mutable_options(google_protobuf_MethodDescriptorProto *msg, upb_arena *arena) {
@@ -978,11 +1057,11 @@ UPB_INLINE struct google_protobuf_MethodOptions* google_protobuf_MethodDescripto
   return sub;
 }
 UPB_INLINE void google_protobuf_MethodDescriptorProto_set_client_streaming(google_protobuf_MethodDescriptorProto *msg, bool value) {
-  _upb_sethas(msg, 1);
+  _upb_sethas(msg, 5);
   *UPB_PTR_AT(msg, UPB_SIZE(1, 1), bool) = value;
 }
 UPB_INLINE void google_protobuf_MethodDescriptorProto_set_server_streaming(google_protobuf_MethodDescriptorProto *msg, bool value) {
-  _upb_sethas(msg, 2);
+  _upb_sethas(msg, 6);
   *UPB_PTR_AT(msg, UPB_SIZE(2, 2), bool) = value;
 }
 
@@ -996,143 +1075,149 @@ UPB_INLINE google_protobuf_FileOptions *google_protobuf_FileOptions_parse(const
   google_protobuf_FileOptions *ret = google_protobuf_FileOptions_new(arena);
   return (ret && upb_decode(buf, size, ret, &google_protobuf_FileOptions_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE google_protobuf_FileOptions *google_protobuf_FileOptions_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  google_protobuf_FileOptions *ret = google_protobuf_FileOptions_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &google_protobuf_FileOptions_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *google_protobuf_FileOptions_serialize(const google_protobuf_FileOptions *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &google_protobuf_FileOptions_msginit, arena, len);
 }
 
-UPB_INLINE bool google_protobuf_FileOptions_has_java_package(const google_protobuf_FileOptions *msg) { return _upb_hasbit(msg, 11); }
-UPB_INLINE upb_strview google_protobuf_FileOptions_java_package(const google_protobuf_FileOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(28, 32), upb_strview); }
-UPB_INLINE bool google_protobuf_FileOptions_has_java_outer_classname(const google_protobuf_FileOptions *msg) { return _upb_hasbit(msg, 12); }
-UPB_INLINE upb_strview google_protobuf_FileOptions_java_outer_classname(const google_protobuf_FileOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(36, 48), upb_strview); }
-UPB_INLINE bool google_protobuf_FileOptions_has_optimize_for(const google_protobuf_FileOptions *msg) { return _upb_hasbit(msg, 1); }
-UPB_INLINE int32_t google_protobuf_FileOptions_optimize_for(const google_protobuf_FileOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(8, 8), int32_t); }
-UPB_INLINE bool google_protobuf_FileOptions_has_java_multiple_files(const google_protobuf_FileOptions *msg) { return _upb_hasbit(msg, 2); }
-UPB_INLINE bool google_protobuf_FileOptions_java_multiple_files(const google_protobuf_FileOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(16, 16), bool); }
-UPB_INLINE bool google_protobuf_FileOptions_has_go_package(const google_protobuf_FileOptions *msg) { return _upb_hasbit(msg, 13); }
-UPB_INLINE upb_strview google_protobuf_FileOptions_go_package(const google_protobuf_FileOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(44, 64), upb_strview); }
-UPB_INLINE bool google_protobuf_FileOptions_has_cc_generic_services(const google_protobuf_FileOptions *msg) { return _upb_hasbit(msg, 3); }
-UPB_INLINE bool google_protobuf_FileOptions_cc_generic_services(const google_protobuf_FileOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(17, 17), bool); }
-UPB_INLINE bool google_protobuf_FileOptions_has_java_generic_services(const google_protobuf_FileOptions *msg) { return _upb_hasbit(msg, 4); }
-UPB_INLINE bool google_protobuf_FileOptions_java_generic_services(const google_protobuf_FileOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(18, 18), bool); }
-UPB_INLINE bool google_protobuf_FileOptions_has_py_generic_services(const google_protobuf_FileOptions *msg) { return _upb_hasbit(msg, 5); }
-UPB_INLINE bool google_protobuf_FileOptions_py_generic_services(const google_protobuf_FileOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(19, 19), bool); }
-UPB_INLINE bool google_protobuf_FileOptions_has_java_generate_equals_and_hash(const google_protobuf_FileOptions *msg) { return _upb_hasbit(msg, 6); }
-UPB_INLINE bool google_protobuf_FileOptions_java_generate_equals_and_hash(const google_protobuf_FileOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(20, 20), bool); }
-UPB_INLINE bool google_protobuf_FileOptions_has_deprecated(const google_protobuf_FileOptions *msg) { return _upb_hasbit(msg, 7); }
-UPB_INLINE bool google_protobuf_FileOptions_deprecated(const google_protobuf_FileOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(21, 21), bool); }
-UPB_INLINE bool google_protobuf_FileOptions_has_java_string_check_utf8(const google_protobuf_FileOptions *msg) { return _upb_hasbit(msg, 8); }
-UPB_INLINE bool google_protobuf_FileOptions_java_string_check_utf8(const google_protobuf_FileOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(22, 22), bool); }
-UPB_INLINE bool google_protobuf_FileOptions_has_cc_enable_arenas(const google_protobuf_FileOptions *msg) { return _upb_hasbit(msg, 9); }
-UPB_INLINE bool google_protobuf_FileOptions_cc_enable_arenas(const google_protobuf_FileOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(23, 23), bool); }
-UPB_INLINE bool google_protobuf_FileOptions_has_objc_class_prefix(const google_protobuf_FileOptions *msg) { return _upb_hasbit(msg, 14); }
-UPB_INLINE upb_strview google_protobuf_FileOptions_objc_class_prefix(const google_protobuf_FileOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(52, 80), upb_strview); }
-UPB_INLINE bool google_protobuf_FileOptions_has_csharp_namespace(const google_protobuf_FileOptions *msg) { return _upb_hasbit(msg, 15); }
-UPB_INLINE upb_strview google_protobuf_FileOptions_csharp_namespace(const google_protobuf_FileOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(60, 96), upb_strview); }
-UPB_INLINE bool google_protobuf_FileOptions_has_swift_prefix(const google_protobuf_FileOptions *msg) { return _upb_hasbit(msg, 16); }
-UPB_INLINE upb_strview google_protobuf_FileOptions_swift_prefix(const google_protobuf_FileOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(68, 112), upb_strview); }
-UPB_INLINE bool google_protobuf_FileOptions_has_php_class_prefix(const google_protobuf_FileOptions *msg) { return _upb_hasbit(msg, 17); }
-UPB_INLINE upb_strview google_protobuf_FileOptions_php_class_prefix(const google_protobuf_FileOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(76, 128), upb_strview); }
-UPB_INLINE bool google_protobuf_FileOptions_has_php_namespace(const google_protobuf_FileOptions *msg) { return _upb_hasbit(msg, 18); }
-UPB_INLINE upb_strview google_protobuf_FileOptions_php_namespace(const google_protobuf_FileOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(84, 144), upb_strview); }
-UPB_INLINE bool google_protobuf_FileOptions_has_php_generic_services(const google_protobuf_FileOptions *msg) { return _upb_hasbit(msg, 10); }
-UPB_INLINE bool google_protobuf_FileOptions_php_generic_services(const google_protobuf_FileOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(24, 24), bool); }
+UPB_INLINE bool google_protobuf_FileOptions_has_java_package(const google_protobuf_FileOptions *msg) { return _upb_hasbit(msg, 1); }
+UPB_INLINE upb_strview google_protobuf_FileOptions_java_package(const google_protobuf_FileOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(20, 24), upb_strview); }
+UPB_INLINE bool google_protobuf_FileOptions_has_java_outer_classname(const google_protobuf_FileOptions *msg) { return _upb_hasbit(msg, 2); }
+UPB_INLINE upb_strview google_protobuf_FileOptions_java_outer_classname(const google_protobuf_FileOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(28, 40), upb_strview); }
+UPB_INLINE bool google_protobuf_FileOptions_has_optimize_for(const google_protobuf_FileOptions *msg) { return _upb_hasbit(msg, 3); }
+UPB_INLINE int32_t google_protobuf_FileOptions_optimize_for(const google_protobuf_FileOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(4, 4), int32_t); }
+UPB_INLINE bool google_protobuf_FileOptions_has_java_multiple_files(const google_protobuf_FileOptions *msg) { return _upb_hasbit(msg, 4); }
+UPB_INLINE bool google_protobuf_FileOptions_java_multiple_files(const google_protobuf_FileOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(8, 8), bool); }
+UPB_INLINE bool google_protobuf_FileOptions_has_go_package(const google_protobuf_FileOptions *msg) { return _upb_hasbit(msg, 5); }
+UPB_INLINE upb_strview google_protobuf_FileOptions_go_package(const google_protobuf_FileOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(36, 56), upb_strview); }
+UPB_INLINE bool google_protobuf_FileOptions_has_cc_generic_services(const google_protobuf_FileOptions *msg) { return _upb_hasbit(msg, 6); }
+UPB_INLINE bool google_protobuf_FileOptions_cc_generic_services(const google_protobuf_FileOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(9, 9), bool); }
+UPB_INLINE bool google_protobuf_FileOptions_has_java_generic_services(const google_protobuf_FileOptions *msg) { return _upb_hasbit(msg, 7); }
+UPB_INLINE bool google_protobuf_FileOptions_java_generic_services(const google_protobuf_FileOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(10, 10), bool); }
+UPB_INLINE bool google_protobuf_FileOptions_has_py_generic_services(const google_protobuf_FileOptions *msg) { return _upb_hasbit(msg, 8); }
+UPB_INLINE bool google_protobuf_FileOptions_py_generic_services(const google_protobuf_FileOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(11, 11), bool); }
+UPB_INLINE bool google_protobuf_FileOptions_has_java_generate_equals_and_hash(const google_protobuf_FileOptions *msg) { return _upb_hasbit(msg, 9); }
+UPB_INLINE bool google_protobuf_FileOptions_java_generate_equals_and_hash(const google_protobuf_FileOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(12, 12), bool); }
+UPB_INLINE bool google_protobuf_FileOptions_has_deprecated(const google_protobuf_FileOptions *msg) { return _upb_hasbit(msg, 10); }
+UPB_INLINE bool google_protobuf_FileOptions_deprecated(const google_protobuf_FileOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(13, 13), bool); }
+UPB_INLINE bool google_protobuf_FileOptions_has_java_string_check_utf8(const google_protobuf_FileOptions *msg) { return _upb_hasbit(msg, 11); }
+UPB_INLINE bool google_protobuf_FileOptions_java_string_check_utf8(const google_protobuf_FileOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(14, 14), bool); }
+UPB_INLINE bool google_protobuf_FileOptions_has_cc_enable_arenas(const google_protobuf_FileOptions *msg) { return _upb_hasbit(msg, 12); }
+UPB_INLINE bool google_protobuf_FileOptions_cc_enable_arenas(const google_protobuf_FileOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(15, 15), bool); }
+UPB_INLINE bool google_protobuf_FileOptions_has_objc_class_prefix(const google_protobuf_FileOptions *msg) { return _upb_hasbit(msg, 13); }
+UPB_INLINE upb_strview google_protobuf_FileOptions_objc_class_prefix(const google_protobuf_FileOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(44, 72), upb_strview); }
+UPB_INLINE bool google_protobuf_FileOptions_has_csharp_namespace(const google_protobuf_FileOptions *msg) { return _upb_hasbit(msg, 14); }
+UPB_INLINE upb_strview google_protobuf_FileOptions_csharp_namespace(const google_protobuf_FileOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(52, 88), upb_strview); }
+UPB_INLINE bool google_protobuf_FileOptions_has_swift_prefix(const google_protobuf_FileOptions *msg) { return _upb_hasbit(msg, 15); }
+UPB_INLINE upb_strview google_protobuf_FileOptions_swift_prefix(const google_protobuf_FileOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(60, 104), upb_strview); }
+UPB_INLINE bool google_protobuf_FileOptions_has_php_class_prefix(const google_protobuf_FileOptions *msg) { return _upb_hasbit(msg, 16); }
+UPB_INLINE upb_strview google_protobuf_FileOptions_php_class_prefix(const google_protobuf_FileOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(68, 120), upb_strview); }
+UPB_INLINE bool google_protobuf_FileOptions_has_php_namespace(const google_protobuf_FileOptions *msg) { return _upb_hasbit(msg, 17); }
+UPB_INLINE upb_strview google_protobuf_FileOptions_php_namespace(const google_protobuf_FileOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(76, 136), upb_strview); }
+UPB_INLINE bool google_protobuf_FileOptions_has_php_generic_services(const google_protobuf_FileOptions *msg) { return _upb_hasbit(msg, 18); }
+UPB_INLINE bool google_protobuf_FileOptions_php_generic_services(const google_protobuf_FileOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(16, 16), bool); }
 UPB_INLINE bool google_protobuf_FileOptions_has_php_metadata_namespace(const google_protobuf_FileOptions *msg) { return _upb_hasbit(msg, 19); }
-UPB_INLINE upb_strview google_protobuf_FileOptions_php_metadata_namespace(const google_protobuf_FileOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(92, 160), upb_strview); }
+UPB_INLINE upb_strview google_protobuf_FileOptions_php_metadata_namespace(const google_protobuf_FileOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(84, 152), upb_strview); }
 UPB_INLINE bool google_protobuf_FileOptions_has_ruby_package(const google_protobuf_FileOptions *msg) { return _upb_hasbit(msg, 20); }
-UPB_INLINE upb_strview google_protobuf_FileOptions_ruby_package(const google_protobuf_FileOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(100, 176), upb_strview); }
-UPB_INLINE bool google_protobuf_FileOptions_has_uninterpreted_option(const google_protobuf_FileOptions *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(108, 192)); }
-UPB_INLINE const google_protobuf_UninterpretedOption* const* google_protobuf_FileOptions_uninterpreted_option(const google_protobuf_FileOptions *msg, size_t *len) { return (const google_protobuf_UninterpretedOption* const*)_upb_array_accessor(msg, UPB_SIZE(108, 192), len); }
+UPB_INLINE upb_strview google_protobuf_FileOptions_ruby_package(const google_protobuf_FileOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(92, 168), upb_strview); }
+UPB_INLINE bool google_protobuf_FileOptions_has_uninterpreted_option(const google_protobuf_FileOptions *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(100, 184)); }
+UPB_INLINE const google_protobuf_UninterpretedOption* const* google_protobuf_FileOptions_uninterpreted_option(const google_protobuf_FileOptions *msg, size_t *len) { return (const google_protobuf_UninterpretedOption* const*)_upb_array_accessor(msg, UPB_SIZE(100, 184), len); }
 
 UPB_INLINE void google_protobuf_FileOptions_set_java_package(google_protobuf_FileOptions *msg, upb_strview value) {
-  _upb_sethas(msg, 11);
-  *UPB_PTR_AT(msg, UPB_SIZE(28, 32), upb_strview) = value;
+  _upb_sethas(msg, 1);
+  *UPB_PTR_AT(msg, UPB_SIZE(20, 24), upb_strview) = value;
 }
 UPB_INLINE void google_protobuf_FileOptions_set_java_outer_classname(google_protobuf_FileOptions *msg, upb_strview value) {
-  _upb_sethas(msg, 12);
-  *UPB_PTR_AT(msg, UPB_SIZE(36, 48), upb_strview) = value;
+  _upb_sethas(msg, 2);
+  *UPB_PTR_AT(msg, UPB_SIZE(28, 40), upb_strview) = value;
 }
 UPB_INLINE void google_protobuf_FileOptions_set_optimize_for(google_protobuf_FileOptions *msg, int32_t value) {
-  _upb_sethas(msg, 1);
-  *UPB_PTR_AT(msg, UPB_SIZE(8, 8), int32_t) = value;
+  _upb_sethas(msg, 3);
+  *UPB_PTR_AT(msg, UPB_SIZE(4, 4), int32_t) = value;
 }
 UPB_INLINE void google_protobuf_FileOptions_set_java_multiple_files(google_protobuf_FileOptions *msg, bool value) {
-  _upb_sethas(msg, 2);
-  *UPB_PTR_AT(msg, UPB_SIZE(16, 16), bool) = value;
+  _upb_sethas(msg, 4);
+  *UPB_PTR_AT(msg, UPB_SIZE(8, 8), bool) = value;
 }
 UPB_INLINE void google_protobuf_FileOptions_set_go_package(google_protobuf_FileOptions *msg, upb_strview value) {
-  _upb_sethas(msg, 13);
-  *UPB_PTR_AT(msg, UPB_SIZE(44, 64), upb_strview) = value;
+  _upb_sethas(msg, 5);
+  *UPB_PTR_AT(msg, UPB_SIZE(36, 56), upb_strview) = value;
 }
 UPB_INLINE void google_protobuf_FileOptions_set_cc_generic_services(google_protobuf_FileOptions *msg, bool value) {
-  _upb_sethas(msg, 3);
-  *UPB_PTR_AT(msg, UPB_SIZE(17, 17), bool) = value;
+  _upb_sethas(msg, 6);
+  *UPB_PTR_AT(msg, UPB_SIZE(9, 9), bool) = value;
 }
 UPB_INLINE void google_protobuf_FileOptions_set_java_generic_services(google_protobuf_FileOptions *msg, bool value) {
-  _upb_sethas(msg, 4);
-  *UPB_PTR_AT(msg, UPB_SIZE(18, 18), bool) = value;
+  _upb_sethas(msg, 7);
+  *UPB_PTR_AT(msg, UPB_SIZE(10, 10), bool) = value;
 }
 UPB_INLINE void google_protobuf_FileOptions_set_py_generic_services(google_protobuf_FileOptions *msg, bool value) {
-  _upb_sethas(msg, 5);
-  *UPB_PTR_AT(msg, UPB_SIZE(19, 19), bool) = value;
+  _upb_sethas(msg, 8);
+  *UPB_PTR_AT(msg, UPB_SIZE(11, 11), bool) = value;
 }
 UPB_INLINE void google_protobuf_FileOptions_set_java_generate_equals_and_hash(google_protobuf_FileOptions *msg, bool value) {
-  _upb_sethas(msg, 6);
-  *UPB_PTR_AT(msg, UPB_SIZE(20, 20), bool) = value;
+  _upb_sethas(msg, 9);
+  *UPB_PTR_AT(msg, UPB_SIZE(12, 12), bool) = value;
 }
 UPB_INLINE void google_protobuf_FileOptions_set_deprecated(google_protobuf_FileOptions *msg, bool value) {
-  _upb_sethas(msg, 7);
-  *UPB_PTR_AT(msg, UPB_SIZE(21, 21), bool) = value;
+  _upb_sethas(msg, 10);
+  *UPB_PTR_AT(msg, UPB_SIZE(13, 13), bool) = value;
 }
 UPB_INLINE void google_protobuf_FileOptions_set_java_string_check_utf8(google_protobuf_FileOptions *msg, bool value) {
-  _upb_sethas(msg, 8);
-  *UPB_PTR_AT(msg, UPB_SIZE(22, 22), bool) = value;
+  _upb_sethas(msg, 11);
+  *UPB_PTR_AT(msg, UPB_SIZE(14, 14), bool) = value;
 }
 UPB_INLINE void google_protobuf_FileOptions_set_cc_enable_arenas(google_protobuf_FileOptions *msg, bool value) {
-  _upb_sethas(msg, 9);
-  *UPB_PTR_AT(msg, UPB_SIZE(23, 23), bool) = value;
+  _upb_sethas(msg, 12);
+  *UPB_PTR_AT(msg, UPB_SIZE(15, 15), bool) = value;
 }
 UPB_INLINE void google_protobuf_FileOptions_set_objc_class_prefix(google_protobuf_FileOptions *msg, upb_strview value) {
-  _upb_sethas(msg, 14);
-  *UPB_PTR_AT(msg, UPB_SIZE(52, 80), upb_strview) = value;
+  _upb_sethas(msg, 13);
+  *UPB_PTR_AT(msg, UPB_SIZE(44, 72), upb_strview) = value;
 }
 UPB_INLINE void google_protobuf_FileOptions_set_csharp_namespace(google_protobuf_FileOptions *msg, upb_strview value) {
-  _upb_sethas(msg, 15);
-  *UPB_PTR_AT(msg, UPB_SIZE(60, 96), upb_strview) = value;
+  _upb_sethas(msg, 14);
+  *UPB_PTR_AT(msg, UPB_SIZE(52, 88), upb_strview) = value;
 }
 UPB_INLINE void google_protobuf_FileOptions_set_swift_prefix(google_protobuf_FileOptions *msg, upb_strview value) {
-  _upb_sethas(msg, 16);
-  *UPB_PTR_AT(msg, UPB_SIZE(68, 112), upb_strview) = value;
+  _upb_sethas(msg, 15);
+  *UPB_PTR_AT(msg, UPB_SIZE(60, 104), upb_strview) = value;
 }
 UPB_INLINE void google_protobuf_FileOptions_set_php_class_prefix(google_protobuf_FileOptions *msg, upb_strview value) {
-  _upb_sethas(msg, 17);
-  *UPB_PTR_AT(msg, UPB_SIZE(76, 128), upb_strview) = value;
+  _upb_sethas(msg, 16);
+  *UPB_PTR_AT(msg, UPB_SIZE(68, 120), upb_strview) = value;
 }
 UPB_INLINE void google_protobuf_FileOptions_set_php_namespace(google_protobuf_FileOptions *msg, upb_strview value) {
-  _upb_sethas(msg, 18);
-  *UPB_PTR_AT(msg, UPB_SIZE(84, 144), upb_strview) = value;
+  _upb_sethas(msg, 17);
+  *UPB_PTR_AT(msg, UPB_SIZE(76, 136), upb_strview) = value;
 }
 UPB_INLINE void google_protobuf_FileOptions_set_php_generic_services(google_protobuf_FileOptions *msg, bool value) {
-  _upb_sethas(msg, 10);
-  *UPB_PTR_AT(msg, UPB_SIZE(24, 24), bool) = value;
+  _upb_sethas(msg, 18);
+  *UPB_PTR_AT(msg, UPB_SIZE(16, 16), bool) = value;
 }
 UPB_INLINE void google_protobuf_FileOptions_set_php_metadata_namespace(google_protobuf_FileOptions *msg, upb_strview value) {
   _upb_sethas(msg, 19);
-  *UPB_PTR_AT(msg, UPB_SIZE(92, 160), upb_strview) = value;
+  *UPB_PTR_AT(msg, UPB_SIZE(84, 152), upb_strview) = value;
 }
 UPB_INLINE void google_protobuf_FileOptions_set_ruby_package(google_protobuf_FileOptions *msg, upb_strview value) {
   _upb_sethas(msg, 20);
-  *UPB_PTR_AT(msg, UPB_SIZE(100, 176), upb_strview) = value;
+  *UPB_PTR_AT(msg, UPB_SIZE(92, 168), upb_strview) = value;
 }
 UPB_INLINE google_protobuf_UninterpretedOption** google_protobuf_FileOptions_mutable_uninterpreted_option(google_protobuf_FileOptions *msg, size_t *len) {
-  return (google_protobuf_UninterpretedOption**)_upb_array_mutable_accessor(msg, UPB_SIZE(108, 192), len);
+  return (google_protobuf_UninterpretedOption**)_upb_array_mutable_accessor(msg, UPB_SIZE(100, 184), len);
 }
 UPB_INLINE google_protobuf_UninterpretedOption** google_protobuf_FileOptions_resize_uninterpreted_option(google_protobuf_FileOptions *msg, size_t len, upb_arena *arena) {
-  return (google_protobuf_UninterpretedOption**)_upb_array_resize_accessor(msg, UPB_SIZE(108, 192), len, UPB_TYPE_MESSAGE, arena);
+  return (google_protobuf_UninterpretedOption**)_upb_array_resize_accessor2(msg, UPB_SIZE(100, 184), len, UPB_SIZE(2, 3), arena);
 }
 UPB_INLINE struct google_protobuf_UninterpretedOption* google_protobuf_FileOptions_add_uninterpreted_option(google_protobuf_FileOptions *msg, upb_arena *arena) {
   struct google_protobuf_UninterpretedOption* sub = (struct google_protobuf_UninterpretedOption*)_upb_msg_new(&google_protobuf_UninterpretedOption_msginit, arena);
-  bool ok = _upb_array_append_accessor(
-      msg, UPB_SIZE(108, 192), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena);
+  bool ok = _upb_array_append_accessor2(
+      msg, UPB_SIZE(100, 184), UPB_SIZE(2, 3), &sub, arena);
   if (!ok) return NULL;
   return sub;
 }
@@ -1147,6 +1232,12 @@ UPB_INLINE google_protobuf_MessageOptions *google_protobuf_MessageOptions_parse(
   google_protobuf_MessageOptions *ret = google_protobuf_MessageOptions_new(arena);
   return (ret && upb_decode(buf, size, ret, &google_protobuf_MessageOptions_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE google_protobuf_MessageOptions *google_protobuf_MessageOptions_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  google_protobuf_MessageOptions *ret = google_protobuf_MessageOptions_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &google_protobuf_MessageOptions_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *google_protobuf_MessageOptions_serialize(const google_protobuf_MessageOptions *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &google_protobuf_MessageOptions_msginit, arena, len);
 }
@@ -1182,12 +1273,12 @@ UPB_INLINE google_protobuf_UninterpretedOption** google_protobuf_MessageOptions_
   return (google_protobuf_UninterpretedOption**)_upb_array_mutable_accessor(msg, UPB_SIZE(8, 8), len);
 }
 UPB_INLINE google_protobuf_UninterpretedOption** google_protobuf_MessageOptions_resize_uninterpreted_option(google_protobuf_MessageOptions *msg, size_t len, upb_arena *arena) {
-  return (google_protobuf_UninterpretedOption**)_upb_array_resize_accessor(msg, UPB_SIZE(8, 8), len, UPB_TYPE_MESSAGE, arena);
+  return (google_protobuf_UninterpretedOption**)_upb_array_resize_accessor2(msg, UPB_SIZE(8, 8), len, UPB_SIZE(2, 3), arena);
 }
 UPB_INLINE struct google_protobuf_UninterpretedOption* google_protobuf_MessageOptions_add_uninterpreted_option(google_protobuf_MessageOptions *msg, upb_arena *arena) {
   struct google_protobuf_UninterpretedOption* sub = (struct google_protobuf_UninterpretedOption*)_upb_msg_new(&google_protobuf_UninterpretedOption_msginit, arena);
-  bool ok = _upb_array_append_accessor(
-      msg, UPB_SIZE(8, 8), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena);
+  bool ok = _upb_array_append_accessor2(
+      msg, UPB_SIZE(8, 8), UPB_SIZE(2, 3), &sub, arena);
   if (!ok) return NULL;
   return sub;
 }
@@ -1202,59 +1293,65 @@ UPB_INLINE google_protobuf_FieldOptions *google_protobuf_FieldOptions_parse(cons
   google_protobuf_FieldOptions *ret = google_protobuf_FieldOptions_new(arena);
   return (ret && upb_decode(buf, size, ret, &google_protobuf_FieldOptions_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE google_protobuf_FieldOptions *google_protobuf_FieldOptions_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  google_protobuf_FieldOptions *ret = google_protobuf_FieldOptions_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &google_protobuf_FieldOptions_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *google_protobuf_FieldOptions_serialize(const google_protobuf_FieldOptions *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &google_protobuf_FieldOptions_msginit, arena, len);
 }
 
 UPB_INLINE bool google_protobuf_FieldOptions_has_ctype(const google_protobuf_FieldOptions *msg) { return _upb_hasbit(msg, 1); }
-UPB_INLINE int32_t google_protobuf_FieldOptions_ctype(const google_protobuf_FieldOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(8, 8), int32_t); }
-UPB_INLINE bool google_protobuf_FieldOptions_has_packed(const google_protobuf_FieldOptions *msg) { return _upb_hasbit(msg, 3); }
-UPB_INLINE bool google_protobuf_FieldOptions_packed(const google_protobuf_FieldOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(24, 24), bool); }
-UPB_INLINE bool google_protobuf_FieldOptions_has_deprecated(const google_protobuf_FieldOptions *msg) { return _upb_hasbit(msg, 4); }
-UPB_INLINE bool google_protobuf_FieldOptions_deprecated(const google_protobuf_FieldOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(25, 25), bool); }
-UPB_INLINE bool google_protobuf_FieldOptions_has_lazy(const google_protobuf_FieldOptions *msg) { return _upb_hasbit(msg, 5); }
-UPB_INLINE bool google_protobuf_FieldOptions_lazy(const google_protobuf_FieldOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(26, 26), bool); }
-UPB_INLINE bool google_protobuf_FieldOptions_has_jstype(const google_protobuf_FieldOptions *msg) { return _upb_hasbit(msg, 2); }
-UPB_INLINE int32_t google_protobuf_FieldOptions_jstype(const google_protobuf_FieldOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(16, 16), int32_t); }
+UPB_INLINE int32_t google_protobuf_FieldOptions_ctype(const google_protobuf_FieldOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(4, 4), int32_t); }
+UPB_INLINE bool google_protobuf_FieldOptions_has_packed(const google_protobuf_FieldOptions *msg) { return _upb_hasbit(msg, 2); }
+UPB_INLINE bool google_protobuf_FieldOptions_packed(const google_protobuf_FieldOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(12, 12), bool); }
+UPB_INLINE bool google_protobuf_FieldOptions_has_deprecated(const google_protobuf_FieldOptions *msg) { return _upb_hasbit(msg, 3); }
+UPB_INLINE bool google_protobuf_FieldOptions_deprecated(const google_protobuf_FieldOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(13, 13), bool); }
+UPB_INLINE bool google_protobuf_FieldOptions_has_lazy(const google_protobuf_FieldOptions *msg) { return _upb_hasbit(msg, 4); }
+UPB_INLINE bool google_protobuf_FieldOptions_lazy(const google_protobuf_FieldOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(14, 14), bool); }
+UPB_INLINE bool google_protobuf_FieldOptions_has_jstype(const google_protobuf_FieldOptions *msg) { return _upb_hasbit(msg, 5); }
+UPB_INLINE int32_t google_protobuf_FieldOptions_jstype(const google_protobuf_FieldOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(8, 8), int32_t); }
 UPB_INLINE bool google_protobuf_FieldOptions_has_weak(const google_protobuf_FieldOptions *msg) { return _upb_hasbit(msg, 6); }
-UPB_INLINE bool google_protobuf_FieldOptions_weak(const google_protobuf_FieldOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(27, 27), bool); }
-UPB_INLINE bool google_protobuf_FieldOptions_has_uninterpreted_option(const google_protobuf_FieldOptions *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(28, 32)); }
-UPB_INLINE const google_protobuf_UninterpretedOption* const* google_protobuf_FieldOptions_uninterpreted_option(const google_protobuf_FieldOptions *msg, size_t *len) { return (const google_protobuf_UninterpretedOption* const*)_upb_array_accessor(msg, UPB_SIZE(28, 32), len); }
+UPB_INLINE bool google_protobuf_FieldOptions_weak(const google_protobuf_FieldOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(15, 15), bool); }
+UPB_INLINE bool google_protobuf_FieldOptions_has_uninterpreted_option(const google_protobuf_FieldOptions *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(16, 16)); }
+UPB_INLINE const google_protobuf_UninterpretedOption* const* google_protobuf_FieldOptions_uninterpreted_option(const google_protobuf_FieldOptions *msg, size_t *len) { return (const google_protobuf_UninterpretedOption* const*)_upb_array_accessor(msg, UPB_SIZE(16, 16), len); }
 
 UPB_INLINE void google_protobuf_FieldOptions_set_ctype(google_protobuf_FieldOptions *msg, int32_t value) {
   _upb_sethas(msg, 1);
-  *UPB_PTR_AT(msg, UPB_SIZE(8, 8), int32_t) = value;
+  *UPB_PTR_AT(msg, UPB_SIZE(4, 4), int32_t) = value;
 }
 UPB_INLINE void google_protobuf_FieldOptions_set_packed(google_protobuf_FieldOptions *msg, bool value) {
-  _upb_sethas(msg, 3);
-  *UPB_PTR_AT(msg, UPB_SIZE(24, 24), bool) = value;
+  _upb_sethas(msg, 2);
+  *UPB_PTR_AT(msg, UPB_SIZE(12, 12), bool) = value;
 }
 UPB_INLINE void google_protobuf_FieldOptions_set_deprecated(google_protobuf_FieldOptions *msg, bool value) {
-  _upb_sethas(msg, 4);
-  *UPB_PTR_AT(msg, UPB_SIZE(25, 25), bool) = value;
+  _upb_sethas(msg, 3);
+  *UPB_PTR_AT(msg, UPB_SIZE(13, 13), bool) = value;
 }
 UPB_INLINE void google_protobuf_FieldOptions_set_lazy(google_protobuf_FieldOptions *msg, bool value) {
-  _upb_sethas(msg, 5);
-  *UPB_PTR_AT(msg, UPB_SIZE(26, 26), bool) = value;
+  _upb_sethas(msg, 4);
+  *UPB_PTR_AT(msg, UPB_SIZE(14, 14), bool) = value;
 }
 UPB_INLINE void google_protobuf_FieldOptions_set_jstype(google_protobuf_FieldOptions *msg, int32_t value) {
-  _upb_sethas(msg, 2);
-  *UPB_PTR_AT(msg, UPB_SIZE(16, 16), int32_t) = value;
+  _upb_sethas(msg, 5);
+  *UPB_PTR_AT(msg, UPB_SIZE(8, 8), int32_t) = value;
 }
 UPB_INLINE void google_protobuf_FieldOptions_set_weak(google_protobuf_FieldOptions *msg, bool value) {
   _upb_sethas(msg, 6);
-  *UPB_PTR_AT(msg, UPB_SIZE(27, 27), bool) = value;
+  *UPB_PTR_AT(msg, UPB_SIZE(15, 15), bool) = value;
 }
 UPB_INLINE google_protobuf_UninterpretedOption** google_protobuf_FieldOptions_mutable_uninterpreted_option(google_protobuf_FieldOptions *msg, size_t *len) {
-  return (google_protobuf_UninterpretedOption**)_upb_array_mutable_accessor(msg, UPB_SIZE(28, 32), len);
+  return (google_protobuf_UninterpretedOption**)_upb_array_mutable_accessor(msg, UPB_SIZE(16, 16), len);
 }
 UPB_INLINE google_protobuf_UninterpretedOption** google_protobuf_FieldOptions_resize_uninterpreted_option(google_protobuf_FieldOptions *msg, size_t len, upb_arena *arena) {
-  return (google_protobuf_UninterpretedOption**)_upb_array_resize_accessor(msg, UPB_SIZE(28, 32), len, UPB_TYPE_MESSAGE, arena);
+  return (google_protobuf_UninterpretedOption**)_upb_array_resize_accessor2(msg, UPB_SIZE(16, 16), len, UPB_SIZE(2, 3), arena);
 }
 UPB_INLINE struct google_protobuf_UninterpretedOption* google_protobuf_FieldOptions_add_uninterpreted_option(google_protobuf_FieldOptions *msg, upb_arena *arena) {
   struct google_protobuf_UninterpretedOption* sub = (struct google_protobuf_UninterpretedOption*)_upb_msg_new(&google_protobuf_UninterpretedOption_msginit, arena);
-  bool ok = _upb_array_append_accessor(
-      msg, UPB_SIZE(28, 32), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena);
+  bool ok = _upb_array_append_accessor2(
+      msg, UPB_SIZE(16, 16), UPB_SIZE(2, 3), &sub, arena);
   if (!ok) return NULL;
   return sub;
 }
@@ -1269,6 +1366,12 @@ UPB_INLINE google_protobuf_OneofOptions *google_protobuf_OneofOptions_parse(cons
   google_protobuf_OneofOptions *ret = google_protobuf_OneofOptions_new(arena);
   return (ret && upb_decode(buf, size, ret, &google_protobuf_OneofOptions_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE google_protobuf_OneofOptions *google_protobuf_OneofOptions_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  google_protobuf_OneofOptions *ret = google_protobuf_OneofOptions_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &google_protobuf_OneofOptions_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *google_protobuf_OneofOptions_serialize(const google_protobuf_OneofOptions *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &google_protobuf_OneofOptions_msginit, arena, len);
 }
@@ -1280,12 +1383,12 @@ UPB_INLINE google_protobuf_UninterpretedOption** google_protobuf_OneofOptions_mu
   return (google_protobuf_UninterpretedOption**)_upb_array_mutable_accessor(msg, UPB_SIZE(0, 0), len);
 }
 UPB_INLINE google_protobuf_UninterpretedOption** google_protobuf_OneofOptions_resize_uninterpreted_option(google_protobuf_OneofOptions *msg, size_t len, upb_arena *arena) {
-  return (google_protobuf_UninterpretedOption**)_upb_array_resize_accessor(msg, UPB_SIZE(0, 0), len, UPB_TYPE_MESSAGE, arena);
+  return (google_protobuf_UninterpretedOption**)_upb_array_resize_accessor2(msg, UPB_SIZE(0, 0), len, UPB_SIZE(2, 3), arena);
 }
 UPB_INLINE struct google_protobuf_UninterpretedOption* google_protobuf_OneofOptions_add_uninterpreted_option(google_protobuf_OneofOptions *msg, upb_arena *arena) {
   struct google_protobuf_UninterpretedOption* sub = (struct google_protobuf_UninterpretedOption*)_upb_msg_new(&google_protobuf_UninterpretedOption_msginit, arena);
-  bool ok = _upb_array_append_accessor(
-      msg, UPB_SIZE(0, 0), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena);
+  bool ok = _upb_array_append_accessor2(
+      msg, UPB_SIZE(0, 0), UPB_SIZE(2, 3), &sub, arena);
   if (!ok) return NULL;
   return sub;
 }
@@ -1300,6 +1403,12 @@ UPB_INLINE google_protobuf_EnumOptions *google_protobuf_EnumOptions_parse(const
   google_protobuf_EnumOptions *ret = google_protobuf_EnumOptions_new(arena);
   return (ret && upb_decode(buf, size, ret, &google_protobuf_EnumOptions_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE google_protobuf_EnumOptions *google_protobuf_EnumOptions_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  google_protobuf_EnumOptions *ret = google_protobuf_EnumOptions_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &google_protobuf_EnumOptions_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *google_protobuf_EnumOptions_serialize(const google_protobuf_EnumOptions *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &google_protobuf_EnumOptions_msginit, arena, len);
 }
@@ -1323,12 +1432,12 @@ UPB_INLINE google_protobuf_UninterpretedOption** google_protobuf_EnumOptions_mut
   return (google_protobuf_UninterpretedOption**)_upb_array_mutable_accessor(msg, UPB_SIZE(4, 8), len);
 }
 UPB_INLINE google_protobuf_UninterpretedOption** google_protobuf_EnumOptions_resize_uninterpreted_option(google_protobuf_EnumOptions *msg, size_t len, upb_arena *arena) {
-  return (google_protobuf_UninterpretedOption**)_upb_array_resize_accessor(msg, UPB_SIZE(4, 8), len, UPB_TYPE_MESSAGE, arena);
+  return (google_protobuf_UninterpretedOption**)_upb_array_resize_accessor2(msg, UPB_SIZE(4, 8), len, UPB_SIZE(2, 3), arena);
 }
 UPB_INLINE struct google_protobuf_UninterpretedOption* google_protobuf_EnumOptions_add_uninterpreted_option(google_protobuf_EnumOptions *msg, upb_arena *arena) {
   struct google_protobuf_UninterpretedOption* sub = (struct google_protobuf_UninterpretedOption*)_upb_msg_new(&google_protobuf_UninterpretedOption_msginit, arena);
-  bool ok = _upb_array_append_accessor(
-      msg, UPB_SIZE(4, 8), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena);
+  bool ok = _upb_array_append_accessor2(
+      msg, UPB_SIZE(4, 8), UPB_SIZE(2, 3), &sub, arena);
   if (!ok) return NULL;
   return sub;
 }
@@ -1343,6 +1452,12 @@ UPB_INLINE google_protobuf_EnumValueOptions *google_protobuf_EnumValueOptions_pa
   google_protobuf_EnumValueOptions *ret = google_protobuf_EnumValueOptions_new(arena);
   return (ret && upb_decode(buf, size, ret, &google_protobuf_EnumValueOptions_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE google_protobuf_EnumValueOptions *google_protobuf_EnumValueOptions_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  google_protobuf_EnumValueOptions *ret = google_protobuf_EnumValueOptions_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &google_protobuf_EnumValueOptions_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *google_protobuf_EnumValueOptions_serialize(const google_protobuf_EnumValueOptions *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &google_protobuf_EnumValueOptions_msginit, arena, len);
 }
@@ -1360,12 +1475,12 @@ UPB_INLINE google_protobuf_UninterpretedOption** google_protobuf_EnumValueOption
   return (google_protobuf_UninterpretedOption**)_upb_array_mutable_accessor(msg, UPB_SIZE(4, 8), len);
 }
 UPB_INLINE google_protobuf_UninterpretedOption** google_protobuf_EnumValueOptions_resize_uninterpreted_option(google_protobuf_EnumValueOptions *msg, size_t len, upb_arena *arena) {
-  return (google_protobuf_UninterpretedOption**)_upb_array_resize_accessor(msg, UPB_SIZE(4, 8), len, UPB_TYPE_MESSAGE, arena);
+  return (google_protobuf_UninterpretedOption**)_upb_array_resize_accessor2(msg, UPB_SIZE(4, 8), len, UPB_SIZE(2, 3), arena);
 }
 UPB_INLINE struct google_protobuf_UninterpretedOption* google_protobuf_EnumValueOptions_add_uninterpreted_option(google_protobuf_EnumValueOptions *msg, upb_arena *arena) {
   struct google_protobuf_UninterpretedOption* sub = (struct google_protobuf_UninterpretedOption*)_upb_msg_new(&google_protobuf_UninterpretedOption_msginit, arena);
-  bool ok = _upb_array_append_accessor(
-      msg, UPB_SIZE(4, 8), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena);
+  bool ok = _upb_array_append_accessor2(
+      msg, UPB_SIZE(4, 8), UPB_SIZE(2, 3), &sub, arena);
   if (!ok) return NULL;
   return sub;
 }
@@ -1380,6 +1495,12 @@ UPB_INLINE google_protobuf_ServiceOptions *google_protobuf_ServiceOptions_parse(
   google_protobuf_ServiceOptions *ret = google_protobuf_ServiceOptions_new(arena);
   return (ret && upb_decode(buf, size, ret, &google_protobuf_ServiceOptions_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE google_protobuf_ServiceOptions *google_protobuf_ServiceOptions_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  google_protobuf_ServiceOptions *ret = google_protobuf_ServiceOptions_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &google_protobuf_ServiceOptions_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *google_protobuf_ServiceOptions_serialize(const google_protobuf_ServiceOptions *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &google_protobuf_ServiceOptions_msginit, arena, len);
 }
@@ -1397,12 +1518,12 @@ UPB_INLINE google_protobuf_UninterpretedOption** google_protobuf_ServiceOptions_
   return (google_protobuf_UninterpretedOption**)_upb_array_mutable_accessor(msg, UPB_SIZE(4, 8), len);
 }
 UPB_INLINE google_protobuf_UninterpretedOption** google_protobuf_ServiceOptions_resize_uninterpreted_option(google_protobuf_ServiceOptions *msg, size_t len, upb_arena *arena) {
-  return (google_protobuf_UninterpretedOption**)_upb_array_resize_accessor(msg, UPB_SIZE(4, 8), len, UPB_TYPE_MESSAGE, arena);
+  return (google_protobuf_UninterpretedOption**)_upb_array_resize_accessor2(msg, UPB_SIZE(4, 8), len, UPB_SIZE(2, 3), arena);
 }
 UPB_INLINE struct google_protobuf_UninterpretedOption* google_protobuf_ServiceOptions_add_uninterpreted_option(google_protobuf_ServiceOptions *msg, upb_arena *arena) {
   struct google_protobuf_UninterpretedOption* sub = (struct google_protobuf_UninterpretedOption*)_upb_msg_new(&google_protobuf_UninterpretedOption_msginit, arena);
-  bool ok = _upb_array_append_accessor(
-      msg, UPB_SIZE(4, 8), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena);
+  bool ok = _upb_array_append_accessor2(
+      msg, UPB_SIZE(4, 8), UPB_SIZE(2, 3), &sub, arena);
   if (!ok) return NULL;
   return sub;
 }
@@ -1417,35 +1538,41 @@ UPB_INLINE google_protobuf_MethodOptions *google_protobuf_MethodOptions_parse(co
   google_protobuf_MethodOptions *ret = google_protobuf_MethodOptions_new(arena);
   return (ret && upb_decode(buf, size, ret, &google_protobuf_MethodOptions_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE google_protobuf_MethodOptions *google_protobuf_MethodOptions_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  google_protobuf_MethodOptions *ret = google_protobuf_MethodOptions_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &google_protobuf_MethodOptions_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *google_protobuf_MethodOptions_serialize(const google_protobuf_MethodOptions *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &google_protobuf_MethodOptions_msginit, arena, len);
 }
 
-UPB_INLINE bool google_protobuf_MethodOptions_has_deprecated(const google_protobuf_MethodOptions *msg) { return _upb_hasbit(msg, 2); }
-UPB_INLINE bool google_protobuf_MethodOptions_deprecated(const google_protobuf_MethodOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(16, 16), bool); }
-UPB_INLINE bool google_protobuf_MethodOptions_has_idempotency_level(const google_protobuf_MethodOptions *msg) { return _upb_hasbit(msg, 1); }
-UPB_INLINE int32_t google_protobuf_MethodOptions_idempotency_level(const google_protobuf_MethodOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(8, 8), int32_t); }
-UPB_INLINE bool google_protobuf_MethodOptions_has_uninterpreted_option(const google_protobuf_MethodOptions *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(20, 24)); }
-UPB_INLINE const google_protobuf_UninterpretedOption* const* google_protobuf_MethodOptions_uninterpreted_option(const google_protobuf_MethodOptions *msg, size_t *len) { return (const google_protobuf_UninterpretedOption* const*)_upb_array_accessor(msg, UPB_SIZE(20, 24), len); }
+UPB_INLINE bool google_protobuf_MethodOptions_has_deprecated(const google_protobuf_MethodOptions *msg) { return _upb_hasbit(msg, 1); }
+UPB_INLINE bool google_protobuf_MethodOptions_deprecated(const google_protobuf_MethodOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(8, 8), bool); }
+UPB_INLINE bool google_protobuf_MethodOptions_has_idempotency_level(const google_protobuf_MethodOptions *msg) { return _upb_hasbit(msg, 2); }
+UPB_INLINE int32_t google_protobuf_MethodOptions_idempotency_level(const google_protobuf_MethodOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(4, 4), int32_t); }
+UPB_INLINE bool google_protobuf_MethodOptions_has_uninterpreted_option(const google_protobuf_MethodOptions *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(12, 16)); }
+UPB_INLINE const google_protobuf_UninterpretedOption* const* google_protobuf_MethodOptions_uninterpreted_option(const google_protobuf_MethodOptions *msg, size_t *len) { return (const google_protobuf_UninterpretedOption* const*)_upb_array_accessor(msg, UPB_SIZE(12, 16), len); }
 
 UPB_INLINE void google_protobuf_MethodOptions_set_deprecated(google_protobuf_MethodOptions *msg, bool value) {
-  _upb_sethas(msg, 2);
-  *UPB_PTR_AT(msg, UPB_SIZE(16, 16), bool) = value;
+  _upb_sethas(msg, 1);
+  *UPB_PTR_AT(msg, UPB_SIZE(8, 8), bool) = value;
 }
 UPB_INLINE void google_protobuf_MethodOptions_set_idempotency_level(google_protobuf_MethodOptions *msg, int32_t value) {
-  _upb_sethas(msg, 1);
-  *UPB_PTR_AT(msg, UPB_SIZE(8, 8), int32_t) = value;
+  _upb_sethas(msg, 2);
+  *UPB_PTR_AT(msg, UPB_SIZE(4, 4), int32_t) = value;
 }
 UPB_INLINE google_protobuf_UninterpretedOption** google_protobuf_MethodOptions_mutable_uninterpreted_option(google_protobuf_MethodOptions *msg, size_t *len) {
-  return (google_protobuf_UninterpretedOption**)_upb_array_mutable_accessor(msg, UPB_SIZE(20, 24), len);
+  return (google_protobuf_UninterpretedOption**)_upb_array_mutable_accessor(msg, UPB_SIZE(12, 16), len);
 }
 UPB_INLINE google_protobuf_UninterpretedOption** google_protobuf_MethodOptions_resize_uninterpreted_option(google_protobuf_MethodOptions *msg, size_t len, upb_arena *arena) {
-  return (google_protobuf_UninterpretedOption**)_upb_array_resize_accessor(msg, UPB_SIZE(20, 24), len, UPB_TYPE_MESSAGE, arena);
+  return (google_protobuf_UninterpretedOption**)_upb_array_resize_accessor2(msg, UPB_SIZE(12, 16), len, UPB_SIZE(2, 3), arena);
 }
 UPB_INLINE struct google_protobuf_UninterpretedOption* google_protobuf_MethodOptions_add_uninterpreted_option(google_protobuf_MethodOptions *msg, upb_arena *arena) {
   struct google_protobuf_UninterpretedOption* sub = (struct google_protobuf_UninterpretedOption*)_upb_msg_new(&google_protobuf_UninterpretedOption_msginit, arena);
-  bool ok = _upb_array_append_accessor(
-      msg, UPB_SIZE(20, 24), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena);
+  bool ok = _upb_array_append_accessor2(
+      msg, UPB_SIZE(12, 16), UPB_SIZE(2, 3), &sub, arena);
   if (!ok) return NULL;
   return sub;
 }
@@ -1460,19 +1587,25 @@ UPB_INLINE google_protobuf_UninterpretedOption *google_protobuf_UninterpretedOpt
   google_protobuf_UninterpretedOption *ret = google_protobuf_UninterpretedOption_new(arena);
   return (ret && upb_decode(buf, size, ret, &google_protobuf_UninterpretedOption_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE google_protobuf_UninterpretedOption *google_protobuf_UninterpretedOption_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  google_protobuf_UninterpretedOption *ret = google_protobuf_UninterpretedOption_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &google_protobuf_UninterpretedOption_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *google_protobuf_UninterpretedOption_serialize(const google_protobuf_UninterpretedOption *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &google_protobuf_UninterpretedOption_msginit, arena, len);
 }
 
 UPB_INLINE bool google_protobuf_UninterpretedOption_has_name(const google_protobuf_UninterpretedOption *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(56, 80)); }
 UPB_INLINE const google_protobuf_UninterpretedOption_NamePart* const* google_protobuf_UninterpretedOption_name(const google_protobuf_UninterpretedOption *msg, size_t *len) { return (const google_protobuf_UninterpretedOption_NamePart* const*)_upb_array_accessor(msg, UPB_SIZE(56, 80), len); }
-UPB_INLINE bool google_protobuf_UninterpretedOption_has_identifier_value(const google_protobuf_UninterpretedOption *msg) { return _upb_hasbit(msg, 4); }
+UPB_INLINE bool google_protobuf_UninterpretedOption_has_identifier_value(const google_protobuf_UninterpretedOption *msg) { return _upb_hasbit(msg, 1); }
 UPB_INLINE upb_strview google_protobuf_UninterpretedOption_identifier_value(const google_protobuf_UninterpretedOption *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(32, 32), upb_strview); }
-UPB_INLINE bool google_protobuf_UninterpretedOption_has_positive_int_value(const google_protobuf_UninterpretedOption *msg) { return _upb_hasbit(msg, 1); }
+UPB_INLINE bool google_protobuf_UninterpretedOption_has_positive_int_value(const google_protobuf_UninterpretedOption *msg) { return _upb_hasbit(msg, 2); }
 UPB_INLINE uint64_t google_protobuf_UninterpretedOption_positive_int_value(const google_protobuf_UninterpretedOption *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(8, 8), uint64_t); }
-UPB_INLINE bool google_protobuf_UninterpretedOption_has_negative_int_value(const google_protobuf_UninterpretedOption *msg) { return _upb_hasbit(msg, 2); }
+UPB_INLINE bool google_protobuf_UninterpretedOption_has_negative_int_value(const google_protobuf_UninterpretedOption *msg) { return _upb_hasbit(msg, 3); }
 UPB_INLINE int64_t google_protobuf_UninterpretedOption_negative_int_value(const google_protobuf_UninterpretedOption *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(16, 16), int64_t); }
-UPB_INLINE bool google_protobuf_UninterpretedOption_has_double_value(const google_protobuf_UninterpretedOption *msg) { return _upb_hasbit(msg, 3); }
+UPB_INLINE bool google_protobuf_UninterpretedOption_has_double_value(const google_protobuf_UninterpretedOption *msg) { return _upb_hasbit(msg, 4); }
 UPB_INLINE double google_protobuf_UninterpretedOption_double_value(const google_protobuf_UninterpretedOption *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(24, 24), double); }
 UPB_INLINE bool google_protobuf_UninterpretedOption_has_string_value(const google_protobuf_UninterpretedOption *msg) { return _upb_hasbit(msg, 5); }
 UPB_INLINE upb_strview google_protobuf_UninterpretedOption_string_value(const google_protobuf_UninterpretedOption *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(40, 48), upb_strview); }
@@ -1483,29 +1616,29 @@ UPB_INLINE google_protobuf_UninterpretedOption_NamePart** google_protobuf_Uninte
   return (google_protobuf_UninterpretedOption_NamePart**)_upb_array_mutable_accessor(msg, UPB_SIZE(56, 80), len);
 }
 UPB_INLINE google_protobuf_UninterpretedOption_NamePart** google_protobuf_UninterpretedOption_resize_name(google_protobuf_UninterpretedOption *msg, size_t len, upb_arena *arena) {
-  return (google_protobuf_UninterpretedOption_NamePart**)_upb_array_resize_accessor(msg, UPB_SIZE(56, 80), len, UPB_TYPE_MESSAGE, arena);
+  return (google_protobuf_UninterpretedOption_NamePart**)_upb_array_resize_accessor2(msg, UPB_SIZE(56, 80), len, UPB_SIZE(2, 3), arena);
 }
 UPB_INLINE struct google_protobuf_UninterpretedOption_NamePart* google_protobuf_UninterpretedOption_add_name(google_protobuf_UninterpretedOption *msg, upb_arena *arena) {
   struct google_protobuf_UninterpretedOption_NamePart* sub = (struct google_protobuf_UninterpretedOption_NamePart*)_upb_msg_new(&google_protobuf_UninterpretedOption_NamePart_msginit, arena);
-  bool ok = _upb_array_append_accessor(
-      msg, UPB_SIZE(56, 80), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena);
+  bool ok = _upb_array_append_accessor2(
+      msg, UPB_SIZE(56, 80), UPB_SIZE(2, 3), &sub, arena);
   if (!ok) return NULL;
   return sub;
 }
 UPB_INLINE void google_protobuf_UninterpretedOption_set_identifier_value(google_protobuf_UninterpretedOption *msg, upb_strview value) {
-  _upb_sethas(msg, 4);
+  _upb_sethas(msg, 1);
   *UPB_PTR_AT(msg, UPB_SIZE(32, 32), upb_strview) = value;
 }
 UPB_INLINE void google_protobuf_UninterpretedOption_set_positive_int_value(google_protobuf_UninterpretedOption *msg, uint64_t value) {
-  _upb_sethas(msg, 1);
+  _upb_sethas(msg, 2);
   *UPB_PTR_AT(msg, UPB_SIZE(8, 8), uint64_t) = value;
 }
 UPB_INLINE void google_protobuf_UninterpretedOption_set_negative_int_value(google_protobuf_UninterpretedOption *msg, int64_t value) {
-  _upb_sethas(msg, 2);
+  _upb_sethas(msg, 3);
   *UPB_PTR_AT(msg, UPB_SIZE(16, 16), int64_t) = value;
 }
 UPB_INLINE void google_protobuf_UninterpretedOption_set_double_value(google_protobuf_UninterpretedOption *msg, double value) {
-  _upb_sethas(msg, 3);
+  _upb_sethas(msg, 4);
   *UPB_PTR_AT(msg, UPB_SIZE(24, 24), double) = value;
 }
 UPB_INLINE void google_protobuf_UninterpretedOption_set_string_value(google_protobuf_UninterpretedOption *msg, upb_strview value) {
@@ -1527,21 +1660,27 @@ UPB_INLINE google_protobuf_UninterpretedOption_NamePart *google_protobuf_Uninter
   google_protobuf_UninterpretedOption_NamePart *ret = google_protobuf_UninterpretedOption_NamePart_new(arena);
   return (ret && upb_decode(buf, size, ret, &google_protobuf_UninterpretedOption_NamePart_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE google_protobuf_UninterpretedOption_NamePart *google_protobuf_UninterpretedOption_NamePart_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  google_protobuf_UninterpretedOption_NamePart *ret = google_protobuf_UninterpretedOption_NamePart_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &google_protobuf_UninterpretedOption_NamePart_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *google_protobuf_UninterpretedOption_NamePart_serialize(const google_protobuf_UninterpretedOption_NamePart *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &google_protobuf_UninterpretedOption_NamePart_msginit, arena, len);
 }
 
-UPB_INLINE bool google_protobuf_UninterpretedOption_NamePart_has_name_part(const google_protobuf_UninterpretedOption_NamePart *msg) { return _upb_hasbit(msg, 2); }
+UPB_INLINE bool google_protobuf_UninterpretedOption_NamePart_has_name_part(const google_protobuf_UninterpretedOption_NamePart *msg) { return _upb_hasbit(msg, 1); }
 UPB_INLINE upb_strview google_protobuf_UninterpretedOption_NamePart_name_part(const google_protobuf_UninterpretedOption_NamePart *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(4, 8), upb_strview); }
-UPB_INLINE bool google_protobuf_UninterpretedOption_NamePart_has_is_extension(const google_protobuf_UninterpretedOption_NamePart *msg) { return _upb_hasbit(msg, 1); }
+UPB_INLINE bool google_protobuf_UninterpretedOption_NamePart_has_is_extension(const google_protobuf_UninterpretedOption_NamePart *msg) { return _upb_hasbit(msg, 2); }
 UPB_INLINE bool google_protobuf_UninterpretedOption_NamePart_is_extension(const google_protobuf_UninterpretedOption_NamePart *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(1, 1), bool); }
 
 UPB_INLINE void google_protobuf_UninterpretedOption_NamePart_set_name_part(google_protobuf_UninterpretedOption_NamePart *msg, upb_strview value) {
-  _upb_sethas(msg, 2);
+  _upb_sethas(msg, 1);
   *UPB_PTR_AT(msg, UPB_SIZE(4, 8), upb_strview) = value;
 }
 UPB_INLINE void google_protobuf_UninterpretedOption_NamePart_set_is_extension(google_protobuf_UninterpretedOption_NamePart *msg, bool value) {
-  _upb_sethas(msg, 1);
+  _upb_sethas(msg, 2);
   *UPB_PTR_AT(msg, UPB_SIZE(1, 1), bool) = value;
 }
 
@@ -1555,6 +1694,12 @@ UPB_INLINE google_protobuf_SourceCodeInfo *google_protobuf_SourceCodeInfo_parse(
   google_protobuf_SourceCodeInfo *ret = google_protobuf_SourceCodeInfo_new(arena);
   return (ret && upb_decode(buf, size, ret, &google_protobuf_SourceCodeInfo_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE google_protobuf_SourceCodeInfo *google_protobuf_SourceCodeInfo_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  google_protobuf_SourceCodeInfo *ret = google_protobuf_SourceCodeInfo_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &google_protobuf_SourceCodeInfo_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *google_protobuf_SourceCodeInfo_serialize(const google_protobuf_SourceCodeInfo *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &google_protobuf_SourceCodeInfo_msginit, arena, len);
 }
@@ -1566,12 +1711,12 @@ UPB_INLINE google_protobuf_SourceCodeInfo_Location** google_protobuf_SourceCodeI
   return (google_protobuf_SourceCodeInfo_Location**)_upb_array_mutable_accessor(msg, UPB_SIZE(0, 0), len);
 }
 UPB_INLINE google_protobuf_SourceCodeInfo_Location** google_protobuf_SourceCodeInfo_resize_location(google_protobuf_SourceCodeInfo *msg, size_t len, upb_arena *arena) {
-  return (google_protobuf_SourceCodeInfo_Location**)_upb_array_resize_accessor(msg, UPB_SIZE(0, 0), len, UPB_TYPE_MESSAGE, arena);
+  return (google_protobuf_SourceCodeInfo_Location**)_upb_array_resize_accessor2(msg, UPB_SIZE(0, 0), len, UPB_SIZE(2, 3), arena);
 }
 UPB_INLINE struct google_protobuf_SourceCodeInfo_Location* google_protobuf_SourceCodeInfo_add_location(google_protobuf_SourceCodeInfo *msg, upb_arena *arena) {
   struct google_protobuf_SourceCodeInfo_Location* sub = (struct google_protobuf_SourceCodeInfo_Location*)_upb_msg_new(&google_protobuf_SourceCodeInfo_Location_msginit, arena);
-  bool ok = _upb_array_append_accessor(
-      msg, UPB_SIZE(0, 0), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena);
+  bool ok = _upb_array_append_accessor2(
+      msg, UPB_SIZE(0, 0), UPB_SIZE(2, 3), &sub, arena);
   if (!ok) return NULL;
   return sub;
 }
@@ -1586,6 +1731,12 @@ UPB_INLINE google_protobuf_SourceCodeInfo_Location *google_protobuf_SourceCodeIn
   google_protobuf_SourceCodeInfo_Location *ret = google_protobuf_SourceCodeInfo_Location_new(arena);
   return (ret && upb_decode(buf, size, ret, &google_protobuf_SourceCodeInfo_Location_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE google_protobuf_SourceCodeInfo_Location *google_protobuf_SourceCodeInfo_Location_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  google_protobuf_SourceCodeInfo_Location *ret = google_protobuf_SourceCodeInfo_Location_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &google_protobuf_SourceCodeInfo_Location_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *google_protobuf_SourceCodeInfo_Location_serialize(const google_protobuf_SourceCodeInfo_Location *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &google_protobuf_SourceCodeInfo_Location_msginit, arena, len);
 }
@@ -1602,20 +1753,20 @@ UPB_INLINE int32_t* google_protobuf_SourceCodeInfo_Location_mutable_path(google_
   return (int32_t*)_upb_array_mutable_accessor(msg, UPB_SIZE(20, 40), len);
 }
 UPB_INLINE int32_t* google_protobuf_SourceCodeInfo_Location_resize_path(google_protobuf_SourceCodeInfo_Location *msg, size_t len, upb_arena *arena) {
-  return (int32_t*)_upb_array_resize_accessor(msg, UPB_SIZE(20, 40), len, UPB_TYPE_INT32, arena);
+  return (int32_t*)_upb_array_resize_accessor2(msg, UPB_SIZE(20, 40), len, 2, arena);
 }
 UPB_INLINE bool google_protobuf_SourceCodeInfo_Location_add_path(google_protobuf_SourceCodeInfo_Location *msg, int32_t val, upb_arena *arena) {
-  return _upb_array_append_accessor(msg, UPB_SIZE(20, 40), UPB_SIZE(4, 4), UPB_TYPE_INT32, &val,
+  return _upb_array_append_accessor2(msg, UPB_SIZE(20, 40), 2, &val,
       arena);
 }
 UPB_INLINE int32_t* google_protobuf_SourceCodeInfo_Location_mutable_span(google_protobuf_SourceCodeInfo_Location *msg, size_t *len) {
   return (int32_t*)_upb_array_mutable_accessor(msg, UPB_SIZE(24, 48), len);
 }
 UPB_INLINE int32_t* google_protobuf_SourceCodeInfo_Location_resize_span(google_protobuf_SourceCodeInfo_Location *msg, size_t len, upb_arena *arena) {
-  return (int32_t*)_upb_array_resize_accessor(msg, UPB_SIZE(24, 48), len, UPB_TYPE_INT32, arena);
+  return (int32_t*)_upb_array_resize_accessor2(msg, UPB_SIZE(24, 48), len, 2, arena);
 }
 UPB_INLINE bool google_protobuf_SourceCodeInfo_Location_add_span(google_protobuf_SourceCodeInfo_Location *msg, int32_t val, upb_arena *arena) {
-  return _upb_array_append_accessor(msg, UPB_SIZE(24, 48), UPB_SIZE(4, 4), UPB_TYPE_INT32, &val,
+  return _upb_array_append_accessor2(msg, UPB_SIZE(24, 48), 2, &val,
       arena);
 }
 UPB_INLINE void google_protobuf_SourceCodeInfo_Location_set_leading_comments(google_protobuf_SourceCodeInfo_Location *msg, upb_strview value) {
@@ -1630,10 +1781,10 @@ UPB_INLINE upb_strview* google_protobuf_SourceCodeInfo_Location_mutable_leading_
   return (upb_strview*)_upb_array_mutable_accessor(msg, UPB_SIZE(28, 56), len);
 }
 UPB_INLINE upb_strview* google_protobuf_SourceCodeInfo_Location_resize_leading_detached_comments(google_protobuf_SourceCodeInfo_Location *msg, size_t len, upb_arena *arena) {
-  return (upb_strview*)_upb_array_resize_accessor(msg, UPB_SIZE(28, 56), len, UPB_TYPE_STRING, arena);
+  return (upb_strview*)_upb_array_resize_accessor2(msg, UPB_SIZE(28, 56), len, UPB_SIZE(3, 4), arena);
 }
 UPB_INLINE bool google_protobuf_SourceCodeInfo_Location_add_leading_detached_comments(google_protobuf_SourceCodeInfo_Location *msg, upb_strview val, upb_arena *arena) {
-  return _upb_array_append_accessor(msg, UPB_SIZE(28, 56), UPB_SIZE(8, 16), UPB_TYPE_STRING, &val,
+  return _upb_array_append_accessor2(msg, UPB_SIZE(28, 56), UPB_SIZE(3, 4), &val,
       arena);
 }
 
@@ -1647,6 +1798,12 @@ UPB_INLINE google_protobuf_GeneratedCodeInfo *google_protobuf_GeneratedCodeInfo_
   google_protobuf_GeneratedCodeInfo *ret = google_protobuf_GeneratedCodeInfo_new(arena);
   return (ret && upb_decode(buf, size, ret, &google_protobuf_GeneratedCodeInfo_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE google_protobuf_GeneratedCodeInfo *google_protobuf_GeneratedCodeInfo_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  google_protobuf_GeneratedCodeInfo *ret = google_protobuf_GeneratedCodeInfo_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &google_protobuf_GeneratedCodeInfo_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *google_protobuf_GeneratedCodeInfo_serialize(const google_protobuf_GeneratedCodeInfo *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &google_protobuf_GeneratedCodeInfo_msginit, arena, len);
 }
@@ -1658,12 +1815,12 @@ UPB_INLINE google_protobuf_GeneratedCodeInfo_Annotation** google_protobuf_Genera
   return (google_protobuf_GeneratedCodeInfo_Annotation**)_upb_array_mutable_accessor(msg, UPB_SIZE(0, 0), len);
 }
 UPB_INLINE google_protobuf_GeneratedCodeInfo_Annotation** google_protobuf_GeneratedCodeInfo_resize_annotation(google_protobuf_GeneratedCodeInfo *msg, size_t len, upb_arena *arena) {
-  return (google_protobuf_GeneratedCodeInfo_Annotation**)_upb_array_resize_accessor(msg, UPB_SIZE(0, 0), len, UPB_TYPE_MESSAGE, arena);
+  return (google_protobuf_GeneratedCodeInfo_Annotation**)_upb_array_resize_accessor2(msg, UPB_SIZE(0, 0), len, UPB_SIZE(2, 3), arena);
 }
 UPB_INLINE struct google_protobuf_GeneratedCodeInfo_Annotation* google_protobuf_GeneratedCodeInfo_add_annotation(google_protobuf_GeneratedCodeInfo *msg, upb_arena *arena) {
   struct google_protobuf_GeneratedCodeInfo_Annotation* sub = (struct google_protobuf_GeneratedCodeInfo_Annotation*)_upb_msg_new(&google_protobuf_GeneratedCodeInfo_Annotation_msginit, arena);
-  bool ok = _upb_array_append_accessor(
-      msg, UPB_SIZE(0, 0), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena);
+  bool ok = _upb_array_append_accessor2(
+      msg, UPB_SIZE(0, 0), UPB_SIZE(2, 3), &sub, arena);
   if (!ok) return NULL;
   return sub;
 }
@@ -1678,38 +1835,44 @@ UPB_INLINE google_protobuf_GeneratedCodeInfo_Annotation *google_protobuf_Generat
   google_protobuf_GeneratedCodeInfo_Annotation *ret = google_protobuf_GeneratedCodeInfo_Annotation_new(arena);
   return (ret && upb_decode(buf, size, ret, &google_protobuf_GeneratedCodeInfo_Annotation_msginit, arena)) ? ret : NULL;
 }
+UPB_INLINE google_protobuf_GeneratedCodeInfo_Annotation *google_protobuf_GeneratedCodeInfo_Annotation_parse_ex(const char *buf, size_t size,
+                           upb_arena *arena, int options) {
+  google_protobuf_GeneratedCodeInfo_Annotation *ret = google_protobuf_GeneratedCodeInfo_Annotation_new(arena);
+  return (ret && _upb_decode(buf, size, ret, &google_protobuf_GeneratedCodeInfo_Annotation_msginit, arena, options))
+      ? ret : NULL;
+}
 UPB_INLINE char *google_protobuf_GeneratedCodeInfo_Annotation_serialize(const google_protobuf_GeneratedCodeInfo_Annotation *msg, upb_arena *arena, size_t *len) {
   return upb_encode(msg, &google_protobuf_GeneratedCodeInfo_Annotation_msginit, arena, len);
 }
 
 UPB_INLINE int32_t const* google_protobuf_GeneratedCodeInfo_Annotation_path(const google_protobuf_GeneratedCodeInfo_Annotation *msg, size_t *len) { return (int32_t const*)_upb_array_accessor(msg, UPB_SIZE(20, 32), len); }
-UPB_INLINE bool google_protobuf_GeneratedCodeInfo_Annotation_has_source_file(const google_protobuf_GeneratedCodeInfo_Annotation *msg) { return _upb_hasbit(msg, 3); }
+UPB_INLINE bool google_protobuf_GeneratedCodeInfo_Annotation_has_source_file(const google_protobuf_GeneratedCodeInfo_Annotation *msg) { return _upb_hasbit(msg, 1); }
 UPB_INLINE upb_strview google_protobuf_GeneratedCodeInfo_Annotation_source_file(const google_protobuf_GeneratedCodeInfo_Annotation *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(12, 16), upb_strview); }
-UPB_INLINE bool google_protobuf_GeneratedCodeInfo_Annotation_has_begin(const google_protobuf_GeneratedCodeInfo_Annotation *msg) { return _upb_hasbit(msg, 1); }
+UPB_INLINE bool google_protobuf_GeneratedCodeInfo_Annotation_has_begin(const google_protobuf_GeneratedCodeInfo_Annotation *msg) { return _upb_hasbit(msg, 2); }
 UPB_INLINE int32_t google_protobuf_GeneratedCodeInfo_Annotation_begin(const google_protobuf_GeneratedCodeInfo_Annotation *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(4, 4), int32_t); }
-UPB_INLINE bool google_protobuf_GeneratedCodeInfo_Annotation_has_end(const google_protobuf_GeneratedCodeInfo_Annotation *msg) { return _upb_hasbit(msg, 2); }
+UPB_INLINE bool google_protobuf_GeneratedCodeInfo_Annotation_has_end(const google_protobuf_GeneratedCodeInfo_Annotation *msg) { return _upb_hasbit(msg, 3); }
 UPB_INLINE int32_t google_protobuf_GeneratedCodeInfo_Annotation_end(const google_protobuf_GeneratedCodeInfo_Annotation *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(8, 8), int32_t); }
 
 UPB_INLINE int32_t* google_protobuf_GeneratedCodeInfo_Annotation_mutable_path(google_protobuf_GeneratedCodeInfo_Annotation *msg, size_t *len) {
   return (int32_t*)_upb_array_mutable_accessor(msg, UPB_SIZE(20, 32), len);
 }
 UPB_INLINE int32_t* google_protobuf_GeneratedCodeInfo_Annotation_resize_path(google_protobuf_GeneratedCodeInfo_Annotation *msg, size_t len, upb_arena *arena) {
-  return (int32_t*)_upb_array_resize_accessor(msg, UPB_SIZE(20, 32), len, UPB_TYPE_INT32, arena);
+  return (int32_t*)_upb_array_resize_accessor2(msg, UPB_SIZE(20, 32), len, 2, arena);
 }
 UPB_INLINE bool google_protobuf_GeneratedCodeInfo_Annotation_add_path(google_protobuf_GeneratedCodeInfo_Annotation *msg, int32_t val, upb_arena *arena) {
-  return _upb_array_append_accessor(msg, UPB_SIZE(20, 32), UPB_SIZE(4, 4), UPB_TYPE_INT32, &val,
+  return _upb_array_append_accessor2(msg, UPB_SIZE(20, 32), 2, &val,
       arena);
 }
 UPB_INLINE void google_protobuf_GeneratedCodeInfo_Annotation_set_source_file(google_protobuf_GeneratedCodeInfo_Annotation *msg, upb_strview value) {
-  _upb_sethas(msg, 3);
+  _upb_sethas(msg, 1);
   *UPB_PTR_AT(msg, UPB_SIZE(12, 16), upb_strview) = value;
 }
 UPB_INLINE void google_protobuf_GeneratedCodeInfo_Annotation_set_begin(google_protobuf_GeneratedCodeInfo_Annotation *msg, int32_t value) {
-  _upb_sethas(msg, 1);
+  _upb_sethas(msg, 2);
   *UPB_PTR_AT(msg, UPB_SIZE(4, 4), int32_t) = value;
 }
 UPB_INLINE void google_protobuf_GeneratedCodeInfo_Annotation_set_end(google_protobuf_GeneratedCodeInfo_Annotation *msg, int32_t value) {
-  _upb_sethas(msg, 2);
+  _upb_sethas(msg, 3);
   *UPB_PTR_AT(msg, UPB_SIZE(8, 8), int32_t) = value;
 }
 
similarity index 91%
rename from third_party/upb/tools/make_cmakelists.py
rename to third_party/upb/cmake/make_cmakelists.py
index c31b413..035debb 100755 (executable)
@@ -46,9 +46,9 @@ class BuildFileFunctions(object):
     found_files = []
     for file in files:
         if os.path.isfile(file):
-            found_files.append(file)
-        elif os.path.isfile("generated_for_cmake/" + file):
-            found_files.append("generated_for_cmake/" + file)
+            found_files.append("../" + file)
+        elif os.path.isfile("cmake/" + file):
+            found_files.append("../cmake/" + file)
         else:
             print("Warning: no such file: " + file)
 
@@ -117,6 +117,9 @@ class BuildFileFunctions(object):
   def proto_library(self, **kwargs):
     pass
 
+  def cc_proto_library(self, **kwargs):
+    pass
+
   def generated_file_staleness_test(self, **kwargs):
     pass
 
@@ -126,6 +129,9 @@ class BuildFileFunctions(object):
   def upb_proto_library(self, **kwargs):
     pass
 
+  def upb_proto_library_copts(self, **kwargs):
+    pass
+
   def upb_proto_reflection_library(self, **kwargs):
     pass
 
@@ -138,6 +144,9 @@ class BuildFileFunctions(object):
   def config_setting(self, **kwargs):
     pass
 
+  def upb_fasttable_enabled(self, **kwargs):
+    pass
+
   def select(self, arg_dict):
     return []
 
@@ -163,6 +172,7 @@ class WorkspaceFileFunctions(object):
 
   def workspace(self, **kwargs):
     self.converter.prelude += "project(%s)\n" % (kwargs["name"])
+    self.converter.prelude += "set(CMAKE_C_STANDARD 99)\n"
 
   def http_archive(self, **kwargs):
     pass
@@ -170,6 +180,9 @@ class WorkspaceFileFunctions(object):
   def git_repository(self, **kwargs):
     pass
 
+  def new_git_repository(self, **kwargs):
+    pass
+
   def bazel_version_repository(self, **kwargs):
     pass
 
@@ -239,8 +252,8 @@ class Converter(object):
       set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -fsanitize=address")
     endif()
 
-    include_directories(.)
-    include_directories(generated_for_cmake)
+    include_directories(..)
+    include_directories(../cmake)
     include_directories(${CMAKE_CURRENT_BINARY_DIR})
 
     if(APPLE)
@@ -260,6 +273,7 @@ converter = Converter()
 
 def GetDict(obj):
   ret = {}
+  ret["UPB_DEFAULT_COPTS"] = []  # HACK
   for k in dir(obj):
     if not k.startswith("_"):
       ret[k] = getattr(obj, k);
@@ -269,6 +283,7 @@ globs = GetDict(converter)
 
 exec(open("WORKSPACE").read(), GetDict(WorkspaceFileFunctions(converter)))
 exec(open("BUILD").read(), GetDict(BuildFileFunctions(converter)))
+exec(open("third_party/wyhash/BUILD").read(), GetDict(BuildFileFunctions(converter)))
 
 with open(sys.argv[1], "w") as f:
   f.write(converter.convert())
similarity index 94%
rename from third_party/upb/tools/staleness_test.py
rename to third_party/upb/cmake/staleness_test.py
index 045cd1a..5857307 100644 (file)
@@ -6,7 +6,7 @@ with the actual list of files before we actually run the script.
 
 from __future__ import absolute_import
 
-from tools import staleness_test_lib
+from cmake import staleness_test_lib
 import unittest
 import sys
 
similarity index 93%
rename from third_party/upb/tools/staleness_test_lib.py
rename to third_party/upb/cmake/staleness_test_lib.py
index 6d5c3d3..cdfcc0d 100644 (file)
@@ -7,6 +7,7 @@ generated_file_staleness_test() rules.
 from __future__ import absolute_import
 from __future__ import print_function
 
+import sys
 import os
 from shutil import copyfile
 
@@ -47,13 +48,13 @@ def _GetFilePairs(config):
 
   ret = []
 
-  has_bazel_genfiles = os.path.exists("bazel-genfiles")
+  has_bazel_genfiles = os.path.exists("bazel-bin")
 
   for filename in config.file_list:
     target = os.path.join(config.package_name, filename)
     generated = os.path.join(config.package_name, config.pattern % filename)
     if has_bazel_genfiles:
-      generated = os.path.join("bazel-genfiles", generated)
+      generated = os.path.join("bazel-bin", generated)
 
     # Generated files should always exist.  Blaze should guarantee this before
     # we are run.
@@ -61,6 +62,7 @@ def _GetFilePairs(config):
       print("Generated file '%s' does not exist." % generated)
       print("Please run this command to generate it:")
       print("  bazel build %s:%s" % (config.package_name, config.target_name))
+      sys.exit(1)
     ret.append(_FilePair(target, generated))
 
   return ret
@@ -87,10 +89,9 @@ def _GetMissingAndStaleFiles(file_pairs):
       missing_files.append(pair)
       continue
 
-    generated = open(pair.generated).read()
-    target = open(pair.target).read()
-    if generated != target:
-      stale_files.append(pair)
+    with open(pair.generated) as g, open(pair.target) as t:
+      if g.read() != t.read():
+        stale_files.append(pair)
 
   return missing_files, stale_files
 
@@ -953,7 +953,7 @@ static bool parse_number_from_buffer(upb_json_parser *p, const char *buf,
   upb_fieldtype_t type = upb_fielddef_type(p->top->f);
   double val;
   double dummy;
-  double inf = UPB_INFINITY;
+  double inf = INFINITY;
 
   errno = 0;
 
@@ -3295,7 +3295,7 @@ static void json_parser_reset(upb_json_parser *p) {
 
 static upb_json_parsermethod *parsermethod_new(upb_json_codecache *c,
                                                const upb_msgdef *md) {
-  upb_msg_field_iter i;
+  int i, n;
   upb_alloc *alloc = upb_arena_alloc(c->arena);
 
   upb_json_parsermethod *m = upb_malloc(alloc, sizeof(*m));
@@ -3306,14 +3306,13 @@ static upb_json_parsermethod *parsermethod_new(upb_json_codecache *c,
   upb_byteshandler_setstring(&m->input_handler_, parse, m);
   upb_byteshandler_setendstr(&m->input_handler_, end, m);
 
-  upb_strtable_init2(&m->name_table, UPB_CTYPE_CONSTPTR, alloc);
+  upb_strtable_init2(&m->name_table, UPB_CTYPE_CONSTPTR, 4, alloc);
 
   /* Build name_table */
 
-  for(upb_msg_field_begin(&i, md);
-      !upb_msg_field_done(&i);
-      upb_msg_field_next(&i)) {
-    const upb_fielddef *f = upb_msg_iter_field(&i);
+  n = upb_msgdef_fieldcount(md);
+  for(i = 0; i < n; i++) {
+    const upb_fielddef *f = upb_msgdef_field(md, i);
     upb_value v = upb_value_constptr(f);
     const char *name;
 
@@ -3402,7 +3401,7 @@ const upb_json_parsermethod *upb_json_codecache_get(upb_json_codecache *c,
                                                     const upb_msgdef *md) {
   upb_json_parsermethod *m;
   upb_value v;
-  upb_msg_field_iter i;
+  int i, n;
   upb_alloc *alloc = upb_arena_alloc(c->arena);
 
   if (upb_inttable_lookupptr(&c->methods, md, &v)) {
@@ -3417,10 +3416,9 @@ const upb_json_parsermethod *upb_json_codecache_get(upb_json_codecache *c,
 
   /* Populate parser methods for all submessages, so the name tables will
    * be available during parsing. */
-  for(upb_msg_field_begin(&i, md);
-      !upb_msg_field_done(&i);
-      upb_msg_field_next(&i)) {
-    upb_fielddef *f = upb_msg_iter_field(&i);
+  n = upb_msgdef_fieldcount(md);
+  for(i = 0; i < n; i++) {
+    const upb_fielddef *f = upb_msgdef_field(md, i);
 
     if (upb_fielddef_issubmsg(f)) {
       const upb_msgdef *subdef = upb_fielddef_msgsubdef(f);
index 9fb5c1f..9711925 100644 (file)
@@ -1,6 +1,8 @@
 load("@rules_proto//proto:defs.bzl", "proto_library")
 load("@upb//bazel:upb_proto_library.bzl", "upb_proto_library")
 
+licenses(["notice"])
+
 proto_library(
     name = "foo_proto",
     srcs = ["foo.proto"],
@@ -14,5 +16,6 @@ upb_proto_library(
 cc_binary(
     name = "test_binary",
     srcs = ["test_binary.c"],
+    copts = ["-std=c99"],
     deps = [":foo_upbproto"],
 )
index 78f367a..98617cf 100644 (file)
@@ -1,7 +1,7 @@
 
 #include <time.h>
 
-#include "foo.upb.h"
+#include "examples/bazel/foo.upb.h"
 
 int main() {
   upb_arena *arena = upb_arena_new();
index 2174e8a..c95ee88 100644 (file)
@@ -11,29 +11,40 @@ fi
 echo PATH=$PATH
 ls -l `which cmake`
 cmake --version
-echo CC=${CC:-cc}
-${CC:-cc} --version
 
 # Log the bazel path and version.
 which bazel
 bazel version
 
 cd $(dirname $0)/../..
-bazel test --test_output=errors :all
 
-if [[ $(uname) = "Linux" ]]; then
-  # Verify the ASAN build.  Have to exclude test_conformance_upb as protobuf
-  # currently leaks memory in the conformance test runner.
-  bazel test --copt=-fsanitize=address --linkopt=-fsanitize=address --test_output=errors :all
+if which gcc; then
+  gcc --version
+  CC=gcc bazel test -c opt --test_output=errors ... -- -benchmarks:benchmark
+  if [[ $(uname) = "Linux" ]]; then
+    CC=gcc bazel test --test_output=errors ...
+    CC=gcc bazel test --test_output=errors ... --//:fasttable_enabled=true -- -cmake:test_generated_files -benchmarks:benchmark
+  fi
+  # TODO: work through these errors and enable this.
+  # if gcc -fanalyzer -x c /dev/null -c -o /dev/null; then
+  #   CC=gcc bazel test --copt=-fanalyzer --test_output=errors ...
+  # fi
+fi
 
-  # Verify the UBSan build. Have to exclude Lua as the version we are using
-  # fails some UBSan tests.
+if which clang; then
+  if [[ $(uname) = "Linux" ]]; then
+    CC=clang bazel test --test_output=errors ...
+    CC=clang bazel test --test_output=errors -c opt ... -- -benchmarks:benchmark
+    CC=clang bazel test --test_output=errors ... --//:fasttable_enabled=true -- -cmake:test_generated_files
 
-  # For some reason kokoro doesn't have Clang available right now.
-  #CC=clang CXX=clang++ bazel test -c dbg --copt=-fsanitize=undefined --copt=-fno-sanitize=function,vptr --linkopt=-fsanitize=undefined --action_env=UBSAN_OPTIONS=halt_on_error=1:print_stacktrace=1 -- :all -:test_lua
+    CC=clang bazel test --test_output=errors --config=m32 ... -- -benchmarks:benchmark
+    CC=clang bazel test --test_output=errors --config=asan ... -- -benchmarks:benchmark
 
+    # TODO: update to a newer Lua that hopefully does not trigger UBSAN.
+    CC=clang bazel test --test_output=errors --config=ubsan ... -- -tests/bindings/lua:test_lua
+  fi
 fi
 
 if which valgrind; then
-  bazel test --run_under='valgrind --leak-check=full --error-exitcode=1' :all -- -:test_conformance_upb -:cmake_build
+  bazel test --config=valgrind ... -- -tests:test_conformance_upb -cmake:cmake_build
 fi
index fa97583..0a7f20c 100644 (file)
@@ -1,2 +1,2 @@
 build_file: "upb/kokoro/ubuntu/build.sh"
-timeout_mins: 15
+timeout_mins: 30
diff --git a/third_party/upb/tests/BUILD b/third_party/upb/tests/BUILD
new file mode 100644 (file)
index 0000000..ad12fce
--- /dev/null
@@ -0,0 +1,283 @@
+load(
+    "//bazel:build_defs.bzl",
+    "UPB_DEFAULT_COPTS",
+    "UPB_DEFAULT_CPPOPTS",
+    "make_shell_script",
+)
+load(
+    "//bazel:upb_proto_library.bzl",
+    "upb_proto_library",
+    "upb_proto_reflection_library",
+)
+
+licenses(["notice"])
+
+config_setting(
+    name = "fuzz",
+    values = {"define": "fuzz=true"},
+)
+
+cc_library(
+    name = "upb_test",
+    testonly = 1,
+    srcs = [
+        "testmain.cc",
+    ],
+    hdrs = [
+        "test_util.h",
+        "upb_test.h",
+    ],
+    copts = UPB_DEFAULT_CPPOPTS,
+    deps = [
+        "//:handlers",
+        "//:port",
+        "//:upb",
+    ],
+)
+
+proto_library(
+    name = "test_proto",
+    testonly = 1,
+    srcs = ["test.proto"],
+)
+
+upb_proto_library(
+    name = "test_upb_proto",
+    testonly = 1,
+    deps = [":test_proto"],
+)
+
+cc_test(
+    name = "test_generated_code",
+    srcs = ["test_generated_code.c"],
+    copts = UPB_DEFAULT_COPTS,
+    deps = [
+        ":empty_upbdefs_proto",
+        ":test_messages_proto3_proto_upb",
+        ":test_upb_proto",
+        ":upb_test",
+    ],
+)
+
+proto_library(
+    name = "empty_proto",
+    srcs = ["empty.proto"],
+)
+
+upb_proto_reflection_library(
+    name = "empty_upbdefs_proto",
+    testonly = 1,
+    deps = [":empty_proto"],
+)
+
+upb_proto_library(
+    name = "test_messages_proto3_proto_upb",
+    testonly = 1,
+    deps = ["@com_google_protobuf//:test_messages_proto3_proto"],
+)
+
+proto_library(
+    name = "test_decoder_proto",
+    srcs = [
+        "pb/test_decoder.proto",
+    ],
+)
+
+upb_proto_reflection_library(
+    name = "test_decoder_upb_proto",
+    deps = [":test_decoder_proto"],
+)
+
+cc_test(
+    name = "test_decoder",
+    srcs = ["pb/test_decoder.cc"],
+    copts = UPB_DEFAULT_CPPOPTS,
+    deps = [
+        ":test_decoder_upb_proto",
+        ":upb_test",
+        "//:handlers",
+        "//:port",
+        "//:upb",
+        "//:upb_pb",
+    ],
+)
+
+proto_library(
+    name = "test_cpp_proto",
+    srcs = [
+        "test_cpp.proto",
+    ],
+)
+
+upb_proto_reflection_library(
+    name = "test_cpp_upb_proto",
+    deps = ["test_cpp_proto"],
+)
+
+cc_test(
+    name = "test_cpp",
+    srcs = ["test_cpp.cc"],
+    copts = UPB_DEFAULT_CPPOPTS,
+    deps = [
+        ":test_cpp_upb_proto",
+        ":upb_test",
+        "//:handlers",
+        "//:port",
+        "//:reflection",
+        "//:upb",
+        "//:upb_pb",
+    ],
+)
+
+cc_test(
+    name = "test_table",
+    srcs = ["test_table.cc"],
+    copts = UPB_DEFAULT_CPPOPTS,
+    deps = [
+        ":upb_test",
+        "//:port",
+        "//:table",
+        "//:upb",
+    ],
+)
+
+# OSS-Fuzz test
+cc_binary(
+    name = "file_descriptor_parsenew_fuzzer",
+    testonly = 1,
+    srcs = ["file_descriptor_parsenew_fuzzer.cc"],
+    copts = UPB_DEFAULT_CPPOPTS + select({
+        "//conditions:default": [],
+        ":fuzz": ["-fsanitize=fuzzer,address"],
+    }),
+    defines = select({
+        "//conditions:default": [],
+        ":fuzz": ["HAVE_FUZZER"],
+    }),
+    deps = [
+        "//:descriptor_upb_proto",
+        "//:upb",
+    ],
+)
+
+# copybara:strip_for_google3_begin
+cc_test(
+    name = "test_encoder",
+    srcs = ["pb/test_encoder.cc"],
+    copts = UPB_DEFAULT_CPPOPTS,
+    deps = [
+        ":upb_test",
+        "//:descriptor_upb_proto",
+        "//:descriptor_upb_proto_reflection",
+        "//:upb",
+        "//:upb_pb",
+    ],
+)
+
+proto_library(
+    name = "test_json_enum_from_separate",
+    srcs = ["json/enum_from_separate_file.proto"],
+    deps = [":test_json_proto"],
+)
+
+proto_library(
+    name = "test_json_proto",
+    srcs = ["json/test.proto"],
+)
+
+upb_proto_reflection_library(
+    name = "test_json_upb_proto_reflection",
+    deps = ["test_json_proto"],
+)
+
+upb_proto_library(
+    name = "test_json_enum_from_separate_upb_proto",
+    deps = [":test_json_enum_from_separate"],
+)
+
+upb_proto_library(
+    name = "test_json_upb_proto",
+    deps = [":test_json_proto"],
+)
+
+cc_test(
+    name = "test_json",
+    srcs = [
+        "json/test_json.cc",
+    ],
+    copts = UPB_DEFAULT_CPPOPTS,
+    deps = [
+        ":test_json_upb_proto",
+        ":test_json_upb_proto_reflection",
+        ":upb_test",
+        "//:upb_json",
+    ],
+)
+# copybara:strip_end
+
+upb_proto_library(
+    name = "conformance_proto_upb",
+    testonly = 1,
+    deps = ["@com_google_protobuf//:conformance_proto"],
+)
+
+upb_proto_reflection_library(
+    name = "conformance_proto_upbdefs",
+    testonly = 1,
+    deps = ["@com_google_protobuf//:conformance_proto"],
+)
+
+upb_proto_reflection_library(
+    name = "test_messages_proto2_upbdefs",
+    testonly = 1,
+    deps = ["@com_google_protobuf//:test_messages_proto2_proto"],
+)
+
+upb_proto_reflection_library(
+    name = "test_messages_proto3_upbdefs",
+    testonly = 1,
+    deps = ["@com_google_protobuf//:test_messages_proto3_proto"],
+)
+
+cc_binary(
+    name = "conformance_upb",
+    testonly = 1,
+    srcs = [
+        "conformance_upb.c",
+    ],
+    copts = UPB_DEFAULT_COPTS,
+    data = [
+        "conformance_upb_failures.txt",
+    ],
+    deps = [
+        ":conformance_proto_upb",
+        ":conformance_proto_upbdefs",
+        ":test_messages_proto2_upbdefs",
+        ":test_messages_proto3_upbdefs",
+        "//:json",
+        "//:port",
+        "//:reflection",
+        "//:textformat",
+        "//:upb",
+    ],
+)
+
+make_shell_script(
+    name = "gen_test_conformance_upb",
+    out = "test_conformance_upb.sh",
+    contents = "external/com_google_protobuf/conformance_test_runner " +
+               " --enforce_recommended " +
+               " --failure_list ./tests/conformance_upb_failures.txt" +
+               " ./tests/conformance_upb",
+)
+
+sh_test(
+    name = "test_conformance_upb",
+    srcs = ["test_conformance_upb.sh"],
+    data = [
+        "conformance_upb_failures.txt",
+        ":conformance_upb",
+        "@com_google_protobuf//:conformance_test_runner",
+    ],
+    deps = ["@bazel_tools//tools/bash/runfiles"],
+)
diff --git a/third_party/upb/tests/benchmark.cc b/third_party/upb/tests/benchmark.cc
deleted file mode 100644 (file)
index c1d6e06..0000000
+++ /dev/null
@@ -1,64 +0,0 @@
-
-#include <string.h>
-#include <benchmark/benchmark.h>
-#include "google/protobuf/descriptor.upb.h"
-#include "google/protobuf/descriptor.upbdefs.h"
-
-upb_strview descriptor = google_protobuf_descriptor_proto_upbdefinit.descriptor;
-
-/* A buffer big enough to parse descriptor.proto without going to heap. */
-char buf[65535];
-
-static void BM_ArenaOneAlloc(benchmark::State& state) {
-  for (auto _ : state) {
-    upb_arena* arena = upb_arena_new();
-    upb_arena_malloc(arena, 1);
-    upb_arena_free(arena);
-  }
-}
-BENCHMARK(BM_ArenaOneAlloc);
-
-static void BM_ArenaInitialBlockOneAlloc(benchmark::State& state) {
-  for (auto _ : state) {
-    upb_arena* arena = upb_arena_init(buf, sizeof(buf), NULL);
-    upb_arena_malloc(arena, 1);
-    upb_arena_free(arena);
-  }
-}
-BENCHMARK(BM_ArenaInitialBlockOneAlloc);
-
-static void BM_ParseDescriptorNoHeap(benchmark::State& state) {
-  size_t bytes = 0;
-  for (auto _ : state) {
-    upb_arena* arena = upb_arena_init(buf, sizeof(buf), NULL);
-    google_protobuf_FileDescriptorProto* set =
-        google_protobuf_FileDescriptorProto_parse(descriptor.data,
-                                                descriptor.size, arena);
-    if (!set) {
-      printf("Failed to parse.\n");
-      exit(1);
-    }
-    bytes += descriptor.size;
-    upb_arena_free(arena);
-  }
-  state.SetBytesProcessed(state.iterations() * descriptor.size);
-}
-BENCHMARK(BM_ParseDescriptorNoHeap);
-
-static void BM_ParseDescriptor(benchmark::State& state) {
-  size_t bytes = 0;
-  for (auto _ : state) {
-    upb_arena* arena = upb_arena_new();
-    google_protobuf_FileDescriptorProto* set =
-        google_protobuf_FileDescriptorProto_parse(descriptor.data,
-                                                descriptor.size, arena);
-    if (!set) {
-      printf("Failed to parse.\n");
-      exit(1);
-    }
-    bytes += descriptor.size;
-    upb_arena_free(arena);
-  }
-  state.SetBytesProcessed(state.iterations() * descriptor.size);
-}
-BENCHMARK(BM_ParseDescriptor);
diff --git a/third_party/upb/tests/bindings/lua/BUILD b/third_party/upb/tests/bindings/lua/BUILD
new file mode 100644 (file)
index 0000000..a065b1d
--- /dev/null
@@ -0,0 +1,68 @@
+load(
+    "//upb/bindings/lua:lua_proto_library.bzl",
+    "lua_proto_library",
+)
+load(
+    "//bazel:build_defs.bzl",
+    "UPB_DEFAULT_COPTS",
+)
+
+licenses(["notice"])
+
+cc_test(
+    name = "test_lua",
+    srcs = ["main.c"],
+    copts = UPB_DEFAULT_COPTS,
+    data = [
+        "test_upb.lua",
+        ":descriptor_proto_lua",
+        ":empty_proto_lua",
+        ":test_messages_proto2_proto_lua",
+        ":test_messages_proto3_proto_lua",
+        ":test_proto_lua",
+        "//:third_party/lunit/console.lua",
+        "//:third_party/lunit/lunit.lua",
+        "//upb/bindings/lua:upb.lua",
+        "@com_google_protobuf//:conformance_proto",
+        "@com_google_protobuf//:descriptor_proto",
+    ],
+    linkstatic = 1,
+    deps = [
+        "//upb/bindings/lua:lupb",
+        "@lua//:liblua",
+    ],
+)
+
+proto_library(
+    name = "test_proto",
+    testonly = 1,
+    srcs = ["test.proto"],
+)
+
+lua_proto_library(
+    name = "test_proto_lua",
+    testonly = 1,
+    deps = [":test_proto"],
+)
+
+lua_proto_library(
+    name = "descriptor_proto_lua",
+    deps = ["@com_google_protobuf//:descriptor_proto"],
+)
+
+lua_proto_library(
+    name = "empty_proto_lua",
+    deps = ["@com_google_protobuf//:empty_proto"],
+)
+
+lua_proto_library(
+    name = "test_messages_proto3_proto_lua",
+    testonly = 1,
+    deps = ["@com_google_protobuf//:test_messages_proto3_proto"],
+)
+
+lua_proto_library(
+    name = "test_messages_proto2_proto_lua",
+    testonly = 1,
+    deps = ["@com_google_protobuf//:test_messages_proto2_proto"],
+)
index f3714b5..6e48cca 100644 (file)
@@ -34,7 +34,7 @@ const char *init =
     "upb/bindings/lua/?.lua"
   "'";
 
-int main() {
+int main(int argc, char **argv) {
   int ret = 0;
   L = luaL_newstate();
   luaL_openlibs(L);
diff --git a/third_party/upb/tests/bindings/lua/test.proto b/third_party/upb/tests/bindings/lua/test.proto
new file mode 100644 (file)
index 0000000..6b45350
--- /dev/null
@@ -0,0 +1,28 @@
+
+syntax = "proto2";
+
+package upb_test;
+
+message MapTest {
+  map<string, double> map_string_double = 1;
+}
+
+message PackedTest {
+  repeated bool bool_packed = 1 [packed = true];
+  repeated int32 i32_packed = 2 [packed = true];
+  repeated int64 i64_packed = 3 [packed = true];
+  repeated fixed32 f32_packed = 4 [packed = true];
+  repeated fixed64 f64_packed = 5 [packed = true];
+}
+
+message UnpackedTest {
+  repeated bool bool_packed = 1 [packed = false];
+  repeated int32 i32_packed = 2 [packed = false];
+  repeated int64 i64_packed = 3 [packed = false];
+  repeated fixed32 f32_packed = 4 [packed = false];
+  repeated fixed64 f64_packed = 5 [packed = false];
+}
+
+message TestLargeFieldNumber {
+  optional int32 i32 = 456214797;
+}
index 4586b34..e2d5345 100644 (file)
@@ -1,10 +1,11 @@
 
 local upb = require "lupb"
 local lunit = require "lunit"
-local upb_test = require "tests.test_pb"
+local upb_test = require "tests.bindings.lua.test_pb"
 local test_messages_proto3 = require "google.protobuf.test_messages_proto3_pb"
 local test_messages_proto2 = require "google.protobuf.test_messages_proto2_pb"
 local descriptor = require "google.protobuf.descriptor_pb"
+local empty = require "google.protobuf.empty_pb"
 
 if _VERSION >= 'Lua 5.2' then
   _ENV = lunit.module("testupb", "seeall")
@@ -37,6 +38,27 @@ function test_def_readers()
   assert_nil(f:containing_oneof())
   assert_equal(m, f:containing_type())
   assert_equal(0, f:default())
+  local message_field_count = 0
+  for field in m:fields() do
+    message_field_count = message_field_count + 1
+  end
+  assert_equal(message_field_count, #m)
+
+  local message_oneof_count = 0
+  for oneof in m:oneofs() do
+    message_oneof_count = message_oneof_count + 1
+  end
+  assert_equal(message_oneof_count, m:oneof_count())
+
+  -- oneof
+  local o = m:lookup_name("oneof_field")
+  assert_equal("oneof_field", o:name())
+  assert_equal(m, o:containing_type())
+  local oneof_field_count = 0
+  for field in o:fields() do
+    oneof_field_count = oneof_field_count + 1
+  end
+  assert_equal(oneof_field_count, #o)
 
   -- enum
   local e = test_messages_proto3['TestAllTypesProto3.NestedEnum']
@@ -70,6 +92,69 @@ function test_msg_map()
   assert_equal(12, msg2.map_int32_int32[6])
 end
 
+function test_map_sorting()
+  function msg_with_int32_entries(start, expand)
+    local msg = test_messages_proto3.TestAllTypesProto3()
+    for i=start,start + 8 do
+      msg.map_int32_int32[i] = i * 2
+    end
+
+    if expand then
+      for i=start+20,200 do
+        msg.map_int32_int32[i] = i
+      end
+      for i=start+20,200 do
+        msg.map_int32_int32[i] = nil
+      end
+    end
+    return msg
+  end
+
+  function msg_with_msg_entries(expand)
+    local msg = test_messages_proto3.TestAllTypesProto3()
+    -- 8! = 40320 possible orderings makes it overwhelmingly likely that two
+    -- random orderings will be different.
+    for i=1,8 do
+      local submsg = test_messages_proto3.TestAllTypesProto3.NestedMessage()
+      submsg.corecursive = msg_with_int32_entries(i, expand)
+      msg.map_string_nested_message[tostring(i)] = submsg
+    end
+
+    expand = false
+    if expand then
+      for i=21,2000 do
+        local submsg = test_messages_proto3.TestAllTypesProto3.NestedMessage()
+        submsg.corecursive = msg_with_int32_entries(i, expand)
+        msg.map_string_nested_message[tostring(i)] = submsg
+      end
+      for i=21,2000 do
+        msg.map_string_nested_message[tostring(i)] = nil
+      end
+    end
+    return msg
+  end
+
+  -- Create two messages with the same contents but (hopefully) different
+  -- map table orderings.
+  local msg = msg_with_msg_entries(false)
+  local msg2 = msg_with_msg_entries(true)
+
+  local text1 = upb.text_encode(msg)
+  local text2 = upb.text_encode(msg2)
+  assert_equal(text1, text2)
+
+  local binary1 = upb.encode(msg, {upb.ENCODE_DETERMINISTIC})
+  local binary2 = upb.encode(msg2, {upb.ENCODE_DETERMINISTIC})
+  assert_equal(binary1, binary2)
+
+  -- Non-sorted map should compare different.
+  local text3 = upb.text_encode(msg, {upb.TXTENC_NOSORT})
+  assert_not_equal(text1, text3)
+
+  local binary3 = upb.encode(msg)
+  assert_not_equal(binary1, binary3)
+end
+
 function test_utf8()
   local proto2_msg = test_messages_proto2.TestAllTypesProto2()
   proto2_msg.optional_string = "\xff"
@@ -83,7 +168,7 @@ function test_utf8()
     upb.decode(test_messages_proto3.TestAllTypesProto3, serialized)
   end)
 
-  -- TOOD(haberman): should proto3 accessors also check UTF-8 at set time?
+  -- TODO(haberman): should proto3 accessors also check UTF-8 at set time?
 end
 
 function test_string_double_map()
@@ -112,6 +197,65 @@ function test_string_double_map()
   assert_equal(2.5, msg2.map_string_double["two point five"])
 end
 
+function test_string_double_map()
+  local function fill_msg(msg)
+    msg.i32_packed[1] = 100
+    msg.i32_packed[2] = 200
+    msg.i32_packed[3] = 50000
+
+    msg.i64_packed[1] = 101
+    msg.i64_packed[2] = 201
+    msg.i64_packed[3] = 50001
+
+    msg.f32_packed[1] = 102
+    msg.f32_packed[2] = 202
+    msg.f32_packed[3] = 50002
+
+    msg.f64_packed[1] = 103
+    msg.f64_packed[2] = 203
+    msg.f64_packed[3] = 50003
+  end
+
+  local function check_msg(msg)
+    assert_equal(100, msg.i32_packed[1])
+    assert_equal(200, msg.i32_packed[2])
+    assert_equal(50000, msg.i32_packed[3])
+    assert_equal(3, #msg.i32_packed)
+
+    assert_equal(101, msg.i64_packed[1])
+    assert_equal(201, msg.i64_packed[2])
+    assert_equal(50001, msg.i64_packed[3])
+    assert_equal(3, #msg.i64_packed)
+
+    assert_equal(102, msg.f32_packed[1])
+    assert_equal(202, msg.f32_packed[2])
+    assert_equal(50002, msg.f32_packed[3])
+    assert_equal(3, #msg.f32_packed)
+
+    assert_equal(103, msg.f64_packed[1])
+    assert_equal(203, msg.f64_packed[2])
+    assert_equal(50003, msg.f64_packed[3])
+    assert_equal(3, #msg.f64_packed)
+  end
+
+  local msg = upb_test.PackedTest()
+  fill_msg(msg)
+  check_msg(msg)
+
+  local serialized_packed = upb.encode(msg)
+  local msg2 = upb.decode(upb_test.PackedTest, serialized_packed)
+  local msg3 = upb.decode(upb_test.UnpackedTest, serialized_packed)
+  check_msg(msg2)
+  check_msg(msg3)
+
+  serialized_unpacked = upb.encode(msg3)
+  local msg4 = upb.decode(upb_test.PackedTest, serialized_unpacked)
+  local msg5 = upb.decode(upb_test.PackedTest, serialized_unpacked)
+  check_msg(msg4)
+  check_msg(msg5)
+
+end
+
 function test_msg_string_map()
   msg = test_messages_proto3.TestAllTypesProto3()
   msg.map_string_string["foo"] = "bar"
@@ -276,6 +420,22 @@ local numeric_types = {
   },
 }
 
+function test_utf8()
+  local invalid_utf8 = "\xff"
+  local proto2_msg = test_messages_proto2.TestAllTypesProto2{
+    optional_string = invalid_utf8,
+  }
+
+  -- As proto2, invalid UTF-8 parses and serializes fine.
+  local serialized = upb.encode(proto2_msg)
+  local proto2_msg2 = upb.decode(test_messages_proto2.TestAllTypesProto2, serialized)
+
+  -- Decoding as proto3 fails.
+  assert_error(function()
+    upb.decode(test_messages_proto3.TestAllTypesProto3, serialized)
+  end)
+end
+
 function test_msg_primitives()
   local msg = test_messages_proto3.TestAllTypesProto3{
     optional_int32 = 10,
@@ -460,6 +620,13 @@ function test_numeric_map()
   end
 end
 
+function test_unknown()
+  local bytes = string.rep("\x38\x00", 1000)
+  for i=1,1000 do
+    local msg = upb.decode(test_messages_proto3.TestAllTypesProto3, bytes)
+  end
+end
+
 function test_foo()
   local symtab = upb.SymbolTable()
   local filename = "external/com_google_protobuf/descriptor_proto-descriptor-set.proto.bin"
@@ -484,6 +651,69 @@ function test_foo()
   assert_equal(set.file[1].name, "google/protobuf/descriptor.proto")
 end
 
+function test_descriptor()
+  local symtab = upb.SymbolTable()
+  local file_proto = descriptor.FileDescriptorProto {
+    name = "test.proto",
+    message_type = upb.Array(descriptor.DescriptorProto, {
+      descriptor.DescriptorProto{
+        name = "ABC",
+      },
+    })
+  }
+  local file = symtab:add_file(upb.encode(file_proto))
+  assert_equal(file:symtab(), symtab)
+end
+
+function test_descriptor_error()
+  local symtab = upb.SymbolTable()
+  local file = descriptor.FileDescriptorProto()
+  file.name = "test.proto"
+  file.message_type[1] = descriptor.DescriptorProto{
+    name = "ABC"
+  }
+  file.message_type[2] = descriptor.DescriptorProto{
+    name = "BC."
+  }
+  assert_error(function () symtab:add_file(upb.encode(file)) end)
+  assert_nil(symtab:lookup_msg("ABC"))
+end
+
+function test_encode_skipunknown()
+  -- Test that upb.ENCODE_SKIPUNKNOWN does not encode unknown fields.
+  local msg = test_messages_proto3.TestAllTypesProto3{
+    optional_int32 = 10,
+    optional_uint32 = 20,
+    optional_int64 = 30,
+  }
+  -- SKIPUNKNOWN here tests that it does *not* affect regular fields.
+  local serialized = upb.encode(msg, {upb.ENCODE_SKIPUNKNOWN})
+  assert_true(#serialized > 0)
+  local empty_with_unknown = upb.decode(empty.Empty, serialized)
+  assert_true(#upb.encode(empty_with_unknown) > 0)
+  -- Verify that unknown fields are not serialized.
+  assert_true(#upb.encode(empty_with_unknown, {upb.ENCODE_SKIPUNKNOWN}) == 0)
+end
+
+function test_json_emit_defaults()
+  local msg = test_messages_proto3.TestAllTypesProto3()
+  local json = upb.json_encode(msg, {upb.JSONENC_EMITDEFAULTS})
+end
+
+function test_encode_depth_limit()
+  local msg = test_messages_proto3.TestAllTypesProto3()
+  msg.recursive_message = msg
+  assert_error(function() upb.encode(msg) end)
+end
+
+function test_large_field_number()
+  local msg = upb_test.TestLargeFieldNumber()
+  msg.i32 = 5
+  local serialized = upb.encode(msg)
+  local msg2 = upb.decode(upb_test.TestLargeFieldNumber, serialized)
+  assert_equal(msg.i32, msg2.i32)
+end
+
 function test_gc()
   local top = test_messages_proto3.TestAllTypesProto3()
   local n = 100
index fe9f522..f444180 100644 (file)
@@ -201,6 +201,16 @@ void DoTest(const ctx* c) {
   upb_msg *msg;
   upb_strview name = conformance_ConformanceRequest_message_type(c->request);
   const upb_msgdef *m = upb_symtab_lookupmsg2(c->symtab, name.data, name.size);
+#if 0
+  // Handy code for limiting conformance tests to a single input payload.
+  // This is a hack since the conformance runner doesn't give an easy way to
+  // specify what test should be run.
+  const char skip[] = "\343>\010\301\002\344>\230?\001\230?\002\230?\003";
+  upb_strview skip_str = upb_strview_make(skip, sizeof(skip) - 1);
+  upb_strview pb_payload =
+      conformance_ConformanceRequest_protobuf_payload(c->request);
+  if (!upb_strview_eql(pb_payload, skip_str)) m = NULL;
+#endif
 
   if (!m) {
     static const char msg[] = "Unknown message type.";
@@ -286,6 +296,7 @@ int main(void) {
     if (!DoTestIo(symtab)) {
       fprintf(stderr, "conformance_upb: received EOF from test runner "
                       "after %d tests, exiting\n", test_count);
+      upb_symtab_free(symtab);
       return 0;
     }
   }
index 14fd72a..110dd2f 100644 (file)
@@ -43,7 +43,6 @@
 #else  // AMALGAMATED
 #include "upb/handlers.h"
 #include "upb/pb/decoder.h"
-#include "upb/pb/varint.int.h"
 #include "upb/upb.h"
 #endif  // !AMALGAMATED
 
 #define PRINT_FAILURE(expr)                                           \
   fprintf(stderr, "Assertion failed: %s:%d\n", __FILE__, __LINE__);   \
   fprintf(stderr, "expr: %s\n", #expr);                               \
-  if (testhash) {                                                     \
-    fprintf(stderr, "assertion failed running test %x.\n", testhash); \
-    if (!filter_hash) {                                               \
-      fprintf(stderr,                                                 \
-              "Run with the arg %x to run only this test. "           \
-              "(This will also turn on extra debugging output)\n",    \
-              testhash);                                              \
-    }                                                                 \
-    fprintf(stderr, "Failed at %02.2f%% through tests.\n",            \
-            (float)completed * 100 / total);                          \
-  }
 
 #define MAX_NESTING 64
 
@@ -114,7 +102,7 @@ using std::string;
 
 void vappendf(string* str, const char *format, va_list args) {
   va_list copy;
-  _upb_va_copy(copy, args);
+  va_copy(copy, args);
 
   int count = vsnprintf(NULL, 0, format, args);
   if (count >= 0)
@@ -147,6 +135,29 @@ void PrintBinary(const string& str) {
   }
 }
 
+#define UPB_PB_VARINT_MAX_LEN 10
+
+static size_t upb_vencode64(uint64_t val, char *buf) {
+  size_t i;
+  if (val == 0) { buf[0] = 0; return 1; }
+  i = 0;
+  while (val) {
+    uint8_t byte = val & 0x7fU;
+    val >>= 7;
+    if (val) byte |= 0x80U;
+    buf[i++] = byte;
+  }
+  return i;
+}
+
+static uint32_t upb_zzenc_32(int32_t n) {
+  return ((uint32_t)n << 1) ^ (n >> 31);
+}
+
+static uint64_t upb_zzenc_64(int64_t n) {
+  return ((uint64_t)n << 1) ^ (n >> 63);
+}
+
 /* Routines for building arbitrary protos *************************************/
 
 const string empty;
@@ -445,17 +456,6 @@ upb::pb::DecoderPtr CreateDecoder(upb::Arena* arena,
   return ret;
 }
 
-uint32_t Hash(const string& proto, const string* expected_output, size_t seam1,
-              size_t seam2, bool may_skip) {
-  uint32_t hash = upb_murmur_hash2(proto.c_str(), proto.size(), 0);
-  if (expected_output)
-    hash = upb_murmur_hash2(expected_output->c_str(), expected_output->size(), hash);
-  hash = upb_murmur_hash2(&seam1, sizeof(seam1), hash);
-  hash = upb_murmur_hash2(&seam2, sizeof(seam2), hash);
-  hash = upb_murmur_hash2(&may_skip, sizeof(may_skip), hash);
-  return hash;
-}
-
 void CheckBytesParsed(upb::pb::DecoderPtr decoder, size_t ofs) {
   // We can't have parsed more data than the decoder callback is telling us it
   // parsed.
@@ -484,13 +484,11 @@ void do_run_decoder(VerboseParserEnvironment* env, upb::pb::DecoderPtr decoder,
   env->Reset(proto.c_str(), proto.size(), may_skip, expected_output == NULL);
   decoder.Reset();
 
-  testhash = Hash(proto, expected_output, i, j, may_skip);
-  if (filter_hash && testhash != filter_hash) return;
   if (test_mode != COUNT_ONLY) {
     output.clear();
 
     if (filter_hash) {
-      fprintf(stderr, "RUNNING TEST CASE, hash=%x\n", testhash);
+      fprintf(stderr, "RUNNING TEST CASE\n");
       fprintf(stderr, "Input (len=%u): ", (unsigned)proto.size());
       PrintBinary(proto);
       fprintf(stderr, "\n");
@@ -549,7 +547,6 @@ void run_decoder(const string& proto, const string* expected_output) {
       }
     }
   }
-  testhash = 0;
 }
 
 const static string thirty_byte_nop = cat(
@@ -849,23 +846,17 @@ void test_valid() {
   // Empty protobuf where we never call PutString between
   // StartString/EndString.
 
-  // Randomly generated hash for this test, hope it doesn't conflict with others
-  // by chance.
-  const uint32_t emptyhash = 0x5709be8e;
-  if (!filter_hash || filter_hash == testhash) {
-    testhash = emptyhash;
-    upb::Status status;
-    upb::Arena arena;
-    upb::Sink sink(global_handlers, &closures[0]);
-    upb::pb::DecoderPtr decoder =
-        CreateDecoder(&arena, global_method, sink, &status);
-    output.clear();
-    bool ok = upb::PutBuffer(std::string(), decoder.input());
-    ASSERT(ok);
-    ASSERT(status.ok());
-    if (test_mode == ALL_HANDLERS) {
-      ASSERT(output == string("<\n>\n"));
-    }
+  upb::Status status;
+  upb::Arena arena;
+  upb::Sink sink(global_handlers, &closures[0]);
+  upb::pb::DecoderPtr decoder =
+      CreateDecoder(&arena, global_method, sink, &status);
+  output.clear();
+  bool ok = upb::PutBuffer(std::string(), decoder.input());
+  ASSERT(ok);
+  ASSERT(status.ok());
+  if (test_mode == ALL_HANDLERS) {
+    ASSERT(output == string("<\n>\n"));
   }
 
   test_valid_data_for_signed_type(UPB_DESCRIPTOR_TYPE_DOUBLE,
index aeca1b3..b358ef5 100644 (file)
@@ -5,12 +5,65 @@
 #include "google/protobuf/descriptor.upbdefs.h"
 #include "tests/test_util.h"
 #include "tests/upb_test.h"
-#include "upb/bindings/stdc++/string.h"
 #include "upb/pb/decoder.h"
 #include "upb/pb/encoder.h"
 #include "upb/port_def.inc"
 #include "upb/upb.hpp"
 
+template <class T>
+class FillStringHandler {
+ public:
+  static void SetHandler(upb_byteshandler* handler) {
+    upb_byteshandler_setstartstr(handler, &FillStringHandler::StartString,
+                                 NULL);
+    upb_byteshandler_setstring(handler, &FillStringHandler::StringBuf, NULL);
+  }
+
+ private:
+  // TODO(haberman): add UpbBind/UpbMakeHandler support to BytesHandler so these
+  // can be prettier callbacks.
+  static void* StartString(void *c, const void *hd, size_t size) {
+    UPB_UNUSED(hd);
+    UPB_UNUSED(size);
+
+    T* str = static_cast<T*>(c);
+    str->clear();
+    return c;
+  }
+
+  static size_t StringBuf(void* c, const void* hd, const char* buf, size_t n,
+                          const upb_bufhandle* h) {
+    UPB_UNUSED(hd);
+    UPB_UNUSED(h);
+
+    T* str = static_cast<T*>(c);
+    try {
+      str->append(buf, n);
+      return n;
+    } catch (const std::exception&) {
+      return 0;
+    }
+  }
+};
+
+class StringSink {
+ public:
+  template <class T>
+  explicit StringSink(T* target) {
+    // TODO(haberman): we need to avoid rebuilding a new handler every time,
+    // but with class globals disallowed for google3 C++ this is tricky.
+    upb_byteshandler_init(&handler_);
+    FillStringHandler<T>::SetHandler(&handler_);
+    input_.Reset(&handler_, target);
+  }
+
+  upb::BytesSink input() { return input_; }
+
+ private:
+  upb_byteshandler handler_;
+  upb::BytesSink input_;
+};
+
 void test_pb_roundtrip() {
   std::string input(
       google_protobuf_descriptor_proto_upbdefinit.descriptor.data,
@@ -29,7 +82,7 @@ void test_pb_roundtrip() {
   const upb::pb::DecoderMethodPtr method = decoder_cache.Get(md);
 
   std::string output;
-  upb::StringSink string_sink(&output);
+  StringSink string_sink(&output);
   upb::pb::EncoderPtr encoder =
       upb::pb::EncoderPtr::Create(&arena, encoder_handlers, string_sink.input());
   upb::pb::DecoderPtr decoder =
diff --git a/third_party/upb/tests/pb/test_varint.c b/third_party/upb/tests/pb/test_varint.c
deleted file mode 100644 (file)
index 45d8e47..0000000
+++ /dev/null
@@ -1,126 +0,0 @@
-
-#include <stdio.h>
-#include "upb/pb/varint.int.h"
-#include "tests/upb_test.h"
-
-#include "upb/port_def.inc"
-
-/* Test that we can round-trip from int->varint->int. */
-static void test_varint_for_num(upb_decoderet (*decoder)(const char*),
-                                uint64_t num) {
-  char buf[16];
-  size_t bytes;
-  upb_decoderet r;
-
-  memset(buf, 0xff, sizeof(buf));
-  bytes = upb_vencode64(num, buf);
-
-  if (num <= UINT32_MAX) {
-    uint64_t encoded = upb_vencode32((uint32_t)num);
-    char buf2[16];
-    upb_decoderet r;
-
-    memset(buf2, 0, sizeof(buf2));
-    memcpy(&buf2, &encoded, 8);
-#ifdef UPB_BIG_ENDIAN
-    char swap[8];
-    swap[0] = buf2[7];
-    swap[1] = buf2[6];
-    swap[2] = buf2[5];
-    swap[3] = buf2[4];
-    swap[4] = buf2[3];
-    swap[5] = buf2[2];
-    swap[6] = buf2[1];
-    swap[7] = buf2[0];
-    buf2[0] = swap[0];
-    buf2[1] = swap[1];
-    buf2[2] = swap[2];
-    buf2[3] = swap[3];
-    buf2[4] = swap[4];
-    buf2[5] = swap[5];
-    buf2[6] = swap[6];
-    buf2[7] = swap[7];
-#endif    
-    r = decoder(buf2);
-    ASSERT(r.val == num);
-    ASSERT(r.p == buf2 + upb_value_size(encoded));
-    ASSERT(upb_zzenc_32(upb_zzdec_32((uint32_t)num)) == num);
-  }
-
-  r = decoder(buf);
-  ASSERT(r.val == num);
-  ASSERT(r.p == buf + bytes);
-  ASSERT(upb_zzenc_64(upb_zzdec_64(num)) == num);
-}
-
-/* Making up for the lack of 64-bit constants in C89. */
-static uint64_t make_u64(uint32_t high, uint32_t low) {
-  uint64_t ret = high;
-  ret = (ret << 32) | low;
-  return ret;
-}
-
-static void test_varint_decoder(upb_decoderet (*decoder)(const char*)) {
-#define TEST(bytes, expected_val) {\
-    size_t n = sizeof(bytes) - 1;  /* for NULL */ \
-    char buf[UPB_PB_VARINT_MAX_LEN]; \
-    upb_decoderet r; \
-    memset(buf, 0xff, sizeof(buf)); \
-    memcpy(buf, bytes, n); \
-    r = decoder(buf); \
-    ASSERT(r.val == expected_val); \
-    ASSERT(r.p == buf + n); \
-  }
-
-  uint64_t num;
-
-  char twelvebyte[16] = {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1, 1};
-  const char *twelvebyte_buf = twelvebyte;
-  /* A varint that terminates before hitting the end of the provided buffer,
-   * but in too many bytes (11 instead of 10). */
-  upb_decoderet r = decoder(twelvebyte_buf);
-  ASSERT(r.p == NULL);
-
-  TEST("\x00", 0UL);
-  TEST("\x01", 1UL);
-  TEST("\x81\x14", 0xa01UL);
-  TEST("\x81\x03", 0x181UL);
-  TEST("\x81\x83\x07", 0x1c181UL);
-  TEST("\x81\x83\x87\x0f", 0x1e1c181UL);
-  TEST("\x81\x83\x87\x8f\x1f", make_u64(0x1, 0xf1e1c181UL));
-  TEST("\x81\x83\x87\x8f\x9f\x3f", make_u64(0x1f9, 0xf1e1c181UL));
-  TEST("\x81\x83\x87\x8f\x9f\xbf\x7f", make_u64(0x1fdf9, 0xf1e1c181UL));
-  TEST("\x81\x83\x87\x8f\x9f\xbf\xff\x01", make_u64(0x3fdf9, 0xf1e1c181UL));
-  TEST("\x81\x83\x87\x8f\x9f\xbf\xff\x81\x03",
-       make_u64(0x303fdf9, 0xf1e1c181UL));
-  TEST("\x81\x83\x87\x8f\x9f\xbf\xff\x81\x83\x07",
-       make_u64(0x8303fdf9, 0xf1e1c181UL));
-#undef TEST
-
-  for (num = 5; num * 1.5 < UINT64_MAX; num *= 1.5) {
-    test_varint_for_num(decoder, num);
-  }
-  test_varint_for_num(decoder, 0);
-}
-
-
-#define TEST_VARINT_DECODER(decoder) \
-  /* Create non-inline versions for convenient inspection of assembly language \
-   * output. */ \
-  upb_decoderet _upb_vdecode_ ## decoder(const char *p) { \
-    return upb_vdecode_ ## decoder(p); \
-  } \
-  void test_ ## decoder(void) { \
-    test_varint_decoder(&_upb_vdecode_ ## decoder); \
-  } \
-
-TEST_VARINT_DECODER(check2_branch32)
-TEST_VARINT_DECODER(check2_branch64)
-
-int run_tests(int argc, char *argv[]) {
-  UPB_UNUSED(argc);
-  UPB_UNUSED(argv);
-  test_check2_branch32();
-  test_check2_branch64();
-  return 0;
-}
index 802b700..9d3f64a 100644 (file)
@@ -952,6 +952,31 @@ void TestArena() {
   }
 }
 
+void TestInlinedArena() {
+  int n = 100000;
+
+  struct Decrementer {
+    Decrementer(int* _p) : p(_p) {}
+    ~Decrementer() { (*p)--; }
+    int* p;
+  };
+
+  {
+    upb::InlinedArena<1024> arena;
+    for (int i = 0; i < n; i++) {
+      arena.Own(new Decrementer(&n));
+
+      // Intersperse allocation and ensure we can write to it.
+      int* val = static_cast<int*>(upb_arena_malloc(arena.ptr(), sizeof(int)));
+      *val = i;
+    }
+
+    // Test a large allocation.
+    upb_arena_malloc(arena.ptr(), 1000000);
+  }
+  ASSERT(n == 0);
+}
+
 extern "C" {
 
 int run_tests() {
index c6f024a..bd1066b 100644 (file)
@@ -24,12 +24,13 @@ const int32_t test_int32_2 = -20;
 const int32_t test_int32_3 = 30;
 const int32_t test_int32_4 = -40;
 
-static void test_scalars() {
+static void test_scalars(void) {
   upb_arena *arena = upb_arena_new();
   protobuf_test_messages_proto3_TestAllTypesProto3 *msg =
       protobuf_test_messages_proto3_TestAllTypesProto3_new(arena);
   protobuf_test_messages_proto3_TestAllTypesProto3 *msg2;
   upb_strview serialized;
+  upb_strview val;
 
   protobuf_test_messages_proto3_TestAllTypesProto3_set_optional_int32(msg, 10);
   protobuf_test_messages_proto3_TestAllTypesProto3_set_optional_int64(msg, 20);
@@ -56,14 +57,35 @@ static void test_scalars() {
   ASSERT(protobuf_test_messages_proto3_TestAllTypesProto3_optional_uint64(
              msg2) == 40);
   ASSERT(protobuf_test_messages_proto3_TestAllTypesProto3_optional_float(
-             msg2) == 50.5);
+             msg2) - 50.5 < 0.01);
   ASSERT(protobuf_test_messages_proto3_TestAllTypesProto3_optional_double(
-             msg2) == 60.6);
+             msg2) - 60.6 < 0.01);
   ASSERT(protobuf_test_messages_proto3_TestAllTypesProto3_optional_bool(
              msg2) == 1);
-  ASSERT(upb_strview_eql(
-      protobuf_test_messages_proto3_TestAllTypesProto3_optional_string(msg2),
-      test_str_view));
+  val = protobuf_test_messages_proto3_TestAllTypesProto3_optional_string(msg2);
+  ASSERT(upb_strview_eql(val, test_str_view));
+
+  upb_arena_free(arena);
+}
+
+static void test_utf8(void) {
+  const char invalid_utf8[] = "\xff";
+  const upb_strview invalid_utf8_view = upb_strview_make(invalid_utf8, 1);
+  upb_arena *arena = upb_arena_new();
+  upb_strview serialized;
+  protobuf_test_messages_proto3_TestAllTypesProto3 *msg =
+      protobuf_test_messages_proto3_TestAllTypesProto3_new(arena);
+  protobuf_test_messages_proto3_TestAllTypesProto3 *msg2;
+
+  protobuf_test_messages_proto3_TestAllTypesProto3_set_optional_string(
+      msg, invalid_utf8_view);
+
+  serialized.data = protobuf_test_messages_proto3_TestAllTypesProto3_serialize(
+      msg, arena, &serialized.size);
+
+  msg2 = protobuf_test_messages_proto3_TestAllTypesProto3_parse(
+      serialized.data, serialized.size, arena);
+  ASSERT(msg2 == NULL);
 
   upb_arena_free(arena);
 }
@@ -117,7 +139,7 @@ static void check_string_map_one_entry(
   ASSERT(!const_ent);
 }
 
-static void test_string_double_map() {
+static void test_string_double_map(void) {
   upb_arena *arena = upb_arena_new();
   upb_strview serialized;
   upb_test_MapTest *msg = upb_test_MapTest_new(arena);
@@ -141,7 +163,7 @@ static void test_string_double_map() {
   upb_arena_free(arena);
 }
 
-static void test_string_map() {
+static void test_string_map(void) {
   upb_arena *arena = upb_arena_new();
   protobuf_test_messages_proto3_TestAllTypesProto3 *msg =
       protobuf_test_messages_proto3_TestAllTypesProto3_new(arena);
@@ -259,7 +281,7 @@ static void check_int32_map_one_entry(
   ASSERT(!const_ent);
 }
 
-static void test_int32_map() {
+static void test_int32_map(void) {
   upb_arena *arena = upb_arena_new();
   protobuf_test_messages_proto3_TestAllTypesProto3 *msg =
       protobuf_test_messages_proto3_TestAllTypesProto3_new(arena);
@@ -328,7 +350,7 @@ static void test_int32_map() {
   upb_arena_free(arena);
 }
 
-void test_repeated() {
+void test_repeated(void) {
   upb_arena *arena = upb_arena_new();
   protobuf_test_messages_proto3_TestAllTypesProto3 *msg =
       protobuf_test_messages_proto3_TestAllTypesProto3_new(arena);
@@ -347,7 +369,7 @@ void test_repeated() {
   upb_arena_free(arena);
 }
 
-void test_null_decode_buf() {
+void test_null_decode_buf(void) {
   upb_arena *arena = upb_arena_new();
   protobuf_test_messages_proto3_TestAllTypesProto3 *msg =
       protobuf_test_messages_proto3_TestAllTypesProto3_parse(NULL, 0, arena);
@@ -359,7 +381,7 @@ void test_null_decode_buf() {
   upb_arena_free(arena);
 }
 
-void test_status_truncation() {
+void test_status_truncation(void) {
   int i, j;
   upb_status status;
   upb_status status2;
@@ -390,6 +412,7 @@ void test_status_truncation() {
 
 int run_tests(int argc, char *argv[]) {
   test_scalars();
+  test_utf8();
   test_string_map();
   test_string_double_map();
   test_int32_map();
index e19a74a..83b49f5 100644 (file)
@@ -618,6 +618,16 @@ void test_delete() {
   upb_inttable_uninit(&t);
 }
 
+void test_init() {
+  for (int i = 0; i < 2048; i++) {
+    /* Tests that the size calculations in init() (lg2 size for target load)
+     * work for all expected sizes. */
+    upb_strtable t;
+    upb_strtable_init2(&t, UPB_CTYPE_BOOL, i, &upb_alloc_global);
+    upb_strtable_uninit(&t);
+  }
+}
+
 extern "C" {
 
 int run_tests(int argc, char *argv[]) {
diff --git a/third_party/upb/third_party/wyhash/BUILD b/third_party/upb/third_party/wyhash/BUILD
new file mode 100644 (file)
index 0000000..f3f3a6f
--- /dev/null
@@ -0,0 +1,17 @@
+licenses(["unencumbered"])
+
+exports_files(["LICENSE"])
+
+cc_library(
+    name = "wyhash",
+    hdrs = ["wyhash.h"],
+    visibility = ["//:__pkg__"],
+)
+
+filegroup(
+    name = "cmake_files",
+    srcs = glob([
+        "**/*",
+    ]),
+    visibility = ["//cmake:__pkg__"],
+)
diff --git a/third_party/upb/third_party/wyhash/LICENSE b/third_party/upb/third_party/wyhash/LICENSE
new file mode 100644 (file)
index 0000000..471f09f
--- /dev/null
@@ -0,0 +1,25 @@
+This is free and unencumbered software released into the public domain.
+
+Anyone is free to copy, modify, publish, use, compile, sell, or
+distribute this software, either in source code form or as a compiled
+binary, for any purpose, commercial or non-commercial, and by any
+means.
+
+In jurisdictions that recognize copyright laws, the author or authors
+of this software dedicate any and all copyright interest in the
+software to the public domain. We make this dedication for the benefit
+of the public at large and to the detriment of our heirs and
+successors. We intend this dedication to be an overt act of
+relinquishment in perpetuity of all present and future rights to this
+software under copyright law.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+
+For more information, please refer to <http://unlicense.org/>
+
diff --git a/third_party/upb/third_party/wyhash/wyhash.h b/third_party/upb/third_party/wyhash/wyhash.h
new file mode 100644 (file)
index 0000000..5658f02
--- /dev/null
@@ -0,0 +1,145 @@
+/* Copyright 2020 çŽ‹ä¸€ Wang Yi <godspeed_china@yeah.net>
+   This is free and unencumbered software released into the public domain. http://unlicense.org/
+   See github.com/wangyi-fudan/wyhash/ LICENSE
+ */
+#ifndef wyhash_final_version
+#define wyhash_final_version
+//defines that change behavior
+#ifndef WYHASH_CONDOM
+#define WYHASH_CONDOM 1 //0: read 8 bytes before and after boundaries, dangerous but fastest. 1: normal valid behavior 2: extra protection against entropy loss (probability=2^-63), aka. "blind multiplication"
+#endif
+#define WYHASH_32BIT_MUM 0     //faster on 32 bit system
+//includes
+#include <stdint.h>
+#include <string.h>
+#if defined(_MSC_VER) && defined(_M_X64)
+  #include <intrin.h>
+  #pragma intrinsic(_umul128)
+#endif
+#if defined(__GNUC__) || defined(__INTEL_COMPILER) || defined(__clang__)
+  #define _likely_(x)  __builtin_expect(x,1)
+  #define _unlikely_(x)        __builtin_expect(x,0)
+#else
+  #define _likely_(x) (x)
+  #define _unlikely_(x) (x)
+#endif
+//mum function
+static inline uint64_t _wyrot(uint64_t x) { return (x>>32)|(x<<32); }
+static inline void _wymum(uint64_t *A, uint64_t *B){
+#if(WYHASH_32BIT_MUM)
+  uint64_t hh=(*A>>32)*(*B>>32), hl=(*A>>32)*(unsigned)*B, lh=(unsigned)*A*(*B>>32), ll=(uint64_t)(unsigned)*A*(unsigned)*B;
+  #if(WYHASH_CONDOM>1)
+  *A^=_wyrot(hl)^hh; *B^=_wyrot(lh)^ll;
+  #else
+  *A=_wyrot(hl)^hh; *B=_wyrot(lh)^ll;
+  #endif
+#elif defined(__SIZEOF_INT128__)
+  __uint128_t r=*A; r*=*B; 
+  #if(WYHASH_CONDOM>1)
+  *A^=(uint64_t)r; *B^=(uint64_t)(r>>64);
+  #else
+  *A=(uint64_t)r; *B=(uint64_t)(r>>64);
+  #endif
+#elif defined(_MSC_VER) && defined(_M_X64)
+  #if(WYHASH_CONDOM>1)
+  uint64_t  a,  b;
+  a=_umul128(*A,*B,&b);
+  *A^=a;  *B^=b;
+  #else
+  *A=_umul128(*A,*B,B);
+  #endif
+#else
+  uint64_t ha=*A>>32, hb=*B>>32, la=(uint32_t)*A, lb=(uint32_t)*B, hi, lo;
+  uint64_t rh=ha*hb, rm0=ha*lb, rm1=hb*la, rl=la*lb, t=rl+(rm0<<32), c=t<rl;
+  lo=t+(rm1<<32); c+=lo<t; hi=rh+(rm0>>32)+(rm1>>32)+c;
+  #if(WYHASH_CONDOM>1)
+  *A^=lo;  *B^=hi;
+  #else
+  *A=lo;  *B=hi;
+  #endif
+#endif
+}
+static inline uint64_t _wymix(uint64_t A, uint64_t B){ _wymum(&A,&B); return A^B; }
+//read functions
+#ifndef WYHASH_LITTLE_ENDIAN
+  #if defined(_WIN32) || defined(__LITTLE_ENDIAN__) || (defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__)
+    #define WYHASH_LITTLE_ENDIAN 1
+  #elif defined(__BIG_ENDIAN__) || (defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__)
+    #define WYHASH_LITTLE_ENDIAN 0
+  #endif
+#endif
+#if (WYHASH_LITTLE_ENDIAN)
+static inline uint64_t _wyr8(const uint8_t *p) { uint64_t v; memcpy(&v, p, 8); return v;}
+static inline uint64_t _wyr4(const uint8_t *p) { unsigned v; memcpy(&v, p, 4); return v;}
+#elif defined(__GNUC__) || defined(__INTEL_COMPILER) || defined(__clang__)
+static inline uint64_t _wyr8(const uint8_t *p) { uint64_t v; memcpy(&v, p, 8); return __builtin_bswap64(v);}
+static inline uint64_t _wyr4(const uint8_t *p) { unsigned v; memcpy(&v, p, 4); return __builtin_bswap32(v);}
+#elif defined(_MSC_VER)
+static inline uint64_t _wyr8(const uint8_t *p) { uint64_t v; memcpy(&v, p, 8); return _byteswap_uint64(v);}
+static inline uint64_t _wyr4(const uint8_t *p) { unsigned v; memcpy(&v, p, 4); return _byteswap_ulong(v);}
+#endif
+static inline uint64_t _wyr3(const uint8_t *p, unsigned k) { return (((uint64_t)p[0])<<16)|(((uint64_t)p[k>>1])<<8)|p[k-1];}
+//wyhash function
+static inline uint64_t _wyfinish16(const uint8_t *p, uint64_t len, uint64_t seed, const uint64_t *secret, uint64_t i){
+#if(WYHASH_CONDOM>0)
+  uint64_t a, b;
+  if(_likely_(i<=8)){
+    if(_likely_(i>=4)){ a=_wyr4(p); b=_wyr4(p+i-4); }
+    else if (_likely_(i)){ a=_wyr3(p,i); b=0; }
+    else a=b=0;
+  } 
+  else{ a=_wyr8(p); b=_wyr8(p+i-8); }
+  return _wymix(secret[1]^len,_wymix(a^secret[1], b^seed));
+#else
+  #define oneshot_shift ((i<8)*((8-i)<<3))
+  return _wymix(secret[1]^len,_wymix((_wyr8(p)<<oneshot_shift)^secret[1],(_wyr8(p+i-8)>>oneshot_shift)^seed));
+#endif
+}
+
+static inline uint64_t _wyfinish(const uint8_t *p, uint64_t len, uint64_t seed, const uint64_t *secret, uint64_t i){
+  if(_likely_(i<=16)) return _wyfinish16(p,len,seed,secret,i);
+  return _wyfinish(p+16,len,_wymix(_wyr8(p)^secret[1],_wyr8(p+8)^seed),secret,i-16);
+}
+
+static inline uint64_t wyhash(const void *key, uint64_t len, uint64_t seed, const uint64_t *secret){
+  const uint8_t *p=(const uint8_t *)key;
+  uint64_t i=len; seed^=*secret;
+  if(_unlikely_(i>64)){
+    uint64_t see1=seed;
+    do{
+      seed=_wymix(_wyr8(p)^secret[1],_wyr8(p+8)^seed)^_wymix(_wyr8(p+16)^secret[2],_wyr8(p+24)^seed);
+      see1=_wymix(_wyr8(p+32)^secret[3],_wyr8(p+40)^see1)^_wymix(_wyr8(p+48)^secret[4],_wyr8(p+56)^see1);
+      p+=64; i-=64;
+    }while(i>64);
+    seed^=see1;
+  }
+  return _wyfinish(p,len,seed,secret,i);
+}
+//utility functions
+const uint64_t _wyp[5] = {0xa0761d6478bd642full, 0xe7037ed1a0b428dbull, 0x8ebc6af09c88c6e3ull, 0x589965cc75374cc3ull, 0x1d8e4e27c47d124full};
+static inline uint64_t wyhash64(uint64_t A, uint64_t B){  A^=_wyp[0]; B^=_wyp[1];  _wymum(&A,&B);  return _wymix(A^_wyp[0],B^_wyp[1]);}
+static inline uint64_t wyrand(uint64_t *seed){  *seed+=_wyp[0]; return _wymix(*seed,*seed^_wyp[1]);}
+static inline double wy2u01(uint64_t r){ const double _wynorm=1.0/(1ull<<52); return (r>>12)*_wynorm;}
+static inline double wy2gau(uint64_t r){ const double _wynorm=1.0/(1ull<<20); return ((r&0x1fffff)+((r>>21)&0x1fffff)+((r>>42)&0x1fffff))*_wynorm-3.0;}
+static inline uint64_t wy2u0k(uint64_t r, uint64_t k){ _wymum(&r,&k); return k; }
+
+static inline void make_secret(uint64_t seed, uint64_t *secret){
+  uint8_t c[] = {15, 23, 27, 29, 30, 39, 43, 45, 46, 51, 53, 54, 57, 58, 60, 71, 75, 77, 78, 83, 85, 86, 89, 90, 92, 99, 101, 102, 105, 106, 108, 113, 114, 116, 120, 135, 139, 141, 142, 147, 149, 150, 153, 154, 156, 163, 165, 166, 169, 170, 172, 177, 178, 180, 184, 195, 197, 198, 201, 202, 204, 209, 210, 212, 216, 225, 226, 228, 232, 240 };
+  for(size_t i=0;i<5;i++){
+    uint8_t ok;
+    do{
+      ok=1; secret[i]=0;
+      for(size_t j=0;j<64;j+=8) secret[i]|=((uint64_t)c[wyrand(&seed)%sizeof(c)])<<j;
+      if(secret[i]%2==0){ ok=0; continue; }
+      for(size_t j=0;j<i;j++)
+#if defined(__GNUC__) || defined(__INTEL_COMPILER) || defined(__clang__)
+        if(__builtin_popcountll(secret[j]^secret[i])!=32){ ok=0; break; }
+#elif defined(_MSC_VER) && defined(_M_X64)
+        if(_mm_popcnt_u64(secret[j]^secret[i])!=32){ ok=0; break; }
+#endif
+       if(!ok)continue;
+       for(uint64_t j=3;j<0x100000000ull;j+=2) if(secret[i]%j==0){ ok=0; break; }
+    }while(!ok);
+  }
+}
+#endif
diff --git a/third_party/upb/upb/bindings/lua/BUILD b/third_party/upb/upb/bindings/lua/BUILD
new file mode 100644 (file)
index 0000000..3b794a8
--- /dev/null
@@ -0,0 +1,41 @@
+load(
+    "//bazel:build_defs.bzl",
+    "UPB_DEFAULT_COPTS",
+    "UPB_DEFAULT_CPPOPTS",
+)
+
+licenses(["notice"])
+
+cc_library(
+    name = "lupb",
+    srcs = [
+        "def.c",
+        "msg.c",
+        "upb.c",
+    ],
+    hdrs = [
+        "upb.h",
+    ],
+    copts = UPB_DEFAULT_COPTS,
+    visibility = ["//visibility:public"],
+    deps = [
+        "//:json",
+        "//:reflection",
+        "//:textformat",
+        "//:upb",
+        "@lua//:liblua",
+    ],
+)
+
+cc_binary(
+    name = "protoc-gen-lua",
+    srcs = ["upbc.cc"],
+    copts = UPB_DEFAULT_CPPOPTS,
+    visibility = ["//visibility:public"],
+    deps = [
+        "@com_google_absl//absl/strings",
+        "@com_google_protobuf//:protoc_lib",
+    ],
+)
+
+exports_files(["upb.lua"])
index 6dc6b1a..a1e8720 100644 (file)
@@ -53,12 +53,12 @@ static void lupb_wrapper_pushwrapper(lua_State *L, int narg, const void *def,
 /* lupb_msgdef_pushsubmsgdef()
  *
  * Pops the msgdef wrapper at the top of the stack and replaces it with a msgdef
- * wrapper for field |f| of this msgdef.
+ * wrapper for field |f| of this msgdef (submsg may not be direct, for example it
+ * may be the submessage of the map value).
  */
 void lupb_msgdef_pushsubmsgdef(lua_State *L, const upb_fielddef *f) {
-  assert(luaL_testudata(L, -1, LUPB_MSGDEF));
   const upb_msgdef *m = upb_fielddef_msgsubdef(f);
-  assert(upb_fielddef_containingtype(f) == lupb_msgdef_check(L, -1));
+  assert(m);
   lupb_wrapper_pushwrapper(L, -1, m, LUPB_MSGDEF);
   lua_replace(L, -2);  /* Replace msgdef with submsgdef. */
 }
@@ -159,10 +159,11 @@ static int lupb_fielddef_name(lua_State *L) {
 static int lupb_fielddef_number(lua_State *L) {
   const upb_fielddef *f = lupb_fielddef_check(L, 1);
   int32_t num = upb_fielddef_number(f);
-  if (num)
+  if (num) {
     lua_pushinteger(L, num);
-  else
+  } else {
     lua_pushnil(L);
+  }
   return 1;
 }
 
@@ -224,58 +225,72 @@ static int lupb_oneofdef_containingtype(lua_State *L) {
   return 1;
 }
 
-/* lupb_oneofdef_field()
- *
- * Handles:
- *   oneof.field(field_number)
- *   oneof.field(field_name)
- */
 static int lupb_oneofdef_field(lua_State *L) {
   const upb_oneofdef *o = lupb_oneofdef_check(L, 1);
-  const upb_fielddef *f;
+  int32_t idx = lupb_checkint32(L, 2);
+  int count = upb_oneofdef_fieldcount(o);
 
-  switch (lua_type(L, 2)) {
-    case LUA_TNUMBER:
-      f = upb_oneofdef_itof(o, lua_tointeger(L, 2));
-      break;
-    case LUA_TSTRING:
-      f = upb_oneofdef_ntofz(o, lua_tostring(L, 2));
-      break;
-    default: {
-      const char *msg = lua_pushfstring(L, "number or string expected, got %s",
-                                        luaL_typename(L, 2));
-      return luaL_argerror(L, 2, msg);
-    }
+  if (idx < 0 || idx >= count) {
+    const char *msg = lua_pushfstring(L, "index %d exceeds field count %d",
+                                      idx, count);
+    return luaL_argerror(L, 2, msg);
   }
 
-  lupb_wrapper_pushwrapper(L, 1, f, LUPB_FIELDDEF);
+  lupb_wrapper_pushwrapper(L, 1, upb_oneofdef_field(o, idx), LUPB_FIELDDEF);
   return 1;
 }
 
 static int lupb_oneofiter_next(lua_State *L) {
-  upb_oneof_iter *i = lua_touserdata(L, lua_upvalueindex(1));
+  const upb_oneofdef *o = lupb_oneofdef_check(L, lua_upvalueindex(1));
+  int *index = lua_touserdata(L, lua_upvalueindex(2));
   const upb_fielddef *f;
-  if (upb_oneof_done(i)) return 0;
-  f = upb_oneof_iter_field(i);
-  upb_oneof_next(i);
-  lupb_symtab_pushwrapper(L, lua_upvalueindex(2), f, LUPB_FIELDDEF);
+  if (*index == upb_oneofdef_fieldcount(o)) return 0;
+  f = upb_oneofdef_field(o, (*index)++);
+  lupb_wrapper_pushwrapper(L, lua_upvalueindex(1), f, LUPB_FIELDDEF);
   return 1;
 }
 
 static int lupb_oneofdef_fields(lua_State *L) {
-  const upb_oneofdef *o = lupb_oneofdef_check(L, 1);
-  upb_oneof_iter *i = lua_newuserdata(L, sizeof(upb_oneof_iter));
-  lupb_wrapper_pushsymtab(L, 1);
-  upb_oneof_begin(i, o);
+  int *index = lua_newuserdata(L, sizeof(int));
+  lupb_oneofdef_check(L, 1);
+  *index = 0;
 
-  /* Closure upvalues are: iter, symtab. */
+  /* Closure upvalues are: oneofdef, index. */
   lua_pushcclosure(L, &lupb_oneofiter_next, 2);
   return 1;
 }
 
 static int lupb_oneofdef_len(lua_State *L) {
   const upb_oneofdef *o = lupb_oneofdef_check(L, 1);
-  lua_pushinteger(L, upb_oneofdef_numfields(o));
+  lua_pushinteger(L, upb_oneofdef_fieldcount(o));
+  return 1;
+}
+
+/* lupb_oneofdef_lookupfield()
+ *
+ * Handles:
+ *   oneof.lookup_field(field_number)
+ *   oneof.lookup_field(field_name)
+ */
+static int lupb_oneofdef_lookupfield(lua_State *L) {
+  const upb_oneofdef *o = lupb_oneofdef_check(L, 1);
+  const upb_fielddef *f;
+
+  switch (lua_type(L, 2)) {
+    case LUA_TNUMBER:
+      f = upb_oneofdef_itof(o, lua_tointeger(L, 2));
+      break;
+    case LUA_TSTRING:
+      f = upb_oneofdef_ntofz(o, lua_tostring(L, 2));
+      break;
+    default: {
+      const char *msg = lua_pushfstring(L, "number or string expected, got %s",
+                                        luaL_typename(L, 2));
+      return luaL_argerror(L, 2, msg);
+    }
+  }
+
+  lupb_wrapper_pushwrapper(L, 1, f, LUPB_FIELDDEF);
   return 1;
 }
 
@@ -289,6 +304,7 @@ static const struct luaL_Reg lupb_oneofdef_m[] = {
   {"containing_type", lupb_oneofdef_containingtype},
   {"field", lupb_oneofdef_field},
   {"fields", lupb_oneofdef_fields},
+  {"lookup_field", lupb_oneofdef_lookupfield},
   {"name", lupb_oneofdef_name},
   {NULL, NULL}
 };
@@ -309,12 +325,38 @@ const upb_msgdef *lupb_msgdef_check(lua_State *L, int narg) {
   return lupb_wrapper_check(L, narg, LUPB_MSGDEF);
 }
 
-static int lupb_msgdef_len(lua_State *L) {
+static int lupb_msgdef_fieldcount(lua_State *L) {
+  const upb_msgdef *m = lupb_msgdef_check(L, 1);
+  lua_pushinteger(L, upb_msgdef_fieldcount(m));
+  return 1;
+}
+
+static int lupb_msgdef_oneofcount(lua_State *L) {
   const upb_msgdef *m = lupb_msgdef_check(L, 1);
-  lua_pushinteger(L, upb_msgdef_numfields(m));
+  lua_pushinteger(L, upb_msgdef_oneofcount(m));
   return 1;
 }
 
+static bool lupb_msgdef_pushnested(lua_State *L, int msgdef, int name) {
+  const upb_msgdef *m = lupb_msgdef_check(L, msgdef);
+  lupb_wrapper_pushsymtab(L, msgdef);
+  upb_symtab *symtab = lupb_symtab_check(L, -1);
+  lua_pop(L, 1);
+
+  /* Construct full package.Message.SubMessage name. */
+  lua_pushstring(L, upb_msgdef_fullname(m));
+  lua_pushstring(L, ".");
+  lua_pushvalue(L, name);
+  lua_concat(L, 3);
+  const char *nested_name = lua_tostring(L, -1);
+
+  /* Try lookup. */
+  const upb_msgdef *nested = upb_symtab_lookupmsg(symtab, nested_name);
+  if (!nested) return false;
+  lupb_wrapper_pushwrapper(L, msgdef, nested, LUPB_MSGDEF);
+  return true;
+}
+
 /* lupb_msgdef_field()
  *
  * Handles:
@@ -376,23 +418,21 @@ static int lupb_msgdef_name(lua_State *L) {
 }
 
 static int lupb_msgfielditer_next(lua_State *L) {
-  upb_msg_field_iter *i = lua_touserdata(L, lua_upvalueindex(1));
+  const upb_msgdef *m = lupb_msgdef_check(L, lua_upvalueindex(1));
+  int *index = lua_touserdata(L, lua_upvalueindex(2));
   const upb_fielddef *f;
-
-  if (upb_msg_field_done(i)) return 0;
-  f = upb_msg_iter_field(i);
-  lupb_symtab_pushwrapper(L, lua_upvalueindex(2), f, LUPB_FIELDDEF);
-  upb_msg_field_next(i);
+  if (*index == upb_msgdef_fieldcount(m)) return 0;
+  f = upb_msgdef_field(m, (*index)++);
+  lupb_wrapper_pushwrapper(L, lua_upvalueindex(1), f, LUPB_FIELDDEF);
   return 1;
 }
 
 static int lupb_msgdef_fields(lua_State *L) {
-  const upb_msgdef *m = lupb_msgdef_check(L, 1);
-  upb_msg_field_iter *i = lua_newuserdata(L, sizeof(upb_msg_field_iter));
-  lupb_wrapper_pushsymtab(L, 1);
-  upb_msg_field_begin(i, m);
+  int *index = lua_newuserdata(L, sizeof(int));
+  lupb_msgdef_check(L, 1);
+  *index = 0;
 
-  /* Closure upvalues are: iter, symtab. */
+  /* Closure upvalues are: msgdef, index. */
   lua_pushcclosure(L, &lupb_msgfielditer_next, 2);
   return 1;
 }
@@ -410,23 +450,29 @@ static int lupb_msgdef_fullname(lua_State *L) {
   return 1;
 }
 
+static int lupb_msgdef_index(lua_State *L) {
+  if (!lupb_msgdef_pushnested(L, 1, 2)) {
+    luaL_error(L, "No such nested message");
+  }
+  return 1;
+}
+
 static int lupb_msgoneofiter_next(lua_State *L) {
-  upb_msg_oneof_iter *i = lua_touserdata(L, lua_upvalueindex(1));
+  const upb_msgdef *m = lupb_msgdef_check(L, lua_upvalueindex(1));
+  int *index = lua_touserdata(L, lua_upvalueindex(2));
   const upb_oneofdef *o;
-  if (upb_msg_oneof_done(i)) return 0;
-  o = upb_msg_iter_oneof(i);
-  upb_msg_oneof_next(i);
-  lupb_symtab_pushwrapper(L, lua_upvalueindex(2), o, LUPB_ONEOFDEF);
+  if (*index == upb_msgdef_oneofcount(m)) return 0;
+  o = upb_msgdef_oneof(m, (*index)++);
+  lupb_wrapper_pushwrapper(L, lua_upvalueindex(1), o, LUPB_ONEOFDEF);
   return 1;
 }
 
 static int lupb_msgdef_oneofs(lua_State *L) {
-  const upb_msgdef *m = lupb_msgdef_check(L, 1);
-  upb_msg_oneof_iter *i = lua_newuserdata(L, sizeof(upb_msg_oneof_iter));
-  lupb_wrapper_pushsymtab(L, 1);
-  upb_msg_oneof_begin(i, m);
+  int *index = lua_newuserdata(L, sizeof(int));
+  lupb_msgdef_check(L, 1);
+  *index = 0;
 
-  /* Closure upvalues are: iter, symtab. */
+  /* Closure upvalues are: msgdef, index. */
   lua_pushcclosure(L, &lupb_msgoneofiter_next, 2);
   return 1;
 }
@@ -451,8 +497,9 @@ static int lupb_msgdef_tostring(lua_State *L) {
 }
 
 static const struct luaL_Reg lupb_msgdef_mm[] = {
-  {"__call", lupb_msg_pushnew},
-  {"__len", lupb_msgdef_len},
+  {"__call", lupb_msgdef_call},
+  {"__index", lupb_msgdef_index},
+  {"__len", lupb_msgdef_fieldcount},
   {"__tostring", lupb_msgdef_tostring},
   {NULL, NULL}
 };
@@ -460,10 +507,12 @@ static const struct luaL_Reg lupb_msgdef_mm[] = {
 static const struct luaL_Reg lupb_msgdef_m[] = {
   {"field", lupb_msgdef_field},
   {"fields", lupb_msgdef_fields},
+  {"field_count", lupb_msgdef_fieldcount},
   {"file", lupb_msgdef_file},
   {"full_name", lupb_msgdef_fullname},
   {"lookup_name", lupb_msgdef_lookupname},
   {"name", lupb_msgdef_name},
+  {"oneof_count", lupb_msgdef_oneofcount},
   {"oneofs", lupb_msgdef_oneofs},
   {"syntax", lupb_msgdef_syntax},
   {"_map_entry", lupb_msgdef_mapentry},
@@ -619,6 +668,13 @@ static int lupb_filedef_package(lua_State *L) {
   return 1;
 }
 
+static int lupb_filedef_symtab(lua_State *L) {
+  const upb_filedef *f = lupb_filedef_check(L, 1);
+  const upb_symtab *symtab = upb_filedef_symtab(f);
+  lupb_wrapper_pushwrapper(L, 1, symtab, LUPB_SYMTAB);
+  return 1;
+}
+
 static int lupb_filedef_syntax(lua_State *L) {
   const upb_filedef *f = lupb_filedef_check(L, 1);
   lua_pushnumber(L, upb_filedef_syntax(f));
@@ -634,6 +690,7 @@ static const struct luaL_Reg lupb_filedef_m[] = {
   {"msgcount", lupb_filedef_msgcount},
   {"name", lupb_filedef_name},
   {"package", lupb_filedef_package},
+  {"symtab", lupb_filedef_symtab},
   {"syntax", lupb_filedef_syntax},
   {NULL, NULL}
 };
@@ -712,6 +769,10 @@ static int lupb_symtab_new(lua_State *L) {
   lua_setfield(L, -2, "__mode");
   lua_setmetatable(L, -2);
 
+  /* Put the symtab itself in the cache metatable. */
+  lua_pushvalue(L, -2);
+  lua_rawsetp(L, -2, lsymtab->symtab);
+
   /* Set the cache as our userval. */
   lua_setiuservalue(L, -2, LUPB_CACHE_INDEX);
 
@@ -729,7 +790,7 @@ static int lupb_symtab_addfile(lua_State *L) {
   size_t len;
   upb_symtab *s = lupb_symtab_check(L, 1);
   const char *str = luaL_checklstring(L, 2, &len);
-  upb_arena *arena = lupb_arena_pushnew(L);;
+  upb_arena *arena = lupb_arena_pushnew(L);
   const google_protobuf_FileDescriptorProto *file;
   const upb_filedef *file_def;
   upb_status status;
@@ -755,7 +816,7 @@ static int lupb_symtab_addset(lua_State *L) {
   google_protobuf_FileDescriptorSet *set;
   upb_symtab *s = lupb_symtab_check(L, 1);
   const char *str = luaL_checklstring(L, 2, &len);
-  upb_arena *arena = lupb_arena_pushnew(L);;
+  upb_arena *arena = lupb_arena_pushnew(L);
   upb_status status;
 
   upb_status_clear(&status);
index f216551..d6ac301 100644 (file)
@@ -1,4 +1,3 @@
-
 load("@bazel_skylib//lib:paths.bzl", "paths")
 
 # Generic support code #########################################################
@@ -12,6 +11,7 @@ def _get_real_short_path(file):
     if short_path.startswith("../"):
         second_slash = short_path.index("/", 3)
         short_path = short_path[second_slash + 1:]
+
     # Sometimes it has another few prefixes like:
     #   _virtual_imports/any_proto/google/protobuf/any.proto
     # We want just google/protobuf/any.proto.
@@ -64,9 +64,10 @@ def _lua_proto_rule_impl(ctx):
     files = dep[_LuaFiles].files
     return [
         DefaultInfo(
-           files = files,
-            data_runfiles = ctx.runfiles(files = files.to_list())),
-        ]
+            files = files,
+            data_runfiles = ctx.runfiles(files = files.to_list()),
+        ),
+    ]
 
 def _lua_proto_library_aspect_impl(target, ctx):
     proto_info = target[ProtoInfo]
@@ -82,7 +83,7 @@ _lua_proto_library_aspect = aspect(
         "_upbc": attr.label(
             executable = True,
             cfg = "host",
-            default = "//:protoc-gen-lua",
+            default = "//upb/bindings/lua:protoc-gen-lua",
         ),
         "_protoc": attr.label(
             executable = True,
index df9f009..c0c5bb9 100644 (file)
 
 #include "lauxlib.h"
 #include "upb/bindings/lua/upb.h"
+#include "upb/json_decode.h"
+#include "upb/json_encode.h"
+#include "upb/port_def.inc"
 #include "upb/reflection.h"
 #include "upb/text_encode.h"
 
-#include "upb/port_def.inc"
-
 /*
  * Message/Map/Array objects.  These objects form a directed graph: a message
  * can contain submessages, arrays, and maps, which can then point to other
@@ -187,6 +188,13 @@ static void lupb_arena_fuse(lua_State *L, int to, int from) {
   upb_arena_fuse(to_arena, from_arena);
 }
 
+static void lupb_arena_fuseobjs(lua_State *L, int to, int from) {
+  lua_getiuservalue(L, to, LUPB_ARENA_INDEX);
+  lua_getiuservalue(L, from, LUPB_ARENA_INDEX);
+  lupb_arena_fuse(L, lua_absindex(L, -2), lua_absindex(L, -1));
+  lua_pop(L, 2);
+}
+
 static int lupb_arena_gc(lua_State *L) {
   upb_arena *a = lupb_arena_check(L, 1);
   upb_arena_free(a);
@@ -398,6 +406,10 @@ static int lupb_array_newindex(lua_State *L) {
     upb_array_set(larray->arr, n, msgval);
   }
 
+  if (larray->type == UPB_TYPE_MESSAGE) {
+    lupb_arena_fuseobjs(L, 1, 3);
+  }
+
   return 0;  /* 1 for chained assignments? */
 }
 
@@ -535,6 +547,9 @@ static int lupb_map_newindex(lua_State *L) {
   } else {
     upb_msgval val = lupb_tomsgval(L, lmap->value_type, 3, 1, LUPB_COPY);
     upb_map_set(map, key, val, lupb_arenaget(L, 1));
+    if (lmap->value_type == UPB_TYPE_MESSAGE) {
+      lupb_arena_fuseobjs(L, 1, 3);
+    }
   }
 
   return 0;
@@ -564,8 +579,8 @@ static int lupb_mapiter_next(lua_State *L) {
  *   pairs(map)
  */
 static int lupb_map_pairs(lua_State *L) {
-  lupb_map_check(L, 1);
   size_t *iter = lua_newuserdata(L, sizeof(*iter));
+  lupb_map_check(L, 1);
 
   *iter = UPB_MAP_BEGIN;
   lua_pushvalue(L, 1);
@@ -600,24 +615,43 @@ static upb_msg *lupb_msg_check(lua_State *L, int narg) {
   return msg->msg;
 }
 
-static const upb_fielddef *lupb_msg_checkfield(lua_State *L, int msg,
-                                               int field) {
+static const upb_msgdef *lupb_msg_getmsgdef(lua_State *L, int msg) {
+  lua_getiuservalue(L, msg, LUPB_MSGDEF_INDEX);
+  const upb_msgdef *m = lupb_msgdef_check(L, -1);
+  lua_pop(L, 1);
+  return m;
+}
+
+static const upb_fielddef *lupb_msg_tofield(lua_State *L, int msg, int field) {
   size_t len;
   const char *fieldname = luaL_checklstring(L, field, &len);
-  const upb_msgdef *m;
-  const upb_fielddef *f;
+  const upb_msgdef *m = lupb_msg_getmsgdef(L, msg);
+  return upb_msgdef_ntof(m, fieldname, len);
+}
 
-  lua_getiuservalue(L, msg, LUPB_MSGDEF_INDEX);
-  m = lupb_msgdef_check(L, -1);
-  f = upb_msgdef_ntof(m, fieldname, len);
+static const upb_fielddef *lupb_msg_checkfield(lua_State *L, int msg,
+                                               int field) {
+  const upb_fielddef *f = lupb_msg_tofield(L, msg, field);
   if (f == NULL) {
-    luaL_error(L, "no such field '%s'", fieldname);
+    luaL_error(L, "no such field '%s'", lua_tostring(L, field));
   }
-  lua_pop(L, 1);
-
   return f;
 }
 
+upb_msg *lupb_msg_pushnew(lua_State *L, int narg) {
+  const upb_msgdef *m = lupb_msgdef_check(L, narg);
+  lupb_msg *lmsg = lupb_newuserdata(L, sizeof(lupb_msg), 2, LUPB_MSG);
+  upb_arena *arena = lupb_arena_pushnew(L);
+
+  lua_setiuservalue(L, -2, LUPB_ARENA_INDEX);
+  lua_pushvalue(L, 1);
+  lua_setiuservalue(L, -2, LUPB_MSGDEF_INDEX);
+
+  lmsg->msg = upb_msg_new(m, arena);
+  lupb_cacheset(L, lmsg->msg);
+  return lmsg->msg;
+}
+
 /**
  * lupb_msg_newmsgwrapper()
  *
@@ -707,28 +741,19 @@ static void lupb_msg_typechecksubmsg(lua_State *L, int narg, int msgarg,
 /* lupb_msg Public API */
 
 /**
- * lupb_msg_pushnew
+ * lupb_msgdef_call
  *
  * Handles:
  *   new_msg = MessageClass()
  *   new_msg = MessageClass{foo = "bar", baz = 3, quux = {foo = 3}}
  */
-int lupb_msg_pushnew(lua_State *L) {
-  int argcount = lua_gettop(L);
-  const upb_msgdef *m = lupb_msgdef_check(L, 1);
-  lupb_msg *lmsg = lupb_newuserdata(L, sizeof(lupb_msg), 2, LUPB_MSG);
-  upb_arena *arena = lupb_arena_pushnew(L);
+int lupb_msgdef_call(lua_State *L) {
+  int arg_count = lua_gettop(L);
+  lupb_msg_pushnew(L, 1);
 
-  lua_setiuservalue(L, -2, LUPB_ARENA_INDEX);
-  lua_pushvalue(L, 1);
-  lua_setiuservalue(L, -2, LUPB_MSGDEF_INDEX);
-
-  lmsg->msg = upb_msg_new(m, arena);
-  lupb_cacheset(L, lmsg->msg);
-
-  if (argcount > 1) {
+  if (arg_count > 1) {
     /* Set initial fields from table. */
-    int msg = lua_gettop(L);
+    int msg = arg_count + 1;
     lua_pushnil(L);
     while (lua_next(L, 2) != 0) {
       lua_pushvalue(L, -2);  /* now stack is key, val, key */
@@ -813,10 +838,7 @@ static int lupb_msg_newindex(lua_State *L) {
   }
 
   if (merge_arenas) {
-    lua_getiuservalue(L, 1, LUPB_ARENA_INDEX);
-    lua_getiuservalue(L, 3, LUPB_ARENA_INDEX);
-    lupb_arena_fuse(L, lua_absindex(L, -2), lua_absindex(L, -1));
-    lua_pop(L, 2);
+    lupb_arena_fuseobjs(L, 1, 3);
   }
 
   upb_msg_set(msg, f, msgval, lupb_arenaget(L, 1));
@@ -867,6 +889,19 @@ static const struct luaL_Reg lupb_msg_mm[] = {
 
 /* lupb_msg toplevel **********************************************************/
 
+static int lupb_getoptions(lua_State *L, int narg) {
+  int options = 0;
+  if (lua_gettop(L) >= narg) {
+    size_t len = lua_rawlen(L, narg);
+    for (size_t i = 1; i <= len; i++) {
+      lua_rawgeti(L, narg, i);
+      options |= lupb_checkuint32(L, -1);
+      lua_pop(L, 1);
+    }
+  }
+  return options;
+}
+
 /**
  * lupb_decode()
  *
@@ -878,26 +913,16 @@ static int lupb_decode(lua_State *L) {
   const upb_msgdef *m = lupb_msgdef_check(L, 1);
   const char *pb = lua_tolstring(L, 2, &len);
   const upb_msglayout *layout = upb_msgdef_layout(m);
+  upb_msg *msg = lupb_msg_pushnew(L, 1);
+  upb_arena *arena = lupb_arenaget(L, -1);
   char *buf;
-  upb_msg *msg;
-  upb_arena *arena;
   bool ok;
 
-  /* Create message. */
-  lua_pushcfunction(L, &lupb_msg_pushnew);
-  lua_pushvalue(L, 1);
-  lua_call(L, 1, 1);
-  msg = lupb_msg_check(L, -1);
-
-  lua_getiuservalue(L, -1, LUPB_ARENA_INDEX);
-  arena = lupb_arena_check(L, -1);
-  lua_pop(L, 1);
-
   /* Copy input data to arena, message will reference it. */
   buf = upb_arena_malloc(arena, len);
   memcpy(buf, pb, len);
 
-  ok = upb_decode(buf, len, msg, layout, arena);
+  ok = _upb_decode(buf, len, msg, layout, arena, UPB_DECODE_ALIAS);
 
   if (!ok) {
     lua_pushstring(L, "Error decoding protobuf.");
@@ -915,16 +940,15 @@ static int lupb_decode(lua_State *L) {
  */
 static int lupb_encode(lua_State *L) {
   const upb_msg *msg = lupb_msg_check(L, 1);
-  const upb_msglayout *layout;
-  upb_arena *arena = lupb_arena_pushnew(L);
+  const upb_msgdef *m = lupb_msg_getmsgdef(L, 1);
+  const upb_msglayout *layout = upb_msgdef_layout(m);
+  int options = lupb_getoptions(L, 2);
+  upb_arena *arena;
   size_t size;
   char *result;
 
-  lua_getiuservalue(L, 1, LUPB_MSGDEF_INDEX);
-  layout = upb_msgdef_layout(lupb_msgdef_check(L, -1));
-  lua_pop(L, 1);
-
-  result = upb_encode(msg, (const void*)layout, arena, &size);
+  arena = lupb_arena_pushnew(L);
+  result = upb_encode_ex(msg, (const void*)layout, options, arena, &size);
 
   if (!result) {
     lua_pushstring(L, "Error encoding protobuf.");
@@ -936,11 +960,101 @@ static int lupb_encode(lua_State *L) {
   return 1;
 }
 
+/**
+ * lupb_jsondecode()
+ *
+ * Handles:
+ *   text_string = upb.json_decode(MessageClass, json_str, {upb.JSONDEC_IGNOREUNKNOWN})
+ */
+static int lupb_jsondecode(lua_State *L) {
+  size_t len;
+  const upb_msgdef *m = lupb_msgdef_check(L, 1);
+  const char *json = lua_tolstring(L, 2, &len);
+  int options = lupb_getoptions(L, 3);
+  upb_msg *msg;
+  upb_arena *arena;
+  upb_status status;
+
+  msg = lupb_msg_pushnew(L, 1);
+  arena = lupb_arenaget(L, -1);
+  upb_status_clear(&status);
+  upb_json_decode(json, len, msg, m, NULL, options, arena, &status);
+  lupb_checkstatus(L, &status);
+
+  return 1;
+}
+
+/**
+ * lupb_jsonencode()
+ *
+ * Handles:
+ *   text_string = upb.json_encode(msg, {upb.JSONENC_EMITDEFAULTS})
+ */
+static int lupb_jsonencode(lua_State *L) {
+  upb_msg *msg = lupb_msg_check(L, 1);
+  const upb_msgdef *m = lupb_msg_getmsgdef(L, 1);
+  int options = lupb_getoptions(L, 2);
+  char buf[1024];
+  size_t size;
+  upb_status status;
+
+  upb_status_clear(&status);
+  size = upb_json_encode(msg, m, NULL, options, buf, sizeof(buf), &status);
+  lupb_checkstatus(L, &status);
+
+  if (size < sizeof(buf)) {
+    lua_pushlstring(L, buf, size);
+  } else {
+    char *ptr = malloc(size + 1);
+    upb_json_encode(msg, m, NULL, options, ptr, size + 1, &status);
+    lupb_checkstatus(L, &status);
+    lua_pushlstring(L, ptr, size);
+    free(ptr);
+  }
+
+  return 1;
+}
+
+/**
+ * lupb_textencode()
+ *
+ * Handles:
+ *   text_string = upb.text_encode(msg, {upb.TXTENC_SINGLELINE})
+ */
+static int lupb_textencode(lua_State *L) {
+  upb_msg *msg = lupb_msg_check(L, 1);
+  const upb_msgdef *m = lupb_msg_getmsgdef(L, 1);
+  int options = lupb_getoptions(L, 2);
+  char buf[1024];
+  size_t size;
+
+  size = upb_text_encode(msg, m, NULL, options, buf, sizeof(buf));
+
+  if (size < sizeof(buf)) {
+    lua_pushlstring(L, buf, size);
+  } else {
+    char *ptr = malloc(size + 1);
+    upb_text_encode(msg, m, NULL, options, ptr, size + 1);
+    lua_pushlstring(L, ptr, size);
+    free(ptr);
+  }
+
+  return 1;
+}
+
+static void lupb_setfieldi(lua_State *L, const char *field, int i) {
+  lua_pushinteger(L, i);
+  lua_setfield(L, -2, field);
+}
+
 static const struct luaL_Reg lupb_msg_toplevel_m[] = {
   {"Array", lupb_array_new},
   {"Map", lupb_map_new},
   {"decode", lupb_decode},
   {"encode", lupb_encode},
+  {"json_decode", lupb_jsondecode},
+  {"json_encode", lupb_jsonencode},
+  {"text_encode", lupb_textencode},
   {NULL, NULL}
 };
 
@@ -952,5 +1066,17 @@ void lupb_msg_registertypes(lua_State *L) {
   lupb_register_type(L, LUPB_MAP,   NULL, lupb_map_mm);
   lupb_register_type(L, LUPB_MSG,   NULL, lupb_msg_mm);
 
+  lupb_setfieldi(L, "TXTENC_SINGLELINE", UPB_TXTENC_SINGLELINE);
+  lupb_setfieldi(L, "TXTENC_SKIPUNKNOWN", UPB_TXTENC_SKIPUNKNOWN);
+  lupb_setfieldi(L, "TXTENC_NOSORT", UPB_TXTENC_NOSORT);
+
+  lupb_setfieldi(L, "ENCODE_DETERMINISTIC", UPB_ENCODE_DETERMINISTIC);
+  lupb_setfieldi(L, "ENCODE_SKIPUNKNOWN", UPB_ENCODE_SKIPUNKNOWN);
+
+  lupb_setfieldi(L, "JSONENC_EMITDEFAULTS", UPB_JSONENC_EMITDEFAULTS);
+  lupb_setfieldi(L, "JSONENC_PROTONAMES", UPB_JSONENC_PROTONAMES);
+
+  lupb_setfieldi(L, "JSONDEC_IGNOREUNKNOWN", UPB_JSONDEC_IGNOREUNKNOWN);
+
   lupb_cacheinit(L);
 }
index 3630ae2..c247c03 100644 (file)
@@ -84,6 +84,24 @@ int lua_getiuservalue(lua_State *L, int index, int n) {
 }
 #endif
 
+/* We use this function as the __index metamethod when a type has both methods
+ * and an __index metamethod. */
+int lupb_indexmm(lua_State *L) {
+  /* Look up in __index table (which is a closure param). */
+  lua_pushvalue(L, 2);
+  lua_rawget(L, lua_upvalueindex(1));
+  if (!lua_isnil(L, -1)) {
+    return 1;
+  }
+
+  /* Not found, chain to user __index metamethod. */
+  lua_pushvalue(L, lua_upvalueindex(2));
+  lua_pushvalue(L, 1);
+  lua_pushvalue(L, 2);
+  lua_call(L, 2, 1);
+  return 1;
+}
+
 void lupb_register_type(lua_State *L, const char *name, const luaL_Reg *m,
                         const luaL_Reg *mm) {
   luaL_newmetatable(L, name);
@@ -93,14 +111,17 @@ void lupb_register_type(lua_State *L, const char *name, const luaL_Reg *m,
   }
 
   if (m) {
-    /* Methods go in the mt's __index method.  This implies that you can'
-     * implement __index and also have methods. */
-    lua_getfield(L, -1, "__index");
-    lupb_assert(L, lua_isnil(L, -1));
-    lua_pop(L, 1);
-
-    lua_createtable(L, 0, 0);
+    lua_createtable(L, 0, 0);  /* __index table */
     lupb_setfuncs(L, m);
+
+    /* Methods go in the mt's __index slot.  If the user also specified an
+     * __index metamethod, use our custom lupb_indexmm() that can check both. */
+    lua_getfield(L, -2, "__index");
+    if (lua_isnil(L, -1)) {
+      lua_pop(L, 1);
+    } else {
+      lua_pushcclosure(L, &lupb_indexmm, 2);
+    }
     lua_setfield(L, -2, "__index");
   }
 
index 02ed341..455752f 100644 (file)
@@ -75,7 +75,7 @@ void lupb_def_registertypes(lua_State *L);
 
 /** From msg.c. ***************************************************************/
 
-int lupb_msg_pushnew(lua_State *L);
+int lupb_msgdef_call(lua_State *L);
 upb_arena *lupb_arena_pushnew(lua_State *L);
 
 void lupb_msg_registertypes(lua_State *L);
diff --git a/third_party/upb/upb/bindings/stdc++/string.h b/third_party/upb/upb/bindings/stdc++/string.h
deleted file mode 100644 (file)
index c346548..0000000
+++ /dev/null
@@ -1,69 +0,0 @@
-
-#ifndef UPB_STDCPP_H_
-#define UPB_STDCPP_H_
-
-#include "upb/sink.h"
-
-#include "upb/port_def.inc"
-
-namespace upb {
-
-template <class T>
-class FillStringHandler {
- public:
-  static void SetHandler(upb_byteshandler* handler) {
-    upb_byteshandler_setstartstr(handler, &FillStringHandler::StartString,
-                                 NULL);
-    upb_byteshandler_setstring(handler, &FillStringHandler::StringBuf, NULL);
-  }
-
- private:
-  // TODO(haberman): add UpbBind/UpbMakeHandler support to BytesHandler so these
-  // can be prettier callbacks.
-  static void* StartString(void *c, const void *hd, size_t size) {
-    UPB_UNUSED(hd);
-    UPB_UNUSED(size);
-
-    T* str = static_cast<T*>(c);
-    str->clear();
-    return c;
-  }
-
-  static size_t StringBuf(void* c, const void* hd, const char* buf, size_t n,
-                          const upb_bufhandle* h) {
-    UPB_UNUSED(hd);
-    UPB_UNUSED(h);
-
-    T* str = static_cast<T*>(c);
-    try {
-      str->append(buf, n);
-      return n;
-    } catch (const std::exception&) {
-      return 0;
-    }
-  }
-};
-
-class StringSink {
- public:
-  template <class T>
-  explicit StringSink(T* target) {
-    // TODO(haberman): we need to avoid rebuilding a new handler every time,
-    // but with class globals disallowed for google3 C++ this is tricky.
-    upb_byteshandler_init(&handler_);
-    FillStringHandler<T>::SetHandler(&handler_);
-    input_.Reset(&handler_, target);
-  }
-
-  BytesSink input() { return input_; }
-
- private:
-  upb_byteshandler handler_;
-  BytesSink input_;
-};
-
-}  // namespace upb
-
-#include "upb/port_undef.inc"
-
-#endif  // UPB_STDCPP_H_
index a9f1cf5..a5f0666 100644 (file)
@@ -1,33 +1,37 @@
 
+#include "upb/decode.h"
+
 #include <setjmp.h>
 #include <string.h>
 
-#include "upb/decode.h"
+#include "upb/decode.int.h"
 #include "upb/upb.h"
+#include "upb/upb.int.h"
 
+/* Must be last. */
 #include "upb/port_def.inc"
 
-/* Maps descriptor type -> upb field type.  */
-static const uint8_t desctype_to_fieldtype[] = {
+/* Maps descriptor type -> elem_size_lg2.  */
+static const uint8_t desctype_to_elem_size_lg2[] = {
     -1,               /* invalid descriptor type */
-    UPB_TYPE_DOUBLE,  /* DOUBLE */
-    UPB_TYPE_FLOAT,   /* FLOAT */
-    UPB_TYPE_INT64,   /* INT64 */
-    UPB_TYPE_UINT64,  /* UINT64 */
-    UPB_TYPE_INT32,   /* INT32 */
-    UPB_TYPE_UINT64,  /* FIXED64 */
-    UPB_TYPE_UINT32,  /* FIXED32 */
-    UPB_TYPE_BOOL,    /* BOOL */
-    UPB_TYPE_STRING,  /* STRING */
-    UPB_TYPE_MESSAGE, /* GROUP */
-    UPB_TYPE_MESSAGE, /* MESSAGE */
-    UPB_TYPE_BYTES,   /* BYTES */
-    UPB_TYPE_UINT32,  /* UINT32 */
-    UPB_TYPE_ENUM,    /* ENUM */
-    UPB_TYPE_INT32,   /* SFIXED32 */
-    UPB_TYPE_INT64,   /* SFIXED64 */
-    UPB_TYPE_INT32,   /* SINT32 */
-    UPB_TYPE_INT64,   /* SINT64 */
+    3,  /* DOUBLE */
+    2,   /* FLOAT */
+    3,   /* INT64 */
+    3,  /* UINT64 */
+    2,   /* INT32 */
+    3,  /* FIXED64 */
+    2,  /* FIXED32 */
+    0,    /* BOOL */
+    UPB_SIZE(3, 4),  /* STRING */
+    UPB_SIZE(2, 3),  /* GROUP */
+    UPB_SIZE(2, 3),  /* MESSAGE */
+    UPB_SIZE(3, 4),  /* BYTES */
+    2,  /* UINT32 */
+    2,    /* ENUM */
+    2,   /* SFIXED32 */
+    3,   /* SFIXED64 */
+    2,   /* SINT32 */
+    3,   /* SINT64 */
 };
 
 /* Maps descriptor type -> upb map size.  */
@@ -134,106 +138,101 @@ static const int8_t delim_ops[37] = {
     OP_VARPCK_LG2(3), /* REPEATED SINT64 */
 };
 
-/* Data pertaining to the parse. */
-typedef struct {
-  const char *limit;       /* End of delimited region or end of buffer. */
-  upb_arena *arena;
-  int depth;
-  uint32_t end_group; /* Set to field number of END_GROUP tag, if any. */
-  jmp_buf err;
-} upb_decstate;
-
 typedef union {
   bool bool_val;
   uint32_t uint32_val;
   uint64_t uint64_val;
-  upb_strview str_val;
+  uint32_t size;
 } wireval;
 
 static const char *decode_msg(upb_decstate *d, const char *ptr, upb_msg *msg,
                               const upb_msglayout *layout);
 
-UPB_NORETURN static void decode_err(upb_decstate *d) { longjmp(d->err, 1); }
-
-void decode_verifyutf8(upb_decstate *d, const char *buf, int len) {
-  static const uint8_t utf8_offset[] = {
-      1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
-      1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
-      1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
-      1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
-      1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
-      1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-      2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
-      2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
-      4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0,
-  };
-
-  int i, j;
-  uint8_t offset;
-
-  i = 0;
-  while (i < len) {
-    offset = utf8_offset[(uint8_t)buf[i]];
-    if (offset == 0 || i + offset > len) {
-      decode_err(d);
-    }
-    for (j = i + 1; j < i + offset; j++) {
-      if ((buf[j] & 0xc0) != 0x80) {
-        decode_err(d);
-      }
-    }
-    i += offset;
-  }
-  if (i != len) decode_err(d);
+UPB_NORETURN static void decode_err(upb_decstate *d) { UPB_LONGJMP(d->err, 1); }
+
+const char *fastdecode_err(upb_decstate *d) {
+  longjmp(d->err, 1);
+  return NULL;
+}
+
+const uint8_t upb_utf8_offsets[] = {
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+    1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+    2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+    4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0,
+};
+
+static void decode_verifyutf8(upb_decstate *d, const char *buf, int len) {
+  if (!decode_verifyutf8_inl(buf, len)) decode_err(d);
 }
 
 static bool decode_reserve(upb_decstate *d, upb_array *arr, size_t elem) {
   bool need_realloc = arr->size - arr->len < elem;
-  if (need_realloc && !_upb_array_realloc(arr, arr->len + elem, d->arena)) {
+  if (need_realloc && !_upb_array_realloc(arr, arr->len + elem, &d->arena)) {
     decode_err(d);
   }
   return need_realloc;
 }
 
+typedef struct {
+  const char *ptr;
+  uint64_t val;
+} decode_vret;
+
 UPB_NOINLINE
-static const char *decode_longvarint64(upb_decstate *d, const char *ptr,
-                                       const char *limit, uint64_t *val) {
-  uint8_t byte;
-  int bitpos = 0;
-  uint64_t out = 0;
-
-  do {
-    if (bitpos >= 70 || ptr == limit) decode_err(d);
-    byte = *ptr;
-    out |= (uint64_t)(byte & 0x7F) << bitpos;
-    ptr++;
-    bitpos += 7;
-  } while (byte & 0x80);
-
-  *val = out;
-  return ptr;
+static decode_vret decode_longvarint64(const char *ptr, uint64_t val) {
+  decode_vret ret = {NULL, 0};
+  uint64_t byte;
+  int i;
+  for (i = 1; i < 10; i++) {
+    byte = (uint8_t)ptr[i];
+    val += (byte - 1) << (i * 7);
+    if (!(byte & 0x80)) {
+      ret.ptr = ptr + i + 1;
+      ret.val = val;
+      return ret;
+    }
+  }
+  return ret;
 }
 
 UPB_FORCEINLINE
 static const char *decode_varint64(upb_decstate *d, const char *ptr,
-                                   const char *limit, uint64_t *val) {
-  if (UPB_LIKELY(ptr < limit && (*ptr & 0x80) == 0)) {
-    *val = (uint8_t)*ptr;
+                                   uint64_t *val) {
+  uint64_t byte = (uint8_t)*ptr;
+  if (UPB_LIKELY((byte & 0x80) == 0)) {
+    *val = byte;
     return ptr + 1;
   } else {
-    return decode_longvarint64(d, ptr, limit, val);
+    decode_vret res = decode_longvarint64(ptr, byte);
+    if (!res.ptr) decode_err(d);
+    *val = res.val;
+    return res.ptr;
   }
 }
 
-static const char *decode_varint32(upb_decstate *d, const char *ptr,
-                                   const char *limit, uint32_t *val) {
-  uint64_t u64;
-  ptr = decode_varint64(d, ptr, limit, &u64);
-  if (u64 > UINT32_MAX) decode_err(d);
-  *val = (uint32_t)u64;
-  return ptr;
+UPB_FORCEINLINE
+static const char *decode_tag(upb_decstate *d, const char *ptr,
+                                   uint32_t *val) {
+  uint64_t byte = (uint8_t)*ptr;
+  if (UPB_LIKELY((byte & 0x80) == 0)) {
+    *val = byte;
+    return ptr + 1;
+  } else {
+    const char *start = ptr;
+    decode_vret res = decode_longvarint64(ptr, byte);
+    ptr = res.ptr;
+    *val = res.val;
+    if (!ptr || *val > UINT32_MAX || ptr - start > 5) decode_err(d);
+    return ptr;
+  }
 }
 
 static void decode_munge(int type, wireval *val) {
@@ -280,33 +279,65 @@ static const upb_msglayout_field *upb_find_field(const upb_msglayout *l,
 static upb_msg *decode_newsubmsg(upb_decstate *d, const upb_msglayout *layout,
                                  const upb_msglayout_field *field) {
   const upb_msglayout *subl = layout->submsgs[field->submsg_index];
-  return _upb_msg_new(subl, d->arena);
+  return _upb_msg_new_inl(subl, &d->arena);
+}
+
+UPB_NOINLINE
+const char *decode_isdonefallback(upb_decstate *d, const char *ptr,
+                                  int overrun) {
+  ptr = decode_isdonefallback_inl(d, ptr, overrun);
+  if (ptr == NULL) {
+    decode_err(d);
+  }
+  return ptr;
+}
+
+static const char *decode_readstr(upb_decstate *d, const char *ptr, int size,
+                                  upb_strview *str) {
+  if (d->alias) {
+    str->data = ptr;
+  } else {
+    char *data =  upb_arena_malloc(&d->arena, size);
+    if (!data) decode_err(d);
+    memcpy(data, ptr, size);
+    str->data = data;
+  }
+  str->size = size;
+  return ptr + size;
 }
 
-static void decode_tosubmsg(upb_decstate *d, upb_msg *submsg,
-                            const upb_msglayout *layout,
-                            const upb_msglayout_field *field, upb_strview val) {
+UPB_FORCEINLINE
+static const char *decode_tosubmsg(upb_decstate *d, const char *ptr,
+                                   upb_msg *submsg, const upb_msglayout *layout,
+                                   const upb_msglayout_field *field, int size) {
   const upb_msglayout *subl = layout->submsgs[field->submsg_index];
-  const char *saved_limit = d->limit;
+  int saved_delta = decode_pushlimit(d, ptr, size);
   if (--d->depth < 0) decode_err(d);
-  d->limit = val.data + val.size;
-  decode_msg(d, val.data, submsg, subl);
-  d->limit = saved_limit;
-  if (d->end_group != 0) decode_err(d);
+  if (!decode_isdone(d, &ptr)) {
+    ptr = decode_msg(d, ptr, submsg, subl);
+  }
+  if (d->end_group != DECODE_NOGROUP) decode_err(d);
+  decode_poplimit(d, ptr, saved_delta);
   d->depth++;
+  return ptr;
 }
 
+UPB_FORCEINLINE
 static const char *decode_group(upb_decstate *d, const char *ptr,
                                 upb_msg *submsg, const upb_msglayout *subl,
                                 uint32_t number) {
   if (--d->depth < 0) decode_err(d);
+  if (decode_isdone(d, &ptr)) {
+    decode_err(d);
+  }
   ptr = decode_msg(d, ptr, submsg, subl);
   if (d->end_group != number) decode_err(d);
-  d->end_group = 0;
+  d->end_group = DECODE_NOGROUP;
   d->depth++;
   return ptr;
 }
 
+UPB_FORCEINLINE
 static const char *decode_togroup(upb_decstate *d, const char *ptr,
                                   upb_msg *submsg, const upb_msglayout *layout,
                                   const upb_msglayout_field *field) {
@@ -322,15 +353,15 @@ static const char *decode_toarray(upb_decstate *d, const char *ptr,
   upb_array *arr = *arrp;
   void *mem;
 
-  if (!arr) {
-    upb_fieldtype_t type = desctype_to_fieldtype[field->descriptortype];
-    arr = _upb_array_new(d->arena, type);
+  if (arr) {
+    decode_reserve(d, arr, 1);
+  } else {
+    size_t lg2 = desctype_to_elem_size_lg2[field->descriptortype];
+    arr = _upb_array_new(&d->arena, 4, lg2);
     if (!arr) decode_err(d);
     *arrp = arr;
   }
 
-  decode_reserve(d, arr, 1);
-
   switch (op) {
     case OP_SCALAR_LG2(0):
     case OP_SCALAR_LG2(2):
@@ -341,15 +372,14 @@ static const char *decode_toarray(upb_decstate *d, const char *ptr,
       memcpy(mem, &val, 1 << op);
       return ptr;
     case OP_STRING:
-      decode_verifyutf8(d, val.str_val.data, val.str_val.size);
+      decode_verifyutf8(d, ptr, val.size);
       /* Fallthrough. */
-    case OP_BYTES:
+    case OP_BYTES: {
       /* Append bytes. */
-      mem =
-          UPB_PTR_AT(_upb_array_ptr(arr), arr->len * sizeof(upb_strview), void);
+      upb_strview *str = (upb_strview*)_upb_array_ptr(arr) + arr->len;
       arr->len++;
-      memcpy(mem, &val, sizeof(upb_strview));
-      return ptr;
+      return decode_readstr(d, ptr, val.size, str);
+    }
     case OP_SUBMSG: {
       /* Append submessage / group. */
       upb_msg *submsg = decode_newsubmsg(d, layout, field);
@@ -357,26 +387,25 @@ static const char *decode_toarray(upb_decstate *d, const char *ptr,
           submsg;
       arr->len++;
       if (UPB_UNLIKELY(field->descriptortype == UPB_DTYPE_GROUP)) {
-        ptr = decode_togroup(d, ptr, submsg, layout, field);
+        return decode_togroup(d, ptr, submsg, layout, field);
       } else {
-        decode_tosubmsg(d, submsg, layout, field, val.str_val);
+        return decode_tosubmsg(d, ptr, submsg, layout, field, val.size);
       }
-      return ptr;
     }
     case OP_FIXPCK_LG2(2):
     case OP_FIXPCK_LG2(3): {
       /* Fixed packed. */
       int lg2 = op - OP_FIXPCK_LG2(0);
       int mask = (1 << lg2) - 1;
-      size_t count = val.str_val.size >> lg2;
-      if ((val.str_val.size & mask) != 0) {
+      size_t count = val.size >> lg2;
+      if ((val.size & mask) != 0) {
         decode_err(d); /* Length isn't a round multiple of elem size. */
       }
       decode_reserve(d, arr, count);
       mem = UPB_PTR_AT(_upb_array_ptr(arr), arr->len << lg2, void);
       arr->len += count;
-      memcpy(mem, val.str_val.data, val.str_val.size);
-      return ptr;
+      memcpy(mem, ptr, val.size);  /* XXX: ptr boundary. */
+      return ptr + val.size;
     }
     case OP_VARPCK_LG2(0):
     case OP_VARPCK_LG2(2):
@@ -384,12 +413,11 @@ static const char *decode_toarray(upb_decstate *d, const char *ptr,
       /* Varint packed. */
       int lg2 = op - OP_VARPCK_LG2(0);
       int scale = 1 << lg2;
-      const char *ptr = val.str_val.data;
-      const char *end = ptr + val.str_val.size;
+      int saved_limit = decode_pushlimit(d, ptr, val.size);
       char *out = UPB_PTR_AT(_upb_array_ptr(arr), arr->len << lg2, void);
-      while (ptr < end) {
+      while (!decode_isdone(d, &ptr)) {
         wireval elem;
-        ptr = decode_varint64(d, ptr, end, &elem.uint64_val);
+        ptr = decode_varint64(d, ptr, &elem.uint64_val);
         decode_munge(field->descriptortype, &elem);
         if (decode_reserve(d, arr, 1)) {
           out = UPB_PTR_AT(_upb_array_ptr(arr), arr->len << lg2, void);
@@ -398,7 +426,7 @@ static const char *decode_toarray(upb_decstate *d, const char *ptr,
         memcpy(out, &elem, scale);
         out += scale;
       }
-      if (ptr != end) decode_err(d);
+      decode_poplimit(d, ptr, saved_limit);
       return ptr;
     }
     default:
@@ -406,9 +434,9 @@ static const char *decode_toarray(upb_decstate *d, const char *ptr,
   }
 }
 
-static void decode_tomap(upb_decstate *d, upb_msg *msg,
-                         const upb_msglayout *layout,
-                         const upb_msglayout_field *field, wireval val) {
+static const char *decode_tomap(upb_decstate *d, const char *ptr, upb_msg *msg,
+                                const upb_msglayout *layout,
+                                const upb_msglayout_field *field, wireval val) {
   upb_map **map_p = UPB_PTR_AT(msg, field->offset, upb_map *);
   upb_map *map = *map_p;
   upb_map_entry ent;
@@ -423,7 +451,7 @@ static void decode_tomap(upb_decstate *d, upb_msg *msg,
     char val_size = desctype_to_mapsize[val_field->descriptortype];
     UPB_ASSERT(key_field->offset == 0);
     UPB_ASSERT(val_field->offset == sizeof(upb_strview));
-    map = _upb_map_new(d->arena, key_size, val_size);
+    map = _upb_map_new(&d->arena, key_size, val_size);
     *map_p = map;
   }
 
@@ -433,13 +461,12 @@ static void decode_tomap(upb_decstate *d, upb_msg *msg,
   if (entry->fields[1].descriptortype == UPB_DESCRIPTOR_TYPE_MESSAGE ||
       entry->fields[1].descriptortype == UPB_DESCRIPTOR_TYPE_GROUP) {
     /* Create proactively to handle the case where it doesn't appear. */
-    ent.v.val = upb_value_ptr(_upb_msg_new(entry->submsgs[0], d->arena));
+    ent.v.val = upb_value_ptr(_upb_msg_new(entry->submsgs[0], &d->arena));
   }
 
-  decode_tosubmsg(d, &ent.k, layout, field, val.str_val);
-
-  /* Insert into map. */
-  _upb_map_set(map, &ent.k, map->key_size, &ent.v, map->val_size, d->arena);
+  ptr = decode_tosubmsg(d, ptr, &ent.k, layout, field, val.size);
+  _upb_map_set(map, &ent.k, map->key_size, &ent.v, map->val_size, &d->arena);
+  return ptr;
 }
 
 static const char *decode_tomsg(upb_decstate *d, const char *ptr, upb_msg *msg,
@@ -473,16 +500,15 @@ static const char *decode_tomsg(upb_decstate *d, const char *ptr, upb_msg *msg,
       if (UPB_UNLIKELY(type == UPB_DTYPE_GROUP)) {
         ptr = decode_togroup(d, ptr, submsg, layout, field);
       } else {
-        decode_tosubmsg(d, submsg, layout, field, val.str_val);
+        ptr = decode_tosubmsg(d, ptr, submsg, layout, field, val.size);
       }
       break;
     }
     case OP_STRING:
-      decode_verifyutf8(d, val.str_val.data, val.str_val.size);
+      decode_verifyutf8(d, ptr, val.size);
       /* Fallthrough. */
     case OP_BYTES:
-      memcpy(mem, &val, sizeof(upb_strview));
-      break;
+      return decode_readstr(d, ptr, val.size, mem);
     case OP_SCALAR_LG2(3):
       memcpy(mem, &val, 8);
       break;
@@ -499,9 +525,24 @@ static const char *decode_tomsg(upb_decstate *d, const char *ptr, upb_msg *msg,
   return ptr;
 }
 
+UPB_FORCEINLINE
+static bool decode_tryfastdispatch(upb_decstate *d, const char **ptr,
+                                   upb_msg *msg, const upb_msglayout *layout) {
+#if UPB_FASTTABLE
+  if (layout && layout->table_mask != (unsigned char)-1) {
+    uint16_t tag = fastdecode_loadtag(*ptr);
+    intptr_t table = decode_totable(layout);
+    *ptr = fastdecode_tagdispatch(d, *ptr, msg, table, 0, tag);
+    return true;
+  }
+#endif
+  return false;
+}
+
+UPB_NOINLINE
 static const char *decode_msg(upb_decstate *d, const char *ptr, upb_msg *msg,
                               const upb_msglayout *layout) {
-  while (ptr < d->limit) {
+  while (true) {
     uint32_t tag;
     const upb_msglayout_field *field;
     int field_number;
@@ -510,7 +551,8 @@ static const char *decode_msg(upb_decstate *d, const char *ptr, upb_msg *msg,
     wireval val;
     int op;
 
-    ptr = decode_varint32(d, ptr, d->limit, &tag);
+    UPB_ASSERT(ptr < d->limit_ptr);
+    ptr = decode_tag(d, ptr, &tag);
     field_number = tag >> 3;
     wire_type = tag & 7;
 
@@ -518,12 +560,11 @@ static const char *decode_msg(upb_decstate *d, const char *ptr, upb_msg *msg,
 
     switch (wire_type) {
       case UPB_WIRE_TYPE_VARINT:
-        ptr = decode_varint64(d, ptr, d->limit, &val.uint64_val);
+        ptr = decode_varint64(d, ptr, &val.uint64_val);
         op = varint_ops[field->descriptortype];
         decode_munge(field->descriptortype, &val);
         break;
       case UPB_WIRE_TYPE_32BIT:
-        if (d->limit - ptr < 4) decode_err(d);
         memcpy(&val.uint32_val, ptr, 4);
         val.uint32_val = _upb_be_swap32(val.uint32_val);
         ptr += 4;
@@ -531,7 +572,6 @@ static const char *decode_msg(upb_decstate *d, const char *ptr, upb_msg *msg,
         if (((1 << field->descriptortype) & fixed32_ok) == 0) goto unknown;
         break;
       case UPB_WIRE_TYPE_64BIT:
-        if (d->limit - ptr < 8) decode_err(d);
         memcpy(&val.uint64_val, ptr, 8);
         val.uint64_val = _upb_be_swap64(val.uint64_val);
         ptr += 8;
@@ -539,17 +579,16 @@ static const char *decode_msg(upb_decstate *d, const char *ptr, upb_msg *msg,
         if (((1 << field->descriptortype) & fixed64_ok) == 0) goto unknown;
         break;
       case UPB_WIRE_TYPE_DELIMITED: {
-        uint32_t size;
         int ndx = field->descriptortype;
+        uint64_t size;
         if (_upb_isrepeated(field)) ndx += 18;
-        ptr = decode_varint32(d, ptr, d->limit, &size);
-        if (size >= INT32_MAX || (size_t)(d->limit - ptr) < size) {
+        ptr = decode_varint64(d, ptr, &size);
+        if (size >= INT32_MAX ||
+            ptr - d->end + (int32_t)size > d->limit) {
           decode_err(d); /* Length overflow. */
         }
-        val.str_val.data = ptr;
-        val.str_val.size = size;
-        ptr += size;
         op = delim_ops[ndx];
+        val.size = size;
         break;
       }
       case UPB_WIRE_TYPE_START_GROUP:
@@ -572,7 +611,7 @@ static const char *decode_msg(upb_decstate *d, const char *ptr, upb_msg *msg,
           ptr = decode_toarray(d, ptr, msg, layout, field, val, op);
           break;
         case _UPB_LABEL_MAP:
-          decode_tomap(d, msg, layout, field, val);
+          ptr = decode_tomap(d, ptr, msg, layout, field, val);
           break;
         default:
           ptr = decode_tomsg(d, ptr, msg, layout, field, val, op);
@@ -582,36 +621,78 @@ static const char *decode_msg(upb_decstate *d, const char *ptr, upb_msg *msg,
     unknown:
       /* Skip unknown field. */
       if (field_number == 0) decode_err(d);
-      if (wire_type == UPB_WIRE_TYPE_START_GROUP) {
-        ptr = decode_group(d, ptr, NULL, NULL, field_number);
-      }
+      if (wire_type == UPB_WIRE_TYPE_DELIMITED) ptr += val.size;
       if (msg) {
+        if (wire_type == UPB_WIRE_TYPE_START_GROUP) {
+          d->unknown = field_start;
+          d->unknown_msg = msg;
+          ptr = decode_group(d, ptr, NULL, NULL, field_number);
+          d->unknown_msg = NULL;
+          field_start = d->unknown;
+        }
         if (!_upb_msg_addunknown(msg, field_start, ptr - field_start,
-                                 d->arena)) {
+                                 &d->arena)) {
           decode_err(d);
         }
+      } else if (wire_type == UPB_WIRE_TYPE_START_GROUP) {
+        ptr = decode_group(d, ptr, NULL, NULL, field_number);
       }
     }
+
+    if (decode_isdone(d, &ptr)) return ptr;
+    if (decode_tryfastdispatch(d, &ptr, msg, layout)) return ptr;
   }
+}
 
-  if (ptr != d->limit) decode_err(d);
-  return ptr;
+const char *fastdecode_generic(struct upb_decstate *d, const char *ptr,
+                               upb_msg *msg, intptr_t table, uint64_t hasbits,
+                               uint64_t data) {
+  (void)data;
+  *(uint32_t*)msg |= hasbits;
+  return decode_msg(d, ptr, msg, decode_totablep(table));
 }
 
-bool upb_decode(const char *buf, size_t size, void *msg, const upb_msglayout *l,
-                upb_arena *arena) {
+bool _upb_decode(const char *buf, size_t size, void *msg,
+                 const upb_msglayout *l, upb_arena *arena, int options) {
+  bool ok;
   upb_decstate state;
-  state.limit = buf + size;
-  state.arena = arena;
-  state.depth = 64;
-  state.end_group = 0;
+  unsigned depth = (unsigned)options >> 16;
+
+  if (size == 0) {
+    return true;
+  } else if (size <= 16) {
+    memset(&state.patch, 0, 32);
+    memcpy(&state.patch, buf, size);
+    buf = state.patch;
+    state.end = buf + size;
+    state.limit = 0;
+    state.alias = false;
+  } else {
+    state.end = buf + size - 16;
+    state.limit = 16;
+    state.alias = options & UPB_DECODE_ALIAS;
+  }
 
-  if (setjmp(state.err)) return false;
+  state.limit_ptr = state.end;
+  state.unknown_msg = NULL;
+  state.depth = depth ? depth : 64;
+  state.end_group = DECODE_NOGROUP;
+  state.arena.head = arena->head;
+  state.arena.last_size = arena->last_size;
+  state.arena.parent = arena;
 
-  if (size == 0) return true;
-  decode_msg(&state, buf, msg, l);
+  if (UPB_UNLIKELY(UPB_SETJMP(state.err))) {
+    ok = false;
+  } else {
+    if (!decode_tryfastdispatch(&state, &buf, msg, l)) {
+      decode_msg(&state, buf, msg, l);
+    }
+    ok = state.end_group == DECODE_NOGROUP;
+  }
 
-  return state.end_group == 0;
+  arena->head.ptr = state.arena.head.ptr;
+  arena->head.end = state.arena.head.end;
+  return ok;
 }
 
 #undef OP_SCALAR_LG2
index 9de8638..eff4b8b 100644 (file)
@@ -7,15 +7,34 @@
 
 #include "upb/msg.h"
 
+/* Must be last. */
+#include "upb/port_def.inc"
+
 #ifdef __cplusplus
 extern "C" {
 #endif
 
+enum {
+  /* If set, strings will alias the input buffer instead of copying into the
+   * arena. */
+  UPB_DECODE_ALIAS = 1,
+};
+
+#define UPB_DECODE_MAXDEPTH(depth) ((depth) << 16)
+
+bool _upb_decode(const char *buf, size_t size, upb_msg *msg,
+                 const upb_msglayout *l, upb_arena *arena, int options);
+
+UPB_INLINE
 bool upb_decode(const char *buf, size_t size, upb_msg *msg,
-                const upb_msglayout *l, upb_arena *arena);
+                const upb_msglayout *l, upb_arena *arena) {
+  return _upb_decode(buf, size, msg, l, arena, 0);
+}
 
 #ifdef __cplusplus
 }  /* extern "C" */
 #endif
 
+#include "upb/port_undef.inc"
+
 #endif  /* UPB_DECODE_H_ */
diff --git a/third_party/upb/upb/decode.int.h b/third_party/upb/upb/decode.int.h
new file mode 100644 (file)
index 0000000..e286b9c
--- /dev/null
@@ -0,0 +1,163 @@
+/*
+** Internal implementation details of the decoder that are shared between
+** decode.c and decode_fast.c.
+*/
+
+#ifndef UPB_DECODE_INT_H_
+#define UPB_DECODE_INT_H_
+
+#include <setjmp.h>
+
+#include "upb/msg.h"
+#include "upb/upb.int.h"
+
+/* Must be last. */
+#include "upb/port_def.inc"
+
+#define DECODE_NOGROUP -1
+
+typedef struct upb_decstate {
+  const char *end;         /* Can read up to 16 bytes slop beyond this. */
+  const char *limit_ptr;   /* = end + UPB_MIN(limit, 0) */
+  upb_msg *unknown_msg;    /* If non-NULL, add unknown data at buffer flip. */
+  const char *unknown;     /* Start of unknown data. */
+  int limit;               /* Submessage limit relative to end. */
+  int depth;
+  uint32_t end_group;   /* field number of END_GROUP tag, else DECODE_NOGROUP */
+  bool alias;
+  char patch[32];
+  upb_arena arena;
+  jmp_buf err;
+} upb_decstate;
+
+/* Error function that will abort decoding with longjmp(). We can't declare this
+ * UPB_NORETURN, even though it is appropriate, because if we do then compilers
+ * will "helpfully" refuse to tailcall to it
+ * (see: https://stackoverflow.com/a/55657013), which will defeat a major goal
+ * of our optimizations. That is also why we must declare it in a separate file,
+ * otherwise the compiler will see that it calls longjmp() and deduce that it is
+ * noreturn. */
+const char *fastdecode_err(upb_decstate *d);
+
+extern const uint8_t upb_utf8_offsets[];
+
+UPB_INLINE
+bool decode_verifyutf8_inl(const char *buf, int len) {
+  int i, j;
+  uint8_t offset;
+
+  i = 0;
+  while (i < len) {
+    offset = upb_utf8_offsets[(uint8_t)buf[i]];
+    if (offset == 0 || i + offset > len) {
+      return false;
+    }
+    for (j = i + 1; j < i + offset; j++) {
+      if ((buf[j] & 0xc0) != 0x80) {
+        return false;
+      }
+    }
+    i += offset;
+  }
+  return i == len;
+}
+
+/* x86-64 pointers always have the high 16 bits matching. So we can shift
+ * left 8 and right 8 without loss of information. */
+UPB_INLINE intptr_t decode_totable(const upb_msglayout *tablep) {
+  return ((intptr_t)tablep << 8) | tablep->table_mask;
+}
+
+UPB_INLINE const upb_msglayout *decode_totablep(intptr_t table) {
+  return (const upb_msglayout*)(table >> 8);
+}
+
+UPB_INLINE
+const char *decode_isdonefallback_inl(upb_decstate *d, const char *ptr,
+                                      int overrun) {
+  if (overrun < d->limit) {
+    /* Need to copy remaining data into patch buffer. */
+    UPB_ASSERT(overrun < 16);
+    if (d->unknown_msg) {
+      if (!_upb_msg_addunknown(d->unknown_msg, d->unknown, ptr - d->unknown,
+                               &d->arena)) {
+        return NULL;
+      }
+      d->unknown = &d->patch[0] + overrun;
+    }
+    memset(d->patch + 16, 0, 16);
+    memcpy(d->patch, d->end, 16);
+    ptr = &d->patch[0] + overrun;
+    d->end = &d->patch[16];
+    d->limit -= 16;
+    d->limit_ptr = d->end + d->limit;
+    d->alias = false;
+    UPB_ASSERT(ptr < d->limit_ptr);
+    return ptr;
+  } else {
+    return NULL;
+  }
+}
+
+const char *decode_isdonefallback(upb_decstate *d, const char *ptr,
+                                  int overrun);
+
+UPB_INLINE
+bool decode_isdone(upb_decstate *d, const char **ptr) {
+  int overrun = *ptr - d->end;
+  if (UPB_LIKELY(*ptr < d->limit_ptr)) {
+    return false;
+  } else if (UPB_LIKELY(overrun == d->limit)) {
+    return true;
+  } else {
+    *ptr = decode_isdonefallback(d, *ptr, overrun);
+    return false;
+  }
+}
+
+UPB_INLINE
+const char *fastdecode_tagdispatch(upb_decstate *d, const char *ptr,
+                                    upb_msg *msg, intptr_t table,
+                                    uint64_t hasbits, uint32_t tag) {
+  const upb_msglayout *table_p = decode_totablep(table);
+  uint8_t mask = table;
+  uint64_t data;
+  size_t idx = tag & mask;
+  UPB_ASSUME((idx & 7) == 0);
+  idx >>= 3;
+  data = table_p->fasttable[idx].field_data ^ tag;
+  return table_p->fasttable[idx].field_parser(d, ptr, msg, table, hasbits, data);
+}
+
+UPB_INLINE uint32_t fastdecode_loadtag(const char* ptr) {
+  uint16_t tag;
+  memcpy(&tag, ptr, 2);
+  return tag;
+}
+
+UPB_INLINE void decode_checklimit(upb_decstate *d) {
+  UPB_ASSERT(d->limit_ptr == d->end + UPB_MIN(0, d->limit));
+}
+
+UPB_INLINE int decode_pushlimit(upb_decstate *d, const char *ptr, int size) {
+  int limit = size + (int)(ptr - d->end);
+  int delta = d->limit - limit;
+  decode_checklimit(d);
+  d->limit = limit;
+  d->limit_ptr = d->end + UPB_MIN(0, limit);
+  decode_checklimit(d);
+  return delta;
+}
+
+UPB_INLINE void decode_poplimit(upb_decstate *d, const char *ptr,
+                                int saved_delta) {
+  UPB_ASSERT(ptr - d->end == d->limit);
+  decode_checklimit(d);
+  d->limit += saved_delta;
+  d->limit_ptr = d->end + UPB_MIN(0, d->limit);
+  decode_checklimit(d);
+}
+
+#include "upb/port_undef.inc"
+
+#endif  /* UPB_DECODE_INT_H_ */
diff --git a/third_party/upb/upb/decode_fast.c b/third_party/upb/upb/decode_fast.c
new file mode 100644 (file)
index 0000000..f628e6d
--- /dev/null
@@ -0,0 +1,1040 @@
+// Fast decoder: ~3x the speed of decode.c, but x86-64 specific.
+// Also the table size grows by 2x.
+//
+// Could potentially be ported to ARM64 or other 64-bit archs that pass at
+// least six arguments in registers.
+//
+// The overall design is to create specialized functions for every possible
+// field type (eg. oneof boolean field with a 1 byte tag) and then dispatch
+// to the specialized function as quickly as possible.
+
+#include "upb/decode_fast.h"
+
+#include "upb/decode.int.h"
+
+/* Must be last. */
+#include "upb/port_def.inc"
+
+#if UPB_FASTTABLE
+
+// The standard set of arguments passed to each parsing function.
+// Thanks to x86-64 calling conventions, these will stay in registers.
+#define UPB_PARSE_PARAMS                                          \
+  upb_decstate *d, const char *ptr, upb_msg *msg, intptr_t table, \
+      uint64_t hasbits, uint64_t data
+
+#define UPB_PARSE_ARGS d, ptr, msg, table, hasbits, data
+
+#define RETURN_GENERIC(m)  \
+  /* fprintf(stderr, m); */ \
+  return fastdecode_generic(d, ptr, msg, table, hasbits, 0);
+
+typedef enum {
+  CARD_s = 0,  /* Singular (optional, non-repeated) */
+  CARD_o = 1,  /* Oneof */
+  CARD_r = 2,  /* Repeated */
+  CARD_p = 3   /* Packed Repeated */
+} upb_card;
+
+UPB_NOINLINE
+static const char *fastdecode_isdonefallback(upb_decstate *d, const char *ptr,
+                                             upb_msg *msg, intptr_t table,
+                                             uint64_t hasbits, int overrun) {
+  ptr = decode_isdonefallback_inl(d, ptr, overrun);
+  if (ptr == NULL) {
+    return fastdecode_err(d);
+  }
+  uint16_t tag = fastdecode_loadtag(ptr);
+  return fastdecode_tagdispatch(d, ptr, msg, table, hasbits, tag);
+}
+
+UPB_FORCEINLINE
+static const char *fastdecode_dispatch(upb_decstate *d, const char *ptr,
+                                       upb_msg *msg, intptr_t table,
+                                       uint64_t hasbits) {
+  if (UPB_UNLIKELY(ptr >= d->limit_ptr)) {
+    int overrun = ptr - d->end;
+    if (UPB_LIKELY(overrun == d->limit)) {
+      // Parse is finished.
+      *(uint32_t*)msg |= hasbits;  // Sync hasbits.
+      return ptr;
+    } else {
+      return fastdecode_isdonefallback(d, ptr, msg, table, hasbits, overrun);
+    }
+  }
+
+  // Read two bytes of tag data (for a one-byte tag, the high byte is junk).
+  uint16_t tag = fastdecode_loadtag(ptr);
+  return fastdecode_tagdispatch(d, ptr, msg, table, hasbits, tag);
+}
+
+UPB_FORCEINLINE
+static bool fastdecode_checktag(uint64_t data, int tagbytes) {
+  if (tagbytes == 1) {
+    return (data & 0xff) == 0;
+  } else {
+    return (data & 0xffff) == 0;
+  }
+}
+
+UPB_FORCEINLINE
+static const char *fastdecode_longsize(const char *ptr, int *size) {
+  int i;
+  UPB_ASSERT(*size & 0x80);
+  *size &= 0xff;
+  for (i = 0; i < 3; i++) {
+    ptr++;
+    size_t byte = (uint8_t)ptr[-1];
+    *size += (byte - 1) << (7 + 7 * i);
+    if (UPB_LIKELY((byte & 0x80) == 0)) return ptr;
+  }
+  ptr++;
+  size_t byte = (uint8_t)ptr[-1];
+  // len is limited by 2gb not 4gb, hence 8 and not 16 as normally expected
+  // for a 32 bit varint.
+  if (UPB_UNLIKELY(byte >= 8)) return NULL;
+  *size += (byte - 1) << 28;
+  return ptr;
+}
+
+UPB_FORCEINLINE
+static bool fastdecode_boundscheck(const char *ptr, size_t len,
+                                   const char *end) {
+  uintptr_t uptr = (uintptr_t)ptr;
+  uintptr_t uend = (uintptr_t)end + 16;
+  uintptr_t res = uptr + len;
+  return res < uptr || res > uend;
+}
+
+UPB_FORCEINLINE
+static bool fastdecode_boundscheck2(const char *ptr, size_t len,
+                                    const char *end) {
+  // This is one extra branch compared to the more normal:
+  //   return (size_t)(end - ptr) < size;
+  // However it is one less computation if we are just about to use "ptr + len":
+  //   https://godbolt.org/z/35YGPz
+  // In microbenchmarks this shows an overall 4% improvement.
+  uintptr_t uptr = (uintptr_t)ptr;
+  uintptr_t uend = (uintptr_t)end;
+  uintptr_t res = uptr + len;
+  return res < uptr || res > uend;
+}
+
+typedef const char *fastdecode_delimfunc(upb_decstate *d, const char *ptr,
+                                         void *ctx);
+
+UPB_FORCEINLINE
+static const char *fastdecode_delimited(upb_decstate *d, const char *ptr,
+                                        fastdecode_delimfunc *func, void *ctx) {
+  ptr++;
+  int len = (int8_t)ptr[-1];
+  if (fastdecode_boundscheck2(ptr, len, d->limit_ptr)) {
+    // Slow case: Sub-message is >=128 bytes and/or exceeds the current buffer.
+    // If it exceeds the buffer limit, limit/limit_ptr will change during
+    // sub-message parsing, so we need to preserve delta, not limit.
+    if (UPB_UNLIKELY(len & 0x80)) {
+      // Size varint >1 byte (length >= 128).
+      ptr = fastdecode_longsize(ptr, &len);
+      if (!ptr) {
+        // Corrupt wire format: size exceeded INT_MAX.
+        return NULL;
+      }
+    }
+    if (ptr - d->end + (int)len > d->limit) {
+      // Corrupt wire format: invalid limit.
+      return NULL;
+    }
+    int delta = decode_pushlimit(d, ptr, len);
+    ptr = func(d, ptr, ctx);
+    decode_poplimit(d, ptr, delta);
+  } else {
+    // Fast case: Sub-message is <128 bytes and fits in the current buffer.
+    // This means we can preserve limit/limit_ptr verbatim.
+    const char *saved_limit_ptr = d->limit_ptr;
+    int saved_limit = d->limit;
+    d->limit_ptr = ptr + len;
+    d->limit = d->limit_ptr - d->end;
+    UPB_ASSERT(d->limit_ptr == d->end + UPB_MIN(0, d->limit));
+    ptr = func(d, ptr, ctx);
+    d->limit_ptr = saved_limit_ptr;
+    d->limit = saved_limit;
+    UPB_ASSERT(d->limit_ptr == d->end + UPB_MIN(0, d->limit));
+  }
+  return ptr;
+}
+
+/* singular, oneof, repeated field handling ***********************************/
+
+typedef struct {
+  upb_array *arr;
+  void *end;
+} fastdecode_arr;
+
+typedef enum {
+  FD_NEXT_ATLIMIT,
+  FD_NEXT_SAMEFIELD,
+  FD_NEXT_OTHERFIELD
+} fastdecode_next;
+
+typedef struct {
+  void *dst;
+  fastdecode_next next;
+  uint32_t tag;
+} fastdecode_nextret;
+
+UPB_FORCEINLINE
+static void *fastdecode_resizearr(upb_decstate *d, void *dst,
+                                  fastdecode_arr *farr, int valbytes) {
+  if (UPB_UNLIKELY(dst == farr->end)) {
+    size_t old_size = farr->arr->size;
+    size_t old_bytes = old_size * valbytes;
+    size_t new_size = old_size * 2;
+    size_t new_bytes = new_size * valbytes;
+    char *old_ptr = _upb_array_ptr(farr->arr);
+    char *new_ptr = upb_arena_realloc(&d->arena, old_ptr, old_bytes, new_bytes);
+    uint8_t elem_size_lg2 = __builtin_ctz(valbytes);
+    farr->arr->size = new_size;
+    farr->arr->data = _upb_array_tagptr(new_ptr, elem_size_lg2);
+    dst = (void*)(new_ptr + (old_size * valbytes));
+    farr->end = (void*)(new_ptr + (new_size * valbytes));
+  }
+  return dst;
+}
+
+UPB_FORCEINLINE
+static bool fastdecode_tagmatch(uint32_t tag, uint64_t data, int tagbytes) {
+  if (tagbytes == 1) {
+    return (uint8_t)tag == (uint8_t)data;
+  } else {
+    return (uint16_t)tag == (uint16_t)data;
+  }
+}
+
+UPB_FORCEINLINE
+static void fastdecode_commitarr(void *dst, fastdecode_arr *farr,
+                                 int valbytes) {
+  farr->arr->len =
+      (size_t)((char *)dst - (char *)_upb_array_ptr(farr->arr)) / valbytes;
+}
+
+UPB_FORCEINLINE
+static fastdecode_nextret fastdecode_nextrepeated(upb_decstate *d, void *dst,
+                                                  const char **ptr,
+                                                  fastdecode_arr *farr,
+                                                  uint64_t data, int tagbytes,
+                                                  int valbytes) {
+  fastdecode_nextret ret;
+  dst = (char *)dst + valbytes;
+
+  if (UPB_LIKELY(!decode_isdone(d, ptr))) {
+    ret.tag = fastdecode_loadtag(*ptr);
+    if (fastdecode_tagmatch(ret.tag, data, tagbytes)) {
+      ret.next = FD_NEXT_SAMEFIELD;
+    } else {
+      fastdecode_commitarr(dst, farr, valbytes);
+      ret.next = FD_NEXT_OTHERFIELD;
+    }
+  } else {
+    fastdecode_commitarr(dst, farr, valbytes);
+    ret.next = FD_NEXT_ATLIMIT;
+  }
+
+  ret.dst = dst;
+  return ret;
+}
+
+UPB_FORCEINLINE
+static void *fastdecode_fieldmem(upb_msg *msg, uint64_t data) {
+  size_t ofs = data >> 48;
+  return (char *)msg + ofs;
+}
+
+UPB_FORCEINLINE
+static void *fastdecode_getfield(upb_decstate *d, const char *ptr, upb_msg *msg,
+                                 uint64_t *data, uint64_t *hasbits,
+                                 fastdecode_arr *farr, int valbytes,
+                                 upb_card card) {
+  switch (card) {
+    case CARD_s: {
+      uint8_t hasbit_index = *data >> 24;
+      // Set hasbit and return pointer to scalar field.
+      *hasbits |= 1ull << hasbit_index;
+      return fastdecode_fieldmem(msg, *data);
+    }
+    case CARD_o: {
+      uint16_t case_ofs = *data >> 32;
+      uint32_t *oneof_case = UPB_PTR_AT(msg, case_ofs, uint32_t);
+      uint8_t field_number = *data >> 24;
+      *oneof_case = field_number;
+      return fastdecode_fieldmem(msg, *data);
+    }
+    case CARD_r: {
+      // Get pointer to upb_array and allocate/expand if necessary.
+      uint8_t elem_size_lg2 = __builtin_ctz(valbytes);
+      upb_array **arr_p = fastdecode_fieldmem(msg, *data);
+      char *begin;
+      *(uint32_t*)msg |= *hasbits;
+      *hasbits = 0;
+      if (UPB_LIKELY(!*arr_p)) {
+        farr->arr = _upb_array_new(&d->arena, 8, elem_size_lg2);
+        *arr_p = farr->arr;
+      } else {
+        farr->arr = *arr_p;
+      }
+      begin = _upb_array_ptr(farr->arr);
+      farr->end = begin + (farr->arr->size * valbytes);
+      *data = fastdecode_loadtag(ptr);
+      return begin + (farr->arr->len * valbytes);
+    }
+    default:
+      UPB_UNREACHABLE();
+  }
+}
+
+UPB_FORCEINLINE
+static bool fastdecode_flippacked(uint64_t *data, int tagbytes) {
+  *data ^= (0x2 ^ 0x0);  // Patch data to match packed wiretype.
+  return fastdecode_checktag(*data, tagbytes);
+}
+
+/* varint fields **************************************************************/
+
+UPB_FORCEINLINE
+static uint64_t fastdecode_munge(uint64_t val, int valbytes, bool zigzag) {
+  if (valbytes == 1) {
+    return val != 0;
+  } else if (zigzag) {
+    if (valbytes == 4) {
+      uint32_t n = val;
+      return (n >> 1) ^ -(int32_t)(n & 1);
+    } else if (valbytes == 8) {
+      return (val >> 1) ^ -(int64_t)(val & 1);
+    }
+    UPB_UNREACHABLE();
+  }
+  return val;
+}
+
+UPB_FORCEINLINE
+static const char *fastdecode_varint64(const char *ptr, uint64_t *val) {
+  ptr++;
+  *val = (uint8_t)ptr[-1];
+  if (UPB_UNLIKELY(*val & 0x80)) {
+    int i;
+    for (i = 0; i < 8; i++) {
+      ptr++;
+      uint64_t byte = (uint8_t)ptr[-1];
+      *val += (byte - 1) << (7 + 7 * i);
+      if (UPB_LIKELY((byte & 0x80) == 0)) goto done;
+    }
+    ptr++;
+    uint64_t byte = (uint8_t)ptr[-1];
+    if (byte > 1) {
+      return NULL;
+    }
+    *val += (byte - 1) << 63;
+  }
+done:
+  UPB_ASSUME(ptr != NULL);
+  return ptr;
+}
+
+UPB_FORCEINLINE
+static const char *fastdecode_unpackedvarint(UPB_PARSE_PARAMS, int tagbytes,
+                                             int valbytes, upb_card card,
+                                             bool zigzag,
+                                             _upb_field_parser *packed) {
+  uint64_t val;
+  void *dst;
+  fastdecode_arr farr;
+
+  if (UPB_UNLIKELY(!fastdecode_checktag(data, tagbytes))) {
+    if (card == CARD_r && fastdecode_flippacked(&data, tagbytes)) {
+      return packed(UPB_PARSE_ARGS);
+    }
+    RETURN_GENERIC("varint field tag mismatch\n");
+  }
+
+  dst =
+      fastdecode_getfield(d, ptr, msg, &data, &hasbits, &farr, valbytes, card);
+  if (card == CARD_r) {
+    if (UPB_UNLIKELY(!dst)) {
+      RETURN_GENERIC("need array resize\n");
+    }
+  }
+
+again:
+  if (card == CARD_r) {
+    dst = fastdecode_resizearr(d, dst, &farr, valbytes);
+  }
+
+  ptr += tagbytes;
+  ptr = fastdecode_varint64(ptr, &val);
+  if (ptr == NULL) return fastdecode_err(d);
+  val = fastdecode_munge(val, valbytes, zigzag);
+  memcpy(dst, &val, valbytes);
+
+  if (card == CARD_r) {
+    fastdecode_nextret ret =
+        fastdecode_nextrepeated(d, dst, &ptr, &farr, data, tagbytes, valbytes);
+    switch (ret.next) {
+      case FD_NEXT_SAMEFIELD:
+        dst = ret.dst;
+        goto again;
+      case FD_NEXT_OTHERFIELD:
+        return fastdecode_tagdispatch(d, ptr, msg, table, hasbits, ret.tag);
+      case FD_NEXT_ATLIMIT:
+        return ptr;
+    }
+  }
+
+  return fastdecode_dispatch(d, ptr, msg, table, hasbits);
+}
+
+typedef struct {
+  uint8_t valbytes;
+  bool zigzag;
+  void *dst;
+  fastdecode_arr farr;
+} fastdecode_varintdata;
+
+UPB_FORCEINLINE
+static const char *fastdecode_topackedvarint(upb_decstate *d, const char *ptr,
+                                             void *ctx) {
+  fastdecode_varintdata *data = ctx;
+  void *dst = data->dst;
+  uint64_t val;
+
+  while (!decode_isdone(d, &ptr)) {
+    dst = fastdecode_resizearr(d, dst, &data->farr, data->valbytes);
+    ptr = fastdecode_varint64(ptr, &val);
+    if (ptr == NULL) return NULL;
+    val = fastdecode_munge(val, data->valbytes, data->zigzag);
+    memcpy(dst, &val, data->valbytes);
+    dst = (char *)dst + data->valbytes;
+  }
+
+  fastdecode_commitarr(dst, &data->farr, data->valbytes);
+  return ptr;
+}
+
+UPB_FORCEINLINE
+static const char *fastdecode_packedvarint(UPB_PARSE_PARAMS, int tagbytes,
+                                           int valbytes, bool zigzag,
+                                           _upb_field_parser *unpacked) {
+  fastdecode_varintdata ctx = {valbytes, zigzag};
+
+  if (UPB_UNLIKELY(!fastdecode_checktag(data, tagbytes))) {
+    if (fastdecode_flippacked(&data, tagbytes)) {
+      return unpacked(UPB_PARSE_ARGS);
+    } else {
+      RETURN_GENERIC("varint field tag mismatch\n");
+    }
+  }
+
+  ctx.dst = fastdecode_getfield(d, ptr, msg, &data, &hasbits, &ctx.farr,
+                                valbytes, CARD_r);
+  if (UPB_UNLIKELY(!ctx.dst)) {
+    RETURN_GENERIC("need array resize\n");
+  }
+
+  ptr += tagbytes;
+  ptr = fastdecode_delimited(d, ptr, &fastdecode_topackedvarint, &ctx);
+
+  if (UPB_UNLIKELY(ptr == NULL)) {
+    return fastdecode_err(d);
+  }
+
+  return fastdecode_dispatch(d, ptr, msg, table, hasbits);
+}
+
+UPB_FORCEINLINE
+static const char *fastdecode_varint(UPB_PARSE_PARAMS, int tagbytes,
+                                     int valbytes, upb_card card, bool zigzag,
+                                     _upb_field_parser *unpacked,
+                                     _upb_field_parser *packed) {
+  if (card == CARD_p) {
+    return fastdecode_packedvarint(UPB_PARSE_ARGS, tagbytes, valbytes, zigzag,
+                                   unpacked);
+  } else {
+    return fastdecode_unpackedvarint(UPB_PARSE_ARGS, tagbytes, valbytes, card,
+                                     zigzag, packed);
+  }
+}
+
+#define z_ZZ true
+#define b_ZZ false
+#define v_ZZ false
+
+/* Generate all combinations:
+ * {s,o,r,p} x {b1,v4,z4,v8,z8} x {1bt,2bt} */
+
+#define F(card, type, valbytes, tagbytes)                                      \
+  UPB_NOINLINE                                                                 \
+  const char *upb_p##card##type##valbytes##_##tagbytes##bt(UPB_PARSE_PARAMS) { \
+    return fastdecode_varint(UPB_PARSE_ARGS, tagbytes, valbytes, CARD_##card,  \
+                             type##_ZZ,                                        \
+                             &upb_pr##type##valbytes##_##tagbytes##bt,         \
+                             &upb_pp##type##valbytes##_##tagbytes##bt);        \
+  }
+
+#define TYPES(card, tagbytes) \
+  F(card, b, 1, tagbytes)     \
+  F(card, v, 4, tagbytes)     \
+  F(card, v, 8, tagbytes)     \
+  F(card, z, 4, tagbytes)     \
+  F(card, z, 8, tagbytes)
+
+#define TAGBYTES(card) \
+  TYPES(card, 1)       \
+  TYPES(card, 2)
+
+TAGBYTES(s)
+TAGBYTES(o)
+TAGBYTES(r)
+TAGBYTES(p)
+
+#undef z_ZZ
+#undef b_ZZ
+#undef v_ZZ
+#undef o_ONEOF
+#undef s_ONEOF
+#undef r_ONEOF
+#undef F
+#undef TYPES
+#undef TAGBYTES
+
+
+/* fixed fields ***************************************************************/
+
+UPB_FORCEINLINE
+static const char *fastdecode_unpackedfixed(UPB_PARSE_PARAMS, int tagbytes,
+                                            int valbytes, upb_card card,
+                                            _upb_field_parser *packed) {
+  void *dst;
+  fastdecode_arr farr;
+
+  if (UPB_UNLIKELY(!fastdecode_checktag(data, tagbytes))) {
+    if (card == CARD_r && fastdecode_flippacked(&data, tagbytes)) {
+      return packed(UPB_PARSE_ARGS);
+    }
+    RETURN_GENERIC("fixed field tag mismatch\n");
+  }
+
+  dst =
+      fastdecode_getfield(d, ptr, msg, &data, &hasbits, &farr, valbytes, card);
+  if (card == CARD_r) {
+    if (UPB_UNLIKELY(!dst)) {
+      RETURN_GENERIC("couldn't allocate array in arena\n");
+    }
+  }
+
+
+again:
+  if (card == CARD_r) {
+    dst = fastdecode_resizearr(d, dst, &farr, valbytes);
+  }
+
+  ptr += tagbytes;
+  memcpy(dst, ptr, valbytes);
+  ptr += valbytes;
+
+  if (card == CARD_r) {
+    fastdecode_nextret ret =
+        fastdecode_nextrepeated(d, dst, &ptr, &farr, data, tagbytes, valbytes);
+    switch (ret.next) {
+      case FD_NEXT_SAMEFIELD:
+        dst = ret.dst;
+        goto again;
+      case FD_NEXT_OTHERFIELD:
+        return fastdecode_tagdispatch(d, ptr, msg, table, hasbits, ret.tag);
+      case FD_NEXT_ATLIMIT:
+        return ptr;
+    }
+  }
+
+  return fastdecode_dispatch(d, ptr, msg, table, hasbits);
+}
+
+UPB_FORCEINLINE
+static const char *fastdecode_packedfixed(UPB_PARSE_PARAMS, int tagbytes,
+                                          int valbytes,
+                                          _upb_field_parser *unpacked) {
+  if (UPB_UNLIKELY(!fastdecode_checktag(data, tagbytes))) {
+    if (fastdecode_flippacked(&data, tagbytes)) {
+      return unpacked(UPB_PARSE_ARGS);
+    } else {
+      RETURN_GENERIC("varint field tag mismatch\n");
+    }
+  }
+
+  ptr += tagbytes;
+  int size = (uint8_t)ptr[0];
+  ptr++;
+  if (size & 0x80) {
+    ptr = fastdecode_longsize(ptr, &size);
+  }
+
+  if (UPB_UNLIKELY(fastdecode_boundscheck(ptr, size, d->limit_ptr)) ||
+      (size % valbytes) != 0) {
+    return fastdecode_err(d);
+  }
+
+  upb_array **arr_p = fastdecode_fieldmem(msg, data);
+  upb_array *arr = *arr_p;
+  uint8_t elem_size_lg2 = __builtin_ctz(valbytes);
+  int elems = size / valbytes;
+
+  if (UPB_LIKELY(!arr)) {
+    *arr_p = arr = _upb_array_new(&d->arena, elems, elem_size_lg2);
+    if (!arr) {
+      return fastdecode_err(d);
+    }
+  } else {
+    _upb_array_resize(arr, elems, &d->arena);
+  }
+
+  char *dst = _upb_array_ptr(arr);
+  memcpy(dst, ptr, size);
+  arr->len = elems;
+
+  return fastdecode_dispatch(d, ptr + size, msg, table, hasbits);
+}
+
+UPB_FORCEINLINE
+static const char *fastdecode_fixed(UPB_PARSE_PARAMS, int tagbytes,
+                                    int valbytes, upb_card card,
+                                    _upb_field_parser *unpacked,
+                                    _upb_field_parser *packed) {
+  if (card == CARD_p) {
+    return fastdecode_packedfixed(UPB_PARSE_ARGS, tagbytes, valbytes, unpacked);
+  } else {
+    return fastdecode_unpackedfixed(UPB_PARSE_ARGS, tagbytes, valbytes, card,
+                                    packed);
+  }
+}
+
+/* Generate all combinations:
+ * {s,o,r,p} x {f4,f8} x {1bt,2bt} */
+
+#define F(card, valbytes, tagbytes)                                          \
+  UPB_NOINLINE                                                               \
+  const char *upb_p##card##f##valbytes##_##tagbytes##bt(UPB_PARSE_PARAMS) {  \
+    return fastdecode_fixed(UPB_PARSE_ARGS, tagbytes, valbytes, CARD_##card, \
+                            &upb_ppf##valbytes##_##tagbytes##bt,             \
+                            &upb_prf##valbytes##_##tagbytes##bt);            \
+  }
+
+#define TYPES(card, tagbytes) \
+  F(card, 4, tagbytes)        \
+  F(card, 8, tagbytes)
+
+#define TAGBYTES(card) \
+  TYPES(card, 1)       \
+  TYPES(card, 2)
+
+TAGBYTES(s)
+TAGBYTES(o)
+TAGBYTES(r)
+TAGBYTES(p)
+
+#undef F
+#undef TYPES
+#undef TAGBYTES
+
+/* string fields **************************************************************/
+
+typedef const char *fastdecode_copystr_func(struct upb_decstate *d,
+                                            const char *ptr, upb_msg *msg,
+                                            const upb_msglayout *table,
+                                            uint64_t hasbits, upb_strview *dst);
+
+UPB_NOINLINE
+static const char *fastdecode_verifyutf8(upb_decstate *d, const char *ptr,
+                                         upb_msg *msg, intptr_t table,
+                                         uint64_t hasbits, upb_strview *dst) {
+  if (!decode_verifyutf8_inl(dst->data, dst->size)) {
+    return fastdecode_err(d);
+  }
+  return fastdecode_dispatch(d, ptr, msg, table, hasbits);
+}
+
+UPB_FORCEINLINE
+static const char *fastdecode_longstring(struct upb_decstate *d,
+                                         const char *ptr, upb_msg *msg,
+                                         intptr_t table, uint64_t hasbits,
+                                         upb_strview *dst,
+                                         bool validate_utf8) {
+  int size = (uint8_t)ptr[0];  // Could plumb through hasbits.
+  ptr++;
+  if (size & 0x80) {
+    ptr = fastdecode_longsize(ptr, &size);
+  }
+
+  if (UPB_UNLIKELY(fastdecode_boundscheck(ptr, size, d->limit_ptr))) {
+    dst->size = 0;
+    return fastdecode_err(d);
+  }
+
+  if (d->alias) {
+    dst->data = ptr;
+    dst->size = size;
+  } else {
+    char *data = upb_arena_malloc(&d->arena, size);
+    if (!data) {
+      return fastdecode_err(d);
+    }
+    memcpy(data, ptr, size);
+    dst->data = data;
+    dst->size = size;
+  }
+
+  if (validate_utf8) {
+    return fastdecode_verifyutf8(d, ptr + size, msg, table, hasbits, dst);
+  } else {
+    return fastdecode_dispatch(d, ptr + size, msg, table, hasbits);
+  }
+}
+
+UPB_NOINLINE
+static const char *fastdecode_longstring_utf8(struct upb_decstate *d,
+                                         const char *ptr, upb_msg *msg,
+                                         intptr_t table, uint64_t hasbits,
+                                         upb_strview *dst) {
+  return fastdecode_longstring(d, ptr, msg, table, hasbits, dst, true);
+}
+
+UPB_NOINLINE
+static const char *fastdecode_longstring_noutf8(struct upb_decstate *d,
+                                                const char *ptr, upb_msg *msg,
+                                                intptr_t table,
+                                                uint64_t hasbits,
+                                                upb_strview *dst) {
+  return fastdecode_longstring(d, ptr, msg, table, hasbits, dst, false);
+}
+
+UPB_FORCEINLINE
+static void fastdecode_docopy(upb_decstate *d, const char *ptr, uint32_t size,
+                              int copy, char *data, upb_strview *dst) {
+  d->arena.head.ptr += copy;
+  dst->data = data;
+  UPB_UNPOISON_MEMORY_REGION(data, copy);
+  memcpy(data, ptr, copy);
+  UPB_POISON_MEMORY_REGION(data + size, copy - size);
+}
+
+UPB_FORCEINLINE
+static const char *fastdecode_copystring(UPB_PARSE_PARAMS, int tagbytes,
+                                         upb_card card, bool validate_utf8) {
+  upb_strview *dst;
+  fastdecode_arr farr;
+  int64_t size;
+  size_t arena_has;
+  size_t common_has;
+  char *buf;
+
+  UPB_ASSERT(!d->alias);
+  UPB_ASSERT(fastdecode_checktag(data, tagbytes));
+
+  dst = fastdecode_getfield(d, ptr, msg, &data, &hasbits, &farr,
+                            sizeof(upb_strview), card);
+
+again:
+  if (card == CARD_r) {
+    dst = fastdecode_resizearr(d, dst, &farr, sizeof(upb_strview));
+  }
+
+  size = (uint8_t)ptr[tagbytes];
+  ptr += tagbytes + 1;
+  dst->size = size;
+
+  buf = d->arena.head.ptr;
+  arena_has = _upb_arenahas(&d->arena);
+  common_has = UPB_MIN(arena_has, (d->end - ptr) + 16);
+
+  if (UPB_LIKELY(size <= 15 - tagbytes)) {
+    if (arena_has < 16) goto longstr;
+    d->arena.head.ptr += 16;
+    memcpy(buf, ptr - tagbytes - 1, 16);
+    dst->data = buf + tagbytes + 1;
+  } else if (UPB_LIKELY(size <= 32)) {
+    if (UPB_UNLIKELY(common_has < 32)) goto longstr;
+    fastdecode_docopy(d, ptr, size, 32, buf, dst);
+  } else if (UPB_LIKELY(size <= 64)) {
+    if (UPB_UNLIKELY(common_has < 64)) goto longstr;
+    fastdecode_docopy(d, ptr, size, 64, buf, dst);
+  } else if (UPB_LIKELY(size < 128)) {
+    if (UPB_UNLIKELY(common_has < 128)) goto longstr;
+    fastdecode_docopy(d, ptr, size, 128, buf, dst);
+  } else {
+    goto longstr;
+  }
+
+  ptr += size;
+
+  if (card == CARD_r) {
+    if (validate_utf8 && !decode_verifyutf8_inl(dst->data, dst->size)) {
+      return fastdecode_err(d);
+    }
+    fastdecode_nextret ret = fastdecode_nextrepeated(
+        d, dst, &ptr, &farr, data, tagbytes, sizeof(upb_strview));
+    switch (ret.next) {
+      case FD_NEXT_SAMEFIELD:
+        dst = ret.dst;
+        goto again;
+      case FD_NEXT_OTHERFIELD:
+        return fastdecode_tagdispatch(d, ptr, msg, table, hasbits, ret.tag);
+      case FD_NEXT_ATLIMIT:
+        return ptr;
+    }
+  }
+
+  if (card != CARD_r && validate_utf8) {
+    return fastdecode_verifyutf8(d, ptr, msg, table, hasbits, dst);
+  }
+
+  return fastdecode_dispatch(d, ptr, msg, table, hasbits);
+
+longstr:
+  ptr--;
+  if (validate_utf8) {
+    return fastdecode_longstring_utf8(d, ptr, msg, table, hasbits, dst);
+  } else {
+    return fastdecode_longstring_noutf8(d, ptr, msg, table, hasbits, dst);
+  }
+}
+
+UPB_FORCEINLINE
+static const char *fastdecode_string(UPB_PARSE_PARAMS, int tagbytes,
+                                     upb_card card, _upb_field_parser *copyfunc,
+                                     bool validate_utf8) {
+  upb_strview *dst;
+  fastdecode_arr farr;
+  int64_t size;
+
+  if (UPB_UNLIKELY(!fastdecode_checktag(data, tagbytes))) {
+    RETURN_GENERIC("string field tag mismatch\n");
+  }
+
+  if (UPB_UNLIKELY(!d->alias)) {
+    return copyfunc(UPB_PARSE_ARGS);
+  }
+
+  dst = fastdecode_getfield(d, ptr, msg, &data, &hasbits, &farr,
+                            sizeof(upb_strview), card);
+
+again:
+  if (card == CARD_r) {
+    dst = fastdecode_resizearr(d, dst, &farr, sizeof(upb_strview));
+  }
+
+  size = (int8_t)ptr[tagbytes];
+  ptr += tagbytes + 1;
+  dst->data = ptr;
+  dst->size = size;
+
+  if (UPB_UNLIKELY(fastdecode_boundscheck(ptr, size, d->end))) {
+    ptr--;
+    if (validate_utf8) {
+      return fastdecode_longstring_utf8(d, ptr, msg, table, hasbits, dst);
+    } else {
+      return fastdecode_longstring_noutf8(d, ptr, msg, table, hasbits, dst);
+    }
+  }
+
+  ptr += size;
+
+  if (card == CARD_r) {
+    if (validate_utf8 && !decode_verifyutf8_inl(dst->data, dst->size)) {
+      return fastdecode_err(d);
+    }
+    fastdecode_nextret ret = fastdecode_nextrepeated(
+        d, dst, &ptr, &farr, data, tagbytes, sizeof(upb_strview));
+    switch (ret.next) {
+      case FD_NEXT_SAMEFIELD:
+        dst = ret.dst;
+        if (UPB_UNLIKELY(!d->alias)) {
+          // Buffer flipped and we can't alias any more. Bounce to copyfunc(),
+          // but via dispatch since we need to reload table data also.
+          fastdecode_commitarr(dst, &farr, sizeof(upb_strview));
+          return fastdecode_tagdispatch(d, ptr, msg, table, hasbits, ret.tag);
+        }
+        goto again;
+      case FD_NEXT_OTHERFIELD:
+        return fastdecode_tagdispatch(d, ptr, msg, table, hasbits, ret.tag);
+      case FD_NEXT_ATLIMIT:
+        return ptr;
+    }
+  }
+
+  if (card != CARD_r && validate_utf8) {
+    return fastdecode_verifyutf8(d, ptr, msg, table, hasbits, dst);
+  }
+
+  return fastdecode_dispatch(d, ptr, msg, table, hasbits);
+}
+
+/* Generate all combinations:
+ * {p,c} x {s,o,r} x {s, b} x {1bt,2bt} */
+
+#define s_VALIDATE true
+#define b_VALIDATE false
+
+#define F(card, tagbytes, type)                                         \
+  UPB_NOINLINE                                                          \
+  const char *upb_c##card##type##_##tagbytes##bt(UPB_PARSE_PARAMS) {    \
+    return fastdecode_copystring(UPB_PARSE_ARGS, tagbytes, CARD_##card, \
+                                 type##_VALIDATE);                      \
+  }                                                                     \
+  const char *upb_p##card##type##_##tagbytes##bt(UPB_PARSE_PARAMS) {    \
+    return fastdecode_string(UPB_PARSE_ARGS, tagbytes, CARD_##card,     \
+                             &upb_c##card##type##_##tagbytes##bt,       \
+                             type##_VALIDATE);                          \
+  }
+
+#define UTF8(card, tagbytes) \
+  F(card, tagbytes, s)       \
+  F(card, tagbytes, b)
+
+#define TAGBYTES(card) \
+  UTF8(card, 1)        \
+  UTF8(card, 2)
+
+TAGBYTES(s)
+TAGBYTES(o)
+TAGBYTES(r)
+
+#undef s_VALIDATE
+#undef b_VALIDATE
+#undef F
+#undef TAGBYTES
+
+/* message fields *************************************************************/
+
+UPB_INLINE
+upb_msg *decode_newmsg_ceil(upb_decstate *d, const upb_msglayout *l,
+                            int msg_ceil_bytes) {
+  size_t size = l->size + sizeof(upb_msg_internal);
+  char *msg_data;
+  if (UPB_LIKELY(msg_ceil_bytes > 0 &&
+                 _upb_arenahas(&d->arena) >= msg_ceil_bytes)) {
+    UPB_ASSERT(size <= (size_t)msg_ceil_bytes);
+    msg_data = d->arena.head.ptr;
+    d->arena.head.ptr += size;
+    UPB_UNPOISON_MEMORY_REGION(msg_data, msg_ceil_bytes);
+    memset(msg_data, 0, msg_ceil_bytes);
+    UPB_POISON_MEMORY_REGION(msg_data + size, msg_ceil_bytes - size);
+  } else {
+    msg_data = (char*)upb_arena_malloc(&d->arena, size);
+    memset(msg_data, 0, size);
+  }
+  return msg_data + sizeof(upb_msg_internal);
+}
+
+typedef struct {
+  intptr_t table;
+  upb_msg *msg;
+} fastdecode_submsgdata;
+
+UPB_FORCEINLINE
+static const char *fastdecode_tosubmsg(upb_decstate *d, const char *ptr,
+                                       void *ctx) {
+  fastdecode_submsgdata *submsg = ctx;
+  ptr = fastdecode_dispatch(d, ptr, submsg->msg, submsg->table, 0);
+  UPB_ASSUME(ptr != NULL);
+  return ptr;
+}
+
+UPB_FORCEINLINE
+static const char *fastdecode_submsg(UPB_PARSE_PARAMS, int tagbytes,
+                                     int msg_ceil_bytes, upb_card card) {
+
+  if (UPB_UNLIKELY(!fastdecode_checktag(data, tagbytes))) {
+    RETURN_GENERIC("submessage field tag mismatch\n");
+  }
+
+  if (--d->depth == 0) return fastdecode_err(d);
+
+  upb_msg **dst;
+  uint32_t submsg_idx = (data >> 16) & 0xff;
+  const upb_msglayout *tablep = decode_totablep(table);
+  const upb_msglayout *subtablep = tablep->submsgs[submsg_idx];
+  fastdecode_submsgdata submsg = {decode_totable(subtablep)};
+  fastdecode_arr farr;
+
+  if (subtablep->table_mask == (uint8_t)-1) {
+    RETURN_GENERIC("submessage doesn't have fast tables.");
+  }
+
+  dst = fastdecode_getfield(d, ptr, msg, &data, &hasbits, &farr,
+                            sizeof(upb_msg *), card);
+
+  if (card == CARD_s) {
+    *(uint32_t*)msg |= hasbits;
+    hasbits = 0;
+  }
+
+again:
+  if (card == CARD_r) {
+    dst = fastdecode_resizearr(d, dst, &farr, sizeof(upb_msg*));
+  }
+
+  submsg.msg = *dst;
+
+  if (card == CARD_r || UPB_LIKELY(!submsg.msg)) {
+    *dst = submsg.msg = decode_newmsg_ceil(d, subtablep, msg_ceil_bytes);
+  }
+
+  ptr += tagbytes;
+  ptr = fastdecode_delimited(d, ptr, fastdecode_tosubmsg, &submsg);
+
+  if (UPB_UNLIKELY(ptr == NULL || d->end_group != DECODE_NOGROUP)) {
+    return fastdecode_err(d);
+  }
+
+  if (card == CARD_r) {
+    fastdecode_nextret ret = fastdecode_nextrepeated(
+        d, dst, &ptr, &farr, data, tagbytes, sizeof(upb_msg *));
+    switch (ret.next) {
+      case FD_NEXT_SAMEFIELD:
+        dst = ret.dst;
+        goto again;
+      case FD_NEXT_OTHERFIELD:
+        d->depth++;
+        return fastdecode_tagdispatch(d, ptr, msg, table, hasbits, ret.tag);
+      case FD_NEXT_ATLIMIT:
+        d->depth++;
+        return ptr;
+    }
+  }
+
+  d->depth++;
+  return fastdecode_dispatch(d, ptr, msg, table, hasbits);
+}
+
+#define F(card, tagbytes, size_ceil, ceil_arg)                                 \
+  const char *upb_p##card##m_##tagbytes##bt_max##size_ceil##b(                 \
+      UPB_PARSE_PARAMS) {                                                      \
+    return fastdecode_submsg(UPB_PARSE_ARGS, tagbytes, ceil_arg, CARD_##card); \
+  }
+
+#define SIZES(card, tagbytes) \
+  F(card, tagbytes, 64, 64) \
+  F(card, tagbytes, 128, 128) \
+  F(card, tagbytes, 192, 192) \
+  F(card, tagbytes, 256, 256) \
+  F(card, tagbytes, max, -1)
+
+#define TAGBYTES(card) \
+  SIZES(card, 1) \
+  SIZES(card, 2)
+
+TAGBYTES(s)
+TAGBYTES(o)
+TAGBYTES(r)
+
+#undef TAGBYTES
+#undef SIZES
+#undef F
+
+#endif  /* UPB_FASTTABLE */
diff --git a/third_party/upb/upb/decode_fast.h b/third_party/upb/upb/decode_fast.h
new file mode 100644 (file)
index 0000000..6d56d12
--- /dev/null
@@ -0,0 +1,126 @@
+// These are the specialized field parser functions for the fast parser.
+// Generated tables will refer to these by name.
+//
+// The function names are encoded with names like:
+//
+//   //  123 4
+//   upb_pss_1bt();   // Parse singular string, 1 byte tag.
+//
+// In position 1:
+//   - 'p' for parse, most function use this
+//   - 'c' for copy, for when we are copying strings instead of aliasing
+//
+// In position 2 (cardinality):
+//   - 's' for singular, with or without hasbit
+//   - 'o' for oneof
+//   - 'r' for non-packed repeated
+//   - 'p' for packed repeated
+//
+// In position 3 (type):
+//   - 'b1' for bool
+//   - 'v4' for 4-byte varint
+//   - 'v8' for 8-byte varint
+//   - 'z4' for zig-zag-encoded 4-byte varint
+//   - 'z8' for zig-zag-encoded 8-byte varint
+//   - 'f4' for 4-byte fixed
+//   - 'f8' for 8-byte fixed
+//   - 'm' for sub-message
+//   - 's' for string (validate UTF-8)
+//   - 'b' for bytes
+//
+// In position 4 (tag length):
+//   - '1' for one-byte tags (field numbers 1-15)
+//   - '2' for two-byte tags (field numbers 16-2048)
+
+#ifndef UPB_DECODE_FAST_H_
+#define UPB_DECODE_FAST_H_
+
+#include "upb/msg.h"
+
+struct upb_decstate;
+
+// The fallback, generic parsing function that can handle any field type.
+// This just uses the regular (non-fast) parser to parse a single field.
+const char *fastdecode_generic(struct upb_decstate *d, const char *ptr,
+                               upb_msg *msg, intptr_t table, uint64_t hasbits,
+                               uint64_t data);
+
+#define UPB_PARSE_PARAMS                                                 \
+  struct upb_decstate *d, const char *ptr, upb_msg *msg, intptr_t table, \
+      uint64_t hasbits, uint64_t data
+
+/* primitive fields ***********************************************************/
+
+#define F(card, type, valbytes, tagbytes) \
+  const char *upb_p##card##type##valbytes##_##tagbytes##bt(UPB_PARSE_PARAMS);
+
+#define TYPES(card, tagbytes) \
+  F(card, b, 1, tagbytes)     \
+  F(card, v, 4, tagbytes)     \
+  F(card, v, 8, tagbytes)     \
+  F(card, z, 4, tagbytes)     \
+  F(card, z, 8, tagbytes)     \
+  F(card, f, 4, tagbytes)     \
+  F(card, f, 8, tagbytes)
+
+#define TAGBYTES(card) \
+  TYPES(card, 1)       \
+  TYPES(card, 2)
+
+TAGBYTES(s)
+TAGBYTES(o)
+TAGBYTES(r)
+TAGBYTES(p)
+
+#undef F
+#undef TYPES
+#undef TAGBYTES
+
+/* string fields **************************************************************/
+
+#define F(card, tagbytes, type)                                     \
+  const char *upb_p##card##type##_##tagbytes##bt(UPB_PARSE_PARAMS); \
+  const char *upb_c##card##type##_##tagbytes##bt(UPB_PARSE_PARAMS);
+
+#define UTF8(card, tagbytes) \
+  F(card, tagbytes, s)       \
+  F(card, tagbytes, b)
+
+#define TAGBYTES(card) \
+  UTF8(card, 1)        \
+  UTF8(card, 2)
+
+TAGBYTES(s)
+TAGBYTES(o)
+TAGBYTES(r)
+
+#undef F
+#undef TAGBYTES
+
+/* sub-message fields *********************************************************/
+
+#define F(card, tagbytes, size_ceil, ceil_arg) \
+  const char *upb_p##card##m_##tagbytes##bt_max##size_ceil##b(UPB_PARSE_PARAMS);
+
+#define SIZES(card, tagbytes) \
+  F(card, tagbytes, 64, 64) \
+  F(card, tagbytes, 128, 128) \
+  F(card, tagbytes, 192, 192) \
+  F(card, tagbytes, 256, 256) \
+  F(card, tagbytes, max, -1)
+
+#define TAGBYTES(card) \
+  SIZES(card, 1) \
+  SIZES(card, 2)
+
+TAGBYTES(s)
+TAGBYTES(o)
+TAGBYTES(r)
+
+#undef TAGBYTES
+#undef SIZES
+#undef F
+
+#undef UPB_PARSE_PARAMS
+
+#endif  /* UPB_DECODE_FAST_H_ */
index 00a5877..4ba553a 100644 (file)
@@ -3,10 +3,11 @@
 
 #include <ctype.h>
 #include <errno.h>
+#include <setjmp.h>
 #include <stdlib.h>
 #include <string.h>
-#include "google/protobuf/descriptor.upb.h"
 
+#include "google/protobuf/descriptor.upb.h"
 #include "upb/port_def.inc"
 
 typedef struct {
@@ -14,15 +15,6 @@ typedef struct {
   char str[1];  /* Null-terminated string data follows. */
 } str_t;
 
-static str_t *newstr(upb_alloc *alloc, const char *data, size_t len) {
-  str_t *ret = upb_malloc(alloc, sizeof(*ret) + len);
-  if (!ret) return NULL;
-  ret->len = len;
-  if (len) memcpy(ret->str, data, len);
-  ret->str[len] = '\0';
-  return ret;
-}
-
 struct upb_fielddef {
   const upb_filedef *file;
   const upb_msgdef *msgdef;
@@ -89,7 +81,9 @@ struct upb_enumdef {
 struct upb_oneofdef {
   const upb_msgdef *parent;
   const char *full_name;
-  uint32_t index;
+  int field_count;
+  bool synthetic;
+  const upb_fielddef **fields;
   upb_strtable ntof;
   upb_inttable itof;
 };
@@ -99,23 +93,25 @@ struct upb_filedef {
   const char *package;
   const char *phpprefix;
   const char *phpnamespace;
-  upb_syntax_t syntax;
 
   const upb_filedef **deps;
   const upb_msgdef *msgs;
   const upb_enumdef *enums;
   const upb_fielddef *exts;
+  const upb_symtab *symtab;
 
   int dep_count;
   int msg_count;
   int enum_count;
   int ext_count;
+  upb_syntax_t syntax;
 };
 
 struct upb_symtab {
   upb_arena *arena;
   upb_strtable syms;  /* full_name -> packed def ptr */
   upb_strtable files;  /* file_name -> upb_filedef* */
+  size_t bytes_loaded;
 };
 
 /* Inside a symtab we store tagged pointers to specific def types. */
@@ -154,38 +150,6 @@ static bool upb_isalphanum(char c) {
   return upb_isletter(c) || upb_isbetween(c, '0', '9');
 }
 
-static bool upb_isident(upb_strview name, bool full, upb_status *s) {
-  const char *str = name.data;
-  size_t len = name.size;
-  bool start = true;
-  size_t i;
-  for (i = 0; i < len; i++) {
-    char c = str[i];
-    if (c == '.') {
-      if (start || !full) {
-        upb_status_seterrf(s, "invalid name: unexpected '.' (%s)", str);
-        return false;
-      }
-      start = true;
-    } else if (start) {
-      if (!upb_isletter(c)) {
-        upb_status_seterrf(
-            s, "invalid name: path components must start with a letter (%s)",
-            str);
-        return false;
-      }
-      start = false;
-    } else {
-      if (!upb_isalphanum(c)) {
-        upb_status_seterrf(s, "invalid name: non-alphanumeric character (%s)",
-                           str);
-        return false;
-      }
-    }
-  }
-  return !start;
-}
-
 static const char *shortdefname(const char *fullname) {
   const char *p;
 
@@ -245,85 +209,6 @@ static void upb_status_setoom(upb_status *status) {
   upb_status_seterrmsg(status, "out of memory");
 }
 
-static bool assign_msg_indices(upb_msgdef *m, upb_status *s) {
-  /* Sort fields.  upb internally relies on UPB_TYPE_MESSAGE fields having the
-   * lowest indexes, but we do not publicly guarantee this. */
-  upb_msg_field_iter j;
-  int i;
-  uint32_t selector;
-  int n = upb_msgdef_numfields(m);
-  upb_fielddef **fields;
-
-  if (n == 0) {
-    m->selector_count = UPB_STATIC_SELECTOR_COUNT;
-    m->submsg_field_count = 0;
-    return true;
-  }
-
-  fields = upb_gmalloc(n * sizeof(*fields));
-  if (!fields) {
-    upb_status_setoom(s);
-    return false;
-  }
-
-  m->submsg_field_count = 0;
-  for(i = 0, upb_msg_field_begin(&j, m);
-      !upb_msg_field_done(&j);
-      upb_msg_field_next(&j), i++) {
-    upb_fielddef *f = upb_msg_iter_field(&j);
-    UPB_ASSERT(f->msgdef == m);
-    if (upb_fielddef_issubmsg(f)) {
-      m->submsg_field_count++;
-    }
-    fields[i] = f;
-  }
-
-  qsort(fields, n, sizeof(*fields), cmp_fields);
-
-  selector = UPB_STATIC_SELECTOR_COUNT + m->submsg_field_count;
-  for (i = 0; i < n; i++) {
-    upb_fielddef *f = fields[i];
-    f->index_ = i;
-    f->selector_base = selector + upb_handlers_selectorbaseoffset(f);
-    selector += upb_handlers_selectorcount(f);
-  }
-  m->selector_count = selector;
-
-  upb_gfree(fields);
-  return true;
-}
-
-static bool check_oneofs(upb_msgdef *m, upb_status *s) {
-  int i;
-  int first_synthetic = -1;
-  upb_oneofdef *mutable_oneofs = (upb_oneofdef*)m->oneofs;
-
-  for (i = 0; i < m->oneof_count; i++) {
-    mutable_oneofs[i].index = i;
-
-    if (upb_oneofdef_issynthetic(&mutable_oneofs[i])) {
-      if (first_synthetic == -1) {
-        first_synthetic = i;
-      }
-    } else {
-      if (first_synthetic != -1) {
-        upb_status_seterrf(
-            s, "Synthetic oneofs must be after all other oneofs: %s",
-            upb_oneofdef_name(&mutable_oneofs[i]));
-        return false;
-      }
-    }
-  }
-
-  if (first_synthetic == -1) {
-    m->real_oneof_count = m->oneof_count;
-  } else {
-    m->real_oneof_count = first_synthetic;
-  }
-
-  return true;
-}
-
 static void assign_msg_wellknowntype(upb_msgdef *m) {
   const char *name = upb_msgdef_fullname(m);
   if (name == NULL) {
@@ -726,15 +611,32 @@ int upb_msgdef_numrealoneofs(const upb_msgdef *m) {
   return m->real_oneof_count;
 }
 
+int upb_msgdef_fieldcount(const upb_msgdef *m) {
+  return m->field_count;
+}
+
+int upb_msgdef_oneofcount(const upb_msgdef *m) {
+  return m->oneof_count;
+}
+
+int upb_msgdef_realoneofcount(const upb_msgdef *m) {
+  return m->real_oneof_count;
+}
+
 const upb_msglayout *upb_msgdef_layout(const upb_msgdef *m) {
   return m->layout;
 }
 
-const upb_fielddef *_upb_msgdef_field(const upb_msgdef *m, int i) {
-  if (i >= m->field_count) return NULL;
+const upb_fielddef *upb_msgdef_field(const upb_msgdef *m, int i) {
+  UPB_ASSERT(i >= 0 && i < m->field_count);
   return &m->fields[i];
 }
 
+const upb_oneofdef *upb_msgdef_oneof(const upb_msgdef *m, int i) {
+  UPB_ASSERT(i >= 0 && i < m->oneof_count);
+  return &m->oneofs[i];
+}
+
 bool upb_msgdef_mapentry(const upb_msgdef *m) {
   return m->map_entry;
 }
@@ -822,22 +724,25 @@ const upb_msgdef *upb_oneofdef_containingtype(const upb_oneofdef *o) {
   return o->parent;
 }
 
+int upb_oneofdef_fieldcount(const upb_oneofdef *o) {
+  return o->field_count;
+}
+
+const upb_fielddef *upb_oneofdef_field(const upb_oneofdef *o, int i) {
+  UPB_ASSERT(i < o->field_count);
+  return o->fields[i];
+}
+
 int upb_oneofdef_numfields(const upb_oneofdef *o) {
-  return (int)upb_strtable_count(&o->ntof);
+  return o->field_count;
 }
 
 uint32_t upb_oneofdef_index(const upb_oneofdef *o) {
-  return o->index;
+  return o - o->parent->oneofs;
 }
 
 bool upb_oneofdef_issynthetic(const upb_oneofdef *o) {
-  upb_inttable_iter iter;
-  const upb_fielddef *f;
-  upb_inttable_begin(&iter, &o->itof);
-  if (upb_oneofdef_numfields(o) != 1) return false;
-  f = upb_value_getptr(upb_inttable_iter_value(&iter));
-  UPB_ASSERT(f);
-  return f->proto3_optional_;
+  return o->synthetic;
 }
 
 const upb_fielddef *upb_oneofdef_ntof(const upb_oneofdef *o,
@@ -873,7 +778,189 @@ void upb_oneof_iter_setdone(upb_oneof_iter *iter) {
   upb_inttable_iter_setdone(iter);
 }
 
-/* Dynamic Layout Generation. *************************************************/
+/* upb_filedef ****************************************************************/
+
+const char *upb_filedef_name(const upb_filedef *f) {
+  return f->name;
+}
+
+const char *upb_filedef_package(const upb_filedef *f) {
+  return f->package;
+}
+
+const char *upb_filedef_phpprefix(const upb_filedef *f) {
+  return f->phpprefix;
+}
+
+const char *upb_filedef_phpnamespace(const upb_filedef *f) {
+  return f->phpnamespace;
+}
+
+upb_syntax_t upb_filedef_syntax(const upb_filedef *f) {
+  return f->syntax;
+}
+
+int upb_filedef_msgcount(const upb_filedef *f) {
+  return f->msg_count;
+}
+
+int upb_filedef_depcount(const upb_filedef *f) {
+  return f->dep_count;
+}
+
+int upb_filedef_enumcount(const upb_filedef *f) {
+  return f->enum_count;
+}
+
+const upb_filedef *upb_filedef_dep(const upb_filedef *f, int i) {
+  return i < 0 || i >= f->dep_count ? NULL : f->deps[i];
+}
+
+const upb_msgdef *upb_filedef_msg(const upb_filedef *f, int i) {
+  return i < 0 || i >= f->msg_count ? NULL : &f->msgs[i];
+}
+
+const upb_enumdef *upb_filedef_enum(const upb_filedef *f, int i) {
+  return i < 0 || i >= f->enum_count ? NULL : &f->enums[i];
+}
+
+const upb_symtab *upb_filedef_symtab(const upb_filedef *f) {
+  return f->symtab;
+}
+
+void upb_symtab_free(upb_symtab *s) {
+  upb_arena_free(s->arena);
+  upb_gfree(s);
+}
+
+upb_symtab *upb_symtab_new(void) {
+  upb_symtab *s = upb_gmalloc(sizeof(*s));
+  upb_alloc *alloc;
+
+  if (!s) {
+    return NULL;
+  }
+
+  s->arena = upb_arena_new();
+  s->bytes_loaded = 0;
+  alloc = upb_arena_alloc(s->arena);
+
+  if (!upb_strtable_init2(&s->syms, UPB_CTYPE_CONSTPTR, 32, alloc) ||
+      !upb_strtable_init2(&s->files, UPB_CTYPE_CONSTPTR, 4, alloc)) {
+    upb_arena_free(s->arena);
+    upb_gfree(s);
+    s = NULL;
+  }
+  return s;
+}
+
+const upb_msgdef *upb_symtab_lookupmsg(const upb_symtab *s, const char *sym) {
+  upb_value v;
+  return upb_strtable_lookup(&s->syms, sym, &v) ?
+      unpack_def(v, UPB_DEFTYPE_MSG) : NULL;
+}
+
+const upb_msgdef *upb_symtab_lookupmsg2(const upb_symtab *s, const char *sym,
+                                        size_t len) {
+  upb_value v;
+  return upb_strtable_lookup2(&s->syms, sym, len, &v) ?
+      unpack_def(v, UPB_DEFTYPE_MSG) : NULL;
+}
+
+const upb_enumdef *upb_symtab_lookupenum(const upb_symtab *s, const char *sym) {
+  upb_value v;
+  return upb_strtable_lookup(&s->syms, sym, &v) ?
+      unpack_def(v, UPB_DEFTYPE_ENUM) : NULL;
+}
+
+const upb_filedef *upb_symtab_lookupfile(const upb_symtab *s, const char *name) {
+  upb_value v;
+  return upb_strtable_lookup(&s->files, name, &v) ? upb_value_getconstptr(v)
+                                                  : NULL;
+}
+
+const upb_filedef *upb_symtab_lookupfile2(
+    const upb_symtab *s, const char *name, size_t len) {
+  upb_value v;
+  return upb_strtable_lookup2(&s->files, name, len, &v) ?
+      upb_value_getconstptr(v) : NULL;
+}
+
+int upb_symtab_filecount(const upb_symtab *s) {
+  return (int)upb_strtable_count(&s->files);
+}
+
+/* Code to build defs from descriptor protos. *********************************/
+
+/* There is a question of how much validation to do here.  It will be difficult
+ * to perfectly match the amount of validation performed by proto2.  But since
+ * this code is used to directly build defs from Ruby (for example) we do need
+ * to validate important constraints like uniqueness of names and numbers. */
+
+#define CHK_OOM(x) if (!(x)) { symtab_oomerr(ctx); }
+
+typedef struct {
+  upb_symtab *symtab;
+  upb_filedef *file;              /* File we are building. */
+  upb_arena *file_arena;          /* Allocate defs here. */
+  upb_alloc *alloc;               /* Alloc of file_arena, for tables. */
+  const upb_msglayout **layouts;  /* NULL if we should build layouts. */
+  upb_status *status;             /* Record errors here. */
+  jmp_buf err;                    /* longjmp() on error. */
+} symtab_addctx;
+
+UPB_NORETURN UPB_NOINLINE
+static void symtab_errf(symtab_addctx *ctx, const char *fmt, ...) {
+  va_list argp;
+  va_start(argp, fmt);
+  upb_status_vseterrf(ctx->status, fmt, argp);
+  va_end(argp);
+  UPB_LONGJMP(ctx->err, 1);
+}
+
+UPB_NORETURN UPB_NOINLINE
+static void symtab_oomerr(symtab_addctx *ctx) {
+  upb_status_setoom(ctx->status);
+  UPB_LONGJMP(ctx->err, 1);
+}
+
+void *symtab_alloc(symtab_addctx *ctx, size_t bytes) {
+  void *ret = upb_arena_malloc(ctx->file_arena, bytes);
+  if (!ret) symtab_oomerr(ctx);
+  return ret;
+}
+
+static void check_ident(symtab_addctx *ctx, upb_strview name, bool full) {
+  const char *str = name.data;
+  size_t len = name.size;
+  bool start = true;
+  size_t i;
+  for (i = 0; i < len; i++) {
+    char c = str[i];
+    if (c == '.') {
+      if (start || !full) {
+        symtab_errf(ctx, "invalid name: unexpected '.' (%.*s)", (int)len, str);
+      }
+      start = true;
+    } else if (start) {
+      if (!upb_isletter(c)) {
+        symtab_errf(
+            ctx,
+            "invalid name: path components must start with a letter (%.*s)",
+            (int)len, str);
+      }
+      start = false;
+    } else {
+      if (!upb_isalphanum(c)) {
+        symtab_errf(ctx, "invalid name: non-alphanumeric character (%.*s)",
+                    (int)len, str);
+      }
+    }
+  }
+  if (start) {
+    symtab_errf(ctx, "invalid name: empty part (%.*s)", (int)len, str);
+  }
+}
 
 static size_t div_round_up(size_t n, size_t d) {
   return (n + d - 1) / d;
@@ -940,7 +1027,7 @@ static void assign_layout_indices(const upb_msgdef *m, upb_msglayout_field *fiel
 
 /* This function is the dynamic equivalent of message_layout.{cc,h} in upbc.
  * It computes a dynamic layout for all of the fields in |m|. */
-static bool make_layout(const upb_symtab *symtab, const upb_msgdef *m) {
+static void make_layout(symtab_addctx *ctx, const upb_msgdef *m) {
   upb_msglayout *l = (upb_msglayout*)m->layout;
   upb_msg_field_iter it;
   upb_msg_oneof_iter oit;
@@ -948,22 +1035,21 @@ static bool make_layout(const upb_symtab *symtab, const upb_msgdef *m) {
   size_t submsg_count = m->submsg_field_count;
   const upb_msglayout **submsgs;
   upb_msglayout_field *fields;
-  upb_alloc *alloc = upb_arena_alloc(symtab->arena);
 
-  memset(l, 0, sizeof(*l));
+  memset(l, 0, sizeof(*l) + sizeof(_upb_fasttable_entry));
 
-  fields = upb_malloc(alloc, upb_msgdef_numfields(m) * sizeof(*fields));
-  submsgs = upb_malloc(alloc, submsg_count * sizeof(*submsgs));
-
-  if ((!fields && upb_msgdef_numfields(m)) ||
-      (!submsgs && submsg_count)) {
-    /* OOM. */
-    return false;
-  }
+  fields = symtab_alloc(ctx, upb_msgdef_numfields(m) * sizeof(*fields));
+  submsgs = symtab_alloc(ctx, submsg_count * sizeof(*submsgs));
 
   l->field_count = upb_msgdef_numfields(m);
   l->fields = fields;
   l->submsgs = submsgs;
+  l->table_mask = 0;
+
+  /* TODO(haberman): initialize fast tables so that reflection-based parsing
+   * can get the same speeds as linked-in types. */
+  l->fasttable[0].field_parser = &fastdecode_generic;
+  l->fasttable[0].field_data = 0;
 
   if (upb_msgdef_mapentry(m)) {
     /* TODO(haberman): refactor this method so this special case is more
@@ -989,7 +1075,7 @@ static bool make_layout(const upb_symtab *symtab, const upb_msgdef *m) {
     l->field_count = 2;
     l->size = 2 * sizeof(upb_strview);
     l->size = UPB_ALIGN_UP(l->size, 8);
-    return true;
+    return;
   }
 
   /* Allocate data offsets in three stages:
@@ -1101,31 +1187,52 @@ static bool make_layout(const upb_symtab *symtab, const upb_msgdef *m) {
   /* Sort fields by number. */
   qsort(fields, upb_msgdef_numfields(m), sizeof(*fields), field_number_cmp);
   assign_layout_indices(m, fields);
-
-  return true;
 }
 
-/* Code to build defs from descriptor protos. *********************************/
+static void assign_msg_indices(symtab_addctx *ctx, upb_msgdef *m) {
+  /* Sort fields.  upb internally relies on UPB_TYPE_MESSAGE fields having the
+   * lowest indexes, but we do not publicly guarantee this. */
+  upb_msg_field_iter j;
+  int i;
+  uint32_t selector;
+  int n = upb_msgdef_numfields(m);
+  upb_fielddef **fields;
 
-/* There is a question of how much validation to do here.  It will be difficult
- * to perfectly match the amount of validation performed by proto2.  But since
- * this code is used to directly build defs from Ruby (for example) we do need
- * to validate important constraints like uniqueness of names and numbers. */
+  if (n == 0) {
+    m->selector_count = UPB_STATIC_SELECTOR_COUNT;
+    m->submsg_field_count = 0;
+    return;
+  }
 
-#define CHK(x) if (!(x)) { return false; }
-#define CHK_OOM(x) if (!(x)) { upb_status_setoom(ctx->status); return false; }
+  fields = upb_gmalloc(n * sizeof(*fields));
 
-typedef struct {
-  const upb_symtab *symtab;
-  upb_filedef *file;              /* File we are building. */
-  upb_alloc *alloc;               /* Allocate defs here. */
-  upb_alloc *tmp;                 /* Alloc for addtab and any other tmp data. */
-  upb_strtable *addtab;           /* full_name -> packed def ptr for new defs */
-  const upb_msglayout **layouts;  /* NULL if we should build layouts. */
-  upb_status *status;             /* Record errors here. */
-} symtab_addctx;
+  m->submsg_field_count = 0;
+  for(i = 0, upb_msg_field_begin(&j, m);
+      !upb_msg_field_done(&j);
+      upb_msg_field_next(&j), i++) {
+    upb_fielddef *f = upb_msg_iter_field(&j);
+    UPB_ASSERT(f->msgdef == m);
+    if (upb_fielddef_issubmsg(f)) {
+      m->submsg_field_count++;
+    }
+    fields[i] = f;
+  }
+
+  qsort(fields, n, sizeof(*fields), cmp_fields);
+
+  selector = UPB_STATIC_SELECTOR_COUNT + m->submsg_field_count;
+  for (i = 0; i < n; i++) {
+    upb_fielddef *f = fields[i];
+    f->index_ = i;
+    f->selector_base = selector + upb_handlers_selectorbaseoffset(f);
+    selector += upb_handlers_selectorcount(f);
+  }
+  m->selector_count = selector;
+
+  upb_gfree(fields);
+}
 
-static char* strviewdup(const symtab_addctx *ctx, upb_strview view) {
+static char *strviewdup(symtab_addctx *ctx, upb_strview view) {
   return upb_strdup2(view.data, view.size, ctx->alloc);
 }
 
@@ -1137,13 +1244,12 @@ static bool streql_view(upb_strview view, const char *b) {
   return streql2(view.data, view.size, b);
 }
 
-static const char *makefullname(const symtab_addctx *ctx, const char *prefix,
+static const char *makefullname(symtab_addctx *ctx, const char *prefix,
                                 upb_strview name) {
   if (prefix) {
     /* ret = prefix + '.' + name; */
     size_t n = strlen(prefix);
-    char *ret = upb_malloc(ctx->alloc, n + name.size + 2);
-    CHK_OOM(ret);
+    char *ret = symtab_alloc(ctx, n + name.size + 2);
     strcpy(ret, prefix);
     ret[n] = '.';
     memcpy(&ret[n + 1], name.data, name.size);
@@ -1154,6 +1260,41 @@ static const char *makefullname(const symtab_addctx *ctx, const char *prefix,
   }
 }
 
+static void finalize_oneofs(symtab_addctx *ctx, upb_msgdef *m) {
+  int i;
+  int synthetic_count = 0;
+  upb_oneofdef *mutable_oneofs = (upb_oneofdef*)m->oneofs;
+
+  for (i = 0; i < m->oneof_count; i++) {
+    upb_oneofdef *o = &mutable_oneofs[i];
+
+    if (o->synthetic && o->field_count != 1) {
+      symtab_errf(ctx, "Synthetic oneofs must have one field, not %d: %s",
+                  o->field_count, upb_oneofdef_name(o));
+    }
+
+    if (o->synthetic) {
+      synthetic_count++;
+    } else if (synthetic_count != 0) {
+      symtab_errf(ctx, "Synthetic oneofs must be after all other oneofs: %s",
+                  upb_oneofdef_name(o));
+    }
+
+    o->fields = symtab_alloc(ctx, sizeof(upb_fielddef *) * o->field_count);
+    o->field_count = 0;
+  }
+
+  for (i = 0; i < m->field_count; i++) {
+    const upb_fielddef *f = &m->fields[i];
+    upb_oneofdef *o = (upb_oneofdef*)f->oneof;
+    if (o) {
+      o->fields[o->field_count++] = f;
+    }
+  }
+
+  m->real_oneof_count = m->oneof_count - synthetic_count;
+}
+
 size_t getjsonname(const char *name, char *buf, size_t len) {
   size_t src, dst = 0;
   bool ucase_next = false;
@@ -1192,76 +1333,57 @@ size_t getjsonname(const char *name, char *buf, size_t len) {
 #undef WRITE
 }
 
-static char* makejsonname(const char* name, upb_alloc *alloc) {
+static char* makejsonname(symtab_addctx *ctx, const char* name) {
   size_t size = getjsonname(name, NULL, 0);
-  char* json_name = upb_malloc(alloc, size);
+  char* json_name = symtab_alloc(ctx, size);
   getjsonname(name, json_name, size);
   return json_name;
 }
 
-static bool symtab_add(const symtab_addctx *ctx, const char *name,
-                       upb_value v) {
-  upb_value tmp;
-  if (upb_strtable_lookup(ctx->addtab, name, &tmp) ||
-      upb_strtable_lookup(&ctx->symtab->syms, name, &tmp)) {
-    upb_status_seterrf(ctx->status, "duplicate symbol '%s'", name);
-    return false;
+static void symtab_add(symtab_addctx *ctx, const char *name, upb_value v) {
+  if (upb_strtable_lookup(&ctx->symtab->syms, name, NULL)) {
+    symtab_errf(ctx, "duplicate symbol '%s'", name);
   }
-
-  CHK_OOM(upb_strtable_insert3(ctx->addtab, name, strlen(name), v, ctx->tmp));
-  return true;
+  upb_alloc *alloc = upb_arena_alloc(ctx->symtab->arena);
+  size_t len = strlen(name);
+  CHK_OOM(upb_strtable_insert3(&ctx->symtab->syms, name, len, v, alloc));
 }
 
 /* Given a symbol and the base symbol inside which it is defined, find the
  * symbol's definition in t. */
-static bool resolvename(const upb_strtable *t, const upb_fielddef *f,
-                        const char *base, upb_strview sym,
-                        upb_deftype_t type, upb_status *status,
-                        const void **def) {
-  if(sym.size == 0) return false;
+static const void *symtab_resolve(symtab_addctx *ctx, const upb_fielddef *f,
+                                  const char *base, upb_strview sym,
+                                  upb_deftype_t type) {
+  const upb_strtable *t = &ctx->symtab->syms;
+  if(sym.size == 0) goto notfound;
   if(sym.data[0] == '.') {
     /* Symbols starting with '.' are absolute, so we do a single lookup.
      * Slice to omit the leading '.' */
     upb_value v;
     if (!upb_strtable_lookup2(t, sym.data + 1, sym.size - 1, &v)) {
-      return false;
+      goto notfound;
     }
 
-    *def = unpack_def(v, type);
-
-    if (!*def) {
-      upb_status_seterrf(status,
-                         "type mismatch when resolving field %s, name %s",
-                         f->full_name, sym.data);
-      return false;
+    const void *ret = unpack_def(v, type);
+    if (!ret) {
+      symtab_errf(ctx, "type mismatch when resolving field %s, name %s",
+                  f->full_name, sym.data);
     }
-
-    return true;
+    return ret;
   } else {
     /* Remove components from base until we find an entry or run out.
      * TODO: This branch is totally broken, but currently not used. */
     (void)base;
     UPB_ASSERT(false);
-    return false;
+    goto notfound;
   }
-}
 
-const void *symtab_resolve(const symtab_addctx *ctx, const upb_fielddef *f,
-                           const char *base, upb_strview sym,
-                           upb_deftype_t type) {
-  const void *ret;
-  if (!resolvename(ctx->addtab, f, base, sym, type, ctx->status, &ret) &&
-      !resolvename(&ctx->symtab->syms, f, base, sym, type, ctx->status, &ret)) {
-    if (upb_ok(ctx->status)) {
-      upb_status_seterrf(ctx->status, "couldn't resolve name '%s'", sym.data);
-    }
-    return false;
-  }
-  return ret;
+notfound:
+  symtab_errf(ctx, "couldn't resolve name '%s'", sym.data);
 }
 
-static bool create_oneofdef(
-    const symtab_addctx *ctx, upb_msgdef *m,
+static void create_oneofdef(
+    symtab_addctx *ctx, upb_msgdef *m,
     const google_protobuf_OneofDescriptorProto *oneof_proto) {
   upb_oneofdef *o;
   upb_strview name = google_protobuf_OneofDescriptorProto_name(oneof_proto);
@@ -1270,18 +1392,27 @@ static bool create_oneofdef(
   o = (upb_oneofdef*)&m->oneofs[m->oneof_count++];
   o->parent = m;
   o->full_name = makefullname(ctx, m->full_name, name);
+  o->field_count = 0;
+  o->synthetic = false;
 
   v = pack_def(o, UPB_DEFTYPE_ONEOF);
-  CHK_OOM(symtab_add(ctx, o->full_name, v));
+  symtab_add(ctx, o->full_name, v);
   CHK_OOM(upb_strtable_insert3(&m->ntof, name.data, name.size, v, ctx->alloc));
 
   CHK_OOM(upb_inttable_init2(&o->itof, UPB_CTYPE_CONSTPTR, ctx->alloc));
-  CHK_OOM(upb_strtable_init2(&o->ntof, UPB_CTYPE_CONSTPTR, ctx->alloc));
+  CHK_OOM(upb_strtable_init2(&o->ntof, UPB_CTYPE_CONSTPTR, 4, ctx->alloc));
+}
 
-  return true;
+static str_t *newstr(symtab_addctx *ctx, const char *data, size_t len) {
+  str_t *ret = symtab_alloc(ctx, sizeof(*ret) + len);
+  if (!ret) return NULL;
+  ret->len = len;
+  if (len) memcpy(ret->str, data, len);
+  ret->str[len] = '\0';
+  return ret;
 }
 
-static bool parse_default(const symtab_addctx *ctx, const char *str, size_t len,
+static void parse_default(symtab_addctx *ctx, const char *str, size_t len,
                           upb_fielddef *f) {
   char *end;
   char nullz[64];
@@ -1296,7 +1427,7 @@ static bool parse_default(const symtab_addctx *ctx, const char *str, size_t len,
     case UPB_TYPE_FLOAT:
       /* Standard C number parsing functions expect null-terminated strings. */
       if (len >= sizeof(nullz) - 1) {
-        return false;
+        symtab_errf(ctx, "Default too long: %.*s", (int)len, str);
       }
       memcpy(nullz, str, len);
       nullz[len] = '\0';
@@ -1309,47 +1440,61 @@ static bool parse_default(const symtab_addctx *ctx, const char *str, size_t len,
   switch (upb_fielddef_type(f)) {
     case UPB_TYPE_INT32: {
       long val = strtol(str, &end, 0);
-      CHK(val <= INT32_MAX && val >= INT32_MIN && errno != ERANGE && !*end);
+      if (val > INT32_MAX || val < INT32_MIN || errno == ERANGE || *end) {
+        goto invalid;
+      }
       f->defaultval.sint = val;
       break;
     }
     case UPB_TYPE_ENUM: {
       const upb_enumdef *e = f->sub.enumdef;
       int32_t val;
-      CHK(upb_enumdef_ntoi(e, str, len, &val));
+      if (!upb_enumdef_ntoi(e, str, len, &val)) {
+        goto invalid;
+      }
       f->defaultval.sint = val;
       break;
     }
     case UPB_TYPE_INT64: {
       /* XXX: Need to write our own strtoll, since it's not available in c89. */
       int64_t val = strtol(str, &end, 0);
-      CHK(val <= INT64_MAX && val >= INT64_MIN && errno != ERANGE && !*end);
+      if (val > INT64_MAX || val < INT64_MIN || errno == ERANGE || *end) {
+        goto invalid;
+      }
       f->defaultval.sint = val;
       break;
     }
     case UPB_TYPE_UINT32: {
       unsigned long val = strtoul(str, &end, 0);
-      CHK(val <= UINT32_MAX && errno != ERANGE && !*end);
+      if (val > UINT32_MAX || errno == ERANGE || *end) {
+        goto invalid;
+      }
       f->defaultval.uint = val;
       break;
     }
     case UPB_TYPE_UINT64: {
       /* XXX: Need to write our own strtoull, since it's not available in c89. */
       uint64_t val = strtoul(str, &end, 0);
-      CHK(val <= UINT64_MAX && errno != ERANGE && !*end);
+      if (val > UINT64_MAX || errno == ERANGE || *end) {
+        goto invalid;
+      }
       f->defaultval.uint = val;
       break;
     }
     case UPB_TYPE_DOUBLE: {
       double val = strtod(str, &end);
-      CHK(errno != ERANGE && !*end);
+      if (errno == ERANGE || *end) {
+        goto invalid;
+      }
       f->defaultval.dbl = val;
       break;
     }
     case UPB_TYPE_FLOAT: {
       /* XXX: Need to write our own strtof, since it's not available in c89. */
       float val = strtod(str, &end);
-      CHK(errno != ERANGE && !*end);
+      if (errno == ERANGE || *end) {
+        goto invalid;
+      }
       f->defaultval.flt = val;
       break;
     }
@@ -1359,25 +1504,30 @@ static bool parse_default(const symtab_addctx *ctx, const char *str, size_t len,
       } else if (streql2(str, len, "true")) {
         f->defaultval.boolean = true;
       } else {
-        return false;
       }
       break;
     }
     case UPB_TYPE_STRING:
-      f->defaultval.str = newstr(ctx->alloc, str, len);
+      f->defaultval.str = newstr(ctx, str, len);
       break;
     case UPB_TYPE_BYTES:
       /* XXX: need to interpret the C-escaped value. */
-      f->defaultval.str = newstr(ctx->alloc, str, len);
+      f->defaultval.str = newstr(ctx, str, len);
       break;
     case UPB_TYPE_MESSAGE:
       /* Should not have a default value. */
-      return false;
+      symtab_errf(ctx, "Message should not have a default (%s)",
+                  upb_fielddef_fullname(f));
   }
-  return true;
+
+  return;
+
+invalid:
+  symtab_errf(ctx, "Invalid default '%.*s' for field %f", (int)len, str,
+              upb_fielddef_fullname(f));
 }
 
-static void set_default_default(const symtab_addctx *ctx, upb_fielddef *f) {
+static void set_default_default(symtab_addctx *ctx, upb_fielddef *f) {
   switch (upb_fielddef_type(f)) {
     case UPB_TYPE_INT32:
     case UPB_TYPE_INT64:
@@ -1394,7 +1544,7 @@ static void set_default_default(const symtab_addctx *ctx, upb_fielddef *f) {
       break;
     case UPB_TYPE_STRING:
     case UPB_TYPE_BYTES:
-      f->defaultval.str = newstr(ctx->alloc, NULL, 0);
+      f->defaultval.str = newstr(ctx, NULL, 0);
       break;
     case UPB_TYPE_BOOL:
       f->defaultval.boolean = false;
@@ -1404,8 +1554,8 @@ static void set_default_default(const symtab_addctx *ctx, upb_fielddef *f) {
   }
 }
 
-static bool create_fielddef(
-    const symtab_addctx *ctx, const char *prefix, upb_msgdef *m,
+static void create_fielddef(
+    symtab_addctx *ctx, const char *prefix, upb_msgdef *m,
     const google_protobuf_FieldDescriptorProto *field_proto) {
   upb_alloc *alloc = ctx->alloc;
   upb_fielddef *f;
@@ -1417,12 +1567,11 @@ static bool create_fielddef(
   uint32_t field_number;
 
   if (!google_protobuf_FieldDescriptorProto_has_name(field_proto)) {
-    upb_status_seterrmsg(ctx->status, "field has no name");
-    return false;
+    symtab_errf(ctx, "field has no name (%s)", upb_msgdef_fullname(m));
   }
 
   name = google_protobuf_FieldDescriptorProto_name(field_proto);
-  CHK(upb_isident(name, false, ctx->status));
+  check_ident(ctx, name, false);
   full_name = makefullname(ctx, prefix, name);
   shortname = shortdefname(full_name);
 
@@ -1430,14 +1579,13 @@ static bool create_fielddef(
     json_name = strviewdup(
         ctx, google_protobuf_FieldDescriptorProto_json_name(field_proto));
   } else {
-    json_name = makejsonname(shortname, ctx->alloc);
+    json_name = makejsonname(ctx, shortname);
   }
 
   field_number = google_protobuf_FieldDescriptorProto_number(field_proto);
 
   if (field_number == 0 || field_number > UPB_MAX_FIELDNUMBER) {
-    upb_status_seterrf(ctx->status, "invalid field number (%u)", field_number);
-    return false;
+    symtab_errf(ctx, "invalid field number (%u)", field_number);
   }
 
   if (m) {
@@ -1450,19 +1598,15 @@ static bool create_fielddef(
     f->is_extension_ = false;
 
     if (upb_strtable_lookup(&m->ntof, shortname, NULL)) {
-      upb_status_seterrf(ctx->status, "duplicate field name (%s)", shortname);
-      return false;
+      symtab_errf(ctx, "duplicate field name (%s)", shortname);
     }
 
     if (upb_strtable_lookup(&m->ntof, json_name, NULL)) {
-      upb_status_seterrf(ctx->status, "duplicate json_name (%s)", json_name);
-      return false;
+      symtab_errf(ctx, "duplicate json_name (%s)", json_name);
     }
 
     if (upb_inttable_lookup(&m->itof, field_number, NULL)) {
-      upb_status_seterrf(ctx->status, "duplicate field number (%u)",
-                         field_number);
-      return false;
+      symtab_errf(ctx, "duplicate field number (%u)", field_number);
     }
 
     field_v = pack_def(f, UPB_DEFTYPE_FIELD);
@@ -1496,7 +1640,7 @@ static bool create_fielddef(
     /* extension field. */
     f = (upb_fielddef*)&ctx->file->exts[ctx->file->ext_count++];
     f->is_extension_ = true;
-    CHK_OOM(symtab_add(ctx, full_name, pack_def(f, UPB_DEFTYPE_FIELD)));
+    symtab_add(ctx, full_name, pack_def(f, UPB_DEFTYPE_FIELD));
   }
 
   f->full_name = full_name;
@@ -1515,9 +1659,7 @@ static bool create_fielddef(
   f->sub.unresolved = field_proto;
 
   if (f->label_ == UPB_LABEL_REQUIRED && f->file->syntax == UPB_SYNTAX_PROTO3) {
-    upb_status_seterrf(ctx->status, "proto3 fields cannot be required (%s)",
-                       f->full_name);
-    return false;
+    symtab_errf(ctx, "proto3 fields cannot be required (%s)", f->full_name);
   }
 
   if (google_protobuf_FieldDescriptorProto_has_oneof_index(field_proto)) {
@@ -1527,32 +1669,34 @@ static bool create_fielddef(
     upb_value v = upb_value_constptr(f);
 
     if (upb_fielddef_label(f) != UPB_LABEL_OPTIONAL) {
-      upb_status_seterrf(ctx->status,
-                         "fields in oneof must have OPTIONAL label (%s)",
-                         f->full_name);
-      return false;
+      symtab_errf(ctx, "fields in oneof must have OPTIONAL label (%s)",
+                  f->full_name);
     }
 
     if (!m) {
-      upb_status_seterrf(ctx->status,
-                         "oneof_index provided for extension field (%s)",
-                         f->full_name);
-      return false;
+      symtab_errf(ctx, "oneof_index provided for extension field (%s)",
+                  f->full_name);
     }
 
     if (oneof_index >= m->oneof_count) {
-      upb_status_seterrf(ctx->status, "oneof_index out of range (%s)",
-                         f->full_name);
-      return false;
+      symtab_errf(ctx, "oneof_index out of range (%s)", f->full_name);
     }
 
     oneof = (upb_oneofdef*)&m->oneofs[oneof_index];
     f->oneof = oneof;
 
-    CHK(upb_inttable_insert2(&oneof->itof, f->number_, v, alloc));
-    CHK(upb_strtable_insert3(&oneof->ntof, name.data, name.size, v, alloc));
+    oneof->field_count++;
+    if (f->proto3_optional_) {
+      oneof->synthetic = true;
+    }
+    CHK_OOM(upb_inttable_insert2(&oneof->itof, f->number_, v, alloc));
+    CHK_OOM(upb_strtable_insert3(&oneof->ntof, name.data, name.size, v, alloc));
   } else {
     f->oneof = NULL;
+    if (f->proto3_optional_) {
+      symtab_errf(ctx, "field with proto3_optional was not in a oneof (%s)",
+                  f->full_name);
+    }
   }
 
   options = google_protobuf_FieldDescriptorProto_has_options(field_proto) ?
@@ -1571,12 +1715,10 @@ static bool create_fielddef(
   } else {
     f->lazy_ = false;
   }
-
-  return true;
 }
 
-static bool create_enumdef(
-    const symtab_addctx *ctx, const char *prefix,
+static void create_enumdef(
+    symtab_addctx *ctx, const char *prefix,
     const google_protobuf_EnumDescriptorProto *enum_proto) {
   upb_enumdef *e;
   const google_protobuf_EnumValueDescriptorProto *const *values;
@@ -1584,25 +1726,22 @@ static bool create_enumdef(
   size_t i, n;
 
   name = google_protobuf_EnumDescriptorProto_name(enum_proto);
-  CHK(upb_isident(name, false, ctx->status));
+  check_ident(ctx, name, false);
 
   e = (upb_enumdef*)&ctx->file->enums[ctx->file->enum_count++];
   e->full_name = makefullname(ctx, prefix, name);
-  CHK_OOM(symtab_add(ctx, e->full_name, pack_def(e, UPB_DEFTYPE_ENUM)));
+  symtab_add(ctx, e->full_name, pack_def(e, UPB_DEFTYPE_ENUM));
 
-  CHK_OOM(upb_strtable_init2(&e->ntoi, UPB_CTYPE_INT32, ctx->alloc));
+  values = google_protobuf_EnumDescriptorProto_value(enum_proto, &n);
+  CHK_OOM(upb_strtable_init2(&e->ntoi, UPB_CTYPE_INT32, n, ctx->alloc));
   CHK_OOM(upb_inttable_init2(&e->iton, UPB_CTYPE_CSTR, ctx->alloc));
 
   e->file = ctx->file;
   e->defaultval = 0;
 
-  values = google_protobuf_EnumDescriptorProto_value(enum_proto, &n);
-
   if (n == 0) {
-    upb_status_seterrf(ctx->status,
-                       "enums must contain at least one value (%s)",
-                       e->full_name);
-    return false;
+    symtab_errf(ctx, "enums must contain at least one value (%s)",
+                e->full_name);
   }
 
   for (i = 0; i < n; i++) {
@@ -1613,15 +1752,12 @@ static bool create_enumdef(
     upb_value v = upb_value_int32(num);
 
     if (i == 0 && e->file->syntax == UPB_SYNTAX_PROTO3 && num != 0) {
-      upb_status_seterrf(ctx->status,
-                         "for proto3, the first enum value must be zero (%s)",
-                         e->full_name);
-      return false;
+      symtab_errf(ctx, "for proto3, the first enum value must be zero (%s)",
+                  e->full_name);
     }
 
     if (upb_strtable_lookup(&e->ntoi, name2, NULL)) {
-      upb_status_seterrf(ctx->status, "duplicate enum label '%s'", name2);
-      return false;
+      symtab_errf(ctx, "duplicate enum label '%s'", name2);
     }
 
     CHK_OOM(name2)
@@ -1635,11 +1771,9 @@ static bool create_enumdef(
   }
 
   upb_inttable_compact2(&e->iton, ctx->alloc);
-
-  return true;
 }
 
-static bool create_msgdef(symtab_addctx *ctx, const char *prefix,
+static void create_msgdef(symtab_addctx *ctx, const char *prefix,
                           const google_protobuf_DescriptorProto *msg_proto) {
   upb_msgdef *m;
   const google_protobuf_MessageOptions *options;
@@ -1647,18 +1781,22 @@ static bool create_msgdef(symtab_addctx *ctx, const char *prefix,
   const google_protobuf_FieldDescriptorProto *const *fields;
   const google_protobuf_EnumDescriptorProto *const *enums;
   const google_protobuf_DescriptorProto *const *msgs;
-  size_t i, n;
+  size_t i, n_oneof, n_field, n;
   upb_strview name;
 
   name = google_protobuf_DescriptorProto_name(msg_proto);
-  CHK(upb_isident(name, false, ctx->status));
+  check_ident(ctx, name, false);
 
   m = (upb_msgdef*)&ctx->file->msgs[ctx->file->msg_count++];
   m->full_name = makefullname(ctx, prefix, name);
-  CHK_OOM(symtab_add(ctx, m->full_name, pack_def(m, UPB_DEFTYPE_MSG)));
+  symtab_add(ctx, m->full_name, pack_def(m, UPB_DEFTYPE_MSG));
+
+  oneofs = google_protobuf_DescriptorProto_oneof_decl(msg_proto, &n_oneof);
+  fields = google_protobuf_DescriptorProto_field(msg_proto, &n_field);
 
   CHK_OOM(upb_inttable_init2(&m->itof, UPB_CTYPE_CONSTPTR, ctx->alloc));
-  CHK_OOM(upb_strtable_init2(&m->ntof, UPB_CTYPE_CONSTPTR, ctx->alloc));
+  CHK_OOM(upb_strtable_init2(&m->ntof, UPB_CTYPE_CONSTPTR, n_oneof + n_field,
+                             ctx->alloc));
 
   m->file = ctx->file;
   m->map_entry = false;
@@ -1674,25 +1812,24 @@ static bool create_msgdef(symtab_addctx *ctx, const char *prefix,
     ctx->layouts++;
   } else {
     /* Allocate now (to allow cross-linking), populate later. */
-    m->layout = upb_malloc(ctx->alloc, sizeof(*m->layout));
+    m->layout = symtab_alloc(
+        ctx, sizeof(*m->layout) + sizeof(_upb_fasttable_entry));
   }
 
-  oneofs = google_protobuf_DescriptorProto_oneof_decl(msg_proto, &n);
   m->oneof_count = 0;
-  m->oneofs = upb_malloc(ctx->alloc, sizeof(*m->oneofs) * n);
-  for (i = 0; i < n; i++) {
-    CHK(create_oneofdef(ctx, m, oneofs[i]));
+  m->oneofs = symtab_alloc(ctx, sizeof(*m->oneofs) * n_oneof);
+  for (i = 0; i < n_oneof; i++) {
+    create_oneofdef(ctx, m, oneofs[i]);
   }
 
-  fields = google_protobuf_DescriptorProto_field(msg_proto, &n);
   m->field_count = 0;
-  m->fields = upb_malloc(ctx->alloc, sizeof(*m->fields) * n);
-  for (i = 0; i < n; i++) {
-    CHK(create_fielddef(ctx, m->full_name, m, fields[i]));
+  m->fields = symtab_alloc(ctx, sizeof(*m->fields) * n_field);
+  for (i = 0; i < n_field; i++) {
+    create_fielddef(ctx, m->full_name, m, fields[i]);
   }
 
-  CHK(assign_msg_indices(m, ctx->status));
-  CHK(check_oneofs(m, ctx->status));
+  assign_msg_indices(ctx, m);
+  finalize_oneofs(ctx, m);
   assign_msg_wellknowntype(m);
   upb_inttable_compact2(&m->itof, ctx->alloc);
 
@@ -1700,93 +1837,78 @@ static bool create_msgdef(symtab_addctx *ctx, const char *prefix,
 
   enums = google_protobuf_DescriptorProto_enum_type(msg_proto, &n);
   for (i = 0; i < n; i++) {
-    CHK(create_enumdef(ctx, m->full_name, enums[i]));
+    create_enumdef(ctx, m->full_name, enums[i]);
   }
 
   msgs = google_protobuf_DescriptorProto_nested_type(msg_proto, &n);
   for (i = 0; i < n; i++) {
-    CHK(create_msgdef(ctx, m->full_name, msgs[i]));
+    create_msgdef(ctx, m->full_name, msgs[i]);
   }
-
-  return true;
 }
 
-typedef struct {
-  int msg_count;
-  int enum_count;
-  int ext_count;
-} decl_counts;
-
 static void count_types_in_msg(const google_protobuf_DescriptorProto *msg_proto,
-                               decl_counts *counts) {
+                               upb_filedef *file) {
   const google_protobuf_DescriptorProto *const *msgs;
   size_t i, n;
 
-  counts->msg_count++;
+  file->msg_count++;
 
   msgs = google_protobuf_DescriptorProto_nested_type(msg_proto, &n);
   for (i = 0; i < n; i++) {
-    count_types_in_msg(msgs[i], counts);
+    count_types_in_msg(msgs[i], file);
   }
 
   google_protobuf_DescriptorProto_enum_type(msg_proto, &n);
-  counts->enum_count += n;
+  file->enum_count += n;
 
   google_protobuf_DescriptorProto_extension(msg_proto, &n);
-  counts->ext_count += n;
+  file->ext_count += n;
 }
 
 static void count_types_in_file(
     const google_protobuf_FileDescriptorProto *file_proto,
-    decl_counts *counts) {
+    upb_filedef *file) {
   const google_protobuf_DescriptorProto *const *msgs;
   size_t i, n;
 
   msgs = google_protobuf_FileDescriptorProto_message_type(file_proto, &n);
   for (i = 0; i < n; i++) {
-    count_types_in_msg(msgs[i], counts);
+    count_types_in_msg(msgs[i], file);
   }
 
   google_protobuf_FileDescriptorProto_enum_type(file_proto, &n);
-  counts->enum_count += n;
+  file->enum_count += n;
 
   google_protobuf_FileDescriptorProto_extension(file_proto, &n);
-  counts->ext_count += n;
+  file->ext_count += n;
 }
 
-static bool resolve_fielddef(const symtab_addctx *ctx, const char *prefix,
+static void resolve_fielddef(symtab_addctx *ctx, const char *prefix,
                              upb_fielddef *f) {
   upb_strview name;
   const google_protobuf_FieldDescriptorProto *field_proto = f->sub.unresolved;
 
   if (f->is_extension_) {
     if (!google_protobuf_FieldDescriptorProto_has_extendee(field_proto)) {
-      upb_status_seterrf(ctx->status,
-                         "extension for field '%s' had no extendee",
-                         f->full_name);
-      return false;
+      symtab_errf(ctx, "extension for field '%s' had no extendee",
+                  f->full_name);
     }
 
     name = google_protobuf_FieldDescriptorProto_extendee(field_proto);
     f->msgdef = symtab_resolve(ctx, f, prefix, name, UPB_DEFTYPE_MSG);
-    CHK(f->msgdef);
   }
 
   if ((upb_fielddef_issubmsg(f) || f->type_ == UPB_DESCRIPTOR_TYPE_ENUM) &&
       !google_protobuf_FieldDescriptorProto_has_type_name(field_proto)) {
-    upb_status_seterrf(ctx->status, "field '%s' is missing type name",
-                       f->full_name);
-    return false;
+    symtab_errf(ctx, "field '%s' is missing type name", f->full_name);
   }
 
   name = google_protobuf_FieldDescriptorProto_type_name(field_proto);
 
   if (upb_fielddef_issubmsg(f)) {
     f->sub.msgdef = symtab_resolve(ctx, f, prefix, name, UPB_DEFTYPE_MSG);
-    CHK(f->sub.msgdef);
   } else if (f->type_ == UPB_DESCRIPTOR_TYPE_ENUM) {
     f->sub.enumdef = symtab_resolve(ctx, f, prefix, name, UPB_DEFTYPE_ENUM);
-    CHK(f->sub.enumdef);
   }
 
   /* Have to delay resolving of the default value until now because of the enum
@@ -1796,54 +1918,36 @@ static bool resolve_fielddef(const symtab_addctx *ctx, const char *prefix,
         google_protobuf_FieldDescriptorProto_default_value(field_proto);
 
     if (f->file->syntax == UPB_SYNTAX_PROTO3) {
-      upb_status_seterrf(ctx->status,
-                         "proto3 fields cannot have explicit defaults (%s)",
-                         f->full_name);
-      return false;
+      symtab_errf(ctx, "proto3 fields cannot have explicit defaults (%s)",
+                  f->full_name);
     }
 
     if (upb_fielddef_issubmsg(f)) {
-      upb_status_seterrf(ctx->status,
-                         "message fields cannot have explicit defaults (%s)",
-                         f->full_name);
-      return false;
+      symtab_errf(ctx, "message fields cannot have explicit defaults (%s)",
+                  f->full_name);
     }
 
-    if (!parse_default(ctx, defaultval.data, defaultval.size, f)) {
-      upb_status_seterrf(ctx->status,
-                         "couldn't parse default '" UPB_STRVIEW_FORMAT
-                         "' for field (%s)",
-                         UPB_STRVIEW_ARGS(defaultval), f->full_name);
-      return false;
-    }
+    parse_default(ctx, defaultval.data, defaultval.size, f);
   } else {
     set_default_default(ctx, f);
   }
-
-  return true;
 }
 
-static bool build_filedef(
+static void build_filedef(
     symtab_addctx *ctx, upb_filedef *file,
     const google_protobuf_FileDescriptorProto *file_proto) {
-  upb_alloc *alloc = ctx->alloc;
   const google_protobuf_FileOptions *file_options_proto;
   const google_protobuf_DescriptorProto *const *msgs;
   const google_protobuf_EnumDescriptorProto *const *enums;
   const google_protobuf_FieldDescriptorProto *const *exts;
   const upb_strview* strs;
   size_t i, n;
-  decl_counts counts = {0, 0, 0};
 
-  count_types_in_file(file_proto, &counts);
+  count_types_in_file(file_proto, file);
 
-  file->msgs = upb_malloc(alloc, sizeof(*file->msgs) * counts.msg_count);
-  file->enums = upb_malloc(alloc, sizeof(*file->enums) * counts.enum_count);
-  file->exts = upb_malloc(alloc, sizeof(*file->exts) * counts.ext_count);
-
-  CHK_OOM(counts.msg_count == 0 || file->msgs);
-  CHK_OOM(counts.enum_count == 0 || file->enums);
-  CHK_OOM(counts.ext_count == 0 || file->exts);
+  file->msgs = symtab_alloc(ctx, sizeof(*file->msgs) * file->msg_count);
+  file->enums = symtab_alloc(ctx, sizeof(*file->enums) * file->enum_count);
+  file->exts = symtab_alloc(ctx, sizeof(*file->exts) * file->ext_count);
 
   /* We increment these as defs are added. */
   file->msg_count = 0;
@@ -1851,8 +1955,7 @@ static bool build_filedef(
   file->ext_count = 0;
 
   if (!google_protobuf_FileDescriptorProto_has_name(file_proto)) {
-    upb_status_seterrmsg(ctx->status, "File has no name");
-    return false;
+    symtab_errf(ctx, "File has no name");
   }
 
   file->name =
@@ -1863,7 +1966,7 @@ static bool build_filedef(
   if (google_protobuf_FileDescriptorProto_has_package(file_proto)) {
     upb_strview package =
         google_protobuf_FileDescriptorProto_package(file_proto);
-    CHK(upb_isident(package, true, ctx->status));
+    check_ident(ctx, package, true);
     file->package = strviewdup(ctx, package);
   } else {
     file->package = NULL;
@@ -1878,9 +1981,8 @@ static bool build_filedef(
     } else if (streql_view(syntax, "proto3")) {
       file->syntax = UPB_SYNTAX_PROTO3;
     } else {
-      upb_status_seterrf(ctx->status, "Invalid syntax '" UPB_STRVIEW_FORMAT "'",
-                         UPB_STRVIEW_ARGS(syntax));
-      return false;
+      symtab_errf(ctx, "Invalid syntax '" UPB_STRVIEW_FORMAT "'",
+                  UPB_STRVIEW_ARGS(syntax));
     }
   } else {
     file->syntax = UPB_SYNTAX_PROTO2;
@@ -1902,19 +2004,17 @@ static bool build_filedef(
 
   /* Verify dependencies. */
   strs = google_protobuf_FileDescriptorProto_dependency(file_proto, &n);
-  file->deps = upb_malloc(alloc, sizeof(*file->deps) * n) ;
-  CHK_OOM(n == 0 || file->deps);
+  file->deps = symtab_alloc(ctx, sizeof(*file->deps) * n);
 
   for (i = 0; i < n; i++) {
     upb_strview dep_name = strs[i];
     upb_value v;
     if (!upb_strtable_lookup2(&ctx->symtab->files, dep_name.data,
                               dep_name.size, &v)) {
-      upb_status_seterrf(ctx->status,
-                         "Depends on file '" UPB_STRVIEW_FORMAT
-                         "', but it has not been loaded",
-                         UPB_STRVIEW_ARGS(dep_name));
-      return false;
+      symtab_errf(ctx,
+                  "Depends on file '" UPB_STRVIEW_FORMAT
+                  "', but it has not been loaded",
+                  UPB_STRVIEW_ARGS(dep_name));
     }
     file->deps[i] = upb_value_getconstptr(v);
   }
@@ -1922,194 +2022,99 @@ static bool build_filedef(
   /* Create messages. */
   msgs = google_protobuf_FileDescriptorProto_message_type(file_proto, &n);
   for (i = 0; i < n; i++) {
-    CHK(create_msgdef(ctx, file->package, msgs[i]));
+    create_msgdef(ctx, file->package, msgs[i]);
   }
 
   /* Create enums. */
   enums = google_protobuf_FileDescriptorProto_enum_type(file_proto, &n);
   for (i = 0; i < n; i++) {
-    CHK(create_enumdef(ctx, file->package, enums[i]));
+    create_enumdef(ctx, file->package, enums[i]);
   }
 
   /* Create extensions. */
   exts = google_protobuf_FileDescriptorProto_extension(file_proto, &n);
-  file->exts = upb_malloc(alloc, sizeof(*file->exts) * n);
-  CHK_OOM(n == 0 || file->exts);
+  file->exts = symtab_alloc(ctx, sizeof(*file->exts) * n);
   for (i = 0; i < n; i++) {
-    CHK(create_fielddef(ctx, file->package, NULL, exts[i]));
+    create_fielddef(ctx, file->package, NULL, exts[i]);
   }
 
   /* Now that all names are in the table, build layouts and resolve refs. */
   for (i = 0; i < (size_t)file->ext_count; i++) {
-    CHK(resolve_fielddef(ctx, file->package, (upb_fielddef*)&file->exts[i]));
+    resolve_fielddef(ctx, file->package, (upb_fielddef*)&file->exts[i]);
   }
 
   for (i = 0; i < (size_t)file->msg_count; i++) {
     const upb_msgdef *m = &file->msgs[i];
     int j;
     for (j = 0; j < m->field_count; j++) {
-      CHK(resolve_fielddef(ctx, m->full_name, (upb_fielddef*)&m->fields[j]));
+      resolve_fielddef(ctx, m->full_name, (upb_fielddef*)&m->fields[j]);
     }
   }
 
   if (!ctx->layouts) {
     for (i = 0; i < (size_t)file->msg_count; i++) {
       const upb_msgdef *m = &file->msgs[i];
-      make_layout(ctx->symtab, m);
+      make_layout(ctx, m);
     }
   }
+}
 
-  return true;
- }
-
-static bool upb_symtab_addtotabs(upb_symtab *s, symtab_addctx *ctx) {
-  const upb_filedef *file = ctx->file;
+static void remove_filedef(upb_symtab *s, upb_filedef *file) {
   upb_alloc *alloc = upb_arena_alloc(s->arena);
-  upb_strtable_iter iter;
-
-  CHK_OOM(upb_strtable_insert3(&s->files, file->name, strlen(file->name),
-                               upb_value_constptr(file), alloc));
-
-  upb_strtable_begin(&iter, ctx->addtab);
-  for (; !upb_strtable_done(&iter); upb_strtable_next(&iter)) {
-    upb_strview key = upb_strtable_iter_key(&iter);
-    upb_value value = upb_strtable_iter_value(&iter);
-    CHK_OOM(upb_strtable_insert3(&s->syms, key.data, key.size, value, alloc));
+  int i;
+  for (i = 0; i < file->msg_count; i++) {
+    const char *name = file->msgs[i].full_name;
+    upb_strtable_remove3(&s->syms, name, strlen(name), NULL, alloc);
   }
-
-  return true;
-}
-
-/* upb_filedef ****************************************************************/
-
-const char *upb_filedef_name(const upb_filedef *f) {
-  return f->name;
-}
-
-const char *upb_filedef_package(const upb_filedef *f) {
-  return f->package;
-}
-
-const char *upb_filedef_phpprefix(const upb_filedef *f) {
-  return f->phpprefix;
-}
-
-const char *upb_filedef_phpnamespace(const upb_filedef *f) {
-  return f->phpnamespace;
-}
-
-upb_syntax_t upb_filedef_syntax(const upb_filedef *f) {
-  return f->syntax;
-}
-
-int upb_filedef_msgcount(const upb_filedef *f) {
-  return f->msg_count;
-}
-
-int upb_filedef_depcount(const upb_filedef *f) {
-  return f->dep_count;
-}
-
-int upb_filedef_enumcount(const upb_filedef *f) {
-  return f->enum_count;
-}
-
-const upb_filedef *upb_filedef_dep(const upb_filedef *f, int i) {
-  return i < 0 || i >= f->dep_count ? NULL : f->deps[i];
-}
-
-const upb_msgdef *upb_filedef_msg(const upb_filedef *f, int i) {
-  return i < 0 || i >= f->msg_count ? NULL : &f->msgs[i];
-}
-
-const upb_enumdef *upb_filedef_enum(const upb_filedef *f, int i) {
-  return i < 0 || i >= f->enum_count ? NULL : &f->enums[i];
-}
-
-void upb_symtab_free(upb_symtab *s) {
-  upb_arena_free(s->arena);
-  upb_gfree(s);
-}
-
-upb_symtab *upb_symtab_new(void) {
-  upb_symtab *s = upb_gmalloc(sizeof(*s));
-  upb_alloc *alloc;
-
-  if (!s) {
-    return NULL;
+  for (i = 0; i < file->enum_count; i++) {
+    const char *name = file->enums[i].full_name;
+    upb_strtable_remove3(&s->syms, name, strlen(name), NULL, alloc);
   }
-
-  s->arena = upb_arena_new();
-  alloc = upb_arena_alloc(s->arena);
-
-  if (!upb_strtable_init2(&s->syms, UPB_CTYPE_CONSTPTR, alloc) ||
-      !upb_strtable_init2(&s->files, UPB_CTYPE_CONSTPTR, alloc)) {
-    upb_arena_free(s->arena);
-    upb_gfree(s);
-    s = NULL;
+  for (i = 0; i < file->ext_count; i++) {
+    const char *name = file->exts[i].full_name;
+    upb_strtable_remove3(&s->syms, name, strlen(name), NULL, alloc);
   }
-  return s;
-}
-
-const upb_msgdef *upb_symtab_lookupmsg(const upb_symtab *s, const char *sym) {
-  upb_value v;
-  return upb_strtable_lookup(&s->syms, sym, &v) ?
-      unpack_def(v, UPB_DEFTYPE_MSG) : NULL;
-}
-
-const upb_msgdef *upb_symtab_lookupmsg2(const upb_symtab *s, const char *sym,
-                                        size_t len) {
-  upb_value v;
-  return upb_strtable_lookup2(&s->syms, sym, len, &v) ?
-      unpack_def(v, UPB_DEFTYPE_MSG) : NULL;
-}
-
-const upb_enumdef *upb_symtab_lookupenum(const upb_symtab *s, const char *sym) {
-  upb_value v;
-  return upb_strtable_lookup(&s->syms, sym, &v) ?
-      unpack_def(v, UPB_DEFTYPE_ENUM) : NULL;
-}
-
-const upb_filedef *upb_symtab_lookupfile(const upb_symtab *s, const char *name) {
-  upb_value v;
-  return upb_strtable_lookup(&s->files, name, &v) ? upb_value_getconstptr(v)
-                                                  : NULL;
-}
-
-const upb_filedef *upb_symtab_lookupfile2(
-    const upb_symtab *s, const char *name, size_t len) {
-  upb_value v;
-  return upb_strtable_lookup2(&s->files, name, len, &v) ?
-      upb_value_getconstptr(v) : NULL;
-}
-
-int upb_symtab_filecount(const upb_symtab *s) {
-  return (int)upb_strtable_count(&s->files);
 }
 
 static const upb_filedef *_upb_symtab_addfile(
     upb_symtab *s, const google_protobuf_FileDescriptorProto *file_proto,
     const upb_msglayout **layouts, upb_status *status) {
-  upb_arena *tmparena = upb_arena_new();
-  upb_strtable addtab;
-  upb_alloc *alloc = upb_arena_alloc(s->arena);
-  upb_filedef *file = upb_malloc(alloc, sizeof(*file));
-  bool ok;
+  upb_arena *file_arena = upb_arena_new();
+  upb_filedef *file;
   symtab_addctx ctx;
 
+  if (!file_arena) return NULL;
+
+  file = upb_arena_malloc(file_arena, sizeof(*file));
+  if (!file) goto done;
+
   ctx.file = file;
   ctx.symtab = s;
-  ctx.alloc = alloc;
-  ctx.tmp = upb_arena_alloc(tmparena);
-  ctx.addtab = &addtab;
+  ctx.file_arena = file_arena;
+  ctx.alloc = upb_arena_alloc(file_arena);
   ctx.layouts = layouts;
   ctx.status = status;
 
-  ok = file && upb_strtable_init2(&addtab, UPB_CTYPE_CONSTPTR, ctx.tmp) &&
-       build_filedef(&ctx, file, file_proto) && upb_symtab_addtotabs(s, &ctx);
+  file->msg_count = 0;
+  file->enum_count = 0;
+  file->ext_count = 0;
+  file->symtab = s;
+
+  if (UPB_UNLIKELY(UPB_SETJMP(ctx.err))) {
+    UPB_ASSERT(!upb_ok(status));
+    remove_filedef(s, file);
+    file = NULL;
+  } else {
+    build_filedef(&ctx, file, file_proto);
+    upb_strtable_insert3(&s->files, file->name, strlen(file->name),
+                         upb_value_constptr(file), ctx.alloc);
+    UPB_ASSERT(upb_ok(status));
+    upb_arena_fuse(s->arena, file_arena);
+  }
 
-  upb_arena_free(tmparena);
-  return ok ? file : NULL;
+done:
+  upb_arena_free(file_arena);
+  return file;
 }
 
 const upb_filedef *upb_symtab_addfile(
@@ -2141,8 +2146,9 @@ bool _upb_symtab_loaddefinit(upb_symtab *s, const upb_def_init *init) {
     if (!_upb_symtab_loaddefinit(s, *deps)) goto err;
   }
 
-  file = google_protobuf_FileDescriptorProto_parse(
-      init->descriptor.data, init->descriptor.size, arena);
+  file = google_protobuf_FileDescriptorProto_parse_ex(
+      init->descriptor.data, init->descriptor.size, arena, UPB_DECODE_ALIAS);
+  s->bytes_loaded += init->descriptor.size;
 
   if (!file) {
     upb_status_seterrf(
@@ -2165,5 +2171,8 @@ err:
   return false;
 }
 
-#undef CHK
+size_t _upb_symtab_bytesloaded(const upb_symtab *s) {
+  return s->bytes_loaded;
+}
+
 #undef CHK_OOM
index a7ce5d0..7206ec0 100644 (file)
@@ -117,9 +117,10 @@ typedef upb_inttable_iter upb_oneof_iter;
 
 const char *upb_oneofdef_name(const upb_oneofdef *o);
 const upb_msgdef *upb_oneofdef_containingtype(const upb_oneofdef *o);
-int upb_oneofdef_numfields(const upb_oneofdef *o);
 uint32_t upb_oneofdef_index(const upb_oneofdef *o);
 bool upb_oneofdef_issynthetic(const upb_oneofdef *o);
+int upb_oneofdef_fieldcount(const upb_oneofdef *o);
+const upb_fielddef *upb_oneofdef_field(const upb_oneofdef *o, int i);
 
 /* Oneof lookups:
  * - ntof:  look up a field by name.
@@ -133,11 +134,8 @@ UPB_INLINE const upb_fielddef *upb_oneofdef_ntofz(const upb_oneofdef *o,
 }
 const upb_fielddef *upb_oneofdef_itof(const upb_oneofdef *o, uint32_t num);
 
-/*  upb_oneof_iter i;
- *  for(upb_oneof_begin(&i, e); !upb_oneof_done(&i); upb_oneof_next(&i)) {
- *    // ...
- *  }
- */
+/* DEPRECATED, slated for removal. */
+int upb_oneofdef_numfields(const upb_oneofdef *o);
 void upb_oneof_begin(upb_oneof_iter *iter, const upb_oneofdef *o);
 void upb_oneof_next(upb_oneof_iter *iter);
 bool upb_oneof_done(upb_oneof_iter *iter);
@@ -145,6 +143,7 @@ upb_fielddef *upb_oneof_iter_field(const upb_oneof_iter *iter);
 void upb_oneof_iter_setdone(upb_oneof_iter *iter);
 bool upb_oneof_iter_isequal(const upb_oneof_iter *iter1,
                             const upb_oneof_iter *iter2);
+/* END DEPRECATED */
 
 /* upb_msgdef *****************************************************************/
 
@@ -170,21 +169,21 @@ typedef upb_strtable_iter upb_msg_oneof_iter;
 const char *upb_msgdef_fullname(const upb_msgdef *m);
 const upb_filedef *upb_msgdef_file(const upb_msgdef *m);
 const char *upb_msgdef_name(const upb_msgdef *m);
-int upb_msgdef_numfields(const upb_msgdef *m);
-int upb_msgdef_numoneofs(const upb_msgdef *m);
-int upb_msgdef_numrealoneofs(const upb_msgdef *m);
 upb_syntax_t upb_msgdef_syntax(const upb_msgdef *m);
 bool upb_msgdef_mapentry(const upb_msgdef *m);
 upb_wellknowntype_t upb_msgdef_wellknowntype(const upb_msgdef *m);
 bool upb_msgdef_iswrapper(const upb_msgdef *m);
 bool upb_msgdef_isnumberwrapper(const upb_msgdef *m);
+int upb_msgdef_fieldcount(const upb_msgdef *m);
+int upb_msgdef_oneofcount(const upb_msgdef *m);
+const upb_fielddef *upb_msgdef_field(const upb_msgdef *m, int i);
+const upb_oneofdef *upb_msgdef_oneof(const upb_msgdef *m, int i);
 const upb_fielddef *upb_msgdef_itof(const upb_msgdef *m, uint32_t i);
 const upb_fielddef *upb_msgdef_ntof(const upb_msgdef *m, const char *name,
                                     size_t len);
 const upb_oneofdef *upb_msgdef_ntoo(const upb_msgdef *m, const char *name,
                                     size_t len);
 const upb_msglayout *upb_msgdef_layout(const upb_msgdef *m);
-const upb_fielddef *_upb_msgdef_field(const upb_msgdef *m, int i);
 
 UPB_INLINE const upb_oneofdef *upb_msgdef_ntooz(const upb_msgdef *m,
                                                const char *name) {
@@ -216,19 +215,10 @@ UPB_INLINE bool upb_msgdef_lookupnamez(const upb_msgdef *m, const char *name,
 const upb_fielddef *upb_msgdef_lookupjsonname(const upb_msgdef *m,
                                               const char *name, size_t len);
 
-/* Iteration over fields and oneofs.  For example:
- *
- * upb_msg_field_iter i;
- * for(upb_msg_field_begin(&i, m);
- *     !upb_msg_field_done(&i);
- *     upb_msg_field_next(&i)) {
- *   upb_fielddef *f = upb_msg_iter_field(&i);
- *   // ...
- * }
- *
- * For C we don't have separate iterators for const and non-const.
- * It is the caller's responsibility to cast the upb_fielddef* to
- * const if the upb_msgdef* is const. */
+/* DEPRECATED, slated for removal */
+int upb_msgdef_numfields(const upb_msgdef *m);
+int upb_msgdef_numoneofs(const upb_msgdef *m);
+int upb_msgdef_numrealoneofs(const upb_msgdef *m);
 void upb_msg_field_begin(upb_msg_field_iter *iter, const upb_msgdef *m);
 void upb_msg_field_next(upb_msg_field_iter *iter);
 bool upb_msg_field_done(const upb_msg_field_iter *iter);
@@ -236,9 +226,6 @@ upb_fielddef *upb_msg_iter_field(const upb_msg_field_iter *iter);
 void upb_msg_field_iter_setdone(upb_msg_field_iter *iter);
 bool upb_msg_field_iter_isequal(const upb_msg_field_iter * iter1,
                                 const upb_msg_field_iter * iter2);
-
-/* Similar to above, we also support iterating through the oneofs in a
- * msgdef. */
 void upb_msg_oneof_begin(upb_msg_oneof_iter * iter, const upb_msgdef *m);
 void upb_msg_oneof_next(upb_msg_oneof_iter * iter);
 bool upb_msg_oneof_done(const upb_msg_oneof_iter *iter);
@@ -246,6 +233,7 @@ const upb_oneofdef *upb_msg_iter_oneof(const upb_msg_oneof_iter *iter);
 void upb_msg_oneof_iter_setdone(upb_msg_oneof_iter * iter);
 bool upb_msg_oneof_iter_isequal(const upb_msg_oneof_iter *iter1,
                                 const upb_msg_oneof_iter *iter2);
+/* END DEPRECATED */
 
 /* upb_enumdef ****************************************************************/
 
@@ -270,11 +258,6 @@ UPB_INLINE bool upb_enumdef_ntoiz(const upb_enumdef *e,
 }
 const char *upb_enumdef_iton(const upb_enumdef *e, int32_t num);
 
-/*  upb_enum_iter i;
- *  for(upb_enum_begin(&i, e); !upb_enum_done(&i); upb_enum_next(&i)) {
- *    // ...
- *  }
- */
 void upb_enum_begin(upb_enum_iter *iter, const upb_enumdef *e);
 void upb_enum_next(upb_enum_iter *iter);
 bool upb_enum_done(upb_enum_iter *iter);
@@ -294,6 +277,7 @@ int upb_filedef_enumcount(const upb_filedef *f);
 const upb_filedef *upb_filedef_dep(const upb_filedef *f, int i);
 const upb_msgdef *upb_filedef_msg(const upb_filedef *f, int i);
 const upb_enumdef *upb_filedef_enum(const upb_filedef *f, int i);
+const upb_symtab *upb_filedef_symtab(const upb_filedef *f);
 
 /* upb_symtab *****************************************************************/
 
@@ -310,6 +294,7 @@ int upb_symtab_filecount(const upb_symtab *s);
 const upb_filedef *upb_symtab_addfile(
     upb_symtab *s, const google_protobuf_FileDescriptorProto *file,
     upb_status *status);
+size_t _upb_symtab_bytesloaded(const upb_symtab *s);
 
 /* For generated code only: loads a generated descriptor. */
 typedef struct upb_def_init {
index 62d06bb..e32da2a 100644 (file)
@@ -129,17 +129,17 @@ class OneofDefPtr {
   explicit OneofDefPtr(const upb_oneofdef* ptr) : ptr_(ptr) {}
 
   const upb_oneofdef* ptr() const { return ptr_; }
-  explicit operator bool() { return ptr_ != nullptr; }
+  explicit operator bool() const { return ptr_ != nullptr; }
 
-  // Returns the MessageDef that owns this OneofDef.
+  // Returns the MessageDef that contains this OneofDef.
   MessageDefPtr containing_type() const;
 
-  // Returns the name of this oneof. This is the name used to look up the oneof
-  // by name once added to a message def.
+  // Returns the name of this oneof.
   const char* name() const { return upb_oneofdef_name(ptr_); }
 
-  // Returns the number of fields currently defined in the oneof.
+  // Returns the number of fields in the oneof.
   int field_count() const { return upb_oneofdef_numfields(ptr_); }
+  FieldDefPtr field(int i) const { return FieldDefPtr(upb_oneofdef_field(ptr_, i)); }
 
   // Looks up by name.
   FieldDefPtr FindFieldByName(const char* name, size_t len) const {
@@ -159,40 +159,6 @@ class OneofDefPtr {
     return FieldDefPtr(upb_oneofdef_itof(ptr_, num));
   }
 
-  class const_iterator
-      : public std::iterator<std::forward_iterator_tag, FieldDefPtr> {
-   public:
-    void operator++() { upb_oneof_next(&iter_); }
-
-    FieldDefPtr operator*() const {
-      return FieldDefPtr(upb_oneof_iter_field(&iter_));
-    }
-
-    bool operator!=(const const_iterator& other) const {
-      return !upb_oneof_iter_isequal(&iter_, &other.iter_);
-    }
-
-    bool operator==(const const_iterator& other) const {
-      return upb_oneof_iter_isequal(&iter_, &other.iter_);
-    }
-
-   private:
-    friend class OneofDefPtr;
-
-    const_iterator() {}
-    explicit const_iterator(OneofDefPtr o) { upb_oneof_begin(&iter_, o.ptr()); }
-    static const_iterator end() {
-      const_iterator iter;
-      upb_oneof_iter_setdone(&iter.iter_);
-      return iter;
-    }
-
-    upb_oneof_iter iter_;
-  };
-
-  const_iterator begin() const { return const_iterator(*this); }
-  const_iterator end() const { return const_iterator::end(); }
-
  private:
   const upb_oneofdef* ptr_;
 };
@@ -211,9 +177,11 @@ class MessageDefPtr {
 
   // The number of fields that belong to the MessageDef.
   int field_count() const { return upb_msgdef_numfields(ptr_); }
+  FieldDefPtr field(int i) const { return FieldDefPtr(upb_msgdef_field(ptr_, i)); }
 
   // The number of oneofs that belong to the MessageDef.
   int oneof_count() const { return upb_msgdef_numoneofs(ptr_); }
+  OneofDefPtr oneof(int i) const { return OneofDefPtr(upb_msgdef_oneof(ptr_, i)); }
 
   upb_syntax_t syntax() const { return upb_msgdef_syntax(ptr_); }
 
@@ -258,112 +226,58 @@ class MessageDefPtr {
   // Whether is a number wrapper.
   bool isnumberwrapper() const { return upb_msgdef_isnumberwrapper(ptr_); }
 
-  // Iteration over fields.  The order is undefined.
-  class const_field_iterator
-      : public std::iterator<std::forward_iterator_tag, FieldDefPtr> {
+ private:
+  class FieldIter {
    public:
-    void operator++() { upb_msg_field_next(&iter_); }
-
-    FieldDefPtr operator*() const {
-      return FieldDefPtr(upb_msg_iter_field(&iter_));
-    }
+    explicit FieldIter(const upb_msgdef *m, int i) : m_(m), i_(i) {}
+    void operator++() { i_++; }
 
-    bool operator!=(const const_field_iterator& other) const {
-      return !upb_msg_field_iter_isequal(&iter_, &other.iter_);
-    }
-
-    bool operator==(const const_field_iterator& other) const {
-      return upb_msg_field_iter_isequal(&iter_, &other.iter_);
-    }
+    FieldDefPtr operator*() { return FieldDefPtr(upb_msgdef_field(m_, i_)); }
+    bool operator!=(const FieldIter& other) { return i_ != other.i_; }
+    bool operator==(const FieldIter& other) { return i_ == other.i_; }
 
    private:
-    friend class MessageDefPtr;
-
-    explicit const_field_iterator() {}
-
-    explicit const_field_iterator(MessageDefPtr msg) {
-      upb_msg_field_begin(&iter_, msg.ptr());
-    }
-
-    static const_field_iterator end() {
-      const_field_iterator iter;
-      upb_msg_field_iter_setdone(&iter.iter_);
-      return iter;
-    }
-
-    upb_msg_field_iter iter_;
+    const upb_msgdef *m_;
+    int i_;
   };
 
-  // Iteration over oneofs. The order is undefined.
-  class const_oneof_iterator
-      : public std::iterator<std::forward_iterator_tag, OneofDefPtr> {
+  class FieldAccessor {
    public:
-    void operator++() { upb_msg_oneof_next(&iter_); }
-
-    OneofDefPtr operator*() const {
-      return OneofDefPtr(upb_msg_iter_oneof(&iter_));
-    }
-
-    bool operator!=(const const_oneof_iterator& other) const {
-      return !upb_msg_oneof_iter_isequal(&iter_, &other.iter_);
-    }
-
-    bool operator==(const const_oneof_iterator& other) const {
-      return upb_msg_oneof_iter_isequal(&iter_, &other.iter_);
-    }
+    explicit FieldAccessor(const upb_msgdef* md) : md_(md) {}
+    FieldIter begin() { return FieldIter(md_, 0); }
+    FieldIter end() { return FieldIter(md_, upb_msgdef_fieldcount(md_)); }
 
    private:
-    friend class MessageDefPtr;
-
-    const_oneof_iterator() {}
-
-    explicit const_oneof_iterator(MessageDefPtr msg) {
-      upb_msg_oneof_begin(&iter_, msg.ptr());
-    }
-
-    static const_oneof_iterator end() {
-      const_oneof_iterator iter;
-      upb_msg_oneof_iter_setdone(&iter.iter_);
-      return iter;
-    }
-
-    upb_msg_oneof_iter iter_;
+    const upb_msgdef* md_;
   };
 
-  class ConstFieldAccessor {
+  class OneofIter {
    public:
-    explicit ConstFieldAccessor(const upb_msgdef* md) : md_(md) {}
-    const_field_iterator begin() { return MessageDefPtr(md_).field_begin(); }
-    const_field_iterator end() { return MessageDefPtr(md_).field_end(); }
+    explicit OneofIter(const upb_msgdef *m, int i) : m_(m), i_(i) {}
+    void operator++() { i_++; }
+
+    OneofDefPtr operator*() { return OneofDefPtr(upb_msgdef_oneof(m_, i_)); }
+    bool operator!=(const OneofIter& other) { return i_ != other.i_; }
+    bool operator==(const OneofIter& other) { return i_ == other.i_; }
 
    private:
-    const upb_msgdef* md_;
+    const upb_msgdef *m_;
+    int i_;
   };
 
-  class ConstOneofAccessor {
+  class OneofAccessor {
    public:
-    explicit ConstOneofAccessor(const upb_msgdef* md) : md_(md) {}
-    const_oneof_iterator begin() { return MessageDefPtr(md_).oneof_begin(); }
-    const_oneof_iterator end() { return MessageDefPtr(md_).oneof_end(); }
+    explicit OneofAccessor(const upb_msgdef* md) : md_(md) {}
+    OneofIter begin() { return OneofIter(md_, 0); }
+    OneofIter end() { return OneofIter(md_, upb_msgdef_oneofcount(md_)); }
 
    private:
     const upb_msgdef* md_;
   };
 
-  const_field_iterator field_begin() const {
-    return const_field_iterator(*this);
-  }
-
-  const_field_iterator field_end() const { return const_field_iterator::end(); }
-
-  const_oneof_iterator oneof_begin() const {
-    return const_oneof_iterator(*this);
-  }
-
-  const_oneof_iterator oneof_end() const { return const_oneof_iterator::end(); }
-
-  ConstFieldAccessor fields() const { return ConstFieldAccessor(ptr()); }
-  ConstOneofAccessor oneofs() const { return ConstOneofAccessor(ptr()); }
+ public:
+  FieldAccessor fields() const { return FieldAccessor(ptr()); }
+  OneofAccessor oneofs() const { return OneofAccessor(ptr()); }
 
  private:
   const upb_msgdef* ptr_;
index a6ce62b..f73ff09 100644 (file)
@@ -2,35 +2,39 @@
 
 #include "upb/encode.h"
 
+#include <setjmp.h>
 #include <string.h>
 
 #include "upb/msg.h"
 #include "upb/upb.h"
 
+/* Must be last. */
 #include "upb/port_def.inc"
 
 #define UPB_PB_VARINT_MAX_LEN 10
-#define CHK(x) do { if (!(x)) { return false; } } while(0)
 
-static size_t upb_encode_varint(uint64_t val, char *buf) {
-  size_t i;
-  if (val < 128) { buf[0] = val; return 1; }
-  i = 0;
-  while (val) {
+UPB_NOINLINE
+static size_t encode_varint64(uint64_t val, char *buf) {
+  size_t i = 0;
+  do {
     uint8_t byte = val & 0x7fU;
     val >>= 7;
     if (val) byte |= 0x80U;
     buf[i++] = byte;
-  }
+  } while (val);
   return i;
 }
 
-static uint32_t upb_zzencode_32(int32_t n) { return ((uint32_t)n << 1) ^ (n >> 31); }
-static uint64_t upb_zzencode_64(int64_t n) { return ((uint64_t)n << 1) ^ (n >> 63); }
+static uint32_t encode_zz32(int32_t n) { return ((uint32_t)n << 1) ^ (n >> 31); }
+static uint64_t encode_zz64(int64_t n) { return ((uint64_t)n << 1) ^ (n >> 63); }
 
 typedef struct {
+  jmp_buf err;
   upb_alloc *alloc;
   char *buf, *ptr, *limit;
+  int options;
+  int depth;
+  _upb_mapsorter sorter;
 } upb_encstate;
 
 static size_t upb_roundup_pow2(size_t bytes) {
@@ -41,11 +45,17 @@ static size_t upb_roundup_pow2(size_t bytes) {
   return ret;
 }
 
-static bool upb_encode_growbuffer(upb_encstate *e, size_t bytes) {
+UPB_NORETURN static void encode_err(upb_encstate *e) {
+  UPB_LONGJMP(e->err, 1);
+}
+
+UPB_NOINLINE
+static void encode_growbuffer(upb_encstate *e, size_t bytes) {
   size_t old_size = e->limit - e->buf;
   size_t new_size = upb_roundup_pow2(bytes + (e->limit - e->ptr));
   char *new_buf = upb_realloc(e->alloc, e->buf, old_size, new_size);
-  CHK(new_buf);
+
+  if (!new_buf) encode_err(e);
 
   /* We want previous data at the end, realloc() put it at the beginning. */
   if (old_size > 0) {
@@ -55,99 +65,116 @@ static bool upb_encode_growbuffer(upb_encstate *e, size_t bytes) {
   e->ptr = new_buf + new_size - (e->limit - e->ptr);
   e->limit = new_buf + new_size;
   e->buf = new_buf;
-  return true;
+
+  e->ptr -= bytes;
 }
 
 /* Call to ensure that at least "bytes" bytes are available for writing at
  * e->ptr.  Returns false if the bytes could not be allocated. */
-static bool upb_encode_reserve(upb_encstate *e, size_t bytes) {
-  CHK(UPB_LIKELY((size_t)(e->ptr - e->buf) >= bytes) ||
-      upb_encode_growbuffer(e, bytes));
+UPB_FORCEINLINE
+static void encode_reserve(upb_encstate *e, size_t bytes) {
+  if ((size_t)(e->ptr - e->buf) < bytes) {
+    encode_growbuffer(e, bytes);
+    return;
+  }
 
   e->ptr -= bytes;
-  return true;
 }
 
 /* Writes the given bytes to the buffer, handling reserve/advance. */
-static bool upb_put_bytes(upb_encstate *e, const void *data, size_t len) {
-  if (len == 0) return true;
-  CHK(upb_encode_reserve(e, len));
+static void encode_bytes(upb_encstate *e, const void *data, size_t len) {
+  if (len == 0) return;  /* memcpy() with zero size is UB */
+  encode_reserve(e, len);
   memcpy(e->ptr, data, len);
-  return true;
 }
 
-static bool upb_put_fixed64(upb_encstate *e, uint64_t val) {
+static void encode_fixed64(upb_encstate *e, uint64_t val) {
   val = _upb_be_swap64(val);
-  return upb_put_bytes(e, &val, sizeof(uint64_t));
+  encode_bytes(e, &val, sizeof(uint64_t));
 }
 
-static bool upb_put_fixed32(upb_encstate *e, uint32_t val) {
+static void encode_fixed32(upb_encstate *e, uint32_t val) {
   val = _upb_be_swap32(val);
-  return upb_put_bytes(e, &val, sizeof(uint32_t));
+  encode_bytes(e, &val, sizeof(uint32_t));
 }
 
-static bool upb_put_varint(upb_encstate *e, uint64_t val) {
+UPB_NOINLINE
+static void encode_longvarint(upb_encstate *e, uint64_t val) {
   size_t len;
   char *start;
-  CHK(upb_encode_reserve(e, UPB_PB_VARINT_MAX_LEN));
-  len = upb_encode_varint(val, e->ptr);
+
+  encode_reserve(e, UPB_PB_VARINT_MAX_LEN);
+  len = encode_varint64(val, e->ptr);
   start = e->ptr + UPB_PB_VARINT_MAX_LEN - len;
   memmove(start, e->ptr, len);
   e->ptr = start;
-  return true;
 }
 
-static bool upb_put_double(upb_encstate *e, double d) {
+UPB_FORCEINLINE
+static void encode_varint(upb_encstate *e, uint64_t val) {
+  if (val < 128 && e->ptr != e->buf) {
+    --e->ptr;
+    *e->ptr = val;
+  } else {
+    encode_longvarint(e, val);
+  }
+}
+
+static void encode_double(upb_encstate *e, double d) {
   uint64_t u64;
   UPB_ASSERT(sizeof(double) == sizeof(uint64_t));
   memcpy(&u64, &d, sizeof(uint64_t));
-  return upb_put_fixed64(e, u64);
+  encode_fixed64(e, u64);
 }
 
-static bool upb_put_float(upb_encstate *e, float d) {
+static void encode_float(upb_encstate *e, float d) {
   uint32_t u32;
   UPB_ASSERT(sizeof(float) == sizeof(uint32_t));
   memcpy(&u32, &d, sizeof(uint32_t));
-  return upb_put_fixed32(e, u32);
+  encode_fixed32(e, u32);
 }
 
-static bool upb_put_tag(upb_encstate *e, int field_number, int wire_type) {
-  return upb_put_varint(e, (field_number << 3) | wire_type);
+static void encode_tag(upb_encstate *e, uint32_t field_number,
+                       uint8_t wire_type) {
+  encode_varint(e, (field_number << 3) | wire_type);
 }
 
-static bool upb_put_fixedarray(upb_encstate *e, const upb_array *arr,
+static void encode_fixedarray(upb_encstate *e, const upb_array *arr,
                                size_t elem_size, uint32_t tag) {
   size_t bytes = arr->len * elem_size;
   const char* data = _upb_array_constptr(arr);
   const char* ptr = data + bytes - elem_size;
   if (tag) {
     while (true) {
-      CHK(upb_put_bytes(e, ptr, elem_size) && upb_put_varint(e, tag));
+      encode_bytes(e, ptr, elem_size);
+      encode_varint(e, tag);
       if (ptr == data) break;
       ptr -= elem_size;
     }
-    return true;
   } else {
-    return upb_put_bytes(e, data, bytes) && upb_put_varint(e, bytes);
+    encode_bytes(e, data, bytes);
   }
 }
 
-bool upb_encode_message(upb_encstate *e, const char *msg,
-                        const upb_msglayout *m, size_t *size);
+static void encode_message(upb_encstate *e, const char *msg,
+                           const upb_msglayout *m, size_t *size);
 
-static bool upb_encode_scalarfield(upb_encstate *e, const void *_field_mem,
-                                   const upb_msglayout *m,
-                                   const upb_msglayout_field *f,
-                                   bool skip_zero_value) {
+static void encode_scalar(upb_encstate *e, const void *_field_mem,
+                          const upb_msglayout *m, const upb_msglayout_field *f,
+                          bool skip_zero_value) {
   const char *field_mem = _field_mem;
-#define CASE(ctype, type, wire_type, encodeval) do { \
-  ctype val = *(ctype*)field_mem; \
-  if (skip_zero_value && val == 0) { \
-    return true; \
-  } \
-  return upb_put_ ## type(e, encodeval) && \
-      upb_put_tag(e, f->number, wire_type); \
-} while(0)
+  int wire_type;
+
+#define CASE(ctype, type, wtype, encodeval) \
+  {                                         \
+    ctype val = *(ctype *)field_mem;        \
+    if (skip_zero_value && val == 0) {      \
+      return;                               \
+    }                                       \
+    encode_##type(e, encodeval);            \
+    wire_type = wtype;                      \
+    break;                                  \
+  }
 
   switch (f->descriptortype) {
     case UPB_DESCRIPTOR_TYPE_DOUBLE:
@@ -171,90 +198,95 @@ static bool upb_encode_scalarfield(upb_encstate *e, const void *_field_mem,
     case UPB_DESCRIPTOR_TYPE_BOOL:
       CASE(bool, varint, UPB_WIRE_TYPE_VARINT, val);
     case UPB_DESCRIPTOR_TYPE_SINT32:
-      CASE(int32_t, varint, UPB_WIRE_TYPE_VARINT, upb_zzencode_32(val));
+      CASE(int32_t, varint, UPB_WIRE_TYPE_VARINT, encode_zz32(val));
     case UPB_DESCRIPTOR_TYPE_SINT64:
-      CASE(int64_t, varint, UPB_WIRE_TYPE_VARINT, upb_zzencode_64(val));
+      CASE(int64_t, varint, UPB_WIRE_TYPE_VARINT, encode_zz64(val));
     case UPB_DESCRIPTOR_TYPE_STRING:
     case UPB_DESCRIPTOR_TYPE_BYTES: {
       upb_strview view = *(upb_strview*)field_mem;
       if (skip_zero_value && view.size == 0) {
-        return true;
+        return;
       }
-      return upb_put_bytes(e, view.data, view.size) &&
-          upb_put_varint(e, view.size) &&
-          upb_put_tag(e, f->number, UPB_WIRE_TYPE_DELIMITED);
+      encode_bytes(e, view.data, view.size);
+      encode_varint(e, view.size);
+      wire_type = UPB_WIRE_TYPE_DELIMITED;
+      break;
     }
     case UPB_DESCRIPTOR_TYPE_GROUP: {
       size_t size;
       void *submsg = *(void **)field_mem;
       const upb_msglayout *subm = m->submsgs[f->submsg_index];
       if (submsg == NULL) {
-        return true;
+        return;
       }
-      return upb_put_tag(e, f->number, UPB_WIRE_TYPE_END_GROUP) &&
-          upb_encode_message(e, submsg, subm, &size) &&
-          upb_put_tag(e, f->number, UPB_WIRE_TYPE_START_GROUP);
+      if (--e->depth == 0) encode_err(e);
+      encode_tag(e, f->number, UPB_WIRE_TYPE_END_GROUP);
+      encode_message(e, submsg, subm, &size);
+      wire_type = UPB_WIRE_TYPE_START_GROUP;
+      e->depth++;
+      break;
     }
     case UPB_DESCRIPTOR_TYPE_MESSAGE: {
       size_t size;
       void *submsg = *(void **)field_mem;
       const upb_msglayout *subm = m->submsgs[f->submsg_index];
       if (submsg == NULL) {
-        return true;
+        return;
       }
-      return upb_encode_message(e, submsg, subm, &size) &&
-          upb_put_varint(e, size) &&
-          upb_put_tag(e, f->number, UPB_WIRE_TYPE_DELIMITED);
+      if (--e->depth == 0) encode_err(e);
+      encode_message(e, submsg, subm, &size);
+      encode_varint(e, size);
+      wire_type = UPB_WIRE_TYPE_DELIMITED;
+      e->depth++;
+      break;
     }
+    default:
+      UPB_UNREACHABLE();
   }
 #undef CASE
-  UPB_UNREACHABLE();
+
+  encode_tag(e, f->number, wire_type);
 }
 
-static bool upb_encode_array(upb_encstate *e, const char *field_mem,
-                             const upb_msglayout *m,
-                             const upb_msglayout_field *f) {
+static void encode_array(upb_encstate *e, const char *field_mem,
+                         const upb_msglayout *m, const upb_msglayout_field *f) {
   const upb_array *arr = *(const upb_array**)field_mem;
   bool packed = f->label == _UPB_LABEL_PACKED;
+  size_t pre_len = e->limit - e->ptr;
 
   if (arr == NULL || arr->len == 0) {
-    return true;
+    return;
   }
 
 #define VARINT_CASE(ctype, encode)                                       \
   {                                                                      \
     const ctype *start = _upb_array_constptr(arr);                       \
     const ctype *ptr = start + arr->len;                                 \
-    size_t pre_len = e->limit - e->ptr;                                  \
     uint32_t tag = packed ? 0 : (f->number << 3) | UPB_WIRE_TYPE_VARINT; \
     do {                                                                 \
       ptr--;                                                             \
-      CHK(upb_put_varint(e, encode));                                    \
-      if (tag) CHK(upb_put_varint(e, tag));                              \
+      encode_varint(e, encode);                                          \
+      if (tag) encode_varint(e, tag);                                    \
     } while (ptr != start);                                              \
-    if (!tag) CHK(upb_put_varint(e, e->limit - e->ptr - pre_len));       \
   }                                                                      \
-  break;                                                                 \
-  do {                                                                   \
-    ;                                                                    \
-  } while (0)
+  break;
 
 #define TAG(wire_type) (packed ? 0 : (f->number << 3 | wire_type))
 
   switch (f->descriptortype) {
     case UPB_DESCRIPTOR_TYPE_DOUBLE:
-      CHK(upb_put_fixedarray(e, arr, sizeof(double), TAG(UPB_WIRE_TYPE_64BIT)));
+      encode_fixedarray(e, arr, sizeof(double), TAG(UPB_WIRE_TYPE_64BIT));
       break;
     case UPB_DESCRIPTOR_TYPE_FLOAT:
-      CHK(upb_put_fixedarray(e, arr, sizeof(float), TAG(UPB_WIRE_TYPE_32BIT)));
+      encode_fixedarray(e, arr, sizeof(float), TAG(UPB_WIRE_TYPE_32BIT));
       break;
     case UPB_DESCRIPTOR_TYPE_SFIXED64:
     case UPB_DESCRIPTOR_TYPE_FIXED64:
-      CHK(upb_put_fixedarray(e, arr, sizeof(uint64_t), TAG(UPB_WIRE_TYPE_64BIT)));
+      encode_fixedarray(e, arr, sizeof(uint64_t), TAG(UPB_WIRE_TYPE_64BIT));
       break;
     case UPB_DESCRIPTOR_TYPE_FIXED32:
     case UPB_DESCRIPTOR_TYPE_SFIXED32:
-      CHK(upb_put_fixedarray(e, arr, sizeof(uint32_t), TAG(UPB_WIRE_TYPE_32BIT)));
+      encode_fixedarray(e, arr, sizeof(uint32_t), TAG(UPB_WIRE_TYPE_32BIT));
       break;
     case UPB_DESCRIPTOR_TYPE_INT64:
     case UPB_DESCRIPTOR_TYPE_UINT64:
@@ -267,154 +299,180 @@ static bool upb_encode_array(upb_encstate *e, const char *field_mem,
     case UPB_DESCRIPTOR_TYPE_BOOL:
       VARINT_CASE(bool, *ptr);
     case UPB_DESCRIPTOR_TYPE_SINT32:
-      VARINT_CASE(int32_t, upb_zzencode_32(*ptr));
+      VARINT_CASE(int32_t, encode_zz32(*ptr));
     case UPB_DESCRIPTOR_TYPE_SINT64:
-      VARINT_CASE(int64_t, upb_zzencode_64(*ptr));
+      VARINT_CASE(int64_t, encode_zz64(*ptr));
     case UPB_DESCRIPTOR_TYPE_STRING:
     case UPB_DESCRIPTOR_TYPE_BYTES: {
       const upb_strview *start = _upb_array_constptr(arr);
       const upb_strview *ptr = start + arr->len;
       do {
         ptr--;
-        CHK(upb_put_bytes(e, ptr->data, ptr->size) &&
-            upb_put_varint(e, ptr->size) &&
-            upb_put_tag(e, f->number, UPB_WIRE_TYPE_DELIMITED));
+        encode_bytes(e, ptr->data, ptr->size);
+        encode_varint(e, ptr->size);
+        encode_tag(e, f->number, UPB_WIRE_TYPE_DELIMITED);
       } while (ptr != start);
-      return true;
+      return;
     }
     case UPB_DESCRIPTOR_TYPE_GROUP: {
       const void *const*start = _upb_array_constptr(arr);
       const void *const*ptr = start + arr->len;
       const upb_msglayout *subm = m->submsgs[f->submsg_index];
+      if (--e->depth == 0) encode_err(e);
       do {
         size_t size;
         ptr--;
-        CHK(upb_put_tag(e, f->number, UPB_WIRE_TYPE_END_GROUP) &&
-            upb_encode_message(e, *ptr, subm, &size) &&
-            upb_put_tag(e, f->number, UPB_WIRE_TYPE_START_GROUP));
+        encode_tag(e, f->number, UPB_WIRE_TYPE_END_GROUP);
+        encode_message(e, *ptr, subm, &size);
+        encode_tag(e, f->number, UPB_WIRE_TYPE_START_GROUP);
       } while (ptr != start);
-      return true;
+      e->depth++;
+      return;
     }
     case UPB_DESCRIPTOR_TYPE_MESSAGE: {
       const void *const*start = _upb_array_constptr(arr);
       const void *const*ptr = start + arr->len;
       const upb_msglayout *subm = m->submsgs[f->submsg_index];
+      if (--e->depth == 0) encode_err(e);
       do {
         size_t size;
         ptr--;
-        CHK(upb_encode_message(e, *ptr, subm, &size) &&
-            upb_put_varint(e, size) &&
-            upb_put_tag(e, f->number, UPB_WIRE_TYPE_DELIMITED));
+        encode_message(e, *ptr, subm, &size);
+        encode_varint(e, size);
+        encode_tag(e, f->number, UPB_WIRE_TYPE_DELIMITED);
       } while (ptr != start);
-      return true;
+      e->depth++;
+      return;
     }
   }
 #undef VARINT_CASE
 
   if (packed) {
-    CHK(upb_put_tag(e, f->number, UPB_WIRE_TYPE_DELIMITED));
+    encode_varint(e, e->limit - e->ptr - pre_len);
+    encode_tag(e, f->number, UPB_WIRE_TYPE_DELIMITED);
   }
-  return true;
 }
 
-static bool upb_encode_map(upb_encstate *e, const char *field_mem,
-                           const upb_msglayout *m,
-                           const upb_msglayout_field *f) {
+static void encode_mapentry(upb_encstate *e, uint32_t number,
+                            const upb_msglayout *layout,
+                            const upb_map_entry *ent) {
+  const upb_msglayout_field *key_field = &layout->fields[0];
+  const upb_msglayout_field *val_field = &layout->fields[1];
+  size_t pre_len = e->limit - e->ptr;
+  size_t size;
+  encode_scalar(e, &ent->v, layout, val_field, false);
+  encode_scalar(e, &ent->k, layout, key_field, false);
+  size = (e->limit - e->ptr) - pre_len;
+  encode_varint(e, size);
+  encode_tag(e, number, UPB_WIRE_TYPE_DELIMITED);
+}
+
+static void encode_map(upb_encstate *e, const char *field_mem,
+                       const upb_msglayout *m, const upb_msglayout_field *f) {
   const upb_map *map = *(const upb_map**)field_mem;
-  const upb_msglayout *entry = m->submsgs[f->submsg_index];
-  const upb_msglayout_field *key_field = &entry->fields[0];
-  const upb_msglayout_field *val_field = &entry->fields[1];
-  upb_strtable_iter i;
-  if (map == NULL) {
-    return true;
-  }
+  const upb_msglayout *layout = m->submsgs[f->submsg_index];
+  UPB_ASSERT(layout->field_count == 2);
+
+  if (map == NULL) return;
 
-  upb_strtable_begin(&i, &map->table);
-  for(; !upb_strtable_done(&i); upb_strtable_next(&i)) {
-    size_t pre_len = e->limit - e->ptr;
-    size_t size;
-    upb_strview key = upb_strtable_iter_key(&i);
-    const upb_value val = upb_strtable_iter_value(&i);
+  if (e->options & UPB_ENCODE_DETERMINISTIC) {
+    _upb_sortedmap sorted;
+    _upb_mapsorter_pushmap(&e->sorter, layout->fields[0].descriptortype, map,
+                           &sorted);
     upb_map_entry ent;
-    _upb_map_fromkey(key, &ent.k, map->key_size);
-    _upb_map_fromvalue(val, &ent.v, map->val_size);
-    CHK(upb_encode_scalarfield(e, &ent.v, entry, val_field, false));
-    CHK(upb_encode_scalarfield(e, &ent.k, entry, key_field, false));
-    size = (e->limit - e->ptr) - pre_len;
-    CHK(upb_put_varint(e, size));
-    CHK(upb_put_tag(e, f->number, UPB_WIRE_TYPE_DELIMITED));
+    while (_upb_sortedmap_next(&e->sorter, map, &sorted, &ent)) {
+      encode_mapentry(e, f->number, layout, &ent);
+    }
+    _upb_mapsorter_popmap(&e->sorter, &sorted);
+  } else {
+    upb_strtable_iter i;
+    upb_strtable_begin(&i, &map->table);
+    for(; !upb_strtable_done(&i); upb_strtable_next(&i)) {
+      upb_strview key = upb_strtable_iter_key(&i);
+      const upb_value val = upb_strtable_iter_value(&i);
+      upb_map_entry ent;
+      _upb_map_fromkey(key, &ent.k, map->key_size);
+      _upb_map_fromvalue(val, &ent.v, map->val_size);
+      encode_mapentry(e, f->number, layout, &ent);
+    }
   }
-
-  return true;
 }
 
+static void encode_scalarfield(upb_encstate *e, const char *msg,
+                               const upb_msglayout *m,
+                               const upb_msglayout_field *f) {
+  bool skip_empty = false;
+  if (f->presence == 0) {
+    /* Proto3 presence. */
+    skip_empty = true;
+  } else if (f->presence > 0) {
+    /* Proto2 presence: hasbit. */
+    if (!_upb_hasbit_field(msg, f)) return;
+  } else {
+    /* Field is in a oneof. */
+    if (_upb_getoneofcase_field(msg, f) != f->number) return;
+  }
+  encode_scalar(e, msg + f->offset, m, f, skip_empty);
+}
 
-bool upb_encode_message(upb_encstate *e, const char *msg,
-                        const upb_msglayout *m, size_t *size) {
-  int i;
+static void encode_message(upb_encstate *e, const char *msg,
+                           const upb_msglayout *m, size_t *size) {
   size_t pre_len = e->limit - e->ptr;
-  const char *unknown;
-  size_t unknown_size;
+  const upb_msglayout_field *f = &m->fields[m->field_count];
+  const upb_msglayout_field *first = &m->fields[0];
 
-  unknown = upb_msg_getunknown(msg, &unknown_size);
+  if ((e->options & UPB_ENCODE_SKIPUNKNOWN) == 0) {
+    size_t unknown_size;
+    const char *unknown = upb_msg_getunknown(msg, &unknown_size);
 
-  if (unknown) {
-    upb_put_bytes(e, unknown, unknown_size);
+    if (unknown) {
+      encode_bytes(e, unknown, unknown_size);
+    }
   }
 
-  for (i = m->field_count - 1; i >= 0; i--) {
-    const upb_msglayout_field *f = &m->fields[i];
-
+  while (f != first) {
+    f--;
     if (_upb_isrepeated(f)) {
-      CHK(upb_encode_array(e, msg + f->offset, m, f));
+      encode_array(e, msg + f->offset, m, f);
     } else if (f->label == _UPB_LABEL_MAP) {
-      CHK(upb_encode_map(e, msg + f->offset, m, f));
+      encode_map(e, msg + f->offset, m, f);
     } else {
-      bool skip_empty = false;
-      if (f->presence == 0) {
-        /* Proto3 presence. */
-        skip_empty = true;
-      } else if (f->presence > 0) {
-        /* Proto2 presence: hasbit. */
-        if (!_upb_hasbit_field(msg, f)) {
-          continue;
-        }
-      } else {
-        /* Field is in a oneof. */
-        if (_upb_getoneofcase_field(msg, f) != f->number) {
-          continue;
-        }
-      }
-      CHK(upb_encode_scalarfield(e, msg + f->offset, m, f, skip_empty));
+      encode_scalarfield(e, msg, m, f);
     }
   }
 
   *size = (e->limit - e->ptr) - pre_len;
-  return true;
 }
 
-char *upb_encode(const void *msg, const upb_msglayout *m, upb_arena *arena,
-                 size_t *size) {
+char *upb_encode_ex(const void *msg, const upb_msglayout *m, int options,
+                    upb_arena *arena, size_t *size) {
   upb_encstate e;
+  unsigned depth = (unsigned)options >> 16;
+
   e.alloc = upb_arena_alloc(arena);
   e.buf = NULL;
   e.limit = NULL;
   e.ptr = NULL;
+  e.depth = depth ? depth : 64;
+  e.options = options;
+  _upb_mapsorter_init(&e.sorter);
+  char *ret = NULL;
 
-  if (!upb_encode_message(&e, msg, m, size)) {
+  if (UPB_SETJMP(e.err)) {
     *size = 0;
-    return NULL;
-  }
-
-  *size = e.limit - e.ptr;
-
-  if (*size == 0) {
-    static char ch;
-    return &ch;
+    ret = NULL;
   } else {
-    UPB_ASSERT(e.ptr);
-    return e.ptr;
+    encode_message(&e, msg, m, size);
+    *size = e.limit - e.ptr;
+    if (*size == 0) {
+      static char ch;
+      ret = &ch;
+    } else {
+      UPB_ASSERT(e.ptr);
+      ret = e.ptr;
+    }
   }
-}
 
-#undef CHK
+  _upb_mapsorter_destroy(&e.sorter);
+  return ret;
+}
index 6842777..d3c1dc9 100644 (file)
@@ -7,12 +7,37 @@
 
 #include "upb/msg.h"
 
+/* Must be last. */
+#include "upb/port_def.inc"
+
 #ifdef __cplusplus
 extern "C" {
 #endif
 
-char *upb_encode(const void *msg, const upb_msglayout *l, upb_arena *arena,
-                 size_t *size);
+enum {
+  /* If set, the results of serializing will be deterministic across all
+   * instances of this binary. There are no guarantees across different
+   * binary builds.
+   *
+   * If your proto contains maps, the encoder will need to malloc()/free()
+   * memory during encode. */
+  UPB_ENCODE_DETERMINISTIC = 1,
+
+  /* When set, unknown fields are not printed. */
+  UPB_ENCODE_SKIPUNKNOWN = 2,
+};
+
+#define UPB_ENCODE_MAXDEPTH(depth) ((depth) << 16)
+
+char *upb_encode_ex(const void *msg, const upb_msglayout *l, int options,
+                    upb_arena *arena, size_t *size);
+
+UPB_INLINE char *upb_encode(const void *msg, const upb_msglayout *l,
+                            upb_arena *arena, size_t *size) {
+  return upb_encode_ex(msg, l, 0, arena, size);
+}
+
+#include "upb/port_undef.inc"
 
 #ifdef __cplusplus
 }  /* extern "C" */
index b90b32c..4168a4f 100644 (file)
@@ -359,7 +359,7 @@ struct upb_handlercache {
 
 const upb_handlers *upb_handlercache_get(upb_handlercache *c,
                                          const upb_msgdef *md) {
-  upb_msg_field_iter i;
+  int i, n;
   upb_value v;
   upb_handlers *h;
 
@@ -377,10 +377,9 @@ const upb_handlers *upb_handlercache_get(upb_handlercache *c,
 
   /* For each submessage field, get or create a handlers object and set it as
    * the subhandlers. */
-  for(upb_msg_field_begin(&i, md);
-      !upb_msg_field_done(&i);
-      upb_msg_field_next(&i)) {
-    upb_fielddef *f = upb_msg_iter_field(&i);
+  n = upb_msgdef_fieldcount(md);
+  for (i = 0; i < n; i++) {
+    const upb_fielddef *f = upb_msgdef_field(md, i);
 
     if (upb_fielddef_issubmsg(f)) {
       const upb_msgdef *subdef = upb_fielddef_msgsubdef(f);
index f1ea076..a7d75ff 100644 (file)
@@ -951,7 +951,7 @@ static bool parse_number_from_buffer(upb_json_parser *p, const char *buf,
   upb_fieldtype_t type = upb_fielddef_type(p->top->f);
   double val;
   double dummy;
-  double inf = UPB_INFINITY;
+  double inf = INFINITY;
 
   errno = 0;
 
@@ -2858,7 +2858,7 @@ static void json_parser_reset(upb_json_parser *p) {
 
 static upb_json_parsermethod *parsermethod_new(upb_json_codecache *c,
                                                const upb_msgdef *md) {
-  upb_msg_field_iter i;
+  int i, n;
   upb_alloc *alloc = upb_arena_alloc(c->arena);
 
   upb_json_parsermethod *m = upb_malloc(alloc, sizeof(*m));
@@ -2869,14 +2869,13 @@ static upb_json_parsermethod *parsermethod_new(upb_json_codecache *c,
   upb_byteshandler_setstring(&m->input_handler_, parse, m);
   upb_byteshandler_setendstr(&m->input_handler_, end, m);
 
-  upb_strtable_init2(&m->name_table, UPB_CTYPE_CONSTPTR, alloc);
+  upb_strtable_init2(&m->name_table, UPB_CTYPE_CONSTPTR, 4, alloc);
 
   /* Build name_table */
 
-  for(upb_msg_field_begin(&i, md);
-      !upb_msg_field_done(&i);
-      upb_msg_field_next(&i)) {
-    const upb_fielddef *f = upb_msg_iter_field(&i);
+  n = upb_msgdef_fieldcount(md);
+  for(i = 0; i < n; i++) {
+    const upb_fielddef *f = upb_msgdef_field(md, i);
     upb_value v = upb_value_constptr(f);
     const char *name;
 
@@ -2965,7 +2964,7 @@ const upb_json_parsermethod *upb_json_codecache_get(upb_json_codecache *c,
                                                     const upb_msgdef *md) {
   upb_json_parsermethod *m;
   upb_value v;
-  upb_msg_field_iter i;
+  int i, n;
   upb_alloc *alloc = upb_arena_alloc(c->arena);
 
   if (upb_inttable_lookupptr(&c->methods, md, &v)) {
@@ -2980,10 +2979,9 @@ const upb_json_parsermethod *upb_json_codecache_get(upb_json_codecache *c,
 
   /* Populate parser methods for all submessages, so the name tables will
    * be available during parsing. */
-  for(upb_msg_field_begin(&i, md);
-      !upb_msg_field_done(&i);
-      upb_msg_field_next(&i)) {
-    upb_fielddef *f = upb_msg_iter_field(&i);
+  n = upb_msgdef_fieldcount(md);
+  for(i = 0; i < n; i++) {
+    const upb_fielddef *f = upb_msgdef_field(md, i);
 
     if (upb_fielddef_issubmsg(f)) {
       const upb_msgdef *subdef = upb_fielddef_msgsubdef(f);
index 3a88219..2f0c8fb 100644 (file)
@@ -7,7 +7,9 @@
 
 #include <ctype.h>
 #include <inttypes.h>
+#include <math.h>
 #include <stdint.h>
+#include <stdio.h>
 #include <string.h>
 #include <time.h>
 
@@ -139,7 +141,7 @@ static void putstring(upb_json_printer *p, const char *buf, size_t len) {
       char escape_buf[8];
       if (!escape) {
         unsigned char byte = (unsigned char)c;
-        _upb_snprintf(escape_buf, sizeof(escape_buf), "\\u%04x", (int)byte);
+        snprintf(escape_buf, sizeof(escape_buf), "\\u%04x", (int)byte);
         escape = escape_buf;
       }
 
@@ -178,53 +180,53 @@ const char neginf[] = "\"-Infinity\"";
 const char inf[] = "\"Infinity\"";
 
 static size_t fmt_double(double val, char* buf, size_t length) {
-  if (val == UPB_INFINITY) {
+  if (val == INFINITY) {
     CHKLENGTH(length >= strlen(inf));
     strcpy(buf, inf);
     return strlen(inf);
-  } else if (val == -UPB_INFINITY) {
+  } else if (val == -INFINITY) {
     CHKLENGTH(length >= strlen(neginf));
     strcpy(buf, neginf);
     return strlen(neginf);
   } else {
-    size_t n = _upb_snprintf(buf, length, "%.17g", val);
+    size_t n = snprintf(buf, length, "%.17g", val);
     CHKLENGTH(n > 0 && n < length);
     return n;
   }
 }
 
 static size_t fmt_float(float val, char* buf, size_t length) {
-  size_t n = _upb_snprintf(buf, length, "%.8g", val);
+  size_t n = snprintf(buf, length, "%.8g", val);
   CHKLENGTH(n > 0 && n < length);
   return n;
 }
 
 static size_t fmt_bool(bool val, char* buf, size_t length) {
-  size_t n = _upb_snprintf(buf, length, "%s", (val ? "true" : "false"));
+  size_t n = snprintf(buf, length, "%s", (val ? "true" : "false"));
   CHKLENGTH(n > 0 && n < length);
   return n;
 }
 
 static size_t fmt_int64_as_number(int64_t val, char* buf, size_t length) {
-  size_t n = _upb_snprintf(buf, length, "%" PRId64, val);
+  size_t n = snprintf(buf, length, "%" PRId64, val);
   CHKLENGTH(n > 0 && n < length);
   return n;
 }
 
 static size_t fmt_uint64_as_number(uint64_t val, char* buf, size_t length) {
-  size_t n = _upb_snprintf(buf, length, "%" PRIu64, val);
+  size_t n = snprintf(buf, length, "%" PRIu64, val);
   CHKLENGTH(n > 0 && n < length);
   return n;
 }
 
 static size_t fmt_int64_as_string(int64_t val, char* buf, size_t length) {
-  size_t n = _upb_snprintf(buf, length, "\"%" PRId64 "\"", val);
+  size_t n = snprintf(buf, length, "\"%" PRId64 "\"", val);
   CHKLENGTH(n > 0 && n < length);
   return n;
 }
 
 static size_t fmt_uint64_as_string(uint64_t val, char* buf, size_t length) {
-  size_t n = _upb_snprintf(buf, length, "\"%" PRIu64 "\"", val);
+  size_t n = snprintf(buf, length, "\"%" PRIu64 "\"", val);
   CHKLENGTH(n > 0 && n < length);
   return n;
 }
@@ -870,12 +872,12 @@ static bool printer_enddurationmsg(void *closure, const void *handler_data,
     return false;
   }
 
-  _upb_snprintf(buffer, sizeof(buffer), "%ld", (long)p->seconds);
+  snprintf(buffer, sizeof(buffer), "%ld", (long)p->seconds);
   base_len = strlen(buffer);
 
   if (p->nanos != 0) {
     char nanos_buffer[UPB_DURATION_MAX_NANO_LEN + 3];
-    _upb_snprintf(nanos_buffer, sizeof(nanos_buffer), "%.9f",
+    snprintf(nanos_buffer, sizeof(nanos_buffer), "%.9f",
                   p->nanos / 1000000000.0);
     /* Remove trailing 0. */
     for (i = UPB_DURATION_MAX_NANO_LEN + 2;
@@ -949,8 +951,8 @@ static bool printer_endtimestampmsg(void *closure, const void *handler_data,
            "%Y-%m-%dT%H:%M:%S", gmtime(&time));
   if (p->nanos != 0) {
     char nanos_buffer[UPB_TIMESTAMP_MAX_NANO_LEN + 3];
-    _upb_snprintf(nanos_buffer, sizeof(nanos_buffer), "%.9f",
-                  p->nanos / 1000000000.0);
+    snprintf(nanos_buffer, sizeof(nanos_buffer), "%.9f",
+             p->nanos / 1000000000.0);
     /* Remove trailing 0. */
     for (i = UPB_TIMESTAMP_MAX_NANO_LEN + 2;
          nanos_buffer[i] == '0'; i--) {
@@ -1124,16 +1126,16 @@ void printer_sethandlers_timestamp(const void *closure, upb_handlers *h) {
 
 void printer_sethandlers_value(const void *closure, upb_handlers *h) {
   const upb_msgdef *md = upb_handlers_msgdef(h);
-  upb_msg_field_iter i;
+  int i, n;
 
   upb_handlerattr empty_attr = UPB_HANDLERATTR_INIT;
 
   upb_handlers_setstartmsg(h, printer_startmsg_noframe, &empty_attr);
   upb_handlers_setendmsg(h, printer_endmsg_noframe, &empty_attr);
 
-  upb_msg_field_begin(&i, md);
-  for(; !upb_msg_field_done(&i); upb_msg_field_next(&i)) {
-    const upb_fielddef *f = upb_msg_iter_field(&i);
+  n = upb_msgdef_fieldcount(md);
+  for (i = 0; i < n; i++) {
+    const upb_fielddef *f = upb_msgdef_field(md, i);
 
     switch (upb_fielddef_type(f)) {
       case UPB_TYPE_ENUM:
@@ -1222,7 +1224,7 @@ void printer_sethandlers(const void *closure, upb_handlers *h) {
   const upb_msgdef *md = upb_handlers_msgdef(h);
   bool is_mapentry = upb_msgdef_mapentry(md);
   upb_handlerattr empty_attr = UPB_HANDLERATTR_INIT;
-  upb_msg_field_iter i;
+  int i, n;
   const upb_json_printercache *cache = closure;
   const bool preserve_fieldnames = cache->preserve_fieldnames;
 
@@ -1287,9 +1289,9 @@ void printer_sethandlers(const void *closure, upb_handlers *h) {
     }                                                                         \
     break;
 
-  upb_msg_field_begin(&i, md);
-  for(; !upb_msg_field_done(&i); upb_msg_field_next(&i)) {
-    const upb_fielddef *f = upb_msg_iter_field(&i);
+  n = upb_msgdef_fieldcount(md);
+  for (i = 0; i < n; i++) {
+    const upb_fielddef *f = upb_msgdef_field(md, i);
 
     upb_handlerattr name_attr = UPB_HANDLERATTR_INIT;
     name_attr.handler_data = newstrpc(h, f, preserve_fieldnames);
index 953d238..bb33744 100644 (file)
@@ -5,6 +5,7 @@
 #include <float.h>
 #include <inttypes.h>
 #include <limits.h>
+#include <math.h>
 #include <setjmp.h>
 #include <stdlib.h>
 #include <string.h>
@@ -42,10 +43,23 @@ static bool jsondec_streql(upb_strview str, const char *lit) {
   return str.size == strlen(lit) && memcmp(str.data, lit, str.size) == 0;
 }
 
+static bool jsondec_isnullvalue(const upb_fielddef *f) {
+  return upb_fielddef_type(f) == UPB_TYPE_ENUM &&
+         strcmp(upb_enumdef_fullname(upb_fielddef_enumsubdef(f)),
+                "google.protobuf.NullValue") == 0;
+}
+
+static bool jsondec_isvalue(const upb_fielddef *f) {
+  return (upb_fielddef_type(f) == UPB_TYPE_MESSAGE &&
+          upb_msgdef_wellknowntype(upb_fielddef_msgsubdef(f)) ==
+              UPB_WELLKNOWN_VALUE) ||
+         jsondec_isnullvalue(f);
+}
+
 UPB_NORETURN static void jsondec_err(jsondec *d, const char *msg) {
   upb_status_seterrf(d->status, "Error parsing JSON @%d:%d: %s", d->line,
                      (int)(d->ptr - d->line_begin), msg);
-  longjmp(d->err, 1);
+  UPB_LONGJMP(d->err, 1);
 }
 
 UPB_NORETURN static void jsondec_errf(jsondec *d, const char *fmt, ...) {
@@ -55,7 +69,7 @@ UPB_NORETURN static void jsondec_errf(jsondec *d, const char *fmt, ...) {
   va_start(argp, fmt);
   upb_status_vappenderrf(d->status, fmt, argp);
   va_end(argp);
-  longjmp(d->err, 1);
+  UPB_LONGJMP(d->err, 1);
 }
 
 static void jsondec_skipws(jsondec *d) {
@@ -382,6 +396,8 @@ static void jsondec_resize(jsondec *d, char **buf, char **end, char **buf_end) {
   size_t size = UPB_MAX(8, 2 * oldsize);
 
   *buf = upb_arena_realloc(d->arena, *buf, len, size);
+  if (!*buf) jsondec_err(d, "Out of memory");
+
   *end = *buf + len;
   *buf_end = *buf + size;
 }
@@ -734,11 +750,11 @@ static upb_msgval jsondec_double(jsondec *d, const upb_fielddef *f) {
     case JD_STRING:
       str = jsondec_string(d);
       if (jsondec_streql(str, "NaN")) {
-        val.double_val = UPB_NAN;
+        val.double_val = NAN;
       } else if (jsondec_streql(str, "Infinity")) {
-        val.double_val = UPB_INFINITY;
+        val.double_val = INFINITY;
       } else if (jsondec_streql(str, "-Infinity")) {
-        val.double_val = -UPB_INFINITY;
+        val.double_val = -INFINITY;
       } else {
         val.double_val = strtod(str.data, NULL);
       }
@@ -748,7 +764,7 @@ static upb_msgval jsondec_double(jsondec *d, const upb_fielddef *f) {
   }
 
   if (upb_fielddef_type(f) == UPB_TYPE_FLOAT) {
-    if (val.double_val != UPB_INFINITY && val.double_val != -UPB_INFINITY &&
+    if (val.double_val != INFINITY && val.double_val != -INFINITY &&
         (val.double_val > FLT_MAX || val.double_val < -FLT_MAX)) {
       jsondec_err(d, "Float out of range");
     }
@@ -769,21 +785,32 @@ static upb_msgval jsondec_strfield(jsondec *d, const upb_fielddef *f) {
 }
 
 static upb_msgval jsondec_enum(jsondec *d, const upb_fielddef *f) {
-  if (jsondec_peek(d) == JD_STRING) {
-    const upb_enumdef *e = upb_fielddef_enumsubdef(f);
-    upb_strview str = jsondec_string(d);
-    upb_msgval val;
-    if (!upb_enumdef_ntoi(e, str.data, str.size, &val.int32_val)) {
-      if (d->options & UPB_JSONDEC_IGNOREUNKNOWN) {
+  switch (jsondec_peek(d)) {
+    case JD_STRING: {
+      const upb_enumdef *e = upb_fielddef_enumsubdef(f);
+      upb_strview str = jsondec_string(d);
+      upb_msgval val;
+      if (!upb_enumdef_ntoi(e, str.data, str.size, &val.int32_val)) {
+        if (d->options & UPB_JSONDEC_IGNOREUNKNOWN) {
+          val.int32_val = 0;
+        } else {
+          jsondec_errf(d, "Unknown enumerator: '" UPB_STRVIEW_FORMAT "'",
+                       UPB_STRVIEW_ARGS(str));
+        }
+      }
+      return val;
+    }
+    case JD_NULL: {
+      if (jsondec_isnullvalue(f)) {
+        upb_msgval val;
+        jsondec_null(d);
         val.int32_val = 0;
-      } else {
-        jsondec_errf(d, "Unknown enumerator: '" UPB_STRVIEW_FORMAT "'",
-                     UPB_STRVIEW_ARGS(str));
+        return val;
       }
     }
-    return val;
-  } else {
-    return jsondec_int(d, f);
+      /* Fallthrough. */
+    default:
+      return jsondec_int(d, f);
   }
 }
 
@@ -867,12 +894,6 @@ static upb_msgval jsondec_msg(jsondec *d, const upb_fielddef *f) {
   return val;
 }
 
-static bool jsondec_isvalue(const upb_fielddef *f) {
-  return upb_fielddef_type(f) == UPB_TYPE_MESSAGE &&
-         upb_msgdef_wellknowntype(upb_fielddef_msgsubdef(f)) ==
-             UPB_WELLKNOWN_VALUE;
-}
-
 static void jsondec_field(jsondec *d, upb_msg *msg, const upb_msgdef *m) {
   upb_strview name;
   const upb_fielddef *f;
@@ -891,7 +912,7 @@ static void jsondec_field(jsondec *d, upb_msg *msg, const upb_msgdef *m) {
     return;
   }
 
-  if (upb_fielddef_containingoneof(f) &&
+  if (upb_fielddef_realcontainingoneof(f) &&
       upb_msg_whichoneof(msg, upb_fielddef_containingoneof(f))) {
     jsondec_err(d, "More than one field for this oneof.");
   }
@@ -1078,6 +1099,7 @@ static void jsondec_duration(jsondec *d, upb_msg *msg, const upb_msgdef *m) {
   upb_strview str = jsondec_string(d);
   const char *ptr = str.data;
   const char *end = ptr + str.size;
+  const int64_t max = (uint64_t)3652500 * 86400;
 
   /* "3.000000001s", "3s", etc. */
   ptr = jsondec_buftoint64(d, ptr, end, &seconds.int64_val);
@@ -1087,7 +1109,7 @@ static void jsondec_duration(jsondec *d, upb_msg *msg, const upb_msgdef *m) {
     jsondec_err(d, "Malformed duration");
   }
 
-  if (seconds.int64_val < -315576000000LL || seconds.int64_val > 315576000000LL) {
+  if (seconds.int64_val < -max || seconds.int64_val > max) {
     jsondec_err(d, "Duration out of range");
   }
 
@@ -1414,7 +1436,7 @@ bool upb_json_decode(const char *buf, size_t size, upb_msg *msg,
   d.debug_field = NULL;
   d.is_first = false;
 
-  if (setjmp(d.err)) return false;
+  if (UPB_SETJMP(d.err)) return false;
 
   jsondec_tomsg(&d, msg, m);
   return true;
index 6b6d99b..9217c65 100644 (file)
@@ -4,14 +4,16 @@
 #include <ctype.h>
 #include <float.h>
 #include <inttypes.h>
+#include <math.h>
+#include <setjmp.h>
 #include <stdarg.h>
 #include <stdio.h>
 #include <string.h>
-#include <setjmp.h>
 
 #include "upb/decode.h"
 #include "upb/reflection.h"
 
+/* Must be last. */
 #include "upb/port_def.inc"
 
 typedef struct {
@@ -76,7 +78,7 @@ static void jsonenc_printf(jsonenc *e, const char *fmt, ...) {
   va_list args;
 
   va_start(args, fmt);
-  n = _upb_vsnprintf(e->ptr, have, fmt, args);
+  n = vsnprintf(e->ptr, have, fmt, args);
   va_end(args);
 
   if (UPB_LIKELY(have > n)) {
@@ -167,12 +169,17 @@ static void jsonenc_duration(jsonenc *e, const upb_msg *msg, const upb_msgdef *m
 
 static void jsonenc_enum(int32_t val, const upb_fielddef *f, jsonenc *e) {
   const upb_enumdef *e_def = upb_fielddef_enumsubdef(f);
-  const char *name = upb_enumdef_iton(e_def, val);
 
-  if (name) {
-    jsonenc_printf(e, "\"%s\"", name);
+  if (strcmp(upb_enumdef_fullname(e_def), "google.protobuf.NullValue") == 0) {
+    jsonenc_putstr(e, "null");
   } else {
-    jsonenc_printf(e, "%" PRId32, val);
+    const char *name = upb_enumdef_iton(e_def, val);
+
+    if (name) {
+      jsonenc_printf(e, "\"%s\"", name);
+    } else {
+      jsonenc_printf(e, "%" PRId32, val);
+    }
   }
 }
 
@@ -263,9 +270,9 @@ static void jsonenc_string(jsonenc *e, upb_strview str) {
 }
 
 static void jsonenc_double(jsonenc *e, const char *fmt, double val) {
-  if (val == UPB_INFINITY) {
+  if (val == INFINITY) {
     jsonenc_putstr(e, "\"Infinity\"");
-  } else if (val == -UPB_INFINITY) {
+  } else if (val == -INFINITY) {
     jsonenc_putstr(e, "\"-Infinity\"");
   } else if (val != val) {
     jsonenc_putstr(e, "\"NaN\"");
@@ -587,7 +594,7 @@ static void jsonenc_mapkey(jsonenc *e, upb_msgval val, const upb_fielddef *f) {
 static void jsonenc_array(jsonenc *e, const upb_array *arr,
                          const upb_fielddef *f) {
   size_t i;
-  size_t size = upb_array_size(arr);
+  size_t size = arr ? upb_array_size(arr) : 0;
   bool first = true;
 
   jsonenc_putstr(e, "[");
@@ -609,10 +616,12 @@ static void jsonenc_map(jsonenc *e, const upb_map *map, const upb_fielddef *f) {
 
   jsonenc_putstr(e, "{");
 
-  while (upb_mapiter_next(map, &iter)) {
-    jsonenc_putsep(e, ",", &first);
-    jsonenc_mapkey(e, upb_mapiter_key(map, iter), key_f);
-    jsonenc_scalar(e, upb_mapiter_value(map, iter), val_f);
+  if (map) {
+    while (upb_mapiter_next(map, &iter)) {
+      jsonenc_putsep(e, ",", &first);
+      jsonenc_mapkey(e, upb_mapiter_key(map, iter), key_f);
+      jsonenc_scalar(e, upb_mapiter_value(map, iter), val_f);
+    }
   }
 
   jsonenc_putstr(e, "}");
@@ -648,11 +657,13 @@ static void jsonenc_msgfields(jsonenc *e, const upb_msg *msg,
 
   if (e->options & UPB_JSONENC_EMITDEFAULTS) {
     /* Iterate over all fields. */
-    upb_msg_field_iter i;
-    for (upb_msg_field_begin(&i, m); !upb_msg_field_done(&i);
-         upb_msg_field_next(&i)) {
-      f = upb_msg_iter_field(&i);
-      jsonenc_fieldval(e, f, upb_msg_get(msg, f), &first);
+    int i = 0;
+    int n = upb_msgdef_fieldcount(m);
+    for (i = 0; i < n; i++) {
+      f = upb_msgdef_field(m, i);
+      if (!upb_fielddef_haspresence(f) || upb_msg_has(msg, f)) {
+        jsonenc_fieldval(e, f, upb_msg_get(msg, f), &first);
+      }
     }
   } else {
     /* Iterate over non-empty fields. */
index 8396fbf..0ad4163 100644 (file)
@@ -9,7 +9,7 @@ extern "C" {
 #endif
 
 enum {
-  /* When set, emits 0/default values.  TOOD(haberman): proto3 only? */
+  /* When set, emits 0/default values.  TODO(haberman): proto3 only? */
   UPB_JSONENC_EMITDEFAULTS = 1,
 
   /* When set, use normal (snake_caes) field names instead of JSON (camelCase)
index 25747c8..876a06d 100644 (file)
 
 /** upb_msg *******************************************************************/
 
-static const char _upb_fieldtype_to_sizelg2[12] = {
-  0,
-  0,  /* UPB_TYPE_BOOL */
-  2,  /* UPB_TYPE_FLOAT */
-  2,  /* UPB_TYPE_INT32 */
-  2,  /* UPB_TYPE_UINT32 */
-  2,  /* UPB_TYPE_ENUM */
-  UPB_SIZE(2, 3),  /* UPB_TYPE_MESSAGE */
-  3,  /* UPB_TYPE_DOUBLE */
-  3,  /* UPB_TYPE_INT64 */
-  3,  /* UPB_TYPE_UINT64 */
-  UPB_SIZE(3, 4),  /* UPB_TYPE_STRING */
-  UPB_SIZE(3, 4),  /* UPB_TYPE_BYTES */
-};
-
-static uintptr_t tag_arrptr(void* ptr, int elem_size_lg2) {
-  UPB_ASSERT(elem_size_lg2 <= 4);
-  return (uintptr_t)ptr | elem_size_lg2;
-}
-
-static int upb_msg_internalsize(const upb_msglayout *l) {
-  return sizeof(upb_msg_internal) - l->extendable * sizeof(void *);
-}
-
-static size_t upb_msg_sizeof(const upb_msglayout *l) {
-  return l->size + upb_msg_internalsize(l);
-}
+static const size_t overhead = sizeof(upb_msg_internal);
 
 static const upb_msg_internal *upb_msg_getinternal_const(const upb_msg *msg) {
   ptrdiff_t size = sizeof(upb_msg_internal);
-  return UPB_PTR_AT(msg, -size, upb_msg_internal);
+  return (upb_msg_internal*)((char*)msg - size);
 }
 
-static upb_msg_internal *upb_msg_getinternal(upb_msg *msg) {
-  return (upb_msg_internal*)upb_msg_getinternal_const(msg);
+upb_msg *_upb_msg_new(const upb_msglayout *l, upb_arena *a) {
+  return _upb_msg_new_inl(l, a);
 }
 
 void _upb_msg_clear(upb_msg *msg, const upb_msglayout *l) {
-  ptrdiff_t internal = upb_msg_internalsize(l);
-  void *mem = UPB_PTR_AT(msg, -internal, char);
-  memset(mem, 0, l->size + internal);
-}
-
-upb_msg *_upb_msg_new(const upb_msglayout *l, upb_arena *a) {
-  void *mem = upb_arena_malloc(a, upb_msg_sizeof(l));
-  upb_msg *msg;
-
-  if (!mem) {
-    return NULL;
-  }
-
-  msg = UPB_PTR_AT(mem, upb_msg_internalsize(l), upb_msg);
-  _upb_msg_clear(msg, l);
-  return msg;
+  void *mem = UPB_PTR_AT(msg, -sizeof(upb_msg_internal), char);
+  memset(mem, 0, upb_msg_sizeof(l));
 }
 
 bool _upb_msg_addunknown(upb_msg *msg, const char *data, size_t len,
                          upb_arena *arena) {
+
   upb_msg_internal *in = upb_msg_getinternal(msg);
-  if (len > in->unknown_size - in->unknown_len) {
-    upb_alloc *alloc = upb_arena_alloc(arena);
-    size_t need = in->unknown_size + len;
-    size_t newsize = UPB_MAX(in->unknown_size * 2, need);
-    void *mem = upb_realloc(alloc, in->unknown, in->unknown_size, newsize);
-    if (!mem) return false;
-    in->unknown = mem;
-    in->unknown_size = newsize;
+  if (!in->unknown) {
+    size_t size = 128;
+    while (size < len) size *= 2;
+    in->unknown = upb_arena_malloc(arena, size + overhead);
+    if (!in->unknown) return false;
+    in->unknown->size = size;
+    in->unknown->len = 0;
+  } else if (in->unknown->size - in->unknown->len < len) {
+    size_t need = in->unknown->len + len;
+    size_t size = in->unknown->size;
+    while (size < need)  size *= 2;
+    in->unknown = upb_arena_realloc(
+        arena, in->unknown, in->unknown->size + overhead, size + overhead);
+    if (!in->unknown) return false;
+    in->unknown->size = size;
   }
-  memcpy(in->unknown + in->unknown_len, data, len);
-  in->unknown_len += len;
+  memcpy(UPB_PTR_AT(in->unknown + 1, in->unknown->len, char), data, len);
+  in->unknown->len += len;
   return true;
 }
 
 void _upb_msg_discardunknown_shallow(upb_msg *msg) {
   upb_msg_internal *in = upb_msg_getinternal(msg);
-  in->unknown_len = 0;
+  if (in->unknown) {
+    in->unknown->len = 0;
+  }
 }
 
 const char *upb_msg_getunknown(const upb_msg *msg, size_t *len) {
   const upb_msg_internal *in = upb_msg_getinternal_const(msg);
-  *len = in->unknown_len;
-  return in->unknown;
-}
-
-/** upb_array *****************************************************************/
-
-upb_array *_upb_array_new(upb_arena *a, upb_fieldtype_t type) {
-  upb_array *arr = upb_arena_malloc(a, sizeof(upb_array));
-
-  if (!arr) {
+  if (in->unknown) {
+    *len = in->unknown->len;
+    return (char*)(in->unknown + 1);
+  } else {
+    *len = 0;
     return NULL;
   }
-
-  arr->data = tag_arrptr(NULL, _upb_fieldtype_to_sizelg2[type]);
-  arr->len = 0;
-  arr->size = 0;
-
-  return arr;
 }
 
+/** upb_array *****************************************************************/
+
 bool _upb_array_realloc(upb_array *arr, size_t min_size, upb_arena *arena) {
   size_t new_size = UPB_MAX(arr->size, 4);
   int elem_size_lg2 = arr->data & 7;
@@ -124,16 +85,16 @@ bool _upb_array_realloc(upb_array *arr, size_t min_size, upb_arena *arena) {
     return false;
   }
 
-  arr->data = tag_arrptr(ptr, elem_size_lg2);
+  arr->data = _upb_tag_arrptr(ptr, elem_size_lg2);
   arr->size = new_size;
   return true;
 }
 
-static upb_array *getorcreate_array(upb_array **arr_ptr, upb_fieldtype_t type,
+static upb_array *getorcreate_array(upb_array **arr_ptr, int elem_size_lg2,
                                     upb_arena *arena) {
   upb_array *arr = *arr_ptr;
   if (!arr) {
-    arr = _upb_array_new(arena, type);
+    arr = _upb_array_new(arena, 4, elem_size_lg2);
     if (!arr) return NULL;
     *arr_ptr = arr;
   }
@@ -141,22 +102,25 @@ static upb_array *getorcreate_array(upb_array **arr_ptr, upb_fieldtype_t type,
 }
 
 void *_upb_array_resize_fallback(upb_array **arr_ptr, size_t size,
-                                 upb_fieldtype_t type, upb_arena *arena) {
-  upb_array *arr = getorcreate_array(arr_ptr, type, arena);
-  return arr && _upb_array_resize(arr, size, arena) ? _upb_array_ptr(arr) : NULL;
+                                 int elem_size_lg2, upb_arena *arena) {
+  upb_array *arr = getorcreate_array(arr_ptr, elem_size_lg2, arena);
+  return arr && _upb_array_resize(arr, size, arena) ? _upb_array_ptr(arr)
+                                                    : NULL;
 }
 
 bool _upb_array_append_fallback(upb_array **arr_ptr, const void *value,
-                                upb_fieldtype_t type, upb_arena *arena) {
-  upb_array *arr = getorcreate_array(arr_ptr, type, arena);
-  size_t elem = arr->len;
-  int lg2 = _upb_fieldtype_to_sizelg2[type];
-  char *data;
+                                int elem_size_lg2, upb_arena *arena) {
+  upb_array *arr = getorcreate_array(arr_ptr, elem_size_lg2, arena);
+  if (!arr) return false;
+
+  size_t elems = arr->len;
 
-  if (!arr || !_upb_array_resize(arr, elem + 1, arena)) return false;
+  if (!_upb_array_resize(arr, elems + 1, arena)) {
+    return false;
+  }
 
-  data = _upb_array_ptr(arr);
-  memcpy(data + (elem << lg2), value, 1 << lg2);
+  char *data = _upb_array_ptr(arr);
+  memcpy(data + (elems << elem_size_lg2), value, 1 << elem_size_lg2);
   return true;
 }
 
@@ -169,9 +133,124 @@ upb_map *_upb_map_new(upb_arena *a, size_t key_size, size_t value_size) {
     return NULL;
   }
 
-  upb_strtable_init2(&map->table, UPB_CTYPE_INT32, upb_arena_alloc(a));
+  upb_strtable_init2(&map->table, UPB_CTYPE_INT32, 4, upb_arena_alloc(a));
   map->key_size = key_size;
   map->val_size = value_size;
 
   return map;
 }
+
+static void _upb_mapsorter_getkeys(const void *_a, const void *_b, void *a_key,
+                                   void *b_key, size_t size) {
+  const upb_tabent *const*a = _a;
+  const upb_tabent *const*b = _b;
+  upb_strview a_tabkey = upb_tabstrview((*a)->key);
+  upb_strview b_tabkey = upb_tabstrview((*b)->key);
+  _upb_map_fromkey(a_tabkey, a_key, size);
+  _upb_map_fromkey(b_tabkey, b_key, size);
+}
+
+static int _upb_mapsorter_cmpi64(const void *_a, const void *_b) {
+  int64_t a, b;
+  _upb_mapsorter_getkeys(_a, _b, &a, &b, 8);
+  return a - b;
+}
+
+static int _upb_mapsorter_cmpu64(const void *_a, const void *_b) {
+  uint64_t a, b;
+  _upb_mapsorter_getkeys(_a, _b, &a, &b, 8);
+  return a - b;
+}
+
+static int _upb_mapsorter_cmpi32(const void *_a, const void *_b) {
+  int32_t a, b;
+  _upb_mapsorter_getkeys(_a, _b, &a, &b, 4);
+  return a - b;
+}
+
+static int _upb_mapsorter_cmpu32(const void *_a, const void *_b) {
+  uint32_t a, b;
+  _upb_mapsorter_getkeys(_a, _b, &a, &b, 4);
+  return a - b;
+}
+
+static int _upb_mapsorter_cmpbool(const void *_a, const void *_b) {
+  bool a, b;
+  _upb_mapsorter_getkeys(_a, _b, &a, &b, 1);
+  return a - b;
+}
+
+static int _upb_mapsorter_cmpstr(const void *_a, const void *_b) {
+  upb_strview a, b;
+  _upb_mapsorter_getkeys(_a, _b, &a, &b, UPB_MAPTYPE_STRING);
+  size_t common_size = UPB_MIN(a.size, b.size);
+  int cmp = memcmp(a.data, b.data, common_size);
+  if (cmp) return cmp;
+  return a.size - b.size;
+}
+
+bool _upb_mapsorter_pushmap(_upb_mapsorter *s, upb_descriptortype_t key_type,
+                            const upb_map *map, _upb_sortedmap *sorted) {
+  int map_size = _upb_map_size(map);
+  sorted->start = s->size;
+  sorted->pos = sorted->start;
+  sorted->end = sorted->start + map_size;
+
+  /* Grow s->entries if necessary. */
+  if (sorted->end > s->cap) {
+    s->cap = _upb_lg2ceilsize(sorted->end);
+    s->entries = realloc(s->entries, s->cap * sizeof(*s->entries));
+    if (!s->entries) return false;
+  }
+
+  s->size = sorted->end;
+
+  /* Copy non-empty entries from the table to s->entries. */
+  upb_tabent const**dst = &s->entries[sorted->start];
+  const upb_tabent *src = map->table.t.entries;
+  const upb_tabent *end = src + upb_table_size(&map->table.t);
+  for (; src < end; src++) {
+    if (!upb_tabent_isempty(src)) {
+      *dst = src;
+      dst++;
+    }
+  }
+  UPB_ASSERT(dst == &s->entries[sorted->end]);
+
+  /* Sort entries according to the key type. */
+
+  int (*compar)(const void *, const void *);
+
+  switch (key_type) {
+    case UPB_DESCRIPTOR_TYPE_INT64:
+    case UPB_DESCRIPTOR_TYPE_SFIXED64:
+    case UPB_DESCRIPTOR_TYPE_SINT64:
+      compar = _upb_mapsorter_cmpi64;
+      break;
+    case UPB_DESCRIPTOR_TYPE_UINT64:
+    case UPB_DESCRIPTOR_TYPE_FIXED64:
+      compar = _upb_mapsorter_cmpu64;
+      break;
+    case UPB_DESCRIPTOR_TYPE_INT32:
+    case UPB_DESCRIPTOR_TYPE_SINT32:
+    case UPB_DESCRIPTOR_TYPE_SFIXED32:
+    case UPB_DESCRIPTOR_TYPE_ENUM:
+      compar = _upb_mapsorter_cmpi32;
+      break;
+    case UPB_DESCRIPTOR_TYPE_UINT32:
+    case UPB_DESCRIPTOR_TYPE_FIXED32:
+      compar = _upb_mapsorter_cmpu32;
+      break;
+    case UPB_DESCRIPTOR_TYPE_BOOL:
+      compar = _upb_mapsorter_cmpbool;
+      break;
+    case UPB_DESCRIPTOR_TYPE_STRING:
+      compar = _upb_mapsorter_cmpstr;
+      break;
+    default:
+      UPB_UNREACHABLE();
+  }
+
+  qsort(&s->entries[sorted->start], map_size, sizeof(*s->entries), compar);
+  return true;
+}
index 695c278..9b4557a 100644 (file)
@@ -9,11 +9,13 @@
 #define UPB_MSG_H_
 
 #include <stdint.h>
+#include <stdlib.h>
 #include <string.h>
 
 #include "upb/table.int.h"
 #include "upb/upb.h"
 
+/* Must be last. */
 #include "upb/port_def.inc"
 
 #ifdef __cplusplus
@@ -46,6 +48,18 @@ typedef struct {
   uint8_t label;          /* google.protobuf.Label or _UPB_LABEL_* above. */
 } upb_msglayout_field;
 
+struct upb_decstate;
+struct upb_msglayout;
+
+typedef const char *_upb_field_parser(struct upb_decstate *d, const char *ptr,
+                                      upb_msg *msg, intptr_t table,
+                                      uint64_t hasbits, uint64_t data);
+
+typedef struct {
+  uint64_t field_data;
+  _upb_field_parser *field_parser;
+} _upb_fasttable_entry;
+
 typedef struct upb_msglayout {
   const struct upb_msglayout *const* submsgs;
   const upb_msglayout_field *fields;
@@ -54,6 +68,10 @@ typedef struct upb_msglayout {
   uint16_t size;
   uint16_t field_count;
   bool extendable;
+  uint8_t table_mask;
+  /* To constant-initialize the tables of variable length, we need a flexible
+   * array member, and we need to compile in C99 mode. */
+  _upb_fasttable_entry fasttable[];
 } upb_msglayout;
 
 /** upb_msg *******************************************************************/
@@ -62,25 +80,42 @@ typedef struct upb_msglayout {
  * compatibility.  We put these before the user's data.  The user's upb_msg*
  * points after the upb_msg_internal. */
 
-/* Used when a message is not extendable. */
 typedef struct {
-  char *unknown;
-  size_t unknown_len;
-  size_t unknown_size;
-} upb_msg_internal;
+  uint32_t len;
+  uint32_t size;
+  /* Data follows. */
+} upb_msg_unknowndata;
 
-/* Used when a message is extendable. */
+/* Used when a message is not extendable. */
 typedef struct {
-  upb_inttable *extdict;
-  upb_msg_internal base;
-} upb_msg_internal_withext;
+  upb_msg_unknowndata *unknown;
+} upb_msg_internal;
 
 /* Maps upb_fieldtype_t -> memory size. */
 extern char _upb_fieldtype_to_size[12];
 
+UPB_INLINE size_t upb_msg_sizeof(const upb_msglayout *l) {
+  return l->size + sizeof(upb_msg_internal);
+}
+
+UPB_INLINE upb_msg *_upb_msg_new_inl(const upb_msglayout *l, upb_arena *a) {
+  size_t size = upb_msg_sizeof(l);
+  void *mem = upb_arena_malloc(a, size);
+  upb_msg *msg;
+  if (UPB_UNLIKELY(!mem)) return NULL;
+  msg = UPB_PTR_AT(mem, sizeof(upb_msg_internal), upb_msg);
+  memset(mem, 0, size);
+  return msg;
+}
+
 /* Creates a new messages with the given layout on the given arena. */
 upb_msg *_upb_msg_new(const upb_msglayout *l, upb_arena *a);
 
+UPB_INLINE upb_msg_internal *upb_msg_getinternal(upb_msg *msg) {
+  ptrdiff_t size = sizeof(upb_msg_internal);
+  return (upb_msg_internal*)((char*)msg - size);
+}
+
 /* Clears the given message. */
 void _upb_msg_clear(upb_msg *msg, const upb_msglayout *l);
 
@@ -173,27 +208,49 @@ typedef struct {
   uintptr_t data;   /* Tagged ptr: low 3 bits of ptr are lg2(elem size). */
   size_t len;   /* Measured in elements. */
   size_t size;  /* Measured in elements. */
+  uint64_t junk;
 } upb_array;
 
 UPB_INLINE const void *_upb_array_constptr(const upb_array *arr) {
+  UPB_ASSERT((arr->data & 7) <= 4);
   return (void*)(arr->data & ~(uintptr_t)7);
 }
 
+UPB_INLINE uintptr_t _upb_array_tagptr(void* ptr, int elem_size_lg2) {
+  UPB_ASSERT(elem_size_lg2 <= 4);
+  return (uintptr_t)ptr | elem_size_lg2;
+}
+
 UPB_INLINE void *_upb_array_ptr(upb_array *arr) {
   return (void*)_upb_array_constptr(arr);
 }
 
-/* Creates a new array on the given arena. */
-upb_array *_upb_array_new(upb_arena *a, upb_fieldtype_t type);
+UPB_INLINE uintptr_t _upb_tag_arrptr(void* ptr, int elem_size_lg2) {
+  UPB_ASSERT(elem_size_lg2 <= 4);
+  UPB_ASSERT(((uintptr_t)ptr & 7) == 0);
+  return (uintptr_t)ptr | (unsigned)elem_size_lg2;
+}
+
+UPB_INLINE upb_array *_upb_array_new(upb_arena *a, size_t init_size,
+                                     int elem_size_lg2) {
+  const size_t arr_size = UPB_ALIGN_UP(sizeof(upb_array), 8);
+  const size_t bytes = sizeof(upb_array) + (init_size << elem_size_lg2);
+  upb_array *arr = (upb_array*)upb_arena_malloc(a, bytes);
+  if (!arr) return NULL;
+  arr->data = _upb_tag_arrptr(UPB_PTR_AT(arr, arr_size, void), elem_size_lg2);
+  arr->len = 0;
+  arr->size = init_size;
+  return arr;
+}
 
 /* Resizes the capacity of the array to be at least min_size. */
 bool _upb_array_realloc(upb_array *arr, size_t min_size, upb_arena *arena);
 
 /* Fallback functions for when the accessors require a resize. */
 void *_upb_array_resize_fallback(upb_array **arr_ptr, size_t size,
-                                 upb_fieldtype_t type, upb_arena *arena);
+                                 int elem_size_lg2, upb_arena *arena);
 bool _upb_array_append_fallback(upb_array **arr_ptr, const void *value,
-                                upb_fieldtype_t type, upb_arena *arena);
+                                int elem_size_lg2, upb_arena *arena);
 
 UPB_INLINE bool _upb_array_reserve(upb_array *arr, size_t size,
                                    upb_arena *arena) {
@@ -232,29 +289,28 @@ UPB_INLINE void *_upb_array_mutable_accessor(void *msg, size_t ofs,
   }
 }
 
-UPB_INLINE void *_upb_array_resize_accessor(void *msg, size_t ofs, size_t size,
-                                            upb_fieldtype_t type,
-                                            upb_arena *arena) {
-  upb_array **arr_ptr = PTR_AT(msg, ofs, upb_array*);
+UPB_INLINE void *_upb_array_resize_accessor2(void *msg, size_t ofs, size_t size,
+                                             int elem_size_lg2,
+                                             upb_arena *arena) {
+  upb_array **arr_ptr = PTR_AT(msg, ofs, upb_array *);
   upb_array *arr = *arr_ptr;
   if (!arr || arr->size < size) {
-    return _upb_array_resize_fallback(arr_ptr, size, type, arena);
+    return _upb_array_resize_fallback(arr_ptr, size, elem_size_lg2, arena);
   }
   arr->len = size;
   return _upb_array_ptr(arr);
 }
 
-
-UPB_INLINE bool _upb_array_append_accessor(void *msg, size_t ofs,
-                                           size_t elem_size,
-                                           upb_fieldtype_t type,
-                                           const void *value,
-                                           upb_arena *arena) {
-  upb_array **arr_ptr = PTR_AT(msg, ofs, upb_array*);
+UPB_INLINE bool _upb_array_append_accessor2(void *msg, size_t ofs,
+                                            int elem_size_lg2,
+                                            const void *value,
+                                            upb_arena *arena) {
+  upb_array **arr_ptr = PTR_AT(msg, ofs, upb_array *);
+  size_t elem_size = 1 << elem_size_lg2;
   upb_array *arr = *arr_ptr;
-  voidptr;
+  void *ptr;
   if (!arr || arr->len == arr->size) {
-    return _upb_array_append_fallback(arr_ptr, value, type, arena);
+    return _upb_array_append_fallback(arr_ptr, value, elem_size_lg2, arena);
   }
   ptr = _upb_array_ptr(arr);
   memcpy(PTR_AT(ptr, arr->len * elem_size, char), value, elem_size);
@@ -262,6 +318,42 @@ UPB_INLINE bool _upb_array_append_accessor(void *msg, size_t ofs,
   return true;
 }
 
+/* Used by old generated code, remove once all code has been regenerated. */
+UPB_INLINE int _upb_sizelg2(upb_fieldtype_t type) {
+  switch (type) {
+    case UPB_TYPE_BOOL:
+      return 0;
+    case UPB_TYPE_FLOAT:
+    case UPB_TYPE_INT32:
+    case UPB_TYPE_UINT32:
+    case UPB_TYPE_ENUM:
+      return 2;
+    case UPB_TYPE_MESSAGE:
+      return UPB_SIZE(2, 3);
+    case UPB_TYPE_DOUBLE:
+    case UPB_TYPE_INT64:
+    case UPB_TYPE_UINT64:
+      return 3;
+    case UPB_TYPE_STRING:
+    case UPB_TYPE_BYTES:
+      return UPB_SIZE(3, 4);
+  }
+  UPB_UNREACHABLE();
+}
+UPB_INLINE void *_upb_array_resize_accessor(void *msg, size_t ofs, size_t size,
+                                             upb_fieldtype_t type,
+                                             upb_arena *arena) {
+  return _upb_array_resize_accessor2(msg, ofs, size, _upb_sizelg2(type), arena);
+}
+UPB_INLINE bool _upb_array_append_accessor(void *msg, size_t ofs,
+                                            size_t elem_size, upb_fieldtype_t type,
+                                            const void *value,
+                                            upb_arena *arena) {
+  (void)elem_size;
+  return _upb_array_append_accessor2(msg, ofs, _upb_sizelg2(type), value,
+                                     arena);
+}
+
 /** upb_map *******************************************************************/
 
 /* Right now we use strmaps for everything.  We'll likely want to use
@@ -318,17 +410,17 @@ UPB_INLINE void _upb_map_fromkey(upb_strview key, void* out, size_t size) {
   }
 }
 
-UPB_INLINE upb_value _upb_map_tovalue(const void *val, size_t size,
-                                      upb_arena *a) {
-  upb_value ret = {0};
+UPB_INLINE bool _upb_map_tovalue(const void *val, size_t size, upb_value *msgval,
+                                 upb_arena *a) {
   if (size == UPB_MAPTYPE_STRING) {
     upb_strview *strp = (upb_strview*)upb_arena_malloc(a, sizeof(*strp));
+    if (!strp) return false;
     *strp = *(upb_strview*)val;
-    ret = upb_value_ptr(strp);
+    *msgval = upb_value_ptr(strp);
   } else {
-    memcpy(&ret, val, size);
+    memcpy(msgval, val, size);
   }
-  return ret;
+  return true;
 }
 
 UPB_INLINE void _upb_map_fromvalue(upb_value val, void* out, size_t size) {
@@ -370,7 +462,8 @@ UPB_INLINE void* _upb_map_next(const upb_map *map, size_t *iter) {
 UPB_INLINE bool _upb_map_set(upb_map *map, const void *key, size_t key_size,
                              void *val, size_t val_size, upb_arena *arena) {
   upb_strview strkey = _upb_map_tokey(key, key_size);
-  upb_value tabval = _upb_map_tovalue(val, val_size, arena);
+  upb_value tabval = {0};
+  if (!_upb_map_tovalue(val, val_size, &tabval, arena)) return false;
   upb_alloc *a = upb_arena_alloc(arena);
 
   /* TODO(haberman): add overwrite operation to minimize number of lookups. */
@@ -462,6 +555,53 @@ UPB_INLINE void _upb_msg_map_set_value(void* msg, const void* val, size_t size)
   }
 }
 
+/** _upb_mapsorter *************************************************************/
+
+/* _upb_mapsorter sorts maps and provides ordered iteration over the entries.
+ * Since maps can be recursive (map values can be messages which contain other maps).
+ * _upb_mapsorter can contain a stack of maps. */
+
+typedef struct {
+  upb_tabent const**entries;
+  int size;
+  int cap;
+} _upb_mapsorter;
+
+typedef struct {
+  int start;
+  int pos;
+  int end;
+} _upb_sortedmap;
+
+UPB_INLINE void _upb_mapsorter_init(_upb_mapsorter *s) {
+  s->entries = NULL;
+  s->size = 0;
+  s->cap = 0;
+}
+
+UPB_INLINE void _upb_mapsorter_destroy(_upb_mapsorter *s) {
+  if (s->entries) free(s->entries);
+}
+
+bool _upb_mapsorter_pushmap(_upb_mapsorter *s, upb_descriptortype_t key_type,
+                            const upb_map *map, _upb_sortedmap *sorted);
+
+UPB_INLINE void _upb_mapsorter_popmap(_upb_mapsorter *s, _upb_sortedmap *sorted) {
+  s->size = sorted->start;
+}
+
+UPB_INLINE bool _upb_sortedmap_next(_upb_mapsorter *s, const upb_map *map,
+                                    _upb_sortedmap *sorted,
+                                    upb_map_entry *ent) {
+  if (sorted->pos == sorted->end) return false;
+  const upb_tabent *tabent = s->entries[sorted->pos++];
+  upb_strview key = upb_tabstrview(tabent->key);
+  _upb_map_fromkey(key, &ent->k, map->key_size);
+  upb_value val = {tabent->val.val};
+  _upb_map_fromvalue(val, &ent->v, map->val_size);
+  return true;
+}
+
 #undef PTR_AT
 
 #ifdef __cplusplus
index 454397b..3c73f1a 100644 (file)
@@ -701,7 +701,7 @@ static void compile_method(compiler *c, upb_pbdecodermethod *method) {
   const upb_handlers *h;
   const upb_msgdef *md;
   uint32_t* start_pc;
-  upb_msg_field_iter i;
+  int i, n;
   upb_value val;
 
   UPB_ASSERT(method);
@@ -718,10 +718,9 @@ static void compile_method(compiler *c, upb_pbdecodermethod *method) {
   putsel(c, OP_STARTMSG, UPB_STARTMSG_SELECTOR, h);
  label(c, LABEL_FIELD);
   start_pc = c->pc;
-  for(upb_msg_field_begin(&i, md);
-      !upb_msg_field_done(&i);
-      upb_msg_field_next(&i)) {
-    const upb_fielddef *f = upb_msg_iter_field(&i);
+  n = upb_msgdef_fieldcount(md);
+  for(i = 0; i < n; i++) {
+    const upb_fielddef *f = upb_msgdef_field(md, i);
     upb_fieldtype_t type = upb_fielddef_type(f);
 
     if (type == UPB_TYPE_MESSAGE && !(haslazyhandlers(h, f) && c->lazy)) {
@@ -765,7 +764,7 @@ static void compile_method(compiler *c, upb_pbdecodermethod *method) {
  * Generates a new method for every destination handlers reachable from "h". */
 static void find_methods(compiler *c, const upb_handlers *h) {
   upb_value v;
-  upb_msg_field_iter i;
+  int i, n;
   const upb_msgdef *md;
   upb_pbdecodermethod *method;
 
@@ -777,10 +776,9 @@ static void find_methods(compiler *c, const upb_handlers *h) {
 
   /* Find submethods. */
   md = upb_handlers_msgdef(h);
-  for(upb_msg_field_begin(&i, md);
-      !upb_msg_field_done(&i);
-      upb_msg_field_next(&i)) {
-    const upb_fielddef *f = upb_msg_iter_field(&i);
+  n = upb_msgdef_fieldcount(md);
+  for (i = 0; i < n; i++) {
+    const upb_fielddef *f = upb_msgdef_field(md, i);
     const upb_handlers *sub_h;
     if (upb_fielddef_type(f) == UPB_TYPE_MESSAGE &&
         (sub_h = upb_handlers_getsubhandlers(h, f)) != NULL) {
index ea4859e..0c47b0d 100644 (file)
@@ -190,7 +190,7 @@ static bool commit(upb_pb_encoder *e) {
 }
 
 /* Writes the given bytes to the buffer, handling reserve/advance. */
-static bool encode_bytes(upb_pb_encoder *e, const void *data, size_t len) {
+static bool encode_bytesval(upb_pb_encoder *e, const void *data, size_t len) {
   if (!reserve(e, len)) {
     return false;
   }
@@ -309,24 +309,24 @@ static void new_tag(upb_handlers *h, const upb_fielddef *f, upb_wiretype_t wt,
   upb_handlers_addcleanup(h, tag, upb_gfree);
 }
 
-static bool encode_tag(upb_pb_encoder *e, const tag_t *tag) {
-  return encode_bytes(e, tag->tag, tag->bytes);
+static bool encode_tagval(upb_pb_encoder *e, const tag_t *tag) {
+  return encode_bytesval(e, tag->tag, tag->bytes);
 }
 
 
 /* encoding of wire types *****************************************************/
 
-static bool encode_fixed64(upb_pb_encoder *e, uint64_t val) {
+static bool doencode_fixed64(upb_pb_encoder *e, uint64_t val) {
   /* TODO(haberman): byte-swap for big endian. */
-  return encode_bytes(e, &val, sizeof(uint64_t));
+  return encode_bytesval(e, &val, sizeof(uint64_t));
 }
 
-static bool encode_fixed32(upb_pb_encoder *e, uint32_t val) {
+static bool doencode_fixed32(upb_pb_encoder *e, uint32_t val) {
   /* TODO(haberman): byte-swap for big endian. */
-  return encode_bytes(e, &val, sizeof(uint32_t));
+  return encode_bytesval(e, &val, sizeof(uint32_t));
 }
 
-static bool encode_varint(upb_pb_encoder *e, uint64_t val) {
+static bool doencode_varint(upb_pb_encoder *e, uint64_t val) {
   if (!reserve(e, UPB_PB_VARINT_MAX_LEN)) {
     return false;
   }
@@ -370,14 +370,14 @@ static bool endmsg(void *c, const void *hd, upb_status *status) {
 }
 
 static void *encode_startdelimfield(void *c, const void *hd) {
-  bool ok = encode_tag(c, hd) && commit(c) && start_delim(c);
+  bool ok = encode_tagval(c, hd) && commit(c) && start_delim(c);
   return ok ? c : UPB_BREAK;
 }
 
 static bool encode_unknown(void *c, const void *hd, const char *buf,
                            size_t len) {
   UPB_UNUSED(hd);
-  return encode_bytes(c, buf, len) && commit(c);
+  return encode_bytesval(c, buf, len) && commit(c);
 }
 
 static bool encode_enddelimfield(void *c, const void *hd) {
@@ -386,11 +386,11 @@ static bool encode_enddelimfield(void *c, const void *hd) {
 }
 
 static void *encode_startgroup(void *c, const void *hd) {
-  return (encode_tag(c, hd) && commit(c)) ? c : UPB_BREAK;
+  return (encode_tagval(c, hd) && commit(c)) ? c : UPB_BREAK;
 }
 
 static bool encode_endgroup(void *c, const void *hd) {
-  return encode_tag(c, hd) && commit(c);
+  return encode_tagval(c, hd) && commit(c);
 }
 
 static void *encode_startstr(void *c, const void *hd, size_t size_hint) {
@@ -402,32 +402,32 @@ static size_t encode_strbuf(void *c, const void *hd, const char *buf,
                             size_t len, const upb_bufhandle *h) {
   UPB_UNUSED(hd);
   UPB_UNUSED(h);
-  return encode_bytes(c, buf, len) ? len : 0;
+  return encode_bytesval(c, buf, len) ? len : 0;
 }
 
-#define T(type, ctype, convert, encode)                                  \
-  static bool encode_scalar_##type(void *e, const void *hd, ctype val) { \
-    return encode_tag(e, hd) && encode(e, (convert)(val)) && commit(e);  \
-  }                                                                      \
-  static bool encode_packed_##type(void *e, const void *hd, ctype val) { \
-    UPB_UNUSED(hd);                                                      \
-    return encode(e, (convert)(val));                                    \
+#define T(type, ctype, convert, encode)                                    \
+  static bool encode_scalar_##type(void *e, const void *hd, ctype val) {   \
+    return encode_tagval(e, hd) && encode(e, (convert)(val)) && commit(e); \
+  }                                                                        \
+  static bool encode_packed_##type(void *e, const void *hd, ctype val) {   \
+    UPB_UNUSED(hd);                                                        \
+    return encode(e, (convert)(val));                                      \
   }
 
-T(double,   double,   dbl2uint64,   encode_fixed64)
-T(float,    float,    flt2uint32,   encode_fixed32)
-T(int64,    int64_t,  uint64_t,     encode_varint)
-T(int32,    int32_t,  int64_t,      encode_varint)
-T(fixed64,  uint64_t, uint64_t,     encode_fixed64)
-T(fixed32,  uint32_t, uint32_t,     encode_fixed32)
-T(bool,     bool,     bool,         encode_varint)
-T(uint32,   uint32_t, uint32_t,     encode_varint)
-T(uint64,   uint64_t, uint64_t,     encode_varint)
-T(enum,     int32_t,  uint32_t,     encode_varint)
-T(sfixed32, int32_t,  uint32_t,     encode_fixed32)
-T(sfixed64, int64_t,  uint64_t,     encode_fixed64)
-T(sint32,   int32_t,  upb_zzenc_32, encode_varint)
-T(sint64,   int64_t,  upb_zzenc_64, encode_varint)
+T(double,   double,   dbl2uint64,   doencode_fixed64)
+T(float,    float,    flt2uint32,   doencode_fixed32)
+T(int64,    int64_t,  uint64_t,     doencode_varint)
+T(int32,    int32_t,  int64_t,      doencode_varint)
+T(fixed64,  uint64_t, uint64_t,     doencode_fixed64)
+T(fixed32,  uint32_t, uint32_t,     doencode_fixed32)
+T(bool,     bool,     bool,         doencode_varint)
+T(uint32,   uint32_t, uint32_t,     doencode_varint)
+T(uint64,   uint64_t, uint64_t,     doencode_varint)
+T(enum,     int32_t,  uint32_t,     doencode_varint)
+T(sfixed32, int32_t,  uint32_t,     doencode_fixed32)
+T(sfixed64, int64_t,  uint64_t,     doencode_fixed64)
+T(sint32,   int32_t,  upb_zzenc_32, doencode_varint)
+T(sint64,   int64_t,  upb_zzenc_64, doencode_varint)
 
 #undef T
 
@@ -437,7 +437,7 @@ T(sint64,   int64_t,  upb_zzenc_64, encode_varint)
 #include <stdio.h>
 static void newhandlers_callback(const void *closure, upb_handlers *h) {
   const upb_msgdef *m;
-  upb_msg_field_iter i;
+  int i, n;
 
   UPB_UNUSED(closure);
 
@@ -446,10 +446,9 @@ static void newhandlers_callback(const void *closure, upb_handlers *h) {
   upb_handlers_setunknown(h, encode_unknown, NULL);
 
   m = upb_handlers_msgdef(h);
-  for(upb_msg_field_begin(&i, m);
-      !upb_msg_field_done(&i);
-      upb_msg_field_next(&i)) {
-    const upb_fielddef *f = upb_msg_iter_field(&i);
+  n = upb_msgdef_fieldcount(m);
+  for(i = 0; i < n; i++) {
+    const upb_fielddef *f = upb_msgdef_field(m, i);
     bool packed = upb_fielddef_isseq(f) && upb_fielddef_isprimitive(f) &&
                   upb_fielddef_packed(f);
     upb_handlerattr attr = UPB_HANDLERATTR_INIT;
index 0760173..1331268 100644 (file)
@@ -105,8 +105,8 @@ bool putf(upb_textprinter *p, const char *fmt, ...) {
   va_start(args, fmt);
 
   /* Run once to get the length of the string. */
-  _upb_va_copy(args_copy, args);
-  len = _upb_vsnprintf(NULL, 0, fmt, args_copy);
+  va_copy(args_copy, args);
+  len = vsnprintf(NULL, 0, fmt, args_copy);
   va_end(args_copy);
 
   /* + 1 for NULL terminator (vsprintf() requires it even if we don't). */
@@ -252,16 +252,15 @@ err:
 
 static void onmreg(const void *c, upb_handlers *h) {
   const upb_msgdef *m = upb_handlers_msgdef(h);
-  upb_msg_field_iter i;
+  int i, n;
   UPB_UNUSED(c);
 
   upb_handlers_setstartmsg(h, textprinter_startmsg, NULL);
   upb_handlers_setendmsg(h, textprinter_endmsg, NULL);
 
-  for(upb_msg_field_begin(&i, m);
-      !upb_msg_field_done(&i);
-      upb_msg_field_next(&i)) {
-    upb_fielddef *f = upb_msg_iter_field(&i);
+  n = upb_msgdef_fieldcount(m);
+  for(i = 0; i < n; i++) {
+    const upb_fielddef *f = upb_msgdef_field(m, i);
     upb_handlerattr attr = UPB_HANDLERATTR_INIT;
     attr.handler_data = f;
     switch (upb_fielddef_type(f)) {
index 8ab0d9f..9b98a81 100644 (file)
@@ -150,9 +150,7 @@ UPB_INLINE uint64_t upb_vencode32(uint32_t val) {
   uint64_t ret = 0;
   UPB_ASSERT(bytes <= 5);
   memcpy(&ret, buf, bytes);
-#ifdef UPB_BIG_ENDIAN
-  ret = byteswap64(ret);
-#endif
+  ret = _upb_be_swap64(ret);
   UPB_ASSERT(ret <= 0xffffffffffU);
   return ret;
 }
diff --git a/third_party/upb/upb/port.c b/third_party/upb/upb/port.c
deleted file mode 100644 (file)
index 9ecf135..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-
-#include "upb/port_def.inc"
-
-#ifdef UPB_MSVC_VSNPRINTF
-/* Visual C++ earlier than 2015 doesn't have standard C99 snprintf and
- * vsnprintf. To support them, missing functions are manually implemented
- * using the existing secure functions. */
-int msvc_vsnprintf(char* s, size_t n, const char* format, va_list arg) {
-  if (!s) {
-    return _vscprintf(format, arg);
-  }
-  int ret = _vsnprintf_s(s, n, _TRUNCATE, format, arg);
-  if (ret < 0) {
-       ret = _vscprintf(format, arg);
-  }
-  return ret;
-}
-
-int msvc_snprintf(char* s, size_t n, const char* format, ...) {
-  va_list arg;
-  va_start(arg, format);
-  int ret = msvc_vsnprintf(s, n, format, arg);
-  va_end(arg);
-  return ret;
-}
-#endif
index 2c144dc..2cd1bb6 100644 (file)
 *
 * This file is private and must not be included by users!
 */
+
+#if !((defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || \
+      (defined(__cplusplus) && __cplusplus >= 201103L) ||           \
+      (defined(_MSC_VER) && _MSC_VER >= 1900))
+#error upb requires C99 or C++11 or MSVC >= 2015.
+#endif
+
 #include <stdint.h>
 #include <stddef.h>
 
 #define UPB_UNLIKELY(x) (x)
 #endif
 
-/* Define UPB_BIG_ENDIAN manually if you're on big endian and your compiler
- * doesn't provide these preprocessor symbols. */
-#if defined(__BYTE_ORDER__) && (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__)
-#define UPB_BIG_ENDIAN
-#endif
-
 /* Macros for function attributes on compilers that support them. */
 #ifdef __GNUC__
 #define UPB_FORCEINLINE __inline__ __attribute__((always_inline))
 #define UPB_NOINLINE __attribute__((noinline))
 #define UPB_NORETURN __attribute__((__noreturn__))
+#elif defined(_MSC_VER)
+#define UPB_NOINLINE
+#define UPB_FORCEINLINE
+#define UPB_NORETURN __declspec(noreturn)
 #else  /* !defined(__GNUC__) */
 #define UPB_FORCEINLINE
 #define UPB_NOINLINE
 #define UPB_NORETURN
 #endif
 
-#if __STDC_VERSION__ >= 199901L || __cplusplus >= 201103L
-/* C99/C++11 versions. */
-#include <stdio.h>
-#define _upb_snprintf snprintf
-#define _upb_vsnprintf vsnprintf
-#define _upb_va_copy(a, b) va_copy(a, b)
-#elif defined(_MSC_VER)
-/* Microsoft C/C++ versions. */
-#include <stdarg.h>
-#include <stdio.h>
-#if _MSC_VER < 1900
-int msvc_snprintf(char* s, size_t n, const char* format, ...);
-int msvc_vsnprintf(char* s, size_t n, const char* format, va_list arg);
-#define UPB_MSVC_VSNPRINTF
-#define _upb_snprintf msvc_snprintf
-#define _upb_vsnprintf msvc_vsnprintf
-#else
-#define _upb_snprintf snprintf
-#define _upb_vsnprintf vsnprintf
-#endif
-#define _upb_va_copy(a, b) va_copy(a, b)
-#elif defined __GNUC__
-/* A few hacky workarounds for functions not in C89.
- * For internal use only!
- * TODO(haberman): fix these by including our own implementations, or finding
- * another workaround.
- */
-#define _upb_snprintf __builtin_snprintf
-#define _upb_vsnprintf __builtin_vsnprintf
-#define _upb_va_copy(a, b) __va_copy(a, b)
-#else
-#error Need implementations of [v]snprintf and va_copy
-#endif
-
-#ifdef __cplusplus
-#if __cplusplus >= 201103L || defined(__GXX_EXPERIMENTAL_CXX0X__) || \
-    (defined(_MSC_VER) && _MSC_VER >= 1900)
-/* C++11 is present */
-#else
-#error upb requires C++11 for C++ support
-#endif
-#endif
-
 #define UPB_MAX(x, y) ((x) > (y) ? (x) : (y))
 #define UPB_MIN(x, y) ((x) < (y) ? (x) : (y))
 
@@ -155,25 +117,76 @@ int msvc_vsnprintf(char* s, size_t n, const char* format, va_list arg);
 #define UPB_ASSERT(expr) assert(expr)
 #endif
 
-/* UPB_ASSERT_DEBUGVAR(): assert that uses functions or variables that only
- * exist in debug mode.  This turns into regular assert. */
-#define UPB_ASSERT_DEBUGVAR(expr) assert(expr)
-
 #if defined(__GNUC__) || defined(__clang__)
 #define UPB_UNREACHABLE() do { assert(0); __builtin_unreachable(); } while(0)
 #else
 #define UPB_UNREACHABLE() do { assert(0); } while(0)
 #endif
 
-/* UPB_INFINITY representing floating-point positive infinity. */
-#include <math.h>
-#ifdef INFINITY
-#define UPB_INFINITY INFINITY
+/* UPB_SETJMP() / UPB_LONGJMP(): avoid setting/restoring signal mask. */
+#ifdef __APPLE__
+#define UPB_SETJMP(buf) _setjmp(buf)
+#define UPB_LONGJMP(buf, val) _longjmp(buf, val)
+#else
+#define UPB_SETJMP(buf) setjmp(buf)
+#define UPB_LONGJMP(buf, val) longjmp(buf, val)
+#endif
+
+/* Configure whether fasttable is switched on or not. *************************/
+
+#if defined(__x86_64__) && defined(__GNUC__)
+#define UPB_FASTTABLE_SUPPORTED 1
+#else
+#define UPB_FASTTABLE_SUPPORTED 0
+#endif
+
+/* define UPB_ENABLE_FASTTABLE to force fast table support.
+ * This is useful when we want to ensure we are really getting fasttable,
+ * for example for testing or benchmarking. */
+#if defined(UPB_ENABLE_FASTTABLE)
+#if !UPB_FASTTABLE_SUPPORTED
+#error fasttable is x86-64 + Clang/GCC only
+#endif
+#define UPB_FASTTABLE 1
+/* Define UPB_TRY_ENABLE_FASTTABLE to use fasttable if possible.
+ * This is useful for releasing code that might be used on multiple platforms,
+ * for example the PHP or Ruby C extensions. */
+#elif defined(UPB_TRY_ENABLE_FASTTABLE)
+#define UPB_FASTTABLE UPB_FASTTABLE_SUPPORTED
 #else
-#define UPB_INFINITY (1.0 / 0.0)
+#define UPB_FASTTABLE 0
 #endif
-#ifdef NAN
-#define UPB_NAN NAN
+
+/* UPB_FASTTABLE_INIT() allows protos compiled for fasttable to gracefully
+ * degrade to non-fasttable if we are using UPB_TRY_ENABLE_FASTTABLE. */
+#if !UPB_FASTTABLE && defined(UPB_TRY_ENABLE_FASTTABLE)
+#define UPB_FASTTABLE_INIT(...)
 #else
-#define UPB_NAN (0.0 / 0.0)
+#define UPB_FASTTABLE_INIT(...) __VA_ARGS__
 #endif
+
+#undef UPB_FASTTABLE_SUPPORTED
+
+/* ASAN poisoning (for arena) *************************************************/
+
+#if defined(__SANITIZE_ADDRESS__)
+#define UPB_ASAN 1
+#ifdef __cplusplus
+extern "C" {
+#endif
+void __asan_poison_memory_region(void const volatile *addr, size_t size);
+void __asan_unpoison_memory_region(void const volatile *addr, size_t size);
+#ifdef __cplusplus
+}  /* extern "C" */
+#endif
+#define UPB_POISON_MEMORY_REGION(addr, size) \
+  __asan_poison_memory_region((addr), (size))
+#define UPB_UNPOISON_MEMORY_REGION(addr, size) \
+  __asan_unpoison_memory_region((addr), (size))
+#else
+#define UPB_ASAN 0
+#define UPB_POISON_MEMORY_REGION(addr, size) \
+  ((void)(addr), (void)(size))
+#define UPB_UNPOISON_MEMORY_REGION(addr, size) \
+  ((void)(addr), (void)(size))
+#endif 
index c2b5f4a..b7be52c 100644 (file)
 #undef UPB_UNUSED
 #undef UPB_ASSUME
 #undef UPB_ASSERT
-#undef UPB_ASSERT_DEBUGVAR
 #undef UPB_UNREACHABLE
-#undef UPB_INFINITY
-#undef UPB_NAN
-#undef UPB_MSVC_VSNPRINTF
-#undef _upb_snprintf
-#undef _upb_vsnprintf
-#undef _upb_va_copy
+#undef UPB_POISON_MEMORY_REGION
+#undef UPB_UNPOISON_MEMORY_REGION
+#undef UPB_ASAN
index 487241b..a233d96 100644 (file)
@@ -48,6 +48,21 @@ static char _upb_fieldtype_to_mapsize[12] = {
   0,  /* UPB_TYPE_BYTES */
 };
 
+static const char _upb_fieldtype_to_sizelg2[12] = {
+  0,
+  0,  /* UPB_TYPE_BOOL */
+  2,  /* UPB_TYPE_FLOAT */
+  2,  /* UPB_TYPE_INT32 */
+  2,  /* UPB_TYPE_UINT32 */
+  2,  /* UPB_TYPE_ENUM */
+  UPB_SIZE(2, 3),  /* UPB_TYPE_MESSAGE */
+  3,  /* UPB_TYPE_DOUBLE */
+  3,  /* UPB_TYPE_INT64 */
+  3,  /* UPB_TYPE_UINT64 */
+  UPB_SIZE(3, 4),  /* UPB_TYPE_STRING */
+  UPB_SIZE(3, 4),  /* UPB_TYPE_BYTES */
+};
+
 /** upb_msg *******************************************************************/
 
 upb_msg *upb_msg_new(const upb_msgdef *m, upb_arena *a) {
@@ -81,20 +96,17 @@ bool upb_msg_has(const upb_msg *msg, const upb_fielddef *f) {
 
 const upb_fielddef *upb_msg_whichoneof(const upb_msg *msg,
                                        const upb_oneofdef *o) {
-  upb_oneof_iter i;
-  const upb_fielddef *f;
-  const upb_msglayout_field *field;
-  const upb_msgdef *m = upb_oneofdef_containingtype(o);
-  uint32_t oneof_case;
-
-  /* This is far from optimal. */
-  upb_oneof_begin(&i, o);
-  if (upb_oneof_done(&i)) return false;
-  f = upb_oneof_iter_field(&i);
-  field = upb_fielddef_layout(f);
-  oneof_case = _upb_getoneofcase_field(msg, field);
-
-  return oneof_case ? upb_msgdef_itof(m, oneof_case) : NULL;
+  const upb_fielddef *f = upb_oneofdef_field(o, 0);
+  if (upb_oneofdef_issynthetic(o)) {
+    UPB_ASSERT(upb_oneofdef_fieldcount(o) == 1);
+    return upb_msg_has(msg, f) ? f : NULL;
+  } else {
+    const upb_msglayout_field *field = upb_fielddef_layout(f);
+    uint32_t oneof_case = _upb_getoneofcase_field(msg, field);
+    f = oneof_case ? upb_oneofdef_itof(o, oneof_case) : NULL;
+    UPB_ASSERT((f != NULL) == (oneof_case != 0));
+    return f;
+  }
 }
 
 upb_msgval upb_msg_get(const upb_msg *msg, const upb_fielddef *f) {
@@ -124,7 +136,7 @@ upb_msgval upb_msg_get(const upb_msg *msg, const upb_fielddef *f) {
         val.double_val = upb_fielddef_defaultdouble(f);
         break;
       case UPB_TYPE_BOOL:
-        val.double_val = upb_fielddef_defaultbool(f);
+        val.bool_val = upb_fielddef_defaultbool(f);
         break;
       case UPB_TYPE_STRING:
       case UPB_TYPE_BYTES:
@@ -207,11 +219,12 @@ void upb_msg_clear(upb_msg *msg, const upb_msgdef *m) {
 bool upb_msg_next(const upb_msg *msg, const upb_msgdef *m,
                   const upb_symtab *ext_pool, const upb_fielddef **out_f,
                   upb_msgval *out_val, size_t *iter) {
-  size_t i = *iter;
+  int i = *iter;
+  int n = upb_msgdef_fieldcount(m);
   const upb_msgval zero = {0};
-  const upb_fielddef *f;
   UPB_UNUSED(ext_pool);
-  while ((f = _upb_msgdef_field(m, (int)++i)) != NULL) {
+  while (++i < n) {
+    const upb_fielddef *f = upb_msgdef_field(m, i);
     upb_msgval val = _upb_msg_getraw(msg, f);
 
     /* Skip field if unset or empty. */
@@ -296,7 +309,7 @@ bool upb_msg_discardunknown(upb_msg *msg, const upb_msgdef *m, int maxdepth) {
 /** upb_array *****************************************************************/
 
 upb_array *upb_array_new(upb_arena *a, upb_fieldtype_t type) {
-  return _upb_array_new(a, type);
+  return _upb_array_new(a, 4, _upb_fieldtype_to_sizelg2[type]);
 }
 
 size_t upb_array_size(const upb_array *arr) {
@@ -348,6 +361,10 @@ bool upb_map_get(const upb_map *map, upb_msgval key, upb_msgval *val) {
   return _upb_map_get(map, &key, map->key_size, val, map->val_size);
 }
 
+void upb_map_clear(upb_map *map) {
+  _upb_map_clear(map);
+}
+
 bool upb_map_set(upb_map *map, upb_msgval key, upb_msgval val,
                  upb_arena *arena) {
   return _upb_map_set(map, &key, map->key_size, &val, map->val_size, arena);
index 34a2053..8837047 100644 (file)
@@ -4,10 +4,12 @@
 ** Implementation is heavily inspired by Lua's ltable.c.
 */
 
-#include "upb/table.int.h"
-
 #include <string.h>
 
+#include "third_party/wyhash/wyhash.h"
+#include "upb/table.int.h"
+
+/* Must be last. */
 #include "upb/port_def.inc"
 
 #define UPB_MAXARRSIZE 16  /* 64k. */
@@ -87,11 +89,7 @@ static upb_tabent *mutable_entries(upb_table *t) {
 }
 
 static bool isfull(upb_table *t) {
-  if (upb_table_size(t) == 0) {
-    return true;
-  } else {
-    return ((double)(t->count + 1) / upb_table_size(t)) > MAX_LOAD;
-  }
+  return t->count == t->max_count;
 }
 
 static bool init(upb_table *t, uint8_t size_lg2, upb_alloc *a) {
@@ -100,6 +98,7 @@ static bool init(upb_table *t, uint8_t size_lg2, upb_alloc *a) {
   t->count = 0;
   t->size_lg2 = size_lg2;
   t->mask = upb_table_size(t) ? upb_table_size(t) - 1 : 0;
+  t->max_count = upb_table_size(t) * MAX_LOAD;
   bytes = upb_table_size(t) * sizeof(upb_tabent);
   if (bytes > 0) {
     t->entries = upb_malloc(a, bytes);
@@ -115,9 +114,17 @@ static void uninit(upb_table *t, upb_alloc *a) {
   upb_free(a, mutable_entries(t));
 }
 
-static upb_tabent *emptyent(upb_table *t) {
-  upb_tabent *e = mutable_entries(t) + upb_table_size(t);
-  while (1) { if (upb_tabent_isempty(--e)) return e; UPB_ASSERT(e > t->entries); }
+static upb_tabent *emptyent(upb_table *t, upb_tabent *e) {
+  upb_tabent *begin = mutable_entries(t);
+  upb_tabent *end = begin + upb_table_size(t);
+  for (e = e + 1; e < end; e++) {
+    if (upb_tabent_isempty(e)) return e;
+  }
+  for (e = begin; e < end; e++) {
+    if (upb_tabent_isempty(e)) return e;
+  }
+  UPB_ASSERT(false);
+  return NULL;
 }
 
 static upb_tabent *getentry_mutable(upb_table *t, uint32_t hash) {
@@ -173,11 +180,11 @@ static void insert(upb_table *t, lookupkey_t key, upb_tabkey tabkey,
     our_e->next = NULL;
   } else {
     /* Collision. */
-    upb_tabent *new_e = emptyent(t);
+    upb_tabent *new_e = emptyent(t, mainpos_e);
     /* Head of collider's chain. */
     upb_tabent *chain = getentry_mutable(t, hashfunc(mainpos_e->key));
     if (chain == mainpos_e) {
-      /* Existing ent is in its main posisiton (it has the same hash as us, and
+      /* Existing ent is in its main position (it has the same hash as us, and
        * is the head of our chain).  Insert to new ent and append to this chain. */
       new_e->next = mainpos_e->next;
       mainpos_e->next = new_e;
@@ -268,10 +275,14 @@ static upb_tabkey strcopy(lookupkey_t k2, upb_alloc *a) {
   return (uintptr_t)str;
 }
 
+static uint32_t table_hash(const char *p, size_t n) {
+  return wyhash(p, n, 0, _wyp);
+}
+
 static uint32_t strhash(upb_tabkey key) {
   uint32_t len;
   char *str = upb_tabstr(key, &len);
-  return upb_murmur_hash2(str, len, 0);
+  return table_hash(str, len);
 }
 
 static bool streql(upb_tabkey k1, lookupkey_t k2) {
@@ -280,9 +291,14 @@ static bool streql(upb_tabkey k1, lookupkey_t k2) {
   return len == k2.str.len && (len == 0 || memcmp(str, k2.str.str, len) == 0);
 }
 
-bool upb_strtable_init2(upb_strtable *t, upb_ctype_t ctype, upb_alloc *a) {
+bool upb_strtable_init2(upb_strtable *t, upb_ctype_t ctype,
+                        size_t expected_size, upb_alloc *a) {
   UPB_UNUSED(ctype);  /* TODO(haberman): rm */
-  return init(&t->t, 2, a);
+  // Multiply by approximate reciprocal of MAX_LOAD (0.85), with pow2 denominator.
+  size_t need_entries = (expected_size + 1) * 1204 / 1024;
+  UPB_ASSERT(need_entries >= expected_size * 0.85);
+  int size_lg2 = _upb_lg2ceil(need_entries);
+  return init(&t->t, size_lg2, a);
 }
 
 void upb_strtable_clear(upb_strtable *t) {
@@ -333,20 +349,20 @@ bool upb_strtable_insert3(upb_strtable *t, const char *k, size_t len,
   tabkey = strcopy(key, a);
   if (tabkey == 0) return false;
 
-  hash = upb_murmur_hash2(key.str.str, key.str.len, 0);
+  hash = table_hash(key.str.str, key.str.len);
   insert(&t->t, key, tabkey, v, hash, &strhash, &streql);
   return true;
 }
 
 bool upb_strtable_lookup2(const upb_strtable *t, const char *key, size_t len,
                           upb_value *v) {
-  uint32_t hash = upb_murmur_hash2(key, len, 0);
+  uint32_t hash = table_hash(key, len);
   return lookup(&t->t, strkey2(key, len), v, hash, &streql);
 }
 
 bool upb_strtable_remove3(upb_strtable *t, const char *key, size_t len,
                          upb_value *val, upb_alloc *alloc) {
-  uint32_t hash = upb_murmur_hash2(key, len, 0);
+  uint32_t hash = table_hash(key, len);
   upb_tabkey tabkey;
   if (rm(&t->t, strkey2(key, len), val, &tabkey, hash, &streql)) {
     if (alloc) {
@@ -699,182 +715,3 @@ bool upb_inttable_iter_isequal(const upb_inttable_iter *i1,
   return i1->t == i2->t && i1->index == i2->index &&
          i1->array_part == i2->array_part;
 }
-
-#if defined(UPB_UNALIGNED_READS_OK) || defined(__s390x__)
-/* -----------------------------------------------------------------------------
- * MurmurHash2, by Austin Appleby (released as public domain).
- * Reformatted and C99-ified by Joshua Haberman.
- * Note - This code makes a few assumptions about how your machine behaves -
- *   1. We can read a 4-byte value from any address without crashing
- *   2. sizeof(int) == 4 (in upb this limitation is removed by using uint32_t
- * And it has a few limitations -
- *   1. It will not work incrementally.
- *   2. It will not produce the same results on little-endian and big-endian
- *      machines. */
-uint32_t upb_murmur_hash2(const void *key, size_t len, uint32_t seed) {
-  /* 'm' and 'r' are mixing constants generated offline.
-   * They're not really 'magic', they just happen to work well. */
-  const uint32_t m = 0x5bd1e995;
-  const int32_t r = 24;
-
-  /* Initialize the hash to a 'random' value */
-  uint32_t h = seed ^ len;
-
-  /* Mix 4 bytes at a time into the hash */
-  const uint8_t * data = (const uint8_t *)key;
-  while(len >= 4) {
-    uint32_t k;
-    memcpy(&k, data, sizeof(k));
-
-    k *= m;
-    k ^= k >> r;
-    k *= m;
-
-    h *= m;
-    h ^= k;
-
-    data += 4;
-    len -= 4;
-  }
-
-  /* Handle the last few bytes of the input array */
-  switch(len) {
-    case 3: h ^= data[2] << 16;
-    case 2: h ^= data[1] << 8;
-    case 1: h ^= data[0]; h *= m;
-  };
-
-  /* Do a few final mixes of the hash to ensure the last few
-   * bytes are well-incorporated. */
-  h ^= h >> 13;
-  h *= m;
-  h ^= h >> 15;
-
-  return h;
-}
-
-#else /* !UPB_UNALIGNED_READS_OK */
-
-/* -----------------------------------------------------------------------------
- * MurmurHashAligned2, by Austin Appleby
- * Same algorithm as MurmurHash2, but only does aligned reads - should be safer
- * on certain platforms.
- * Performance will be lower than MurmurHash2 */
-
-#define MIX(h,k,m) { k *= m; k ^= k >> r; k *= m; h *= m; h ^= k; }
-
-uint32_t upb_murmur_hash2(const void * key, size_t len, uint32_t seed) {
-  const uint32_t m = 0x5bd1e995;
-  const int32_t r = 24;
-  const uint8_t * data = (const uint8_t *)key;
-  uint32_t h = (uint32_t)(seed ^ len);
-  uint8_t align = (uintptr_t)data & 3;
-
-  if(align && (len >= 4)) {
-    /* Pre-load the temp registers */
-    uint32_t t = 0, d = 0;
-    int32_t sl;
-    int32_t sr;
-
-    switch(align) {
-      case 1: t |= data[2] << 16;  /* fallthrough */
-      case 2: t |= data[1] << 8;   /* fallthrough */
-      case 3: t |= data[0];
-    }
-
-    t <<= (8 * align);
-
-    data += 4-align;
-    len -= 4-align;
-
-    sl = 8 * (4-align);
-    sr = 8 * align;
-
-    /* Mix */
-
-    while(len >= 4) {
-      uint32_t k;
-
-      d = *(uint32_t *)data;
-      t = (t >> sr) | (d << sl);
-
-      k = t;
-
-      MIX(h,k,m);
-
-      t = d;
-
-      data += 4;
-      len -= 4;
-    }
-
-    /* Handle leftover data in temp registers */
-
-    d = 0;
-
-    if(len >= align) {
-      uint32_t k;
-
-      switch(align) {
-        case 3: d |= data[2] << 16;  /* fallthrough */
-        case 2: d |= data[1] << 8;   /* fallthrough */
-        case 1: d |= data[0];        /* fallthrough */
-      }
-
-      k = (t >> sr) | (d << sl);
-      MIX(h,k,m);
-
-      data += align;
-      len -= align;
-
-      /* ----------
-       * Handle tail bytes */
-
-      switch(len) {
-        case 3: h ^= data[2] << 16;    /* fallthrough */
-        case 2: h ^= data[1] << 8;     /* fallthrough */
-        case 1: h ^= data[0]; h *= m;  /* fallthrough */
-      };
-    } else {
-      switch(len) {
-        case 3: d |= data[2] << 16;  /* fallthrough */
-        case 2: d |= data[1] << 8;   /* fallthrough */
-        case 1: d |= data[0];        /* fallthrough */
-        case 0: h ^= (t >> sr) | (d << sl); h *= m;
-      }
-    }
-
-    h ^= h >> 13;
-    h *= m;
-    h ^= h >> 15;
-
-    return h;
-  } else {
-    while(len >= 4) {
-      uint32_t k = *(uint32_t *)data;
-
-      MIX(h,k,m);
-
-      data += 4;
-      len -= 4;
-    }
-
-    /* ----------
-     * Handle tail bytes */
-
-    switch(len) {
-      case 3: h ^= data[2] << 16; /* fallthrough */
-      case 2: h ^= data[1] << 8;  /* fallthrough */
-      case 1: h ^= data[0]; h *= m;
-    };
-
-    h ^= h >> 13;
-    h *= m;
-    h ^= h >> 15;
-
-    return h;
-  }
-}
-#undef MIX
-
-#endif /* UPB_UNALIGNED_READS_OK */
index 600637e..49caac4 100644 (file)
@@ -13,7 +13,7 @@
 ** store pointers or integers of at least 32 bits (upb isn't really useful on
 ** systems where sizeof(void*) < 4).
 **
-** The table must be homogenous (all values of the same type).  In debug
+** The table must be homogeneous (all values of the same type).  In debug
 ** mode, we check this on insert and lookup.
 */
 
@@ -147,10 +147,17 @@ UPB_INLINE char *upb_tabstr(upb_tabkey key, uint32_t *len) {
   return mem + sizeof(*len);
 }
 
+UPB_INLINE upb_strview upb_tabstrview(upb_tabkey key) {
+  upb_strview ret;
+  uint32_t len;
+  ret.data = upb_tabstr(key, &len);
+  ret.size = len;
+  return ret;
+}
 
 /* upb_tabval *****************************************************************/
 
-typedef struct {
+typedef struct upb_tabval {
   uint64_t val;
 } upb_tabval;
 
@@ -171,7 +178,8 @@ typedef struct _upb_tabent {
 
 typedef struct {
   size_t count;          /* Number of entries in the hash part. */
-  size_t mask;           /* Mask to turn hash value -> bucket. */
+  uint32_t mask;         /* Mask to turn hash value -> bucket. */
+  uint32_t max_count;    /* Max count before we hit our load limit. */
   uint8_t size_lg2;      /* Size of the hashtable part is 2^size_lg2 entries. */
 
   /* Hash table entries.
@@ -230,7 +238,8 @@ UPB_INLINE bool upb_arrhas(upb_tabval key) {
 /* Initialize and uninitialize a table, respectively.  If memory allocation
  * failed, false is returned that the table is uninitialized. */
 bool upb_inttable_init2(upb_inttable *table, upb_ctype_t ctype, upb_alloc *a);
-bool upb_strtable_init2(upb_strtable *table, upb_ctype_t ctype, upb_alloc *a);
+bool upb_strtable_init2(upb_strtable *table, upb_ctype_t ctype,
+                        size_t expected_size, upb_alloc *a);
 void upb_inttable_uninit2(upb_inttable *table, upb_alloc *a);
 void upb_strtable_uninit2(upb_strtable *table, upb_alloc *a);
 
@@ -239,7 +248,7 @@ UPB_INLINE bool upb_inttable_init(upb_inttable *table, upb_ctype_t ctype) {
 }
 
 UPB_INLINE bool upb_strtable_init(upb_strtable *table, upb_ctype_t ctype) {
-  return upb_strtable_init2(table, ctype, &upb_alloc_global);
+  return upb_strtable_init2(table, ctype, 4, &upb_alloc_global);
 }
 
 UPB_INLINE void upb_inttable_uninit(upb_inttable *table) {
index 7c99228..028cc29 100644 (file)
@@ -17,6 +17,7 @@ typedef struct {
   int indent_depth;
   int options;
   const upb_symtab *ext_pool;
+  _upb_mapsorter sorter;
 } txtenc;
 
 static void txtenc_msg(txtenc *e, const upb_msg *msg, const upb_msgdef *m);
@@ -43,7 +44,7 @@ static void txtenc_printf(txtenc *e, const char *fmt, ...) {
   va_list args;
 
   va_start(args, fmt);
-  n = _upb_vsnprintf(e->ptr, have, fmt, args);
+  n = vsnprintf(e->ptr, have, fmt, args);
   va_end(args);
 
   if (UPB_LIKELY(have > n)) {
@@ -187,6 +188,25 @@ static void txtenc_array(txtenc *e, const upb_array *arr,
   }
 }
 
+static void txtenc_mapentry(txtenc *e, upb_msgval key, upb_msgval val,
+                            const upb_fielddef *f) {
+  const upb_msgdef *entry = upb_fielddef_msgsubdef(f);
+  const upb_fielddef *key_f = upb_msgdef_field(entry, 0);
+  const upb_fielddef *val_f = upb_msgdef_field(entry, 1);
+  txtenc_indent(e);
+  txtenc_printf(e, "%s: {", upb_fielddef_name(f));
+  txtenc_endfield(e);
+  e->indent_depth++;
+
+  txtenc_field(e, key, key_f);
+  txtenc_field(e, val, val_f);
+
+  e->indent_depth--;
+  txtenc_indent(e);
+  txtenc_putstr(e, "}");
+  txtenc_endfield(e);
+}
+
 /*
  * Maps print as messages of key/value, etc.
  *
@@ -200,27 +220,28 @@ static void txtenc_array(txtenc *e, const upb_array *arr,
  *    }
  */
 static void txtenc_map(txtenc *e, const upb_map *map, const upb_fielddef *f) {
-  const upb_msgdef *entry = upb_fielddef_msgsubdef(f);
-  const upb_fielddef *key_f = upb_msgdef_itof(entry, 1);
-  const upb_fielddef *val_f = upb_msgdef_itof(entry, 2);
-  size_t iter = UPB_MAP_BEGIN;
-
-  while (upb_mapiter_next(map, &iter)) {
-    upb_msgval key = upb_mapiter_key(map, iter);
-    upb_msgval val = upb_mapiter_value(map, iter);
-
-    txtenc_indent(e);
-    txtenc_printf(e, "%s: {", upb_fielddef_name(f));
-    txtenc_endfield(e);
-    e->indent_depth++;
-
-    txtenc_field(e, key, key_f);
-    txtenc_field(e, val, val_f);
-
-    e->indent_depth--;
-    txtenc_indent(e);
-    txtenc_putstr(e, "}");
-    txtenc_endfield(e);
+  if (e->options & UPB_TXTENC_NOSORT) {
+    size_t iter = UPB_MAP_BEGIN;
+    while (upb_mapiter_next(map, &iter)) {
+      upb_msgval key = upb_mapiter_key(map, iter);
+      upb_msgval val = upb_mapiter_value(map, iter);
+      txtenc_mapentry(e, key, val, f);
+    }
+  } else {
+    const upb_msgdef *entry = upb_fielddef_msgsubdef(f);
+    const upb_fielddef *key_f = upb_msgdef_field(entry, 0);
+    _upb_sortedmap sorted;
+    upb_map_entry ent;
+
+    _upb_mapsorter_pushmap(&e->sorter, upb_fielddef_descriptortype(key_f), map,
+                           &sorted);
+    while (_upb_sortedmap_next(&e->sorter, map, &sorted, &ent)) {
+      upb_msgval key, val;
+      memcpy(&key, &ent.k, sizeof(key));
+      memcpy(&val, &ent.v, sizeof(val));
+      txtenc_mapentry(e, key, val, f);
+    }
+    _upb_mapsorter_popmap(&e->sorter, &sorted);
   }
 }
 
@@ -392,7 +413,9 @@ size_t upb_text_encode(const upb_msg *msg, const upb_msgdef *m,
   e.indent_depth = 0;
   e.options = options;
   e.ext_pool = ext_pool;
+  _upb_mapsorter_init(&e.sorter);
 
   txtenc_msg(&e, msg, m);
+  _upb_mapsorter_destroy(&e.sorter);
   return txtenc_nullz(&e, size);
 }
index 1a0003c..4ad3d1c 100644 (file)
@@ -13,7 +13,10 @@ enum {
   UPB_TXTENC_SINGLELINE = 1,
 
   /* When set, unknown fields are not printed. */
-  UPB_TXTENC_SKIPUNKNOWN = 2
+  UPB_TXTENC_SKIPUNKNOWN = 2,
+
+  /* When set, maps are *not* sorted (this avoids allocating tmp mem). */
+  UPB_TXTENC_NOSORT = 4
 };
 
 /* Encodes the given |msg| to text format.  The message's reflection is given in
index 3089c05..a126569 100644 (file)
@@ -1,5 +1,5 @@
 
-#include "upb/upb.h"
+#include "upb/upb.int.h"
 
 #include <errno.h>
 #include <stdarg.h>
@@ -40,7 +40,7 @@ void upb_status_seterrf(upb_status *status, const char *fmt, ...) {
 void upb_status_vseterrf(upb_status *status, const char *fmt, va_list args) {
   if (!status) return;
   status->ok = false;
-  _upb_vsnprintf(status->msg, sizeof(status->msg), fmt, args);
+  vsnprintf(status->msg, sizeof(status->msg), fmt, args);
   status->msg[UPB_STATUS_MAX_MESSAGE - 1] = '\0';
 }
 
@@ -49,7 +49,7 @@ void upb_status_vappenderrf(upb_status *status, const char *fmt, va_list args) {
   if (!status) return;
   status->ok = false;
   len = strlen(status->msg);
-  _upb_vsnprintf(status->msg + len, sizeof(status->msg) - len, fmt, args);
+  vsnprintf(status->msg + len, sizeof(status->msg) - len, fmt, args);
   status->msg[UPB_STATUS_MAX_MESSAGE - 1] = '\0';
 }
 
@@ -73,37 +73,18 @@ upb_alloc upb_alloc_global = {&upb_global_allocfunc};
 
 /* Be conservative and choose 16 in case anyone is using SSE. */
 
-typedef struct mem_block {
+struct mem_block {
   struct mem_block *next;
   uint32_t size;
   uint32_t cleanups;
   /* Data follows. */
-} mem_block;
+};
 
 typedef struct cleanup_ent {
   upb_cleanup_func *cleanup;
   void *ud;
 } cleanup_ent;
 
-struct upb_arena {
-  _upb_arena_head head;
-  uint32_t *cleanups;
-
-  /* Allocator to allocate arena blocks.  We are responsible for freeing these
-   * when we are destroyed. */
-  upb_alloc *block_alloc;
-  uint32_t last_size;
-
-  /* When multiple arenas are fused together, each arena points to a parent
-   * arena (root points to itself). The root tracks how many live arenas
-   * reference it. */
-  uint32_t refcount;  /* Only used when a->parent == a */
-  struct upb_arena *parent;
-
-  /* Linked list of blocks to free/cleanup. */
-  mem_block *freelist, *freelist_tail;
-};
-
 static const size_t memblock_reserve = UPB_ALIGN_UP(sizeof(mem_block), 16);
 
 static upb_arena *arena_findroot(upb_arena *a) {
@@ -117,9 +98,9 @@ static upb_arena *arena_findroot(upb_arena *a) {
   return a;
 }
 
-static void upb_arena_addblock(upb_arena *a, void *ptr, size_t size) {
+static void upb_arena_addblock(upb_arena *a, upb_arena *root, void *ptr,
+                               size_t size) {
   mem_block *block = ptr;
-  upb_arena *root = arena_findroot(a);
 
   /* The block is for arena |a|, but should appear in the freelist of |root|. */
   block->next = root->freelist;
@@ -133,26 +114,22 @@ static void upb_arena_addblock(upb_arena *a, void *ptr, size_t size) {
   a->head.end = UPB_PTR_AT(block, size, char);
   a->cleanups = &block->cleanups;
 
-  /* TODO(haberman): ASAN poison. */
+  UPB_POISON_MEMORY_REGION(a->head.ptr, a->head.end - a->head.ptr);
 }
 
 static bool upb_arena_allocblock(upb_arena *a, size_t size) {
+  upb_arena *root = arena_findroot(a);
   size_t block_size = UPB_MAX(size, a->last_size * 2) + memblock_reserve;
-  mem_block *block = upb_malloc(a->block_alloc, block_size);
+  mem_block *block = upb_malloc(root->block_alloc, block_size);
 
   if (!block) return false;
-  upb_arena_addblock(a, block, block_size);
+  upb_arena_addblock(a, root, block, block_size);
   return true;
 }
 
-static bool arena_has(upb_arena *a, size_t size) {
-  _upb_arena_head *h = (_upb_arena_head*)a;
-  return (size_t)(h->end - h->ptr) >= size;
-}
-
 void *_upb_arena_slowmalloc(upb_arena *a, size_t size) {
   if (!upb_arena_allocblock(a, size)) return NULL;  /* Out of memory. */
-  UPB_ASSERT(arena_has(a, size));
+  UPB_ASSERT(_upb_arenahas(a) >= size);
   return upb_arena_malloc(a, size);
 }
 
@@ -184,7 +161,7 @@ upb_arena *arena_initslow(void *mem, size_t n, upb_alloc *alloc) {
   a->freelist = NULL;
   a->freelist_tail = NULL;
 
-  upb_arena_addblock(a, mem, n);
+  upb_arena_addblock(a, a, mem, n);
 
   return a;
 }
@@ -201,15 +178,14 @@ upb_arena *upb_arena_init(void *mem, size_t n, upb_alloc *alloc) {
   }
 
   a = UPB_PTR_AT(mem, n - sizeof(*a), upb_arena);
-  n -= sizeof(*a);
 
   a->head.alloc.func = &upb_arena_doalloc;
   a->block_alloc = alloc;
   a->parent = a;
   a->refcount = 1;
-  a->last_size = 128;
+  a->last_size = UPB_MAX(128, n);
   a->head.ptr = mem;
-  a->head.end = UPB_PTR_AT(mem, n, char);
+  a->head.end = UPB_PTR_AT(mem, n - sizeof(*a), char);
   a->freelist = NULL;
   a->cleanups = NULL;
 
@@ -247,14 +223,15 @@ void upb_arena_free(upb_arena *a) {
 bool upb_arena_addcleanup(upb_arena *a, void *ud, upb_cleanup_func *func) {
   cleanup_ent *ent;
 
-  if (!a->cleanups || !arena_has(a, sizeof(cleanup_ent))) {
+  if (!a->cleanups || _upb_arenahas(a) < sizeof(cleanup_ent)) {
     if (!upb_arena_allocblock(a, 128)) return false;  /* Out of memory. */
-    UPB_ASSERT(arena_has(a, sizeof(cleanup_ent)));
+    UPB_ASSERT(_upb_arenahas(a) >= sizeof(cleanup_ent));
   }
 
   a->head.end -= sizeof(cleanup_ent);
   ent = (cleanup_ent*)a->head.end;
   (*a->cleanups)++;
+  UPB_UNPOISON_MEMORY_REGION(ent, sizeof(cleanup_ent));
 
   ent->cleanup = func;
   ent->ud = ud;
index e1d9d8c..11c0e4d 100644 (file)
@@ -161,17 +161,35 @@ void *_upb_arena_slowmalloc(upb_arena *a, size_t size);
 
 UPB_INLINE upb_alloc *upb_arena_alloc(upb_arena *a) { return (upb_alloc*)a; }
 
+UPB_INLINE size_t _upb_arenahas(upb_arena *a) {
+  _upb_arena_head *h = (_upb_arena_head*)a;
+  return (size_t)(h->end - h->ptr);
+}
+
 UPB_INLINE void *upb_arena_malloc(upb_arena *a, size_t size) {
   _upb_arena_head *h = (_upb_arena_head*)a;
   void* ret;
   size = UPB_ALIGN_MALLOC(size);
 
-  if (UPB_UNLIKELY((size_t)(h->end - h->ptr) < size)) {
+  if (UPB_UNLIKELY(_upb_arenahas(a) < size)) {
     return _upb_arena_slowmalloc(a, size);
   }
 
   ret = h->ptr;
   h->ptr += size;
+  UPB_UNPOISON_MEMORY_REGION(ret, size);
+
+#if UPB_ASAN
+  {
+    size_t guard_size = 32;
+    if (_upb_arenahas(a) >= guard_size) {
+      h->ptr += guard_size;
+    } else {
+      h->ptr = h->end;
+    }
+  }
+#endif
+
   return ret;
 }
 
@@ -283,7 +301,7 @@ UPB_INLINE uint32_t _upb_be_swap32(uint32_t val) {
     return val;
   } else {
     return ((val & 0xff) << 24) | ((val & 0xff00) << 8) |
-           ((val & 0xff0000ULL) >> 8) | ((val & 0xff000000ULL) >> 24);
+           ((val & 0xff0000) >> 8) | ((val & 0xff000000) >> 24);
   }
 }
 
@@ -291,14 +309,25 @@ UPB_INLINE uint64_t _upb_be_swap64(uint64_t val) {
   if (_upb_isle()) {
     return val;
   } else {
-    return ((val & 0xff) << 56) | ((val & 0xff00) << 40) |
-           ((val & 0xff0000) << 24) | ((val & 0xff000000) << 8) |
-           ((val & 0xff00000000ULL) >> 8) | ((val & 0xff0000000000ULL) >> 24) |
-           ((val & 0xff000000000000ULL) >> 40) |
-           ((val & 0xff00000000000000ULL) >> 56);
+    return ((uint64_t)_upb_be_swap32(val) << 32) | _upb_be_swap32(val >> 32);
   }
 }
 
+UPB_INLINE int _upb_lg2ceil(int x) {
+  if (x <= 1) return 0;
+#ifdef __GNUC__
+  return 32 - __builtin_clz(x - 1);
+#else
+  int lg2 = 0;
+  while (1 << lg2 < x) lg2++;
+  return lg2;
+#endif
+}
+
+UPB_INLINE int _upb_lg2ceilsize(int x) {
+  return 1 << _upb_lg2ceil(x);
+}
+
 #include "upb/port_undef.inc"
 
 #ifdef __cplusplus
index a3ec5fa..b7b9976 100644 (file)
@@ -41,6 +41,9 @@ class Arena {
  public:
   // A simple arena with no initial memory block and the default allocator.
   Arena() : ptr_(upb_arena_new(), upb_arena_free) {}
+  Arena(char *initial_block, size_t size)
+      : ptr_(upb_arena_init(initial_block, size, &upb_alloc_global),
+             upb_arena_free) {}
 
   upb_arena* ptr() { return ptr_.get(); }
 
@@ -71,15 +74,12 @@ class Arena {
 template <int N>
 class InlinedArena : public Arena {
  public:
-  InlinedArena() : ptr_(upb_arena_new(&initial_block_, N, &upb_alloc_global)) {}
-
-  upb_arena* ptr() { return ptr_.get(); }
+  InlinedArena() : Arena(initial_block_, N) {}
 
  private:
   InlinedArena(const InlinedArena*) = delete;
   InlinedArena& operator=(const InlinedArena*) = delete;
 
-  std::unique_ptr<upb_arena, decltype(&upb_arena_free)> ptr_;
   char initial_block_[N];
 };
 
diff --git a/third_party/upb/upb/upb.int.h b/third_party/upb/upb/upb.int.h
new file mode 100644 (file)
index 0000000..b857560
--- /dev/null
@@ -0,0 +1,29 @@
+
+#ifndef UPB_INT_H_
+#define UPB_INT_H_
+
+#include "upb/upb.h"
+
+struct mem_block;
+typedef struct mem_block mem_block;
+
+struct upb_arena {
+  _upb_arena_head head;
+  uint32_t *cleanups;
+
+  /* Allocator to allocate arena blocks.  We are responsible for freeing these
+   * when we are destroyed. */
+  upb_alloc *block_alloc;
+  uint32_t last_size;
+
+  /* When multiple arenas are fused together, each arena points to a parent
+   * arena (root points to itself). The root tracks how many live arenas
+   * reference it. */
+  uint32_t refcount;  /* Only used when a->parent == a */
+  struct upb_arena *parent;
+
+  /* Linked list of blocks to free/cleanup. */
+  mem_block *freelist, *freelist_tail;
+};
+
+#endif  /* UPB_INT_H_ */
diff --git a/third_party/upb/upbc/BUILD b/third_party/upb/upbc/BUILD
new file mode 100644 (file)
index 0000000..3b7d69b
--- /dev/null
@@ -0,0 +1,53 @@
+load(
+    "//bazel:build_defs.bzl",
+    "UPB_DEFAULT_CPPOPTS",
+)
+
+licenses(["notice"])
+
+cc_library(
+    name = "common",
+    hdrs = ["common.h"],
+    srcs = ["common.cc"],
+    copts = UPB_DEFAULT_CPPOPTS,
+    deps = [
+        "@com_google_protobuf//:protobuf",
+        "@com_google_absl//absl/strings",
+    ],
+)
+
+cc_binary(
+    name = "protoc-gen-upb",
+    srcs = [
+        "protoc-gen-upb.cc",
+        "message_layout.cc",
+        "message_layout.h",
+    ],
+    copts = UPB_DEFAULT_CPPOPTS,
+    visibility = ["//visibility:public"],
+    deps = [
+        ":common",
+        "@com_google_absl//absl/base:core_headers",
+        "@com_google_absl//absl/container:flat_hash_map",
+        "@com_google_absl//absl/strings",
+        "@com_google_protobuf//:protobuf",
+        "@com_google_protobuf//:protoc_lib",
+    ],
+)
+
+cc_binary(
+    name = "protoc-gen-upbdefs",
+    srcs = [
+        "protoc-gen-upbdefs.cc",
+    ],
+    copts = UPB_DEFAULT_CPPOPTS,
+    visibility = ["//visibility:public"],
+    deps = [
+        ":common",
+        "@com_google_absl//absl/base:core_headers",
+        "@com_google_absl//absl/container:flat_hash_map",
+        "@com_google_absl//absl/strings",
+        "@com_google_protobuf//:protobuf",
+        "@com_google_protobuf//:protoc_lib",
+    ],
+)
diff --git a/third_party/upb/upbc/common.cc b/third_party/upb/upbc/common.cc
new file mode 100644 (file)
index 0000000..c1b30a3
--- /dev/null
@@ -0,0 +1,65 @@
+
+#include "absl/strings/str_replace.h"
+#include "upbc/common.h"
+
+namespace upbc {
+namespace {
+
+namespace protobuf = ::google::protobuf;
+
+void AddMessages(const protobuf::Descriptor* message,
+                 std::vector<const protobuf::Descriptor*>* messages) {
+  messages->push_back(message);
+  for (int i = 0; i < message->nested_type_count(); i++) {
+    AddMessages(message->nested_type(i), messages);
+  }
+}
+
+}  // namespace
+
+std::string StripExtension(absl::string_view fname) {
+  size_t lastdot = fname.find_last_of(".");
+  if (lastdot == std::string::npos) {
+    return std::string(fname);
+  }
+  return std::string(fname.substr(0, lastdot));
+}
+
+std::string ToCIdent(absl::string_view str) {
+  return absl::StrReplaceAll(str, {{".", "_"}, {"/", "_"}});
+}
+
+std::string ToPreproc(absl::string_view str) {
+  return absl::AsciiStrToUpper(ToCIdent(str));
+}
+
+void EmitFileWarning(const protobuf::FileDescriptor* file, Output& output) {
+  output(
+      "/* This file was generated by upbc (the upb compiler) from the input\n"
+      " * file:\n"
+      " *\n"
+      " *     $0\n"
+      " *\n"
+      " * Do not edit -- your changes will be discarded when the file is\n"
+      " * regenerated. */\n\n",
+      file->name());
+}
+
+std::vector<const protobuf::Descriptor*> SortedMessages(
+    const protobuf::FileDescriptor* file) {
+  std::vector<const protobuf::Descriptor*> messages;
+  for (int i = 0; i < file->message_type_count(); i++) {
+    AddMessages(file->message_type(i), &messages);
+  }
+  return messages;
+}
+
+std::string MessageName(const protobuf::Descriptor* descriptor) {
+  return ToCIdent(descriptor->full_name());
+}
+
+std::string MessageInit(const protobuf::Descriptor* descriptor) {
+  return MessageName(descriptor) + "_msginit";
+}
+
+}  // namespace upbc
diff --git a/third_party/upb/upbc/common.h b/third_party/upb/upbc/common.h
new file mode 100644 (file)
index 0000000..5825786
--- /dev/null
@@ -0,0 +1,66 @@
+
+#ifndef UPBC_COMMON_H
+#define UPBC_COMMON_H
+
+#include <vector>
+
+#include "absl/strings/substitute.h"
+#include "google/protobuf/descriptor.h"
+#include "google/protobuf/io/zero_copy_stream.h"
+
+namespace upbc {
+
+class Output {
+ public:
+  Output(google::protobuf::io::ZeroCopyOutputStream* stream)
+      : stream_(stream) {}
+  ~Output() { stream_->BackUp((int)size_); }
+
+  template <class... Arg>
+  void operator()(absl::string_view format, const Arg&... arg) {
+    Write(absl::Substitute(format, arg...));
+  }
+
+ private:
+  void Write(absl::string_view data) {
+    while (!data.empty()) {
+      RefreshOutput();
+      size_t to_write = std::min(data.size(), size_);
+      memcpy(ptr_, data.data(), to_write);
+      data.remove_prefix(to_write);
+      ptr_ += to_write;
+      size_ -= to_write;
+    }
+  }
+
+  void RefreshOutput() {
+    while (size_ == 0) {
+      void *ptr;
+      int size;
+      if (!stream_->Next(&ptr, &size)) {
+        fprintf(stderr, "upbc: Failed to write to to output\n");
+        abort();
+      }
+      ptr_ = static_cast<char*>(ptr);
+      size_ = size;
+    }
+  }
+
+  google::protobuf::io::ZeroCopyOutputStream* stream_;
+  char *ptr_ = nullptr;
+  size_t size_ = 0;
+};
+
+std::string StripExtension(absl::string_view fname);
+std::string ToCIdent(absl::string_view str);
+std::string ToPreproc(absl::string_view str);
+void EmitFileWarning(const google::protobuf::FileDescriptor* file,
+                     Output& output);
+std::vector<const google::protobuf::Descriptor*> SortedMessages(
+    const google::protobuf::FileDescriptor* file);
+std::string MessageInit(const google::protobuf::Descriptor* descriptor);
+std::string MessageName(const google::protobuf::Descriptor* descriptor);
+
+}  // namespace upbc
+
+# endif  // UPBC_COMMON_H
diff --git a/third_party/upb/upbc/generator.h b/third_party/upb/upbc/generator.h
deleted file mode 100644 (file)
index ed6cedc..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-
-#ifndef UPBC_GENERATOR_H_
-#define UPBC_GENERATOR_H_
-
-#include <memory>
-#include <google/protobuf/compiler/code_generator.h>
-
-namespace upbc {
-std::unique_ptr<google::protobuf::compiler::CodeGenerator> GetGenerator();
-}
-
-#endif  // UPBC_GENERATOR_H_
diff --git a/third_party/upb/upbc/main.cc b/third_party/upb/upbc/main.cc
deleted file mode 100644 (file)
index a9682a9..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-
-#include <google/protobuf/compiler/plugin.h>
-
-#include "upbc/generator.h"
-
-int main(int argc, char** argv) {
-  return google::protobuf::compiler::PluginMain(argc, argv,
-                                                upbc::GetGenerator().get());
-}
index cb7f7f9..3d35448 100644 (file)
@@ -24,9 +24,7 @@ MessageLayout::Size MessageLayout::Place(
 }
 
 bool MessageLayout::HasHasbit(const protobuf::FieldDescriptor* field) {
-  return field->file()->syntax() == protobuf::FileDescriptor::SYNTAX_PROTO2 &&
-         field->label() != protobuf::FieldDescriptor::LABEL_REPEATED &&
-         !field->containing_oneof() &&
+  return field->has_presence() && !field->real_containing_oneof() &&
          !field->containing_type()->options().map_entry();
 }
 
@@ -51,10 +49,15 @@ MessageLayout::SizeAndAlign MessageLayout::SizeOfUnwrapped(
     case protobuf::FieldDescriptor::CPPTYPE_FLOAT:
     case protobuf::FieldDescriptor::CPPTYPE_INT32:
     case protobuf::FieldDescriptor::CPPTYPE_UINT32:
+    case protobuf::FieldDescriptor::CPPTYPE_ENUM:
       return {{4, 4}, {4, 4}};
-    default:
+    case protobuf::FieldDescriptor::CPPTYPE_INT64:
+    case protobuf::FieldDescriptor::CPPTYPE_UINT64:
+    case protobuf::FieldDescriptor::CPPTYPE_DOUBLE:
       return {{8, 8}, {8, 8}};
   }
+  assert(false);
+  return {{-1, -1}, {-1, -1}};
 }
 
 int64_t MessageLayout::FieldLayoutRank(const protobuf::FieldDescriptor* field) {
@@ -105,7 +108,7 @@ int64_t MessageLayout::FieldLayoutRank(const protobuf::FieldDescriptor* field) {
 
 void MessageLayout::ComputeLayout(const protobuf::Descriptor* descriptor) {
   size_ = Size{0, 0};
-  maxalign_ = Size{0, 0};
+  maxalign_ = Size{8, 8};
 
   if (descriptor->options().map_entry()) {
     // Map entries aren't actually stored, they are only used during parsing.
@@ -140,7 +143,7 @@ void MessageLayout::PlaceNonOneofFields(
 
   // Place/count hasbits.
   int hasbit_count = 0;
-  for (auto field : field_order) {
+  for (auto field : FieldHotnessOrder(descriptor)) {
     if (HasHasbit(field)) {
       // We don't use hasbit 0, so that 0 can indicate "no presence" in the
       // table. This wastes one hasbit, but we don't worry about it for now.
index c2446a0..f257a96 100644 (file)
@@ -102,6 +102,23 @@ class MessageLayout {
   Size size_;
 };
 
+// Returns fields in order of "hotness", eg. how frequently they appear in
+// serialized payloads. Ideally this will use a profile. When we don't have
+// that, we assume that fields with smaller numbers are used more frequently.
+inline std::vector<const google::protobuf::FieldDescriptor*> FieldHotnessOrder(
+    const google::protobuf::Descriptor* message) {
+  std::vector<const google::protobuf::FieldDescriptor*> fields;
+  for (int i = 0; i < message->field_count(); i++) {
+    fields.push_back(message->field(i));
+  }
+  std::sort(fields.begin(), fields.end(),
+            [](const google::protobuf::FieldDescriptor* a,
+               const google::protobuf::FieldDescriptor* b) {
+              return a->number() < b->number();
+            });
+  return fields;
+}
+
 }  // namespace upbc
 
 #endif  // UPBC_MESSAGE_LAYOUT_H
similarity index 69%
rename from third_party/upb/upbc/generator.cc
rename to third_party/upb/upbc/protoc-gen-upb.cc
index 72df024..e099ad4 100644 (file)
 
 #include "absl/container/flat_hash_map.h"
 #include "absl/strings/ascii.h"
-#include "absl/strings/str_replace.h"
 #include "absl/strings/substitute.h"
 #include "google/protobuf/compiler/code_generator.h"
+#include "google/protobuf/compiler/plugin.h"
 #include "google/protobuf/descriptor.h"
 #include "google/protobuf/descriptor.pb.h"
-#include "google/protobuf/io/zero_copy_stream.h"
-
-#include "upbc/generator.h"
+#include "google/protobuf/wire_format.h"
+#include "upbc/common.h"
 #include "upbc/message_layout.h"
 
+namespace upbc {
+namespace {
+
 namespace protoc = ::google::protobuf::compiler;
 namespace protobuf = ::google::protobuf;
 
-static std::string StripExtension(absl::string_view fname) {
-  size_t lastdot = fname.find_last_of(".");
-  if (lastdot == std::string::npos) {
-    return std::string(fname);
-  }
-  return std::string(fname.substr(0, lastdot));
-}
-
-static std::string HeaderFilename(std::string proto_filename) {
+std::string HeaderFilename(std::string proto_filename) {
   return StripExtension(proto_filename) + ".upb.h";
 }
 
-static std::string SourceFilename(std::string proto_filename) {
+std::string SourceFilename(std::string proto_filename) {
   return StripExtension(proto_filename) + ".upb.c";
 }
 
-static std::string DefHeaderFilename(std::string proto_filename) {
-  return StripExtension(proto_filename) + ".upbdefs.h";
-}
-
-static std::string DefSourceFilename(std::string proto_filename) {
-  return StripExtension(proto_filename) + ".upbdefs.c";
-}
-
-class Output {
- public:
-  Output(protobuf::io::ZeroCopyOutputStream* stream) : stream_(stream) {}
-  ~Output() { stream_->BackUp((int)size_); }
-
-  template <class... Arg>
-  void operator()(absl::string_view format, const Arg&... arg) {
-    Write(absl::Substitute(format, arg...));
-  }
-
- private:
-  void Write(absl::string_view data) {
-    while (!data.empty()) {
-      RefreshOutput();
-      size_t to_write = std::min(data.size(), size_);
-      memcpy(ptr_, data.data(), to_write);
-      data.remove_prefix(to_write);
-      ptr_ += to_write;
-      size_ -= to_write;
-    }
-  }
-
-  void RefreshOutput() {
-    while (size_ == 0) {
-      void *ptr;
-      int size;
-      if (!stream_->Next(&ptr, &size)) {
-        fprintf(stderr, "upbc: Failed to write to to output\n");
-        abort();
-      }
-      ptr_ = static_cast<char*>(ptr);
-      size_ = size;
-    }
-  }
-
-  protobuf::io::ZeroCopyOutputStream* stream_;
-  char *ptr_ = nullptr;
-  size_t size_ = 0;
-};
-
-namespace upbc {
-
-class Generator : public protoc::CodeGenerator {
-  ~Generator() override {}
-  bool Generate(const protobuf::FileDescriptor* file,
-                const std::string& parameter, protoc::GeneratorContext* context,
-                std::string* error) const override;
-  uint64_t GetSupportedFeatures() const override {
-    return FEATURE_PROTO3_OPTIONAL;
-  }
-};
-
-void AddMessages(const protobuf::Descriptor* message,
-                 std::vector<const protobuf::Descriptor*>* messages) {
-  messages->push_back(message);
-  for (int i = 0; i < message->nested_type_count(); i++) {
-    AddMessages(message->nested_type(i), messages);
-  }
-}
-
 void AddEnums(const protobuf::Descriptor* message,
               std::vector<const protobuf::EnumDescriptor*>* enums) {
   for (int i = 0; i < message->enum_type_count(); i++) {
@@ -116,15 +42,6 @@ void SortDefs(std::vector<T>* defs) {
             [](T a, T b) { return a->full_name() < b->full_name(); });
 }
 
-std::vector<const protobuf::Descriptor*> SortedMessages(
-    const protobuf::FileDescriptor* file) {
-  std::vector<const protobuf::Descriptor*> messages;
-  for (int i = 0; i < file->message_type_count(); i++) {
-    AddMessages(file->message_type(i), &messages);
-  }
-  return messages;
-}
-
 std::vector<const protobuf::EnumDescriptor*> SortedEnums(
     const protobuf::FileDescriptor* file) {
   std::vector<const protobuf::EnumDescriptor*> enums;
@@ -140,16 +57,16 @@ std::vector<const protobuf::EnumDescriptor*> SortedEnums(
 
 std::vector<const protobuf::FieldDescriptor*> FieldNumberOrder(
     const protobuf::Descriptor* message) {
-  std::vector<const protobuf::FieldDescriptor*> messages;
+  std::vector<const protobuf::FieldDescriptor*> fields;
   for (int i = 0; i < message->field_count(); i++) {
-    messages.push_back(message->field(i));
+    fields.push_back(message->field(i));
   }
-  std::sort(messages.begin(), messages.end(),
+  std::sort(fields.begin(), fields.end(),
             [](const protobuf::FieldDescriptor* a,
                const protobuf::FieldDescriptor* b) {
               return a->number() < b->number();
             });
-  return messages;
+  return fields;
 }
 
 std::vector<const protobuf::FieldDescriptor*> SortedSubmessages(
@@ -170,18 +87,6 @@ std::vector<const protobuf::FieldDescriptor*> SortedSubmessages(
   return ret;
 }
 
-std::string ToCIdent(absl::string_view str) {
-  return absl::StrReplaceAll(str, {{".", "_"}, {"/", "_"}});
-}
-
-std::string DefInitSymbol(const protobuf::FileDescriptor *file) {
-  return ToCIdent(file->name()) + "_upbdefinit";
-}
-
-std::string ToPreproc(absl::string_view str) {
-  return absl::AsciiStrToUpper(ToCIdent(str));
-}
-
 std::string EnumValueSymbol(const protobuf::EnumValueDescriptor* value) {
   return ToCIdent(value->full_name());
 }
@@ -190,14 +95,6 @@ std::string GetSizeInit(const MessageLayout::Size& size) {
   return absl::Substitute("UPB_SIZE($0, $1)", size.size32, size.size64);
 }
 
-std::string MessageName(const protobuf::Descriptor* descriptor) {
-  return ToCIdent(descriptor->full_name());
-}
-
-std::string MessageInit(const protobuf::Descriptor* descriptor) {
-  return MessageName(descriptor) + "_msginit";
-}
-
 std::string CTypeInternal(const protobuf::FieldDescriptor* field,
                           bool is_const) {
   std::string maybe_const = is_const ? "const " : "";
@@ -231,28 +128,28 @@ std::string CTypeInternal(const protobuf::FieldDescriptor* field,
   }
 }
 
-std::string UpbType(const protobuf::FieldDescriptor* field) {
+std::string SizeLg2(const protobuf::FieldDescriptor* field) {
   switch (field->cpp_type()) {
     case protobuf::FieldDescriptor::CPPTYPE_MESSAGE:
-      return "UPB_TYPE_MESSAGE";
+      return "UPB_SIZE(2, 3)";
     case protobuf::FieldDescriptor::CPPTYPE_ENUM:
-      return "UPB_TYPE_ENUM";
+      return std::to_string(2);
     case protobuf::FieldDescriptor::CPPTYPE_BOOL:
-      return "UPB_TYPE_BOOL";
+      return std::to_string(1);
     case protobuf::FieldDescriptor::CPPTYPE_FLOAT:
-      return "UPB_TYPE_FLOAT";
+      return std::to_string(2);
     case protobuf::FieldDescriptor::CPPTYPE_INT32:
-      return "UPB_TYPE_INT32";
+      return std::to_string(2);
     case protobuf::FieldDescriptor::CPPTYPE_UINT32:
-      return "UPB_TYPE_UINT32";
+      return std::to_string(2);
     case protobuf::FieldDescriptor::CPPTYPE_DOUBLE:
-      return "UPB_TYPE_DOUBLE";
+      return std::to_string(3);
     case protobuf::FieldDescriptor::CPPTYPE_INT64:
-      return "UPB_TYPE_INT64";
+      return std::to_string(3);
     case protobuf::FieldDescriptor::CPPTYPE_UINT64:
-      return "UPB_TYPE_UINT64";
+      return std::to_string(3);
     case protobuf::FieldDescriptor::CPPTYPE_STRING:
-      return "UPB_TYPE_STRING";
+      return "UPB_SIZE(3, 4)";
     default:
       fprintf(stderr, "Unexpected type");
       abort();
@@ -318,18 +215,6 @@ void DumpEnumValues(const protobuf::EnumDescriptor* desc, Output& output) {
   }
 }
 
-void EmitFileWarning(const protobuf::FileDescriptor* file, Output& output) {
-  output(
-      "/* This file was generated by upbc (the upb compiler) from the input\n"
-      " * file:\n"
-      " *\n"
-      " *     $0\n"
-      " *\n"
-      " * Do not edit -- your changes will be discarded when the file is\n"
-      " * regenerated. */\n\n",
-      file->name());
-}
-
 void GenerateMessageInHeader(const protobuf::Descriptor* message, Output& output) {
   MessageLayout layout(message);
 
@@ -346,6 +231,12 @@ void GenerateMessageInHeader(const protobuf::Descriptor* message, Output& output
         "  $0 *ret = $0_new(arena);\n"
         "  return (ret && upb_decode(buf, size, ret, &$1, arena)) ? ret : NULL;\n"
         "}\n"
+        "UPB_INLINE $0 *$0_parse_ex(const char *buf, size_t size,\n"
+        "                           upb_arena *arena, int options) {\n"
+        "  $0 *ret = $0_new(arena);\n"
+        "  return (ret && _upb_decode(buf, size, ret, &$1, arena, options))\n"
+        "      ? ret : NULL;\n"
+        "}\n"
         "UPB_INLINE char *$0_serialize(const $0 *msg, upb_arena *arena, size_t "
         "*len) {\n"
         "  return upb_encode(msg, &$1, arena, len);\n"
@@ -505,35 +396,33 @@ void GenerateMessageInHeader(const protobuf::Descriptor* message, Output& output
       output(
           "UPB_INLINE $0* $1_resize_$2($1 *msg, size_t len, "
           "upb_arena *arena) {\n"
-          "  return ($0*)_upb_array_resize_accessor(msg, $3, len, $4, arena);\n"
+          "  return ($0*)_upb_array_resize_accessor2(msg, $3, len, $4, arena);\n"
           "}\n",
           CType(field), msgname, field->name(),
           GetSizeInit(layout.GetFieldOffset(field)),
-          UpbType(field));
+          SizeLg2(field));
       if (field->cpp_type() == protobuf::FieldDescriptor::CPPTYPE_MESSAGE) {
         output(
             "UPB_INLINE struct $0* $1_add_$2($1 *msg, upb_arena *arena) {\n"
             "  struct $0* sub = (struct $0*)_upb_msg_new(&$3, arena);\n"
-            "  bool ok = _upb_array_append_accessor(\n"
-            "      msg, $4, $5, $6, &sub, arena);\n"
+            "  bool ok = _upb_array_append_accessor2(\n"
+            "      msg, $4, $5, &sub, arena);\n"
             "  if (!ok) return NULL;\n"
             "  return sub;\n"
             "}\n",
             MessageName(field->message_type()), msgname, field->name(),
             MessageInit(field->message_type()),
             GetSizeInit(layout.GetFieldOffset(field)),
-            GetSizeInit(MessageLayout::SizeOfUnwrapped(field).size),
-            UpbType(field));
+            SizeLg2(field));
       } else {
         output(
             "UPB_INLINE bool $1_add_$2($1 *msg, $0 val, upb_arena *arena) {\n"
-            "  return _upb_array_append_accessor(msg, $3, $4, $5, &val,\n"
+            "  return _upb_array_append_accessor2(msg, $3, $4, &val,\n"
             "      arena);\n"
             "}\n",
             CType(field), msgname, field->name(),
             GetSizeInit(layout.GetFieldOffset(field)),
-            GetSizeInit(MessageLayout::SizeOfUnwrapped(field).size),
-            UpbType(field));
+            SizeLg2(field));
       }
     } else {
       // Non-repeated field.
@@ -600,6 +489,7 @@ void WriteHeader(const protobuf::FileDescriptor* file, Output& output) {
       "#define $0_UPB_H_\n\n"
       "#include \"upb/msg.h\"\n"
       "#include \"upb/decode.h\"\n"
+      "#include \"upb/decode_fast.h\"\n"
       "#include \"upb/encode.h\"\n\n",
       ToPreproc(file->name()));
 
@@ -703,7 +593,234 @@ int TableDescriptorType(const protobuf::FieldDescriptor* field) {
   }
 }
 
-void WriteSource(const protobuf::FileDescriptor* file, Output& output) {
+struct SubmsgArray {
+ public:
+  SubmsgArray(const protobuf::Descriptor* message) : message_(message) {
+    MessageLayout layout(message);
+    std::vector<const protobuf::FieldDescriptor*> sorted_submsgs =
+        SortedSubmessages(message);
+    int i = 0;
+    for (auto submsg : sorted_submsgs) {
+      if (indexes_.find(submsg->message_type()) != indexes_.end()) {
+        continue;
+      }
+      submsgs_.push_back(submsg->message_type());
+      indexes_[submsg->message_type()] = i++;
+    }
+  }
+
+  const std::vector<const protobuf::Descriptor*>& submsgs() const {
+    return submsgs_;
+  }
+
+  int GetIndex(const protobuf::FieldDescriptor* field) {
+    (void)message_;
+    assert(field->containing_type() == message_);
+    auto it = indexes_.find(field->message_type());
+    assert(it != indexes_.end());
+    return it->second;
+  }
+
+ private:
+  const protobuf::Descriptor* message_;
+  std::vector<const protobuf::Descriptor*> submsgs_;
+  absl::flat_hash_map<const protobuf::Descriptor*, int> indexes_;
+};
+
+typedef std::pair<std::string, uint64_t> TableEntry;
+
+uint64_t GetEncodedTag(const protobuf::FieldDescriptor* field) {
+  protobuf::internal::WireFormatLite::WireType wire_type =
+      protobuf::internal::WireFormat::WireTypeForField(field);
+  uint32_t unencoded_tag =
+      protobuf::internal::WireFormatLite::MakeTag(field->number(), wire_type);
+  uint8_t tag_bytes[10] = {0};
+  protobuf::io::CodedOutputStream::WriteVarint32ToArray(unencoded_tag,
+                                                        tag_bytes);
+  uint64_t encoded_tag = 0;
+  memcpy(&encoded_tag, tag_bytes, sizeof(encoded_tag));
+  // TODO: byte-swap for big endian.
+  return encoded_tag;
+}
+
+int GetTableSlot(const protobuf::FieldDescriptor* field) {
+  uint64_t tag = GetEncodedTag(field);
+  if (tag > 0x7fff) {
+    // Tag must fit within a two-byte varint.
+    return -1;
+  }
+  return (tag & 0xf8) >> 3;
+}
+
+bool TryFillTableEntry(const protobuf::Descriptor* message,
+                       const MessageLayout& layout,
+                       const protobuf::FieldDescriptor* field,
+                       TableEntry& ent) {
+  std::string type = "";
+  std::string cardinality = "";
+  switch (field->type()) {
+    case protobuf::FieldDescriptor::TYPE_BOOL:
+      type = "b1";
+      break;
+    case protobuf::FieldDescriptor::TYPE_INT32:
+    case protobuf::FieldDescriptor::TYPE_ENUM:
+    case protobuf::FieldDescriptor::TYPE_UINT32:
+      type = "v4";
+      break;
+    case protobuf::FieldDescriptor::TYPE_INT64:
+    case protobuf::FieldDescriptor::TYPE_UINT64:
+      type = "v8";
+      break;
+    case protobuf::FieldDescriptor::TYPE_FIXED32:
+    case protobuf::FieldDescriptor::TYPE_SFIXED32:
+    case protobuf::FieldDescriptor::TYPE_FLOAT:
+      type = "f4";
+      break;
+    case protobuf::FieldDescriptor::TYPE_FIXED64:
+    case protobuf::FieldDescriptor::TYPE_SFIXED64:
+    case protobuf::FieldDescriptor::TYPE_DOUBLE:
+      type = "f8";
+      break;
+    case protobuf::FieldDescriptor::TYPE_SINT32:
+      type = "z4";
+      break;
+    case protobuf::FieldDescriptor::TYPE_SINT64:
+      type = "z8";
+      break;
+    case protobuf::FieldDescriptor::TYPE_STRING:
+      if (field->file()->syntax() == protobuf::FileDescriptor::SYNTAX_PROTO3) {
+        // Only proto3 validates UTF-8.
+        type = "s";
+        break;
+      }
+      ABSL_FALLTHROUGH_INTENDED;
+    case protobuf::FieldDescriptor::TYPE_BYTES:
+      type = "b";
+      break;
+    case protobuf::FieldDescriptor::TYPE_MESSAGE:
+      if (field->is_map()) {
+        return false;  // Not supported yet (ever?).
+      }
+      type = "m";
+      break;
+    default:
+      return false;  // Not supported yet.
+  }
+
+  switch (field->label()) {
+    case protobuf::FieldDescriptor::LABEL_REPEATED:
+      if (field->is_packed()) {
+        cardinality = "p";
+      } else {
+        cardinality = "r";
+      }
+      break;
+    case protobuf::FieldDescriptor::LABEL_OPTIONAL:
+    case protobuf::FieldDescriptor::LABEL_REQUIRED:
+      if (field->real_containing_oneof()) {
+        cardinality = "o";
+      } else {
+        cardinality = "s";
+      }
+      break;
+  }
+
+  uint64_t expected_tag = GetEncodedTag(field);
+  MessageLayout::Size offset = layout.GetFieldOffset(field);
+
+  // Data is:
+  //
+  //                  48                32                16                 0
+  // |--------|--------|--------|--------|--------|--------|--------|--------|
+  // |   offset (16)   |case offset (16) |presence| submsg |  exp. tag (16)  |
+  // |--------|--------|--------|--------|--------|--------|--------|--------|
+  //
+  // - |presence| is either hasbit index or field number for oneofs.
+
+  uint64_t data = offset.size64 << 48 | expected_tag;
+
+  if (field->is_repeated()) {
+    // No hasbit/oneof-related fields.
+  } if (field->real_containing_oneof()) {
+    MessageLayout::Size case_offset =
+        layout.GetOneofCaseOffset(field->real_containing_oneof());
+    if (case_offset.size64 > 0xffff) return false;
+    assert(field->number() < 256);
+    data |= field->number() << 24;
+    data |= case_offset.size64 << 32;
+  } else {
+    uint64_t hasbit_index = 63;  // No hasbit (set a high, unused bit).
+    if (layout.HasHasbit(field)) {
+      hasbit_index = layout.GetHasbitIndex(field);
+      if (hasbit_index > 31) return false;
+    }
+    data |= hasbit_index << 24;
+  }
+
+  if (field->cpp_type() == protobuf::FieldDescriptor::CPPTYPE_MESSAGE) {
+    SubmsgArray submsg_array(message);
+    uint64_t idx = submsg_array.GetIndex(field);
+    if (idx > 255) return false;
+    data |= idx << 16;
+
+    std::string size_ceil = "max";
+    size_t size = SIZE_MAX;
+    if (field->message_type()->file() == field->file()) {
+      // We can only be guaranteed the size of the sub-message if it is in the
+      // same file as us.  We could relax this to increase the speed of
+      // cross-file sub-message parsing if we are comfortable requiring that
+      // users compile all messages at the same time.
+      MessageLayout sub_layout(field->message_type());
+      size = sub_layout.message_size().size64 + 8;
+    }
+    std::vector<size_t> breaks = {64, 128, 192, 256};
+    for (auto brk : breaks) {
+      if (size <= brk) {
+        size_ceil = std::to_string(brk);
+        break;
+      }
+    }
+    ent.first = absl::Substitute("upb_p$0$1_$2bt_max$3b", cardinality, type,
+                                 expected_tag > 0xff ? "2" : "1", size_ceil);
+
+  } else {
+    ent.first = absl::Substitute("upb_p$0$1_$2bt", cardinality, type,
+                                 expected_tag > 0xff ? "2" : "1");
+  }
+  ent.second = data;
+  return true;
+}
+
+std::vector<TableEntry> FastDecodeTable(const protobuf::Descriptor* message,
+                                        const MessageLayout& layout) {
+  std::vector<TableEntry> table;
+  for (const auto field : FieldHotnessOrder(message)) {
+    TableEntry ent;
+    int slot = GetTableSlot(field);
+    // std::cerr << "table slot: " << field->number() << ": " << slot << "\n";
+    if (slot < 0) {
+      // Tag can't fit in the table.
+      continue;
+    }
+    if (!TryFillTableEntry(message, layout, field, ent)) {
+      // Unsupported field type or offset, hasbit index, etc. doesn't fit.
+      continue;
+    }
+    while ((size_t)slot >= table.size()) {
+      size_t size = std::max(static_cast<size_t>(1), table.size() * 2);
+      table.resize(size, TableEntry{"fastdecode_generic", 0});
+    }
+    if (table[slot].first != "fastdecode_generic") {
+      // A hotter field already filled this slot.
+      continue;
+    }
+    table[slot] = ent;
+  }
+  return table;
+}
+
+void WriteSource(const protobuf::FileDescriptor* file, Output& output,
+                 bool fasttable_enabled) {
   EmitFileWarning(file, output);
 
   output(
@@ -726,27 +843,19 @@ void WriteSource(const protobuf::FileDescriptor* file, Output& output) {
     std::string msgname = ToCIdent(message->full_name());
     std::string fields_array_ref = "NULL";
     std::string submsgs_array_ref = "NULL";
-    absl::flat_hash_map<const protobuf::Descriptor*, int> submsg_indexes;
     MessageLayout layout(message);
-    std::vector<const protobuf::FieldDescriptor*> sorted_submsgs =
-        SortedSubmessages(message);
+    SubmsgArray submsg_array(message);
 
-    if (!sorted_submsgs.empty()) {
+    if (!submsg_array.submsgs().empty()) {
       // TODO(haberman): could save a little bit of space by only generating a
       // "submsgs" array for every strongly-connected component.
       std::string submsgs_array_name = msgname + "_submsgs";
       submsgs_array_ref = "&" + submsgs_array_name + "[0]";
       output("static const upb_msglayout *const $0[$1] = {\n",
-             submsgs_array_name, sorted_submsgs.size());
+             submsgs_array_name, submsg_array.submsgs().size());
 
-      int i = 0;
-      for (auto submsg : sorted_submsgs) {
-        if (submsg_indexes.find(submsg->message_type()) !=
-            submsg_indexes.end()) {
-          continue;
-        }
-        output("  &$0,\n", MessageInit(submsg->message_type()));
-        submsg_indexes[submsg->message_type()] = i++;
+      for (auto submsg : submsg_array.submsgs()) {
+        output("  &$0,\n", MessageInit(submsg));
       }
 
       output("};\n\n");
@@ -764,7 +873,7 @@ void WriteSource(const protobuf::FileDescriptor* file, Output& output) {
         std::string presence = "0";
 
         if (field->cpp_type() == protobuf::FieldDescriptor::CPPTYPE_MESSAGE) {
-          submsg_index = submsg_indexes[field->message_type()];
+          submsg_index = submsg_array.GetIndex(field);
         }
 
         if (MessageLayout::HasHasbit(field)) {
@@ -803,14 +912,34 @@ void WriteSource(const protobuf::FileDescriptor* file, Output& output) {
       output("};\n\n");
     }
 
+    std::vector<TableEntry> table;
+    uint8_t table_mask = -1;
+
+    if (fasttable_enabled) {
+      table = FastDecodeTable(message, layout);
+    }
+
+    if (table.size() > 1) {
+      assert((table.size() & (table.size() - 1)) == 0);
+      table_mask = (table.size() - 1) << 3;
+    }
+
     output("const upb_msglayout $0 = {\n", MessageInit(message));
     output("  $0,\n", submsgs_array_ref);
     output("  $0,\n", fields_array_ref);
-    output("  $0, $1, $2,\n", GetSizeInit(layout.message_size()),
+    output("  $0, $1, $2, $3,\n", GetSizeInit(layout.message_size()),
            field_number_order.size(),
-           "false"  // TODO: extendable
+           "false",  // TODO: extendable
+           table_mask
     );
-
+    if (!table.empty()) {
+      output("  UPB_FASTTABLE_INIT({\n");
+      for (const auto& ent : table) {
+        output("    {0x$1, &$0},\n", ent.first,
+               absl::StrCat(absl::Hex(ent.second, absl::kZeroPad16)));
+      }
+      output("  }),\n");
+    }
     output("};\n\n");
   }
 
@@ -818,149 +947,47 @@ void WriteSource(const protobuf::FileDescriptor* file, Output& output) {
   output("\n");
 }
 
-void GenerateMessageDefAccessor(const protobuf::Descriptor* d, Output& output) {
-  output("UPB_INLINE const upb_msgdef *$0_getmsgdef(upb_symtab *s) {\n",
-         ToCIdent(d->full_name()));
-  output("  _upb_symtab_loaddefinit(s, &$0);\n", DefInitSymbol(d->file()));
-  output("  return upb_symtab_lookupmsg(s, \"$0\");\n", d->full_name());
-  output("}\n");
-  output("\n");
-
-  for (int i = 0; i < d->nested_type_count(); i++) {
-    GenerateMessageDefAccessor(d->nested_type(i), output);
-  }
-}
-
-void WriteDefHeader(const protobuf::FileDescriptor* file, Output& output) {
-  EmitFileWarning(file, output);
-
-  output(
-      "#ifndef $0_UPBDEFS_H_\n"
-      "#define $0_UPBDEFS_H_\n\n"
-      "#include \"upb/def.h\"\n"
-      "#include \"upb/port_def.inc\"\n"
-      "#ifdef __cplusplus\n"
-      "extern \"C\" {\n"
-      "#endif\n\n",
-      ToPreproc(file->name()));
-
-  output("#include \"upb/def.h\"\n");
-  output("\n");
-  output("#include \"upb/port_def.inc\"\n");
-  output("\n");
-
-  output("extern upb_def_init $0;\n", DefInitSymbol(file));
-  output("\n");
-
-  for (int i = 0; i < file->message_type_count(); i++) {
-    GenerateMessageDefAccessor(file->message_type(i), output);
-  }
-
-  output(
-      "#ifdef __cplusplus\n"
-      "}  /* extern \"C\" */\n"
-      "#endif\n"
-      "\n"
-      "#include \"upb/port_undef.inc\"\n"
-      "\n"
-      "#endif  /* $0_UPBDEFS_H_ */\n",
-      ToPreproc(file->name()));
-}
-
-// Escape C++ trigraphs by escaping question marks to \?
-std::string EscapeTrigraphs(absl::string_view to_escape) {
-  return absl::StrReplaceAll(to_escape, {{"?", "\\?"}});
-}
-
-void WriteDefSource(const protobuf::FileDescriptor* file, Output& output) {
-  EmitFileWarning(file, output);
-
-  output("#include \"upb/def.h\"\n");
-  output("#include \"$0\"\n", DefHeaderFilename(file->name()));
-  output("\n");
-
-  for (int i = 0; i < file->dependency_count(); i++) {
-    output("extern upb_def_init $0;\n", DefInitSymbol(file->dependency(i)));
-  }
-
-  std::vector<const protobuf::Descriptor*> file_messages =
-      SortedMessages(file);
-
-  for (auto message : file_messages) {
-    output("extern const upb_msglayout $0;\n", MessageInit(message));
-  }
-  output("\n");
-
-  if (!file_messages.empty()) {
-    output("static const upb_msglayout *layouts[$0] = {\n", file_messages.size());
-    for (auto message : file_messages) {
-      output("  &$0,\n", MessageInit(message));
-    }
-    output("};\n");
-    output("\n");
+class Generator : public protoc::CodeGenerator {
+  ~Generator() override {}
+  bool Generate(const protobuf::FileDescriptor* file,
+                const std::string& parameter, protoc::GeneratorContext* context,
+                std::string* error) const override;
+  uint64_t GetSupportedFeatures() const override {
+    return FEATURE_PROTO3_OPTIONAL;
   }
+};
 
-  protobuf::FileDescriptorProto file_proto;
-  file->CopyTo(&file_proto);
-  std::string file_data;
-  file_proto.SerializeToString(&file_data);
-
-  output("static const char descriptor[$0] = {", file_data.size());
-
-  // C90 only guarantees that strings can be up to 509 characters, and some
-  // implementations have limits here (for example, MSVC only allows 64k:
-  // https://docs.microsoft.com/en-us/cpp/error-messages/compiler-errors-1/fatal-error-c1091.
-  // So we always emit an array instead of a string.
-  for (size_t i = 0; i < file_data.size();) {
-    for (size_t j = 0; j < 25 && i < file_data.size(); ++i, ++j) {
-      output("'$0', ", absl::CEscape(file_data.substr(i, 1)));
+bool Generator::Generate(const protobuf::FileDescriptor* file,
+                         const std::string& parameter,
+                         protoc::GeneratorContext* context,
+                         std::string* error) const {
+  bool fasttable_enabled = false;
+  std::vector<std::pair<std::string, std::string>> params;
+  google::protobuf::compiler::ParseGeneratorParameter(parameter, &params);
+
+  for (const auto& pair : params) {
+    if (pair.first == "fasttable") {
+      fasttable_enabled = true;
+    } else {
+      *error = "Unknown parameter: " + pair.first;
+      return false;
     }
-    output("\n");
-  }
-  output("};\n\n");
-
-  output("static upb_def_init *deps[$0] = {\n", file->dependency_count() + 1);
-  for (int i = 0; i < file->dependency_count(); i++) {
-    output("  &$0,\n", DefInitSymbol(file->dependency(i)));
-  }
-  output("  NULL\n");
-  output("};\n");
-  output("\n");
-
-  output("upb_def_init $0 = {\n", DefInitSymbol(file));
-  output("  deps,\n");
-  if (file_messages.empty()) {
-    output("  NULL,\n");
-  } else {
-    output("  layouts,\n");
   }
-  output("  \"$0\",\n", file->name());
-  output("  UPB_STRVIEW_INIT(descriptor, $0)\n", file_data.size());
-  output("};\n");
-}
 
-bool Generator::Generate(const protobuf::FileDescriptor* file,
-                         const std::string& /* parameter */,
-                         protoc::GeneratorContext* context,
-                         std::string* /* error */) const {
   Output h_output(context->Open(HeaderFilename(file->name())));
   WriteHeader(file, h_output);
 
   Output c_output(context->Open(SourceFilename(file->name())));
-  WriteSource(file, c_output);
-
-  Output h_def_output(context->Open(DefHeaderFilename(file->name())));
-  WriteDefHeader(file, h_def_output);
-
-  Output c_def_output(context->Open(DefSourceFilename(file->name())));
-  WriteDefSource(file, c_def_output);
+  WriteSource(file, c_output, fasttable_enabled);
 
   return true;
 }
 
-std::unique_ptr<google::protobuf::compiler::CodeGenerator> GetGenerator() {
-  return std::unique_ptr<google::protobuf::compiler::CodeGenerator>(
-      new Generator());
-}
-
+}  // namespace
 }  // namespace upbc
+
+int main(int argc, char** argv) {
+  std::unique_ptr<google::protobuf::compiler::CodeGenerator> generator(
+      new upbc::Generator());
+  return google::protobuf::compiler::PluginMain(argc, argv, generator.get());
+}
diff --git a/third_party/upb/upbc/protoc-gen-upbdefs.cc b/third_party/upb/upbc/protoc-gen-upbdefs.cc
new file mode 100644 (file)
index 0000000..f51ae07
--- /dev/null
@@ -0,0 +1,183 @@
+
+#include <memory>
+
+#include "google/protobuf/compiler/code_generator.h"
+#include "google/protobuf/compiler/plugin.h"
+#include "google/protobuf/descriptor.h"
+#include "google/protobuf/descriptor.pb.h"
+#include "upbc/common.h"
+
+namespace upbc {
+namespace {
+
+namespace protoc = ::google::protobuf::compiler;
+namespace protobuf = ::google::protobuf;
+
+std::string DefInitSymbol(const protobuf::FileDescriptor *file) {
+  return ToCIdent(file->name()) + "_upbdefinit";
+}
+
+static std::string DefHeaderFilename(std::string proto_filename) {
+  return StripExtension(proto_filename) + ".upbdefs.h";
+}
+
+static std::string DefSourceFilename(std::string proto_filename) {
+  return StripExtension(proto_filename) + ".upbdefs.c";
+}
+
+void GenerateMessageDefAccessor(const protobuf::Descriptor* d, Output& output) {
+  output("UPB_INLINE const upb_msgdef *$0_getmsgdef(upb_symtab *s) {\n",
+         ToCIdent(d->full_name()));
+  output("  _upb_symtab_loaddefinit(s, &$0);\n", DefInitSymbol(d->file()));
+  output("  return upb_symtab_lookupmsg(s, \"$0\");\n", d->full_name());
+  output("}\n");
+  output("\n");
+
+  for (int i = 0; i < d->nested_type_count(); i++) {
+    GenerateMessageDefAccessor(d->nested_type(i), output);
+  }
+}
+
+void WriteDefHeader(const protobuf::FileDescriptor* file, Output& output) {
+  EmitFileWarning(file, output);
+
+  output(
+      "#ifndef $0_UPBDEFS_H_\n"
+      "#define $0_UPBDEFS_H_\n\n"
+      "#include \"upb/def.h\"\n"
+      "#include \"upb/port_def.inc\"\n"
+      "#ifdef __cplusplus\n"
+      "extern \"C\" {\n"
+      "#endif\n\n",
+      ToPreproc(file->name()));
+
+  output("#include \"upb/def.h\"\n");
+  output("\n");
+  output("#include \"upb/port_def.inc\"\n");
+  output("\n");
+
+  output("extern upb_def_init $0;\n", DefInitSymbol(file));
+  output("\n");
+
+  for (int i = 0; i < file->message_type_count(); i++) {
+    GenerateMessageDefAccessor(file->message_type(i), output);
+  }
+
+  output(
+      "#ifdef __cplusplus\n"
+      "}  /* extern \"C\" */\n"
+      "#endif\n"
+      "\n"
+      "#include \"upb/port_undef.inc\"\n"
+      "\n"
+      "#endif  /* $0_UPBDEFS_H_ */\n",
+      ToPreproc(file->name()));
+}
+
+
+void WriteDefSource(const protobuf::FileDescriptor* file, Output& output) {
+  EmitFileWarning(file, output);
+
+  output("#include \"upb/def.h\"\n");
+  output("#include \"$0\"\n", DefHeaderFilename(file->name()));
+  output("\n");
+
+  for (int i = 0; i < file->dependency_count(); i++) {
+    output("extern upb_def_init $0;\n", DefInitSymbol(file->dependency(i)));
+  }
+
+  std::vector<const protobuf::Descriptor*> file_messages =
+      SortedMessages(file);
+
+  for (auto message : file_messages) {
+    output("extern const upb_msglayout $0;\n", MessageInit(message));
+  }
+  output("\n");
+
+  if (!file_messages.empty()) {
+    output("static const upb_msglayout *layouts[$0] = {\n", file_messages.size());
+    for (auto message : file_messages) {
+      output("  &$0,\n", MessageInit(message));
+    }
+    output("};\n");
+    output("\n");
+  }
+
+  protobuf::FileDescriptorProto file_proto;
+  file->CopyTo(&file_proto);
+  std::string file_data;
+  file_proto.SerializeToString(&file_data);
+
+  output("static const char descriptor[$0] = {", file_data.size());
+
+  // C90 only guarantees that strings can be up to 509 characters, and some
+  // implementations have limits here (for example, MSVC only allows 64k:
+  // https://docs.microsoft.com/en-us/cpp/error-messages/compiler-errors-1/fatal-error-c1091.
+  // So we always emit an array instead of a string.
+  for (size_t i = 0; i < file_data.size();) {
+    for (size_t j = 0; j < 25 && i < file_data.size(); ++i, ++j) {
+      output("'$0', ", absl::CEscape(file_data.substr(i, 1)));
+    }
+    output("\n");
+  }
+  output("};\n\n");
+
+  output("static upb_def_init *deps[$0] = {\n", file->dependency_count() + 1);
+  for (int i = 0; i < file->dependency_count(); i++) {
+    output("  &$0,\n", DefInitSymbol(file->dependency(i)));
+  }
+  output("  NULL\n");
+  output("};\n");
+  output("\n");
+
+  output("upb_def_init $0 = {\n", DefInitSymbol(file));
+  output("  deps,\n");
+  if (file_messages.empty()) {
+    output("  NULL,\n");
+  } else {
+    output("  layouts,\n");
+  }
+  output("  \"$0\",\n", file->name());
+  output("  UPB_STRVIEW_INIT(descriptor, $0)\n", file_data.size());
+  output("};\n");
+}
+
+class Generator : public protoc::CodeGenerator {
+  ~Generator() override {}
+  bool Generate(const protobuf::FileDescriptor* file,
+                const std::string& parameter, protoc::GeneratorContext* context,
+                std::string* error) const override;
+  uint64_t GetSupportedFeatures() const override {
+    return FEATURE_PROTO3_OPTIONAL;
+  }
+};
+
+bool Generator::Generate(const protobuf::FileDescriptor* file,
+                         const std::string& parameter,
+                         protoc::GeneratorContext* context,
+                         std::string* error) const {
+  std::vector<std::pair<std::string, std::string>> params;
+  google::protobuf::compiler::ParseGeneratorParameter(parameter, &params);
+
+  for (const auto& pair : params) {
+    *error = "Unknown parameter: " + pair.first;
+    return false;
+  }
+
+  Output h_def_output(context->Open(DefHeaderFilename(file->name())));
+  WriteDefHeader(file, h_def_output);
+
+  Output c_def_output(context->Open(DefSourceFilename(file->name())));
+  WriteDefSource(file, c_def_output);
+
+  return true;
+}
+
+}  // namespace
+}  // namespace upbc
+
+int main(int argc, char** argv) {
+  std::unique_ptr<google::protobuf::compiler::CodeGenerator> generator(
+      new upbc::Generator());
+  return google::protobuf::compiler::PluginMain(argc, argv, generator.get());
+}
index 8383bb2..80633cc 100755 (executable)
@@ -40,7 +40,9 @@ then
   fi
 fi
 
-VERSION=2.2.0
+# IMPORTANT: if you update the version here, other parts of infrastructure might needs updating as well
+# (e.g. win RBE builds, sanity checks, bazel toolchains etc.)
+VERSION=3.7.1
 echo "INFO: Running bazel wrapper (see //tools/bazel for details), bazel version $VERSION will be used instead of system-wide bazel installation." >&2
 
 # update tools/update_mirror.sh to populate the mirror with new bazel archives
index cda6f71..b044cb7 100755 (executable)
@@ -1,4 +1,4 @@
-#!/usr/bin/env python2.7
+#!/usr/bin/env python3
 # Copyright 2015 gRPC authors.
 #
 # Licensed under the Apache License, Version 2.0 (the "License");
@@ -83,7 +83,7 @@ def cleaned_build_yaml_dict_as_string(indict):
 if __name__ == '__main__':
     for filename in sys.argv[1:]:
         with open(filename) as f:
-            js = yaml.load(f)
+            js = yaml.load(f, Loader=yaml.FullLoader)
         output = cleaned_build_yaml_dict_as_string(js)
         if TEST:
             with open(filename) as f:
index 9ad9878..0ed9b1e 100755 (executable)
@@ -25,8 +25,7 @@ gen_build_yaml_dirs="  \
   src/zlib             \
   src/c-ares           \
   test/core/end2end    \
-  test/cpp/naming      \
-  tools/run_tests/lb_interop_tests"
+  test/cpp/naming"
 
 
 gen_build_files=""
index 81c1615..9b5c0f5 100755 (executable)
@@ -18,6 +18,9 @@ set -e
 
 export TEST=${TEST:-false}
 
+# Upgrade Python's YAML library
+python3 -m pip install --upgrade --ignore-installed PyYAML --user
+
 echo "Generating build_autogenerated.yaml from bazel BUILD file"
 rm -f build_autogenerated.yaml
 python3 tools/buildgen/extract_metadata_from_bazel_xml.py
index f0202cd..06ee30f 100755 (executable)
 """Simple Mako renderer.
 
 Just a wrapper around the mako rendering library.
-
 """
 
 import getopt
-import imp
+import importlib.util
 import os
 import pickle
 import shutil
 import sys
 
+import yaml
 from mako.lookup import TemplateLookup
 from mako.runtime import Context
 from mako.template import Template
+
 import bunch
-import yaml
 
 
 # Imports a plugin
-def import_plugin(name):
-    _, base_ex = os.path.split(name)
-    base, _ = os.path.splitext(base_ex)
-    return imp.load_source(base, name)
+def import_plugin(path):
+    module_name = os.path.basename(path).replace('.py', '')
+    spec = importlib.util.spec_from_file_location(module_name, path)
+    module = importlib.util.module_from_spec(spec)
+    sys.modules[module_name] = module
+    spec.loader.exec_module(module)
+    return module
 
 
 def out(msg):
@@ -104,7 +107,9 @@ def main(argv):
         elif opt == '-d':
             assert not got_preprocessed_input
             with open(arg, 'r') as dict_file:
-                bunch.merge_json(json_dict, yaml.load(dict_file.read()))
+                bunch.merge_json(
+                    json_dict,
+                    yaml.load(dict_file.read(), Loader=yaml.FullLoader))
         elif opt == '-p':
             plugins.append(import_plugin(arg))
         elif opt == '-w':
@@ -127,7 +132,7 @@ def main(argv):
     for arg in args:
         got_input = True
         with open(arg) as f:
-            srcs = list(yaml.load_all(f.read()))
+            srcs = list(yaml.load_all(f.read(), Loader=yaml.FullLoader))
         for src in srcs:
             if isinstance(src, str):
                 assert len(srcs) == 1
index 26e11bc..7958dd4 100755 (executable)
@@ -127,3 +127,5 @@ def mako_plugin(dictionary):
         else:
             settings[version_tag] = Version(version_str,
                                             override_major=override_major)
+    settings['protobuf_major_minor_version'] = ('.'.join(
+        settings['protobuf_version'].split('.')[:2]))
index 4d3a38c..08cc139 100755 (executable)
@@ -637,7 +637,7 @@ static uint32_t %(name)s_phash(uint32_t i) {
   uint32_t y = i / %(t)d;
   uint32_t h = x;
   if (y < GPR_ARRAY_SIZE(%(name)s_r)) {
-    uint32_t delta = (uint32_t)%(name)s_r[y];
+    uint32_t delta = static_cast<uint32_t>(%(name)s_r[y]);
     h += delta;
   }
   return h;
index 49f6a6d..b4f7688 100755 (executable)
@@ -25,17 +25,22 @@ if [ $# -eq 0 ]; then
   rm -rf $UPB_OUTPUT_DIR
   rm -rf $UPBDEFS_OUTPUT_DIR
   mkdir -p $UPB_OUTPUT_DIR
+  mkdir -p $UPBDEFS_OUTPUT_DIR
 else
   UPB_OUTPUT_DIR=$1/upb-generated
   UPBDEFS_OUTPUT_DIR=$1/upbdefs-generated
   mkdir $UPB_OUTPUT_DIR
+  mkdir $UPBDEFS_OUTPUT_DIR
 fi
 
 $bazel build @com_google_protobuf//:protoc
 PROTOC=$PWD/bazel-bin/external/com_google_protobuf/protoc
 
-$bazel build @upb//:protoc-gen-upb
-UPB_PLUGIN=$PWD/bazel-bin/external/upb/protoc-gen-upb
+$bazel build @upb//upbc:protoc-gen-upb
+UPB_PLUGIN=$PWD/bazel-bin/external/upb/upbc/protoc-gen-upb
+
+$bazel build @upb//upbc:protoc-gen-upbdefs
+UPBDEFS_PLUGIN=$PWD/bazel-bin/external/upb/upbc/protoc-gen-upbdefs
 
 proto_files=( \
   "envoy/annotations/deprecation.proto" \
@@ -127,32 +132,27 @@ proto_files=( \
   "udpa/core/v1/resource.proto" \
   "validate/validate.proto")
 
+INCLUDE_OPTIONS="-I=$PWD/third_party/udpa \
+  -I=$PWD/third_party/envoy-api \
+  -I=$PWD/third_party/googleapis \
+  -I=$PWD/third_party/protobuf/src \
+  -I=$PWD/third_party/protoc-gen-validate \
+  -I=$PWD"
+
 for i in "${proto_files[@]}"
 do
   echo "Compiling: ${i}"
   $PROTOC \
-    -I=$PWD/third_party/udpa \
-    -I=$PWD/third_party/envoy-api \
-    -I=$PWD/third_party/googleapis \
-    -I=$PWD/third_party/protobuf/src \
-    -I=$PWD/third_party/protoc-gen-validate \
-    -I=$PWD \
+    $INCLUDE_OPTIONS \
     $i \
     --upb_out=$UPB_OUTPUT_DIR \
     --plugin=protoc-gen-upb=$UPB_PLUGIN
+  # In PHP build Makefile, the files with .upb.c suffix collide .upbdefs.c suffix due to a PHP buildsystem bug.
+  # Work around this by placing the generated files with ".upbdefs.h" and ".upbdefs.c" suffix under a different directory.
+  # See https://github.com/grpc/grpc/issues/23307
+  $PROTOC \
+    $INCLUDE_OPTIONS \
+    $i \
+    --upb_out=$UPBDEFS_OUTPUT_DIR \
+    --plugin=protoc-gen-upb=$UPBDEFS_PLUGIN    
 done
-
-# In PHP build Makefile, the files with .upb.c suffix collide .upbdefs.c suffix due to a PHP buildsystem bug.
-# Work around this by placing the generated files with ".upbdefs.h" and ".upbdefs.c" suffix under a different directory.
-# See https://github.com/grpc/grpc/issues/23307
-
-# move all .upbdefs.h and .upbdefs.c files from under src/core/ext/upb-generated to src/core/ext/upbdefs-generated
-cp -r $UPB_OUTPUT_DIR $UPBDEFS_OUTPUT_DIR
-
-# remove files that don't belong under upb-generated
-find $UPB_OUTPUT_DIR -name "*.upbdefs.c" -type f -delete
-find $UPB_OUTPUT_DIR -name "*.upbdefs.h" -type f -delete
-
-# remove files that don't belong under upbdefs-generated
-find $UPBDEFS_OUTPUT_DIR -name "*.upb.h" -type f -delete
-find $UPBDEFS_OUTPUT_DIR -name "*.upb.c" -type f -delete
index 9737828..905725d 100755 (executable)
@@ -1,4 +1,4 @@
-#!/usr/bin/env python2.7
+#!/usr/bin/env python3
 
 # Copyright 2015 gRPC authors.
 #
@@ -14,7 +14,6 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-from __future__ import print_function
 import argparse
 import datetime
 import os
@@ -107,7 +106,7 @@ RE_LICENSE = dict(
     (k, r'\n'.join(LICENSE_PREFIX[k] +
                    (RE_YEAR if re.search(RE_YEAR, line) else re.escape(line))
                    for line in LICENSE_NOTICE))
-    for k, v in LICENSE_PREFIX.iteritems())
+    for k, v in LICENSE_PREFIX.items())
 
 if args.precommit:
     FILE_LIST_COMMAND = 'git status -z | grep -Poz \'(?<=^[MARC][MARCD ] )[^\s]+\''
@@ -143,7 +142,7 @@ ok = True
 filename_list = []
 try:
     filename_list = subprocess.check_output(FILE_LIST_COMMAND,
-                                            shell=True).splitlines()
+                                            shell=True).decode().splitlines()
 except subprocess.CalledProcessError:
     sys.exit(0)
 
index 0d37290..91fe46e 100755 (executable)
@@ -1,4 +1,4 @@
-#!/usr/bin/env python2.7
+#!/usr/bin/env python3
 
 # Copyright 2016 gRPC authors.
 #
@@ -14,7 +14,6 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-from __future__ import print_function
 import argparse
 import os
 import os.path
@@ -177,7 +176,7 @@ ok = True
 filename_list = []
 try:
     filename_list = subprocess.check_output(FILE_LIST_COMMAND,
-                                            shell=True).splitlines()
+                                            shell=True).decode().splitlines()
     # Filter out non-existent files (ie, file removed or renamed)
     filename_list = (f for f in filename_list if os.path.isfile(f))
 except subprocess.CalledProcessError:
index 4c97607..d4ca1bc 100644 (file)
@@ -14,4 +14,5 @@
 
 # AUTO-GENERATED FROM `$REPO_ROOT/templates/tools/distrib/python/grpcio_tools/grpc_version.py.template`!!!
 
-VERSION = '1.34.1'
+VERSION = '1.35.0'
+PROTOBUF_VERSION = '3.14.0'
index 9304f1e..3aab128 100644 (file)
@@ -14,4 +14,5 @@
 
 # AUTO-GENERATED FROM `$REPO_ROOT/templates/tools/distrib/python/grpcio_tools/grpc_version.py.template`!!!
 
-VERSION = '1.34.1'
+VERSION = '1.35.0'
+PROTOBUF_VERSION = '3.14.0'
index f9c3cab..2851f9e 100644 (file)
 # limitations under the License.
 
 # AUTO-GENERATED BY make_grpcio_tools.py!
-CC_FILES=['google/protobuf/compiler/zip_writer.cc', 'google/protobuf/compiler/subprocess.cc', 'google/protobuf/compiler/ruby/ruby_generator.cc', 'google/protobuf/compiler/python/python_generator.cc', 'google/protobuf/compiler/plugin.pb.cc', 'google/protobuf/compiler/plugin.cc', 'google/protobuf/compiler/php/php_generator.cc', 'google/protobuf/compiler/objectivec/objectivec_primitive_field.cc', 'google/protobuf/compiler/objectivec/objectivec_oneof.cc', 'google/protobuf/compiler/objectivec/objectivec_message_field.cc', 'google/protobuf/compiler/objectivec/objectivec_message.cc', 'google/protobuf/compiler/objectivec/objectivec_map_field.cc', 'google/protobuf/compiler/objectivec/objectivec_helpers.cc', 'google/protobuf/compiler/objectivec/objectivec_generator.cc', 'google/protobuf/compiler/objectivec/objectivec_file.cc', 'google/protobuf/compiler/objectivec/objectivec_field.cc', 'google/protobuf/compiler/objectivec/objectivec_extension.cc', 'google/protobuf/compiler/objectivec/objectivec_enum_field.cc', 'google/protobuf/compiler/objectivec/objectivec_enum.cc', 'google/protobuf/compiler/js/well_known_types_embed.cc', 'google/protobuf/compiler/js/js_generator.cc', 'google/protobuf/compiler/java/java_string_field_lite.cc', 'google/protobuf/compiler/java/java_string_field.cc', 'google/protobuf/compiler/java/java_shared_code_generator.cc', 'google/protobuf/compiler/java/java_service.cc', 'google/protobuf/compiler/java/java_primitive_field_lite.cc', 'google/protobuf/compiler/java/java_primitive_field.cc', 'google/protobuf/compiler/java/java_name_resolver.cc', 'google/protobuf/compiler/java/java_message_lite.cc', 'google/protobuf/compiler/java/java_message_field_lite.cc', 'google/protobuf/compiler/java/java_message_field.cc', 'google/protobuf/compiler/java/java_message_builder_lite.cc', 'google/protobuf/compiler/java/java_message_builder.cc', 'google/protobuf/compiler/java/java_message.cc', 'google/protobuf/compiler/java/java_map_field_lite.cc', 'google/protobuf/compiler/java/java_map_field.cc', 'google/protobuf/compiler/java/java_helpers.cc', 'google/protobuf/compiler/java/java_generator_factory.cc', 'google/protobuf/compiler/java/java_generator.cc', 'google/protobuf/compiler/java/java_file.cc', 'google/protobuf/compiler/java/java_field.cc', 'google/protobuf/compiler/java/java_extension_lite.cc', 'google/protobuf/compiler/java/java_extension.cc', 'google/protobuf/compiler/java/java_enum_lite.cc', 'google/protobuf/compiler/java/java_enum_field_lite.cc', 'google/protobuf/compiler/java/java_enum_field.cc', 'google/protobuf/compiler/java/java_enum.cc', 'google/protobuf/compiler/java/java_doc_comment.cc', 'google/protobuf/compiler/java/java_context.cc', 'google/protobuf/compiler/csharp/csharp_wrapper_field.cc', 'google/protobuf/compiler/csharp/csharp_source_generator_base.cc', 'google/protobuf/compiler/csharp/csharp_repeated_primitive_field.cc', 'google/protobuf/compiler/csharp/csharp_repeated_message_field.cc', 'google/protobuf/compiler/csharp/csharp_repeated_enum_field.cc', 'google/protobuf/compiler/csharp/csharp_reflection_class.cc', 'google/protobuf/compiler/csharp/csharp_primitive_field.cc', 'google/protobuf/compiler/csharp/csharp_message_field.cc', 'google/protobuf/compiler/csharp/csharp_message.cc', 'google/protobuf/compiler/csharp/csharp_map_field.cc', 'google/protobuf/compiler/csharp/csharp_helpers.cc', 'google/protobuf/compiler/csharp/csharp_generator.cc', 'google/protobuf/compiler/csharp/csharp_field_base.cc', 'google/protobuf/compiler/csharp/csharp_enum_field.cc', 'google/protobuf/compiler/csharp/csharp_enum.cc', 'google/protobuf/compiler/csharp/csharp_doc_comment.cc', 'google/protobuf/compiler/cpp/cpp_string_field.cc', 'google/protobuf/compiler/cpp/cpp_service.cc', 'google/protobuf/compiler/cpp/cpp_primitive_field.cc', 'google/protobuf/compiler/cpp/cpp_padding_optimizer.cc', 'google/protobuf/compiler/cpp/cpp_message_field.cc', 'google/protobuf/compiler/cpp/cpp_message.cc', 'google/protobuf/compiler/cpp/cpp_map_field.cc', 'google/protobuf/compiler/cpp/cpp_helpers.cc', 'google/protobuf/compiler/cpp/cpp_generator.cc', 'google/protobuf/compiler/cpp/cpp_file.cc', 'google/protobuf/compiler/cpp/cpp_field.cc', 'google/protobuf/compiler/cpp/cpp_extension.cc', 'google/protobuf/compiler/cpp/cpp_enum_field.cc', 'google/protobuf/compiler/cpp/cpp_enum.cc', 'google/protobuf/compiler/command_line_interface.cc', 'google/protobuf/compiler/code_generator.cc', 'google/protobuf/wrappers.pb.cc', 'google/protobuf/wire_format.cc', 'google/protobuf/util/type_resolver_util.cc', 'google/protobuf/util/time_util.cc', 'google/protobuf/util/message_differencer.cc', 'google/protobuf/util/json_util.cc', 'google/protobuf/util/internal/utility.cc', 'google/protobuf/util/internal/type_info_test_helper.cc', 'google/protobuf/util/internal/type_info.cc', 'google/protobuf/util/internal/protostream_objectwriter.cc', 'google/protobuf/util/internal/protostream_objectsource.cc', 'google/protobuf/util/internal/proto_writer.cc', 'google/protobuf/util/internal/object_writer.cc', 'google/protobuf/util/internal/json_stream_parser.cc', 'google/protobuf/util/internal/json_objectwriter.cc', 'google/protobuf/util/internal/json_escaping.cc', 'google/protobuf/util/internal/field_mask_utility.cc', 'google/protobuf/util/internal/error_listener.cc', 'google/protobuf/util/internal/default_value_objectwriter.cc', 'google/protobuf/util/internal/datapiece.cc', 'google/protobuf/util/field_mask_util.cc', 'google/protobuf/util/field_comparator.cc', 'google/protobuf/util/delimited_message_util.cc', 'google/protobuf/unknown_field_set.cc', 'google/protobuf/type.pb.cc', 'google/protobuf/timestamp.pb.cc', 'google/protobuf/text_format.cc', 'google/protobuf/stubs/substitute.cc', 'google/protobuf/struct.pb.cc', 'google/protobuf/source_context.pb.cc', 'google/protobuf/service.cc', 'google/protobuf/reflection_ops.cc', 'google/protobuf/message.cc', 'google/protobuf/map_field.cc', 'google/protobuf/io/tokenizer.cc', 'google/protobuf/io/printer.cc', 'google/protobuf/io/gzip_stream.cc', 'google/protobuf/generated_message_table_driven.cc', 'google/protobuf/generated_message_reflection.cc', 'google/protobuf/field_mask.pb.cc', 'google/protobuf/extension_set_heavy.cc', 'google/protobuf/empty.pb.cc', 'google/protobuf/dynamic_message.cc', 'google/protobuf/duration.pb.cc', 'google/protobuf/descriptor_database.cc', 'google/protobuf/descriptor.pb.cc', 'google/protobuf/descriptor.cc', 'google/protobuf/compiler/parser.cc', 'google/protobuf/compiler/importer.cc', 'google/protobuf/api.pb.cc', 'google/protobuf/any.pb.cc', 'google/protobuf/any.cc', 'google/protobuf/wire_format_lite.cc', 'google/protobuf/stubs/time.cc', 'google/protobuf/stubs/strutil.cc', 'google/protobuf/stubs/structurally_valid.cc', 'google/protobuf/stubs/stringprintf.cc', 'google/protobuf/stubs/stringpiece.cc', 'google/protobuf/stubs/statusor.cc', 'google/protobuf/stubs/status.cc', 'google/protobuf/stubs/int128.cc', 'google/protobuf/stubs/common.cc', 'google/protobuf/stubs/bytestream.cc', 'google/protobuf/repeated_field.cc', 'google/protobuf/parse_context.cc', 'google/protobuf/message_lite.cc', 'google/protobuf/io/zero_copy_stream_impl_lite.cc', 'google/protobuf/io/zero_copy_stream_impl.cc', 'google/protobuf/io/zero_copy_stream.cc', 'google/protobuf/io/strtod.cc', 'google/protobuf/io/io_win32.cc', 'google/protobuf/io/coded_stream.cc', 'google/protobuf/implicit_weak_message.cc', 'google/protobuf/generated_message_util.cc', 'google/protobuf/generated_message_table_driven_lite.cc', 'google/protobuf/generated_enum_util.cc', 'google/protobuf/extension_set.cc', 'google/protobuf/arena.cc', 'google/protobuf/any_lite.cc']
+CC_FILES=['google/protobuf/compiler/zip_writer.cc', 'google/protobuf/compiler/subprocess.cc', 'google/protobuf/compiler/ruby/ruby_generator.cc', 'google/protobuf/compiler/python/python_generator.cc', 'google/protobuf/compiler/plugin.pb.cc', 'google/protobuf/compiler/plugin.cc', 'google/protobuf/compiler/php/php_generator.cc', 'google/protobuf/compiler/objectivec/objectivec_primitive_field.cc', 'google/protobuf/compiler/objectivec/objectivec_oneof.cc', 'google/protobuf/compiler/objectivec/objectivec_message_field.cc', 'google/protobuf/compiler/objectivec/objectivec_message.cc', 'google/protobuf/compiler/objectivec/objectivec_map_field.cc', 'google/protobuf/compiler/objectivec/objectivec_helpers.cc', 'google/protobuf/compiler/objectivec/objectivec_generator.cc', 'google/protobuf/compiler/objectivec/objectivec_file.cc', 'google/protobuf/compiler/objectivec/objectivec_field.cc', 'google/protobuf/compiler/objectivec/objectivec_extension.cc', 'google/protobuf/compiler/objectivec/objectivec_enum_field.cc', 'google/protobuf/compiler/objectivec/objectivec_enum.cc', 'google/protobuf/compiler/js/well_known_types_embed.cc', 'google/protobuf/compiler/js/js_generator.cc', 'google/protobuf/compiler/java/java_string_field_lite.cc', 'google/protobuf/compiler/java/java_string_field.cc', 'google/protobuf/compiler/java/java_shared_code_generator.cc', 'google/protobuf/compiler/java/java_service.cc', 'google/protobuf/compiler/java/java_primitive_field_lite.cc', 'google/protobuf/compiler/java/java_primitive_field.cc', 'google/protobuf/compiler/java/java_name_resolver.cc', 'google/protobuf/compiler/java/java_message_lite.cc', 'google/protobuf/compiler/java/java_message_field_lite.cc', 'google/protobuf/compiler/java/java_message_field.cc', 'google/protobuf/compiler/java/java_message_builder_lite.cc', 'google/protobuf/compiler/java/java_message_builder.cc', 'google/protobuf/compiler/java/java_message.cc', 'google/protobuf/compiler/java/java_map_field_lite.cc', 'google/protobuf/compiler/java/java_map_field.cc', 'google/protobuf/compiler/java/java_helpers.cc', 'google/protobuf/compiler/java/java_generator_factory.cc', 'google/protobuf/compiler/java/java_generator.cc', 'google/protobuf/compiler/java/java_file.cc', 'google/protobuf/compiler/java/java_field.cc', 'google/protobuf/compiler/java/java_extension_lite.cc', 'google/protobuf/compiler/java/java_extension.cc', 'google/protobuf/compiler/java/java_enum_lite.cc', 'google/protobuf/compiler/java/java_enum_field_lite.cc', 'google/protobuf/compiler/java/java_enum_field.cc', 'google/protobuf/compiler/java/java_enum.cc', 'google/protobuf/compiler/java/java_doc_comment.cc', 'google/protobuf/compiler/java/java_context.cc', 'google/protobuf/compiler/csharp/csharp_wrapper_field.cc', 'google/protobuf/compiler/csharp/csharp_source_generator_base.cc', 'google/protobuf/compiler/csharp/csharp_repeated_primitive_field.cc', 'google/protobuf/compiler/csharp/csharp_repeated_message_field.cc', 'google/protobuf/compiler/csharp/csharp_repeated_enum_field.cc', 'google/protobuf/compiler/csharp/csharp_reflection_class.cc', 'google/protobuf/compiler/csharp/csharp_primitive_field.cc', 'google/protobuf/compiler/csharp/csharp_message_field.cc', 'google/protobuf/compiler/csharp/csharp_message.cc', 'google/protobuf/compiler/csharp/csharp_map_field.cc', 'google/protobuf/compiler/csharp/csharp_helpers.cc', 'google/protobuf/compiler/csharp/csharp_generator.cc', 'google/protobuf/compiler/csharp/csharp_field_base.cc', 'google/protobuf/compiler/csharp/csharp_enum_field.cc', 'google/protobuf/compiler/csharp/csharp_enum.cc', 'google/protobuf/compiler/csharp/csharp_doc_comment.cc', 'google/protobuf/compiler/cpp/cpp_string_field.cc', 'google/protobuf/compiler/cpp/cpp_service.cc', 'google/protobuf/compiler/cpp/cpp_primitive_field.cc', 'google/protobuf/compiler/cpp/cpp_padding_optimizer.cc', 'google/protobuf/compiler/cpp/cpp_message_field.cc', 'google/protobuf/compiler/cpp/cpp_message.cc', 'google/protobuf/compiler/cpp/cpp_map_field.cc', 'google/protobuf/compiler/cpp/cpp_helpers.cc', 'google/protobuf/compiler/cpp/cpp_generator.cc', 'google/protobuf/compiler/cpp/cpp_file.cc', 'google/protobuf/compiler/cpp/cpp_field.cc', 'google/protobuf/compiler/cpp/cpp_extension.cc', 'google/protobuf/compiler/cpp/cpp_enum_field.cc', 'google/protobuf/compiler/cpp/cpp_enum.cc', 'google/protobuf/compiler/command_line_interface.cc', 'google/protobuf/compiler/code_generator.cc', 'google/protobuf/wrappers.pb.cc', 'google/protobuf/wire_format.cc', 'google/protobuf/util/type_resolver_util.cc', 'google/protobuf/util/time_util.cc', 'google/protobuf/util/message_differencer.cc', 'google/protobuf/util/json_util.cc', 'google/protobuf/util/internal/utility.cc', 'google/protobuf/util/internal/type_info_test_helper.cc', 'google/protobuf/util/internal/type_info.cc', 'google/protobuf/util/internal/protostream_objectwriter.cc', 'google/protobuf/util/internal/protostream_objectsource.cc', 'google/protobuf/util/internal/proto_writer.cc', 'google/protobuf/util/internal/object_writer.cc', 'google/protobuf/util/internal/json_stream_parser.cc', 'google/protobuf/util/internal/json_objectwriter.cc', 'google/protobuf/util/internal/json_escaping.cc', 'google/protobuf/util/internal/field_mask_utility.cc', 'google/protobuf/util/internal/error_listener.cc', 'google/protobuf/util/internal/default_value_objectwriter.cc', 'google/protobuf/util/internal/datapiece.cc', 'google/protobuf/util/field_mask_util.cc', 'google/protobuf/util/field_comparator.cc', 'google/protobuf/util/delimited_message_util.cc', 'google/protobuf/unknown_field_set.cc', 'google/protobuf/type.pb.cc', 'google/protobuf/timestamp.pb.cc', 'google/protobuf/text_format.cc', 'google/protobuf/stubs/substitute.cc', 'google/protobuf/struct.pb.cc', 'google/protobuf/source_context.pb.cc', 'google/protobuf/service.cc', 'google/protobuf/reflection_ops.cc', 'google/protobuf/message.cc', 'google/protobuf/map_field.cc', 'google/protobuf/io/tokenizer.cc', 'google/protobuf/io/printer.cc', 'google/protobuf/io/gzip_stream.cc', 'google/protobuf/generated_message_table_driven.cc', 'google/protobuf/generated_message_reflection.cc', 'google/protobuf/field_mask.pb.cc', 'google/protobuf/extension_set_heavy.cc', 'google/protobuf/empty.pb.cc', 'google/protobuf/dynamic_message.cc', 'google/protobuf/duration.pb.cc', 'google/protobuf/descriptor_database.cc', 'google/protobuf/descriptor.pb.cc', 'google/protobuf/descriptor.cc', 'google/protobuf/compiler/parser.cc', 'google/protobuf/compiler/importer.cc', 'google/protobuf/api.pb.cc', 'google/protobuf/any.pb.cc', 'google/protobuf/any.cc', 'google/protobuf/wire_format_lite.cc', 'google/protobuf/stubs/time.cc', 'google/protobuf/stubs/strutil.cc', 'google/protobuf/stubs/structurally_valid.cc', 'google/protobuf/stubs/stringprintf.cc', 'google/protobuf/stubs/stringpiece.cc', 'google/protobuf/stubs/statusor.cc', 'google/protobuf/stubs/status.cc', 'google/protobuf/stubs/int128.cc', 'google/protobuf/stubs/common.cc', 'google/protobuf/stubs/bytestream.cc', 'google/protobuf/repeated_field.cc', 'google/protobuf/parse_context.cc', 'google/protobuf/message_lite.cc', 'google/protobuf/map.cc', 'google/protobuf/io/zero_copy_stream_impl_lite.cc', 'google/protobuf/io/zero_copy_stream_impl.cc', 'google/protobuf/io/zero_copy_stream.cc', 'google/protobuf/io/strtod.cc', 'google/protobuf/io/io_win32.cc', 'google/protobuf/io/coded_stream.cc', 'google/protobuf/implicit_weak_message.cc', 'google/protobuf/generated_message_util.cc', 'google/protobuf/generated_message_table_driven_lite.cc', 'google/protobuf/generated_enum_util.cc', 'google/protobuf/extension_set.cc', 'google/protobuf/arenastring.cc', 'google/protobuf/arena.cc', 'google/protobuf/any_lite.cc']
 PROTO_FILES=['google/protobuf/wrappers.proto', 'google/protobuf/type.proto', 'google/protobuf/timestamp.proto', 'google/protobuf/struct.proto', 'google/protobuf/source_context.proto', 'google/protobuf/field_mask.proto', 'google/protobuf/empty.proto', 'google/protobuf/duration.proto', 'google/protobuf/descriptor.proto', 'google/protobuf/compiler/plugin.proto', 'google/protobuf/api.proto', 'google/protobuf/any.proto']
 
 CC_INCLUDE='third_party/protobuf/src'
 PROTO_INCLUDE='third_party/protobuf/src'
 
-PROTOBUF_SUBMODULE_VERSION="fde7cf7358ec7cd69e8db9be4f1fa6a5c431386a"
+PROTOBUF_SUBMODULE_VERSION="19fb89416f3fdc2d6668f3738f444885575285bc"
index 7a5c438..b35fc17 100755 (executable)
@@ -23,15 +23,15 @@ def docker_image_for_rake_compiler(platform)
   dockerfile = File.join(grpc_root, 'third_party', 'rake-compiler-dock', 'rake_' + platform, 'Dockerfile')
   dockerpath = File.dirname(dockerfile)
   version = Digest::SHA1.file(dockerfile).hexdigest
-  image_name = 'rake_' + platform + '_' + version
+  image_name = 'rake_' + platform + ':' + version
   ENV.fetch('DOCKERHUB_ORGANIZATION', 'grpctesting') + '/' + image_name
 end
 
 def run_rake_compiler(platform, args)
   require 'rake_compiler_dock'
 
-  options = { :rubyvm => 'mri', :platform => platform }
-  options[:runas] = false if platform =~ /linux/
+  ENV['RCD_RUBYVM'] = 'mri'
+  ENV['RCD_PLATFORM'] = platform
   ENV['RCD_IMAGE'] = docker_image_for_rake_compiler(platform)
-  RakeCompilerDock.sh args, options
+  RakeCompilerDock.sh args
 end
index 9af6c8f..345dd00 100755 (executable)
@@ -60,5 +60,5 @@ for filename in args.files:
             timeout_seconds=15 * 60,
         ))
 
-num_fails, res_set = jobset.run(jobs, maxjobs=args.jobs)
+num_fails, res_set = jobset.run(jobs, maxjobs=args.jobs, quiet_success=True)
 sys.exit(num_fails)
@@ -1,4 +1,4 @@
-# Copyright 2015 gRPC authors.
+# 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.
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-FROM centos:6
+FROM debian:jessie
 
-RUN yum install -y curl
+# Install Git and basic packages.
+RUN apt-get update && apt-get install -y \
+  curl \
+  gcc && apt-get clean
 
-RUN yum install -y tar which
+#==================
+# Ruby dependencies
 
 # Install rvm
 RUN gpg --keyserver hkp://keys.gnupg.net --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3 7D2BAF1CF37B13E2069D6956105BD0E739499BDB
-RUN curl -sSL https://get.rvm.io | bash -s stable
+RUN \curl -sSL https://get.rvm.io | bash -s stable
 
-# Install Ruby 2.3
-# Running the installation twice to work around docker issue when using overlay.
-# https://github.com/docker/docker/issues/10180
-RUN (/bin/bash -l -c "rvm install ruby-2.3.8") || (/bin/bash -l -c "rvm install ruby-2.3.8")
-RUN /bin/bash -l -c "rvm use --default ruby-2.3.8"
+# Install Ruby 3.0
+RUN /bin/bash -l -c "rvm install ruby-3.0.0"
+RUN /bin/bash -l -c "rvm use --default ruby-3.0.0"
 RUN /bin/bash -l -c "echo 'gem: --no-document' > ~/.gemrc"
 RUN /bin/bash -l -c "echo 'export PATH=/usr/local/rvm/bin:$PATH' >> ~/.bashrc"
-RUN /bin/bash -l -c "echo 'rvm --default use ruby-2.3.8' >> ~/.bashrc"
-RUN /bin/bash -l -c "gem install bundler -v 1.17.3 --no-document"
+RUN /bin/bash -l -c "echo 'rvm --default use ruby-3.0.0' >> ~/.bashrc"
+RUN /bin/bash -l -c "gem install bundler --no-document"
 
 RUN mkdir /var/local/jenkins
 
-RUN /bin/bash -l -c "echo '. /etc/profile.d/rvm.sh' >> ~/.bashrc"
+# Define the default command.
+CMD ["bash"]
index 947ffba..1127679 100755 (executable)
@@ -22,7 +22,7 @@ cd ${CLANG_TIDY_ROOT}
 
 # run clang tidy for all source files
 cat compile_commands.json | jq -r '.[].file' \
-  | grep -E "(^src/core/|^src/cpp/|^test/core/|^test/cpp/)" \
+  | grep -E "(^include/|^src/core/|^src/cpp/|^test/core/|^test/cpp/)" \
   | grep -v -E "/upb-generated/|/upbdefs-generated/" \
   | sort \
   | xargs tools/distrib/run_clang_tidy.py "$@"
index 9507dbc..7ea3d3b 100644 (file)
@@ -12,8 +12,7 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-FROM debian:jessie
-
+FROM debian:buster
 
 # Install Git and basic packages.
 RUN apt-get update && apt-get install -y \
@@ -70,11 +69,12 @@ RUN pip install futures==2.2.0 enum34==1.0.4 protobuf==3.5.2.post1 six==1.15.0 t
 # Ruby dependencies
 
 # Install rvm
-RUN apt-get update && apt-get install -y gnupg2
+RUN apt-get update && apt-get install -y gnupg2 && apt-get clean
 RUN gpg2 --keyserver hkp://pool.sks-keyservers.net --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3 7D2BAF1CF37B13E2069D6956105BD0E739499BDB
 RUN \curl -sSL https://get.rvm.io | bash -s stable
 
 # Install Ruby 2.5
+RUN apt-get update && apt-get install -y procps && apt-get clean
 RUN /bin/bash -l -c "rvm install ruby-2.5"
 RUN /bin/bash -l -c "rvm use --default ruby-2.5"
 RUN /bin/bash -l -c "echo 'gem: --no-document' > ~/.gemrc"
diff --git a/tools/dockerfile/interoptest/lb_interop_fake_servers/build_interop.sh b/tools/dockerfile/interoptest/lb_interop_fake_servers/build_interop.sh
deleted file mode 100644 (file)
index 1846d51..0000000
+++ /dev/null
@@ -1,35 +0,0 @@
-#!/bin/bash
-# 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.
-#
-# Gets a built Go interop server, fake balancer server, and python
-# DNS server into a base image.
-set -e
-
-# Clone just the grpc-go source code without any dependencies.
-# We are cloning from a local git repo that contains the right revision
-# to test instead of using "go get" to download from Github directly.
-git clone --recursive /var/local/jenkins/grpc-go src/google.golang.org/grpc
-
-# Get all gRPC Go dependencies
-(cd src/google.golang.org/grpc && make deps && make testdeps)
-
-# Build the interop server and fake balancer
-(cd src/google.golang.org/grpc/interop/server && go install)
-(cd src/google.golang.org/grpc/interop/fake_grpclb && go install)
-  
-# Clone the grpc/grpc repo to get the python DNS server.
-# Hack: we don't need to init submodules for the scripts we need.
-mkdir -p /var/local/git/grpc
-git clone /var/local/jenkins/grpc /var/local/git/grpc
index 7d2068e..3c9ad50 100755 (executable)
@@ -29,7 +29,7 @@ cd -
 
 DOCKERHUB_ORGANIZATION=grpctesting
 
-for DOCKERFILE_DIR in tools/dockerfile/test/* tools/dockerfile/grpc_artifact_* tools/dockerfile/interoptest/* tools/dockerfile/distribtest/*
+for DOCKERFILE_DIR in tools/dockerfile/test/* tools/dockerfile/grpc_artifact_* tools/dockerfile/interoptest/* tools/dockerfile/distribtest/* third_party/rake-compiler-dock/*/
 do
   # Generate image name based on Dockerfile checksum. That works well as long
   # as can count on dockerfiles being written in a way that changing the logical 
index c10b83e..984a394 100644 (file)
@@ -75,7 +75,7 @@ RUN python3.6 -m ensurepip && \
 # Bazel installation
 
 # Must be in sync with tools/bazel
-ENV BAZEL_VERSION 2.2.0
+ENV BAZEL_VERSION 3.7.1
 
 # The correct bazel version is already preinstalled, no need to use //tools/bazel wrapper.
 ENV DISABLE_BAZEL_WRAPPER 1
@@ -12,8 +12,7 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-FROM debian:jessie
-
+FROM debian:buster
 
 # Install Git and basic packages.
 RUN apt-get update && apt-get install -y \
@@ -73,11 +72,12 @@ RUN pip install --upgrade google-api-python-client oauth2client
 # Ruby dependencies
 
 # Install rvm
-RUN apt-get update && apt-get install -y gnupg2
+RUN apt-get update && apt-get install -y gnupg2 && apt-get clean
 RUN gpg2 --keyserver hkp://pool.sks-keyservers.net --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3 7D2BAF1CF37B13E2069D6956105BD0E739499BDB
 RUN \curl -sSL https://get.rvm.io | bash -s stable
 
 # Install Ruby 2.5
+RUN apt-get update && apt-get install -y procps && apt-get clean
 RUN /bin/bash -l -c "rvm install ruby-2.5"
 RUN /bin/bash -l -c "rvm use --default ruby-2.5"
 RUN /bin/bash -l -c "echo 'gem: --no-document' > ~/.gemrc"
@@ -85,6 +85,12 @@ RUN /bin/bash -l -c "echo 'export PATH=/usr/local/rvm/bin:$PATH' >> ~/.bashrc"
 RUN /bin/bash -l -c "echo 'rvm --default use ruby-2.5' >> ~/.bashrc"
 RUN /bin/bash -l -c "gem install bundler --no-document -v 1.9"
 
+#=================
+# Install cmake
+# Note that this step should be only used for distributions that have new enough cmake to satisfy gRPC's cmake version requirement.
+
+RUN apt-get update && apt-get install -y cmake && apt-get clean
+
 
 RUN mkdir /var/local/jenkins
 
index 2d4c243..41b265a 100644 (file)
@@ -79,7 +79,7 @@ RUN apt-get update && apt-get install -y \
       curl \
       shellcheck
 RUN python2 -m pip install simplejson mako virtualenv==16.7.9 lxml
-RUN python3 -m pip install simplejson mako virtualenv==16.7.9 lxml
+RUN python3 -m pip install simplejson mako virtualenv==16.7.9 lxml six
 
 # Add buster-backports for more recent clang packages
 RUN echo "deb http://deb.debian.org/debian buster-backports main" | tee /etc/apt/sources.list.d/buster-backports.list
@@ -94,7 +94,7 @@ ENV CLANG_TIDY=clang-tidy-8
 # Bazel installation
 
 # Must be in sync with tools/bazel
-ENV BAZEL_VERSION 2.2.0
+ENV BAZEL_VERSION 3.7.1
 
 # The correct bazel version is already preinstalled, no need to use //tools/bazel wrapper.
 ENV DISABLE_BAZEL_WRAPPER 1
index 39d42bc..d90ee96 100644 (file)
@@ -40,7 +40,7 @@ PROJECT_NAME           = "GRPC C++"
 # could be handy for archiving the generated documentation or if some version
 # control system is used.
 
-PROJECT_NUMBER         = 1.34.1
+PROJECT_NUMBER         = 1.35.0
 
 # Using the PROJECT_BRIEF tag one can provide an optional one line description
 # for a project that appears at the top of each page and should give viewer a
@@ -1037,7 +1037,8 @@ include/grpcpp/support/string_ref.h \
 include/grpcpp/support/stub_options.h \
 include/grpcpp/support/sync_stream.h \
 include/grpcpp/support/time.h \
-include/grpcpp/support/validate_service_config.h
+include/grpcpp/support/validate_service_config.h \
+include/grpcpp/xds_server_builder.h
 
 # This tag can be used to specify the character encoding of the source files
 # that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses
index 73f32b1..a576eb9 100644 (file)
@@ -40,7 +40,7 @@ PROJECT_NAME           = "GRPC C++"
 # could be handy for archiving the generated documentation or if some version
 # control system is used.
 
-PROJECT_NUMBER         = 1.34.1
+PROJECT_NUMBER         = 1.35.0
 
 # Using the PROJECT_BRIEF tag one can provide an optional one line description
 # for a project that appears at the top of each page and should give viewer a
@@ -1038,6 +1038,7 @@ include/grpcpp/support/stub_options.h \
 include/grpcpp/support/sync_stream.h \
 include/grpcpp/support/time.h \
 include/grpcpp/support/validate_service_config.h \
+include/grpcpp/xds_server_builder.h \
 src/core/ext/filters/census/grpc_context.cc \
 src/core/ext/filters/client_channel/backend_metric.cc \
 src/core/ext/filters/client_channel/backend_metric.h \
@@ -1054,6 +1055,8 @@ src/core/ext/filters/client_channel/client_channel_plugin.cc \
 src/core/ext/filters/client_channel/config_selector.cc \
 src/core/ext/filters/client_channel/config_selector.h \
 src/core/ext/filters/client_channel/connector.h \
+src/core/ext/filters/client_channel/dynamic_filters.cc \
+src/core/ext/filters/client_channel/dynamic_filters.h \
 src/core/ext/filters/client_channel/global_subchannel_pool.cc \
 src/core/ext/filters/client_channel/global_subchannel_pool.h \
 src/core/ext/filters/client_channel/health/health_check_client.cc \
@@ -1086,10 +1089,11 @@ src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc \
 src/core/ext/filters/client_channel/lb_policy/subchannel_list.h \
 src/core/ext/filters/client_channel/lb_policy/weighted_target/weighted_target.cc \
 src/core/ext/filters/client_channel/lb_policy/xds/cds.cc \
-src/core/ext/filters/client_channel/lb_policy/xds/eds.cc \
 src/core/ext/filters/client_channel/lb_policy/xds/xds.h \
+src/core/ext/filters/client_channel/lb_policy/xds/xds_channel_args.h \
 src/core/ext/filters/client_channel/lb_policy/xds/xds_cluster_impl.cc \
 src/core/ext/filters/client_channel/lb_policy/xds/xds_cluster_manager.cc \
+src/core/ext/filters/client_channel/lb_policy/xds/xds_cluster_resolver.cc \
 src/core/ext/filters/client_channel/lb_policy_factory.h \
 src/core/ext/filters/client_channel/lb_policy_registry.cc \
 src/core/ext/filters/client_channel/lb_policy_registry.h \
@@ -1101,14 +1105,12 @@ src/core/ext/filters/client_channel/proxy_mapper_registry.h \
 src/core/ext/filters/client_channel/resolver.cc \
 src/core/ext/filters/client_channel/resolver.h \
 src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc \
-src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.cc \
 src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.h \
 src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_libuv.cc \
 src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_posix.cc \
 src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_windows.cc \
 src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc \
 src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h \
-src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_fallback.cc \
 src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv.cc \
 src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_posix.cc \
 src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc \
@@ -1125,8 +1127,6 @@ src/core/ext/filters/client_channel/resolver_registry.cc \
 src/core/ext/filters/client_channel/resolver_registry.h \
 src/core/ext/filters/client_channel/resolver_result_parsing.cc \
 src/core/ext/filters/client_channel/resolver_result_parsing.h \
-src/core/ext/filters/client_channel/resolving_lb_policy.cc \
-src/core/ext/filters/client_channel/resolving_lb_policy.h \
 src/core/ext/filters/client_channel/retry_throttle.cc \
 src/core/ext/filters/client_channel/retry_throttle.h \
 src/core/ext/filters/client_channel/server_address.cc \
@@ -1560,8 +1560,6 @@ src/core/ext/xds/certificate_provider_store.cc \
 src/core/ext/xds/certificate_provider_store.h \
 src/core/ext/xds/file_watcher_certificate_provider_factory.cc \
 src/core/ext/xds/file_watcher_certificate_provider_factory.h \
-src/core/ext/xds/google_mesh_ca_certificate_provider_factory.cc \
-src/core/ext/xds/google_mesh_ca_certificate_provider_factory.h \
 src/core/ext/xds/xds_api.cc \
 src/core/ext/xds/xds_api.h \
 src/core/ext/xds/xds_bootstrap.cc \
@@ -1573,6 +1571,7 @@ src/core/ext/xds/xds_client.cc \
 src/core/ext/xds/xds_client.h \
 src/core/ext/xds/xds_client_stats.cc \
 src/core/ext/xds/xds_client_stats.h \
+src/core/ext/xds/xds_server_config_fetcher.cc \
 src/core/lib/avl/avl.cc \
 src/core/lib/avl/avl.h \
 src/core/lib/backoff/backoff.cc \
@@ -1683,7 +1682,6 @@ src/core/lib/gprpp/global_config_generic.h \
 src/core/lib/gprpp/host_port.cc \
 src/core/lib/gprpp/host_port.h \
 src/core/lib/gprpp/manual_constructor.h \
-src/core/lib/gprpp/map.h \
 src/core/lib/gprpp/memory.h \
 src/core/lib/gprpp/mpscq.cc \
 src/core/lib/gprpp/mpscq.h \
@@ -1914,6 +1912,8 @@ src/core/lib/security/credentials/composite/composite_credentials.h \
 src/core/lib/security/credentials/credentials.cc \
 src/core/lib/security/credentials/credentials.h \
 src/core/lib/security/credentials/credentials_metadata.cc \
+src/core/lib/security/credentials/external/aws_external_account_credentials.cc \
+src/core/lib/security/credentials/external/aws_external_account_credentials.h \
 src/core/lib/security/credentials/external/aws_request_signer.cc \
 src/core/lib/security/credentials/external/aws_request_signer.h \
 src/core/lib/security/credentials/external/external_account_credentials.cc \
@@ -1952,6 +1952,8 @@ src/core/lib/security/credentials/tls/grpc_tls_credentials_options.cc \
 src/core/lib/security/credentials/tls/grpc_tls_credentials_options.h \
 src/core/lib/security/credentials/tls/tls_credentials.cc \
 src/core/lib/security/credentials/tls/tls_credentials.h \
+src/core/lib/security/credentials/tls/tls_utils.cc \
+src/core/lib/security/credentials/tls/tls_utils.h \
 src/core/lib/security/credentials/xds/xds_credentials.cc \
 src/core/lib/security/credentials/xds/xds_credentials.h \
 src/core/lib/security/security_connector/alts/alts_security_connector.cc \
@@ -2172,6 +2174,7 @@ src/cpp/server/server_context.cc \
 src/cpp/server/server_credentials.cc \
 src/cpp/server/server_posix.cc \
 src/cpp/server/thread_pool_interface.h \
+src/cpp/server/xds_server_credentials.cc \
 src/cpp/thread_manager/thread_manager.cc \
 src/cpp/thread_manager/thread_manager.h \
 src/cpp/util/byte_buffer_cc.cc \
index fd1cc39..7b9ca54 100644 (file)
@@ -881,6 +881,8 @@ src/core/ext/filters/client_channel/client_channel_plugin.cc \
 src/core/ext/filters/client_channel/config_selector.cc \
 src/core/ext/filters/client_channel/config_selector.h \
 src/core/ext/filters/client_channel/connector.h \
+src/core/ext/filters/client_channel/dynamic_filters.cc \
+src/core/ext/filters/client_channel/dynamic_filters.h \
 src/core/ext/filters/client_channel/global_subchannel_pool.cc \
 src/core/ext/filters/client_channel/global_subchannel_pool.h \
 src/core/ext/filters/client_channel/health/health_check_client.cc \
@@ -913,10 +915,11 @@ src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc \
 src/core/ext/filters/client_channel/lb_policy/subchannel_list.h \
 src/core/ext/filters/client_channel/lb_policy/weighted_target/weighted_target.cc \
 src/core/ext/filters/client_channel/lb_policy/xds/cds.cc \
-src/core/ext/filters/client_channel/lb_policy/xds/eds.cc \
 src/core/ext/filters/client_channel/lb_policy/xds/xds.h \
+src/core/ext/filters/client_channel/lb_policy/xds/xds_channel_args.h \
 src/core/ext/filters/client_channel/lb_policy/xds/xds_cluster_impl.cc \
 src/core/ext/filters/client_channel/lb_policy/xds/xds_cluster_manager.cc \
+src/core/ext/filters/client_channel/lb_policy/xds/xds_cluster_resolver.cc \
 src/core/ext/filters/client_channel/lb_policy_factory.h \
 src/core/ext/filters/client_channel/lb_policy_registry.cc \
 src/core/ext/filters/client_channel/lb_policy_registry.h \
@@ -929,14 +932,12 @@ src/core/ext/filters/client_channel/resolver.cc \
 src/core/ext/filters/client_channel/resolver.h \
 src/core/ext/filters/client_channel/resolver/README.md \
 src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc \
-src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.cc \
 src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.h \
 src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_libuv.cc \
 src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_posix.cc \
 src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_windows.cc \
 src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc \
 src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h \
-src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_fallback.cc \
 src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv.cc \
 src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_posix.cc \
 src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc \
@@ -955,8 +956,6 @@ src/core/ext/filters/client_channel/resolver_registry.cc \
 src/core/ext/filters/client_channel/resolver_registry.h \
 src/core/ext/filters/client_channel/resolver_result_parsing.cc \
 src/core/ext/filters/client_channel/resolver_result_parsing.h \
-src/core/ext/filters/client_channel/resolving_lb_policy.cc \
-src/core/ext/filters/client_channel/resolving_lb_policy.h \
 src/core/ext/filters/client_channel/retry_throttle.cc \
 src/core/ext/filters/client_channel/retry_throttle.h \
 src/core/ext/filters/client_channel/server_address.cc \
@@ -1397,8 +1396,6 @@ src/core/ext/xds/certificate_provider_store.cc \
 src/core/ext/xds/certificate_provider_store.h \
 src/core/ext/xds/file_watcher_certificate_provider_factory.cc \
 src/core/ext/xds/file_watcher_certificate_provider_factory.h \
-src/core/ext/xds/google_mesh_ca_certificate_provider_factory.cc \
-src/core/ext/xds/google_mesh_ca_certificate_provider_factory.h \
 src/core/ext/xds/xds_api.cc \
 src/core/ext/xds/xds_api.h \
 src/core/ext/xds/xds_bootstrap.cc \
@@ -1410,6 +1407,7 @@ src/core/ext/xds/xds_client.cc \
 src/core/ext/xds/xds_client.h \
 src/core/ext/xds/xds_client_stats.cc \
 src/core/ext/xds/xds_client_stats.h \
+src/core/ext/xds/xds_server_config_fetcher.cc \
 src/core/lib/README.md \
 src/core/lib/avl/avl.cc \
 src/core/lib/avl/avl.h \
@@ -1524,7 +1522,6 @@ src/core/lib/gprpp/global_config_generic.h \
 src/core/lib/gprpp/host_port.cc \
 src/core/lib/gprpp/host_port.h \
 src/core/lib/gprpp/manual_constructor.h \
-src/core/lib/gprpp/map.h \
 src/core/lib/gprpp/memory.h \
 src/core/lib/gprpp/mpscq.cc \
 src/core/lib/gprpp/mpscq.h \
@@ -1756,6 +1753,8 @@ src/core/lib/security/credentials/composite/composite_credentials.h \
 src/core/lib/security/credentials/credentials.cc \
 src/core/lib/security/credentials/credentials.h \
 src/core/lib/security/credentials/credentials_metadata.cc \
+src/core/lib/security/credentials/external/aws_external_account_credentials.cc \
+src/core/lib/security/credentials/external/aws_external_account_credentials.h \
 src/core/lib/security/credentials/external/aws_request_signer.cc \
 src/core/lib/security/credentials/external/aws_request_signer.h \
 src/core/lib/security/credentials/external/external_account_credentials.cc \
@@ -1794,6 +1793,8 @@ src/core/lib/security/credentials/tls/grpc_tls_credentials_options.cc \
 src/core/lib/security/credentials/tls/grpc_tls_credentials_options.h \
 src/core/lib/security/credentials/tls/tls_credentials.cc \
 src/core/lib/security/credentials/tls/tls_credentials.h \
+src/core/lib/security/credentials/tls/tls_utils.cc \
+src/core/lib/security/credentials/tls/tls_utils.h \
 src/core/lib/security/credentials/xds/xds_credentials.cc \
 src/core/lib/security/credentials/xds/xds_credentials.h \
 src/core/lib/security/security_connector/alts/alts_security_connector.cc \
index 6b018c2..a9c096f 100644 (file)
@@ -40,7 +40,7 @@ PROJECT_NAME           = "GRPC Objective-C"
 # could be handy for archiving the generated documentation or if some version
 # control system is used.
 
-PROJECT_NUMBER         = 1.34.1
+PROJECT_NUMBER         = 1.35.0
 
 # Using the PROJECT_BRIEF tag one can provide an optional one line description
 # for a project that appears at the top of each page and should give viewer a
index bd231f8..7fc91c0 100644 (file)
@@ -40,7 +40,7 @@ PROJECT_NAME           = "GRPC Objective-C"
 # could be handy for archiving the generated documentation or if some version
 # control system is used.
 
-PROJECT_NUMBER         = 1.34.1
+PROJECT_NUMBER         = 1.35.0
 
 # Using the PROJECT_BRIEF tag one can provide an optional one line description
 # for a project that appears at the top of each page and should give viewer a
index 406a597..1aef67c 100644 (file)
@@ -40,7 +40,7 @@ PROJECT_NAME           = "GRPC PHP"
 # could be handy for archiving the generated documentation or if some version
 # control system is used.
 
-PROJECT_NUMBER         = 1.34.1
+PROJECT_NUMBER         = 1.35.0
 
 # Using the PROJECT_BRIEF tag one can provide an optional one line description
 # for a project that appears at the top of each page and should give viewer a
diff --git a/tools/failures/detect_new_failures.py b/tools/failures/detect_new_failures.py
deleted file mode 100644 (file)
index cdbd4a4..0000000
+++ /dev/null
@@ -1,304 +0,0 @@
-#!/usr/bin/env python
-# 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.
-"""Detect new flakes and create issues for them"""
-
-from __future__ import absolute_import
-from __future__ import division
-from __future__ import print_function
-
-import datetime
-import json
-import logging
-import os
-import pprint
-import sys
-import urllib
-import urllib2
-from collections import namedtuple
-
-gcp_utils_dir = os.path.abspath(
-    os.path.join(os.path.dirname(__file__), '../gcp/utils'))
-sys.path.append(gcp_utils_dir)
-
-import big_query_utils
-
-GH_ISSUE_CREATION_URL = 'https://api.github.com/repos/grpc/grpc/issues'
-GH_ISSUE_SEARCH_URL = 'https://api.github.com/search/issues'
-KOKORO_BASE_URL = 'https://kokoro2.corp.google.com/job/'
-
-
-def gh(url, data=None):
-    request = urllib2.Request(url, data=data)
-    assert TOKEN
-    request.add_header('Authorization', 'token {}'.format(TOKEN))
-    if data:
-        request.add_header('Content-type', 'application/json')
-    response = urllib2.urlopen(request)
-    if 200 <= response.getcode() < 300:
-        return json.loads(response.read())
-    else:
-        raise ValueError('Error ({}) accessing {}'.format(
-            response.getcode(), response.geturl()))
-
-
-def search_gh_issues(search_term, status='open'):
-    params = ' '.join((search_term, 'is:issue', 'is:open', 'repo:grpc/grpc'))
-    qargs = urllib.urlencode({'q': params})
-    url = '?'.join((GH_ISSUE_SEARCH_URL, qargs))
-    response = gh(url)
-    return response
-
-
-def create_gh_issue(title, body, labels, assignees=[]):
-    params = {'title': title, 'body': body, 'labels': labels}
-    if assignees:
-        params['assignees'] = assignees
-    data = json.dumps(params)
-    response = gh(GH_ISSUE_CREATION_URL, data)
-    issue_url = response['html_url']
-    print('Created issue {} for {}'.format(issue_url, title))
-
-
-def build_kokoro_url(job_name, build_id):
-    job_path = '{}/{}'.format('/job/'.join(job_name.split('/')), build_id)
-    return KOKORO_BASE_URL + job_path
-
-
-def create_issues(new_flakes, always_create):
-    for test_name, results_row in new_flakes.items():
-        poll_strategy, job_name, build_id, timestamp = results_row
-        # TODO(dgq): the Kokoro URL has a limited lifetime. The permanent and ideal
-        # URL would be the sponge one, but there's currently no easy way to retrieve
-        # it.
-        url = build_kokoro_url(job_name, build_id)
-        title = 'New Failure: ' + test_name
-        body = '- Test: {}\n- Poll Strategy: {}\n- URL: {}'.format(
-            test_name, poll_strategy, url)
-        labels = ['infra/New Failure']
-        if always_create:
-            proceed = True
-        else:
-            preexisting_issues = search_gh_issues(test_name)
-            if preexisting_issues['total_count'] > 0:
-                print('\nFound {} issues for "{}":'.format(
-                    preexisting_issues['total_count'], test_name))
-                for issue in preexisting_issues['items']:
-                    print('\t"{}" ; URL: {}'.format(issue['title'],
-                                                    issue['html_url']))
-            else:
-                print(
-                    '\nNo preexisting issues found for "{}"'.format(test_name))
-            proceed = raw_input(
-                'Create issue for:\nTitle: {}\nBody: {}\n[Y/n] '.format(
-                    title, body)) in ('y', 'Y', '')
-        if proceed:
-            assignees_str = raw_input(
-                'Asignees? (comma-separated, leave blank for unassigned): ')
-            assignees = [
-                assignee.strip() for assignee in assignees_str.split(',')
-            ]
-            create_gh_issue(title, body, labels, assignees)
-
-
-def print_table(table, format):
-    first_time = True
-    for test_name, results_row in table.items():
-        poll_strategy, job_name, build_id, timestamp = results_row
-        full_kokoro_url = build_kokoro_url(job_name, build_id)
-        if format == 'human':
-            print("\t- Test: {}, Polling: {}, Timestamp: {}, url: {}".format(
-                test_name, poll_strategy, timestamp, full_kokoro_url))
-        else:
-            assert (format == 'csv')
-            if first_time:
-                print('test,timestamp,url')
-                first_time = False
-            print("{},{},{}".format(test_name, timestamp, full_kokoro_url))
-
-
-Row = namedtuple('Row', ['poll_strategy', 'job_name', 'build_id', 'timestamp'])
-
-
-def get_new_failures(dates):
-    bq = big_query_utils.create_big_query()
-    this_script_path = os.path.join(os.path.dirname(__file__))
-    sql_script = os.path.join(this_script_path, 'sql/new_failures_24h.sql')
-    with open(sql_script) as query_file:
-        query = query_file.read().format(
-            calibration_begin=dates['calibration']['begin'],
-            calibration_end=dates['calibration']['end'],
-            reporting_begin=dates['reporting']['begin'],
-            reporting_end=dates['reporting']['end'])
-    logging.debug("Query:\n%s", query)
-    query_job = big_query_utils.sync_query_job(bq, 'grpc-testing', query)
-    page = bq.jobs().getQueryResults(
-        pageToken=None, **query_job['jobReference']).execute(num_retries=3)
-    rows = page.get('rows')
-    if rows:
-        return {
-            row['f'][0]['v']: Row(poll_strategy=row['f'][1]['v'],
-                                  job_name=row['f'][2]['v'],
-                                  build_id=row['f'][3]['v'],
-                                  timestamp=row['f'][4]['v']) for row in rows
-        }
-    else:
-        return {}
-
-
-def parse_isodate(date_str):
-    return datetime.datetime.strptime(date_str, "%Y-%m-%d").date()
-
-
-def get_new_flakes(args):
-    """The from_date_str argument marks the beginning of the "calibration", used
-  to establish the set of pre-existing flakes, which extends over
-  "calibration_days".  After the calibration period, "reporting_days" is the
-  length of time during which new flakes will be reported.
-
-from
-date
-  |--------------------|---------------|
-  ^____________________^_______________^
-       calibration         reporting
-         days                days
-  """
-    dates = process_date_args(args)
-    new_failures = get_new_failures(dates)
-    logging.info('|new failures| = %d', len(new_failures))
-    return new_failures
-
-
-def build_args_parser():
-    import argparse, datetime
-    parser = argparse.ArgumentParser()
-    today = datetime.date.today()
-    a_week_ago = today - datetime.timedelta(days=7)
-    parser.add_argument(
-        '--calibration_days',
-        type=int,
-        default=7,
-        help='How many days to consider for pre-existing flakes.')
-    parser.add_argument(
-        '--reporting_days',
-        type=int,
-        default=1,
-        help='How many days to consider for the detection of new flakes.')
-    parser.add_argument('--count_only',
-                        dest='count_only',
-                        action='store_true',
-                        help='Display only number of new flakes.')
-    parser.set_defaults(count_only=False)
-    parser.add_argument('--create_issues',
-                        dest='create_issues',
-                        action='store_true',
-                        help='Create issues for all new flakes.')
-    parser.set_defaults(create_issues=False)
-    parser.add_argument(
-        '--always_create_issues',
-        dest='always_create_issues',
-        action='store_true',
-        help='Always create issues for all new flakes. Otherwise,'
-        ' interactively prompt for every issue.')
-    parser.set_defaults(always_create_issues=False)
-    parser.add_argument(
-        '--token',
-        type=str,
-        default='',
-        help='GitHub token to use its API with a higher rate limit')
-    parser.add_argument('--format',
-                        type=str,
-                        choices=['human', 'csv'],
-                        default='human',
-                        help='Output format: are you a human or a machine?')
-    parser.add_argument(
-        '--loglevel',
-        type=str,
-        choices=['INFO', 'DEBUG', 'WARNING', 'ERROR', 'CRITICAL'],
-        default='WARNING',
-        help='Logging level.')
-    return parser
-
-
-def process_date_args(args):
-    calibration_begin = (datetime.date.today() -
-                         datetime.timedelta(days=args.calibration_days) -
-                         datetime.timedelta(days=args.reporting_days))
-    calibration_end = calibration_begin + datetime.timedelta(
-        days=args.calibration_days)
-    reporting_begin = calibration_end
-    reporting_end = reporting_begin + datetime.timedelta(
-        days=args.reporting_days)
-    return {
-        'calibration': {
-            'begin': calibration_begin,
-            'end': calibration_end
-        },
-        'reporting': {
-            'begin': reporting_begin,
-            'end': reporting_end
-        }
-    }
-
-
-def main():
-    global TOKEN
-    args_parser = build_args_parser()
-    args = args_parser.parse_args()
-    if args.create_issues and not args.token:
-        raise ValueError(
-            'Missing --token argument, needed to create GitHub issues')
-    TOKEN = args.token
-
-    logging_level = getattr(logging, args.loglevel)
-    logging.basicConfig(format='%(asctime)s %(message)s', level=logging_level)
-    new_flakes = get_new_flakes(args)
-
-    dates = process_date_args(args)
-
-    dates_info_string = 'from {} until {} (calibrated from {} until {})'.format(
-        dates['reporting']['begin'].isoformat(),
-        dates['reporting']['end'].isoformat(),
-        dates['calibration']['begin'].isoformat(),
-        dates['calibration']['end'].isoformat())
-
-    if args.format == 'human':
-        if args.count_only:
-            print(len(new_flakes), dates_info_string)
-        elif new_flakes:
-            found_msg = 'Found {} new flakes {}'.format(len(new_flakes),
-                                                        dates_info_string)
-            print(found_msg)
-            print('*' * len(found_msg))
-            print_table(new_flakes, 'human')
-            if args.create_issues:
-                create_issues(new_flakes, args.always_create_issues)
-        else:
-            print('No new flakes found '.format(len(new_flakes)),
-                  dates_info_string)
-    elif args.format == 'csv':
-        if args.count_only:
-            print('from_date,to_date,count')
-            print('{},{},{}'.format(dates['reporting']['begin'].isoformat(),
-                                    dates['reporting']['end'].isoformat(),
-                                    len(new_flakes)))
-        else:
-            print_table(new_flakes, 'csv')
-    else:
-        raise ValueError('Invalid argument for --format: {}'.format(
-            args.format))
-
-
-if __name__ == '__main__':
-    main()
diff --git a/tools/failures/sql/new_failures_24h.sql b/tools/failures/sql/new_failures_24h.sql
deleted file mode 100644 (file)
index 6ce0c5d..0000000
+++ /dev/null
@@ -1,62 +0,0 @@
-#standardSQL
-WITH calibration AS (
-  SELECT
-    RTRIM(LTRIM(REGEXP_REPLACE(filtered_test_name, r'(/\d+)|(bins/.+/)|(cmake/.+/.+/)', ''))) AS test_binary,
-    REGEXP_EXTRACT(test_name, r'GRPC_POLL_STRATEGY=(\w+)') AS poll_strategy,
-    job_name,
-    build_id
-  FROM (
-    SELECT
-      REGEXP_REPLACE(test_name, r'(/\d+)|(GRPC_POLL_STRATEGY=.+)', '') AS filtered_test_name,
-      test_name,
-      job_name,
-      build_id,
-      timestamp
-    FROM
-      `grpc-testing.jenkins_test_results.aggregate_results`
-    WHERE
-      timestamp > TIMESTAMP(DATETIME("{calibration_begin} 00:00:00", "America/Los_Angeles"))
-      AND timestamp <= TIMESTAMP(DATETIME("{calibration_end} 23:59:59", "America/Los_Angeles"))
-      AND NOT REGEXP_CONTAINS(job_name,
-        'portability')
-      AND result != 'PASSED'
-      AND result != 'SKIPPED' )),
-  reporting AS (
-  SELECT
-    RTRIM(LTRIM(REGEXP_REPLACE(filtered_test_name, r'(/\d+)|(bins/.+/)|(cmake/.+/.+/)', ''))) AS test_binary,
-    REGEXP_EXTRACT(test_name, r'GRPC_POLL_STRATEGY=(\w+)') AS poll_strategy,
-    job_name,
-    build_id,
-    timestamp
-  FROM (
-    SELECT
-      REGEXP_REPLACE(test_name, r'(/\d+)|(GRPC_POLL_STRATEGY=.+)', '') AS filtered_test_name,
-      test_name,
-      job_name,
-      build_id,
-      timestamp
-    FROM
-      `grpc-testing.jenkins_test_results.aggregate_results`
-    WHERE
-      timestamp > TIMESTAMP(DATETIME("{reporting_begin} 00:00:00", "America/Los_Angeles"))
-      AND timestamp <= TIMESTAMP(DATETIME("{reporting_end} 23:59:59", "America/Los_Angeles"))
-      AND NOT REGEXP_CONTAINS(job_name,
-        'portability')
-      AND result != 'PASSED'
-      AND result != 'SKIPPED' ))
-SELECT
-  reporting.test_binary,
-  reporting.poll_strategy,
-  reporting.job_name,
-  reporting.build_id,
-  STRING(reporting.timestamp, "America/Los_Angeles") as timestamp_MTV
-FROM
-  reporting
-LEFT JOIN
-  calibration
-ON
-  reporting.test_binary = calibration.test_binary
-WHERE
-  calibration.test_binary IS NULL
-ORDER BY
-  timestamp DESC;
diff --git a/tools/internal_ci/helper_scripts/prepare_build_grpclb_interop_rc b/tools/internal_ci/helper_scripts/prepare_build_grpclb_interop_rc
deleted file mode 100644 (file)
index a8e350b..0000000
+++ /dev/null
@@ -1,33 +0,0 @@
-#!/bin/bash
-# Copyright 2017 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.
-
-# Source this rc script to prepare the environment for interop builds
-# This rc script must be used in the root directory of gRPC
-
-export LANG=en_US.UTF-8
-
-# Download Docker images from DockerHub
-export DOCKERHUB_ORGANIZATION=grpctesting
-
-git submodule update --init
-
-# Set up gRPC-Go and gRPC-Java to test
-git clone --recursive https://github.com/grpc/grpc-go ./../grpc-go
-git clone --recursive https://github.com/grpc/grpc-java ./../grpc-java
-
-# TODO(apolcyn): move to kokoro image?
-virtualenv env
-source env/bin/activate
-pip install twisted
index e7528f2..f469d57 100644 (file)
@@ -67,7 +67,7 @@ then
   time git clone --depth 1 https://github.com/CocoaPods/Specs.git ~/.cocoapods/repos/master
 
   # Needed for ios-binary-size
-  time pip install --user pyyaml pyjwt cryptography requests
+  time pip install --user pyyaml pyjwt==1.7.1 pyOpenSSL cryptography requests
 
   # Store intermediate build files of ObjC tests into /tmpfs
   # TODO(jtattermusch): this has likely been done to avoid running
@@ -85,7 +85,7 @@ if [ "${PREPARE_BUILD_INSTALL_DEPS_PYTHON}" == "true" ]
 then
   # python
   time pip install --user virtualenv
-  time pip install --user --upgrade Mako tox setuptools==44.1.1 twisted pyyaml pyjwt cryptography requests
+  time pip install --user --upgrade Mako tox setuptools==44.1.1 twisted pyyaml pyjwt==1.7.1 pyOpenSSL cryptography requests
 
   # Install Python 3.7 if it doesn't exist
   if [ ! -f "/usr/local/bin/python3.7" ]; then
index 87c7a24..e0bee1c 100755 (executable)
 
 set -ex
 
-# Install packages which were not preinstalled yet.
-# Protobuf needs autoconf & automake to build
-sudo apt-get install -y autoconf automake 
-
 # Accept the Android SDK licences.
 yes | /opt/android-sdk/current/tools/bin/sdkmanager --licenses
 
@@ -30,17 +26,24 @@ REPO_ROOT="$(pwd)"
 git submodule update --init
 
 # Build protoc and grpc_cpp_plugin. Codegen is not cross-compiled to Android
-make HAS_SYSTEM_PROTOBUF=false
+mkdir -p cmake/build
+pushd cmake/build
+cmake -DgRPC_BUILD_TESTS=OFF -DCMAKE_BUILD_TYPE=Release ../..
+make protoc grpc_cpp_plugin -j2
+popd
+
+PROTOC=${REPO_ROOT}/cmake/build/third_party/protobuf/protoc
+PLUGIN=${REPO_ROOT}/cmake/build/grpc_cpp_plugin
 
 # Build and run interop instrumentation tests on Firebase Test Lab
 
 cd "${REPO_ROOT}/src/android/test/interop/"
 ./gradlew assembleDebug \
-    "-Pprotoc=${REPO_ROOT}/third_party/protobuf/src/protoc" \
-    "-Pgrpc_cpp_plugin=${REPO_ROOT}/bins/opt/grpc_cpp_plugin"
+    "-Pprotoc=${PROTOC}" \
+    "-Pgrpc_cpp_plugin=${PLUGIN}"
 ./gradlew assembleDebugAndroidTest \
-    "-Pprotoc=${REPO_ROOT}/third_party/protobuf/src/protoc" \
-    "-Pgrpc_cpp_plugin=${REPO_ROOT}/bins/opt/grpc_cpp_plugin"
+    "-Pprotoc=${PROTOC}" \
+    "-Pgrpc_cpp_plugin=${PLUGIN}"
 gcloud firebase test android run \
     --type instrumentation \
     --app app/build/outputs/apk/debug/app-debug.apk \
@@ -59,5 +62,5 @@ gcloud firebase test android run \
 
 cd "${REPO_ROOT}/examples/android/helloworld"
 ./gradlew build \
-    "-Pprotoc=${REPO_ROOT}/third_party/protobuf/src/protoc" \
-    "-Pgrpc_cpp_plugin=${REPO_ROOT}/bins/opt/grpc_cpp_plugin"
+    "-Pprotoc=${PROTOC}" \
+    "-Pgrpc_cpp_plugin=${PLUGIN}"
index d14ccc7..dcf83ee 100755 (executable)
@@ -62,11 +62,11 @@ bazel build //src/python/grpcio_tests/tests_py3_only/interop:xds_interop_client
 
 # Test cases "path_matching" and "header_matching" are not included in "all",
 # because not all interop clients in all languages support these new tests.
-GRPC_VERBOSITY=debug GRPC_TRACE=xds_client,xds_resolver,xds_cluster_manager_lb,cds_lb,eds_lb,priority_lb,xds_cluster_impl_lb,weighted_target_lb "$PYTHON" \
+GRPC_VERBOSITY=debug GRPC_TRACE=xds_client,xds_resolver,xds_cluster_manager_lb,cds_lb,xds_cluster_resolver_lb,priority_lb,xds_cluster_impl_lb,weighted_target_lb "$PYTHON" \
   tools/run_tests/run_xds_tests.py \
-    --test_case="all,path_matching,header_matching" \
+    --test_case="all,path_matching,header_matching,circuit_breaking" \
     --project_id=grpc-testing \
-    --source_image=projects/grpc-testing/global/images/xds-test-server-2 \
+    --source_image=projects/grpc-testing/global/images/xds-test-server-3 \
     --path_to_server_binary=/java_server/grpc-java/interop-testing/build/install/grpc-interop-testing/bin/xds-test-server \
     --gcp_suffix=$(date '+%s') \
     --verbose \
index c14fd7e..7057ade 100755 (executable)
@@ -65,11 +65,11 @@ bazel build test/cpp/interop:xds_interop_client
 #
 # TODO: remove "path_matching" and "header_matching" from --test_case after
 # they are added into "all".
-GRPC_VERBOSITY=debug GRPC_TRACE=xds_client,xds_resolver,xds_cluster_manager_lb,cds_lb,eds_lb,priority_lb,xds_cluster_impl_lb,weighted_target_lb "$PYTHON" \
+GRPC_VERBOSITY=debug GRPC_TRACE=xds_client,xds_resolver,xds_cluster_manager_lb,cds_lb,xds_cluster_resolver_lb,priority_lb,xds_cluster_impl_lb,weighted_target_lb "$PYTHON" \
   tools/run_tests/run_xds_tests.py \
-    --test_case="all,path_matching,header_matching" \
+    --test_case="all,path_matching,header_matching,circuit_breaking" \
     --project_id=grpc-testing \
-    --source_image=projects/grpc-testing/global/images/xds-test-server-2 \
+    --source_image=projects/grpc-testing/global/images/xds-test-server-3 \
     --path_to_server_binary=/java_server/grpc-java/interop-testing/build/install/grpc-interop-testing/bin/xds-test-server \
     --gcp_suffix=$(date '+%s') \
     --verbose \
index 36c4c88..83a539d 100755 (executable)
@@ -65,7 +65,7 @@ python tools/run_tests/run_tests.py -l csharp -c opt --build_only
 #
 # TODO(jtattermusch): remove "path_matching" and "header_matching" from
 # --test_case after they are added into "all".
-GRPC_VERBOSITY=debug GRPC_TRACE=xds_client,xds_resolver,xds_cluster_manager_lb,cds_lb,eds_lb,priority_lb,xds_cluster_impl_lb,weighted_target_lb "$PYTHON" \
+GRPC_VERBOSITY=debug GRPC_TRACE=xds_client,xds_resolver,xds_cluster_manager_lb,cds_lb,xds_cluster_resolver_lb,priority_lb,xds_cluster_impl_lb,weighted_target_lb "$PYTHON" \
   tools/run_tests/run_xds_tests.py \
     --test_case="all,path_matching,header_matching" \
     --project_id=grpc-testing \
index bcb72cf..125f6a5 100755 (executable)
@@ -70,7 +70,7 @@ export CC=/usr/bin/gcc
   composer install && \
   ./bin/generate_proto_php.sh)
 
-GRPC_VERBOSITY=debug GRPC_TRACE=xds_client,xds_resolver,xds_cluster_manager_lb,cds_lb,eds_lb,priority_lb,xds_cluster_impl_lb,weighted_target_lb "$PYTHON" \
+GRPC_VERBOSITY=debug GRPC_TRACE=xds_client,xds_resolver,xds_cluster_manager_lb,cds_lb,xds_cluster_resolver_lb,priority_lb,xds_cluster_impl_lb,weighted_target_lb "$PYTHON" \
   tools/run_tests/run_xds_tests.py \
   --test_case="all,path_matching,header_matching" \
   --project_id=grpc-testing \
index 1b22193..e1df497 100644 (file)
@@ -20,7 +20,7 @@ cd $(dirname $0)/../../..
 
 source tools/internal_ci/helper_scripts/prepare_build_linux_rc
 
-export DOCKERFILE_DIR=tools/dockerfile/test/ruby_jessie_x64
+export DOCKERFILE_DIR=tools/dockerfile/test/ruby_buster_x64
 export DOCKER_RUN_SCRIPT=tools/internal_ci/linux/grpc_xds_ruby_test_in_docker.sh
 export OUTPUT_DIR=reports
 exec tools/run_tests/dockerize/build_and_run_docker.sh
index 47ead81..b7b7455 100644 (file)
@@ -60,11 +60,11 @@ touch "$TOOLS_DIR"/src/proto/grpc/health/v1/__init__.py
 
 (cd src/ruby && bundle && rake compile)
 
-GRPC_VERBOSITY=debug GRPC_TRACE=xds_client,xds_resolver,xds_cluster_manager_lb,cds_lb,eds_lb,priority_lb,xds_cluster_impl_lb,weighted_target_lb "$PYTHON" \
+GRPC_VERBOSITY=debug GRPC_TRACE=xds_client,xds_resolver,xds_cluster_manager_lb,cds_lb,xds_cluster_resolver_lb,priority_lb,xds_cluster_impl_lb,weighted_target_lb "$PYTHON" \
   tools/run_tests/run_xds_tests.py \
-    --test_case="all,path_matching,header_matching" \
+    --test_case="all,path_matching,header_matching,circuit_breaking" \
     --project_id=grpc-testing \
-    --source_image=projects/grpc-testing/global/images/xds-test-server-2 \
+    --source_image=projects/grpc-testing/global/images/xds-test-server-3 \
     --path_to_server_binary=/java_server/grpc-java/interop-testing/build/install/grpc-interop-testing/bin/xds-test-server \
     --gcp_suffix=$(date '+%s') \
     --verbose \
index a878434..65397a7 100644 (file)
@@ -14,7 +14,7 @@
 
 @rem TODO(jtattermusch): make this generate less output
 @rem TODO(jtattermusch): use tools/bazel script to keep the versions in sync
-choco install bazel -y --version 2.2.0 --limit-output
+choco install bazel -y --version 3.7.1 --limit-output
 
 cd github/grpc
 set PATH=C:\tools\msys64\usr\bin;C:\Python27;%PATH%
index f3f7bb9..16e1ebd 100644 (file)
@@ -109,6 +109,7 @@ LANG_RELEASE_MATRIX = {
             ('v1.31.1', ReleaseInfo(testcases_file='cxx__v1.31.1')),
             ('v1.32.0', ReleaseInfo()),
             ('v1.33.2', ReleaseInfo()),
+            ('v1.34.0', ReleaseInfo()),
         ]),
     'go':
         OrderedDict([
@@ -150,20 +151,35 @@ LANG_RELEASE_MATRIX = {
              ReleaseInfo(runtimes=['go1.11'], testcases_file='go__v1.0.5')),
             ('v1.19.0',
              ReleaseInfo(runtimes=['go1.11'], testcases_file='go__v1.0.5')),
-            ('v1.20.0', ReleaseInfo(runtimes=['go1.11'])),
-            ('v1.21.3', ReleaseInfo(runtimes=['go1.11'])),
-            ('v1.22.3', ReleaseInfo(runtimes=['go1.11'])),
-            ('v1.23.1', ReleaseInfo(runtimes=['go1.11'])),
-            ('v1.24.0', ReleaseInfo(runtimes=['go1.11'])),
-            ('v1.25.0', ReleaseInfo(runtimes=['go1.11'])),
-            ('v1.26.0', ReleaseInfo(runtimes=['go1.11'])),
-            ('v1.27.1', ReleaseInfo(runtimes=['go1.11'])),
-            ('v1.28.0', ReleaseInfo(runtimes=['go1.11'])),
-            ('v1.29.0', ReleaseInfo(runtimes=['go1.11'])),
-            ('v1.30.0', ReleaseInfo(runtimes=['go1.11'])),
-            ('v1.31.1', ReleaseInfo(runtimes=['go1.11'])),
-            ('v1.32.0', ReleaseInfo(runtimes=['go1.11'])),
-            ('v1.33.1', ReleaseInfo(runtimes=['go1.11'])),
+            ('v1.20.0',
+             ReleaseInfo(runtimes=['go1.11'], testcases_file='go__v1.20.0')),
+            ('v1.21.3',
+             ReleaseInfo(runtimes=['go1.11'], testcases_file='go__v1.20.0')),
+            ('v1.22.3',
+             ReleaseInfo(runtimes=['go1.11'], testcases_file='go__v1.20.0')),
+            ('v1.23.1',
+             ReleaseInfo(runtimes=['go1.11'], testcases_file='go__v1.20.0')),
+            ('v1.24.0',
+             ReleaseInfo(runtimes=['go1.11'], testcases_file='go__v1.20.0')),
+            ('v1.25.0',
+             ReleaseInfo(runtimes=['go1.11'], testcases_file='go__v1.20.0')),
+            ('v1.26.0',
+             ReleaseInfo(runtimes=['go1.11'], testcases_file='go__v1.20.0')),
+            ('v1.27.1',
+             ReleaseInfo(runtimes=['go1.11'], testcases_file='go__v1.20.0')),
+            ('v1.28.0',
+             ReleaseInfo(runtimes=['go1.11'], testcases_file='go__v1.20.0')),
+            ('v1.29.0',
+             ReleaseInfo(runtimes=['go1.11'], testcases_file='go__v1.20.0')),
+            ('v1.30.0',
+             ReleaseInfo(runtimes=['go1.11'], testcases_file='go__v1.20.0')),
+            ('v1.31.1',
+             ReleaseInfo(runtimes=['go1.11'], testcases_file='go__v1.20.0')),
+            ('v1.32.0',
+             ReleaseInfo(runtimes=['go1.11'], testcases_file='go__v1.20.0')),
+            ('v1.33.1',
+             ReleaseInfo(runtimes=['go1.11'], testcases_file='go__v1.20.0')),
+            ('v1.34.0', ReleaseInfo(runtimes=['go1.11'])),
         ]),
     'java':
         OrderedDict([
@@ -231,6 +247,7 @@ LANG_RELEASE_MATRIX = {
             ('v1.31.1', ReleaseInfo()),
             ('v1.32.2', ReleaseInfo()),
             ('v1.33.1', ReleaseInfo()),
+            ('v1.34.1', ReleaseInfo()),
         ]),
     'python':
         OrderedDict([
@@ -290,6 +307,7 @@ LANG_RELEASE_MATRIX = {
             ('v1.31.1', ReleaseInfo(runtimes=['python'])),
             ('v1.32.0', ReleaseInfo(runtimes=['python'])),
             ('v1.33.2', ReleaseInfo(runtimes=['python'])),
+            ('v1.34.0', ReleaseInfo(runtimes=['python'])),
         ]),
     'node':
         OrderedDict([
@@ -352,6 +370,7 @@ LANG_RELEASE_MATRIX = {
             ('v1.31.1', ReleaseInfo()),
             ('v1.32.0', ReleaseInfo()),
             ('v1.33.2', ReleaseInfo()),
+            ('v1.34.0', ReleaseInfo()),
         ]),
     'php':
         OrderedDict([
@@ -387,6 +406,7 @@ LANG_RELEASE_MATRIX = {
             ('v1.31.1', ReleaseInfo()),
             ('v1.32.0', ReleaseInfo()),
             ('v1.33.2', ReleaseInfo()),
+            ('v1.34.0', ReleaseInfo()),
         ]),
     'csharp':
         OrderedDict([
@@ -427,5 +447,6 @@ LANG_RELEASE_MATRIX = {
             ('v1.31.1', ReleaseInfo()),
             ('v1.32.0', ReleaseInfo()),
             ('v1.33.2', ReleaseInfo()),
+            ('v1.34.0', ReleaseInfo()),
         ]),
 }
index ab83d6b..fa679f8 100755 (executable)
@@ -1,22 +1,22 @@
 #!/bin/bash
 # DO NOT MODIFY
 # This file is generated by run_interop_tests.py/create_testcases.sh
-echo "Testing ${docker_image:=grpc_interop_go:45617187-1a75-4f2f-b7af-c602d882bbc0}"
-docker run -i --rm=true -w /go/src/google.golang.org/grpc/interop/client --net=host $docker_image bash -c "go run client.go --server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=large_unary --use_tls=true"
-docker run -i --rm=true -w /go/src/google.golang.org/grpc/interop/client --net=host $docker_image bash -c "go run client.go --server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=empty_unary --use_tls=true"
-docker run -i --rm=true -w /go/src/google.golang.org/grpc/interop/client --net=host $docker_image bash -c "go run client.go --server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=ping_pong --use_tls=true"
-docker run -i --rm=true -w /go/src/google.golang.org/grpc/interop/client --net=host $docker_image bash -c "go run client.go --server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=empty_stream --use_tls=true"
-docker run -i --rm=true -w /go/src/google.golang.org/grpc/interop/client --net=host $docker_image bash -c "go run client.go --server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=client_streaming --use_tls=true"
-docker run -i --rm=true -w /go/src/google.golang.org/grpc/interop/client --net=host $docker_image bash -c "go run client.go --server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=server_streaming --use_tls=true"
-docker run -i --rm=true -w /go/src/google.golang.org/grpc/interop/client --net=host $docker_image bash -c "go run client.go --server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=cancel_after_begin --use_tls=true"
-docker run -i --rm=true -w /go/src/google.golang.org/grpc/interop/client --net=host $docker_image bash -c "go run client.go --server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=cancel_after_first_response --use_tls=true"
-docker run -i --rm=true -w /go/src/google.golang.org/grpc/interop/client --net=host $docker_image bash -c "go run client.go --server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=timeout_on_sleeping_server --use_tls=true"
-docker run -i --rm=true -w /go/src/google.golang.org/grpc/interop/client --net=host $docker_image bash -c "go run client.go --server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=large_unary --use_tls=true"
-docker run -i --rm=true -w /go/src/google.golang.org/grpc/interop/client --net=host $docker_image bash -c "go run client.go --server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=empty_unary --use_tls=true"
-docker run -i --rm=true -w /go/src/google.golang.org/grpc/interop/client --net=host $docker_image bash -c "go run client.go --server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=ping_pong --use_tls=true"
-docker run -i --rm=true -w /go/src/google.golang.org/grpc/interop/client --net=host $docker_image bash -c "go run client.go --server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=empty_stream --use_tls=true"
-docker run -i --rm=true -w /go/src/google.golang.org/grpc/interop/client --net=host $docker_image bash -c "go run client.go --server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=client_streaming --use_tls=true"
-docker run -i --rm=true -w /go/src/google.golang.org/grpc/interop/client --net=host $docker_image bash -c "go run client.go --server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=server_streaming --use_tls=true"
-docker run -i --rm=true -w /go/src/google.golang.org/grpc/interop/client --net=host $docker_image bash -c "go run client.go --server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=cancel_after_begin --use_tls=true"
-docker run -i --rm=true -w /go/src/google.golang.org/grpc/interop/client --net=host $docker_image bash -c "go run client.go --server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=cancel_after_first_response --use_tls=true"
-docker run -i --rm=true -w /go/src/google.golang.org/grpc/interop/client --net=host $docker_image bash -c "go run client.go --server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=timeout_on_sleeping_server --use_tls=true"
+echo "Testing ${docker_image:=grpc_interop_go:fea70d36-60ef-4497-ab63-5426093a34b2}"
+docker run -i --rm=true -e GO111MODULE=on -w /go/src/google.golang.org/grpc/interop/client --net=host $docker_image bash -c "go run client.go --server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=large_unary --use_tls=true"
+docker run -i --rm=true -e GO111MODULE=on -w /go/src/google.golang.org/grpc/interop/client --net=host $docker_image bash -c "go run client.go --server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=empty_unary --use_tls=true"
+docker run -i --rm=true -e GO111MODULE=on -w /go/src/google.golang.org/grpc/interop/client --net=host $docker_image bash -c "go run client.go --server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=ping_pong --use_tls=true"
+docker run -i --rm=true -e GO111MODULE=on -w /go/src/google.golang.org/grpc/interop/client --net=host $docker_image bash -c "go run client.go --server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=empty_stream --use_tls=true"
+docker run -i --rm=true -e GO111MODULE=on -w /go/src/google.golang.org/grpc/interop/client --net=host $docker_image bash -c "go run client.go --server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=client_streaming --use_tls=true"
+docker run -i --rm=true -e GO111MODULE=on -w /go/src/google.golang.org/grpc/interop/client --net=host $docker_image bash -c "go run client.go --server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=server_streaming --use_tls=true"
+docker run -i --rm=true -e GO111MODULE=on -w /go/src/google.golang.org/grpc/interop/client --net=host $docker_image bash -c "go run client.go --server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=cancel_after_begin --use_tls=true"
+docker run -i --rm=true -e GO111MODULE=on -w /go/src/google.golang.org/grpc/interop/client --net=host $docker_image bash -c "go run client.go --server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=cancel_after_first_response --use_tls=true"
+docker run -i --rm=true -e GO111MODULE=on -w /go/src/google.golang.org/grpc/interop/client --net=host $docker_image bash -c "go run client.go --server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=timeout_on_sleeping_server --use_tls=true"
+docker run -i --rm=true -e GO111MODULE=on -w /go/src/google.golang.org/grpc/interop/client --net=host $docker_image bash -c "go run client.go --server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=large_unary --use_tls=true"
+docker run -i --rm=true -e GO111MODULE=on -w /go/src/google.golang.org/grpc/interop/client --net=host $docker_image bash -c "go run client.go --server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=empty_unary --use_tls=true"
+docker run -i --rm=true -e GO111MODULE=on -w /go/src/google.golang.org/grpc/interop/client --net=host $docker_image bash -c "go run client.go --server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=ping_pong --use_tls=true"
+docker run -i --rm=true -e GO111MODULE=on -w /go/src/google.golang.org/grpc/interop/client --net=host $docker_image bash -c "go run client.go --server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=empty_stream --use_tls=true"
+docker run -i --rm=true -e GO111MODULE=on -w /go/src/google.golang.org/grpc/interop/client --net=host $docker_image bash -c "go run client.go --server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=client_streaming --use_tls=true"
+docker run -i --rm=true -e GO111MODULE=on -w /go/src/google.golang.org/grpc/interop/client --net=host $docker_image bash -c "go run client.go --server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=server_streaming --use_tls=true"
+docker run -i --rm=true -e GO111MODULE=on -w /go/src/google.golang.org/grpc/interop/client --net=host $docker_image bash -c "go run client.go --server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=cancel_after_begin --use_tls=true"
+docker run -i --rm=true -e GO111MODULE=on -w /go/src/google.golang.org/grpc/interop/client --net=host $docker_image bash -c "go run client.go --server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=cancel_after_first_response --use_tls=true"
+docker run -i --rm=true -e GO111MODULE=on -w /go/src/google.golang.org/grpc/interop/client --net=host $docker_image bash -c "go run client.go --server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=timeout_on_sleeping_server --use_tls=true"
diff --git a/tools/interop_matrix/testcases/go__v1.20.0 b/tools/interop_matrix/testcases/go__v1.20.0
new file mode 100755 (executable)
index 0000000..ab83d6b
--- /dev/null
@@ -0,0 +1,22 @@
+#!/bin/bash
+# DO NOT MODIFY
+# This file is generated by run_interop_tests.py/create_testcases.sh
+echo "Testing ${docker_image:=grpc_interop_go:45617187-1a75-4f2f-b7af-c602d882bbc0}"
+docker run -i --rm=true -w /go/src/google.golang.org/grpc/interop/client --net=host $docker_image bash -c "go run client.go --server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=large_unary --use_tls=true"
+docker run -i --rm=true -w /go/src/google.golang.org/grpc/interop/client --net=host $docker_image bash -c "go run client.go --server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=empty_unary --use_tls=true"
+docker run -i --rm=true -w /go/src/google.golang.org/grpc/interop/client --net=host $docker_image bash -c "go run client.go --server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=ping_pong --use_tls=true"
+docker run -i --rm=true -w /go/src/google.golang.org/grpc/interop/client --net=host $docker_image bash -c "go run client.go --server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=empty_stream --use_tls=true"
+docker run -i --rm=true -w /go/src/google.golang.org/grpc/interop/client --net=host $docker_image bash -c "go run client.go --server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=client_streaming --use_tls=true"
+docker run -i --rm=true -w /go/src/google.golang.org/grpc/interop/client --net=host $docker_image bash -c "go run client.go --server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=server_streaming --use_tls=true"
+docker run -i --rm=true -w /go/src/google.golang.org/grpc/interop/client --net=host $docker_image bash -c "go run client.go --server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=cancel_after_begin --use_tls=true"
+docker run -i --rm=true -w /go/src/google.golang.org/grpc/interop/client --net=host $docker_image bash -c "go run client.go --server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=cancel_after_first_response --use_tls=true"
+docker run -i --rm=true -w /go/src/google.golang.org/grpc/interop/client --net=host $docker_image bash -c "go run client.go --server_host=grpc-test.sandbox.googleapis.com --server_port=443 --test_case=timeout_on_sleeping_server --use_tls=true"
+docker run -i --rm=true -w /go/src/google.golang.org/grpc/interop/client --net=host $docker_image bash -c "go run client.go --server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=large_unary --use_tls=true"
+docker run -i --rm=true -w /go/src/google.golang.org/grpc/interop/client --net=host $docker_image bash -c "go run client.go --server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=empty_unary --use_tls=true"
+docker run -i --rm=true -w /go/src/google.golang.org/grpc/interop/client --net=host $docker_image bash -c "go run client.go --server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=ping_pong --use_tls=true"
+docker run -i --rm=true -w /go/src/google.golang.org/grpc/interop/client --net=host $docker_image bash -c "go run client.go --server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=empty_stream --use_tls=true"
+docker run -i --rm=true -w /go/src/google.golang.org/grpc/interop/client --net=host $docker_image bash -c "go run client.go --server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=client_streaming --use_tls=true"
+docker run -i --rm=true -w /go/src/google.golang.org/grpc/interop/client --net=host $docker_image bash -c "go run client.go --server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=server_streaming --use_tls=true"
+docker run -i --rm=true -w /go/src/google.golang.org/grpc/interop/client --net=host $docker_image bash -c "go run client.go --server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=cancel_after_begin --use_tls=true"
+docker run -i --rm=true -w /go/src/google.golang.org/grpc/interop/client --net=host $docker_image bash -c "go run client.go --server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=cancel_after_first_response --use_tls=true"
+docker run -i --rm=true -w /go/src/google.golang.org/grpc/interop/client --net=host $docker_image bash -c "go run client.go --server_host=grpc-test4.sandbox.googleapis.com --server_port=443 --test_case=timeout_on_sleeping_server --use_tls=true"
index 81e183b..3dd4dbe 100755 (executable)
@@ -38,33 +38,36 @@ argp.add_argument('-j', '--jobs', type=int, default=multiprocessing.cpu_count())
 
 args = argp.parse_args()
 
+# the libraries for which check bloat difference is calculated
 LIBS = [
     'libgrpc.so',
     'libgrpc++.so',
 ]
 
 
-def build(where):
-    subprocess.check_call('make -j%d' % args.jobs, shell=True, cwd='.')
-    shutil.rmtree('bloat_diff_%s' % where, ignore_errors=True)
-    os.rename('libs', 'bloat_diff_%s' % where)
+def _build(output_dir):
+    """Perform the cmake build under the output_dir."""
+    shutil.rmtree(output_dir, ignore_errors=True)
+    subprocess.check_call('mkdir -p %s' % output_dir, shell=True, cwd='.')
+    subprocess.check_call(
+        'cmake -DgRPC_BUILD_TESTS=OFF -DBUILD_SHARED_LIBS=ON -DCMAKE_BUILD_TYPE=RelWithDebInfo ..',
+        shell=True,
+        cwd=output_dir)
+    subprocess.check_call('make -j%d' % args.jobs, shell=True, cwd=output_dir)
 
 
-build('new')
+_build('bloat_diff_new')
 
 if args.diff_base:
-    old = 'old'
     where_am_i = subprocess.check_output(
         ['git', 'rev-parse', '--abbrev-ref', 'HEAD']).strip()
+    # checkout the diff base (="old")
     subprocess.check_call(['git', 'checkout', args.diff_base])
     subprocess.check_call(['git', 'submodule', 'update'])
     try:
-        try:
-            build('old')
-        except subprocess.CalledProcessError, e:
-            subprocess.check_call(['make', 'clean'])
-            build('old')
+        _build('bloat_diff_old')
     finally:
+        # restore the original revision (="new")
         subprocess.check_call(['git', 'checkout', where_am_i])
         subprocess.check_call(['git', 'submodule', 'update'])
 
@@ -76,19 +79,19 @@ text = ''
 for lib in LIBS:
     text += '****************************************************************\n\n'
     text += lib + '\n\n'
-    old_version = glob.glob('bloat_diff_old/opt/%s' % lib)
-    new_version = glob.glob('bloat_diff_new/opt/%s' % lib)
+    old_version = glob.glob('bloat_diff_old/%s' % lib)
+    new_version = glob.glob('bloat_diff_new/%s' % lib)
     assert len(new_version) == 1
     cmd = 'third_party/bloaty/bloaty -d compileunits,symbols'
     if old_version:
         assert len(old_version) == 1
         text += subprocess.check_output('%s %s -- %s' %
                                         (cmd, new_version[0], old_version[0]),
-                                        shell=True)
+                                        shell=True).decode()
     else:
         text += subprocess.check_output('%s %s' % (cmd, new_version[0]),
-                                        shell=True)
+                                        shell=True).decode()
     text += '\n\n'
 
-print text
+print(text)
 check_on_pr.check_on_pr('Bloat Difference', '```\n%s\n```' % text)
index 215abce..a8f9013 100644 (file)
@@ -203,7 +203,7 @@ class RubyArtifact:
         return create_jobspec(
             self.name, ['tools/run_tests/artifacts/build_artifact_ruby.sh'],
             use_workspace=True,
-            timeout_seconds=45 * 60)
+            timeout_seconds=60 * 60)
 
 
 class CSharpExtArtifact:
@@ -233,6 +233,7 @@ class CSharpExtArtifact:
             return create_jobspec(
                 self.name,
                 ['tools/run_tests/artifacts/build_artifact_csharp_ios.sh'],
+                timeout_seconds=45 * 60,
                 use_workspace=True)
         elif self.platform == 'windows':
             return create_jobspec(self.name, [
@@ -304,17 +305,9 @@ class ProtocArtifact:
 
     def build_jobspec(self):
         if self.platform != 'windows':
-            cxxflags = '-DNDEBUG %s' % _ARCH_FLAG_MAP[self.arch]
-            ldflags = '%s' % _ARCH_FLAG_MAP[self.arch]
-            if self.platform != 'macos':
-                ldflags += '  -static-libgcc -static-libstdc++ -s'
-            environ = {
-                'CONFIG': 'opt',
-                'CXXFLAGS': cxxflags,
-                'LDFLAGS': ldflags,
-                'PROTOBUF_LDFLAGS_EXTRA': ldflags
-            }
+            environ = {'CXXFLAGS': '', 'LDFLAGS': ''}
             if self.platform == 'linux':
+                environ['LDFLAGS'] += ' -static-libgcc -static-libstdc++ -s'
                 return create_docker_jobspec(
                     self.name,
                     'tools/dockerfile/grpc_artifact_centos6_{}'.format(
index 3b2a89f..1271471 100755 (executable)
@@ -17,7 +17,13 @@ set -ex
 
 cd "$(dirname "$0")/../../.."
 
-EMBED_ZLIB=true PROTOBUF_CONFIG_OPTS=--with-zlib=no make plugins
+mkdir -p cmake/build
+pushd cmake/build
+
+cmake -DgRPC_BUILD_TESTS=OFF -DCMAKE_BUILD_TYPE=Release ../..
+make protoc plugins -j2
+
+popd
 
 mkdir -p "${ARTIFACTS_OUT}"
-cp bins/opt/protobuf/protoc bins/opt/*_plugin "${ARTIFACTS_OUT}"/
+cp cmake/build/third_party/protobuf/protoc cmake/build/*_plugin "${ARTIFACTS_OUT}"/
index c2df322..fcd4e74 100644 (file)
@@ -363,12 +363,12 @@ def targets():
         RubyDistribTest('linux', 'x64', 'jessie', ruby_version='ruby_2_5'),
         RubyDistribTest('linux', 'x64', 'jessie', ruby_version='ruby_2_6'),
         RubyDistribTest('linux', 'x64', 'jessie', ruby_version='ruby_2_7'),
+        # TODO(apolcyn): add a ruby 3.0 test once protobuf adds support
         RubyDistribTest('linux',
                         'x64',
                         'jessie',
                         ruby_version='ruby_2_3',
                         source=True),
-        RubyDistribTest('linux', 'x64', 'centos6'),
         RubyDistribTest('linux', 'x64', 'centos7'),
         RubyDistribTest('linux', 'x64', 'fedora23'),
         RubyDistribTest('linux', 'x64', 'opensuse'),
index 61ac2ff..48bfe19 100644 (file)
     "flaky": false,
     "gtest": false,
     "language": "c",
+    "name": "concurrent_connectivity_test",
+    "platforms": [
+      "linux",
+      "mac",
+      "posix",
+      "windows"
+    ],
+    "uses_polling": true
+  },
+  {
+    "args": [],
+    "benchmark": false,
+    "ci_platforms": [
+      "linux",
+      "mac",
+      "posix",
+      "windows"
+    ],
+    "cpu_cost": 1.0,
+    "exclude_configs": [],
+    "exclude_iomgrs": [],
+    "flaky": false,
+    "gtest": false,
+    "language": "c",
     "name": "connection_refused_test",
     "platforms": [
       "linux",
     "flaky": false,
     "gtest": false,
     "language": "c",
-    "name": "log_test",
-    "platforms": [
-      "linux",
-      "mac",
-      "posix",
-      "windows"
-    ],
-    "uses_polling": false
-  },
-  {
-    "args": [],
-    "benchmark": false,
-    "ci_platforms": [
-      "linux",
-      "mac",
-      "posix",
-      "windows"
-    ],
-    "cpu_cost": 1.0,
-    "exclude_configs": [],
-    "exclude_iomgrs": [],
-    "flaky": false,
-    "gtest": false,
-    "language": "c",
     "name": "manual_constructor_test",
     "platforms": [
       "linux",
     "flaky": false,
     "gtest": false,
     "language": "c",
-    "name": "uri_parser_test",
-    "platforms": [
-      "linux",
-      "mac",
-      "posix",
-      "windows"
-    ],
-    "uses_polling": true
-  },
-  {
-    "args": [],
-    "benchmark": false,
-    "ci_platforms": [
-      "linux",
-      "mac",
-      "posix",
-      "windows"
-    ],
-    "cpu_cost": 1.0,
-    "exclude_configs": [],
-    "exclude_iomgrs": [],
-    "flaky": false,
-    "gtest": false,
-    "language": "c",
     "name": "useful_test",
     "platforms": [
       "linux",
     "flaky": false,
     "gtest": true,
     "language": "c++",
+    "name": "cancel_ares_query_test",
+    "platforms": [
+      "linux",
+      "mac",
+      "posix",
+      "windows"
+    ],
+    "uses_polling": true
+  },
+  {
+    "args": [],
+    "benchmark": false,
+    "ci_platforms": [
+      "linux",
+      "mac",
+      "posix",
+      "windows"
+    ],
+    "cpu_cost": 1.0,
+    "exclude_configs": [],
+    "exclude_iomgrs": [],
+    "flaky": false,
+    "gtest": true,
+    "language": "c++",
     "name": "certificate_provider_registry_test",
     "platforms": [
       "linux",
     "flaky": false,
     "gtest": true,
     "language": "c++",
+    "name": "grpc_tls_certificate_provider_test",
+    "platforms": [
+      "linux",
+      "mac",
+      "posix",
+      "windows"
+    ],
+    "uses_polling": true
+  },
+  {
+    "args": [],
+    "benchmark": false,
+    "ci_platforms": [
+      "linux",
+      "mac",
+      "posix",
+      "windows"
+    ],
+    "cpu_cost": 1.0,
+    "exclude_configs": [],
+    "exclude_iomgrs": [],
+    "flaky": false,
+    "gtest": true,
+    "language": "c++",
     "name": "grpc_tls_credentials_options_test",
     "platforms": [
       "linux",
     "flaky": false,
     "gtest": true,
     "language": "c++",
+    "name": "log_test",
+    "platforms": [
+      "linux",
+      "mac",
+      "posix",
+      "windows"
+    ],
+    "uses_polling": false
+  },
+  {
+    "args": [],
+    "benchmark": false,
+    "ci_platforms": [
+      "linux",
+      "mac",
+      "posix",
+      "windows"
+    ],
+    "cpu_cost": 1.0,
+    "exclude_configs": [],
+    "exclude_iomgrs": [],
+    "flaky": false,
+    "gtest": true,
+    "language": "c++",
     "name": "message_allocator_end2end_test",
     "platforms": [
       "linux",
     "flaky": false,
     "gtest": true,
     "language": "c++",
+    "name": "stranded_event_test",
+    "platforms": [
+      "linux",
+      "mac",
+      "posix"
+    ],
+    "uses_polling": true
+  },
+  {
+    "args": [],
+    "benchmark": false,
+    "ci_platforms": [
+      "linux",
+      "mac",
+      "posix"
+    ],
+    "cpu_cost": 1.0,
+    "exclude_configs": [],
+    "exclude_iomgrs": [],
+    "flaky": false,
+    "gtest": true,
+    "language": "c++",
     "name": "streaming_throughput_test",
     "platforms": [
       "linux",
     "flaky": false,
     "gtest": true,
     "language": "c++",
+    "name": "uri_parser_test",
+    "platforms": [
+      "linux",
+      "mac",
+      "posix",
+      "windows"
+    ],
+    "uses_polling": true
+  },
+  {
+    "args": [],
+    "benchmark": false,
+    "ci_platforms": [
+      "linux",
+      "mac",
+      "posix",
+      "windows"
+    ],
+    "cpu_cost": 1.0,
+    "exclude_configs": [],
+    "exclude_iomgrs": [],
+    "flaky": false,
+    "gtest": true,
+    "language": "c++",
     "name": "window_overflow_bad_client_test",
     "platforms": [
       "linux",
   },
   {
     "args": [],
+    "benchmark": false,
+    "ci_platforms": [
+      "linux",
+      "mac",
+      "posix",
+      "windows"
+    ],
+    "cpu_cost": 1.0,
+    "exclude_configs": [],
+    "exclude_iomgrs": [],
+    "flaky": false,
+    "gtest": true,
+    "language": "c++",
+    "name": "xds_credentials_test",
+    "platforms": [
+      "linux",
+      "mac",
+      "posix",
+      "windows"
+    ],
+    "uses_polling": true
+  },
+  {
+    "args": [],
     "boringssl": true,
     "ci_platforms": [
       "linux",
index 38f99d8..cc1fe92 100755 (executable)
 set -ex
 
 export GRPC_CONFIG=${CONFIG:-opt}
+if [ "${GRPC_CONFIG}" == "dbg" ]
+then
+  CMAKE_CONFIG=Debug
+else
+  CMAKE_CONFIG=Release
+fi
 
 # change to grpc's ruby directory
 cd "$(dirname "$0")/../../.."
@@ -25,4 +31,12 @@ rm -rf ./tmp
 rake compile
 
 # build grpc_ruby_plugin
-make grpc_ruby_plugin -j8
+mkdir -p cmake/build
+pushd cmake/build
+cmake -DgRPC_BUILD_TESTS=OFF -DCMAKE_BUILD_TYPE=${CMAKE_CONFIG} ../..
+make protoc grpc_ruby_plugin -j2
+popd
+
+# unbreak subsequent make builds by restoring zconf.h (previously renamed by cmake build)
+# see https://github.com/madler/zlib/issues/133
+(cd third_party/zlib; git checkout zconf.h)
diff --git a/tools/run_tests/performance/scenario_config_exporter.py b/tools/run_tests/performance/scenario_config_exporter.py
new file mode 100755 (executable)
index 0000000..23aad5c
--- /dev/null
@@ -0,0 +1,61 @@
+#!/usr/bin/env python3
+
+# Copyright 2020 The 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.
+
+# Helper script to extract JSON scenario definitions from scenario_config.py
+# Useful to construct "ScenariosJSON" configuration accepted by the OSS benchmarks framework
+# See https://github.com/grpc/test-infra/blob/master/config/samples/cxx_example_loadtest.yaml
+
+import json
+import re
+import scenario_config
+import sys
+
+
+def get_json_scenarios(language_name, scenario_name_regex='.*', category='all'):
+    """Returns list of scenarios that match given constraints."""
+    result = []
+    scenarios = scenario_config.LANGUAGES[language_name].scenarios()
+    for scenario_json in scenarios:
+        if re.search(scenario_name_regex, scenario_json['name']):
+            # if the 'CATEGORIES' key is missing, treat scenario as part of 'scalable' and 'smoketest'
+            # this matches the behavior of run_performance_tests.py
+            scenario_categories = scenario_json.get('CATEGORIES',
+                                                    ['scalable', 'smoketest'])
+            # TODO(jtattermusch): consider adding filtering for 'CLIENT_LANGUAGE' and 'SERVER_LANGUAGE'
+            # fields, before the get stripped away.
+            if category in scenario_categories or category == 'all':
+                scenario_json_stripped = scenario_config.remove_nonproto_fields(
+                    scenario_json)
+                result.append(scenario_json_stripped)
+    return result
+
+
+def dump_to_json_files(json_scenarios, filename_prefix='scenario_dump_'):
+    """Dump a list of json scenarios to json files"""
+    for scenario in json_scenarios:
+        filename = "%s%s.json" % (filename_prefix, scenario['name'])
+        print('Writing file %s' % filename, file=sys.stderr)
+        with open(filename, 'w') as outfile:
+            # the dump file should have {"scenarios" : []} as the top level element
+            json.dump({'scenarios': [scenario]}, outfile, indent=2)
+
+
+if __name__ == "__main__":
+    # example usage: extract C# scenarios and dump them as .json files
+    scenarios = get_json_scenarios('csharp',
+                                   scenario_name_regex='.*',
+                                   category='scalable')
+    dump_to_json_files(scenarios, 'scenario_dump_')
index ac462df..d87a2f2 100755 (executable)
@@ -648,7 +648,7 @@ class PythonLanguage(object):
         return [
             self.config.job_spec(
                 config.run,
-                timeout_seconds=5 * 60,
+                timeout_seconds=8 * 60,
                 environ=dict(GRPC_PYTHON_TESTRUNNER_FILTER=str(suite_name),
                              **environment),
                 shortname='%s.%s.%s' %
@@ -893,7 +893,7 @@ class RubyLanguage(object):
         return 'Makefile'
 
     def dockerfile_dir(self):
-        return 'tools/dockerfile/test/ruby_jessie_%s' % _docker_arch_suffix(
+        return 'tools/dockerfile/test/ruby_buster_%s' % _docker_arch_suffix(
             self.args.arch)
 
     def __str__(self):
index 1fca4de..6b397d4 100755 (executable)
@@ -277,7 +277,8 @@ _TESTS_TO_RUN_MULTIPLE_RPCS = ['path_matching', 'header_matching']
 # Tests that make UnaryCall with test metadata.
 _TESTS_TO_SEND_METADATA = ['header_matching']
 _TEST_METADATA_KEY = 'xds_md'
-_TEST_METADATA_VALUE = 'exact_match'
+_TEST_METADATA_VALUE_UNARY = 'unary_yranu'
+_TEST_METADATA_VALUE_EMPTY = 'empty_ytpme'
 _PATH_MATCHER_NAME = 'path-matcher'
 _BASE_TEMPLATE_NAME = 'test-template'
 _BASE_INSTANCE_GROUP_NAME = 'test-ig'
@@ -431,6 +432,7 @@ def wait_until_rpcs_in_flight(rpc_type, timeout_sec, num_rpcs, threshold):
         error_msg = _check_rpcs_in_flight(rpc_type, num_rpcs, threshold,
                                           threshold_fraction)
         if error_msg:
+            logger.debug('Progress: %s', error_msg)
             time.sleep(2)
         else:
             break
@@ -1024,25 +1026,85 @@ def test_header_matching(gcp, original_backend_service, instance_group,
 
     try:
         # A list of tuples (route_rules, expected_instances).
-        test_cases = [(
-            [{
-                'priority': 0,
-                # Header ExactMatch -> alternate_backend_service.
-                # EmptyCall is sent with the metadata.
-                'matchRules': [{
-                    'prefixMatch':
-                        '/',
-                    'headerMatches': [{
-                        'headerName': _TEST_METADATA_KEY,
-                        'exactMatch': _TEST_METADATA_VALUE
-                    }]
+        test_cases = [
+            (
+                [{
+                    'priority': 0,
+                    # Header ExactMatch -> alternate_backend_service.
+                    # EmptyCall is sent with the metadata.
+                    'matchRules': [{
+                        'prefixMatch':
+                            '/',
+                        'headerMatches': [{
+                            'headerName': _TEST_METADATA_KEY,
+                            'exactMatch': _TEST_METADATA_VALUE_EMPTY
+                        }]
+                    }],
+                    'service': alternate_backend_service.url
                 }],
-                'service': alternate_backend_service.url
-            }],
-            {
-                "EmptyCall": alternate_backend_instances,
-                "UnaryCall": original_backend_instances
-            })]
+                {
+                    "EmptyCall": alternate_backend_instances,
+                    "UnaryCall": original_backend_instances
+                }),
+            (
+                [{
+                    'priority': 0,
+                    # Header PrefixMatch -> alternate_backend_service.
+                    # UnaryCall is sent with the metadata.
+                    'matchRules': [{
+                        'prefixMatch':
+                            '/',
+                        'headerMatches': [{
+                            'headerName': _TEST_METADATA_KEY,
+                            'prefixMatch': _TEST_METADATA_VALUE_UNARY[:2]
+                        }]
+                    }],
+                    'service': alternate_backend_service.url
+                }],
+                {
+                    "EmptyCall": original_backend_instances,
+                    "UnaryCall": alternate_backend_instances
+                }),
+            (
+                [{
+                    'priority': 0,
+                    # Header SuffixMatch -> alternate_backend_service.
+                    # EmptyCall is sent with the metadata.
+                    'matchRules': [{
+                        'prefixMatch':
+                            '/',
+                        'headerMatches': [{
+                            'headerName': _TEST_METADATA_KEY,
+                            'suffixMatch': _TEST_METADATA_VALUE_EMPTY[-2:]
+                        }]
+                    }],
+                    'service': alternate_backend_service.url
+                }],
+                {
+                    "EmptyCall": alternate_backend_instances,
+                    "UnaryCall": original_backend_instances
+                }),
+            (
+                [{
+                    'priority': 0,
+                    # Header invert ExactMatch -> alternate_backend_service.
+                    # EmptyCall is sent with the metadata, so will be sent to original.
+                    'matchRules': [{
+                        'prefixMatch':
+                            '/',
+                        'headerMatches': [{
+                            'headerName': _TEST_METADATA_KEY,
+                            'exactMatch': _TEST_METADATA_VALUE_EMPTY,
+                            'invertMatch': True
+                        }]
+                    }],
+                    'service': alternate_backend_service.url
+                }],
+                {
+                    "EmptyCall": original_backend_instances,
+                    "UnaryCall": alternate_backend_instances
+                }),
+        ]
 
         for (route_rules, expected_instances) in test_cases:
             logger.info('patching url map with %s -> alternative',
@@ -1059,7 +1121,7 @@ def test_header_matching(gcp, original_backend_service, instance_group,
                 original_backend_instances + alternate_backend_instances,
                 _WAIT_FOR_STATS_SEC)
 
-            retry_count = 10
+            retry_count = 20
             # Each attempt takes about 10 seconds, 10 retries is equivalent to 100
             # seconds timeout.
             for i in range(retry_count):
@@ -1195,11 +1257,15 @@ def test_circuit_breaking(gcp, original_backend_service, instance_group,
             'UNARY_CALL', (_WAIT_FOR_BACKEND_SEC +
                            int(extra_backend_service_max_requests / args.qps)),
             extra_backend_service_max_requests, 1)
+        logger.info('UNARY_CALL reached stable state (%d)',
+                    extra_backend_service_max_requests)
         wait_until_rpcs_in_flight(
             'EMPTY_CALL',
             (_WAIT_FOR_BACKEND_SEC +
              int(more_extra_backend_service_max_requests / args.qps)),
             more_extra_backend_service_max_requests, 1)
+        logger.info('EMPTY_CALL reached stable state (%d)',
+                    more_extra_backend_service_max_requests)
 
         # Increment circuit breakers max_requests threshold.
         extra_backend_service_max_requests = 800
@@ -1213,6 +1279,13 @@ def test_circuit_breaking(gcp, original_backend_service, instance_group,
             'UNARY_CALL', (_WAIT_FOR_BACKEND_SEC +
                            int(extra_backend_service_max_requests / args.qps)),
             extra_backend_service_max_requests, 1)
+        logger.info('UNARY_CALL reached stable state after increase (%d)',
+                    extra_backend_service_max_requests)
+        logger.info('success')
+        # Avoid new RPCs being outstanding (some test clients create threads
+        # for sending RPCs) after restoring backend services.
+        configure_client(
+            [messages_pb2.ClientConfigureRequest.RpcType.UNARY_CALL], [])
     finally:
         patch_url_map_backend_service(gcp, original_backend_service)
         patch_backend_service(gcp, original_backend_service, [instance_group])
@@ -1934,11 +2007,13 @@ try:
     gcp_suffix = args.gcp_suffix
     health_check_name = _BASE_HEALTH_CHECK_NAME + gcp_suffix
     if not args.use_existing_gcp_resources:
-        if gcp_suffix:
-            num_attempts = 5
-        else:
-            # If not given a suffix, do not retry if already in use.
+        if args.keep_gcp_resources:
+            # Auto-generating a unique suffix in case of conflict should not be
+            # combined with --keep_gcp_resources, as the suffix actually used
+            # for GCP resources will not match the provided --gcp_suffix value.
             num_attempts = 1
+        else:
+            num_attempts = 5
         for i in range(num_attempts):
             try:
                 logger.info('Using GCP suffix %s', gcp_suffix)
@@ -2057,8 +2132,11 @@ try:
                 rpcs_to_send = '--rpc="UnaryCall"'
 
             if test_case in _TESTS_TO_SEND_METADATA:
-                metadata_to_send = '--metadata="EmptyCall:{key}:{value}"'.format(
-                    key=_TEST_METADATA_KEY, value=_TEST_METADATA_VALUE)
+                metadata_to_send = '--metadata="EmptyCall:{keyE}:{valueE},UnaryCall:{keyU}:{valueU}"'.format(
+                    keyE=_TEST_METADATA_KEY,
+                    valueE=_TEST_METADATA_VALUE_EMPTY,
+                    keyU=_TEST_METADATA_KEY,
+                    valueU=_TEST_METADATA_VALUE_UNARY)
             else:
                 # Setting the arg explicitly to empty with '--metadata=""'
                 # makes C# client fail
index b73f1f2..4070e63 100755 (executable)
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
 
 # Copyright 2016 gRPC authors.
 #
@@ -14,8 +14,6 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-from __future__ import print_function
-
 import ast
 import os
 import re
@@ -27,8 +25,8 @@ os.chdir(os.path.join(os.path.dirname(sys.argv[0]), '../../..'))
 git_hash_pattern = re.compile('[0-9a-f]{40}')
 
 # Parse git hashes from submodules
-git_submodules = subprocess.check_output('git submodule',
-                                         shell=True).strip().split('\n')
+git_submodules = subprocess.check_output(
+    'git submodule', shell=True).decode().strip().split('\n')
 git_submodule_hashes = {
     re.search(git_hash_pattern, s).group() for s in git_submodules
 }
@@ -148,17 +146,14 @@ build_rules = {
     'git_repository': lambda **args: eval_state.git_repository(**args),
     'grpc_python_deps': lambda: None,
 }
-exec(bazel_file) in build_rules
+exec((bazel_file), build_rules)
 for name in _GRPC_DEP_NAMES:
-    assert name in names_and_urls.keys()
-if len(_GRPC_DEP_NAMES) != len(names_and_urls.keys()):
-    assert False, "Diff: " + (str(set(_GRPC_DEP_NAMES) - set(names_and_urls)) +
-                              "," +
-                              str(set(names_and_urls) - set(_GRPC_DEP_NAMES)))
+    assert name in list(names_and_urls.keys())
+assert len(_GRPC_DEP_NAMES) == len(list(names_and_urls.keys()))
 
 # There are some "bazel-only" deps that are exceptions to this sanity check,
 # we don't require that there is a corresponding git module for these.
-names_without_bazel_only_deps = names_and_urls.keys()
+names_without_bazel_only_deps = list(names_and_urls.keys())
 for dep_name in _GRPC_BAZEL_ONLY_DEPS:
     names_without_bazel_only_deps.remove(dep_name)
 archive_urls = [names_and_urls[name] for name in names_without_bazel_only_deps]
@@ -195,7 +190,7 @@ for name in _GRPC_DEP_NAMES:
         'git_repository': lambda **args: state.git_repository(**args),
         'grpc_python_deps': lambda *args, **kwargs: None,
     }
-    exec(bazel_file) in rules
-    assert name not in names_and_urls_with_overridden_name.keys()
+    exec((bazel_file), rules)
+    assert name not in list(names_and_urls_with_overridden_name.keys())
 
 sys.exit(0)
index 02307fe..64e2080 100755 (executable)
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
 
 # Copyright 2018 gRPC authors.
 #
@@ -14,8 +14,6 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-from __future__ import print_function
-
 import os
 import sys
 
index b1ef137..4b7c92f 100755 (executable)
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
 
 # Copyright 2017 gRPC authors.
 #
@@ -64,6 +64,6 @@ all_bad_files += check_port_platform_inclusion(os.path.join('include', 'grpc'))
 
 if len(all_bad_files) > 0:
     for f in all_bad_files:
-        print(('port_platform.h is not the first included header or there '
-               'is not a blank line following its inclusion in %s') % f)
+        print((('port_platform.h is not the first included header or there '
+                'is not a blank line following its inclusion in %s') % f))
     sys.exit(1)
index 0c63d09..363e6f1 100755 (executable)
@@ -35,7 +35,7 @@ cat << EOF | awk '{ print $1 }' | sort > "$want_submodules"
  80ed4d0bbf65d57cc267dfc63bd2584557f11f9b third_party/googleapis (common-protos-1_3_1-915-g80ed4d0bb)
  c9ccac7cb7345901884aabf5d1a786cfa6e2f397 third_party/googletest (6e2f397)
  15ae750151ac9341e5945eb38f8982d59fb99201 third_party/libuv (v1.34.0)
fde7cf7358ec7cd69e8db9be4f1fa6a5c431386a third_party/protobuf (v3.7.0-rc.2-1277-gfde7cf735)
19fb89416f3fdc2d6668f3738f444885575285bc third_party/protobuf (v3.7.0-rc.2-1277-gfde7cf735)
  e020f3aef8ae6cb59f384bfbaaed72e71e88ccd6 third_party/protoc-gen-validate (v0.4.1)
  aecba11114cf1fac5497aeb844b6966106de3eb6 third_party/re2 (heads/master)
  1f710aca26a95876e64973a6d2a927a9f4b20ca4 third_party/udpa (heads/master)
index 0b6b77e..ea9039f 100755 (executable)
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
 
 # Copyright 2016 gRPC authors.
 #
@@ -67,8 +67,8 @@ class TestFilteringTest(unittest.TestCase):
         filtered_jobs = [
             job for job in filtered_jobs if "sanity" not in job.labels
         ]
-        self.assertEquals(sanity_tests_in_all_jobs,
-                          sanity_tests_in_filtered_jobs)
+        self.assertEqual(sanity_tests_in_all_jobs,
+                         sanity_tests_in_filtered_jobs)
 
         for label in labels:
             for job in filtered_jobs:
@@ -79,8 +79,8 @@ class TestFilteringTest(unittest.TestCase):
             for job in all_jobs:
                 if (label in job.labels):
                     jobs_matching_labels += 1
-        self.assertEquals(len(filtered_jobs),
-                          len(all_jobs) - jobs_matching_labels)
+        self.assertEqual(len(filtered_jobs),
+                         len(all_jobs) - jobs_matching_labels)
 
     def test_individual_language_filters(self):
         # Changing unlisted file should trigger all languages
@@ -152,7 +152,7 @@ class TestFilteringTest(unittest.TestCase):
             'src/core/foo.bar', 'some_file_not_on_the_white_list', 'BUILD',
             'etc/roots.pem', 'Makefile', 'tools/foo'
         ]
-        for key in whitelist.keys():
+        for key in list(whitelist.keys()):
             for file_name in files_that_should_trigger_all_tests:
                 self.assertFalse(re.match(key, file_name))
 
index c4c7653..019e44f 100755 (executable)
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
 
 # Copyright 2017 gRPC authors.
 #
@@ -14,8 +14,6 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-from __future__ import print_function
-
 import os
 import sys
 import re
index d53fa09..5e963c4 100755 (executable)
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
 
 # Copyright 2016 gRPC authors.
 #
@@ -14,8 +14,6 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-from __future__ import print_function
-
 import sys
 import yaml
 import os
@@ -66,7 +64,7 @@ if not check_version(top_version):
     errors += 1
     print(warning % ('version', top_version))
 
-for tag, value in settings.iteritems():
+for tag, value in settings.items():
     if re.match(r'^[a-z]+_version$', tag):
         value = Version(value)
         if tag != 'core_version':
index a551c80..200ff39 100755 (executable)
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
 
 # Copyright 2016 gRPC authors.
 #
@@ -14,8 +14,6 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-from __future__ import print_function
-
 import os
 import sys
 
diff --git a/tools/run_tests/xds_k8s_test_driver/.gitignore b/tools/run_tests/xds_k8s_test_driver/.gitignore
new file mode 100644 (file)
index 0000000..cc78445
--- /dev/null
@@ -0,0 +1,4 @@
+config/local-dev.cfg
+src/proto
+venv/
+out/
diff --git a/tools/run_tests/xds_k8s_test_driver/README.md b/tools/run_tests/xds_k8s_test_driver/README.md
new file mode 100644 (file)
index 0000000..640582b
--- /dev/null
@@ -0,0 +1,96 @@
+# xDS Kubernetes Interop Tests
+
+Proxyless Security Mesh Interop Tests executed on Kubernetes.
+
+### Experimental
+Work in progress. Internal APIs may and will change. Please refrain from making 
+changes to this codebase at the moment.
+
+### Stabilization roadmap 
+- [ ] Replace retrying with tenacity
+- [ ] Generate namespace for each test to prevent resource name conflicts and
+      allow running tests in parallel
+- [ ] Security: run server and client in separate namespaces
+- [ ] Make framework.infrastructure.gcp resources [first-class citizen](https://en.wikipedia.org/wiki/First-class_citizen),
+      support simpler CRUD
+- [ ] Security: manage `roles/iam.workloadIdentityUser` role grant lifecycle
+      for dynamically-named namespaces 
+- [ ] Restructure `framework.test_app` and `framework.xds_k8s*` into a module
+      containing xDS-interop-specific logic
+- [ ] Address inline TODOs in code
+- [ ] Improve README.md documentation, explain helpers in bin/ folder
+
+## Installation
+
+#### Requirements
+1. Python v3.6+
+2. [Google Cloud SDK](https://cloud.google.com/sdk/docs/install)
+
+#### Configure GKE cluster access
+
+```sh
+# Update gloud sdk
+gcloud -q components update
+
+# Configuring GKE cluster access for kubectl
+gcloud container clusters get-credentials "your_gke_cluster_name" --zone "your_gke_cluster_zone"
+
+# Save generated kube context name
+KUBE_CONTEXT="$(kubectl config current-context)"
+``` 
+
+#### Install python dependencies
+
+```sh
+# Create python virtual environment
+python3.6 -m venv venv
+
+# Activate virtual environment
+. ./venv/bin/activate
+
+# Install requirements
+pip install -r requirements.txt
+
+# Generate protos
+python -m grpc_tools.protoc --proto_path=../../../ \
+    --python_out=. --grpc_python_out=. \
+    src/proto/grpc/testing/empty.proto \
+    src/proto/grpc/testing/messages.proto \
+    src/proto/grpc/testing/test.proto
+```
+
+# Basic usage
+
+### xDS Baseline Tests
+
+Test suite meant to confirm that basic xDS features work as expected.
+Executing it before other test suites will help to identify whether test failure
+related to specific features under test, or caused by unrelated infrastructure
+disturbances.
+
+```sh
+# Help
+python -m tests.baseline_test --help
+python -m tests.baseline_test --helpfull
+
+# Run on grpc-testing cluster
+python -m tests.baseline_test \
+  --flagfile="config/grpc-testing.cfg" \
+  --kube_context="${KUBE_CONTEXT}" \
+  --server_image="gcr.io/grpc-testing/xds-k8s-test-server-java:latest" \
+  --client_image="gcr.io/grpc-testing/xds-k8s-test-client-java:latest" \
+```
+
+### xDS Security Tests
+```sh
+# Help
+python -m tests.security_test --help
+python -m tests.security_test --helpfull
+
+# Run on grpc-testing cluster
+python -m tests.security_test \
+  --flagfile="config/grpc-testing.cfg" \
+  --kube_context="${KUBE_CONTEXT}" \
+  --server_image="gcr.io/grpc-testing/xds-k8s-test-server-java:latest" \
+  --client_image="gcr.io/grpc-testing/xds-k8s-test-client-java:latest" \
+```
@@ -1,4 +1,4 @@
-# Copyright 2017 gRPC authors.
+# 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.
 # 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.
-
-# Config file for the internal CI (in protobuf text format)
-
-# Location of the continuous shell script in repository.
-build_file: "grpc/tools/internal_ci/linux/grpc_run_grpclb_interop_tests.sh"
-timeout_mins: 60
-action {
-  define_artifacts {
-    regex: "**/sponge_log.xml"
-    regex: "github/grpc/reports/**"
-  }
-}
diff --git a/tools/run_tests/xds_k8s_test_driver/bin/run_channelz.py b/tools/run_tests/xds_k8s_test_driver/bin/run_channelz.py
new file mode 100755 (executable)
index 0000000..a3ccb3a
--- /dev/null
@@ -0,0 +1,212 @@
+# 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.
+"""Channelz debugging tool for xDS test client/server.
+
+This is intended as a debugging / local development helper and not executed
+as a part of interop test suites.
+
+Typical usage examples:
+
+    # Show channel and server socket pair
+    python -m bin.run_channelz --flagfile=config/local-dev.cfg
+
+    # Evaluate setup for different security configurations
+    python -m bin.run_channelz --flagfile=config/local-dev.cfg --security=tls
+    python -m bin.run_channelz --flagfile=config/local-dev.cfg --security=mtls_error
+
+    # More information and usage options
+    python -m bin.run_channelz --helpfull
+"""
+import hashlib
+import logging
+
+from absl import app
+from absl import flags
+
+from framework import xds_flags
+from framework import xds_k8s_flags
+from framework.infrastructure import k8s
+from framework.rpc import grpc_channelz
+from framework.test_app import client_app
+from framework.test_app import server_app
+
+logger = logging.getLogger(__name__)
+# Flags
+_SERVER_RPC_HOST = flags.DEFINE_string('server_rpc_host',
+                                       default='127.0.0.1',
+                                       help='Server RPC host')
+_CLIENT_RPC_HOST = flags.DEFINE_string('client_rpc_host',
+                                       default='127.0.0.1',
+                                       help='Client RPC host')
+_SECURITY = flags.DEFINE_enum('security',
+                              default=None,
+                              enum_values=[
+                                  'mtls', 'tls', 'plaintext', 'mtls_error',
+                                  'server_authz_error'
+                              ],
+                              help='Show info for a security setup')
+flags.adopt_module_key_flags(xds_flags)
+flags.adopt_module_key_flags(xds_k8s_flags)
+
+# Type aliases
+_Channel = grpc_channelz.Channel
+_Socket = grpc_channelz.Socket
+_ChannelState = grpc_channelz.ChannelState
+_XdsTestServer = server_app.XdsTestServer
+_XdsTestClient = client_app.XdsTestClient
+
+
+def debug_cert(cert):
+    if not cert:
+        return '<missing>'
+    sha1 = hashlib.sha1(cert)
+    return f'sha1={sha1.hexdigest()}, len={len(cert)}'
+
+
+def debug_sock_tls(tls):
+    return (f'local:  {debug_cert(tls.local_certificate)}\n'
+            f'remote: {debug_cert(tls.remote_certificate)}')
+
+
+def get_deployment_pod_ips(k8s_ns, deployment_name):
+    deployment = k8s_ns.get_deployment(deployment_name)
+    pods = k8s_ns.list_deployment_pods(deployment)
+    return [pod.status.pod_ip for pod in pods]
+
+
+def debug_security_setup_negative(test_client):
+    """Debug negative cases: mTLS Error, Server AuthZ error
+
+    1) mTLS Error: Server expects client mTLS cert,
+       but client configured only for TLS.
+    2) AuthZ error: Client does not authorize server because of mismatched
+       SAN name.
+    """
+    # Client side.
+    client_correct_setup = True
+    channel: _Channel = test_client.wait_for_server_channel_state(
+        state=_ChannelState.TRANSIENT_FAILURE)
+    try:
+        subchannel, *subchannels = list(
+            test_client.channelz.list_channel_subchannels(channel))
+    except ValueError:
+        print("Client setup fail: subchannel not found. "
+              "Common causes: test client didn't connect to TD; "
+              "test client exhausted retries, and closed all subchannels.")
+        return
+
+    # Client must have exactly one subchannel.
+    logger.debug('Found subchannel, %s', subchannel)
+    if subchannels:
+        client_correct_setup = False
+        print(f'Unexpected subchannels {subchannels}')
+    subchannel_state: _ChannelState = subchannel.data.state.state
+    if subchannel_state is not _ChannelState.TRANSIENT_FAILURE:
+        client_correct_setup = False
+        print('Subchannel expected to be in '
+              'TRANSIENT_FAILURE, same as its channel')
+
+    # Client subchannel must have no sockets.
+    sockets = list(test_client.channelz.list_subchannels_sockets(subchannel))
+    if sockets:
+        client_correct_setup = False
+        print(f'Unexpected subchannel sockets {sockets}')
+
+    # Results.
+    if client_correct_setup:
+        print('Client setup pass: the channel '
+              'to the server has exactly one subchannel '
+              'in TRANSIENT_FAILURE, and no sockets')
+
+
+def debug_security_setup_positive(test_client, test_server):
+    """Debug positive cases: mTLS, TLS, Plaintext."""
+    test_client.wait_for_active_server_channel()
+    client_sock: _Socket = test_client.get_active_server_channel_socket()
+    server_sock: _Socket = test_server.get_server_socket_matching_client(
+        client_sock)
+
+    server_tls = server_sock.security.tls
+    client_tls = client_sock.security.tls
+
+    print(f'\nServer certs:\n{debug_sock_tls(server_tls)}')
+    print(f'\nClient certs:\n{debug_sock_tls(client_tls)}')
+    print()
+
+    if server_tls.local_certificate:
+        eq = server_tls.local_certificate == client_tls.remote_certificate
+        print(f'(TLS)  Server local matches client remote: {eq}')
+    else:
+        print('(TLS)  Not detected')
+
+    if server_tls.remote_certificate:
+        eq = server_tls.remote_certificate == client_tls.local_certificate
+        print(f'(mTLS) Server remote matches client local: {eq}')
+    else:
+        print('(mTLS) Not detected')
+
+
+def debug_basic_setup(test_client, test_server):
+    """Show channel and server socket pair"""
+    test_client.wait_for_active_server_channel()
+    client_sock: _Socket = test_client.get_active_server_channel_socket()
+    server_sock: _Socket = test_server.get_server_socket_matching_client(
+        client_sock)
+
+    print(f'Client socket:\n{client_sock}\n')
+    print(f'Matching server:\n{server_sock}\n')
+
+
+def main(argv):
+    if len(argv) > 1:
+        raise app.UsageError('Too many command-line arguments.')
+
+    k8s_api_manager = k8s.KubernetesApiManager(xds_k8s_flags.KUBE_CONTEXT.value)
+
+    # Server
+    server_name = xds_flags.SERVER_NAME.value
+    server_namespace = xds_flags.NAMESPACE.value
+    server_k8s_ns = k8s.KubernetesNamespace(k8s_api_manager, server_namespace)
+    server_pod_ip = get_deployment_pod_ips(server_k8s_ns, server_name)[0]
+    test_server: _XdsTestServer = _XdsTestServer(
+        ip=server_pod_ip,
+        rpc_port=xds_flags.SERVER_PORT.value,
+        xds_host=xds_flags.SERVER_XDS_HOST.value,
+        xds_port=xds_flags.SERVER_XDS_PORT.value,
+        rpc_host=_SERVER_RPC_HOST.value)
+
+    # Client
+    client_name = xds_flags.CLIENT_NAME.value
+    client_namespace = xds_flags.NAMESPACE.value
+    client_k8s_ns = k8s.KubernetesNamespace(k8s_api_manager, client_namespace)
+    client_pod_ip = get_deployment_pod_ips(client_k8s_ns, client_name)[0]
+    test_client: _XdsTestClient = _XdsTestClient(
+        ip=client_pod_ip,
+        server_target=test_server.xds_uri,
+        rpc_port=xds_flags.CLIENT_PORT.value,
+        rpc_host=_CLIENT_RPC_HOST.value)
+
+    if _SECURITY.value in ('mtls', 'tls', 'plaintext'):
+        debug_security_setup_positive(test_client, test_server)
+    elif _SECURITY.value == ('mtls_error', 'server_authz_error'):
+        debug_security_setup_negative(test_client)
+    else:
+        debug_basic_setup(test_client, test_server)
+
+    test_client.close()
+    test_server.close()
+
+
+if __name__ == '__main__':
+    app.run(main)
diff --git a/tools/run_tests/xds_k8s_test_driver/bin/run_td_setup.py b/tools/run_tests/xds_k8s_test_driver/bin/run_td_setup.py
new file mode 100755 (executable)
index 0000000..a3b57d4
--- /dev/null
@@ -0,0 +1,202 @@
+# 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.
+"""Configure Traffic Director for different GRPC Proxyless.
+
+This is intended as a debugging / local development helper and not executed
+as a part of interop test suites.
+
+Typical usage examples:
+
+    # Regular proxyless setup
+    python -m bin.run_td_setup --flagfile=config/local-dev.cfg
+
+    # Additional commands: cleanup, backend management, etc.
+    python -m bin.run_td_setup --flagfile=config/local-dev.cfg --cmd=cleanup
+
+    # PSM security setup options: mtls, tls, etc.
+    python -m bin.run_td_setup --flagfile=config/local-dev.cfg --security=mtls
+
+    # More information and usage options
+    python -m bin.run_td_setup --helpfull
+"""
+import logging
+import uuid
+
+from absl import app
+from absl import flags
+
+from framework import xds_flags
+from framework import xds_k8s_flags
+from framework.infrastructure import gcp
+from framework.infrastructure import k8s
+from framework.infrastructure import traffic_director
+
+logger = logging.getLogger(__name__)
+# Flags
+_CMD = flags.DEFINE_enum('cmd',
+                         default='create',
+                         enum_values=[
+                             'cycle', 'create', 'cleanup', 'backends-add',
+                             'backends-cleanup'
+                         ],
+                         help='Command')
+_SECURITY = flags.DEFINE_enum('security',
+                              default=None,
+                              enum_values=[
+                                  'mtls', 'tls', 'plaintext', 'mtls_error',
+                                  'server_authz_error'
+                              ],
+                              help='Configure TD with security')
+flags.adopt_module_key_flags(xds_flags)
+flags.adopt_module_key_flags(xds_k8s_flags)
+
+
+def main(argv):
+    if len(argv) > 1:
+        raise app.UsageError('Too many command-line arguments.')
+
+    command = _CMD.value
+    security_mode = _SECURITY.value
+
+    project: str = xds_flags.PROJECT.value
+    network: str = xds_flags.NETWORK.value
+    namespace = xds_flags.NAMESPACE.value
+
+    # Test server
+    server_name = xds_flags.SERVER_NAME.value
+    server_port = xds_flags.SERVER_PORT.value
+    server_xds_host = xds_flags.SERVER_XDS_HOST.value
+    server_xds_port = xds_flags.SERVER_XDS_PORT.value
+
+    gcp_api_manager = gcp.api.GcpApiManager()
+
+    if security_mode is None:
+        td = traffic_director.TrafficDirectorManager(gcp_api_manager,
+                                                     project=project,
+                                                     resource_prefix=namespace,
+                                                     network=network)
+    else:
+        td = traffic_director.TrafficDirectorSecureManager(
+            gcp_api_manager,
+            project=project,
+            resource_prefix=namespace,
+            network=network)
+
+    try:
+        if command in ('create', 'cycle'):
+            logger.info('Create mode')
+            if security_mode is None:
+                logger.info('No security')
+                td.setup_for_grpc(server_xds_host, server_xds_port)
+
+            elif security_mode == 'mtls':
+                logger.info('Setting up mtls')
+                td.setup_for_grpc(server_xds_host, server_xds_port)
+                td.setup_server_security(server_namespace=namespace,
+                                         server_name=server_name,
+                                         server_port=server_port,
+                                         tls=True,
+                                         mtls=True)
+                td.setup_client_security(server_namespace=namespace,
+                                         server_name=server_name,
+                                         tls=True,
+                                         mtls=True)
+
+            elif security_mode == 'tls':
+                logger.info('Setting up tls')
+                td.setup_for_grpc(server_xds_host, server_xds_port)
+                td.setup_server_security(server_namespace=namespace,
+                                         server_name=server_name,
+                                         server_port=server_port,
+                                         tls=True,
+                                         mtls=False)
+                td.setup_client_security(server_namespace=namespace,
+                                         server_name=server_name,
+                                         tls=True,
+                                         mtls=False)
+
+            elif security_mode == 'plaintext':
+                logger.info('Setting up plaintext')
+                td.setup_for_grpc(server_xds_host, server_xds_port)
+                td.setup_server_security(server_namespace=namespace,
+                                         server_name=server_name,
+                                         server_port=server_port,
+                                         tls=False,
+                                         mtls=False)
+                td.setup_client_security(server_namespace=namespace,
+                                         server_name=server_name,
+                                         tls=False,
+                                         mtls=False)
+
+            elif security_mode == 'mtls_error':
+                # Error case: server expects client mTLS cert,
+                # but client configured only for TLS
+                logger.info('Setting up mtls_error')
+                td.setup_for_grpc(server_xds_host, server_xds_port)
+                td.setup_server_security(server_namespace=namespace,
+                                         server_name=server_name,
+                                         server_port=server_port,
+                                         tls=True,
+                                         mtls=True)
+                td.setup_client_security(server_namespace=namespace,
+                                         server_name=server_name,
+                                         tls=True,
+                                         mtls=False)
+
+            elif security_mode == 'server_authz_error':
+                # Error case: client does not authorize server
+                # because of mismatched SAN name.
+                logger.info('Setting up mtls_error')
+                td.setup_for_grpc(server_xds_host, server_xds_port)
+                # Regular TLS setup, but with client policy configured using
+                # intentionality incorrect server_namespace.
+                td.setup_server_security(server_namespace=namespace,
+                                         server_name=server_name,
+                                         server_port=server_port,
+                                         tls=True,
+                                         mtls=False)
+                incorrect_namespace = f'incorrect-namespace-{uuid.uuid4().hex}'
+                td.setup_client_security(server_namespace=incorrect_namespace,
+                                         server_name=server_name,
+                                         tls=True,
+                                         mtls=False)
+
+            logger.info('Works!')
+    except Exception:  # noqa pylint: disable=broad-except
+        logger.exception('Got error during creation')
+
+    if command in ('cleanup', 'cycle'):
+        logger.info('Cleaning up')
+        td.cleanup(force=True)
+
+    if command == 'backends-add':
+        logger.info('Adding backends')
+        k8s_api_manager = k8s.KubernetesApiManager(
+            xds_k8s_flags.KUBE_CONTEXT.value)
+        k8s_namespace = k8s.KubernetesNamespace(k8s_api_manager, namespace)
+
+        neg_name, neg_zones = k8s_namespace.get_service_neg(
+            server_name, server_port)
+
+        td.load_backend_service()
+        td.backend_service_add_neg_backends(neg_name, neg_zones)
+        td.wait_for_backends_healthy_status()
+        # TODO(sergiitk): wait until client reports rpc health
+    elif command == 'backends-cleanup':
+        td.load_backend_service()
+        td.backend_service_remove_all_backends()
+
+
+if __name__ == '__main__':
+    app.run(main)
diff --git a/tools/run_tests/xds_k8s_test_driver/bin/run_test_client.py b/tools/run_tests/xds_k8s_test_driver/bin/run_test_client.py
new file mode 100755 (executable)
index 0000000..2d1bc06
--- /dev/null
@@ -0,0 +1,93 @@
+# 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.
+import logging
+
+from absl import app
+from absl import flags
+
+from framework import xds_flags
+from framework import xds_k8s_flags
+from framework.infrastructure import k8s
+from framework.test_app import client_app
+
+logger = logging.getLogger(__name__)
+# Flags
+_CMD = flags.DEFINE_enum('cmd',
+                         default='run',
+                         enum_values=['run', 'cleanup'],
+                         help='Command')
+_SECURE = flags.DEFINE_bool("secure",
+                            default=False,
+                            help="Run client in the secure mode")
+_QPS = flags.DEFINE_integer('qps', default=25, help='Queries per second')
+_PRINT_RESPONSE = flags.DEFINE_bool("print_response",
+                                    default=False,
+                                    help="Client prints responses")
+_REUSE_NAMESPACE = flags.DEFINE_bool("reuse_namespace",
+                                     default=True,
+                                     help="Use existing namespace if exists")
+_CLEANUP_NAMESPACE = flags.DEFINE_bool(
+    "cleanup_namespace",
+    default=False,
+    help="Delete namespace during resource cleanup")
+flags.adopt_module_key_flags(xds_flags)
+flags.adopt_module_key_flags(xds_k8s_flags)
+
+
+def main(argv):
+    if len(argv) > 1:
+        raise app.UsageError('Too many command-line arguments.')
+
+    # Base namespace
+    namespace = xds_flags.NAMESPACE.value
+    client_namespace = namespace
+
+    runner_kwargs = dict(
+        deployment_name=xds_flags.CLIENT_NAME.value,
+        image_name=xds_k8s_flags.CLIENT_IMAGE.value,
+        gcp_service_account=xds_k8s_flags.GCP_SERVICE_ACCOUNT.value,
+        network=xds_flags.NETWORK.value,
+        td_bootstrap_image=xds_k8s_flags.TD_BOOTSTRAP_IMAGE.value,
+        stats_port=xds_flags.CLIENT_PORT.value,
+        reuse_namespace=_REUSE_NAMESPACE.value)
+
+    if _SECURE.value:
+        runner_kwargs.update(
+            deployment_template='client-secure.deployment.yaml')
+
+    k8s_api_manager = k8s.KubernetesApiManager(xds_k8s_flags.KUBE_CONTEXT.value)
+    client_runner = client_app.KubernetesClientRunner(
+        k8s.KubernetesNamespace(k8s_api_manager, client_namespace),
+        **runner_kwargs)
+
+    # Server target
+    server_xds_host = xds_flags.SERVER_XDS_HOST.value
+    server_xds_port = xds_flags.SERVER_XDS_PORT.value
+
+    if _CMD.value == 'run':
+        logger.info('Run client, secure_mode=%s', _SECURE.value)
+        client_runner.run(
+            server_target=f'xds:///{server_xds_host}:{server_xds_port}',
+            qps=_QPS.value,
+            print_response=_PRINT_RESPONSE.value,
+            secure_mode=_SECURE.value)
+
+    elif _CMD.value == 'cleanup':
+        logger.info('Cleanup client')
+        client_runner.cleanup(force=True,
+                              force_namespace=_CLEANUP_NAMESPACE.value)
+
+
+if __name__ == '__main__':
+    app.run(main)
diff --git a/tools/run_tests/xds_k8s_test_driver/bin/run_test_server.py b/tools/run_tests/xds_k8s_test_driver/bin/run_test_server.py
new file mode 100755 (executable)
index 0000000..fe78799
--- /dev/null
@@ -0,0 +1,81 @@
+# 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.
+import logging
+
+from absl import app
+from absl import flags
+
+from framework import xds_flags
+from framework import xds_k8s_flags
+from framework.infrastructure import k8s
+from framework.test_app import server_app
+
+logger = logging.getLogger(__name__)
+# Flags
+_CMD = flags.DEFINE_enum('cmd',
+                         default='run',
+                         enum_values=['run', 'cleanup'],
+                         help='Command')
+_SECURE = flags.DEFINE_bool("secure",
+                            default=False,
+                            help="Run server in the secure mode")
+_REUSE_NAMESPACE = flags.DEFINE_bool("reuse_namespace",
+                                     default=True,
+                                     help="Use existing namespace if exists")
+_CLEANUP_NAMESPACE = flags.DEFINE_bool(
+    "cleanup_namespace",
+    default=False,
+    help="Delete namespace during resource cleanup")
+flags.adopt_module_key_flags(xds_flags)
+flags.adopt_module_key_flags(xds_k8s_flags)
+
+
+def main(argv):
+    if len(argv) > 1:
+        raise app.UsageError('Too many command-line arguments.')
+
+    # Base namespace
+    namespace = xds_flags.NAMESPACE.value
+    server_namespace = namespace
+
+    runner_kwargs = dict(
+        deployment_name=xds_flags.SERVER_NAME.value,
+        image_name=xds_k8s_flags.SERVER_IMAGE.value,
+        gcp_service_account=xds_k8s_flags.GCP_SERVICE_ACCOUNT.value,
+        network=xds_flags.NETWORK.value,
+        reuse_namespace=_REUSE_NAMESPACE.value)
+
+    if _SECURE.value:
+        runner_kwargs.update(
+            td_bootstrap_image=xds_k8s_flags.TD_BOOTSTRAP_IMAGE.value,
+            deployment_template='server-secure.deployment.yaml')
+
+    k8s_api_manager = k8s.KubernetesApiManager(xds_k8s_flags.KUBE_CONTEXT.value)
+    server_runner = server_app.KubernetesServerRunner(
+        k8s.KubernetesNamespace(k8s_api_manager, server_namespace),
+        **runner_kwargs)
+
+    if _CMD.value == 'run':
+        logger.info('Run server, secure_mode=%s', _SECURE.value)
+        server_runner.run(test_port=xds_flags.SERVER_PORT.value,
+                          secure_mode=_SECURE.value)
+
+    elif _CMD.value == 'cleanup':
+        logger.info('Cleanup server')
+        server_runner.cleanup(force=True,
+                              force_namespace=_CLEANUP_NAMESPACE.value)
+
+
+if __name__ == '__main__':
+    app.run(main)
diff --git a/tools/run_tests/xds_k8s_test_driver/config/common.cfg b/tools/run_tests/xds_k8s_test_driver/config/common.cfg
new file mode 100644 (file)
index 0000000..9e253aa
--- /dev/null
@@ -0,0 +1,4 @@
+--namespace=interop-psm-security
+--td_bootstrap_image=gcr.io/trafficdirector-prod/td-grpc-bootstrap:0.10.0
+--logger_levels=__main__:DEBUG,framework:INFO
+--verbosity=0
diff --git a/tools/run_tests/xds_k8s_test_driver/config/grpc-testing.cfg b/tools/run_tests/xds_k8s_test_driver/config/grpc-testing.cfg
new file mode 100644 (file)
index 0000000..7a362a8
--- /dev/null
@@ -0,0 +1,5 @@
+--flagfile=config/common.cfg
+--project=grpc-testing
+--network=default-vpc
+--gcp_service_account=830293263384-compute@developer.gserviceaccount.com
+--private_api_key_secret_name=projects/830293263384/secrets/xds-interop-tests-private-api-access-key
diff --git a/tools/run_tests/xds_k8s_test_driver/config/local-dev.cfg.example b/tools/run_tests/xds_k8s_test_driver/config/local-dev.cfg.example
new file mode 100644 (file)
index 0000000..b32517a
--- /dev/null
@@ -0,0 +1,10 @@
+# Copy to local-dev.cfg
+# Local dev settings
+--flagfile=config/grpc-testing.cfg
+--kube_context=gke_grpc-testing_us-central1-a_interop-test-psm-sec1-us-central1
+--namespace=your-namespace
+# Test images
+--server_image=gcr.io/grpc-testing/xds-k8s-test-server-java:latest
+--client_image=gcr.io/grpc-testing/xds-k8s-test-client-java:latest
+# Enable port forwarding in local dev
+--debug_use_port_forwarding
old mode 100755 (executable)
new mode 100644 (file)
similarity index 58%
rename from tools/internal_ci/linux/grpc_run_grpclb_interop_tests.sh
rename to tools/run_tests/xds_k8s_test_driver/framework/__init__.py
index 806b5c9..1c0a3a3
@@ -1,5 +1,4 @@
-#!/bin/bash
-# Copyright 2017 gRPC authors.
+# 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.
 # 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.
-
-set -ex
-
-export LANG=en_US.UTF-8
-
-# Enter the gRPC repo root
-cd $(dirname $0)/../../..
-
-source tools/internal_ci/helper_scripts/prepare_build_linux_rc
-source tools/internal_ci/helper_scripts/prepare_build_grpclb_interop_rc
-
-tools/run_tests/run_grpclb_interop_tests.py -l all --scenarios_file=tools/run_tests/generated/lb_interop_test_scenarios.json
diff --git a/tools/run_tests/xds_k8s_test_driver/framework/helpers/__init__.py b/tools/run_tests/xds_k8s_test_driver/framework/helpers/__init__.py
new file mode 100644 (file)
index 0000000..1c0a3a3
--- /dev/null
@@ -0,0 +1,13 @@
+# 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.
diff --git a/tools/run_tests/xds_k8s_test_driver/framework/helpers/retryers.py b/tools/run_tests/xds_k8s_test_driver/framework/helpers/retryers.py
new file mode 100644 (file)
index 0000000..d76a406
--- /dev/null
@@ -0,0 +1,53 @@
+# 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.
+"""This contains common retrying helpers (retryers).
+
+We use tenacity as a general-purpose retrying library.
+
+> It [tenacity] originates from a fork of retrying which is sadly no
+> longer maintained. Tenacity isn’t api compatible with retrying but >
+> adds significant new functionality and fixes a number of longstanding bugs.
+> - https://tenacity.readthedocs.io/en/latest/index.html
+"""
+import datetime
+from typing import Any, List, Optional
+
+import tenacity
+
+# Type aliases
+timedelta = datetime.timedelta
+Retrying = tenacity.Retrying
+_retry_if_exception_type = tenacity.retry_if_exception_type
+_stop_after_delay = tenacity.stop_after_delay
+_wait_exponential = tenacity.wait_exponential
+
+
+def _retry_on_exceptions(retry_on_exceptions: Optional[List[Any]] = None):
+    # Retry on all exceptions by default
+    if retry_on_exceptions is None:
+        retry_on_exceptions = (Exception,)
+    return _retry_if_exception_type(retry_on_exceptions)
+
+
+def exponential_retryer_with_timeout(
+        *,
+        wait_min: timedelta,
+        wait_max: timedelta,
+        timeout: timedelta,
+        retry_on_exceptions: Optional[List[Any]] = None) -> Retrying:
+    return Retrying(retry=_retry_on_exceptions(retry_on_exceptions),
+                    wait=_wait_exponential(min=wait_min.total_seconds(),
+                                           max=wait_max.total_seconds()),
+                    stop=_stop_after_delay(timeout.total_seconds()),
+                    reraise=True)
diff --git a/tools/run_tests/xds_k8s_test_driver/framework/infrastructure/__init__.py b/tools/run_tests/xds_k8s_test_driver/framework/infrastructure/__init__.py
new file mode 100644 (file)
index 0000000..1c0a3a3
--- /dev/null
@@ -0,0 +1,13 @@
+# 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.
diff --git a/tools/run_tests/xds_k8s_test_driver/framework/infrastructure/gcp/__init__.py b/tools/run_tests/xds_k8s_test_driver/framework/infrastructure/gcp/__init__.py
new file mode 100644 (file)
index 0000000..02d8fad
--- /dev/null
@@ -0,0 +1,17 @@
+# 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.
+from framework.infrastructure.gcp import api
+from framework.infrastructure.gcp import compute
+from framework.infrastructure.gcp import network_security
+from framework.infrastructure.gcp import network_services
diff --git a/tools/run_tests/xds_k8s_test_driver/framework/infrastructure/gcp/api.py b/tools/run_tests/xds_k8s_test_driver/framework/infrastructure/gcp/api.py
new file mode 100644 (file)
index 0000000..b326f54
--- /dev/null
@@ -0,0 +1,291 @@
+# 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.
+import abc
+import contextlib
+import functools
+import logging
+from typing import Optional
+
+# Workaround: `grpc` must be imported before `google.protobuf.json_format`,
+# to prevent "Segmentation fault". Ref https://github.com/grpc/grpc/issues/24897
+# TODO(sergiitk): Remove after #24897 is solved
+import grpc  # noqa pylint: disable=unused-import
+from absl import flags
+from google.cloud import secretmanager_v1
+from google.longrunning import operations_pb2
+from google.protobuf import json_format
+from google.rpc import code_pb2
+from googleapiclient import discovery
+import googleapiclient.errors
+import tenacity
+import yaml
+
+logger = logging.getLogger(__name__)
+PRIVATE_API_KEY_SECRET_NAME = flags.DEFINE_string(
+    "private_api_key_secret_name",
+    default=None,
+    help="Load Private API access key from the latest version of the secret "
+    "with the given name, in the format projects/*/secrets/*")
+V1_DISCOVERY_URI = flags.DEFINE_string("v1_discovery_uri",
+                                       default=discovery.V1_DISCOVERY_URI,
+                                       help="Override v1 Discovery URI")
+V2_DISCOVERY_URI = flags.DEFINE_string("v2_discovery_uri",
+                                       default=discovery.V2_DISCOVERY_URI,
+                                       help="Override v2 Discovery URI")
+COMPUTE_V1_DISCOVERY_FILE = flags.DEFINE_string(
+    "compute_v1_discovery_file",
+    default=None,
+    help="Load compute v1 from discovery file")
+
+# Type aliases
+Operation = operations_pb2.Operation
+
+
+class GcpApiManager:
+
+    def __init__(self,
+                 *,
+                 v1_discovery_uri=None,
+                 v2_discovery_uri=None,
+                 compute_v1_discovery_file=None,
+                 private_api_key_secret_name=None):
+        self.v1_discovery_uri = v1_discovery_uri or V1_DISCOVERY_URI.value
+        self.v2_discovery_uri = v2_discovery_uri or V2_DISCOVERY_URI.value
+        self.compute_v1_discovery_file = (compute_v1_discovery_file or
+                                          COMPUTE_V1_DISCOVERY_FILE.value)
+        self.private_api_key_secret_name = (private_api_key_secret_name or
+                                            PRIVATE_API_KEY_SECRET_NAME.value)
+        # TODO(sergiitk): add options to pass google Credentials
+        self._exit_stack = contextlib.ExitStack()
+
+    def close(self):
+        self._exit_stack.close()
+
+    @property
+    @functools.lru_cache(None)
+    def private_api_key(self):
+        """
+        Private API key.
+
+        Return API key credential that identifies a GCP project allow-listed for
+        accessing private API discovery documents.
+        https://pantheon.corp.google.com/apis/credentials
+
+        This method lazy-loads the content of the key from the Secret Manager.
+        https://pantheon.corp.google.com/security/secret-manager
+        """
+        if not self.private_api_key_secret_name:
+            raise ValueError('private_api_key_secret_name must be set to '
+                             'access private_api_key.')
+
+        secrets_api = self.secrets('v1')
+        version_resource_path = secrets_api.secret_version_path(
+            **secrets_api.parse_secret_path(self.private_api_key_secret_name),
+            secret_version='latest')
+        secret: secretmanager_v1.AccessSecretVersionResponse
+        secret = secrets_api.access_secret_version(name=version_resource_path)
+        return secret.payload.data.decode()
+
+    @functools.lru_cache(None)
+    def compute(self, version):
+        api_name = 'compute'
+        if version == 'v1':
+            if self.compute_v1_discovery_file:
+                return self._build_from_file(self.compute_v1_discovery_file)
+            else:
+                return self._build_from_discovery_v1(api_name, version)
+
+        raise NotImplementedError(f'Compute {version} not supported')
+
+    @functools.lru_cache(None)
+    def networksecurity(self, version):
+        api_name = 'networksecurity'
+        if version == 'v1alpha1':
+            return self._build_from_discovery_v2(api_name,
+                                                 version,
+                                                 api_key=self.private_api_key)
+
+        raise NotImplementedError(f'Network Security {version} not supported')
+
+    @functools.lru_cache(None)
+    def networkservices(self, version):
+        api_name = 'networkservices'
+        if version == 'v1alpha1':
+            return self._build_from_discovery_v2(api_name,
+                                                 version,
+                                                 api_key=self.private_api_key)
+
+        raise NotImplementedError(f'Network Services {version} not supported')
+
+    @functools.lru_cache(None)
+    def secrets(self, version):
+        if version == 'v1':
+            return secretmanager_v1.SecretManagerServiceClient()
+
+        raise NotImplementedError(f'Secrets Manager {version} not supported')
+
+    def _build_from_discovery_v1(self, api_name, version):
+        api = discovery.build(api_name,
+                              version,
+                              cache_discovery=False,
+                              discoveryServiceUrl=self.v1_discovery_uri)
+        self._exit_stack.enter_context(api)
+        return api
+
+    def _build_from_discovery_v2(self, api_name, version, *, api_key=None):
+        key_arg = f'&key={api_key}' if api_key else ''
+        api = discovery.build(
+            api_name,
+            version,
+            cache_discovery=False,
+            discoveryServiceUrl=f'{self.v2_discovery_uri}{key_arg}')
+        self._exit_stack.enter_context(api)
+        return api
+
+    def _build_from_file(self, discovery_file):
+        with open(discovery_file, 'r') as f:
+            api = discovery.build_from_document(f.read())
+        self._exit_stack.enter_context(api)
+        return api
+
+
+class Error(Exception):
+    """Base error class for GCP API errors"""
+
+
+class OperationError(Error):
+    """
+    Operation was not successful.
+
+    Assuming Operation based on Google API Style Guide:
+    https://cloud.google.com/apis/design/design_patterns#long_running_operations
+    https://github.com/googleapis/googleapis/blob/master/google/longrunning/operations.proto
+    """
+
+    def __init__(self, api_name, operation_response, message=None):
+        self.api_name = api_name
+        operation = json_format.ParseDict(operation_response, Operation())
+        self.name = operation.name or 'unknown'
+        self.error = operation.error
+        self.code_name = code_pb2.Code.Name(operation.error.code)
+        if message is None:
+            message = (f'{api_name} operation "{self.name}" failed. Error '
+                       f'code: {self.error.code} ({self.code_name}), '
+                       f'message: {self.error.message}')
+        self.message = message
+        super().__init__(message)
+
+
+class GcpProjectApiResource:
+    # TODO(sergiitk): move someplace better
+    _WAIT_FOR_OPERATION_SEC = 60 * 5
+    _WAIT_FIXED_SEC = 2
+    _GCP_API_RETRIES = 5
+
+    def __init__(self, api: discovery.Resource, project: str):
+        self.api: discovery.Resource = api
+        self.project: str = project
+
+    @staticmethod
+    def wait_for_operation(operation_request,
+                           test_success_fn,
+                           timeout_sec=_WAIT_FOR_OPERATION_SEC,
+                           wait_sec=_WAIT_FIXED_SEC):
+        retryer = tenacity.Retrying(
+            retry=(tenacity.retry_if_not_result(test_success_fn) |
+                   tenacity.retry_if_exception_type()),
+            wait=tenacity.wait_fixed(wait_sec),
+            stop=tenacity.stop_after_delay(timeout_sec),
+            after=tenacity.after_log(logger, logging.DEBUG),
+            reraise=True)
+        return retryer(operation_request.execute)
+
+    @staticmethod
+    def _resource_pretty_format(body: dict) -> str:
+        """Return a string with pretty-printed resource body."""
+        return yaml.dump(body, explicit_start=True, explicit_end=True)
+
+
+class GcpStandardCloudApiResource(GcpProjectApiResource, metaclass=abc.ABCMeta):
+    GLOBAL_LOCATION = 'global'
+
+    def parent(self, location: Optional[str] = GLOBAL_LOCATION):
+        if location is None:
+            location = self.GLOBAL_LOCATION
+        return f'projects/{self.project}/locations/{location}'
+
+    def resource_full_name(self, name, collection_name):
+        return f'{self.parent()}/{collection_name}/{name}'
+
+    def _create_resource(self, collection: discovery.Resource, body: dict,
+                         **kwargs):
+        logger.info("Creating %s resource:\n%s", self.api_name,
+                    self._resource_pretty_format(body))
+        create_req = collection.create(parent=self.parent(),
+                                       body=body,
+                                       **kwargs)
+        self._execute(create_req)
+
+    @property
+    @abc.abstractmethod
+    def api_name(self) -> str:
+        raise NotImplementedError
+
+    @property
+    @abc.abstractmethod
+    def api_version(self) -> str:
+        raise NotImplementedError
+
+    def _get_resource(self, collection: discovery.Resource, full_name):
+        resource = collection.get(name=full_name).execute()
+        logger.info('Loaded %s:\n%s', full_name,
+                    self._resource_pretty_format(resource))
+        return resource
+
+    def _delete_resource(self, collection: discovery.Resource,
+                         full_name: str) -> bool:
+        logger.debug("Deleting %s", full_name)
+        try:
+            self._execute(collection.delete(name=full_name))
+            return True
+        except googleapiclient.errors.HttpError as error:
+            if error.resp and error.resp.status == 404:
+                logger.info('%s not deleted since it does not exist', full_name)
+            else:
+                logger.warning('Failed to delete %s, %r', full_name, error)
+        return False
+
+    def _execute(self,
+                 request,
+                 timeout_sec=GcpProjectApiResource._WAIT_FOR_OPERATION_SEC):
+        operation = request.execute(num_retries=self._GCP_API_RETRIES)
+        self._wait(operation, timeout_sec)
+
+    def _wait(self,
+              operation,
+              timeout_sec=GcpProjectApiResource._WAIT_FOR_OPERATION_SEC):
+        op_name = operation['name']
+        logger.debug('Waiting for %s operation, timeout %s sec: %s',
+                     self.api_name, timeout_sec, op_name)
+
+        op_request = self.api.projects().locations().operations().get(
+            name=op_name)
+        operation = self.wait_for_operation(
+            operation_request=op_request,
+            test_success_fn=lambda result: result['done'],
+            timeout_sec=timeout_sec)
+
+        logger.debug('Completed operation: %s', operation)
+        if 'error' in operation:
+            raise OperationError(self.api_name, operation)
diff --git a/tools/run_tests/xds_k8s_test_driver/framework/infrastructure/gcp/compute.py b/tools/run_tests/xds_k8s_test_driver/framework/infrastructure/gcp/compute.py
new file mode 100644 (file)
index 0000000..a001346
--- /dev/null
@@ -0,0 +1,346 @@
+# 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.
+import dataclasses
+import enum
+import logging
+from typing import Any, Dict, Optional
+
+from googleapiclient import discovery
+import googleapiclient.errors
+# TODO(sergiitk): replace with tenacity
+import retrying
+
+from framework.infrastructure import gcp
+
+logger = logging.getLogger(__name__)
+
+
+class ComputeV1(gcp.api.GcpProjectApiResource):
+    # TODO(sergiitk): move someplace better
+    _WAIT_FOR_BACKEND_SEC = 60 * 5
+    _WAIT_FOR_OPERATION_SEC = 60 * 5
+
+    @dataclasses.dataclass(frozen=True)
+    class GcpResource:
+        name: str
+        url: str
+
+    @dataclasses.dataclass(frozen=True)
+    class ZonalGcpResource(GcpResource):
+        zone: str
+
+    def __init__(self, api_manager: gcp.api.GcpApiManager, project: str):
+        super().__init__(api_manager.compute('v1'), project)
+
+    class HealthCheckProtocol(enum.Enum):
+        TCP = enum.auto()
+
+    class BackendServiceProtocol(enum.Enum):
+        HTTP2 = enum.auto()
+        GRPC = enum.auto()
+
+    def create_health_check_tcp(self, name,
+                                use_serving_port=False) -> GcpResource:
+        health_check_settings = {}
+        if use_serving_port:
+            health_check_settings['portSpecification'] = 'USE_SERVING_PORT'
+
+        return self._insert_resource(self.api.healthChecks(), {
+            'name': name,
+            'type': 'TCP',
+            'tcpHealthCheck': health_check_settings,
+        })
+
+    def delete_health_check(self, name):
+        self._delete_resource(self.api.healthChecks(), 'healthCheck', name)
+
+    def create_backend_service_traffic_director(
+            self,
+            name: str,
+            health_check: GcpResource,
+            protocol: Optional[BackendServiceProtocol] = None) -> GcpResource:
+        if not isinstance(protocol, self.BackendServiceProtocol):
+            raise TypeError(f'Unexpected Backend Service protocol: {protocol}')
+        return self._insert_resource(
+            self.api.backendServices(),
+            {
+                'name': name,
+                'loadBalancingScheme':
+                    'INTERNAL_SELF_MANAGED',  # Traffic Director
+                'healthChecks': [health_check.url],
+                'protocol': protocol.name,
+            })
+
+    def get_backend_service_traffic_director(self, name: str) -> GcpResource:
+        return self._get_resource(self.api.backendServices(),
+                                  backendService=name)
+
+    def patch_backend_service(self, backend_service, body, **kwargs):
+        self._patch_resource(collection=self.api.backendServices(),
+                             backendService=backend_service.name,
+                             body=body,
+                             **kwargs)
+
+    def backend_service_add_backends(self, backend_service, backends):
+        backend_list = [{
+            'group': backend.url,
+            'balancingMode': 'RATE',
+            'maxRatePerEndpoint': 5
+        } for backend in backends]
+
+        self._patch_resource(collection=self.api.backendServices(),
+                             body={'backends': backend_list},
+                             backendService=backend_service.name)
+
+    def backend_service_remove_all_backends(self, backend_service):
+        self._patch_resource(collection=self.api.backendServices(),
+                             body={'backends': []},
+                             backendService=backend_service.name)
+
+    def delete_backend_service(self, name):
+        self._delete_resource(self.api.backendServices(), 'backendService',
+                              name)
+
+    def create_url_map(
+            self,
+            name: str,
+            matcher_name: str,
+            src_hosts,
+            dst_default_backend_service: GcpResource,
+            dst_host_rule_match_backend_service: Optional[GcpResource] = None,
+    ) -> GcpResource:
+        if dst_host_rule_match_backend_service is None:
+            dst_host_rule_match_backend_service = dst_default_backend_service
+        return self._insert_resource(
+            self.api.urlMaps(), {
+                'name':
+                    name,
+                'defaultService':
+                    dst_default_backend_service.url,
+                'hostRules': [{
+                    'hosts': src_hosts,
+                    'pathMatcher': matcher_name,
+                }],
+                'pathMatchers': [{
+                    'name': matcher_name,
+                    'defaultService': dst_host_rule_match_backend_service.url,
+                }],
+            })
+
+    def delete_url_map(self, name):
+        self._delete_resource(self.api.urlMaps(), 'urlMap', name)
+
+    def create_target_grpc_proxy(
+            self,
+            name: str,
+            url_map: GcpResource,
+    ) -> GcpResource:
+        return self._insert_resource(self.api.targetGrpcProxies(), {
+            'name': name,
+            'url_map': url_map.url,
+            'validate_for_proxyless': True,
+        })
+
+    def delete_target_grpc_proxy(self, name):
+        self._delete_resource(self.api.targetGrpcProxies(), 'targetGrpcProxy',
+                              name)
+
+    def create_target_http_proxy(
+            self,
+            name: str,
+            url_map: GcpResource,
+    ) -> GcpResource:
+        return self._insert_resource(self.api.targetHttpProxies(), {
+            'name': name,
+            'url_map': url_map.url,
+        })
+
+    def delete_target_http_proxy(self, name):
+        self._delete_resource(self.api.targetHttpProxies(), 'targetHttpProxy',
+                              name)
+
+    def create_forwarding_rule(
+            self,
+            name: str,
+            src_port: int,
+            target_proxy: GcpResource,
+            network_url: str,
+    ) -> GcpResource:
+        return self._insert_resource(
+            self.api.globalForwardingRules(),
+            {
+                'name': name,
+                'loadBalancingScheme':
+                    'INTERNAL_SELF_MANAGED',  # Traffic Director
+                'portRange': src_port,
+                'IPAddress': '0.0.0.0',
+                'network': network_url,
+                'target': target_proxy.url,
+            })
+
+    def delete_forwarding_rule(self, name):
+        self._delete_resource(self.api.globalForwardingRules(),
+                              'forwardingRule', name)
+
+    @staticmethod
+    def _network_endpoint_group_not_ready(neg):
+        return not neg or neg.get('size', 0) == 0
+
+    def wait_for_network_endpoint_group(self, name, zone):
+
+        @retrying.retry(retry_on_result=self._network_endpoint_group_not_ready,
+                        stop_max_delay=60 * 1000,
+                        wait_fixed=2 * 1000)
+        def _wait_for_network_endpoint_group_ready():
+            try:
+                neg = self.get_network_endpoint_group(name, zone)
+                logger.debug(
+                    'Waiting for endpoints: NEG %s in zone %s, '
+                    'current count %s', neg['name'], zone, neg.get('size'))
+            except googleapiclient.errors.HttpError as error:
+                # noinspection PyProtectedMember
+                reason = error._get_reason()
+                logger.debug('Retrying NEG load, got %s, details %s',
+                             error.resp.status, reason)
+                raise
+            return neg
+
+        network_endpoint_group = _wait_for_network_endpoint_group_ready()
+        # TODO(sergiitk): dataclass
+        return self.ZonalGcpResource(network_endpoint_group['name'],
+                                     network_endpoint_group['selfLink'], zone)
+
+    def get_network_endpoint_group(self, name, zone):
+        neg = self.api.networkEndpointGroups().get(project=self.project,
+                                                   networkEndpointGroup=name,
+                                                   zone=zone).execute()
+        # TODO(sergiitk): dataclass
+        return neg
+
+    def wait_for_backends_healthy_status(
+            self,
+            backend_service,
+            backends,
+            timeout_sec=_WAIT_FOR_BACKEND_SEC,
+            wait_sec=4,
+    ):
+        pending = set(backends)
+
+        @retrying.retry(retry_on_result=lambda result: not result,
+                        stop_max_delay=timeout_sec * 1000,
+                        wait_fixed=wait_sec * 1000)
+        def _retry_backends_health():
+            for backend in pending:
+                result = self.get_backend_service_backend_health(
+                    backend_service, backend)
+
+                if 'healthStatus' not in result:
+                    logger.debug('Waiting for instances: backend %s, zone %s',
+                                 backend.name, backend.zone)
+                    continue
+
+                backend_healthy = True
+                for instance in result['healthStatus']:
+                    logger.debug(
+                        'Backend %s in zone %s: instance %s:%s health: %s',
+                        backend.name, backend.zone, instance['ipAddress'],
+                        instance['port'], instance['healthState'])
+                    if instance['healthState'] != 'HEALTHY':
+                        backend_healthy = False
+
+                if backend_healthy:
+                    logger.info('Backend %s in zone %s reported healthy',
+                                backend.name, backend.zone)
+                    pending.remove(backend)
+
+            return not pending
+
+        _retry_backends_health()
+
+    def get_backend_service_backend_health(self, backend_service, backend):
+        return self.api.backendServices().getHealth(
+            project=self.project,
+            backendService=backend_service.name,
+            body={
+                "group": backend.url
+            }).execute()
+
+    def _get_resource(self, collection: discovery.Resource,
+                      **kwargs) -> GcpResource:
+        resp = collection.get(project=self.project, **kwargs).execute()
+        logger.info('Loaded compute resource:\n%s',
+                    self._resource_pretty_format(resp))
+        return self.GcpResource(resp['name'], resp['selfLink'])
+
+    def _insert_resource(self, collection: discovery.Resource,
+                         body: Dict[str, Any]) -> GcpResource:
+        logger.info('Creating compute resource:\n%s',
+                    self._resource_pretty_format(body))
+        resp = self._execute(collection.insert(project=self.project, body=body))
+        return self.GcpResource(body['name'], resp['targetLink'])
+
+    def _patch_resource(self, collection, body, **kwargs):
+        logger.info('Patching compute resource:\n%s',
+                    self._resource_pretty_format(body))
+        self._execute(
+            collection.patch(project=self.project, body=body, **kwargs))
+
+    def _delete_resource(self, collection: discovery.Resource,
+                         resource_type: str, resource_name: str) -> bool:
+        try:
+            params = {"project": self.project, resource_type: resource_name}
+            self._execute(collection.delete(**params))
+            return True
+        except googleapiclient.errors.HttpError as error:
+            if error.resp and error.resp.status == 404:
+                logger.info(
+                    'Resource %s "%s" not deleted since it does not exist',
+                    resource_type, resource_name)
+            else:
+                logger.warning('Failed to delete %s "%s", %r', resource_type,
+                               resource_name, error)
+        return False
+
+    @staticmethod
+    def _operation_status_done(operation):
+        return 'status' in operation and operation['status'] == 'DONE'
+
+    def _execute(self,
+                 request,
+                 *,
+                 test_success_fn=None,
+                 timeout_sec=_WAIT_FOR_OPERATION_SEC):
+        operation = request.execute(num_retries=self._GCP_API_RETRIES)
+        logger.debug('Response %s', operation)
+
+        # TODO(sergiitk) try using wait() here
+        # https://googleapis.github.io/google-api-python-client/docs/dyn/compute_v1.globalOperations.html#wait
+        operation_request = self.api.globalOperations().get(
+            project=self.project, operation=operation['name'])
+
+        if test_success_fn is None:
+            test_success_fn = self._operation_status_done
+
+        logger.debug('Waiting for global operation %s, timeout %s sec',
+                     operation['name'], timeout_sec)
+        response = self.wait_for_operation(operation_request=operation_request,
+                                           test_success_fn=test_success_fn,
+                                           timeout_sec=timeout_sec)
+
+        if 'error' in response:
+            logger.debug('Waiting for global operation failed, response: %r',
+                         response)
+            raise Exception(f'Operation {operation["name"]} did not complete '
+                            f'within {timeout_sec}s, error={response["error"]}')
+        return response
diff --git a/tools/run_tests/xds_k8s_test_driver/framework/infrastructure/gcp/network_security.py b/tools/run_tests/xds_k8s_test_driver/framework/infrastructure/gcp/network_security.py
new file mode 100644 (file)
index 0000000..cb60840
--- /dev/null
@@ -0,0 +1,120 @@
+# 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.
+import logging
+
+import dataclasses
+from google.rpc import code_pb2
+import tenacity
+
+from framework.infrastructure import gcp
+
+logger = logging.getLogger(__name__)
+
+
+class NetworkSecurityV1Alpha1(gcp.api.GcpStandardCloudApiResource):
+    SERVER_TLS_POLICIES = 'serverTlsPolicies'
+    CLIENT_TLS_POLICIES = 'clientTlsPolicies'
+
+    @dataclasses.dataclass(frozen=True)
+    class ServerTlsPolicy:
+        url: str
+        name: str
+        server_certificate: dict
+        mtls_policy: dict
+        update_time: str
+        create_time: str
+
+    @dataclasses.dataclass(frozen=True)
+    class ClientTlsPolicy:
+        url: str
+        name: str
+        client_certificate: dict
+        server_validation_ca: list
+        update_time: str
+        create_time: str
+
+    def __init__(self, api_manager: gcp.api.GcpApiManager, project: str):
+        super().__init__(api_manager.networksecurity(self.api_version), project)
+        # Shortcut to projects/*/locations/ endpoints
+        self._api_locations = self.api.projects().locations()
+
+    @property
+    def api_name(self) -> str:
+        return 'networksecurity'
+
+    @property
+    def api_version(self) -> str:
+        return 'v1alpha1'
+
+    def create_server_tls_policy(self, name, body: dict):
+        return self._create_resource(self._api_locations.serverTlsPolicies(),
+                                     body,
+                                     serverTlsPolicyId=name)
+
+    def get_server_tls_policy(self, name: str) -> ServerTlsPolicy:
+        result = self._get_resource(
+            collection=self._api_locations.serverTlsPolicies(),
+            full_name=self.resource_full_name(name, self.SERVER_TLS_POLICIES))
+
+        return self.ServerTlsPolicy(name=name,
+                                    url=result['name'],
+                                    server_certificate=result.get(
+                                        'serverCertificate', {}),
+                                    mtls_policy=result.get('mtlsPolicy', {}),
+                                    create_time=result['createTime'],
+                                    update_time=result['updateTime'])
+
+    def delete_server_tls_policy(self, name):
+        return self._delete_resource(
+            collection=self._api_locations.serverTlsPolicies(),
+            full_name=self.resource_full_name(name, self.SERVER_TLS_POLICIES))
+
+    def create_client_tls_policy(self, name, body: dict):
+        return self._create_resource(self._api_locations.clientTlsPolicies(),
+                                     body,
+                                     clientTlsPolicyId=name)
+
+    def get_client_tls_policy(self, name: str) -> ClientTlsPolicy:
+        result = self._get_resource(
+            collection=self._api_locations.clientTlsPolicies(),
+            full_name=self.resource_full_name(name, self.CLIENT_TLS_POLICIES))
+
+        return self.ClientTlsPolicy(
+            name=name,
+            url=result['name'],
+            client_certificate=result.get('clientCertificate', {}),
+            server_validation_ca=result.get('serverValidationCa', []),
+            create_time=result['createTime'],
+            update_time=result['updateTime'])
+
+    def delete_client_tls_policy(self, name):
+        return self._delete_resource(
+            collection=self._api_locations.clientTlsPolicies(),
+            full_name=self.resource_full_name(name, self.CLIENT_TLS_POLICIES))
+
+    def _execute(self, *args, **kwargs):  # pylint: disable=signature-differs
+        # Workaround TD bug: throttled operations are reported as internal.
+        # Ref b/175345578
+        retryer = tenacity.Retrying(
+            retry=tenacity.retry_if_exception(self._operation_internal_error),
+            wait=tenacity.wait_fixed(10),
+            stop=tenacity.stop_after_delay(5 * 60),
+            before_sleep=tenacity.before_sleep_log(logger, logging.DEBUG),
+            reraise=True)
+        retryer(super()._execute, *args, **kwargs)
+
+    @staticmethod
+    def _operation_internal_error(exception):
+        return (isinstance(exception, gcp.api.OperationError) and
+                exception.error.code == code_pb2.INTERNAL)
diff --git a/tools/run_tests/xds_k8s_test_driver/framework/infrastructure/gcp/network_services.py b/tools/run_tests/xds_k8s_test_driver/framework/infrastructure/gcp/network_services.py
new file mode 100644 (file)
index 0000000..b331ade
--- /dev/null
@@ -0,0 +1,96 @@
+# 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.
+import logging
+from typing import Optional
+
+import dataclasses
+from google.rpc import code_pb2
+import tenacity
+
+from framework.infrastructure import gcp
+
+logger = logging.getLogger(__name__)
+
+
+class NetworkServicesV1Alpha1(gcp.api.GcpStandardCloudApiResource):
+    ENDPOINT_CONFIG_SELECTORS = 'endpointConfigSelectors'
+
+    @dataclasses.dataclass(frozen=True)
+    class EndpointConfigSelector:
+        url: str
+        name: str
+        type: str
+        server_tls_policy: Optional[str]
+        traffic_port_selector: dict
+        endpoint_matcher: dict
+        http_filters: dict
+        update_time: str
+        create_time: str
+
+    def __init__(self, api_manager: gcp.api.GcpApiManager, project: str):
+        super().__init__(api_manager.networkservices(self.api_version), project)
+        # Shortcut to projects/*/locations/ endpoints
+        self._api_locations = self.api.projects().locations()
+
+    @property
+    def api_name(self) -> str:
+        return 'networkservices'
+
+    @property
+    def api_version(self) -> str:
+        return 'v1alpha1'
+
+    def create_endpoint_config_selector(self, name, body: dict):
+        return self._create_resource(
+            self._api_locations.endpointConfigSelectors(),
+            body,
+            endpointConfigSelectorId=name)
+
+    def get_endpoint_config_selector(self, name: str) -> EndpointConfigSelector:
+        result = self._get_resource(
+            collection=self._api_locations.endpointConfigSelectors(),
+            full_name=self.resource_full_name(name,
+                                              self.ENDPOINT_CONFIG_SELECTORS))
+        return self.EndpointConfigSelector(
+            name=name,
+            url=result['name'],
+            type=result['type'],
+            server_tls_policy=result.get('serverTlsPolicy', None),
+            traffic_port_selector=result['trafficPortSelector'],
+            endpoint_matcher=result['endpointMatcher'],
+            http_filters=result['httpFilters'],
+            update_time=result['updateTime'],
+            create_time=result['createTime'])
+
+    def delete_endpoint_config_selector(self, name):
+        return self._delete_resource(
+            collection=self._api_locations.endpointConfigSelectors(),
+            full_name=self.resource_full_name(name,
+                                              self.ENDPOINT_CONFIG_SELECTORS))
+
+    def _execute(self, *args, **kwargs):  # pylint: disable=signature-differs
+        # Workaround TD bug: throttled operations are reported as internal.
+        # Ref b/175345578
+        retryer = tenacity.Retrying(
+            retry=tenacity.retry_if_exception(self._operation_internal_error),
+            wait=tenacity.wait_fixed(10),
+            stop=tenacity.stop_after_delay(5 * 60),
+            before_sleep=tenacity.before_sleep_log(logger, logging.DEBUG),
+            reraise=True)
+        retryer(super()._execute, *args, **kwargs)
+
+    @staticmethod
+    def _operation_internal_error(exception):
+        return (isinstance(exception, gcp.api.OperationError) and
+                exception.error.code == code_pb2.INTERNAL)
diff --git a/tools/run_tests/xds_k8s_test_driver/framework/infrastructure/k8s.py b/tools/run_tests/xds_k8s_test_driver/framework/infrastructure/k8s.py
new file mode 100644 (file)
index 0000000..ca446bc
--- /dev/null
@@ -0,0 +1,342 @@
+# 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.
+import functools
+import json
+import logging
+import subprocess
+import time
+from typing import Optional, List, Tuple
+
+# TODO(sergiitk): replace with tenacity
+import retrying
+import kubernetes.config
+from kubernetes import client
+from kubernetes import utils
+
+logger = logging.getLogger(__name__)
+# Type aliases
+V1Deployment = client.V1Deployment
+V1ServiceAccount = client.V1ServiceAccount
+V1Pod = client.V1Pod
+V1PodList = client.V1PodList
+V1Service = client.V1Service
+V1Namespace = client.V1Namespace
+ApiException = client.ApiException
+
+
+def simple_resource_get(func):
+
+    def wrap_not_found_return_none(*args, **kwargs):
+        try:
+            return func(*args, **kwargs)
+        except client.ApiException as e:
+            if e.status == 404:
+                # Ignore 404
+                return None
+            raise
+
+    return wrap_not_found_return_none
+
+
+def label_dict_to_selector(labels: dict) -> str:
+    return ','.join(f'{k}=={v}' for k, v in labels.items())
+
+
+class KubernetesApiManager:
+
+    def __init__(self, context):
+        self.context = context
+        self.client = self._cached_api_client_for_context(context)
+        self.apps = client.AppsV1Api(self.client)
+        self.core = client.CoreV1Api(self.client)
+
+    def close(self):
+        self.client.close()
+
+    @classmethod
+    @functools.lru_cache(None)
+    def _cached_api_client_for_context(cls, context: str) -> client.ApiClient:
+        client_instance = kubernetes.config.new_client_from_config(
+            context=context)
+        logger.info('Using kubernetes context "%s", active host: %s', context,
+                    client_instance.configuration.host)
+        return client_instance
+
+
+class PortForwardingError(Exception):
+    """Error forwarding port"""
+
+
+class KubernetesNamespace:
+    NEG_STATUS_META = 'cloud.google.com/neg-status'
+    PORT_FORWARD_LOCAL_ADDRESS: str = '127.0.0.1'
+    DELETE_GRACE_PERIOD_SEC: int = 5
+
+    def __init__(self, api: KubernetesApiManager, name: str):
+        self.name = name
+        self.api = api
+
+    def apply_manifest(self, manifest):
+        return utils.create_from_dict(self.api.client,
+                                      manifest,
+                                      namespace=self.name)
+
+    @simple_resource_get
+    def get_service(self, name) -> V1Service:
+        return self.api.core.read_namespaced_service(name, self.name)
+
+    @simple_resource_get
+    def get_service_account(self, name) -> V1Service:
+        return self.api.core.read_namespaced_service_account(name, self.name)
+
+    def delete_service(self, name,
+                       grace_period_seconds=DELETE_GRACE_PERIOD_SEC):
+        self.api.core.delete_namespaced_service(
+            name=name,
+            namespace=self.name,
+            body=client.V1DeleteOptions(
+                propagation_policy='Foreground',
+                grace_period_seconds=grace_period_seconds))
+
+    def delete_service_account(self,
+                               name,
+                               grace_period_seconds=DELETE_GRACE_PERIOD_SEC):
+        self.api.core.delete_namespaced_service_account(
+            name=name,
+            namespace=self.name,
+            body=client.V1DeleteOptions(
+                propagation_policy='Foreground',
+                grace_period_seconds=grace_period_seconds))
+
+    @simple_resource_get
+    def get(self) -> V1Namespace:
+        return self.api.core.read_namespace(self.name)
+
+    def delete(self, grace_period_seconds=DELETE_GRACE_PERIOD_SEC):
+        self.api.core.delete_namespace(
+            name=self.name,
+            body=client.V1DeleteOptions(
+                propagation_policy='Foreground',
+                grace_period_seconds=grace_period_seconds))
+
+    def wait_for_service_deleted(self, name: str, timeout_sec=60, wait_sec=1):
+
+        @retrying.retry(retry_on_result=lambda r: r is not None,
+                        stop_max_delay=timeout_sec * 1000,
+                        wait_fixed=wait_sec * 1000)
+        def _wait_for_deleted_service_with_retry():
+            service = self.get_service(name)
+            if service is not None:
+                logger.debug('Waiting for service %s to be deleted',
+                             service.metadata.name)
+            return service
+
+        _wait_for_deleted_service_with_retry()
+
+    def wait_for_service_account_deleted(self,
+                                         name: str,
+                                         timeout_sec=60,
+                                         wait_sec=1):
+
+        @retrying.retry(retry_on_result=lambda r: r is not None,
+                        stop_max_delay=timeout_sec * 1000,
+                        wait_fixed=wait_sec * 1000)
+        def _wait_for_deleted_service_account_with_retry():
+            service_account = self.get_service_account(name)
+            if service_account is not None:
+                logger.debug('Waiting for service account %s to be deleted',
+                             service_account.metadata.name)
+            return service_account
+
+        _wait_for_deleted_service_account_with_retry()
+
+    def wait_for_namespace_deleted(self, timeout_sec=240, wait_sec=5):
+
+        @retrying.retry(retry_on_result=lambda r: r is not None,
+                        stop_max_delay=timeout_sec * 1000,
+                        wait_fixed=wait_sec * 1000)
+        def _wait_for_deleted_namespace_with_retry():
+            namespace = self.get()
+            if namespace is not None:
+                logger.debug('Waiting for namespace %s to be deleted',
+                             namespace.metadata.name)
+            return namespace
+
+        _wait_for_deleted_namespace_with_retry()
+
+    def wait_for_service_neg(self, name: str, timeout_sec=60, wait_sec=1):
+
+        @retrying.retry(retry_on_result=lambda r: not r,
+                        stop_max_delay=timeout_sec * 1000,
+                        wait_fixed=wait_sec * 1000)
+        def _wait_for_service_neg():
+            service = self.get_service(name)
+            if self.NEG_STATUS_META not in service.metadata.annotations:
+                logger.debug('Waiting for service %s NEG',
+                             service.metadata.name)
+                return False
+            return True
+
+        _wait_for_service_neg()
+
+    def get_service_neg(self, service_name: str,
+                        service_port: int) -> Tuple[str, List[str]]:
+        service = self.get_service(service_name)
+        neg_info: dict = json.loads(
+            service.metadata.annotations[self.NEG_STATUS_META])
+        neg_name: str = neg_info['network_endpoint_groups'][str(service_port)]
+        neg_zones: List[str] = neg_info['zones']
+        return neg_name, neg_zones
+
+    @simple_resource_get
+    def get_deployment(self, name) -> V1Deployment:
+        return self.api.apps.read_namespaced_deployment(name, self.name)
+
+    def delete_deployment(self,
+                          name,
+                          grace_period_seconds=DELETE_GRACE_PERIOD_SEC):
+        self.api.apps.delete_namespaced_deployment(
+            name=name,
+            namespace=self.name,
+            body=client.V1DeleteOptions(
+                propagation_policy='Foreground',
+                grace_period_seconds=grace_period_seconds))
+
+    def list_deployment_pods(self, deployment: V1Deployment) -> List[V1Pod]:
+        # V1LabelSelector.match_expressions not supported at the moment
+        return self.list_pods_with_labels(deployment.spec.selector.match_labels)
+
+    def wait_for_deployment_available_replicas(self,
+                                               name,
+                                               count=1,
+                                               timeout_sec=60,
+                                               wait_sec=3):
+
+        @retrying.retry(
+            retry_on_result=lambda r: not self._replicas_available(r, count),
+            stop_max_delay=timeout_sec * 1000,
+            wait_fixed=wait_sec * 1000)
+        def _wait_for_deployment_available_replicas():
+            deployment = self.get_deployment(name)
+            logger.debug(
+                'Waiting for deployment %s to have %s available '
+                'replicas, current count %s', deployment.metadata.name, count,
+                deployment.status.available_replicas)
+            return deployment
+
+        _wait_for_deployment_available_replicas()
+
+    def wait_for_deployment_deleted(self,
+                                    deployment_name: str,
+                                    timeout_sec=60,
+                                    wait_sec=1):
+
+        @retrying.retry(retry_on_result=lambda r: r is not None,
+                        stop_max_delay=timeout_sec * 1000,
+                        wait_fixed=wait_sec * 1000)
+        def _wait_for_deleted_deployment_with_retry():
+            deployment = self.get_deployment(deployment_name)
+            if deployment is not None:
+                logger.debug(
+                    'Waiting for deployment %s to be deleted. '
+                    'Non-terminated replicas: %s', deployment.metadata.name,
+                    deployment.status.replicas)
+            return deployment
+
+        _wait_for_deleted_deployment_with_retry()
+
+    def list_pods_with_labels(self, labels: dict) -> List[V1Pod]:
+        pod_list: V1PodList = self.api.core.list_namespaced_pod(
+            self.name, label_selector=label_dict_to_selector(labels))
+        return pod_list.items
+
+    def get_pod(self, name) -> client.V1Pod:
+        return self.api.core.read_namespaced_pod(name, self.name)
+
+    def wait_for_pod_started(self, pod_name, timeout_sec=60, wait_sec=1):
+
+        @retrying.retry(retry_on_result=lambda r: not self._pod_started(r),
+                        stop_max_delay=timeout_sec * 1000,
+                        wait_fixed=wait_sec * 1000)
+        def _wait_for_pod_started():
+            pod = self.get_pod(pod_name)
+            logger.debug('Waiting for pod %s to start, current phase: %s',
+                         pod.metadata.name, pod.status.phase)
+            return pod
+
+        _wait_for_pod_started()
+
+    def port_forward_pod(
+            self,
+            pod: V1Pod,
+            remote_port: int,
+            local_port: Optional[int] = None,
+            local_address: Optional[str] = None,
+    ) -> subprocess.Popen:
+        """Experimental"""
+        local_address = local_address or self.PORT_FORWARD_LOCAL_ADDRESS
+        local_port = local_port or remote_port
+        cmd = [
+            "kubectl", "--context", self.api.context, "--namespace", self.name,
+            "port-forward", "--address", local_address,
+            f"pod/{pod.metadata.name}", f"{local_port}:{remote_port}"
+        ]
+        pf = subprocess.Popen(cmd,
+                              stdout=subprocess.PIPE,
+                              stderr=subprocess.STDOUT,
+                              universal_newlines=True)
+        # Wait for stdout line indicating successful start.
+        expected = (f"Forwarding from {local_address}:{local_port}"
+                    f" -> {remote_port}")
+        try:
+            while True:
+                time.sleep(0.05)
+                output = pf.stdout.readline().strip()
+                if not output:
+                    return_code = pf.poll()
+                    if return_code is not None:
+                        errors = [error for error in pf.stdout.readlines()]
+                        raise PortForwardingError(
+                            'Error forwarding port, kubectl return '
+                            f'code {return_code}, output {errors}')
+                elif output != expected:
+                    raise PortForwardingError(
+                        f'Error forwarding port, unexpected output {output}')
+                else:
+                    logger.info(output)
+                    break
+        except Exception:
+            self.port_forward_stop(pf)
+            raise
+
+        # TODO(sergiitk): return new PortForwarder object
+        return pf
+
+    @staticmethod
+    def port_forward_stop(pf):
+        logger.info('Shutting down port forwarding, pid %s', pf.pid)
+        pf.kill()
+        stdout, _stderr = pf.communicate(timeout=5)
+        logger.info('Port forwarding stopped')
+        logger.debug('Port forwarding remaining stdout: %s', stdout)
+
+    @staticmethod
+    def _pod_started(pod: V1Pod):
+        return pod.status.phase not in ('Pending', 'Unknown')
+
+    @staticmethod
+    def _replicas_available(deployment, count):
+        return (deployment is not None and
+                deployment.status.available_replicas is not None and
+                deployment.status.available_replicas >= count)
diff --git a/tools/run_tests/xds_k8s_test_driver/framework/infrastructure/traffic_director.py b/tools/run_tests/xds_k8s_test_driver/framework/infrastructure/traffic_director.py
new file mode 100644 (file)
index 0000000..895651f
--- /dev/null
@@ -0,0 +1,483 @@
+# 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.
+import logging
+from typing import Optional, Set
+
+from framework.infrastructure import gcp
+
+logger = logging.getLogger(__name__)
+
+# Type aliases
+# Compute
+_ComputeV1 = gcp.compute.ComputeV1
+GcpResource = _ComputeV1.GcpResource
+HealthCheckProtocol = _ComputeV1.HealthCheckProtocol
+ZonalGcpResource = _ComputeV1.ZonalGcpResource
+BackendServiceProtocol = _ComputeV1.BackendServiceProtocol
+_BackendGRPC = BackendServiceProtocol.GRPC
+
+# Network Security
+_NetworkSecurityV1Alpha1 = gcp.network_security.NetworkSecurityV1Alpha1
+ServerTlsPolicy = _NetworkSecurityV1Alpha1.ServerTlsPolicy
+ClientTlsPolicy = _NetworkSecurityV1Alpha1.ClientTlsPolicy
+
+# Network Services
+_NetworkServicesV1Alpha1 = gcp.network_services.NetworkServicesV1Alpha1
+EndpointConfigSelector = _NetworkServicesV1Alpha1.EndpointConfigSelector
+
+
+class TrafficDirectorManager:
+    compute: _ComputeV1
+    BACKEND_SERVICE_NAME = "backend-service"
+    HEALTH_CHECK_NAME = "health-check"
+    URL_MAP_NAME = "url-map"
+    URL_MAP_PATH_MATCHER_NAME = "path-matcher"
+    TARGET_PROXY_NAME = "target-proxy"
+    FORWARDING_RULE_NAME = "forwarding-rule"
+
+    def __init__(
+            self,
+            gcp_api_manager: gcp.api.GcpApiManager,
+            project: str,
+            *,
+            resource_prefix: str,
+            network: str = 'default',
+    ):
+        # API
+        self.compute = _ComputeV1(gcp_api_manager, project)
+
+        # Settings
+        self.project: str = project
+        self.network: str = network
+        self.resource_prefix: str = resource_prefix
+
+        # Managed resources
+        self.health_check: Optional[GcpResource] = None
+        self.backend_service: Optional[GcpResource] = None
+        # TODO(sergiitk): remove this flag once backend service resource loaded
+        self.backend_service_protocol: Optional[BackendServiceProtocol] = None
+        self.url_map: Optional[GcpResource] = None
+        self.target_proxy: Optional[GcpResource] = None
+        # TODO(sergiitk): remove this flag once target proxy resource loaded
+        self.target_proxy_is_http: bool = False
+        self.forwarding_rule: Optional[GcpResource] = None
+        self.backends: Set[ZonalGcpResource] = set()
+
+    @property
+    def network_url(self):
+        return f'global/networks/{self.network}'
+
+    def setup_for_grpc(
+            self,
+            service_host,
+            service_port,
+            *,
+            backend_protocol: Optional[BackendServiceProtocol] = _BackendGRPC):
+        self.setup_backend_for_grpc(protocol=backend_protocol)
+        self.setup_routing_rule_map_for_grpc(service_host, service_port)
+
+    def setup_backend_for_grpc(
+            self, *, protocol: Optional[BackendServiceProtocol] = _BackendGRPC):
+        self.create_health_check()
+        self.create_backend_service(protocol)
+
+    def setup_routing_rule_map_for_grpc(self, service_host, service_port):
+        self.create_url_map(service_host, service_port)
+        self.create_target_proxy()
+        self.create_forwarding_rule(service_port)
+
+    def cleanup(self, *, force=False):
+        # Cleanup in the reverse order of creation
+        self.delete_forwarding_rule(force=force)
+        if self.target_proxy_is_http:
+            self.delete_target_http_proxy(force=force)
+        else:
+            self.delete_target_grpc_proxy(force=force)
+        self.delete_url_map(force=force)
+        self.delete_backend_service(force=force)
+        self.delete_health_check(force=force)
+
+    def _ns_name(self, name):
+        return f'{self.resource_prefix}-{name}'
+
+    def create_health_check(self, protocol=HealthCheckProtocol.TCP):
+        if self.health_check:
+            raise ValueError(f'Health check {self.health_check.name} '
+                             'already created, delete it first')
+        name = self._ns_name(self.HEALTH_CHECK_NAME)
+        logger.info('Creating %s Health Check "%s"', protocol.name, name)
+        if protocol is HealthCheckProtocol.TCP:
+            resource = self.compute.create_health_check_tcp(
+                name, use_serving_port=True)
+        else:
+            raise ValueError('Unexpected protocol')
+        self.health_check = resource
+
+    def delete_health_check(self, force=False):
+        if force:
+            name = self._ns_name(self.HEALTH_CHECK_NAME)
+        elif self.health_check:
+            name = self.health_check.name
+        else:
+            return
+        logger.info('Deleting Health Check "%s"', name)
+        self.compute.delete_health_check(name)
+        self.health_check = None
+
+    def create_backend_service(
+            self, protocol: Optional[BackendServiceProtocol] = _BackendGRPC):
+        if protocol is None:
+            protocol = _BackendGRPC
+
+        name = self._ns_name(self.BACKEND_SERVICE_NAME)
+        logger.info('Creating %s Backend Service "%s"', protocol.name, name)
+        resource = self.compute.create_backend_service_traffic_director(
+            name, health_check=self.health_check, protocol=protocol)
+        self.backend_service = resource
+        self.backend_service_protocol = protocol
+
+    def load_backend_service(self):
+        name = self._ns_name(self.BACKEND_SERVICE_NAME)
+        resource = self.compute.get_backend_service_traffic_director(name)
+        self.backend_service = resource
+
+    def delete_backend_service(self, force=False):
+        if force:
+            name = self._ns_name(self.BACKEND_SERVICE_NAME)
+        elif self.backend_service:
+            name = self.backend_service.name
+        else:
+            return
+        logger.info('Deleting Backend Service "%s"', name)
+        self.compute.delete_backend_service(name)
+        self.backend_service = None
+
+    def backend_service_add_neg_backends(self, name, zones):
+        logger.info('Waiting for Network Endpoint Groups to load endpoints.')
+        for zone in zones:
+            backend = self.compute.wait_for_network_endpoint_group(name, zone)
+            logger.info('Loaded NEG "%s" in zone %s', backend.name,
+                        backend.zone)
+            self.backends.add(backend)
+        self.backend_service_add_backends()
+
+    def backend_service_add_backends(self):
+        logging.info('Adding backends to Backend Service %s: %r',
+                     self.backend_service.name, self.backends)
+        self.compute.backend_service_add_backends(self.backend_service,
+                                                  self.backends)
+
+    def backend_service_remove_all_backends(self):
+        logging.info('Removing backends from Backend Service %s',
+                     self.backend_service.name)
+        self.compute.backend_service_remove_all_backends(self.backend_service)
+
+    def wait_for_backends_healthy_status(self):
+        logger.debug(
+            "Waiting for Backend Service %s to report all backends healthy %r",
+            self.backend_service, self.backends)
+        self.compute.wait_for_backends_healthy_status(self.backend_service,
+                                                      self.backends)
+
+    def create_url_map(
+            self,
+            src_host: str,
+            src_port: int,
+    ) -> GcpResource:
+        src_address = f'{src_host}:{src_port}'
+        name = self._ns_name(self.URL_MAP_NAME)
+        matcher_name = self._ns_name(self.URL_MAP_PATH_MATCHER_NAME)
+        logger.info('Creating URL map "%s": %s -> %s', name, src_address,
+                    self.backend_service.name)
+        resource = self.compute.create_url_map(name, matcher_name,
+                                               [src_address],
+                                               self.backend_service)
+        self.url_map = resource
+        return resource
+
+    def delete_url_map(self, force=False):
+        if force:
+            name = self._ns_name(self.URL_MAP_NAME)
+        elif self.url_map:
+            name = self.url_map.name
+        else:
+            return
+        logger.info('Deleting URL Map "%s"', name)
+        self.compute.delete_url_map(name)
+        self.url_map = None
+
+    def create_target_proxy(self):
+        name = self._ns_name(self.TARGET_PROXY_NAME)
+        if self.backend_service_protocol is BackendServiceProtocol.GRPC:
+            target_proxy_type = 'GRPC'
+            create_proxy_fn = self.compute.create_target_grpc_proxy
+            self.target_proxy_is_http = False
+        elif self.backend_service_protocol is BackendServiceProtocol.HTTP2:
+            target_proxy_type = 'HTTP'
+            create_proxy_fn = self.compute.create_target_http_proxy
+            self.target_proxy_is_http = True
+        else:
+            raise TypeError('Unexpected backend service protocol')
+
+        logger.info('Creating target %s proxy "%s" to URL map %s', name,
+                    target_proxy_type, self.url_map.name)
+        self.target_proxy = create_proxy_fn(name, self.url_map)
+
+    def delete_target_grpc_proxy(self, force=False):
+        if force:
+            name = self._ns_name(self.TARGET_PROXY_NAME)
+        elif self.target_proxy:
+            name = self.target_proxy.name
+        else:
+            return
+        logger.info('Deleting Target GRPC proxy "%s"', name)
+        self.compute.delete_target_grpc_proxy(name)
+        self.target_proxy = None
+        self.target_proxy_is_http = False
+
+    def delete_target_http_proxy(self, force=False):
+        if force:
+            name = self._ns_name(self.TARGET_PROXY_NAME)
+        elif self.target_proxy:
+            name = self.target_proxy.name
+        else:
+            return
+        logger.info('Deleting HTTP Target proxy "%s"', name)
+        self.compute.delete_target_http_proxy(name)
+        self.target_proxy = None
+        self.target_proxy_is_http = False
+
+    def create_forwarding_rule(self, src_port: int):
+        name = self._ns_name(self.FORWARDING_RULE_NAME)
+        src_port = int(src_port)
+        logging.info(
+            'Creating forwarding rule "%s" in network "%s": 0.0.0.0:%s -> %s',
+            name, self.network, src_port, self.target_proxy.url)
+        resource = self.compute.create_forwarding_rule(name, src_port,
+                                                       self.target_proxy,
+                                                       self.network_url)
+        self.forwarding_rule = resource
+        return resource
+
+    def delete_forwarding_rule(self, force=False):
+        if force:
+            name = self._ns_name(self.FORWARDING_RULE_NAME)
+        elif self.forwarding_rule:
+            name = self.forwarding_rule.name
+        else:
+            return
+        logger.info('Deleting Forwarding rule "%s"', name)
+        self.compute.delete_forwarding_rule(name)
+        self.forwarding_rule = None
+
+
+class TrafficDirectorSecureManager(TrafficDirectorManager):
+    netsec: Optional[_NetworkSecurityV1Alpha1]
+    SERVER_TLS_POLICY_NAME = "server-tls-policy"
+    CLIENT_TLS_POLICY_NAME = "client-tls-policy"
+    ENDPOINT_CONFIG_SELECTOR_NAME = "endpoint-config-selector"
+    CERTIFICATE_PROVIDER_INSTANCE = "google_cloud_private_spiffe"
+
+    def __init__(
+            self,
+            gcp_api_manager: gcp.api.GcpApiManager,
+            project: str,
+            *,
+            resource_prefix: str,
+            network: str = 'default',
+    ):
+        super().__init__(gcp_api_manager,
+                         project,
+                         resource_prefix=resource_prefix,
+                         network=network)
+
+        # API
+        self.netsec = _NetworkSecurityV1Alpha1(gcp_api_manager, project)
+        self.netsvc = _NetworkServicesV1Alpha1(gcp_api_manager, project)
+
+        # Managed resources
+        self.server_tls_policy: Optional[ServerTlsPolicy] = None
+        self.ecs: Optional[EndpointConfigSelector] = None
+        self.client_tls_policy: Optional[ClientTlsPolicy] = None
+
+    def setup_server_security(self,
+                              *,
+                              server_namespace,
+                              server_name,
+                              server_port,
+                              tls=True,
+                              mtls=True):
+        self.create_server_tls_policy(tls=tls, mtls=mtls)
+        self.create_endpoint_config_selector(server_namespace=server_namespace,
+                                             server_name=server_name,
+                                             server_port=server_port)
+
+    def setup_client_security(self,
+                              *,
+                              server_namespace,
+                              server_name,
+                              tls=True,
+                              mtls=True):
+        self.create_client_tls_policy(tls=tls, mtls=mtls)
+        self.backend_service_apply_client_mtls_policy(server_namespace,
+                                                      server_name)
+
+    def cleanup(self, *, force=False):
+        # Cleanup in the reverse order of creation
+        super().cleanup(force=force)
+        self.delete_endpoint_config_selector(force=force)
+        self.delete_server_tls_policy(force=force)
+        self.delete_client_tls_policy(force=force)
+
+    def create_server_tls_policy(self, *, tls, mtls):
+        name = self._ns_name(self.SERVER_TLS_POLICY_NAME)
+        logger.info('Creating Server TLS Policy %s', name)
+        if not tls and not mtls:
+            logger.warning(
+                'Server TLS Policy %s neither TLS, nor mTLS '
+                'policy. Skipping creation', name)
+            return
+
+        certificate_provider = self._get_certificate_provider()
+        policy = {}
+        if tls:
+            policy["serverCertificate"] = certificate_provider
+        if mtls:
+            policy["mtlsPolicy"] = {
+                "clientValidationCa": [certificate_provider],
+            }
+
+        self.netsec.create_server_tls_policy(name, policy)
+        self.server_tls_policy = self.netsec.get_server_tls_policy(name)
+        logger.debug('Server TLS Policy loaded: %r', self.server_tls_policy)
+
+    def delete_server_tls_policy(self, force=False):
+        if force:
+            name = self._ns_name(self.SERVER_TLS_POLICY_NAME)
+        elif self.server_tls_policy:
+            name = self.server_tls_policy.name
+        else:
+            return
+        logger.info('Deleting Server TLS Policy %s', name)
+        self.netsec.delete_server_tls_policy(name)
+        self.server_tls_policy = None
+
+    def create_endpoint_config_selector(self, server_namespace, server_name,
+                                        server_port):
+        name = self._ns_name(self.ENDPOINT_CONFIG_SELECTOR_NAME)
+        logger.info('Creating Endpoint Config Selector %s', name)
+        endpoint_matcher_labels = [{
+            "labelName": "app",
+            "labelValue": f"{server_namespace}-{server_name}"
+        }]
+        port_selector = {"ports": [str(server_port)]}
+        label_matcher_all = {
+            "metadataLabelMatchCriteria": "MATCH_ALL",
+            "metadataLabels": endpoint_matcher_labels
+        }
+        config = {
+            "type": "SIDECAR_PROXY",
+            "httpFilters": {},
+            "trafficPortSelector": port_selector,
+            "endpointMatcher": {
+                "metadataLabelMatcher": label_matcher_all
+            },
+        }
+        if self.server_tls_policy:
+            config["serverTlsPolicy"] = self.server_tls_policy.name
+        else:
+            logger.warning(
+                'Creating Endpoint Config Selector %s with '
+                'no Server TLS policy attached', name)
+
+        self.netsvc.create_endpoint_config_selector(name, config)
+        self.ecs = self.netsvc.get_endpoint_config_selector(name)
+        logger.debug('Loaded Endpoint Config Selector: %r', self.ecs)
+
+    def delete_endpoint_config_selector(self, force=False):
+        if force:
+            name = self._ns_name(self.ENDPOINT_CONFIG_SELECTOR_NAME)
+        elif self.ecs:
+            name = self.ecs.name
+        else:
+            return
+        logger.info('Deleting Endpoint Config Selector %s', name)
+        self.netsvc.delete_endpoint_config_selector(name)
+        self.ecs = None
+
+    def create_client_tls_policy(self, *, tls, mtls):
+        name = self._ns_name(self.CLIENT_TLS_POLICY_NAME)
+        logger.info('Creating Client TLS Policy %s', name)
+        if not tls and not mtls:
+            logger.warning(
+                'Client TLS Policy %s neither TLS, nor mTLS '
+                'policy. Skipping creation', name)
+            return
+
+        certificate_provider = self._get_certificate_provider()
+        policy = {}
+        if tls:
+            policy["serverValidationCa"] = [certificate_provider]
+        if mtls:
+            policy["clientCertificate"] = certificate_provider
+
+        self.netsec.create_client_tls_policy(name, policy)
+        self.client_tls_policy = self.netsec.get_client_tls_policy(name)
+        logger.debug('Client TLS Policy loaded: %r', self.client_tls_policy)
+
+    def delete_client_tls_policy(self, force=False):
+        if force:
+            name = self._ns_name(self.CLIENT_TLS_POLICY_NAME)
+        elif self.client_tls_policy:
+            name = self.client_tls_policy.name
+        else:
+            return
+        logger.info('Deleting Client TLS Policy %s', name)
+        self.netsec.delete_client_tls_policy(name)
+        self.client_tls_policy = None
+
+    def backend_service_apply_client_mtls_policy(
+            self,
+            server_namespace,
+            server_name,
+    ):
+        if not self.client_tls_policy:
+            logger.warning(
+                'Client TLS policy not created, '
+                'skipping attaching to Backend Service %s',
+                self.backend_service.name)
+            return
+
+        server_spiffe = (f'spiffe://{self.project}.svc.id.goog/'
+                         f'ns/{server_namespace}/sa/{server_name}')
+        logging.info(
+            'Adding Client TLS Policy to Backend Service %s: %s, '
+            'server %s', self.backend_service.name, self.client_tls_policy.url,
+            server_spiffe)
+
+        self.compute.patch_backend_service(
+            self.backend_service, {
+                'securitySettings': {
+                    'clientTlsPolicy': self.client_tls_policy.url,
+                    'subjectAltNames': [server_spiffe]
+                }
+            })
+
+    @classmethod
+    def _get_certificate_provider(cls):
+        return {
+            "certificateProviderInstance": {
+                "pluginInstance": cls.CERTIFICATE_PROVIDER_INSTANCE,
+            },
+        }
diff --git a/tools/run_tests/xds_k8s_test_driver/framework/rpc/__init__.py b/tools/run_tests/xds_k8s_test_driver/framework/rpc/__init__.py
new file mode 100644 (file)
index 0000000..30d2263
--- /dev/null
@@ -0,0 +1,14 @@
+# 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.
+from framework.rpc import grpc
diff --git a/tools/run_tests/xds_k8s_test_driver/framework/rpc/grpc.py b/tools/run_tests/xds_k8s_test_driver/framework/rpc/grpc.py
new file mode 100644 (file)
index 0000000..79ab84a
--- /dev/null
@@ -0,0 +1,104 @@
+# 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.
+import logging
+import re
+from typing import ClassVar, Dict, Optional
+
+# Workaround: `grpc` must be imported before `google.protobuf.json_format`,
+# to prevent "Segmentation fault". Ref https://github.com/grpc/grpc/issues/24897
+import grpc
+from google.protobuf import json_format
+import google.protobuf.message
+
+logger = logging.getLogger(__name__)
+
+# Type aliases
+Message = google.protobuf.message.Message
+
+
+class GrpcClientHelper:
+    channel: grpc.Channel
+    DEFAULT_CONNECTION_TIMEOUT_SEC = 60
+    DEFAULT_WAIT_FOR_READY_SEC = 60
+
+    def __init__(self, channel: grpc.Channel, stub_class: ClassVar):
+        self.channel = channel
+        self.stub = stub_class(channel)
+        # This is purely cosmetic to make RPC logs look like method calls.
+        self.log_service_name = re.sub('Stub$', '',
+                                       self.stub.__class__.__name__)
+
+    def call_unary_with_deadline(
+            self,
+            *,
+            rpc: str,
+            req: Message,
+            wait_for_ready_sec: Optional[int] = DEFAULT_WAIT_FOR_READY_SEC,
+            connection_timeout_sec: Optional[
+                int] = DEFAULT_CONNECTION_TIMEOUT_SEC,
+            log_level: Optional[int] = logging.DEBUG) -> Message:
+        if wait_for_ready_sec is None:
+            wait_for_ready_sec = self.DEFAULT_WAIT_FOR_READY_SEC
+        if connection_timeout_sec is None:
+            connection_timeout_sec = self.DEFAULT_CONNECTION_TIMEOUT_SEC
+
+        timeout_sec = wait_for_ready_sec + connection_timeout_sec
+        rpc_callable: grpc.UnaryUnaryMultiCallable = getattr(self.stub, rpc)
+
+        call_kwargs = dict(wait_for_ready=True, timeout=timeout_sec)
+        self._log_rpc_request(rpc, req, call_kwargs, log_level)
+        return rpc_callable(req, **call_kwargs)
+
+    def _log_rpc_request(self, rpc, req, call_kwargs, log_level=logging.DEBUG):
+        logger.log(logging.DEBUG if log_level is None else log_level,
+                   'RPC %s.%s(request=%s(%r), %s)', self.log_service_name, rpc,
+                   req.__class__.__name__, json_format.MessageToDict(req),
+                   ', '.join({f'{k}={v}' for k, v in call_kwargs.items()}))
+
+
+class GrpcApp:
+    channels: Dict[int, grpc.Channel]
+
+    class NotFound(Exception):
+        """Requested resource not found"""
+
+        def __init__(self, message):
+            self.message = message
+            super().__init__(message)
+
+    def __init__(self, rpc_host):
+        self.rpc_host = rpc_host
+        # Cache gRPC channels per port
+        self.channels = dict()
+
+    def _make_channel(self, port) -> grpc.Channel:
+        if port not in self.channels:
+            target = f'{self.rpc_host}:{port}'
+            self.channels[port] = grpc.insecure_channel(target)
+        return self.channels[port]
+
+    def close(self):
+        # Close all channels
+        for channel in self.channels.values():
+            channel.close()
+
+    def __enter__(self):
+        return self
+
+    def __exit__(self, exc_type, exc_val, exc_tb):
+        self.close()
+        return False
+
+    def __del__(self):
+        self.close()
diff --git a/tools/run_tests/xds_k8s_test_driver/framework/rpc/grpc_channelz.py b/tools/run_tests/xds_k8s_test_driver/framework/rpc/grpc_channelz.py
new file mode 100644 (file)
index 0000000..3bf4b26
--- /dev/null
@@ -0,0 +1,196 @@
+# 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.
+"""
+This contains helpers for gRPC services defined in
+https://github.com/grpc/grpc-proto/blob/master/grpc/channelz/v1/channelz.proto
+"""
+import ipaddress
+import logging
+from typing import Iterator, Optional
+
+import grpc
+from grpc_channelz.v1 import channelz_pb2
+from grpc_channelz.v1 import channelz_pb2_grpc
+
+import framework.rpc
+
+logger = logging.getLogger(__name__)
+
+# Type aliases
+# Channel
+Channel = channelz_pb2.Channel
+ChannelConnectivityState = channelz_pb2.ChannelConnectivityState
+ChannelState = ChannelConnectivityState.State  # pylint: disable=no-member
+_GetTopChannelsRequest = channelz_pb2.GetTopChannelsRequest
+_GetTopChannelsResponse = channelz_pb2.GetTopChannelsResponse
+# Subchannel
+Subchannel = channelz_pb2.Subchannel
+_GetSubchannelRequest = channelz_pb2.GetSubchannelRequest
+_GetSubchannelResponse = channelz_pb2.GetSubchannelResponse
+# Server
+Server = channelz_pb2.Server
+_GetServersRequest = channelz_pb2.GetServersRequest
+_GetServersResponse = channelz_pb2.GetServersResponse
+# Sockets
+Socket = channelz_pb2.Socket
+SocketRef = channelz_pb2.SocketRef
+_GetSocketRequest = channelz_pb2.GetSocketRequest
+_GetSocketResponse = channelz_pb2.GetSocketResponse
+Address = channelz_pb2.Address
+Security = channelz_pb2.Security
+# Server Sockets
+_GetServerSocketsRequest = channelz_pb2.GetServerSocketsRequest
+_GetServerSocketsResponse = channelz_pb2.GetServerSocketsResponse
+
+
+class ChannelzServiceClient(framework.rpc.grpc.GrpcClientHelper):
+    stub: channelz_pb2_grpc.ChannelzStub
+
+    def __init__(self, channel: grpc.Channel):
+        super().__init__(channel, channelz_pb2_grpc.ChannelzStub)
+
+    @staticmethod
+    def is_sock_tcpip_address(address: Address):
+        return address.WhichOneof('address') == 'tcpip_address'
+
+    @staticmethod
+    def is_ipv4(tcpip_address: Address.TcpIpAddress):
+        # According to proto, tcpip_address.ip_address is either IPv4 or IPv6.
+        # Correspondingly, it's either 4 bytes or 16 bytes in length.
+        return len(tcpip_address.ip_address) == 4
+
+    @classmethod
+    def sock_address_to_str(cls, address: Address):
+        if cls.is_sock_tcpip_address(address):
+            tcpip_address: Address.TcpIpAddress = address.tcpip_address
+            if cls.is_ipv4(tcpip_address):
+                ip = ipaddress.IPv4Address(tcpip_address.ip_address)
+            else:
+                ip = ipaddress.IPv6Address(tcpip_address.ip_address)
+            return f'{ip}:{tcpip_address.port}'
+        else:
+            raise NotImplementedError('Only tcpip_address implemented')
+
+    @classmethod
+    def sock_addresses_pretty(cls, socket: Socket):
+        return (f'local={cls.sock_address_to_str(socket.local)}, '
+                f'remote={cls.sock_address_to_str(socket.remote)}')
+
+    @staticmethod
+    def find_server_socket_matching_client(server_sockets: Iterator[Socket],
+                                           client_socket: Socket) -> Socket:
+        for server_socket in server_sockets:
+            if server_socket.remote == client_socket.local:
+                return server_socket
+        return None
+
+    def find_channels_for_target(self, target: str) -> Iterator[Channel]:
+        return (channel for channel in self.list_channels()
+                if channel.data.target == target)
+
+    def find_server_listening_on_port(self, port: int) -> Optional[Server]:
+        for server in self.list_servers():
+            listen_socket_ref: SocketRef
+            for listen_socket_ref in server.listen_socket:
+                listen_socket = self.get_socket(listen_socket_ref.socket_id)
+                listen_address: Address = listen_socket.local
+                if (self.is_sock_tcpip_address(listen_address) and
+                        listen_address.tcpip_address.port == port):
+                    return server
+        return None
+
+    def list_channels(self) -> Iterator[Channel]:
+        """
+        Iterate over all pages of all root channels.
+
+        Root channels are those which application has directly created.
+        This does not include subchannels nor non-top level channels.
+        """
+        start: int = -1
+        response: Optional[_GetTopChannelsResponse] = None
+        while start < 0 or not response.end:
+            # From proto: To request subsequent pages, the client generates this
+            # value by adding 1 to the highest seen result ID.
+            start += 1
+            response = self.call_unary_with_deadline(
+                rpc='GetTopChannels',
+                req=_GetTopChannelsRequest(start_channel_id=start))
+            for channel in response.channel:
+                start = max(start, channel.ref.channel_id)
+                yield channel
+
+    def list_servers(self) -> Iterator[Server]:
+        """Iterate over all pages of all servers that exist in the process."""
+        start: int = -1
+        response: Optional[_GetServersResponse] = None
+        while start < 0 or not response.end:
+            # From proto: To request subsequent pages, the client generates this
+            # value by adding 1 to the highest seen result ID.
+            start += 1
+            response = self.call_unary_with_deadline(
+                rpc='GetServers', req=_GetServersRequest(start_server_id=start))
+            for server in response.server:
+                start = max(start, server.ref.server_id)
+                yield server
+
+    def list_server_sockets(self, server: Server) -> Iterator[Socket]:
+        """List all server sockets that exist in server process.
+
+        Iterating over the results will resolve additional pages automatically.
+        """
+        start: int = -1
+        response: Optional[_GetServerSocketsResponse] = None
+        while start < 0 or not response.end:
+            # From proto: To request subsequent pages, the client generates this
+            # value by adding 1 to the highest seen result ID.
+            start += 1
+            response = self.call_unary_with_deadline(
+                rpc='GetServerSockets',
+                req=_GetServerSocketsRequest(server_id=server.ref.server_id,
+                                             start_socket_id=start))
+            socket_ref: SocketRef
+            for socket_ref in response.socket_ref:
+                start = max(start, socket_ref.socket_id)
+                # Yield actual socket
+                yield self.get_socket(socket_ref.socket_id)
+
+    def list_channel_sockets(self, channel: Channel) -> Iterator[Socket]:
+        """List all sockets of all subchannels of a given channel."""
+        for subchannel in self.list_channel_subchannels(channel):
+            yield from self.list_subchannels_sockets(subchannel)
+
+    def list_channel_subchannels(self,
+                                 channel: Channel) -> Iterator[Subchannel]:
+        """List all subchannels of a given channel."""
+        for subchannel_ref in channel.subchannel_ref:
+            yield self.get_subchannel(subchannel_ref.subchannel_id)
+
+    def list_subchannels_sockets(self,
+                                 subchannel: Subchannel) -> Iterator[Socket]:
+        """List all sockets of a given subchannel."""
+        for socket_ref in subchannel.socket_ref:
+            yield self.get_socket(socket_ref.socket_id)
+
+    def get_subchannel(self, subchannel_id) -> Subchannel:
+        """Return a single Subchannel, otherwise raises RpcError."""
+        response: _GetSubchannelResponse = self.call_unary_with_deadline(
+            rpc='GetSubchannel',
+            req=_GetSubchannelRequest(subchannel_id=subchannel_id))
+        return response.subchannel
+
+    def get_socket(self, socket_id) -> Socket:
+        """Return a single Socket, otherwise raises RpcError."""
+        response: _GetSocketResponse = self.call_unary_with_deadline(
+            rpc='GetSocket', req=_GetSocketRequest(socket_id=socket_id))
+        return response.socket
diff --git a/tools/run_tests/xds_k8s_test_driver/framework/rpc/grpc_testing.py b/tools/run_tests/xds_k8s_test_driver/framework/rpc/grpc_testing.py
new file mode 100644 (file)
index 0000000..58fff64
--- /dev/null
@@ -0,0 +1,53 @@
+# 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.
+"""
+This contains helpers for gRPC services defined in
+https://github.com/grpc/grpc/blob/master/src/proto/grpc/testing/test.proto
+"""
+import logging
+from typing import Optional
+
+import grpc
+
+import framework.rpc
+from src.proto.grpc.testing import test_pb2_grpc
+from src.proto.grpc.testing import messages_pb2
+
+# Type aliases
+_LoadBalancerStatsRequest = messages_pb2.LoadBalancerStatsRequest
+LoadBalancerStatsResponse = messages_pb2.LoadBalancerStatsResponse
+
+
+class LoadBalancerStatsServiceClient(framework.rpc.grpc.GrpcClientHelper):
+    stub: test_pb2_grpc.LoadBalancerStatsServiceStub
+    STATS_PARTIAL_RESULTS_TIMEOUT_SEC = 1200
+
+    def __init__(self, channel: grpc.Channel):
+        super().__init__(channel, test_pb2_grpc.LoadBalancerStatsServiceStub)
+
+    def get_client_stats(
+            self,
+            *,
+            num_rpcs: int,
+            timeout_sec: Optional[int] = STATS_PARTIAL_RESULTS_TIMEOUT_SEC,
+    ) -> LoadBalancerStatsResponse:
+        if timeout_sec is None:
+            timeout_sec = self.STATS_PARTIAL_RESULTS_TIMEOUT_SEC
+
+        return self.call_unary_with_deadline(rpc='GetClientStats',
+                                             req=_LoadBalancerStatsRequest(
+                                                 num_rpcs=num_rpcs,
+                                                 timeout_sec=timeout_sec),
+                                             wait_for_ready_sec=timeout_sec,
+                                             log_level=logging.INFO)
diff --git a/tools/run_tests/xds_k8s_test_driver/framework/test_app/__init__.py b/tools/run_tests/xds_k8s_test_driver/framework/test_app/__init__.py
new file mode 100644 (file)
index 0000000..1c0a3a3
--- /dev/null
@@ -0,0 +1,13 @@
+# 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.
diff --git a/tools/run_tests/xds_k8s_test_driver/framework/test_app/base_runner.py b/tools/run_tests/xds_k8s_test_driver/framework/test_app/base_runner.py
new file mode 100644 (file)
index 0000000..58a73d4
--- /dev/null
@@ -0,0 +1,246 @@
+# 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.
+import contextlib
+import logging
+import pathlib
+from typing import Optional
+
+import mako.template
+import yaml
+
+from framework.infrastructure import k8s
+
+logger = logging.getLogger(__name__)
+
+
+class RunnerError(Exception):
+    """Error running app"""
+
+
+class KubernetesBaseRunner:
+    TEMPLATE_DIR_NAME = 'kubernetes-manifests'
+    TEMPLATE_DIR_RELATIVE_PATH = f'../../{TEMPLATE_DIR_NAME}'
+
+    def __init__(self,
+                 k8s_namespace,
+                 namespace_template=None,
+                 reuse_namespace=False):
+        # Kubernetes namespaced resources manager
+        self.k8s_namespace: k8s.KubernetesNamespace = k8s_namespace
+        self.reuse_namespace = reuse_namespace
+        self.namespace_template = namespace_template or 'namespace.yaml'
+
+        # Mutable state
+        self.namespace: Optional[k8s.V1Namespace] = None
+
+    def run(self, **kwargs):
+        if self.reuse_namespace:
+            self.namespace = self._reuse_namespace()
+        if not self.namespace:
+            self.namespace = self._create_namespace(
+                self.namespace_template, namespace_name=self.k8s_namespace.name)
+
+    def cleanup(self, *, force=False):
+        if (self.namespace and not self.reuse_namespace) or force:
+            self._delete_namespace()
+            self.namespace = None
+
+    @staticmethod
+    def _render_template(template_file, **kwargs):
+        template = mako.template.Template(filename=str(template_file))
+        return template.render(**kwargs)
+
+    @staticmethod
+    def _manifests_from_yaml_file(yaml_file):
+        with open(yaml_file) as f:
+            with contextlib.closing(yaml.safe_load_all(f)) as yml:
+                for manifest in yml:
+                    yield manifest
+
+    @staticmethod
+    def _manifests_from_str(document):
+        with contextlib.closing(yaml.safe_load_all(document)) as yml:
+            for manifest in yml:
+                yield manifest
+
+    @classmethod
+    def _template_file_from_name(cls, template_name):
+        templates_path = (pathlib.Path(__file__).parent /
+                          cls.TEMPLATE_DIR_RELATIVE_PATH)
+        return templates_path.joinpath(template_name).resolve()
+
+    def _create_from_template(self, template_name, **kwargs):
+        template_file = self._template_file_from_name(template_name)
+        logger.debug("Loading k8s manifest template: %s", template_file)
+
+        yaml_doc = self._render_template(template_file, **kwargs)
+        logger.info("Rendered template %s/%s:\n%s", self.TEMPLATE_DIR_NAME,
+                    template_name, yaml_doc)
+
+        manifests = self._manifests_from_str(yaml_doc)
+        manifest = next(manifests)
+        # Error out on multi-document yaml
+        if next(manifests, False):
+            raise RunnerError('Exactly one document expected in manifest '
+                              f'{template_file}')
+        k8s_objects = self.k8s_namespace.apply_manifest(manifest)
+        if len(k8s_objects) != 1:
+            raise RunnerError('Expected exactly one object must created from '
+                              f'manifest {template_file}')
+
+        logger.info('%s %s created', k8s_objects[0].kind,
+                    k8s_objects[0].metadata.name)
+        return k8s_objects[0]
+
+    def _reuse_deployment(self, deployment_name) -> k8s.V1Deployment:
+        deployment = self.k8s_namespace.get_deployment(deployment_name)
+        # TODO(sergiitk): check if good or must be recreated
+        return deployment
+
+    def _reuse_service(self, service_name) -> k8s.V1Service:
+        service = self.k8s_namespace.get_service(service_name)
+        # TODO(sergiitk): check if good or must be recreated
+        return service
+
+    def _reuse_namespace(self) -> k8s.V1Namespace:
+        return self.k8s_namespace.get()
+
+    def _create_namespace(self, template, **kwargs) -> k8s.V1Namespace:
+        namespace = self._create_from_template(template, **kwargs)
+        if not isinstance(namespace, k8s.V1Namespace):
+            raise RunnerError('Expected V1Namespace to be created '
+                              f'from manifest {template}')
+        if namespace.metadata.name != kwargs['namespace_name']:
+            raise RunnerError('V1Namespace created with unexpected name: '
+                              f'{namespace.metadata.name}')
+        logger.debug('V1Namespace %s created at %s',
+                     namespace.metadata.self_link,
+                     namespace.metadata.creation_timestamp)
+        return namespace
+
+    def _create_service_account(self, template,
+                                **kwargs) -> k8s.V1ServiceAccount:
+        resource = self._create_from_template(template, **kwargs)
+        if not isinstance(resource, k8s.V1ServiceAccount):
+            raise RunnerError('Expected V1ServiceAccount to be created '
+                              f'from manifest {template}')
+        if resource.metadata.name != kwargs['service_account_name']:
+            raise RunnerError('V1ServiceAccount created with unexpected name: '
+                              f'{resource.metadata.name}')
+        logger.debug('V1ServiceAccount %s created at %s',
+                     resource.metadata.self_link,
+                     resource.metadata.creation_timestamp)
+        return resource
+
+    def _create_deployment(self, template, **kwargs) -> k8s.V1Deployment:
+        deployment = self._create_from_template(template, **kwargs)
+        if not isinstance(deployment, k8s.V1Deployment):
+            raise RunnerError('Expected V1Deployment to be created '
+                              f'from manifest {template}')
+        if deployment.metadata.name != kwargs['deployment_name']:
+            raise RunnerError('V1Deployment created with unexpected name: '
+                              f'{deployment.metadata.name}')
+        logger.debug('V1Deployment %s created at %s',
+                     deployment.metadata.self_link,
+                     deployment.metadata.creation_timestamp)
+        return deployment
+
+    def _create_service(self, template, **kwargs) -> k8s.V1Service:
+        service = self._create_from_template(template, **kwargs)
+        if not isinstance(service, k8s.V1Service):
+            raise RunnerError('Expected V1Service to be created '
+                              f'from manifest {template}')
+        if service.metadata.name != kwargs['service_name']:
+            raise RunnerError('V1Service created with unexpected name: '
+                              f'{service.metadata.name}')
+        logger.debug('V1Service %s created at %s', service.metadata.self_link,
+                     service.metadata.creation_timestamp)
+        return service
+
+    def _delete_deployment(self, name, wait_for_deletion=True):
+        logger.info('Deleting deployment %s', name)
+        try:
+            self.k8s_namespace.delete_deployment(name)
+        except k8s.ApiException as e:
+            logger.info('Deployment %s deletion failed, error: %s %s', name,
+                        e.status, e.reason)
+            return
+
+        if wait_for_deletion:
+            self.k8s_namespace.wait_for_deployment_deleted(name)
+        logger.debug('Deployment %s deleted', name)
+
+    def _delete_service(self, name, wait_for_deletion=True):
+        logger.info('Deleting service %s', name)
+        try:
+            self.k8s_namespace.delete_service(name)
+        except k8s.ApiException as e:
+            logger.info('Service %s deletion failed, error: %s %s', name,
+                        e.status, e.reason)
+            return
+
+        if wait_for_deletion:
+            self.k8s_namespace.wait_for_service_deleted(name)
+        logger.debug('Service %s deleted', name)
+
+    def _delete_service_account(self, name, wait_for_deletion=True):
+        logger.info('Deleting service account %s', name)
+        try:
+            self.k8s_namespace.delete_service_account(name)
+        except k8s.ApiException as e:
+            logger.info('Service account %s deletion failed, error: %s %s',
+                        name, e.status, e.reason)
+            return
+
+        if wait_for_deletion:
+            self.k8s_namespace.wait_for_service_account_deleted(name)
+        logger.debug('Service account %s deleted', name)
+
+    def _delete_namespace(self, wait_for_deletion=True):
+        logger.info('Deleting namespace %s', self.k8s_namespace.name)
+        try:
+            self.k8s_namespace.delete()
+        except k8s.ApiException as e:
+            logger.info('Namespace %s deletion failed, error: %s %s',
+                        self.k8s_namespace.name, e.status, e.reason)
+            return
+
+        if wait_for_deletion:
+            self.k8s_namespace.wait_for_namespace_deleted()
+        logger.debug('Namespace %s deleted', self.k8s_namespace.name)
+
+    def _wait_deployment_with_available_replicas(self, name, count=1, **kwargs):
+        logger.info('Waiting for deployment %s to have %s available replica(s)',
+                    name, count)
+        self.k8s_namespace.wait_for_deployment_available_replicas(
+            name, count, **kwargs)
+        deployment = self.k8s_namespace.get_deployment(name)
+        logger.info('Deployment %s has %i replicas available',
+                    deployment.metadata.name,
+                    deployment.status.available_replicas)
+
+    def _wait_pod_started(self, name, **kwargs):
+        logger.info('Waiting for pod %s to start', name)
+        self.k8s_namespace.wait_for_pod_started(name, **kwargs)
+        pod = self.k8s_namespace.get_pod(name)
+        logger.info('Pod %s ready, IP: %s', pod.metadata.name,
+                    pod.status.pod_ip)
+
+    def _wait_service_neg(self, name, service_port, **kwargs):
+        logger.info('Waiting for NEG for service %s', name)
+        self.k8s_namespace.wait_for_service_neg(name, **kwargs)
+        neg_name, neg_zones = self.k8s_namespace.get_service_neg(
+            name, service_port)
+        logger.info("Service %s: detected NEG=%s in zones=%s", name, neg_name,
+                    neg_zones)
diff --git a/tools/run_tests/xds_k8s_test_driver/framework/test_app/client_app.py b/tools/run_tests/xds_k8s_test_driver/framework/test_app/client_app.py
new file mode 100644 (file)
index 0000000..31ec666
--- /dev/null
@@ -0,0 +1,285 @@
+# 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.
+"""
+xDS Test Client.
+
+TODO(sergiitk): separate XdsTestClient and KubernetesClientRunner to individual
+modules.
+"""
+import datetime
+import functools
+import logging
+from typing import Iterator, Optional
+
+from framework.helpers import retryers
+from framework.infrastructure import k8s
+import framework.rpc
+from framework.rpc import grpc_channelz
+from framework.rpc import grpc_testing
+from framework.test_app import base_runner
+
+logger = logging.getLogger(__name__)
+
+# Type aliases
+_timedelta = datetime.timedelta
+_LoadBalancerStatsServiceClient = grpc_testing.LoadBalancerStatsServiceClient
+_ChannelzServiceClient = grpc_channelz.ChannelzServiceClient
+_ChannelzChannel = grpc_channelz.Channel
+_ChannelzChannelState = grpc_channelz.ChannelState
+_ChannelzSubchannel = grpc_channelz.Subchannel
+_ChannelzSocket = grpc_channelz.Socket
+
+
+class XdsTestClient(framework.rpc.grpc.GrpcApp):
+    """
+    Represents RPC services implemented in Client component of the xds test app.
+    https://github.com/grpc/grpc/blob/master/doc/xds-test-descriptions.md#client
+    """
+
+    def __init__(self,
+                 *,
+                 ip: str,
+                 rpc_port: int,
+                 server_target: str,
+                 rpc_host: Optional[str] = None,
+                 maintenance_port: Optional[int] = None):
+        super().__init__(rpc_host=(rpc_host or ip))
+        self.ip = ip
+        self.rpc_port = rpc_port
+        self.server_target = server_target
+        self.maintenance_port = maintenance_port or rpc_port
+
+    @property
+    @functools.lru_cache(None)
+    def load_balancer_stats(self) -> _LoadBalancerStatsServiceClient:
+        return _LoadBalancerStatsServiceClient(self._make_channel(
+            self.rpc_port))
+
+    @property
+    @functools.lru_cache(None)
+    def channelz(self) -> _ChannelzServiceClient:
+        return _ChannelzServiceClient(self._make_channel(self.maintenance_port))
+
+    def get_load_balancer_stats(
+            self,
+            *,
+            num_rpcs: int,
+            timeout_sec: Optional[int] = None,
+    ) -> grpc_testing.LoadBalancerStatsResponse:
+        """
+        Shortcut to LoadBalancerStatsServiceClient.get_client_stats()
+        """
+        return self.load_balancer_stats.get_client_stats(
+            num_rpcs=num_rpcs, timeout_sec=timeout_sec)
+
+    def get_server_channels(self) -> Iterator[_ChannelzChannel]:
+        return self.channelz.find_channels_for_target(self.server_target)
+
+    def wait_for_active_server_channel(self) -> _ChannelzChannel:
+        """Wait for the channel to the server to transition to READY.
+
+        Raises:
+            GrpcApp.NotFound: If the channel never transitioned to READY.
+        """
+        return self.wait_for_server_channel_state(_ChannelzChannelState.READY)
+
+    def get_active_server_channel(self) -> _ChannelzChannel:
+        """Return a READY channel to the server.
+
+        Raises:
+            GrpcApp.NotFound: If there's no READY channel to the server.
+        """
+        return self.find_server_channel_with_state(_ChannelzChannelState.READY)
+
+    def get_active_server_channel_socket(self) -> _ChannelzSocket:
+        channel = self.get_active_server_channel()
+        # Get the first subchannel of the active channel to the server.
+        logger.debug(
+            'Retrieving client -> server socket, '
+            'channel_id: %s, subchannel: %s', channel.ref.channel_id,
+            channel.subchannel_ref[0].name)
+        subchannel, *subchannels = list(
+            self.channelz.list_channel_subchannels(channel))
+        if subchannels:
+            logger.warning('Unexpected subchannels: %r', subchannels)
+        # Get the first socket of the subchannel
+        socket, *sockets = list(
+            self.channelz.list_subchannels_sockets(subchannel))
+        if sockets:
+            logger.warning('Unexpected sockets: %r', subchannels)
+        logger.debug('Found client -> server socket: %s', socket.ref.name)
+        return socket
+
+    def wait_for_server_channel_state(self,
+                                      state: _ChannelzChannelState,
+                                      *,
+                                      timeout: Optional[_timedelta] = None
+                                     ) -> _ChannelzChannel:
+        # Fine-tuned to wait for the channel to the server.
+        retryer = retryers.exponential_retryer_with_timeout(
+            wait_min=_timedelta(seconds=10),
+            wait_max=_timedelta(seconds=25),
+            timeout=_timedelta(minutes=3) if timeout is None else timeout)
+
+        logger.info('Waiting for client %s to report a %s channel to %s',
+                    self.ip, _ChannelzChannelState.Name(state),
+                    self.server_target)
+        channel = retryer(self.find_server_channel_with_state, state)
+        logger.info('Client %s channel to %s transitioned to state %s:\n%s',
+                    self.ip, self.server_target,
+                    _ChannelzChannelState.Name(state), channel)
+        return channel
+
+    def find_server_channel_with_state(self,
+                                       state: _ChannelzChannelState,
+                                       *,
+                                       check_subchannel=True
+                                      ) -> _ChannelzChannel:
+        for channel in self.get_server_channels():
+            channel_state: _ChannelzChannelState = channel.data.state.state
+            logger.info('Server channel: %s, state: %s', channel.ref.name,
+                        _ChannelzChannelState.Name(channel_state))
+            if channel_state is state:
+                if check_subchannel:
+                    # When requested, check if the channel has at least
+                    # one subchannel in the requested state.
+                    try:
+                        subchannel = self.find_subchannel_with_state(
+                            channel, state)
+                        logger.info('Found subchannel in state %s: %s', state,
+                                    subchannel)
+                    except self.NotFound as e:
+                        # Otherwise, keep searching.
+                        logger.info(e.message)
+                        continue
+                return channel
+
+        raise self.NotFound(
+            f'Client has no {_ChannelzChannelState.Name(state)} channel with '
+            'the server')
+
+    def find_subchannel_with_state(self, channel: _ChannelzChannel,
+                                   state: _ChannelzChannelState
+                                  ) -> _ChannelzSubchannel:
+        for subchannel in self.channelz.list_channel_subchannels(channel):
+            if subchannel.data.state.state is state:
+                return subchannel
+
+        raise self.NotFound(
+            f'Not found a {_ChannelzChannelState.Name(state)} '
+            f'subchannel for channel_id {channel.ref.channel_id}')
+
+
+class KubernetesClientRunner(base_runner.KubernetesBaseRunner):
+
+    def __init__(self,
+                 k8s_namespace,
+                 *,
+                 deployment_name,
+                 image_name,
+                 gcp_service_account,
+                 td_bootstrap_image,
+                 service_account_name=None,
+                 stats_port=8079,
+                 network='default',
+                 deployment_template='client.deployment.yaml',
+                 service_account_template='service-account.yaml',
+                 reuse_namespace=False,
+                 namespace_template=None,
+                 debug_use_port_forwarding=False):
+        super().__init__(k8s_namespace, namespace_template, reuse_namespace)
+
+        # Settings
+        self.deployment_name = deployment_name
+        self.image_name = image_name
+        self.gcp_service_account = gcp_service_account
+        self.service_account_name = service_account_name or deployment_name
+        self.stats_port = stats_port
+        # xDS bootstrap generator
+        self.td_bootstrap_image = td_bootstrap_image
+        self.network = network
+        self.deployment_template = deployment_template
+        self.service_account_template = service_account_template
+        self.debug_use_port_forwarding = debug_use_port_forwarding
+
+        # Mutable state
+        self.deployment: Optional[k8s.V1Deployment] = None
+        self.service_account: Optional[k8s.V1ServiceAccount] = None
+        self.port_forwarder = None
+
+    def run(self,
+            *,
+            server_target,
+            rpc='UnaryCall',
+            qps=25,
+            secure_mode=False,
+            print_response=False) -> XdsTestClient:
+        super().run()
+        # TODO(sergiitk): make rpc UnaryCall enum or get it from proto
+
+        # Create service account
+        self.service_account = self._create_service_account(
+            self.service_account_template,
+            service_account_name=self.service_account_name,
+            namespace_name=self.k8s_namespace.name,
+            gcp_service_account=self.gcp_service_account)
+
+        # Always create a new deployment
+        self.deployment = self._create_deployment(
+            self.deployment_template,
+            deployment_name=self.deployment_name,
+            image_name=self.image_name,
+            namespace_name=self.k8s_namespace.name,
+            service_account_name=self.service_account_name,
+            td_bootstrap_image=self.td_bootstrap_image,
+            network_name=self.network,
+            stats_port=self.stats_port,
+            server_target=server_target,
+            rpc=rpc,
+            qps=qps,
+            secure_mode=secure_mode,
+            print_response=print_response)
+
+        self._wait_deployment_with_available_replicas(self.deployment_name)
+
+        # Load test client pod. We need only one client at the moment
+        pod = self.k8s_namespace.list_deployment_pods(self.deployment)[0]
+        self._wait_pod_started(pod.metadata.name)
+        pod_ip = pod.status.pod_ip
+        rpc_host = None
+
+        # Experimental, for local debugging.
+        if self.debug_use_port_forwarding:
+            logger.info('LOCAL DEV MODE: Enabling port forwarding to %s:%s',
+                        pod_ip, self.stats_port)
+            self.port_forwarder = self.k8s_namespace.port_forward_pod(
+                pod, remote_port=self.stats_port)
+            rpc_host = self.k8s_namespace.PORT_FORWARD_LOCAL_ADDRESS
+
+        return XdsTestClient(ip=pod_ip,
+                             rpc_port=self.stats_port,
+                             server_target=server_target,
+                             rpc_host=rpc_host)
+
+    def cleanup(self, *, force=False, force_namespace=False):
+        if self.port_forwarder:
+            self.k8s_namespace.port_forward_stop(self.port_forwarder)
+            self.port_forwarder = None
+        if self.deployment or force:
+            self._delete_deployment(self.deployment_name)
+            self.deployment = None
+        if self.service_account or force:
+            self._delete_service_account(self.service_account_name)
+            self.service_account = None
+        super().cleanup(force=force_namespace and force)
diff --git a/tools/run_tests/xds_k8s_test_driver/framework/test_app/server_app.py b/tools/run_tests/xds_k8s_test_driver/framework/test_app/server_app.py
new file mode 100644 (file)
index 0000000..0f41df7
--- /dev/null
@@ -0,0 +1,280 @@
+# 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.
+"""
+xDS Test Server.
+
+TODO(sergiitk): separate XdsTestServer and KubernetesServerRunner to individual
+modules.
+"""
+import functools
+import logging
+from typing import Iterator, Optional
+
+from framework.infrastructure import k8s
+import framework.rpc
+from framework.rpc import grpc_channelz
+from framework.test_app import base_runner
+
+logger = logging.getLogger(__name__)
+
+# Type aliases
+_ChannelzServiceClient = grpc_channelz.ChannelzServiceClient
+
+
+class XdsTestServer(framework.rpc.grpc.GrpcApp):
+    """
+    Represents RPC services implemented in Server component of the xDS test app.
+    https://github.com/grpc/grpc/blob/master/doc/xds-test-descriptions.md#server
+    """
+
+    def __init__(self,
+                 *,
+                 ip: str,
+                 rpc_port: int,
+                 maintenance_port: Optional[int] = None,
+                 secure_mode: Optional[bool] = False,
+                 server_id: Optional[str] = None,
+                 xds_host: Optional[str] = None,
+                 xds_port: Optional[int] = None,
+                 rpc_host: Optional[str] = None):
+        super().__init__(rpc_host=(rpc_host or ip))
+        self.ip = ip
+        self.rpc_port = rpc_port
+        self.maintenance_port = maintenance_port or rpc_port
+        self.secure_mode = secure_mode
+        self.server_id = server_id
+        self.xds_host, self.xds_port = xds_host, xds_port
+
+    @property
+    @functools.lru_cache(None)
+    def channelz(self) -> _ChannelzServiceClient:
+        return _ChannelzServiceClient(self._make_channel(self.maintenance_port))
+
+    def set_xds_address(self, xds_host, xds_port: Optional[int] = None):
+        self.xds_host, self.xds_port = xds_host, xds_port
+
+    @property
+    def xds_address(self) -> str:
+        if not self.xds_host:
+            return ''
+        if not self.xds_port:
+            return self.xds_host
+        return f'{self.xds_host}:{self.xds_port}'
+
+    @property
+    def xds_uri(self) -> str:
+        if not self.xds_host:
+            return ''
+        return f'xds:///{self.xds_address}'
+
+    def get_test_server(self) -> grpc_channelz.Server:
+        """Return channelz representation of a server running TestService.
+
+        Raises:
+            GrpcApp.NotFound: Test server not found.
+        """
+        server = self.channelz.find_server_listening_on_port(self.rpc_port)
+        if not server:
+            raise self.NotFound(
+                f'Server listening on port {self.rpc_port} not found')
+        return server
+
+    def get_test_server_sockets(self) -> Iterator[grpc_channelz.Socket]:
+        """List all sockets of the test server.
+
+        Raises:
+            GrpcApp.NotFound: Test server not found.
+        """
+        server = self.get_test_server()
+        return self.channelz.list_server_sockets(server)
+
+    def get_server_socket_matching_client(self,
+                                          client_socket: grpc_channelz.Socket):
+        """Find test server socket that matches given test client socket.
+
+        Sockets are matched using TCP endpoints (ip:port), further on "address".
+        Server socket remote address matched with client socket local address.
+
+         Raises:
+             GrpcApp.NotFound: Server socket matching client socket not found.
+         """
+        client_local = self.channelz.sock_address_to_str(client_socket.local)
+        logger.debug('Looking for a server socket connected to the client %s',
+                     client_local)
+
+        server_socket = self.channelz.find_server_socket_matching_client(
+            self.get_test_server_sockets(), client_socket)
+        if not server_socket:
+            raise self.NotFound(
+                f'Server socket to client {client_local} not found')
+
+        logger.info('Found matching socket pair: server(%s) <-> client(%s)',
+                    self.channelz.sock_addresses_pretty(server_socket),
+                    self.channelz.sock_addresses_pretty(client_socket))
+        return server_socket
+
+
+class KubernetesServerRunner(base_runner.KubernetesBaseRunner):
+
+    def __init__(self,
+                 k8s_namespace,
+                 *,
+                 deployment_name,
+                 image_name,
+                 gcp_service_account,
+                 service_account_name=None,
+                 service_name=None,
+                 neg_name=None,
+                 td_bootstrap_image=None,
+                 network='default',
+                 deployment_template='server.deployment.yaml',
+                 service_account_template='service-account.yaml',
+                 service_template='server.service.yaml',
+                 reuse_service=False,
+                 reuse_namespace=False,
+                 namespace_template=None,
+                 debug_use_port_forwarding=False):
+        super().__init__(k8s_namespace, namespace_template, reuse_namespace)
+
+        # Settings
+        self.deployment_name = deployment_name
+        self.image_name = image_name
+        self.gcp_service_account = gcp_service_account
+        self.service_account_name = service_account_name or deployment_name
+        self.service_name = service_name or deployment_name
+        # xDS bootstrap generator
+        self.td_bootstrap_image = td_bootstrap_image
+        # This only works in k8s >= 1.18.10-gke.600
+        # https://cloud.google.com/kubernetes-engine/docs/how-to/standalone-neg#naming_negs
+        self.neg_name = neg_name or (f'{self.k8s_namespace.name}-'
+                                     f'{self.service_name}')
+        self.network = network
+        self.deployment_template = deployment_template
+        self.service_account_template = service_account_template
+        self.service_template = service_template
+        self.reuse_service = reuse_service
+        self.debug_use_port_forwarding = debug_use_port_forwarding
+
+        # Mutable state
+        self.deployment: Optional[k8s.V1Deployment] = None
+        self.service_account: Optional[k8s.V1ServiceAccount] = None
+        self.service: Optional[k8s.V1Service] = None
+        self.port_forwarder = None
+
+    def run(self,
+            *,
+            test_port=8080,
+            maintenance_port=None,
+            secure_mode=False,
+            server_id=None,
+            replica_count=1) -> XdsTestServer:
+        # TODO(sergiitk): multiple replicas
+        if replica_count != 1:
+            raise NotImplementedError("Multiple replicas not yet supported")
+
+        # Implementation detail: in secure mode, maintenance ("backchannel")
+        # port must be different from the test port so communication with
+        # maintenance services can be reached independently from the security
+        # configuration under test.
+        if maintenance_port is None:
+            maintenance_port = test_port if not secure_mode else test_port + 1
+        if secure_mode and maintenance_port == test_port:
+            raise ValueError('port and maintenance_port must be different '
+                             'when running test server in secure mode')
+        # To avoid bugs with comparing wrong types.
+        if not (isinstance(test_port, int) and
+                isinstance(maintenance_port, int)):
+            raise TypeError('Port numbers must be integer')
+
+        # Create namespace.
+        super().run()
+
+        # Reuse existing if requested, create a new deployment when missing.
+        # Useful for debugging to avoid NEG loosing relation to deleted service.
+        if self.reuse_service:
+            self.service = self._reuse_service(self.service_name)
+        if not self.service:
+            self.service = self._create_service(
+                self.service_template,
+                service_name=self.service_name,
+                namespace_name=self.k8s_namespace.name,
+                deployment_name=self.deployment_name,
+                neg_name=self.neg_name,
+                test_port=test_port)
+        self._wait_service_neg(self.service_name, test_port)
+
+        # Create service account
+        self.service_account = self._create_service_account(
+            self.service_account_template,
+            service_account_name=self.service_account_name,
+            namespace_name=self.k8s_namespace.name,
+            gcp_service_account=self.gcp_service_account)
+
+        # Always create a new deployment
+        self.deployment = self._create_deployment(
+            self.deployment_template,
+            deployment_name=self.deployment_name,
+            image_name=self.image_name,
+            namespace_name=self.k8s_namespace.name,
+            service_account_name=self.service_account_name,
+            td_bootstrap_image=self.td_bootstrap_image,
+            network_name=self.network,
+            replica_count=replica_count,
+            test_port=test_port,
+            maintenance_port=maintenance_port,
+            server_id=server_id,
+            secure_mode=secure_mode)
+
+        self._wait_deployment_with_available_replicas(self.deployment_name,
+                                                      replica_count,
+                                                      timeout_sec=120)
+
+        # Wait for pods running
+        pods = self.k8s_namespace.list_deployment_pods(self.deployment)
+        for pod in pods:
+            self._wait_pod_started(pod.metadata.name)
+
+        # TODO(sergiitk): This is why multiple replicas not yet supported
+        pod = pods[0]
+        pod_ip = pod.status.pod_ip
+        rpc_host = None
+        # Experimental, for local debugging.
+        if self.debug_use_port_forwarding:
+            logger.info('LOCAL DEV MODE: Enabling port forwarding to %s:%s',
+                        pod_ip, maintenance_port)
+            self.port_forwarder = self.k8s_namespace.port_forward_pod(
+                pod, remote_port=maintenance_port)
+            rpc_host = self.k8s_namespace.PORT_FORWARD_LOCAL_ADDRESS
+
+        return XdsTestServer(ip=pod_ip,
+                             rpc_port=test_port,
+                             maintenance_port=maintenance_port,
+                             secure_mode=secure_mode,
+                             server_id=server_id,
+                             rpc_host=rpc_host)
+
+    def cleanup(self, *, force=False, force_namespace=False):
+        if self.port_forwarder:
+            self.k8s_namespace.port_forward_stop(self.port_forwarder)
+            self.port_forwarder = None
+        if self.deployment or force:
+            self._delete_deployment(self.deployment_name)
+            self.deployment = None
+        if (self.service and not self.reuse_service) or force:
+            self._delete_service(self.service_name)
+            self.service = None
+        if self.service_account or force:
+            self._delete_service_account(self.service_account_name)
+            self.service_account = None
+        super().cleanup(force=(force_namespace and force))
diff --git a/tools/run_tests/xds_k8s_test_driver/framework/xds_flags.py b/tools/run_tests/xds_k8s_test_driver/framework/xds_flags.py
new file mode 100644 (file)
index 0000000..dc118ad
--- /dev/null
@@ -0,0 +1,54 @@
+# 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.
+from absl import flags
+import googleapiclient.discovery
+
+# GCP
+PROJECT = flags.DEFINE_string("project",
+                              default=None,
+                              help="GCP Project ID. Required")
+NAMESPACE = flags.DEFINE_string(
+    "namespace",
+    default=None,
+    help="Isolate GCP resources using given namespace / name prefix. Required")
+NETWORK = flags.DEFINE_string("network",
+                              default="default",
+                              help="GCP Network ID")
+
+# Test server
+SERVER_NAME = flags.DEFINE_string("server_name",
+                                  default="psm-grpc-server",
+                                  help="Server deployment and service name")
+SERVER_PORT = flags.DEFINE_integer("server_port",
+                                   default=8080,
+                                   help="Server test port")
+SERVER_XDS_HOST = flags.DEFINE_string("server_xds_host",
+                                      default='xds-test-server',
+                                      help="Test server xDS hostname")
+SERVER_XDS_PORT = flags.DEFINE_integer("server_xds_port",
+                                       default=8000,
+                                       help="Test server xDS port")
+
+# Test client
+CLIENT_NAME = flags.DEFINE_string("client_name",
+                                  default="psm-grpc-client",
+                                  help="Client deployment and service name")
+CLIENT_PORT = flags.DEFINE_integer("client_port",
+                                   default=8079,
+                                   help="Client test port")
+
+flags.mark_flags_as_required([
+    "project",
+    "namespace",
+])
diff --git a/tools/run_tests/xds_k8s_test_driver/framework/xds_k8s_flags.py b/tools/run_tests/xds_k8s_test_driver/framework/xds_k8s_flags.py
new file mode 100644 (file)
index 0000000..d7f3f0b
--- /dev/null
@@ -0,0 +1,47 @@
+# 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.
+from absl import flags
+
+# GCP
+KUBE_CONTEXT = flags.DEFINE_string("kube_context",
+                                   default=None,
+                                   help="Kubectl context to use")
+GCP_SERVICE_ACCOUNT = flags.DEFINE_string(
+    "gcp_service_account",
+    default=None,
+    help="GCP Service account for GKE workloads to impersonate")
+TD_BOOTSTRAP_IMAGE = flags.DEFINE_string(
+    "td_bootstrap_image",
+    default=None,
+    help="Traffic Director gRPC Bootstrap Docker image")
+
+# Test app
+SERVER_IMAGE = flags.DEFINE_string("server_image",
+                                   default=None,
+                                   help="Server Docker image name")
+CLIENT_IMAGE = flags.DEFINE_string("client_image",
+                                   default=None,
+                                   help="Client Docker image name")
+DEBUG_USE_PORT_FORWARDING = flags.DEFINE_bool(
+    "debug_use_port_forwarding",
+    default=False,
+    help="Development only: use kubectl port-forward to connect to test app")
+
+flags.mark_flags_as_required([
+    "gcp_service_account",
+    "kube_context",
+    "td_bootstrap_image",
+    "server_image",
+    "client_image",
+])
diff --git a/tools/run_tests/xds_k8s_test_driver/framework/xds_k8s_testcase.py b/tools/run_tests/xds_k8s_test_driver/framework/xds_k8s_testcase.py
new file mode 100644 (file)
index 0000000..eaa3c24
--- /dev/null
@@ -0,0 +1,461 @@
+# 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.
+import datetime
+import enum
+import hashlib
+import logging
+import time
+from typing import Optional, Tuple
+
+from absl import flags
+from absl.testing import absltest
+
+from framework import xds_flags
+from framework import xds_k8s_flags
+from framework.infrastructure import gcp
+from framework.infrastructure import k8s
+from framework.infrastructure import traffic_director
+from framework.rpc import grpc_channelz
+from framework.rpc import grpc_testing
+from framework.test_app import client_app
+from framework.test_app import server_app
+
+logger = logging.getLogger(__name__)
+_FORCE_CLEANUP = flags.DEFINE_bool(
+    "force_cleanup",
+    default=False,
+    help="Force resource cleanup, even if not created by this test run")
+flags.adopt_module_key_flags(xds_flags)
+flags.adopt_module_key_flags(xds_k8s_flags)
+
+# Type aliases
+XdsTestServer = server_app.XdsTestServer
+XdsTestClient = client_app.XdsTestClient
+LoadBalancerStatsResponse = grpc_testing.LoadBalancerStatsResponse
+_ChannelState = grpc_channelz.ChannelState
+_timedelta = datetime.timedelta
+
+
+class XdsKubernetesTestCase(absltest.TestCase):
+    k8s_api_manager: k8s.KubernetesApiManager
+    gcp_api_manager: gcp.api.GcpApiManager
+
+    @classmethod
+    def setUpClass(cls):
+        # GCP
+        cls.project: str = xds_flags.PROJECT.value
+        cls.network: str = xds_flags.NETWORK.value
+        cls.gcp_service_account: str = xds_k8s_flags.GCP_SERVICE_ACCOUNT.value
+        cls.td_bootstrap_image = xds_k8s_flags.TD_BOOTSTRAP_IMAGE.value
+
+        # Base namespace
+        # TODO(sergiitk): generate for each test
+        cls.namespace: str = xds_flags.NAMESPACE.value
+
+        # Test server
+        cls.server_image = xds_k8s_flags.SERVER_IMAGE.value
+        cls.server_name = xds_flags.SERVER_NAME.value
+        cls.server_port = xds_flags.SERVER_PORT.value
+        cls.server_xds_host = xds_flags.SERVER_NAME.value
+        cls.server_xds_port = xds_flags.SERVER_XDS_PORT.value
+
+        # Test client
+        cls.client_image = xds_k8s_flags.CLIENT_IMAGE.value
+        cls.client_name = xds_flags.CLIENT_NAME.value
+        cls.client_port = xds_flags.CLIENT_PORT.value
+
+        # Test suite settings
+        cls.force_cleanup = _FORCE_CLEANUP.value
+        cls.debug_use_port_forwarding = \
+            xds_k8s_flags.DEBUG_USE_PORT_FORWARDING.value
+
+        # Resource managers
+        cls.k8s_api_manager = k8s.KubernetesApiManager(
+            xds_k8s_flags.KUBE_CONTEXT.value)
+        cls.gcp_api_manager = gcp.api.GcpApiManager()
+
+    def setUp(self):
+        # TODO(sergiitk): generate namespace with run id for each test
+        self.server_namespace = self.namespace
+        self.client_namespace = self.namespace
+
+        # Init this in child class
+        # TODO(sergiitk): consider making a method to be less error-prone
+        self.server_runner = None
+        self.client_runner = None
+        self.td = None
+
+    @classmethod
+    def tearDownClass(cls):
+        cls.k8s_api_manager.close()
+        cls.gcp_api_manager.close()
+
+    def tearDown(self):
+        logger.info('----- TestMethod %s teardown -----', self.id())
+        self.td.cleanup(force=self.force_cleanup)
+        self.client_runner.cleanup(force=self.force_cleanup)
+        self.server_runner.cleanup(force=self.force_cleanup,
+                                   force_namespace=self.force_cleanup)
+
+    def setupTrafficDirectorGrpc(self):
+        self.td.setup_for_grpc(self.server_xds_host, self.server_xds_port)
+
+    def setupServerBackends(self, *, wait_for_healthy_status=True):
+        # Load Backends
+        neg_name, neg_zones = self.server_runner.k8s_namespace.get_service_neg(
+            self.server_runner.service_name, self.server_port)
+
+        # Add backends to the Backend Service
+        self.td.backend_service_add_neg_backends(neg_name, neg_zones)
+        if wait_for_healthy_status:
+            self.td.wait_for_backends_healthy_status()
+
+    def assertSuccessfulRpcs(self,
+                             test_client: XdsTestClient,
+                             num_rpcs: int = 100):
+        lb_stats = self.sendRpcs(test_client, num_rpcs)
+        self.assertAllBackendsReceivedRpcs(lb_stats)
+        failed = int(lb_stats.num_failures)
+        self.assertLessEqual(
+            failed,
+            0,
+            msg=f'Expected all RPCs to succeed: {failed} of {num_rpcs} failed')
+
+    def assertFailedRpcs(self,
+                         test_client: XdsTestClient,
+                         num_rpcs: Optional[int] = 100):
+        lb_stats = self.sendRpcs(test_client, num_rpcs)
+        failed = int(lb_stats.num_failures)
+        self.assertEqual(
+            failed,
+            num_rpcs,
+            msg=f'Expected all RPCs to fail: {failed} of {num_rpcs} failed')
+
+    @staticmethod
+    def sendRpcs(test_client: XdsTestClient,
+                 num_rpcs: int) -> LoadBalancerStatsResponse:
+        lb_stats = test_client.get_load_balancer_stats(num_rpcs=num_rpcs)
+        logger.info(
+            'Received LoadBalancerStatsResponse from test client %s:\n%s',
+            test_client.ip, lb_stats)
+        return lb_stats
+
+    def assertAllBackendsReceivedRpcs(self, lb_stats):
+        # TODO(sergiitk): assert backends length
+        for backend, rpcs_count in lb_stats.rpcs_by_peer.items():
+            self.assertGreater(
+                int(rpcs_count),
+                0,
+                msg=f'Backend {backend} did not receive a single RPC')
+
+
+class RegularXdsKubernetesTestCase(XdsKubernetesTestCase):
+
+    def setUp(self):
+        super().setUp()
+
+        # Traffic Director Configuration
+        self.td = traffic_director.TrafficDirectorManager(
+            self.gcp_api_manager,
+            project=self.project,
+            resource_prefix=self.namespace,
+            network=self.network)
+
+        # Test Server Runner
+        self.server_runner = server_app.KubernetesServerRunner(
+            k8s.KubernetesNamespace(self.k8s_api_manager,
+                                    self.server_namespace),
+            deployment_name=self.server_name,
+            image_name=self.server_image,
+            gcp_service_account=self.gcp_service_account,
+            network=self.network,
+            td_bootstrap_image=self.td_bootstrap_image)
+
+        # Test Client Runner
+        self.client_runner = client_app.KubernetesClientRunner(
+            k8s.KubernetesNamespace(self.k8s_api_manager,
+                                    self.client_namespace),
+            deployment_name=self.client_name,
+            image_name=self.client_image,
+            gcp_service_account=self.gcp_service_account,
+            network=self.network,
+            td_bootstrap_image=self.td_bootstrap_image,
+            debug_use_port_forwarding=self.debug_use_port_forwarding,
+            stats_port=self.client_port,
+            reuse_namespace=self.server_namespace == self.client_namespace)
+
+    def startTestServer(self, replica_count=1, **kwargs) -> XdsTestServer:
+        test_server = self.server_runner.run(replica_count=replica_count,
+                                             test_port=self.server_port,
+                                             **kwargs)
+        test_server.set_xds_address(self.server_xds_host, self.server_xds_port)
+        return test_server
+
+    def startTestClient(self, test_server: XdsTestServer,
+                        **kwargs) -> XdsTestClient:
+        test_client = self.client_runner.run(server_target=test_server.xds_uri,
+                                             **kwargs)
+        test_client.wait_for_active_server_channel()
+        return test_client
+
+
+class SecurityXdsKubernetesTestCase(XdsKubernetesTestCase):
+
+    class SecurityMode(enum.Enum):
+        MTLS = enum.auto()
+        TLS = enum.auto()
+        PLAINTEXT = enum.auto()
+
+    def setUp(self):
+        super().setUp()
+
+        # Traffic Director Configuration
+        self.td = traffic_director.TrafficDirectorSecureManager(
+            self.gcp_api_manager,
+            project=self.project,
+            resource_prefix=self.namespace,
+            network=self.network)
+
+        # Test Server Runner
+        self.server_runner = server_app.KubernetesServerRunner(
+            k8s.KubernetesNamespace(self.k8s_api_manager,
+                                    self.server_namespace),
+            deployment_name=self.server_name,
+            image_name=self.server_image,
+            gcp_service_account=self.gcp_service_account,
+            network=self.network,
+            td_bootstrap_image=self.td_bootstrap_image,
+            deployment_template='server-secure.deployment.yaml',
+            debug_use_port_forwarding=self.debug_use_port_forwarding)
+
+        # Test Client Runner
+        self.client_runner = client_app.KubernetesClientRunner(
+            k8s.KubernetesNamespace(self.k8s_api_manager,
+                                    self.client_namespace),
+            deployment_name=self.client_name,
+            image_name=self.client_image,
+            gcp_service_account=self.gcp_service_account,
+            network=self.network,
+            td_bootstrap_image=self.td_bootstrap_image,
+            deployment_template='client-secure.deployment.yaml',
+            stats_port=self.client_port,
+            reuse_namespace=self.server_namespace == self.client_namespace,
+            debug_use_port_forwarding=self.debug_use_port_forwarding)
+
+    def startSecureTestServer(self, replica_count=1, **kwargs) -> XdsTestServer:
+        test_server = self.server_runner.run(replica_count=replica_count,
+                                             test_port=self.server_port,
+                                             maintenance_port=8081,
+                                             secure_mode=True,
+                                             **kwargs)
+        test_server.set_xds_address(self.server_xds_host, self.server_xds_port)
+        return test_server
+
+    def setupSecurityPolicies(self, *, server_tls, server_mtls, client_tls,
+                              client_mtls):
+        self.td.setup_client_security(server_namespace=self.server_namespace,
+                                      server_name=self.server_name,
+                                      tls=client_tls,
+                                      mtls=client_mtls)
+        self.td.setup_server_security(server_namespace=self.server_namespace,
+                                      server_name=self.server_name,
+                                      server_port=self.server_port,
+                                      tls=server_tls,
+                                      mtls=server_mtls)
+
+    def startSecureTestClient(self,
+                              test_server: XdsTestServer,
+                              *,
+                              wait_for_active_server_channel=True,
+                              **kwargs) -> XdsTestClient:
+        test_client = self.client_runner.run(server_target=test_server.xds_uri,
+                                             secure_mode=True,
+                                             **kwargs)
+        if wait_for_active_server_channel:
+            test_client.wait_for_active_server_channel()
+        return test_client
+
+    def assertTestAppSecurity(self, mode: SecurityMode,
+                              test_client: XdsTestClient,
+                              test_server: XdsTestServer):
+        client_socket, server_socket = self.getConnectedSockets(
+            test_client, test_server)
+        server_security: grpc_channelz.Security = server_socket.security
+        client_security: grpc_channelz.Security = client_socket.security
+        logger.info('Server certs: %s', self.debug_sock_certs(server_security))
+        logger.info('Client certs: %s', self.debug_sock_certs(client_security))
+
+        if mode is self.SecurityMode.MTLS:
+            self.assertSecurityMtls(client_security, server_security)
+        elif mode is self.SecurityMode.TLS:
+            self.assertSecurityTls(client_security, server_security)
+        elif mode is self.SecurityMode.PLAINTEXT:
+            self.assertSecurityPlaintext(client_security, server_security)
+        else:
+            raise TypeError('Incorrect security mode')
+
+    def assertSecurityMtls(self, client_security: grpc_channelz.Security,
+                           server_security: grpc_channelz.Security):
+        self.assertEqual(client_security.WhichOneof('model'),
+                         'tls',
+                         msg='(mTLS) Client socket security model must be TLS')
+        self.assertEqual(server_security.WhichOneof('model'),
+                         'tls',
+                         msg='(mTLS) Server socket security model must be TLS')
+        server_tls, client_tls = server_security.tls, client_security.tls
+
+        # Confirm regular TLS: server local cert == client remote cert
+        self.assertNotEmpty(server_tls.local_certificate,
+                            msg="(mTLS) Server local certificate is missing")
+        self.assertNotEmpty(client_tls.remote_certificate,
+                            msg="(mTLS) Client remote certificate is missing")
+        self.assertEqual(
+            server_tls.local_certificate,
+            client_tls.remote_certificate,
+            msg="(mTLS) Server local certificate must match client's "
+            "remote certificate")
+
+        # mTLS: server remote cert == client local cert
+        self.assertNotEmpty(server_tls.remote_certificate,
+                            msg="(mTLS) Server remote certificate is missing")
+        self.assertNotEmpty(client_tls.local_certificate,
+                            msg="(mTLS) Client local certificate is missing")
+        self.assertEqual(
+            server_tls.remote_certificate,
+            client_tls.local_certificate,
+            msg="(mTLS) Server remote certificate must match client's "
+            "local certificate")
+
+    def assertSecurityTls(self, client_security: grpc_channelz.Security,
+                          server_security: grpc_channelz.Security):
+        self.assertEqual(client_security.WhichOneof('model'),
+                         'tls',
+                         msg='(TLS) Client socket security model must be TLS')
+        self.assertEqual(server_security.WhichOneof('model'),
+                         'tls',
+                         msg='(TLS) Server socket security model must be TLS')
+        server_tls, client_tls = server_security.tls, client_security.tls
+
+        # Regular TLS: server local cert == client remote cert
+        self.assertNotEmpty(server_tls.local_certificate,
+                            msg="(TLS) Server local certificate is missing")
+        self.assertNotEmpty(client_tls.remote_certificate,
+                            msg="(TLS) Client remote certificate is missing")
+        self.assertEqual(server_tls.local_certificate,
+                         client_tls.remote_certificate,
+                         msg="(TLS) Server local certificate must match client "
+                         "remote certificate")
+
+        # mTLS must not be used
+        self.assertEmpty(
+            server_tls.remote_certificate,
+            msg="(TLS) Server remote certificate must be empty in TLS mode. "
+            "Is server security incorrectly configured for mTLS?")
+        self.assertEmpty(
+            client_tls.local_certificate,
+            msg="(TLS) Client local certificate must be empty in TLS mode. "
+            "Is client security incorrectly configured for mTLS?")
+
+    def assertSecurityPlaintext(self, client_security, server_security):
+        server_tls, client_tls = server_security.tls, client_security.tls
+        # Not TLS
+        self.assertEmpty(
+            server_tls.local_certificate,
+            msg="(Plaintext) Server local certificate must be empty.")
+        self.assertEmpty(
+            client_tls.local_certificate,
+            msg="(Plaintext) Client local certificate must be empty.")
+
+        # Not mTLS
+        self.assertEmpty(
+            server_tls.remote_certificate,
+            msg="(Plaintext) Server remote certificate must be empty.")
+        self.assertEmpty(
+            client_tls.local_certificate,
+            msg="(Plaintext) Client local certificate must be empty.")
+
+    def assertClientCannotReachServerRepeatedly(
+            self,
+            test_client: XdsTestClient,
+            *,
+            times: Optional[int] = None,
+            delay: Optional[_timedelta] = None):
+        """
+        Asserts that the client repeatedly cannot reach the server.
+
+        With negative tests we can't be absolutely certain expected failure
+        state is not caused by something else.
+        To mitigate for this, we repeat the checks several times, and expect
+        all of them to succeed.
+
+        This is useful in case the channel eventually stabilizes, and RPCs pass.
+
+        Args:
+            test_client: An instance of XdsTestClient
+            times: Optional; A positive number of times to confirm that
+                the server is unreachable. Defaults to `3` attempts.
+            delay: Optional; Specifies how long to wait before the next check.
+                Defaults to `10` seconds.
+        """
+        if times is None or times < 1:
+            times = 3
+        if delay is None:
+            delay = _timedelta(seconds=10)
+
+        for i in range(1, times + 1):
+            self.assertClientCannotReachServer(test_client)
+            if i < times:
+                logger.info('Check %s passed, waiting %s before the next check',
+                            i, delay)
+                time.sleep(delay.total_seconds())
+
+    def assertClientCannotReachServer(self, test_client: XdsTestClient):
+        self.assertClientChannelFailed(test_client)
+        self.assertFailedRpcs(test_client)
+
+    def assertClientChannelFailed(self, test_client: XdsTestClient):
+        channel = test_client.wait_for_server_channel_state(
+            state=_ChannelState.TRANSIENT_FAILURE)
+        subchannels = list(
+            test_client.channelz.list_channel_subchannels(channel))
+        self.assertLen(subchannels,
+                       1,
+                       msg="Client channel must have exactly one subchannel "
+                       "in state TRANSIENT_FAILURE.")
+        sockets = list(
+            test_client.channelz.list_subchannels_sockets(subchannels[0]))
+        self.assertEmpty(sockets, msg="Client subchannel must have no sockets")
+
+    @staticmethod
+    def getConnectedSockets(
+            test_client: XdsTestClient, test_server: XdsTestServer
+    ) -> Tuple[grpc_channelz.Socket, grpc_channelz.Socket]:
+        client_sock = test_client.get_active_server_channel_socket()
+        server_sock = test_server.get_server_socket_matching_client(client_sock)
+        return client_sock, server_sock
+
+    @classmethod
+    def debug_sock_certs(cls, security: grpc_channelz.Security):
+        if security.WhichOneof('model') == 'other':
+            return f'other: <{security.other.name}={security.other.value}>'
+
+        return (f'local: <{cls.debug_cert(security.tls.local_certificate)}>, '
+                f'remote: <{cls.debug_cert(security.tls.remote_certificate)}>')
+
+    @staticmethod
+    def debug_cert(cert):
+        if not cert:
+            return 'missing'
+        sha1 = hashlib.sha1(cert)
+        return f'sha1={sha1.hexdigest()}, len={len(cert)}'
diff --git a/tools/run_tests/xds_k8s_test_driver/kubernetes-manifests/client-secure.deployment.yaml b/tools/run_tests/xds_k8s_test_driver/kubernetes-manifests/client-secure.deployment.yaml
new file mode 100644 (file)
index 0000000..18630ad
--- /dev/null
@@ -0,0 +1,82 @@
+---
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+  name: ${deployment_name}
+  namespace: ${namespace_name}
+  labels:
+    app: ${deployment_name}
+    owner: xds-k8s-interop-test
+spec:
+  replicas: 1
+  selector:
+    matchLabels:
+      app: ${deployment_name}
+  template:
+    metadata:
+      labels:
+        app: ${deployment_name}
+        owner: xds-k8s-interop-test
+    spec:
+      serviceAccountName: ${service_account_name}
+      containers:
+      - name: ${deployment_name}
+        image: ${image_name}
+        imagePullPolicy: Always
+        args:
+          - "--server=${server_target}"
+          - "--stats_port=${stats_port}"
+          - "--secure_mode=${secure_mode}"
+          - "--qps=${qps}"
+          - "--rpc=${rpc}"
+          - "--print_response=${print_response}"
+        ports:
+          - containerPort: ${stats_port}
+        env:
+          - name: GRPC_XDS_BOOTSTRAP
+            value: "/tmp/grpc-xds/td-grpc-bootstrap.json"
+          - name: GRPC_XDS_EXPERIMENTAL_SECURITY_SUPPORT
+            value: "true"
+          - name: GRPC_XDS_EXPERIMENTAL_V3_SUPPORT
+            value: "true"
+        volumeMounts:
+          - mountPath: /tmp/grpc-xds/
+            name: grpc-td-conf
+            readOnly: true
+          - mountPath: /var/run/gke-spiffe/certs
+            name: gke-spiffe-certs-volume
+            readOnly: true
+        resources:
+          limits:
+            cpu: 800m
+            memory: 512Mi
+          requests:
+            cpu: 100m
+            memory: 512Mi
+      initContainers:
+        - name: grpc-td-init
+          image: ${td_bootstrap_image}
+          imagePullPolicy: Always
+          args:
+            - "--output=/tmp/bootstrap/td-grpc-bootstrap.json"
+            - "--vpc-network-name=${network_name}"
+            - "--include-v3-features-experimental"
+            - "--include-psm-security-experimental"
+          resources:
+            limits:
+              cpu: 100m
+              memory: 100Mi
+            requests:
+              cpu: 10m
+              memory: 100Mi
+          volumeMounts:
+            - mountPath: /tmp/bootstrap/
+              name: grpc-td-conf
+      volumes:
+        - name: grpc-td-conf
+          emptyDir:
+            medium: Memory
+        - name: gke-spiffe-certs-volume
+          csi:
+            driver: certs.spiffe.gke.io
+...
diff --git a/tools/run_tests/xds_k8s_test_driver/kubernetes-manifests/client.deployment.yaml b/tools/run_tests/xds_k8s_test_driver/kubernetes-manifests/client.deployment.yaml
new file mode 100644 (file)
index 0000000..793bef6
--- /dev/null
@@ -0,0 +1,69 @@
+---
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+  name: ${deployment_name}
+  namespace: ${namespace_name}
+  labels:
+    app: ${deployment_name}
+    owner: xds-k8s-interop-test
+spec:
+  replicas: 1
+  selector:
+    matchLabels:
+      app: ${deployment_name}
+  template:
+    metadata:
+      labels:
+        app: ${deployment_name}
+        owner: xds-k8s-interop-test
+    spec:
+      serviceAccountName: ${service_account_name}
+      containers:
+      - name: ${deployment_name}
+        image: ${image_name}
+        imagePullPolicy: Always
+        args:
+          - "--server=${server_target}"
+          - "--stats_port=${stats_port}"
+          - "--qps=${qps}"
+          - "--rpc=${rpc}"
+          - "--print_response=${print_response}"
+        ports:
+          - containerPort: ${stats_port}
+        env:
+          - name: GRPC_XDS_BOOTSTRAP
+            value: "/tmp/grpc-xds/td-grpc-bootstrap.json"
+        volumeMounts:
+          - mountPath: /tmp/grpc-xds/
+            name: grpc-td-conf
+            readOnly: true
+        resources:
+          limits:
+            cpu: 800m
+            memory: 512Mi
+          requests:
+            cpu: 100m
+            memory: 512Mi
+      initContainers:
+        - name: grpc-td-init
+          image: ${td_bootstrap_image}
+          imagePullPolicy: Always
+          args:
+            - "--output=/tmp/bootstrap/td-grpc-bootstrap.json"
+            - "--vpc-network-name=${network_name}"
+          resources:
+            limits:
+              cpu: 100m
+              memory: 100Mi
+            requests:
+              cpu: 10m
+              memory: 100Mi
+          volumeMounts:
+            - mountPath: /tmp/bootstrap/
+              name: grpc-td-conf
+      volumes:
+        - name: grpc-td-conf
+          emptyDir:
+            medium: Memory
+...
diff --git a/tools/run_tests/xds_k8s_test_driver/kubernetes-manifests/namespace.yaml b/tools/run_tests/xds_k8s_test_driver/kubernetes-manifests/namespace.yaml
new file mode 100644 (file)
index 0000000..8b8153a
--- /dev/null
@@ -0,0 +1,9 @@
+---
+apiVersion: v1
+kind: Namespace
+metadata:
+  name: ${namespace_name}
+  labels:
+    name: ${namespace_name}
+    owner: xds-k8s-interop-test
+...
diff --git a/tools/run_tests/xds_k8s_test_driver/kubernetes-manifests/server-secure.deployment.yaml b/tools/run_tests/xds_k8s_test_driver/kubernetes-manifests/server-secure.deployment.yaml
new file mode 100644 (file)
index 0000000..0687aa0
--- /dev/null
@@ -0,0 +1,81 @@
+---
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+  name: ${deployment_name}
+  namespace: ${namespace_name}
+  labels:
+    app: ${deployment_name}
+    owner: xds-k8s-interop-test
+spec:
+  replicas: ${replica_count}
+  selector:
+    matchLabels:
+      app: ${deployment_name}
+  template:
+    metadata:
+      labels:
+        app: ${deployment_name}
+        owner: xds-k8s-interop-test
+    spec:
+      serviceAccountName: ${service_account_name}
+      containers:
+      - name: ${deployment_name}
+        image: ${image_name}
+        imagePullPolicy: Always
+        args:
+          - "--port=${test_port}"
+          - "--maintenance_port=${maintenance_port}"
+          - "--secure_mode=${secure_mode}"
+        ports:
+          - containerPort: ${test_port}
+          - containerPort: ${maintenance_port}
+        env:
+          - name: GRPC_XDS_BOOTSTRAP
+            value: "/tmp/grpc-xds/td-grpc-bootstrap.json"
+          - name: GRPC_XDS_EXPERIMENTAL_SECURITY_SUPPORT
+            value: "true"
+          - name: GRPC_XDS_EXPERIMENTAL_V3_SUPPORT
+            value: "true"
+        volumeMounts:
+          - mountPath: /tmp/grpc-xds/
+            name: grpc-td-conf
+            readOnly: true
+          - mountPath: /var/run/gke-spiffe/certs
+            name: gke-spiffe-certs-volume
+            readOnly: true
+        resources:
+          limits:
+            cpu: 800m
+            memory: 512Mi
+          requests:
+            cpu: 100m
+            memory: 512Mi
+      initContainers:
+        - name: grpc-td-init
+          image: ${td_bootstrap_image}
+          imagePullPolicy: Always
+          args:
+            - "--output=/tmp/bootstrap/td-grpc-bootstrap.json"
+            - "--vpc-network-name=${network_name}"
+            - "--include-v3-features-experimental"
+            - "--include-psm-security-experimental"
+            - "--node-metadata-experimental=app=${namespace_name}-${deployment_name}"
+          resources:
+            limits:
+              cpu: 100m
+              memory: 100Mi
+            requests:
+              cpu: 10m
+              memory: 100Mi
+          volumeMounts:
+            - mountPath: /tmp/bootstrap/
+              name: grpc-td-conf
+      volumes:
+        - name: grpc-td-conf
+          emptyDir:
+            medium: Memory
+        - name: gke-spiffe-certs-volume
+          csi:
+            driver: certs.spiffe.gke.io
+...
diff --git a/tools/run_tests/xds_k8s_test_driver/kubernetes-manifests/server.deployment.yaml b/tools/run_tests/xds_k8s_test_driver/kubernetes-manifests/server.deployment.yaml
new file mode 100644 (file)
index 0000000..e3ace2e
--- /dev/null
@@ -0,0 +1,36 @@
+---
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+  name: ${deployment_name}
+  namespace: ${namespace_name}
+  labels:
+    app: ${deployment_name}
+    owner: xds-k8s-interop-test
+spec:
+  replicas: ${replica_count}
+  selector:
+    matchLabels:
+      app: ${deployment_name}
+  template:
+    metadata:
+      labels:
+        app: ${deployment_name}
+    spec:
+      serviceAccountName: ${service_account_name}
+      containers:
+      - name: ${deployment_name}
+        image: ${image_name}
+        imagePullPolicy: Always
+        args:
+          - "--port=${test_port}"
+        ports:
+          - containerPort: ${test_port}
+        resources:
+          limits:
+            cpu: 800m
+            memory: 512Mi
+          requests:
+            cpu: 100m
+            memory: 512Mi
+...
diff --git a/tools/run_tests/xds_k8s_test_driver/kubernetes-manifests/server.service.yaml b/tools/run_tests/xds_k8s_test_driver/kubernetes-manifests/server.service.yaml
new file mode 100644 (file)
index 0000000..376de17
--- /dev/null
@@ -0,0 +1,19 @@
+---
+apiVersion: v1
+kind: Service
+metadata:
+  name: ${service_name}
+  namespace: ${namespace_name}
+  labels:
+    owner: xds-k8s-interop-test
+  annotations:
+    cloud.google.com/neg: '{"exposed_ports": {"${test_port}":{"name":"${neg_name}"}}}'
+spec:
+  type: ClusterIP
+  selector:
+    app: ${deployment_name}
+  ports:
+  - port: ${test_port}
+    protocol: TCP
+    targetPort: ${test_port}
+...
diff --git a/tools/run_tests/xds_k8s_test_driver/kubernetes-manifests/service-account.yaml b/tools/run_tests/xds_k8s_test_driver/kubernetes-manifests/service-account.yaml
new file mode 100644 (file)
index 0000000..35d99df
--- /dev/null
@@ -0,0 +1,11 @@
+---
+apiVersion: v1
+kind: ServiceAccount
+metadata:
+  name: ${service_account_name}
+  namespace: ${namespace_name}
+  labels:
+    owner: xds-k8s-interop-test
+  annotations:
+    iam.gke.io/gcp-service-account: ${gcp_service_account}
+...
diff --git a/tools/run_tests/xds_k8s_test_driver/requirements.txt b/tools/run_tests/xds_k8s_test_driver/requirements.txt
new file mode 100644 (file)
index 0000000..bf7fb6b
--- /dev/null
@@ -0,0 +1,15 @@
+Mako~=1.1
+PyYAML~=5.3
+absl-py~=0.11
+dataclasses~=0.8
+google-api-python-client~=1.12
+google-cloud-secret-manager~=2.1
+grpcio~=1.34
+grpcio-tools~=1.34
+grpcio-channelz~=1.34
+kubernetes~=12.0
+# TODO(sergiitk): remove retrying when replaced with tenacity in code.
+# Context: https://github.com/grpc/grpc/pull/24983#discussion_r543017022
+retrying~=1.3
+tenacity~=6.2
+protobuf~=3.14
diff --git a/tools/run_tests/xds_k8s_test_driver/tests/__init__.py b/tools/run_tests/xds_k8s_test_driver/tests/__init__.py
new file mode 100644 (file)
index 0000000..1c0a3a3
--- /dev/null
@@ -0,0 +1,13 @@
+# 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.
diff --git a/tools/run_tests/xds_k8s_test_driver/tests/baseline_test.py b/tools/run_tests/xds_k8s_test_driver/tests/baseline_test.py
new file mode 100644 (file)
index 0000000..2a61e69
--- /dev/null
@@ -0,0 +1,61 @@
+# 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.
+import logging
+
+from absl import flags
+from absl.testing import absltest
+
+from framework import xds_k8s_testcase
+
+logger = logging.getLogger(__name__)
+flags.adopt_module_key_flags(xds_k8s_testcase)
+
+# Type aliases
+_XdsTestServer = xds_k8s_testcase.XdsTestServer
+_XdsTestClient = xds_k8s_testcase.XdsTestClient
+
+
+class BaselineTest(xds_k8s_testcase.RegularXdsKubernetesTestCase):
+
+    def test_traffic_director_grpc_setup(self):
+        with self.subTest('0_create_health_check'):
+            self.td.create_health_check()
+
+        with self.subTest('1_create_backend_service'):
+            self.td.create_backend_service()
+
+        with self.subTest('2_create_url_map'):
+            self.td.create_url_map(self.server_xds_host, self.server_xds_port)
+
+        with self.subTest('3_create_target_proxy'):
+            self.td.create_target_proxy()
+
+        with self.subTest('4_create_forwarding_rule'):
+            self.td.create_forwarding_rule(self.server_xds_port)
+
+        with self.subTest('5_start_test_server'):
+            test_server: _XdsTestServer = self.startTestServer()
+
+        with self.subTest('6_add_server_backends_to_backend_service'):
+            self.setupServerBackends()
+
+        with self.subTest('7_start_test_client'):
+            test_client: _XdsTestClient = self.startTestClient(test_server)
+
+        with self.subTest('8_test_server_received_rpcs_from_test_client'):
+            self.assertSuccessfulRpcs(test_client)
+
+
+if __name__ == '__main__':
+    absltest.main(failfast=True)
diff --git a/tools/run_tests/xds_k8s_test_driver/tests/security_test.py b/tools/run_tests/xds_k8s_test_driver/tests/security_test.py
new file mode 100644 (file)
index 0000000..58604b7
--- /dev/null
@@ -0,0 +1,185 @@
+# 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.
+import logging
+import uuid
+
+from absl import flags
+from absl.testing import absltest
+
+from framework import xds_k8s_testcase
+
+logger = logging.getLogger(__name__)
+flags.adopt_module_key_flags(xds_k8s_testcase)
+
+# Type aliases
+_XdsTestServer = xds_k8s_testcase.XdsTestServer
+_XdsTestClient = xds_k8s_testcase.XdsTestClient
+_SecurityMode = xds_k8s_testcase.SecurityXdsKubernetesTestCase.SecurityMode
+
+
+class SecurityTest(xds_k8s_testcase.SecurityXdsKubernetesTestCase):
+
+    def test_mtls(self):
+        """mTLS test.
+
+        Both client and server configured to use TLS and mTLS.
+        """
+        self.setupTrafficDirectorGrpc()
+        self.setupSecurityPolicies(server_tls=True,
+                                   server_mtls=True,
+                                   client_tls=True,
+                                   client_mtls=True)
+
+        test_server: _XdsTestServer = self.startSecureTestServer()
+        self.setupServerBackends()
+        test_client: _XdsTestClient = self.startSecureTestClient(test_server)
+
+        self.assertTestAppSecurity(_SecurityMode.MTLS, test_client, test_server)
+        self.assertSuccessfulRpcs(test_client)
+        logger.info('[SUCCESS] mTLS security mode confirmed.')
+
+    def test_tls(self):
+        """TLS test.
+
+        Both client and server configured to use TLS and not use mTLS.
+        """
+        self.setupTrafficDirectorGrpc()
+        self.setupSecurityPolicies(server_tls=True,
+                                   server_mtls=False,
+                                   client_tls=True,
+                                   client_mtls=False)
+
+        test_server: _XdsTestServer = self.startSecureTestServer()
+        self.setupServerBackends()
+        test_client: _XdsTestClient = self.startSecureTestClient(test_server)
+
+        self.assertTestAppSecurity(_SecurityMode.TLS, test_client, test_server)
+        self.assertSuccessfulRpcs(test_client)
+        logger.info('[SUCCESS] TLS security mode confirmed.')
+
+    def test_plaintext_fallback(self):
+        """Plain-text fallback test.
+
+        Control plane provides no security config so both client and server
+        fallback to plaintext based on fallback-credentials.
+        """
+        self.setupTrafficDirectorGrpc()
+        self.setupSecurityPolicies(server_tls=False,
+                                   server_mtls=False,
+                                   client_tls=False,
+                                   client_mtls=False)
+
+        test_server: _XdsTestServer = self.startSecureTestServer()
+        self.setupServerBackends()
+        test_client: _XdsTestClient = self.startSecureTestClient(test_server)
+
+        self.assertTestAppSecurity(_SecurityMode.PLAINTEXT, test_client,
+                                   test_server)
+        self.assertSuccessfulRpcs(test_client)
+        logger.info('[SUCCESS] Plaintext security mode confirmed.')
+
+    def test_mtls_error(self):
+        """Negative test: mTLS Error.
+
+        Server expects client mTLS cert, but client configured only for TLS.
+
+        Note: because this is a negative test we need to make sure the mTLS
+        failure happens after receiving the correct configuration at the
+        client. To ensure that we will perform the following steps in that
+        sequence:
+
+        - Creation of a backendService, and attaching the backend (NEG)
+        - Creation of the Server mTLS Policy, and attaching to the ECS
+        - Creation of the Client TLS Policy, and attaching to the backendService
+        - Creation of the urlMap, targetProxy, and forwardingRule
+
+        With this sequence we are sure that when the client receives the
+        endpoints of the backendService the security-config would also have
+        been received as confirmed by the TD team.
+        """
+        # Create backend service
+        self.td.setup_backend_for_grpc()
+
+        # Start server and attach its NEGs to the backend service, but
+        # until they become healthy.
+        test_server: _XdsTestServer = self.startSecureTestServer()
+        self.setupServerBackends(wait_for_healthy_status=False)
+
+        # Setup policies and attach them.
+        self.setupSecurityPolicies(server_tls=True,
+                                   server_mtls=True,
+                                   client_tls=True,
+                                   client_mtls=False)
+
+        # Create the routing rule map.
+        self.td.setup_routing_rule_map_for_grpc(self.server_xds_host,
+                                                self.server_xds_port)
+        # Now that TD setup is complete, Backend Service can be populated
+        # with healthy backends (NEGs).
+        self.td.wait_for_backends_healthy_status()
+
+        # Start the client, but don't wait for it to report a healthy channel.
+        test_client: _XdsTestClient = self.startSecureTestClient(
+            test_server, wait_for_active_server_channel=False)
+
+        self.assertClientCannotReachServerRepeatedly(test_client)
+        logger.info(
+            "[SUCCESS] Client's connectivity state is consistent with a mTLS "
+            "error caused by not presenting mTLS certificate to the server.")
+
+    def test_server_authz_error(self):
+        """Negative test: AuthZ error.
+
+        Client does not authorize server because of mismatched SAN name.
+        The order of operations is the same as in `test_mtls_error`.
+        """
+        # Create backend service
+        self.td.setup_backend_for_grpc()
+
+        # Start server and attach its NEGs to the backend service, but
+        # until they become healthy.
+        test_server: _XdsTestServer = self.startSecureTestServer()
+        self.setupServerBackends(wait_for_healthy_status=False)
+
+        # Regular TLS setup, but with client policy configured using
+        # intentionality incorrect server_namespace.
+        self.td.setup_server_security(server_namespace=self.server_namespace,
+                                      server_name=self.server_name,
+                                      server_port=self.server_port,
+                                      tls=True,
+                                      mtls=False)
+        incorrect_namespace = f'incorrect-namespace-{uuid.uuid4().hex}'
+        self.td.setup_client_security(server_namespace=incorrect_namespace,
+                                      server_name=self.server_name,
+                                      tls=True,
+                                      mtls=False)
+
+        # Create the routing rule map.
+        self.td.setup_routing_rule_map_for_grpc(self.server_xds_host,
+                                                self.server_xds_port)
+        # Now that TD setup is complete, Backend Service can be populated
+        # with healthy backends (NEGs).
+        self.td.wait_for_backends_healthy_status()
+
+        # Start the client, but don't wait for it to report a healthy channel.
+        test_client: _XdsTestClient = self.startSecureTestClient(
+            test_server, wait_for_active_server_channel=False)
+
+        self.assertClientCannotReachServerRepeatedly(test_client)
+        logger.info("[SUCCESS] Client's connectivity state is consistent with "
+                    "AuthZ error caused by server presenting incorrect SAN.")
+
+
+if __name__ == '__main__':
+    absltest.main()