Slice Metadata Directives
On this page:
General Metadata Directives
amd
This directive applies to interfaces, classes, and individual operations. It enables code generation for asynchronous method dispatch. (See the relevant language mapping chapter for details.)
async-oneway
This directive applies to local interfaces, local classes and individual operations in local classes and local interfaces. It enables the generation of and extra asynchronous version of the operation. For TypeScript only the asynchronous version of the operation will be generated in this case.
delegate
This directive applies only to local interfaces with one operation. Interfaces with this metadata will be generated as a std::function
in C++, a delegate
in C#, and an interface with one operation (usable as a FunctionalInterface
for Java 8)
in Java.
deprecate
This directive allows you to emit a deprecation warning for Slice constructs.
ice-prefix
This file directive allows the use of identifiers that start with the reserved prefix Ice
(or ICE
, ice
etc.). Only Slice files provided by Ice should use this directive.
format
This directive defines the encoding format used for any classes or exceptions marshaled as the arguments or results of an operation. The tag can be applied to an interface, which affects all of its operations, or to individual operations. Legal values for the tag are format:sliced
, format:compact
, and format:default
. A tag specified for an operation overrides any setting applied to its enclosing interface. The Ice.Default.SlicedFormat
property defines the behavior when no tag is present.
marshaled-result
This directive changes the return type of servant methods so that a servant can force its results to be marshaled immediately in a thread-safe manner. Refer to the relevant server-side language mapping sections for more information on the rules for parameter passing.
preserve-slice
This directive applies to classes and exceptions, allowing an intermediary to forward an instance of the annotated type, or any of its subtypes, with all of its slices intact. Operations that transfer such types must be annotated with format:sliced
. It is not necessary to repeat the preserve-slice
tag on derived types, but you may wish to do so for documentation purposes.
protected
This directive applies to data members of classes and changes code generation to make these members protected. See class mapping of the relevant language mapping chapter for more information.
suppress-warning
This file directive allows to suppress Slice compiler warnings. It applies to all definitions in the Slice file that includes this directive. If one or more categories are specified (for example "suppress-warning:invalid-metadata"
or "suppress-warning:deprecated, invalid-metadata"
) only warnings matching these categories will be suppressed, otherwise all warnings are suppressed. The categories are described in the following table:
Suppress Warning Category | Description |
---|---|
all | Suppress all Slice compiler warnings. Equivalent to [["suppress-warning"]] . |
deprecated | Suppress warnings related to deprecated features. |
invalid-metadata | Suppress warnings related to invalid metadata. |
underscore
This file directive allows the use of identifiers with underscores. It applies to all definitions in the Slice file that includes this directive.
Metadata Directives for C++
The Slice to C++ compiler understands three C++ metadata prefixes: cpp
, cpp11
and cpp98
. Most C++ metadata directives can be specified with either one of the prefixes.
cpp11
and cpp98
directives applies only to their respective mapping. A cpp
metadata directive applies to both mappings, and can be overridden by the same directive with cpp98
or cpp11
. For example:
["cpp:type:MyType", "cpp11:type:MyNewType"] sequence<byte> ByteSeq;
maps ByteSeq
to MyType
with the C++98 mapping, and to MyNewType
with the C++11 mapping.
cpp:array
This directive applies to sequence parameters in operations. It directs the code generator to map these parameters to pairs of pointers.
cpp:class
This directive applies to structures. It directs the code generator to create a C++ class (instead of a C++ structure) to represent a Slice structure. This is a C++98-only metadata: it has no effect with the C++11 mapping.
cpp:comparable
This directive applies to structures. It directs the code generator to generate comparison operators for a structure regardless of whether it qualifies as a legal dictionary key type. This is a C++98-only metadata: it has no effect with the C++11 mapping.
cpp:const
This directive applies to operations. It directs the code generator to create a const
pure virtual member function for the skeleton class.
cpp:dll-export:SYMBOL
This file directive applies to all definitions in a Slice file.
Use SYMBOL
to control the export and import of symbols from DLLs on Windows and dynamic shared libraries on other platforms. This option allows you to export symbols from the generated code, and place such generated code in a DLL (on Windows) or shared library (on other platforms). As an example, compiling a Slice file Widget.ice
with:
[["cpp:dll-export:WIDGET_API"]]
results in the following additional code being generated into Widget.h
:
#ifndef WIDGET_API # if defined(ICE_STATIC_LIBS) # define WIDGET_API /**/ # ifdef WIDGET_API_EXPORTS # define WIDGET_API ICE_DECLSPEC_EXPORT # else # define WIDGET_API ICE_DECLSPEC_IMPORT # endif #endif
The generated code also includes the provided SYMBOL
name (WIDGET_API
in our example) in the declaration of classes and functions that need to be exported (when building a DLL or dynamic library) or imported (when using such library).
ICE_DECLSPEC_EXPORT
and ICE_DECLSPEC_IMPORT
are macros that expand to compiler-specific attributes. For example, for Visual Studio, they are defined as:
#if defined(_MSC_VER) # define ICE_DECLSPEC_EXPORT __declspec(dllexport) # define ICE_DECLSPEC_IMPORT __declspec(dllimport)
With GCC and clang, they are defined as:
#elif defined(__GNUC__) || defined(__clang__) # define ICE_DECLSPEC_EXPORT __attribute__((visibility ("default"))) # define ICE_DECLSPEC_IMPORT __attribute__((visibility ("default")))
The generated .cpp file (Widget.cpp
in our example) defines SYMBOL_EXPORTS
; this way, you don't need to do anything special when compiling generated files.
cpp:header-ext
This file directive allows you to use a file extension for C++ header files other than the default .h
extension.
cpp:ice_print
This directive applies to exceptions. It directs the code generator to declare (but not implement) an ice_print
member function that overrides the ice_print
virtual function inherited from an Ice base class. The application must provide the implementation of this ice_print
function.
cpp:include
This file directive allows you inject additional #include
directives into the generated C++ header file. This is useful for custom types.
cpp:noexcept
This directive applies only to operations on local interfaces. When specified, the generated C++ pure virtual function declaration will carry the noexcept
specifier (C++11) or the ICE_NOEXCEPT
macro (C++98). ICE_NOEXCEPT expands to noexcept
or throw()
depending the C++ compiler and C++ compilation flags.
cpp:range
This directive applies to sequence parameters in operations. It directs the code generator to map these parameters to pairs of iterators. This is a C++98-only metadata direcetive: it has no effect with the C++11 mapping.
cpp:scoped
This directive applies to enumerations. It directs the code generator to use the enumeration's name as prefix for all generated C++ enumerators. This is a C++98-only metadata directive: it has no effect on the C++11 mapping. See also cpp:unscoped
below.
cpp:source-ext
This file directive allows you to use a file extension for C++ source files other than the default .cpp
extension.
cpp:source-include
This file directive allows you inject additional #include
directives into the generated C++ source file. This is required to make forward declared types visible to the source files.
cpp:type:c++-type
This directive applies to sequences and dictionaries. It directs the code generator to map the Slice type or parameter to the provided C++ type.
cpp:type:string
and cpp:type:wstring
These directives apply to data members of type string as well as to containers, such as structures, classes and exceptions. String members map by default to std::string
. You can use the cpp:type:wstring
metadata to cause a string data member (or all string data members in a structure, class or exception) to map to std::wstring
instead. Use the cpp:type:string
metadata to force string members to use the default mapping regardless of any enclosing metadata.
module A { ["cpp:type:wstring"] struct Struct1 { string s1; // Maps to std::wstring ["cpp:type:string"] string s2; // Maps to std::string } }
cpp:unscoped
This directive applies to enumerations. It directs the code generator to create an old-type unscoped C++ enumeration instead of a scoped enumeration (enum class
). This is a C++11-only directive: it has no effect on the C++98 mapping. See also cpp:scoped
above.
cpp:view-type:c++-view-type
This directive applies to string, sequence and dictionary parameters. It directs the code generator to map this parameter to the provided C++ type when this parameter does not need to hold any memory, for example when mapping an in-parameter to a proxy function.
cpp:virtual
This directive applies to classes with the C++98 mapping only. It has no effect with the C++11 mapping. If the directive is present and a class has base classes, the generated C++ class derives virtually from its bases; without this directive, slice2cpp generates the class so it derives non-virtually from its bases.
This directive is useful if you use Slice classes as servants and want to inherit the implementation of operations in the base class in the derived class. For example:
class Base { int baseOp(); } ["cpp:virtual"] class Derived extends Base { string derivedOp(); }
The metadata directive causes slice2cpp to generate the class definition for Derived
using virtual inheritance:
class Base : public virtual Ice::Object { // ... }; class Derived : public virtual Base { // ... };
This allows you to reuse the implementation of baseOp
in the servant for Derived
using ladder inheritance:
class BaseI : public virtual Base { Ice::Int baseOp(const Ice::Current&); // ... }; class DerivedI : public virtual Derived, public virtual BaseI { // Re-use inherited baseOp() };
Note that, if you have data member in classes and use virtual inheritance, you need to take care to correctly call base class constructors if you implement your own one-shot constructor. For example:
class Base { int baseInt; } class Derived extends Base { int derivedInt; }
The generated one-shot constructor for Derived
initializes both baseInt
and derivedInt
:
Derived::Derived(Ice::Int iceP_baseInt, Ice::Int iceP_derivedInt) : M::Base(iceP_baseInt), derivedInt(iceP_derivedInt) { }
If you derive your own class from Derived
and add a one-shot constructor to your class, you must explicitly call the constructor of all the base classes, including Base
. Failure to call the Base
constructor will result in Base
being default-constructed instead of getting a defined value. For example:
class DerivedI : public virtual Derived { public: DerivedI(int baseInt, int derivedInt, const string& s) : Base(baseInt), Derived(baseInt, derivedInt), _s(s) { } private: string _s; };
This code correctly initializes the baseInt
member of the Base
part of the class. Note that the following does not work as intended and leaves the Base
part default-constructed (meaning that baseInt
is not initialized):
class DerivedI : public virtual Derived { public: DerivedI(int baseInt, int derivedInt, const string& s) : Derived(baseInt, derivedInt), _s(s) { // WRONG: Base::baseInt is not initialized. } private: string _s; };
Metadata Directives for C#
The metadata for C# (or .NET) directives uses the cs
prefix or the clr
prefix. These two prefixes are interchangeable: cs:attribute
and clr:attribute
have exactly the same meaning. We present these directives with the cs
prefix below.
In Ice releases prior to 3.7, the cs
prefix was used exclusively for the metadata directives cs:attribute
and cs:tie
while the clr
prefix was used for all other directives.
cs:attribute
This directive can be used both as a file directive and as directive for specific Slice constructs. It injects C# attribute definitions into the generated code. (See C-Sharp Attribute Metadata Directive.)
cs:class
This directive applies to Slice structures. It directs the code generator to emit a C# class instead of a structure.
cs:generic:List
, cs:generic:LinkedList
, cs:generic:Queue
and cs:generic:Stack
These directives apply to sequences and map them to the specified sequence type.
cs:generic:SortedDictionary
This directive applies to dictionaries and maps them to SortedDictionary
.
cs:generic
This directive applies to sequences and allows you map them to custom types.
cs:implements:type
This directive adds the specified base type to the generated code for a Slice structure, class or interface. For example, Ice defines the Communicator
interface as shown below:
["cs:implements:global::System.IDisposable"] local interface Communicator { ... }
Consequently, the generated C# interface Ice.Communicator
implements IDisposable
.
When used with structs, this metadata can only refer to interfaces without operations. With classes, the code is responsible for registering a value factory if the Slice class is transferred over-the-wire and uses this metadata to implement native C# interfaces.
cs:namespace:namespace
This module directive instructs the code generator to place the generated C# constructs into the specified namespace. This directive applies only to top-level modules.
When applying this directive to a module that is reopened by your Slice file, you must repeat the metadata for each reopening of the module if you want to remain consistent:
// // module M is mapped to namespace MyWidget.M // ["cs:namespace:MyWidget"] module M { ... } // // Re-open module M to define more types // ["cs:namespace:MyWidget"] module M { ... }
cs:property
This directive applies to Slice structures and classes. It directs the code generator to create C# property definitions for data members.
cs:serializable
This directive allows you to use Ice to transmit serializable CLR classes as native objects, without having to define corresponding Slice definitions for these classes.
cs:tie
This directive applies to an interface or a class with operations, and triggers the generation of a tie class.
cs:typeid-namespace:namespace
This file directive instructs the code generator to generate type ID helper classes in the specified namespace. If not specified, these helper classes are generated in the Ice.TypeId
namespace. See the C-Sharp Mapping for Modules for more details.
Metadata Directives for Java
java:buffer
This directive applies to sequences of certain primitive types. It directs the translator to map the sequence to a subclass of java.nio.Buffer
.
java:getset
This directive applies to data members and structures, classes, and exceptions. It adds accessor and modifier methods (JavaBean methods) for data members.
java:implements:type
This directive adds the specified base interface to the generated code for a Slice structure, class or interface. For example, Ice defines the Communicator
interface as shown below:
["java:implements:java.lang.AutoCloseable"] local interface Communicator { ... }
Consequently, the generated Java interface Communicator
implements java.lang.AutoCloseable
.
When used with structs, this metadata can only refer to interfaces without operations. With classes or interfaces, the generated Java interface will be marked as abstract
. The code is responsible for registering a value factory if the Slice class is transferred over-the-wire and uses this metadata to implement native Java interfaces.
java:optional
This directive is only used by the Java Compat mapping and has no effect in the Java mapping.
This directive forces optional output parameters to use the optional mapping instead of the default required mapping in servants.
java:package:package
This directive instructs the code generator to place the generated classes into a specific package. The directive can be used as file metadata and can also be applied to top-level modules. File metadata (if any) serves as the default directive unless overridden by module metadata.
When applying this directive to a module that is reopened by your Slice file, you must repeat the metadata for each reopening of the module if you want the packaging to remain consistent:
["java:package:MyPackage"] module M { ... } // // Re-open module M to define more types // ["java:package:MyPackage"] module M { ... }
java:serializable
This directive allows you to use Ice to transmit serializable Java classes as native objects, without having to define corresponding Slice definitions for these classes.
java:serialVersionUID
This directive overrides the default (generated) value of serialVersionUID
for a Slice type.
java:tie
This directive is only used by the Java Compat mapping and has no effect in the Java mapping.
This directive applies to an interface or a class with operations, and triggers the generation of a tie class.
java:type
This directive allows you to use custom types for sequences and dictionaries.
java:UserException
This directive applies to operations, and indicates that the generated Java methods on the mapped servant interfaces and class can throw any user exception, regardless of its specific definition. The exception specification for these methods is simply throws com.zeroc.Ice.UserException
(Java) or throws Ice.UserException
(Java Compat). This metadata has no effect on the methods of generated proxies. The directive UserException
(without the java:
prefix) is a deprecated alias for java:UserException
.
Metadata Directives for JavaScript
The metadatra for JavaScript directives uses the js
prefix.
js:async
This directive applies to local operations, and affects the TypeScript
generated definition for a local operation, enabling the generation of an asynchronous operation definition instead of the default synchronous definition generated for local operations.
js:defined-in:file-name
This directive apply to forward declarations, slice2js needs to know where the forward declared type is defined in order to generate the correct in JavaScript import statements, file-name must be the relative path to the file that defines the forward declared type.
js:es6-module
This file directive allows you to change the default mapping of JavaScript modules and enables the use of ES6 modules. See JavaScript mapping for modules.
js:module:module-name
This file directive allows you to bundle the generated code for several Slice files into a single JavaScript module. See JavaScript mapping for modules.
Metadata Directives for Objective-C
objc:dll-export:SYMBOL
This file directive applies to all definitions in a Slice file.
Use SYMBOL
to control the export of symbols from dynamic shared libraries. This option allows you to export symbols from the generated code and place such generated code in a shared library. Compiling a Slice definition with:
[["objc:dll-export:WIDGET_API"]]
adds the provided SYMBOL
name (WIDGET_API
in our example) to the declaration of interfaces and protocols that need to be exported. The generated code also defines the provided SYMBOL as __attribute__((visibility ("default")))
.
This option is useful when you create a shared library and compile your Objective-C code with -fvisibility=hidden
to reduce the number of symbols exported.
objc:header-dir
This file directive allows you to specify a prefix for the header path in generated Objective-C files. For example, all the Slice files from Ice set this metadata to objc
to allow importing Objective-C headers from the objc
directory (e.g.: #import <objc/Ice/Ice.h>
).
objc:prefix
This directive applies to modules and changes the default mapping for modules to use a specified prefix.
objc:scoped
This directive applies to enumerations. It directs the code generator to use the enumeration's name as prefix for all generated Objective-C enumerators.
Metadata Directives for Python
python:array.array
Instruct the Ice for Python run-time to unmarshall a sequence as a Python array.array type, it is valid for integral builtin types excluding strings see customizing the sequence mapping in Python.
python:memoryview:<factory>
Instruct the Ice for Python run-time to unmarshall a sequence as a custom Python type created from a Python memoryview object see customizing the sequence mapping in Python.
python:numpy.ndarray
Instruct the Ice for Python run-time to unmarshall a sequence as a Python numpy.ndarray type, it is valid for integral builtin types excluding strings see customizing the sequence mapping in Python.
python:package:package
This directive instructs the code generator to enclose the generated code in a specified Python package. The directive can be used as file metadata and can also be applied to top-level modules. File metadata (if any) serves as the default directive unless overridden by module metadata.
When applying this directive to a module that is reopened by your Slice file, you must repeat the metadata for each reopening of the module if you want the packaging to remain consistent:
["python:package:MyPackage"] module M { ... } // // Re-open module M to define more types // ["python:package:MyPackage"] module M { ... }
python:pkgdir
This file directive instructs the code generator to place the generated code into a specified directory.
python:seq:default
, python:seq:list
and python:seq:tuple
These directives allow you to change the mapping for Slice sequences.
Metadata Directives for Swift
swift:attribute:attribute
This directive adds the specified Swift attribute to the generated code. It can be used with classes, enums, exceptions and local operations. For example, the ObjectAdapter
operation add
uses the Swift @discardableResult
attribute as shown below:
["swift:nonnull", "swift:attribute:@discardableResult"] Object* add(["swift:nonnull"] Object servant, Identity id);
swift:inherits:protocol
This directive adds the specified base type (usually a protocol) to the generated code for a Slice class or interface. For non-local types, only the generated skeleton protocol inherits from the specified type.
For example, Ice defines the Endpoint
interface as shown below:
["swift:inherits:Swift.CustomStringConvertible"] local interface Endpoint
swift:module:module:prefix
This directive applies to Slice modules and instructs the code generator to map this Slice module to the specified Swift module. All Swift identifiers also receive the specified prefix, as if they were defined in a nested module prefix.
With respect to the Swift mapping:
["swift:module:Mod:Pre"] module Test { ... }
is equivalent to:
module Mod { module Pre { ... } }
Metadata directives never change type IDs. For example, exception E
defined in module Test
has type ID "::Test::E"
regardless of any swift:module
metadata directive on module Test
.
swift:noexcept
This directive applies to local operations and instructs the code generator to generate a Swift instance method that does not throw any exception. For example:
local interface Communicator { ["swift:noexcept"] void destroy(); }
is mapped to:
public protocol Communicator: AnyObject { func destroy() }
swift:nonnull
This directive applies to a parameter and the return value of a local operation, when the associated type is a nullable Slice type, namely:
- a proxy such as
Object*
orHello*
- a class instance, such as
Value
orEmployeeDescription
- a servant (
Object
) - a local interface or class, such as
Communicator
orEndpointInfo
This directive instructs the code generator to generate a non-optional parameter or return value. For example:
local interface ObjectAdapter { ["swift:nonnull"] Object* add(["swift:nonnull"] Object servant, Identity id); }
is mapped to:
public protocol ObjectAdapter: AnyObject { func add(servant: Object, id: Identity) throws -> ObjectPrx }
Without the nonnull
metadata directive, the mapped instance method would accept an Object?
servant and return an ObjectPrx?
.
This directive also applies to local Slice sequences and values of local Slice dictionaries. For example, you can define a local sequence of non-null proxies, and a local dictionary with non-null values as follows:
["swift:nonnull"] local sequence<Object*> ProxySeq; local dictionary<string, ["swift:nonnull"] Object*> StringProxyDict;
And the corresponding Swift code is:
public typealias ProxySeq = [Ice.ObjectPrx] public typealias StringProxyDict = [String: Ice.ObjectPrx]
swift:type:type
This directive applies to local types. It directs the code generator to map the Slice type or parameter to the provided Swift type.
Metadata Directives for Freeze
freeze:read
and freeze:write
These directives inform a Freeze evictor whether an operation updates the state of an object, so the evictor knows whether it must save an object before evicting it.