]> git.proxmox.com Git - ceph.git/blame - ceph/src/jaegertracing/thrift/doc/specs/idl.md
buildsys: switch source download to quincy
[ceph.git] / ceph / src / jaegertracing / thrift / doc / specs / idl.md
CommitLineData
f67539c2
TL
1## Thrift interface description language
2
3For Thrift version 0.13.0.
4
5The 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.
6
7## Description
8
9Here is a description of the Thrift IDL.
10
11## Document
12
13Every Thrift document contains 0 or more headers followed by 0 or more definitions.
14
15 [1] Document ::= Header* Definition*
16
17## Header
18
19A header is either a Thrift include, a C++ include, or a namespace declaration.
20
21 [2] Header ::= Include | CppInclude | Namespace
22
23### Thrift Include
24
25An 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.
26
27 [3] Include ::= 'include' Literal
28
29### C++ Include
30
31A C++ include adds a custom C++ include to the output of the C++ code generator for this Thrift document.
32
33 [4] CppInclude ::= 'cpp_include' Literal
34
35### Namespace
36
37A 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.
38
39 [5] Namespace ::= ( 'namespace' ( NamespaceScope Identifier ) )
40
41 [6] NamespaceScope ::= '*' | 'c_glib' | 'cpp' | 'csharp' | 'delphi' | 'go' | 'java' | 'js' | 'lua' | 'netcore' | 'perl' | 'php' | 'py' | 'py.twisted' | 'rb' | 'st' | 'xsd'
42
43## Definition
44
45 [7] Definition ::= Const | Typedef | Enum | Senum | Struct | Union | Exception | Service
46
47### Const
48
49 [8] Const ::= 'const' FieldType Identifier '=' ConstValue ListSeparator?
50
51### Typedef
52
53A typedef creates an alternate name for a type.
54
55 [9] Typedef ::= 'typedef' DefinitionType Identifier
56
57### Enum
58
59An 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.
60
61 [10] Enum ::= 'enum' Identifier '{' (Identifier ('=' IntConstant)? ListSeparator?)* '}'
62
63### Senum
64
65Senum (and Slist) are now deprecated and should both be replaced with String.
66
67 [11] Senum ::= 'senum' Identifier '{' (Literal ListSeparator?)* '}'
68
69### Struct
70
71Structs are the fundamental compositional type in Thrift. The name of each field must be unique within the struct.
72
73 [12] Struct ::= 'struct' Identifier 'xsd_all'? '{' Field* '}'
74
75N.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
76
77### Union
78
79Unions 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).
80
81 [13] Union ::= 'union' Identifier 'xsd_all'? '{' Field* '}'
82
83N.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
84
85### Exception
86
87Exceptions 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.
88
89 [14] Exception ::= 'exception' Identifier '{' Field* '}'
90
91### Service
92
93A 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.
94
95 [15] Service ::= 'service' Identifier ( 'extends' Identifier )? '{' Function* '}'
96
97## Field
98
99 [16] Field ::= FieldID? FieldReq? FieldType Identifier ('=' ConstValue)? XsdFieldOptions ListSeparator?
100
101### Field ID
102
103 [17] FieldID ::= IntConstant ':'
104
105### Field Requiredness
106
107There are two explicit requiredness values, and a third one that is applied implicity if neither *required* nor *optional* are given: *default* requiredness.
108
109 [18] FieldReq ::= 'required' | 'optional'
110
111The general rules for requiredness are as follows:
112
113#### required
114
115- Write: Required fields are always written and are expected to be set.
116- Read: Required fields are always read and are expected to be contained in the input stream.
117- Defaults values: are always written
118
119If 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.
120
121Because 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.
122
123#### optional
124
125- Write: Optional fields are only written when they are set
126- Read: Optional fields may, or may not be part of the input stream.
127- Default values: are written when the isset flag is set
128
129Most language implementations use the recommended practice 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.
130
131#### default requiredness (implicit)
132
133- Write: In theory, the fields are always written. There are some exceptions to that rule, see below.
134- Read: Like optional, the field may, or may not be part of the input stream.
135- Default values: may not be written (see next section)
136
137Default requiredness 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.
138
139#### Semantics of Default Values
140
141There 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.
142
143The 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.
144
145### XSD Options
146
147N.B.: These have some internal purpose at Facebook but serve no current purpose in Thrift. Use of these options is strongly discouraged.
148
149 [19] XsdFieldOptions ::= 'xsd_optional'? 'xsd_nillable'? XsdAttrs?
150
151 [20] XsdAttrs ::= 'xsd_attrs' '{' Field* '}'
152
153## Functions
154
155 [21] Function ::= 'oneway'? FunctionType Identifier '(' Field* ')' Throws? ListSeparator?
156
157 [22] FunctionType ::= FieldType | 'void'
158
159 [23] Throws ::= 'throws' '(' Field* ')'
160
161## Types
162
163 [24] FieldType ::= Identifier | BaseType | ContainerType
164
165 [25] DefinitionType ::= BaseType | ContainerType
166
167 [26] BaseType ::= 'bool' | 'byte' | 'i8' | 'i16' | 'i32' | 'i64' | 'double' | 'string' | 'binary' | 'slist'
168
169 [27] ContainerType ::= MapType | SetType | ListType
170
171 [28] MapType ::= 'map' CppType? '<' FieldType ',' FieldType '>'
172
173 [29] SetType ::= 'set' CppType? '<' FieldType '>'
174
175 [30] ListType ::= 'list' '<' FieldType '>' CppType?
176
177 [31] CppType ::= 'cpp_type' Literal
178
179## Constant Values
180
181 [32] ConstValue ::= IntConstant | DoubleConstant | Literal | Identifier | ConstList | ConstMap
182
183 [33] IntConstant ::= ('+' | '-')? Digit+
184
185 [34] DoubleConstant ::= ('+' | '-')? Digit* ('.' Digit+)? ( ('E' | 'e') IntConstant )?
186
187 [35] ConstList ::= '[' (ConstValue ListSeparator?)* ']'
188
189 [36] ConstMap ::= '{' (ConstValue ':' ConstValue ListSeparator?)* '}'
190
191## Basic Definitions
192
193### Literal
194
195 [37] Literal ::= ('"' [^"]* '"') | ("'" [^']* "'")
196
197### Identifier
198
199 [38] Identifier ::= ( Letter | '_' ) ( Letter | Digit | '.' | '_' )*
200
201 [39] STIdentifier ::= ( Letter | '_' ) ( Letter | Digit | '.' | '_' | '-' )*
202
203### List Separator
204
205 [40] ListSeparator ::= ',' | ';'
206
207### Letters and Digits
208
209 [41] Letter ::= ['A'-'Z'] | ['a'-'z']
210
211 [42] Digit ::= ['0'-'9']
212
213## Examples
214
215Here are some examples of Thrift definitions, using the Thrift IDL:
216
217 * [ThriftTest.thrift][] used by the Thrift TestFramework
218 * Thrift [tutorial][]
219 * Facebook's [fb303.thrift][]
220 * [Apache Cassandra's][] Thrift IDL: [cassandra.thrift][]
221 * [Evernote API][]
222
223 [ThriftTest.thrift]: https://raw.githubusercontent.com/apache/thrift/master/test/ThriftTest.thrift
224 [tutorial]: /tutorial/
225 [fb303.thrift]: https://raw.githubusercontent.com/apache/thrift/master/contrib/fb303/if/fb303.thrift
226 [Apache Cassandra's]: http://cassandra.apache.org/
227 [cassandra.thrift]: http://svn.apache.org/viewvc/cassandra/trunk/interface/cassandra.thrift?view=co
228 [Evernote API]: http://www.evernote.com/about/developer/api/
229
230## To Do/Questions
231
232Initialization of Base Types for all Languages?
233
234 * Do all Languages initialize them to 0, bool=false and string=""? or null, undefined?
235
236Why does position of `CppType` vary between `SetType` and `ListType`?
237
238 * 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
239 * The question is, how other languages are doing that? What about custom objects, do they have a Compare function the set the order correctly?
240
241 [C++ std:set reference]: http://www.cplusplus.com/reference/stl/set/
242
243Why can't `DefinitionType` be the same as `FieldType` (i.e. include `Identifier`)?
244
245Examine the `smalltalk.prefix` and `smalltalk.category` status (esp `smalltalk.category`, which takes `STIdentifier` as its argument)...
246
247What to do about `ListSeparator`? Do we really want to be as lax as we currently are?
248
249Should `Field*` really be `Field+` in `Struct`, `Enum`, etc.?
250