/* * 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. */ #pragma once /** * Macros to be used by codegen'd X_types.h and X_types.cpp files, intended to * reduce the coupling between code generation and library code */ #define FROZEN_FIELD(NAME, ID, /*TYPE*/...) Field<__VA_ARGS__> NAME##Field; #define FROZEN_FIELD_OPT(NAME, ID, /*TYPE*/...) \ Field> NAME##Field; #define FROZEN_FIELD_REQ FROZEN_FIELD #define FROZEN_FIELD_REF FROZEN_FIELD #define FROZEN_VIEW_FIELD(NAME, /*TYPE*/...) \ auto NAME() const { \ return this->layout_->NAME##Field.layout.view( \ this->position_(this->layout_->NAME##Field.pos)); \ } \ auto NAME##_ref() const { \ return FieldView::View>( \ this->layout_->NAME##Field.layout.view( \ this->position_(this->layout_->NAME##Field.pos))); \ } \ auto get_##NAME() const { \ return this->layout_->NAME##Field.layout.view( \ this->position_(this->layout_->NAME##Field.pos)); \ } #define FROZEN_VIEW_FIELD_OPT(NAME, /*TYPE*/...) \ auto NAME() const { \ return this->layout_->NAME##Field.layout.view( \ this->position_(this->layout_->NAME##Field.pos)); \ } #define FROZEN_VIEW_FIELD_REQ FROZEN_VIEW_FIELD #define FROZEN_VIEW_FIELD_REF FROZEN_VIEW_FIELD #define FROZEN_VIEW(...) \ struct View : public ViewBase { \ View() {} \ View(const LayoutSelf* layout, ViewPosition position) \ : ViewBase(layout, position) {} \ bool operator==(const View& other) const; \ bool operator<(const View& other) const; \ __VA_ARGS__ \ }; \ View view(ViewPosition self) const { return View(this, self); } #define FROZEN_TYPE(TYPE, ...) \ template <> \ struct Layout : public LayoutBase { \ typedef LayoutBase Base; \ typedef Layout LayoutSelf; \ Layout(); \ typedef TYPE T; \ FieldPosition maximize(); \ FieldPosition layout(LayoutRoot& root, const T& x, LayoutPosition self); \ void freeze(FreezeRoot& root, const T& x, FreezePosition self) const; \ void thaw(ViewPosition self, T& out) const; \ void print(std::ostream& os, int level) const final; \ void clear() final; \ struct View; \ static size_t hash(const TYPE&); \ static size_t hash(const View&); \ __VA_ARGS__ \ } #define FROZEN_CTOR_FIELD(NAME, ID) , NAME##Field(ID, #NAME) #define FROZEN_CTOR_FIELD_OPT(NAME, ID) , NAME##Field(ID, #NAME) #define FROZEN_CTOR_FIELD_REQ FROZEN_CTOR_FIELD #define FROZEN_CTOR_FIELD_REF FROZEN_CTOR_FIELD #define FROZEN_CTOR(TYPE, ...) \ Layout::Layout() : LayoutBase(typeid(TYPE)) __VA_ARGS__ {} #define FROZEN_MAXIMIZE_FIELD(NAME) pos = maximizeField(pos, this->NAME##Field); #define FROZEN_MAXIMIZE(TYPE, ...) \ FieldPosition Layout::maximize() { \ FieldPosition pos = startFieldPosition(); \ __VA_ARGS__; \ return pos; \ } #define FROZEN_LAYOUT_FIELD(NAME) \ pos = root.layoutField(self, pos, this->NAME##Field, *x.NAME##_ref()); #define FROZEN_LAYOUT_FIELD_OPT(NAME) \ pos = root.layoutOptionalField(self, pos, this->NAME##Field, x.NAME##_ref()); #define FROZEN_LAYOUT_FIELD_REQ(NAME) \ pos = root.layoutField(self, pos, this->NAME##Field, *x.NAME##_ref()); #define FROZEN_LAYOUT_FIELD_REF(NAME) \ pos = root.layoutField(self, pos, this->NAME##Field, x.NAME##_ref()); #define FROZEN_LAYOUT(TYPE, ...) \ FieldPosition Layout::layout( \ [[maybe_unused]] LayoutRoot& root, \ [[maybe_unused]] const T& x, \ [[maybe_unused]] LayoutPosition self) { \ FieldPosition pos = startFieldPosition(); \ __VA_ARGS__; \ return pos; \ } #define FROZEN_FREEZE_FIELD(NAME) \ root.freezeField(self, this->NAME##Field, *x.NAME##_ref()); #define FROZEN_FREEZE_FIELD_OPT(NAME) \ root.freezeOptionalField(self, this->NAME##Field, x.NAME##_ref()); #define FROZEN_FREEZE_FIELD_REQ(NAME) \ root.freezeField(self, this->NAME##Field, *x.NAME##_ref()); #define FROZEN_FREEZE_FIELD_REF(NAME) \ root.freezeField(self, this->NAME##Field, x.NAME##_ref()); #define FROZEN_FREEZE(TYPE, ...) \ void Layout::freeze( \ [[maybe_unused]] FreezeRoot& root, \ [[maybe_unused]] const T& x, \ [[maybe_unused]] FreezePosition self) const { \ __VA_ARGS__; \ } #define FROZEN_THAW_FIELD(NAME) \ thawField(self, this->NAME##Field, out.NAME##_ref().ensure()); \ if (this->NAME##Field.layout.empty()) { \ ::apache::thrift::unset_unsafe_deprecated(out.NAME##_ref()); \ } #define FROZEN_THAW_FIELD_OPT(NAME) \ thawField(self, this->NAME##Field, out.NAME##_ref()); #define FROZEN_THAW_FIELD_REQ(NAME) \ thawField(self, this->NAME##Field, *out.NAME##_ref()); #define FROZEN_THAW_FIELD_REF(NAME) \ thawField(self, this->NAME##Field, out.NAME##_ref()); #define FROZEN_THAW(TYPE, ...) \ void Layout::thaw( \ [[maybe_unused]] ViewPosition self, [[maybe_unused]] T& out) const { \ __VA_ARGS__; \ } #define FROZEN_DEBUG_FIELD(NAME) this->NAME##Field.print(os, level + 1); #define FROZEN_DEBUG(TYPE, ...) \ void Layout::print(std::ostream& os, int level) const { \ LayoutBase::print(os, level); \ os << #TYPE; \ __VA_ARGS__ \ } #define FROZEN_CLEAR_FIELD(NAME) this->NAME##Field.clear(); #define FROZEN_CLEAR(TYPE, ...) \ void Layout::clear() { \ LayoutBase::clear(); \ __VA_ARGS__ \ } #define FROZEN_SAVE_FIELD(NAME) \ this->NAME##Field.template save(schema, _layout, helper); #define FROZEN_SAVE_BODY(...) \ Base::template save(schema, _layout, helper); \ __VA_ARGS__ #define FROZEN_SAVE_INLINE(...) \ template \ inline void save( \ typename SchemaInfo::Schema& schema, \ typename SchemaInfo::Layout& _layout, \ typename SchemaInfo::Helper& helper) const { \ FROZEN_SAVE_BODY(__VA_ARGS__) \ } #define FROZEN_LOAD_FIELD(NAME, ID) \ case ID: \ this->NAME##Field.template load(schema, field, root); \ break; #define FROZEN_LOAD_BODY(...) \ Base::template load(schema, _layout, root); \ for (const auto& field : _layout.getFields()) { \ switch (field.getId()) { __VA_ARGS__ } \ } #define FROZEN_LOAD_INLINE(...) \ template \ inline void load( \ const typename SchemaInfo::Schema& schema, \ const typename SchemaInfo::Layout& _layout, \ LoadRoot& root) { \ FROZEN_LOAD_BODY(__VA_ARGS__) \ } #define FROZEN_EXCLUDE_TYPE(...) \ template <> \ struct IsExcluded<__VA_ARGS__> : std::true_type {};