Skip to main content

Annotations

Annotations provide a way to attach structured metadata to IR specification types. Unlike attributes, which are used for implementation-level metadata (like source locations or inferred types), annotations are used for higher-level semantic labeling of signatures, similar to annotations in Java or Scala.

Annotation Structure

An annotation consists of a fully qualified name (the annotation type) and a set of arguments. Arguments can be positional (a list of values) or named (a mapping from names to values).

pub type Annotation {
Annotation(
name: FQName,
arguments: List(AnnotationArgument)
)
}

pub type AnnotationArgument {
/// Positional argument
PositionalArgument(value: Value)
/// Named argument: @MyAnno(name = "value")
NamedArgument(name: Name, value: Value)
}

JSON Serialization

Annotations support a canonical object format and a compact shorthand string format.

Shorthand Format (Compact)

For simple annotations, a string format is supported: fqname:value.

CaseFormatNote
Marker (0 args)"package:module#name"Just the FQName string
Single Value (1 arg)"package:module#name:value"FQName followed by colon and value

Examples:

  • "morphir/sdk:annotations#stable"
  • "my-org/sdk:annotations#deprecated:Use new-function instead"
  • "my-org/sdk:annotations#version:1.0.0"

Object Format (Canonical)

{
"name": "my-org/sdk:annotations#deprecated",
"arguments": [
{ "Literal": { "StringLiteral": "Use new-function instead" } }
]
}

Named Arguments

{
"name": "my-org/sdk:annotations#info",
"arguments": [
{ "name": "author", "value": { "Literal": { "StringLiteral": "Damian" } } },
{ "name": "version", "value": { "Literal": { "StringLiteral": "1.0.0" } } }
]
}

Mixed Arguments

{
"name": "my-org/sdk:annotations#task",
"arguments": [
{ "Literal": { "StringLiteral": "Refactor this" } },
{ "name": "priority", "value": { "Literal": { "IntegerLiteral": 1 } } }
]
}

Usage Examples and Use Cases

These examples show how common Scala/Java annotations translate into the Morphir IR v4 canonical representation.

1. Stability and Life-cycle

Used to communicate the stability of an API or its deprecation status.

Source (Scala):

@deprecated("Use newMethod instead", "2.0.0")
@stable
def oldMethod(x: Int): Int = ???

Transformed IR (JSON):

{
"annotations": [
{
"name": "morphir/sdk:annotations#deprecated",
"arguments": [
{ "Literal": { "StringLiteral": "Use newMethod instead" } },
{ "Literal": { "StringLiteral": "2.0.0" } }
]
},
"morphir/sdk:annotations#stable"
]
}

2. Physical Schema Mapping

Used to provide hints for code generation or database mapping (e.g. JSON field names).

Source (Scala):

@jsonName("user_id")
case class User(id: String)

Transformed IR (JSON):

{
"CustomTypeSpecification": {
"annotations": [
"my-org/sdk:annotations#json-name:user_id"
],
"typeParams": [],
"constructors": { ... }
}
}

3. Custom Metadata and Tooling Hints

Used for domain-specific labeling or to provide hints to downstream tools (e.g. security audits).

Source (Scala):

@security(level = SecurityLevel.High, roles = Array("admin", "auditor"))
def transferFunds(amount: Double): Unit = ???

Transformed IR (JSON):

{
"annotations": [
{
"name": "my-org/security:annotations#security",
"arguments": [
{
"name": "level",
"value": { "Reference": "my-org/security:types#security-level.high" }
},
{
"name": "roles",
"value": {
"List": [
{ "Literal": { "StringLiteral": "admin" } },
{ "Literal": { "StringLiteral": "auditor" } }
]
}
}
]
}
]
}

Specification Integration

Annotations are only supported on Specification types in Morphir IR v4.

Module Specification

{
"ModuleSpecification": {
"annotations": [
{ "name": "my-org/sdk:annotations#stable", "arguments": [] }
],
"types": { ... },
"values": { ... }
}
}

Type Specification

{
"TypeAliasSpecification": {
"annotations": [
{ "name": "my-org/sdk:annotations#json-name", "arguments": [{ "Literal": { "StringLiteral": "user_id" } }] }
],
"typeParams": [],
"typeExp": "morphir/sdk:string#string"
}
}

Value Specification

{
"ValueSpecification": {
"annotations": [
{ "name": "my-org/sdk:annotations#pure", "arguments": [] }
],
"inputs": { ... },
"output": { ... }
}
}