/* * 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 #include #include #include #include #include namespace apache { namespace thrift { namespace detail { namespace md { using ThriftMetadata = ::apache::thrift::metadata::ThriftMetadata; using ThriftType = ::apache::thrift::metadata::ThriftType; using ThriftConstValue = ::apache::thrift::metadata::ThriftConstValue; using ThriftConstValuePair = ::apache::thrift::metadata::ThriftConstValuePair; using ThriftConstStruct = ::apache::thrift::metadata::ThriftConstStruct; using ThriftStructType = ::apache::thrift::metadata::ThriftStructType; class MetadataTypeInterface { public: /** * writeAndGenType() performs two things: * 1. Ensures the type is present in metadata. * 2. Populates ThriftType datastruct so that the caller can look * up the type inside metadata. */ virtual void writeAndGenType(ThriftType& ty, ThriftMetadata& metadata) = 0; virtual ~MetadataTypeInterface() {} }; /** * @brief Used in module metadata templates */ struct EncodedThriftField { int32_t id; const char* name; bool is_optional; std::unique_ptr metadata_type_interface; std::vector structured_annotations; }; class Primitive : public MetadataTypeInterface { public: Primitive(::apache::thrift::metadata::ThriftPrimitiveType base) : base_(base) {} void writeAndGenType(ThriftType& ty, ThriftMetadata&) override { ty.t_primitive_ref() = base_; } private: ::apache::thrift::metadata::ThriftPrimitiveType base_; }; class List : public MetadataTypeInterface { public: List(::std::unique_ptr elemType) : elemType_(::std::move(elemType)) {} void writeAndGenType(ThriftType& ty, ThriftMetadata& metadata) override { ::apache::thrift::metadata::ThriftListType tyList; tyList.valueType_ref() = ::std::make_unique(); elemType_->writeAndGenType(*tyList.valueType_ref(), metadata); ty.t_list_ref() = ::std::move(tyList); } private: ::std::unique_ptr elemType_; }; class Set : public MetadataTypeInterface { public: Set(::std::unique_ptr elemType) : elemType_(::std::move(elemType)) {} void writeAndGenType(ThriftType& ty, ThriftMetadata& metadata) override { ::apache::thrift::metadata::ThriftSetType tySet; tySet.valueType_ref() = ::std::make_unique(); elemType_->writeAndGenType(*tySet.valueType_ref(), metadata); ty.t_set_ref() = ::std::move(tySet); } private: ::std::unique_ptr elemType_; }; class Map : public MetadataTypeInterface { public: Map(::std::unique_ptr keyType, ::std::unique_ptr valueType) : keyType_(::std::move(keyType)), valueType_(::std::move(valueType)) {} void writeAndGenType(ThriftType& ty, ThriftMetadata& metadata) override { ::apache::thrift::metadata::ThriftMapType tyMap; tyMap.keyType_ref() = ::std::make_unique(); keyType_->writeAndGenType(*tyMap.keyType_ref(), metadata); tyMap.valueType_ref() = ::std::make_unique(); valueType_->writeAndGenType(*tyMap.valueType_ref(), metadata); ty.t_map_ref() = ::std::move(tyMap); } private: ::std::unique_ptr keyType_; ::std::unique_ptr valueType_; }; template class Enum : public MetadataTypeInterface { public: Enum(const char* name) : name_(name) {} void writeAndGenType(ThriftType& ty, ThriftMetadata& metadata) override { EnumMetadata::gen(metadata); ::apache::thrift::metadata::ThriftEnumType tyEnum; tyEnum.name() = name_; ty.t_enum_ref() = ::std::move(tyEnum); } private: const char* name_; }; template class Struct : public MetadataTypeInterface { public: Struct(const char* name) : name_(name) {} void writeAndGenType(ThriftType& ty, ThriftMetadata& metadata) override { StructMetadata::gen(metadata); ::apache::thrift::metadata::ThriftStructType tyStruct; tyStruct.name() = name_; ty.t_struct_ref() = ::std::move(tyStruct); } private: const char* name_; }; template class Union : public MetadataTypeInterface { public: Union(const char* name) : name_(name) {} void writeAndGenType(ThriftType& ty, ThriftMetadata& metadata) override { StructMetadata::gen(metadata); ::apache::thrift::metadata::ThriftUnionType tyUnion; tyUnion.name() = name_; ty.t_union_ref() = ::std::move(tyUnion); } private: const char* name_; }; class Typedef : public MetadataTypeInterface { public: Typedef( const char* name, ::std::unique_ptr underlyingType, ::std::vector structured_annotations) : name_(name), underlyingType_(::std::move(underlyingType)), structured_annotations_(::std::move(structured_annotations)) {} void writeAndGenType(ThriftType& ty, ThriftMetadata& metadata) override { ::apache::thrift::metadata::ThriftTypedefType tyTypedef; tyTypedef.name() = name_; tyTypedef.underlyingType_ref() = ::std::make_unique(); tyTypedef.structured_annotations() = structured_annotations_; underlyingType_->writeAndGenType(*tyTypedef.underlyingType_ref(), metadata); ty.t_typedef_ref() = ::std::move(tyTypedef); } private: const char* name_; ::std::unique_ptr underlyingType_; ::std::vector structured_annotations_; }; class Stream : public MetadataTypeInterface { public: Stream( ::std::unique_ptr elemType, ::std::unique_ptr initialResponseType = nullptr) : elemType_(::std::move(elemType)), initialResponseType_(::std::move(initialResponseType)) {} void writeAndGenType(ThriftType& ty, ThriftMetadata& metadata) override { ::apache::thrift::metadata::ThriftStreamType tyStream; tyStream.elemType_ref() = ::std::make_unique(); elemType_->writeAndGenType(*tyStream.elemType_ref(), metadata); if (initialResponseType_) { tyStream.initialResponseType_ref() = ::std::make_unique(); initialResponseType_->writeAndGenType( *tyStream.initialResponseType_ref(), metadata); } ty.t_stream_ref() = ::std::move(tyStream); } private: ::std::unique_ptr elemType_; ::std::unique_ptr initialResponseType_; }; class Sink : public MetadataTypeInterface { public: Sink( ::std::unique_ptr elemType, ::std::unique_ptr finalResponseType, ::std::unique_ptr initialResponseType = nullptr) : elemType_(::std::move(elemType)), finalResponseType_(::std::move(finalResponseType)), initialResponseType_(::std::move(initialResponseType)) {} void writeAndGenType(ThriftType& ty, ThriftMetadata& metadata) override { ::apache::thrift::metadata::ThriftSinkType tySink; tySink.elemType_ref() = ::std::make_unique(); elemType_->writeAndGenType(*tySink.elemType_ref(), metadata); tySink.finalResponseType_ref() = ::std::make_unique(); finalResponseType_->writeAndGenType( *tySink.finalResponseType_ref(), metadata); if (initialResponseType_) { tySink.initialResponseType_ref() = ::std::make_unique(); initialResponseType_->writeAndGenType( *tySink.initialResponseType_ref(), metadata); } ty.t_sink_ref() = ::std::move(tySink); } private: ::std::unique_ptr elemType_; ::std::unique_ptr finalResponseType_; ::std::unique_ptr initialResponseType_; }; ThriftConstValue cvBool(bool value); ThriftConstValue cvInteger(int64_t value); ThriftConstValue cvDouble(double value); ThriftConstValue cvString(const char* value); ThriftConstValue cvMap(std::vector&& value); ThriftConstValue cvList(std::vector&& value); ThriftConstValue cvStruct( const char* name, std::map&& fields); ThriftConstValuePair cvPair(ThriftConstValue&& key, ThriftConstValue&& value); } // namespace md } // namespace detail } // namespace thrift } // namespace apache