/* * Copyright (c) Meta Platforms, Inc. and affiliates. * * 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 THRIFT_FATAL_REFLECTION_INL_PRE_H_ #define THRIFT_FATAL_REFLECTION_INL_PRE_H_ 1 #if !defined THRIFT_FATAL_REFLECTION_H_ #error "This file must be included from reflection.h" #endif namespace apache { namespace thrift { namespace detail { template struct invoke_reffer; struct thru_field_ref_fn { template FOLLY_ERASE constexpr T operator()(field_ref ref) const noexcept { return *ref; } template FOLLY_ERASE constexpr T operator()(optional_field_ref ref) const noexcept { return ref.value_unchecked(); } template FOLLY_ERASE constexpr T operator()(terse_field_ref ref) const noexcept { return *ref; } template FOLLY_ERASE constexpr optional_boxed_field_ref operator()( optional_boxed_field_ref ref) const noexcept { return ref; } template FOLLY_ERASE constexpr T operator()(required_field_ref ref) const noexcept { return *ref; } template < typename T, typename D = folly::remove_cvref_t, std::enable_if_t, int> = 0> FOLLY_ERASE constexpr T&& operator()(T&& ref) const noexcept { return static_cast(ref); } }; inline constexpr thru_field_ref_fn thru_field_ref{}; template struct invoke_reffer_thru { template FOLLY_ERASE constexpr auto operator()(A&&... a) noexcept( noexcept(access_field(static_cast(a)...))) -> decltype(thru_field_ref(access_field(static_cast(a)...))) { return thru_field_ref(access_field(static_cast(a)...)); } }; template struct reflect_module_tag_selector { using type = Default; static_assert( IsTry, "given type has no reflection metadata or is not a struct, enum or union"); }; template struct reflect_module_tag_get; template struct reflect_module_tag_try_get; template struct reflect_type_class_of_thrift_class_impl; template struct reflect_type_class_of_thrift_class_enum_impl; struct reflection_metadata_tag {}; struct struct_traits_metadata_tag {}; namespace reflection_impl { // FIXME: There is a bug that is_set(...) always return `true` for cpp.ref field // We need to investigate how to fix this since it's breaking change. struct is_set_fn { template bool operator()(const std::unique_ptr&) const { return true; } template bool operator()(const std::shared_ptr&) const { return true; } template bool operator()(terse_field_ref) const { return true; } template bool operator()(T ref) const { return ref.has_value(); } }; constexpr is_set_fn is_set; struct mark_set_fn { template void operator()(required_field_ref, bool) const {} template void operator()(terse_field_ref, bool) const {} template void operator()(field_ref ref, bool b) const { if (b) { ref.ensure(); } else { ::apache::thrift::unset_unsafe_deprecated(ref); } } template void operator()(optional_field_ref ref, bool b) const { if (b) { ::apache::thrift::ensure_isset_unsafe_deprecated(ref); } else { ::apache::thrift::unset_unsafe_deprecated(ref); } } template void operator()(optional_boxed_field_ref ref, bool b) const { if (b) { ref.ensure(); } else { ref.reset(); } } template void operator()(boxed_value_ptr&, bool) const {} template void operator()(std::unique_ptr&, bool) const {} template void operator()(std::shared_ptr&, bool) const {} }; constexpr mark_set_fn mark_set; struct variant_member_name { template using apply = typename Descriptor::metadata::name; }; struct variant_member_field_id { template using apply = typename Descriptor::metadata::id; }; template using data_member_accessor = invoke_reffer_thru; template struct chained_data_member_accessor; template <> struct chained_data_member_accessor<> { template FOLLY_ERASE constexpr T&& operator()(T&& t) const noexcept { return static_cast(t); } }; template struct chained_data_member_accessor { template FOLLY_ERASE constexpr auto operator()(T&& t) const noexcept( noexcept(chained_data_member_accessor{}(V{}(static_cast(t))))) -> decltype(chained_data_member_accessor{}( V{}(static_cast(t)))) { return chained_data_member_accessor{}(V{}(static_cast(t))); } }; template struct getter_direct_getter { using type = G; }; template struct getter_direct_getter> { using type = V; }; template using getter_direct_getter_t = folly::_t>; } // namespace reflection_impl } // namespace detail #define THRIFT_REGISTER_REFLECTION_METADATA(Tag, Traits) \ FATAL_REGISTER_TYPE( \ ::apache::thrift::detail::reflection_metadata_tag, \ Tag, \ ::apache::thrift::reflected_module) #define THRIFT_REGISTER_STRUCT_TRAITS(Struct, Traits) \ FATAL_REGISTER_TYPE( \ ::apache::thrift::detail::struct_traits_metadata_tag, \ Struct, \ ::apache::thrift::reflected_struct) template struct reflected_annotations; } // namespace thrift } // namespace apache #endif // THRIFT_FATAL_REFLECTION_INL_PRE_H_