mirror of
https://github.com/facebook/sapling.git
synced 2024-10-04 13:57:13 +03:00
a03d82d685
Summary: Typed interceptors (aka `ServiceMethodDecorator`) is taking a backseat while we revisit the approach. Let's clean up this unused code. Reviewed By: thedavekwon Differential Revision: D54316280 fbshipit-source-id: 49c5a0e93216e1b267ce743fd760741a0123e481
361 lines
12 KiB
Thrift
361 lines
12 KiB
Thrift
/*
|
|
* 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.
|
|
*/
|
|
|
|
include "thrift/annotation/scope.thrift"
|
|
include "thrift/annotation/thrift.thrift"
|
|
|
|
package "facebook.com/thrift/annotation/cpp"
|
|
|
|
namespace java com.facebook.thrift.annotation.cpp_deprecated
|
|
namespace android com.facebook.thrift.annotation.cpp_deprecated
|
|
namespace js thrift.annotation.cpp
|
|
namespace py.asyncio facebook_thrift_asyncio.annotation.cpp
|
|
namespace go thrift.annotation.cpp
|
|
namespace py thrift.annotation.cpp
|
|
|
|
// start
|
|
|
|
/**
|
|
* Changes the native type of a Thrift object (the C++ type used in codegen) to the value of the `name` field.
|
|
* Container types may instead provide the `template` field, in which case template parameters will be filled in by thrift.
|
|
* (e.g. `template = "folly::sorted_vector_set"` is equivalent to `type = "folly::sorted_vector_set<T>"` on `set<T>`)
|
|
*
|
|
* It is also possible to add `cpp_include` to bring in additional data structures and use them here.
|
|
* It is required that the custom type matches the specified Thrift type even for internal container types.
|
|
* Prefer types that can leverage `reserve(size_t)` as Thrift makes uses these optimizations.
|
|
* *Special Case*: This annotation can be used to define a string/binary type as `IOBuf` or `unique_ptr<IOBuf>` so that you can leverage Thrift's support for zero-copy buffer manipulation through `IOBuf`.
|
|
* During deserialization, thrift receives a buffer that is used to allocate the appropriate fields in the struct. When using smart pointers, instead of making a copy of the data, it only modifies the pointer to point to the address that is used by the buffer.
|
|
*
|
|
* The custom type must provide the following methods
|
|
* * `list`: `push_back(T)`
|
|
* * `map`: `insert(std::pair<T1, T2>)`
|
|
* * `set`: `insert(T)`
|
|
*/
|
|
@scope.Typedef
|
|
@scope.Field
|
|
struct Type {
|
|
1: string name;
|
|
2: string template (cpp.name = "template_");
|
|
}
|
|
|
|
/**
|
|
* Allocates a field on the heap instead of inline.
|
|
* This annotation is added to support recursive types. However, you can also use it to turn a field from a value to a smart pointer.
|
|
* `@cpp.Ref` is equivalent having type`@cpp.RefType.Unique`.
|
|
*
|
|
* NOTE: A struct may transitively contain itself as a field only if at least one of the fields in the inclusion chain is either an optional Ref field or a container. Otherwise the struct would have infinite size.
|
|
*/
|
|
@scope.Field
|
|
struct Ref {
|
|
1: RefType type; /// Optional, defaults to Unique
|
|
}
|
|
enum RefType {
|
|
Unique = 0, /// `std::unique_ptr<T>`
|
|
Shared = 1, /// `std::shared_ptr<const T> `
|
|
SharedMutable = 2, /// `std::shared_ptr<T>`
|
|
}
|
|
|
|
/**
|
|
* Changes the name of the definition in generated C++ code.
|
|
* In most cases a much better solution is to rename the problematic Thrift field itself. Only use the `@cpp.Name` annotation if such renaming is problematic,
|
|
* e.g. when the field name appears in code as a string, particularly when using JSON serialization, and it is hard to change all usage sites.
|
|
*/
|
|
@scope.Definition
|
|
struct Name {
|
|
1: string value;
|
|
}
|
|
|
|
/**
|
|
Lazily deserialize large field on first access.
|
|
|
|
```
|
|
FooWithLazyField foo;
|
|
apache::thrift::CompactSerializer::deserialize(serializedData, foo);
|
|
|
|
// large_field is lazy field, it will be deserialized on first access
|
|
// The data will be deserialized in method call large_field_ref()
|
|
LOG(INFO) << foo.large_field_ref()->size();
|
|
|
|
// Result will be cached, we won't deserialize again
|
|
LOG(INFO) << foo.large_field_ref()->size();
|
|
```
|
|
|
|
Read more: /doc/fb/languages/cpp/lazy.md
|
|
*/
|
|
|
|
@scope.Field
|
|
struct Lazy {
|
|
// Use std::unique_ptr<folly::IOBuf> instead of folly::IOBuf to store serialized data.
|
|
1: bool ref = false;
|
|
}
|
|
|
|
@scope.Struct
|
|
struct DisableLazyChecksum {}
|
|
|
|
/**
|
|
* An annotation that applies a C++ adapter to typedef, field, or struct.
|
|
*
|
|
* For example:
|
|
*
|
|
* @cpp.Adapter{name = "::ns::IdAdapter"}
|
|
* typedef i64 MyI64;
|
|
*
|
|
* Here the type `MyI64` has the C++ adapter `IdAdapter`.
|
|
*
|
|
* struct User {
|
|
* @cpp.Adapter{name = "::ns::IdAdapter"}
|
|
* 1: i64 id;
|
|
* }
|
|
*
|
|
* Here the field `id` has the C++ adapter `IdAdapter`.
|
|
*/
|
|
@scope.Field
|
|
@scope.Typedef
|
|
@scope.Structured
|
|
@scope.Const
|
|
struct Adapter {
|
|
/**
|
|
* The name of a C++ adapter type used to convert between Thrift and native
|
|
* C++ representation.
|
|
*
|
|
* The adapter can be either a Type or Field adapter, providing either of the following APIs:
|
|
*
|
|
* struct ThriftTypeAdapter {
|
|
* static AdaptedType fromThrift(ThriftType thrift);
|
|
* static {const ThriftType& | ThriftType} toThrift(const AdaptedType& native);
|
|
* };
|
|
*
|
|
* struct ThriftFieldAdapter {
|
|
* // Context is an instantiation of apache::thrift::FieldContext
|
|
* template <class Context>
|
|
* static void construct(AdaptedType& field, Context ctx);
|
|
*
|
|
* template <class Context>
|
|
* static AdaptedType fromThriftField(ThriftType value, Context ctx);
|
|
*
|
|
* template <class Context>
|
|
* static {const ThriftType& | ThriftType} toThrift(const AdaptedType& adapted, Context ctx);
|
|
* };
|
|
*/
|
|
1: string name;
|
|
|
|
/**
|
|
* It is sometimes necessary to specify AdaptedType here (in case the codegen would
|
|
* have a circular depdenceny, which will cause the C++ build to fail).
|
|
*/
|
|
2: string adaptedType;
|
|
|
|
/**
|
|
* The name and/or extra namespace to use when directly adapting a type
|
|
* (as opposed a typedef).
|
|
*
|
|
* In this case, the IDL name of the type will refer to the adapted type in
|
|
* C++ and the underlying thrift type will be generated in a nested
|
|
* namespace and/or with a different name.
|
|
*
|
|
* If neither `underlyingName` or `extraNamespace` is provided, the
|
|
* underlying type will be generated in a nested 'detail' namespace with
|
|
* the same name.
|
|
*/
|
|
3: string underlyingName;
|
|
4: string extraNamespace;
|
|
|
|
/** Must set to true when adapted type is not copyable. */
|
|
5: bool moveOnly;
|
|
}
|
|
|
|
/**
|
|
* Packs isset bits into fewer bytes to save space at the cost of making access more expensive.
|
|
* Passing `atomic = false` reduces the access cost while making concurrent writes UB.
|
|
* Read more: /doc/fb/languages/cpp/isset-bitpacking.md
|
|
*/
|
|
@scope.Struct
|
|
struct PackIsset {
|
|
1: bool atomic = true;
|
|
}
|
|
|
|
/**
|
|
This annotation enables reordering of fields in the generated C++ struct to minimize padding.
|
|
This is achieved by placing the fields in the order of decreasing alignments. The order of fields with the same alignment is preserved.
|
|
|
|
```
|
|
@cpp.MinimizePadding
|
|
struct Padded {
|
|
1: byte small
|
|
2: i64 big
|
|
3: i16 medium
|
|
4: i32 biggish
|
|
5: byte tiny
|
|
}
|
|
```
|
|
|
|
For example, the C++ fields for the `Padded` Thrift struct above will be generated in the following order:
|
|
|
|
```
|
|
int64_t big;
|
|
int32_t biggish;
|
|
int16_t medium;
|
|
int8_t small;
|
|
int8_t tiny;
|
|
```
|
|
|
|
which gives the size of 16 bytes compared to 32 bytes if `cpp.MinimizePadding` was not specified.
|
|
*/
|
|
@scope.Struct
|
|
struct MinimizePadding {}
|
|
|
|
@scope.Struct
|
|
struct TriviallyRelocatable {}
|
|
|
|
@scope.Union
|
|
struct ScopedEnumAsUnionType {}
|
|
|
|
/**
|
|
* Indicates a typedef should be 'strong', and require an explicit cast to
|
|
* the underlying type.
|
|
*
|
|
* Currently only works for integer typedefs, for example:
|
|
*
|
|
* @cpp.StrongType
|
|
* typedef i32 MyId;
|
|
*
|
|
* Will cause an enum class to be used instead of a typedef in the genearte code, for example:
|
|
*
|
|
* enum class MyId : ::std::int32_t {};
|
|
*
|
|
*/
|
|
@thrift.Experimental
|
|
@scope.Typedef
|
|
struct StrongType {}
|
|
|
|
/**
|
|
* An annotation that intercepts field access with C++ field interceptor.
|
|
* Use with *caution* since this may introduce substantial performance overhead on each field access.
|
|
*
|
|
* For example:
|
|
*
|
|
* struct Foo {
|
|
* @cpp.FieldInterceptor{name = "MyFieldInterceptor"}
|
|
* 1: i64 id;
|
|
* }
|
|
*
|
|
* The field interceptor `MyFieldInterceptor` will intercept with `interceptThriftFieldAccess`
|
|
* when the field `id` is accessed.
|
|
*/
|
|
@scope.Field
|
|
@thrift.Experimental
|
|
struct FieldInterceptor {
|
|
/**
|
|
* The name of a field interceptor.
|
|
*
|
|
* The field interceptor provides the following API:
|
|
*
|
|
* struct ThriftFieldInterceptor {
|
|
* template <typename T, typename Struct, int16_t FieldId>
|
|
* static void interceptThriftFieldAccess(T&& field,
|
|
* apache::thrift::FieldContext<Struct, FieldId>&& ctx);
|
|
* };
|
|
*
|
|
* The field interceptor intercepts with the field value and the field context.
|
|
* It enforces an easily searchable function name `interceptThriftFieldAccess`.
|
|
*/
|
|
1: string name;
|
|
|
|
/**
|
|
* Setting to true makes compiler not inline and erase function signature for
|
|
* the intercepting field accessor.
|
|
*/
|
|
2: bool noinline;
|
|
}
|
|
|
|
@scope.Program
|
|
@scope.Structured
|
|
struct UseOpEncode {}
|
|
|
|
/**
|
|
* Enum in C++ by default uses signed 32 bit integer. There is no need to specify
|
|
* underlying type for signed 32 bit integer.
|
|
* 64-bit is not supported to avoid truncation since enums are sent as 32-bit integers over the wire.
|
|
*/
|
|
enum EnumUnderlyingType {
|
|
/** ::std::int8_t */
|
|
I8 = 0,
|
|
/** ::std::uint8_t */
|
|
U8 = 1,
|
|
/** ::std::int16_t */
|
|
I16 = 2,
|
|
/** ::std::uint16_t */
|
|
U16 = 3,
|
|
/** ::std::uint32_t */
|
|
U32 = 4,
|
|
}
|
|
|
|
/**
|
|
* Indicates an integer type for C++ to use as the underlying type of enum, for example:
|
|
*
|
|
* @cpp.EnumType{type = cpp.EnumUnderlyingType.I8}
|
|
* enum Fruit {
|
|
* Apple = 0,
|
|
* Banana = 1,
|
|
* }
|
|
*
|
|
* will be generated into the following:
|
|
*
|
|
* enum class Fruit : ::std::int8_t {
|
|
* Apple = 0,
|
|
* Banana = 1,
|
|
* };
|
|
*
|
|
*/
|
|
@scope.Enum
|
|
struct EnumType {
|
|
1: EnumUnderlyingType type;
|
|
}
|
|
|
|
/**
|
|
* Indicates that frozen types should not be generated for a given struct.
|
|
*/
|
|
@scope.Structured
|
|
struct Frozen2Exclude {}
|
|
|
|
/**
|
|
* Indicates that the container params must be complete at the time this type is instantiated.
|
|
* Only required in rare cases where the build fails with a frozen-related assert failure.
|
|
*/
|
|
@scope.Typedef
|
|
struct Frozen2RequiresCompleteContainerParams {}
|
|
|
|
/**
|
|
* Causes C++ handler code to run inline on the EventBase thread.
|
|
* Disables overload protection, use with caution.
|
|
* Cannot be applied to individual functions in interactions.
|
|
*
|
|
* Causes the request to be executed on the event base thread directly instead of rescheduling onto a thread manager thread, provided the async_eb_ handler method is implemented.
|
|
* You should only execute the request on the event base thread if it is very fast and you have measured that rescheduling is a substantial chunk of your service's CPU usage.
|
|
* If a request executing on the event base thread blocks or takes a long time, all other requests sharing the same event base are affected and latency will increase significantly.
|
|
* We strongly discourage the use of this annotation unless strictly necessary. You will have to implement the harder-to-use async_eb_ handler method.
|
|
* This also disables queue timeouts, an important form of overload protection.
|
|
*/
|
|
@scope.Function
|
|
@scope.Interaction
|
|
struct ProcessInEbThreadUnsafe {}
|
|
|
|
/**
|
|
* Applies to structured annotation that need to be accessed in Runtime.
|
|
*/
|
|
@scope.Struct
|
|
struct RuntimeAnnotation {}
|