blob: b7eb23cd579392467666f56eb7a148baf2819561 [file] [log] [blame] [view]
Roger Meierc5026aa2015-02-09 12:03:59 +01001## Thrift interface description language
2The Thrift interface definition language (IDL) allows for the definition of [Thrift Types](/docs/types). A Thrift IDL file is processed by the Thrift code generator to produce code for the various target languages to support the defined structs and services in the IDL file.
3
4## Description
5
6*Under construction*
7
8Here is a description of the Thrift IDL.
9
10## Document
11
12Every Thrift document contains 0 or more headers followed by 0 or more definitions.
13
14 [1] Document ::= Header* Definition*
15
16## Header
17
18A header is either a Thrift include, a C++ include, or a namespace declaration.
19
20 [2] Header ::= Include | CppInclude | Namespace
21
22### Thrift Include
23
24An include makes all the symbols from another file visible (with a prefix) and adds corresponding include statements into the code generated for this Thrift document.
25
26 [3] Include ::= 'include' Literal
27
28### C++ Include
29
30A C++ include adds a custom C++ include to the output of the C++ code generator for this Thrift document.
31
32 [4] CppInclude ::= 'cpp_include' Literal
33
34### Namespace
35
36A namespace declares which namespaces/package/module/etc. the type definitions in this file will be declared in for the target languages. The namespace scope indicates which language the namespace applies to; a scope of '*' indicates that the namespace applies to all target languages.
37
38 [5] Namespace ::= ( 'namespace' ( NamespaceScope Identifier ) |
39 ( 'smalltalk.category' STIdentifier ) |
40 ( 'smalltalk.prefix' Identifier ) ) |
41 ( 'php_namespace' Literal ) |
42 ( 'xsd_namespace' Literal )
43
44 [6] NamespaceScope ::= '*' | 'cpp' | 'java' | 'py' | 'perl' | 'rb' | 'cocoa' | 'csharp'
45
Roger Meier17aa4742015-02-09 12:09:19 +010046N.B.: Smalltalk has two distinct types of namespace commands:
47
48- smalltalk.prefix: Prepended to generated classnames.
49 - Smalltalk does not have namespaces for classes, so prefixes
50 are used to avoid class-name collisions.
51 Often, the prefix is the author's initials, like "KB" or "JWS",
52 or an abbreviation of the package name, like "MC" for "Monticello".
53- smalltalk.category: Determines the category for generated classes.
54 Any dots in the identifier will be replaced with hyphens when generating
55 the category name.
56 If not provided, defaults to "Generated-" + the program name.
57 Methods will not be categorized beyond "as yet uncategorized".
58 - Smalltalk allows filing both classes and methods within classes into named
59 groups. These named groups of methods are called categories.
Roger Meierc5026aa2015-02-09 12:03:59 +010060
61N.B.: The `php_namespace` directive will be deprecated at some point in the future in favor of the scoped syntax, but the scoped syntax is not yet supported for PHP.
62
63N.B.: The `xsd_namespace` directive has some purpose internal to Facebook but serves no purpose in Thrift itself. Use of this feature is strongly discouraged
64
65## Definition
66
67 [7] Definition ::= Const | Typedef | Enum | Senum | Struct | Union | Exception | Service
68
69### Const
70
71 [8] Const ::= 'const' FieldType Identifier '=' ConstValue ListSeparator?
72
73### Typedef
74
75A typedef creates an alternate name for a type.
76
77 [9] Typedef ::= 'typedef' DefinitionType Identifier
78
79### Enum
80
81An enum creates an enumerated type, with named values. If no constant value is supplied, the value is either 0 for the first element, or one greater than the preceding value for any subsequent element. Any constant value that is supplied must be non-negative.
82
83 [10] Enum ::= 'enum' Identifier '{' (Identifier ('=' IntConstant)? ListSeparator?)* '}'
84
85### Senum
86
87Senum (and Slist) are now deprecated and should both be replaced with String.
88
89 [11] Senum ::= 'senum' Identifier '{' (Literal ListSeparator?)* '}'
90
91### Struct
92
93Structs are the fundamental compositional type in Thrift. The name of each field must be unique within the struct.
94
95 [12] Struct ::= 'struct' Identifier 'xsd_all'? '{' Field* '}'
96
97N.B.: The `xsd_all` keyword has some purpose internal to Facebook but serves no purpose in Thrift itself. Use of this feature is strongly discouraged
98
99### Union
100
Jens Geyerfe9222a2016-03-24 00:33:06 +0200101Unions are similar to structs, except that they provide a means to transport exactly one field of a possible set of fields, just like union {} in C++. Consequently, union members are implicitly considered optional (see requiredness).
Roger Meierc5026aa2015-02-09 12:03:59 +0100102
103 [13] Union ::= 'union' Identifier 'xsd_all'? '{' Field* '}'
104
105N.B.: The `xsd_all` keyword has some purpose internal to Facebook but serves no purpose in Thrift itself. Use of this feature is strongly discouraged
106
107### Exception
108
109Exceptions are similar to structs except that they are intended to integrate with the native exception handling mechanisms in the target languages. The name of each field must be unique within the exception.
110
111 [14] Exception ::= 'exception' Identifier '{' Field* '}'
112
113### Service
114
115A service provides the interface for a set of functionality provided by a Thrift server. The interface is simply a list of functions. A service can extend another service, which simply means that it provides the functions of the extended service in addition to its own.
116
117 [15] Service ::= 'service' Identifier ( 'extends' Identifier )? '{' Function* '}'
118
119## Field
120
121 [16] Field ::= FieldID? FieldReq? FieldType Identifier ('= ConstValue)? XsdFieldOptions ListSeparator?
122
123### Field ID
124
125 [17] FieldID ::= IntConstant ':'
126
127### Field Requiredness
128
Jens Geyerfe9222a2016-03-24 00:33:06 +0200129There are two explicit requiredness values, and a third one that is applied implicity if neither *required* nor *optional* are given: *default* requiredness.
130
131 [18] FieldReq ::= 'required' | 'optional'
132
133The general rules for requiredness are as follows:
134
135#### required
136
137- Write: Required fields are always written and are expected to be set.
138- Read: Required fields are always read and are expected to be contained in the input stream.
139- Defaults values: are always written
140
141If a required field is missing during read, the expected behaviour is to indicate an unsuccessful read operation to the caller, e.g. by throwing an exception or returning an error.
142
143Because of this behaviour, required fields drastically limit the options with regard to soft versioning. Because they must be present on read, the fields cannot be deprecated. If a required field would be removed (or changed to optional), the data are no longer compatible between versions.
144
145#### optional
146
147- Write: Optional fields are only written when they are set
148- Read: Optional fields may, or may not be part of the input stream.
149- Default values: are written when the isset flag is set
150
151Most language implementations use the recommended pratice of so-called "isset" flags to indicate whether a particular optional field is set or not. Only fields with this flag set are written, and conversely the flag is only set when a field value has been read from the input stream.
152
153#### default requiredness (implicit)
154
155- Write: In theory, the fields are always written. There are some exceptions to that rule, see below.
156- Read: Like optional, the field may, or may not be part of the input stream.
157- Default values: may not be written (see next section)
158
159Default requiredess is a good starting point. The desired behaviour is a mix of optional and required, hence the internal name "opt-in, req-out". Although in theory these fields are supposed to be written ("req-out"), in reality unset fields are not always written. This is especially the case, when the field contains a <null> value, which by definition cannot be transported through thrift. The only way to achieve this is by not writing that field at all, and that's what most languages do.
160
161#### Semantics of Default Values
162
163There are ongoing discussions about that topic, see JIRA for details. Not all implementations treat default values in the very same way, but the current status quo is more or less that default fields are typically set at initialization time. Therefore, a value that equals the default may not be written, because the read end will set the value implicitly. On the other hand, an implementation is free to write the default value anyways, as there is no hard restriction that prevents this.
164
165The major point to keep in mind here is the fact, that any unwritten default value implicitly becomes part of the interface version. If that default is changed, the interface changes. If, in contrast, the default value is written into the output data, the default in the IDL can change at any time without affecting serialized data.
Roger Meierc5026aa2015-02-09 12:03:59 +0100166
167### XSD Options
168
169N.B.: These have some internal purpose at Facebook but serve no current purpose in Thrift. Use of these options is strongly discouraged.
170
171 [19] XsdFieldOptions ::= 'xsd_optional'? 'xsd_nillable'? XsdAttrs?
172
173 [20] XsdAttrs ::= 'xsd_attrs' '{' Field* '}'
174
175## Functions
176
177 [21] Function ::= 'oneway'? FunctionType Identifier '(' Field* ')' Throws? ListSeparator?
178
179 [22] FunctionType ::= FieldType | 'void'
180
181 [23] Throws ::= 'throws' '(' Field* ')'
182
183## Types
184
185 [24] FieldType ::= Identifier | BaseType | ContainerType
186
187 [25] DefinitionType ::= BaseType | ContainerType
188
Nobuaki Sukegawa1d8e7452016-01-04 02:02:17 +0900189 [26] BaseType ::= 'bool' | 'byte' | 'i8' | 'i16' | 'i32' | 'i64' | 'double' | 'string' | 'binary' | 'slist'
Roger Meierc5026aa2015-02-09 12:03:59 +0100190
191 [27] ContainerType ::= MapType | SetType | ListType
192
193 [28] MapType ::= 'map' CppType? '<' FieldType ',' FieldType '>'
194
195 [29] SetType ::= 'set' CppType? '<' FieldType '>'
196
197 [30] ListType ::= 'list' '<' FieldType '>' CppType?
198
199 [31] CppType ::= 'cpp_type' Literal
200
201## Constant Values
202
203 [32] ConstValue ::= IntConstant | DoubleConstant | Literal | Identifier | ConstList | ConstMap
204
205 [33] IntConstant ::= ('+' | '-')? Digit+
206
207 [34] DoubleConstant ::= ('+' | '-')? Digit* ('.' Digit+)? ( ('E' | 'e') IntConstant )?
208
209 [35] ConstList ::= '[' (ConstValue ListSeparator?)* ']'
210
211 [36] ConstMap ::= '{' (ConstValue ':' ConstValue ListSeparator?)* '}'
212
213## Basic Definitions
214
215### Literal
216
217 [37] Literal ::= ('"' [^"]* '"') | ("'" [^']* "'")
218
219### Identifier
220
221 [38] Identifier ::= ( Letter | '_' ) ( Letter | Digit | '.' | '_' )*
222
223 [39] STIdentifier ::= ( Letter | '_' ) ( Letter | Digit | '.' | '_' | '-' )*
224
225### List Separator
226
227 [40] ListSeparator ::= ',' | ';'
228
229### Letters and Digits
230
231 [41] Letter ::= ['A'-'Z'] | ['a'-'z']
232
233 [42] Digit ::= ['0'-'9']
234
235## Examples
236
237Here are some examples of Thrift definitions, using the Thrift IDL:
238
239 * [ThriftTest.thrift][] used by the Thrift TestFramework
240 * Thrift [tutorial][]
241 * Facebook's [fb303.thrift][]
242 * [Apache Cassandra's][] Thrift IDL: [cassandra.thrift][]
243 * [Evernote API][]
244
245 [ThriftTest.thrift]: https://git-wip-us.apache.org/repos/asf?p=thrift.git;a=blob_plain;f=test/ThriftTest.thrift;hb=HEAD
246 [tutorial]: /tutorial/
247 [fb303.thrift]: https://git-wip-us.apache.org/repos/asf?p=thrift.git;a=blob_plain;f=contrib/fb303/if/fb303.thrift;hb=HEAD
248 [Apache Cassandra's]: http://cassandra.apache.org/
249 [cassandra.thrift]: http://svn.apache.org/viewvc/cassandra/trunk/interface/cassandra.thrift?view=co
250 [Evernote API]: http://www.evernote.com/about/developer/api/
251
252## To Do/Questions
253
254Initialization of Base Types for all Languages?
255
256 * Do all Languages initialize them to 0, bool=false and string=""? or null, undefined?
257
258Why does position of `CppType` vary between `SetType` and `ListType`?
259
260 * std::set does sort the elements automatically, that's the design. see [Thrift Types](/docs/types) or the [C++ std:set reference][] for further details
261 * The question is, how other languages are doing that? What about custom objects, do they have a Compare function the set the order correctly?
262
263 [C++ std:set reference]: http://www.cplusplus.com/reference/stl/set/
264
265Why can't `DefinitionType` be the same as `FieldType` (i.e. include `Identifier`)?
266
267Examine the `smalltalk.prefix` and `smalltalk.category` status (esp `smalltalk.category`, which takes `STIdentifier` as its argument)...
268
269What to do about `ListSeparator`? Do we really want to be as lax as we currently are?
270
271Should `Field*` really be `Field+` in `Struct`, `Enum`, etc.?
272